0
0
mirror of https://github.com/sp-tarkov/server.git synced 2025-02-13 09:50:43 -05:00

Add support for daily quests to request specific weapon kill requirements on elimination quests

This commit is contained in:
Dev 2023-10-11 17:04:18 +01:00
parent 67324edd9c
commit c2a6ca678e
5 changed files with 512 additions and 26 deletions

View File

@ -219,7 +219,7 @@
} }
} }
], ],
"bodyPartProb": 0.4, "bodyPartProb": 0.2,
"bodyParts": [{ "bodyParts": [{
"key": "Head", "key": "Head",
"relativeProbability": 1, "relativeProbability": 1,
@ -244,7 +244,77 @@
"maxDist": 100, "maxDist": 100,
"minDist": 20, "minDist": 20,
"maxKills": 3, "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": { "levelRange": {
"min": 16, "min": 16,
@ -312,7 +382,7 @@
} }
}, { }, {
"key": "bossBoar", "key": "bossBoar",
"relativeProbability": 0.5, "relativeProbability": 0,
"data": { "data": {
"isBoss": true "isBoss": true
} }
@ -349,7 +419,77 @@
"maxDist": 200, "maxDist": 200,
"minDist": 20, "minDist": 20,
"maxKills": 5, "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": [{ "bodyParts": [{
"key": "Head", "key": "Head",
"relativeProbability": 1, "relativeProbability": 1,
@ -537,7 +677,77 @@
"maxDist": 100, "maxDist": 100,
"minDist": 20, "minDist": 20,
"maxKills": 10, "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": { "levelRange": {
"min": 16, "min": 16,
@ -605,7 +815,7 @@
} }
}, { }, {
"key": "bossBoar", "key": "bossBoar",
"relativeProbability": 0.5, "relativeProbability": 0,
"data": { "data": {
"isBoss": true "isBoss": true
} }
@ -642,7 +852,77 @@
"maxDist": 200, "maxDist": 200,
"minDist": 20, "minDist": 20,
"maxKills": 15, "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": [{ "bodyParts": [{
"key": "Head", "key": "Head",
"relativeProbability": 1, "relativeProbability": 1,
@ -744,7 +1024,77 @@
"maxDist": 100, "maxDist": 100,
"minDist": 20, "minDist": 20,
"maxKills": 3, "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": { "levelRange": {
"min": 16, "min": 16,
@ -784,7 +1134,77 @@
"maxDist": 200, "maxDist": 200,
"minDist": 20, "minDist": 20,
"maxKills": 5, "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", "Lighthouse": "5704e4dad2720bb55b8b4567",
"laboratory": "5b0fc42d86f7744a585f9105", "laboratory": "5b0fc42d86f7744a585f9105",
"RezervBase": "5704e5fad2720bc05b8b4567", "RezervBase": "5704e5fad2720bc05b8b4567",
"TarkovStreets": "5714dc692459777137212e12" "TarkovStreets": "5714dc692459777137212e12"
} }
} }

View File

@ -73,7 +73,10 @@ export interface IEliminationTargetPool
bossKilla?: ITargetLocation bossKilla?: ITargetLocation
bossSanitar?: ITargetLocation bossSanitar?: ITargetLocation
bossTagilla?: ITargetLocation bossTagilla?: ITargetLocation
bossKojaniy?: ITargetLocation bossKnight?: ITargetLocation
bossZryachiy?: ITargetLocation
bossBoar?: ITargetLocation
bossBoarSniper?: ITargetLocation
} }
export interface ITargetLocation export interface ITargetLocation
@ -595,6 +598,8 @@ export class RepeatableQuestController
const locationsConfig = repeatableConfig.locations; const locationsConfig = repeatableConfig.locations;
let targetsConfig = this.probabilityObjectArray(eliminationConfig.targets); let targetsConfig = this.probabilityObjectArray(eliminationConfig.targets);
const bodypartsConfig = this.probabilityObjectArray(eliminationConfig.bodyParts); 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 // the difficulty of the quest varies in difficulty depending on the condition
// possible conditions are // possible conditions are
@ -628,15 +633,15 @@ export class RepeatableQuestController
const maxKillDifficulty = eliminationConfig.maxKills; 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)); targetsConfig = targetsConfig.filter(x => Object.keys(questTypePool.pool.Elimination.targets).includes(x.key));
if (targetsConfig.length === 0 || targetsConfig.every(x => x.data.isBoss)) 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 // 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 // -> then it would not be a quest with low probability anymore
questTypePool.types = questTypePool.types.filter(t => t !== "Elimination"); questTypePool.types = questTypePool.types.filter(t => t !== "Elimination");
@ -646,7 +651,8 @@ export class RepeatableQuestController
const targetKey = targetsConfig.draw()[0]; const targetKey = targetsConfig.draw()[0];
const targetDifficulty = 1 / targetsConfig.probability(targetKey); 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 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 // we use any also if the random condition is not met in case only "any" was in the pool
let locationKey = "any"; let locationKey = "any";
@ -726,18 +732,39 @@ export class RepeatableQuestController
distanceDifficulty = maxDistDifficulty * distance / eliminationConfig.maxDist; 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 kills = this.randomUtil.randInt(eliminationConfig.minKills, eliminationConfig.maxKills + 1);
const killDifficulty = kills; const killDifficulty = kills;
// not perfectly happy here; we give difficulty = 1 to the quest reward generation when we have the most diffucult mission // 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. // 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( const curDifficulty = difficultyWeighing(
targetDifficulty / maxTargetDifficulty, targetDifficulty / maxTargetDifficulty,
bodyPartDifficulty / maxBodyPartsDifficulty, bodyPartDifficulty / maxBodyPartsDifficulty,
distanceDifficulty / maxDistDifficulty, 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 // 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 = []; quest.conditions.AvailableForFinish[0]._props.counter.conditions = [];
if (locationKey !== "any") 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.value = kills;
quest.conditions.AvailableForFinish[0]._props.id = this.objectId.generate(); quest.conditions.AvailableForFinish[0]._props.id = this.objectId.generate();
quest.location = this.getQuestLocationByMapId(locationKey); quest.location = this.getQuestLocationByMapId(locationKey);
@ -852,10 +879,9 @@ export class RepeatableQuestController
* @param {string} location the location on which to fulfill the elimination quest * @param {string} location the location on which to fulfill the elimination quest
* @returns {object} object of "Elimination"-location-subcondition * @returns {object} object of "Elimination"-location-subcondition
*/ */
protected generateEliminationLocation(location: string[]): IEliminationCondition protected generateEliminationLocation(location: string[], allowedWeapon: string, allowedWeaponCategory: string): IEliminationCondition
{ {
const propsObject: IEliminationCondition = {
return {
_props: { _props: {
target: location, target: location,
id: this.objectId.generate(), id: this.objectId.generate(),
@ -863,6 +889,18 @@ export class RepeatableQuestController
}, },
_parent: "Location" _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) * @param {number} distance distance from which to kill (currently only >= supported)
* @returns {object} object of "Elimination"-kill-subcondition * @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 = { const killConditionProps: IKillConditionProps = {
target: target, target: target,
@ -902,6 +940,16 @@ export class RepeatableQuestController
}; };
} }
if (allowedWeapon)
{
killConditionProps.weapon = [allowedWeapon];
}
if (allowedWeaponCategory?.length > 0)
{
killConditionProps.weaponCategories = [allowedWeaponCategory];
}
return { return {
_props: killConditionProps, _props: killConditionProps,
_parent: "Kills" _parent: "Kills"

View File

@ -1050,6 +1050,11 @@ class ItemHelper
{ {
return this.localeService.getLocaleDb()[`${itemTpl} Name`]; 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 namespace ItemHelper

View File

@ -234,6 +234,8 @@ export interface ICompletionAvailableForProps extends IAvailableForProps
export interface ILocationConditionProps extends IConditionProps export interface ILocationConditionProps extends IConditionProps
{ {
target: string[], target: string[],
weapon?: string[]
weaponCategories?: string[]
} }
export interface IKillConditionProps extends IConditionProps export interface IKillConditionProps extends IConditionProps
@ -243,6 +245,8 @@ export interface IKillConditionProps extends IConditionProps
savageRole?: string[] savageRole?: string[]
bodyPart?: string[] bodyPart?: string[]
distance?: IDistanceCheck distance?: IDistanceCheck
weapon?: string[]
weaponCategories? : string[]
} }
export interface IDistanceCheck export interface IDistanceCheck

View File

@ -117,6 +117,10 @@ export interface IEliminationConfig
minDist: number minDist: number
maxKills: number maxKills: number
minKills: number minKills: number
weaponCategoryRequirementProb: number
weaponCategoryRequirements: IWeaponRequirement[]
weaponRequirementProb: number
weaponRequirements: IWeaponRequirement[]
} }
export interface ITarget extends IProbabilityObject export interface ITarget extends IProbabilityObject
@ -134,6 +138,11 @@ export interface IBodyPart extends IProbabilityObject
data: string[] data: string[]
} }
export interface IWeaponRequirement extends IProbabilityObject
{
data: string[]
}
export interface IProbabilityObject export interface IProbabilityObject
{ {
key: string key: string