Refactor handleScavCase() to use addItemToStash()

blacklist soft armor inserts from scavcase rewards
This commit is contained in:
Dev 2024-01-21 16:40:14 +00:00
parent 8e232e8250
commit c68c9a72fb
4 changed files with 77 additions and 61 deletions

View File

@ -20,7 +20,8 @@
"5448bf274bdc2dfc2f8b456a", "5448bf274bdc2dfc2f8b456a",
"5d52cc5ba4b9367408500062", "5d52cc5ba4b9367408500062",
"5e997f0b86f7741ac73993e2", "5e997f0b86f7741ac73993e2",
"62f109593b54472778797866" "62f109593b54472778797866",
"65649eb40bf0ed77b8044453"
], ],
"rewardItemBlacklist": [ "rewardItemBlacklist": [
"5ede4739e0350d05467f73e8", "5ede4739e0350d05467f73e8",
@ -43,7 +44,6 @@
"63a0b2eabea67a6d93009e52", "63a0b2eabea67a6d93009e52",
"609e860ebd219504d8507525" "609e860ebd219504d8507525"
], ],
"moneyRewards": { "moneyRewards": {
"moneyRewardChancePercent": 10, "moneyRewardChancePercent": 10,
"rubCount": { "rubCount": {

View File

@ -946,39 +946,32 @@ export class HideoutController
// Create rewards for scav case // Create rewards for scav case
const scavCaseRewards = this.scavCaseRewardGenerator.generate(request.recipeId); const scavCaseRewards = this.scavCaseRewardGenerator.generate(request.recipeId);
// Add scav case rewards to player profile for (const itemWithChildren of scavCaseRewards)
pmcData.Hideout.Production[prodId].Products = scavCaseRewards; {
const addToStashRequest: IAddItemDirectRequest = {
itemWithModsToAdd: itemWithChildren,
foundInRaid: true,
callback: null,
useSortingTable: false
}
this.inventoryHelper.addItemToStash(sessionID, addToStashRequest, pmcData, output);
if (output.warnings.length > 0)
{
const errorMessage = "Unable to give scavcase reward to player";
return this.httpResponse.appendErrorToOutput(output, errorMessage);
}
}
// Remove the old production from output object before its sent to client // Remove the old production from output object before its sent to client
delete output.profileChanges[sessionID].production[request.recipeId]; delete output.profileChanges[sessionID].production[request.recipeId];
// Get array of item created + count of them after completing hideout craft // Flag as complete - will be cleaned up later by hideoutController.update()
const itemsToAdd = pmcData.Hideout.Production[prodId].Products.map( pmcData.Hideout.Production[prodId].sptIsComplete = true;
(x: { _tpl: string; upd?: { StackObjectsCount?: number; }; }) =>
{
const itemTpl = this.presetHelper.hasPreset(x._tpl)
? this.presetHelper.getDefaultPreset(x._tpl)._id
: x._tpl;
// Count of items crafted // Crafting complete, flag
const numOfItems = !x.upd?.StackObjectsCount ? 1 : x.upd.StackObjectsCount; pmcData.Hideout.Production[prodId].inProgress = false;
// eslint-disable-next-line @typescript-eslint/naming-convention
return { item_id: itemTpl, count: numOfItems };
},
);
const newReq = { items: itemsToAdd, tid: "ragfair" }; return output;
const callback = () =>
{
// Flag as complete - will be cleaned up later by hideoutController.update()
pmcData.Hideout.Production[prodId].sptIsComplete = true;
// Crafting complete, flag as such
pmcData.Hideout.Production[prodId].inProgress = false;
};
// Add crafted item to player inventory
return this.inventoryHelper.addItem(pmcData, newReq, output, sessionID, callback, true);
} }
/** /**

View File

@ -1,8 +1,9 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { Product } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Product } from "@spt-aki/models/eft/common/tables/IBotBase";
import { Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
import { IHideoutScavCase } from "@spt-aki/models/eft/hideout/IHideoutScavCase"; import { IHideoutScavCase } from "@spt-aki/models/eft/hideout/IHideoutScavCase";
import { BaseClasses } from "@spt-aki/models/enums/BaseClasses"; import { BaseClasses } from "@spt-aki/models/enums/BaseClasses";
@ -19,6 +20,7 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService"; import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { RagfairPriceService } from "@spt-aki/services/RagfairPriceService"; import { RagfairPriceService } from "@spt-aki/services/RagfairPriceService";
import { HashUtil } from "@spt-aki/utils/HashUtil"; import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil";
/** /**
@ -34,8 +36,10 @@ export class ScavCaseRewardGenerator
constructor( constructor(
@inject("WinstonLogger") protected logger: ILogger, @inject("WinstonLogger") protected logger: ILogger,
@inject("RandomUtil") protected randomUtil: RandomUtil, @inject("RandomUtil") protected randomUtil: RandomUtil,
@inject("JsonUtil") protected jsonUtil: JsonUtil,
@inject("HashUtil") protected hashUtil: HashUtil, @inject("HashUtil") protected hashUtil: HashUtil,
@inject("ItemHelper") protected itemHelper: ItemHelper, @inject("ItemHelper") protected itemHelper: ItemHelper,
@inject("PresetHelper") protected presetHelper: PresetHelper,
@inject("DatabaseServer") protected databaseServer: DatabaseServer, @inject("DatabaseServer") protected databaseServer: DatabaseServer,
@inject("RagfairPriceService") protected ragfairPriceService: RagfairPriceService, @inject("RagfairPriceService") protected ragfairPriceService: RagfairPriceService,
@inject("ItemFilterService") protected itemFilterService: ItemFilterService, @inject("ItemFilterService") protected itemFilterService: ItemFilterService,
@ -50,7 +54,7 @@ export class ScavCaseRewardGenerator
* @param recipeId recipe of the scav case craft * @param recipeId recipe of the scav case craft
* @returns Product array * @returns Product array
*/ */
public generate(recipeId: string): Product[] public generate(recipeId: string): Item[][]
{ {
this.cacheDbItems(); this.cacheDbItems();
@ -274,44 +278,63 @@ export class ScavCaseRewardGenerator
* @param rewardItems items to convert * @param rewardItems items to convert
* @returns Product array * @returns Product array
*/ */
protected randomiseContainerItemRewards(rewardItems: ITemplateItem[], rarity: string): Product[] protected randomiseContainerItemRewards(rewardItems: ITemplateItem[], rarity: string): Item[][]
{ {
const result: Product[] = []; /** Each array is an item + children */
for (const item of rewardItems) const result: Item[][] = [];
for (const rewardItemDb of rewardItems)
{ {
const resultItem = { _id: this.hashUtil.generate(), _tpl: item._id, upd: undefined }; let resultItem: Item[] = [
{
_id: this.hashUtil.generate(),
_tpl: rewardItemDb._id,
upd: undefined
}
];
const rootItem = resultItem[0];
this.addStackCountToAmmoAndMoney(item, resultItem, rarity); if (this.itemHelper.isOfBaseclass(rewardItemDb._id, BaseClasses.AMMO_BOX))
// Clean up upd object if it wasn't used
if (!resultItem.upd)
{ {
delete resultItem.upd; this.itemHelper.addCartridgesToAmmoBox(resultItem, rewardItemDb);
}
// Armor or weapon = use default preset from globals.json
else if (this.itemHelper.armorItemCanHoldMods(rewardItemDb._id)
|| this.itemHelper.isOfBaseclass(rewardItemDb._id, BaseClasses.WEAPON))
{
const preset = this.presetHelper.getDefaultPreset(rewardItemDb._id);
if (!preset)
{
this.logger.warning(`No preset for item: ${rewardItemDb._id} ${rewardItemDb._name}, skipping`);
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(
null,
this.jsonUtil.clone(preset._items),
);
this.itemHelper.remapRootItemId(presetAndMods);
resultItem = presetAndMods;
}
else if (this.itemHelper.isOfBaseclasses(rewardItemDb._id, [BaseClasses.AMMO, BaseClasses.MONEY]))
{
rootItem.upd = { StackObjectsCount: this.getRandomAmountRewardForScavCase(rewardItemDb, rarity) };
} }
result.push(resultItem); // Clean up upd object if it wasn't used
if (!rootItem.upd)
{
delete rootItem.upd;
}
result.push(resultItem)
} }
return result; return result;
} }
/**
* Add a randomised stack count to ammo or money items
* @param item money or ammo item
* @param resultItem money or ammo item with a randomise stack size
*/
protected addStackCountToAmmoAndMoney(
item: ITemplateItem,
resultItem: { _id: string; _tpl: string; upd: Upd; },
rarity: string,
): void
{
if (item._parent === BaseClasses.AMMO || item._parent === BaseClasses.MONEY)
{
resultItem.upd = { StackObjectsCount: this.getRandomAmountRewardForScavCase(item, rarity) };
}
}
/** /**
* @param dbItems all items from the items.json * @param dbItems all items from the items.json
* @param itemFilters controls how the dbItems will be filtered and returned (handbook price) * @param itemFilters controls how the dbItems will be filtered and returned (handbook price)

View File

@ -1271,15 +1271,15 @@ export class ItemHelper
continue; continue;
} }
const moditemToAdd = { const modItemToAdd = {
_id: this.hashUtil.generate(), _id: this.hashUtil.generate(),
_tpl: chosenTpl, _tpl: chosenTpl,
parentId: result[0]._id, parentId: result[0]._id,
slotId: slot._name slotId: slot._name
}; };
result.push(moditemToAdd); result.push(modItemToAdd);
const modItemDbDetails = this.getItem(moditemToAdd._tpl)[1]; const modItemDbDetails = this.getItem(modItemToAdd._tpl)[1];
// Include conflicting items of newly added mod in pool to be used for next mod choice // Include conflicting items of newly added mod in pool to be used for next mod choice
// biome-ignore lint/complexity/noForEach: <explanation> // biome-ignore lint/complexity/noForEach: <explanation>