improve add trader example

This commit is contained in:
Chomp 2022-12-25 11:04:14 +00:00
parent 24f6974570
commit a06b37273d

View File

@ -16,7 +16,7 @@ import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { IDatabaseTables } from "@spt-aki/models/spt/server/IDatabaseTables"; import { IDatabaseTables } from "@spt-aki/models/spt/server/IDatabaseTables";
import { Money } from "@spt-aki/models/enums/Money"; import { Money } from "@spt-aki/models/enums/Money";
// The new trader config // New trader settings
import * as baseJson from "../db/base.json"; import * as baseJson from "../db/base.json";
class SampleTrader implements IPreAkiLoadMod, IPostDBLoadMod { class SampleTrader implements IPreAkiLoadMod, IPostDBLoadMod {
@ -24,65 +24,103 @@ class SampleTrader implements IPreAkiLoadMod, IPostDBLoadMod {
logger: ILogger logger: ILogger
constructor() { constructor() {
this.mod = "13AddTrader"; this.mod = "13AddTrader"; // Set name of mod so we can log it to console later
} }
/**
* Some work needs to be done prior to SPT code being loaded, registering the profile image + setting trader update time inside the trader config json
* @param container Dependency container
*/
public preAkiLoad(container: DependencyContainer): void { public preAkiLoad(container: DependencyContainer): void {
this.logger = container.resolve<ILogger>("WinstonLogger"); this.logger = container.resolve<ILogger>("WinstonLogger");
this.logger.debug(`[${this.mod}] Loading... `); this.logger.debug(`[${this.mod}] preAki Loading... `);
this.registerProfileImage(container); const preAkiModLoader: PreAkiModLoader = container.resolve<PreAkiModLoader>("PreAkiModLoader");
const imageRouter: ImageRouter = container.resolve<ImageRouter>("ImageRouter");
const configServer = container.resolve<ConfigServer>("ConfigServer");
const traderConfig: ITraderConfig = configServer.getConfig<ITraderConfig>(ConfigTypes.TRADER);
this.setupTraderUpdateTime(container); this.registerProfileImage(preAkiModLoader, imageRouter);
this.logger.debug(`[${this.mod}] Loaded`); this.setupTraderUpdateTime(traderConfig);
this.logger.debug(`[${this.mod}] preAki Loaded`);
} }
/**
* Majority of trader-related work occurs after the aki database has been loaded but prior to SPT code being run
* @param container Dependency container
*/
public postDBLoad(container: DependencyContainer): void { public postDBLoad(container: DependencyContainer): void {
this.logger.debug(`[${this.mod}] Delayed Loading... `); this.logger.debug(`[${this.mod}] postDb Loading... `);
// Resolve SPT classes we'll use
const databaseServer: DatabaseServer = container.resolve<DatabaseServer>("DatabaseServer"); const databaseServer: DatabaseServer = container.resolve<DatabaseServer>("DatabaseServer");
const configServer: ConfigServer = container.resolve<ConfigServer>("ConfigServer"); const configServer: ConfigServer = container.resolve<ConfigServer>("ConfigServer");
const traderConfig: ITraderConfig = configServer.getConfig(ConfigTypes.TRADER); const traderConfig: ITraderConfig = configServer.getConfig(ConfigTypes.TRADER);
const jsonUtil = container.resolve<JsonUtil>("JsonUtil"); const jsonUtil: JsonUtil = container.resolve<JsonUtil>("JsonUtil");
// Keep a reference to the tables // Get a reference to the database tables
const tables = databaseServer.getTables(); const tables = databaseServer.getTables();
// Add the new trader to the trader lists in DatabaseServer // Add new trader to the trader dictionary in DatabaseServer
tables.traders[baseJson._id] = { this.addTraderToDb(baseJson, tables, jsonUtil);
assort: this.createAssortTable(),
base: jsonUtil.deserialize(jsonUtil.serialize(baseJson)) as ITraderBase,
questassort: {} // Empty object as trader has no assorts unlocked by quests
};
this.addTraderToLocales(tables, baseJson.name, "Cat", baseJson.nickname, baseJson.location, "This is the cat shop"); this.addTraderToLocales(tables, baseJson.name, "Cat", baseJson.nickname, baseJson.location, "This is the cat shop");
// Add item purchase threshold value (what % durability does trader stop buying items at) // Add item purchase threshold value (what % durability does trader stop buying items at)
traderConfig.durabilityPurchaseThreshhold[baseJson._id] = 60; traderConfig.durabilityPurchaseThreshhold[baseJson._id] = 60;
this.logger.debug(`[${this.mod}] Delayed Loaded`); this.logger.debug(`[${this.mod}] postDb Loaded`);
} }
private registerProfileImage(container: DependencyContainer): void { /**
* Add profile picture to our trader
* @param preAkiModLoader mod loader class - used to get the mods file path
* @param imageRouter image router class - used to register the trader image path so we see their image on trader page
*/
private registerProfileImage(preAkiModLoader: PreAkiModLoader, imageRouter: ImageRouter): void
{
// Reference the mod "res" folder // Reference the mod "res" folder
const preAkiModLoader = container.resolve<PreAkiModLoader>("PreAkiModLoader");
const imageFilepath = `./${preAkiModLoader.getModPath(this.mod)}res`; const imageFilepath = `./${preAkiModLoader.getModPath(this.mod)}res`;
// Register route pointing to the profile picture // Register a route to point to the profile picture
const imageRouter = container.resolve<ImageRouter>("ImageRouter");
imageRouter.addRoute(baseJson.avatar.replace(".jpg", ""), `${imageFilepath}/cat.jpg`); imageRouter.addRoute(baseJson.avatar.replace(".jpg", ""), `${imageFilepath}/cat.jpg`);
} }
private setupTraderUpdateTime(container: DependencyContainer): void { /**
// Add refresh time in seconds when Config server allows to set configs * Add record to trader config to set the refresh time of trader in seconds (default is 60 minutes)
const configServer = container.resolve<ConfigServer>("ConfigServer"); * @param traderConfig trader config to add our trader to
const traderConfig = configServer.getConfig<ITraderConfig>(ConfigTypes.TRADER); */
const traderRefreshConfig: UpdateTime = { traderId: baseJson._id, seconds: 3600 } private setupTraderUpdateTime(traderConfig: ITraderConfig): void
traderConfig.updateTime.push(traderRefreshConfig); {
// Add refresh time in seconds to config
const traderRefreshRecord: UpdateTime = { traderId: baseJson._id, seconds: 3600 }
traderConfig.updateTime.push(traderRefreshRecord);
} }
private createAssortTable(): ITraderAssort { /**
* Add our new trader to the database
* @param traderDetailsToAdd trader details
* @param tables database
* @param jsonUtil json utility class
*/
private addTraderToDb(traderDetailsToAdd: any, tables: IDatabaseTables, jsonUtil: JsonUtil): void
{
// Add trader to trader table, key is the traders id
tables.traders[traderDetailsToAdd._id] = {
assort: this.createAssortTable(), // assorts are the 'offers' trader sells, can be a single item (e.g. carton of milk) or multiple items as a collection (e.g. a gun)
base: jsonUtil.deserialize(jsonUtil.serialize(traderDetailsToAdd)) as ITraderBase,
questassort: {} // Empty object as trader has no assorts unlocked by quests
};
}
/**
* Create assorts for trader and add milk to it
* @returns ITraderAssort
*/
private createAssortTable(): ITraderAssort
{
// Assort table // Assort table
const assortTable: ITraderAssort = { const assortTable: ITraderAssort = {
nextResupply: 0, nextResupply: 0,
@ -91,8 +129,8 @@ class SampleTrader implements IPreAkiLoadMod, IPostDBLoadMod {
loyal_level_items: {} loyal_level_items: {}
} }
const MILK_ID = "575146b724597720a27126d5"; const MILK_ID = "575146b724597720a27126d5"; // Can find item ids in `database\templates\items.json`
this.addItemToAssort(assortTable, MILK_ID, true, 9999999, 1, Money.ROUBLES, 1); this.addSingleItemToAssort(assortTable, MILK_ID, true, 9999999, 1, Money.ROUBLES, 1);
return assortTable; return assortTable;
} }
@ -107,7 +145,8 @@ class SampleTrader implements IPreAkiLoadMod, IPostDBLoadMod {
* @param currencyType What currency does item sell for * @param currencyType What currency does item sell for
* @param currencyValue Amount of currency item can be purchased for * @param currencyValue Amount of currency item can be purchased for
*/ */
private addItemToAssort(assortTable: ITraderAssort, itemTpl: string, unlimitedCount: boolean, stackCount: number, loyaltyLevel: number, currencyType: Money, currencyValue: number) { private addSingleItemToAssort(assortTable: ITraderAssort, itemTpl: string, unlimitedCount: boolean, stackCount: number, loyaltyLevel: number, currencyType: Money, currencyValue: number)
{
// Define item in the table // Define item in the table
const newItem: Item = { const newItem: Item = {
_id: itemTpl, _id: itemTpl,
@ -135,6 +174,15 @@ class SampleTrader implements IPreAkiLoadMod, IPostDBLoadMod {
assortTable.loyal_level_items[itemTpl] = loyaltyLevel; assortTable.loyal_level_items[itemTpl] = loyaltyLevel;
} }
/**
* Add traders name/location/description to the locale table
* @param tables database tables
* @param fullName fullname of trader
* @param firstName first name of trader
* @param nickName nickname of trader
* @param location location of trader
* @param description description of trader
*/
private addTraderToLocales(tables: IDatabaseTables, fullName: string, firstName: string, nickName: string, location: string, description: string) private addTraderToLocales(tables: IDatabaseTables, fullName: string, firstName: string, nickName: string, location: string, description: string)
{ {
// For each language, add locale for the new trader // For each language, add locale for the new trader