flea-sell-changes (!176)

Co-authored-by: Shibdib <shibdib@noreply.dev.sp-tarkov.com>
Co-authored-by: Dev <dev@dev.sp-tarkov.com>
Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/176
This commit is contained in:
chomp 2023-12-17 10:36:54 +00:00
parent 10b88b54b3
commit 1cf8b1ec9b
3 changed files with 39 additions and 38 deletions

View File

@ -1,12 +1,12 @@
{ {
"runIntervalSeconds": 45, "runIntervalSeconds": 45,
"sell": { "sell": {
"simulatedSellHours": 12,
"fees": true, "fees": true,
"chance": { "chance": {
"base": 50, "base": 50,
"overpriced": 1.7, "sellMultiplier": 1.24,
"underpriced": 2 "maxSellChancePercent": 100,
"minSellChancePercent": 0
}, },
"time": { "time": {
"base": 1.5, "base": 1.5,

View File

@ -5,6 +5,7 @@ import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { IRagfairConfig } from "@spt-aki/models/spt/config/IRagfairConfig"; import { IRagfairConfig } from "@spt-aki/models/spt/config/IRagfairConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil";
@ -17,6 +18,7 @@ export class RagfairSellHelper
@inject("WinstonLogger") protected logger: ILogger, @inject("WinstonLogger") protected logger: ILogger,
@inject("RandomUtil") protected randomUtil: RandomUtil, @inject("RandomUtil") protected randomUtil: RandomUtil,
@inject("TimeUtil") protected timeUtil: TimeUtil, @inject("TimeUtil") protected timeUtil: TimeUtil,
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
@inject("ConfigServer") protected configServer: ConfigServer, @inject("ConfigServer") protected configServer: ConfigServer,
) )
{ {
@ -36,32 +38,28 @@ export class RagfairSellHelper
qualityMultiplier: number, qualityMultiplier: number,
): number ): number
{ {
const baseSellChancePercent = this.ragfairConfig.sell.chance.base * qualityMultiplier; const sellConfig = this.ragfairConfig.sell.chance;
const listedPriceAboveAverage = playerListedPriceRub > averageOfferPriceRub; // Base sell chance modified by items quality
// Get sell chance multiplier const baseSellChancePercent = sellConfig.base * qualityMultiplier;
const multiplier = listedPriceAboveAverage
? this.ragfairConfig.sell.chance.overpriced // Player price is over average listing price
: this.getSellMultiplierWhenPlayerPriceIsBelowAverageListingPrice(
averageOfferPriceRub,
playerListedPriceRub,
);
return Math.round(baseSellChancePercent * (averageOfferPriceRub / playerListedPriceRub * multiplier)); // Modfier gets applied twice to either penalize or incentivize over/under pricing (Probably a cleaner way to do this)
const sellModifier = (averageOfferPriceRub / playerListedPriceRub) * sellConfig.sellMultiplier;
let sellChance = Math.round((baseSellChancePercent * sellModifier) * sellModifier);
// Adjust sell chance if below config value
if (sellChance < sellConfig.minSellChancePercent)
{
sellChance = sellConfig.minSellChancePercent;
} }
/** // Adjust sell chance if above config value
* Get percent chance to sell an item when price is below items average listing price if (sellChance > sellConfig.maxSellChancePercent)
* @param playerListedPriceRub Price player listed item for in roubles
* @param averageOfferPriceRub Price of average offer in roubles
* @returns percent value
*/
protected getSellMultiplierWhenPlayerPriceIsBelowAverageListingPrice(
averageOfferPriceRub: number,
playerListedPriceRub: number,
): number
{ {
return (playerListedPriceRub < averageOfferPriceRub) ? this.ragfairConfig.sell.chance.underpriced : 1; sellChance = sellConfig.maxSellChancePercent;
}
return sellChance;
} }
/** /**
@ -75,10 +73,7 @@ export class RagfairSellHelper
const startTime = this.timeUtil.getTimestamp(); const startTime = this.timeUtil.getTimestamp();
// Get a time in future to stop simulating sell chances at // Get a time in future to stop simulating sell chances at
const endTime = startTime + this.timeUtil.getHoursAsSeconds(this.ragfairConfig.sell.simulatedSellHours); const endTime = startTime + this.timeUtil.getHoursAsSeconds(this.databaseServer.getTables().globals.config.RagFair.offerDurationTimeInHour);
// TODO - Write comment - what is going on here
const chance = 100 - Math.min(Math.max(sellChancePercent, 0), 100);
let sellTime = startTime; let sellTime = startTime;
let remainingCount = itemSellCount; let remainingCount = itemSellCount;
@ -107,10 +102,13 @@ export class RagfairSellHelper
if (this.randomUtil.getChance100(sellChancePercent)) if (this.randomUtil.getChance100(sellChancePercent))
{ {
// Passed roll check, item will be sold // Passed roll check, item will be sold
sellTime += Math.max( // Weight time to sell towards selling faster based on how cheap the item sold
Math.round(chance / 100 * this.ragfairConfig.sell.time.max * 60), const weighting = (100 - sellChancePercent) / 100;
this.ragfairConfig.sell.time.min * 60, let maximumTime = weighting * (this.ragfairConfig.sell.time.max * 60);
); const minimumTime = this.ragfairConfig.sell.time.min * 60;
if (maximumTime < minimumTime) maximumTime = minimumTime + 5;
// Sell time will be random between min/max
sellTime += Math.floor(Math.random() * (maximumTime - minimumTime) + minimumTime);
result.push({ sellTime: sellTime, amount: boughtAmount }); result.push({ sellTime: sellTime, amount: boughtAmount });

View File

@ -23,17 +23,20 @@ export interface Sell
time: Time; time: Time;
/** Player offer reputation gain/loss settings */ /** Player offer reputation gain/loss settings */
reputation: Reputation; reputation: Reputation;
/** How many hours are simulated to figure out if player offer was sold */
simulatedSellHours: number;
/**Seconds from clicking remove to remove offer from market */ /**Seconds from clicking remove to remove offer from market */
expireSeconds: number; expireSeconds: number;
} }
export interface Chance export interface Chance
{ {
/** Base chance percent to sell an item */
base: number; base: number;
overpriced: number; /** Value to multiply the sell chance by */
underpriced: number; sellMultiplier: number;
/** Max possible sell chance % for a player listed offer */
maxSellChancePercent: number;
/** Min possible sell chance % for a player listed offer */
minSellChancePercent: number;
} }
export interface Time extends MinMax export interface Time extends MinMax