From 8853ff9aade8b4acb4377711f73697d8255a3a32 Mon Sep 17 00:00:00 2001 From: DrakiaXYZ Date: Sat, 17 Feb 2024 10:48:52 +0000 Subject: [PATCH] Remove maps the player can't access due to PMC level from the list of possible daily locations (!229) This change should handle any map having its level range changed. With base data, no changes should occur, because GZ currently lists level 0-100 as its level range. You can however change GZ's base.json to limit it to level 20 for testing Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com> Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/229 Co-authored-by: DrakiaXYZ Co-committed-by: DrakiaXYZ --- .../controllers/RepeatableQuestController.ts | 68 +++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/project/src/controllers/RepeatableQuestController.ts b/project/src/controllers/RepeatableQuestController.ts index f2276255..6b9a7eac 100644 --- a/project/src/controllers/RepeatableQuestController.ts +++ b/project/src/controllers/RepeatableQuestController.ts @@ -32,6 +32,7 @@ import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { ObjectId } from "@spt-aki/utils/ObjectId"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; @injectable() export class RepeatableQuestController @@ -301,12 +302,13 @@ export class RepeatableQuestController { const questPool = this.createBaseQuestPool(repeatableConfig); - for (const location in repeatableConfig.locations) + const locations = this.getAllowedLocations(repeatableConfig.locations, pmcLevel); + for (const location in locations) { if (location !== ELocationName.ANY) { - questPool.pool.Exploration.locations[location] = repeatableConfig.locations[location]; - questPool.pool.Pickup.locations[location] = repeatableConfig.locations[location]; + questPool.pool.Exploration.locations[location] = locations[location]; + questPool.pool.Pickup.locations[location] = locations[location]; } } @@ -324,9 +326,9 @@ export class RepeatableQuestController } else { - const possibleLocations = Object.keys(repeatableConfig.locations); + const possibleLocations = Object.keys(locations); - // Set possible locations for elimination task, ift arget is savage, exclude labs from locations + // Set possible locations for elimination task, if target is savage, exclude labs from locations questPool.pool.Elimination.targets[probabilityObject.key] = (probabilityObject.key === "Savage") ? { locations: possibleLocations.filter((x) => x !== "laboratory") } : { locations: possibleLocations }; @@ -344,6 +346,62 @@ export class RepeatableQuestController }; } + /** + * Return the locations this PMC is allowed to get daily quests for based on their level + * @param locations The original list of locations + * @param pmcLevel The level of the player PMC + * @returns A filtered list of locations that allow the player PMC level to access it + */ + protected getAllowedLocations( + locations: Record, + pmcLevel: number + ): Partial> + { + const allowedLocation: Partial> = {}; + + for (const location in locations) + { + const locationNames = []; + for (const locationName of locations[location]) + { + if (this.isPmcLevelAllowedOnLocation(locationName, pmcLevel)) + { + locationNames.push(locationName); + } + } + + if (locationNames.length > 0) + { + allowedLocation[location] = locationNames; + } + } + + return allowedLocation; + } + + /** + * Return true if the given pmcLevel is allowed on the given location + * @param location The location name to check + * @param pmcLevel The level of the pmc + * @returns True if the given pmc level is allowed to access the given location + */ + protected isPmcLevelAllowedOnLocation(location: string, pmcLevel: number): boolean + { + if (location === ELocationName.ANY) + { + return true; + } + + const locationBase: ILocationBase = this.databaseServer.getTables().locations[location.toLowerCase()]?.base; + if (!locationBase) + { + return true; + } + + return (pmcLevel <= locationBase.RequiredPlayerLevelMax + && pmcLevel >= locationBase.RequiredPlayerLevelMin); + } + public debugLogRepeatableQuestIds(pmcData: IPmcData): void { for (const repeatable of pmcData.RepeatableQuests)