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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"slices"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"lunar-tear/server/internal/model"
|
"lunar-tear/server/internal/model"
|
||||||
@@ -126,27 +125,16 @@ func LoadGachaPool() (*GachaCatalog, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
catalogCostumeSet := make(map[int32]bool, len(catalogCostumes))
|
catalogCostumeSet := make(map[int32]bool, len(catalogCostumes))
|
||||||
costumeTermId := make(map[int32]int32, len(catalogCostumes))
|
|
||||||
for _, c := range catalogCostumes {
|
for _, c := range catalogCostumes {
|
||||||
catalogCostumeSet[c.CostumeId] = true
|
catalogCostumeSet[c.CostumeId] = true
|
||||||
costumeTermId[c.CostumeId] = c.CatalogTermId
|
|
||||||
}
|
}
|
||||||
catalogWeaponSet := make(map[int32]bool, len(catalogWeapons))
|
catalogWeaponSet := make(map[int32]bool, len(catalogWeapons))
|
||||||
for _, w := range catalogWeapons {
|
for _, w := range catalogWeapons {
|
||||||
catalogWeaponSet[w.WeaponId] = true
|
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)
|
restrictedWeapons := make(map[int32]bool)
|
||||||
for _, w := range weapons {
|
for _, w := range weapons {
|
||||||
weaponTypeById[w.WeaponId] = w.WeaponType
|
|
||||||
weaponRarityById[w.WeaponId] = w.RarityType
|
|
||||||
if w.IsRestrictDiscard {
|
if w.IsRestrictDiscard {
|
||||||
restrictedWeapons[w.WeaponId] = true
|
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",
|
log.Printf("[GachaPool] pool excludes %d evolved, %d quest-granted costumes, %d quest-granted weapons, %d restricted weapons",
|
||||||
evolvedFilteredCount, questGrantedCostumeCount, questGrantedWeaponCount, restrictedCount)
|
evolvedFilteredCount, questGrantedCostumeCount, questGrantedWeaponCount, restrictedCount)
|
||||||
|
|
||||||
type weaponKey struct {
|
for costumeId := range pool.CostumeById {
|
||||||
TermId int32
|
if wid, ok := costumeWeaponPairings[costumeId]; ok {
|
||||||
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 {
|
|
||||||
pool.CostumeWeaponMap[costumeId] = wid
|
pool.CostumeWeaponMap[costumeId] = wid
|
||||||
pattern++
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
log.Printf("[GachaPool] costume-weapon pairing: %d entries from lookup table", len(pool.CostumeWeaponMap))
|
||||||
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))
|
|
||||||
|
|
||||||
for _, m := range materials {
|
for _, m := range materials {
|
||||||
pool.Materials = append(pool.Materials, GachaPoolItem{
|
pool.Materials = append(pool.Materials, GachaPoolItem{
|
||||||
@@ -330,7 +270,6 @@ func LoadGachaPool() (*GachaCatalog, error) {
|
|||||||
|
|
||||||
func (pool *GachaCatalog) BuildShopFeatured(shop *ShopCatalog) {
|
func (pool *GachaCatalog) BuildShopFeatured(shop *ShopCatalog) {
|
||||||
pool.ShopFeaturedByMedal = make(map[int32][]ShopFeaturedEntry)
|
pool.ShopFeaturedByMedal = make(map[int32][]ShopFeaturedEntry)
|
||||||
shopPairs := 0
|
|
||||||
for _, cells := range shop.ExchangeShopCells {
|
for _, cells := range shop.ExchangeShopCells {
|
||||||
consumableId := shop.Items[cells[0].ShopItemId].PriceId
|
consumableId := shop.Items[cells[0].ShopItemId].PriceId
|
||||||
|
|
||||||
@@ -350,16 +289,12 @@ func (pool *GachaCatalog) BuildShopFeatured(shop *ShopCatalog) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
entries = append(entries, ShopFeaturedEntry{CostumeId: costumeId, WeaponId: weaponId})
|
entries = append(entries, ShopFeaturedEntry{CostumeId: costumeId, WeaponId: weaponId})
|
||||||
if costumeId != 0 && weaponId != 0 {
|
|
||||||
pool.CostumeWeaponMap[costumeId] = weaponId
|
|
||||||
shopPairs++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if len(entries) > 0 {
|
if len(entries) > 0 {
|
||||||
pool.ShopFeaturedByMedal[consumableId] = entries
|
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() {
|
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) {
|
func (h *QuestHandler) applyQuestVictory(user *store.UserState, questId int32, outcome *FinishOutcome, nowMillis int64, wasReplay bool) {
|
||||||
questState := user.Quests[questId]
|
questState := user.Quests[questId]
|
||||||
if !questState.IsRewardGranted {
|
|
||||||
h.applyExpAndGoldRewards(user, questId, nowMillis)
|
h.applyExpAndGoldRewards(user, questId, nowMillis)
|
||||||
|
if !questState.IsRewardGranted {
|
||||||
if !wasReplay {
|
if !wasReplay {
|
||||||
h.applyFirstClearItemRewards(user, questId, nowMillis)
|
h.applyFirstClearItemRewards(user, questId, nowMillis)
|
||||||
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||||
|
|||||||
Reference in New Issue
Block a user