diff --git a/src/controllers/api/completeCalendarEventController.ts b/src/controllers/api/completeCalendarEventController.ts index 993b55c7..11aba85c 100644 --- a/src/controllers/api/completeCalendarEventController.ts +++ b/src/controllers/api/completeCalendarEventController.ts @@ -1,4 +1,4 @@ -import { checkCalendarChallengeCompletion, getCalendarProgress, getInventory } from "@/src/services/inventoryService"; +import { checkCalendarAutoAdvance, getCalendarProgress, getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; import { getWorldState } from "@/src/services/worldStateService"; @@ -28,7 +28,7 @@ export const completeCalendarEventController: RequestHandler = async (req, res) } } calendarProgress.SeasonProgress.LastCompletedDayIdx = dayIndex; - checkCalendarChallengeCompletion(calendarProgress, currentSeason); + checkCalendarAutoAdvance(inventory, currentSeason); await inventory.save(); res.json({ InventoryChanges: inventoryChanges, diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 05d6aec2..0d2e8ac7 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -12,6 +12,7 @@ import { addEmailItem, addMiscItems, allDailyAffiliationKeys, + checkCalendarAutoAdvance, cleanupInventory, createLibraryDailyTask, getCalendarProgress @@ -29,6 +30,7 @@ import { unixTimesInMs } from "@/src/constants/timeConstants"; import { DailyDeal } from "@/src/models/worldStateModel"; import { EquipmentFeatures } from "@/src/types/equipmentTypes"; import { generateRewardSeed } from "@/src/services/rngService"; +import { getWorldState } from "@/src/services/worldStateService"; export const inventoryController: RequestHandler = async (request, response) => { const account = await getAccountForRequest(request); @@ -111,58 +113,61 @@ export const inventoryController: RequestHandler = async (request, response) => } } - if (inventory.CalendarProgress) { - const previousYearIteration = inventory.CalendarProgress.Iteration; - getCalendarProgress(inventory); // handle year rollover; the client expects to receive an inventory with an up-to-date CalendarProgress + // TODO: Setup CalendarProgress as part of 1999 mission completion? - // also handle sending of kiss cinematic at year rollover - if ( - inventory.CalendarProgress.Iteration != previousYearIteration && - inventory.DialogueHistory && - inventory.DialogueHistory.Dialogues - ) { - let kalymos = false; - for (const { dialogueName, kissEmail } of [ - { - dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/ArthurDialogue_rom.dialogue", - kissEmail: "/Lotus/Types/Items/EmailItems/ArthurKissEmailItem" - }, - { - dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/EleanorDialogue_rom.dialogue", - kissEmail: "/Lotus/Types/Items/EmailItems/EleanorKissEmailItem" - }, - { - dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/LettieDialogue_rom.dialogue", - kissEmail: "/Lotus/Types/Items/EmailItems/LettieKissEmailItem" - }, - { - dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/JabirDialogue_rom.dialogue", - kissEmail: "/Lotus/Types/Items/EmailItems/AmirKissEmailItem" - }, - { - dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/AoiDialogue_rom.dialogue", - kissEmail: "/Lotus/Types/Items/EmailItems/AoiKissEmailItem" - }, - { - dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/QuincyDialogue_rom.dialogue", - kissEmail: "/Lotus/Types/Items/EmailItems/QuincyKissEmailItem" + const previousYearIteration = inventory.CalendarProgress?.Iteration; + + // We need to do the following to ensure the in-game calendar does not break: + getCalendarProgress(inventory); // Keep the CalendarProgress up-to-date (at least for the current year iteration) (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2364) + checkCalendarAutoAdvance(inventory, getWorldState().KnownCalendarSeasons[0]); // Skip birthday events for characters if we do not have them unlocked yet (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2424) + + // also handle sending of kiss cinematic at year rollover + if ( + inventory.CalendarProgress!.Iteration != previousYearIteration && + inventory.DialogueHistory && + inventory.DialogueHistory.Dialogues + ) { + let kalymos = false; + for (const { dialogueName, kissEmail } of [ + { + dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/ArthurDialogue_rom.dialogue", + kissEmail: "/Lotus/Types/Items/EmailItems/ArthurKissEmailItem" + }, + { + dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/EleanorDialogue_rom.dialogue", + kissEmail: "/Lotus/Types/Items/EmailItems/EleanorKissEmailItem" + }, + { + dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/LettieDialogue_rom.dialogue", + kissEmail: "/Lotus/Types/Items/EmailItems/LettieKissEmailItem" + }, + { + dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/JabirDialogue_rom.dialogue", + kissEmail: "/Lotus/Types/Items/EmailItems/AmirKissEmailItem" + }, + { + dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/AoiDialogue_rom.dialogue", + kissEmail: "/Lotus/Types/Items/EmailItems/AoiKissEmailItem" + }, + { + dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/QuincyDialogue_rom.dialogue", + kissEmail: "/Lotus/Types/Items/EmailItems/QuincyKissEmailItem" + } + ]) { + const dialogue = inventory.DialogueHistory.Dialogues.find(x => x.DialogueName == dialogueName); + if (dialogue) { + if (dialogue.Rank == 7) { + await addEmailItem(inventory, kissEmail); + kalymos = false; + break; } - ]) { - const dialogue = inventory.DialogueHistory.Dialogues.find(x => x.DialogueName == dialogueName); - if (dialogue) { - if (dialogue.Rank == 7) { - await addEmailItem(inventory, kissEmail); - kalymos = false; - break; - } - if (dialogue.Rank == 6) { - kalymos = true; - } + if (dialogue.Rank == 6) { + kalymos = true; } } - if (kalymos) { - await addEmailItem(inventory, "/Lotus/Types/Items/EmailItems/KalymosKissEmailItem"); - } + } + if (kalymos) { + await addEmailItem(inventory, "/Lotus/Types/Items/EmailItems/KalymosKissEmailItem"); } } diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index fe9a683a..32595cdd 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -1216,8 +1216,8 @@ const calenderProgressSchema = new Schema( }, SeasonProgress: { SeasonType: { type: String, required: true }, - LastCompletedDayIdx: { type: Number, default: 0 }, - LastCompletedChallengeDayIdx: { type: Number, default: 0 }, + LastCompletedDayIdx: { type: Number, default: -1 }, + LastCompletedChallengeDayIdx: { type: Number, default: -1 }, ActivatedChallenges: { type: [String], default: [] } } }, diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 6042e34f..5dd57c12 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -1897,7 +1897,7 @@ export const addCalendarProgress = (inventory: TInventoryDatabaseDocument, value calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = currentSeason.Days.findIndex( day => day.events.length != 0 && day.events[0].challenge == value[value.length - 1].challenge ); - checkCalendarChallengeCompletion(calendarProgress, currentSeason); + checkCalendarAutoAdvance(inventory, currentSeason); }; export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag, Completes, Tier }: IMission): void => { @@ -2082,8 +2082,8 @@ export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICal }, SeasonProgress: { SeasonType: currentSeason.Season, - LastCompletedDayIdx: 0, - LastCompletedChallengeDayIdx: 0, + LastCompletedDayIdx: -1, + LastCompletedChallengeDayIdx: -1, ActivatedChallenges: [] } }; @@ -2104,16 +2104,44 @@ export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICal return inventory.CalendarProgress; }; -export const checkCalendarChallengeCompletion = ( - calendarProgress: ICalendarProgress, +export const checkCalendarAutoAdvance = ( + inventory: TInventoryDatabaseDocument, currentSeason: ICalendarSeason ): void => { - const dayIndex = calendarProgress.SeasonProgress.LastCompletedDayIdx + 1; - if (calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx >= dayIndex) { + const calendarProgress = inventory.CalendarProgress!; + for ( + let dayIndex = calendarProgress.SeasonProgress.LastCompletedDayIdx + 1; + dayIndex != currentSeason.Days.length; + ++dayIndex + ) { const day = currentSeason.Days[dayIndex]; - if (day.events.length != 0 && day.events[0].type == "CET_CHALLENGE") { + if (day.events.length == 0) { + // birthday + if (day.day == 1) { + // kaya + if ((inventory.Affiliations.find(x => x.Tag == "HexSyndicate")?.Title || 0) >= 4) { + break; + } + logger.debug(`cannot talk to kaya, skipping birthday`); + calendarProgress.SeasonProgress.LastCompletedDayIdx++; + } else if (day.day == 74 || day.day == 355) { + // minerva, velimir + if ((inventory.Affiliations.find(x => x.Tag == "HexSyndicate")?.Title || 0) >= 5) { + break; + } + logger.debug(`cannot talk to minerva/velimir, skipping birthday`); + calendarProgress.SeasonProgress.LastCompletedDayIdx++; + } else { + break; + } + } else if (day.events[0].type == "CET_CHALLENGE") { + if (calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx < dayIndex) { + break; + } //logger.debug(`already completed the challenge, skipping ahead`); calendarProgress.SeasonProgress.LastCompletedDayIdx++; + } else { + break; } } };