Ticket #4366: 4366_barterUI_v1-3.patch

File 4366_barterUI_v1-3.patch, 23.2 KB (added by s0600204, 2 years ago)

Updated patch, please see comment #15 for details.

  • binaries/data/config/default.cfg

    diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
    index 47f8528cf..b31e6467e 100644
    a b console.toggle = BackQuote, F9 ; Open/close console 
    157157fps.toggle = "Alt+F"                  ; Toggle frame counter
    158158realtime.toggle = "Alt+T"             ; Toggle current display of computer time
    159159session.devcommands.toggle = "Alt+D"  ; Toggle developer commands panel
    160 session.gui.toggle = "Alt+G"          ; Toggle visibility of session GUI
    161 menu.toggle = "F10"                   ; Toggle in-game menu
    162160timeelapsedcounter.toggle = "F12"     ; Toggle time elapsed counter
    163161session.showstatusbars = Tab          ; Toggle display of status bars
    164162session.highlightguarding = PgDn      ; Toggle highlight of guarding units
    deselectgroup = Ctrl ; Modifier to deselect units when clicking group ic 
    294292rotate.cw = RightBracket     ; Rotate building placement preview clockwise
    295293rotate.ccw = LeftBracket     ; Rotate building placement preview anticlockwise
    296294
     295[hotkey.session.gui]
     296toggle = "Alt+G"             ; Toggle visibility of session GUI
     297menu.toggle = "F10"          ; Toggle in-game menu
     298barter.toggle = "Ctrl+B"     ; Toggle in-game barter/trade page
     299
    297300[hotkey.session.savedgames]
    298301delete = Delete               ; Delete the selected saved game asking confirmation
    299302noconfirmation = Shift        ; Do not ask confirmation when deleting a game
  • binaries/data/mods/public/gui/session/hotkeys/misc.xml

    diff --git a/binaries/data/mods/public/gui/session/hotkeys/misc.xml b/binaries/data/mods/public/gui/session/hotkeys/misc.xml
    index 87844d24c..b9a40bea1 100644
    a b  
    1212        <action on="Press">openChat(true);</action>
    1313    </object>
    1414
    15     <object hotkey="menu.toggle">
     15    <object hotkey="session.gui.menu.toggle">
    1616        <action on="Press">toggleMenu();</action>
    1717    </object>
    1818
     19    <object hotkey="session.gui.barter.toggle">
     20        <action on="Press">toggleTrade();</action>
     21    </object>
     22
    1923    <object hotkey="silhouettes">
    2024        <action on="Press">
    2125            var newSetting = !Engine.Renderer_GetSilhouettesEnabled();
     
    6872    </object>
    6973
    7074    <object hotkey="session.massbarter">
    71         <action on="Press">updateSelectionDetails();</action>
    72         <action on="Release">updateSelectionDetails();</action>
     75        <action on="Press">
     76            updateSelectionDetails();
     77            updateBarterButtons();
     78        </action>
     79        <action on="Release">
     80            updateSelectionDetails();
     81            updateBarterButtons();
     82        </action>
    7383    </object>
    7484
    7585    <!-- Find idle warrior - TODO: Potentially move this to own UI button? -->
  • binaries/data/mods/public/gui/session/menu.js

    diff --git a/binaries/data/mods/public/gui/session/menu.js b/binaries/data/mods/public/gui/session/menu.js
    index 12f2a025e..985e95f9a 100644
    a b const STEP = 5; 
    2828// Shown in the trade dialog.
    2929const g_IdleTraderTextColor = "orange";
    3030
     31const BARTER_RESOURCE_AMOUNT_TO_SELL = 100;
     32const BARTER_BUNCH_MULTIPLIER = 5;
     33const BARTER_ACTIONS = ["Buy", "Sell"];
     34var g_BarterSell;
     35
    3136var g_IsMenuOpen = false;
    3237
    3338var g_IsDiplomacyOpen = false;
    function openTrade() 
    489494
    490495    g_IsTradeOpen = true;
    491496
    492     var updateButtons = function()
     497    let proba = Engine.GuiInterfaceCall("GetTradingGoods", g_ViewedPlayer);
     498    let button = {};
     499    let resCodes = g_ResourceData.GetCodes();
     500    let currTradeSelection = resCodes[0];
     501
     502    let updateTradeButtons = function()
    493503    {
    494504        for (let res in button)
    495505        {
    496506            button[res].label.caption = proba[res] + "%";
    497507
    498             button[res].sel.hidden = !controlsPlayer(g_ViewedPlayer) || res != selec;
    499             button[res].up.hidden = !controlsPlayer(g_ViewedPlayer) || res == selec || proba[res] == 100 || proba[selec] == 0;
    500             button[res].dn.hidden = !controlsPlayer(g_ViewedPlayer) || res == selec || proba[res] == 0 || proba[selec] == 100;
     508            button[res].sel.hidden = !controlsPlayer(g_ViewedPlayer) || res != currTradeSelection;
     509            button[res].up.hidden = !controlsPlayer(g_ViewedPlayer) || res == currTradeSelection || proba[res] == 100 || proba[currTradeSelection] == 0;
     510            button[res].dn.hidden = !controlsPlayer(g_ViewedPlayer) || res == currTradeSelection || proba[res] == 0 || proba[currTradeSelection] == 100;
    501511        }
    502512    };
    503513
    504     let proba = Engine.GuiInterfaceCall("GetTradingGoods", g_ViewedPlayer);
    505     let button = {};
    506     let resCodes = g_ResourceData.GetCodes();
    507     let selec = resCodes[0];
    508514    hideRemaining("tradeResources", resCodes.length);
    509515    Engine.GetGUIObjectByName("tradeHelp").hidden = false;
    510516
    511517    for (let i = 0; i < resCodes.length; ++i)
    512518    {
     519        let resCode = resCodes[i];
     520
     521        // Barter
     522        let barterButton = {};
     523        for (let action of BARTER_ACTIONS)
     524            barterButton[action] = Engine.GetGUIObjectByName("barter" + action + "Button[" + i + "]");
     525
     526        if (!g_BarterSell)
     527            g_BarterSell = g_ResourceData.GetCodes()[0];
     528
     529        let resource = getLocalizedResourceName(g_ResourceData.GetNames()[resCode], "withinSentence");
     530        barterButton.Buy.tooltip = sprintf(translate("Buy %(resource)s"), { "resource": resource });
     531        barterButton.Sell.tooltip = sprintf(translate("Sell %(resource)s"), { "resource": resource });
     532
     533        barterButton.Sell.onPress = function() {
     534            g_BarterSell = resCode;
     535            updateBarterButtons();
     536        };
     537
     538        setPanelObjectPosition(Engine.GetGUIObjectByName("barterResource[" + i + "]"), i, i+1);
     539
     540        // Trade
    513541        let tradeResource = Engine.GetGUIObjectByName("tradeResource["+i+"]");
    514542        if (!tradeResource)
    515543        {
    function openTrade() 
    519547
    520548        setPanelObjectPosition(tradeResource, i, i+1);
    521549
    522         let resCode = resCodes[i];
    523         proba[resCode] = proba[resCode] || 0;
    524 
    525550        let icon = Engine.GetGUIObjectByName("tradeResourceIcon["+i+"]");
    526551        icon.sprite = "stretched:session/icons/resources/" + resCode + ".png";
    527552
    function openTrade() 
    535560            "sel": Engine.GetGUIObjectByName("tradeResourceSelection["+i+"]")
    536561        };
    537562
     563        proba[resCode] = proba[resCode] || 0;
     564
    538565        let buttonResource = Engine.GetGUIObjectByName("tradeResourceButton["+i+"]");
    539566        buttonResource.enabled = controlsPlayer(g_ViewedPlayer);
    540         buttonResource.onpress = (function(resource){
     567        buttonResource.onPress = (function(resource){
    541568            return function() {
    542569                if (Engine.HotkeyIsPressed("session.fulltradeswap"))
    543570                {
    function openTrade() 
    546573                    proba[resource] = 100;
    547574                    Engine.PostNetworkCommand({"type": "set-trading-goods", "tradingGoods": proba});
    548575                }
    549                 selec = resource;
    550                 updateButtons();
     576                currTradeSelection = resource;
     577                updateTradeButtons();
    551578            };
    552579        })(resCode);
    553580
    554581        buttonUp.enabled = controlsPlayer(g_ViewedPlayer);
    555         buttonUp.onpress = (function(resource){
     582        buttonUp.onPress = (function(resource){
    556583            return function() {
    557                 proba[resource] += Math.min(STEP, proba[selec]);
    558                 proba[selec]    -= Math.min(STEP, proba[selec]);
     584                proba[resource] += Math.min(STEP, proba[currTradeSelection]);
     585                proba[currTradeSelection] -= Math.min(STEP, proba[currTradeSelection]);
    559586                Engine.PostNetworkCommand({"type": "set-trading-goods", "tradingGoods": proba});
    560                 updateButtons();
     587                updateTradeButtons();
    561588            };
    562589        })(resCode);
    563590
    564591        buttonDn.enabled = controlsPlayer(g_ViewedPlayer);
    565         buttonDn.onpress = (function(resource){
     592        buttonDn.onPress = (function(resource){
    566593            return function() {
    567                 proba[selec]    += Math.min(STEP, proba[resource]);
     594                proba[currTradeSelection] += Math.min(STEP, proba[resource]);
    568595                proba[resource] -= Math.min(STEP, proba[resource]);
    569596                Engine.PostNetworkCommand({"type": "set-trading-goods", "tradingGoods": proba});
    570                 updateButtons();
     597                updateTradeButtons();
    571598            };
    572599        })(resCode);
    573600    }
    574     updateButtons();
     601    updateTradeButtons();
    575602
    576603    let traderNumber = Engine.GuiInterfaceCall("GetTraderNumber", g_ViewedPlayer);
    577     Engine.GetGUIObjectByName("landTraders").caption = getIdleLandTradersText(traderNumber);
    578     Engine.GetGUIObjectByName("shipTraders").caption = getIdleShipTradersText(traderNumber);
     604    Engine.GetGUIObjectByName("traders").caption = getIdleLandTradersText(traderNumber) + "\n\n" + getIdleShipTradersText(traderNumber);
    579605    Engine.GetGUIObjectByName("tradeDialogPanel").hidden = false;
    580606}
    581607
     608function updateBarterButtons()
     609{
     610    let resCodes = g_ResourceData.GetCodes();
     611    if (!g_BarterSell)
     612        g_BarterSell = resCodes[0];
     613
     614    let canBarter = Engine.GuiInterfaceCall("PlayerCanBarter", g_ViewedPlayer);
     615    Engine.GetGUIObjectByName("barterNoMarketsMessage").hidden = canBarter;
     616    Engine.GetGUIObjectByName("barterResources").hidden = !canBarter;
     617    if (!canBarter)
     618        return;
     619
     620    for (let i = 0; i < resCodes.length; ++i)
     621    {
     622        let resCode = resCodes[i];
     623        let barterButton = {};
     624        let barterIcon = {};
     625        let barterAmount = {};
     626        for (let action of BARTER_ACTIONS)
     627        {
     628            barterButton[action] = Engine.GetGUIObjectByName("barter" + action + "Button[" + i + "]");
     629            barterIcon[action] = Engine.GetGUIObjectByName("barter" + action + "Icon[" + i + "]");
     630            barterAmount[action] = Engine.GetGUIObjectByName("barter" + action + "Amount[" + i + "]");
     631        }
     632        let selectionIcon = Engine.GetGUIObjectByName("barterSellSelection[" + i + "]");
     633
     634        let amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL;
     635        if (Engine.HotkeyIsPressed("session.massbarter"))
     636            amountToSell *= BARTER_BUNCH_MULTIPLIER;
     637
     638        let isSelected = resCode == g_BarterSell;
     639        let grayscale = isSelected ? "color:0 0 0 100:grayscale:" : "";
     640
     641        // Do we have enough of this resource to sell?
     642        let neededRes = {};
     643        neededRes[resCode] = amountToSell;
     644        let canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", {
     645            "cost": neededRes,
     646            "player": g_ViewedPlayer
     647        }) ? "color:255 0 0 80:" : "";
     648
     649        // Let's see if we have enough resources to barter.
     650        neededRes = {};
     651        neededRes[g_BarterSell] = amountToSell;
     652        let canBuyAny = Engine.GuiInterfaceCall("GetNeededResources", {
     653            "cost": neededRes,
     654            "player": g_ViewedPlayer
     655        }) ? "color:255 0 0 80:" : "";
     656
     657        barterIcon.Sell.sprite = canSellCurrent + "stretched:" + grayscale + "session/icons/resources/" + resCode + ".png";
     658        barterIcon.Buy.sprite = canBuyAny + "stretched:" + grayscale + "session/icons/resources/" + resCode + ".png";
     659
     660        barterAmount.Sell.caption = "-" + amountToSell;
     661        let prices = Engine.GuiInterfaceCall("GetBarterPrices");
     662        barterAmount.Buy.caption = "+" + Math.round(prices.sell[g_BarterSell] / prices.buy[resCode] * amountToSell);
     663
     664        barterButton.Buy.onPress = function() {
     665            Engine.PostNetworkCommand({
     666                "type": "barter",
     667                "sell": g_BarterSell,
     668                "buy": resCode,
     669                "amount": amountToSell
     670            });
     671        };
     672
     673        barterButton.Buy.hidden = isSelected;
     674        barterButton.Buy.enabled = controlsPlayer(g_ViewedPlayer);
     675        barterButton.Sell.hidden = false;
     676        selectionIcon.hidden = !isSelected;
     677    }
     678};
     679
    582680function getIdleLandTradersText(traderNumber)
    583681{
    584682    let active = traderNumber.landTrader.trading;
  • binaries/data/mods/public/gui/session/selection_panels.js

    diff --git a/binaries/data/mods/public/gui/session/selection_panels.js b/binaries/data/mods/public/gui/session/selection_panels.js
    index 6bc6e12be..da353a173 100644
    a b let g_FormationsInfo = new Map(); 
    3333
    3434let g_SelectionPanels = {};
    3535
    36 let g_BarterSell;
    37 
    3836g_SelectionPanels.Alert = {
    3937    "getMaxNumberOfItems": function()
    4038    {
    g_SelectionPanels.Barter = { 
    110108    },
    111109    "setupButton": function(data)
    112110    {
     111        // If more than four resources, don't display icons here at all
     112        if (g_ResourceData.GetCodes().length > this.rowLength)
     113            return;
     114
    113115        // data.item is the resource name in this case
    114116        let button = {};
    115117        let icon = {};
    116118        let amount = {};
    117         for (let a of BARTER_ACTIONS)
     119        for (let action of BARTER_ACTIONS)
    118120        {
    119             button[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Button[" + data.i + "]");
    120             icon[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Icon[" + data.i + "]");
    121             amount[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Amount[" + data.i + "]");
     121            button[action] = Engine.GetGUIObjectByName("unitBarter" + action + "Button[" + data.i + "]");
     122            icon[action] = Engine.GetGUIObjectByName("unitBarter" + action + "Icon[" + data.i + "]");
     123            amount[action] = Engine.GetGUIObjectByName("unitBarter" + action + "Amount[" + data.i + "]");
    122124        }
    123125        let selectionIcon = Engine.GetGUIObjectByName("unitBarterSellSelection[" + data.i + "]");
    124126
    g_SelectionPanels.Barter = { 
    159161        };
    160162
    161163        let isSelected = data.item == g_BarterSell;
    162         let grayscale = isSelected ? "color: 0 0 0 100:grayscale:" : "";
     164        let grayscale = isSelected ? "color:0 0 0 100:grayscale:" : "";
    163165
    164         // do we have enough of this resource to sell?
     166        // Do we have enough of this resource to sell?
    165167        let neededRes = {};
    166168        neededRes[data.item] = amountToSell;
    167169        let canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", {
    g_SelectionPanels.Upgrade = { 
    12171219 */
    12181220let g_PanelsOrder = [
    12191221    // LEFT PANE
    1220     "Barter", // Must always be visible on markets
     1222    "Barter", // Must always be visible on markets, if less than five resources
    12211223    "Garrison", // More important than Formation, as you want to see the garrisoned units in ships
    12221224    "Alert",
    12231225    "Formation",
  • binaries/data/mods/public/gui/session/selection_panels_helpers.js

    diff --git a/binaries/data/mods/public/gui/session/selection_panels_helpers.js b/binaries/data/mods/public/gui/session/selection_panels_helpers.js
    index 6b9f507d6..e5b1f0354 100644
    a b  
    1 const BARTER_RESOURCE_AMOUNT_TO_SELL = 100;
    2 const BARTER_BUNCH_MULTIPLIER = 5;
    3 const BARTER_ACTIONS = ["Sell", "Buy"];
    41const GATE_ACTIONS = ["lock", "unlock"];
    52
    63const UPGRADING_NOT_STARTED = -2;
  • binaries/data/mods/public/gui/session/session.js

    diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js
    index e2b43aae5..469ede741 100644
    a b function updateGUIObjects() 
    768768    updateBuildingPlacementPreview();
    769769    updateTimeNotifications();
    770770    updateIdleWorkerButton();
     771    updateBarterButtons();
    771772
    772773    if (g_ViewedPlayer > 0)
    773774    {
  • binaries/data/mods/public/gui/session/top_panel/button_trade.xml

    diff --git a/binaries/data/mods/public/gui/session/top_panel/button_trade.xml b/binaries/data/mods/public/gui/session/top_panel/button_trade.xml
    index 787c1f760..6f59e92aa 100644
    a b  
    77>
    88    <!-- TODO make the button less ugly -->
    99    <object size="0 0 100% 100%" name="tradeButtonImage" type="image" sprite="stretched:session/icons/economics.png" ghost="true"/>
    10     <translatableAttribute id="tooltip">Trade</translatableAttribute>
     10    <translatableAttribute id="tooltip">Barter &amp; Trade</translatableAttribute>
    1111    <action on="Press">
    1212        toggleTrade();
    1313    </action>
  • binaries/data/mods/public/gui/session/trade_window.xml

    diff --git a/binaries/data/mods/public/gui/session/trade_window.xml b/binaries/data/mods/public/gui/session/trade_window.xml
    index 537eac505..f4d0d66de 100644
    a b  
    11<?xml version="1.0" encoding="utf-8"?>
    22<object name="tradeDialogPanel"
    3     size="50%-134 50%-130 50%+134 50%+100"
     3    size="50%-80 50%-280 50%+80 50%+136"
    44    type="image"
    55    hidden="true"
    66    sprite="ModernDialog"
     7    z="100"
    78>
    89    <object type="text" style="TitleText" size="50%-96 -16 50%+96 16">
    9         <translatableAttribute id="caption">Trade</translatableAttribute>
     10        <translatableAttribute id="caption">Barter &amp; Trade Goods</translatableAttribute>
    1011    </object>
    1112
    12     <!-- Trading goods -->
    13     <object name="tradeGoods" size="20 50 100%-20 82">
    14         <object name="tradeHeader" size="0 0 180 100%" type="text" style="ModernLabelText" text_align="left" ghost="true">
    15             <translatableAttribute id="caption">Trading goods selection:</translatableAttribute>
     13
     14    <!-- Barter Goods -->
     15    <object size="24 24 100%-24 33%">
     16
     17        <object name="barterHeader" size="8 0 100% 32" type="text" style="ModernLeftLabelText">
     18            <translatableAttribute id="caption">Barter</translatableAttribute>
    1619        </object>
     20        <object size="0 28 100% 29" type="image" sprite="ModernGoldLine"/>
     21
     22        <object size="0 38 100% 122">
     23
     24            <object size="0 0 60 41" type="text" style="ModernRightLabelText">
     25                <translatableAttribute id="caption">Sell:</translatableAttribute>
     26            </object>
     27
     28            <object size="0 100%-41 60 100%" type="text" style="ModernRightLabelText">
     29                <translatableAttribute id="caption">Buy:</translatableAttribute>
     30            </object>
     31
     32            <object size="72 0 100% 100%" type="text" style="ModernLabelText" name="barterNoMarketsMessage">
     33                <translatableAttribute id="caption">No Markets Available</translatableAttribute>
     34            </object>
     35
     36            <object name="barterResources" size="72 0 100% 100%">
     37                <repeat count="8">
     38                    <object name="barterResource[n]" size="0 0 58 100%">
     39
     40                        <!-- Sell -->
     41                        <object name="barterSellButton[n]" style="iconButton" type="button" size="0 0 41 41" tooltip_style="sessionToolTipBottomBold" hidden="true">
     42                            <object name="barterSellIcon[n]" type="image" ghost="true" size="3 3 100%-3 100%-3"/>
     43                            <object name="barterSellAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/>
     44                            <object name="barterSellSelection[n]" hidden="true" type="image" ghost="true" size="3 3 100%-3 100%-3" sprite="stretched:session/icons/corners.png"/>
     45                        </object>
     46
     47                        <!-- Buy -->
     48                        <object name="barterBuyButton[n]" style="iconButton" type="button" size="0 100%-41 41 100%" tooltip_style="sessionToolTipBottomBold" hidden="true">
     49                            <object name="barterBuyIcon[n]" type="image" ghost="true" size="3 3 100%-3 100%-3"/>
     50                            <object name="barterBuyAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/>
     51                        </object>
    1752
    18         <object size="180 0 100% 100%" name="tradeResources">
    19             <repeat count="8">
    20                 <object name="tradeResource[n]" size="0 0 58 32">
    21                     <object name="tradeResourceButton[n]" size="4 0 36 100%" type="button" style="StoneButton">
    22                         <object name="tradeResourceIcon[n]" type="image" ghost="true"/>
    23                         <object name="tradeResourceSelection[n]" type="image" sprite="stretched:session/icons/corners.png" ghost="true"/>
    24                         <object name="tradeResourceText[n]" type="text" style="ModernLabelText" ghost="true"/>
    25                     </object>
    26                     <object name="tradeArrowUp[n]" size="36 0 52 50%" type="button" style="iconButton">
    27                         <object type="image" ghost="true" sprite="StoneArrowUp"/>
    2853                    </object>
    29                     <object name="tradeArrowDn[n]" size="36 50% 52 100%" type="button" style="iconButton">
    30                         <object type="image" ghost="true" sprite="StoneArrowDn"/>
     54                </repeat>
     55            </object>
     56
     57        </object>
     58    </object>
     59
     60    <!-- Trading goods -->
     61    <object size="24 33%+32 100%-24 100%-64">
     62
     63        <object name="tradeHeader" size="8 0 100% 32" type="text" style="ModernLeftLabelText">
     64            <translatableAttribute id="caption">Trade</translatableAttribute>
     65        </object>
     66        <object size="0 28 100% 29" type="image" sprite="ModernGoldLine"/>
     67
     68        <object name="tradeGoods" size="0 38 100% 70">
     69
     70            <object size="0 0 60 100%" type="text" style="ModernRightLabelText">
     71                <translatableAttribute id="caption">Goods:</translatableAttribute>
     72            </object>
     73
     74            <object size="72 0 100% 100%" name="tradeResources">
     75                <repeat count="8">
     76                    <object name="tradeResource[n]" size="0 0 58 32">
     77
     78                        <object name="tradeResourceButton[n]" size="4 0 36 100%" type="button" style="StoneButton">
     79                            <object name="tradeResourceIcon[n]" type="image" ghost="true"/>
     80                            <object name="tradeResourceSelection[n]" type="image" sprite="stretched:session/icons/corners.png" ghost="true"/>
     81                            <object name="tradeResourceText[n]" type="text" style="ModernLabelText" ghost="true"/>
     82                        </object>
     83                        <object name="tradeArrowUp[n]" size="36 0 52 50%" type="button" style="iconButton">
     84                            <object type="image" ghost="true" sprite="StoneArrowUp"/>
     85                        </object>
     86                        <object name="tradeArrowDn[n]" size="36 50% 52 100%" type="button" style="iconButton">
     87                            <object type="image" ghost="true" sprite="StoneArrowDn"/>
     88                        </object>
     89
    3190                    </object>
    32                 </object>
    33             </repeat>
     91                </repeat>
     92            </object>
     93
    3494            <object name="tradeHelp" size="100%-24 4 100% 28" enabled="false" type="button" style="StoneButton" tooltip_style="sessionToolTipBold">
    3595                <object size="20% 15% 80% 75%" type="image" ghost="true" sprite="iconInfoWhite"/>
    3696            </object>
     97
    3798        </object>
    38     </object>
    3999
    40     <object name="tradeStatistics" size="20 90 100%-20 168">
    41         <object name="landTraders" size="0 0 100% 50%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
    42         <object name="shipTraders" size="0 50% 100% 100%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
     100        <object name="traders" size="8 88 100% 100%" type="text" style="ModernLeftTabLabelText"/>
     101
    43102    </object>
    44103
    45104    <object size="50%-64 100%-50 50%+64 100%-22" type="button" style="StoneButton">
  • binaries/data/mods/public/gui/session/unit_actions.js

    diff --git a/binaries/data/mods/public/gui/session/unit_actions.js b/binaries/data/mods/public/gui/session/unit_actions.js
    index 85e7b050f..3f75ba5cf 100644
    a b var g_EntityCommands = 
    12601260                return false;
    12611261
    12621262            return {
    1263                 "tooltip": translate("Select trading goods"),
     1263                "tooltip": translate("Barter & Trade"),
    12641264                "icon": "economics.png"
    12651265            };
    12661266        },
  • binaries/data/mods/public/simulation/components/GuiInterface.js

    diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
    index 932c8cd3d..f548fc3f0 100644
    a b GuiInterface.prototype.GetSimulationState = function() 
    150150    ret.alliedVictory = cmpEndGameManager.GetAlliedVictory();
    151151
    152152    // Add bartering prices
    153     let cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter);
    154     ret.barterPrices = cmpBarter.GetPrices();
     153    ret.barterPrices = this.GetBarterPrices();
    155154
    156155    // Add Resource Codes, untranslated names and AI Analysis
    157156    ret.resources = {
    GuiInterface.prototype.GetExtendedEntityState = function(player, ent) 
    565564        };
    566565
    567566    if (!cmpFoundation && cmpIdentity && cmpIdentity.HasClass("BarterMarket"))
    568     {
    569         let cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter);
    570         ret.barterMarket = { "prices": cmpBarter.GetPrices() };
    571     }
     567        ret.barterMarket = { "prices": this.GetBarterPrices() };
    572568
    573569    let cmpHeal = Engine.QueryInterface(ent, IID_Heal);
    574570    if (cmpHeal)
    GuiInterface.prototype.GetTradingGoods = function(player) 
    19541950    return QueryPlayerIDInterface(player).GetTradingGoods();
    19551951};
    19561952
     1953GuiInterface.prototype.GetBarterPrices = function()
     1954{
     1955    return Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter).GetPrices();
     1956};
     1957
     1958GuiInterface.prototype.PlayerCanBarter = function(player)
     1959{
     1960    let playerEnt = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetPlayerByID(player);
     1961    return Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter).PlayerHasMarket(playerEnt);
     1962};
     1963
    19571964GuiInterface.prototype.OnGlobalEntityRenamed = function(msg)
    19581965{
    19591966    this.renamedEntities.push(msg);
    let exposedFunctions = { 
    20182025
    20192026    "GetTraderNumber": 1,
    20202027    "GetTradingGoods": 1,
     2028    "GetBarterPrices": 1,
     2029    "PlayerCanBarter": 1,
    20212030};
    20222031
    20232032GuiInterface.prototype.ScriptCall = function(player, name, args)