Ticket #3488: 3488.6.diff

File 3488.6.diff, 6.5 KB (added by Stan, 8 years ago)

Should fix those.

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

     
    3232
    3333BuildingAI.prototype.OnGarrisonedUnitsChanged = function(msg)
    3434{
     35    if (msg.visible)
     36        return;
    3537    let classes = this.template.GarrisonArrowClasses;
    3638
    3739    for (let ent of msg.added)
  • 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        "visible": this.IsVisiblyGarrisoned(entity),
     269        "removed": []
     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        "visible": this.IsVisiblyGarrisoned(entity),
     362        "removed": [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                "visible": this.IsVisiblyGarrisoned(entity),
     659                "removed": [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 */
     
    712750    }
    713751
    714752    if (killedEntities.length > 0)
    715         Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities });
     753        for (let entity of killedEntities)
     754            Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
     755                "added": [],
     756                "visible": this.IsVisiblyGarrisoned(entity),
     757                "removed" : [entity]
     758                });
    716759    this.UpdateGarrisonFlag();
    717760};
    718761
    719762/**
     763 * Gives insight about the unit type of garrisoning.
     764 * @return{bool} returns true if the unit is visible on the structure
     765 * @param {int} the entity's id
     766 */
     767GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity)
     768{
     769    return this.visibleGarrisonPoints.some(point => point.entity === entity);
     770};
     771
     772/**
    720773 * Checks if an entity is ejectable on destroy if possible
    721774 */
    722775GarrisonHolder.prototype.IsEjectable = function(entity)