Refactor functions (!90)
(cherry picked from commit f6fc6e41c0
)
Co-authored-by: Dev <dev@noreply.dev.sp-tarkov.com>
Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/90
This commit is contained in:
parent
2bc582d65c
commit
7974e4531b
@ -26,7 +26,7 @@ export class DialogueController
|
|||||||
const profiles = this.saveServer.getProfiles();
|
const profiles = this.saveServer.getProfiles();
|
||||||
for (const sessionID in profiles)
|
for (const sessionID in profiles)
|
||||||
{
|
{
|
||||||
this.removeExpiredItems(sessionID);
|
this.removeExpiredItemsFromMessages(sessionID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,20 +220,40 @@ export class DialogueController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete expired items. triggers when updating traders.
|
* Delete expired items from all messages in player profile. triggers when updating traders.
|
||||||
* @param sessionID Session id
|
* @param sessionId Session id
|
||||||
*/
|
*/
|
||||||
protected removeExpiredItems(sessionID: string): void
|
protected removeExpiredItemsFromMessages(sessionId: string): void
|
||||||
{
|
{
|
||||||
for (const dialogueId in this.saveServer.getProfile(sessionID).dialogues)
|
for (const dialogueId in this.saveServer.getProfile(sessionId).dialogues)
|
||||||
{
|
{
|
||||||
for (const message of this.saveServer.getProfile(sessionID).dialogues[dialogueId].messages)
|
this.removeExpiredItemsFromMessage(sessionId, dialogueId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes expired items from a message in player profile
|
||||||
|
* @param sessionId Session id
|
||||||
|
* @param dialogueId Dialog id
|
||||||
|
*/
|
||||||
|
protected removeExpiredItemsFromMessage(sessionId: string, dialogueId: string): void
|
||||||
|
{
|
||||||
|
for (const message of this.saveServer.getProfile(sessionId).dialogues[dialogueId].messages)
|
||||||
|
{
|
||||||
|
if (this.messageHasExpired(message))
|
||||||
{
|
{
|
||||||
if ((this.timeUtil.getTimestamp()) > (message.dt + message.maxStorageTime))
|
message.items = {};
|
||||||
{
|
|
||||||
message.items = {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has a dialog message expired
|
||||||
|
* @param message Message to check expiry of
|
||||||
|
* @returns true or false
|
||||||
|
*/
|
||||||
|
protected messageHasExpired(message: Message): boolean
|
||||||
|
{
|
||||||
|
return (this.timeUtil.getTimestamp()) > (message.dt + message.maxStorageTime);
|
||||||
|
}
|
||||||
}
|
}
|
@ -327,67 +327,38 @@ export class RagfairController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public addPlayerOffer(pmcData: IPmcData, info: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse
|
/**
|
||||||
|
* List item(s) on flea for sale
|
||||||
|
* @param pmcData Player profile
|
||||||
|
* @param offerRequest Flea list creatio offer
|
||||||
|
* @param sessionID Session id
|
||||||
|
* @returns IItemEventRouterResponse
|
||||||
|
*/
|
||||||
|
public addPlayerOffer(pmcData: IPmcData, offerRequest: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse
|
||||||
{
|
{
|
||||||
let output = this.eventOutputHolder.getOutput(sessionID);
|
let output = this.eventOutputHolder.getOutput(sessionID);
|
||||||
let requirementsPriceInRub = 0;
|
|
||||||
const invItems: Item[] = [];
|
|
||||||
|
|
||||||
if (!info?.items || info.items.length === 0)
|
const validationMessage = "";
|
||||||
|
if (!this.isValidPlayerOfferRequest(offerRequest, validationMessage))
|
||||||
{
|
{
|
||||||
this.logger.error(this.localisationService.getText("ragfair-invalid_player_offer_request"));
|
return this.httpResponse.appendErrorToOutput(output, validationMessage);
|
||||||
|
|
||||||
return this.httpResponse.appendErrorToOutput(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info.requirements)
|
// Get an array of items from player inventory to list on flea
|
||||||
|
const getItemsFromInventoryErrorMessage = "";
|
||||||
|
const itemsInInventoryToList = this.getItemsToListOnFleaFromInventory(pmcData, offerRequest.items, getItemsFromInventoryErrorMessage);
|
||||||
|
if (!itemsInInventoryToList)
|
||||||
{
|
{
|
||||||
return this.httpResponse.appendErrorToOutput(output, this.localisationService.getText("ragfair-unable_to_place_offer_with_no_requirements"));
|
this.httpResponse.appendErrorToOutput(output, getItemsFromInventoryErrorMessage);
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of info.requirements)
|
|
||||||
{
|
|
||||||
const requestedItemTpl = item._tpl;
|
|
||||||
|
|
||||||
if (this.paymentHelper.isMoneyTpl(requestedItemTpl))
|
|
||||||
{
|
|
||||||
requirementsPriceInRub += this.handbookHelper.inRUB(item.count, requestedItemTpl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
requirementsPriceInRub += this.ragfairPriceService.getDynamicPriceForItem(requestedItemTpl) * item.count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count how many items are being sold and multiply the requested amount accordingly
|
|
||||||
for (const itemId of info.items)
|
|
||||||
{
|
|
||||||
let item = pmcData.Inventory.items.find(i => i._id === itemId);
|
|
||||||
|
|
||||||
if (item === undefined)
|
|
||||||
{
|
|
||||||
this.logger.error(this.localisationService.getText("ragfair-unable_to_find_item_in_inventory", {id: itemId}));
|
|
||||||
|
|
||||||
return this.httpResponse.appendErrorToOutput(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
item = this.itemHelper.fixItemStackCount(item);
|
|
||||||
invItems.push(...this.itemHelper.findAndReturnChildrenAsItems(pmcData.Inventory.items, itemId));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!invItems?.length)
|
|
||||||
{
|
|
||||||
this.logger.error(this.localisationService.getText("ragfair-unable_to_find_requested_items_in_inventory"));
|
|
||||||
|
|
||||||
return this.httpResponse.appendErrorToOutput(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preparations are done, create the offer
|
// Preparations are done, create the offer
|
||||||
const offer = this.createPlayerOffer(this.saveServer.getProfile(sessionID), info.requirements, this.ragfairHelper.mergeStackable(invItems), info.sellInOnePiece, requirementsPriceInRub);
|
const requirementsPriceInRub = this.calculateRequirementsPriceInRub(offerRequest.requirements);
|
||||||
|
const offer = this.createPlayerOffer(this.saveServer.getProfile(sessionID), offerRequest.requirements, this.ragfairHelper.mergeStackable(itemsInInventoryToList), offerRequest.sellInOnePiece, requirementsPriceInRub);
|
||||||
const rootItem = offer.items[0];
|
const rootItem = offer.items[0];
|
||||||
const qualityMultiplier = this.itemHelper.getItemQualityModifier(rootItem);
|
const qualityMultiplier = this.itemHelper.getItemQualityModifier(rootItem);
|
||||||
const averageOfferPrice = this.ragfairPriceService.getFleaPriceForItem(rootItem._tpl) * rootItem.upd.StackObjectsCount * qualityMultiplier;
|
const averageOfferPrice = this.ragfairPriceService.getFleaPriceForItem(rootItem._tpl) * rootItem.upd.StackObjectsCount * qualityMultiplier;
|
||||||
const itemStackCount = (!info.sellInOnePiece) ? offer.items[0].upd.StackObjectsCount : 1;
|
const itemStackCount = (!offerRequest.sellInOnePiece) ? offer.items[0].upd.StackObjectsCount : 1;
|
||||||
const singleOfferValue = averageOfferPrice / itemStackCount;
|
const singleOfferValue = averageOfferPrice / itemStackCount;
|
||||||
let sellChance = this.ragfairConfig.sell.chance.base * qualityMultiplier;
|
let sellChance = this.ragfairConfig.sell.chance.base * qualityMultiplier;
|
||||||
|
|
||||||
@ -397,7 +368,7 @@ export class RagfairController
|
|||||||
// Subtract flea market fee from stash
|
// Subtract flea market fee from stash
|
||||||
if (this.ragfairConfig.sell.fees)
|
if (this.ragfairConfig.sell.fees)
|
||||||
{
|
{
|
||||||
const tax = this.ragfairTaxHelper.calculateTax(rootItem, pmcData, requirementsPriceInRub, itemStackCount, info.sellInOnePiece);
|
const tax = this.ragfairTaxHelper.calculateTax(rootItem, pmcData, requirementsPriceInRub, itemStackCount, offerRequest.sellInOnePiece);
|
||||||
|
|
||||||
const request: IProcessBuyTradeRequestData = {
|
const request: IProcessBuyTradeRequestData = {
|
||||||
tid: "ragfair",
|
tid: "ragfair",
|
||||||
@ -428,7 +399,7 @@ export class RagfairController
|
|||||||
output.profileChanges[sessionID].ragFairOffers.push(offer);
|
output.profileChanges[sessionID].ragFairOffers.push(offer);
|
||||||
|
|
||||||
// Remove items from inventory after creating offer
|
// Remove items from inventory after creating offer
|
||||||
for (const itemToRemove of info.items)
|
for (const itemToRemove of offerRequest.items)
|
||||||
{
|
{
|
||||||
this.inventoryHelper.removeItem(pmcData, itemToRemove, sessionID, output);
|
this.inventoryHelper.removeItem(pmcData, itemToRemove, sessionID, output);
|
||||||
}
|
}
|
||||||
@ -436,6 +407,95 @@ export class RagfairController
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the item to be listed on the flea valid
|
||||||
|
* @param offerRequest Client offer request
|
||||||
|
* @param errorMessage message to show to player when offer is invalid
|
||||||
|
* @returns Is offer valid
|
||||||
|
*/
|
||||||
|
protected isValidPlayerOfferRequest(offerRequest: IAddOfferRequestData, errorMessage: string): boolean
|
||||||
|
{
|
||||||
|
if (!offerRequest?.items || offerRequest.items.length === 0)
|
||||||
|
{
|
||||||
|
errorMessage = this.localisationService.getText("ragfair-invalid_player_offer_request");
|
||||||
|
this.logger.error(errorMessage);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!offerRequest.requirements)
|
||||||
|
{
|
||||||
|
errorMessage = this.localisationService.getText("ragfair-unable_to_place_offer_with_no_requirements");
|
||||||
|
this.logger.error(errorMessage);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the handbook price in roubles for the items being listed
|
||||||
|
* @param requirements
|
||||||
|
* @returns Rouble price
|
||||||
|
*/
|
||||||
|
protected calculateRequirementsPriceInRub(requirements: Requirement[]): number
|
||||||
|
{
|
||||||
|
let requirementsPriceInRub = 0;
|
||||||
|
for (const item of requirements)
|
||||||
|
{
|
||||||
|
const requestedItemTpl = item._tpl;
|
||||||
|
|
||||||
|
if (this.paymentHelper.isMoneyTpl(requestedItemTpl))
|
||||||
|
{
|
||||||
|
requirementsPriceInRub += this.handbookHelper.inRUB(item.count, requestedItemTpl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requirementsPriceInRub += this.ragfairPriceService.getDynamicPriceForItem(requestedItemTpl) * item.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requirementsPriceInRub;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using item ids from flea offer request, find corrispnding items from player inventory and return as array
|
||||||
|
* @param pmcData Player profile
|
||||||
|
* @param itemIdsFromFleaOfferRequest Ids from request
|
||||||
|
* @param errorMessage if item is not found, add error message to this parameter
|
||||||
|
* @returns Array of items from player inventory
|
||||||
|
*/
|
||||||
|
protected getItemsToListOnFleaFromInventory(pmcData: IPmcData, itemIdsFromFleaOfferRequest: string[], errorMessage: string): Item[]
|
||||||
|
{
|
||||||
|
const itemsToReturn = [];
|
||||||
|
// Count how many items are being sold and multiply the requested amount accordingly
|
||||||
|
for (const itemId of itemIdsFromFleaOfferRequest)
|
||||||
|
{
|
||||||
|
let item = pmcData.Inventory.items.find(i => i._id === itemId);
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
errorMessage = this.localisationService.getText("ragfair-unable_to_find_item_in_inventory", {id: itemId});
|
||||||
|
this.logger.error(errorMessage);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = this.itemHelper.fixItemStackCount(item);
|
||||||
|
itemsToReturn.push(...this.itemHelper.findAndReturnChildrenAsItems(pmcData.Inventory.items, itemId));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!itemsToReturn?.length)
|
||||||
|
{
|
||||||
|
errorMessage = this.localisationService.getText("ragfair-unable_to_find_requested_items_in_inventory");
|
||||||
|
this.logger.error(errorMessage);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemsToReturn;
|
||||||
|
}
|
||||||
|
|
||||||
public createPlayerOffer(profile: IAkiProfile, requirements: Requirement[], items: Item[], sellInOnePiece: boolean, amountToSend: number): IRagfairOffer
|
public createPlayerOffer(profile: IAkiProfile, requirements: Requirement[], items: Item[], sellInOnePiece: boolean, amountToSend: number): IRagfairOffer
|
||||||
{
|
{
|
||||||
const loyalLevel = 1;
|
const loyalLevel = 1;
|
||||||
|
@ -13,6 +13,11 @@ import { LocalisationService } from "../services/LocalisationService";
|
|||||||
import { HashUtil } from "../utils/HashUtil";
|
import { HashUtil } from "../utils/HashUtil";
|
||||||
import { RandomUtil } from "../utils/RandomUtil";
|
import { RandomUtil } from "../utils/RandomUtil";
|
||||||
|
|
||||||
|
type ItemLimit = {
|
||||||
|
current: number,
|
||||||
|
max: number
|
||||||
|
};
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class LootGenerator
|
export class LootGenerator
|
||||||
{
|
{
|
||||||
@ -71,19 +76,18 @@ export class LootGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct item limit record to hold max and current item count
|
* Construct item limit record to hold max and current item count for each item type
|
||||||
* @param limits limits as defined in config
|
* @param limits limits as defined in config
|
||||||
* @returns record, key: item tplId, value: current/max item count allowed
|
* @returns record, key: item tplId, value: current/max item count allowed
|
||||||
*/
|
*/
|
||||||
protected initItemLimitCounter(limits: Record<string, number>): Record<string, {current: number, max: number}>
|
protected initItemLimitCounter(limits: Record<string, number>): Record<string, ItemLimit>
|
||||||
{
|
{
|
||||||
const itemTypeCounts: Record<string, {current: number, max: number}> = {};
|
const itemTypeCounts: Record<string, ItemLimit> = {};
|
||||||
|
for (const itemTypeId in limits)
|
||||||
for (const x in limits)
|
|
||||||
{
|
{
|
||||||
itemTypeCounts[x] = {
|
itemTypeCounts[itemTypeId] = {
|
||||||
current: 0,
|
current: 0,
|
||||||
max: limits[x]
|
max: limits[itemTypeId]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ export class RagfairServerHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generated offer
|
// generated offer
|
||||||
// recurse if name is longer than max characters allowed (15 characters)
|
// recurivse if name is longer than max characters allowed (15 characters)
|
||||||
const type = (this.randomUtil.getInt(0, 1) === 0) ? "usec" : "bear";
|
const type = (this.randomUtil.getInt(0, 1) === 0) ? "usec" : "bear";
|
||||||
const name = this.randomUtil.getStringArrayValue(this.databaseServer.getTables().bots.types[type].firstName);
|
const name = this.randomUtil.getStringArrayValue(this.databaseServer.getTables().bots.types[type].firstName);
|
||||||
return (name.length > 15) ? this.getNickname(userID) : name;
|
return (name.length > 15) ? this.getNickname(userID) : name;
|
||||||
|
@ -126,17 +126,26 @@ export class TraderHelper
|
|||||||
const traderInfo = pmcData.TradersInfo[traderId];
|
const traderInfo = pmcData.TradersInfo[traderId];
|
||||||
|
|
||||||
// Add standing to trader
|
// Add standing to trader
|
||||||
traderInfo.standing += standingToAdd;
|
traderInfo.standing = this.addStandingValuesTogether(traderInfo.standing, standingToAdd);
|
||||||
|
|
||||||
// dont allow standing to fall below 0
|
|
||||||
if (traderInfo.standing < 0)
|
|
||||||
{
|
|
||||||
traderInfo.standing = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lvlUp(traderId, sessionId);
|
this.lvlUp(traderId, sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add standing to current standing and clamp value if it goes too low
|
||||||
|
* @param currentStanding current trader standing
|
||||||
|
* @param standingToAdd stansding to add to trader standing
|
||||||
|
* @returns current standing + added standing (clamped if needed)
|
||||||
|
*/
|
||||||
|
protected addStandingValuesTogether(currentStanding: number, standingToAdd: number): number
|
||||||
|
{
|
||||||
|
const newStanding = currentStanding + standingToAdd;
|
||||||
|
|
||||||
|
return newStanding < 0
|
||||||
|
? 0
|
||||||
|
: newStanding;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate traders level based on exp amount and increments level if over threshold
|
* Calculate traders level based on exp amount and increments level if over threshold
|
||||||
* @param traderID trader to process
|
* @param traderID trader to process
|
||||||
|
Loading…
Reference in New Issue
Block a user