mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-20 23:33:59 -07:00
Make rally points work for trade. Patch from Deiz/F00. Fixes #1173.
This was SVN commit r12191.
This commit is contained in:
parent
006aa8ee21
commit
0dc1d2139e
7 changed files with 109 additions and 42 deletions
|
|
@ -210,6 +210,7 @@ function getActionInfo(action, target)
|
|||
var gaiaOwned = (targetState.player == 0);
|
||||
|
||||
var cursor = "";
|
||||
var tooltip;
|
||||
|
||||
// default to walking there
|
||||
var data = {command: "walk"};
|
||||
|
|
@ -254,8 +255,29 @@ function getActionInfo(action, target)
|
|||
data.target = target;
|
||||
cursor = "action-repair";
|
||||
}
|
||||
else if (hasClass(entState, "Market") && hasClass(targetState, "Market") && entState.id != targetState.id &&
|
||||
(!hasClass(entState, "NavalMarket") || hasClass(targetState, "NavalMarket")))
|
||||
{
|
||||
// Find a trader (if any) that this building can produce.
|
||||
var trader;
|
||||
if (entState.production && entState.production.entities.length)
|
||||
for (var i = 0; i < entState.production.entities.length; ++i)
|
||||
if ((trader = GetTemplateData(entState.production.entities[i]).trader))
|
||||
break;
|
||||
|
||||
var traderData = { "firstMarket": entState.id, "secondMarket": targetState.id, "template": trader };
|
||||
var gain = Engine.GuiInterfaceCall("GetTradingRouteGain", traderData);
|
||||
if (gain !== null)
|
||||
{
|
||||
data.command = "trade";
|
||||
data.target = traderData.secondMarket;
|
||||
data.source = traderData.firstMarket;
|
||||
cursor = "action-setup-trade-route";
|
||||
tooltip = "Click to establish a default route for new traders. Gain: " + gain + " metal.";
|
||||
}
|
||||
}
|
||||
|
||||
return {"possible": true, "data": data, "position": targetState.position, "cursor": cursor};
|
||||
return {"possible": true, "data": data, "position": targetState.position, "cursor": cursor, "tooltip": tooltip};
|
||||
}
|
||||
|
||||
for each (var entityID in selection)
|
||||
|
|
@ -463,7 +485,7 @@ function determineAction(x, y, fromMinimap)
|
|||
else if (getActionInfo("repair", target).possible)
|
||||
return {"type": "build", "cursor": "action-repair", "target": target};
|
||||
else if ((actionInfo = getActionInfo("set-rallypoint", target)).possible)
|
||||
return {"type": "set-rallypoint", "cursor": actionInfo.cursor, "data": actionInfo.data, "position": actionInfo.position};
|
||||
return {"type": "set-rallypoint", "cursor": actionInfo.cursor, "data": actionInfo.data, "tooltip": actionInfo.tooltip, "position": actionInfo.position};
|
||||
else if (getActionInfo("heal", target).possible)
|
||||
return {"type": "heal", "cursor": "action-heal", "target": target};
|
||||
else if (getActionInfo("attack", target).possible)
|
||||
|
|
|
|||
|
|
@ -452,6 +452,9 @@ GuiInterface.prototype.GetTemplateData = function(player, name)
|
|||
if (template.UnitMotion.Run) ret.speed.run = +template.UnitMotion.Run.Speed;
|
||||
}
|
||||
|
||||
if (template.Trader)
|
||||
ret.trader = template.Trader;
|
||||
|
||||
if (template.WallSet)
|
||||
{
|
||||
ret.wallSet = {
|
||||
|
|
@ -1474,6 +1477,14 @@ GuiInterface.prototype.FindIdleUnit = function(player, data)
|
|||
return 0;
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetTradingRouteGain = function(player, data)
|
||||
{
|
||||
if (!data.firstMarket || !data.secondMarket)
|
||||
return null;
|
||||
|
||||
return CalculateTraderGain(data.firstMarket, data.secondMarket, data.template);
|
||||
}
|
||||
|
||||
GuiInterface.prototype.GetTradingDetails = function(player, data)
|
||||
{
|
||||
var cmpEntityTrader = Engine.QueryInterface(data.trader, IID_Trader);
|
||||
|
|
@ -1595,6 +1606,7 @@ var exposedFunctions = {
|
|||
"GetFoundationSnapData": 1,
|
||||
"PlaySound": 1,
|
||||
"FindIdleUnit": 1,
|
||||
"GetTradingRouteGain": 1,
|
||||
"GetTradingDetails": 1,
|
||||
"CanAttack": 1,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
// This constant used to adjust gain value depending on distance
|
||||
const DISTANCE_FACTOR = 1 / 110;
|
||||
// See helpers/TraderGain.js for the CalculateTaderGain() function which works out how many
|
||||
// resources a trader gets
|
||||
|
||||
// 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;
|
||||
|
||||
|
|
@ -36,30 +34,13 @@ Trader.prototype.Init = function()
|
|||
this.goods = { "type": null, "amount": 0 };
|
||||
}
|
||||
|
||||
Trader.prototype.CalculateGain = function(firstMarket, secondMarket)
|
||||
Trader.prototype.CalculateGain = function(firstMarket, secondMarket, template)
|
||||
{
|
||||
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
|
||||
// Calculate this here to save passing unnecessary stuff into the CalculatetraderGain function
|
||||
var garrisonMultiplier = 1;
|
||||
var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
|
||||
if (cmpIdentity.HasClass("Ship"))
|
||||
if (cmpIdentity && cmpIdentity.HasClass("Ship"))
|
||||
{
|
||||
var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
|
||||
if (cmpGarrisonHolder)
|
||||
|
|
@ -71,14 +52,11 @@ Trader.prototype.CalculateGain = function(firstMarket, secondMarket)
|
|||
if (cmpGarrisonedUnitTrader)
|
||||
garrisonedTradersCount++;
|
||||
}
|
||||
gain *= 1 + GARRISONED_TRADER_ADDITION * garrisonedTradersCount / 100;
|
||||
garrisonMultiplier *= 1 + GARRISONED_TRADER_ADDITION * garrisonedTradersCount / 100;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.template.GainMultiplier)
|
||||
gain *= this.template.GainMultiplier;
|
||||
gain = Math.round(gain);
|
||||
return gain;
|
||||
|
||||
return garrisonMultiplier * CalculateTraderGain(firstMarket, secondMarket, this.template);
|
||||
}
|
||||
|
||||
Trader.prototype.GetGain = function()
|
||||
|
|
@ -88,7 +66,7 @@ Trader.prototype.GetGain = function()
|
|||
|
||||
// Set target as target market.
|
||||
// Return true if at least one of markets was changed.
|
||||
Trader.prototype.SetTargetMarket = function(target)
|
||||
Trader.prototype.SetTargetMarket = function(target, source)
|
||||
{
|
||||
// Check that target is a market
|
||||
var cmpTargetIdentity = Engine.QueryInterface(target, IID_Identity);
|
||||
|
|
@ -96,24 +74,37 @@ Trader.prototype.SetTargetMarket = function(target)
|
|||
return false;
|
||||
if (!cmpTargetIdentity.HasClass("Market") && !cmpTargetIdentity.HasClass("NavalMarket"))
|
||||
return false;
|
||||
var marketsChanged = false;
|
||||
var marketsChanged = true;
|
||||
if (source)
|
||||
{
|
||||
// Establish a trade route with both markets in one go.
|
||||
cmpTargetIdentity = Engine.QueryInterface(source, IID_Identity);
|
||||
if (!cmpTargetIdentity)
|
||||
return false;
|
||||
if (!cmpTargetIdentity.HasClass("Market") && !cmpTargetIdentity.HasClass("NavalMarket"))
|
||||
return false;
|
||||
|
||||
this.firstMarket = source;
|
||||
this.secondMarket = INVALID_ENTITY;
|
||||
}
|
||||
|
||||
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)
|
||||
if (target == this.firstMarket)
|
||||
marketsChanged = false;
|
||||
else
|
||||
{
|
||||
this.secondMarket = target;
|
||||
this.gain = this.CalculateGain(this.firstMarket, this.secondMarket);
|
||||
marketsChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -121,7 +112,6 @@ Trader.prototype.SetTargetMarket = function(target)
|
|||
// Else we don't have target markets at all,
|
||||
// set the target as first market
|
||||
this.firstMarket = target;
|
||||
marketsChanged = true;
|
||||
}
|
||||
if (marketsChanged)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2919,7 +2919,7 @@ UnitAI.prototype.ReturnResource = function(target, queued)
|
|||
* Adds trade order to the queue. Either walk to the first market, or
|
||||
* start a new route. Not forced, so it can be interrupted by attacks.
|
||||
*/
|
||||
UnitAI.prototype.SetupTradeRoute = function(target, queued)
|
||||
UnitAI.prototype.SetupTradeRoute = function(target, source, queued)
|
||||
{
|
||||
if (!this.CanTrade(target))
|
||||
{
|
||||
|
|
@ -2928,7 +2928,7 @@ UnitAI.prototype.SetupTradeRoute = function(target, queued)
|
|||
}
|
||||
|
||||
var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
|
||||
var marketsChanged = cmpTrader.SetTargetMarket(target);
|
||||
var marketsChanged = cmpTrader.SetTargetMarket(target, source);
|
||||
if (marketsChanged)
|
||||
{
|
||||
if (cmpTrader.HasBothMarkets())
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ function ProcessCommand(player, cmd)
|
|||
{
|
||||
var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
|
||||
if (cmpUnitAI)
|
||||
cmpUnitAI.SetupTradeRoute(cmd.target);
|
||||
cmpUnitAI.SetupTradeRoute(cmd.target, cmd.source);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,15 @@ function GetRallyPointCommands(cmpRallyPoint, spawnedEnts)
|
|||
"queued": true
|
||||
});
|
||||
break;
|
||||
case "trade":
|
||||
ret.push( {
|
||||
"type": "setup-trade-route",
|
||||
"entities": spawnedEnts,
|
||||
"source": data[i].source,
|
||||
"target": data[i].target,
|
||||
"queued": true
|
||||
});
|
||||
break;
|
||||
default:
|
||||
ret.push( {
|
||||
"type": "walk",
|
||||
|
|
|
|||
34
binaries/data/mods/public/simulation/helpers/TraderGain.js
Normal file
34
binaries/data/mods/public/simulation/helpers/TraderGain.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// This constant used to adjust gain value depending on distance
|
||||
const DISTANCE_FACTOR = 1 / 110;
|
||||
|
||||
// Additional gain for trading performed between markets of different players, in percents
|
||||
const INTERNATIONAL_TRADING_ADDITION = 50;
|
||||
|
||||
function CalculateTraderGain(firstMarket, secondMarket, template)
|
||||
{
|
||||
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;
|
||||
|
||||
if (template.GainMultiplier)
|
||||
gain *= template.GainMultiplier;
|
||||
gain = Math.round(gain);
|
||||
return gain;
|
||||
}
|
||||
|
||||
Engine.RegisterGlobal("CalculateTraderGain", CalculateTraderGain);
|
||||
Loading…
Reference in a new issue