2011-11-24 16:43:32 +01:00
|
|
|
// True price of 100 units of resource (for case if some resource is more worth).
|
|
|
|
// 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.
|
|
|
|
const TRUE_PRICES = { "food": 100, "wood": 100, "stone": 100, "metal": 100 };
|
|
|
|
|
|
|
|
// Constant part of price difference between true price and buy/sell price.
|
|
|
|
// In percents.
|
|
|
|
// Buy price equal to true price plus constant difference.
|
|
|
|
// Sell price equal to true price minus constant difference.
|
|
|
|
const CONSTANT_DIFFERENCE = 10;
|
|
|
|
|
|
|
|
// Additional difference of prices, added after each deal to specified resource price.
|
|
|
|
// In percents.
|
2012-01-25 03:51:48 +01:00
|
|
|
const DIFFERENCE_PER_DEAL = 2;
|
2011-11-24 16:43:32 +01:00
|
|
|
|
|
|
|
// Price difference which restored each restore timer tick
|
|
|
|
// In percents.
|
2011-12-06 19:25:40 +01:00
|
|
|
const DIFFERENCE_RESTORE = 0.5;
|
2011-11-24 16:43:32 +01:00
|
|
|
|
|
|
|
// Interval of timer which slowly restore prices after deals
|
|
|
|
const RESTORE_TIMER_INTERVAL = 5000;
|
|
|
|
|
|
|
|
// Array of resource names
|
|
|
|
const RESOURCES = ["food", "wood", "stone", "metal"];
|
|
|
|
|
|
|
|
function Barter() {}
|
|
|
|
|
|
|
|
Barter.prototype.Schema =
|
|
|
|
"<a:component type='system'/><empty/>";
|
|
|
|
|
|
|
|
Barter.prototype.Init = function()
|
|
|
|
{
|
|
|
|
this.priceDifferences = {};
|
|
|
|
for each (var resource in RESOURCES)
|
|
|
|
this.priceDifferences[resource] = 0;
|
|
|
|
this.restoreTimer = undefined;
|
|
|
|
};
|
|
|
|
|
|
|
|
Barter.prototype.GetPrices = function()
|
|
|
|
{
|
|
|
|
var prices = { "buy": {}, "sell": {} };
|
|
|
|
for each (var resource in RESOURCES)
|
|
|
|
{
|
|
|
|
prices["buy"][resource] = TRUE_PRICES[resource] * (100 + CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100;
|
|
|
|
prices["sell"][resource] = TRUE_PRICES[resource] * (100 - CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100;
|
|
|
|
}
|
|
|
|
return prices;
|
|
|
|
};
|
|
|
|
|
|
|
|
Barter.prototype.PlayerHasMarket = function(playerEntity)
|
|
|
|
{
|
|
|
|
var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player);
|
|
|
|
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
|
|
|
var entities = cmpRangeManager.GetEntitiesByPlayer(cmpPlayer.GetPlayerID());
|
|
|
|
for each (var entity in entities)
|
|
|
|
{
|
|
|
|
var cmpFoundation = Engine.QueryInterface(entity, IID_Foundation);
|
|
|
|
var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
|
|
|
|
if (!cmpFoundation && cmpIdentity.HasClass("BarterMarket"))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Barter.prototype.ExchangeResources = function(playerEntity, resourceToSell, resourceToBuy, amount)
|
|
|
|
{
|
|
|
|
// Data verification
|
|
|
|
if (amount <= 0)
|
|
|
|
{
|
|
|
|
warn("ExchangeResources: incorrect amount: " + uneval(amount));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (RESOURCES.indexOf(resourceToSell) == -1)
|
|
|
|
{
|
|
|
|
warn("ExchangeResources: incorrect resource to sell: " + uneval(resourceToSell));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (RESOURCES.indexOf(resourceToBuy) == -1)
|
|
|
|
{
|
|
|
|
warn("ExchangeResources: incorrect resource to buy: " + uneval(resourceToBuy));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!this.PlayerHasMarket(playerEntity))
|
|
|
|
{
|
|
|
|
warn("ExchangeResources: player has no markets");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player);
|
|
|
|
var prices = this.GetPrices();
|
|
|
|
var amountsToSubtract = {};
|
|
|
|
amountsToSubtract[resourceToSell] = amount;
|
|
|
|
if (cmpPlayer.TrySubtractResources(amountsToSubtract))
|
|
|
|
{
|
|
|
|
var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount);
|
|
|
|
cmpPlayer.AddResource(resourceToBuy, amountToAdd);
|
|
|
|
var numberOfDeals = Math.round(amount / 100);
|
|
|
|
|
|
|
|
// Increase price difference for both exchange resources.
|
|
|
|
// Overal price difference (constant + dynamic) can't exceed +-99%
|
|
|
|
// so both buy/sell prices limited to [1%; 199%] interval.
|
|
|
|
this.priceDifferences[resourceToSell] -= DIFFERENCE_PER_DEAL * numberOfDeals;
|
|
|
|
this.priceDifferences[resourceToSell] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToSell]));
|
|
|
|
this.priceDifferences[resourceToBuy] += DIFFERENCE_PER_DEAL * numberOfDeals;
|
|
|
|
this.priceDifferences[resourceToBuy] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToBuy]));
|
|
|
|
}
|
|
|
|
|
2012-03-04 23:59:14 +01:00
|
|
|
if (this.restoreTimer === undefined)
|
2011-11-24 16:43:32 +01:00
|
|
|
{
|
|
|
|
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
|
|
|
this.restoreTimer = cmpTimer.SetInterval(this.entity, IID_Barter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, RESTORE_TIMER_INTERVAL, {});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Barter.prototype.ProgressTimeout = function(data)
|
|
|
|
{
|
|
|
|
var needRestore = false;
|
|
|
|
for each (var resource in RESOURCES)
|
|
|
|
{
|
|
|
|
// Calculate value to restore, it should be limited to [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval
|
|
|
|
var differenceRestore = Math.min(DIFFERENCE_RESTORE, Math.max(-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)
|
|
|
|
needRestore = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!needRestore)
|
|
|
|
{
|
|
|
|
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
|
|
|
cmpTimer.CancelTimer(this.restoreTimer);
|
|
|
|
this.restoreTimer = undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Engine.RegisterComponentType(IID_Barter, "Barter", Barter);
|
|
|
|
|