Ticket #3894: marketVisibility-v3.patch

File marketVisibility-v3.patch, 11.6 KB (added by mimo, 8 years ago)
  • binaries/data/mods/public/simulation/components/Fogging.js

     
    129129    if (cmpResourceSupply)
    130130        cmpMirage.CopyResourceSupply(cmpResourceSupply);
    131131
     132    var cmpMarket = Engine.QueryInterface(this.entity, IID_Market);
     133    if (cmpMarket)
     134        cmpMirage.CopyMarket(cmpMarket);
     135
    132136    // Notify the GUI the entity has been replaced by a mirage, in case it is selected at this moment
    133137    var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
    134138    cmpGuiInterface.AddMiragedEntity(player, this.entity, this.mirages[player]);
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    289289    if (cmpBuilder)
    290290        ret.builder = true;
    291291
    292     let cmpMarket = Engine.QueryInterface(ent, IID_Market);
     292    let cmpMarket = QueryMiragedInterface(ent, IID_Market);
    293293    if (cmpMarket)
    294294        ret.market = {
    295295            "land": cmpMarket.HasType("land"),
  • binaries/data/mods/public/simulation/components/Market.js

     
    4141    return this.tradeType.has(type);
    4242};
    4343
     44Market.prototype.GetType = function()
     45{
     46    return this.tradeType;
     47};
     48
     49Market.prototype.GetTraders = function()
     50{
     51    return this.traders;
     52};
     53
    4454/**
    45  * Check if all traders with a route on this market can still trade
     55 * Check if the traders attached to this market can still trade with it
     56 * Warning: traders currently trading with a mirage of this market are dealt with in Mirage.js
    4657 */
    47 Market.prototype.OnDiplomacyChanged = function(msg)
     58
     59Market.prototype.UpdateTraders = function(onDestruction)
    4860{
    49     for (let ent of this.traders)
     61    for (let trader of this.traders)
    5062    {
    51         let cmpTrader = Engine.QueryInterface(ent, IID_Trader);
     63        let cmpTrader = Engine.QueryInterface(trader, IID_Trader);
    5264        if (!cmpTrader)
    53             this.RemoveTrader(ent);
    54         else if (!cmpTrader.CanTrade(this.entity))
    5565        {
    56             this.RemoveTrader(ent);
    57             cmpTrader.RemoveMarket(this.entity);
     66            this.RemoveTrader(trader);
     67            continue;
    5868        }
     69        if (!cmpTrader.HasMarket(this.entity) || (!onDestruction && cmpTrader.CanTrade(this.entity)))
     70            continue;
     71        // this trader can no more trade
     72        this.RemoveTrader(trader);
     73        cmpTrader.RemoveMarket(this.entity);
    5974    }
    6075};
    6176
     77Market.prototype.OnDiplomacyChanged = function(msg)
     78{
     79    this.UpdateTraders(false);
     80};
     81
    6282Market.prototype.OnOwnershipChanged = function(msg)
    6383{
    64     for (let ent of this.traders)
    65     {
    66         let cmpTrader = Engine.QueryInterface(ent, IID_Trader);
    67         if (!cmpTrader)
    68             this.RemoveTrader(ent);
    69         else if (msg.to == -1)
    70             cmpTrader.RemoveMarket(this.entity);
    71         else if (!cmpTrader.CanTrade(this.entity))
    72         {
    73             this.RemoveTrader(ent);
    74             cmpTrader.RemoveMarket(this.entity);
    75         }
    76     }
     84    this.UpdateTraders((msg.to == -1));
    7785};
    7886
    7987Engine.RegisterComponentType(IID_Market, "Market", Market);
  • binaries/data/mods/public/simulation/components/Mirage.js

     
    3434    this.killBeforeGather = null;
    3535    this.maxGatherers = null;
    3636    this.numGatherers = null;
     37
     38    this.traders = null;
     39    this.marketType = null;
     40    this.internationalBonus = null;
    3741};
    3842
    3943Mirage.prototype.SetParent = function(ent)
     
    125129Mirage.prototype.GetMaxGatherers = function() { return this.maxGatherers; };
    126130Mirage.prototype.GetNumGatherers = function() { return this.numGatherers; };
    127131
     132// Market data
     133
     134Mirage.prototype.CopyMarket = function(cmpMarket)
     135{
     136    this.miragedIids.add(IID_Market);
     137    this.traders = new Set();
     138    for (let trader of cmpMarket.GetTraders())
     139    {
     140        let cmpTrader = Engine.QueryInterface(trader, IID_Trader);
     141        let cmpOwnership = Engine.QueryInterface(trader, IID_Ownership);
     142        if (!cmpTrader || !cmpOwnership)
     143        {
     144            cmpMarket.RemoveTrader(trader);
     145            continue;
     146        }
     147        if (this.player != cmpOwnership.GetOwner())
     148            continue;
     149        cmpTrader.SwitchMarket(cmpMarket.entity, this.entity);
     150        cmpMarket.RemoveTrader(trader);
     151        this.AddTrader(trader);
     152    }
     153    this.marketType = cmpMarket.GetType();
     154    this.internationalBonus = cmpMarket.GetInternationalBonus();
     155};
     156
     157Mirage.prototype.HasType = function(type) { return this.marketType.has(type); };
     158Mirage.prototype.GetInternationalBonus = function() { return this.internationalBonus; };
     159Mirage.prototype.AddTrader = function(trader) { this.traders.add(trader); };
     160Mirage.prototype.RemoveTrader = function(trader) { this.traders.delete(trader); };
     161
     162Mirage.prototype.UpdateTraders = function(msg)
     163{
     164    let cmpMarket = Engine.QueryInterface(this.parent, IID_Market);
     165    if (!cmpMarket) // The parent market does not exist anymore
     166    {
     167        for (let trader of this.traders)
     168        {
     169            let cmpTrader = Engine.QueryInterface(trader, IID_Trader);
     170            if (cmpTrader)
     171                cmpTrader.RemoveMarket(this.entity);
     172        }
     173        return;
     174    }
     175
     176    // The market becomes visible, switch all traders from the mirage to the market
     177    for (let trader of this.traders)
     178    {
     179        let cmpTrader = Engine.QueryInterface(trader, IID_Trader);
     180        if (!cmpTrader)
     181            continue;
     182        cmpTrader.SwitchMarket(this.entity, cmpMarket.entity);
     183        this.RemoveTrader(trader);
     184        cmpMarket.AddTrader(trader);
     185    }
     186};
     187
    128188// ============================
    129189
    130190Mirage.prototype.OnVisibilityChanged = function(msg)
     
    132192    if (msg.player != this.player || msg.newVisibility != VIS_HIDDEN)
    133193        return;
    134194
     195    if (this.miragedIids.has(IID_Market))
     196        this.UpdateTraders(msg);
     197
    135198    if (this.parent == INVALID_ENTITY)
    136199        Engine.DestroyEntity(this.entity);
    137200    else
  • binaries/data/mods/public/simulation/components/Trader.js

     
    4444        {
    4545            var garrisonMultiplier = 1;
    4646            var garrisonedTradersCount = 0;
    47             for each (var entity in cmpGarrisonHolder.GetEntities())
     47            for (let entity of cmpGarrisonHolder.GetEntities())
    4848            {
    4949                var cmpGarrisonedUnitTrader = Engine.QueryInterface(entity, IID_Trader);
    5050                if (cmpGarrisonedUnitTrader)
     
    6868// Return true if at least one of markets was changed.
    6969Trader.prototype.SetTargetMarket = function(target, source)
    7070{
    71     var cmpTargetMarket = Engine.QueryInterface(target, IID_Market);
     71    let cmpTargetMarket = QueryMiragedInterface(target, IID_Market);
    7272    if (!cmpTargetMarket)
    7373        return false;
    7474
     
    7575    if (source)
    7676    {
    7777        // Establish a trade route with both markets in one go.
    78         let cmpSourceMarket = Engine.QueryInterface(source, IID_Market);
     78        let cmpSourceMarket = QueryMiragedInterface(source, IID_Market);
    7979        if (!cmpSourceMarket)
    8080            return false;
    8181        this.markets = [source];
    82         cmpSourceMarket.AddTrader(this.entity);
    8382    }
    8483    if (this.markets.length >= 2)
    8584    {
     
    8786        // and use the target as first market
    8887        for (let market of this.markets)
    8988        {
    90             let cmpMarket = Engine.QueryInterface(market, IID_Market);
     89            let cmpMarket = QueryMiragedInterface(market, IID_Market);
    9190            if (cmpMarket)
    9291                cmpMarket.RemoveTrader(this.entity);
    9392        }
     
    160159{
    161160    var cmpTraderIdentity = Engine.QueryInterface(this.entity, IID_Identity);
    162161    // Check that the target exists
    163     var cmpTargetMarket = Engine.QueryInterface(target, IID_Market);
     162    var cmpTargetMarket = QueryMiragedInterface(target, IID_Market);
    164163    if (!cmpTargetMarket)
    165164        return false;
    166165    // Check that the target is not a foundation
     
    252251};
    253252
    254253/**
    255  * Called when this trader can no longer trade with the market
     254 * Returns true if the trader has the given market (can be either a market or a mirage)
    256255 */
     256Trader.prototype.HasMarket = function(market)
     257{
     258    return this.markets.indexOf(market) != -1;
     259};
     260
     261/**
     262 * Remove a market when this trader can no longer trade with it
     263 */
    257264Trader.prototype.RemoveMarket = function(market)
    258265{
    259266    let index = this.markets.indexOf(market);
    260     if (index != -1)
    261         this.markets.splice(index, 1);
     267    if (index == -1)
     268        return;
     269    this.markets.splice(index, 1);
     270    let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI);
     271    if (cmpUnitAI)
     272        cmpUnitAI.MarketRemoved(market);
    262273};
    263274
     275/**
     276 * Switch between a market and its mirage according to visibility
     277 */
     278Trader.prototype.SwitchMarket = function(oldMarket, newMarket)
     279{
     280    let index = this.markets.indexOf(oldMarket);
     281    if (index == -1)
     282        return;
     283    this.markets[index] = newMarket;
     284    let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI);
     285    if (cmpUnitAI)
     286        cmpUnitAI.SwitchMarketOrder(oldMarket, newMarket);
     287};
     288
    264289Trader.prototype.StopTrading = function()
    265290{
    266291    for (let market of this.markets)
    267292    {
    268         let cmpMarket = Engine.QueryInterface(market, IID_Market);
     293        let cmpMarket = QueryMiragedInterface(market, IID_Market);
    269294        if (cmpMarket)
    270295            cmpMarket.RemoveTrader(this.entity);
    271296    }
  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    648648    "Order.Trade": function(msg) {
    649649        // We must check if this trader has both markets in case it was a back-to-work order
    650650        var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
    651         if (!cmpTrader || ! cmpTrader.HasBothMarkets())
     651        if (!cmpTrader || !cmpTrader.HasBothMarkets())
    652652        {
    653653            this.FinishOrder();
    654654            return;
     
    52095209    return marketsChanged;
    52105210};
    52115211
     5212UnitAI.prototype.SwitchMarketOrder = function(oldMarket, newMarket)
     5213{
     5214    if (this.order.data && this.order.data.target && this.order.data.target == oldMarket)
     5215        this.order.data.target == newMarket;
     5216};
     5217
    52125218UnitAI.prototype.MoveToMarket = function(targetMarket)
    52135219{
    52145220    if (this.waypoints && this.waypoints.length > 1)
     
    52685274        this.StopTrading();
    52695275};
    52705276
     5277UnitAI.prototype.MarketRemoved = function(market)
     5278{
     5279    if (this.GetCurrentState().split(".").pop() != "APPROACHINGMARKET" || this.order.data.target != market)
     5280        return;
     5281    let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
     5282    let otherMarket = cmpTrader ? cmpTrader.GetFirstMarket() : undefined;
     5283    this.StopTrading();
     5284    if (otherMarket)
     5285        this.WalkToTarget(otherMarket);
     5286};
     5287
    52715288UnitAI.prototype.StopTrading = function()
    52725289{
    52735290    this.StopMoving();
  • binaries/data/mods/public/simulation/helpers/TraderGain.js

     
    11function CalculateTraderGain(firstMarket, secondMarket, traderTemplate, trader)
    22{
    3     let cmpMarket1 = Engine.QueryInterface(firstMarket, IID_Market);
    4     let cmpMarket2 = Engine.QueryInterface(secondMarket, IID_Market);
     3    let cmpMarket1 = QueryMiragedInterface(firstMarket, IID_Market);
     4    let cmpMarket2 = QueryMiragedInterface(secondMarket, IID_Market);
    55    if (!cmpMarket1 || !cmpMarket2)
    66        return null;
    77