Fixed an issue where revolvers/rpd/ppsh would not properly filter out cartridges during ammo selection
This commit is contained in:
parent
2f412641b2
commit
852157aabf
@ -105,8 +105,8 @@ export class BotWeaponGenerator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generated a weapon based on the supplied weapon tpl
|
* Generated a weapon based on the supplied weapon tpl
|
||||||
* @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
|
* @param weaponTpl Weapon tpl to generate (use pickWeightedWeaponTplFromPool())
|
||||||
* @param equipmentSlot slot to fit into, primary/secondary/holster
|
* @param slotName Slot to fit into, primary/secondary/holster
|
||||||
* @param botTemplateInventory e.g. assault.json
|
* @param botTemplateInventory e.g. assault.json
|
||||||
* @param weaponParentId ParentId of the weapon being generated
|
* @param weaponParentId ParentId of the weapon being generated
|
||||||
* @param modChances Dictionary of item types and % chance weapon will have that mod
|
* @param modChances Dictionary of item types and % chance weapon will have that mod
|
||||||
@ -117,7 +117,7 @@ export class BotWeaponGenerator {
|
|||||||
public generateWeaponByTpl(
|
public generateWeaponByTpl(
|
||||||
sessionId: string,
|
sessionId: string,
|
||||||
weaponTpl: string,
|
weaponTpl: string,
|
||||||
equipmentSlot: string,
|
slotName: string,
|
||||||
botTemplateInventory: Inventory,
|
botTemplateInventory: Inventory,
|
||||||
weaponParentId: string,
|
weaponParentId: string,
|
||||||
modChances: ModsChances,
|
modChances: ModsChances,
|
||||||
@ -130,7 +130,7 @@ export class BotWeaponGenerator {
|
|||||||
|
|
||||||
if (!weaponItemTemplate) {
|
if (!weaponItemTemplate) {
|
||||||
this.logger.error(this.localisationService.getText("bot-missing_item_template", weaponTpl));
|
this.logger.error(this.localisationService.getText("bot-missing_item_template", weaponTpl));
|
||||||
this.logger.error(`WeaponSlot -> ${equipmentSlot}`);
|
this.logger.error(`WeaponSlot -> ${slotName}`);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -147,20 +147,23 @@ export class BotWeaponGenerator {
|
|||||||
let weaponWithModsArray = this.constructWeaponBaseArray(
|
let weaponWithModsArray = this.constructWeaponBaseArray(
|
||||||
weaponTpl,
|
weaponTpl,
|
||||||
weaponParentId,
|
weaponParentId,
|
||||||
equipmentSlot,
|
slotName,
|
||||||
weaponItemTemplate,
|
weaponItemTemplate,
|
||||||
botRole,
|
botRole,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Chance to add randomised weapon enhancement
|
// Chance to add randomised weapon enhancement
|
||||||
if (isPmc && this.randomUtil.getChance100(this.pmcConfig.weaponHasEnhancementChancePercent)) {
|
if (isPmc && this.randomUtil.getChance100(this.pmcConfig.weaponHasEnhancementChancePercent)) {
|
||||||
const weaponConfig = this.repairConfig.repairKit.weapon;
|
// Add buff to weapon root
|
||||||
this.repairService.addBuff(weaponConfig, weaponWithModsArray[0]);
|
this.repairService.addBuff(this.repairConfig.repairKit.weapon, weaponWithModsArray[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add mods to weapon base
|
// Add mods to weapon base
|
||||||
if (Object.keys(modPool).includes(weaponTpl)) {
|
if (Object.keys(modPool).includes(weaponTpl)) {
|
||||||
|
// Role to treat bot as e.g. pmc/scav/boss
|
||||||
const botEquipmentRole = this.botGeneratorHelper.getBotEquipmentRole(botRole);
|
const botEquipmentRole = this.botGeneratorHelper.getBotEquipmentRole(botRole);
|
||||||
|
|
||||||
|
// Different limits if bot is boss vs scav
|
||||||
const modLimits = this.botWeaponModLimitService.getWeaponModLimits(botEquipmentRole);
|
const modLimits = this.botWeaponModLimitService.getWeaponModLimits(botEquipmentRole);
|
||||||
|
|
||||||
const generateWeaponModsRequest: IGenerateWeaponRequest = {
|
const generateWeaponModsRequest: IGenerateWeaponRequest = {
|
||||||
@ -185,7 +188,7 @@ export class BotWeaponGenerator {
|
|||||||
// Weapon is bad, fall back to weapons preset
|
// Weapon is bad, fall back to weapons preset
|
||||||
weaponWithModsArray = this.getPresetWeaponMods(
|
weaponWithModsArray = this.getPresetWeaponMods(
|
||||||
weaponTpl,
|
weaponTpl,
|
||||||
equipmentSlot,
|
slotName,
|
||||||
weaponParentId,
|
weaponParentId,
|
||||||
weaponItemTemplate,
|
weaponItemTemplate,
|
||||||
botRole,
|
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)
|
* 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 cartridgePool Dict of all cartridges keyed by type e.g. Caliber556x45NATO
|
||||||
* @param weaponTemplate the weapon we want to pick ammo for
|
* @param weaponTemplate Weapon details from db we want to pick ammo for
|
||||||
* @returns an ammo tpl that works with the desired gun
|
* @returns Ammo tpl that works with the desired gun
|
||||||
*/
|
*/
|
||||||
protected getWeightedCompatibleAmmo(
|
protected getWeightedCompatibleAmmo(
|
||||||
ammo: Record<string, Record<string, number>>,
|
cartridgePool: Record<string, Record<string, number>>,
|
||||||
weaponTemplate: ITemplateItem,
|
weaponTemplate: ITemplateItem,
|
||||||
): string {
|
): string {
|
||||||
const desiredCaliber = this.getWeaponCaliber(weaponTemplate);
|
const desiredCaliber = this.getWeaponCaliber(weaponTemplate);
|
||||||
|
|
||||||
const compatibleCartridges = this.cloner.clone(ammo[desiredCaliber]);
|
const cartridgePoolForWeapon = cartridgePool[desiredCaliber];
|
||||||
if (!compatibleCartridges || compatibleCartridges?.length === 0) {
|
if (!cartridgePoolForWeapon || cartridgePoolForWeapon?.length === 0) {
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
this.localisationService.getText("bot-no_caliber_data_for_weapon_falling_back_to_default", {
|
this.localisationService.getText("bot-no_caliber_data_for_weapon_falling_back_to_default", {
|
||||||
weaponId: weaponTemplate._id,
|
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;
|
return weaponTemplate._props.defAmmo;
|
||||||
}
|
}
|
||||||
|
|
||||||
let chosenAmmoTpl: string;
|
// Get cartridges the weapons first chamber allow
|
||||||
while (!chosenAmmoTpl) {
|
const compatibleCartridgesInTemplate = this.getCompatibleCartridgesFromWeaponTemplate(weaponTemplate);
|
||||||
const possibleAmmo = this.weightedRandomHelper.getWeightedValue<string>(compatibleCartridges);
|
if (!compatibleCartridgesInTemplate) {
|
||||||
|
// No chamber data found in weapon, send default
|
||||||
// Weapon has chamber but does not support cartridge
|
return weaponTemplate._props.defAmmo;
|
||||||
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,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set ammo to default and exit
|
|
||||||
chosenAmmoTpl = weaponTemplate._props.defAmmo;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not compatible, remove item from possible list and try again
|
// Inner join the weapons allowed + passed in cartridge pool to get compatible cartridges
|
||||||
delete compatibleCartridges[possibleAmmo];
|
const compatibleCartridges = Object.keys(cartridgePoolForWeapon)
|
||||||
} else {
|
.filter((cartridge) => compatibleCartridgesInTemplate.includes(cartridge))
|
||||||
// Compatible ammo found
|
.reduce((acc, key) => ({ ...acc, [key]: cartridgePoolForWeapon[key] }), {});
|
||||||
chosenAmmoTpl = possibleAmmo;
|
|
||||||
break;
|
if (!compatibleCartridges) {
|
||||||
|
// No compatible cartridges, use default
|
||||||
|
return weaponTemplate._props.defAmmo;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user