fix: skip birthdays of characters we can't talk to (#2425)

Closes #2424

Reviewed-on: OpenWF/SpaceNinjaServer#2425
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2025-07-06 20:13:50 -07:00 committed by Sainan
parent ea3e299861
commit 76e61129bf
4 changed files with 93 additions and 60 deletions

View File

@ -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 { getAccountIdForRequest } from "@/src/services/loginService";
import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
import { getWorldState } from "@/src/services/worldStateService"; import { getWorldState } from "@/src/services/worldStateService";
@ -28,7 +28,7 @@ export const completeCalendarEventController: RequestHandler = async (req, res)
} }
} }
calendarProgress.SeasonProgress.LastCompletedDayIdx = dayIndex; calendarProgress.SeasonProgress.LastCompletedDayIdx = dayIndex;
checkCalendarChallengeCompletion(calendarProgress, currentSeason); checkCalendarAutoAdvance(inventory, currentSeason);
await inventory.save(); await inventory.save();
res.json({ res.json({
InventoryChanges: inventoryChanges, InventoryChanges: inventoryChanges,

View File

@ -12,6 +12,7 @@ import {
addEmailItem, addEmailItem,
addMiscItems, addMiscItems,
allDailyAffiliationKeys, allDailyAffiliationKeys,
checkCalendarAutoAdvance,
cleanupInventory, cleanupInventory,
createLibraryDailyTask, createLibraryDailyTask,
getCalendarProgress getCalendarProgress
@ -29,6 +30,7 @@ import { unixTimesInMs } from "@/src/constants/timeConstants";
import { DailyDeal } from "@/src/models/worldStateModel"; import { DailyDeal } from "@/src/models/worldStateModel";
import { EquipmentFeatures } from "@/src/types/equipmentTypes"; import { EquipmentFeatures } from "@/src/types/equipmentTypes";
import { generateRewardSeed } from "@/src/services/rngService"; import { generateRewardSeed } from "@/src/services/rngService";
import { getWorldState } from "@/src/services/worldStateService";
export const inventoryController: RequestHandler = async (request, response) => { export const inventoryController: RequestHandler = async (request, response) => {
const account = await getAccountForRequest(request); const account = await getAccountForRequest(request);
@ -111,13 +113,17 @@ export const inventoryController: RequestHandler = async (request, response) =>
} }
} }
if (inventory.CalendarProgress) { // TODO: Setup CalendarProgress as part of 1999 mission completion?
const previousYearIteration = inventory.CalendarProgress.Iteration;
getCalendarProgress(inventory); // handle year rollover; the client expects to receive an inventory with an up-to-date CalendarProgress 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 // also handle sending of kiss cinematic at year rollover
if ( if (
inventory.CalendarProgress.Iteration != previousYearIteration && inventory.CalendarProgress!.Iteration != previousYearIteration &&
inventory.DialogueHistory && inventory.DialogueHistory &&
inventory.DialogueHistory.Dialogues inventory.DialogueHistory.Dialogues
) { ) {
@ -164,7 +170,6 @@ export const inventoryController: RequestHandler = async (request, response) =>
await addEmailItem(inventory, "/Lotus/Types/Items/EmailItems/KalymosKissEmailItem"); await addEmailItem(inventory, "/Lotus/Types/Items/EmailItems/KalymosKissEmailItem");
} }
} }
}
cleanupInventory(inventory); cleanupInventory(inventory);

View File

@ -1216,8 +1216,8 @@ const calenderProgressSchema = new Schema<ICalendarProgress>(
}, },
SeasonProgress: { SeasonProgress: {
SeasonType: { type: String, required: true }, SeasonType: { type: String, required: true },
LastCompletedDayIdx: { type: Number, default: 0 }, LastCompletedDayIdx: { type: Number, default: -1 },
LastCompletedChallengeDayIdx: { type: Number, default: 0 }, LastCompletedChallengeDayIdx: { type: Number, default: -1 },
ActivatedChallenges: { type: [String], default: [] } ActivatedChallenges: { type: [String], default: [] }
} }
}, },

View File

@ -1897,7 +1897,7 @@ export const addCalendarProgress = (inventory: TInventoryDatabaseDocument, value
calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = currentSeason.Days.findIndex( calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = currentSeason.Days.findIndex(
day => day.events.length != 0 && day.events[0].challenge == value[value.length - 1].challenge 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 => { export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag, Completes, Tier }: IMission): void => {
@ -2082,8 +2082,8 @@ export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICal
}, },
SeasonProgress: { SeasonProgress: {
SeasonType: currentSeason.Season, SeasonType: currentSeason.Season,
LastCompletedDayIdx: 0, LastCompletedDayIdx: -1,
LastCompletedChallengeDayIdx: 0, LastCompletedChallengeDayIdx: -1,
ActivatedChallenges: [] ActivatedChallenges: []
} }
}; };
@ -2104,16 +2104,44 @@ export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICal
return inventory.CalendarProgress; return inventory.CalendarProgress;
}; };
export const checkCalendarChallengeCompletion = ( export const checkCalendarAutoAdvance = (
calendarProgress: ICalendarProgress, inventory: TInventoryDatabaseDocument,
currentSeason: ICalendarSeason currentSeason: ICalendarSeason
): void => { ): void => {
const dayIndex = calendarProgress.SeasonProgress.LastCompletedDayIdx + 1; const calendarProgress = inventory.CalendarProgress!;
if (calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx >= dayIndex) { for (
let dayIndex = calendarProgress.SeasonProgress.LastCompletedDayIdx + 1;
dayIndex != currentSeason.Days.length;
++dayIndex
) {
const day = currentSeason.Days[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`); //logger.debug(`already completed the challenge, skipping ahead`);
calendarProgress.SeasonProgress.LastCompletedDayIdx++; calendarProgress.SeasonProgress.LastCompletedDayIdx++;
} else {
break;
} }
} }
}; };