make easy AI levels easier and hard levels harders by also applying the bonus/malus to trade, fixes #3722

add some info on AI levels in the AI config window

This was SVN commit r17626.
This commit is contained in:
mimo 2016-01-10 21:57:01 +00:00
parent 7fa2962c45
commit 3246b02cda
5 changed files with 46 additions and 17 deletions

View file

@ -10,7 +10,7 @@
<!-- Add a translucent black background to fade out the menu page -->
<object type="image" sprite="ModernFade"/>
<object type="image" style="ModernDialog" size="50%-230 50%-130 50%+230 50%+130">
<object type="image" style="ModernDialog" size="50%-230 50%-150 50%+230 50%+150">
<object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
<translatableAttribute id="caption">AI Configuration</translatableAttribute>
@ -33,7 +33,7 @@
</object>
</object>
<object name="aiDescription" type="text" style="ModernLabelText" size="8% 50%-54 92% 50%+74"/>
<object name="aiDescription" type="text" style="ModernLabelText" size="8% 90 92% 100%-60"/>
<object type="button" style="ModernButtonRed" size="18 100%-45 50%-5 100%-17" hotkey="cancel">
<translatableAttribute id="caption">Cancel</translatableAttribute>

View file

@ -1,6 +1,6 @@
{
"name": "Petra Bot",
"description": "Started as a fork of Aegis bot, Petra is the most stable AI available. It supports naval maps and is generally more challenging. Please report issues to Wildfire Games (see the link in the main menu).",
"description": "Petra is the default 0AD AI bot. Please report issues to Wildfire Games (see the link in the main menu).\n\nThe AI has a malus-bonus on resource stockpiling (either gathering rate or trade gain) varying from 0.5 for Sandbox to 1.6 for Very Hard (Medium = 1.0). In addition, the Sandbox level does not expand nor attack.",
"moduleName" : "PETRA",
"constructor": "PetraBot",
"useShared": true

View file

@ -36,6 +36,7 @@ Player.prototype.Init = function()
this.controlAllUnits = false;
this.isAI = false;
this.gatherRateMultiplier = 1;
this.tradeRateMultiplier = 1;
this.cheatsEnabled = false;
this.cheatTimeMultiplier = 1;
this.heroes = [];
@ -156,6 +157,16 @@ Player.prototype.GetGatherRateMultiplier = function()
return this.gatherRateMultiplier;
};
Player.prototype.SetTradeRateMultiplier = function(value)
{
this.tradeRateMultiplier = value;
};
Player.prototype.GetTradeRateMultiplier = function()
{
return this.tradeRateMultiplier;
};
Player.prototype.GetHeroes = function()
{
return this.heroes;

View file

@ -42,6 +42,8 @@ function InitGame(settings)
cmpRangeManager.ExploreAllTiles(i);
}
// Sandbox, Very Easy, Easy, Medium, Hard, Very Hard
let rate = [ 0.50, 0.64, 0.80, 1.00, 1.25, 1.56 ];
let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
let cmpAIManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIManager);
for (let i = 1; i < settings.PlayerData.length; ++i)
@ -50,10 +52,12 @@ function InitGame(settings)
cmpPlayer.SetCheatsEnabled(!!settings.CheatsEnabled);
if (settings.PlayerData[i] && settings.PlayerData[i].AI && settings.PlayerData[i].AI != "")
{
cmpAIManager.AddPlayer(settings.PlayerData[i].AI, i, +settings.PlayerData[i].AIDiff);
let AIDiff = +settings.PlayerData[i].AIDiff;
cmpAIManager.AddPlayer(settings.PlayerData[i].AI, i, AIDiff);
cmpPlayer.SetAI(true);
// Sandbox: 50%, very easy: 50%, easy: 66%, Medium: 100%, hard: 133%, very hard: 166%
cmpPlayer.SetGatherRateMultiplier(Math.max(0.5,(+settings.PlayerData[i].AIDiff)/3.0));
AIDiff = Math.min(AIDiff, rate.length - 1);
cmpPlayer.SetGatherRateMultiplier(rate[AIDiff]);
cmpPlayer.SetTradeRateMultiplier(rate[AIDiff]);
}
if (settings.PopulationCap)
cmpPlayer.SetMaxPopulation(settings.PopulationCap);

View file

@ -11,14 +11,15 @@ function CalculateTraderGain(firstMarket, secondMarket, template, trader)
var cmpFirstMarketPosition = Engine.QueryInterface(firstMarket, IID_Position);
var cmpSecondMarketPosition = Engine.QueryInterface(secondMarket, IID_Position);
if (!cmpFirstMarketPosition || !cmpFirstMarketPosition.IsInWorld() || !cmpSecondMarketPosition || !cmpSecondMarketPosition.IsInWorld())
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));
var distance = firstMarketPosition.distanceTo(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)
@ -28,12 +29,10 @@ function CalculateTraderGain(firstMarket, secondMarket, template, trader)
else // called from the gui with modifications already applied
gain.traderGain *= template.GainMultiplier;
}
gain.traderGain = Math.round(gain.traderGain);
// If trader undefined, the trader owner is supposed to be the same as the first market
if (trader)
var cmpOwnership = Engine.QueryInterface(trader, IID_Ownership);
else
var cmpOwnership = Engine.QueryInterface(firstMarket, IID_Ownership);
var cmpOwnership = trader ? Engine.QueryInterface(trader, IID_Ownership) : Engine.QueryInterface(firstMarket, IID_Ownership);
if (!cmpOwnership)
return null;
gain.traderOwner = cmpOwnership.GetOwner();
// If markets belong to different players, add gain from international trading
@ -41,13 +40,28 @@ function CalculateTraderGain(firstMarket, secondMarket, template, trader)
var ownerSecondMarket = Engine.QueryInterface(secondMarket, IID_Ownership).GetOwner();
if (ownerFirstMarket != ownerSecondMarket)
{
var internationalGain1 = ApplyValueModificationsToEntity("Trade/International", INTERNATIONAL_TRADING_ADDITION, firstMarket);
gain.market1Gain = Math.round(gain.traderGain * internationalGain1 / 100);
gain.market1Gain = gain.traderGain * ApplyValueModificationsToEntity("Trade/International", INTERNATIONAL_TRADING_ADDITION, firstMarket) / 100;
gain.market1Owner = ownerFirstMarket;
var internationalGain2 = ApplyValueModificationsToEntity("Trade/International", INTERNATIONAL_TRADING_ADDITION, secondMarket);
gain.market2Gain = Math.round(gain.traderGain * internationalGain2 / 100);
gain.market2Gain = gain.traderGain * ApplyValueModificationsToEntity("Trade/International", INTERNATIONAL_TRADING_ADDITION, secondMarket) / 100;
gain.market2Owner = ownerSecondMarket;
}
// Add potential trade multipliers and roundings
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(gain.traderOwner), IID_Player);
if (cmpPlayer)
gain.traderGain *= cmpPlayer.GetTradeRateMultiplier();
gain.traderGain = Math.round(gain.traderGain);
if (ownerFirstMarket != ownerSecondMarket)
{
if ((cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(gain.market1Owner), IID_Player)))
gain.market1Gain *= cmpPlayer.GetTradeRateMultiplier();
gain.market1Gain = Math.round(gain.market1Gain);
if ((cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(gain.market2Owner), IID_Player)))
gain.market2Gain *= cmpPlayer.GetTradeRateMultiplier();
gain.market2Gain = Math.round(gain.market2Gain);
}
return gain;