Ticket #3488: 3488.12.diff

File 3488.12.diff, 7.6 KB (added by Stan, 8 years ago)

Use mimo's way of sending messages.

  • binaries/data/mods/public/simulation/components/BuildingAI.js

     
    3636
    3737    for (let ent of msg.added)
    3838    {
    39         let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
    40         if (!cmpIdentity)
     39        let cmpIdentity = Engine.QueryInterface(ent.id, IID_Identity);
     40        if (msg.visible[ent] || !cmpIdentity)
    4141            continue;
    4242        if (MatchesClassList(cmpIdentity.GetClassesList(), classes))
    4343            ++this.archersGarrisoned;
     
    4545
    4646    for (let ent of msg.removed)
    4747    {
    48         let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
    49         if (!cmpIdentity)
     48        let cmpIdentity = Engine.QueryInterface(ent.id, IID_Identity);
     49        if (msg.visible[ent] || !cmpIdentity)
    5050            continue;
    5151        if (MatchesClassList(cmpIdentity.GetClassesList(), classes))
    5252            --this.archersGarrisoned;
  • binaries/data/mods/public/simulation/components/GarrisonHolder.js

     
     1/**
     2 * @class Defines an entity's ability to garrison units.
     3 */
    14function GarrisonHolder() {}
    25
    36GarrisonHolder.prototype.Schema =
     
    4548                        "<element name='Z'>" +
    4649                            "<data type='decimal'/>" +
    4750                        "</element>" +
     51                        "<optional>" +
     52                            "<element name='VisibleGarrisonAllowedClasses'>" +
     53                                "<attribute name='datatype'>" +
     54                                    "<value>tokens</value>" +
     55                                "</attribute>" +
     56                                "<text/>" +
     57                            "</element>" +
     58                        "</optional>" +
    4859                    "</interleave>" +
    4960                "</element>" +
    5061            "</zeroOrMore>" +
     
    7283            o.x = +offset.X;
    7384            o.y = +offset.Y;
    7485            o.z = +offset.Z;
    75             this.visibleGarrisonPoints.push({"offset":o, "entity": null});
     86            this.visibleGarrisonPoints.push({ "offset": o, "entity": null, "allowedClass": offset.VisibleGarrisonAllowedClasses });
    7687        }
    7788    }
    7889};
     
    100111    return IsOwnedByPlayer(player, ent);
    101112};
    102113
    103 
    104114/**
    105115 * Return the list of entities garrisoned inside
    106116 */
     
    204214};
    205215
    206216/**
     217 * Returns true if the unit is allowed be visible on that garrison point, false otherwise.
     218 */
     219GarrisonHolder.prototype.AllowedToVisibleGarrisoning = function(visibleGarrisonPoint, entity)
     220{
     221    let allowedClassesList = visibleGarrisonPoint.allowedClass._string;
     222    // If classlist is empty, everybody can garrison.
     223    if (!allowedClassesList)
     224        return true;
     225   
     226    return MatchesClassList(Engine.QueryInterface(entity, IID_Identity).GetClassesList(), allowedClassesList);
     227};
     228
     229/**
    207230 * Garrison a unit inside.
    208231 * Returns true if successful, false if not
    209232 * The timer for AutoHeal is started here
     
    229252            break;
    230253        }
    231254    }
    232 
    233     if (visibleGarrisonPoint)
     255    if (visibleGarrisonPoint && this.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity))
    234256    {
    235257        visibleGarrisonPoint.entity = entity;
    236258        cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset);
     
    240262    }
    241263    else
    242264        cmpPosition.MoveOutOfWorld();
    243 
     265    // Should only be called after the garrison has been performed else the visible Garrison Points are not updated yet.
     266    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     267        "added": [entity],
     268        "removed": [],
     269        "visible": { entity: this.IsVisiblyGarrisoned(entity) }
     270    });
    244271    return true;
    245272};
    246273
     274/**
     275 * Garrison units inside the entity
     276 * @return true if successful, false if not
     277 */
    247278GarrisonHolder.prototype.PerformGarrison = function(entity)
    248279{
    249280    if (!this.HasEnoughHealth())
     
    250281        return false;
    251282
    252283    // Check if the unit is allowed to be garrisoned inside the building
    253     if(!this.AllowedToGarrison(entity))
     284    if (!this.AllowedToGarrison(entity))
    254285        return false;
    255286
    256     // check the capacity
     287    // Check the capacity
    257288    var extraCount = 0;
    258289    var cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
    259290    if (cmpGarrisonHolder)
     
    278309    if (cmpAura && cmpAura.HasGarrisonAura())
    279310        cmpAura.ApplyGarrisonBonus(this.entity);
    280311
    281     Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });
    282 
    283312    var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
    284313    if (cmpUnitAI && cmpUnitAI.IsUnderAlert())
    285314        Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity});
     
    326355
    327356    var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
    328357    this.entities.splice(entityIndex, 1);
    329 
     358    // Should only be called before the ejection has been performed else the visible Garrison Points will be empty.
     359    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     360        "added": [],
     361        "removed": [entity],
     362        "visible": { entity: this.IsVisiblyGarrisoned(entity) }
     363    });
    330364    for (var vgp of this.visibleGarrisonPoints)
    331365    {
    332366        if (vgp.entity != entity)
     
    356390    cmpNewPosition.SetHeightOffset(0);
    357391    // TODO: what direction should they face in?
    358392
    359     Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });
    360393
    361394    return true;
    362395};
     
    620653        if (cmpHealth && cmpHealth.GetHitpoints() == 0)
    621654        {
    622655            this.entities.splice(entityIndex, 1);
    623             Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] });
     656            Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     657                "added": [],
     658                "removed": [msg.entity],
     659                "visible": { msg.entity: this.IsVisiblyGarrisoned(msg.entity) }
     660            });
    624661            this.UpdateGarrisonFlag();
    625662
    626663            for (var pt of this.visibleGarrisonPoints)
     
    634671
    635672/**
    636673 * Update list of garrisoned entities if one gets renamed (e.g. by promotion)
     674 * vgpEntity is only defined in some peculiar case where we want to reuse the same visibleGarrisonPoint,
     675 * in case of promotion for example, and thus should always be allowed.
    637676 */
    638677GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
    639678{
     
    670709    }
    671710};
    672711
    673 
    674712/**
    675713 * Eject all foreign garrisoned entities which are no more allied
    676714 */
     
    687725GarrisonHolder.prototype.EjectOrKill = function(entities)
    688726{
    689727    var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
    690     // Eject the units which can be ejected (if not in world, it generally means this holder
     728    // Eject the units which can be ejected (if not in world, it often means this holder
    691729    // is inside a holder which kills its entities, so do not eject)
    692730    if (cmpPosition.IsInWorld())
    693731    {
     
    710748        this.entities.splice(entityIndex, 1);
    711749        killedEntities.push(entity);
    712750    }
    713 
    714751    if (killedEntities.length > 0)
    715         Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities });
     752    {
     753        let visibleEntitiesIds = {};
     754        for (let ent of killedEntities)
     755            visibleEntitiesIds[ent] = this.IsVisiblyGarrisoned(ent);
     756       
     757        Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     758            "added": [],
     759            "removed": killedEntities,
     760            "visible": visibleEntitiesIds
     761        });
     762    }
    716763    this.UpdateGarrisonFlag();
    717764};
    718765
    719766/**
     767 * Gives insight about the unit type of garrisoning.
     768 * @return{bool} returns true if the unit is visible on the structure
     769 * @param {int} the entity's id
     770 */
     771GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity)
     772{
     773    return this.visibleGarrisonPoints.some(point => point.entity == entity);
     774};
     775
     776/**
    720777 * Checks if an entity is ejectable on destroy if possible
    721778 */
    722779GarrisonHolder.prototype.IsEjectable = function(entity)