diff --git a/project/assets/configs/quest.json b/project/assets/configs/quest.json index 93aadffa..4f9429e1 100644 --- a/project/assets/configs/quest.json +++ b/project/assets/configs/quest.json @@ -219,7 +219,7 @@ } } ], - "bodyPartProb": 0.4, + "bodyPartProb": 0.2, "bodyParts": [{ "key": "Head", "relativeProbability": 1, @@ -244,7 +244,77 @@ "maxDist": 100, "minDist": 20, "maxKills": 3, - "minKills": 2 + "minKills": 2, + "weaponRequirementProb": 0.9, + "weaponCategoryRequirementProb": 0.2, + "weaponCategoryRequirements": [{ + "key": "Shotgun", + "relativeProbability": 15, + "data": ["5b5f794b86f77409407a7f92"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5b5f792486f77447ed5636b3"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5b5f78fc86f77409407a7f90"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 15, + "data": ["5b5f78e986f77447ed5636b1"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5b5f796a86f774093f2ed3c0"] + }, { + "key": "Melee", + "relativeProbability": 0, + "data": ["5b5f7a0886f77409407a7f96"] + }, { + "key": "DMR", + "relativeProbability": 1, + "data": ["5b5f791486f774093f2ed3be"] + } + ], + "weaponRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5447b6094bdc2dc3278b4567"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5447b5cf4bdc2d65278b4567"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5447b5f14bdc2d61278b4567"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 10, + "data": ["5447b5fc4bdc2d87278b4567"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5447b5e04bdc2d62278b4567"] + } + ] }, { "levelRange": { "min": 16, @@ -312,7 +382,7 @@ } }, { "key": "bossBoar", - "relativeProbability": 0.5, + "relativeProbability": 0, "data": { "isBoss": true } @@ -349,7 +419,77 @@ "maxDist": 200, "minDist": 20, "maxKills": 5, - "minKills": 2 + "minKills": 2, + "weaponRequirementProb": 0.9, + "weaponCategoryRequirementProb": 0.2, + "weaponCategoryRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5b5f794b86f77409407a7f92"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5b5f792486f77447ed5636b3"] + }, { + "key": "AssaultRifle", + "relativeProbability": 10, + "data": ["5b5f78fc86f77409407a7f90"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 15, + "data": ["5b5f78e986f77447ed5636b1"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 8, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 8, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 8, + "data": ["5b5f796a86f774093f2ed3c0"] + }, { + "key": "Melee", + "relativeProbability": 1, + "data": ["5b5f7a0886f77409407a7f96"] + }, { + "key": "DMR", + "relativeProbability": 8, + "data": ["5b5f791486f774093f2ed3be"] + } + ], + "weaponRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5447b6094bdc2dc3278b4567"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5447b5cf4bdc2d65278b4567"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5447b5f14bdc2d61278b4567"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5447b5fc4bdc2d87278b4567"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5447b5e04bdc2d62278b4567"] + } + ] } ] }, @@ -512,7 +652,7 @@ } } ], - "bodyPartProb": 0.3, + "bodyPartProb": 0.2, "bodyParts": [{ "key": "Head", "relativeProbability": 1, @@ -537,7 +677,77 @@ "maxDist": 100, "minDist": 20, "maxKills": 10, - "minKills": 5 + "minKills": 5, + "weaponRequirementProb": 0.9, + "weaponCategoryRequirementProb": 0.2, + "weaponCategoryRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5b5f794b86f77409407a7f92"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5b5f792486f77447ed5636b3"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5b5f78fc86f77409407a7f90"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5b5f78e986f77447ed5636b1"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5b5f796a86f774093f2ed3c0"] + }, { + "key": "Melee", + "relativeProbability": 1, + "data": ["5b5f7a0886f77409407a7f96"] + }, { + "key": "DMR", + "relativeProbability": 1, + "data": ["5b5f791486f774093f2ed3be"] + } + ], + "weaponRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5447b6094bdc2dc3278b4567"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5447b5cf4bdc2d65278b4567"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5447b5f14bdc2d61278b4567"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5447b5fc4bdc2d87278b4567"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5447b5e04bdc2d62278b4567"] + } + ] }, { "levelRange": { "min": 16, @@ -605,7 +815,7 @@ } }, { "key": "bossBoar", - "relativeProbability": 0.5, + "relativeProbability": 0, "data": { "isBoss": true } @@ -642,7 +852,77 @@ "maxDist": 200, "minDist": 20, "maxKills": 15, - "minKills": 5 + "minKills": 5, + "weaponRequirementProb": 0.9, + "weaponCategoryRequirementProb": 0.2, + "weaponCategoryRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5b5f794b86f77409407a7f92"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5b5f792486f77447ed5636b3"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5b5f78fc86f77409407a7f90"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5b5f78e986f77447ed5636b1"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5b5f796a86f774093f2ed3c0"] + }, { + "key": "Melee", + "relativeProbability": 1, + "data": ["5b5f7a0886f77409407a7f96"] + }, { + "key": "DMR", + "relativeProbability": 1, + "data": ["5b5f791486f774093f2ed3be"] + } + ], + "weaponRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5447b6094bdc2dc3278b4567"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5447b5cf4bdc2d65278b4567"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5447b5f14bdc2d61278b4567"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5447b5fc4bdc2d87278b4567"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5447b5e04bdc2d62278b4567"] + } + ] } ] }, @@ -719,7 +999,7 @@ } } ], - "bodyPartProb": 0.4, + "bodyPartProb": 0.2, "bodyParts": [{ "key": "Head", "relativeProbability": 1, @@ -744,7 +1024,77 @@ "maxDist": 100, "minDist": 20, "maxKills": 3, - "minKills": 1 + "minKills": 1, + "weaponRequirementProb": 0.9, + "weaponCategoryRequirementProb": 0.2, + "weaponCategoryRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5b5f794b86f77409407a7f92"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5b5f792486f77447ed5636b3"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5b5f78fc86f77409407a7f90"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5b5f78e986f77447ed5636b1"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5b5f796a86f774093f2ed3c0"] + }, { + "key": "Melee", + "relativeProbability": 1, + "data": ["5b5f7a0886f77409407a7f96"] + }, { + "key": "DMR", + "relativeProbability": 1, + "data": ["5b5f791486f774093f2ed3be"] + } + ], + "weaponRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5447b6094bdc2dc3278b4567"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5447b5cf4bdc2d65278b4567"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5447b5f14bdc2d61278b4567"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5447b5fc4bdc2d87278b4567"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5447b5e04bdc2d62278b4567"] + } + ] }, { "levelRange": { "min": 16, @@ -784,7 +1134,77 @@ "maxDist": 200, "minDist": 20, "maxKills": 5, - "minKills": 2 + "minKills": 2, + "weaponRequirementProb": 0.9, + "weaponCategoryRequirementProb": 0.2, + "weaponCategoryRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5b5f794b86f77409407a7f92"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5b5f792486f77447ed5636b3"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5b5f78fc86f77409407a7f90"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5b5f78e986f77447ed5636b1"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5b5f796a86f774093f2ed3c0"] + }, { + "key": "Melee", + "relativeProbability": 1, + "data": ["5b5f7a0886f77409407a7f96"] + }, { + "key": "DMR", + "relativeProbability": 1, + "data": ["5b5f791486f774093f2ed3be"] + } + ], + "weaponRequirements": [{ + "key": "Shotgun", + "relativeProbability": 10, + "data": ["5447b6094bdc2dc3278b4567"] + }, { + "key": "Pistol", + "relativeProbability": 10, + "data": ["5447b5cf4bdc2d65278b4567"] + }, { + "key": "AssaultRifle", + "relativeProbability": 3, + "data": ["5447b5f14bdc2d61278b4567"] + }, { + "key": "AssaultCarbine", + "relativeProbability": 5, + "data": ["5447b5fc4bdc2d87278b4567"] + }, { + "key": "MarksmanRifle", + "relativeProbability": 1, + "data": ["5447b6194bdc2d67278b4567"] + }, { + "key": "SniperRifle", + "relativeProbability": 1, + "data": ["5447b6254bdc2dc3278b4568"] + }, { + "key": "SMG", + "relativeProbability": 1, + "data": ["5447b5e04bdc2d62278b4567"] + } + ] } ] }, @@ -804,6 +1224,6 @@ "Lighthouse": "5704e4dad2720bb55b8b4567", "laboratory": "5b0fc42d86f7744a585f9105", "RezervBase": "5704e5fad2720bc05b8b4567", - "TarkovStreets": "5714dc692459777137212e12" + "TarkovStreets": "5714dc692459777137212e12" } } diff --git a/project/src/controllers/RepeatableQuestController.ts b/project/src/controllers/RepeatableQuestController.ts index ac5878c8..34da9d37 100644 --- a/project/src/controllers/RepeatableQuestController.ts +++ b/project/src/controllers/RepeatableQuestController.ts @@ -73,7 +73,10 @@ export interface IEliminationTargetPool bossKilla?: ITargetLocation bossSanitar?: ITargetLocation bossTagilla?: ITargetLocation - bossKojaniy?: ITargetLocation + bossKnight?: ITargetLocation + bossZryachiy?: ITargetLocation + bossBoar?: ITargetLocation + bossBoarSniper?: ITargetLocation } export interface ITargetLocation @@ -595,6 +598,8 @@ export class RepeatableQuestController const locationsConfig = repeatableConfig.locations; let targetsConfig = this.probabilityObjectArray(eliminationConfig.targets); const bodypartsConfig = this.probabilityObjectArray(eliminationConfig.bodyParts); + const weaponCategoryRequirementConfig = this.probabilityObjectArray(eliminationConfig.weaponCategoryRequirements); + const weaponRequirementConfig = this.probabilityObjectArray(eliminationConfig.weaponRequirements); // the difficulty of the quest varies in difficulty depending on the condition // possible conditions are @@ -628,15 +633,15 @@ export class RepeatableQuestController const maxKillDifficulty = eliminationConfig.maxKills; - function difficultyWeighing(target: number, bodyPart: number, dist: number, kill: number): number + function difficultyWeighing(target: number, bodyPart: number, dist: number, kill: number, weaponRequirement: number): number { - return Math.sqrt(Math.sqrt(target) + bodyPart + dist) * kill; + return Math.sqrt(Math.sqrt(target) + bodyPart + dist + weaponRequirement) * kill; } targetsConfig = targetsConfig.filter(x => Object.keys(questTypePool.pool.Elimination.targets).includes(x.key)); if (targetsConfig.length === 0 || targetsConfig.every(x => x.data.isBoss)) { - // there are no more targets left for elimination; delete it as a possible quest type + // There are no more targets left for elimination; delete it as a possible quest type // also if only bosses are left we need to leave otherwise it's a guaranteed boss elimination // -> then it would not be a quest with low probability anymore questTypePool.types = questTypePool.types.filter(t => t !== "Elimination"); @@ -646,7 +651,8 @@ export class RepeatableQuestController const targetKey = targetsConfig.draw()[0]; const targetDifficulty = 1 / targetsConfig.probability(targetKey); - let locations = questTypePool.pool.Elimination.targets[targetKey].locations; + let locations: string[] = questTypePool.pool.Elimination.targets[targetKey].locations; + // we use any as location if "any" is in the pool and we do not hit the specific location random // we use any also if the random condition is not met in case only "any" was in the pool let locationKey = "any"; @@ -726,18 +732,39 @@ export class RepeatableQuestController distanceDifficulty = maxDistDifficulty * distance / eliminationConfig.maxDist; } - // draw how many npcs are required to be killed + let allowedWeaponsCategory: string = undefined; + if (eliminationConfig.weaponCategoryRequirementProb > Math.random()) + { + // Pick a weighted weapon categroy + const weaponRequirement = weaponCategoryRequirementConfig.draw(1, false); + + // Get the hideout id value stored in the .data array + allowedWeaponsCategory = weaponCategoryRequirementConfig.data(weaponRequirement[0])[0]; + } + + // Only allow a specific weapon requirement if a weapon category was not chosen + let allowedWeapon: string = undefined; + if (!allowedWeaponsCategory && eliminationConfig.weaponRequirementProb > Math.random()) + { + const weaponRequirement = weaponRequirementConfig.draw(1, false); + const allowedWeaponsCategory = weaponRequirementConfig.data(weaponRequirement[0])[0]; + const allowedWeapons = this.itemHelper.getItemTplsOfBaseType(allowedWeaponsCategory); + allowedWeapon = this.randomUtil.getArrayValue(allowedWeapons); + } + + // Draw how many npm kills are required const kills = this.randomUtil.randInt(eliminationConfig.minKills, eliminationConfig.maxKills + 1); const killDifficulty = kills; // 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. - const maxDifficulty = difficultyWeighing(1, 1, 1, 1); + const maxDifficulty = difficultyWeighing(1, 1, 1, 1, 1); const curDifficulty = difficultyWeighing( targetDifficulty / maxTargetDifficulty, bodyPartDifficulty / maxBodyPartsDifficulty, distanceDifficulty / maxDistDifficulty, - killDifficulty / maxKillDifficulty + killDifficulty / maxKillDifficulty, + (allowedWeaponsCategory || allowedWeapon) ? 1 : 0 ); // aforementioned issue makes it a bit crazy since now all easier quests give significantly lower rewards than Completion / Exploration @@ -751,9 +778,9 @@ export class RepeatableQuestController quest.conditions.AvailableForFinish[0]._props.counter.conditions = []; if (locationKey !== "any") { - quest.conditions.AvailableForFinish[0]._props.counter.conditions.push(this.generateEliminationLocation(locationsConfig[locationKey])); + quest.conditions.AvailableForFinish[0]._props.counter.conditions.push(this.generateEliminationLocation(locationsConfig[locationKey], allowedWeapon, allowedWeaponsCategory)); } - quest.conditions.AvailableForFinish[0]._props.counter.conditions.push(this.generateEliminationCondition(targetKey, bodyPartsToClient, distance)); + quest.conditions.AvailableForFinish[0]._props.counter.conditions.push(this.generateEliminationCondition(targetKey, bodyPartsToClient, distance, allowedWeapon, allowedWeaponsCategory)); quest.conditions.AvailableForFinish[0]._props.value = kills; quest.conditions.AvailableForFinish[0]._props.id = this.objectId.generate(); quest.location = this.getQuestLocationByMapId(locationKey); @@ -852,10 +879,9 @@ export class RepeatableQuestController * @param {string} location the location on which to fulfill the elimination quest * @returns {object} object of "Elimination"-location-subcondition */ - protected generateEliminationLocation(location: string[]): IEliminationCondition + protected generateEliminationLocation(location: string[], allowedWeapon: string, allowedWeaponCategory: string): IEliminationCondition { - - return { + const propsObject: IEliminationCondition = { _props: { target: location, id: this.objectId.generate(), @@ -863,6 +889,18 @@ export class RepeatableQuestController }, _parent: "Location" }; + + if (allowedWeapon) + { + propsObject._props.weapon = [allowedWeapon]; + } + + if (allowedWeaponCategory) + { + propsObject._props.weaponCategories = [allowedWeaponCategory]; + } + + return propsObject; } /** @@ -874,7 +912,7 @@ export class RepeatableQuestController * @param {number} distance distance from which to kill (currently only >= supported) * @returns {object} object of "Elimination"-kill-subcondition */ - protected generateEliminationCondition(target: string, bodyPart: string[], distance: number): IEliminationCondition + protected generateEliminationCondition(target: string, bodyPart: string[], distance: number, allowedWeapon: string, allowedWeaponCategory: string): IEliminationCondition { const killConditionProps: IKillConditionProps = { target: target, @@ -902,6 +940,16 @@ export class RepeatableQuestController }; } + if (allowedWeapon) + { + killConditionProps.weapon = [allowedWeapon]; + } + + if (allowedWeaponCategory?.length > 0) + { + killConditionProps.weaponCategories = [allowedWeaponCategory]; + } + return { _props: killConditionProps, _parent: "Kills" diff --git a/project/src/helpers/ItemHelper.ts b/project/src/helpers/ItemHelper.ts index 681b89da..41b77e10 100644 --- a/project/src/helpers/ItemHelper.ts +++ b/project/src/helpers/ItemHelper.ts @@ -1050,6 +1050,11 @@ class ItemHelper { return this.localeService.getLocaleDb()[`${itemTpl} Name`]; } + + public getItemTplsOfBaseType(desiredBaseType: string): string[] + { + return Object.values(this.databaseServer.getTables().templates.items).filter(x => x._parent === desiredBaseType).map(x =>x._id); + } } namespace ItemHelper diff --git a/project/src/models/eft/common/tables/IRepeatableQuests.ts b/project/src/models/eft/common/tables/IRepeatableQuests.ts index d4b3985e..f2ee2c2d 100644 --- a/project/src/models/eft/common/tables/IRepeatableQuests.ts +++ b/project/src/models/eft/common/tables/IRepeatableQuests.ts @@ -234,6 +234,8 @@ export interface ICompletionAvailableForProps extends IAvailableForProps export interface ILocationConditionProps extends IConditionProps { target: string[], + weapon?: string[] + weaponCategories?: string[] } export interface IKillConditionProps extends IConditionProps @@ -243,6 +245,8 @@ export interface IKillConditionProps extends IConditionProps savageRole?: string[] bodyPart?: string[] distance?: IDistanceCheck + weapon?: string[] + weaponCategories? : string[] } export interface IDistanceCheck diff --git a/project/src/models/spt/config/IQuestConfig.ts b/project/src/models/spt/config/IQuestConfig.ts index 34f27427..73843d3c 100644 --- a/project/src/models/spt/config/IQuestConfig.ts +++ b/project/src/models/spt/config/IQuestConfig.ts @@ -117,6 +117,10 @@ export interface IEliminationConfig minDist: number maxKills: number minKills: number + weaponCategoryRequirementProb: number + weaponCategoryRequirements: IWeaponRequirement[] + weaponRequirementProb: number + weaponRequirements: IWeaponRequirement[] } export interface ITarget extends IProbabilityObject @@ -134,6 +138,11 @@ export interface IBodyPart extends IProbabilityObject data: string[] } +export interface IWeaponRequirement extends IProbabilityObject +{ + data: string[] +} + export interface IProbabilityObject { key: string