Cultist circle:
Added support for weapon/armor rewards Added support for variable stack sizes (only ammo for now) Added support for breaking out of reward item while loop if no item is found (5 attempts max) Added helper function `itemHelper.getRandomisedAmmoStackSize()`
This commit is contained in:
parent
d720f7fa3a
commit
6803ee6241
@ -30,6 +30,7 @@ import { IAddItemDirectRequest } from "@spt/models/eft/inventory/IAddItemDirectR
|
||||
import { IAddItemsDirectRequest } from "@spt/models/eft/inventory/IAddItemsDirectRequest";
|
||||
import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
import { BackendErrorCodes } from "@spt/models/enums/BackendErrorCodes";
|
||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
||||
import { BonusType } from "@spt/models/enums/BonusType";
|
||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||
import { HideoutAreas } from "@spt/models/enums/HideoutAreas";
|
||||
@ -874,10 +875,10 @@ export class HideoutController {
|
||||
// Reward is weapon/armor preset, handle differently compared to 'normal' items
|
||||
const rewardIsPreset = this.presetHelper.hasPreset(recipe.endProduct);
|
||||
if (rewardIsPreset) {
|
||||
const preset = this.presetHelper.getDefaultPreset(recipe.endProduct);
|
||||
const defaultPreset = this.presetHelper.getDefaultPreset(recipe.endProduct);
|
||||
|
||||
// Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory
|
||||
const presetAndMods: Item[] = this.itemHelper.replaceIDs(preset._items);
|
||||
const presetAndMods: Item[] = this.itemHelper.replaceIDs(defaultPreset._items);
|
||||
|
||||
this.itemHelper.remapRootItemId(presetAndMods);
|
||||
|
||||
@ -1384,15 +1385,49 @@ export class HideoutController {
|
||||
// Pick random rewards until we have exhausted the sacrificed items budget
|
||||
let totalCost = 0;
|
||||
let itemsRewardedCount = 0;
|
||||
let failedAttempts = 0;
|
||||
while (totalCost < rewardBudget && rewardItemTplPool.length > 0 && itemsRewardedCount < 5) {
|
||||
if (failedAttempts > 5) {
|
||||
this.logger.warning(`Exiting reward generation after ${failedAttempts} failed attempts`);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Choose a random tpl from pool
|
||||
const randomItemTplFromPool = this.randomUtil.getArrayValue(rewardItemTplPool);
|
||||
|
||||
// Is weapon/armor, handle differently
|
||||
if (
|
||||
this.itemHelper.armorItemHasRemovableOrSoftInsertSlots(randomItemTplFromPool) ||
|
||||
this.itemHelper.isOfBaseclass(randomItemTplFromPool, BaseClasses.WEAPON)
|
||||
) {
|
||||
const defaultPreset = this.presetHelper.getDefaultPreset(randomItemTplFromPool);
|
||||
if (!defaultPreset) {
|
||||
this.logger.warning(`Reward tpl: ${randomItemTplFromPool} lacks a default preset, skipping reward`);
|
||||
failedAttempts++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory
|
||||
const presetAndMods: Item[] = this.itemHelper.replaceIDs(defaultPreset._items);
|
||||
|
||||
this.itemHelper.remapRootItemId(presetAndMods);
|
||||
|
||||
rewards.push(presetAndMods);
|
||||
}
|
||||
|
||||
// Some items can have variable stack size, e.g. ammo
|
||||
const stackSize = this.getRewardStackSize(randomItemTplFromPool);
|
||||
|
||||
// Not a weapon/armor, standard single item
|
||||
const rewardItem: Item = {
|
||||
_id: this.hashUtil.generate(),
|
||||
_tpl: randomItemTplFromPool,
|
||||
parentId: cultistCircleStashId,
|
||||
slotId: HideoutController.circleOfCultistSlotId,
|
||||
upd: {
|
||||
StackObjectsCount: 1,
|
||||
StackObjectsCount: stackSize,
|
||||
SpawnedInSession: true,
|
||||
},
|
||||
};
|
||||
@ -1407,6 +1442,15 @@ export class HideoutController {
|
||||
return rewards;
|
||||
}
|
||||
|
||||
protected getRewardStackSize(randomItemTplFromPool: string) {
|
||||
if (this.itemHelper.isOfBaseclass(randomItemTplFromPool, BaseClasses.AMMO)) {
|
||||
const ammoTemplate = this.itemHelper.getItem(randomItemTplFromPool)[1];
|
||||
return this.itemHelper.getRandomisedAmmoStackSize(ammoTemplate);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas
|
||||
* @param sessionId Session id
|
||||
|
@ -760,14 +760,7 @@ export class BotLootGenerator {
|
||||
* @param ammoItem Ammo item to randomise
|
||||
*/
|
||||
protected randomiseAmmoStackSize(isPmc: boolean, itemTemplate: ITemplateItem, ammoItem: Item): void {
|
||||
const randomSize =
|
||||
itemTemplate._props.StackMaxSize === 1
|
||||
? 1
|
||||
: this.randomUtil.getInt(
|
||||
itemTemplate._props.StackMinRandom,
|
||||
Math.min(itemTemplate._props.StackMaxRandom, 60),
|
||||
);
|
||||
|
||||
const randomSize = this.itemHelper.getRandomisedAmmoStackSize(itemTemplate);
|
||||
this.itemHelper.addUpdObjectToItem(ammoItem);
|
||||
|
||||
ammoItem.upd.StackObjectsCount = randomSize;
|
||||
|
@ -1723,9 +1723,28 @@ export class ItemHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all tpls from Money enum
|
||||
* @returns string tpls
|
||||
*/
|
||||
public getMoneyTpls(): string[] {
|
||||
return Object.values(Money);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a randomsied stack size for the passed in ammo
|
||||
* @param ammoItemTemplate Ammo to get stack size for
|
||||
* @param maxLimit default: Limit to 60 to prevent crazy values when players use stack increase mods
|
||||
* @returns number
|
||||
*/
|
||||
public getRandomisedAmmoStackSize(ammoItemTemplate: ITemplateItem, maxLimit = 60): number {
|
||||
return ammoItemTemplate._props.StackMaxSize === 1
|
||||
? 1
|
||||
: this.randomUtil.getInt(
|
||||
ammoItemTemplate._props.StackMinRandom,
|
||||
Math.min(ammoItemTemplate._props.StackMaxRandom, maxLimit),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ItemHelper {
|
||||
|
@ -116,9 +116,9 @@ export class PresetHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default preset for passed in item id
|
||||
* @param templateId Item id to get preset for
|
||||
* @returns Null if no default preset, otherwise IPreset
|
||||
* Get a cloned default preset for passed in item tpl
|
||||
* @param templateId Item tpl to get preset for
|
||||
* @returns undefined if no default preset, otherwise IPreset
|
||||
*/
|
||||
public getDefaultPreset(templateId: string): IPreset | undefined {
|
||||
if (!this.hasPreset(templateId)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user