Ticket #23: barter_2011_09_14_v2.diff

File barter_2011_09_14_v2.diff, 13.5 KB (added by fcxSanya, 13 years ago)
  • source/simulation2/Simulation2.cpp

     
    101101                LOGERROR(L"Can't find component type " L##name); \
    102102            m_ComponentManager.AddComponent(SYSTEM_ENTITY, cid, noParam)
    103103
     104            LOAD_SCRIPTED_COMPONENT("GlobalBarter");
    104105            LOAD_SCRIPTED_COMPONENT("AIInterface");
    105106            LOAD_SCRIPTED_COMPONENT("EndGameManager");
    106107            LOAD_SCRIPTED_COMPONENT("GuiInterface");
  • binaries/data/mods/public/gui/session/session.xml

     
    493493                    </object>
    494494                </object>
    495495
     496                <object name="unitBarterPanel"
     497                    size="3 6 100% 100%"
     498                >
     499                    <object name="unitBarterBuy" ghost="true" style="resourceText" type="text" size="0 0 46 46">Buy:</object>
     500                    <object name="unitBarterSell" ghost="true" style="resourceText" type="text" size="0 46 46 92">Sell:</object>
     501                    <object size="46 0 100% 100%">
     502                        <repeat count="6">
     503                            <object name="unitBarterButton[n]" hidden="true" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold" z="100">
     504                                <object name="unitBarterIcon[n]" type="image" ghost="true" size="3 3 43 43"/>
     505                                <object name="unitBarterPrice[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/>
     506                            </object>
     507                        </repeat>
     508                    </object>
     509                </object>
     510
    496511                <!-- Stance Selection -->
    497512                <object name="unitStancePanel"
    498513                    style="TranslucentPanel"
  • binaries/data/mods/public/gui/session/input.js

     
    10081008    inputState = INPUT_BUILDING_PLACEMENT;
    10091009}
    10101010
     1011// Called by GUI when user clicks exchange resources button
     1012function exchangeResources(command)
     1013{
     1014    Engine.PostNetworkCommand({"type": "barter", "action": command.action, "resource": command.resource});
     1015}
     1016
     1017
    10111018// Batch training:
    10121019// When the user shift-clicks, we set these variables and switch to INPUT_BATCHTRAINING
    10131020// When the user releases shift, or clicks on a different training button, we create the batched units
  • binaries/data/mods/public/gui/session/unit_commands.js

     
    1414const UNIT_PANEL_HEIGHT = 44; // QUEUE: The height needed for a row of buttons
    1515
    1616// The number of currently visible buttons (used to optimise showing/hiding)
    17 var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Training": 0, "Construction": 0, "Command": 0, "Stance": 0};
     17var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Barter": 0, "Training": 0, "Construction": 0, "Command": 0, "Stance": 0};
    1818
    1919// Unit panels are panels with row(s) of buttons
    20 var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", "Training", "Construction", "Research", "Stance", "Command"];
     20var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", "Barter", "Training", "Construction", "Research", "Stance", "Command"];
    2121
    2222// Lay out a row of centered buttons (does not work inside a loop like the other function)
    2323function layoutButtonRowCentered(rowNumber, guiName, startIndex, endIndex, width)
     
    323323    else if (guiName == "Formation" || guiName == "Garrison" || guiName == "Command")
    324324        rowLength = 4;
    325325
     326    if (guiName == "Barter")
     327    {
     328        numButtons = 6;
     329        rowLength = 3;
     330
     331        for (var i = 0; i < numButtons; i++)
     332        {
     333            var action = ["buy", "sell"][Math.floor(i/3)];
     334            var resource = ["food", "wood", "stone"][i%3];
     335
     336            var button = getGUIObjectByName("unitBarterButton["+i+"]");
     337            button.hidden = false;
     338            button.tooltip = action + " 100 " + resource + " for " + unitEntState.barterPrices[action][resource] + " metal";
     339            var command = { "action": action, "resource": resource };
     340            button.onpress = (function(e) { return function() { exchangeResources(e) } })(command);
     341       
     342            var icon = getGUIObjectByName("unitBarterIcon["+i+"]");
     343            icon.sprite = "stretched:session/resources/" + resource + ".png";
     344
     345            getGUIObjectByName("unitBarterPrice["+i+"]").caption = unitEntState.barterPrices[action][resource];
     346        }
     347    }
     348
    326349    var numRows = Math.ceil(numButtons / rowLength);
    327350    var buttonSideLength = getGUIObjectByName("unit"+guiName+"Button[0]").size.bottom;
    328351    var buttonSpacer = buttonSideLength+1;
     
    410433                function (item) { performStance(entState.id, item); } );
    411434        }
    412435
     436        if (entState.barterMarket)
     437        {
     438            setupUnitPanel("Barter", usedPanels, entState, [], null );
     439        }
     440
    413441        if (entState.buildEntities && entState.buildEntities.length)
    414442        {
    415443            setupUnitPanel("Construction", usedPanels, entState, entState.buildEntities, startBuildingPlacement);
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
    319319        }
    320320        break;
    321321
     322    case "barter":
     323        var cmpGlobalBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_GlobalBarter);
     324        cmpGlobalBarter.ExchangeResources(playerEnt, cmd.action, cmd.resource);
     325        break;
     326
    322327    default:
    323328        error("Ignoring unrecognised command type '" + cmd.type + "'");
    324329    }
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    135135            "classes": cmpIdentity.GetClassesList(),
    136136            "selectionGroupName": cmpIdentity.GetSelectionGroupName()
    137137        };
     138
     139        if (cmpIdentity.GetClassesList().indexOf("BarterMarket") != -1)
     140        {
     141            ret.barterMarket = true;
     142            var cmpGlobalBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_GlobalBarter);
     143            ret.barterPrices = cmpGlobalBarter.GetPrices();
     144        }
    138145    }
    139146   
    140147    var cmpPosition = Engine.QueryInterface(ent, IID_Position);
  • binaries/data/mods/public/simulation/components/interfaces/GlobalBarter.js

     
     1Engine.RegisterInterface("GlobalBarter");
  • binaries/data/mods/public/simulation/components/Identity.js

     
    8181                        "<value>Civic</value>" +
    8282                        "<value>CivCentre</value>" +
    8383                        "<value>Economic</value>" +
     84                        "<value>BarterMarket</value>" +
    8485                        "<value>Defensive</value>" +
    8586                        "<value>Village</value>" +
    8687                        "<value>Town</value>" +
  • binaries/data/mods/public/simulation/components/GlobalBarter.js

     
     1// true price of 100 resource in metal (for case if some resource is more worth)
     2const TRUE_PRICES = { "food": 100, "wood": 200, "stone": 300 };
     3
     4// constant part of price different between true price and buy/sell price
     5// in percents
     6// buy price equal to true price plus constant difference
     7// sell price equal to true price minus constant difference
     8const CONSTANT_DIFFERENCE = 25;
     9
     10// additional difference of prices, added after each deal to specified resource price
     11// in percents
     12const DIFFERENCE_PER_DEAL = 5;
     13
     14// price difference which restored each restore timer tick
     15// in percents
     16const DIFFERENCE_RESTORE = 2;
     17
     18// interval of timer which slowly restore prices after deals
     19const RESTORE_TIMER_INTERVAL = 5000;
     20
     21function GlobalBarter() {}
     22
     23GlobalBarter.prototype.Schema =
     24    "<a:component type='system'/><empty/>";
     25
     26GlobalBarter.prototype.Init = function()
     27{
     28    this.priceDifferences = {};
     29    for each (var resource in ["food", "wood", "stone"])
     30        this.priceDifferences[resource] = 0;
     31    this.restoreTimer = undefined;
     32};
     33
     34GlobalBarter.prototype.GetPrices = function()
     35{
     36    var prices = { "buy": {}, "sell": {} };
     37    for each (var resource in ["food", "wood", "stone"])
     38    {
     39        prices["buy"][resource] = Math.round(TRUE_PRICES[resource] * (100 + CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100);
     40        prices["sell"][resource] = Math.round(TRUE_PRICES[resource] * (100 - CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100);
     41    }
     42    return prices;
     43};
     44
     45GlobalBarter.prototype.ExchangeResources = function(playerEntity, action, resource)
     46{
     47    var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player);
     48    var amountsToSubtract = {
     49        "food": 0,
     50        "wood": 0,
     51        "stone": 0,
     52        "metal": 0
     53    };
     54    var prices = this.GetPrices();
     55    switch (action)
     56    {
     57    case "buy":
     58        amountsToSubtract["metal"] = prices["buy"][resource];
     59        if (cmpPlayer.TrySubtractResources(amountsToSubtract))
     60        {
     61            cmpPlayer.AddResource(resource, 100);
     62            if (this.priceDifferences[resource] + DIFFERENCE_PER_DEAL < 100 - CONSTANT_DIFFERENCE)
     63                this.priceDifferences[resource] += DIFFERENCE_PER_DEAL;
     64        }
     65        break;
     66    case "sell":
     67        amountsToSubtract[resource] = 100;
     68        if (cmpPlayer.TrySubtractResources(amountsToSubtract))
     69        {
     70            cmpPlayer.AddResource("metal", prices["sell"][resource]);
     71            if (this.priceDifferences[resource] - DIFFERENCE_PER_DEAL > CONSTANT_DIFFERENCE - 100)
     72                this.priceDifferences[resource] -= DIFFERENCE_PER_DEAL;
     73        }
     74        break;
     75    }
     76    if (this.restoreTimer == undefined)
     77    {
     78        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     79        this.restoreTimer = cmpTimer.SetTimeout(this.entity, IID_GlobalBarter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, {});
     80    }
     81};
     82
     83GlobalBarter.prototype.ProgressTimeout = function(data)
     84{
     85    this.restoreTimer = undefined;
     86
     87    var needRestore = false;
     88    for each (var resource in ["food", "wood", "stone"])
     89    {
     90        // calculate value to restore, it should be:
     91        // clamping into [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval
     92        var differenceRestore = Math.min(DIFFERENCE_RESTORE, Math.max(-DIFFERENCE_RESTORE, this.priceDifferences[resource]));
     93        // change sign, because we need to restore price
     94        differenceRestore = -differenceRestore;
     95        this.priceDifferences[resource] += differenceRestore;
     96        // if price difference still exists then set flag to run timer again
     97        if (this.priceDifferences[resource] != 0)
     98            needRestore = true;
     99    }
     100
     101    if (needRestore)
     102    {
     103        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     104        this.restoreTimer = cmpTimer.SetTimeout(this.entity, IID_GlobalBarter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, data);
     105    }
     106}
     107
     108Engine.RegisterComponentType(IID_GlobalBarter, "GlobalBarter", GlobalBarter);
     109
  • binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml

     
    2323  </Health>
    2424  <Identity>
    2525    <GenericName>Market</GenericName>
    26     <Tooltip>Create Trade units and Barter resources. (Currently a useless structure)</Tooltip>
    27     <Classes datatype="tokens">Town</Classes>
     26    <Tooltip>Create Trade units and Barter resources.</Tooltip>
     27    <Classes datatype="tokens">Town BarterMarket</Classes>
    2828    <Icon>structures/market.png</Icon>
    2929  </Identity>
    3030  <Obstruction>