Ticket #4102: garrison-4102.patch

File garrison-4102.patch, 18.0 KB (added by mimo, 8 years ago)

updated version of the garrisonHolder cleanup

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

     
    6565    this.allowGarrisoning = {};
    6666    this.visibleGarrisonPoints = [];
    6767    if (this.template.VisibleGarrisonPoints)
    68     {
    69         for each (var offset in this.template.VisibleGarrisonPoints)
    70         {
    71             var o = {};
    72             o.x = +offset.X;
    73             o.y = +offset.Y;
    74             o.z = +offset.Z;
    75             this.visibleGarrisonPoints.push({"offset":o, "entity": null});
    76         }
    77     }
     68        for (let name in this.template.VisibleGarrisonPoints)
     69            this.visibleGarrisonPoints.push({
     70                "offset": {
     71                    "x": +this.template.VisibleGarrisonPoints[name].X,
     72                    "y": +this.template.VisibleGarrisonPoints[name].Y,
     73                    "z": +this.template.VisibleGarrisonPoints[name].Z
     74                    }, "entity": null });
    7875};
    7976
    8077/**
     
    8279 */
    8380GarrisonHolder.prototype.GetLoadingRange = function()
    8481{
    85     var max = +this.template.LoadingRange;
    86     return { "max": max, "min": 0 };
     82    return { "max": +this.template.LoadingRange, "min": 0 };
    8783};
    8884
    8985/**
     
    9389{
    9490    if (!this.template.Pickup || this.IsFull())
    9591        return false;
    96     var cmpOwner = Engine.QueryInterface(this.entity, IID_Ownership);
     92    let cmpOwner = Engine.QueryInterface(this.entity, IID_Ownership);
    9793    if (!cmpOwner)
    9894        return false;
    99     var player = cmpOwner.GetOwner();
    100     return IsOwnedByPlayer(player, ent);
     95    return IsOwnedByPlayer(cmpOwner.GetOwner(), ent);
    10196};
    10297
    10398
     
    163158 */
    164159GarrisonHolder.prototype.IsGarrisoningAllowed = function()
    165160{
    166     for each (var allow in this.allowGarrisoning)
    167     {
    168         if (!allow)
     161    for (let allow in this.allowGarrisoning)
     162        if (!this.allowGarrisoning[allow])
    169163            return false;
    170     }
     164
    171165    return true;
    172166};
    173167
     
    176170 */
    177171GarrisonHolder.prototype.GetGarrisonedEntitiesCount = function()
    178172{
    179     var count = 0;
    180     for each (var ent in this.entities)
     173    let count = 0;
     174    for (let ent of this.entities)
    181175    {
    182         count++;
    183         var cmpGarrisonHolder = Engine.QueryInterface(ent, IID_GarrisonHolder);
     176        ++count;
     177        let cmpGarrisonHolder = Engine.QueryInterface(ent, IID_GarrisonHolder);
    184178        if (cmpGarrisonHolder)
    185179            count += cmpGarrisonHolder.GetGarrisonedEntitiesCount();
    186180    }
     
    196190    if (!this.IsGarrisoningAllowed())
    197191        return false;
    198192
    199     var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
     193    let cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
    200194    if (!cmpIdentity)
    201195        return false;
    202     var entityClasses = cmpIdentity.GetClassesList();
    203     return MatchesClassList(entityClasses, this.template.List._string);
     196    return MatchesClassList(cmpIdentity.GetClassesList(), this.template.List._string);
    204197};
    205198
    206199/**
     
    211204 */
    212205GarrisonHolder.prototype.Garrison = function(entity, vgpEntity)
    213206{
    214     var cmpPosition = Engine.QueryInterface(entity, IID_Position);
     207    let cmpPosition = Engine.QueryInterface(entity, IID_Position);
    215208    if (!cmpPosition)
    216209        return false;
    217210
     
    254247        return false;
    255248
    256249    // check the capacity
    257     var extraCount = 0;
    258     var cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
     250    let extraCount = 0;
     251    let cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
    259252    if (cmpGarrisonHolder)
    260253        extraCount += cmpGarrisonHolder.GetGarrisonedEntitiesCount();
    261254    if (this.GetGarrisonedEntitiesCount() + extraCount >= this.GetCapacity())
     
    263256
    264257    if (!this.timer && this.GetHealRate() > 0)
    265258    {
    266         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     259        let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    267260        this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
    268261    }
    269262
     
    270263    // Actual garrisoning happens here
    271264    this.entities.push(entity);
    272265    this.UpdateGarrisonFlag();
    273     var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
     266    let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
    274267    if (cmpProductionQueue)
    275268        cmpProductionQueue.PauseProduction();
    276269
    277     var cmpAura = Engine.QueryInterface(entity, IID_Auras);
     270    let cmpAura = Engine.QueryInterface(entity, IID_Auras);
    278271    if (cmpAura && cmpAura.HasGarrisonAura())
    279272        cmpAura.ApplyGarrisonBonus(this.entity);
    280273
    281     Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });
     274    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [entity], "removed": [] });
    282275
    283     var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
     276    let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
    284277    if (cmpUnitAI && cmpUnitAI.IsUnderAlert())
    285         Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity});
     278        Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, { "holder": this.entity, "unit": entity });
    286279
    287280    return true;
    288281};
     
    294287 */
    295288GarrisonHolder.prototype.Eject = function(entity, forced)
    296289{
    297     var entityIndex = this.entities.indexOf(entity);
     290    let entityIndex = this.entities.indexOf(entity);
    298291    // Error: invalid entity ID, usually it's already been ejected
    299292    if (entityIndex == -1)
    300293        return false; // Fail
    301294
    302295    // Find spawning location
    303     var cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint);
    304     var cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
    305     var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
     296    let cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint);
     297    let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
     298    let cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
    306299    // If the garrisonHolder is a sinking ship, restrict the location to the intersection of both passabilities
    307300    // TODO: should use passability classes to be more generic
    308     if ((!cmpHealth || cmpHealth.GetHitpoints() == 0) && cmpIdentity && cmpIdentity.HasClass("Ship"))
    309         var pos = cmpFootprint.PickSpawnPointBothPass(entity);
    310     else
    311         var pos = cmpFootprint.PickSpawnPoint(entity);
     301    let pos = (!cmpHealth || cmpHealth.GetHitpoints() === 0) && cmpIdentity && cmpIdentity.HasClass("Ship") ?
     302        cmpFootprint.PickSpawnPointBothPass(entity) :
     303        cmpFootprint.PickSpawnPoint(entity);
    312304
    313305    if (pos.y < 0)
    314306    {
     
    315307        // Error: couldn't find space satisfying the unit's passability criteria
    316308        if (forced)
    317309        {   // If ejection is forced, we need to continue, so use center of the building
    318             var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
     310            let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
    319311            pos = cmpPosition.GetPosition();
    320312        }
    321313        else
     
    324316        }
    325317    }
    326318
    327     var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
     319    let cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
    328320    this.entities.splice(entityIndex, 1);
    329321
    330     for (var vgp of this.visibleGarrisonPoints)
     322    let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
     323    for (let vgp of this.visibleGarrisonPoints)
    331324    {
    332325        if (vgp.entity != entity)
    333326            continue;
    334327        cmpNewPosition.SetTurretParent(INVALID_ENTITY, new Vector3D());
    335         var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
    336328        if (cmpUnitAI)
    337329            cmpUnitAI.ResetTurretStance();
    338330        vgp.entity = null;
     
    339331        break;
    340332    }
    341333
    342     var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
    343334    if (cmpUnitAI)
    344335        cmpUnitAI.Ungarrison();
    345336
    346     var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
     337    let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
    347338    if (cmpProductionQueue)
    348339        cmpProductionQueue.UnpauseProduction();
    349340
    350     var cmpAura = Engine.QueryInterface(entity, IID_Auras);
     341    let cmpAura = Engine.QueryInterface(entity, IID_Auras);
    351342    if (cmpAura && cmpAura.HasGarrisonAura())
    352343        cmpAura.RemoveGarrisonBonus(this.entity);
    353344
     
    366357 */
    367358GarrisonHolder.prototype.OrderWalkToRallyPoint = function(entities)
    368359{
    369     var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
    370     var cmpRallyPoint = Engine.QueryInterface(this.entity, IID_RallyPoint);
     360    let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     361    let cmpRallyPoint = Engine.QueryInterface(this.entity, IID_RallyPoint);
    371362    if (cmpRallyPoint)
    372363    {
    373         var rallyPos = cmpRallyPoint.GetPositions()[0];
     364        let rallyPos = cmpRallyPoint.GetPositions()[0];
    374365        if (rallyPos)
    375366        {
    376             var commands = GetRallyPointCommands(cmpRallyPoint, entities);
     367            let commands = GetRallyPointCommands(cmpRallyPoint, entities);
    377368            // ignore the rally point if it is autogarrison
    378369            if (commands[0].type == "garrison" && commands[0].target == this.entity)
    379370                return;
    380             for each (var com in commands)
    381             {
    382                 ProcessCommand(cmpOwnership.GetOwner(), com);
    383             }
     371            for (let command of commands)
     372                ProcessCommand(cmpOwnership.GetOwner(), command);
    384373        }
    385374    }
    386375};
     
    396385    if (!this.IsGarrisoningAllowed() && !forced)
    397386        return false;
    398387
    399     var ejectedEntities = [];
    400     var success = true;
    401     var failedRadius;
    402     for (var entity of entities)
     388    let ejectedEntities = [];
     389    let success = true;
     390    let failedRadius;
     391    for (let entity of entities)
    403392    {
    404393        if (failedRadius !== undefined)
    405394        {
    406             var cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
    407             var radius = cmpObstruction ? cmpObstruction.GetUnitRadius() : 0;
     395            let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
     396            let radius = cmpObstruction ? cmpObstruction.GetUnitRadius() : 0;
    408397            if (radius >= failedRadius)
    409398                continue;
    410399        }
     
    411400
    412401        if (this.Eject(entity, forced))
    413402        {
    414             var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
    415             var cmpEntOwnership = Engine.QueryInterface(entity, IID_Ownership);
     403            let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     404            let cmpEntOwnership = Engine.QueryInterface(entity, IID_Ownership);
    416405            if (cmpOwnership && cmpEntOwnership && cmpOwnership.GetOwner() == cmpEntOwnership.GetOwner())
    417406                ejectedEntities.push(entity);
    418407        }
     
    423412                failedRadius = Math.min(failedRadius, radius);
    424413            else
    425414            {
    426                 var cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
     415                let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
    427416                failedRadius = cmpObstruction ? cmpObstruction.GetUnitRadius() : 0;
    428417            }
    429418        }
     
    454443 */
    455444GarrisonHolder.prototype.UnloadTemplate = function(extendedTemplate, all, forced)
    456445{
    457     var index = extendedTemplate.indexOf("&");
     446    let index = extendedTemplate.indexOf("&");
    458447    if (index == -1)
    459448        return false;
    460449
    461     var owner = +extendedTemplate.slice(1,index);
    462     var template = extendedTemplate.slice(index+1);
     450    let owner = +extendedTemplate.slice(1,index);
     451    let template = extendedTemplate.slice(index+1);
    463452
    464     var entities = [];
    465     var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
    466     for each (var entity in this.entities)
     453    let entities = [];
     454    let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
     455    for (let entity of this.entities)
    467456    {
    468         var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
     457        let cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
    469458
    470459        // Units with multiple ranks are grouped together.
    471         var name = cmpIdentity.GetSelectionGroupName()
    472                    || cmpTemplateManager.GetCurrentTemplateName(entity);
     460        let name = cmpIdentity.GetSelectionGroupName() || cmpTemplateManager.GetCurrentTemplateName(entity);
    473461
    474462        if (name != template)
    475463            continue;
     
    493481 */
    494482GarrisonHolder.prototype.UnloadAllByOwner = function(owner, forced)
    495483{
    496     var entities = this.entities.filter(ent => {
    497         var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
     484    let entities = this.entities.filter(ent => {
     485        let cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
    498486        return cmpOwnership && cmpOwnership.GetOwner() == owner;
    499487    });
    500488    return this.PerformEject(entities, forced);
     
    507495 */
    508496GarrisonHolder.prototype.UnloadAll = function(forced)
    509497{
    510     var entities = this.entities.slice();
    511     return this.PerformEject(entities, forced);
     498    return this.PerformEject(this.entities.slice(), forced);
    512499};
    513500
    514501/**
     
    518505GarrisonHolder.prototype.OnHealthChanged = function(msg)
    519506{
    520507    if (!this.HasEnoughHealth() && this.entities.length)
    521     {
    522         var entities = this.entities.slice();
    523         this.EjectOrKill(entities);
    524     }
     508        this.EjectOrKill(this.entities.slice());
    525509};
    526510
    527511/**
     
    529513 */
    530514GarrisonHolder.prototype.HasEnoughHealth = function()
    531515{
    532     var cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
    533     var hitpoints = cmpHealth.GetHitpoints();
    534     var maxHitpoints = cmpHealth.GetMaxHitpoints();
    535     var ejectHitpoints = Math.floor((+this.template.EjectHealth) * maxHitpoints);
     516    let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
     517    let hitpoints = cmpHealth.GetHitpoints();
     518    let maxHitpoints = cmpHealth.GetMaxHitpoints();
     519    let ejectHitpoints = Math.floor((+this.template.EjectHealth) * maxHitpoints);
    536520    return hitpoints > ejectHitpoints;
    537521};
    538522
     
    541525 */
    542526GarrisonHolder.prototype.HealTimeout = function(data)
    543527{
    544     if (this.entities.length == 0)
     528    let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     529    if (!this.entities.length)
    545530    {
    546         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    547531        cmpTimer.CancelTimer(this.timer);
    548532        this.timer = undefined;
     533        return;
    549534    }
    550     else
     535
     536    for (let entity of this.entities)
    551537    {
    552         for each (var entity in this.entities)
     538        let cmpHealth = Engine.QueryInterface(entity, IID_Health);
     539        if (cmpHealth)
    553540        {
    554             var cmpHealth = Engine.QueryInterface(entity, IID_Health);
    555             if (cmpHealth)
    556             {
    557                 // We do not want to heal unhealable units
    558                 if (!cmpHealth.IsUnhealable())
    559                     cmpHealth.Increase(this.GetHealRate());
    560             }
     541            // We do not want to heal unhealable units
     542            if (!cmpHealth.IsUnhealable())
     543                cmpHealth.Increase(this.GetHealRate());
    561544        }
    562         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    563         this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
    564545    }
     546    this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
    565547};
    566548
    567549GarrisonHolder.prototype.UpdateGarrisonFlag = function()
     
    580562{
    581563    if (this.timer)
    582564    {
    583         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     565        let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    584566        cmpTimer.CancelTimer(this.timer);
    585567    }
    586568};
     
    595577    // the ownership change may be on the garrisonholder
    596578    if (this.entity == msg.entity)
    597579    {
    598         var entities = [];
    599         for each (var entity in this.entities)
     580        let entities = [];
     581        for (let entity of this.entities)
    600582        {
    601583            if (msg.to == -1 || !IsOwnedByMutualAllyOfEntity(this.entity, entity))
    602584                entities.push(entity);
     
    607589    }
    608590
    609591    // or on some of its garrisoned units
    610     var entityIndex = this.entities.indexOf(msg.entity);
     592    let entityIndex = this.entities.indexOf(msg.entity);
    611593    if (entityIndex != -1)
    612594    {
    613595        // If the entity is dead, remove it directly instead of ejecting the corpse
    614         var cmpHealth = Engine.QueryInterface(msg.entity, IID_Health);
    615         if (cmpHealth && cmpHealth.GetHitpoints() == 0)
     596        let cmpHealth = Engine.QueryInterface(msg.entity, IID_Health);
     597        if (cmpHealth && cmpHealth.GetHitpoints() === 0)
    616598        {
    617599            this.entities.splice(entityIndex, 1);
    618600            Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] });
    619601            this.UpdateGarrisonFlag();
    620602
    621             for (var pt of this.visibleGarrisonPoints)
     603            for (let pt of this.visibleGarrisonPoints)
    622604                if (pt.entity == msg.entity)
    623605                    pt.entity = null;
    624606        }
     
    632614 */
    633615GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
    634616{
    635     var entityIndex = this.entities.indexOf(msg.entity);
     617    let entityIndex = this.entities.indexOf(msg.entity);
    636618    if (entityIndex != -1)
    637619    {
    638620        let vgpRenamed;
     
    671653 */
    672654GarrisonHolder.prototype.OnDiplomacyChanged = function()
    673655{
    674     var entities = this.entities.filter(ent => !IsOwnedByMutualAllyOfEntity(this.entity, ent));
     656    let entities = this.entities.filter(ent => !IsOwnedByMutualAllyOfEntity(this.entity, ent));
    675657    this.EjectOrKill(entities);
    676658};
    677659
     
    686668    // is inside a holder which kills its entities, so do not eject)
    687669    if (cmpPosition.IsInWorld())
    688670    {
    689         var cmpGarrisonHolder = this;
    690         var ejectables = entities.filter(function(ent) { return cmpGarrisonHolder.IsEjectable(ent); });
     671        let ejectables = entities.filter(ent => this.IsEjectable(ent), this);
    691672        if (ejectables.length)
    692673            this.PerformEject(ejectables, false);
    693674    }
    694675
    695676    // And destroy all remaining entities
    696     var killedEntities = [];
    697     for each (var entity in entities)
     677    let killedEntities = [];
     678    for (let entity of entities)
    698679    {
    699         var entityIndex = this.entities.indexOf(entity);
     680        let entityIndex = this.entities.indexOf(entity);
    700681        if (entityIndex == -1)
    701682            continue;
    702         var cmpHealth = Engine.QueryInterface(entity, IID_Health);
     683        let cmpHealth = Engine.QueryInterface(entity, IID_Health);
    703684        if (cmpHealth)
    704685            cmpHealth.Kill();
    705686        this.entities.splice(entityIndex, 1);
     
    707688    }
    708689
    709690    if (killedEntities.length > 0)
    710         Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities });
     691        Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": killedEntities });
    711692    this.UpdateGarrisonFlag();
    712693};
    713694
     
    716697 */
    717698GarrisonHolder.prototype.IsEjectable = function(entity)
    718699{
    719     var ejectableClasses = this.template.EjectClassesOnDestroy._string;
     700    let ejectableClasses = this.template.EjectClassesOnDestroy._string;
    720701    ejectableClasses = ejectableClasses ? ejectableClasses.split(/\s+/) : [];
    721     var entityClasses = (Engine.QueryInterface(entity, IID_Identity)).GetClassesList();
    722     for each (var ejectableClass in ejectableClasses)
    723         if (entityClasses.indexOf(ejectableClass) != -1)
    724             return true;
    725 
    726     return false;
     702    let entityClasses = (Engine.QueryInterface(entity, IID_Identity)).GetClassesList();
     703    return ejectableClasses.some(ejectableClass => entityClasses.indexOf(ejectableClass) != -1);
    727704};
    728705
    729706/**
     
    744721};
    745722
    746723Engine.RegisterComponentType(IID_GarrisonHolder, "GarrisonHolder", GarrisonHolder);
    747