mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Fix repeated weapon story unlock notifications by sending only changed stories in diffs
This commit is contained in:
@@ -35,7 +35,7 @@ func (h *QuestHandler) HandleBigHuntQuestFinish(user *store.UserState, questId i
|
|||||||
|
|
||||||
outcome := h.evaluateFinishOutcome(user, questId)
|
outcome := h.evaluateFinishOutcome(user, questId)
|
||||||
if !isRetired {
|
if !isRetired {
|
||||||
h.applyQuestVictory(user, questId, outcome, nowMillis)
|
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func (h *QuestHandler) HandleEventQuestFinish(user *store.UserState, eventQuestC
|
|||||||
|
|
||||||
outcome := h.evaluateFinishOutcome(user, questId)
|
outcome := h.evaluateFinishOutcome(user, questId)
|
||||||
if !isRetired {
|
if !isRetired {
|
||||||
h.applyQuestVictory(user, questId, outcome, nowMillis)
|
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func (h *QuestHandler) HandleExtraQuestFinish(user *store.UserState, questId int
|
|||||||
|
|
||||||
outcome := h.evaluateFinishOutcome(user, questId)
|
outcome := h.evaluateFinishOutcome(user, questId)
|
||||||
if !isRetired {
|
if !isRetired {
|
||||||
h.applyQuestVictory(user, questId, outcome, nowMillis)
|
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ type FinishOutcome struct {
|
|||||||
MissionClearCompleteRewards []RewardGrant
|
MissionClearCompleteRewards []RewardGrant
|
||||||
BigWinClearedQuestMissionIds []int32
|
BigWinClearedQuestMissionIds []int32
|
||||||
IsBigWin bool
|
IsBigWin bool
|
||||||
|
ChangedWeaponStoryIds []int32
|
||||||
}
|
}
|
||||||
|
|
||||||
type QuestHandler struct {
|
type QuestHandler struct {
|
||||||
|
|||||||
@@ -112,12 +112,14 @@ func (h *QuestHandler) handleQuestStartInternal(user *store.UserState, questId i
|
|||||||
user.Quests[questId] = questState
|
user.Quests[questId] = questState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *QuestHandler) applyQuestVictory(user *store.UserState, questId int32, outcome FinishOutcome, nowMillis int64) {
|
func (h *QuestHandler) applyQuestVictory(user *store.UserState, questId int32, outcome *FinishOutcome, nowMillis int64) {
|
||||||
questState := user.Quests[questId]
|
questState := user.Quests[questId]
|
||||||
if !questState.IsRewardGranted {
|
if !questState.IsRewardGranted {
|
||||||
h.applyQuestRewards(user, questId, nowMillis)
|
h.applyQuestRewards(user, questId, nowMillis)
|
||||||
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeHalfResult, nowMillis)
|
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||||
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeFullResult, nowMillis)
|
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeHalfResult, nowMillis)...)
|
||||||
|
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||||
|
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeFullResult, nowMillis)...)
|
||||||
questState.IsRewardGranted = true
|
questState.IsRewardGranted = true
|
||||||
}
|
}
|
||||||
for _, drop := range outcome.DropRewards {
|
for _, drop := range outcome.DropRewards {
|
||||||
@@ -141,7 +143,7 @@ func (h *QuestHandler) HandleQuestFinish(user *store.UserState, questId int32, i
|
|||||||
|
|
||||||
outcome := h.evaluateFinishOutcome(user, questId)
|
outcome := h.evaluateFinishOutcome(user, questId)
|
||||||
if !isRetired {
|
if !isRetired {
|
||||||
h.applyQuestVictory(user, questId, outcome, nowMillis)
|
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
||||||
|
|||||||
@@ -316,8 +316,8 @@ func (h *QuestHandler) grantParts(user *store.UserState, partsId int32, nowMilli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *QuestHandler) grantWeaponStoryUnlock(user *store.UserState, weaponId, storyIndex int32, nowMillis int64) {
|
func (h *QuestHandler) grantWeaponStoryUnlock(user *store.UserState, weaponId, storyIndex int32, nowMillis int64) bool {
|
||||||
store.GrantWeaponStoryUnlock(user, weaponId, storyIndex, nowMillis)
|
return store.GrantWeaponStoryUnlock(user, weaponId, storyIndex, nowMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
var tutorialCompanionChoices = map[int32]int32{
|
var tutorialCompanionChoices = map[int32]int32{
|
||||||
@@ -354,11 +354,12 @@ func (h *QuestHandler) BattleDropRewards(questId int32) []masterdata.BattleDropI
|
|||||||
return h.BattleDropsByQuestId[questId]
|
return h.BattleDropsByQuestId[questId]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *QuestHandler) grantWeaponStoryUnlocksForQuestScene(user *store.UserState, questId int32, resultType model.QuestResultType, nowMillis int64) {
|
func (h *QuestHandler) grantWeaponStoryUnlocksForQuestScene(user *store.UserState, questId int32, resultType model.QuestResultType, nowMillis int64) []int32 {
|
||||||
|
var changedIds []int32
|
||||||
if resultType == model.QuestResultTypeHalfResult {
|
if resultType == model.QuestResultTypeHalfResult {
|
||||||
questDef, ok := h.QuestById[questId]
|
questDef, ok := h.QuestById[questId]
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
rewardGroupId := h.firstClearRewardGroupId(user, questDef)
|
rewardGroupId := h.firstClearRewardGroupId(user, questDef)
|
||||||
for _, reward := range h.FirstClearRewardsByGroupId[rewardGroupId] {
|
for _, reward := range h.FirstClearRewardsByGroupId[rewardGroupId] {
|
||||||
@@ -373,22 +374,27 @@ func (h *QuestHandler) grantWeaponStoryUnlocksForQuestScene(user *store.UserStat
|
|||||||
groupId := weapon.WeaponStoryReleaseConditionGroupId
|
groupId := weapon.WeaponStoryReleaseConditionGroupId
|
||||||
for _, cond := range h.ReleaseConditionsByGroupId[groupId] {
|
for _, cond := range h.ReleaseConditionsByGroupId[groupId] {
|
||||||
if cond.WeaponStoryReleaseConditionType == model.WeaponStoryReleaseConditionTypeAcquisition && cond.ConditionValue == 0 {
|
if cond.WeaponStoryReleaseConditionType == model.WeaponStoryReleaseConditionTypeAcquisition && cond.ConditionValue == 0 {
|
||||||
h.grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
if h.grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis) {
|
||||||
|
changedIds = append(changedIds, weaponId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return changedIds
|
||||||
}
|
}
|
||||||
if resultType == model.QuestResultTypeFullResult {
|
if resultType == model.QuestResultTypeFullResult {
|
||||||
for groupId, conditions := range h.ReleaseConditionsByGroupId {
|
for groupId, conditions := range h.ReleaseConditionsByGroupId {
|
||||||
for _, cond := range conditions {
|
for _, cond := range conditions {
|
||||||
if cond.WeaponStoryReleaseConditionType == model.WeaponStoryReleaseConditionTypeQuestClear && cond.ConditionValue == questId {
|
if cond.WeaponStoryReleaseConditionType == model.WeaponStoryReleaseConditionTypeQuestClear && cond.ConditionValue == questId {
|
||||||
for _, weaponId := range h.WeaponIdsByReleaseConditionGroupId[groupId] {
|
for _, weaponId := range h.WeaponIdsByReleaseConditionGroupId[groupId] {
|
||||||
h.grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
if h.grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis) {
|
||||||
|
changedIds = append(changedIds, weaponId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return changedIds
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,11 @@ func (s *CageOrnamentServiceServer) ReceiveReward(ctx context.Context, req *pb.R
|
|||||||
"IUserMaterial", "IUserConsumableItem", "IUserGem",
|
"IUserMaterial", "IUserConsumableItem", "IUserGem",
|
||||||
"IUserCostume", "IUserCostumeActiveSkill", "IUserCharacter",
|
"IUserCostume", "IUserCostumeActiveSkill", "IUserCharacter",
|
||||||
"IUserWeapon", "IUserWeaponSkill", "IUserWeaponAbility",
|
"IUserWeapon", "IUserWeaponSkill", "IUserWeaponAbility",
|
||||||
"IUserWeaponNote", "IUserWeaponStory",
|
"IUserWeaponNote",
|
||||||
"IUserCageOrnamentReward",
|
"IUserCageOrnamentReward",
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
userdata.AddWeaponStoryDiff(diff, user, s.granter.DrainChangedStoryWeaponIds())
|
||||||
|
|
||||||
return &pb.ReceiveRewardResponse{
|
return &pb.ReceiveRewardResponse{
|
||||||
CageOrnamentReward: []*pb.CageOrnamentReward{
|
CageOrnamentReward: []*pb.CageOrnamentReward{
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ var gachaDiffTables = []string{
|
|||||||
"IUserWeaponNote",
|
"IUserWeaponNote",
|
||||||
"IUserWeaponSkill",
|
"IUserWeaponSkill",
|
||||||
"IUserWeaponAbility",
|
"IUserWeaponAbility",
|
||||||
"IUserWeaponStory",
|
|
||||||
"IUserCharacter",
|
"IUserCharacter",
|
||||||
"IUserMaterial",
|
"IUserMaterial",
|
||||||
}
|
}
|
||||||
@@ -296,6 +295,7 @@ func (s *GachaServiceServer) Draw(ctx context.Context, req *pb.DrawRequest) (*pb
|
|||||||
userdata.FullClientTableMap(updatedUser),
|
userdata.FullClientTableMap(updatedUser),
|
||||||
gachaDiffTables,
|
gachaDiffTables,
|
||||||
))
|
))
|
||||||
|
userdata.AddWeaponStoryDiff(diff, updatedUser, s.handler.Granter.DrainChangedStoryWeaponIds())
|
||||||
|
|
||||||
return &pb.DrawResponse{
|
return &pb.DrawResponse{
|
||||||
NextGacha: nextGacha,
|
NextGacha: nextGacha,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"lunar-tear/server/internal/gametime"
|
"lunar-tear/server/internal/gametime"
|
||||||
"lunar-tear/server/internal/questflow"
|
"lunar-tear/server/internal/questflow"
|
||||||
"lunar-tear/server/internal/store"
|
"lunar-tear/server/internal/store"
|
||||||
|
"lunar-tear/server/internal/userdata"
|
||||||
|
|
||||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||||
)
|
)
|
||||||
@@ -52,6 +53,28 @@ func (s *QuestServiceServer) FinishEventQuest(ctx context.Context, req *pb.Finis
|
|||||||
outcome = s.engine.HandleEventQuestFinish(user, req.EventQuestChapterId, req.QuestId, req.IsRetired, req.IsAnnihilated, nowMillis)
|
outcome = s.engine.HandleEventQuestFinish(user, req.EventQuestChapterId, req.QuestId, req.IsRetired, req.IsAnnihilated, nowMillis)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
diff := buildSelectedQuestDiff(user, []string{
|
||||||
|
"IUserQuest",
|
||||||
|
"IUserQuestMission",
|
||||||
|
"IUserEventQuestProgressStatus",
|
||||||
|
"IUserStatus",
|
||||||
|
"IUserGem",
|
||||||
|
"IUserCharacter",
|
||||||
|
"IUserCostume",
|
||||||
|
"IUserCostumeActiveSkill",
|
||||||
|
"IUserWeapon",
|
||||||
|
"IUserWeaponSkill",
|
||||||
|
"IUserWeaponAbility",
|
||||||
|
"IUserWeaponNote",
|
||||||
|
"IUserCompanion",
|
||||||
|
"IUserConsumableItem",
|
||||||
|
"IUserMaterial",
|
||||||
|
"IUserImportantItem",
|
||||||
|
"IUserParts",
|
||||||
|
"IUserPartsGroupNote",
|
||||||
|
})
|
||||||
|
userdata.AddWeaponStoryDiff(diff, user, outcome.ChangedWeaponStoryIds)
|
||||||
|
|
||||||
return &pb.FinishEventQuestResponse{
|
return &pb.FinishEventQuestResponse{
|
||||||
DropReward: toProtoRewards(outcome.DropRewards),
|
DropReward: toProtoRewards(outcome.DropRewards),
|
||||||
FirstClearReward: toProtoRewards(outcome.FirstClearRewards),
|
FirstClearReward: toProtoRewards(outcome.FirstClearRewards),
|
||||||
@@ -61,27 +84,7 @@ func (s *QuestServiceServer) FinishEventQuest(ctx context.Context, req *pb.Finis
|
|||||||
IsBigWin: outcome.IsBigWin,
|
IsBigWin: outcome.IsBigWin,
|
||||||
BigWinClearedQuestMissionIdList: outcome.BigWinClearedQuestMissionIds,
|
BigWinClearedQuestMissionIdList: outcome.BigWinClearedQuestMissionIds,
|
||||||
UserStatusCampaignReward: []*pb.QuestReward{},
|
UserStatusCampaignReward: []*pb.QuestReward{},
|
||||||
DiffUserData: buildSelectedQuestDiff(user, []string{
|
DiffUserData: diff,
|
||||||
"IUserQuest",
|
|
||||||
"IUserQuestMission",
|
|
||||||
"IUserEventQuestProgressStatus",
|
|
||||||
"IUserStatus",
|
|
||||||
"IUserGem",
|
|
||||||
"IUserCharacter",
|
|
||||||
"IUserCostume",
|
|
||||||
"IUserCostumeActiveSkill",
|
|
||||||
"IUserWeapon",
|
|
||||||
"IUserWeaponSkill",
|
|
||||||
"IUserWeaponAbility",
|
|
||||||
"IUserWeaponNote",
|
|
||||||
"IUserWeaponStory",
|
|
||||||
"IUserCompanion",
|
|
||||||
"IUserConsumableItem",
|
|
||||||
"IUserMaterial",
|
|
||||||
"IUserImportantItem",
|
|
||||||
"IUserParts",
|
|
||||||
"IUserPartsGroupNote",
|
|
||||||
}),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,21 +114,24 @@ func (s *QuestServiceServer) UpdateEventQuestSceneProgress(ctx context.Context,
|
|||||||
s.engine.HandleEventQuestSceneProgress(user, req.QuestSceneId, gametime.NowMillis())
|
s.engine.HandleEventQuestSceneProgress(user, req.QuestSceneId, gametime.NowMillis())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
diff := buildSelectedQuestDiff(user, []string{
|
||||||
|
"IUserEventQuestProgressStatus",
|
||||||
|
"IUserCharacter",
|
||||||
|
"IUserCostume",
|
||||||
|
"IUserWeapon",
|
||||||
|
"IUserWeaponSkill",
|
||||||
|
"IUserWeaponAbility",
|
||||||
|
"IUserCompanion",
|
||||||
|
"IUserConsumableItem",
|
||||||
|
"IUserMaterial",
|
||||||
|
"IUserImportantItem",
|
||||||
|
"IUserParts",
|
||||||
|
"IUserPartsGroupNote",
|
||||||
|
})
|
||||||
|
userdata.AddWeaponStoryDiff(diff, user, s.engine.Granter.DrainChangedStoryWeaponIds())
|
||||||
|
|
||||||
return &pb.UpdateEventQuestSceneProgressResponse{
|
return &pb.UpdateEventQuestSceneProgressResponse{
|
||||||
DiffUserData: buildSelectedQuestDiff(user, []string{
|
DiffUserData: diff,
|
||||||
"IUserEventQuestProgressStatus",
|
|
||||||
"IUserCharacter",
|
|
||||||
"IUserCostume",
|
|
||||||
"IUserWeapon",
|
|
||||||
"IUserWeaponSkill",
|
|
||||||
"IUserWeaponAbility",
|
|
||||||
"IUserCompanion",
|
|
||||||
"IUserConsumableItem",
|
|
||||||
"IUserMaterial",
|
|
||||||
"IUserImportantItem",
|
|
||||||
"IUserParts",
|
|
||||||
"IUserPartsGroupNote",
|
|
||||||
}),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"lunar-tear/server/internal/gametime"
|
"lunar-tear/server/internal/gametime"
|
||||||
"lunar-tear/server/internal/questflow"
|
"lunar-tear/server/internal/questflow"
|
||||||
"lunar-tear/server/internal/store"
|
"lunar-tear/server/internal/store"
|
||||||
|
"lunar-tear/server/internal/userdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *QuestServiceServer) StartExtraQuest(ctx context.Context, req *pb.StartExtraQuestRequest) (*pb.StartExtraQuestResponse, error) {
|
func (s *QuestServiceServer) StartExtraQuest(ctx context.Context, req *pb.StartExtraQuestRequest) (*pb.StartExtraQuestResponse, error) {
|
||||||
@@ -50,6 +51,28 @@ func (s *QuestServiceServer) FinishExtraQuest(ctx context.Context, req *pb.Finis
|
|||||||
outcome = s.engine.HandleExtraQuestFinish(user, req.QuestId, req.IsRetired, req.IsAnnihilated, nowMillis)
|
outcome = s.engine.HandleExtraQuestFinish(user, req.QuestId, req.IsRetired, req.IsAnnihilated, nowMillis)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
diff := buildSelectedQuestDiff(user, []string{
|
||||||
|
"IUserQuest",
|
||||||
|
"IUserQuestMission",
|
||||||
|
"IUserExtraQuestProgressStatus",
|
||||||
|
"IUserStatus",
|
||||||
|
"IUserGem",
|
||||||
|
"IUserCharacter",
|
||||||
|
"IUserCostume",
|
||||||
|
"IUserCostumeActiveSkill",
|
||||||
|
"IUserWeapon",
|
||||||
|
"IUserWeaponSkill",
|
||||||
|
"IUserWeaponAbility",
|
||||||
|
"IUserWeaponNote",
|
||||||
|
"IUserCompanion",
|
||||||
|
"IUserConsumableItem",
|
||||||
|
"IUserMaterial",
|
||||||
|
"IUserImportantItem",
|
||||||
|
"IUserParts",
|
||||||
|
"IUserPartsGroupNote",
|
||||||
|
})
|
||||||
|
userdata.AddWeaponStoryDiff(diff, user, outcome.ChangedWeaponStoryIds)
|
||||||
|
|
||||||
return &pb.FinishExtraQuestResponse{
|
return &pb.FinishExtraQuestResponse{
|
||||||
DropReward: toProtoRewards(outcome.DropRewards),
|
DropReward: toProtoRewards(outcome.DropRewards),
|
||||||
FirstClearReward: toProtoRewards(outcome.FirstClearRewards),
|
FirstClearReward: toProtoRewards(outcome.FirstClearRewards),
|
||||||
@@ -58,27 +81,7 @@ func (s *QuestServiceServer) FinishExtraQuest(ctx context.Context, req *pb.Finis
|
|||||||
IsBigWin: outcome.IsBigWin,
|
IsBigWin: outcome.IsBigWin,
|
||||||
BigWinClearedQuestMissionIdList: outcome.BigWinClearedQuestMissionIds,
|
BigWinClearedQuestMissionIdList: outcome.BigWinClearedQuestMissionIds,
|
||||||
UserStatusCampaignReward: []*pb.QuestReward{},
|
UserStatusCampaignReward: []*pb.QuestReward{},
|
||||||
DiffUserData: buildSelectedQuestDiff(user, []string{
|
DiffUserData: diff,
|
||||||
"IUserQuest",
|
|
||||||
"IUserQuestMission",
|
|
||||||
"IUserExtraQuestProgressStatus",
|
|
||||||
"IUserStatus",
|
|
||||||
"IUserGem",
|
|
||||||
"IUserCharacter",
|
|
||||||
"IUserCostume",
|
|
||||||
"IUserCostumeActiveSkill",
|
|
||||||
"IUserWeapon",
|
|
||||||
"IUserWeaponSkill",
|
|
||||||
"IUserWeaponAbility",
|
|
||||||
"IUserWeaponNote",
|
|
||||||
"IUserWeaponStory",
|
|
||||||
"IUserCompanion",
|
|
||||||
"IUserConsumableItem",
|
|
||||||
"IUserMaterial",
|
|
||||||
"IUserImportantItem",
|
|
||||||
"IUserParts",
|
|
||||||
"IUserPartsGroupNote",
|
|
||||||
}),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,20 +122,23 @@ func (s *QuestServiceServer) UpdateExtraQuestSceneProgress(ctx context.Context,
|
|||||||
s.engine.HandleExtraQuestSceneProgress(user, req.QuestSceneId, gametime.NowMillis())
|
s.engine.HandleExtraQuestSceneProgress(user, req.QuestSceneId, gametime.NowMillis())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
diff := buildSelectedQuestDiff(user, []string{
|
||||||
|
"IUserExtraQuestProgressStatus",
|
||||||
|
"IUserCharacter",
|
||||||
|
"IUserCostume",
|
||||||
|
"IUserWeapon",
|
||||||
|
"IUserWeaponSkill",
|
||||||
|
"IUserWeaponAbility",
|
||||||
|
"IUserCompanion",
|
||||||
|
"IUserConsumableItem",
|
||||||
|
"IUserMaterial",
|
||||||
|
"IUserImportantItem",
|
||||||
|
"IUserParts",
|
||||||
|
"IUserPartsGroupNote",
|
||||||
|
})
|
||||||
|
userdata.AddWeaponStoryDiff(diff, user, s.engine.Granter.DrainChangedStoryWeaponIds())
|
||||||
|
|
||||||
return &pb.UpdateExtraQuestSceneProgressResponse{
|
return &pb.UpdateExtraQuestSceneProgressResponse{
|
||||||
DiffUserData: buildSelectedQuestDiff(user, []string{
|
DiffUserData: diff,
|
||||||
"IUserExtraQuestProgressStatus",
|
|
||||||
"IUserCharacter",
|
|
||||||
"IUserCostume",
|
|
||||||
"IUserWeapon",
|
|
||||||
"IUserWeaponSkill",
|
|
||||||
"IUserWeaponAbility",
|
|
||||||
"IUserCompanion",
|
|
||||||
"IUserConsumableItem",
|
|
||||||
"IUserMaterial",
|
|
||||||
"IUserImportantItem",
|
|
||||||
"IUserParts",
|
|
||||||
"IUserPartsGroupNote",
|
|
||||||
}),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,30 +41,32 @@ func (s *QuestServiceServer) UpdateMainFlowSceneProgress(ctx context.Context, re
|
|||||||
s.engine.HandleMainFlowSceneProgress(user, req.QuestSceneId, gametime.NowMillis())
|
s.engine.HandleMainFlowSceneProgress(user, req.QuestSceneId, gametime.NowMillis())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
diff := buildSelectedQuestDiff(user, []string{
|
||||||
|
"IUserMainQuestFlowStatus",
|
||||||
|
"IUserMainQuestMainFlowStatus",
|
||||||
|
"IUserMainQuestProgressStatus",
|
||||||
|
"IUserMainQuestSeasonRoute",
|
||||||
|
"IUserPortalCageStatus",
|
||||||
|
"IUserSideStoryQuestSceneProgressStatus",
|
||||||
|
"IUserQuest",
|
||||||
|
"IUserCharacter",
|
||||||
|
"IUserCostume",
|
||||||
|
"IUserCostumeActiveSkill",
|
||||||
|
"IUserWeapon",
|
||||||
|
"IUserWeaponSkill",
|
||||||
|
"IUserWeaponAbility",
|
||||||
|
"IUserWeaponNote",
|
||||||
|
"IUserCompanion",
|
||||||
|
"IUserConsumableItem",
|
||||||
|
"IUserMaterial",
|
||||||
|
"IUserImportantItem",
|
||||||
|
"IUserParts",
|
||||||
|
"IUserPartsGroupNote",
|
||||||
|
})
|
||||||
|
userdata.AddWeaponStoryDiff(diff, user, s.engine.Granter.DrainChangedStoryWeaponIds())
|
||||||
|
|
||||||
return &pb.UpdateMainFlowSceneProgressResponse{
|
return &pb.UpdateMainFlowSceneProgressResponse{
|
||||||
DiffUserData: buildSelectedQuestDiff(user, []string{
|
DiffUserData: diff,
|
||||||
"IUserMainQuestFlowStatus",
|
|
||||||
"IUserMainQuestMainFlowStatus",
|
|
||||||
"IUserMainQuestProgressStatus",
|
|
||||||
"IUserMainQuestSeasonRoute",
|
|
||||||
"IUserPortalCageStatus",
|
|
||||||
"IUserSideStoryQuestSceneProgressStatus",
|
|
||||||
"IUserQuest",
|
|
||||||
"IUserCharacter",
|
|
||||||
"IUserCostume",
|
|
||||||
"IUserCostumeActiveSkill",
|
|
||||||
"IUserWeapon",
|
|
||||||
"IUserWeaponSkill",
|
|
||||||
"IUserWeaponAbility",
|
|
||||||
"IUserWeaponNote",
|
|
||||||
"IUserWeaponStory",
|
|
||||||
"IUserCompanion",
|
|
||||||
"IUserConsumableItem",
|
|
||||||
"IUserMaterial",
|
|
||||||
"IUserImportantItem",
|
|
||||||
"IUserParts",
|
|
||||||
"IUserPartsGroupNote",
|
|
||||||
}),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +171,32 @@ func (s *QuestServiceServer) FinishMainQuest(ctx context.Context, req *pb.Finish
|
|||||||
outcome = s.engine.HandleQuestFinish(user, req.QuestId, req.IsRetired, req.IsAnnihilated, nowMillis)
|
outcome = s.engine.HandleQuestFinish(user, req.QuestId, req.IsRetired, req.IsAnnihilated, nowMillis)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
diff := buildSelectedQuestDiff(user, []string{
|
||||||
|
"IUserQuest",
|
||||||
|
"IUserQuestMission",
|
||||||
|
"IUserMainQuestFlowStatus",
|
||||||
|
"IUserMainQuestMainFlowStatus",
|
||||||
|
"IUserMainQuestProgressStatus",
|
||||||
|
"IUserMainQuestSeasonRoute",
|
||||||
|
"IUserMainQuestReplayFlowStatus",
|
||||||
|
"IUserStatus",
|
||||||
|
"IUserGem",
|
||||||
|
"IUserCharacter",
|
||||||
|
"IUserCostume",
|
||||||
|
"IUserCostumeActiveSkill",
|
||||||
|
"IUserWeapon",
|
||||||
|
"IUserWeaponSkill",
|
||||||
|
"IUserWeaponAbility",
|
||||||
|
"IUserWeaponNote",
|
||||||
|
"IUserCompanion",
|
||||||
|
"IUserConsumableItem",
|
||||||
|
"IUserMaterial",
|
||||||
|
"IUserImportantItem",
|
||||||
|
"IUserParts",
|
||||||
|
"IUserPartsGroupNote",
|
||||||
|
})
|
||||||
|
userdata.AddWeaponStoryDiff(diff, user, outcome.ChangedWeaponStoryIds)
|
||||||
|
|
||||||
return &pb.FinishMainQuestResponse{
|
return &pb.FinishMainQuestResponse{
|
||||||
DropReward: toProtoRewards(outcome.DropRewards),
|
DropReward: toProtoRewards(outcome.DropRewards),
|
||||||
FirstClearReward: toProtoRewards(outcome.FirstClearRewards),
|
FirstClearReward: toProtoRewards(outcome.FirstClearRewards),
|
||||||
@@ -179,31 +207,7 @@ func (s *QuestServiceServer) FinishMainQuest(ctx context.Context, req *pb.Finish
|
|||||||
BigWinClearedQuestMissionIdList: outcome.BigWinClearedQuestMissionIds,
|
BigWinClearedQuestMissionIdList: outcome.BigWinClearedQuestMissionIds,
|
||||||
ReplayFlowFirstClearReward: toProtoRewards(outcome.ReplayFlowFirstClearRewards),
|
ReplayFlowFirstClearReward: toProtoRewards(outcome.ReplayFlowFirstClearRewards),
|
||||||
UserStatusCampaignReward: []*pb.QuestReward{},
|
UserStatusCampaignReward: []*pb.QuestReward{},
|
||||||
DiffUserData: buildSelectedQuestDiff(user, []string{
|
DiffUserData: diff,
|
||||||
"IUserQuest",
|
|
||||||
"IUserQuestMission",
|
|
||||||
"IUserMainQuestFlowStatus",
|
|
||||||
"IUserMainQuestMainFlowStatus",
|
|
||||||
"IUserMainQuestProgressStatus",
|
|
||||||
"IUserMainQuestSeasonRoute",
|
|
||||||
"IUserMainQuestReplayFlowStatus",
|
|
||||||
"IUserStatus",
|
|
||||||
"IUserGem",
|
|
||||||
"IUserCharacter",
|
|
||||||
"IUserCostume",
|
|
||||||
"IUserCostumeActiveSkill",
|
|
||||||
"IUserWeapon",
|
|
||||||
"IUserWeaponSkill",
|
|
||||||
"IUserWeaponAbility",
|
|
||||||
"IUserWeaponNote",
|
|
||||||
"IUserWeaponStory",
|
|
||||||
"IUserCompanion",
|
|
||||||
"IUserConsumableItem",
|
|
||||||
"IUserMaterial",
|
|
||||||
"IUserImportantItem",
|
|
||||||
"IUserParts",
|
|
||||||
"IUserPartsGroupNote",
|
|
||||||
}),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ var shopDiffTables = []string{
|
|||||||
"IUserWeaponSkill",
|
"IUserWeaponSkill",
|
||||||
"IUserWeaponAbility",
|
"IUserWeaponAbility",
|
||||||
"IUserWeaponNote",
|
"IUserWeaponNote",
|
||||||
"IUserWeaponStory",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShopServiceServer struct {
|
type ShopServiceServer struct {
|
||||||
@@ -92,6 +91,7 @@ func (s *ShopServiceServer) Buy(ctx context.Context, req *pb.BuyRequest) (*pb.Bu
|
|||||||
|
|
||||||
tables := userdata.FullClientTableMap(snapshot)
|
tables := userdata.FullClientTableMap(snapshot)
|
||||||
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, shopDiffTables))
|
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, shopDiffTables))
|
||||||
|
userdata.AddWeaponStoryDiff(diff, snapshot, s.granter.DrainChangedStoryWeaponIds())
|
||||||
|
|
||||||
return &pb.BuyResponse{
|
return &pb.BuyResponse{
|
||||||
OverflowPossession: []*pb.Possession{},
|
OverflowPossession: []*pb.Possession{},
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ var startedGameStartTables = []string{
|
|||||||
"IUserQuestMission",
|
"IUserQuestMission",
|
||||||
"IUserTutorialProgress",
|
"IUserTutorialProgress",
|
||||||
"IUserWeaponNote",
|
"IUserWeaponNote",
|
||||||
"IUserWeaponStory",
|
|
||||||
"IUserCostumeActiveSkill",
|
"IUserCostumeActiveSkill",
|
||||||
"IUserDeckTypeNote",
|
"IUserDeckTypeNote",
|
||||||
"IUserDeckSubWeaponGroup",
|
"IUserDeckSubWeaponGroup",
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ var weaponDiffTables = []string{
|
|||||||
"IUserWeaponAbility",
|
"IUserWeaponAbility",
|
||||||
"IUserMaterial",
|
"IUserMaterial",
|
||||||
"IUserConsumableItem",
|
"IUserConsumableItem",
|
||||||
"IUserWeaponStory",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var limitBreakDiffTables = []string{
|
var limitBreakDiffTables = []string{
|
||||||
@@ -98,6 +97,7 @@ func (s *WeaponServiceServer) EnhanceByMaterial(ctx context.Context, req *pb.Enh
|
|||||||
userId := currentUserId(ctx, s.users, s.sessions)
|
userId := currentUserId(ctx, s.users, s.sessions)
|
||||||
nowMillis := gametime.NowMillis()
|
nowMillis := gametime.NowMillis()
|
||||||
|
|
||||||
|
var changedStoryIds []int32
|
||||||
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
weapon, ok := user.Weapons[req.UserWeaponUuid]
|
weapon, ok := user.Weapons[req.UserWeaponUuid]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -149,6 +149,8 @@ func (s *WeaponServiceServer) EnhanceByMaterial(ctx context.Context, req *pb.Enh
|
|||||||
weapon.LatestVersion = nowMillis
|
weapon.LatestVersion = nowMillis
|
||||||
user.Weapons[req.UserWeaponUuid] = weapon
|
user.Weapons[req.UserWeaponUuid] = weapon
|
||||||
log.Printf("[WeaponService] EnhanceByMaterial: weaponId=%d +%d exp -> total=%d level=%d", weapon.WeaponId, totalExp, weapon.Exp, weapon.Level)
|
log.Printf("[WeaponService] EnhanceByMaterial: weaponId=%d +%d exp -> total=%d level=%d", weapon.WeaponId, totalExp, weapon.Exp, weapon.Level)
|
||||||
|
|
||||||
|
changedStoryIds = s.checkWeaponStoryUnlocks(user, weapon.WeaponId, weapon.Level, nowMillis)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("weapon enhance by material: %w", err)
|
return nil, fmt.Errorf("weapon enhance by material: %w", err)
|
||||||
@@ -156,6 +158,7 @@ func (s *WeaponServiceServer) EnhanceByMaterial(ctx context.Context, req *pb.Enh
|
|||||||
|
|
||||||
tables := userdata.FullClientTableMap(snapshot)
|
tables := userdata.FullClientTableMap(snapshot)
|
||||||
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
|
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
|
||||||
|
userdata.AddWeaponStoryDiff(diff, snapshot, changedStoryIds)
|
||||||
|
|
||||||
return &pb.EnhanceByMaterialResponse{
|
return &pb.EnhanceByMaterialResponse{
|
||||||
IsGreatSuccess: false,
|
IsGreatSuccess: false,
|
||||||
@@ -227,6 +230,7 @@ func (s *WeaponServiceServer) Evolve(ctx context.Context, req *pb.EvolveRequest)
|
|||||||
userId := currentUserId(ctx, s.users, s.sessions)
|
userId := currentUserId(ctx, s.users, s.sessions)
|
||||||
nowMillis := gametime.NowMillis()
|
nowMillis := gametime.NowMillis()
|
||||||
|
|
||||||
|
var changedStoryIds []int32
|
||||||
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
weapon, ok := user.Weapons[req.UserWeaponUuid]
|
weapon, ok := user.Weapons[req.UserWeaponUuid]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -286,7 +290,7 @@ func (s *WeaponServiceServer) Evolve(ctx context.Context, req *pb.EvolveRequest)
|
|||||||
|
|
||||||
log.Printf("[WeaponService] Evolve: weaponId %d -> %d", wm.WeaponId, evolvedId)
|
log.Printf("[WeaponService] Evolve: weaponId %d -> %d", wm.WeaponId, evolvedId)
|
||||||
|
|
||||||
s.checkEvolutionStoryUnlocks(user, evolvedId, nowMillis)
|
changedStoryIds = s.checkWeaponStoryUnlocks(user, evolvedId, weapon.Level, nowMillis)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("weapon evolve: %w", err)
|
return nil, fmt.Errorf("weapon evolve: %w", err)
|
||||||
@@ -294,6 +298,7 @@ func (s *WeaponServiceServer) Evolve(ctx context.Context, req *pb.EvolveRequest)
|
|||||||
|
|
||||||
tables := userdata.FullClientTableMap(snapshot)
|
tables := userdata.FullClientTableMap(snapshot)
|
||||||
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
|
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
|
||||||
|
userdata.AddWeaponStoryDiff(diff, snapshot, changedStoryIds)
|
||||||
|
|
||||||
return &pb.EvolveResponse{DiffUserData: diff}, nil
|
return &pb.EvolveResponse{DiffUserData: diff}, nil
|
||||||
}
|
}
|
||||||
@@ -665,6 +670,7 @@ func (s *WeaponServiceServer) EnhanceByWeapon(ctx context.Context, req *pb.Enhan
|
|||||||
Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}).
|
Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}).
|
||||||
Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"})
|
Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"})
|
||||||
|
|
||||||
|
var changedStoryIds []int32
|
||||||
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
weapon, ok := user.Weapons[req.UserWeaponUuid]
|
weapon, ok := user.Weapons[req.UserWeaponUuid]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -725,6 +731,8 @@ func (s *WeaponServiceServer) EnhanceByWeapon(ctx context.Context, req *pb.Enhan
|
|||||||
weapon.LatestVersion = nowMillis
|
weapon.LatestVersion = nowMillis
|
||||||
user.Weapons[req.UserWeaponUuid] = weapon
|
user.Weapons[req.UserWeaponUuid] = weapon
|
||||||
log.Printf("[WeaponService] EnhanceByWeapon: weaponId=%d +%d exp -> total=%d level=%d", weapon.WeaponId, totalExp, weapon.Exp, weapon.Level)
|
log.Printf("[WeaponService] EnhanceByWeapon: weaponId=%d +%d exp -> total=%d level=%d", weapon.WeaponId, totalExp, weapon.Exp, weapon.Level)
|
||||||
|
|
||||||
|
changedStoryIds = s.checkWeaponStoryUnlocks(user, weapon.WeaponId, weapon.Level, nowMillis)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("weapon enhance by weapon: %w", err)
|
return nil, fmt.Errorf("weapon enhance by weapon: %w", err)
|
||||||
@@ -732,6 +740,7 @@ func (s *WeaponServiceServer) EnhanceByWeapon(ctx context.Context, req *pb.Enhan
|
|||||||
|
|
||||||
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), weaponDiffTables)
|
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), weaponDiffTables)
|
||||||
diff := tracker.Apply(snapshot, tables)
|
diff := tracker.Apply(snapshot, tables)
|
||||||
|
userdata.AddWeaponStoryDiff(diff, snapshot, changedStoryIds)
|
||||||
|
|
||||||
return &pb.EnhanceByWeaponResponse{
|
return &pb.EnhanceByWeaponResponse{
|
||||||
IsGreatSuccess: false,
|
IsGreatSuccess: false,
|
||||||
@@ -740,21 +749,49 @@ func (s *WeaponServiceServer) EnhanceByWeapon(ctx context.Context, req *pb.Enhan
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WeaponServiceServer) checkEvolutionStoryUnlocks(user *store.UserState, weaponId int32, nowMillis int64) {
|
func (s *WeaponServiceServer) checkWeaponStoryUnlocks(user *store.UserState, weaponId, level int32, nowMillis int64) []int32 {
|
||||||
wm, ok := s.catalog.Weapons[weaponId]
|
wm, ok := s.catalog.Weapons[weaponId]
|
||||||
if !ok || wm.WeaponStoryReleaseConditionGroupId == 0 {
|
if !ok || wm.WeaponStoryReleaseConditionGroupId == 0 {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
evoOrder, hasEvo := s.catalog.EvolutionOrder[weaponId]
|
evoOrder, hasEvo := s.catalog.EvolutionOrder[weaponId]
|
||||||
conditions := s.catalog.ReleaseConditionsByGroupId[wm.WeaponStoryReleaseConditionGroupId]
|
conditions := s.catalog.ReleaseConditionsByGroupId[wm.WeaponStoryReleaseConditionGroupId]
|
||||||
|
|
||||||
|
changed := false
|
||||||
for _, cond := range conditions {
|
for _, cond := range conditions {
|
||||||
|
granted := false
|
||||||
switch cond.WeaponStoryReleaseConditionType {
|
switch cond.WeaponStoryReleaseConditionType {
|
||||||
|
case model.WeaponStoryReleaseConditionTypeAcquisition:
|
||||||
|
granted = store.GrantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
||||||
|
case model.WeaponStoryReleaseConditionTypeReachSpecifiedLevel:
|
||||||
|
if level >= cond.ConditionValue {
|
||||||
|
granted = store.GrantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
||||||
|
}
|
||||||
|
case model.WeaponStoryReleaseConditionTypeReachInitialMaxLevel:
|
||||||
|
if maxFunc, ok := s.catalog.MaxLevelByEnhanceId[wm.WeaponSpecificEnhanceId]; ok {
|
||||||
|
if level >= maxFunc.Evaluate(0) {
|
||||||
|
granted = store.GrantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case model.WeaponStoryReleaseConditionTypeReachOnceEvolvedMaxLevel:
|
||||||
|
if hasEvo && evoOrder >= 1 {
|
||||||
|
if maxFunc, ok := s.catalog.MaxLevelByEnhanceId[wm.WeaponSpecificEnhanceId]; ok {
|
||||||
|
if level >= maxFunc.Evaluate(0) {
|
||||||
|
granted = store.GrantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
case model.WeaponStoryReleaseConditionTypeReachSpecifiedEvolutionCount:
|
case model.WeaponStoryReleaseConditionTypeReachSpecifiedEvolutionCount:
|
||||||
if hasEvo && evoOrder >= cond.ConditionValue {
|
if hasEvo && evoOrder >= cond.ConditionValue {
|
||||||
store.GrantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
granted = store.GrantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
||||||
}
|
}
|
||||||
case model.WeaponStoryReleaseConditionTypeAcquisition:
|
}
|
||||||
store.GrantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
if granted {
|
||||||
|
changed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if changed {
|
||||||
|
return []int32{weaponId}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,14 @@ type PossessionGranter struct {
|
|||||||
WeaponSkillSlots map[int32][]int32
|
WeaponSkillSlots map[int32][]int32
|
||||||
WeaponAbilitySlots map[int32][]int32
|
WeaponAbilitySlots map[int32][]int32
|
||||||
ReleaseConditions map[int32][]WeaponStoryReleaseCond
|
ReleaseConditions map[int32][]WeaponStoryReleaseCond
|
||||||
|
|
||||||
|
LastChangedStoryWeaponIds []int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *PossessionGranter) DrainChangedStoryWeaponIds() []int32 {
|
||||||
|
ids := g.LastChangedStoryWeaponIds
|
||||||
|
g.LastChangedStoryWeaponIds = nil
|
||||||
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *PossessionGranter) GrantFull(user *UserState, possessionType model.PossessionType, possessionId, count int32, nowMillis int64) {
|
func (g *PossessionGranter) GrantFull(user *UserState, possessionType model.PossessionType, possessionId, count int32, nowMillis int64) {
|
||||||
@@ -170,16 +178,24 @@ func (g *PossessionGranter) GrantWeapon(user *UserState, weaponId int32, nowMill
|
|||||||
|
|
||||||
g.populateWeaponSkillsAbilities(user, key, weapon)
|
g.populateWeaponSkillsAbilities(user, key, weapon)
|
||||||
if weapon.WeaponStoryReleaseConditionGroupId != 0 {
|
if weapon.WeaponStoryReleaseConditionGroupId != 0 {
|
||||||
|
changed := false
|
||||||
for _, cond := range g.ReleaseConditions[weapon.WeaponStoryReleaseConditionGroupId] {
|
for _, cond := range g.ReleaseConditions[weapon.WeaponStoryReleaseConditionGroupId] {
|
||||||
switch cond.WeaponStoryReleaseConditionType {
|
switch cond.WeaponStoryReleaseConditionType {
|
||||||
case model.WeaponStoryReleaseConditionTypeAcquisition:
|
case model.WeaponStoryReleaseConditionTypeAcquisition:
|
||||||
grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
if grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis) {
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
case model.WeaponStoryReleaseConditionTypeQuestClear:
|
case model.WeaponStoryReleaseConditionTypeQuestClear:
|
||||||
if qs, ok := user.Quests[cond.ConditionValue]; ok && qs.QuestStateType == model.UserQuestStateTypeCleared {
|
if qs, ok := user.Quests[cond.ConditionValue]; ok && qs.QuestStateType == model.UserQuestStateTypeCleared {
|
||||||
grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis)
|
if grantWeaponStoryUnlock(user, weaponId, cond.StoryIndex, nowMillis) {
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if changed {
|
||||||
|
g.LastChangedStoryWeaponIds = append(g.LastChangedStoryWeaponIds, weaponId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,11 +224,11 @@ func (g *PossessionGranter) populateWeaponSkillsAbilities(user *UserState, weapo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GrantWeaponStoryUnlock(user *UserState, weaponId, storyIndex int32, nowMillis int64) {
|
func GrantWeaponStoryUnlock(user *UserState, weaponId, storyIndex int32, nowMillis int64) bool {
|
||||||
grantWeaponStoryUnlock(user, weaponId, storyIndex, nowMillis)
|
return grantWeaponStoryUnlock(user, weaponId, storyIndex, nowMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
func grantWeaponStoryUnlock(user *UserState, weaponId, storyIndex int32, nowMillis int64) {
|
func grantWeaponStoryUnlock(user *UserState, weaponId, storyIndex int32, nowMillis int64) bool {
|
||||||
hasWeapon := false
|
hasWeapon := false
|
||||||
for _, row := range user.Weapons {
|
for _, row := range user.Weapons {
|
||||||
if row.WeaponId == weaponId {
|
if row.WeaponId == weaponId {
|
||||||
@@ -222,20 +238,21 @@ func grantWeaponStoryUnlock(user *UserState, weaponId, storyIndex int32, nowMill
|
|||||||
}
|
}
|
||||||
if !hasWeapon {
|
if !hasWeapon {
|
||||||
log.Printf("[grantWeaponStoryUnlock] skipping weaponId=%d (weapon not in user.Weapons)", weaponId)
|
log.Printf("[grantWeaponStoryUnlock] skipping weaponId=%d (weapon not in user.Weapons)", weaponId)
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
if user.WeaponStories == nil {
|
if user.WeaponStories == nil {
|
||||||
user.WeaponStories = make(map[int32]WeaponStoryState)
|
user.WeaponStories = make(map[int32]WeaponStoryState)
|
||||||
}
|
}
|
||||||
cur := user.WeaponStories[weaponId]
|
cur := user.WeaponStories[weaponId]
|
||||||
if storyIndex <= cur.ReleasedMaxStoryIndex {
|
if storyIndex <= cur.ReleasedMaxStoryIndex {
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
user.WeaponStories[weaponId] = WeaponStoryState{
|
user.WeaponStories[weaponId] = WeaponStoryState{
|
||||||
WeaponId: weaponId,
|
WeaponId: weaponId,
|
||||||
ReleasedMaxStoryIndex: storyIndex,
|
ReleasedMaxStoryIndex: storyIndex,
|
||||||
LatestVersion: nowMillis,
|
LatestVersion: nowMillis,
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnsureDefaultDeck(user *UserState, nowMillis int64) {
|
func EnsureDefaultDeck(user *UserState, nowMillis int64) {
|
||||||
|
|||||||
@@ -258,6 +258,27 @@ func sortedWeaponStoryRecords(user store.UserState) []map[string]any {
|
|||||||
return records
|
return records
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WeaponStoryRecordsForIds(user store.UserState, weaponIds []int32) string {
|
||||||
|
if len(weaponIds) == 0 {
|
||||||
|
return "[]"
|
||||||
|
}
|
||||||
|
records := make([]map[string]any, 0, len(weaponIds))
|
||||||
|
for _, weaponId := range weaponIds {
|
||||||
|
row, ok := user.WeaponStories[weaponId]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
records = append(records, map[string]any{
|
||||||
|
"userId": user.UserId,
|
||||||
|
"weaponId": row.WeaponId,
|
||||||
|
"releasedMaxStoryIndex": row.ReleasedMaxStoryIndex,
|
||||||
|
"latestVersion": row.LatestVersion,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s, _ := encodeJSONMaps(records...)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
func sortedWeaponNoteRecords(user store.UserState) []map[string]any {
|
func sortedWeaponNoteRecords(user store.UserState) []map[string]any {
|
||||||
weaponIds := make([]int32, 0, len(user.WeaponNotes))
|
weaponIds := make([]int32, 0, len(user.WeaponNotes))
|
||||||
for id := range user.WeaponNotes {
|
for id := range user.WeaponNotes {
|
||||||
|
|||||||
@@ -170,3 +170,13 @@ func BuildDiffFromTablesOrdered(tables map[string]string, order []string) map[st
|
|||||||
}
|
}
|
||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddWeaponStoryDiff(diff map[string]*pb.DiffData, user store.UserState, weaponIds []int32) {
|
||||||
|
if len(weaponIds) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
diff["IUserWeaponStory"] = &pb.DiffData{
|
||||||
|
UpdateRecordsJson: WeaponStoryRecordsForIds(user, weaponIds),
|
||||||
|
DeleteKeysJson: "[]",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user