Ticket #3488: 3488.14.diff

File 3488.14.diff, 8.7 KB (added by Stan, 8 years ago)

Fix some var/let remove useless lines (that didn't work before but meh) and 644 is because you can't use msg.entity as a key, that toggles an error.

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

     
    3737    for (let ent of msg.added)
    3838    {
    3939        let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
    40         if (!cmpIdentity)
     40        if (msg.visible[ent] || !cmpIdentity)
    4141            continue;
    4242        if (MatchesClassList(cmpIdentity.GetClassesList(), classes))
    4343            ++this.archersGarrisoned;
     
    4646    for (let ent of msg.removed)
    4747    {
    4848        let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
    49         if (!cmpIdentity)
     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
     
    225248        {
    226249            if (vgp.entity)
    227250                continue;
    228             visibleGarrisonPoint = vgp;
    229             break;
     251            if (this.AllowedToVisibleGarrisoning(vgp, entity))
     252            {
     253                visibleGarrisonPoint = vgp;
     254                break;
     255            }
    230256        }
    231257    }
    232 
    233     if (visibleGarrisonPoint)
     258    if (visibleGarrisonPoint && this.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity))
    234259    {
    235260        visibleGarrisonPoint.entity = entity;
    236261        cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset);
     
    241266    else
    242267        cmpPosition.MoveOutOfWorld();
    243268
     269    let visible = {};
     270    visible[entity] = this.IsVisiblyGarrisoned(entity);
     271    // Should only be called after the garrison has been performed else the visible Garrison Points are not updated yet.
     272    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     273        "added": [entity],
     274        "removed": [],
     275        "visible": visible
     276    });
    244277    return true;
    245278};
    246279
     280/**
     281 * Garrison units inside the entity
     282 * @return true if successful, false if not
     283 */
    247284GarrisonHolder.prototype.PerformGarrison = function(entity)
    248285{
    249286    if (!this.HasEnoughHealth())
     
    250287        return false;
    251288
    252289    // Check if the unit is allowed to be garrisoned inside the building
    253     if(!this.AllowedToGarrison(entity))
     290    if (!this.AllowedToGarrison(entity))
    254291        return false;
    255292
    256     // check the capacity
     293    // Check the capacity
    257294    var extraCount = 0;
    258295    var cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
    259296    if (cmpGarrisonHolder)
     
    278315    if (cmpAura && cmpAura.HasGarrisonAura())
    279316        cmpAura.ApplyGarrisonBonus(this.entity);
    280317
    281     Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });
    282 
    283318    var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
    284319    if (cmpUnitAI && cmpUnitAI.IsUnderAlert())
    285320        Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity});
     
    326361
    327362    var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
    328363    this.entities.splice(entityIndex, 1);
    329 
     364   
     365    let visible = {};
     366    visible[entity] = this.IsVisiblyGarrisoned(entity);
     367    // Should only be called before the ejection has been performed else the visible Garrison Points will be empty.
     368    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     369        "added": [],
     370        "removed": [entity],
     371        "visible": visible
     372    });
    330373    for (var vgp of this.visibleGarrisonPoints)
    331374    {
    332375        if (vgp.entity != entity)
     
    356399    cmpNewPosition.SetHeightOffset(0);
    357400    // TODO: what direction should they face in?
    358401
    359     Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });
    360402
    361403    return true;
    362404};
     
    597639 */
    598640GarrisonHolder.prototype.OnGlobalOwnershipChanged = function(msg)
    599641{
     642    let msgEntity = msg.entity;
    600643    // the ownership change may be on the garrisonholder
    601     if (this.entity == msg.entity)
     644    if (this.entity == msgEntity)
    602645    {
    603646        var entities = [];
    604647        for each (var entity in this.entities)
     
    612655    }
    613656
    614657    // or on some of its garrisoned units
    615     var entityIndex = this.entities.indexOf(msg.entity);
     658    let entityIndex = this.entities.indexOf(msgEntity);
    616659    if (entityIndex != -1)
    617660    {
    618661        // If the entity is dead, remove it directly instead of ejecting the corpse
    619         var cmpHealth = Engine.QueryInterface(msg.entity, IID_Health);
     662        let cmpHealth = Engine.QueryInterface(msgEntity, IID_Health);
    620663        if (cmpHealth && cmpHealth.GetHitpoints() == 0)
    621664        {
    622665            this.entities.splice(entityIndex, 1);
    623             Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] });
     666            let visible = {};
     667            visible[msgEntity] = this.IsVisiblyGarrisoned(msgEntity);
     668            Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     669                "added": [],
     670                "removed": [msgEntity],
     671                "visible": visible
     672            });
    624673            this.UpdateGarrisonFlag();
    625674
    626675            for (var pt of this.visibleGarrisonPoints)
    627                 if (pt.entity == msg.entity)
     676                if (pt.entity == msgEntity)
    628677                    pt.entity = null;
    629678        }
    630         else if (msg.to == -1 || !IsOwnedByMutualAllyOfEntity(this.entity, msg.entity))
    631             this.EjectOrKill([msg.entity]);
     679        else if (msg.to == -1 || !IsOwnedByMutualAllyOfEntity(this.entity, msgEntity))
     680            this.EjectOrKill([msgEntity]);
    632681    }
    633682};
    634683
    635684/**
    636685 * Update list of garrisoned entities if one gets renamed (e.g. by promotion)
     686 * vgpEntity is only defined in some peculiar case where we want to reuse the same visibleGarrisonPoint,
     687 * in case of promotion for example, and thus should always be allowed.
    637688 */
    638689GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
    639690{
     
    670721    }
    671722};
    672723
    673 
    674724/**
    675725 * Eject all foreign garrisoned entities which are no more allied
    676726 */
     
    687737GarrisonHolder.prototype.EjectOrKill = function(entities)
    688738{
    689739    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
     740    // Eject the units which can be ejected (if not in world, it often means this holder
    691741    // is inside a holder which kills its entities, so do not eject)
    692742    if (cmpPosition.IsInWorld())
    693743    {
     
    710760        this.entities.splice(entityIndex, 1);
    711761        killedEntities.push(entity);
    712762    }
    713 
    714763    if (killedEntities.length > 0)
    715         Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities });
     764    {
     765        let visibleEntitiesIds = {};
     766        for (let ent of killedEntities)
     767            visibleEntitiesIds[ent] = this.IsVisiblyGarrisoned(ent);
     768        Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     769            "added": [],
     770            "removed": killedEntities,
     771            "visible": visibleEntitiesIds
     772        });
     773    }
    716774    this.UpdateGarrisonFlag();
    717775};
    718776
    719777/**
     778 * Gives insight about the unit type of garrisoning.
     779 * @return{bool} returns true if the unit is visible on the structure
     780 * @param {int} the entity's id
     781 */
     782GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity)
     783{
     784    return this.visibleGarrisonPoints.some(point => point.entity == entity);
     785};
     786
     787/**
    720788 * Checks if an entity is ejectable on destroy if possible
    721789 */
    722790GarrisonHolder.prototype.IsEjectable = function(entity)