Add barter buttons to the trade window for quicker access and to support mods with more than four resource types.

The dialog is resized automatically and can be opened with a new hotkey.

Patch By: s0600204
Differential Revision: https://code.wildfiregames.com/D88
Fixes #4366
Refs #3934

This was SVN commit r19354.
This commit is contained in:
elexis 2017-03-28 02:34:32 +00:00
parent dbd56403b9
commit a934dfad5f
11 changed files with 325 additions and 160 deletions

View File

@ -157,8 +157,6 @@ console.toggle = BackQuote, F9 ; Open/close console
fps.toggle = "Alt+F" ; Toggle frame counter
realtime.toggle = "Alt+T" ; Toggle current display of computer time
session.devcommands.toggle = "Alt+D" ; Toggle developer commands panel
session.gui.toggle = "Alt+G" ; Toggle visibility of session GUI
menu.toggle = "F10" ; Toggle in-game menu
timeelapsedcounter.toggle = "F12" ; Toggle time elapsed counter
session.showstatusbars = Tab ; Toggle display of status bars
session.highlightguarding = PgDn ; Toggle highlight of guarding units
@ -295,6 +293,11 @@ deselectgroup = Ctrl ; Modifier to deselect units when clicking group ic
rotate.cw = RightBracket ; Rotate building placement preview clockwise
rotate.ccw = LeftBracket ; Rotate building placement preview anticlockwise
[hotkey.session.gui]
toggle = "Alt+G" ; Toggle visibility of session GUI
menu.toggle = "F10" ; Toggle in-game menu
barter.toggle = "Ctrl+B" ; Toggle in-game barter/trade page
[hotkey.session.savedgames]
delete = Delete ; Delete the selected saved game asking confirmation
noconfirmation = Shift ; Do not ask confirmation when deleting a game

View File

@ -16,10 +16,14 @@
<action on="Press">openChat(g_LastChatAddressee);</action>
</object>
<object hotkey="menu.toggle">
<object hotkey="session.gui.menu.toggle">
<action on="Press">toggleMenu();</action>
</object>
<object hotkey="session.gui.barter.toggle">
<action on="Press">toggleTrade();</action>
</object>
<object hotkey="silhouettes">
<action on="Press">
var newSetting = !Engine.Renderer_GetSilhouettesEnabled();
@ -72,8 +76,15 @@
</object>
<object hotkey="session.massbarter">
<action on="Press">updateSelectionDetails();</action>
<action on="Release">updateSelectionDetails();</action>
<action on="Press">
updateSelectionDetails();
updateBarterButtons();
</action>
<action on="Release">
updateSelectionDetails();
updateBarterButtons();
</action>
</object>
<!-- Find idle warrior - TODO: Potentially move this to own UI button? -->

View File

@ -28,6 +28,26 @@ const STEP = 5;
// Shown in the trade dialog.
const g_IdleTraderTextColor = "orange";
/**
* Quantity of goods to sell per click.
*/
const g_BarterResourceSellQuantity = 100;
/**
* Multiplier to be applied when holding the massbarter hotkey.
*/
const g_BarterMultiplier = 5;
/**
* Barter actions, as mapped to the names of GUI Buttons.
*/
const g_BarterActions = ["Buy", "Sell"];
/**
* Currently selected resource type to sell in the barter GUI.
*/
var g_BarterSell;
var g_IsMenuOpen = false;
var g_IsDiplomacyOpen = false;
@ -565,39 +585,51 @@ function openTrade()
g_IsTradeOpen = true;
var updateButtons = function()
let proba = Engine.GuiInterfaceCall("GetTradingGoods", g_ViewedPlayer);
let button = {};
let resCodes = g_ResourceData.GetCodes();
let currTradeSelection = resCodes[0];
let updateTradeButtons = function()
{
for (let res in button)
{
button[res].label.caption = proba[res] + "%";
button[res].sel.hidden = !controlsPlayer(g_ViewedPlayer) || res != selec;
button[res].up.hidden = !controlsPlayer(g_ViewedPlayer) || res == selec || proba[res] == 100 || proba[selec] == 0;
button[res].dn.hidden = !controlsPlayer(g_ViewedPlayer) || res == selec || proba[res] == 0 || proba[selec] == 100;
button[res].sel.hidden = !controlsPlayer(g_ViewedPlayer) || res != currTradeSelection;
button[res].up.hidden = !controlsPlayer(g_ViewedPlayer) || res == currTradeSelection || proba[res] == 100 || proba[currTradeSelection] == 0;
button[res].dn.hidden = !controlsPlayer(g_ViewedPlayer) || res == currTradeSelection || proba[res] == 0 || proba[currTradeSelection] == 100;
}
};
let proba = Engine.GuiInterfaceCall("GetTradingGoods", g_ViewedPlayer);
let button = {};
let resCodes = g_ResourceData.GetCodes();
let selec = resCodes[0];
hideRemaining("tradeResources", resCodes.length);
Engine.GetGUIObjectByName("tradeHelp").hidden = false;
for (let i = 0; i < resCodes.length; ++i)
{
let resCode = resCodes[i];
let barterResource = Engine.GetGUIObjectByName("barterResource[" + i + "]")
if (!barterResource)
{
warn("Current GUI limits prevent displaying more than " + i + " resources in the barter dialog!");
break;
}
// Barter:
barterOpenCommon(resCode, i, "barter");
setPanelObjectPosition(barterResource, i, i+1);
// Trade:
let tradeResource = Engine.GetGUIObjectByName("tradeResource["+i+"]");
if (!tradeResource)
{
warn("Current GUI limits prevent displaying more than " + r + " resources in the trading goods selection dialog!");
warn("Current GUI limits prevent displaying more than " + i + " resources in the trading goods selection dialog!");
break;
}
setPanelObjectPosition(tradeResource, i, i+1);
let resCode = resCodes[i];
proba[resCode] = proba[resCode] || 0;
let icon = Engine.GetGUIObjectByName("tradeResourceIcon["+i+"]");
icon.sprite = "stretched:session/icons/resources/" + resCode + ".png";
@ -611,10 +643,12 @@ function openTrade()
"sel": Engine.GetGUIObjectByName("tradeResourceSelection["+i+"]")
};
proba[resCode] = proba[resCode] || 0;
let buttonResource = Engine.GetGUIObjectByName("tradeResourceButton["+i+"]");
buttonResource.enabled = controlsPlayer(g_ViewedPlayer);
buttonResource.onPress = (function(resource){
return function() {
buttonResource.onPress = (resource => {
return () => {
if (Engine.HotkeyIsPressed("session.fulltradeswap"))
{
for (let res of resCodes)
@ -622,39 +656,152 @@ function openTrade()
proba[resource] = 100;
Engine.PostNetworkCommand({"type": "set-trading-goods", "tradingGoods": proba});
}
selec = resource;
updateButtons();
currTradeSelection = resource;
updateTradeButtons();
};
})(resCode);
buttonUp.enabled = controlsPlayer(g_ViewedPlayer);
buttonUp.onPress = (function(resource){
return function() {
proba[resource] += Math.min(STEP, proba[selec]);
proba[selec] -= Math.min(STEP, proba[selec]);
buttonUp.onPress = (resource => {
return () => {
proba[resource] += Math.min(STEP, proba[currTradeSelection]);
proba[currTradeSelection] -= Math.min(STEP, proba[currTradeSelection]);
Engine.PostNetworkCommand({"type": "set-trading-goods", "tradingGoods": proba});
updateButtons();
updateTradeButtons();
};
})(resCode);
buttonDn.enabled = controlsPlayer(g_ViewedPlayer);
buttonDn.onPress = (function(resource){
return function() {
proba[selec] += Math.min(STEP, proba[resource]);
buttonDn.onPress = (resource => {
return () => {
proba[currTradeSelection] += Math.min(STEP, proba[resource]);
proba[resource] -= Math.min(STEP, proba[resource]);
Engine.PostNetworkCommand({"type": "set-trading-goods", "tradingGoods": proba});
updateButtons();
updateTradeButtons();
};
})(resCode);
}
updateButtons();
let traderNumber = Engine.GuiInterfaceCall("GetTraderNumber", g_ViewedPlayer);
Engine.GetGUIObjectByName("landTraders").caption = getIdleLandTradersText(traderNumber);
Engine.GetGUIObjectByName("shipTraders").caption = getIdleShipTradersText(traderNumber);
updateTradeButtons();
updateTraderTexts();
Engine.GetGUIObjectByName("tradeDialogPanel").hidden = false;
}
function updateTraderTexts()
{
let traderNumber = Engine.GuiInterfaceCall("GetTraderNumber", g_ViewedPlayer);
Engine.GetGUIObjectByName("traderCountText").caption = getIdleLandTradersText(traderNumber) + "\n\n" + getIdleShipTradersText(traderNumber);
}
/**
* Code common to both the Barter Panel and the Trade/Barter Dialog, that
* only needs to be run when the panel or dialog is opened by the player.
*
* @param {string} resourceCode
* @param {number} idx - Element index within its set
* @param {string} prefix - Common prefix of the gui elements to be worked upon
*/
function barterOpenCommon(resourceCode, idx, prefix)
{
let barterButton = {};
for (let action of g_BarterActions)
barterButton[action] = Engine.GetGUIObjectByName(prefix + action + "Button[" + idx + "]");
let resource = getLocalizedResourceName(g_ResourceData.GetNames()[resourceCode], "withinSentence");
barterButton.Buy.tooltip = sprintf(translate("Buy %(resource)s"), { "resource": resource });
barterButton.Sell.tooltip = sprintf(translate("Sell %(resource)s"), { "resource": resource });
barterButton.Sell.onPress = function() {
g_BarterSell = resourceCode;
updateSelectionDetails();
updateBarterButtons();
};
}
/**
* Code common to both the Barter Panel and the Trade/Barter Dialog, that
* needs to be run on simulation update and when relevant hotkeys
* (i.e. massbarter) are pressed.
*
* @param {string} resourceCode
* @param {number} idx - Element index within its set
* @param {string} prefix - Common prefix of the gui elements to be worked upon
* @param {number} player
*/
function barterUpdateCommon(resourceCode, idx, prefix, player)
{
let barterButton = {};
let barterIcon = {};
let barterAmount = {};
for (let action of g_BarterActions)
{
barterButton[action] = Engine.GetGUIObjectByName(prefix + action + "Button[" + idx + "]");
barterIcon[action] = Engine.GetGUIObjectByName(prefix + action + "Icon[" + idx + "]");
barterAmount[action] = Engine.GetGUIObjectByName(prefix + action + "Amount[" + idx + "]");
}
let selectionIcon = Engine.GetGUIObjectByName(prefix + "SellSelection[" + idx + "]");
let amountToSell = g_BarterResourceSellQuantity;
if (Engine.HotkeyIsPressed("session.massbarter"))
amountToSell *= g_BarterMultiplier;
let isSelected = resourceCode == g_BarterSell;
let grayscale = isSelected ? "color:0 0 0 100:grayscale:" : "";
// Select color of the sell button
let neededRes = {};
neededRes[resourceCode] = amountToSell;
let canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", {
"cost": neededRes,
"player": player
}) ? "color:255 0 0 80:" : "";
// Select color of the buy button
neededRes = {};
neededRes[g_BarterSell] = amountToSell;
let canBuyAny = Engine.GuiInterfaceCall("GetNeededResources", {
"cost": neededRes,
"player": player
}) ? "color:255 0 0 80:" : "";
barterIcon.Sell.sprite = canSellCurrent + "stretched:" + grayscale + "session/icons/resources/" + resourceCode + ".png";
barterIcon.Buy.sprite = canBuyAny + "stretched:" + grayscale + "session/icons/resources/" + resourceCode + ".png";
barterAmount.Sell.caption = "-" + amountToSell;
let prices = GetSimState().barterPrices;
barterAmount.Buy.caption = "+" + Math.round(prices.sell[g_BarterSell] / prices.buy[resourceCode] * amountToSell);
barterButton.Buy.onPress = function() {
Engine.PostNetworkCommand({
"type": "barter",
"sell": g_BarterSell,
"buy": resourceCode,
"amount": amountToSell
});
};
barterButton.Buy.hidden = isSelected;
barterButton.Buy.enabled = controlsPlayer(player);
barterButton.Sell.hidden = false;
selectionIcon.hidden = !isSelected;
}
function updateBarterButtons()
{
let canBarter = GetSimState().players[g_ViewedPlayer].canBarter;
Engine.GetGUIObjectByName("barterNoMarketsMessage").hidden = canBarter;
Engine.GetGUIObjectByName("barterResources").hidden = !canBarter;
Engine.GetGUIObjectByName("barterHelp").hidden = !canBarter;
if (!canBarter)
return;
let resCodes = g_ResourceData.GetCodes();
for (let i = 0; i < resCodes.length; ++i)
barterUpdateCommon(resCodes[i], i, "barter", g_ViewedPlayer);
}
function getIdleLandTradersText(traderNumber)
{
let active = traderNumber.landTrader.trading;

View File

@ -33,8 +33,6 @@ let g_FormationsInfo = new Map();
let g_SelectionPanels = {};
let g_BarterSell;
g_SelectionPanels.Alert = {
"getMaxNumberOfItems": function()
{
@ -104,86 +102,19 @@ g_SelectionPanels.Barter = {
"conflictsWith": ["Alert", "Garrison"],
"getItems": function(unitEntStates)
{
if (unitEntStates.every(state => !state.barterMarket))
// If more than `rowLength` resources, don't display icons.
if (unitEntStates.every(state => !state.isBarterMarket) || g_ResourceData.GetCodes().length > this.rowLength)
return [];
return g_ResourceData.GetCodes();
},
"setupButton": function(data)
{
// data.item is the resource name in this case
barterOpenCommon(data.item, data.i, "unitBarter");
barterUpdateCommon(data.item, data.i, "unitBarter", data.player);
let button = {};
let icon = {};
let amount = {};
for (let a of BARTER_ACTIONS)
{
button[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Button[" + data.i + "]");
icon[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Icon[" + data.i + "]");
amount[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Amount[" + data.i + "]");
}
let selectionIcon = Engine.GetGUIObjectByName("unitBarterSellSelection[" + data.i + "]");
let amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL;
if (Engine.HotkeyIsPressed("session.massbarter"))
amountToSell *= BARTER_BUNCH_MULTIPLIER;
if (!g_BarterSell)
g_BarterSell = g_ResourceData.GetCodes()[0];
amount.Sell.caption = "-" + amountToSell;
let prices;
for (let state of data.unitEntStates)
if (state.barterMarket)
{
prices = state.barterMarket.prices;
break;
}
amount.Buy.caption = "+" + Math.round(prices.sell[g_BarterSell] / prices.buy[data.item] * amountToSell);
let resource = getLocalizedResourceName(g_ResourceData.GetNames()[data.item], "withinSentence");
button.Buy.tooltip = sprintf(translate("Buy %(resource)s"), { "resource": resource });
button.Sell.tooltip = sprintf(translate("Sell %(resource)s"), { "resource": resource });
button.Sell.onPress = function() {
g_BarterSell = data.item;
updateSelectionDetails();
};
button.Buy.onPress = function() {
Engine.PostNetworkCommand({
"type": "barter",
"sell": g_BarterSell,
"buy": data.item,
"amount": amountToSell
});
};
let isSelected = data.item == g_BarterSell;
let grayscale = isSelected ? "color: 0 0 0 100:grayscale:" : "";
// do we have enough of this resource to sell?
let neededRes = {};
neededRes[data.item] = amountToSell;
let canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", {
"cost": neededRes,
"player": data.player
}) ? "color:255 0 0 80:" : "";
// Let's see if we have enough resources to barter.
neededRes = {};
neededRes[g_BarterSell] = amountToSell;
let canBuyAny = Engine.GuiInterfaceCall("GetNeededResources", {
"cost": neededRes,
"player": data.player
}) ? "color:255 0 0 80:" : "";
icon.Sell.sprite = canSellCurrent + "stretched:" + grayscale + "session/icons/resources/" + data.item + ".png";
icon.Buy.sprite = canBuyAny + "stretched:" + grayscale + "session/icons/resources/" + data.item + ".png";
button.Buy.hidden = isSelected;
button.Buy.enabled = controlsPlayer(data.player);
button.Sell.hidden = false;
selectionIcon.hidden = !isSelected;
for (let action of g_BarterActions)
button[action] = Engine.GetGUIObjectByName("unitBarter" + action + "Button[" + data.i + "]");
setPanelObjectPosition(button.Sell, data.i, data.rowLength);
setPanelObjectPosition(button.Buy, data.i + data.rowLength, data.rowLength);

View File

@ -1,6 +1,3 @@
const BARTER_RESOURCE_AMOUNT_TO_SELL = 100;
const BARTER_BUNCH_MULTIPLIER = 5;
const BARTER_ACTIONS = ["Sell", "Buy"];
const GATE_ACTIONS = ["lock", "unlock"];
const UPGRADING_NOT_STARTED = -2;

View File

@ -271,6 +271,8 @@ function init(initData, hotloadData)
g_CivData = loadCivData();
g_CivData.gaia = { "Code": "gaia", "Name": translate("Gaia") };
g_BarterSell = g_ResourceData.GetCodes()[0];
initializeMusic(); // before changing the perspective
let gameSpeed = Engine.GetGUIObjectByName("gameSpeed");
@ -398,6 +400,13 @@ function updateHotkeyTooltips()
Engine.GetGUIObjectByName("tradeHelp").tooltip = colorizeHotkey(
translate("Select one type of goods you want to modify by clicking on it (Pressing %(hotkey)s while selecting will also bring its share to 100%%) and then use the arrows of the other types to modify their shares."),
"session.fulltradeswap");
Engine.GetGUIObjectByName("barterHelp").tooltip = sprintf(
translate("Start by selecting the resource from the upper row that you wish to sell. Upon each press on one of the lower buttons, %(quantity)s of the upper resource will be sold for the displayed quantity of the lower. Press and hold %(hotkey)s to temporarily multiply all quantities by %(multiplier)s."), {
"quantity": g_BarterResourceSellQuantity,
"hotkey": colorizeHotkey("%(hotkey)s", "session.massbarter"),
"multiplier": g_BarterMultiplier
});
}
function initGUIHeroes(slot)
@ -833,6 +842,12 @@ function updateGUIObjects()
updateTimeNotifications();
updateIdleWorkerButton();
if (g_IsTradeOpen)
{
updateTraderTexts();
updateBarterButtons();
}
if (g_ViewedPlayer > 0)
{
let playerState = GetSimState().players[g_ViewedPlayer];

View File

@ -5,9 +5,8 @@
style="iconButton"
tooltip_style="sessionToolTip"
>
<!-- TODO make the button less ugly -->
<object size="0 0 100% 100%" name="tradeButtonImage" type="image" sprite="stretched:session/icons/economics.png" ghost="true"/>
<translatableAttribute id="tooltip">Trade</translatableAttribute>
<translatableAttribute id="tooltip">Barter &amp; Trade</translatableAttribute>
<action on="Press">
toggleTrade();
</action>

View File

@ -1,48 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<object name="tradeDialogPanel"
size="50%-134 50%-130 50%+134 50%+100"
size="50%-80 50%-280 50%+80 50%+136"
type="image"
hidden="true"
sprite="ModernDialog"
>
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">
<translatableAttribute id="caption">Trade</translatableAttribute>
<object type="text" size="50%-96 -16 50%+96 16" style="TitleText">
<translatableAttribute id="caption">Barter &amp; Trade Goods</translatableAttribute>
</object>
<!-- Barter Goods -->
<object size="24 24 100%-24 33%">
<object type="text" size="8 0 100% 32" style="ModernLeftLabelText">
<translatableAttribute id="caption">Barter</translatableAttribute>
</object>
<object type="image" size="0 28 100% 29" sprite="ModernGoldLine"/>
<object size="0 38 100% 122">
<object type="text" size="0 0 60 41" style="ModernRightLabelText">
<translatableAttribute id="caption">Sell:</translatableAttribute>
</object>
<object type="text" size="0 100%-41 60 100%" style="ModernRightLabelText">
<translatableAttribute id="caption">Buy:</translatableAttribute>
</object>
<object name="barterNoMarketsMessage" type="text" size="72 0 100% 100%" style="ModernLabelText">
<translatableAttribute id="caption">No Markets Available</translatableAttribute>
</object>
<object name="barterResources" size="72 0 100% 100%">
<repeat count="10">
<object name="barterResource[n]" size="0 0 58 100%">
<!-- Sell -->
<object name="barterSellButton[n]" type="button" size="0 0 41 41" style="iconButton" tooltip_style="sessionToolTipBottomBold" hidden="true">
<object name="barterSellIcon[n]" type="image" size="3 3 100%-3 100%-3" ghost="true"/>
<object name="barterSellAmount[n]" type="text" size="0 0 100% 50%" style="resourceText" ghost="true"/>
<object name="barterSellSelection[n]" type="image" size="3 3 100%-3 100%-3" sprite="stretched:session/icons/corners.png" hidden="true" ghost="true"/>
</object>
<!-- Buy -->
<object name="barterBuyButton[n]" type="button" size="0 100%-41 41 100%" style="iconButton" tooltip_style="sessionToolTipBottomBold" hidden="true">
<object name="barterBuyIcon[n]" type="image" size="3 3 100%-3 100%-3" ghost="true"/>
<object name="barterBuyAmount[n]" type="text" size="0 0 100% 50%" style="resourceText" ghost="true"/>
</object>
</object>
</repeat>
</object>
<object name="barterHelp" type="button" size="100%-24 50%-12 100% 50%+12" style="StoneButton" tooltip_style="sessionToolTipBold" enabled="false">
<object type="image" size="20% 15% 80% 75%" sprite="iconInfoWhite" ghost="true"/>
</object>
</object>
</object>
<!-- Trading goods -->
<object name="tradeGoods" size="20 50 100%-20 82">
<object name="tradeHeader" size="0 0 180 100%" type="text" style="ModernLabelText" text_align="left" ghost="true">
<translatableAttribute id="caption">Trading goods selection:</translatableAttribute>
</object>
<object size="24 33%+32 100%-24 100%-64">
<object size="180 0 100% 100%" name="tradeResources">
<repeat count="8">
<object name="tradeResource[n]" size="0 0 58 32">
<object name="tradeResourceButton[n]" size="4 0 36 100%" type="button" style="StoneButton">
<object name="tradeResourceIcon[n]" type="image" ghost="true"/>
<object name="tradeResourceSelection[n]" type="image" sprite="stretched:session/icons/corners.png" ghost="true"/>
<object name="tradeResourceText[n]" type="text" style="ModernLabelText" ghost="true"/>
</object>
<object name="tradeArrowUp[n]" size="36 0 52 50%" type="button" style="iconButton">
<object type="image" ghost="true" sprite="StoneArrowUp"/>
</object>
<object name="tradeArrowDn[n]" size="36 50% 52 100%" type="button" style="iconButton">
<object type="image" ghost="true" sprite="StoneArrowDn"/>
</object>
</object>
</repeat>
<object name="tradeHelp" size="100%-24 4 100% 28" enabled="false" type="button" style="StoneButton" tooltip_style="sessionToolTipBold">
<object size="20% 15% 80% 75%" type="image" ghost="true" sprite="iconInfoWhite"/>
<object type="text" size="8 0 100% 32" style="ModernLeftLabelText">
<translatableAttribute id="caption">Trade</translatableAttribute>
</object>
<object type="image" size="0 28 100% 29" sprite="ModernGoldLine"/>
<object name="tradeGoods" size="0 38 100% 70">
<object type="text" size="0 0 60 100%" style="ModernRightLabelText">
<!-- Translation: Used in the Trade Dialog -->
<translatableAttribute id="caption">Goods:</translatableAttribute>
</object>
<object name="tradeResources" size="72 0 100% 100%">
<repeat count="8">
<object name="tradeResource[n]" size="0 0 58 32">
<object name="tradeResourceButton[n]" type="button" size="4 0 36 100%" style="StoneButton">
<object name="tradeResourceIcon[n]" type="image" ghost="true"/>
<object name="tradeResourceSelection[n]" type="image" sprite="stretched:session/icons/corners.png" ghost="true"/>
<object name="tradeResourceText[n]" type="text" style="ModernLabelText" ghost="true"/>
</object>
<object name="tradeArrowUp[n]" type="button" size="36 0 52 50%" style="iconButton">
<object type="image" sprite="StoneArrowUp" ghost="true"/>
</object>
<object name="tradeArrowDn[n]" type="button" size="36 50% 52 100%" style="iconButton">
<object type="image" sprite="StoneArrowDn" ghost="true"/>
</object>
</object>
</repeat>
</object>
<object name="tradeHelp" type="button" size="100%-24 4 100% 28" style="StoneButton" tooltip_style="sessionToolTipBold" enabled="false">
<object type="image" size="20% 15% 80% 75%" sprite="iconInfoWhite" ghost="true"/>
</object>
</object>
<object name="traderCountText" type="text" size="8 88 100% 100%" style="ModernLeftTabLabelText"/>
</object>
<object name="tradeStatistics" size="20 90 100%-20 168">
<object name="landTraders" size="0 0 100% 50%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
<object name="shipTraders" size="0 50% 100% 100%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
</object>
<object size="50%-64 100%-50 50%+64 100%-22" type="button" style="StoneButton">
<object type="button" size="50%-64 100%-50 50%+64 100%-22" style="StoneButton">
<translatableAttribute id="caption">Close</translatableAttribute>
<action on="Press">closeTrade();</action>
</object>

View File

@ -1260,7 +1260,7 @@ var g_EntityCommands =
return false;
return {
"tooltip": translate("Select trading goods"),
"tooltip": translate("Barter & Trade"),
"icon": "economics.png"
};
},

View File

@ -121,7 +121,8 @@ GuiInterface.prototype.GetSimulationState = function()
"researchStarted": cmpTechnologyManager ? cmpTechnologyManager.GetStartedResearch() : null,
"researchedTechs": cmpTechnologyManager ? cmpTechnologyManager.GetResearchedTechs() : null,
"classCounts": cmpTechnologyManager ? cmpTechnologyManager.GetClassCounts() : null,
"typeCountsByClass": cmpTechnologyManager ? cmpTechnologyManager.GetTypeCountsByClass() : null
"typeCountsByClass": cmpTechnologyManager ? cmpTechnologyManager.GetTypeCountsByClass() : null,
"canBarter": Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter).PlayerHasMarket(playerEnt)
});
}
@ -150,9 +151,7 @@ GuiInterface.prototype.GetSimulationState = function()
ret.gameType = cmpEndGameManager.GetGameType();
ret.alliedVictory = cmpEndGameManager.GetAlliedVictory();
// Add bartering prices
let cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter);
ret.barterPrices = cmpBarter.GetPrices();
ret.barterPrices = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter).GetPrices();
// Add Resource Codes, untranslated names and AI Analysis
ret.resources = {
@ -424,9 +423,9 @@ GuiInterface.prototype.GetExtendedEntityState = function(player, ent)
let ret = {
"armour": null,
"attack": null,
"barterMarket": null,
"buildingAI": null,
"heal": null,
"isBarterMarket": null,
"loot": null,
"obstruction": null,
"turretParent":null,
@ -561,10 +560,7 @@ GuiInterface.prototype.GetExtendedEntityState = function(player, ent)
};
if (!cmpFoundation && cmpIdentity && cmpIdentity.HasClass("BarterMarket"))
{
let cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter);
ret.barterMarket = { "prices": cmpBarter.GetPrices() };
}
ret.isBarterMarket = true;
let cmpHeal = Engine.QueryInterface(ent, IID_Heal);
if (cmpHeal)

View File

@ -58,7 +58,8 @@ AddMock(SYSTEM_ENTITY, IID_Barter, {
"buy": { "food": 150 },
"sell": { "food": 25 }
};
}
},
PlayerHasMarket: function () { return false; }
});
AddMock(SYSTEM_ENTITY, IID_EndGameManager, {
@ -293,6 +294,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
researchedTechs: {},
classCounts: {},
typeCountsByClass: {},
canBarter: false,
statistics: {
resourcesGathered: {
food: 100,
@ -336,6 +338,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
researchedTechs: {},
classCounts: {},
typeCountsByClass: {},
canBarter: false,
statistics: {
resourcesGathered: {
food: 100,
@ -407,6 +410,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
researchedTechs: {},
classCounts: {},
typeCountsByClass: {},
canBarter: false,
statistics: {
unitsTrained: 10,
unitsLost: 9,
@ -463,6 +467,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
researchedTechs: {},
classCounts: {},
typeCountsByClass: {},
canBarter: false,
statistics: {
unitsTrained: 10,
unitsLost: 9,
@ -591,11 +596,9 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetEntityState(-1, 10), {
TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedEntityState(-1, 10), {
armour: null,
attack: null,
barterMarket: {
prices: { "buy": {"food":150}, "sell": {"food":25} },
},
buildingAI: null,
heal: null,
isBarterMarket: true,
loot: null,
obstruction: null,
turretParent: null,