Fixed an issue where revolvers/rpd/ppsh would not properly filter out cartridges during ammo selection

This commit is contained in:
Dev 2024-07-28 13:19:34 +01:00
parent 2f412641b2
commit 852157aabf

View File

@ -105,8 +105,8 @@ export class BotWeaponGenerator {
/**
* Generated a weapon based on the supplied weapon tpl
* @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
* @param equipmentSlot slot to fit into, primary/secondary/holster
* @param weaponTpl Weapon tpl to generate (use pickWeightedWeaponTplFromPool())
* @param slotName Slot to fit into, primary/secondary/holster
* @param botTemplateInventory e.g. assault.json
* @param weaponParentId ParentId of the weapon being generated
* @param modChances Dictionary of item types and % chance weapon will have that mod
@ -117,7 +117,7 @@ export class BotWeaponGenerator {
public generateWeaponByTpl(
sessionId: string,
weaponTpl: string,
equipmentSlot: string,
slotName: string,
botTemplateInventory: Inventory,
weaponParentId: string,
modChances: ModsChances,
@ -130,7 +130,7 @@ export class BotWeaponGenerator {
if (!weaponItemTemplate) {
this.logger.error(this.localisationService.getText("bot-missing_item_template", weaponTpl));
this.logger.error(`WeaponSlot -> ${equipmentSlot}`);
this.logger.error(`WeaponSlot -> ${slotName}`);
return;
}
@ -147,20 +147,23 @@ export class BotWeaponGenerator {
let weaponWithModsArray = this.constructWeaponBaseArray(
weaponTpl,
weaponParentId,
equipmentSlot,
slotName,
weaponItemTemplate,
botRole,
);
// Chance to add randomised weapon enhancement
if (isPmc && this.randomUtil.getChance100(this.pmcConfig.weaponHasEnhancementChancePercent)) {
const weaponConfig = this.repairConfig.repairKit.weapon;
this.repairService.addBuff(weaponConfig, weaponWithModsArray[0]);
// Add buff to weapon root
this.repairService.addBuff(this.repairConfig.repairKit.weapon, weaponWithModsArray[0]);
}
// Add mods to weapon base
if (Object.keys(modPool).includes(weaponTpl)) {
// Role to treat bot as e.g. pmc/scav/boss
const botEquipmentRole = this.botGeneratorHelper.getBotEquipmentRole(botRole);
// Different limits if bot is boss vs scav
const modLimits = this.botWeaponModLimitService.getWeaponModLimits(botEquipmentRole);
const generateWeaponModsRequest: IGenerateWeaponRequest = {
@ -185,7 +188,7 @@ export class BotWeaponGenerator {
// Weapon is bad, fall back to weapons preset
weaponWithModsArray = this.getPresetWeaponMods(
weaponTpl,
equipmentSlot,
slotName,
weaponParentId,
weaponItemTemplate,
botRole,
@ -535,18 +538,18 @@ export class BotWeaponGenerator {
/**
* Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
* @param ammo a list of ammo tpls the weapon can use
* @param weaponTemplate the weapon we want to pick ammo for
* @returns an ammo tpl that works with the desired gun
* @param cartridgePool Dict of all cartridges keyed by type e.g. Caliber556x45NATO
* @param weaponTemplate Weapon details from db we want to pick ammo for
* @returns Ammo tpl that works with the desired gun
*/
protected getWeightedCompatibleAmmo(
ammo: Record<string, Record<string, number>>,
cartridgePool: Record<string, Record<string, number>>,
weaponTemplate: ITemplateItem,
): string {
const desiredCaliber = this.getWeaponCaliber(weaponTemplate);
const compatibleCartridges = this.cloner.clone(ammo[desiredCaliber]);
if (!compatibleCartridges || compatibleCartridges?.length === 0) {
const cartridgePoolForWeapon = cartridgePool[desiredCaliber];
if (!cartridgePoolForWeapon || cartridgePoolForWeapon?.length === 0) {
this.logger.debug(
this.localisationService.getText("bot-no_caliber_data_for_weapon_falling_back_to_default", {
weaponId: weaponTemplate._id,
@ -555,45 +558,53 @@ export class BotWeaponGenerator {
}),
);
// Immediately returns, as default ammo is guaranteed to be compatible
// Immediately returns, default ammo is guaranteed to be compatible
return weaponTemplate._props.defAmmo;
}
let chosenAmmoTpl: string;
while (!chosenAmmoTpl) {
const possibleAmmo = this.weightedRandomHelper.getWeightedValue<string>(compatibleCartridges);
// Get cartridges the weapons first chamber allow
const compatibleCartridgesInTemplate = this.getCompatibleCartridgesFromWeaponTemplate(weaponTemplate);
if (!compatibleCartridgesInTemplate) {
// No chamber data found in weapon, send default
return weaponTemplate._props.defAmmo;
}
// Weapon has chamber but does not support cartridge
if (
weaponTemplate._props.Chambers[0] &&
!weaponTemplate._props.Chambers[0]._props.filters[0].Filter.includes(possibleAmmo)
) {
// Ran out of possible choices, use default ammo
if (Object.keys(compatibleCartridges).length === 0) {
this.logger.debug(
this.localisationService.getText("bot-incompatible_ammo_for_weapon_falling_back_to_default", {
chosenAmmo: chosenAmmoTpl,
weaponId: weaponTemplate._id,
weaponName: weaponTemplate._name,
defaultAmmo: weaponTemplate._props.defAmmo,
}),
);
// Inner join the weapons allowed + passed in cartridge pool to get compatible cartridges
const compatibleCartridges = Object.keys(cartridgePoolForWeapon)
.filter((cartridge) => compatibleCartridgesInTemplate.includes(cartridge))
.reduce((acc, key) => ({ ...acc, [key]: cartridgePoolForWeapon[key] }), {});
// Set ammo to default and exit
chosenAmmoTpl = weaponTemplate._props.defAmmo;
break;
}
if (!compatibleCartridges) {
// No compatible cartridges, use default
return weaponTemplate._props.defAmmo;
}
// Not compatible, remove item from possible list and try again
delete compatibleCartridges[possibleAmmo];
} else {
// Compatible ammo found
chosenAmmoTpl = possibleAmmo;
break;
return this.weightedRandomHelper.getWeightedValue<string>(compatibleCartridges);
}
/**
* Get the cartridge ids from a weapon template that work with the weapon
* @param weaponTemplate Weapon db template to get cartridges for
* @returns Array of cartridge tpls
*/
protected getCompatibleCartridgesFromWeaponTemplate(weaponTemplate: ITemplateItem): string[] {
let cartridges = weaponTemplate._props.Chambers[0]?._props?.filters[0]?.Filter;
if (!cartridges) {
// Fallback to the magazine if possible, e.g. for revolvers
// Grab the magazines template
const firstMagazine = weaponTemplate._props.Slots.find((slot) => slot._name === "mod_magazine");
const magazineTemplate = this.itemHelper.getItem(firstMagazine._props.filters[0].Filter[0]);
// Get the first slots array of cartridges
cartridges = magazineTemplate[1]._props.Slots[0]?._props.filters[0].Filter;
if (!cartridges) {
// Normal magazines
// None found, try the cartridges array
cartridges = magazineTemplate[1]._props.Cartridges[0]?._props.filters[0].Filter;
}
}
return chosenAmmoTpl;
return cartridges;
}
/**