mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Pair gacha costume bonuses via curated lookup table
Build and Push Docker images to Docker Hub / build-and-push (push) Has been cancelled
Build and Push Docker images to Docker Hub / build-and-push (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
package masterdata
|
||||
|
||||
// Source: based on public_costumes_link_export_2026-05-21_142314.csv by @Keziah,
|
||||
// with each weapon resolved to its m_weapon_evolution_group EvolutionOrder=1 root
|
||||
var costumeWeaponPairings = map[int32]int32{
|
||||
10100: 101001,
|
||||
10101: 101011,
|
||||
10102: 101021,
|
||||
10103: 101031,
|
||||
10104: 101041,
|
||||
10105: 101051,
|
||||
10106: 101061,
|
||||
10107: 101071,
|
||||
10108: 101081,
|
||||
10109: 101091,
|
||||
10110: 101101,
|
||||
10111: 101121,
|
||||
10112: 101111,
|
||||
10113: 101131,
|
||||
10114: 101141,
|
||||
10115: 101151,
|
||||
10116: 101161,
|
||||
10117: 101171,
|
||||
10118: 101181,
|
||||
10119: 101191,
|
||||
10120: 101201,
|
||||
10121: 101211,
|
||||
21000: 210161,
|
||||
21001: 210031,
|
||||
21002: 210171,
|
||||
21003: 210181,
|
||||
21004: 210191,
|
||||
21005: 210271,
|
||||
22000: 220081,
|
||||
22001: 220021,
|
||||
22002: 220051,
|
||||
22003: 220061,
|
||||
22004: 220141,
|
||||
22005: 220161,
|
||||
22006: 220181,
|
||||
22007: 220191,
|
||||
22008: 220211,
|
||||
22009: 220231,
|
||||
22010: 220241,
|
||||
23000: 230001,
|
||||
23001: 230021,
|
||||
23004: 230051,
|
||||
23005: 230151,
|
||||
23006: 230261,
|
||||
23007: 230271,
|
||||
23008: 230281,
|
||||
24000: 240091,
|
||||
24001: 240121,
|
||||
24002: 240131,
|
||||
24003: 240011,
|
||||
24004: 240081,
|
||||
24005: 240201,
|
||||
24006: 240221,
|
||||
24007: 240241,
|
||||
24008: 240271,
|
||||
24009: 240311,
|
||||
25000: 250121,
|
||||
25001: 250071,
|
||||
25002: 250011,
|
||||
25003: 250151,
|
||||
25005: 250021,
|
||||
25006: 250171,
|
||||
25007: 250221,
|
||||
25008: 250231,
|
||||
25009: 250261,
|
||||
31000: 310081,
|
||||
31001: 310061,
|
||||
31002: 310021,
|
||||
31004: 310191,
|
||||
31005: 310211,
|
||||
31008: 310221,
|
||||
31009: 310241,
|
||||
31010: 310261,
|
||||
31011: 310291,
|
||||
31013: 310321,
|
||||
31014: 310331,
|
||||
31015: 310371,
|
||||
31016: 310401,
|
||||
31017: 310411,
|
||||
31018: 310421,
|
||||
31019: 310431,
|
||||
31020: 310461,
|
||||
31021: 310471,
|
||||
31022: 310481,
|
||||
31023: 310511,
|
||||
31024: 310531,
|
||||
31025: 310541,
|
||||
31026: 310551,
|
||||
31027: 310571,
|
||||
31028: 310591,
|
||||
31029: 310621,
|
||||
31030: 310641,
|
||||
31031: 310661,
|
||||
31032: 310691,
|
||||
31033: 310701,
|
||||
31034: 310711,
|
||||
32000: 320081,
|
||||
32001: 320041,
|
||||
32002: 320011,
|
||||
32003: 320111,
|
||||
32004: 320051,
|
||||
32005: 320141,
|
||||
32006: 320151,
|
||||
32007: 320171,
|
||||
32008: 320181,
|
||||
32009: 320201,
|
||||
32011: 320231,
|
||||
32012: 320241,
|
||||
32013: 320271,
|
||||
32014: 320281,
|
||||
32015: 320301,
|
||||
32016: 320331,
|
||||
32017: 320351,
|
||||
32018: 320371,
|
||||
32019: 320381,
|
||||
32020: 320391,
|
||||
32021: 320421,
|
||||
32022: 320431,
|
||||
32023: 320441,
|
||||
32024: 320451,
|
||||
32025: 320461,
|
||||
32026: 320471,
|
||||
32027: 320501,
|
||||
32028: 320531,
|
||||
32029: 320541,
|
||||
32030: 320551,
|
||||
32031: 320561,
|
||||
32032: 320581,
|
||||
32033: 320601,
|
||||
32034: 320611,
|
||||
32035: 320621,
|
||||
32036: 320641,
|
||||
33000: 330001,
|
||||
33001: 330121,
|
||||
33002: 330011,
|
||||
33003: 330021,
|
||||
33005: 330161,
|
||||
33006: 330171,
|
||||
33007: 330191,
|
||||
33009: 330211,
|
||||
33010: 330231,
|
||||
33011: 330261,
|
||||
33012: 330281,
|
||||
33013: 330321,
|
||||
33014: 330341,
|
||||
33015: 330381,
|
||||
33016: 330401,
|
||||
33017: 330421,
|
||||
33018: 330451,
|
||||
33019: 330471,
|
||||
33020: 330501,
|
||||
33021: 330521,
|
||||
33022: 330541,
|
||||
33023: 330551,
|
||||
33024: 330561,
|
||||
33025: 330571,
|
||||
33026: 330581,
|
||||
33027: 330591,
|
||||
33028: 330601,
|
||||
33029: 330631,
|
||||
33030: 330641,
|
||||
33031: 330671,
|
||||
33032: 330691,
|
||||
33033: 330701,
|
||||
34000: 340011,
|
||||
34001: 340121,
|
||||
34002: 340151,
|
||||
34003: 340161,
|
||||
34004: 340131,
|
||||
34005: 340071,
|
||||
34009: 340231,
|
||||
34010: 340241,
|
||||
34011: 340251,
|
||||
34012: 340261,
|
||||
34013: 340281,
|
||||
34014: 340291,
|
||||
34015: 340301,
|
||||
34016: 340321,
|
||||
34017: 340341,
|
||||
34018: 340351,
|
||||
34019: 340361,
|
||||
34020: 340381,
|
||||
34021: 340391,
|
||||
34022: 340411,
|
||||
34023: 340421,
|
||||
34024: 340441,
|
||||
34025: 340451,
|
||||
34026: 340461,
|
||||
34027: 340491,
|
||||
34028: 340501,
|
||||
34029: 340521,
|
||||
34030: 340531,
|
||||
34031: 340541,
|
||||
34032: 340571,
|
||||
34033: 340601,
|
||||
34034: 340611,
|
||||
34035: 340621,
|
||||
34036: 340631,
|
||||
34037: 340651,
|
||||
34038: 340681,
|
||||
34039: 340701,
|
||||
34040: 340721,
|
||||
34041: 340731,
|
||||
34042: 340751,
|
||||
34043: 340761,
|
||||
34044: 340781,
|
||||
34045: 340801,
|
||||
34046: 340831,
|
||||
34047: 340861,
|
||||
34048: 340871,
|
||||
35000: 350011,
|
||||
35001: 350161,
|
||||
35002: 350141,
|
||||
35003: 350061,
|
||||
35005: 350081,
|
||||
35006: 350121,
|
||||
35008: 350181,
|
||||
35009: 350191,
|
||||
35010: 350221,
|
||||
35011: 350231,
|
||||
35012: 350261,
|
||||
35013: 350271,
|
||||
35014: 350301,
|
||||
35015: 350321,
|
||||
35016: 350341,
|
||||
35017: 350361,
|
||||
35018: 350391,
|
||||
35019: 350401,
|
||||
35020: 350411,
|
||||
35021: 350431,
|
||||
35022: 350441,
|
||||
35023: 350451,
|
||||
35024: 350461,
|
||||
35025: 350491,
|
||||
35026: 350501,
|
||||
35027: 350511,
|
||||
35028: 350531,
|
||||
35029: 350551,
|
||||
35030: 350601,
|
||||
35031: 350621,
|
||||
35032: 350631,
|
||||
35033: 350641,
|
||||
35034: 350661,
|
||||
35035: 350681,
|
||||
35036: 350691,
|
||||
35037: 350701,
|
||||
35038: 350711,
|
||||
41000: 410031,
|
||||
41001: 410071,
|
||||
41002: 410111,
|
||||
41003: 410151,
|
||||
42000: 420031,
|
||||
42001: 420071,
|
||||
42002: 420111,
|
||||
42003: 420151,
|
||||
43000: 430031,
|
||||
43001: 430071,
|
||||
43002: 430111,
|
||||
43003: 430151,
|
||||
44000: 440031,
|
||||
44001: 440071,
|
||||
44002: 440111,
|
||||
44003: 440151,
|
||||
44004: 440191,
|
||||
45000: 450031,
|
||||
45001: 450071,
|
||||
45002: 450111,
|
||||
45003: 450151,
|
||||
51001: 510011,
|
||||
51002: 510021,
|
||||
51003: 510031,
|
||||
52001: 520011,
|
||||
52002: 520021,
|
||||
53001: 530011,
|
||||
53002: 530021,
|
||||
54001: 540011,
|
||||
54002: 540021,
|
||||
55001: 550011,
|
||||
55002: 550021,
|
||||
55003: 550031,
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package masterdata
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"slices"
|
||||
"sort"
|
||||
|
||||
"lunar-tear/server/internal/model"
|
||||
@@ -126,27 +125,16 @@ func LoadGachaPool() (*GachaCatalog, error) {
|
||||
}
|
||||
|
||||
catalogCostumeSet := make(map[int32]bool, len(catalogCostumes))
|
||||
costumeTermId := make(map[int32]int32, len(catalogCostumes))
|
||||
for _, c := range catalogCostumes {
|
||||
catalogCostumeSet[c.CostumeId] = true
|
||||
costumeTermId[c.CostumeId] = c.CatalogTermId
|
||||
}
|
||||
catalogWeaponSet := make(map[int32]bool, len(catalogWeapons))
|
||||
for _, w := range catalogWeapons {
|
||||
catalogWeaponSet[w.WeaponId] = true
|
||||
}
|
||||
|
||||
costumeWeaponType := make(map[int32]int32, len(costumes))
|
||||
for _, c := range costumes {
|
||||
costumeWeaponType[c.CostumeId] = c.SkillfulWeaponType
|
||||
}
|
||||
|
||||
weaponTypeById := make(map[int32]int32, len(weapons))
|
||||
weaponRarityById := make(map[int32]int32, len(weapons))
|
||||
restrictedWeapons := make(map[int32]bool)
|
||||
for _, w := range weapons {
|
||||
weaponTypeById[w.WeaponId] = w.WeaponType
|
||||
weaponRarityById[w.WeaponId] = w.RarityType
|
||||
if w.IsRestrictDiscard {
|
||||
restrictedWeapons[w.WeaponId] = true
|
||||
}
|
||||
@@ -262,60 +250,12 @@ func LoadGachaPool() (*GachaCatalog, error) {
|
||||
log.Printf("[GachaPool] pool excludes %d evolved, %d quest-granted costumes, %d quest-granted weapons, %d restricted weapons",
|
||||
evolvedFilteredCount, questGrantedCostumeCount, questGrantedWeaponCount, restrictedCount)
|
||||
|
||||
type weaponKey struct {
|
||||
TermId int32
|
||||
WeaponType int32
|
||||
Rarity int32
|
||||
}
|
||||
weaponsByKey := make(map[weaponKey][]int32)
|
||||
for _, cw := range catalogWeapons {
|
||||
if evolvedWeapons[cw.WeaponId] || restrictedWeapons[cw.WeaponId] {
|
||||
continue
|
||||
}
|
||||
wt := weaponTypeById[cw.WeaponId]
|
||||
r := weaponRarityById[cw.WeaponId]
|
||||
if wt == 0 || r < model.RaritySRare {
|
||||
continue
|
||||
}
|
||||
k := weaponKey{TermId: cw.CatalogTermId, WeaponType: wt, Rarity: r}
|
||||
weaponsByKey[k] = append(weaponsByKey[k], cw.WeaponId)
|
||||
}
|
||||
for k, ids := range weaponsByKey {
|
||||
slices.Sort(ids)
|
||||
weaponsByKey[k] = ids
|
||||
}
|
||||
|
||||
exact, pattern, bestGuess := 0, 0, 0
|
||||
for costumeId, item := range pool.CostumeById {
|
||||
tid := costumeTermId[costumeId]
|
||||
wt := costumeWeaponType[costumeId]
|
||||
k := weaponKey{TermId: tid, WeaponType: wt, Rarity: item.RarityType}
|
||||
candidates := weaponsByKey[k]
|
||||
if len(candidates) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(candidates) == 1 {
|
||||
pool.CostumeWeaponMap[costumeId] = candidates[0]
|
||||
exact++
|
||||
continue
|
||||
}
|
||||
idPattern := costumeId*10 + 1
|
||||
found := false
|
||||
for _, wid := range candidates {
|
||||
if wid == idPattern {
|
||||
for costumeId := range pool.CostumeById {
|
||||
if wid, ok := costumeWeaponPairings[costumeId]; ok {
|
||||
pool.CostumeWeaponMap[costumeId] = wid
|
||||
pattern++
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
pool.CostumeWeaponMap[costumeId] = candidates[0]
|
||||
bestGuess++
|
||||
}
|
||||
}
|
||||
log.Printf("[GachaPool] costume-weapon pairing: %d exact, %d id-pattern, %d best-guess, %d total",
|
||||
exact, pattern, bestGuess, len(pool.CostumeWeaponMap))
|
||||
log.Printf("[GachaPool] costume-weapon pairing: %d entries from lookup table", len(pool.CostumeWeaponMap))
|
||||
|
||||
for _, m := range materials {
|
||||
pool.Materials = append(pool.Materials, GachaPoolItem{
|
||||
@@ -330,7 +270,6 @@ func LoadGachaPool() (*GachaCatalog, error) {
|
||||
|
||||
func (pool *GachaCatalog) BuildShopFeatured(shop *ShopCatalog) {
|
||||
pool.ShopFeaturedByMedal = make(map[int32][]ShopFeaturedEntry)
|
||||
shopPairs := 0
|
||||
for _, cells := range shop.ExchangeShopCells {
|
||||
consumableId := shop.Items[cells[0].ShopItemId].PriceId
|
||||
|
||||
@@ -350,16 +289,12 @@ func (pool *GachaCatalog) BuildShopFeatured(shop *ShopCatalog) {
|
||||
continue
|
||||
}
|
||||
entries = append(entries, ShopFeaturedEntry{CostumeId: costumeId, WeaponId: weaponId})
|
||||
if costumeId != 0 && weaponId != 0 {
|
||||
pool.CostumeWeaponMap[costumeId] = weaponId
|
||||
shopPairs++
|
||||
}
|
||||
}
|
||||
if len(entries) > 0 {
|
||||
pool.ShopFeaturedByMedal[consumableId] = entries
|
||||
}
|
||||
}
|
||||
log.Printf("[GachaPool] shop featured: %d consumables, %d costume-weapon pairs overridden", len(pool.ShopFeaturedByMedal), shopPairs)
|
||||
log.Printf("[GachaPool] shop featured: %d consumables", len(pool.ShopFeaturedByMedal))
|
||||
}
|
||||
|
||||
func (pool *GachaCatalog) PruneUnpairedCostumes() {
|
||||
|
||||
@@ -185,8 +185,8 @@ func (h *QuestHandler) menuPickSceneId(questId int32, isBattleOnly bool) int32 {
|
||||
|
||||
func (h *QuestHandler) applyQuestVictory(user *store.UserState, questId int32, outcome *FinishOutcome, nowMillis int64, wasReplay bool) {
|
||||
questState := user.Quests[questId]
|
||||
if !questState.IsRewardGranted {
|
||||
h.applyExpAndGoldRewards(user, questId, nowMillis)
|
||||
if !questState.IsRewardGranted {
|
||||
if !wasReplay {
|
||||
h.applyFirstClearItemRewards(user, questId, nowMillis)
|
||||
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||
|
||||
Reference in New Issue
Block a user