mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Share exp-cap helper across enhance flows; fix quest-reward rebirth
Build and Push Docker images to Docker Hub / build-and-push (push) Has been cancelled
Build and Push Docker images to Docker Hub / build-and-push (push) Has been cancelled
This commit is contained in:
@@ -17,3 +17,16 @@ func LevelAndCap(exp int32, thresholds []int32) (level, capped int32) {
|
|||||||
}
|
}
|
||||||
return level, exp
|
return level, exp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplyExpWithMaxLevel runs LevelAndCap and then clamps the resulting
|
||||||
|
// level to the per-instance maxLevel (e.g. limit break + awaken for
|
||||||
|
// weapons, limit break + rebirth for costumes). A maxLevel <= 0 means
|
||||||
|
// "no per-instance cap" and the result is identical to LevelAndCap.
|
||||||
|
func ApplyExpWithMaxLevel(exp int32, thresholds []int32, maxLevel int32) (level, capped int32) {
|
||||||
|
level, capped = LevelAndCap(exp, thresholds)
|
||||||
|
if maxLevel > 0 && level > maxLevel && int(maxLevel) < len(thresholds) {
|
||||||
|
level = maxLevel
|
||||||
|
capped = thresholds[maxLevel]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,25 @@ type CharacterRebirthCatalog struct {
|
|||||||
MaterialsByGroupId map[int32][]EntityMCharacterRebirthMaterialGroup
|
MaterialsByGroupId map[int32][]EntityMCharacterRebirthMaterialGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CharacterRebirthCatalog) CostumeLevelLimitUp(characterId, rebirthCount int32) int32 {
|
||||||
|
if c == nil || rebirthCount <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
stepGroupId, ok := c.StepGroupByCharacterId[characterId]
|
||||||
|
if !ok {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var total int32
|
||||||
|
for i := range rebirthCount {
|
||||||
|
step, ok := c.StepByGroupAndCount[StepKey{GroupId: stepGroupId, BeforeRebirthCount: i}]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
total += step.CostumeLevelLimitUp
|
||||||
|
}
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
func LoadCharacterRebirthCatalog() (*CharacterRebirthCatalog, error) {
|
func LoadCharacterRebirthCatalog() (*CharacterRebirthCatalog, error) {
|
||||||
rebirthRows, err := utils.ReadTable[EntityMCharacterRebirth]("m_character_rebirth")
|
rebirthRows, err := utils.ReadTable[EntityMCharacterRebirth]("m_character_rebirth")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -32,9 +32,10 @@ type QuestHandler struct {
|
|||||||
Granter *store.PossessionGranter
|
Granter *store.PossessionGranter
|
||||||
SideStoryChapterByEventQuestId map[int32]int32
|
SideStoryChapterByEventQuestId map[int32]int32
|
||||||
Campaigns *campaign.Catalog
|
Campaigns *campaign.Catalog
|
||||||
|
CharacterRebirth *masterdata.CharacterRebirthCatalog
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQuestHandler(catalog *masterdata.QuestCatalog, config *masterdata.GameConfig, sideStory *masterdata.SideStoryCatalog, campaigns *campaign.Catalog) *QuestHandler {
|
func NewQuestHandler(catalog *masterdata.QuestCatalog, config *masterdata.GameConfig, sideStory *masterdata.SideStoryCatalog, campaigns *campaign.Catalog, characterRebirth *masterdata.CharacterRebirthCatalog) *QuestHandler {
|
||||||
granter := BuildGranter(catalog)
|
granter := BuildGranter(catalog)
|
||||||
var sideStoryChapters map[int32]int32
|
var sideStoryChapters map[int32]int32
|
||||||
if sideStory != nil {
|
if sideStory != nil {
|
||||||
@@ -46,6 +47,7 @@ func NewQuestHandler(catalog *masterdata.QuestCatalog, config *masterdata.GameCo
|
|||||||
Granter: granter,
|
Granter: granter,
|
||||||
SideStoryChapterByEventQuestId: sideStoryChapters,
|
SideStoryChapterByEventQuestId: sideStoryChapters,
|
||||||
Campaigns: campaigns,
|
Campaigns: campaigns,
|
||||||
|
CharacterRebirth: characterRebirth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -197,8 +197,10 @@ func (h *QuestHandler) applyExpRewards(user *store.UserState, questId int32, now
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
var maxLevel int32
|
||||||
if maxLevelFunc, hasMax := h.CostumeMaxLevelByRarity[cm.RarityType]; hasMax {
|
if maxLevelFunc, hasMax := h.CostumeMaxLevelByRarity[cm.RarityType]; hasMax {
|
||||||
maxLevel := maxLevelFunc.Evaluate(row.LimitBreakCount)
|
maxLevel = maxLevelFunc.Evaluate(row.LimitBreakCount) +
|
||||||
|
h.CharacterRebirth.CostumeLevelLimitUp(cm.CharacterId, user.CharacterRebirths[cm.CharacterId].RebirthCount)
|
||||||
if row.Level >= maxLevel {
|
if row.Level >= maxLevel {
|
||||||
log.Printf("[applyExpRewards] questId=%d costume=%d (key=%s): at max level %d, skipping", questId, row.CostumeId, key, row.Level)
|
log.Printf("[applyExpRewards] questId=%d costume=%d (key=%s): at max level %d, skipping", questId, row.CostumeId, key, row.Level)
|
||||||
continue
|
continue
|
||||||
@@ -206,14 +208,7 @@ func (h *QuestHandler) applyExpRewards(user *store.UserState, questId int32, now
|
|||||||
}
|
}
|
||||||
row.Exp += questDef.CostumeExp
|
row.Exp += questDef.CostumeExp
|
||||||
if thresholds, ok := h.CostumeExpByRarity[cm.RarityType]; ok {
|
if thresholds, ok := h.CostumeExpByRarity[cm.RarityType]; ok {
|
||||||
row.Level, row.Exp = gameutil.LevelAndCap(row.Exp, thresholds)
|
row.Level, row.Exp = gameutil.ApplyExpWithMaxLevel(row.Exp, thresholds, maxLevel)
|
||||||
if maxLevelFunc, hasMax := h.CostumeMaxLevelByRarity[cm.RarityType]; hasMax {
|
|
||||||
maxLevel := maxLevelFunc.Evaluate(row.LimitBreakCount)
|
|
||||||
if row.Level > maxLevel && int(maxLevel) < len(thresholds) {
|
|
||||||
row.Level = maxLevel
|
|
||||||
row.Exp = thresholds[maxLevel]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
user.Costumes[key] = row
|
user.Costumes[key] = row
|
||||||
log.Printf("[applyExpRewards] questId=%d costume=%d (key=%s): +%d exp -> total=%d level=%d", questId, row.CostumeId, key, questDef.CostumeExp, row.Exp, row.Level)
|
log.Printf("[applyExpRewards] questId=%d costume=%d (key=%s): +%d exp -> total=%d level=%d", questId, row.CostumeId, key, questDef.CostumeExp, row.Exp, row.Level)
|
||||||
|
|||||||
@@ -41,7 +41,12 @@ func buildCatalogs() (*Catalogs, error) {
|
|||||||
return nil, fmt.Errorf("load campaign catalog: %w", err)
|
return nil, fmt.Errorf("load campaign catalog: %w", err)
|
||||||
}
|
}
|
||||||
log.Printf("campaign catalog loaded: %d enhance, %d quest", campaignCatalog.EnhanceCount(), campaignCatalog.QuestCount())
|
log.Printf("campaign catalog loaded: %d enhance, %d quest", campaignCatalog.EnhanceCount(), campaignCatalog.QuestCount())
|
||||||
questHandler := questflow.NewQuestHandler(questCatalog, gameConfig, sideStoryCatalog, campaignCatalog)
|
characterRebirthCatalog, err := masterdata.LoadCharacterRebirthCatalog()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("load character rebirth catalog: %w", err)
|
||||||
|
}
|
||||||
|
log.Printf("character rebirth catalog loaded: %d characters", len(characterRebirthCatalog.StepGroupByCharacterId))
|
||||||
|
questHandler := questflow.NewQuestHandler(questCatalog, gameConfig, sideStoryCatalog, campaignCatalog, characterRebirthCatalog)
|
||||||
userdata.SetQuestHandler(questHandler)
|
userdata.SetQuestHandler(questHandler)
|
||||||
|
|
||||||
gachaEntries, medalInfo, err := masterdata.LoadGachaCatalog()
|
gachaEntries, medalInfo, err := masterdata.LoadGachaCatalog()
|
||||||
@@ -133,12 +138,6 @@ func buildCatalogs() (*Catalogs, error) {
|
|||||||
}
|
}
|
||||||
log.Printf("character board catalog loaded: %d panels, %d boards", len(characterBoardCatalog.PanelById), len(characterBoardCatalog.BoardById))
|
log.Printf("character board catalog loaded: %d panels, %d boards", len(characterBoardCatalog.PanelById), len(characterBoardCatalog.BoardById))
|
||||||
|
|
||||||
characterRebirthCatalog, err := masterdata.LoadCharacterRebirthCatalog()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("load character rebirth catalog: %w", err)
|
|
||||||
}
|
|
||||||
log.Printf("character rebirth catalog loaded: %d characters", len(characterRebirthCatalog.StepGroupByCharacterId))
|
|
||||||
|
|
||||||
companionCatalog, err := masterdata.LoadCompanionCatalog()
|
companionCatalog, err := masterdata.LoadCompanionCatalog()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load companion catalog: %w", err)
|
return nil, fmt.Errorf("load companion catalog: %w", err)
|
||||||
|
|||||||
@@ -90,7 +90,12 @@ func (s *CostumeServiceServer) Enhance(ctx context.Context, req *pb.EnhanceReque
|
|||||||
costume.Exp += totalExp
|
costume.Exp += totalExp
|
||||||
|
|
||||||
if thresholds, ok := catalog.ExpByRarity[cm.RarityType]; ok {
|
if thresholds, ok := catalog.ExpByRarity[cm.RarityType]; ok {
|
||||||
costume.Level, costume.Exp = gameutil.LevelAndCap(costume.Exp, thresholds)
|
var maxLevel int32
|
||||||
|
if maxLevelFunc, hasMax := catalog.MaxLevelByRarity[cm.RarityType]; hasMax {
|
||||||
|
maxLevel = maxLevelFunc.Evaluate(costume.LimitBreakCount) +
|
||||||
|
cat.CharacterRebirth.CostumeLevelLimitUp(cm.CharacterId, user.CharacterRebirths[cm.CharacterId].RebirthCount)
|
||||||
|
}
|
||||||
|
costume.Level, costume.Exp = gameutil.ApplyExpWithMaxLevel(costume.Exp, thresholds, maxLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
costume.LatestVersion = nowMillis
|
costume.LatestVersion = nowMillis
|
||||||
|
|||||||
@@ -131,16 +131,11 @@ func (s *WeaponServiceServer) EnhanceByMaterial(ctx context.Context, req *pb.Enh
|
|||||||
weapon.Exp += totalExp
|
weapon.Exp += totalExp
|
||||||
levelingEnhanceId := catalog.LevelingEnhanceIdByWeaponId[weapon.WeaponId]
|
levelingEnhanceId := catalog.LevelingEnhanceIdByWeaponId[weapon.WeaponId]
|
||||||
if thresholds, ok := catalog.ExpByEnhanceId[levelingEnhanceId]; ok {
|
if thresholds, ok := catalog.ExpByEnhanceId[levelingEnhanceId]; ok {
|
||||||
weapon.Level, weapon.Exp = gameutil.LevelAndCap(weapon.Exp, thresholds)
|
var maxLevel int32
|
||||||
if maxFunc, ok := catalog.MaxLevelByEnhanceId[wm.WeaponSpecificEnhanceId]; ok {
|
if maxFunc, ok := catalog.MaxLevelByEnhanceId[wm.WeaponSpecificEnhanceId]; ok {
|
||||||
cap := awakenedLevelCap(catalog, user, weapon, req.UserWeaponUuid, maxFunc.Evaluate(weapon.LimitBreakCount))
|
maxLevel = awakenedLevelCap(catalog, user, weapon, req.UserWeaponUuid, maxFunc.Evaluate(weapon.LimitBreakCount))
|
||||||
if weapon.Level > cap {
|
|
||||||
weapon.Level = cap
|
|
||||||
if int(cap) >= 0 && int(cap) < len(thresholds) {
|
|
||||||
weapon.Exp = thresholds[cap]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
weapon.Level, weapon.Exp = gameutil.ApplyExpWithMaxLevel(weapon.Exp, thresholds, maxLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
note := user.WeaponNotes[weapon.WeaponId]
|
note := user.WeaponNotes[weapon.WeaponId]
|
||||||
@@ -759,16 +754,11 @@ func (s *WeaponServiceServer) EnhanceByWeapon(ctx context.Context, req *pb.Enhan
|
|||||||
weapon.Exp += totalExp
|
weapon.Exp += totalExp
|
||||||
levelingEnhanceId := catalog.LevelingEnhanceIdByWeaponId[weapon.WeaponId]
|
levelingEnhanceId := catalog.LevelingEnhanceIdByWeaponId[weapon.WeaponId]
|
||||||
if thresholds, ok := catalog.ExpByEnhanceId[levelingEnhanceId]; ok {
|
if thresholds, ok := catalog.ExpByEnhanceId[levelingEnhanceId]; ok {
|
||||||
weapon.Level, weapon.Exp = gameutil.LevelAndCap(weapon.Exp, thresholds)
|
var maxLevel int32
|
||||||
if maxFunc, ok := catalog.MaxLevelByEnhanceId[wm.WeaponSpecificEnhanceId]; ok {
|
if maxFunc, ok := catalog.MaxLevelByEnhanceId[wm.WeaponSpecificEnhanceId]; ok {
|
||||||
cap := awakenedLevelCap(catalog, user, weapon, req.UserWeaponUuid, maxFunc.Evaluate(weapon.LimitBreakCount))
|
maxLevel = awakenedLevelCap(catalog, user, weapon, req.UserWeaponUuid, maxFunc.Evaluate(weapon.LimitBreakCount))
|
||||||
if weapon.Level > cap {
|
|
||||||
weapon.Level = cap
|
|
||||||
if int(cap) >= 0 && int(cap) < len(thresholds) {
|
|
||||||
weapon.Exp = thresholds[cap]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
weapon.Level, weapon.Exp = gameutil.ApplyExpWithMaxLevel(weapon.Exp, thresholds, maxLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
note := user.WeaponNotes[weapon.WeaponId]
|
note := user.WeaponNotes[weapon.WeaponId]
|
||||||
|
|||||||
Reference in New Issue
Block a user