1
0
forked from mirrors/0ad

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
+5 -2
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
@@ -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? -->
+176 -29
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;
@@ -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);
@@ -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;
@@ -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];
@@ -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>
@@ -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>
@@ -1260,7 +1260,7 @@ var g_EntityCommands =
return false;
return {
"tooltip": translate("Select trading goods"),
"tooltip": translate("Barter & Trade"),
"icon": "economics.png"
};
},
@@ -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)
@@ -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,