forked from mirrors/0ad
Move the const from simulation/helpers/TraderGain.js into the templates (InternationalBonus and GainMultiplier)
Add a tech to improve the internalBonus and give an improved bonus to cart Patch from fatherbushido, fixes #3917 This was SVN commit r18108.
This commit is contained in:
@@ -10,6 +10,9 @@ Market.prototype.Schema =
|
||||
"</choice>" +
|
||||
"</oneOrMore>" +
|
||||
"</list>" +
|
||||
"</element>" +
|
||||
"<element name='InternationalBonus' a:help='Additional part of the gain donated when two different players trade'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>";
|
||||
|
||||
Market.prototype.Init = function()
|
||||
@@ -28,6 +31,11 @@ Market.prototype.RemoveTrader = function(ent)
|
||||
this.traders.delete(ent);
|
||||
};
|
||||
|
||||
Market.prototype.GetInternationalBonus = function()
|
||||
{
|
||||
return ApplyValueModificationsToEntity("Market/InternationalBonus", +this.template.InternationalBonus, this.entity);
|
||||
}
|
||||
|
||||
Market.prototype.HasType = function(type)
|
||||
{
|
||||
return this.tradeType.has(type);
|
||||
|
||||
@@ -12,10 +12,9 @@ function Trader() {}
|
||||
Trader.prototype.Schema =
|
||||
"<a:help>Lets the unit generate resouces while moving between markets (or docks in case of water trading).</a:help>" +
|
||||
"<a:example>" +
|
||||
"<MaxDistance>2.0</MaxDistance>" +
|
||||
"<GainMultiplier>1.0</GainMultiplier>" +
|
||||
"<GainMultiplier>0.75</GainMultiplier>" +
|
||||
"</a:example>" +
|
||||
"<element name='GainMultiplier' a:help='Additional gain multiplier'>" +
|
||||
"<element name='GainMultiplier' a:help='Trader gain for a 100m distance'>" +
|
||||
"<ref name='positiveDecimal'/>" +
|
||||
"</element>";
|
||||
|
||||
@@ -133,6 +132,11 @@ Trader.prototype.GetSecondMarket = function()
|
||||
return this.markets[1] || null;
|
||||
};
|
||||
|
||||
Trader.prototype.GetTraderGainMultiplier = function()
|
||||
{
|
||||
return ApplyValueModificationsToEntity("Trader/GainMultiplier", +this.template.GainMultiplier, this.entity);
|
||||
}
|
||||
|
||||
Trader.prototype.HasBothMarkets = function()
|
||||
{
|
||||
return this.markets.length >= 2;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"genericName": "Commercial Treaty",
|
||||
"description": "Improve the international trading profit.",
|
||||
"cost": { "food": 0, "wood": 0, "stone": 0, "metal": 100 },
|
||||
"requirements": { "tech": "phase_town" },
|
||||
"requirementsTooltip": "Unlocked in Town Phase.",
|
||||
"icon": "sibylline_books.png",
|
||||
"researchTime": 40,
|
||||
"tooltip": "Market +10% International Bonus.",
|
||||
"modifications": [{ "value": "Market/InternationalBonus", "add": 0.10 }],
|
||||
"affects": ["Market"],
|
||||
"soundComplete": "interface/alarm/alarm_upgradearmory.xml"
|
||||
}
|
||||
@@ -1,67 +1,67 @@
|
||||
// This constant used to adjust gain value depending on distance
|
||||
const DISTANCE_FACTOR = 1 / 115;
|
||||
|
||||
// Additional gain (applying to each market) for trading performed between markets of different players, in percents
|
||||
const INTERNATIONAL_TRADING_ADDITION = 25;
|
||||
|
||||
// If trader undefined, the trader owner is supposed to be the same as the first market
|
||||
function CalculateTraderGain(firstMarket, secondMarket, template, trader)
|
||||
function CalculateTraderGain(firstMarket, secondMarket, traderTemplate, trader)
|
||||
{
|
||||
var gain = {};
|
||||
|
||||
var cmpFirstMarketPosition = Engine.QueryInterface(firstMarket, IID_Position);
|
||||
var cmpSecondMarketPosition = Engine.QueryInterface(secondMarket, IID_Position);
|
||||
if (!cmpFirstMarketPosition || !cmpFirstMarketPosition.IsInWorld() ||
|
||||
!cmpSecondMarketPosition || !cmpSecondMarketPosition.IsInWorld())
|
||||
let cmpMarket1 = Engine.QueryInterface(firstMarket, IID_Market);
|
||||
let cmpMarket2 = Engine.QueryInterface(secondMarket, IID_Market);
|
||||
if (!cmpMarket1 || !cmpMarket2)
|
||||
return null;
|
||||
var firstMarketPosition = cmpFirstMarketPosition.GetPosition2D();
|
||||
var secondMarketPosition = cmpSecondMarketPosition.GetPosition2D();
|
||||
|
||||
let cmpMarket1Player = QueryOwnerInterface(firstMarket);
|
||||
let cmpMarket2Player = QueryOwnerInterface(secondMarket);
|
||||
if (!cmpMarket1Player || !cmpMarket2Player)
|
||||
return null;
|
||||
|
||||
let cmpFirstMarketPosition = Engine.QueryInterface(firstMarket, IID_Position);
|
||||
let cmpSecondMarketPosition = Engine.QueryInterface(secondMarket, IID_Position);
|
||||
if (!cmpFirstMarketPosition || !cmpFirstMarketPosition.IsInWorld() ||
|
||||
!cmpSecondMarketPosition || !cmpSecondMarketPosition.IsInWorld())
|
||||
return null;
|
||||
let firstMarketPosition = cmpFirstMarketPosition.GetPosition2D();
|
||||
let secondMarketPosition = cmpSecondMarketPosition.GetPosition2D();
|
||||
|
||||
let gainMultiplier;
|
||||
if (trader)
|
||||
{
|
||||
let cmpTrader = Engine.QueryInterface(trader, IID_Trader);
|
||||
if (!cmpTrader)
|
||||
return null;
|
||||
gainMultiplier = cmpTrader.GetTraderGainMultiplier();
|
||||
}
|
||||
else //called from the gui, modifications already applied
|
||||
{
|
||||
if (!traderTemplate || !traderTemplate.GainMultiplier)
|
||||
return null;
|
||||
gainMultiplier = traderTemplate.GainMultiplier;
|
||||
}
|
||||
|
||||
let gain = {};
|
||||
|
||||
// Calculate ordinary Euclidean distance between markets.
|
||||
// We don't use pathfinder, because ordinary distance looks more fair.
|
||||
var distance = firstMarketPosition.distanceTo(secondMarketPosition);
|
||||
let distanceSq = firstMarketPosition.distanceToSquared(secondMarketPosition);
|
||||
// We calculate gain as square of distance to encourage trading between remote markets
|
||||
gain.traderGain = Math.pow(distance * DISTANCE_FACTOR, 2);
|
||||
if (template && template.GainMultiplier)
|
||||
{
|
||||
if (trader)
|
||||
gain.traderGain *= ApplyValueModificationsToEntity("Trader/GainMultiplier", +template.GainMultiplier, trader);
|
||||
else // called from the gui with modifications already applied
|
||||
gain.traderGain *= template.GainMultiplier;
|
||||
}
|
||||
// and gainMultiplier corresponds to the gain for a 100m distance
|
||||
gain.traderGain = distanceSq * gainMultiplier / 10000;
|
||||
|
||||
gain.market1Owner = cmpMarket1Player.GetPlayerID();
|
||||
gain.market2Owner = cmpMarket2Player.GetPlayerID();
|
||||
// If trader undefined, the trader owner is supposed to be the same as the first market
|
||||
var cmpOwnership = trader ? Engine.QueryInterface(trader, IID_Ownership) : Engine.QueryInterface(firstMarket, IID_Ownership);
|
||||
if (!cmpOwnership)
|
||||
let cmpPlayer = trader ? QueryOwnerInterface(trader) : cmpMarket1Player;
|
||||
if (!cmpPlayer)
|
||||
return null;
|
||||
gain.traderOwner = cmpOwnership.GetOwner();
|
||||
|
||||
gain.traderOwner = cmpPlayer.GetPlayerID();
|
||||
// Add potential player trade multipliers
|
||||
let playerBonus = cmpPlayer.GetTradeRateMultiplier();
|
||||
// If markets belong to different players, add gain from international trading
|
||||
var ownerFirstMarket = Engine.QueryInterface(firstMarket, IID_Ownership).GetOwner();
|
||||
var ownerSecondMarket = Engine.QueryInterface(secondMarket, IID_Ownership).GetOwner();
|
||||
if (ownerFirstMarket != ownerSecondMarket)
|
||||
if (gain.market1Owner != gain.market2Owner)
|
||||
{
|
||||
gain.market1Gain = gain.traderGain * ApplyValueModificationsToEntity("Trade/International", INTERNATIONAL_TRADING_ADDITION, firstMarket) / 100;
|
||||
gain.market1Owner = ownerFirstMarket;
|
||||
gain.market2Gain = gain.traderGain * ApplyValueModificationsToEntity("Trade/International", INTERNATIONAL_TRADING_ADDITION, secondMarket) / 100;
|
||||
gain.market2Owner = ownerSecondMarket;
|
||||
}
|
||||
|
||||
// Add potential trade multipliers and roundings
|
||||
var cmpPlayer = trader ? QueryOwnerInterface(trader) : QueryOwnerInterface(firstMarket);
|
||||
if (cmpPlayer)
|
||||
gain.traderGain *= cmpPlayer.GetTradeRateMultiplier();
|
||||
gain.traderGain = Math.round(gain.traderGain);
|
||||
|
||||
if (ownerFirstMarket != ownerSecondMarket)
|
||||
{
|
||||
if ((cmpPlayer = QueryOwnerInterface(firstMarket)))
|
||||
gain.market1Gain *= cmpPlayer.GetTradeRateMultiplier();
|
||||
gain.market1Gain = Math.round(gain.market1Gain);
|
||||
|
||||
if ((cmpPlayer = QueryOwnerInterface(secondMarket)))
|
||||
gain.market2Gain *= cmpPlayer.GetTradeRateMultiplier();
|
||||
gain.market2Gain = Math.round(gain.market2Gain);
|
||||
let market1PlayerBonus = cmpMarket1Player.GetTradeRateMultiplier();
|
||||
let market2PlayerBonus = cmpMarket2Player.GetTradeRateMultiplier();
|
||||
let internationalBonus1 = cmpMarket1.GetInternationalBonus();
|
||||
let internationalBonus2 = cmpMarket2.GetInternationalBonus();
|
||||
gain.market1Gain = Math.round(gain.traderGain * internationalBonus1 * market1PlayerBonus);
|
||||
gain.market2Gain = Math.round(gain.traderGain * internationalBonus2 * market2PlayerBonus);
|
||||
}
|
||||
gain.traderGain = Math.round(gain.traderGain * playerBonus);
|
||||
|
||||
return gain;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
<History>The Carthaginians were famous for their sea trade. Carthage itself had an entire harbor dedicated to nothing more than commercial sea trade.</History>
|
||||
<Tooltip>Construct fishing boats to gather meat and merchant ships to trade with other docks.</Tooltip>
|
||||
</Identity>
|
||||
<Market>
|
||||
<InternationalBonus op="add">0.1</InternationalBonus>
|
||||
</Market>
|
||||
<Obstruction>
|
||||
<Static width="30.0" depth="19.0"/>
|
||||
</Obstruction>
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
<SpecificName>Šūq</SpecificName>
|
||||
<History>Carthaginian markets were probably just big sheds or structures surrounding a ?market? area or in a wharf area of a port.</History>
|
||||
</Identity>
|
||||
<Market>
|
||||
<InternationalBonus op="add">0.1</InternationalBonus>
|
||||
</Market>
|
||||
<Obstruction>
|
||||
<Static width="27.0" depth="20.0"/>
|
||||
</Obstruction>
|
||||
|
||||
@@ -41,6 +41,6 @@
|
||||
<PassabilityClass>large</PassabilityClass>
|
||||
</UnitMotion>
|
||||
<Trader>
|
||||
<GainMultiplier>1.0</GainMultiplier>
|
||||
<GainMultiplier>0.75</GainMultiplier>
|
||||
</Trader>
|
||||
</Entity>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
</Loot>
|
||||
<Market>
|
||||
<TradeType>land</TradeType>
|
||||
<InternationalBonus>0.2</InternationalBonus>
|
||||
</Market>
|
||||
<Obstruction>
|
||||
<Static width="30.0" depth="26.0"/>
|
||||
@@ -59,6 +60,7 @@
|
||||
trade_convoys_armor
|
||||
trade_gain_01
|
||||
trade_gain_02
|
||||
trade_commercial_treaty
|
||||
</Technologies>
|
||||
<Entities datatype="tokens">
|
||||
units/{civ}_support_trader
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
</Loot>
|
||||
<Market>
|
||||
<TradeType>land naval</TradeType>
|
||||
<InternationalBonus>0.2</InternationalBonus>
|
||||
</Market>
|
||||
<Obstruction>
|
||||
<Static width="18.0" depth="18.0"/>
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@
|
||||
<HeightOffset>6.0</HeightOffset>
|
||||
</StatusBars>
|
||||
<Trader>
|
||||
<GainMultiplier>1.0</GainMultiplier>
|
||||
<GainMultiplier>0.75</GainMultiplier>
|
||||
</Trader>
|
||||
<UnitAI>
|
||||
<DefaultStance>passive</DefaultStance>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
</SoundGroups>
|
||||
</Sound>
|
||||
<Trader>
|
||||
<GainMultiplier>1.0</GainMultiplier>
|
||||
<GainMultiplier>0.75</GainMultiplier>
|
||||
</Trader>
|
||||
<UnitAI>
|
||||
<CanGuard>false</CanGuard>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<RequiredTechnology>phase_village</RequiredTechnology>
|
||||
</Identity>
|
||||
<Trader>
|
||||
<GainMultiplier>1.25</GainMultiplier>
|
||||
<GainMultiplier op="mul">1.25</GainMultiplier>
|
||||
</Trader>
|
||||
<VisualActor>
|
||||
<Actor>structures/carthaginians/merchant_ship.xml</Actor>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</SoundGroups>
|
||||
</Sound>
|
||||
<Trader>
|
||||
<GainMultiplier>1.25</GainMultiplier>
|
||||
<GainMultiplier op="mul">1.25</GainMultiplier>
|
||||
</Trader>
|
||||
<VisualActor>
|
||||
<Actor>units/persians/trader.xml</Actor>
|
||||
|
||||
Reference in New Issue
Block a user