Ticket #3277: trading_v4.patch

File trading_v4.patch, 11.5 KB (added by otero, 8 years ago)
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    16631663    let firstMarket = cmpEntityTrader.GetFirstMarket();
    16641664    let secondMarket = cmpEntityTrader.GetSecondMarket();
    16651665    let result = null;
    1666     if (data.target === firstMarket)
     1666    if (!firstMarket)
     1667        result = { "type": "set first" };
     1668    else if (!secondMarket)
    16671669    {
    16681670        result = {
     1671            "type": "set second",
     1672            "gain": cmpEntityTrader.CalculateGain(firstMarket, data.target),
     1673        };
     1674    }
     1675    else if (data.target === firstMarket)
     1676    {
     1677        result = {
    16691678            "type": "is first",
    16701679            "hasBothMarkets": cmpEntityTrader.HasBothMarkets()
    16711680        };
     
    16791688            "gain": cmpEntityTrader.GetGoods().amount,
    16801689        };
    16811690    }
    1682     else if (!firstMarket)
    1683     {
    1684         result = { "type": "set first" };
    1685     }
    1686     else if (!secondMarket)
    1687     {
    1688         result = {
    1689             "type": "set second",
    1690             "gain": cmpEntityTrader.CalculateGain(firstMarket, data.target),
    1691         };
    1692     }
    16931691    else
    16941692    {
    16951693        // Else both markets are not null and target is different from them
  • binaries/data/mods/public/simulation/components/Market.js

     
     1/**
     2 @file Market.js
     3 Component used for the management of market and trade units in the field
     4*/
     5function Market() {}
     6
     7Market.prototype.Schema = "<a:component type='system'/><empty/>";
     8
     9Market.prototype.Init = function()
     10{
     11    this.tradeEntities = []; // List of trade entities from which this market works as a target
     12};
     13
     14/**
     15 Subscribes a new trader to this market.
     16 @param {Object} trader - The trader object expected being subscribed inside the market.
     17*/
     18
     19Market.prototype.SubscribeTrader = function(trader)
     20{
     21    // First check that this trader has not been already registered inside the market.
     22    // If that is the case then do nothing
     23    if (!(trader in this.tradeEntities))
     24        // If the entity has not been registered for this market,
     25        // add it to the list of traders
     26        this.tradeEntities.push(trader);
     27};
     28
     29Market.prototype.OnDestroy = function()
     30{
     31    this.NotifySubscribedTraders();
     32};
     33
     34Market.prototype.OnOwnershipChanged = function(msg)
     35{
     36    if (msg.to != -1 && msg.from != -1)
     37    {
     38        let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     39        let cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(msg.to), IID_Player);
     40
     41        // If the new owner is an not an ally the trader should display a behavior
     42        // similar when the market is destroyed.
     43        if(!cmpPlayer.IsAlly(msg.from) || !cmpPlayer.isNeutral(msg.from))
     44            this.NotifySubscribedTraders();
     45    }
     46};
     47
     48Market.prototype.OnDiplomacyChanged = function(msg)
     49{
     50    let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     51    let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     52    let cmpPlayer = undefined;
     53    if(cmpPlayerManager)
     54        cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(msg.player), IID_Player);
     55
     56    if(!cmpOwnership || !cmpPlayer)
     57        return;
     58
     59    // If the new diplomatic position of the player is not an ally return to
     60    // respective ally markets
     61    if (!cmpPlayer.IsAlly(cmpOwnership.GetOwner()) || !cmpPlayer.IsNeutral(cmpOwnership.GetOwner()))
     62        this.NotifySubscribedTraders();
     63}
     64
     65/**
     66 Notifies traders subscribed to this market to change their trading behavior
     67*/
     68Market.prototype.NotifySubscribedTraders = function() {
     69
     70    let cmpUnitAI = undefined;
     71    for(let i=0, l=this.tradeEntities.length; i<l; ++i)
     72    {
     73        if (this.tradeEntities[i])
     74        {
     75            cmpUnitAI = Engine.QueryInterface(this.tradeEntities[i], IID_UnitAI);
     76            if (cmpUnitAI)
     77            {
     78                // Unsubscribe the trader from the market
     79                delete this.tradeEntities[i];
     80                cmpUnitAI.InvalidateTradingMarket(this.entity);
     81            }
     82        }
     83    }
     84}
     85
     86Engine.RegisterComponentType(IID_Market, "Market", Market);
  • binaries/data/mods/public/simulation/components/Trader.js

     
    1 // See helpers/TraderGain.js for the CalculateTaderGain() function which works out how many 
    2 // resources a trader gets 
     1// See helpers/TraderGain.js for the CalculateTaderGain() function which works out how many
     2// resources a trader gets
    33
    44// Additional gain for ships for each garrisoned trader, in percents
    55const GARRISONED_TRADER_ADDITION = 20;
     
    6161                gain.market2Gain = Math.round(garrisonMultiplier * gain.market2Gain);
    6262        }
    6363    }
    64    
     64
    6565    return gain;
    6666};
    6767
     
    273273        this.goods.amount = this.CalculateGain(this.markets[0], this.markets[1]);
    274274};
    275275
     276Trader.prototype.InvalidateFirstMarket = function()
     277{
     278    this.firstMarket = INVALID_ENTITY;
     279}
     280
     281Trader.prototype.InvalidateSecondMarket = function()
     282{
     283    this.secondMarket = INVALID_ENTITY;
     284}
     285
    276286Engine.RegisterComponentType(IID_Trader, "Trader", Trader);
  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    353353        var needToMove = true;
    354354        var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
    355355        if (this.lastShorelinePosition && cmpPosition && (this.lastShorelinePosition.x == cmpPosition.GetPosition().x)
    356             && (this.lastShorelinePosition.z == cmpPosition.GetPosition().z))
     356            && (this.lastShorelinePosition.z == cmpPosition.GetPosition().z))
    357357        {
    358358            // we were already on the shoreline, and have not moved since
    359359            if (DistanceBetweenEntities(this.entity, this.order.data.target) < 50)
     
    583583                return;
    584584            }
    585585
    586             this.PushOrderFront("Attack", { "target": this.order.data.target, "force": false, "hunting": true, "allowCapture": false });
     586            this.PushOrderFront("Attack", { "target": this.order.data.target, "force": false, "hunting": true, "allowCapture": false });
    587587            return;
    588588        }
    589589
     
    15511551            },
    15521552        },
    15531553
     1554        "INVALIDATEPENDINGMARKET": {
     1555            "enter": function() {
     1556                this.StartTimer(500,1000);
     1557            },
     1558
     1559            "Timer": function(msg) {
     1560                if(!this.CheckTargetVisible(this.order.data.target))
     1561                    this.InvalidateTradingMarket(this.order.data.target);
     1562            },
     1563
     1564            "MoveCompleted": function() {
     1565                this.StopTimer();
     1566            }
     1567
     1568        },
     1569
    15541570        "GUARD": {
    15551571            "RemoveGuard": function() {
    15561572                this.StopMoving();
     
    27242740                    let dropsiteTypes = cmpResourceDropsite.GetTypes();
    27252741                    cmpResourceGatherer.CommitResources(dropsiteTypes);
    27262742                    this.SetGathererAnimationOverride();
    2727                 } 
     2743                }
    27282744
    27292745                // We finished building it.
    27302746                // Switch to the next order (if any)
     
    34363452    var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    34373453    if (this.losRangeQuery)
    34383454        this.SetupRangeQuery(cmpRangeManager.IsActiveQueryEnabled(this.losRangeQuery));
    3439  
     3455
    34403456    if (this.IsHealer() && this.losHealRangeQuery)
    34413457        this.SetupHealRangeQuery(cmpRangeManager.IsActiveQueryEnabled(this.losHealRangeQuery));
    34423458};
     
    51565172        return;
    51575173    }
    51585174
    5159     var marketsChanged = this.SetTargetMarket(target, source);
     5175    let marketsChanged = this.SetTargetMarket(target, source);
    51605176    if (!marketsChanged)
    51615177        return;
    51625178
    5163     var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
     5179    let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
     5180    let cmpMarket = Engine.QueryInterface(target, IID_Market);
     5181    if(!cmpTrader || !cmpMarket)
     5182        return;
     5183
     5184    cmpMarket.SubscribeTrader(this.entity);
     5185
    51645186    if (cmpTrader.HasBothMarkets())
    51655187    {
    51665188        let data = {
     
    51795201        if (this.IsFormationController())
    51805202        {
    51815203            this.CallMemberFunction("AddOrder", ["Trade", data, queued]);
    5182             var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     5204            let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
    51835205            if (cmpFormation)
    51845206                cmpFormation.Disband();
    51855207        }
     
    52275249    return ok;
    52285250};
    52295251
     5252/**
     5253 * Makes a routing trade invalid sending the trader unit to the next
     5254 * possible market.
     5255 */
     5256UnitAI.prototype.InvalidateTradingMarket = function(market)
     5257{
     5258    // Find the entity inside the one of the markets in the trader
     5259    //
     5260    // If the market is found as the first market then send the trader to the
     5261    // second market.
     5262    //
     5263    // If the market is found in the second market then send the trader to the
     5264    // first market
     5265    //
     5266    // If the source and target have been captured then stop
     5267    // trading
     5268    let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
     5269
     5270    // Check if the market is visible, otherwise add it to the Queue
     5271    if(cmpTrader && !this.CheckTargetVisible(market))
     5272    {
     5273        if (!cmpTrader.GetFirstMarket() || !cmpTrader.GetSecondMarket())
     5274            this.StopTrading();
     5275        else if(cmpTrader.GetFirstMarket() === market)
     5276        {
     5277            cmpTrader.InvalidateFirstMarket();
     5278            this.MoveToMarket(cmpTrader.GetSecondMarket());
     5279        }
     5280        else if(cmpTrader.GetSecondMarket() === market)
     5281        {
     5282            cmpTrader.InvalidateSecondMarket();
     5283            this.MoveToMarket(cmpTrader.GetFirstMarket());
     5284        }
     5285    }
     5286    else
     5287    {
     5288        this.order.data.target = market;
     5289        this.SetNextState("INDIVIDUAL.INVALIDATEPENDINGMARKET");
     5290    }
     5291};
     5292
    52305293UnitAI.prototype.PerformTradeAndMoveToNextMarket = function(currentMarket)
    52315294{
    52325295    if (!this.CanTrade(currentMarket))
     
    52435306    }
    52445307
    52455308    let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
     5309    if(!cmpTrader)
     5310    {
     5311        this.StopTrading();
     5312        return;
     5313    }
     5314
    52465315    cmpTrader.PerformTrade(currentMarket);
    52475316    if (!cmpTrader.GetGoods().amount.traderGain)
    52485317    {
     
    52705339UnitAI.prototype.StopTrading = function()
    52715340{
    52725341    this.StopMoving();
    5273     this.FinishOrder();
    5274     var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
     5342    let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
    52755343    cmpTrader.StopTrading();
    52765344};
    52775345
  • binaries/data/mods/public/simulation/components/interfaces/Market.js

     
     1Engine.RegisterInterface("Market");
  • binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml

     
    6464  <Vision>
    6565    <Range>32</Range>
    6666  </Vision>
     67  <Market/>
    6768  <VisualActor>
    6869    <FoundationActor>structures/fndn_5x5.xml</FoundationActor>
    6970  </VisualActor>
  • binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml

     
    7575   <Vision>
    7676    <Range>40</Range>
    7777  </Vision>
     78  <Market/>
    7879  <VisualActor>
    7980    <FoundationActor>structures/fndn_4x4_dock.xml</FoundationActor>
    8081  </VisualActor>