package runtime import ( "fmt" "log" "lunar-tear/server/internal/gacha" "lunar-tear/server/internal/masterdata" "lunar-tear/server/internal/masterdata/memorydb" "lunar-tear/server/internal/questflow" ) // buildCatalogs runs the full Load*/Build*/Enrich* sequence against whatever // memorydb currently holds and returns a fully populated *Catalogs. Called // once at startup and again on every reload. func buildCatalogs() (*Catalogs, error) { log.Printf("master data loaded (%d tables)", memorydb.TableCount()) gameConfig, err := masterdata.LoadGameConfig() if err != nil { return nil, fmt.Errorf("load game config: %w", err) } log.Printf("game config loaded (goldId=%d, skipTicketId=%d, rebirthGold=%d)", gameConfig.ConsumableItemIdForGold, gameConfig.ConsumableItemIdForQuestSkipTicket, gameConfig.CharacterRebirthConsumeGold) partsCatalog, err := masterdata.LoadPartsCatalog() if err != nil { return nil, fmt.Errorf("load parts catalog: %w", err) } log.Printf("parts catalog loaded: %d parts, %d rarities", len(partsCatalog.PartsById), len(partsCatalog.RarityByRarityType)) questCatalog, err := masterdata.LoadQuestCatalog(partsCatalog) if err != nil { return nil, fmt.Errorf("load quest catalog: %w", err) } sideStoryCatalog := masterdata.LoadSideStoryCatalog() questHandler := questflow.NewQuestHandler(questCatalog, gameConfig, sideStoryCatalog) gachaEntries, medalInfo, err := masterdata.LoadGachaCatalog() if err != nil { return nil, fmt.Errorf("load gacha catalog: %w", err) } log.Printf("gacha catalog loaded: %d entries", len(gachaEntries)) gachaPool, err := masterdata.LoadGachaPool() if err != nil { return nil, fmt.Errorf("load gacha pool: %w", err) } log.Printf("gacha pool loaded: costumes=%d rarities, weapons=%d rarities, materials=%d", len(gachaPool.CostumesByRarity), len(gachaPool.WeaponsByRarity), len(gachaPool.Materials)) shopCatalog, err := masterdata.LoadShopCatalog() if err != nil { return nil, fmt.Errorf("load shop catalog: %w", err) } log.Printf("shop catalog loaded: %d items, %d content groups, %d exchange shops", len(shopCatalog.Items), len(shopCatalog.Contents), len(shopCatalog.ExchangeShopCells)) gachaPool.BuildShopFeatured(shopCatalog) gachaPool.PruneUnpairedCostumes() gachaPool.BuildFeaturedFromTerms(gachaEntries) gachaPool.BuildBannerPools(gachaEntries) masterdata.EnrichCatalogPromotions(gachaEntries, gachaPool) dupExchange, err := masterdata.LoadDupExchange() if err != nil { return nil, fmt.Errorf("load dup exchange: %w", err) } dupAdded, err := masterdata.EnrichDupExchange(dupExchange, gachaPool) if err != nil { return nil, fmt.Errorf("enrich dup exchange: %w", err) } log.Printf("dup exchange loaded: %d entries (%d derived from limit-break materials)", len(dupExchange), dupAdded) gachaHandler := gacha.NewGachaHandler(gachaPool, gameConfig, questHandler.Granter, medalInfo, dupExchange) conditionResolver, err := masterdata.LoadConditionResolver() if err != nil { return nil, fmt.Errorf("load condition resolver: %w", err) } cageOrnamentCatalog := masterdata.LoadCageOrnamentCatalog() loginBonusCatalog := masterdata.LoadLoginBonusCatalog() characterViewerCatalog := masterdata.LoadCharacterViewerCatalog(conditionResolver) omikujiCatalog := masterdata.LoadOmikujiCatalog() materialCatalog, err := masterdata.LoadMaterialCatalog() if err != nil { return nil, fmt.Errorf("load material catalog: %w", err) } log.Printf("material catalog loaded: %d materials", len(materialCatalog.All)) consumableItemCatalog, err := masterdata.LoadConsumableItemCatalog() if err != nil { return nil, fmt.Errorf("load consumable item catalog: %w", err) } log.Printf("consumable item catalog loaded: %d items", len(consumableItemCatalog.All)) costumeCatalog, err := masterdata.LoadCostumeCatalog(materialCatalog) if err != nil { return nil, fmt.Errorf("load costume catalog: %w", err) } log.Printf("costume catalog loaded: %d costumes, %d materials, %d rarity curves", len(costumeCatalog.Costumes), len(costumeCatalog.Materials), len(costumeCatalog.ExpByRarity)) weaponCatalog, err := masterdata.LoadWeaponCatalog(materialCatalog) if err != nil { return nil, fmt.Errorf("load weapon catalog: %w", err) } log.Printf("weapon catalog loaded: %d weapons, %d materials, %d enhance configs", len(weaponCatalog.Weapons), len(weaponCatalog.Materials), len(weaponCatalog.ExpByEnhanceId)) exploreCatalog, err := masterdata.LoadExploreCatalog() if err != nil { return nil, fmt.Errorf("load explore catalog: %w", err) } log.Printf("explore catalog loaded: %d explores, %d grade assets", len(exploreCatalog.Explores), len(exploreCatalog.GradeAssets)) gimmickCatalog, err := masterdata.LoadGimmickCatalog(conditionResolver) if err != nil { return nil, fmt.Errorf("load gimmick catalog: %w", err) } characterBoardCatalog, err := masterdata.LoadCharacterBoardCatalog() if err != nil { return nil, fmt.Errorf("load character board catalog: %w", err) } log.Printf("character board catalog loaded: %d panels, %d boards", len(characterBoardCatalog.PanelById), len(characterBoardCatalog.BoardById)) characterRebirthCatalog, err := masterdata.LoadCharacterRebirthCatalog() if err != nil { return nil, fmt.Errorf("load character rebirth catalog: %w", err) } log.Printf("character rebirth catalog loaded: %d characters", len(characterRebirthCatalog.StepGroupByCharacterId)) companionCatalog, err := masterdata.LoadCompanionCatalog() if err != nil { return nil, fmt.Errorf("load companion catalog: %w", err) } log.Printf("companion catalog loaded: %d companions, %d categories", len(companionCatalog.CompanionById), len(companionCatalog.GoldCostByCategory)) bigHuntCatalog := masterdata.LoadBigHuntCatalog() return &Catalogs{ GameConfig: gameConfig, Parts: partsCatalog, Quest: questCatalog, GachaEntries: gachaEntries, GachaMedals: medalInfo, GachaPool: gachaPool, Shop: shopCatalog, DupExchange: dupExchange, ConditionResolver: conditionResolver, CageOrnament: cageOrnamentCatalog, LoginBonus: loginBonusCatalog, CharacterViewer: characterViewerCatalog, Omikuji: omikujiCatalog, Material: materialCatalog, ConsumableItem: consumableItemCatalog, Costume: costumeCatalog, Weapon: weaponCatalog, Explore: exploreCatalog, Gimmick: gimmickCatalog, CharacterBoard: characterBoardCatalog, CharacterRebirth: characterRebirthCatalog, Companion: companionCatalog, SideStory: sideStoryCatalog, BigHunt: bigHuntCatalog, QuestHandler: questHandler, GachaHandler: gachaHandler, }, nil }