Unify trade gain computation between simulation and ai
Reviewed By: elexis Differential Revision: https://code.wildfiregames.com/D964 This was SVN commit r20320.
This commit is contained in:
parent
e5ec6d0bff
commit
23893415d1
15
binaries/data/mods/public/globalscripts/Trade.js
Normal file
15
binaries/data/mods/public/globalscripts/Trade.js
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Normalize the trade gain as a function of mapSize, default=1024
|
||||
*/
|
||||
function TradeGainNormalization(mapSize)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependance of the gain with distance, normalized on a distance of 100m
|
||||
*/
|
||||
function NormalizedTradeGain(distanceSquared)
|
||||
{
|
||||
return distanceSquared / 10000;
|
||||
}
|
@ -936,10 +936,13 @@ m.GameState.prototype.getTraderTemplatesGains = function()
|
||||
let supportTraderTemplateName = this.applyCiv("units/{civ}_support_trader");
|
||||
let shipMerchantTemplate = !this.isTemplateDisabled(shipMechantTemplateName) && this.getTemplate(shipMechantTemplateName);
|
||||
let supportTraderTemplate = !this.isTemplateDisabled(supportTraderTemplateName) && this.getTemplate(supportTraderTemplateName);
|
||||
return {
|
||||
"navalGainMultiplier": shipMerchantTemplate && shipMerchantTemplate.gainMultiplier(),
|
||||
"landGainMultiplier": supportTraderTemplate && supportTraderTemplate.gainMultiplier()
|
||||
};
|
||||
let norm = TradeGainNormalization(this.sharedScript.mapSize);
|
||||
let ret = {};
|
||||
if (supportTraderTemplate)
|
||||
ret.landGainMultiplier = norm * supportTraderTemplate.gainMultiplier();
|
||||
if (shipMerchantTemplate)
|
||||
ret.navalGainMultiplier = norm * shipMerchantTemplate.gainMultiplier();
|
||||
return ret;
|
||||
};
|
||||
|
||||
return m;
|
||||
|
@ -1104,8 +1104,9 @@ m.HQ.prototype.findStrategicCCLocation = function(gameState, template)
|
||||
/**
|
||||
* Returns the best position to build a new market: if the allies already have a market, build it as far as possible
|
||||
* from it, although not in our border to be able to defend it easily. If no allied market, our second market will
|
||||
* follow the same logic
|
||||
* TODO check that it is on same accessIndex
|
||||
* follow the same logic.
|
||||
* To do so, we suppose that the gain/distance is an increasing function of distance and look for the max distance
|
||||
* for performance reasons.
|
||||
*/
|
||||
m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
{
|
||||
@ -1127,6 +1128,8 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
let bestIdx;
|
||||
let bestJdx;
|
||||
let bestVal;
|
||||
let bestDistSq;
|
||||
let bestGainMult;
|
||||
let radius = Math.ceil(template.obstructionRadius().max / obstructions.cellSize);
|
||||
let isNavalMarket = template.hasClass("NavalMarket");
|
||||
|
||||
@ -1152,6 +1155,8 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
let pos = [cellSize * (j%width+0.5), cellSize * (Math.floor(j/width)+0.5)];
|
||||
// checking distances to other markets
|
||||
let maxVal = 0;
|
||||
let maxDistSq;
|
||||
let maxGainMult;
|
||||
let gainMultiplier;
|
||||
for (let market of markets)
|
||||
{
|
||||
@ -1168,9 +1173,13 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
continue;
|
||||
if (!gainMultiplier)
|
||||
continue;
|
||||
let val = API3.SquareVectorDistance(market.position(), pos) * gainMultiplier;
|
||||
if (val > maxVal)
|
||||
maxVal = val;
|
||||
let distSq = API3.SquareVectorDistance(market.position(), pos);
|
||||
if (gainMultiplier * distSq > maxVal)
|
||||
{
|
||||
maxVal = gainMultiplier * distSq;
|
||||
maxDistSq = distSq;
|
||||
maxGainMult = gainMultiplier;
|
||||
}
|
||||
}
|
||||
if (maxVal === 0)
|
||||
continue;
|
||||
@ -1179,6 +1188,8 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
if (this.isDangerousLocation(gameState, pos, halfSize))
|
||||
continue;
|
||||
bestVal = maxVal;
|
||||
bestDistSq = maxDistSq;
|
||||
bestGainMult = maxGainMult;
|
||||
bestIdx = i;
|
||||
bestJdx = j;
|
||||
}
|
||||
@ -1188,7 +1199,7 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
|
||||
if (bestVal === undefined) // no constraints. For the time being, place it arbitrarily by the ConstructionPlan
|
||||
return [-1, -1, -1, 0];
|
||||
let expectedGain = Math.round(bestVal / 10000);
|
||||
let expectedGain = Math.round(bestGainMult * NormalizedTradeGain(bestDistSq));
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("this would give a trading gain of " + expectedGain);
|
||||
// do not keep it if gain is too small, except if this is our first BarterMarket
|
||||
|
@ -444,7 +444,7 @@ m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex)
|
||||
gainMultiplier = traderTemplatesGains.navalGainMultiplier;
|
||||
else
|
||||
continue;
|
||||
let gain = Math.round(API3.SquareVectorDistance(m1.position(), m2.position()) * gainMultiplier / 10000);
|
||||
let gain = Math.round(gainMultiplier * NormalizedTradeGain(API3.SquareVectorDistance(m1.position(), m2.position())));
|
||||
if (gain < this.minimalGain)
|
||||
continue;
|
||||
if (m1.foundationProgress() === undefined && m2.foundationProgress() === undefined)
|
||||
|
@ -11,7 +11,7 @@ Trader.prototype.Schema =
|
||||
"<a:example>" +
|
||||
"<GainMultiplier>0.75</GainMultiplier>" +
|
||||
"</a:example>" +
|
||||
"<element name='GainMultiplier' a:help='Trader gain for a 100m distance'>" +
|
||||
"<element name='GainMultiplier' a:help='Trader gain for a 100m distance and mapSize = 1024'>" +
|
||||
"<ref name='positiveDecimal'/>" +
|
||||
"</element>";
|
||||
|
||||
|
@ -18,19 +18,19 @@ function CalculateTraderGain(firstMarket, secondMarket, traderTemplate, trader)
|
||||
let firstMarketPosition = cmpFirstMarketPosition.GetPosition2D();
|
||||
let secondMarketPosition = cmpSecondMarketPosition.GetPosition2D();
|
||||
|
||||
let gainMultiplier;
|
||||
let gainMultiplier = TradeGainNormalization(Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain).GetMapSize());
|
||||
if (trader)
|
||||
{
|
||||
let cmpTrader = Engine.QueryInterface(trader, IID_Trader);
|
||||
if (!cmpTrader)
|
||||
return null;
|
||||
gainMultiplier = cmpTrader.GetTraderGainMultiplier();
|
||||
gainMultiplier *= cmpTrader.GetTraderGainMultiplier();
|
||||
}
|
||||
else //called from the gui, modifications already applied
|
||||
{
|
||||
if (!traderTemplate || !traderTemplate.GainMultiplier)
|
||||
return null;
|
||||
gainMultiplier = traderTemplate.GainMultiplier;
|
||||
gainMultiplier *= traderTemplate.GainMultiplier;
|
||||
}
|
||||
|
||||
let gain = {};
|
||||
@ -40,7 +40,7 @@ function CalculateTraderGain(firstMarket, secondMarket, traderTemplate, trader)
|
||||
let distanceSq = firstMarketPosition.distanceToSquared(secondMarketPosition);
|
||||
// We calculate gain as square of distance to encourage trading between remote markets
|
||||
// and gainMultiplier corresponds to the gain for a 100m distance
|
||||
gain.traderGain = gainMultiplier * distanceSq / 10000;
|
||||
gain.traderGain = gainMultiplier * NormalizedTradeGain(distanceSq);
|
||||
|
||||
gain.market1Owner = cmpMarket1Player.GetPlayerID();
|
||||
gain.market2Owner = cmpMarket2Player.GetPlayerID();
|
||||
|
Loading…
Reference in New Issue
Block a user