1
0
forked from mirrors/0ad

fixes confusion between markets when doing trade, fixes #3812, patch by leper and fatherbushido

This was SVN commit r17854.
This commit is contained in:
mimo
2016-03-09 19:54:12 +00:00
parent 7409fe4bec
commit 98b4fe6d00
4 changed files with 79 additions and 99 deletions
@@ -74,6 +74,8 @@ function getRankIconSprite(entState)
*/
function getTradingTooltip(gain)
{
if (!gain)
return "";
var playerID = Engine.GetPlayerID();
var simState = GetSimState();
@@ -1667,13 +1667,13 @@ GuiInterface.prototype.GetTradingDetails = function(player, data)
"hasBothMarkets": cmpEntityTrader.HasBothMarkets()
};
if (cmpEntityTrader.HasBothMarkets())
result.gain = cmpEntityTrader.GetGain();
result.gain = cmpEntityTrader.GetGoods().amount;
}
else if (data.target === secondMarket)
{
result = {
"type": "is second",
"gain": cmpEntityTrader.GetGain(),
"gain": cmpEntityTrader.GetGoods().amount,
};
}
else if (!firstMarket)
@@ -21,19 +21,17 @@ Trader.prototype.Schema =
Trader.prototype.Init = function()
{
this.firstMarket = INVALID_ENTITY;
this.secondMarket = INVALID_ENTITY;
// Gain from one pass between markets
this.gain = null;
this.markets = [];
this.index = -1;
// Selected resource for trading
this.requiredGoods = undefined;
// Currently carried goods
this.goods = { "type": null, "amount": null, "origin": null };
};
Trader.prototype.CalculateGain = function(firstMarket, secondMarket)
Trader.prototype.CalculateGain = function(currentMarket, nextMarket)
{
var gain = CalculateTraderGain(firstMarket, secondMarket, this.template, this.entity);
let gain = CalculateTraderGain(currentMarket, nextMarket, this.template, this.entity);
if (!gain) // One of our markets must have been destroyed
return null;
@@ -67,11 +65,6 @@ Trader.prototype.CalculateGain = function(firstMarket, secondMarket)
return gain;
};
Trader.prototype.GetGain = function()
{
return this.gain;
};
// Set target as target market.
// Return true if at least one of markets was changed.
Trader.prototype.SetTargetMarket = function(target, source)
@@ -91,35 +84,34 @@ Trader.prototype.SetTargetMarket = function(target, source)
return false;
if (!cmpTargetIdentity.HasClass("Market") && !cmpTargetIdentity.HasClass("NavalMarket"))
return false;
this.firstMarket = source;
this.secondMarket = INVALID_ENTITY;
this.markets = [source];
}
if (this.secondMarket)
if (this.markets.length >= 2)
{
// If we already have both markets - drop them
// and use the target as first market
this.firstMarket = target;
this.secondMarket = INVALID_ENTITY;
this.index = 0;
this.markets = [target];
}
else if (this.firstMarket)
else if (this.markets.length == 1)
{
// 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.markets[0])
marketsChanged = false;
else
{
this.secondMarket = target;
this.gain = this.CalculateGain(this.firstMarket, this.secondMarket);
this.index = 0;
this.markets.push(target);
this.goods.amount = this.CalculateGain(this.markets[0], this.markets[1]);
}
}
else
{
// Else we don't have target markets at all,
// set the target as first market
this.firstMarket = target;
this.index = 0;
this.markets = [target];
}
if (marketsChanged)
{
@@ -131,17 +123,17 @@ Trader.prototype.SetTargetMarket = function(target, source)
Trader.prototype.GetFirstMarket = function()
{
return this.firstMarket;
return this.markets[0] || null;
};
Trader.prototype.GetSecondMarket = function()
{
return this.secondMarket;
return this.markets[1] || null;
};
Trader.prototype.HasBothMarkets = function()
{
return this.firstMarket && this.secondMarket;
return this.markets.length >= 2;
};
Trader.prototype.GetRequiredGoods = function()
@@ -186,6 +178,15 @@ Trader.prototype.CanTrade = function(target)
Trader.prototype.PerformTrade = function(currentMarket)
{
let previousMarket = this.markets[(this.index+this.markets.length) % this.markets.length];
this.index = ++this.index % this.markets.length;
let nextMarket = this.markets[(this.index+this.markets.length) % this.markets.length];
if (previousMarket != currentMarket)
warn("Markets are not matching.");
if (this.goods.amount && this.goods.amount.traderGain)
{
var cmpPlayer = QueryOwnerInterface(this.entity);
@@ -198,22 +199,22 @@ Trader.prototype.PerformTrade = function(currentMarket)
if (this.goods.amount.market1Gain)
{
var cmpPlayer = QueryOwnerInterface(this.firstMarket);
let cmpPlayer = QueryOwnerInterface(previousMarket);
if (cmpPlayer)
cmpPlayer.AddResource(this.goods.type, this.goods.amount.market1Gain);
var cmpStatisticsTracker = QueryOwnerInterface(this.firstMarket, IID_StatisticsTracker);
let cmpStatisticsTracker = QueryOwnerInterface(previousMarket, IID_StatisticsTracker);
if (cmpStatisticsTracker)
cmpStatisticsTracker.IncreaseTradeIncomeCounter(this.goods.amount.market1Gain);
}
if (this.goods.amount.market2Gain)
{
var cmpPlayer = QueryOwnerInterface(this.secondMarket);
let cmpPlayer = QueryOwnerInterface(nextMarket);
if (cmpPlayer)
cmpPlayer.AddResource(this.goods.type, this.goods.amount.market2Gain);
var cmpStatisticsTracker = QueryOwnerInterface(this.secondMarket, IID_StatisticsTracker);
let cmpStatisticsTracker = QueryOwnerInterface(nextMarket, IID_StatisticsTracker);
if (cmpStatisticsTracker)
cmpStatisticsTracker.IncreaseTradeIncomeCounter(this.goods.amount.market2Gain);
}
@@ -234,7 +235,7 @@ Trader.prototype.PerformTrade = function(currentMarket)
nextGoods = "metal";
}
this.goods.type = nextGoods;
this.goods.amount = this.CalculateGain(this.firstMarket, this.secondMarket);
this.goods.amount = this.CalculateGain(currentMarket, nextMarket);
this.goods.origin = currentMarket;
};
@@ -243,23 +244,14 @@ Trader.prototype.GetGoods = function()
return this.goods;
};
Trader.prototype.GetNextMarket = function()
{
if (this.goods.amount && this.goods.origin == this.firstMarket)
return this.secondMarket;
if (this.goods.amount && this.goods.origin != this.secondMarket)
this.goods.amount = null; // leftover from previous trading
return this.firstMarket;
};
Trader.prototype.StopTrading = function()
{
this.index = -1;
this.markets = [];
// Drop carried goods
this.goods.amount = null;
// Reset markets
this.firstMarket = INVALID_ENTITY;
this.secondMarket = INVALID_ENTITY;
this.markets = [];
};
// Get range in which deals with market are available,
@@ -277,7 +269,7 @@ Trader.prototype.GetRange = function()
Trader.prototype.OnGarrisonedUnitsChanged = function()
{
if (this.HasBothMarkets())
this.gain = this.CalculateGain(this.firstMarket, this.secondMarket);
this.goods.amount = this.CalculateGain(this.markets[0], this.markets[1]);
};
Engine.RegisterComponentType(IID_Trader, "Trader", Trader);
@@ -654,17 +654,11 @@ UnitAI.prototype.UnitFsmSpec = {
return;
}
var nextMarket = cmpTrader.GetNextMarket();
if (nextMarket == this.order.data.firstMarket)
var state = "TRADE.APPROACHINGFIRSTMARKET";
else
var state = "TRADE.APPROACHINGSECONDMARKET";
// TODO find the nearest way-point from our position, and start with it
this.waypoints = undefined;
if (this.MoveToMarket(nextMarket))
if (this.MoveToMarket(this.order.data.target))
// We've started walking to the next market
this.SetNextState(state);
this.SetNextState("TRADE.APPROACHINGMARKET");
else
this.FinishOrder();
},
@@ -2605,7 +2599,7 @@ UnitAI.prototype.UnitFsmSpec = {
// TODO: Inform player
},
"APPROACHINGFIRSTMARKET": {
"APPROACHINGMARKET": {
"enter": function () {
this.SelectAnimation("move");
},
@@ -2613,27 +2607,11 @@ UnitAI.prototype.UnitFsmSpec = {
"MoveCompleted": function() {
if (this.waypoints && this.waypoints.length)
{
if (!this.MoveToMarket(this.order.data.firstMarket))
if (!this.MoveToMarket(this.order.data.target))
this.StopTrading();
}
else
this.PerformTradeAndMoveToNextMarket(this.order.data.firstMarket, this.order.data.secondMarket, "APPROACHINGSECONDMARKET");
},
},
"APPROACHINGSECONDMARKET": {
"enter": function () {
this.SelectAnimation("move");
},
"MoveCompleted": function() {
if (this.waypoints && this.waypoints.length)
{
if (!this.MoveToMarket(this.order.data.secondMarket))
this.StopTrading();
}
else
this.PerformTradeAndMoveToNextMarket(this.order.data.secondMarket, this.order.data.firstMarket, "APPROACHINGFIRSTMARKET");
this.PerformTradeAndMoveToNextMarket(this.order.data.target);
},
},
},
@@ -5170,7 +5148,13 @@ UnitAI.prototype.SetupTradeRoute = function(target, source, route, queued)
var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
if (cmpTrader.HasBothMarkets())
{
var data = { "firstMarket": cmpTrader.GetFirstMarket(), "secondMarket": cmpTrader.GetSecondMarket(), "route": route, "force": false };
let data = {
"target": cmpTrader.GetFirstMarket(),
"firstMarket": cmpTrader.GetFirstMarket(),
"secondMarket": cmpTrader.GetSecondMarket(),
"route": route,
"force": false
};
if (this.expectedRoute)
{
@@ -5230,7 +5214,7 @@ UnitAI.prototype.MoveToMarket = function(targetMarket)
return ok;
};
UnitAI.prototype.PerformTradeAndMoveToNextMarket = function(currentMarket, nextMarket, nextFsmStateName)
UnitAI.prototype.PerformTradeAndMoveToNextMarket = function(currentMarket)
{
if (!this.CanTrade(currentMarket))
{
@@ -5238,34 +5222,36 @@ UnitAI.prototype.PerformTradeAndMoveToNextMarket = function(currentMarket, nextM
return;
}
if (this.CheckTargetRange(currentMarket, IID_Trader))
{
var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
cmpTrader.PerformTrade(currentMarket);
if (!cmpTrader.GetGain().traderGain)
{
this.StopTrading();
return;
}
if (this.order.data.route && this.order.data.route.length)
{
this.waypoints = this.order.data.route.slice();
if (nextFsmStateName == "APPROACHINGSECONDMARKET")
this.waypoints.reverse();
this.waypoints.unshift(null); // additionnal dummy point for the market
}
if (this.MoveToMarket(nextMarket)) // We've started walking to the next market
this.SetNextState(nextFsmStateName);
else
this.StopTrading();
}
else
if (!this.CheckTargetRange(currentMarket, IID_Trader))
{
if (!this.MoveToMarket(currentMarket)) // If the current market is not reached try again
this.StopTrading();
return;
}
let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
cmpTrader.PerformTrade(currentMarket);
let nextMarket = cmpTrader.markets[cmpTrader.index];
if (!cmpTrader.GetGoods().amount.traderGain)
{
this.StopTrading();
return;
}
this.order.data.target = nextMarket;
if (this.order.data.route && this.order.data.route.length)
{
this.waypoints = this.order.data.route.slice();
if (this.order.data.target == cmpTrader.GetSecondMarket())
this.waypoints.reverse();
this.waypoints.unshift(null); // additionnal dummy point for the market
}
if (this.MoveToMarket(nextMarket)) // We've started walking to the next market
this.SetNextState("APPROACHINGMARKET");
else
this.StopTrading();
};
UnitAI.prototype.StopTrading = function()