2023-03-03 15:23:46 +00:00
|
|
|
import { inject, injectable } from "tsyringe";
|
|
|
|
|
2023-10-19 17:21:17 +00:00
|
|
|
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
2024-01-16 10:28:08 +00:00
|
|
|
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
|
2023-10-19 17:21:17 +00:00
|
|
|
import { IPreset } from "@spt-aki/models/eft/common/IGlobals";
|
|
|
|
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
|
|
|
|
import { BaseClasses } from "@spt-aki/models/enums/BaseClasses";
|
|
|
|
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
|
|
|
import { IRagfairConfig } from "@spt-aki/models/spt/config/IRagfairConfig";
|
|
|
|
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
|
|
|
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
|
|
|
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
|
|
|
|
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
|
|
|
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
2023-03-03 15:23:46 +00:00
|
|
|
|
|
|
|
@injectable()
|
|
|
|
export class RagfairAssortGenerator
|
|
|
|
{
|
2024-01-23 14:17:01 +00:00
|
|
|
protected generatedAssortItems: Item[][] = [];
|
2023-03-03 15:23:46 +00:00
|
|
|
protected ragfairConfig: IRagfairConfig;
|
|
|
|
|
2024-01-23 12:46:29 +00:00
|
|
|
protected ragfairItemInvalidBaseTypes: string[] = [
|
|
|
|
BaseClasses.LOOT_CONTAINER, // Safe, barrel cache etc
|
|
|
|
BaseClasses.STASH, // Player inventory stash
|
|
|
|
BaseClasses.SORTING_TABLE,
|
|
|
|
BaseClasses.INVENTORY,
|
|
|
|
BaseClasses.STATIONARY_CONTAINER,
|
|
|
|
BaseClasses.POCKETS,
|
|
|
|
BaseClasses.BUILT_IN_INSERTS,
|
|
|
|
];
|
|
|
|
|
2023-03-03 15:23:46 +00:00
|
|
|
constructor(
|
|
|
|
@inject("JsonUtil") protected jsonUtil: JsonUtil,
|
|
|
|
@inject("HashUtil") protected hashUtil: HashUtil,
|
|
|
|
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
2024-01-16 10:28:08 +00:00
|
|
|
@inject("PresetHelper") protected presetHelper: PresetHelper,
|
2023-03-03 15:23:46 +00:00
|
|
|
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
|
|
|
|
@inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService,
|
2023-11-15 20:35:05 -05:00
|
|
|
@inject("ConfigServer") protected configServer: ConfigServer,
|
2023-03-03 15:23:46 +00:00
|
|
|
)
|
|
|
|
{
|
|
|
|
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-01-23 14:17:01 +00:00
|
|
|
* Get an array of arrays that can be sold on the flea
|
|
|
|
* Each sub array contains item + children (if any)
|
|
|
|
* @returns array of arrays
|
2023-03-03 15:23:46 +00:00
|
|
|
*/
|
2024-01-23 14:17:01 +00:00
|
|
|
public getAssortItems(): Item[][]
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
|
|
|
if (!this.assortsAreGenerated())
|
|
|
|
{
|
|
|
|
this.generatedAssortItems = this.generateRagfairAssortItems();
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.generatedAssortItems;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check internal generatedAssortItems array has objects
|
|
|
|
* @returns true if array has objects
|
|
|
|
*/
|
|
|
|
protected assortsAreGenerated(): boolean
|
|
|
|
{
|
|
|
|
return this.generatedAssortItems.length > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-01-23 14:17:01 +00:00
|
|
|
* Generate an array of arrays (item + children) the flea can sell
|
|
|
|
* @returns array of arrays (item + children)
|
2023-03-03 15:23:46 +00:00
|
|
|
*/
|
2024-01-23 14:17:01 +00:00
|
|
|
protected generateRagfairAssortItems(): Item[][]
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-01-23 14:17:01 +00:00
|
|
|
const results: Item[][] = [];
|
2023-03-03 15:23:46 +00:00
|
|
|
|
2024-01-23 12:46:29 +00:00
|
|
|
/** Get cloned items from db */
|
2024-02-02 13:54:07 -05:00
|
|
|
const dbItemsClone = this.itemHelper.getItems().filter((item) => item._type !== "Node");
|
2024-01-23 12:46:29 +00:00
|
|
|
|
2024-01-23 14:17:01 +00:00
|
|
|
/** Store processed preset tpls so we dont add them when procesing non-preset items */
|
2024-01-23 12:46:29 +00:00
|
|
|
const processedArmorItems: string[] = [];
|
2023-03-03 15:23:46 +00:00
|
|
|
const seasonalEventActive = this.seasonalEventService.seasonalEventEnabled();
|
2023-11-01 11:35:05 +00:00
|
|
|
const seasonalItemTplBlacklist = this.seasonalEventService.getInactiveSeasonalEventItems();
|
2024-02-02 13:54:07 -05:00
|
|
|
|
2024-01-23 12:46:29 +00:00
|
|
|
const presets = this.getPresetsToAdd();
|
|
|
|
for (const preset of presets)
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-01-23 14:17:01 +00:00
|
|
|
// Update Ids and clone
|
2024-02-05 22:22:03 -05:00
|
|
|
const presetAndMods: Item[] = this.itemHelper.replaceIDs(preset._items);
|
2024-01-23 14:17:01 +00:00
|
|
|
this.itemHelper.remapRootItemId(presetAndMods);
|
2024-01-23 12:46:29 +00:00
|
|
|
|
|
|
|
// Add presets base item tpl to the processed list so its skipped later on when processing items
|
2024-01-23 14:17:01 +00:00
|
|
|
processedArmorItems.push(preset._items[0]._tpl);
|
2024-01-23 12:46:29 +00:00
|
|
|
|
2024-01-23 14:17:01 +00:00
|
|
|
presetAndMods[0].parentId = "hideout";
|
|
|
|
presetAndMods[0].slotId = "hideout";
|
2024-02-02 13:54:07 -05:00
|
|
|
presetAndMods[0].upd = { StackObjectsCount: 99999999, UnlimitedCount: true, sptPresetId: preset._id };
|
2024-01-23 14:17:01 +00:00
|
|
|
|
2024-02-02 13:54:07 -05:00
|
|
|
results.push(presetAndMods);
|
2024-01-23 12:46:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const item of dbItemsClone)
|
|
|
|
{
|
|
|
|
if (!this.itemHelper.isValidItem(item._id, this.ragfairItemInvalidBaseTypes))
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-01-23 12:46:29 +00:00
|
|
|
// Skip seasonal items when not in-season
|
2023-11-15 20:35:05 -05:00
|
|
|
if (
|
|
|
|
this.ragfairConfig.dynamic.removeSeasonalItemsWhenNotInEvent && !seasonalEventActive
|
|
|
|
&& seasonalItemTplBlacklist.includes(item._id)
|
|
|
|
)
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-01-23 12:46:29 +00:00
|
|
|
if (processedArmorItems.includes(item._id))
|
|
|
|
{
|
|
|
|
// Already processed
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-03 15:23:46 +00:00
|
|
|
|
2024-01-23 14:17:01 +00:00
|
|
|
const ragfairAssort = this.createRagfairAssortRootItem(item._id, item._id); // tplid and id must be the same so hideout recipe rewards work
|
|
|
|
|
2024-02-02 13:54:07 -05:00
|
|
|
results.push([ragfairAssort]);
|
2023-03-03 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return results;
|
|
|
|
}
|
2023-11-15 20:35:05 -05:00
|
|
|
|
2024-01-23 12:46:29 +00:00
|
|
|
/**
|
|
|
|
* Get presets from globals to add to flea
|
|
|
|
* ragfairConfig.dynamic.showDefaultPresetsOnly decides if its all presets or just defaults
|
|
|
|
* @returns IPreset array
|
|
|
|
*/
|
|
|
|
protected getPresetsToAdd(): IPreset[]
|
|
|
|
{
|
|
|
|
return (this.ragfairConfig.dynamic.showDefaultPresetsOnly)
|
2024-02-02 13:54:07 -05:00
|
|
|
? Object.values(this.presetHelper.getDefaultPresets())
|
|
|
|
: this.presetHelper.getAllPresets();
|
2024-01-23 12:46:29 +00:00
|
|
|
}
|
|
|
|
|
2023-03-03 15:23:46 +00:00
|
|
|
/**
|
|
|
|
* 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
|
2024-01-23 14:17:01 +00:00
|
|
|
* @returns Hydrated Item object
|
2023-03-03 15:23:46 +00:00
|
|
|
*/
|
2024-01-23 14:17:01 +00:00
|
|
|
protected createRagfairAssortRootItem(tplId: string, id = this.hashUtil.generate()): Item
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
|
|
|
return {
|
|
|
|
_id: id,
|
|
|
|
_tpl: tplId,
|
|
|
|
parentId: "hideout",
|
|
|
|
slotId: "hideout",
|
2023-11-15 20:35:05 -05:00
|
|
|
upd: { StackObjectsCount: 99999999, UnlimitedCount: true },
|
2023-03-03 15:23:46 +00:00
|
|
|
};
|
|
|
|
}
|
2023-11-15 20:35:05 -05:00
|
|
|
}
|