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";
|
|
|
|
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
|
|
|
import { TradeHelper } from "@spt-aki/helpers/TradeHelper";
|
|
|
|
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
|
|
|
|
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
|
|
|
import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem";
|
|
|
|
import { ITraderBase } from "@spt-aki/models/eft/common/tables/ITrader";
|
|
|
|
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
2024-01-16 11:47:40 +00:00
|
|
|
import { IRagfairOffer } from "@spt-aki/models/eft/ragfair/IRagfairOffer";
|
2023-10-19 17:21:17 +00:00
|
|
|
import { IProcessBaseTradeRequestData } from "@spt-aki/models/eft/trade/IProcessBaseTradeRequestData";
|
|
|
|
import { IProcessBuyTradeRequestData } from "@spt-aki/models/eft/trade/IProcessBuyTradeRequestData";
|
2024-02-02 13:54:07 -05:00
|
|
|
import {
|
|
|
|
IOfferRequest,
|
|
|
|
IProcessRagfairTradeRequestData,
|
|
|
|
} from "@spt-aki/models/eft/trade/IProcessRagfairTradeRequestData";
|
2023-10-19 17:21:17 +00:00
|
|
|
import { IProcessSellTradeRequestData } from "@spt-aki/models/eft/trade/IProcessSellTradeRequestData";
|
|
|
|
import { ISellScavItemsToFenceRequestData } from "@spt-aki/models/eft/trade/ISellScavItemsToFenceRequestData";
|
|
|
|
import { BackendErrorCodes } from "@spt-aki/models/enums/BackendErrorCodes";
|
|
|
|
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
|
|
|
import { MemberCategory } from "@spt-aki/models/enums/MemberCategory";
|
2024-02-04 19:27:35 +00:00
|
|
|
import { MessageType } from "@spt-aki/models/enums/MessageType";
|
2023-10-19 17:21:17 +00:00
|
|
|
import { Traders } from "@spt-aki/models/enums/Traders";
|
|
|
|
import { IRagfairConfig } from "@spt-aki/models/spt/config/IRagfairConfig";
|
|
|
|
import { ITraderConfig } from "@spt-aki/models/spt/config/ITraderConfig";
|
|
|
|
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
|
|
|
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
|
|
|
|
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
2024-02-04 19:27:35 +00:00
|
|
|
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
2023-10-19 17:21:17 +00:00
|
|
|
import { RagfairServer } from "@spt-aki/servers/RagfairServer";
|
|
|
|
import { LocalisationService } from "@spt-aki/services/LocalisationService";
|
2024-02-04 19:27:35 +00:00
|
|
|
import { MailSendService } from "@spt-aki/services/MailSendService";
|
2023-10-19 17:21:17 +00:00
|
|
|
import { RagfairPriceService } from "@spt-aki/services/RagfairPriceService";
|
2024-02-04 19:27:35 +00:00
|
|
|
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
2023-10-19 17:21:17 +00:00
|
|
|
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
|
|
|
|
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
2024-02-04 19:27:35 +00:00
|
|
|
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
|
|
|
|
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
|
2023-03-03 15:23:46 +00:00
|
|
|
|
|
|
|
@injectable()
|
2023-12-15 14:43:05 +00:00
|
|
|
export class TradeController
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-02-04 19:27:35 +00:00
|
|
|
protected roubleTpl = "5449016a4bdc2d6f028b456f";
|
|
|
|
|
2023-03-03 15:23:46 +00:00
|
|
|
protected ragfairConfig: IRagfairConfig;
|
|
|
|
protected traderConfig: ITraderConfig;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
@inject("WinstonLogger") protected logger: ILogger,
|
2024-02-04 19:27:35 +00:00
|
|
|
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
|
2023-03-03 15:23:46 +00:00
|
|
|
@inject("EventOutputHolder") protected eventOutputHolder: EventOutputHolder,
|
|
|
|
@inject("TradeHelper") protected tradeHelper: TradeHelper,
|
2024-02-04 19:27:35 +00:00
|
|
|
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
|
|
|
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
|
|
@inject("HashUtil") protected hashUtil: HashUtil,
|
2023-03-03 15:23:46 +00:00
|
|
|
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
|
|
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
2023-10-10 11:03:20 +00:00
|
|
|
@inject("TraderHelper") protected traderHelper: TraderHelper,
|
2023-08-09 10:49:45 +00:00
|
|
|
@inject("JsonUtil") protected jsonUtil: JsonUtil,
|
2023-03-03 15:23:46 +00:00
|
|
|
@inject("RagfairServer") protected ragfairServer: RagfairServer,
|
|
|
|
@inject("HttpResponseUtil") protected httpResponse: HttpResponseUtil,
|
|
|
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
2023-10-10 11:03:20 +00:00
|
|
|
@inject("RagfairPriceService") protected ragfairPriceService: RagfairPriceService,
|
2024-02-04 19:27:35 +00:00
|
|
|
@inject("MailSendService") protected mailSendService: MailSendService,
|
2023-11-16 21:42:06 +00:00
|
|
|
@inject("ConfigServer") protected configServer: ConfigServer,
|
2023-03-03 15:23:46 +00:00
|
|
|
)
|
|
|
|
{
|
|
|
|
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
|
|
|
|
this.traderConfig = this.configServer.getConfig(ConfigTypes.TRADER);
|
|
|
|
}
|
|
|
|
|
2023-07-15 14:49:25 +01:00
|
|
|
/** Handle TradingConfirm event */
|
2023-11-16 21:42:06 +00:00
|
|
|
public confirmTrading(
|
|
|
|
pmcData: IPmcData,
|
|
|
|
request: IProcessBaseTradeRequestData,
|
|
|
|
sessionID: string,
|
|
|
|
): IItemEventRouterResponse
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-01-16 11:47:40 +00:00
|
|
|
const output = this.eventOutputHolder.getOutput(sessionID);
|
|
|
|
|
|
|
|
// Buying
|
|
|
|
if (request.type === "buy_from_trader")
|
|
|
|
{
|
|
|
|
const foundInRaid = this.traderConfig.purchasesAreFoundInRaid;
|
|
|
|
const buyData = <IProcessBuyTradeRequestData>request;
|
2024-01-16 12:21:42 +00:00
|
|
|
this.tradeHelper.buyItem(pmcData, buyData, sessionID, foundInRaid, output);
|
|
|
|
|
|
|
|
return output;
|
2024-01-16 11:47:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Selling
|
|
|
|
if (request.type === "sell_to_trader")
|
|
|
|
{
|
|
|
|
const sellData = <IProcessSellTradeRequestData>request;
|
2024-01-16 12:21:42 +00:00
|
|
|
this.tradeHelper.sellItem(pmcData, pmcData, sellData, sessionID, output);
|
|
|
|
|
|
|
|
return output;
|
2024-01-16 11:47:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const errorMessage = `Unhandled trade event: ${request.type}`;
|
|
|
|
this.logger.error(errorMessage);
|
|
|
|
|
|
|
|
return this.httpResponse.appendErrorToOutput(output, errorMessage, BackendErrorCodes.RAGFAIRUNAVAILABLE);
|
2023-03-03 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
2023-07-15 14:49:25 +01:00
|
|
|
/** Handle RagFairBuyOffer event */
|
2023-11-16 21:42:06 +00:00
|
|
|
public confirmRagfairTrading(
|
|
|
|
pmcData: IPmcData,
|
2024-01-16 11:47:40 +00:00
|
|
|
request: IProcessRagfairTradeRequestData,
|
2023-11-16 21:42:06 +00:00
|
|
|
sessionID: string,
|
|
|
|
): IItemEventRouterResponse
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-01-16 11:47:40 +00:00
|
|
|
const output = this.eventOutputHolder.getOutput(sessionID);
|
2023-03-03 15:23:46 +00:00
|
|
|
|
2024-01-16 11:47:40 +00:00
|
|
|
for (const offer of request.offers)
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
|
|
|
const fleaOffer = this.ragfairServer.getOffer(offer.id);
|
2023-11-16 21:42:06 +00:00
|
|
|
if (!fleaOffer)
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2023-11-16 21:42:06 +00:00
|
|
|
return this.httpResponse.appendErrorToOutput(
|
|
|
|
output,
|
|
|
|
`Offer with ID ${offer.id} not found`,
|
|
|
|
BackendErrorCodes.OFFERNOTFOUND,
|
|
|
|
);
|
2023-03-03 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (offer.count === 0)
|
|
|
|
{
|
2023-11-16 21:42:06 +00:00
|
|
|
const errorMessage = this.localisationService.getText(
|
|
|
|
"ragfair-unable_to_purchase_0_count_item",
|
|
|
|
this.itemHelper.getItem(fleaOffer.items[0]._tpl)[1]._name,
|
|
|
|
);
|
2023-10-10 11:03:20 +00:00
|
|
|
return this.httpResponse.appendErrorToOutput(output, errorMessage, BackendErrorCodes.OFFEROUTOFSTOCK);
|
|
|
|
}
|
|
|
|
|
2023-12-03 12:06:52 +00:00
|
|
|
const sellerIsTrader = fleaOffer.user.memberType === MemberCategory.TRADER;
|
2024-01-16 11:47:40 +00:00
|
|
|
if (sellerIsTrader)
|
2023-10-10 11:03:20 +00:00
|
|
|
{
|
2024-01-16 11:47:40 +00:00
|
|
|
this.buyTraderItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.buyPmcItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output);
|
2023-03-03 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
2024-01-16 11:47:40 +00:00
|
|
|
// Exit loop early if problem found
|
2024-01-16 19:00:21 +00:00
|
|
|
if (output.warnings.length > 0)
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-01-16 11:47:40 +00:00
|
|
|
return output;
|
2023-03-03 15:23:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2024-01-16 11:47:40 +00:00
|
|
|
/**
|
|
|
|
* Buy an item off the flea sold by a trader
|
|
|
|
* @param sessionId Session id
|
|
|
|
* @param pmcData Player profile
|
|
|
|
* @param fleaOffer Offer being purchased
|
|
|
|
* @param requestOffer request data from client
|
|
|
|
* @param output Output to send back to client
|
|
|
|
*/
|
2024-02-02 13:54:07 -05:00
|
|
|
protected buyTraderItemFromRagfair(
|
|
|
|
sessionId: string,
|
|
|
|
pmcData: IPmcData,
|
|
|
|
fleaOffer: IRagfairOffer,
|
|
|
|
requestOffer: IOfferRequest,
|
|
|
|
output: IItemEventRouterResponse,
|
|
|
|
): void
|
2024-01-16 11:47:40 +00:00
|
|
|
{
|
|
|
|
// Skip buying items when player doesn't have needed loyalty
|
|
|
|
if (this.playerLacksTraderLoyaltyLevelToBuyOffer(fleaOffer, pmcData))
|
|
|
|
{
|
|
|
|
const errorMessage = `Unable to buy item: ${
|
|
|
|
fleaOffer.items[0]._tpl
|
2024-02-02 13:54:07 -05:00
|
|
|
} from trader: ${fleaOffer.user.id} as loyalty level too low, skipping`;
|
2024-01-16 11:47:40 +00:00
|
|
|
this.logger.debug(errorMessage);
|
|
|
|
|
2024-01-16 19:00:21 +00:00
|
|
|
this.httpResponse.appendErrorToOutput(output, errorMessage, BackendErrorCodes.RAGFAIRUNAVAILABLE);
|
|
|
|
|
|
|
|
return;
|
2024-01-16 11:47:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const buyData: IProcessBuyTradeRequestData = {
|
|
|
|
Action: "TradingConfirm",
|
|
|
|
type: "buy_from_ragfair",
|
|
|
|
tid: fleaOffer.user.id,
|
|
|
|
item_id: fleaOffer.root,
|
|
|
|
count: requestOffer.count,
|
|
|
|
scheme_id: 0,
|
|
|
|
scheme_items: requestOffer.items,
|
|
|
|
};
|
|
|
|
|
|
|
|
this.tradeHelper.buyItem(pmcData, buyData, sessionId, this.traderConfig.purchasesAreFoundInRaid, output);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Buy an item off the flea sold by a PMC
|
|
|
|
* @param sessionId Session id
|
|
|
|
* @param pmcData Player profile
|
|
|
|
* @param fleaOffer Offer being purchased
|
|
|
|
* @param requestOffer Request data from client
|
|
|
|
* @param output Output to send back to client
|
|
|
|
*/
|
2024-02-02 13:54:07 -05:00
|
|
|
protected buyPmcItemFromRagfair(
|
|
|
|
sessionId: string,
|
|
|
|
pmcData: IPmcData,
|
|
|
|
fleaOffer: IRagfairOffer,
|
|
|
|
requestOffer: IOfferRequest,
|
|
|
|
output: IItemEventRouterResponse,
|
|
|
|
): void
|
2024-01-16 11:47:40 +00:00
|
|
|
{
|
|
|
|
const buyData: IProcessBuyTradeRequestData = {
|
|
|
|
Action: "TradingConfirm",
|
|
|
|
type: "buy_from_ragfair",
|
|
|
|
tid: "ragfair",
|
|
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
|
|
item_id: fleaOffer._id, // Store ragfair offerId in buyRequestData.item_id
|
|
|
|
count: requestOffer.count,
|
|
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
|
|
scheme_id: 0,
|
|
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
|
|
scheme_items: requestOffer.items,
|
|
|
|
};
|
|
|
|
|
|
|
|
// buyItem() must occur prior to removing the offer stack, otherwise item inside offer doesn't exist for confirmTrading() to use
|
2024-02-02 13:54:07 -05:00
|
|
|
this.tradeHelper.buyItem(
|
|
|
|
pmcData,
|
|
|
|
buyData,
|
|
|
|
sessionId,
|
|
|
|
this.ragfairConfig.dynamic.purchasesAreFoundInRaid,
|
|
|
|
output,
|
|
|
|
);
|
2024-01-16 11:47:40 +00:00
|
|
|
if (output.warnings.length > 0)
|
|
|
|
{
|
2024-01-16 19:00:21 +00:00
|
|
|
return;
|
2024-01-16 11:47:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove/lower stack count of item purchased from flea offer
|
|
|
|
this.ragfairServer.removeOfferStack(fleaOffer._id, requestOffer.count);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Does Player have necessary trader loyalty to purchase flea offer
|
|
|
|
* @param sellerIsTrader is seller trader
|
|
|
|
* @param fleaOffer FLea offer being bought
|
|
|
|
* @param pmcData Player profile
|
|
|
|
* @returns True if player can buy offer
|
|
|
|
*/
|
|
|
|
protected playerLacksTraderLoyaltyLevelToBuyOffer(fleaOffer: IRagfairOffer, pmcData: IPmcData): boolean
|
|
|
|
{
|
|
|
|
return fleaOffer.loyaltyLevel > pmcData.TradersInfo[fleaOffer.user.id].loyaltyLevel;
|
|
|
|
}
|
|
|
|
|
2023-10-10 11:03:20 +00:00
|
|
|
/** Handle SellAllFromSavage event */
|
2023-11-16 21:42:06 +00:00
|
|
|
public sellScavItemsToFence(
|
|
|
|
pmcData: IPmcData,
|
2023-12-03 12:06:52 +00:00
|
|
|
request: ISellScavItemsToFenceRequestData,
|
2023-11-16 21:42:06 +00:00
|
|
|
sessionId: string,
|
|
|
|
): IItemEventRouterResponse
|
2023-10-10 11:03:20 +00:00
|
|
|
{
|
2024-01-16 12:21:42 +00:00
|
|
|
const output = this.eventOutputHolder.getOutput(sessionId);
|
2023-10-10 11:03:20 +00:00
|
|
|
const scavProfile = this.profileHelper.getFullProfile(sessionId)?.characters?.scav;
|
|
|
|
if (!scavProfile)
|
|
|
|
{
|
2024-02-02 13:54:07 -05:00
|
|
|
return this.httpResponse.appendErrorToOutput(output, `Profile ${request.fromOwner.id} has no scav account`);
|
2023-10-10 11:03:20 +00:00
|
|
|
}
|
|
|
|
|
2024-02-04 19:27:35 +00:00
|
|
|
this.calculateCostOfScavInventoryAndMailMoneyToPlayer(sessionId, scavProfile, Traders.FENCE);
|
2024-01-16 12:21:42 +00:00
|
|
|
|
|
|
|
return output;
|
2023-10-10 11:03:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-02-04 19:27:35 +00:00
|
|
|
* Get cost of items in inventory and send rouble total to player as mail
|
2023-10-10 11:03:20 +00:00
|
|
|
* @param sessionId Session id
|
2023-11-16 21:42:06 +00:00
|
|
|
* @param profileWithItemsToSell Profile with items to be sold to trader
|
2023-10-10 11:03:20 +00:00
|
|
|
* @param profileThatGetsMoney Profile that gets the money after selling items
|
|
|
|
* @param trader Trader to sell items to
|
2024-01-16 12:21:42 +00:00
|
|
|
* @param output IItemEventRouterResponse
|
2023-10-10 11:03:20 +00:00
|
|
|
*/
|
2024-02-04 19:27:35 +00:00
|
|
|
protected calculateCostOfScavInventoryAndMailMoneyToPlayer(
|
2023-11-16 21:42:06 +00:00
|
|
|
sessionId: string,
|
|
|
|
profileWithItemsToSell: IPmcData,
|
|
|
|
trader: Traders,
|
2024-01-16 12:21:42 +00:00
|
|
|
): void
|
2023-10-10 11:03:20 +00:00
|
|
|
{
|
|
|
|
const handbookPrices = this.ragfairPriceService.getAllStaticPrices();
|
|
|
|
// TODO, apply trader sell bonuses?
|
|
|
|
const traderDetails = this.traderHelper.getTrader(trader, sessionId);
|
|
|
|
|
|
|
|
// Get all base items that scav has (primaryweapon/backpack/pockets etc)
|
|
|
|
// Add items that trader will buy (only sell items that have the container as parent) to request object
|
2024-02-04 19:27:35 +00:00
|
|
|
let roublesToSend = 0;
|
|
|
|
const containerAndEquipmentItems = profileWithItemsToSell.Inventory.items.filter((item) =>
|
|
|
|
item.parentId === profileWithItemsToSell.Inventory.equipment
|
2023-11-16 21:42:06 +00:00
|
|
|
);
|
2023-10-10 11:03:20 +00:00
|
|
|
for (const itemToSell of containerAndEquipmentItems)
|
|
|
|
{
|
|
|
|
// Increment sell price in request
|
2024-02-04 19:27:35 +00:00
|
|
|
roublesToSend += this.getPriceOfItemAndChildren(
|
2023-11-16 21:42:06 +00:00
|
|
|
itemToSell._id,
|
|
|
|
profileWithItemsToSell.Inventory.items,
|
|
|
|
handbookPrices,
|
|
|
|
traderDetails,
|
|
|
|
);
|
2023-10-10 11:03:20 +00:00
|
|
|
}
|
2024-02-06 10:33:59 +00:00
|
|
|
|
|
|
|
// Server-side calcualted isnt matching clientside calcualtion, temp fix to get it to be closer
|
|
|
|
roublesToSend /= 2;
|
|
|
|
|
2024-02-04 19:27:35 +00:00
|
|
|
this.logger.debug(`Selling scav items to fence for ${roublesToSend} roubles`);
|
|
|
|
|
|
|
|
// Create single currency item with all currency on it
|
|
|
|
const rootCurrencyReward = {
|
|
|
|
_id: this.hashUtil.generate(),
|
|
|
|
_tpl: this.roubleTpl,
|
|
|
|
upd: { StackObjectsCount: roublesToSend },
|
|
|
|
};
|
|
|
|
|
|
|
|
// Ensure money is properly split to follow its max stack size limit
|
|
|
|
const curencyReward = this.itemHelper.splitStackIntoSeparateItems(rootCurrencyReward);
|
|
|
|
|
|
|
|
// Send mail from trader
|
|
|
|
this.mailSendService.sendLocalisedNpcMessageToPlayer(
|
|
|
|
sessionId,
|
|
|
|
this.traderHelper.getTraderById(trader),
|
|
|
|
MessageType.MESSAGE_WITH_ITEMS,
|
|
|
|
this.randomUtil.getArrayValue(this.databaseServer.getTables().traders[trader].dialogue.soldItems),
|
|
|
|
curencyReward.flatMap((x) => x),
|
|
|
|
this.timeUtil.getHoursAsSeconds(72),
|
|
|
|
);
|
2023-10-10 11:03:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Looks up an items children and gets total handbook price for them
|
|
|
|
* @param parentItemId parent item that has children we want to sum price of
|
|
|
|
* @param items All items (parent + children)
|
|
|
|
* @param handbookPrices Prices of items from handbook
|
|
|
|
* @param traderDetails Trader being sold to to perform buy category check against
|
|
|
|
* @returns Rouble price
|
|
|
|
*/
|
2023-11-16 21:42:06 +00:00
|
|
|
protected getPriceOfItemAndChildren(
|
|
|
|
parentItemId: string,
|
|
|
|
items: Item[],
|
|
|
|
handbookPrices: Record<string, number>,
|
|
|
|
traderDetails: ITraderBase,
|
|
|
|
): number
|
2023-10-10 11:03:20 +00:00
|
|
|
{
|
|
|
|
const itemWithChildren = this.itemHelper.findAndReturnChildrenAsItems(items, parentItemId);
|
|
|
|
|
|
|
|
let totalPrice = 0;
|
|
|
|
for (const itemToSell of itemWithChildren)
|
|
|
|
{
|
|
|
|
const itemDetails = this.itemHelper.getItem(itemToSell._tpl);
|
2023-11-16 21:42:06 +00:00
|
|
|
if (
|
|
|
|
!(itemDetails[0]
|
|
|
|
&& this.itemHelper.isOfBaseclasses(itemDetails[1]._id, traderDetails.items_buy.category))
|
|
|
|
)
|
2023-10-10 11:03:20 +00:00
|
|
|
{
|
|
|
|
// Skip if tpl isnt item OR item doesn't fulfill match traders buy categories
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get price of item multiplied by how many are in stack
|
|
|
|
totalPrice += (handbookPrices[itemToSell._tpl] ?? 0) * (itemToSell.upd?.StackObjectsCount ?? 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return totalPrice;
|
|
|
|
}
|
2024-02-02 13:54:07 -05:00
|
|
|
}
|