mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Add authentication server, dev CLI, Docker multi-service setup, and cross-platform improvements
This commit is contained in:
@@ -8,15 +8,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type bigHuntBossQuestRow struct {
|
||||
BigHuntBossQuestId int32 `json:"BigHuntBossQuestId"`
|
||||
BigHuntBossId int32 `json:"BigHuntBossId"`
|
||||
BigHuntQuestGroupId int32 `json:"BigHuntQuestGroupId"`
|
||||
BigHuntBossQuestScoreCoefficientId int32 `json:"BigHuntBossQuestScoreCoefficientId"`
|
||||
BigHuntScoreRewardGroupScheduleId int32 `json:"BigHuntScoreRewardGroupScheduleId"`
|
||||
DailyChallengeCount int32 `json:"DailyChallengeCount"`
|
||||
}
|
||||
|
||||
type BigHuntBossQuestRow struct {
|
||||
BigHuntBossQuestId int32
|
||||
BigHuntBossId int32
|
||||
@@ -25,97 +16,39 @@ type BigHuntBossQuestRow struct {
|
||||
DailyChallengeCount int32
|
||||
}
|
||||
|
||||
type bigHuntQuestRow struct {
|
||||
BigHuntQuestId int32 `json:"BigHuntQuestId"`
|
||||
QuestId int32 `json:"QuestId"`
|
||||
BigHuntQuestScoreCoefficientId int32 `json:"BigHuntQuestScoreCoefficientId"`
|
||||
}
|
||||
|
||||
type BigHuntQuestRow struct {
|
||||
BigHuntQuestId int32
|
||||
QuestId int32
|
||||
BigHuntQuestScoreCoefficientId int32
|
||||
}
|
||||
|
||||
type bigHuntQuestScoreCoefficientRow struct {
|
||||
BigHuntQuestScoreCoefficientId int32 `json:"BigHuntQuestScoreCoefficientId"`
|
||||
ScoreDifficultBonusPermil int32 `json:"ScoreDifficultBonusPermil"`
|
||||
}
|
||||
|
||||
type bigHuntBossRow struct {
|
||||
BigHuntBossId int32 `json:"BigHuntBossId"`
|
||||
BigHuntBossGradeGroupId int32 `json:"BigHuntBossGradeGroupId"`
|
||||
AttributeType int32 `json:"AttributeType"`
|
||||
}
|
||||
|
||||
type BigHuntBossRow struct {
|
||||
BigHuntBossId int32
|
||||
BigHuntBossGradeGroupId int32
|
||||
AttributeType int32
|
||||
}
|
||||
|
||||
type bigHuntBossGradeGroupRow struct {
|
||||
BigHuntBossGradeGroupId int32 `json:"BigHuntBossGradeGroupId"`
|
||||
NecessaryScore int64 `json:"NecessaryScore"`
|
||||
AssetGradeIconId int32 `json:"AssetGradeIconId"`
|
||||
}
|
||||
|
||||
type GradeThreshold struct {
|
||||
NecessaryScore int64
|
||||
AssetGradeIconId int32
|
||||
}
|
||||
|
||||
type bigHuntScheduleRow struct {
|
||||
BigHuntScheduleId int32 `json:"BigHuntScheduleId"`
|
||||
ChallengeStartDatetime int64 `json:"ChallengeStartDatetime"`
|
||||
ChallengeEndDatetime int64 `json:"ChallengeEndDatetime"`
|
||||
}
|
||||
|
||||
type scoreRewardScheduleRow struct {
|
||||
BigHuntScoreRewardGroupScheduleId int32 `json:"BigHuntScoreRewardGroupScheduleId"`
|
||||
GroupIndex int32 `json:"GroupIndex"`
|
||||
BigHuntScoreRewardGroupId int32 `json:"BigHuntScoreRewardGroupId"`
|
||||
StartDatetime int64 `json:"StartDatetime"`
|
||||
}
|
||||
|
||||
type ScoreRewardScheduleEntry struct {
|
||||
BigHuntScoreRewardGroupId int32
|
||||
StartDatetime int64
|
||||
}
|
||||
|
||||
type scoreRewardGroupRow struct {
|
||||
BigHuntScoreRewardGroupId int32 `json:"BigHuntScoreRewardGroupId"`
|
||||
NecessaryScore int64 `json:"NecessaryScore"`
|
||||
BigHuntRewardGroupId int32 `json:"BigHuntRewardGroupId"`
|
||||
}
|
||||
|
||||
type ScoreRewardThreshold struct {
|
||||
NecessaryScore int64
|
||||
BigHuntRewardGroupId int32
|
||||
}
|
||||
|
||||
type rewardGroupRow struct {
|
||||
BigHuntRewardGroupId int32 `json:"BigHuntRewardGroupId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
PossessionType int32 `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type RewardItem struct {
|
||||
PossessionType int32
|
||||
PossessionId int32
|
||||
Count int32
|
||||
}
|
||||
|
||||
type weeklyRewardScheduleRow struct {
|
||||
BigHuntWeeklyAttributeScoreRewardGroupScheduleId int32 `json:"BigHuntWeeklyAttributeScoreRewardGroupScheduleId"`
|
||||
AttributeType int32 `json:"AttributeType"`
|
||||
GroupIndex int32 `json:"GroupIndex"`
|
||||
BigHuntScoreRewardGroupId int32 `json:"BigHuntScoreRewardGroupId"`
|
||||
StartDatetime int64 `json:"StartDatetime"`
|
||||
}
|
||||
|
||||
type BigHuntWeeklyRewardKey struct {
|
||||
ScheduleId int32
|
||||
AttributeType int32
|
||||
@@ -189,7 +122,7 @@ func (c *BigHuntCatalog) CollectNewRewards(scoreRewardGroupId int32, oldMax, new
|
||||
}
|
||||
|
||||
func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
bossQuestRows, err := utils.ReadJSON[bigHuntBossQuestRow]("EntityMBigHuntBossQuestTable.json")
|
||||
bossQuestRows, err := utils.ReadTable[EntityMBigHuntBossQuest]("m_big_hunt_boss_quest")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt boss quest table: %v", err)
|
||||
}
|
||||
@@ -204,7 +137,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
}
|
||||
}
|
||||
|
||||
questRows, err := utils.ReadJSON[bigHuntQuestRow]("EntityMBigHuntQuestTable.json")
|
||||
questRows, err := utils.ReadTable[EntityMBigHuntQuest]("m_big_hunt_quest")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt quest table: %v", err)
|
||||
}
|
||||
@@ -217,7 +150,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
}
|
||||
}
|
||||
|
||||
coeffRows, err := utils.ReadJSON[bigHuntQuestScoreCoefficientRow]("EntityMBigHuntQuestScoreCoefficientTable.json")
|
||||
coeffRows, err := utils.ReadTable[EntityMBigHuntQuestScoreCoefficient]("m_big_hunt_quest_score_coefficient")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt quest score coefficient table: %v", err)
|
||||
}
|
||||
@@ -226,7 +159,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
scoreCoefficients[r.BigHuntQuestScoreCoefficientId] = r.ScoreDifficultBonusPermil
|
||||
}
|
||||
|
||||
bossRows, err := utils.ReadJSON[bigHuntBossRow]("EntityMBigHuntBossTable.json")
|
||||
bossRows, err := utils.ReadTable[EntityMBigHuntBoss]("m_big_hunt_boss")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt boss table: %v", err)
|
||||
}
|
||||
@@ -239,7 +172,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
}
|
||||
}
|
||||
|
||||
gradeRows, err := utils.ReadJSON[bigHuntBossGradeGroupRow]("EntityMBigHuntBossGradeGroupTable.json")
|
||||
gradeRows, err := utils.ReadTable[EntityMBigHuntBossGradeGroup]("m_big_hunt_boss_grade_group")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt boss grade group table: %v", err)
|
||||
}
|
||||
@@ -256,7 +189,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
})
|
||||
}
|
||||
|
||||
scheduleRows, err := utils.ReadJSON[bigHuntScheduleRow]("EntityMBigHuntScheduleTable.json")
|
||||
scheduleRows, err := utils.ReadTable[EntityMBigHuntSchedule]("m_big_hunt_schedule")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt schedule table: %v", err)
|
||||
}
|
||||
@@ -274,7 +207,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
}
|
||||
}
|
||||
|
||||
rewardSchedRows, err := utils.ReadJSON[scoreRewardScheduleRow]("EntityMBigHuntScoreRewardGroupScheduleTable.json")
|
||||
rewardSchedRows, err := utils.ReadTable[EntityMBigHuntScoreRewardGroupSchedule]("m_big_hunt_score_reward_group_schedule")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt score reward group schedule table: %v", err)
|
||||
}
|
||||
@@ -294,7 +227,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
})
|
||||
}
|
||||
|
||||
rewardGroupRows, err := utils.ReadJSON[scoreRewardGroupRow]("EntityMBigHuntScoreRewardGroupTable.json")
|
||||
rewardGroupRows, err := utils.ReadTable[EntityMBigHuntScoreRewardGroup]("m_big_hunt_score_reward_group")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt score reward group table: %v", err)
|
||||
}
|
||||
@@ -314,7 +247,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
})
|
||||
}
|
||||
|
||||
rewardItemRows, err := utils.ReadJSON[rewardGroupRow]("EntityMBigHuntRewardGroupTable.json")
|
||||
rewardItemRows, err := utils.ReadTable[EntityMBigHuntRewardGroup]("m_big_hunt_reward_group")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt reward group table: %v", err)
|
||||
}
|
||||
@@ -327,7 +260,7 @@ func LoadBigHuntCatalog() *BigHuntCatalog {
|
||||
})
|
||||
}
|
||||
|
||||
weeklySchedRows, err := utils.ReadJSON[weeklyRewardScheduleRow]("EntityMBigHuntWeeklyAttributeScoreRewardGroupScheduleTable.json")
|
||||
weeklySchedRows, err := utils.ReadTable[EntityMBigHuntWeeklyAttributeScoreRewardGroupSchedule]("m_big_hunt_weekly_attribute_score_reward_group_schedule")
|
||||
if err != nil {
|
||||
log.Fatalf("load big hunt weekly attribute score reward group schedule table: %v", err)
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type cageOrnament struct {
|
||||
CageOrnamentId int32 `json:"CageOrnamentId"`
|
||||
CageOrnamentRewardId int32 `json:"CageOrnamentRewardId"`
|
||||
}
|
||||
|
||||
type cageOrnamentRewardRow struct {
|
||||
CageOrnamentRewardId int32 `json:"CageOrnamentRewardId"`
|
||||
PossessionType int32 `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type CageOrnamentReward struct {
|
||||
PossessionType int32
|
||||
PossessionId int32
|
||||
@@ -38,11 +26,11 @@ func (c *CageOrnamentCatalog) LookupReward(cageOrnamentId int32) (CageOrnamentRe
|
||||
}
|
||||
|
||||
func LoadCageOrnamentCatalog() *CageOrnamentCatalog {
|
||||
ornaments, err := utils.ReadJSON[cageOrnament]("EntityMCageOrnamentTable.json")
|
||||
ornaments, err := utils.ReadTable[EntityMCageOrnament]("m_cage_ornament")
|
||||
if err != nil {
|
||||
log.Fatalf("load cage ornament table: %v", err)
|
||||
}
|
||||
rewards, err := utils.ReadJSON[cageOrnamentRewardRow]("EntityMCageOrnamentRewardTable.json")
|
||||
rewards, err := utils.ReadTable[EntityMCageOrnamentReward]("m_cage_ornament_reward")
|
||||
if err != nil {
|
||||
log.Fatalf("load cage ornament reward table: %v", err)
|
||||
}
|
||||
|
||||
@@ -6,24 +6,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type CharacterRebirthRow struct {
|
||||
CharacterId int32 `json:"CharacterId"`
|
||||
CharacterRebirthStepGroupId int32 `json:"CharacterRebirthStepGroupId"`
|
||||
}
|
||||
|
||||
type CharacterRebirthStepRow struct {
|
||||
CharacterRebirthStepGroupId int32 `json:"CharacterRebirthStepGroupId"`
|
||||
BeforeRebirthCount int32 `json:"BeforeRebirthCount"`
|
||||
CostumeLevelLimitUp int32 `json:"CostumeLevelLimitUp"`
|
||||
CharacterRebirthMaterialGroupId int32 `json:"CharacterRebirthMaterialGroupId"`
|
||||
}
|
||||
|
||||
type CharacterRebirthMaterialRow struct {
|
||||
CharacterRebirthMaterialGroupId int32 `json:"CharacterRebirthMaterialGroupId"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type StepKey struct {
|
||||
GroupId int32
|
||||
BeforeRebirthCount int32
|
||||
@@ -31,22 +13,22 @@ type StepKey struct {
|
||||
|
||||
type CharacterRebirthCatalog struct {
|
||||
StepGroupByCharacterId map[int32]int32
|
||||
StepByGroupAndCount map[StepKey]CharacterRebirthStepRow
|
||||
MaterialsByGroupId map[int32][]CharacterRebirthMaterialRow
|
||||
StepByGroupAndCount map[StepKey]EntityMCharacterRebirthStepGroup
|
||||
MaterialsByGroupId map[int32][]EntityMCharacterRebirthMaterialGroup
|
||||
}
|
||||
|
||||
func LoadCharacterRebirthCatalog() (*CharacterRebirthCatalog, error) {
|
||||
rebirthRows, err := utils.ReadJSON[CharacterRebirthRow]("EntityMCharacterRebirthTable.json")
|
||||
rebirthRows, err := utils.ReadTable[EntityMCharacterRebirth]("m_character_rebirth")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character rebirth table: %w", err)
|
||||
}
|
||||
|
||||
stepRows, err := utils.ReadJSON[CharacterRebirthStepRow]("EntityMCharacterRebirthStepGroupTable.json")
|
||||
stepRows, err := utils.ReadTable[EntityMCharacterRebirthStepGroup]("m_character_rebirth_step_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character rebirth step group table: %w", err)
|
||||
}
|
||||
|
||||
materialRows, err := utils.ReadJSON[CharacterRebirthMaterialRow]("EntityMCharacterRebirthMaterialGroupTable.json")
|
||||
materialRows, err := utils.ReadTable[EntityMCharacterRebirthMaterialGroup]("m_character_rebirth_material_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character rebirth material group table: %w", err)
|
||||
}
|
||||
@@ -56,12 +38,12 @@ func LoadCharacterRebirthCatalog() (*CharacterRebirthCatalog, error) {
|
||||
stepGroupByCharacterId[r.CharacterId] = r.CharacterRebirthStepGroupId
|
||||
}
|
||||
|
||||
stepByGroupAndCount := make(map[StepKey]CharacterRebirthStepRow, len(stepRows))
|
||||
stepByGroupAndCount := make(map[StepKey]EntityMCharacterRebirthStepGroup, len(stepRows))
|
||||
for _, s := range stepRows {
|
||||
stepByGroupAndCount[StepKey{GroupId: s.CharacterRebirthStepGroupId, BeforeRebirthCount: s.BeforeRebirthCount}] = s
|
||||
}
|
||||
|
||||
materialsByGroupId := make(map[int32][]CharacterRebirthMaterialRow)
|
||||
materialsByGroupId := make(map[int32][]EntityMCharacterRebirthMaterialGroup)
|
||||
for _, m := range materialRows {
|
||||
materialsByGroupId[m.CharacterRebirthMaterialGroupId] = append(materialsByGroupId[m.CharacterRebirthMaterialGroupId], m)
|
||||
}
|
||||
|
||||
@@ -7,66 +7,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type CharacterBoardPanelRow struct {
|
||||
CharacterBoardPanelId int32 `json:"CharacterBoardPanelId"`
|
||||
CharacterBoardId int32 `json:"CharacterBoardId"`
|
||||
CharacterBoardPanelUnlockConditionGroupId int32 `json:"CharacterBoardPanelUnlockConditionGroupId"`
|
||||
CharacterBoardPanelReleasePossessionGroupId int32 `json:"CharacterBoardPanelReleasePossessionGroupId"`
|
||||
CharacterBoardPanelReleaseRewardGroupId int32 `json:"CharacterBoardPanelReleaseRewardGroupId"`
|
||||
CharacterBoardPanelReleaseEffectGroupId int32 `json:"CharacterBoardPanelReleaseEffectGroupId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
ParentCharacterBoardPanelId int32 `json:"ParentCharacterBoardPanelId"`
|
||||
PlaceIndex int32 `json:"PlaceIndex"`
|
||||
}
|
||||
|
||||
type CharacterBoardReleasePossessionRow struct {
|
||||
CharacterBoardPanelReleasePossessionGroupId int32 `json:"CharacterBoardPanelReleasePossessionGroupId"`
|
||||
PossessionType int32 `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type CharacterBoardReleaseEffectRow struct {
|
||||
CharacterBoardPanelReleaseEffectGroupId int32 `json:"CharacterBoardPanelReleaseEffectGroupId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
CharacterBoardEffectType int32 `json:"CharacterBoardEffectType"`
|
||||
CharacterBoardEffectId int32 `json:"CharacterBoardEffectId"`
|
||||
EffectValue int32 `json:"EffectValue"`
|
||||
}
|
||||
|
||||
type CharacterBoardRow struct {
|
||||
CharacterBoardId int32 `json:"CharacterBoardId"`
|
||||
CharacterBoardGroupId int32 `json:"CharacterBoardGroupId"`
|
||||
CharacterBoardUnlockConditionGroupId int32 `json:"CharacterBoardUnlockConditionGroupId"`
|
||||
ReleaseRank int32 `json:"ReleaseRank"`
|
||||
}
|
||||
|
||||
type CharacterBoardStatusUpRow struct {
|
||||
CharacterBoardStatusUpId int32 `json:"CharacterBoardStatusUpId"`
|
||||
CharacterBoardStatusUpType int32 `json:"CharacterBoardStatusUpType"`
|
||||
CharacterBoardEffectTargetGroupId int32 `json:"CharacterBoardEffectTargetGroupId"`
|
||||
}
|
||||
|
||||
type CharacterBoardAbilityRow struct {
|
||||
CharacterBoardAbilityId int32 `json:"CharacterBoardAbilityId"`
|
||||
CharacterBoardEffectTargetGroupId int32 `json:"CharacterBoardEffectTargetGroupId"`
|
||||
AbilityId int32 `json:"AbilityId"`
|
||||
}
|
||||
|
||||
type CharacterBoardAbilityMaxLevelRow struct {
|
||||
CharacterId int32 `json:"CharacterId"`
|
||||
AbilityId int32 `json:"AbilityId"`
|
||||
MaxLevel int32 `json:"MaxLevel"`
|
||||
}
|
||||
|
||||
type CharacterBoardEffectTargetRow struct {
|
||||
CharacterBoardEffectTargetGroupId int32 `json:"CharacterBoardEffectTargetGroupId"`
|
||||
GroupIndex int32 `json:"GroupIndex"`
|
||||
CharacterBoardEffectTargetType int32 `json:"CharacterBoardEffectTargetType"`
|
||||
TargetValue int32 `json:"TargetValue"`
|
||||
}
|
||||
|
||||
type CharacterBoardAssignmentRow struct {
|
||||
CharacterId int32 `json:"CharacterId"`
|
||||
CharacterBoardCategoryId int32 `json:"CharacterBoardCategoryId"`
|
||||
@@ -83,68 +23,68 @@ type CharacterBoardGroupRow struct {
|
||||
}
|
||||
|
||||
type CharacterBoardCatalog struct {
|
||||
PanelById map[int32]CharacterBoardPanelRow
|
||||
PanelsByBoardId map[int32][]CharacterBoardPanelRow
|
||||
ReleaseCostsByGroupId map[int32][]CharacterBoardReleasePossessionRow
|
||||
ReleaseEffectsByGroupId map[int32][]CharacterBoardReleaseEffectRow
|
||||
StatusUpById map[int32]CharacterBoardStatusUpRow
|
||||
AbilityById map[int32]CharacterBoardAbilityRow
|
||||
PanelById map[int32]EntityMCharacterBoardPanel
|
||||
PanelsByBoardId map[int32][]EntityMCharacterBoardPanel
|
||||
ReleaseCostsByGroupId map[int32][]EntityMCharacterBoardPanelReleasePossessionGroup
|
||||
ReleaseEffectsByGroupId map[int32][]EntityMCharacterBoardPanelReleaseEffectGroup
|
||||
StatusUpById map[int32]EntityMCharacterBoardStatusUp
|
||||
AbilityById map[int32]EntityMCharacterBoardAbility
|
||||
AbilityMaxLevel map[store.CharacterBoardAbilityKey]int32
|
||||
EffectTargetsByGroupId map[int32][]CharacterBoardEffectTargetRow
|
||||
BoardById map[int32]CharacterBoardRow
|
||||
EffectTargetsByGroupId map[int32][]EntityMCharacterBoardEffectTargetGroup
|
||||
BoardById map[int32]EntityMCharacterBoard
|
||||
}
|
||||
|
||||
func LoadCharacterBoardCatalog() (*CharacterBoardCatalog, error) {
|
||||
panels, err := utils.ReadJSON[CharacterBoardPanelRow]("EntityMCharacterBoardPanelTable.json")
|
||||
panels, err := utils.ReadTable[EntityMCharacterBoardPanel]("m_character_board_panel")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board panel table: %w", err)
|
||||
}
|
||||
|
||||
costs, err := utils.ReadJSON[CharacterBoardReleasePossessionRow]("EntityMCharacterBoardPanelReleasePossessionGroupTable.json")
|
||||
costs, err := utils.ReadTable[EntityMCharacterBoardPanelReleasePossessionGroup]("m_character_board_panel_release_possession_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board release possession table: %w", err)
|
||||
}
|
||||
|
||||
effects, err := utils.ReadJSON[CharacterBoardReleaseEffectRow]("EntityMCharacterBoardPanelReleaseEffectGroupTable.json")
|
||||
effects, err := utils.ReadTable[EntityMCharacterBoardPanelReleaseEffectGroup]("m_character_board_panel_release_effect_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board release effect table: %w", err)
|
||||
}
|
||||
|
||||
boards, err := utils.ReadJSON[CharacterBoardRow]("EntityMCharacterBoardTable.json")
|
||||
boards, err := utils.ReadTable[EntityMCharacterBoard]("m_character_board")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board table: %w", err)
|
||||
}
|
||||
|
||||
statusUps, err := utils.ReadJSON[CharacterBoardStatusUpRow]("EntityMCharacterBoardStatusUpTable.json")
|
||||
statusUps, err := utils.ReadTable[EntityMCharacterBoardStatusUp]("m_character_board_status_up")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board status up table: %w", err)
|
||||
}
|
||||
|
||||
abilities, err := utils.ReadJSON[CharacterBoardAbilityRow]("EntityMCharacterBoardAbilityTable.json")
|
||||
abilities, err := utils.ReadTable[EntityMCharacterBoardAbility]("m_character_board_ability")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board ability table: %w", err)
|
||||
}
|
||||
|
||||
abilityMaxLevels, err := utils.ReadJSON[CharacterBoardAbilityMaxLevelRow]("EntityMCharacterBoardAbilityMaxLevelTable.json")
|
||||
abilityMaxLevels, err := utils.ReadTable[EntityMCharacterBoardAbilityMaxLevel]("m_character_board_ability_max_level")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board ability max level table: %w", err)
|
||||
}
|
||||
|
||||
targets, err := utils.ReadJSON[CharacterBoardEffectTargetRow]("EntityMCharacterBoardEffectTargetGroupTable.json")
|
||||
targets, err := utils.ReadTable[EntityMCharacterBoardEffectTargetGroup]("m_character_board_effect_target_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load character board effect target table: %w", err)
|
||||
}
|
||||
|
||||
catalog := &CharacterBoardCatalog{
|
||||
PanelById: make(map[int32]CharacterBoardPanelRow, len(panels)),
|
||||
PanelsByBoardId: make(map[int32][]CharacterBoardPanelRow),
|
||||
ReleaseCostsByGroupId: make(map[int32][]CharacterBoardReleasePossessionRow),
|
||||
ReleaseEffectsByGroupId: make(map[int32][]CharacterBoardReleaseEffectRow),
|
||||
StatusUpById: make(map[int32]CharacterBoardStatusUpRow, len(statusUps)),
|
||||
AbilityById: make(map[int32]CharacterBoardAbilityRow, len(abilities)),
|
||||
PanelById: make(map[int32]EntityMCharacterBoardPanel, len(panels)),
|
||||
PanelsByBoardId: make(map[int32][]EntityMCharacterBoardPanel),
|
||||
ReleaseCostsByGroupId: make(map[int32][]EntityMCharacterBoardPanelReleasePossessionGroup),
|
||||
ReleaseEffectsByGroupId: make(map[int32][]EntityMCharacterBoardPanelReleaseEffectGroup),
|
||||
StatusUpById: make(map[int32]EntityMCharacterBoardStatusUp, len(statusUps)),
|
||||
AbilityById: make(map[int32]EntityMCharacterBoardAbility, len(abilities)),
|
||||
AbilityMaxLevel: make(map[store.CharacterBoardAbilityKey]int32, len(abilityMaxLevels)),
|
||||
EffectTargetsByGroupId: make(map[int32][]CharacterBoardEffectTargetRow),
|
||||
BoardById: make(map[int32]CharacterBoardRow, len(boards)),
|
||||
EffectTargetsByGroupId: make(map[int32][]EntityMCharacterBoardEffectTargetGroup),
|
||||
BoardById: make(map[int32]EntityMCharacterBoard, len(boards)),
|
||||
}
|
||||
|
||||
for _, p := range panels {
|
||||
|
||||
@@ -9,11 +9,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type characterViewerField struct {
|
||||
CharacterViewerFieldId int32 `json:"CharacterViewerFieldId"`
|
||||
ReleaseEvaluateConditionId int32 `json:"ReleaseEvaluateConditionId"`
|
||||
}
|
||||
|
||||
type characterViewerFieldEntry struct {
|
||||
FieldId int32
|
||||
RequiredQuestId int32
|
||||
@@ -39,7 +34,7 @@ func (c *CharacterViewerCatalog) ReleasedFieldIds(user store.UserState) []int32
|
||||
}
|
||||
|
||||
func LoadCharacterViewerCatalog(resolver *ConditionResolver) *CharacterViewerCatalog {
|
||||
fields, err := utils.ReadJSON[characterViewerField]("EntityMCharacterViewerFieldTable.json")
|
||||
fields, err := utils.ReadTable[EntityMCharacterViewerField]("m_character_viewer_field")
|
||||
if err != nil {
|
||||
log.Fatalf("load character viewer field table: %v", err)
|
||||
}
|
||||
|
||||
@@ -6,23 +6,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type companionRow struct {
|
||||
CompanionId int32 `json:"CompanionId"`
|
||||
CompanionCategoryType int32 `json:"CompanionCategoryType"`
|
||||
}
|
||||
|
||||
type companionCategoryRow struct {
|
||||
CompanionCategoryType int32 `json:"CompanionCategoryType"`
|
||||
EnhancementCostNumericalFunctionId int32 `json:"EnhancementCostNumericalFunctionId"`
|
||||
}
|
||||
|
||||
type companionEnhancementMaterialRow struct {
|
||||
CompanionCategoryType int32 `json:"CompanionCategoryType"`
|
||||
Level int32 `json:"Level"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type CompanionLevelKey struct {
|
||||
CategoryType int32
|
||||
Level int32
|
||||
@@ -34,23 +17,23 @@ type CompanionMaterialCost struct {
|
||||
}
|
||||
|
||||
type CompanionCatalog struct {
|
||||
CompanionById map[int32]companionRow
|
||||
CompanionById map[int32]EntityMCompanion
|
||||
GoldCostByCategory map[int32]NumericalFunc
|
||||
MaterialsByKey map[CompanionLevelKey]CompanionMaterialCost
|
||||
}
|
||||
|
||||
func LoadCompanionCatalog() (*CompanionCatalog, error) {
|
||||
companions, err := utils.ReadJSON[companionRow]("EntityMCompanionTable.json")
|
||||
companions, err := utils.ReadTable[EntityMCompanion]("m_companion")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load companion table: %w", err)
|
||||
}
|
||||
|
||||
categories, err := utils.ReadJSON[companionCategoryRow]("EntityMCompanionCategoryTable.json")
|
||||
categories, err := utils.ReadTable[EntityMCompanionCategory]("m_companion_category")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load companion category table: %w", err)
|
||||
}
|
||||
|
||||
materials, err := utils.ReadJSON[companionEnhancementMaterialRow]("EntityMCompanionEnhancementMaterialTable.json")
|
||||
materials, err := utils.ReadTable[EntityMCompanionEnhancementMaterial]("m_companion_enhancement_material")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load companion enhancement material table: %w", err)
|
||||
}
|
||||
@@ -60,7 +43,7 @@ func LoadCompanionCatalog() (*CompanionCatalog, error) {
|
||||
return nil, fmt.Errorf("load function resolver: %w", err)
|
||||
}
|
||||
|
||||
companionById := make(map[int32]companionRow, len(companions))
|
||||
companionById := make(map[int32]EntityMCompanion, len(companions))
|
||||
for _, c := range companions {
|
||||
companionById[c.CompanionId] = c
|
||||
}
|
||||
|
||||
@@ -7,19 +7,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type evaluateCondition struct {
|
||||
EvaluateConditionId int32 `json:"EvaluateConditionId"`
|
||||
EvaluateConditionFunctionType model.EvaluateConditionFunctionType `json:"EvaluateConditionFunctionType"`
|
||||
EvaluateConditionEvaluateType model.EvaluateConditionEvaluateType `json:"EvaluateConditionEvaluateType"`
|
||||
EvaluateConditionValueGroupId int32 `json:"EvaluateConditionValueGroupId"`
|
||||
}
|
||||
|
||||
type evaluateConditionValueGroup struct {
|
||||
EvaluateConditionValueGroupId int32 `json:"EvaluateConditionValueGroupId"`
|
||||
GroupIndex int32 `json:"GroupIndex"`
|
||||
Value int64 `json:"Value"`
|
||||
}
|
||||
|
||||
const defaultGroupIndex = 1
|
||||
|
||||
type ConditionResolver struct {
|
||||
@@ -27,16 +14,16 @@ type ConditionResolver struct {
|
||||
}
|
||||
|
||||
func LoadConditionResolver() (*ConditionResolver, error) {
|
||||
conditions, err := utils.ReadJSON[evaluateCondition]("EntityMEvaluateConditionTable.json")
|
||||
conditions, err := utils.ReadTable[EntityMEvaluateCondition]("m_evaluate_condition")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load evaluate condition table: %w", err)
|
||||
}
|
||||
valueGroups, err := utils.ReadJSON[evaluateConditionValueGroup]("EntityMEvaluateConditionValueGroupTable.json")
|
||||
valueGroups, err := utils.ReadTable[EntityMEvaluateConditionValueGroup]("m_evaluate_condition_value_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load evaluate condition value group table: %w", err)
|
||||
}
|
||||
|
||||
condById := make(map[int32]evaluateCondition, len(conditions))
|
||||
condById := make(map[int32]EntityMEvaluateCondition, len(conditions))
|
||||
for _, c := range conditions {
|
||||
condById[c.EvaluateConditionId] = c
|
||||
}
|
||||
@@ -52,8 +39,8 @@ func LoadConditionResolver() (*ConditionResolver, error) {
|
||||
|
||||
resolved := make(map[int32]int32)
|
||||
for _, c := range conditions {
|
||||
if c.EvaluateConditionFunctionType == model.EvaluateConditionFunctionTypeQuestClear &&
|
||||
c.EvaluateConditionEvaluateType == model.EvaluateConditionEvaluateTypeIdContain {
|
||||
if model.EvaluateConditionFunctionType(c.EvaluateConditionFunctionType) == model.EvaluateConditionFunctionTypeQuestClear &&
|
||||
model.EvaluateConditionEvaluateType(c.EvaluateConditionEvaluateType) == model.EvaluateConditionEvaluateTypeIdContain {
|
||||
if questId, ok := vgByKey[vgKey{c.EvaluateConditionValueGroupId, defaultGroupIndex}]; ok {
|
||||
resolved[c.EvaluateConditionId] = int32(questId)
|
||||
}
|
||||
|
||||
@@ -7,11 +7,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type configRow struct {
|
||||
ConfigKey string `json:"ConfigKey"`
|
||||
Value string `json:"Value"`
|
||||
}
|
||||
|
||||
type GameConfig struct {
|
||||
ConsumableItemIdForGold int32
|
||||
ConsumableItemIdForMedal int32
|
||||
@@ -41,7 +36,7 @@ type GameConfig struct {
|
||||
}
|
||||
|
||||
func LoadGameConfig() (*GameConfig, error) {
|
||||
rows, err := utils.ReadJSON[configRow]("EntityMConfigTable.json")
|
||||
rows, err := utils.ReadTable[EntityMConfig]("m_config")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load config table: %w", err)
|
||||
}
|
||||
|
||||
@@ -6,23 +6,18 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type ConsumableItemRow struct {
|
||||
ConsumableItemId int32 `json:"ConsumableItemId"`
|
||||
SellPrice int32 `json:"SellPrice"`
|
||||
}
|
||||
|
||||
type ConsumableItemCatalog struct {
|
||||
All map[int32]ConsumableItemRow
|
||||
All map[int32]EntityMConsumableItem
|
||||
}
|
||||
|
||||
func LoadConsumableItemCatalog() (*ConsumableItemCatalog, error) {
|
||||
rows, err := utils.ReadJSON[ConsumableItemRow]("EntityMConsumableItemTable.json")
|
||||
rows, err := utils.ReadTable[EntityMConsumableItem]("m_consumable_item")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load consumable item table: %w", err)
|
||||
}
|
||||
|
||||
catalog := &ConsumableItemCatalog{
|
||||
All: make(map[int32]ConsumableItemRow, len(rows)),
|
||||
All: make(map[int32]EntityMConsumableItem, len(rows)),
|
||||
}
|
||||
for _, row := range rows {
|
||||
catalog.All[row.ConsumableItemId] = row
|
||||
|
||||
@@ -8,132 +8,37 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type CostumeMasterRow struct {
|
||||
CostumeId int32 `json:"CostumeId"`
|
||||
CharacterId int32 `json:"CharacterId"`
|
||||
SkillfulWeaponType int32 `json:"SkillfulWeaponType"`
|
||||
RarityType int32 `json:"RarityType"`
|
||||
CostumeLimitBreakMaterialGroupId int32 `json:"CostumeLimitBreakMaterialGroupId"`
|
||||
CostumeActiveSkillGroupId int32 `json:"CostumeActiveSkillGroupId"`
|
||||
}
|
||||
|
||||
type costumeRarityRow struct {
|
||||
RarityType int32 `json:"RarityType"`
|
||||
CostumeLimitBreakMaterialRarityGroupId int32 `json:"CostumeLimitBreakMaterialRarityGroupId"`
|
||||
RequiredExpForLevelUpNumericalParameterMapId int32 `json:"RequiredExpForLevelUpNumericalParameterMapId"`
|
||||
EnhancementCostByMaterialNumericalFunctionId int32 `json:"EnhancementCostByMaterialNumericalFunctionId"`
|
||||
LimitBreakCostNumericalFunctionId int32 `json:"LimitBreakCostNumericalFunctionId"`
|
||||
MaxLevelNumericalFunctionId int32 `json:"MaxLevelNumericalFunctionId"`
|
||||
ActiveSkillMaxLevelNumericalFunctionId int32 `json:"ActiveSkillMaxLevelNumericalFunctionId"`
|
||||
ActiveSkillEnhancementCostNumericalFunctionId int32 `json:"ActiveSkillEnhancementCostNumericalFunctionId"`
|
||||
}
|
||||
|
||||
type CostumeAwakenRow struct {
|
||||
CostumeId int32 `json:"CostumeId"`
|
||||
CostumeAwakenEffectGroupId int32 `json:"CostumeAwakenEffectGroupId"`
|
||||
CostumeAwakenStepMaterialGroupId int32 `json:"CostumeAwakenStepMaterialGroupId"`
|
||||
CostumeAwakenPriceGroupId int32 `json:"CostumeAwakenPriceGroupId"`
|
||||
}
|
||||
|
||||
type costumeAwakenPriceRow struct {
|
||||
CostumeAwakenPriceGroupId int32 `json:"CostumeAwakenPriceGroupId"`
|
||||
AwakenStepLowerLimit int32 `json:"AwakenStepLowerLimit"`
|
||||
Gold int32 `json:"Gold"`
|
||||
}
|
||||
|
||||
type CostumeAwakenEffectRow struct {
|
||||
CostumeAwakenEffectGroupId int32 `json:"CostumeAwakenEffectGroupId"`
|
||||
AwakenStep int32 `json:"AwakenStep"`
|
||||
CostumeAwakenEffectType int32 `json:"CostumeAwakenEffectType"`
|
||||
CostumeAwakenEffectId int32 `json:"CostumeAwakenEffectId"`
|
||||
}
|
||||
|
||||
type CostumeAwakenStatusUpRow struct {
|
||||
CostumeAwakenStatusUpGroupId int32 `json:"CostumeAwakenStatusUpGroupId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
StatusKindType int32 `json:"StatusKindType"`
|
||||
StatusCalculationType int32 `json:"StatusCalculationType"`
|
||||
EffectValue int32 `json:"EffectValue"`
|
||||
}
|
||||
|
||||
type CostumeAwakenItemAcquireRow struct {
|
||||
CostumeAwakenItemAcquireId int32 `json:"CostumeAwakenItemAcquireId"`
|
||||
PossessionType int32 `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type CostumeActiveSkillGroupRow struct {
|
||||
CostumeActiveSkillGroupId int32 `json:"CostumeActiveSkillGroupId"`
|
||||
CostumeLimitBreakCountLowerLimit int32 `json:"CostumeLimitBreakCountLowerLimit"`
|
||||
CostumeActiveSkillId int32 `json:"CostumeActiveSkillId"`
|
||||
CostumeActiveSkillEnhancementMaterialId int32 `json:"CostumeActiveSkillEnhancementMaterialId"`
|
||||
}
|
||||
|
||||
type CostumeActiveSkillEnhanceMaterialRow struct {
|
||||
CostumeActiveSkillEnhancementMaterialId int32 `json:"CostumeActiveSkillEnhancementMaterialId"`
|
||||
SkillLevel int32 `json:"SkillLevel"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type CostumeLotteryEffectRow struct {
|
||||
CostumeId int32 `json:"CostumeId"`
|
||||
SlotNumber int32 `json:"SlotNumber"`
|
||||
CostumeLotteryEffectOddsGroupId int32 `json:"CostumeLotteryEffectOddsGroupId"`
|
||||
CostumeLotteryEffectUnlockMaterialGroupId int32 `json:"CostumeLotteryEffectUnlockMaterialGroupId"`
|
||||
CostumeLotteryEffectDrawMaterialGroupId int32 `json:"CostumeLotteryEffectDrawMaterialGroupId"`
|
||||
CostumeLotteryEffectReleaseScheduleId int32 `json:"CostumeLotteryEffectReleaseScheduleId"`
|
||||
}
|
||||
|
||||
type CostumeLotteryEffectMaterialGroupRow struct {
|
||||
CostumeLotteryEffectMaterialGroupId int32 `json:"CostumeLotteryEffectMaterialGroupId"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type CostumeLotteryEffectOddsRow struct {
|
||||
CostumeLotteryEffectOddsGroupId int32 `json:"CostumeLotteryEffectOddsGroupId"`
|
||||
OddsNumber int32 `json:"OddsNumber"`
|
||||
Weight int32 `json:"Weight"`
|
||||
CostumeLotteryEffectType int32 `json:"CostumeLotteryEffectType"`
|
||||
CostumeLotteryEffectTargetId int32 `json:"CostumeLotteryEffectTargetId"`
|
||||
RarityType int32 `json:"RarityType"`
|
||||
}
|
||||
|
||||
type CostumeCatalog struct {
|
||||
Costumes map[int32]CostumeMasterRow
|
||||
Materials map[int32]MaterialRow
|
||||
Costumes map[int32]EntityMCostume
|
||||
Materials map[int32]EntityMMaterial
|
||||
ExpByRarity map[int32][]int32
|
||||
EnhanceCostByRarity map[int32]NumericalFunc
|
||||
MaxLevelByRarity map[int32]NumericalFunc
|
||||
LimitBreakCostByRarity map[int32]NumericalFunc
|
||||
|
||||
AwakenByCostumeId map[int32]CostumeAwakenRow
|
||||
AwakenByCostumeId map[int32]EntityMCostumeAwaken
|
||||
AwakenPriceByGroup map[int32]int32
|
||||
AwakenEffectsByGroupAndStep map[int32]map[int32]CostumeAwakenEffectRow
|
||||
AwakenStatusUpByGroup map[int32][]CostumeAwakenStatusUpRow
|
||||
AwakenItemAcquireById map[int32]CostumeAwakenItemAcquireRow
|
||||
AwakenEffectsByGroupAndStep map[int32]map[int32]EntityMCostumeAwakenEffectGroup
|
||||
AwakenStatusUpByGroup map[int32][]EntityMCostumeAwakenStatusUpGroup
|
||||
AwakenItemAcquireById map[int32]EntityMCostumeAwakenItemAcquire
|
||||
|
||||
ActiveSkillGroupsByGroupId map[int32][]CostumeActiveSkillGroupRow // sorted by CostumeLimitBreakCountLowerLimit desc
|
||||
ActiveSkillEnhanceMats map[[2]int32][]CostumeActiveSkillEnhanceMaterialRow // key: [enhancementMaterialId, skillLevel]
|
||||
ActiveSkillGroupsByGroupId map[int32][]EntityMCostumeActiveSkillGroup // sorted by CostumeLimitBreakCountLowerLimit desc
|
||||
ActiveSkillEnhanceMats map[[2]int32][]EntityMCostumeActiveSkillEnhancementMaterial // key: [enhancementMaterialId, skillLevel]
|
||||
ActiveSkillMaxLevelByRarity map[int32]NumericalFunc
|
||||
ActiveSkillCostByRarity map[int32]NumericalFunc
|
||||
|
||||
LotteryEffects map[[2]int32]CostumeLotteryEffectRow // key: [costumeId, slotNumber]
|
||||
LotteryEffectMats map[int32][]CostumeLotteryEffectMaterialGroupRow // key: materialGroupId (both unlock and draw)
|
||||
LotteryEffectOdds map[int32][]CostumeLotteryEffectOddsRow // key: oddsGroupId
|
||||
LotteryEffects map[[2]int32]EntityMCostumeLotteryEffect // key: [costumeId, slotNumber]
|
||||
LotteryEffectMats map[int32][]EntityMCostumeLotteryEffectMaterialGroup // key: materialGroupId (both unlock and draw)
|
||||
LotteryEffectOdds map[int32][]EntityMCostumeLotteryEffectOddsGroup // key: oddsGroupId
|
||||
}
|
||||
|
||||
func LoadCostumeCatalog(matCatalog *MaterialCatalog) (*CostumeCatalog, error) {
|
||||
costumes, err := utils.ReadJSON[CostumeMasterRow]("EntityMCostumeTable.json")
|
||||
costumes, err := utils.ReadTable[EntityMCostume]("m_costume")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume table: %w", err)
|
||||
}
|
||||
|
||||
rarities, err := utils.ReadJSON[costumeRarityRow]("EntityMCostumeRarityTable.json")
|
||||
rarities, err := utils.ReadTable[EntityMCostumeRarity]("m_costume_rarity")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume rarity table: %w", err)
|
||||
}
|
||||
@@ -148,71 +53,71 @@ func LoadCostumeCatalog(matCatalog *MaterialCatalog) (*CostumeCatalog, error) {
|
||||
return nil, fmt.Errorf("load function resolver: %w", err)
|
||||
}
|
||||
|
||||
awakenRows, err := utils.ReadJSON[CostumeAwakenRow]("EntityMCostumeAwakenTable.json")
|
||||
awakenRows, err := utils.ReadTable[EntityMCostumeAwaken]("m_costume_awaken")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume awaken table: %w", err)
|
||||
}
|
||||
awakenPriceRows, err := utils.ReadJSON[costumeAwakenPriceRow]("EntityMCostumeAwakenPriceGroupTable.json")
|
||||
awakenPriceRows, err := utils.ReadTable[EntityMCostumeAwakenPriceGroup]("m_costume_awaken_price_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume awaken price table: %w", err)
|
||||
}
|
||||
awakenEffectRows, err := utils.ReadJSON[CostumeAwakenEffectRow]("EntityMCostumeAwakenEffectGroupTable.json")
|
||||
awakenEffectRows, err := utils.ReadTable[EntityMCostumeAwakenEffectGroup]("m_costume_awaken_effect_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume awaken effect table: %w", err)
|
||||
}
|
||||
awakenStatusUpRows, err := utils.ReadJSON[CostumeAwakenStatusUpRow]("EntityMCostumeAwakenStatusUpGroupTable.json")
|
||||
awakenStatusUpRows, err := utils.ReadTable[EntityMCostumeAwakenStatusUpGroup]("m_costume_awaken_status_up_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume awaken status up table: %w", err)
|
||||
}
|
||||
awakenItemAcquireRows, err := utils.ReadJSON[CostumeAwakenItemAcquireRow]("EntityMCostumeAwakenItemAcquireTable.json")
|
||||
awakenItemAcquireRows, err := utils.ReadTable[EntityMCostumeAwakenItemAcquire]("m_costume_awaken_item_acquire")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume awaken item acquire table: %w", err)
|
||||
}
|
||||
|
||||
activeSkillGroupRows, err := utils.ReadJSON[CostumeActiveSkillGroupRow]("EntityMCostumeActiveSkillGroupTable.json")
|
||||
activeSkillGroupRows, err := utils.ReadTable[EntityMCostumeActiveSkillGroup]("m_costume_active_skill_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume active skill group table: %w", err)
|
||||
}
|
||||
activeSkillMatRows, err := utils.ReadJSON[CostumeActiveSkillEnhanceMaterialRow]("EntityMCostumeActiveSkillEnhancementMaterialTable.json")
|
||||
activeSkillMatRows, err := utils.ReadTable[EntityMCostumeActiveSkillEnhancementMaterial]("m_costume_active_skill_enhancement_material")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume active skill enhancement material table: %w", err)
|
||||
}
|
||||
|
||||
lotteryEffectRows, err := utils.ReadJSON[CostumeLotteryEffectRow]("EntityMCostumeLotteryEffectTable.json")
|
||||
lotteryEffectRows, err := utils.ReadTable[EntityMCostumeLotteryEffect]("m_costume_lottery_effect")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume lottery effect table: %w", err)
|
||||
}
|
||||
lotteryEffectMatRows, err := utils.ReadJSON[CostumeLotteryEffectMaterialGroupRow]("EntityMCostumeLotteryEffectMaterialGroupTable.json")
|
||||
lotteryEffectMatRows, err := utils.ReadTable[EntityMCostumeLotteryEffectMaterialGroup]("m_costume_lottery_effect_material_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume lottery effect material group table: %w", err)
|
||||
}
|
||||
lotteryEffectOddsRows, err := utils.ReadJSON[CostumeLotteryEffectOddsRow]("EntityMCostumeLotteryEffectOddsGroupTable.json")
|
||||
lotteryEffectOddsRows, err := utils.ReadTable[EntityMCostumeLotteryEffectOddsGroup]("m_costume_lottery_effect_odds_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume lottery effect odds group table: %w", err)
|
||||
}
|
||||
|
||||
catalog := &CostumeCatalog{
|
||||
Costumes: make(map[int32]CostumeMasterRow, len(costumes)),
|
||||
Costumes: make(map[int32]EntityMCostume, len(costumes)),
|
||||
Materials: matCatalog.ByType[model.MaterialTypeCostumeEnhancement],
|
||||
ExpByRarity: make(map[int32][]int32, len(rarities)),
|
||||
EnhanceCostByRarity: make(map[int32]NumericalFunc, len(rarities)),
|
||||
MaxLevelByRarity: make(map[int32]NumericalFunc, len(rarities)),
|
||||
LimitBreakCostByRarity: make(map[int32]NumericalFunc, len(rarities)),
|
||||
|
||||
AwakenByCostumeId: make(map[int32]CostumeAwakenRow, len(awakenRows)),
|
||||
AwakenByCostumeId: make(map[int32]EntityMCostumeAwaken, len(awakenRows)),
|
||||
AwakenPriceByGroup: make(map[int32]int32, len(awakenPriceRows)),
|
||||
AwakenEffectsByGroupAndStep: make(map[int32]map[int32]CostumeAwakenEffectRow),
|
||||
AwakenStatusUpByGroup: make(map[int32][]CostumeAwakenStatusUpRow),
|
||||
AwakenItemAcquireById: make(map[int32]CostumeAwakenItemAcquireRow, len(awakenItemAcquireRows)),
|
||||
AwakenEffectsByGroupAndStep: make(map[int32]map[int32]EntityMCostumeAwakenEffectGroup),
|
||||
AwakenStatusUpByGroup: make(map[int32][]EntityMCostumeAwakenStatusUpGroup),
|
||||
AwakenItemAcquireById: make(map[int32]EntityMCostumeAwakenItemAcquire, len(awakenItemAcquireRows)),
|
||||
|
||||
ActiveSkillGroupsByGroupId: make(map[int32][]CostumeActiveSkillGroupRow),
|
||||
ActiveSkillEnhanceMats: make(map[[2]int32][]CostumeActiveSkillEnhanceMaterialRow),
|
||||
ActiveSkillGroupsByGroupId: make(map[int32][]EntityMCostumeActiveSkillGroup),
|
||||
ActiveSkillEnhanceMats: make(map[[2]int32][]EntityMCostumeActiveSkillEnhancementMaterial),
|
||||
ActiveSkillMaxLevelByRarity: make(map[int32]NumericalFunc, len(rarities)),
|
||||
ActiveSkillCostByRarity: make(map[int32]NumericalFunc, len(rarities)),
|
||||
|
||||
LotteryEffects: make(map[[2]int32]CostumeLotteryEffectRow, len(lotteryEffectRows)),
|
||||
LotteryEffectMats: make(map[int32][]CostumeLotteryEffectMaterialGroupRow),
|
||||
LotteryEffectOdds: make(map[int32][]CostumeLotteryEffectOddsRow),
|
||||
LotteryEffects: make(map[[2]int32]EntityMCostumeLotteryEffect, len(lotteryEffectRows)),
|
||||
LotteryEffectMats: make(map[int32][]EntityMCostumeLotteryEffectMaterialGroup),
|
||||
LotteryEffectOdds: make(map[int32][]EntityMCostumeLotteryEffectOddsGroup),
|
||||
}
|
||||
|
||||
for _, row := range costumes {
|
||||
@@ -259,7 +164,7 @@ func LoadCostumeCatalog(matCatalog *MaterialCatalog) (*CostumeCatalog, error) {
|
||||
for _, row := range awakenEffectRows {
|
||||
m, ok := catalog.AwakenEffectsByGroupAndStep[row.CostumeAwakenEffectGroupId]
|
||||
if !ok {
|
||||
m = make(map[int32]CostumeAwakenEffectRow)
|
||||
m = make(map[int32]EntityMCostumeAwakenEffectGroup)
|
||||
catalog.AwakenEffectsByGroupAndStep[row.CostumeAwakenEffectGroupId] = m
|
||||
}
|
||||
m[row.AwakenStep] = row
|
||||
|
||||
@@ -5,17 +5,10 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type costumeDupRow struct {
|
||||
CostumeId int32 `json:"CostumeId"`
|
||||
PossessionType int32 `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
func LoadDupExchange() (map[int32][]model.DupExchangeEntry, error) {
|
||||
result := make(map[int32][]model.DupExchangeEntry)
|
||||
|
||||
costumeRows, err := utils.ReadJSON[costumeDupRow]("EntityMCostumeDuplicationExchangePossessionGroupTable.json")
|
||||
costumeRows, err := utils.ReadTable[EntityMCostumeDuplicationExchangePossessionGroup]("m_costume_duplication_exchange_possession_group")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -30,20 +23,10 @@ func LoadDupExchange() (map[int32][]model.DupExchangeEntry, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type lbMaterialRow struct {
|
||||
CostumeLimitBreakMaterialGroupId int32 `json:"CostumeLimitBreakMaterialGroupId"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
}
|
||||
|
||||
type costumeLBRef struct {
|
||||
CostumeId int32 `json:"CostumeId"`
|
||||
CostumeLimitBreakMaterialGroupId int32 `json:"CostumeLimitBreakMaterialGroupId"`
|
||||
}
|
||||
|
||||
const dupExchangeFallbackCount int32 = 10
|
||||
|
||||
func EnrichDupExchange(dupMap map[int32][]model.DupExchangeEntry, pool *GachaCatalog) (int, error) {
|
||||
lbRows, err := utils.ReadJSON[lbMaterialRow]("EntityMCostumeLimitBreakMaterialGroupTable.json")
|
||||
lbRows, err := utils.ReadTable[EntityMCostumeLimitBreakMaterialGroup]("m_costume_limit_break_material_group")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -52,7 +35,7 @@ func EnrichDupExchange(dupMap map[int32][]model.DupExchangeEntry, pool *GachaCat
|
||||
groupToMaterial[r.CostumeLimitBreakMaterialGroupId] = r.MaterialId
|
||||
}
|
||||
|
||||
costumeRows, err := utils.ReadJSON[costumeLBRef]("EntityMCostumeTable.json")
|
||||
costumeRows, err := utils.ReadTable[EntityMCostume]("m_costume")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,48 +7,31 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type ExploreRow struct {
|
||||
ExploreId int32 `json:"ExploreId"`
|
||||
ConsumeItemCount int32 `json:"ConsumeItemCount"`
|
||||
RewardLotteryCount int32 `json:"RewardLotteryCount"`
|
||||
}
|
||||
|
||||
type ExploreGradeScoreRow struct {
|
||||
ExploreId int32 `json:"ExploreId"`
|
||||
NecessaryScore int32 `json:"NecessaryScore"`
|
||||
ExploreGradeId int32 `json:"ExploreGradeId"`
|
||||
}
|
||||
|
||||
type ExploreGradeAssetRow struct {
|
||||
ExploreGradeId int32 `json:"ExploreGradeId"`
|
||||
AssetGradeIconId int32 `json:"AssetGradeIconId"`
|
||||
}
|
||||
|
||||
type ExploreCatalog struct {
|
||||
Explores map[int32]ExploreRow
|
||||
GradeScores map[int32][]ExploreGradeScoreRow // keyed by ExploreId, sorted desc by NecessaryScore
|
||||
GradeAssets map[int32]int32 // gradeId -> assetGradeIconId
|
||||
Explores map[int32]EntityMExplore
|
||||
GradeScores map[int32][]EntityMExploreGradeScore // keyed by ExploreId, sorted desc by NecessaryScore
|
||||
GradeAssets map[int32]int32 // gradeId -> assetGradeIconId
|
||||
}
|
||||
|
||||
func LoadExploreCatalog() (*ExploreCatalog, error) {
|
||||
explores, err := utils.ReadJSON[ExploreRow]("EntityMExploreTable.json")
|
||||
explores, err := utils.ReadTable[EntityMExplore]("m_explore")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load explore table: %w", err)
|
||||
}
|
||||
|
||||
gradeScores, err := utils.ReadJSON[ExploreGradeScoreRow]("EntityMExploreGradeScoreTable.json")
|
||||
gradeScores, err := utils.ReadTable[EntityMExploreGradeScore]("m_explore_grade_score")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load explore grade score table: %w", err)
|
||||
}
|
||||
|
||||
gradeAssets, err := utils.ReadJSON[ExploreGradeAssetRow]("EntityMExploreGradeAssetTable.json")
|
||||
gradeAssets, err := utils.ReadTable[EntityMExploreGradeAsset]("m_explore_grade_asset")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load explore grade asset table: %w", err)
|
||||
}
|
||||
|
||||
catalog := &ExploreCatalog{
|
||||
Explores: make(map[int32]ExploreRow, len(explores)),
|
||||
GradeScores: make(map[int32][]ExploreGradeScoreRow),
|
||||
Explores: make(map[int32]EntityMExplore, len(explores)),
|
||||
GradeScores: make(map[int32][]EntityMExploreGradeScore),
|
||||
GradeAssets: make(map[int32]int32, len(gradeAssets)),
|
||||
}
|
||||
|
||||
|
||||
@@ -10,24 +10,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type gachaMedalRow struct {
|
||||
GachaMedalId int32 `json:"GachaMedalId"`
|
||||
ShopTransitionGachaId int32 `json:"ShopTransitionGachaId"`
|
||||
ConsumableItemId int32 `json:"ConsumableItemId"`
|
||||
AutoConvertDatetime int64 `json:"AutoConvertDatetime"`
|
||||
ConversionRate int32 `json:"ConversionRate"`
|
||||
}
|
||||
|
||||
type momBannerRow struct {
|
||||
MomBannerId int32 `json:"MomBannerId"`
|
||||
SortOrderDesc int32 `json:"SortOrderDesc"`
|
||||
DestinationDomainType int32 `json:"DestinationDomainType"`
|
||||
DestinationDomainId int32 `json:"DestinationDomainId"`
|
||||
BannerAssetName string `json:"BannerAssetName"`
|
||||
StartDatetime int64 `json:"StartDatetime"`
|
||||
EndDatetime int64 `json:"EndDatetime"`
|
||||
}
|
||||
|
||||
type GachaMedalInfo struct {
|
||||
GachaMedalId int32
|
||||
ConsumableItemId int32
|
||||
@@ -38,16 +20,16 @@ type GachaMedalInfo struct {
|
||||
const chapterGachaIdBase int32 = 200000
|
||||
|
||||
func LoadGachaCatalog() ([]store.GachaCatalogEntry, map[int32]GachaMedalInfo, error) {
|
||||
medals, err := utils.ReadJSON[gachaMedalRow]("EntityMGachaMedalTable.json")
|
||||
medals, err := utils.ReadTable[EntityMGachaMedal]("m_gacha_medal")
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("load gacha medal table: %w", err)
|
||||
}
|
||||
banners, err := utils.ReadJSON[momBannerRow]("EntityMMomBannerTable.json")
|
||||
banners, err := utils.ReadTable[EntityMMomBanner]("m_mom_banner")
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("load mom banner table: %w", err)
|
||||
}
|
||||
|
||||
gachaToMedal := make(map[int32]gachaMedalRow)
|
||||
gachaToMedal := make(map[int32]EntityMGachaMedal)
|
||||
medalInfoByGacha := make(map[int32]GachaMedalInfo)
|
||||
for _, m := range medals {
|
||||
gachaToMedal[m.ShopTransitionGachaId] = m
|
||||
@@ -59,7 +41,7 @@ func LoadGachaCatalog() ([]store.GachaCatalogEntry, map[int32]GachaMedalInfo, er
|
||||
}
|
||||
}
|
||||
|
||||
stepupSteps := make(map[int32][]momBannerRow)
|
||||
stepupSteps := make(map[int32][]EntityMMomBanner)
|
||||
var entries []store.GachaCatalogEntry
|
||||
|
||||
for _, b := range banners {
|
||||
|
||||
@@ -46,58 +46,28 @@ type GachaCatalog struct {
|
||||
ShopFeaturedByMedal map[int32][]ShopFeaturedEntry // consumableId -> paired entries
|
||||
}
|
||||
|
||||
type costumePoolRow struct {
|
||||
CostumeId int32 `json:"CostumeId"`
|
||||
CharacterId int32 `json:"CharacterId"`
|
||||
SkillfulWeaponType int32 `json:"SkillfulWeaponType"`
|
||||
RarityType int32 `json:"RarityType"`
|
||||
}
|
||||
|
||||
type weaponPoolRow struct {
|
||||
WeaponId int32 `json:"WeaponId"`
|
||||
WeaponType int32 `json:"WeaponType"`
|
||||
RarityType int32 `json:"RarityType"`
|
||||
IsRestrictDiscard bool `json:"IsRestrictDiscard"`
|
||||
}
|
||||
|
||||
type catalogCostumeRow struct {
|
||||
CostumeId int32 `json:"CostumeId"`
|
||||
CatalogTermId int32 `json:"CatalogTermId"`
|
||||
}
|
||||
|
||||
type catalogWeaponRow struct {
|
||||
WeaponId int32 `json:"WeaponId"`
|
||||
CatalogTermId int32 `json:"CatalogTermId"`
|
||||
}
|
||||
|
||||
type materialPoolRow struct {
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
MaterialType int32 `json:"MaterialType"`
|
||||
RarityType int32 `json:"RarityType"`
|
||||
}
|
||||
|
||||
func LoadGachaPool() (*GachaCatalog, error) {
|
||||
costumes, err := utils.ReadJSON[costumePoolRow]("EntityMCostumeTable.json")
|
||||
costumes, err := utils.ReadTable[EntityMCostume]("m_costume")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume table: %w", err)
|
||||
}
|
||||
weapons, err := utils.ReadJSON[weaponPoolRow]("EntityMWeaponTable.json")
|
||||
weapons, err := utils.ReadTable[EntityMWeapon]("m_weapon")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon table: %w", err)
|
||||
}
|
||||
catalogCostumes, err := utils.ReadJSON[catalogCostumeRow]("EntityMCatalogCostumeTable.json")
|
||||
catalogCostumes, err := utils.ReadTable[EntityMCatalogCostume]("m_catalog_costume")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load catalog costume table: %w", err)
|
||||
}
|
||||
catalogWeapons, err := utils.ReadJSON[catalogWeaponRow]("EntityMCatalogWeaponTable.json")
|
||||
catalogWeapons, err := utils.ReadTable[EntityMCatalogWeapon]("m_catalog_weapon")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load catalog weapon table: %w", err)
|
||||
}
|
||||
materials, err := utils.ReadJSON[materialPoolRow]("EntityMMaterialTable.json")
|
||||
materials, err := utils.ReadTable[EntityMMaterial]("m_material")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load material table: %w", err)
|
||||
}
|
||||
evoGroupRows, err := utils.ReadJSON[WeaponEvolutionGroupRow]("EntityMWeaponEvolutionGroupTable.json")
|
||||
evoGroupRows, err := utils.ReadTable[EntityMWeaponEvolutionGroup]("m_weapon_evolution_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon evolution group table: %w", err)
|
||||
}
|
||||
@@ -414,8 +384,8 @@ func (pool *GachaCatalog) BuildBannerPools(entries []store.GachaCatalogEntry) {
|
||||
len(pool.BannerPools), len(allFeaturedCostumes), len(allFeaturedWeapons))
|
||||
}
|
||||
|
||||
func buildEvolvedWeaponSet(rows []WeaponEvolutionGroupRow) map[int32]bool {
|
||||
grouped := make(map[int32][]WeaponEvolutionGroupRow)
|
||||
func buildEvolvedWeaponSet(rows []EntityMWeaponEvolutionGroup) map[int32]bool {
|
||||
grouped := make(map[int32][]EntityMWeaponEvolutionGroup)
|
||||
for _, r := range rows {
|
||||
grouped[r.WeaponEvolutionGroupId] = append(grouped[r.WeaponEvolutionGroupId], r)
|
||||
}
|
||||
|
||||
@@ -9,14 +9,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type gimmickScheduleRow struct {
|
||||
GimmickSequenceScheduleId int32 `json:"GimmickSequenceScheduleId"`
|
||||
StartDatetime int64 `json:"StartDatetime"`
|
||||
EndDatetime int64 `json:"EndDatetime"`
|
||||
FirstGimmickSequenceId int32 `json:"FirstGimmickSequenceId"`
|
||||
ReleaseEvaluateConditionId int32 `json:"ReleaseEvaluateConditionId"`
|
||||
}
|
||||
|
||||
type gimmickScheduleEntry struct {
|
||||
ScheduleId int32
|
||||
StartDatetime int64
|
||||
@@ -30,7 +22,7 @@ type GimmickCatalog struct {
|
||||
}
|
||||
|
||||
func LoadGimmickCatalog(resolver *ConditionResolver) (*GimmickCatalog, error) {
|
||||
rows, err := utils.ReadJSON[gimmickScheduleRow]("EntityMGimmickSequenceScheduleTable.json")
|
||||
rows, err := utils.ReadTable[EntityMGimmickSequenceSchedule]("m_gimmick_sequence_schedule")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load gimmick sequence schedule table: %w", err)
|
||||
}
|
||||
|
||||
@@ -5,15 +5,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type loginBonusStamp struct {
|
||||
LoginBonusId int32 `json:"LoginBonusId"`
|
||||
LowerPageNumber int32 `json:"LowerPageNumber"`
|
||||
StampNumber int32 `json:"StampNumber"`
|
||||
RewardPossessionType int32 `json:"RewardPossessionType"`
|
||||
RewardPossessionId int32 `json:"RewardPossessionId"`
|
||||
RewardCount int32 `json:"RewardCount"`
|
||||
}
|
||||
|
||||
type loginBonusStampKey struct {
|
||||
LoginBonusId int32
|
||||
LowerPageNumber int32
|
||||
@@ -36,7 +27,7 @@ func (c *LoginBonusCatalog) LookupStampReward(loginBonusId, pageNumber, stampNum
|
||||
}
|
||||
|
||||
func LoadLoginBonusCatalog() *LoginBonusCatalog {
|
||||
stamps, err := utils.ReadJSON[loginBonusStamp]("EntityMLoginBonusStampTable.json")
|
||||
stamps, err := utils.ReadTable[EntityMLoginBonusStamp]("m_login_bonus_stamp")
|
||||
if err != nil {
|
||||
log.Fatalf("load login bonus stamp table: %v", err)
|
||||
}
|
||||
|
||||
@@ -7,29 +7,15 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type MaterialRow struct {
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
MaterialType model.MaterialType `json:"MaterialType"`
|
||||
WeaponType int32 `json:"WeaponType"`
|
||||
EffectValue int32 `json:"EffectValue"`
|
||||
SellPrice int32 `json:"SellPrice"`
|
||||
}
|
||||
|
||||
type numericalParameterMapRow struct {
|
||||
NumericalParameterMapId int32 `json:"NumericalParameterMapId"`
|
||||
ParameterKey int32 `json:"ParameterKey"`
|
||||
ParameterValue int32 `json:"ParameterValue"`
|
||||
}
|
||||
|
||||
func LoadParameterMap() ([]numericalParameterMapRow, error) {
|
||||
rows, err := utils.ReadJSON[numericalParameterMapRow]("EntityMNumericalParameterMapTable.json")
|
||||
func LoadParameterMap() ([]EntityMNumericalParameterMap, error) {
|
||||
rows, err := utils.ReadTable[EntityMNumericalParameterMap]("m_numerical_parameter_map")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load numerical parameter map table: %w", err)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func BuildExpThresholds(paramMapRows []numericalParameterMapRow, mapId int32) []int32 {
|
||||
func BuildExpThresholds(paramMapRows []EntityMNumericalParameterMap, mapId int32) []int32 {
|
||||
maxKey := int32(0)
|
||||
for _, r := range paramMapRows {
|
||||
if r.NumericalParameterMapId == mapId && r.ParameterKey > maxKey {
|
||||
@@ -46,26 +32,27 @@ func BuildExpThresholds(paramMapRows []numericalParameterMapRow, mapId int32) []
|
||||
}
|
||||
|
||||
type MaterialCatalog struct {
|
||||
All map[int32]MaterialRow
|
||||
ByType map[model.MaterialType]map[int32]MaterialRow
|
||||
All map[int32]EntityMMaterial
|
||||
ByType map[model.MaterialType]map[int32]EntityMMaterial
|
||||
}
|
||||
|
||||
func LoadMaterialCatalog() (*MaterialCatalog, error) {
|
||||
rows, err := utils.ReadJSON[MaterialRow]("EntityMMaterialTable.json")
|
||||
rows, err := utils.ReadTable[EntityMMaterial]("m_material")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load material table: %w", err)
|
||||
}
|
||||
|
||||
catalog := &MaterialCatalog{
|
||||
All: make(map[int32]MaterialRow, len(rows)),
|
||||
ByType: make(map[model.MaterialType]map[int32]MaterialRow),
|
||||
All: make(map[int32]EntityMMaterial, len(rows)),
|
||||
ByType: make(map[model.MaterialType]map[int32]EntityMMaterial),
|
||||
}
|
||||
for _, row := range rows {
|
||||
catalog.All[row.MaterialId] = row
|
||||
if catalog.ByType[row.MaterialType] == nil {
|
||||
catalog.ByType[row.MaterialType] = make(map[int32]MaterialRow)
|
||||
mt := model.MaterialType(row.MaterialType)
|
||||
if catalog.ByType[mt] == nil {
|
||||
catalog.ByType[mt] = make(map[int32]EntityMMaterial)
|
||||
}
|
||||
catalog.ByType[row.MaterialType][row.MaterialId] = row
|
||||
catalog.ByType[mt][row.MaterialId] = row
|
||||
}
|
||||
return catalog, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
package memorydb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/pierrec/lz4/v4"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
var tables map[string][]byte
|
||||
|
||||
const (
|
||||
aesKeyHex = "36436230313332314545356536624265"
|
||||
aesIVHex = "45666341656634434165356536446141"
|
||||
lz4ExtCode = int8(99)
|
||||
)
|
||||
|
||||
func Init(binPath string) error {
|
||||
encrypted, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read bin.e: %w", err)
|
||||
}
|
||||
|
||||
decrypted, err := decrypt(encrypted)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decrypt: %w", err)
|
||||
}
|
||||
|
||||
toc, dataBlob, err := parseHeader(decrypted)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse header: %w", err)
|
||||
}
|
||||
|
||||
tables = make(map[string][]byte, len(toc))
|
||||
for name, offLen := range toc {
|
||||
off := offLen[0]
|
||||
length := offLen[1]
|
||||
if off+length > len(dataBlob) {
|
||||
return fmt.Errorf("table %q: offset %d + length %d exceeds data blob size %d", name, off, length, len(dataBlob))
|
||||
}
|
||||
tables[name] = dataBlob[off : off+length]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TableCount() int {
|
||||
return len(tables)
|
||||
}
|
||||
|
||||
func TableBytes(key string) ([]byte, bool) {
|
||||
b, ok := tables[key]
|
||||
return b, ok
|
||||
}
|
||||
|
||||
func ReadTable[T any](key string) ([]T, error) {
|
||||
raw, ok := TableBytes(key)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("table %q not found in master data", key)
|
||||
}
|
||||
return decompressAndUnmarshal[T](raw)
|
||||
}
|
||||
|
||||
func decrypt(data []byte) ([]byte, error) {
|
||||
key, err := hex.DecodeString(aesKeyHex)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode key: %w", err)
|
||||
}
|
||||
iv, err := hex.DecodeString(aesIVHex)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode iv: %w", err)
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new cipher: %w", err)
|
||||
}
|
||||
|
||||
if len(data)%aes.BlockSize != 0 {
|
||||
return nil, fmt.Errorf("ciphertext length %d is not a multiple of block size %d", len(data), aes.BlockSize)
|
||||
}
|
||||
|
||||
decrypted := make([]byte, len(data))
|
||||
cbc := cipher.NewCBCDecrypter(block, iv)
|
||||
cbc.CryptBlocks(decrypted, data)
|
||||
|
||||
decrypted, err = pkcs7Unpad(decrypted, aes.BlockSize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unpad: %w", err)
|
||||
}
|
||||
return decrypted, nil
|
||||
}
|
||||
|
||||
func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
|
||||
if len(data) == 0 {
|
||||
return nil, fmt.Errorf("empty data")
|
||||
}
|
||||
padLen := int(data[len(data)-1])
|
||||
if padLen == 0 || padLen > blockSize || padLen > len(data) {
|
||||
return nil, fmt.Errorf("invalid padding length %d", padLen)
|
||||
}
|
||||
for _, b := range data[len(data)-padLen:] {
|
||||
if int(b) != padLen {
|
||||
return nil, fmt.Errorf("invalid padding byte")
|
||||
}
|
||||
}
|
||||
return data[:len(data)-padLen], nil
|
||||
}
|
||||
|
||||
func parseHeader(data []byte) (map[string][2]int, []byte, error) {
|
||||
// Decode the header (first msgpack object) using Decode into interface{},
|
||||
// then compute how many bytes it consumed to find the data blob start.
|
||||
r := bytes.NewReader(data)
|
||||
dec := msgpack.NewDecoder(r)
|
||||
dec.UseLooseInterfaceDecoding(true)
|
||||
|
||||
var headerRaw interface{}
|
||||
if err := dec.Decode(&headerRaw); err != nil {
|
||||
return nil, nil, fmt.Errorf("decode header: %w", err)
|
||||
}
|
||||
|
||||
headerMap, ok := headerRaw.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("header is not a map, got %T", headerRaw)
|
||||
}
|
||||
|
||||
toc := make(map[string][2]int, len(headerMap))
|
||||
for name, val := range headerMap {
|
||||
arr, ok := val.([]interface{})
|
||||
if !ok || len(arr) != 2 {
|
||||
return nil, nil, fmt.Errorf("table %q: expected [offset, length] array, got %T", name, val)
|
||||
}
|
||||
offset, err := toInt(arr[0])
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("table %q offset: %w", name, err)
|
||||
}
|
||||
length, err := toInt(arr[1])
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("table %q length: %w", name, err)
|
||||
}
|
||||
toc[name] = [2]int{offset, length}
|
||||
}
|
||||
|
||||
consumed := int(int64(len(data)) - int64(r.Len()))
|
||||
return toc, data[consumed:], nil
|
||||
}
|
||||
|
||||
func toInt(v interface{}) (int, error) {
|
||||
switch n := v.(type) {
|
||||
case int8:
|
||||
return int(n), nil
|
||||
case int16:
|
||||
return int(n), nil
|
||||
case int32:
|
||||
return int(n), nil
|
||||
case int64:
|
||||
return int(n), nil
|
||||
case uint8:
|
||||
return int(n), nil
|
||||
case uint16:
|
||||
return int(n), nil
|
||||
case uint32:
|
||||
return int(n), nil
|
||||
case uint64:
|
||||
return int(n), nil
|
||||
default:
|
||||
return 0, fmt.Errorf("cannot convert %T to int", v)
|
||||
}
|
||||
}
|
||||
|
||||
func decompressAndUnmarshal[T any](raw []byte) ([]T, error) {
|
||||
// Peek at the raw msgpack to check if it's an ext type (LZ4 compressed)
|
||||
// or a plain array.
|
||||
if len(raw) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Try to decode as ext type first
|
||||
dec := msgpack.NewDecoder(bytes.NewReader(raw))
|
||||
code, extData, err := decodeExt(dec)
|
||||
if err == nil && code == lz4ExtCode {
|
||||
uncompressedSize, lz4Data, err := readLZ4ExtHeader(extData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read lz4 ext header: %w", err)
|
||||
}
|
||||
|
||||
decompressed := make([]byte, uncompressedSize)
|
||||
n, err := lz4.UncompressBlock(lz4Data, decompressed)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lz4 decompress: %w", err)
|
||||
}
|
||||
decompressed = decompressed[:n]
|
||||
|
||||
var result []T
|
||||
if err := msgpack.Unmarshal(decompressed, &result); err != nil {
|
||||
return nil, fmt.Errorf("unmarshal decompressed table: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Not LZ4 compressed, try as plain array
|
||||
var result []T
|
||||
if err := msgpack.Unmarshal(raw, &result); err != nil {
|
||||
return nil, fmt.Errorf("unmarshal plain table: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func decodeExt(dec *msgpack.Decoder) (int8, []byte, error) {
|
||||
var ext msgpack.RawMessage
|
||||
if err := dec.Decode(&ext); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
// ext is the full msgpack ext bytes including the header.
|
||||
// Re-decode just the header to get the type code, then the body is the rest.
|
||||
innerDec := msgpack.NewDecoder(bytes.NewReader(ext))
|
||||
extID, extLen, err := innerDec.DecodeExtHeader()
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
extData := make([]byte, extLen)
|
||||
if _, err := innerDec.Buffered().Read(extData); err != nil {
|
||||
return 0, nil, fmt.Errorf("read ext data: %w", err)
|
||||
}
|
||||
return extID, extData, nil
|
||||
}
|
||||
|
||||
func readLZ4ExtHeader(data []byte) (int, []byte, error) {
|
||||
if len(data) == 0 {
|
||||
return 0, nil, fmt.Errorf("empty ext data")
|
||||
}
|
||||
tag := data[0]
|
||||
switch {
|
||||
case tag == 0xd2: // big-endian int32
|
||||
if len(data) < 5 {
|
||||
return 0, nil, fmt.Errorf("not enough data for int32 size")
|
||||
}
|
||||
size := int(int32(binary.BigEndian.Uint32(data[1:5])))
|
||||
return size, data[5:], nil
|
||||
case tag == 0xce: // big-endian uint32
|
||||
if len(data) < 5 {
|
||||
return 0, nil, fmt.Errorf("not enough data for uint32 size")
|
||||
}
|
||||
size := int(binary.BigEndian.Uint32(data[1:5]))
|
||||
return size, data[5:], nil
|
||||
case tag <= 0x7f: // positive fixint
|
||||
return int(tag), data[1:], nil
|
||||
default:
|
||||
return 0, nil, fmt.Errorf("unexpected tag 0x%02x in LZ4 ext header", tag)
|
||||
}
|
||||
}
|
||||
@@ -8,18 +8,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type numericalFunctionRow struct {
|
||||
NumericalFunctionId int32 `json:"NumericalFunctionId"`
|
||||
NumericalFunctionType int32 `json:"NumericalFunctionType"`
|
||||
NumericalFunctionParameterGroupId int32 `json:"NumericalFunctionParameterGroupId"`
|
||||
}
|
||||
|
||||
type numericalFunctionParameterRow struct {
|
||||
NumericalFunctionParameterGroupId int32 `json:"NumericalFunctionParameterGroupId"`
|
||||
ParameterIndex int32 `json:"ParameterIndex"`
|
||||
ParameterValue int32 `json:"ParameterValue"`
|
||||
}
|
||||
|
||||
type NumericalFunc struct {
|
||||
Type model.NumericalFunctionType
|
||||
Params []int32
|
||||
@@ -61,17 +49,17 @@ type FunctionResolver struct {
|
||||
}
|
||||
|
||||
func LoadFunctionResolver() (*FunctionResolver, error) {
|
||||
funcRows, err := utils.ReadJSON[numericalFunctionRow]("EntityMNumericalFunctionTable.json")
|
||||
funcRows, err := utils.ReadTable[EntityMNumericalFunction]("m_numerical_function")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load numerical function table: %w", err)
|
||||
}
|
||||
|
||||
paramRows, err := utils.ReadJSON[numericalFunctionParameterRow]("EntityMNumericalFunctionParameterGroupTable.json")
|
||||
paramRows, err := utils.ReadTable[EntityMNumericalFunctionParameterGroup]("m_numerical_function_parameter_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load numerical function parameter group table: %w", err)
|
||||
}
|
||||
|
||||
paramsByGroup := make(map[int32][]numericalFunctionParameterRow, len(paramRows))
|
||||
paramsByGroup := make(map[int32][]EntityMNumericalFunctionParameterGroup, len(paramRows))
|
||||
for _, r := range paramRows {
|
||||
paramsByGroup[r.NumericalFunctionParameterGroupId] = append(
|
||||
paramsByGroup[r.NumericalFunctionParameterGroupId], r)
|
||||
|
||||
@@ -5,11 +5,6 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type omikujiEntry struct {
|
||||
OmikujiId int32 `json:"OmikujiId"`
|
||||
OmikujiAssetId int32 `json:"OmikujiAssetId"`
|
||||
}
|
||||
|
||||
type OmikujiCatalog struct {
|
||||
assetIds map[int32]int32
|
||||
}
|
||||
@@ -22,7 +17,7 @@ func (c *OmikujiCatalog) LookupAssetId(omikujiId int32) int32 {
|
||||
}
|
||||
|
||||
func LoadOmikujiCatalog() *OmikujiCatalog {
|
||||
entries, err := utils.ReadJSON[omikujiEntry]("EntityMOmikujiTable.json")
|
||||
entries, err := utils.ReadTable[EntityMOmikuji]("m_omikuji")
|
||||
if err != nil {
|
||||
log.Fatalf("load omikuji table: %v", err)
|
||||
}
|
||||
|
||||
@@ -7,63 +7,37 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type PartsRow struct {
|
||||
PartsId int32 `json:"PartsId"`
|
||||
RarityType model.RarityType `json:"RarityType"`
|
||||
PartsGroupId int32 `json:"PartsGroupId"`
|
||||
PartsStatusMainLotteryGroupId int32 `json:"PartsStatusMainLotteryGroupId"`
|
||||
}
|
||||
|
||||
type PartsRarityRow struct {
|
||||
RarityType model.RarityType `json:"RarityType"`
|
||||
PartsLevelUpRateGroupId int32 `json:"PartsLevelUpRateGroupId"`
|
||||
PartsLevelUpPriceGroupId int32 `json:"PartsLevelUpPriceGroupId"`
|
||||
SellPriceNumericalFunctionId int32 `json:"SellPriceNumericalFunctionId"`
|
||||
}
|
||||
|
||||
type partsLevelUpRateRow struct {
|
||||
PartsLevelUpRateGroupId int32 `json:"PartsLevelUpRateGroupId"`
|
||||
LevelLowerLimit int32 `json:"LevelLowerLimit"`
|
||||
SuccessRatePermil int32 `json:"SuccessRatePermil"`
|
||||
}
|
||||
|
||||
type partsLevelUpPriceRow struct {
|
||||
PartsLevelUpPriceGroupId int32 `json:"PartsLevelUpPriceGroupId"`
|
||||
LevelLowerLimit int32 `json:"LevelLowerLimit"`
|
||||
Gold int32 `json:"Gold"`
|
||||
}
|
||||
|
||||
type PartsCatalog struct {
|
||||
PartsById map[int32]PartsRow
|
||||
PartsById map[int32]EntityMParts
|
||||
DefaultPartsStatusMainByLotteryGroup map[int32]int32
|
||||
RarityByRarityType map[model.RarityType]PartsRarityRow
|
||||
RarityByRarityType map[model.RarityType]EntityMPartsRarity
|
||||
RateByGroupAndLevel map[int32]map[int32]int32
|
||||
PriceByGroupAndLevel map[int32]map[int32]int32
|
||||
SellPriceByRarity map[model.RarityType]NumericalFunc
|
||||
}
|
||||
|
||||
func LoadPartsCatalog() (*PartsCatalog, error) {
|
||||
partsRows, err := utils.ReadJSON[PartsRow]("EntityMPartsTable.json")
|
||||
partsRows, err := utils.ReadTable[EntityMParts]("m_parts")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load parts table: %w", err)
|
||||
}
|
||||
|
||||
rarityRows, err := utils.ReadJSON[PartsRarityRow]("EntityMPartsRarityTable.json")
|
||||
rarityRows, err := utils.ReadTable[EntityMPartsRarity]("m_parts_rarity")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load parts rarity table: %w", err)
|
||||
}
|
||||
|
||||
rateRows, err := utils.ReadJSON[partsLevelUpRateRow]("EntityMPartsLevelUpRateGroupTable.json")
|
||||
rateRows, err := utils.ReadTable[EntityMPartsLevelUpRateGroup]("m_parts_level_up_rate_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load parts level up rate table: %w", err)
|
||||
}
|
||||
|
||||
priceRows, err := utils.ReadJSON[partsLevelUpPriceRow]("EntityMPartsLevelUpPriceGroupTable.json")
|
||||
priceRows, err := utils.ReadTable[EntityMPartsLevelUpPriceGroup]("m_parts_level_up_price_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load parts level up price table: %w", err)
|
||||
}
|
||||
|
||||
partsById := make(map[int32]PartsRow, len(partsRows))
|
||||
partsById := make(map[int32]EntityMParts, len(partsRows))
|
||||
for _, p := range partsRows {
|
||||
partsById[p.PartsId] = p
|
||||
}
|
||||
@@ -84,7 +58,7 @@ func LoadPartsCatalog() (*PartsCatalog, error) {
|
||||
return nil, fmt.Errorf("load function resolver: %w", err)
|
||||
}
|
||||
|
||||
rarityByRarityType := make(map[model.RarityType]PartsRarityRow, len(rarityRows))
|
||||
rarityByRarityType := make(map[model.RarityType]EntityMPartsRarity, len(rarityRows))
|
||||
sellPriceByRarity := make(map[model.RarityType]NumericalFunc, len(rarityRows))
|
||||
for _, r := range rarityRows {
|
||||
rarityByRarityType[r.RarityType] = r
|
||||
|
||||
@@ -4,214 +4,34 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"lunar-tear/server/internal/model"
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type QuestSceneRow struct {
|
||||
QuestSceneId int32 `json:"QuestSceneId"`
|
||||
QuestId int32 `json:"QuestId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
QuestSceneType model.QuestSceneType `json:"QuestSceneType"`
|
||||
AssetBackgroundId int32 `json:"AssetBackgroundId"`
|
||||
EventMapNumberUpper int32 `json:"EventMapNumberUpper"`
|
||||
EventMapNumberLower int32 `json:"EventMapNumberLower"`
|
||||
IsMainFlowQuestTarget bool `json:"IsMainFlowQuestTarget"`
|
||||
IsBattleOnlyTarget bool `json:"IsBattleOnlyTarget"`
|
||||
QuestResultType model.QuestResultType `json:"QuestResultType"`
|
||||
IsStorySkipTarget bool `json:"IsStorySkipTarget"`
|
||||
}
|
||||
|
||||
type QuestRow struct {
|
||||
QuestId int32 `json:"QuestId"`
|
||||
NameQuestTextId int32 `json:"NameQuestTextId"`
|
||||
PictureBookNameQuestTextId int32 `json:"PictureBookNameQuestTextId"`
|
||||
QuestReleaseConditionListId int32 `json:"QuestReleaseConditionListId"`
|
||||
StoryQuestTextId int32 `json:"StoryQuestTextId"`
|
||||
QuestDisplayAttributeGroupId int32 `json:"QuestDisplayAttributeGroupId"`
|
||||
RecommendedDeckPower int32 `json:"RecommendedDeckPower"`
|
||||
QuestFirstClearRewardGroupId int32 `json:"QuestFirstClearRewardGroupId"`
|
||||
QuestPickupRewardGroupId int32 `json:"QuestPickupRewardGroupId"`
|
||||
QuestDeckRestrictionGroupId int32 `json:"QuestDeckRestrictionGroupId"`
|
||||
QuestMissionGroupId int32 `json:"QuestMissionGroupId"`
|
||||
Stamina int32 `json:"Stamina"`
|
||||
UserExp int32 `json:"UserExp"`
|
||||
CharacterExp int32 `json:"CharacterExp"`
|
||||
CostumeExp int32 `json:"CostumeExp"`
|
||||
Gold int32 `json:"Gold"`
|
||||
DailyClearableCount int32 `json:"DailyClearableCount"`
|
||||
IsRunInTheBackground bool `json:"IsRunInTheBackground"`
|
||||
IsCountedAsQuest bool `json:"IsCountedAsQuest"`
|
||||
QuestBonusId int32 `json:"QuestBonusId"`
|
||||
IsNotShowAfterClear bool `json:"IsNotShowAfterClear"`
|
||||
IsBigWinTarget bool `json:"IsBigWinTarget"`
|
||||
IsUsableSkipTicket bool `json:"IsUsableSkipTicket"`
|
||||
QuestReplayFlowRewardGroupId int32 `json:"QuestReplayFlowRewardGroupId"`
|
||||
InvisibleQuestMissionGroupId int32 `json:"InvisibleQuestMissionGroupId"`
|
||||
FieldEffectGroupId int32 `json:"FieldEffectGroupId"`
|
||||
}
|
||||
|
||||
type QuestMissionRow struct {
|
||||
QuestMissionId int32 `json:"QuestMissionId"`
|
||||
QuestMissionConditionType model.QuestMissionConditionType `json:"QuestMissionConditionType"`
|
||||
QuestMissionRewardId int32 `json:"QuestMissionRewardId"`
|
||||
QuestMissionConditionValueGroupId int32 `json:"QuestMissionConditionValueGroupId"`
|
||||
}
|
||||
|
||||
type QuestMissionGroupRow struct {
|
||||
QuestMissionGroupId int32 `json:"QuestMissionGroupId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
QuestMissionId int32 `json:"QuestMissionId"`
|
||||
}
|
||||
|
||||
type QuestMissionRewardRow struct {
|
||||
QuestMissionRewardId int32 `json:"QuestMissionRewardId"`
|
||||
PossessionType model.PossessionType `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type MainQuestSequenceRow struct {
|
||||
MainQuestSequenceId int32 `json:"MainQuestSequenceId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
QuestId int32 `json:"QuestId"`
|
||||
}
|
||||
|
||||
type MainQuestRouteRow struct {
|
||||
MainQuestRouteId int32 `json:"MainQuestRouteId"`
|
||||
MainQuestSeasonId int32 `json:"MainQuestSeasonId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
CharacterId int32 `json:"CharacterId"`
|
||||
}
|
||||
|
||||
type MainQuestChapterRow struct {
|
||||
MainQuestChapterId int32 `json:"MainQuestChapterId"`
|
||||
MainQuestRouteId int32 `json:"MainQuestRouteId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
MainQuestSequenceGroupId int32 `json:"MainQuestSequenceGroupId"`
|
||||
PortalCageCharacterGroupId int32 `json:"PortalCageCharacterGroupId"`
|
||||
StartDatetime int64 `json:"StartDatetime"`
|
||||
IsInvisibleInLibrary bool `json:"IsInvisibleInLibrary"`
|
||||
JoinLibraryChapterId int32 `json:"JoinLibraryChapterId"`
|
||||
}
|
||||
|
||||
type QuestFirstClearRewardSwitchRow struct {
|
||||
QuestId int32 `json:"QuestId"`
|
||||
QuestFirstClearRewardGroupId int32 `json:"QuestFirstClearRewardGroupId"`
|
||||
SwitchConditionClearQuestId int32 `json:"SwitchConditionClearQuestId"`
|
||||
}
|
||||
|
||||
type QuestFirstClearRewardGroupRow struct {
|
||||
QuestFirstClearRewardGroupId int32 `json:"QuestFirstClearRewardGroupId"`
|
||||
QuestFirstClearRewardType int32 `json:"QuestFirstClearRewardType"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
PossessionType model.PossessionType `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
IsPickup bool `json:"IsPickup"`
|
||||
}
|
||||
|
||||
type QuestReplayFlowRewardGroupRow struct {
|
||||
QuestReplayFlowRewardGroupId int32 `json:"QuestReplayFlowRewardGroupId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
PossessionType model.PossessionType `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type QuestSceneGrantRow struct {
|
||||
QuestSceneId int32 `json:"QuestSceneId"`
|
||||
PossessionType model.PossessionType `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type QuestPickupRewardGroupRow struct {
|
||||
QuestPickupRewardGroupId int32 `json:"QuestPickupRewardGroupId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
BattleDropRewardId int32 `json:"BattleDropRewardId"`
|
||||
}
|
||||
|
||||
type BattleDropRewardRow struct {
|
||||
BattleDropRewardId int32 `json:"BattleDropRewardId"`
|
||||
PossessionType model.PossessionType `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type QuestSceneBattleRow struct {
|
||||
QuestSceneId int32 `json:"QuestSceneId"`
|
||||
BattleGroupId int32 `json:"BattleGroupId"`
|
||||
}
|
||||
|
||||
type BattleGroupRow struct {
|
||||
BattleGroupId int32 `json:"BattleGroupId"`
|
||||
WaveNumber int32 `json:"WaveNumber"`
|
||||
BattleId int32 `json:"BattleId"`
|
||||
}
|
||||
|
||||
type BattleRow struct {
|
||||
BattleId int32 `json:"BattleId"`
|
||||
BattleNpcId int32 `json:"BattleNpcId"`
|
||||
DeckType model.DeckType `json:"DeckType"`
|
||||
BattleNpcDeckNumber int32 `json:"BattleNpcDeckNumber"`
|
||||
}
|
||||
|
||||
type BattleNpcDeckRow struct {
|
||||
BattleNpcId int32 `json:"BattleNpcId"`
|
||||
DeckType model.DeckType `json:"DeckType"`
|
||||
BattleNpcDeckNumber int32 `json:"BattleNpcDeckNumber"`
|
||||
BattleNpcDeckCharacterUuid01 string `json:"BattleNpcDeckCharacterUuid01"`
|
||||
BattleNpcDeckCharacterUuid02 string `json:"BattleNpcDeckCharacterUuid02"`
|
||||
BattleNpcDeckCharacterUuid03 string `json:"BattleNpcDeckCharacterUuid03"`
|
||||
}
|
||||
|
||||
type BattleNpcDropCategoryRow struct {
|
||||
BattleNpcId int32 `json:"BattleNpcId"`
|
||||
BattleNpcDeckCharacterUuid string `json:"BattleNpcDeckCharacterUuid"`
|
||||
BattleDropCategoryId int32 `json:"BattleDropCategoryId"`
|
||||
}
|
||||
|
||||
type BattleDropInfo struct {
|
||||
QuestSceneId int32
|
||||
BattleDropCategoryId int32
|
||||
}
|
||||
|
||||
type TutorialUnlockConditionRow struct {
|
||||
TutorialType int32 `json:"TutorialType"`
|
||||
TutorialUnlockConditionType int32 `json:"TutorialUnlockConditionType"`
|
||||
ConditionValue int32 `json:"ConditionValue"`
|
||||
}
|
||||
|
||||
type RentalDeckRow struct {
|
||||
BattleGroupId int32 `json:"BattleGroupId"`
|
||||
}
|
||||
|
||||
type UserLevelRow struct {
|
||||
UserLevel int32 `json:"UserLevel"`
|
||||
MaxStamina int32 `json:"MaxStamina"`
|
||||
}
|
||||
|
||||
type QuestCatalog struct {
|
||||
SceneById map[int32]QuestSceneRow
|
||||
MissionById map[int32]QuestMissionRow
|
||||
QuestById map[int32]QuestRow
|
||||
SceneById map[int32]EntityMQuestScene
|
||||
MissionById map[int32]EntityMQuestMission
|
||||
QuestById map[int32]EntityMQuest
|
||||
MissionIdsByQuestId map[int32][]int32
|
||||
RouteIdByQuestId map[int32]int32
|
||||
SceneIdsByQuestId map[int32][]int32
|
||||
OrderedQuestIds []int32
|
||||
FirstClearRewardsByGroupId map[int32][]QuestFirstClearRewardGroupRow
|
||||
FirstClearRewardSwitchesByQuestId map[int32][]QuestFirstClearRewardSwitchRow
|
||||
MissionRewardsByMissionId map[int32][]QuestMissionRewardRow
|
||||
FirstClearRewardsByGroupId map[int32][]EntityMQuestFirstClearRewardGroup
|
||||
FirstClearRewardSwitchesByQuestId map[int32][]EntityMQuestFirstClearRewardSwitch
|
||||
MissionRewardsByMissionId map[int32][]EntityMQuestMissionReward
|
||||
WeaponIdsByReleaseConditionGroupId map[int32][]int32
|
||||
ReleaseConditionsByGroupId map[int32][]WeaponStoryReleaseConditionRow
|
||||
SceneGrantsBySceneId map[int32][]QuestSceneGrantRow
|
||||
BattleDropRewardById map[int32]BattleDropRewardRow
|
||||
ReleaseConditionsByGroupId map[int32][]EntityMWeaponStoryReleaseConditionGroup
|
||||
SceneGrantsBySceneId map[int32][]EntityMUserQuestSceneGrantPossession
|
||||
BattleDropRewardById map[int32]EntityMBattleDropReward
|
||||
PickupRewardIdsByGroupId map[int32][]int32
|
||||
BattleDropsByQuestId map[int32][]BattleDropInfo
|
||||
ReplayFlowRewardsByGroupId map[int32][]QuestReplayFlowRewardGroupRow
|
||||
ReplayFlowRewardsByGroupId map[int32][]EntityMQuestReplayFlowRewardGroup
|
||||
RentalQuestIds map[int32]bool
|
||||
TutorialUnlockConditions []TutorialUnlockConditionRow
|
||||
TutorialUnlockConditions []EntityMTutorialUnlockCondition
|
||||
ChapterLastSceneByQuestId map[int32]int32
|
||||
SeasonIdByRouteId map[int32]int32
|
||||
|
||||
@@ -221,8 +41,8 @@ type QuestCatalog struct {
|
||||
CostumeMaxLevelByRarity map[int32]NumericalFunc
|
||||
MaxStaminaByLevel map[int32]int32
|
||||
|
||||
CostumeById map[int32]CostumeMasterRow
|
||||
WeaponById map[int32]WeaponMasterRow
|
||||
CostumeById map[int32]EntityMCostume
|
||||
WeaponById map[int32]EntityMWeapon
|
||||
|
||||
WeaponSkillSlots map[int32][]int32
|
||||
WeaponAbilitySlots map[int32][]int32
|
||||
@@ -231,7 +51,7 @@ type QuestCatalog struct {
|
||||
}
|
||||
|
||||
func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
scenes, err := utils.ReadJSON[QuestSceneRow]("EntityMQuestSceneTable.json")
|
||||
scenes, err := utils.ReadTable[EntityMQuestScene]("m_quest_scene")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest scene table: %w", err)
|
||||
}
|
||||
@@ -245,17 +65,17 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
return scenes[i].QuestSceneId < scenes[j].QuestSceneId
|
||||
})
|
||||
|
||||
missions, err := utils.ReadJSON[QuestMissionRow]("EntityMQuestMissionTable.json")
|
||||
missions, err := utils.ReadTable[EntityMQuestMission]("m_quest_mission")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest mission table: %w", err)
|
||||
}
|
||||
|
||||
quests, err := utils.ReadJSON[QuestRow]("EntityMQuestTable.json")
|
||||
quests, err := utils.ReadTable[EntityMQuest]("m_quest")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest table: %w", err)
|
||||
}
|
||||
|
||||
missionGroups, err := utils.ReadJSON[QuestMissionGroupRow]("EntityMQuestMissionGroupTable.json")
|
||||
missionGroups, err := utils.ReadTable[EntityMQuestMissionGroup]("m_quest_mission_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest mission group table: %w", err)
|
||||
}
|
||||
@@ -269,7 +89,7 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
return missionGroups[i].QuestMissionId < missionGroups[j].QuestMissionId
|
||||
})
|
||||
|
||||
sequences, err := utils.ReadJSON[MainQuestSequenceRow]("EntityMMainQuestSequenceTable.json")
|
||||
sequences, err := utils.ReadTable[EntityMMainQuestSequence]("m_main_quest_sequence")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load main quest sequence table: %w", err)
|
||||
}
|
||||
@@ -283,12 +103,12 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
return sequences[i].QuestId < sequences[j].QuestId
|
||||
})
|
||||
|
||||
chapters, err := utils.ReadJSON[MainQuestChapterRow]("EntityMMainQuestChapterTable.json")
|
||||
chapters, err := utils.ReadTable[EntityMMainQuestChapter]("m_main_quest_chapter")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load main quest chapter table: %w", err)
|
||||
}
|
||||
|
||||
routes, err := utils.ReadJSON[MainQuestRouteRow]("EntityMMainQuestRouteTable.json")
|
||||
routes, err := utils.ReadTable[EntityMMainQuestRoute]("m_main_quest_route")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load main quest route table: %w", err)
|
||||
}
|
||||
@@ -297,12 +117,12 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
seasonIdByRouteId[r.MainQuestRouteId] = r.MainQuestSeasonId
|
||||
}
|
||||
|
||||
firstClearSwitches, err := utils.ReadJSON[QuestFirstClearRewardSwitchRow]("EntityMQuestFirstClearRewardSwitchTable.json")
|
||||
firstClearSwitches, err := utils.ReadTable[EntityMQuestFirstClearRewardSwitch]("m_quest_first_clear_reward_switch")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest first clear reward switch table: %w", err)
|
||||
}
|
||||
|
||||
firstClearRewards, err := utils.ReadJSON[QuestFirstClearRewardGroupRow]("EntityMQuestFirstClearRewardGroupTable.json")
|
||||
firstClearRewards, err := utils.ReadTable[EntityMQuestFirstClearRewardGroup]("m_quest_first_clear_reward_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest first clear reward group table: %w", err)
|
||||
}
|
||||
@@ -316,7 +136,7 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
return firstClearRewards[i].QuestFirstClearRewardType < firstClearRewards[j].QuestFirstClearRewardType
|
||||
})
|
||||
|
||||
replayFlowRewards, err := utils.ReadJSON[QuestReplayFlowRewardGroupRow]("EntityMQuestReplayFlowRewardGroupTable.json")
|
||||
replayFlowRewards, err := utils.ReadTable[EntityMQuestReplayFlowRewardGroup]("m_quest_replay_flow_reward_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest replay flow reward group table: %w", err)
|
||||
}
|
||||
@@ -327,52 +147,52 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
return replayFlowRewards[i].SortOrder < replayFlowRewards[j].SortOrder
|
||||
})
|
||||
|
||||
missionRewards, err := utils.ReadJSON[QuestMissionRewardRow]("EntityMQuestMissionRewardTable.json")
|
||||
missionRewards, err := utils.ReadTable[EntityMQuestMissionReward]("m_quest_mission_reward")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest mission reward table: %w", err)
|
||||
}
|
||||
|
||||
weapons, err := utils.ReadJSON[WeaponMasterRow]("EntityMWeaponTable.json")
|
||||
weapons, err := utils.ReadTable[EntityMWeapon]("m_weapon")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon table: %w", err)
|
||||
}
|
||||
|
||||
weaponSkillGroups, err := utils.ReadJSON[WeaponSkillGroupRow]("EntityMWeaponSkillGroupTable.json")
|
||||
weaponSkillGroups, err := utils.ReadTable[EntityMWeaponSkillGroup]("m_weapon_skill_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon skill group table: %w", err)
|
||||
}
|
||||
|
||||
weaponAbilityGroups, err := utils.ReadJSON[WeaponAbilityGroupRow]("EntityMWeaponAbilityGroupTable.json")
|
||||
weaponAbilityGroups, err := utils.ReadTable[EntityMWeaponAbilityGroup]("m_weapon_ability_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon ability group table: %w", err)
|
||||
}
|
||||
|
||||
releaseConditions, err := utils.ReadJSON[WeaponStoryReleaseConditionRow]("EntityMWeaponStoryReleaseConditionGroupTable.json")
|
||||
releaseConditions, err := utils.ReadTable[EntityMWeaponStoryReleaseConditionGroup]("m_weapon_story_release_condition_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon story release condition table: %w", err)
|
||||
}
|
||||
|
||||
costumeMasters, err := utils.ReadJSON[CostumeMasterRow]("EntityMCostumeTable.json")
|
||||
costumeMasters, err := utils.ReadTable[EntityMCostume]("m_costume")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume table: %w", err)
|
||||
}
|
||||
|
||||
costumeRarities, err := utils.ReadJSON[costumeRarityRow]("EntityMCostumeRarityTable.json")
|
||||
costumeRarities, err := utils.ReadTable[EntityMCostumeRarity]("m_costume_rarity")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load costume rarity table: %w", err)
|
||||
}
|
||||
|
||||
sceneGrants, err := utils.ReadJSON[QuestSceneGrantRow]("EntityMUserQuestSceneGrantPossessionTable.json")
|
||||
sceneGrants, err := utils.ReadTable[EntityMUserQuestSceneGrantPossession]("m_user_quest_scene_grant_possession")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest scene grant table: %w", err)
|
||||
}
|
||||
|
||||
battleDropRewards, err := utils.ReadJSON[BattleDropRewardRow]("EntityMBattleDropRewardTable.json")
|
||||
battleDropRewards, err := utils.ReadTable[EntityMBattleDropReward]("m_battle_drop_reward")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load battle drop reward table: %w", err)
|
||||
}
|
||||
|
||||
pickupRewardGroups, err := utils.ReadJSON[QuestPickupRewardGroupRow]("EntityMQuestPickupRewardGroupTable.json")
|
||||
pickupRewardGroups, err := utils.ReadTable[EntityMQuestPickupRewardGroup]("m_quest_pickup_reward_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest pickup reward group table: %w", err)
|
||||
}
|
||||
@@ -383,37 +203,37 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
return pickupRewardGroups[i].SortOrder < pickupRewardGroups[j].SortOrder
|
||||
})
|
||||
|
||||
sceneBattles, err := utils.ReadJSON[QuestSceneBattleRow]("EntityMQuestSceneBattleTable.json")
|
||||
sceneBattles, err := utils.ReadTable[EntityMQuestSceneBattle]("m_quest_scene_battle")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load quest scene battle table: %w", err)
|
||||
}
|
||||
|
||||
battleGroups, err := utils.ReadJSON[BattleGroupRow]("EntityMBattleGroupTable.json")
|
||||
battleGroups, err := utils.ReadTable[EntityMBattleGroup]("m_battle_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load battle group table: %w", err)
|
||||
}
|
||||
|
||||
battles, err := utils.ReadJSON[BattleRow]("EntityMBattleTable.json")
|
||||
battles, err := utils.ReadTable[EntityMBattle]("m_battle")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load battle table: %w", err)
|
||||
}
|
||||
|
||||
npcDecks, err := utils.ReadJSON[BattleNpcDeckRow]("EntityMBattleNpcDeckTable.json")
|
||||
npcDecks, err := utils.ReadTable[EntityMBattleNpcDeck]("m_battle_npc_deck")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load battle npc deck table: %w", err)
|
||||
}
|
||||
|
||||
npcDropCategories, err := utils.ReadJSON[BattleNpcDropCategoryRow]("EntityMBattleNpcDeckCharacterDropCategoryTable.json")
|
||||
npcDropCategories, err := utils.ReadTable[EntityMBattleNpcDeckCharacterDropCategory]("m_battle_npc_deck_character_drop_category")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load battle npc drop category table: %w", err)
|
||||
}
|
||||
|
||||
rentalDecks, err := utils.ReadJSON[RentalDeckRow]("EntityMBattleRentalDeckTable.json")
|
||||
rentalDecks, err := utils.ReadTable[EntityMBattleRentalDeck]("m_battle_rental_deck")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load battle rental deck table: %w", err)
|
||||
}
|
||||
|
||||
tutorialUnlockConds, err := utils.ReadJSON[TutorialUnlockConditionRow]("EntityMTutorialUnlockConditionTable.json")
|
||||
tutorialUnlockConds, err := utils.ReadTable[EntityMTutorialUnlockCondition]("m_tutorial_unlock_condition")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load tutorial unlock condition table: %w", err)
|
||||
}
|
||||
@@ -423,7 +243,7 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userLevels, err := utils.ReadJSON[UserLevelRow]("EntityMUserLevelTable.json")
|
||||
userLevels, err := utils.ReadTable[EntityMUserLevel]("m_user_level")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load user level table: %w", err)
|
||||
}
|
||||
@@ -450,12 +270,12 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
}
|
||||
}
|
||||
|
||||
costumeById := make(map[int32]CostumeMasterRow, len(costumeMasters))
|
||||
costumeById := make(map[int32]EntityMCostume, len(costumeMasters))
|
||||
for _, cm := range costumeMasters {
|
||||
costumeById[cm.CostumeId] = cm
|
||||
}
|
||||
|
||||
weaponById := make(map[int32]WeaponMasterRow, len(weapons))
|
||||
weaponById := make(map[int32]EntityMWeapon, len(weapons))
|
||||
for _, w := range weapons {
|
||||
weaponById[w.WeaponId] = w
|
||||
}
|
||||
@@ -469,19 +289,19 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
abilitySlots[row.WeaponAbilityGroupId] = append(abilitySlots[row.WeaponAbilityGroupId], row.SlotNumber)
|
||||
}
|
||||
|
||||
sceneById := make(map[int32]QuestSceneRow, len(scenes))
|
||||
sceneById := make(map[int32]EntityMQuestScene, len(scenes))
|
||||
sceneIdsByQuestId := make(map[int32][]int32)
|
||||
for _, scene := range scenes {
|
||||
sceneById[scene.QuestSceneId] = scene
|
||||
sceneIdsByQuestId[scene.QuestId] = append(sceneIdsByQuestId[scene.QuestId], scene.QuestSceneId)
|
||||
}
|
||||
|
||||
missionById := make(map[int32]QuestMissionRow, len(missions))
|
||||
missionById := make(map[int32]EntityMQuestMission, len(missions))
|
||||
for _, mission := range missions {
|
||||
missionById[mission.QuestMissionId] = mission
|
||||
}
|
||||
|
||||
questById := make(map[int32]QuestRow, len(quests))
|
||||
questById := make(map[int32]EntityMQuest, len(quests))
|
||||
for _, quest := range quests {
|
||||
questById[quest.QuestId] = quest
|
||||
}
|
||||
@@ -500,7 +320,7 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
missionIdsByQuestId[questId] = append([]int32(nil), missionIds...)
|
||||
}
|
||||
|
||||
chapterBySequenceId := make(map[int32]MainQuestChapterRow, len(chapters))
|
||||
chapterBySequenceId := make(map[int32]EntityMMainQuestChapter, len(chapters))
|
||||
for _, chapter := range chapters {
|
||||
chapterBySequenceId[chapter.MainQuestSequenceGroupId] = chapter
|
||||
}
|
||||
@@ -511,12 +331,12 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
}
|
||||
}
|
||||
|
||||
sortedChapters := make([]MainQuestChapterRow, len(chapters))
|
||||
sortedChapters := make([]EntityMMainQuestChapter, len(chapters))
|
||||
copy(sortedChapters, chapters)
|
||||
sort.Slice(sortedChapters, func(i, j int) bool {
|
||||
return sortedChapters[i].SortOrder < sortedChapters[j].SortOrder
|
||||
})
|
||||
sequencesByGroupId := make(map[int32][]MainQuestSequenceRow)
|
||||
sequencesByGroupId := make(map[int32][]EntityMMainQuestSequence)
|
||||
for _, seq := range sequences {
|
||||
sequencesByGroupId[seq.MainQuestSequenceId] = append(sequencesByGroupId[seq.MainQuestSequenceId], seq)
|
||||
}
|
||||
@@ -544,25 +364,25 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
}
|
||||
}
|
||||
|
||||
firstClearRewardsByGroupId := make(map[int32][]QuestFirstClearRewardGroupRow, len(firstClearRewards))
|
||||
firstClearRewardsByGroupId := make(map[int32][]EntityMQuestFirstClearRewardGroup, len(firstClearRewards))
|
||||
for _, reward := range firstClearRewards {
|
||||
firstClearRewardsByGroupId[reward.QuestFirstClearRewardGroupId] = append(
|
||||
firstClearRewardsByGroupId[reward.QuestFirstClearRewardGroupId], reward)
|
||||
}
|
||||
|
||||
replayFlowRewardsByGroupId := make(map[int32][]QuestReplayFlowRewardGroupRow, len(replayFlowRewards))
|
||||
replayFlowRewardsByGroupId := make(map[int32][]EntityMQuestReplayFlowRewardGroup, len(replayFlowRewards))
|
||||
for _, reward := range replayFlowRewards {
|
||||
replayFlowRewardsByGroupId[reward.QuestReplayFlowRewardGroupId] = append(
|
||||
replayFlowRewardsByGroupId[reward.QuestReplayFlowRewardGroupId], reward)
|
||||
}
|
||||
|
||||
firstClearRewardSwitchesByQuestId := make(map[int32][]QuestFirstClearRewardSwitchRow, len(firstClearSwitches))
|
||||
firstClearRewardSwitchesByQuestId := make(map[int32][]EntityMQuestFirstClearRewardSwitch, len(firstClearSwitches))
|
||||
for _, switchRow := range firstClearSwitches {
|
||||
firstClearRewardSwitchesByQuestId[switchRow.QuestId] = append(
|
||||
firstClearRewardSwitchesByQuestId[switchRow.QuestId], switchRow)
|
||||
}
|
||||
|
||||
missionRewardsByMissionId := make(map[int32][]QuestMissionRewardRow, len(missionRewards))
|
||||
missionRewardsByMissionId := make(map[int32][]EntityMQuestMissionReward, len(missionRewards))
|
||||
for _, reward := range missionRewards {
|
||||
missionRewardsByMissionId[reward.QuestMissionRewardId] = append(
|
||||
missionRewardsByMissionId[reward.QuestMissionRewardId], reward)
|
||||
@@ -576,18 +396,18 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
}
|
||||
}
|
||||
|
||||
releaseConditionsByGroupId := make(map[int32][]WeaponStoryReleaseConditionRow)
|
||||
releaseConditionsByGroupId := make(map[int32][]EntityMWeaponStoryReleaseConditionGroup)
|
||||
for _, c := range releaseConditions {
|
||||
releaseConditionsByGroupId[c.WeaponStoryReleaseConditionGroupId] = append(
|
||||
releaseConditionsByGroupId[c.WeaponStoryReleaseConditionGroupId], c)
|
||||
}
|
||||
|
||||
sceneGrantsBySceneId := make(map[int32][]QuestSceneGrantRow)
|
||||
sceneGrantsBySceneId := make(map[int32][]EntityMUserQuestSceneGrantPossession)
|
||||
for _, sg := range sceneGrants {
|
||||
sceneGrantsBySceneId[sg.QuestSceneId] = append(sceneGrantsBySceneId[sg.QuestSceneId], sg)
|
||||
}
|
||||
|
||||
battleDropRewardById := make(map[int32]BattleDropRewardRow, len(battleDropRewards))
|
||||
battleDropRewardById := make(map[int32]EntityMBattleDropReward, len(battleDropRewards))
|
||||
for _, bdr := range battleDropRewards {
|
||||
battleDropRewardById[bdr.BattleDropRewardId] = bdr
|
||||
}
|
||||
@@ -609,22 +429,22 @@ func LoadQuestCatalog(partsCatalog *PartsCatalog) (*QuestCatalog, error) {
|
||||
}
|
||||
|
||||
type npcDeckKey struct {
|
||||
BattleNpcId int32
|
||||
DeckType model.DeckType
|
||||
BattleNpcId int64
|
||||
DeckType int32
|
||||
BattleNpcDeckNumber int32
|
||||
}
|
||||
npcDeckByKey := make(map[npcDeckKey]BattleNpcDeckRow, len(npcDecks))
|
||||
npcDeckByKey := make(map[npcDeckKey]EntityMBattleNpcDeck, len(npcDecks))
|
||||
for _, d := range npcDecks {
|
||||
npcDeckByKey[npcDeckKey{d.BattleNpcId, d.DeckType, d.BattleNpcDeckNumber}] = d
|
||||
}
|
||||
|
||||
battleByIdMap := make(map[int32]BattleRow, len(battles))
|
||||
battleByIdMap := make(map[int32]EntityMBattle, len(battles))
|
||||
for _, b := range battles {
|
||||
battleByIdMap[b.BattleId] = b
|
||||
}
|
||||
|
||||
type dropCatKey struct {
|
||||
BattleNpcId int32
|
||||
BattleNpcId int64
|
||||
Uuid string
|
||||
}
|
||||
dropCategoryByKey := make(map[dropCatKey]int32, len(npcDropCategories))
|
||||
|
||||
@@ -8,96 +8,47 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type ShopItemRow struct {
|
||||
ShopItemId int32 `json:"ShopItemId"`
|
||||
PriceType int32 `json:"PriceType"`
|
||||
PriceId int32 `json:"PriceId"`
|
||||
Price int32 `json:"Price"`
|
||||
ShopItemLimitedStockId int32 `json:"ShopItemLimitedStockId"`
|
||||
}
|
||||
|
||||
type ShopContentRow struct {
|
||||
ShopItemId int32 `json:"ShopItemId"`
|
||||
PossessionType int32 `json:"PossessionType"`
|
||||
PossessionId int32 `json:"PossessionId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type ShopContentEffectRow struct {
|
||||
ShopItemId int32 `json:"ShopItemId"`
|
||||
EffectTargetType int32 `json:"EffectTargetType"`
|
||||
EffectValueType int32 `json:"EffectValueType"`
|
||||
EffectValue int32 `json:"EffectValue"`
|
||||
}
|
||||
|
||||
type shopItemLimitedStockRow struct {
|
||||
ShopItemLimitedStockId int32 `json:"ShopItemLimitedStockId"`
|
||||
MaxCount int32 `json:"MaxCount"`
|
||||
}
|
||||
|
||||
type shopRow struct {
|
||||
ShopId int32 `json:"ShopId"`
|
||||
ShopGroupType int32 `json:"ShopGroupType"`
|
||||
ShopItemCellGroupId int32 `json:"ShopItemCellGroupId"`
|
||||
}
|
||||
|
||||
type shopItemCellGroupRow struct {
|
||||
ShopItemCellGroupId int32 `json:"ShopItemCellGroupId"`
|
||||
ShopItemCellId int32 `json:"ShopItemCellId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type shopItemCellRow struct {
|
||||
ShopItemCellId int32 `json:"ShopItemCellId"`
|
||||
ShopItemId int32 `json:"ShopItemId"`
|
||||
}
|
||||
|
||||
type ExchangeShopCell struct {
|
||||
SortOrder int32
|
||||
ShopItemId int32
|
||||
}
|
||||
|
||||
type ShopCatalog struct {
|
||||
Items map[int32]ShopItemRow
|
||||
Contents map[int32][]ShopContentRow
|
||||
Effects map[int32][]ShopContentEffectRow
|
||||
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
|
||||
}
|
||||
|
||||
type userLevelEntry struct {
|
||||
UserLevel int32 `json:"UserLevel"`
|
||||
MaxStamina int32 `json:"MaxStamina"`
|
||||
}
|
||||
|
||||
func LoadShopCatalog() (*ShopCatalog, error) {
|
||||
items, err := utils.ReadJSON[ShopItemRow]("EntityMShopItemTable.json")
|
||||
items, err := utils.ReadTable[EntityMShopItem]("m_shop_item")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load shop item table: %w", err)
|
||||
}
|
||||
contents, err := utils.ReadJSON[ShopContentRow]("EntityMShopItemContentPossessionTable.json")
|
||||
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.ReadJSON[ShopContentEffectRow]("EntityMShopItemContentEffectTable.json")
|
||||
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.ReadJSON[userLevelEntry]("EntityMUserLevelTable.json")
|
||||
userLevels, err := utils.ReadTable[EntityMUserLevel]("m_user_level")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load user level table: %w", err)
|
||||
}
|
||||
stockRows, err := utils.ReadJSON[shopItemLimitedStockRow]("EntityMShopItemLimitedStockTable.json")
|
||||
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]ShopItemRow, len(items)),
|
||||
Contents: make(map[int32][]ShopContentRow, len(contents)),
|
||||
Effects: make(map[int32][]ShopContentEffectRow, len(effects)),
|
||||
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)),
|
||||
}
|
||||
@@ -117,15 +68,15 @@ func LoadShopCatalog() (*ShopCatalog, error) {
|
||||
catalog.LimitedStock[row.ShopItemLimitedStockId] = row.MaxCount
|
||||
}
|
||||
|
||||
shops, err := utils.ReadJSON[shopRow]("EntityMShopTable.json")
|
||||
shops, err := utils.ReadTable[EntityMShop]("m_shop")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load shop table: %w", err)
|
||||
}
|
||||
cellGroups, err := utils.ReadJSON[shopItemCellGroupRow]("EntityMShopItemCellGroupTable.json")
|
||||
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.ReadJSON[shopItemCellRow]("EntityMShopItemCellTable.json")
|
||||
cells, err := utils.ReadTable[EntityMShopItemCell]("m_shop_item_cell")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load shop item cell table: %w", err)
|
||||
}
|
||||
@@ -135,7 +86,7 @@ func LoadShopCatalog() (*ShopCatalog, error) {
|
||||
cellIdToItemId[c.ShopItemCellId] = c.ShopItemId
|
||||
}
|
||||
|
||||
cellGroupByCGId := make(map[int32][]shopItemCellGroupRow, len(cellGroups))
|
||||
cellGroupByCGId := make(map[int32][]EntityMShopItemCellGroup, len(cellGroups))
|
||||
for _, cg := range cellGroups {
|
||||
cellGroupByCGId[cg.ShopItemCellGroupId] = append(cellGroupByCGId[cg.ShopItemCellGroupId], cg)
|
||||
}
|
||||
|
||||
@@ -5,18 +5,12 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type sideStorySceneRow struct {
|
||||
SideStoryQuestId int32 `json:"SideStoryQuestId"`
|
||||
SideStoryQuestSceneId int32 `json:"SideStoryQuestSceneId"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type SideStoryCatalog struct {
|
||||
FirstSceneByQuestId map[int32]int32
|
||||
}
|
||||
|
||||
func LoadSideStoryCatalog() *SideStoryCatalog {
|
||||
scenes, err := utils.ReadJSON[sideStorySceneRow]("EntityMSideStoryQuestSceneTable.json")
|
||||
scenes, err := utils.ReadTable[EntityMSideStoryQuestScene]("m_side_story_quest_scene")
|
||||
if err != nil {
|
||||
log.Fatalf("load side story quest scene table: %v", err)
|
||||
}
|
||||
|
||||
@@ -9,172 +9,55 @@ import (
|
||||
"lunar-tear/server/internal/utils"
|
||||
)
|
||||
|
||||
type WeaponMasterRow struct {
|
||||
WeaponId int32 `json:"WeaponId"`
|
||||
RarityType int32 `json:"RarityType"`
|
||||
WeaponType int32 `json:"WeaponType"`
|
||||
WeaponSpecificEnhanceId int32 `json:"WeaponSpecificEnhanceId"`
|
||||
WeaponSkillGroupId int32 `json:"WeaponSkillGroupId"`
|
||||
WeaponAbilityGroupId int32 `json:"WeaponAbilityGroupId"`
|
||||
WeaponStoryReleaseConditionGroupId int32 `json:"WeaponStoryReleaseConditionGroupId"`
|
||||
WeaponEvolutionMaterialGroupId int32 `json:"WeaponEvolutionMaterialGroupId"`
|
||||
}
|
||||
|
||||
type WeaponStoryReleaseConditionRow struct {
|
||||
WeaponStoryReleaseConditionGroupId int32 `json:"WeaponStoryReleaseConditionGroupId"`
|
||||
StoryIndex int32 `json:"StoryIndex"`
|
||||
WeaponStoryReleaseConditionType model.WeaponStoryReleaseConditionType `json:"WeaponStoryReleaseConditionType"`
|
||||
ConditionValue int32 `json:"ConditionValue"`
|
||||
WeaponStoryReleaseConditionOperationGroupId int32 `json:"WeaponStoryReleaseConditionOperationGroupId"`
|
||||
}
|
||||
|
||||
type WeaponSkillGroupRow struct {
|
||||
WeaponSkillGroupId int32 `json:"WeaponSkillGroupId"`
|
||||
SlotNumber int32 `json:"SlotNumber"`
|
||||
SkillId int32 `json:"SkillId"`
|
||||
WeaponSkillEnhancementMaterialId int32 `json:"WeaponSkillEnhancementMaterialId"`
|
||||
}
|
||||
|
||||
type WeaponAbilityGroupRow struct {
|
||||
WeaponAbilityGroupId int32 `json:"WeaponAbilityGroupId"`
|
||||
SlotNumber int32 `json:"SlotNumber"`
|
||||
AbilityId int32 `json:"AbilityId"`
|
||||
WeaponAbilityEnhancementMaterialId int32 `json:"WeaponAbilityEnhancementMaterialId"`
|
||||
}
|
||||
|
||||
type weaponSpecificEnhanceRow struct {
|
||||
WeaponSpecificEnhanceId int32 `json:"WeaponSpecificEnhanceId"`
|
||||
BaseEnhancementObtainedExp int32 `json:"BaseEnhancementObtainedExp"`
|
||||
SellPriceNumericalFunctionId int32 `json:"SellPriceNumericalFunctionId"`
|
||||
RequiredExpForLevelUpNumericalParameterMapId int32 `json:"RequiredExpForLevelUpNumericalParameterMapId"`
|
||||
EnhancementCostByWeaponNumericalFunctionId int32 `json:"EnhancementCostByWeaponNumericalFunctionId"`
|
||||
EnhancementCostByMaterialNumericalFunctionId int32 `json:"EnhancementCostByMaterialNumericalFunctionId"`
|
||||
MaxLevelNumericalFunctionId int32 `json:"MaxLevelNumericalFunctionId"`
|
||||
EvolutionCostNumericalFunctionId int32 `json:"EvolutionCostNumericalFunctionId"`
|
||||
LimitBreakCostByWeaponNumericalFunctionId int32 `json:"LimitBreakCostByWeaponNumericalFunctionId"`
|
||||
LimitBreakCostByMaterialNumericalFunctionId int32 `json:"LimitBreakCostByMaterialNumericalFunctionId"`
|
||||
MaxSkillLevelNumericalFunctionId int32 `json:"MaxSkillLevelNumericalFunctionId"`
|
||||
SkillEnhancementCostNumericalFunctionId int32 `json:"SkillEnhancementCostNumericalFunctionId"`
|
||||
MaxAbilityLevelNumericalFunctionId int32 `json:"MaxAbilityLevelNumericalFunctionId"`
|
||||
AbilityEnhancementCostNumericalFunctionId int32 `json:"AbilityEnhancementCostNumericalFunctionId"`
|
||||
}
|
||||
|
||||
type weaponConsumeExchangeRow struct {
|
||||
WeaponId int32 `json:"WeaponId"`
|
||||
ConsumableItemId int32 `json:"ConsumableItemId"`
|
||||
Count int32 `json:"Count"`
|
||||
}
|
||||
|
||||
type WeaponEvolutionGroupRow struct {
|
||||
WeaponEvolutionGroupId int32 `json:"WeaponEvolutionGroupId"`
|
||||
EvolutionOrder int32 `json:"EvolutionOrder"`
|
||||
WeaponId int32 `json:"WeaponId"`
|
||||
}
|
||||
|
||||
type WeaponEvolutionMaterialRow struct {
|
||||
WeaponEvolutionMaterialGroupId int32 `json:"WeaponEvolutionMaterialGroupId"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type WeaponSkillEnhanceMaterialRow struct {
|
||||
WeaponSkillEnhancementMaterialId int32 `json:"WeaponSkillEnhancementMaterialId"`
|
||||
SkillLevel int32 `json:"SkillLevel"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type WeaponAbilityEnhanceMaterialRow struct {
|
||||
WeaponAbilityEnhancementMaterialId int32 `json:"WeaponAbilityEnhancementMaterialId"`
|
||||
AbilityLevel int32 `json:"AbilityLevel"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type WeaponAwakenRow struct {
|
||||
WeaponId int32 `json:"WeaponId"`
|
||||
WeaponAwakenEffectGroupId int32 `json:"WeaponAwakenEffectGroupId"`
|
||||
WeaponAwakenMaterialGroupId int32 `json:"WeaponAwakenMaterialGroupId"`
|
||||
ConsumeGold int32 `json:"ConsumeGold"`
|
||||
LevelLimitUp int32 `json:"LevelLimitUp"`
|
||||
}
|
||||
|
||||
type WeaponAwakenEffectGroupRow struct {
|
||||
WeaponAwakenEffectGroupId int32 `json:"WeaponAwakenEffectGroupId"`
|
||||
WeaponAwakenEffectType int32 `json:"WeaponAwakenEffectType"`
|
||||
WeaponAwakenEffectId int32 `json:"WeaponAwakenEffectId"`
|
||||
}
|
||||
|
||||
type WeaponAwakenMaterialGroupRow struct {
|
||||
WeaponAwakenMaterialGroupId int32 `json:"WeaponAwakenMaterialGroupId"`
|
||||
MaterialId int32 `json:"MaterialId"`
|
||||
Count int32 `json:"Count"`
|
||||
SortOrder int32 `json:"SortOrder"`
|
||||
}
|
||||
|
||||
type weaponRarityEnhanceRow struct {
|
||||
RarityType int32 `json:"RarityType"`
|
||||
BaseEnhancementObtainedExp int32 `json:"BaseEnhancementObtainedExp"`
|
||||
SellPriceNumericalFunctionId int32 `json:"SellPriceNumericalFunctionId"`
|
||||
RequiredExpForLevelUpNumericalParameterMapId int32 `json:"RequiredExpForLevelUpNumericalParameterMapId"`
|
||||
EnhancementCostByWeaponNumericalFunctionId int32 `json:"EnhancementCostByWeaponNumericalFunctionId"`
|
||||
EnhancementCostByMaterialNumericalFunctionId int32 `json:"EnhancementCostByMaterialNumericalFunctionId"`
|
||||
MaxLevelNumericalFunctionId int32 `json:"MaxLevelNumericalFunctionId"`
|
||||
EvolutionCostNumericalFunctionId int32 `json:"EvolutionCostNumericalFunctionId"`
|
||||
LimitBreakCostByWeaponNumericalFunctionId int32 `json:"LimitBreakCostByWeaponNumericalFunctionId"`
|
||||
LimitBreakCostByMaterialNumericalFunctionId int32 `json:"LimitBreakCostByMaterialNumericalFunctionId"`
|
||||
MaxSkillLevelNumericalFunctionId int32 `json:"MaxSkillLevelNumericalFunctionId"`
|
||||
SkillEnhancementCostNumericalFunctionId int32 `json:"SkillEnhancementCostNumericalFunctionId"`
|
||||
MaxAbilityLevelNumericalFunctionId int32 `json:"MaxAbilityLevelNumericalFunctionId"`
|
||||
AbilityEnhancementCostNumericalFunctionId int32 `json:"AbilityEnhancementCostNumericalFunctionId"`
|
||||
}
|
||||
|
||||
type WeaponCatalog struct {
|
||||
Weapons map[int32]WeaponMasterRow
|
||||
Materials map[int32]MaterialRow
|
||||
Weapons map[int32]EntityMWeapon
|
||||
Materials map[int32]EntityMMaterial
|
||||
ExpByEnhanceId map[int32][]int32
|
||||
GoldCostByEnhanceId map[int32]NumericalFunc
|
||||
MaxLevelByEnhanceId map[int32]NumericalFunc
|
||||
SellPriceByEnhanceId map[int32]NumericalFunc
|
||||
MedalsByWeaponId map[int32]map[int32]int32 // WeaponId -> ConsumableItemId -> Count
|
||||
EvolutionNextWeaponId map[int32]int32
|
||||
EvolutionOrder map[int32]int32 // WeaponId -> 0-based position in evolution chain
|
||||
EvolutionMaterials map[int32][]WeaponEvolutionMaterialRow // WeaponEvolutionMaterialGroupId -> materials
|
||||
EvolutionOrder map[int32]int32 // WeaponId -> 0-based position in evolution chain
|
||||
EvolutionMaterials map[int32][]EntityMWeaponEvolutionMaterialGroup // WeaponEvolutionMaterialGroupId -> materials
|
||||
EvolutionCostByEnhanceId map[int32]NumericalFunc
|
||||
AbilitySlots map[int32][]int32 // WeaponAbilityGroupId -> slot numbers
|
||||
SkillGroupsByGroupId map[int32][]WeaponSkillGroupRow
|
||||
SkillEnhanceMats map[[2]int32][]WeaponSkillEnhanceMaterialRow // key: [enhancementMaterialId, skillLevel]
|
||||
SkillGroupsByGroupId map[int32][]EntityMWeaponSkillGroup
|
||||
SkillEnhanceMats map[[2]int32][]EntityMWeaponSkillEnhancementMaterial // key: [enhancementMaterialId, skillLevel]
|
||||
SkillMaxLevelByEnhanceId map[int32]NumericalFunc
|
||||
SkillCostByEnhanceId map[int32]NumericalFunc
|
||||
AbilityGroupsByGroupId map[int32][]WeaponAbilityGroupRow
|
||||
AbilityEnhanceMats map[[2]int32][]WeaponAbilityEnhanceMaterialRow // key: [enhancementMaterialId, abilityLevel]
|
||||
AbilityGroupsByGroupId map[int32][]EntityMWeaponAbilityGroup
|
||||
AbilityEnhanceMats map[[2]int32][]EntityMWeaponAbilityEnhancementMaterial // key: [enhancementMaterialId, abilityLevel]
|
||||
AbilityMaxLevelByEnhanceId map[int32]NumericalFunc
|
||||
AbilityCostByEnhanceId map[int32]NumericalFunc
|
||||
EnhanceCostByWeaponByEnhanceId map[int32]NumericalFunc
|
||||
LimitBreakCostByWeaponByEnhanceId map[int32]NumericalFunc
|
||||
LimitBreakCostByMaterialByEnhanceId map[int32]NumericalFunc
|
||||
BaseExpByEnhanceId map[int32]int32
|
||||
ReleaseConditionsByGroupId map[int32][]WeaponStoryReleaseConditionRow
|
||||
ReleaseConditionsByGroupId map[int32][]EntityMWeaponStoryReleaseConditionGroup
|
||||
|
||||
AwakenByWeaponId map[int32]WeaponAwakenRow
|
||||
AwakenMaterialsByGroupId map[int32][]WeaponAwakenMaterialGroupRow
|
||||
AwakenByWeaponId map[int32]EntityMWeaponAwaken
|
||||
AwakenMaterialsByGroupId map[int32][]EntityMWeaponAwakenMaterialGroup
|
||||
}
|
||||
|
||||
func LoadWeaponCatalog(matCatalog *MaterialCatalog) (*WeaponCatalog, error) {
|
||||
weapons, err := utils.ReadJSON[WeaponMasterRow]("EntityMWeaponTable.json")
|
||||
weapons, err := utils.ReadTable[EntityMWeapon]("m_weapon")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon table: %w", err)
|
||||
}
|
||||
|
||||
enhanceRows, err := utils.ReadJSON[weaponSpecificEnhanceRow]("EntityMWeaponSpecificEnhanceTable.json")
|
||||
enhanceRows, err := utils.ReadTable[EntityMWeaponSpecificEnhance]("m_weapon_specific_enhance")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon specific enhance table: %w", err)
|
||||
}
|
||||
|
||||
rarityEnhanceRows, err := utils.ReadJSON[weaponRarityEnhanceRow]("EntityMWeaponRarityTable.json")
|
||||
rarityEnhanceRows, err := utils.ReadTable[EntityMWeaponRarity]("m_weapon_rarity")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon rarity table: %w", err)
|
||||
}
|
||||
@@ -189,51 +72,51 @@ func LoadWeaponCatalog(matCatalog *MaterialCatalog) (*WeaponCatalog, error) {
|
||||
return nil, fmt.Errorf("load function resolver: %w", err)
|
||||
}
|
||||
|
||||
exchangeRows, err := utils.ReadJSON[weaponConsumeExchangeRow]("EntityMWeaponConsumeExchangeConsumableItemGroupTable.json")
|
||||
exchangeRows, err := utils.ReadTable[EntityMWeaponConsumeExchangeConsumableItemGroup]("m_weapon_consume_exchange_consumable_item_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon consume exchange table: %w", err)
|
||||
}
|
||||
|
||||
evoGroupRows, err := utils.ReadJSON[WeaponEvolutionGroupRow]("EntityMWeaponEvolutionGroupTable.json")
|
||||
evoGroupRows, err := utils.ReadTable[EntityMWeaponEvolutionGroup]("m_weapon_evolution_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon evolution group table: %w", err)
|
||||
}
|
||||
evoMatRows, err := utils.ReadJSON[WeaponEvolutionMaterialRow]("EntityMWeaponEvolutionMaterialGroupTable.json")
|
||||
evoMatRows, err := utils.ReadTable[EntityMWeaponEvolutionMaterialGroup]("m_weapon_evolution_material_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon evolution material group table: %w", err)
|
||||
}
|
||||
abilityGroupRows, err := utils.ReadJSON[WeaponAbilityGroupRow]("EntityMWeaponAbilityGroupTable.json")
|
||||
abilityGroupRows, err := utils.ReadTable[EntityMWeaponAbilityGroup]("m_weapon_ability_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon ability group table: %w", err)
|
||||
}
|
||||
skillGroupRows, err := utils.ReadJSON[WeaponSkillGroupRow]("EntityMWeaponSkillGroupTable.json")
|
||||
skillGroupRows, err := utils.ReadTable[EntityMWeaponSkillGroup]("m_weapon_skill_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon skill group table: %w", err)
|
||||
}
|
||||
skillMatRows, err := utils.ReadJSON[WeaponSkillEnhanceMaterialRow]("EntityMWeaponSkillEnhancementMaterialTable.json")
|
||||
skillMatRows, err := utils.ReadTable[EntityMWeaponSkillEnhancementMaterial]("m_weapon_skill_enhancement_material")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon skill enhancement material table: %w", err)
|
||||
}
|
||||
abilityMatRows, err := utils.ReadJSON[WeaponAbilityEnhanceMaterialRow]("EntityMWeaponAbilityEnhancementMaterialTable.json")
|
||||
abilityMatRows, err := utils.ReadTable[EntityMWeaponAbilityEnhancementMaterial]("m_weapon_ability_enhancement_material")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon ability enhancement material table: %w", err)
|
||||
}
|
||||
releaseConditions, err := utils.ReadJSON[WeaponStoryReleaseConditionRow]("EntityMWeaponStoryReleaseConditionGroupTable.json")
|
||||
releaseConditions, err := utils.ReadTable[EntityMWeaponStoryReleaseConditionGroup]("m_weapon_story_release_condition_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon story release condition table: %w", err)
|
||||
}
|
||||
|
||||
awakenRows, err := utils.ReadJSON[WeaponAwakenRow]("EntityMWeaponAwakenTable.json")
|
||||
awakenRows, err := utils.ReadTable[EntityMWeaponAwaken]("m_weapon_awaken")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon awaken table: %w", err)
|
||||
}
|
||||
awakenMatRows, err := utils.ReadJSON[WeaponAwakenMaterialGroupRow]("EntityMWeaponAwakenMaterialGroupTable.json")
|
||||
awakenMatRows, err := utils.ReadTable[EntityMWeaponAwakenMaterialGroup]("m_weapon_awaken_material_group")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load weapon awaken material group table: %w", err)
|
||||
}
|
||||
|
||||
catalog := &WeaponCatalog{
|
||||
Weapons: make(map[int32]WeaponMasterRow, len(weapons)),
|
||||
Weapons: make(map[int32]EntityMWeapon, len(weapons)),
|
||||
Materials: matCatalog.ByType[model.MaterialTypeWeaponEnhancement],
|
||||
ExpByEnhanceId: make(map[int32][]int32, len(enhanceRows)),
|
||||
GoldCostByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
@@ -242,25 +125,25 @@ func LoadWeaponCatalog(matCatalog *MaterialCatalog) (*WeaponCatalog, error) {
|
||||
MedalsByWeaponId: make(map[int32]map[int32]int32),
|
||||
EvolutionNextWeaponId: make(map[int32]int32),
|
||||
EvolutionOrder: make(map[int32]int32),
|
||||
EvolutionMaterials: make(map[int32][]WeaponEvolutionMaterialRow),
|
||||
EvolutionMaterials: make(map[int32][]EntityMWeaponEvolutionMaterialGroup),
|
||||
EvolutionCostByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
AbilitySlots: make(map[int32][]int32),
|
||||
SkillGroupsByGroupId: make(map[int32][]WeaponSkillGroupRow),
|
||||
SkillEnhanceMats: make(map[[2]int32][]WeaponSkillEnhanceMaterialRow),
|
||||
SkillGroupsByGroupId: make(map[int32][]EntityMWeaponSkillGroup),
|
||||
SkillEnhanceMats: make(map[[2]int32][]EntityMWeaponSkillEnhancementMaterial),
|
||||
SkillMaxLevelByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
SkillCostByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
AbilityGroupsByGroupId: make(map[int32][]WeaponAbilityGroupRow),
|
||||
AbilityEnhanceMats: make(map[[2]int32][]WeaponAbilityEnhanceMaterialRow),
|
||||
AbilityGroupsByGroupId: make(map[int32][]EntityMWeaponAbilityGroup),
|
||||
AbilityEnhanceMats: make(map[[2]int32][]EntityMWeaponAbilityEnhancementMaterial),
|
||||
AbilityMaxLevelByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
AbilityCostByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
EnhanceCostByWeaponByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
LimitBreakCostByWeaponByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
LimitBreakCostByMaterialByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)),
|
||||
BaseExpByEnhanceId: make(map[int32]int32, len(enhanceRows)),
|
||||
ReleaseConditionsByGroupId: make(map[int32][]WeaponStoryReleaseConditionRow),
|
||||
ReleaseConditionsByGroupId: make(map[int32][]EntityMWeaponStoryReleaseConditionGroup),
|
||||
|
||||
AwakenByWeaponId: make(map[int32]WeaponAwakenRow, len(awakenRows)),
|
||||
AwakenMaterialsByGroupId: make(map[int32][]WeaponAwakenMaterialGroupRow),
|
||||
AwakenByWeaponId: make(map[int32]EntityMWeaponAwaken, len(awakenRows)),
|
||||
AwakenMaterialsByGroupId: make(map[int32][]EntityMWeaponAwakenMaterialGroup),
|
||||
}
|
||||
|
||||
for _, w := range weapons {
|
||||
@@ -338,7 +221,7 @@ func LoadWeaponCatalog(matCatalog *MaterialCatalog) (*WeaponCatalog, error) {
|
||||
catalog.MedalsByWeaponId[ex.WeaponId][ex.ConsumableItemId] = ex.Count
|
||||
}
|
||||
|
||||
grouped := make(map[int32][]WeaponEvolutionGroupRow)
|
||||
grouped := make(map[int32][]EntityMWeaponEvolutionGroup)
|
||||
for _, row := range evoGroupRows {
|
||||
grouped[row.WeaponEvolutionGroupId] = append(grouped[row.WeaponEvolutionGroupId], row)
|
||||
}
|
||||
@@ -399,7 +282,7 @@ func LoadWeaponCatalog(matCatalog *MaterialCatalog) (*WeaponCatalog, error) {
|
||||
|
||||
// Rarity-based enhancement fallback: for weapons with WeaponSpecificEnhanceId == 0,
|
||||
// use EntityMWeaponRarityTable curves via synthetic enhance IDs (-RarityType).
|
||||
rarityByType := make(map[int32]weaponRarityEnhanceRow, len(rarityEnhanceRows))
|
||||
rarityByType := make(map[int32]EntityMWeaponRarity, len(rarityEnhanceRows))
|
||||
for _, r := range rarityEnhanceRows {
|
||||
rarityByType[r.RarityType] = r
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user