Some cleaning in the Barter component.
- Add explicit variables for magic values. - `let`s to `const`. - Don't start the regen timer when not needed. Differential revision: https://code.wildfiregames.com/D4965 Comments by: @Stan This was SVN commit r27707.
This commit is contained in:
parent
291f17b3c5
commit
fdd30b3d85
@ -4,23 +4,37 @@ Barter.prototype.Schema =
|
||||
"<a:component type='system'/><empty/>";
|
||||
|
||||
/**
|
||||
* The "true price" is a base price of 100 units of resource (for the case of some resources being of more worth than others).
|
||||
* The "true price" is a base price of Barter.prototype.DEAL_AMOUNT units of resource (for the case of some resources being of more worth than others).
|
||||
* With current bartering system only relative values makes sense so if for example stone is two times more expensive than wood,
|
||||
* there will 2:1 exchange rate.
|
||||
*
|
||||
* Keep gui/session/trade/BarterButton.js in sync with this value.
|
||||
*/
|
||||
Barter.prototype.DEAL_AMOUNT = 100;
|
||||
|
||||
/**
|
||||
* Deals per mass barter.
|
||||
* Keep gui/session/trade/BarterButton.js in sync with this value.
|
||||
*/
|
||||
Barter.prototype.BATCH_SIZE = 5;
|
||||
|
||||
/**
|
||||
* Constant part of price percentage difference between true price and buy/sell price.
|
||||
* Buy price equal to true price plus constant difference.
|
||||
* Sell price equal to true price minus constant difference.
|
||||
*/
|
||||
Barter.prototype.CONSTANT_DIFFERENCE = 10;
|
||||
|
||||
/**
|
||||
* Additional difference of prices in percents, added after each deal to specified resource price.
|
||||
*/
|
||||
Barter.prototype.DIFFERENCE_PER_DEAL = 2;
|
||||
|
||||
/**
|
||||
* Price difference percentage which restored each restore timer tick
|
||||
*/
|
||||
Barter.prototype.DIFFERENCE_RESTORE = 0.5;
|
||||
|
||||
/**
|
||||
* Interval of timer which slowly restore prices after deals
|
||||
*/
|
||||
@ -29,20 +43,19 @@ Barter.prototype.RESTORE_TIMER_INTERVAL = 5000;
|
||||
Barter.prototype.Init = function()
|
||||
{
|
||||
this.priceDifferences = {};
|
||||
for (let resource of Resources.GetBarterableCodes())
|
||||
for (const resource of Resources.GetBarterableCodes())
|
||||
this.priceDifferences[resource] = 0;
|
||||
this.restoreTimer = undefined;
|
||||
};
|
||||
|
||||
Barter.prototype.GetPrices = function(cmpPlayer)
|
||||
{
|
||||
let prices = { "buy": {}, "sell": {} };
|
||||
let multiplier = cmpPlayer.GetBarterMultiplier();
|
||||
for (let resource of Resources.GetBarterableCodes())
|
||||
const prices = { "buy": {}, "sell": {} };
|
||||
const multiplier = cmpPlayer.GetBarterMultiplier();
|
||||
for (const resource in this.priceDifferences)
|
||||
{
|
||||
let truePrice = Resources.GetResource(resource).truePrice;
|
||||
prices.buy[resource] = truePrice * (100 + this.CONSTANT_DIFFERENCE + this.priceDifferences[resource]) * multiplier.buy[resource] / 100;
|
||||
prices.sell[resource] = truePrice * (100 - this.CONSTANT_DIFFERENCE + this.priceDifferences[resource]) * multiplier.sell[resource] / 100;
|
||||
const truePrice = Resources.GetResource(resource).truePrice;
|
||||
prices.buy[resource] = truePrice * (this.DEAL_AMOUNT + this.CONSTANT_DIFFERENCE + this.priceDifferences[resource]) * multiplier.buy[resource] / this.DEAL_AMOUNT;
|
||||
prices.sell[resource] = truePrice * (this.DEAL_AMOUNT - this.CONSTANT_DIFFERENCE + this.priceDifferences[resource]) * multiplier.sell[resource] / this.DEAL_AMOUNT;
|
||||
}
|
||||
return prices;
|
||||
};
|
||||
@ -55,85 +68,81 @@ Barter.prototype.ExchangeResources = function(playerID, resourceToSell, resource
|
||||
return;
|
||||
}
|
||||
|
||||
let availResources = Resources.GetBarterableCodes();
|
||||
if (availResources.indexOf(resourceToSell) == -1)
|
||||
if (!(resourceToSell in this.priceDifferences))
|
||||
{
|
||||
warn("ExchangeResources: incorrect resource to sell: " + uneval(resourceToSell));
|
||||
return;
|
||||
}
|
||||
|
||||
if (availResources.indexOf(resourceToBuy) == -1)
|
||||
if (!(resourceToBuy in this.priceDifferences))
|
||||
{
|
||||
warn("ExchangeResources: incorrect resource to buy: " + uneval(resourceToBuy));
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount != 100 && amount != 500)
|
||||
if (amount !== this.DEAL_AMOUNT && amount !== (this.BATCH_SIZE * this.DEAL_AMOUNT))
|
||||
return;
|
||||
|
||||
let cmpPlayer = QueryPlayerIDInterface(playerID);
|
||||
if (!cmpPlayer || !cmpPlayer.CanBarter())
|
||||
const cmpPlayer = QueryPlayerIDInterface(playerID);
|
||||
if (!cmpPlayer?.CanBarter())
|
||||
return;
|
||||
|
||||
let prices = this.GetPrices(cmpPlayer);
|
||||
let amountsToSubtract = {};
|
||||
amountsToSubtract[resourceToSell] = amount;
|
||||
if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|
||||
const amountsToSubtract = {
|
||||
[resourceToSell]: amount
|
||||
};
|
||||
if (!cmpPlayer.TrySubtractResources(amountsToSubtract))
|
||||
return;
|
||||
|
||||
const prices = this.GetPrices(cmpPlayer);
|
||||
const amountToAdd = Math.round(prices.sell[resourceToSell] / prices.buy[resourceToBuy] * amount);
|
||||
cmpPlayer.AddResource(resourceToBuy, amountToAdd);
|
||||
|
||||
Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface)?.PushNotification({
|
||||
"type": "barter",
|
||||
"players": [playerID],
|
||||
"amountGiven": amount,
|
||||
"amountGained": amountToAdd,
|
||||
"resourceGiven": resourceToSell,
|
||||
"resourceGained": resourceToBuy
|
||||
});
|
||||
|
||||
const cmpStatisticsTracker = QueryPlayerIDInterface(playerID, IID_StatisticsTracker);
|
||||
if (cmpStatisticsTracker)
|
||||
{
|
||||
let amountToAdd = Math.round(prices.sell[resourceToSell] / prices.buy[resourceToBuy] * amount);
|
||||
cmpPlayer.AddResource(resourceToBuy, amountToAdd);
|
||||
|
||||
// Display chat message to observers.
|
||||
let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
if (cmpGUIInterface)
|
||||
cmpGUIInterface.PushNotification({
|
||||
"type": "barter",
|
||||
"players": [playerID],
|
||||
"amountGiven": amount,
|
||||
"amountGained": amountToAdd,
|
||||
"resourceGiven": resourceToSell,
|
||||
"resourceGained": resourceToBuy
|
||||
});
|
||||
|
||||
let cmpStatisticsTracker = QueryPlayerIDInterface(playerID, IID_StatisticsTracker);
|
||||
if (cmpStatisticsTracker)
|
||||
{
|
||||
cmpStatisticsTracker.IncreaseResourcesSoldCounter(resourceToSell, amount);
|
||||
cmpStatisticsTracker.IncreaseResourcesBoughtCounter(resourceToBuy, amountToAdd);
|
||||
}
|
||||
|
||||
let difference = this.DIFFERENCE_PER_DEAL * amount / 100;
|
||||
// Increase price difference for both exchange resources.
|
||||
// Overall price difference (dynamic +/- constant) can't exceed +-99%.
|
||||
this.priceDifferences[resourceToSell] -= difference;
|
||||
this.priceDifferences[resourceToSell] = Math.min(99 - this.CONSTANT_DIFFERENCE, Math.max(this.CONSTANT_DIFFERENCE - 99, this.priceDifferences[resourceToSell]));
|
||||
this.priceDifferences[resourceToBuy] += difference;
|
||||
this.priceDifferences[resourceToBuy] = Math.min(99 - this.CONSTANT_DIFFERENCE, Math.max(this.CONSTANT_DIFFERENCE - 99, this.priceDifferences[resourceToBuy]));
|
||||
cmpStatisticsTracker.IncreaseResourcesSoldCounter(resourceToSell, amount);
|
||||
cmpStatisticsTracker.IncreaseResourcesBoughtCounter(resourceToBuy, amountToAdd);
|
||||
}
|
||||
|
||||
if (this.restoreTimer === undefined)
|
||||
this.restoreTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).SetInterval(this.entity, IID_Barter, "ProgressTimeout", this.RESTORE_TIMER_INTERVAL, this.RESTORE_TIMER_INTERVAL, {});
|
||||
const difference = this.DIFFERENCE_PER_DEAL * amount / this.DEAL_AMOUNT;
|
||||
// Overall price difference (dynamic +/- constant) can't exceed +-99%.
|
||||
const maxDifference = this.DEAL_AMOUNT * 0.99;
|
||||
|
||||
// Increase price difference for both exchanged resources.
|
||||
this.priceDifferences[resourceToSell] -= difference;
|
||||
this.priceDifferences[resourceToSell] = Math.min(maxDifference - this.CONSTANT_DIFFERENCE, Math.max(this.CONSTANT_DIFFERENCE - maxDifference, this.priceDifferences[resourceToSell]));
|
||||
this.priceDifferences[resourceToBuy] += difference;
|
||||
this.priceDifferences[resourceToBuy] = Math.min(maxDifference - this.CONSTANT_DIFFERENCE, Math.max(this.CONSTANT_DIFFERENCE - maxDifference, this.priceDifferences[resourceToBuy]));
|
||||
|
||||
if (!this.restoreTimer)
|
||||
this.restoreTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).SetInterval(this.entity, IID_Barter, "ProgressTimeout", this.RESTORE_TIMER_INTERVAL, this.RESTORE_TIMER_INTERVAL, null);
|
||||
};
|
||||
|
||||
Barter.prototype.ProgressTimeout = function(data)
|
||||
{
|
||||
let needRestore = false;
|
||||
for (let resource of Resources.GetBarterableCodes())
|
||||
for (const resource in this.priceDifferences)
|
||||
{
|
||||
// Calculate value to restore, it should be limited to [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval
|
||||
let differenceRestore = Math.min(this.DIFFERENCE_RESTORE, Math.max(-this.DIFFERENCE_RESTORE, this.priceDifferences[resource]));
|
||||
differenceRestore = -differenceRestore;
|
||||
this.priceDifferences[resource] += differenceRestore;
|
||||
// If price difference still exists then set flag to run timer again
|
||||
if (this.priceDifferences[resource] != 0)
|
||||
this.priceDifferences[resource] -= Math.min(this.DIFFERENCE_RESTORE, Math.max(-this.DIFFERENCE_RESTORE, this.priceDifferences[resource]));
|
||||
// If price difference still exists then set flag to keep the timer running.
|
||||
if (this.priceDifferences[resource] !== 0)
|
||||
needRestore = true;
|
||||
}
|
||||
|
||||
if (!needRestore)
|
||||
{
|
||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
cmpTimer.CancelTimer(this.restoreTimer);
|
||||
this.restoreTimer = undefined;
|
||||
Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).CancelTimer(this.restoreTimer);
|
||||
delete this.restoreTimer;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -144,10 +144,6 @@ AddMock(playerEnt, IID_Player, {
|
||||
});
|
||||
cmpBarter.ExchangeResources(playerID, "wood", "stone", 100);
|
||||
|
||||
// It seems useless to try to activate the timer if we don't barter any resources.
|
||||
TS_ASSERT_EQUALS(cmpBarter.restoreTimer, 7);
|
||||
TS_ASSERT(timerActivated);
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpBarter.priceDifferences, { "wood": 0, "stone": 0, "metal": 0 });
|
||||
|
||||
DeleteMock(playerEnt, IID_Player);
|
||||
|
Loading…
Reference in New Issue
Block a user