mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 13:53:41 +03:00
129 lines
4.3 KiB
Go
129 lines
4.3 KiB
Go
package masterdata
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
|
|
"lunar-tear/server/internal/model"
|
|
"lunar-tear/server/internal/utils"
|
|
)
|
|
|
|
type ExchangeShopCell struct {
|
|
SortOrder int32
|
|
ShopItemId int32
|
|
}
|
|
|
|
type ShopCatalog struct {
|
|
Items map[int32]EntityMShopItem
|
|
Contents map[int32][]EntityMShopItemContentPossession
|
|
Effects map[int32][]EntityMShopItemContentEffect
|
|
MaxStaminaMillis map[int32]int32 // level -> max stamina in millis
|
|
LimitedStock map[int32]int32 // stock id -> max count
|
|
ItemShopPool []int32 // shop item IDs for the replaceable item shop, sorted by cell sort order
|
|
ExchangeShopCells map[int32][]ExchangeShopCell // shopId -> sorted cells for exchange shops
|
|
}
|
|
|
|
func LoadShopCatalog() (*ShopCatalog, error) {
|
|
items, err := utils.ReadTable[EntityMShopItem]("m_shop_item")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load shop item table: %w", err)
|
|
}
|
|
contents, err := utils.ReadTable[EntityMShopItemContentPossession]("m_shop_item_content_possession")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load shop content possession table: %w", err)
|
|
}
|
|
effects, err := utils.ReadTable[EntityMShopItemContentEffect]("m_shop_item_content_effect")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load shop content effect table: %w", err)
|
|
}
|
|
userLevels, err := utils.ReadTable[EntityMUserLevel]("m_user_level")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load user level table: %w", err)
|
|
}
|
|
stockRows, err := utils.ReadTable[EntityMShopItemLimitedStock]("m_shop_item_limited_stock")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load shop item limited stock table: %w", err)
|
|
}
|
|
|
|
catalog := &ShopCatalog{
|
|
Items: make(map[int32]EntityMShopItem, len(items)),
|
|
Contents: make(map[int32][]EntityMShopItemContentPossession, len(contents)),
|
|
Effects: make(map[int32][]EntityMShopItemContentEffect, len(effects)),
|
|
MaxStaminaMillis: make(map[int32]int32, len(userLevels)),
|
|
LimitedStock: make(map[int32]int32, len(stockRows)),
|
|
}
|
|
for _, row := range items {
|
|
catalog.Items[row.ShopItemId] = row
|
|
}
|
|
for _, row := range contents {
|
|
catalog.Contents[row.ShopItemId] = append(catalog.Contents[row.ShopItemId], row)
|
|
}
|
|
for _, row := range effects {
|
|
catalog.Effects[row.ShopItemId] = append(catalog.Effects[row.ShopItemId], row)
|
|
}
|
|
for _, ul := range userLevels {
|
|
catalog.MaxStaminaMillis[ul.UserLevel] = ul.MaxStamina * 1000
|
|
}
|
|
for _, row := range stockRows {
|
|
catalog.LimitedStock[row.ShopItemLimitedStockId] = row.MaxCount
|
|
}
|
|
|
|
shops, err := utils.ReadTable[EntityMShop]("m_shop")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load shop table: %w", err)
|
|
}
|
|
cellGroups, err := utils.ReadTable[EntityMShopItemCellGroup]("m_shop_item_cell_group")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load shop item cell group table: %w", err)
|
|
}
|
|
cells, err := utils.ReadTable[EntityMShopItemCell]("m_shop_item_cell")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load shop item cell table: %w", err)
|
|
}
|
|
|
|
cellIdToItemId := make(map[int32]int32, len(cells))
|
|
for _, c := range cells {
|
|
cellIdToItemId[c.ShopItemCellId] = c.ShopItemId
|
|
}
|
|
|
|
cellGroupByCGId := make(map[int32][]EntityMShopItemCellGroup, len(cellGroups))
|
|
for _, cg := range cellGroups {
|
|
cellGroupByCGId[cg.ShopItemCellGroupId] = append(cellGroupByCGId[cg.ShopItemCellGroupId], cg)
|
|
}
|
|
|
|
catalog.ExchangeShopCells = make(map[int32][]ExchangeShopCell)
|
|
for _, s := range shops {
|
|
entries := cellGroupByCGId[s.ShopItemCellGroupId]
|
|
if len(entries) == 0 {
|
|
continue
|
|
}
|
|
|
|
switch s.ShopGroupType {
|
|
case model.ShopGroupTypeItemShop:
|
|
var poolCells []ExchangeShopCell
|
|
for _, cg := range entries {
|
|
if itemId, ok := cellIdToItemId[cg.ShopItemCellId]; ok {
|
|
poolCells = append(poolCells, ExchangeShopCell{cg.SortOrder, itemId})
|
|
}
|
|
}
|
|
sort.Slice(poolCells, func(i, j int) bool { return poolCells[i].SortOrder < poolCells[j].SortOrder })
|
|
catalog.ItemShopPool = make([]int32, len(poolCells))
|
|
for i, pc := range poolCells {
|
|
catalog.ItemShopPool[i] = pc.ShopItemId
|
|
}
|
|
|
|
case model.ShopGroupTypeExchangeShop:
|
|
var sc []ExchangeShopCell
|
|
for _, cg := range entries {
|
|
if itemId, ok := cellIdToItemId[cg.ShopItemCellId]; ok {
|
|
sc = append(sc, ExchangeShopCell{cg.SortOrder, itemId})
|
|
}
|
|
}
|
|
sort.Slice(sc, func(i, j int) bool { return sc[i].SortOrder < sc[j].SortOrder })
|
|
catalog.ExchangeShopCells[s.ShopId] = sc
|
|
}
|
|
}
|
|
|
|
return catalog, nil
|
|
}
|