Index: ps/trunk/binaries/data/mods/public/simulation/components/Trader.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/Trader.js (revision 12116)
+++ ps/trunk/binaries/data/mods/public/simulation/components/Trader.js (revision 12117)
@@ -1,222 +1,222 @@
// This constant used to adjust gain value depending on distance
-const DISTANCE_FACTOR = 1 / 50;
+const DISTANCE_FACTOR = 1 / 110;
// Additional gain for trading performed between markets of different players, in percents
const INTERNATIONAL_TRADING_ADDITION = 50;
// Additional gain for ships for each garrisoned trader, in percents
const GARRISONED_TRADER_ADDITION = 20;
// Array of resource names
const RESOURCES = ["food", "wood", "stone", "metal"];
function Trader() {}
Trader.prototype.Schema =
"Lets the unit generate resouces while moving between markets (or docks in case of water trading)." +
"" +
"2.0" +
"1.0" +
"" +
"" +
"" +
"" +
"" +
"" +
"";
Trader.prototype.Init = function()
{
this.firstMarket = INVALID_ENTITY;
this.secondMarket = INVALID_ENTITY;
// Gain from one pass between markets
this.gain = null;
// Selected resource for trading
this.preferredGoods = "metal";
// Currently carried goods
this.goods = { "type": null, "amount": 0 };
}
Trader.prototype.CalculateGain = function(firstMarket, secondMarket)
{
var cmpFirstMarketPosition = Engine.QueryInterface(firstMarket, IID_Position);
var cmpSecondMarketPosition = Engine.QueryInterface(secondMarket, IID_Position);
if (!cmpFirstMarketPosition || !cmpFirstMarketPosition.IsInWorld() || !cmpSecondMarketPosition || !cmpSecondMarketPosition.IsInWorld())
return null;
var firstMarketPosition = cmpFirstMarketPosition.GetPosition2D();
var secondMarketPosition = cmpSecondMarketPosition.GetPosition2D();
// Calculate ordinary Euclidean distance between markets.
// We don't use pathfinder, because ordinary distance looks more fair.
var distance = Math.sqrt(Math.pow(firstMarketPosition.x - secondMarketPosition.x, 2) + Math.pow(firstMarketPosition.y - secondMarketPosition.y, 2));
// We calculate gain as square of distance to encourage trading between remote markets
var gain = Math.pow(distance * DISTANCE_FACTOR, 2);
// If markets belongs to different players, multiple gain to INTERNATIONAL_TRADING_MULTIPLIER
var cmpFirstMarketOwnership = Engine.QueryInterface(firstMarket, IID_Ownership);
var cmpSecondMarketOwnership = Engine.QueryInterface(secondMarket, IID_Ownership);
if (cmpFirstMarketOwnership.GetOwner() != cmpSecondMarketOwnership.GetOwner())
gain *= 1 + INTERNATIONAL_TRADING_ADDITION / 100;
// For ship increase gain for each garrisoned trader
var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
if (cmpIdentity.HasClass("Ship"))
{
var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
if (cmpGarrisonHolder)
{
var garrisonedTradersCount = 0;
for each (var entity in cmpGarrisonHolder.GetEntities())
{
var cmpGarrisonedUnitTrader = Engine.QueryInterface(entity, IID_Trader);
if (cmpGarrisonedUnitTrader)
garrisonedTradersCount++;
}
gain *= 1 + GARRISONED_TRADER_ADDITION * garrisonedTradersCount / 100;
}
}
if (this.template.GainMultiplier)
gain *= this.template.GainMultiplier;
gain = Math.round(gain);
return gain;
}
Trader.prototype.GetGain = function()
{
return this.gain;
}
// Set target as target market.
// Return true if at least one of markets was changed.
Trader.prototype.SetTargetMarket = function(target)
{
// Check that target is a market
var cmpTargetIdentity = Engine.QueryInterface(target, IID_Identity);
if (!cmpTargetIdentity)
return false;
if (!cmpTargetIdentity.HasClass("Market") && !cmpTargetIdentity.HasClass("NavalMarket"))
return false;
var marketsChanged = false;
if (this.secondMarket)
{
// If we already have both markets - drop them
// and use the target as first market
this.firstMarket = target;
this.secondMarket = INVALID_ENTITY;
marketsChanged = true;
}
else if (this.firstMarket)
{
// If we have only one market and target is different from it,
// set the target as second one
if (target != this.firstMarket)
{
this.secondMarket = target;
this.gain = this.CalculateGain(this.firstMarket, this.secondMarket);
marketsChanged = true;
}
}
else
{
// Else we don't have target markets at all,
// set the target as first market
this.firstMarket = target;
marketsChanged = true;
}
if (marketsChanged)
{
// Drop carried goods
this.goods.amount = 0;
}
return marketsChanged;
}
Trader.prototype.GetFirstMarket = function()
{
return this.firstMarket;
}
Trader.prototype.GetSecondMarket = function()
{
return this.secondMarket;
}
Trader.prototype.HasBothMarkets = function()
{
return this.firstMarket && this.secondMarket;
}
Trader.prototype.GetPreferredGoods = function()
{
return this.preferredGoods;
}
Trader.prototype.SetPreferredGoods = function(preferredGoods)
{
// Check that argument is a correct resource name
if (RESOURCES.indexOf(preferredGoods) == -1)
return;
this.preferredGoods = preferredGoods;
}
Trader.prototype.CanTrade = function(target)
{
var cmpTraderIdentity = Engine.QueryInterface(this.entity, IID_Identity);
var cmpTargetIdentity = Engine.QueryInterface(target, IID_Identity);
// Check that the target exists
if (!cmpTargetIdentity)
return false;
// Check that the target is not a foundation
var cmpTargetFoundation = Engine.QueryInterface(target, IID_Foundation);
if (cmpTargetFoundation)
return false;
var landTradingPossible = cmpTraderIdentity.HasClass("Organic") && cmpTargetIdentity.HasClass("Market");
var seaTradingPossible = cmpTraderIdentity.HasClass("Ship") && cmpTargetIdentity.HasClass("NavalMarket");
if (!landTradingPossible && !seaTradingPossible)
return false;
var cmpTraderPlayer = QueryOwnerInterface(this.entity, IID_Player);
var traderPlayerId = cmpTraderPlayer.GetPlayerID();
var cmpTargetPlayer = QueryOwnerInterface(target, IID_Player);
var targetPlayerId = cmpTargetPlayer.GetPlayerID();
var ownershipSuitableForTrading = (traderPlayerId == targetPlayerId) || cmpTraderPlayer.IsAlly(targetPlayerId);
if (!ownershipSuitableForTrading)
return false;
return true;
}
Trader.prototype.PerformTrade = function()
{
if (this.goods.amount > 0)
{
var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
cmpPlayer.AddResource(this.goods.type, this.goods.amount);
}
this.goods.type = this.preferredGoods;
this.goods.amount = this.gain;
}
Trader.prototype.GetGoods = function()
{
return this.goods;
}
Trader.prototype.StopTrading = function()
{
// Drop carried goods
this.goods.amount = 0;
// Reset markets
this.firstMarket = INVALID_ENTITY;
this.secondMarket = INVALID_ENTITY;
}
// Get range in which deals with market are available,
// i.e. trader should be in no more than MaxDistance from market
// to be able to trade with it.
Trader.prototype.GetRange = function()
{
return { "min": 0, "max": +this.template.MaxDistance };
}
Engine.RegisterComponentType(IID_Trader, "Trader", Trader);
Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_trader.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_trader.xml (revision 12116)
+++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_trader.xml (revision 12117)
@@ -1,53 +1,53 @@
5.08.05.0
- 50
- 50
+ 100
+ 80100TraderTraderTrade was a very important part of ancient civilisation - effective trading and control of trade routes equaled wealth. Trade took place by many forms from foot to caravans to merchant ships. One of the most notorious examples of the power of trade was the Silk Road.Trade resources between your own markets and those of your allies.voice/hellenes/civ/civ_male_ack.xmlvoice/hellenes/civ/civ_male_ack.xmlvoice/hellenes/civ/civ_male_attack.xmlvoice/hellenes/civ/civ_male_ack.xmlvoice/hellenes/civ/civ_male_ack.xmlactor/human/movement/walk.xmlactor/human/movement/run.xmlattack/weapon/sword.xmlactor/human/death/death.xmlresource/construction/con_wood.xmlresource/foraging/forage_leaves.xmlresource/farming/farm.xmlresource/lumbering/lumbering.xmlresource/mining/pickaxe.xmlresource/mining/mining.xml2.01.08.060