From 1cf63ad1ad6c55f30d9551e7c10bb7c0cb9f2d33 Mon Sep 17 00:00:00 2001 From: Dev Date: Tue, 24 Oct 2023 15:01:31 +0100 Subject: [PATCH] Split pmc kill requirement for elimination into separate min/max counts from other bot types --- project/assets/configs/quest.json | 114 +++++++++++++----- .../generators/RepeatableQuestGenerator.ts | 34 ++++-- project/src/models/spt/config/IQuestConfig.ts | 3 + 3 files changed, 111 insertions(+), 40 deletions(-) diff --git a/project/assets/configs/quest.json b/project/assets/configs/quest.json index a43ddba3..9ee848da 100644 --- a/project/assets/configs/quest.json +++ b/project/assets/configs/quest.json @@ -131,7 +131,7 @@ } }, "repeatableQuests": [{ - "id": "615ffc701c97c768137e719b", + "id": "615ffc701c97c768137e719b", "name": "Daily", "side": "Pmc", "types": [ @@ -249,6 +249,8 @@ "minKills": 2, "maxBossKills": 1, "minBossKills": 1, + "maxPmcKills": 2, + "minPmcKills": 1, "weaponRequirementProb": 0, "weaponCategoryRequirementProb": 0.15, "weaponCategoryRequirements": [{ @@ -334,7 +336,8 @@ "key": "AnyPmc", "relativeProbability": 2, "data": { - "isBoss": false + "isBoss": false, + "isPmc": true } }, { "key": "bossBully", @@ -426,6 +429,8 @@ "minKills": 5, "maxBossKills": 2, "minBossKills": 1, + "maxPmcKills": 5, + "minPmcKills": 2, "weaponRequirementProb": 0, "weaponCategoryRequirementProb": 0.2, "weaponCategoryRequirements": [{ @@ -497,8 +502,7 @@ "data": ["5447b5e04bdc2d62278b4567"] } ] - }, - { + }, { "levelRange": { "min": 41, "max": 100 @@ -513,7 +517,8 @@ "key": "AnyPmc", "relativeProbability": 2, "data": { - "isBoss": false + "isBoss": false, + "isPmc": true } }, { "key": "bossBully", @@ -605,6 +610,8 @@ "minKills": 5, "maxBossKills": 4, "minBossKills": 2, + "maxPmcKills": 6, + "minPmcKills": 3, "weaponRequirementProb": 0, "weaponCategoryRequirementProb": 0.3, "weaponCategoryRequirements": [{ @@ -682,7 +689,7 @@ "rewardBlacklist": ["627bce33f21bc425b06ab967"], "rewardAmmoStackMinSize": 20 }, { - "id": "618035d38012292db3081bf0", + "id": "618035d38012292db3081bf0", "name": "Weekly", "side": "Pmc", "types": [ @@ -774,7 +781,8 @@ "key": "AnyPmc", "relativeProbability": 1, "data": { - "isBoss": false + "isBoss": false, + "isPmc": true } }, { "key": "bossBully", @@ -863,9 +871,11 @@ "maxDist": 75, "minDist": 10, "maxKills": 20, - "minKills": 10, + "minKills": 8, "maxBossKills": 7, "minBossKills": 3, + "maxPmcKills": 8, + "minPmcKills": 5, "weaponRequirementProb": 0, "weaponCategoryRequirementProb": 0.2, "weaponCategoryRequirements": [{ @@ -951,7 +961,8 @@ "key": "AnyPmc", "relativeProbability": 2, "data": { - "isBoss": false + "isBoss": false, + "isPmc": true } }, { "key": "bossBully", @@ -1043,6 +1054,8 @@ "minKills": 15, "maxBossKills": 30, "minBossKills": 15, + "maxPmcKills": 15, + "minPmcKills": 10, "weaponRequirementProb": 0, "weaponCategoryRequirementProb": 0.25, "weaponCategoryRequirements": [{ @@ -1128,7 +1141,8 @@ "key": "AnyPmc", "relativeProbability": 2, "data": { - "isBoss": false + "isBoss": false, + "isPmc": true } }, { "key": "bossBully", @@ -1220,6 +1234,8 @@ "minKills": 20, "maxBossKills": 20, "minBossKills": 10, + "maxPmcKills": 25, + "minPmcKills": 10, "weaponRequirementProb": 0, "weaponCategoryRequirementProb": 0.3, "weaponCategoryRequirements": [{ @@ -1297,17 +1313,17 @@ "rewardBlacklist": ["627bce33f21bc425b06ab967"], "rewardAmmoStackMinSize": 15 }, { - "id": "62825ef60e88d037dc1eb426", + "id": "62825ef60e88d037dc1eb426", "name": "Daily_Savage", "side": "Scav", "types": [ - "Exploration", + "Exploration", "Elimination", "Completion", - "Pickup" + "Pickup" ], "resetTime": 86400, - "numQuests": 1, + "numQuests": 4, "minPlayerLevel": 1, "rewardScaling": { "levels": [1, 20, 45, 100], @@ -1347,22 +1363,52 @@ ] } }, - "Pickup": { - "ItemTypeToFetchWithMaxCount": [ - {"itemType": "5b47574386f77428ca22b335", "minPickupCount": 2, "maxPickupCount": 4}, - {"itemType": "5b47574386f77428ca22b336", "minPickupCount": 2, "maxPickupCount": 4}, - {"itemType": "5b47574386f77428ca22b2ee", "minPickupCount": 2, "maxPickupCount": 3}, - {"itemType": "5b47574386f77428ca22b2ef", "minPickupCount": 1, "maxPickupCount": 2}, - {"itemType": "5b47574386f77428ca22b33a", "minPickupCount": 1, "maxPickupCount": 2}, - {"itemType": "5b5f701386f774093f2ecf0f", "minPickupCount": 1, "maxPickupCount": 2}, - {"itemType": "5b5f754a86f774094242f19b", "minPickupCount": 1, "maxPickupCount": 3}, - {"itemType": "5b5f75c686f774094242f19f", "minPickupCount": 1, "maxPickupCount": 2}, - {"itemType": "5b5f792486f77447ed5636b3", "minPickupCount": 1, "maxPickupCount": 2}, - {"itemType": "5b5f73ab86f774094242f195", "minPickupCount": 1, "maxPickupCount": 2} - ], - "ItemTypesToFetch": ["5b47574386f77428ca22b335", "5b47574386f77428ca22b336", "5b47574386f77428ca22b2ee"], - "maxItemFetchCount": 3 - }, + "Pickup": { + "ItemTypeToFetchWithMaxCount": [{ + "itemType": "5b47574386f77428ca22b335", + "minPickupCount": 2, + "maxPickupCount": 4 + }, { + "itemType": "5b47574386f77428ca22b336", + "minPickupCount": 2, + "maxPickupCount": 4 + }, { + "itemType": "5b47574386f77428ca22b2ee", + "minPickupCount": 2, + "maxPickupCount": 3 + }, { + "itemType": "5b47574386f77428ca22b2ef", + "minPickupCount": 1, + "maxPickupCount": 2 + }, { + "itemType": "5b47574386f77428ca22b33a", + "minPickupCount": 1, + "maxPickupCount": 2 + }, { + "itemType": "5b5f701386f774093f2ecf0f", + "minPickupCount": 1, + "maxPickupCount": 2 + }, { + "itemType": "5b5f754a86f774094242f19b", + "minPickupCount": 1, + "maxPickupCount": 3 + }, { + "itemType": "5b5f75c686f774094242f19f", + "minPickupCount": 1, + "maxPickupCount": 2 + }, { + "itemType": "5b5f792486f77447ed5636b3", + "minPickupCount": 1, + "maxPickupCount": 2 + }, { + "itemType": "5b5f73ab86f774094242f195", + "minPickupCount": 1, + "maxPickupCount": 2 + } + ], + "ItemTypesToFetch": ["5b47574386f77428ca22b335", "5b47574386f77428ca22b336", "5b47574386f77428ca22b2ee"], + "maxItemFetchCount": 3 + }, "Completion": { "minRequestedAmount": 1, "maxRequestedAmount": 5, @@ -1381,7 +1427,8 @@ "key": "AnyPmc", "relativeProbability": 1, "data": { - "isBoss": false + "isBoss": false, + "isPmc": true } } ], @@ -1493,7 +1540,8 @@ "key": "AnyPmc", "relativeProbability": 1, "data": { - "isBoss": false + "isBoss": false, + "isPmc": true } } ], @@ -1521,7 +1569,7 @@ "distProb": 0.25, "maxDist": 75, "minDist": 10, - "maxKills": 15, + "maxKills": 9, "minKills": 3, "maxBossKills": 3, "minBossKills": 1, diff --git a/project/src/generators/RepeatableQuestGenerator.ts b/project/src/generators/RepeatableQuestGenerator.ts index 74cf7b1e..731ea949 100644 --- a/project/src/generators/RepeatableQuestGenerator.ts +++ b/project/src/generators/RepeatableQuestGenerator.ts @@ -24,7 +24,7 @@ import { BaseClasses } from "@spt-aki/models/enums/BaseClasses"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { Money } from "@spt-aki/models/enums/Money"; import { Traders } from "@spt-aki/models/enums/Traders"; -import { IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig"; +import { IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig"; import { IQuestTypePool } from "@spt-aki/models/spt/repeatable/IQuestTypePool"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder"; @@ -38,7 +38,7 @@ import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { MathUtil } from "@spt-aki/utils/MathUtil"; import { ObjectId } from "@spt-aki/utils/ObjectId"; -import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +import { ProbabilityObjectArray, RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @injectable() @@ -285,10 +285,8 @@ export class RepeatableQuestGenerator } // Draw how many npm kills are required - const kills = (targetsConfig.data(targetKey).isBoss) - ? this.randomUtil.randInt(eliminationConfig.minBossKills, eliminationConfig.maxBossKills + 1) - : this.randomUtil.randInt(eliminationConfig.minKills, eliminationConfig.maxKills + 1); - const killDifficulty = kills; + const desiredKillCount = this.getEliminationKillCount(targetKey, targetsConfig, eliminationConfig); + const killDifficulty = desiredKillCount; // not perfectly happy here; we give difficulty = 1 to the quest reward generation when we have the most diffucult mission // e.g. killing reshala 5 times from a distance of 200m with a headshot. @@ -322,7 +320,7 @@ export class RepeatableQuestGenerator availableForFinishCondition._props.counter.conditions.push(this.generateEliminationLocation(locationsConfig[locationKey], allowedWeapon, allowedWeaponsCategory)); } availableForFinishCondition._props.counter.conditions.push(this.generateEliminationCondition(targetKey, bodyPartsToClient, distance, allowedWeapon, allowedWeaponsCategory)); - availableForFinishCondition._props.value = kills; + availableForFinishCondition._props.value = desiredKillCount; availableForFinishCondition._props.id = this.objectId.generate(); quest.location = this.getQuestLocationByMapId(locationKey); @@ -331,6 +329,28 @@ export class RepeatableQuestGenerator return quest; } + /** + * Get a number of kills neded to complete elimination quest + * @param targetKey Target type desired e.g. anyPmc/bossBully/Savage + * @param targetsConfig Config + * @param eliminationConfig Config + * @returns Number of AI to kill + */ + getEliminationKillCount(targetKey: string, targetsConfig: ProbabilityObjectArray, eliminationConfig: IEliminationConfig): number + { + if (targetsConfig.data(targetKey).isBoss) + { + return this.randomUtil.randInt(eliminationConfig.minBossKills, eliminationConfig.maxBossKills + 1); + } + + if (targetsConfig.data(targetKey).isPmc) + { + return this.randomUtil.randInt(eliminationConfig.minBossKills, eliminationConfig.maxBossKills + 1); + } + + return this.randomUtil.randInt(eliminationConfig.minKills, eliminationConfig.maxKills + 1); + } + /** * A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json) * This is a helper method for GenerateEliminationQuest to create a location condition. diff --git a/project/src/models/spt/config/IQuestConfig.ts b/project/src/models/spt/config/IQuestConfig.ts index 64051d0e..39a82437 100644 --- a/project/src/models/spt/config/IQuestConfig.ts +++ b/project/src/models/spt/config/IQuestConfig.ts @@ -133,6 +133,8 @@ export interface IEliminationConfig minKills: number minBossKills: number maxBossKills: number + minPmcKills: number + maxPmcKills: number weaponCategoryRequirementProb: number weaponCategoryRequirements: IWeaponRequirement[] weaponRequirementProb: number @@ -147,6 +149,7 @@ export interface ITarget extends IProbabilityObject export interface IBossInfo { isBoss: boolean + isPmc: boolean } export interface IBodyPart extends IProbabilityObject