Filter out event quests from data prior to sending them to player
Rework season service to use enum instead of magic strings for event names Add config property to control showing/hiding non-seasonal event quests from player
This commit is contained in:
parent
cad5dcd679
commit
ad6b94d8a9
@ -14,6 +14,121 @@
|
||||
"exploration": "62825ef60e88d037dc1eb42c"
|
||||
}
|
||||
},
|
||||
"showNonSeasonalEventQuests": false
|
||||
"eventQuests": {
|
||||
"641dbfd7f43eda9d810d7137": {
|
||||
"name": "Important Patient",
|
||||
"season": "None",
|
||||
"startTimestamp": 1333753200000,
|
||||
"endTimestamp": 1334444400000,
|
||||
"yearly": false
|
||||
},
|
||||
"64764abcd125ab430a14ccb5": {
|
||||
"name": "Bloodhounds",
|
||||
"season": "None",
|
||||
"startTimestamp": 1338591600000,
|
||||
"endTimestamp": 1340578800000,
|
||||
"yearly": false
|
||||
},
|
||||
"647710905320c660d91c15a5": {
|
||||
"name": "Hint",
|
||||
"season": "None",
|
||||
"startTimestamp": 1338591600000,
|
||||
"endTimestamp": ,
|
||||
"yearly": false
|
||||
},
|
||||
"649567f359eab30d1b7c9585": {
|
||||
"name": "Hustle",
|
||||
"season": "None",
|
||||
"startTimestamp": 1341270000000,
|
||||
"endTimestamp": ,
|
||||
"yearly": false
|
||||
},
|
||||
"649570491bb4d158bc4d0168": {
|
||||
"name": "Tourist",
|
||||
"season": "None",
|
||||
"startTimestamp": 1341270000000,
|
||||
"endTimestamp": "",
|
||||
"yearly": false
|
||||
},
|
||||
"64916da7ad4e722c106f2345": {
|
||||
"name": "Failed setup",
|
||||
"season": "None",
|
||||
"startTimestamp": 1340665200000,
|
||||
"endTimestamp": "",
|
||||
"yearly": false
|
||||
},
|
||||
"649af47d717cb30e7e4b5e26": {
|
||||
"name": "Cocktail Tasting",
|
||||
"season": "None",
|
||||
"startTimestamp": 1341615600000,
|
||||
"endTimestamp": "",
|
||||
"yearly": false
|
||||
},
|
||||
"61bb474dce7374453b45dfd2": {
|
||||
"name": "Fairy Tale Showdown",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61bb474b1ab5304c3817a53a": {
|
||||
"name": "Disrupting the Party",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61bb47481908c67d4249a205": {
|
||||
"name": "No Gifts for You",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61bb468b8d7cac1532300ccc": {
|
||||
"name": "Party Preparations",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61b9e1aaef9a1b5d6a79899a": {
|
||||
"name": "Santas bag",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61bb47516b70332c062ca7b9": {
|
||||
"name": "Stop the Fight!",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61bb475467f83663e155e26a": {
|
||||
"name": "A Kind Snow Maiden",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61bb4756883b2c16a163870a": {
|
||||
"name": "Home Comfort",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
},
|
||||
"61bb47578d7cac1532300ccd": {
|
||||
"name": "Bad Santa",
|
||||
"season": "christmas",
|
||||
"startTimestamp": 1701388800000,
|
||||
"endTimestamp": 1703980800000,
|
||||
"yearly": true
|
||||
}
|
||||
},
|
||||
"repeatableQuests": [{
|
||||
"name": "Daily",
|
||||
"side": "Pmc",
|
||||
|
@ -218,14 +218,16 @@
|
||||
],
|
||||
"events": [{
|
||||
"name": "halloween",
|
||||
"type": "HALLOWEEN",
|
||||
"startDay": "24",
|
||||
"startMonth": "10",
|
||||
"endDay": "4",
|
||||
"endMonth": "11"
|
||||
}, {
|
||||
"name": "christmas",
|
||||
"startDay": "16",
|
||||
"startMonth": "12",
|
||||
"type": "CHRISTMAS",
|
||||
"startDay": "7",
|
||||
"startMonth": "7",
|
||||
"endDay": "31",
|
||||
"endMonth": "12"
|
||||
}
|
||||
|
@ -153,6 +153,7 @@ export class GameController
|
||||
}
|
||||
}
|
||||
|
||||
/** Check for any missing assorts inside each traders assort.json data, checking against traders qeustassort.json */
|
||||
protected validateQuestAssortUnlocksExist(): void
|
||||
{
|
||||
const db = this.databaseServer.getTables();
|
||||
@ -176,7 +177,8 @@ export class GameController
|
||||
// Does assort key exist in trader assort file
|
||||
if (!traderAssorts.loyal_level_items[assortKey])
|
||||
{
|
||||
this.logger.warning(this.localisationService.getText("assort-missing_quest_assort_unlocks", {traderName: Object.keys(Traders)[Object.values(Traders).indexOf(traderId)], questName: quests[questKey].QuestName}));
|
||||
// reverse lookup of enum key by value
|
||||
this.logger.warning(this.localisationService.getText("assort-missing_quest_assort_unlock", {traderName: Object.keys(Traders)[Object.values(Traders).indexOf(traderId)], questName: quests[questKey].QuestName}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { SeasonalEventType } from "@spt-aki/models/enums/SeasonalEventType";
|
||||
import { DialogueHelper } from "../helpers/DialogueHelper";
|
||||
import { ItemHelper } from "../helpers/ItemHelper";
|
||||
import { ProfileHelper } from "../helpers/ProfileHelper";
|
||||
@ -26,6 +27,7 @@ import { DatabaseServer } from "../servers/DatabaseServer";
|
||||
import { LocaleService } from "../services/LocaleService";
|
||||
import { LocalisationService } from "../services/LocalisationService";
|
||||
import { PlayerService } from "../services/PlayerService";
|
||||
import { SeasonalEventService } from "../services/SeasonalEventService";
|
||||
import { HttpResponseUtil } from "../utils/HttpResponseUtil";
|
||||
import { TimeUtil } from "../utils/TimeUtil";
|
||||
|
||||
@ -47,6 +49,7 @@ export class QuestController
|
||||
@inject("QuestConditionHelper") protected questConditionHelper: QuestConditionHelper,
|
||||
@inject("PlayerService") protected playerService: PlayerService,
|
||||
@inject("LocaleService") protected localeService: LocaleService,
|
||||
@inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService,
|
||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer
|
||||
)
|
||||
@ -54,7 +57,6 @@ export class QuestController
|
||||
this.questConfig = this.configServer.getConfig(ConfigTypes.QUEST);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all quests visible to player
|
||||
* Exclude quests with incomplete preconditions (level/loyalty)
|
||||
@ -66,21 +68,42 @@ export class QuestController
|
||||
const quests: IQuest[] = [];
|
||||
const allQuests = this.questHelper.getQuestsFromDb();
|
||||
const profile: IPmcData = this.profileHelper.getPmcProfile(sessionID);
|
||||
const isChristmasEventActive = this.seasonalEventService.christmasEventEnabled();
|
||||
const isHalloweenEventActive = this.seasonalEventService.halloweenEventEnabled();
|
||||
|
||||
for (const quest of allQuests)
|
||||
{
|
||||
// If a quest is already in the profile we need to just add it
|
||||
// Player already accepted the quest, show it regardless of status
|
||||
if (profile.Quests.some(x => x.qid === quest._id))
|
||||
{
|
||||
quests.push(quest);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filter out bear quests for usec and vice versa
|
||||
if (this.questIsForOtherSide(profile.Info.Side, quest._id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not christmas
|
||||
if (!isChristmasEventActive && this.seasonalEventService.isQuestRelatedToEvent(quest._id, SeasonalEventType.CHRISTMAS))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not halloween + quest is for halloween
|
||||
if (!isHalloweenEventActive && this.seasonalEventService.isQuestRelatedToEvent(quest._id, SeasonalEventType.HALLOWEEN))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Should event quests be shown to player
|
||||
if (!this.questConfig.showNonSeasonalEventQuests && this.seasonalEventService.isQuestRelatedToEvent(quest._id, SeasonalEventType.NONE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't add quests that have a level higher than the user's
|
||||
const levelConditions = this.questConditionHelper.getLevelConditions(quest.conditions.AvailableForStart);
|
||||
if (levelConditions.length)
|
||||
|
6
project/src/models/enums/SeasonalEventType.ts
Normal file
6
project/src/models/enums/SeasonalEventType.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export enum SeasonalEventType
|
||||
{
|
||||
NONE = "None",
|
||||
CHRISTMAS = "Christmas",
|
||||
HALLOWEEN = "Halloween"
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { MinMax } from "../../../models/common/MinMax";
|
||||
import { SeasonalEventType } from "../../../models/enums/SeasonalEventType";
|
||||
import { ELocationName } from "../../enums/ELocationName";
|
||||
import { IBaseConfig } from "./IBaseConfig";
|
||||
|
||||
@ -7,6 +8,9 @@ export interface IQuestConfig extends IBaseConfig
|
||||
kind: "aki-quest"
|
||||
redeemTime: number
|
||||
questTemplateIds: IPlayerTypeQuestIds
|
||||
/** Show non-seasonal quests be shown to player */
|
||||
showNonSeasonalEventQuests: boolean
|
||||
eventQuests: Record<string, IEventQuestData>
|
||||
repeatableQuests: IRepeatableQuestConfig[]
|
||||
locationIdMap: Record<string, string>
|
||||
bearOnlyQuests: string[]
|
||||
@ -26,6 +30,15 @@ export interface IQuestTypeIds
|
||||
Exploration: string
|
||||
}
|
||||
|
||||
export interface IEventQuestData
|
||||
{
|
||||
name: string
|
||||
season: SeasonalEventType
|
||||
startTimestamp: number
|
||||
endTimestamp: number
|
||||
yearly: boolean
|
||||
}
|
||||
|
||||
export interface IRepeatableQuestConfig
|
||||
{
|
||||
name: string
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { SeasonalEventType } from "../../../models/enums/SeasonalEventType";
|
||||
import { IBaseConfig } from "./IBaseConfig";
|
||||
|
||||
export interface ISeasonalEventConfig extends IBaseConfig
|
||||
@ -13,6 +14,7 @@ export interface ISeasonalEventConfig extends IBaseConfig
|
||||
export interface ISeasonalEvent
|
||||
{
|
||||
name: string
|
||||
type: SeasonalEventType
|
||||
startDay: number
|
||||
startMonth: number
|
||||
endDay: number
|
||||
|
@ -4,6 +4,8 @@ import { BotHelper } from "../helpers/BotHelper";
|
||||
import { Config } from "../models/eft/common/IGlobals";
|
||||
import { Inventory } from "../models/eft/common/tables/IBotType";
|
||||
import { ConfigTypes } from "../models/enums/ConfigTypes";
|
||||
import { SeasonalEventType } from "../models/enums/SeasonalEventType";
|
||||
import { IQuestConfig } from "../models/spt/config/IQuestConfig";
|
||||
import { ISeasonalEvent, ISeasonalEventConfig } from "../models/spt/config/ISeasonalEventConfig";
|
||||
import { ILocationData } from "../models/spt/server/ILocations";
|
||||
import { ILogger } from "../models/spt/utils/ILogger";
|
||||
@ -15,6 +17,7 @@ import { LocalisationService } from "./LocalisationService";
|
||||
export class SeasonalEventService
|
||||
{
|
||||
protected seasonalEventConfig: ISeasonalEventConfig;
|
||||
protected questConfig: IQuestConfig;
|
||||
|
||||
constructor(
|
||||
@inject("WinstonLogger") protected logger: ILogger,
|
||||
@ -25,15 +28,7 @@ export class SeasonalEventService
|
||||
)
|
||||
{
|
||||
this.seasonalEventConfig = this.configServer.getConfig(ConfigTypes.SEASONAL_EVENT);
|
||||
}
|
||||
|
||||
protected get events(): Record<string, string>
|
||||
{
|
||||
return {
|
||||
"None": "None",
|
||||
"Christmas": "Christmas",
|
||||
"Halloween": "Halloween"
|
||||
};
|
||||
this.questConfig = this.configServer.getConfig(ConfigTypes.QUEST);
|
||||
}
|
||||
|
||||
protected get christmasEventItems(): string[]
|
||||
@ -144,26 +139,26 @@ export class SeasonalEventService
|
||||
*/
|
||||
public seasonalEventEnabled(): boolean
|
||||
{
|
||||
return this.databaseServer.getTables().globals.config.EventType.includes(this.events.Christmas) ||
|
||||
this.databaseServer.getTables().globals.config.EventType.includes(this.events.Halloween);
|
||||
return this.databaseServer.getTables().globals.config.EventType.includes(SeasonalEventType.CHRISTMAS) ||
|
||||
this.databaseServer.getTables().globals.config.EventType.includes(SeasonalEventType.HALLOWEEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* is christmas event active
|
||||
* Is christmas event active (Globals eventtype array contains even name)
|
||||
* @returns true if active
|
||||
*/
|
||||
public christmasEventEnabled(): boolean
|
||||
{
|
||||
return this.databaseServer.getTables().globals.config.EventType.includes(this.events.Christmas);
|
||||
return this.databaseServer.getTables().globals.config.EventType.includes(SeasonalEventType.CHRISTMAS);
|
||||
}
|
||||
|
||||
/**
|
||||
* is christmas event active
|
||||
* is halloween event active (Globals eventtype array contains even name)
|
||||
* @returns true if active
|
||||
*/
|
||||
public halloweenEventEnabled(): boolean
|
||||
{
|
||||
return this.databaseServer.getTables().globals.config.EventType.includes(this.events.Halloween);
|
||||
return this.databaseServer.getTables().globals.config.EventType.includes(SeasonalEventType.HALLOWEEN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,9 +175,9 @@ export class SeasonalEventService
|
||||
* @param eventName Name of event to get gear changes for
|
||||
* @returns bots with equipment changes
|
||||
*/
|
||||
protected getEventBotGear(eventName: string): Record<string, Record<string, Record<string, number>>>
|
||||
protected getEventBotGear(eventType: SeasonalEventType): Record<string, Record<string, Record<string, number>>>
|
||||
{
|
||||
return this.seasonalEventConfig.eventGear[eventName.toLowerCase()];
|
||||
return this.seasonalEventConfig.eventGear[eventType.toLowerCase()];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -194,6 +189,23 @@ export class SeasonalEventService
|
||||
return this.seasonalEventConfig.events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up quest in configs/quest.json
|
||||
* @param questId Quest to look up
|
||||
* @param event event type (Christmas/Halloween/None)
|
||||
* @returns true if related
|
||||
*/
|
||||
public isQuestRelatedToEvent(questId: string, event: SeasonalEventType): boolean
|
||||
{
|
||||
const eventQuestData = this.questConfig.eventQuests[questId];
|
||||
if (eventQuestData?.season.toLowerCase() === event.toLowerCase())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current date falls inside any of the seasons events pased in, if so, handle them
|
||||
*/
|
||||
@ -212,7 +224,7 @@ export class SeasonalEventService
|
||||
if (currentDate >= eventStartDate
|
||||
&& currentDate <= eventEndDate)
|
||||
{
|
||||
this.updateGlobalEvents(globalConfig, event.name);
|
||||
this.updateGlobalEvents(globalConfig, event.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,29 +270,29 @@ export class SeasonalEventService
|
||||
* @param globalConfig globals.json
|
||||
* @param eventName Name of the event to enable. e.g. Christmas
|
||||
*/
|
||||
protected updateGlobalEvents(globalConfig: Config, eventName: string): void
|
||||
protected updateGlobalEvents(globalConfig: Config, eventType: SeasonalEventType): void
|
||||
{
|
||||
switch (eventName.toLowerCase())
|
||||
switch (eventType.toLowerCase())
|
||||
{
|
||||
case "halloween":
|
||||
case SeasonalEventType.HALLOWEEN.toLowerCase():
|
||||
globalConfig.EventType = globalConfig.EventType.filter(x => x !== "None");
|
||||
globalConfig.EventType.push("Halloween");
|
||||
globalConfig.EventType.push("HalloweenIllumination");
|
||||
globalConfig.Health.ProfileHealthSettings.DefaultStimulatorBuff = "Buffs_Halloween";
|
||||
this.addEventGearToBots("halloween");
|
||||
this.addEventGearToBots(eventType);
|
||||
this.addPumpkinsToScavBackpacks();
|
||||
break;
|
||||
case "christmas":
|
||||
case SeasonalEventType.CHRISTMAS.toLowerCase():
|
||||
globalConfig.EventType = globalConfig.EventType.filter(x => x !== "None");
|
||||
globalConfig.EventType.push("Christmas");
|
||||
this.addEventGearToBots("christmas");
|
||||
this.addEventGearToBots(eventType);
|
||||
this.addGifterBotToMaps();
|
||||
this.addLootItemsToGifterDropItemsList();
|
||||
this.enableDancingTree();
|
||||
break;
|
||||
default:
|
||||
// Likely a mod event
|
||||
this.addEventGearToBots(eventName.toLowerCase());
|
||||
this.addEventGearToBots(eventType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -301,12 +313,12 @@ export class SeasonalEventService
|
||||
* Read in data from seasonalEvents.json and add found equipment items to bots
|
||||
* @param eventName Name of the event to read equipment in from config
|
||||
*/
|
||||
protected addEventGearToBots(eventName: string): void
|
||||
protected addEventGearToBots(eventType: SeasonalEventType): void
|
||||
{
|
||||
const botGearChanges = this.getEventBotGear(eventName);
|
||||
const botGearChanges = this.getEventBotGear(eventType);
|
||||
if (!botGearChanges)
|
||||
{
|
||||
this.logger.warning(this.localisationService.getText("gameevent-no_gear_data", eventName));
|
||||
this.logger.warning(this.localisationService.getText("gameevent-no_gear_data", eventType));
|
||||
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user