Index: ps/trunk/binaries/data/mods/public/gui/session/unit_actions.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/unit_actions.js +++ ps/trunk/binaries/data/mods/public/gui/session/unit_actions.js @@ -528,6 +528,58 @@ "specificness": 2, }, + "cancel-setup-trade-route": + { + "execute":function(target, action, selection, queued) + { + Engine.PostNetworkCommand({ + "type": "cancel-setup-trade-route", + "entities": selection, + "target": action.target, + "queued": queued + }); + + return true; + }, + "getActionInfo": function(entState, targetState) + { + if (targetState.foundation || !entState.trader || !targetState.market || + playerCheck(entState, targetState, ["Enemy"]) || + !(targetState.market.land && hasClass(entState, "Organic") || + targetState.market.naval && hasClass(entState, "Ship"))) + return false; + + let tradingDetails = Engine.GuiInterfaceCall("GetTradingDetails", { + "trader": entState.id, + "target": targetState.id + }); + + if (!tradingDetails || !tradingDetails.type) + return false; + + if (tradingDetails.type == "is first" && !tradingDetails.hasBothMarkets) + return { + "possible": true, + "tooltip": translate("This is the origin trade market.\nRight-click to cancel trade route.") + }; + return false; + }, + "actionCheck": function(target, selection) + { + let actionInfo = getActionInfo("cancel-setup-trade-route", target, selection); + + if (!actionInfo.possible) + return false; + return { + "type": "cancel-setup-trade-route", + "cursor": "action-cancel-setup-trade-route", + "tooltip": actionInfo.tooltip, + "target": target + } + }, + "specificness": 2, + }, + "setup-trade-route": { "execute": function(target, action, selection, queued) @@ -574,7 +626,7 @@ "gain": getTradingTooltip(tradingDetails.gain) }); else - tooltip += translate("Right-click on another market to set it as a destination trade market."); + return false; break; case "is second": Index: ps/trunk/binaries/data/mods/public/simulation/components/Trader.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Trader.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Trader.js @@ -65,6 +65,24 @@ return gain; }; +/** + * Remove market from trade route iff only first market is set. + * @param {number} id of market to be removed. + * @return {boolean} true iff removal was successful. + */ +Trader.prototype.RemoveTargetMarket = function(target) +{ + if (this.markets.length != 1 || this.markets[0] != target) + return false; + let cmpTargetMarket = QueryMiragedInterface(target, IID_Market); + if (!cmpTargetMarket) + return false; + cmpTargetMarket.RemoveTrader(this.entity); + this.index = -1; + this.markets = []; + return true; +} + // Set target as target market. // Return true if at least one of markets was changed. Trader.prototype.SetTargetMarket = function(target, source) Index: ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js +++ ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js @@ -5400,6 +5400,16 @@ this.AddOrder("ReturnResource", { "target": target, "force": true }, queued); }; +UnitAI.prototype.CancelSetupTradeRoute = function(target) +{ + let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); + if (!cmpTrader) + return; + cmpTrader.RemoveTargetMarket(target); + + if (this.IsFormationController()) + this.CallMemberFunction("CancelSetupTradeRoute", [target]); +} /** * 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. Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js @@ -639,6 +639,13 @@ }); }, + "cancel-setup-trade-route": function(player, cmd, data) + { + GetFormationUnitAIs(data.entities, player).forEach(cmpUnitAI => { + cmpUnitAI.CancelSetupTradeRoute(cmd.target); + }); + }, + "set-trading-goods": function(player, cmd, data) { data.cmpPlayer.SetTradingGoods(cmd.tradingGoods);