mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Fix map replay flow and quest mission rewards
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:
@@ -35,7 +35,7 @@ func (h *QuestHandler) HandleBigHuntQuestFinish(user *store.UserState, questId i
|
||||
|
||||
outcome := h.evaluateFinishOutcome(user, questId)
|
||||
if !isRetired {
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis, false)
|
||||
}
|
||||
|
||||
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
||||
|
||||
@@ -44,7 +44,7 @@ func (h *QuestHandler) HandleEventQuestFinish(user *store.UserState, eventQuestC
|
||||
|
||||
outcome := h.evaluateFinishOutcome(user, questId)
|
||||
if !isRetired {
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis, false)
|
||||
}
|
||||
|
||||
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
||||
@@ -72,8 +72,7 @@ func (h *QuestHandler) HandleEventQuestRestart(user *store.UserState, eventQuest
|
||||
}
|
||||
|
||||
func (h *QuestHandler) HandleEventQuestSceneProgress(user *store.UserState, questSceneId int32, nowMillis int64) {
|
||||
scene, ok := h.SceneById[questSceneId]
|
||||
if !ok {
|
||||
if _, ok := h.SceneById[questSceneId]; !ok {
|
||||
log.Printf("[HandleEventQuestSceneProgress] unknown sceneId=%d, skipping", questSceneId)
|
||||
return
|
||||
}
|
||||
@@ -84,8 +83,4 @@ func (h *QuestHandler) HandleEventQuestSceneProgress(user *store.UserState, ques
|
||||
}
|
||||
|
||||
h.applySceneGrants(user, questSceneId, nowMillis)
|
||||
|
||||
if model.QuestResultType(scene.QuestResultType) == model.QuestResultTypeHalfResult {
|
||||
h.clearQuestMissions(user, scene.QuestId, nowMillis)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func (h *QuestHandler) HandleExtraQuestFinish(user *store.UserState, questId int
|
||||
|
||||
outcome := h.evaluateFinishOutcome(user, questId)
|
||||
if !isRetired {
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis, false)
|
||||
}
|
||||
|
||||
if isRetired && !isAnnihilated && quest.Stamina > 1 {
|
||||
@@ -67,8 +67,7 @@ func (h *QuestHandler) HandleExtraQuestRestart(user *store.UserState, questId in
|
||||
}
|
||||
|
||||
func (h *QuestHandler) HandleExtraQuestSceneProgress(user *store.UserState, questSceneId int32, nowMillis int64) {
|
||||
scene, ok := h.SceneById[questSceneId]
|
||||
if !ok {
|
||||
if _, ok := h.SceneById[questSceneId]; !ok {
|
||||
log.Printf("[HandleExtraQuestSceneProgress] unknown sceneId=%d, skipping", questSceneId)
|
||||
return
|
||||
}
|
||||
@@ -79,8 +78,4 @@ func (h *QuestHandler) HandleExtraQuestSceneProgress(user *store.UserState, ques
|
||||
}
|
||||
|
||||
h.applySceneGrants(user, questSceneId, nowMillis)
|
||||
|
||||
if model.QuestResultType(scene.QuestResultType) == model.QuestResultTypeHalfResult {
|
||||
h.clearQuestMissions(user, scene.QuestId, nowMillis)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,13 +78,9 @@ func (h *QuestHandler) handleQuestStartInternal(user *store.UserState, questId i
|
||||
log.Printf("[HandleQuestStart] QuestMenuPick quest=%d isBattleOnly=%v scene=%d cleared=%v",
|
||||
questId, isBattleOnly, sceneId, isCleared)
|
||||
|
||||
case isCleared && isReplayFlow:
|
||||
snapshotMainQuestIfNeeded(user)
|
||||
user.MainQuest.CurrentQuestFlowType = int32(model.QuestFlowTypeReplayFlow)
|
||||
user.MainQuest.ReplayFlowCurrentQuestSceneId = 0
|
||||
user.MainQuest.ReplayFlowHeadQuestSceneId = 0
|
||||
user.MainQuest.LatestVersion = nowMillis
|
||||
log.Printf("[HandleQuestStart] MapPlay quest=%d isBattleOnly=%v", questId, isBattleOnly)
|
||||
case isReplayFlow:
|
||||
h.applyReplayStart(user, questId, isBattleOnly, nowMillis)
|
||||
return
|
||||
}
|
||||
|
||||
if isCleared {
|
||||
@@ -129,6 +125,27 @@ func snapshotMainQuestIfNeeded(user *store.UserState) {
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve CurrentQuestFlowType when HandleReplayFlowSceneProgress already
|
||||
// set it: replay-variant ids (30000+) aren't in RouteIdByQuestId.
|
||||
func (h *QuestHandler) applyReplayStart(user *store.UserState, questId int32, isBattleOnly bool, nowMillis int64) {
|
||||
flowType := h.replayFlowTypeFromQuestId(user, questId)
|
||||
if model.IsReplayQuestFlowType(user.MainQuest.CurrentQuestFlowType) {
|
||||
flowType = model.QuestFlowType(user.MainQuest.CurrentQuestFlowType)
|
||||
}
|
||||
user.MainQuest.CurrentQuestFlowType = int32(flowType)
|
||||
user.MainQuest.LatestVersion = nowMillis
|
||||
|
||||
questState := user.Quests[questId]
|
||||
questState.QuestStateType = model.UserQuestStateTypeActive
|
||||
questState.LatestStartDatetime = nowMillis
|
||||
user.Quests[questId] = questState
|
||||
|
||||
log.Printf("[HandleQuestStart] replay quest=%d flowType=%s isBattleOnly=%v current=%d head=%d",
|
||||
questId, flowType, isBattleOnly,
|
||||
user.MainQuest.ReplayFlowCurrentQuestSceneId,
|
||||
user.MainQuest.ReplayFlowHeadQuestSceneId)
|
||||
}
|
||||
|
||||
func (h *QuestHandler) menuPickSceneId(questId int32, isBattleOnly bool) int32 {
|
||||
if isBattleOnly {
|
||||
if v, ok := h.BattleOnlyTargetSceneIdFor(questId); ok {
|
||||
@@ -141,14 +158,24 @@ func (h *QuestHandler) menuPickSceneId(questId int32, isBattleOnly bool) int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
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, wasReplay bool) {
|
||||
questState := user.Quests[questId]
|
||||
if !questState.IsRewardGranted {
|
||||
h.applyQuestRewards(user, questId, nowMillis)
|
||||
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeHalfResult, nowMillis)...)
|
||||
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeFullResult, nowMillis)...)
|
||||
h.applyExpAndGoldRewards(user, questId, nowMillis)
|
||||
if !wasReplay {
|
||||
h.applyFirstClearItemRewards(user, questId, nowMillis)
|
||||
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeHalfResult, nowMillis)...)
|
||||
outcome.ChangedWeaponStoryIds = append(outcome.ChangedWeaponStoryIds,
|
||||
h.grantWeaponStoryUnlocksForQuestScene(user, questId, model.QuestResultTypeFullResult, nowMillis)...)
|
||||
}
|
||||
|
||||
for _, r := range outcome.MissionClearRewards {
|
||||
h.applyRewardPossession(user, r.PossessionType, r.PossessionId, r.Count, nowMillis)
|
||||
}
|
||||
for _, r := range outcome.MissionClearCompleteRewards {
|
||||
h.applyRewardPossession(user, r.PossessionType, r.PossessionId, r.Count, nowMillis)
|
||||
}
|
||||
questState.IsRewardGranted = true
|
||||
}
|
||||
for _, drop := range outcome.DropRewards {
|
||||
@@ -197,13 +224,13 @@ func (h *QuestHandler) HandleQuestFinish(user *store.UserState, questId int32, i
|
||||
h.initQuestState(user, questId)
|
||||
|
||||
outcome := h.evaluateFinishOutcome(user, questId)
|
||||
wasReplay := user.MainQuest.CurrentQuestFlowType == int32(model.QuestFlowTypeReplayFlow)
|
||||
wasReplay := model.IsReplayQuestFlowType(user.MainQuest.CurrentQuestFlowType)
|
||||
wasMenuReplay := user.MainQuest.SavedContext.Active
|
||||
|
||||
if !isRetired {
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis)
|
||||
h.applyQuestVictory(user, questId, &outcome, nowMillis, wasReplay)
|
||||
|
||||
if isMainQuestPlayable(quest) && !wasReplay && !wasMenuReplay {
|
||||
if isMainQuestPlayable(quest) && !wasMenuReplay {
|
||||
lastSceneId := h.getLastMainFlowSceneId(questId)
|
||||
h.advanceMainFlowScene(user, questId, lastSceneId)
|
||||
}
|
||||
@@ -229,8 +256,12 @@ func (h *QuestHandler) HandleQuestFinish(user *store.UserState, questId int32, i
|
||||
|
||||
user.MainQuest.ProgressQuestSceneId = 0
|
||||
user.MainQuest.ProgressHeadQuestSceneId = 0
|
||||
user.MainQuest.ProgressQuestFlowType = 0
|
||||
user.MainQuest.CurrentQuestFlowType = int32(model.QuestFlowTypeMainFlow)
|
||||
if !wasReplay {
|
||||
// Keep replay flow types on replay finish so the client's
|
||||
// Story.ApplyNewestPlayingScene keeps _isReplayed=true (popup result UI).
|
||||
user.MainQuest.ProgressQuestFlowType = 0
|
||||
user.MainQuest.CurrentQuestFlowType = int32(model.QuestFlowTypeUnknown)
|
||||
}
|
||||
|
||||
if wasMenuReplay {
|
||||
ctx := user.MainQuest.SavedContext
|
||||
@@ -248,12 +279,6 @@ func (h *QuestHandler) HandleQuestFinish(user *store.UserState, questId int32, i
|
||||
ctx.CurrentQuestSceneId, ctx.HeadQuestSceneId, ctx.PortalCageInProgress)
|
||||
}
|
||||
|
||||
if wasReplay {
|
||||
user.MainQuest.ReplayFlowCurrentQuestSceneId = 0
|
||||
user.MainQuest.ReplayFlowHeadQuestSceneId = 0
|
||||
log.Printf("[HandleQuestFinish] replay flow ended for quest %d", questId)
|
||||
}
|
||||
|
||||
h.clearQuestMissions(user, questId, nowMillis)
|
||||
|
||||
return outcome
|
||||
|
||||
@@ -51,7 +51,9 @@ func (h *QuestHandler) evaluateFinishOutcome(user *store.UserState, questId int3
|
||||
panic(fmt.Sprintf("unknown questId=%d for evaluateFinishOutcome", questId))
|
||||
}
|
||||
|
||||
if !questState.IsRewardGranted {
|
||||
isReplay := model.IsReplayQuestFlowType(user.MainQuest.CurrentQuestFlowType)
|
||||
|
||||
if !questState.IsRewardGranted && !isReplay {
|
||||
rewardGroupId := h.firstClearRewardGroupId(user, questDef)
|
||||
for _, reward := range h.FirstClearRewardsByGroupId[rewardGroupId] {
|
||||
outcome.FirstClearRewards = append(outcome.FirstClearRewards, RewardGrant{
|
||||
@@ -62,7 +64,7 @@ func (h *QuestHandler) evaluateFinishOutcome(user *store.UserState, questId int3
|
||||
}
|
||||
}
|
||||
|
||||
if user.MainQuest.CurrentQuestFlowType == int32(model.QuestFlowTypeReplayFlow) && questDef.QuestReplayFlowRewardGroupId > 0 {
|
||||
if isReplay && questDef.QuestReplayFlowRewardGroupId > 0 {
|
||||
for _, reward := range h.ReplayFlowRewardsByGroupId[questDef.QuestReplayFlowRewardGroupId] {
|
||||
outcome.ReplayFlowFirstClearRewards = append(outcome.ReplayFlowFirstClearRewards, RewardGrant{
|
||||
PossessionType: model.PossessionType(reward.PossessionType),
|
||||
@@ -72,48 +74,53 @@ func (h *QuestHandler) evaluateFinishOutcome(user *store.UserState, questId int3
|
||||
}
|
||||
}
|
||||
|
||||
pendingClearCount := 0
|
||||
regularMissionCount := 0
|
||||
for _, questMissionId := range h.MissionIdsByQuestId[questId] {
|
||||
missionDef, ok := h.MissionById[questMissionId]
|
||||
if !ok || model.QuestMissionConditionType(missionDef.QuestMissionConditionType) == model.QuestMissionConditionTypeComplete {
|
||||
continue
|
||||
}
|
||||
regularMissionCount++
|
||||
|
||||
key := store.QuestMissionKey{QuestId: questId, QuestMissionId: questMissionId}
|
||||
mission := user.QuestMissions[key]
|
||||
|
||||
if !mission.IsClear {
|
||||
pendingClearCount++
|
||||
outcome.MissionClearRewards = appendMissionRewards(
|
||||
outcome.MissionClearRewards,
|
||||
h.MissionRewardsByMissionId[missionDef.QuestMissionRewardId],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
priorClearCount := regularMissionCount - pendingClearCount
|
||||
// On our server every mission auto-clears, so priorClearCount + pendingClearCount
|
||||
// always equals regularMissionCount. The two-variable form is kept to mirror the
|
||||
// original game's intent where individual missions could fail their conditions.
|
||||
allRegularWillClear := regularMissionCount > 0 && (priorClearCount+pendingClearCount) == regularMissionCount
|
||||
if allRegularWillClear {
|
||||
// Mission rewards / BigWin are first-clear concepts. Reference
|
||||
// IUserQuestMissionTable has no rows for replay-variant ids (30000+):
|
||||
// the popup is empty on replay in the original game.
|
||||
if !isReplay {
|
||||
pendingClearCount := 0
|
||||
regularMissionCount := 0
|
||||
for _, questMissionId := range h.MissionIdsByQuestId[questId] {
|
||||
missionDef, ok := h.MissionById[questMissionId]
|
||||
if !ok || model.QuestMissionConditionType(missionDef.QuestMissionConditionType) != model.QuestMissionConditionTypeComplete {
|
||||
if !ok || model.QuestMissionConditionType(missionDef.QuestMissionConditionType) == model.QuestMissionConditionTypeComplete {
|
||||
continue
|
||||
}
|
||||
regularMissionCount++
|
||||
|
||||
key := store.QuestMissionKey{QuestId: questId, QuestMissionId: questMissionId}
|
||||
if !user.QuestMissions[key].IsClear {
|
||||
outcome.MissionClearCompleteRewards = appendMissionRewards(
|
||||
outcome.MissionClearCompleteRewards,
|
||||
mission := user.QuestMissions[key]
|
||||
|
||||
if !mission.IsClear {
|
||||
pendingClearCount++
|
||||
outcome.MissionClearRewards = appendMissionRewards(
|
||||
outcome.MissionClearRewards,
|
||||
h.MissionRewardsByMissionId[missionDef.QuestMissionRewardId],
|
||||
)
|
||||
outcome.BigWinClearedQuestMissionIds = append(outcome.BigWinClearedQuestMissionIds, questMissionId)
|
||||
}
|
||||
}
|
||||
outcome.IsBigWin = len(outcome.BigWinClearedQuestMissionIds) > 0
|
||||
|
||||
priorClearCount := regularMissionCount - pendingClearCount
|
||||
// On our server every mission auto-clears, so priorClearCount + pendingClearCount
|
||||
// always equals regularMissionCount. The two-variable form is kept to mirror the
|
||||
// original game's intent where individual missions could fail their conditions.
|
||||
allRegularWillClear := regularMissionCount > 0 && (priorClearCount+pendingClearCount) == regularMissionCount
|
||||
if allRegularWillClear {
|
||||
for _, questMissionId := range h.MissionIdsByQuestId[questId] {
|
||||
missionDef, ok := h.MissionById[questMissionId]
|
||||
if !ok || model.QuestMissionConditionType(missionDef.QuestMissionConditionType) != model.QuestMissionConditionTypeComplete {
|
||||
continue
|
||||
}
|
||||
key := store.QuestMissionKey{QuestId: questId, QuestMissionId: questMissionId}
|
||||
if !user.QuestMissions[key].IsClear {
|
||||
outcome.MissionClearCompleteRewards = appendMissionRewards(
|
||||
outcome.MissionClearCompleteRewards,
|
||||
h.MissionRewardsByMissionId[missionDef.QuestMissionRewardId],
|
||||
)
|
||||
outcome.BigWinClearedQuestMissionIds = append(outcome.BigWinClearedQuestMissionIds, questMissionId)
|
||||
}
|
||||
}
|
||||
outcome.IsBigWin = len(outcome.BigWinClearedQuestMissionIds) > 0
|
||||
}
|
||||
}
|
||||
|
||||
outcome.DropRewards = h.computeDropRewards(questDef)
|
||||
@@ -240,7 +247,7 @@ func (h *QuestHandler) resolveDeckUnits(user *store.UserState, questId int32) (c
|
||||
return costumeUuids, characterIds
|
||||
}
|
||||
|
||||
func (h *QuestHandler) applyQuestRewards(user *store.UserState, questId int32, nowMillis int64) {
|
||||
func (h *QuestHandler) applyExpAndGoldRewards(user *store.UserState, questId int32, nowMillis int64) {
|
||||
questDef, ok := h.QuestById[questId]
|
||||
if !ok {
|
||||
return
|
||||
@@ -252,13 +259,24 @@ func (h *QuestHandler) applyQuestRewards(user *store.UserState, questId int32, n
|
||||
user.ConsumableItems[h.Config.ConsumableItemIdForGold] += questDef.Gold
|
||||
log.Printf("[applyQuestRewards] questId=%d gold: +%d -> total=%d", questId, questDef.Gold, user.ConsumableItems[h.Config.ConsumableItemIdForGold])
|
||||
}
|
||||
}
|
||||
|
||||
func (h *QuestHandler) applyFirstClearItemRewards(user *store.UserState, questId int32, nowMillis int64) {
|
||||
questDef, ok := h.QuestById[questId]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
rewardGroupId := h.firstClearRewardGroupId(user, questDef)
|
||||
for _, reward := range h.FirstClearRewardsByGroupId[rewardGroupId] {
|
||||
h.applyRewardPossession(user, model.PossessionType(reward.PossessionType), reward.PossessionId, reward.Count, nowMillis)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *QuestHandler) applyQuestRewards(user *store.UserState, questId int32, nowMillis int64) {
|
||||
h.applyExpAndGoldRewards(user, questId, nowMillis)
|
||||
h.applyFirstClearItemRewards(user, questId, nowMillis)
|
||||
}
|
||||
|
||||
func (h *QuestHandler) applyRewardPossession(user *store.UserState, possType model.PossessionType, possId, count int32, nowMillis int64) {
|
||||
h.Granter.GrantFull(user, possType, possId, count, nowMillis)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package questflow
|
||||
|
||||
// MainQuest scene-field families mirror three client entity tables:
|
||||
//
|
||||
// MainFlow* — EntityIUserMainQuestMainFlowStatus (#11443)
|
||||
// Progress* — EntityIUserMainQuestProgressStatus (#11444)
|
||||
// ReplayFlow* — EntityIUserMainQuestReplayFlowStatus (#11445)
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
@@ -45,10 +51,8 @@ func (h *QuestHandler) advanceMainFlowScene(user *store.UserState, questId, scen
|
||||
}
|
||||
}
|
||||
|
||||
// RecordSeasonRoute upserts the (season, route) pair into the player's history,
|
||||
// bumping LatestVersion on first insert. The history backs IUserMainQuestSeasonRoute,
|
||||
// which the client uses to know which chapters' scene metadata to load (so cage
|
||||
// menu-replay can transition to quests from older chapters without crashing).
|
||||
// Backs IUserMainQuestSeasonRoute: the client needs the history to load
|
||||
// scene metadata when cage menu-replay jumps to older chapters.
|
||||
func RecordSeasonRoute(user *store.UserState, seasonId, routeId int32, nowMillis int64) {
|
||||
if seasonId <= 0 || routeId <= 0 {
|
||||
return
|
||||
@@ -133,11 +137,48 @@ func (h *QuestHandler) getChapterLastSceneId(questId int32) int32 {
|
||||
|
||||
func (h *QuestHandler) HandleReplayFlowSceneProgress(user *store.UserState, questSceneId int32, nowMillis int64) {
|
||||
user.MainQuest.ReplayFlowCurrentQuestSceneId = questSceneId
|
||||
if user.MainQuest.ReplayFlowHeadQuestSceneId == 0 || h.isSceneAhead(questSceneId, user.MainQuest.ReplayFlowHeadQuestSceneId) {
|
||||
user.MainQuest.ReplayFlowHeadQuestSceneId = questSceneId
|
||||
}
|
||||
user.MainQuest.ReplayFlowHeadQuestSceneId = questSceneId
|
||||
|
||||
user.PortalCageStatus.IsCurrentProgress = false
|
||||
user.PortalCageStatus.LatestVersion = nowMillis
|
||||
|
||||
flowType := h.replayFlowType(user, questSceneId)
|
||||
user.MainQuest.CurrentQuestFlowType = int32(flowType)
|
||||
user.MainQuest.LatestVersion = nowMillis
|
||||
log.Printf("[HandleReplayFlowSceneProgress] sceneId=%d replayHead=%d", questSceneId, user.MainQuest.ReplayFlowHeadQuestSceneId)
|
||||
log.Printf("[HandleReplayFlowSceneProgress] sceneId=%d flowType=%s", questSceneId, flowType)
|
||||
}
|
||||
|
||||
func (h *QuestHandler) replayFlowType(user *store.UserState, questSceneId int32) model.QuestFlowType {
|
||||
scene, ok := h.SceneById[questSceneId]
|
||||
if !ok {
|
||||
return model.QuestFlowTypeReplayFlow
|
||||
}
|
||||
routeId, ok := h.RouteIdByQuestId[scene.QuestId]
|
||||
if !ok {
|
||||
return model.QuestFlowTypeReplayFlow
|
||||
}
|
||||
return h.replayFlowTypeForRoute(user, routeId)
|
||||
}
|
||||
|
||||
func (h *QuestHandler) replayFlowTypeForRoute(user *store.UserState, routeId int32) model.QuestFlowType {
|
||||
seasonId, ok := h.SeasonIdByRouteId[routeId]
|
||||
if !ok {
|
||||
return model.QuestFlowTypeReplayFlow
|
||||
}
|
||||
for key, entry := range user.MainQuestSeasonRoutes {
|
||||
if key.MainQuestSeasonId == seasonId && entry.MainQuestRouteId != routeId {
|
||||
return model.QuestFlowTypeAnotherRouteReplayFlow
|
||||
}
|
||||
}
|
||||
return model.QuestFlowTypeReplayFlow
|
||||
}
|
||||
|
||||
func (h *QuestHandler) replayFlowTypeFromQuestId(user *store.UserState, questId int32) model.QuestFlowType {
|
||||
routeId, ok := h.RouteIdByQuestId[questId]
|
||||
if !ok {
|
||||
return model.QuestFlowTypeReplayFlow
|
||||
}
|
||||
return h.replayFlowTypeForRoute(user, routeId)
|
||||
}
|
||||
|
||||
func (h *QuestHandler) HandleMainQuestSceneProgress(user *store.UserState, questSceneId int32) {
|
||||
@@ -153,22 +194,27 @@ func (h *QuestHandler) HandleMainQuestSceneProgress(user *store.UserState, quest
|
||||
|
||||
if prevSceneId := user.MainQuest.ProgressQuestSceneId; prevSceneId != 0 {
|
||||
if prevScene, ok := h.SceneById[prevSceneId]; ok && prevScene.QuestId != quest.QuestId {
|
||||
h.finalizeChainPreviousQuest(user, prevScene.QuestId, gametime.NowMillis())
|
||||
// Skip if the previous quest is playable — it has its own FinishMainQuest;
|
||||
// chain-finalizing here would double-increment ClearCount.
|
||||
if prevQuest, ok := h.QuestById[prevScene.QuestId]; ok && !isMainQuestPlayable(prevQuest) {
|
||||
h.finalizeChainPreviousQuest(user, prevScene.QuestId, gametime.NowMillis())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isMainQuestPlayable(quest) {
|
||||
if model.QuestResultType(scene.QuestResultType) == model.QuestResultTypeHalfResult {
|
||||
nowMillis := gametime.NowMillis()
|
||||
h.clearQuestMissions(user, quest.QuestId, nowMillis)
|
||||
}
|
||||
isReplay := model.IsReplayQuestFlowType(user.MainQuest.CurrentQuestFlowType)
|
||||
|
||||
if isMainQuestPlayable(quest) {
|
||||
user.MainQuest.ProgressQuestSceneId = questSceneId
|
||||
if h.isSceneAhead(questSceneId, user.MainQuest.ProgressHeadQuestSceneId) {
|
||||
user.MainQuest.ProgressHeadQuestSceneId = questSceneId
|
||||
}
|
||||
user.MainQuest.CurrentQuestFlowType = int32(model.QuestFlowTypeSubFlow)
|
||||
user.MainQuest.ProgressQuestFlowType = int32(model.QuestFlowTypeSubFlow)
|
||||
if isReplay {
|
||||
user.MainQuest.ProgressQuestFlowType = user.MainQuest.CurrentQuestFlowType
|
||||
} else {
|
||||
user.MainQuest.CurrentQuestFlowType = int32(model.QuestFlowTypeSubFlow)
|
||||
user.MainQuest.ProgressQuestFlowType = int32(model.QuestFlowTypeSubFlow)
|
||||
}
|
||||
} else {
|
||||
user.MainQuest.CurrentQuestSceneId = questSceneId
|
||||
if h.isSceneAhead(questSceneId, user.MainQuest.HeadQuestSceneId) {
|
||||
@@ -177,4 +223,12 @@ func (h *QuestHandler) HandleMainQuestSceneProgress(user *store.UserState, quest
|
||||
lastSceneId := h.getChapterLastSceneId(quest.QuestId)
|
||||
user.MainQuest.IsReachedLastQuestScene = questSceneId == lastSceneId
|
||||
}
|
||||
|
||||
if isReplay {
|
||||
user.MainQuest.ReplayFlowCurrentQuestSceneId = questSceneId
|
||||
if h.isSceneAhead(questSceneId, user.MainQuest.ReplayFlowHeadQuestSceneId) {
|
||||
user.MainQuest.ReplayFlowHeadQuestSceneId = questSceneId
|
||||
}
|
||||
user.MainQuest.LatestVersion = gametime.NowMillis()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user