Refactor of RagfairAssortGenerator
and associated code that touches it
This commit is contained in:
parent
86d34e3efe
commit
4ce26ea870
@ -16,7 +16,7 @@ import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
||||
@injectable()
|
||||
export class RagfairAssortGenerator
|
||||
{
|
||||
protected generatedAssortItems: Item[] = [];
|
||||
protected generatedAssortItems: Item[][] = [];
|
||||
protected ragfairConfig: IRagfairConfig;
|
||||
|
||||
protected ragfairItemInvalidBaseTypes: string[] = [
|
||||
@ -43,10 +43,11 @@ export class RagfairAssortGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of unique items that can be sold on the flea
|
||||
* @returns array of unique items
|
||||
* Get an array of arrays that can be sold on the flea
|
||||
* Each sub array contains item + children (if any)
|
||||
* @returns array of arrays
|
||||
*/
|
||||
public getAssortItems(): Item[]
|
||||
public getAssortItems(): Item[][]
|
||||
{
|
||||
if (!this.assortsAreGenerated())
|
||||
{
|
||||
@ -66,16 +67,17 @@ export class RagfairAssortGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of items the flea can sell
|
||||
* @returns array of unique items
|
||||
* Generate an array of arrays (item + children) the flea can sell
|
||||
* @returns array of arrays (item + children)
|
||||
*/
|
||||
protected generateRagfairAssortItems(): Item[]
|
||||
protected generateRagfairAssortItems(): Item[][]
|
||||
{
|
||||
const results: Item[] = [];
|
||||
const results: Item[][] = [];
|
||||
|
||||
/** Get cloned items from db */
|
||||
const dbItemsClone = this.itemHelper.getItems().filter(item => item._type !== "Node");
|
||||
|
||||
/** Store processed preset tpls so we dont add them when procesing non-preset items */
|
||||
const processedArmorItems: string[] = [];
|
||||
const seasonalEventActive = this.seasonalEventService.seasonalEventEnabled();
|
||||
const seasonalItemTplBlacklist = this.seasonalEventService.getInactiveSeasonalEventItems();
|
||||
@ -83,13 +85,21 @@ export class RagfairAssortGenerator
|
||||
const presets = this.getPresetsToAdd();
|
||||
for (const preset of presets)
|
||||
{
|
||||
const presetItemTpl = preset._items[0]._tpl;
|
||||
// Update Ids and clone
|
||||
const presetAndMods: Item[] = this.itemHelper.replaceIDs(
|
||||
null,
|
||||
this.jsonUtil.clone(preset._items),
|
||||
);
|
||||
this.itemHelper.remapRootItemId(presetAndMods);
|
||||
|
||||
// Add presets base item tpl to the processed list so its skipped later on when processing items
|
||||
processedArmorItems.push(presetItemTpl)
|
||||
processedArmorItems.push(preset._items[0]._tpl);
|
||||
|
||||
// Preset id must be passed through to ensure flea shows preset
|
||||
results.push(this.createRagfairAssortItem(presetItemTpl, preset._id));
|
||||
presetAndMods[0].parentId = "hideout";
|
||||
presetAndMods[0].slotId = "hideout";
|
||||
presetAndMods[0].upd = { StackObjectsCount: 99999999, UnlimitedCount: true, sptPresetId: preset._id};
|
||||
|
||||
results.push(presetAndMods);
|
||||
}
|
||||
|
||||
for (const item of dbItemsClone)
|
||||
@ -114,7 +124,9 @@ export class RagfairAssortGenerator
|
||||
continue;
|
||||
}
|
||||
|
||||
results.push(this.createRagfairAssortItem(item._id, item._id)); // tplid and id must be the same so hideout recipe rewards work
|
||||
const ragfairAssort = this.createRagfairAssortRootItem(item._id, item._id); // tplid and id must be the same so hideout recipe rewards work
|
||||
|
||||
results.push([ragfairAssort]);
|
||||
}
|
||||
|
||||
return results;
|
||||
@ -136,9 +148,9 @@ export class RagfairAssortGenerator
|
||||
* Create a base assort item and return it with populated values + 999999 stack count + unlimited count = true
|
||||
* @param tplId tplid to add to item
|
||||
* @param id id to add to item
|
||||
* @returns hydrated Item object
|
||||
* @returns Hydrated Item object
|
||||
*/
|
||||
protected createRagfairAssortItem(tplId: string, id = this.hashUtil.generate()): Item
|
||||
protected createRagfairAssortRootItem(tplId: string, id = this.hashUtil.generate()): Item
|
||||
{
|
||||
return {
|
||||
_id: id,
|
||||
|
@ -312,21 +312,22 @@ export class RagfairOfferGenerator
|
||||
* Create multiple offers for items by using a unique list of items we've generated previously
|
||||
* @param expiredOffers optional, expired offers to regenerate
|
||||
*/
|
||||
public async generateDynamicOffers(expiredOffers: Item[] = null): Promise<void>
|
||||
public async generateDynamicOffers(expiredOffers: Item[][] = null): Promise<void>
|
||||
{
|
||||
const replacingExpiredOffers = expiredOffers?.length > 0;
|
||||
const config = this.ragfairConfig.dynamic;
|
||||
|
||||
// get assort items from param if they exist, otherwise grab freshly generated assorts
|
||||
const assortItemsToProcess: Item[] = expiredOffers
|
||||
const assortItemsToProcess: Item[][] = replacingExpiredOffers
|
||||
? expiredOffers
|
||||
: this.ragfairAssortGenerator.getAssortItems();
|
||||
|
||||
// Store all functions to create an offer for every item and pass into Promise.all to run async
|
||||
const assorOffersForItemsProcesses = [];
|
||||
for (const assortItemIndex in assortItemsToProcess)
|
||||
for (const assortItemWithChildren of assortItemsToProcess)
|
||||
{
|
||||
assorOffersForItemsProcesses.push(
|
||||
this.createOffersForItems(assortItemIndex, assortItemsToProcess, expiredOffers, config),
|
||||
this.createOffersFromAssort(assortItemWithChildren, replacingExpiredOffers, config),
|
||||
);
|
||||
}
|
||||
|
||||
@ -334,47 +335,34 @@ export class RagfairOfferGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param assortItemIndex Index of assort item
|
||||
* @param assortItemsToProcess Item array containing index
|
||||
* @param expiredOffers Currently expired offers on flea
|
||||
* @param assortItemWithChildren Item with its children to process into offers
|
||||
* @param isExpiredOffer is an expired offer
|
||||
* @param config Ragfair dynamic config
|
||||
*/
|
||||
protected async createOffersForItems(
|
||||
assortItemIndex: string,
|
||||
assortItemsToProcess: Item[],
|
||||
expiredOffers: Item[],
|
||||
protected async createOffersFromAssort(
|
||||
assortItemWithChildren: Item[],
|
||||
isExpiredOffer: boolean,
|
||||
config: Dynamic,
|
||||
): Promise<void>
|
||||
{
|
||||
const assortItem = assortItemsToProcess[assortItemIndex];
|
||||
const itemDetails = this.itemHelper.getItem(assortItem._tpl);
|
||||
|
||||
const isPreset = this.presetHelper.isPreset(assortItem._id);
|
||||
const itemDetails = this.itemHelper.getItem(assortItemWithChildren[0]._tpl);
|
||||
const isPreset = this.presetHelper.isPreset(assortItemWithChildren[0].upd.sptPresetId);
|
||||
|
||||
// Only perform checks on newly generated items, skip expired items being refreshed
|
||||
if (!(expiredOffers || this.ragfairServerHelper.isItemValidRagfairItem(itemDetails)))
|
||||
if (!(isExpiredOffer || this.ragfairServerHelper.isItemValidRagfairItem(itemDetails)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get item + sub-items (weapons + armors), otherwise just get item
|
||||
const itemWithChildren: Item[] = isPreset
|
||||
? this.ragfairServerHelper.getPresetItems(assortItem)
|
||||
: [
|
||||
...[assortItem],
|
||||
...this.itemHelper.findAndReturnChildrenByAssort(assortItem._id, this.ragfairAssortGenerator.getAssortItems(),
|
||||
),
|
||||
];
|
||||
|
||||
// Armor presets can hold plates above the allowed flea level, remove if necessary
|
||||
if (isPreset && this.ragfairConfig.dynamic.blacklist.enableBsgList)
|
||||
{
|
||||
this.removeBannedPlatesFromPreset(itemWithChildren, this.ragfairConfig.dynamic.blacklist.armorPlateMaxProtectionLevel);
|
||||
this.removeBannedPlatesFromPreset(assortItemWithChildren, this.ragfairConfig.dynamic.blacklist.armorPlateMaxProtectionLevel);
|
||||
}
|
||||
|
||||
// Get number of offers to create
|
||||
// Limit to 1 offer when processing expired
|
||||
const offerCount = expiredOffers
|
||||
// Limit to 1 offer when processing expired - like-for-like replacement
|
||||
const offerCount = isExpiredOffer
|
||||
? 1
|
||||
: Math.round(this.randomUtil.getInt(config.offerItemCount.min, config.offerItemCount.max));
|
||||
|
||||
@ -385,13 +373,13 @@ export class RagfairOfferGenerator
|
||||
if (!isPreset)
|
||||
{
|
||||
// Presets get unique id generated during getPresetItems() earlier + would require regenerating all children to match
|
||||
itemWithChildren[0]._id = this.hashUtil.generate();
|
||||
assortItemWithChildren[0]._id = this.hashUtil.generate();
|
||||
}
|
||||
|
||||
delete itemWithChildren[0].parentId;
|
||||
delete itemWithChildren[0].slotId;
|
||||
delete assortItemWithChildren[0].parentId;
|
||||
delete assortItemWithChildren[0].slotId;
|
||||
|
||||
assortSingleOfferProcesses.push(this.createSingleOfferForItem(itemWithChildren, isPreset, itemDetails));
|
||||
assortSingleOfferProcesses.push(this.createSingleOfferForItem(assortItemWithChildren, isPreset, itemDetails));
|
||||
}
|
||||
|
||||
await Promise.all(assortSingleOfferProcesses);
|
||||
|
@ -261,7 +261,7 @@ export class TraderAssortHelper
|
||||
protected getRagfairDataAsTraderAssort(): ITraderAssort
|
||||
{
|
||||
return {
|
||||
items: this.ragfairAssortGenerator.getAssortItems(),
|
||||
items: this.ragfairAssortGenerator.getAssortItems().flat(),
|
||||
barter_scheme: {},
|
||||
loyal_level_items: {},
|
||||
nextResupply: null,
|
||||
|
@ -47,27 +47,27 @@ export class RagfairServer
|
||||
|
||||
// Generate trader offers
|
||||
const traders = this.getUpdateableTraders();
|
||||
for (const traderID of traders)
|
||||
for (const traderId of traders)
|
||||
{
|
||||
// Skip generating fence offers
|
||||
if (traderID === Traders.FENCE)
|
||||
if (traderId === Traders.FENCE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.ragfairOfferService.traderOffersNeedRefreshing(traderID))
|
||||
if (this.ragfairOfferService.traderOffersNeedRefreshing(traderId))
|
||||
{
|
||||
this.ragfairOfferGenerator.generateFleaOffersForTrader(traderID);
|
||||
this.ragfairOfferGenerator.generateFleaOffersForTrader(traderId);
|
||||
}
|
||||
}
|
||||
|
||||
// Regen expired offers when over threshold count
|
||||
// Regenerate expired offers when over threshold limit
|
||||
if (this.ragfairOfferService.getExpiredOfferCount() >= this.ragfairConfig.dynamic.expiredOfferThreshold)
|
||||
{
|
||||
const expiredOfferItems = this.ragfairOfferService.getExpiredOfferItems();
|
||||
await this.ragfairOfferGenerator.generateDynamicOffers(expiredOfferItems);
|
||||
const expiredAssortsWithChildren = this.ragfairOfferService.getExpiredOfferAssorts();
|
||||
await this.ragfairOfferGenerator.generateDynamicOffers(expiredAssortsWithChildren);
|
||||
|
||||
// reset expired offers now we've genned them
|
||||
// Clear out expired offers now we've generated them
|
||||
this.ragfairOfferService.resetExpiredOffers();
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import { TimeUtil } from "@spt-aki/utils/TimeUtil";
|
||||
export class RagfairOfferService
|
||||
{
|
||||
protected playerOffersLoaded = false;
|
||||
/** Offer id + offer object */
|
||||
protected expiredOffers: Record<string, IRagfairOffer> = {};
|
||||
|
||||
protected ragfairConfig: IRagfairConfig;
|
||||
@ -71,27 +72,35 @@ export class RagfairOfferService
|
||||
this.expiredOffers[staleOffer._id] = staleOffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total count of current expired offers
|
||||
* @returns Number of expired offers
|
||||
*/
|
||||
public getExpiredOfferCount(): number
|
||||
{
|
||||
return Object.keys(this.expiredOffers).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of expired items not yet processed into new offers
|
||||
* @returns items that need to be turned into offers
|
||||
* Get an array of arrays of expired offer items + children
|
||||
* @returns Expired offer assorts
|
||||
*/
|
||||
public getExpiredOfferItems(): Item[]
|
||||
public getExpiredOfferAssorts(): Item[][]
|
||||
{
|
||||
const expiredItems: Item[] = [];
|
||||
const expiredItems: Item[][] = [];
|
||||
|
||||
for (const expiredOfferId in this.expiredOffers)
|
||||
{
|
||||
expiredItems.push(this.expiredOffers[expiredOfferId].items[0]);
|
||||
const expiredOffer = this.expiredOffers[expiredOfferId];
|
||||
expiredItems.push(expiredOffer.items);
|
||||
}
|
||||
|
||||
return expiredItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out internal expiredOffers dictionary of all items
|
||||
*/
|
||||
public resetExpiredOffers(): void
|
||||
{
|
||||
this.expiredOffers = {};
|
||||
|
Loading…
Reference in New Issue
Block a user