1
0
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:
mimo
2016-04-29 18:52:44 +00:00
parent b780073e24
commit b88f63b699
13 changed files with 95 additions and 61 deletions
@@ -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"/>
@@ -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>