Ticket #2370: ECasMaps.diff

File ECasMaps.diff, 26.2 KB (added by mimo, 9 years ago)

wip patch for EC as maps instead of objects

  • binaries/data/mods/public/simulation/ai/common-api/entity.js

     
    680680            var ress = undefined;
    681681            // this is an abuse of "_ai" but it works.
    682682            if (this.unitAIState().split(".")[1] === "GATHER" && this.unitAIOrderData()[0]["target"] !== undefined)
    683                 ress = this._ai._entities[this.unitAIOrderData()[0]["target"]];
     683                ress = this._ai._entities.get(this.unitAIOrderData()[0]["target"]);
    684684            else if (this.unitAIOrderData()[1] !== undefined && this.unitAIOrderData()[1]["target"] !== undefined)
    685                 ress = this._ai._entities[this.unitAIOrderData()[1]["target"]];
     685                ress = this._ai._entities.get(this.unitAIOrderData()[1]["target"]);
    686686
    687687            if (ress == undefined)
    688688                return undefined;
  • binaries/data/mods/public/simulation/ai/common-api/entitycollection.js

     
    44m.EntityCollection = function(sharedAI, entities, filters)
    55{
    66    this._ai = sharedAI;
    7     this._entities = entities || {};
     7    if (entities && !(entities instanceof Map))
     8    {
     9        this._entities = new Map();
     10        for (let key in entities)
     11            this._entities.set(+key, entities[key]);
     12    }
     13    else
     14        this._entities = entities || new Map();
    815    this._filters = filters || [];
    916   
    10     this._quickIter = false;    // will make the entity collection store an array (not associative) of entities used when calling "foreach".
    11     // probably should not be usde for very dynamic entity collections.
    12 
    13     // Compute length lazily on demand, since it can be
    14     // expensive for large collections
    15     this._length = undefined;
    1617    Object.defineProperty(this, "length", {
    1718        get: function () {
    18             if (this._length === undefined)
    19             {
    20                 this._length = 0;
    21                 for (var id in entities)
    22                     ++this._length;
    23             }
    24             return this._length;
     19            return this._entities.size;
    2520        }
    2621    });
    2722    this.frozen = false;
     
    3530    return {
    3631        "ents": this.toIdArray(),
    3732        "frozen": this.frozen,
    38         "quickIter": this._quickIter,
    3933        "filters": filters
    4034    };
    4135};
     
    4337m.EntityCollection.prototype.Deserialize = function(data, sharedAI)
    4438{
    4539    this._ai = sharedAI;
    46     for each (var id in data.ents)
    47         this._entities[id] = sharedAI._entities[id];
     40    for (let id of data.ents)
     41        this._entities.set(id, sharedAI._entities.get(id));
    4842
    49     for each (var f in data.filters)
     43    for (let f of data.filters)
    5044        this._filters.push(eval(f));
    5145
    5246    if (data.frozen)
     
    5347        this.freeze;
    5448    else
    5549        this.defreeze;
    56 
    57     if (data.quickIter)
    58         this.allowQuickIter();
    59     else
    60         this.preventQuickIter();
    6150};
    6251
    6352// If an entitycollection is frozen, it will never automatically add a unit.
     
    7564
    7665m.EntityCollection.prototype.allowQuickIter = function()
    7766{
    78     this._quickIter = true;
    79     this._entitiesArray = [];
    80     for each (var ent in this._entities)
    81         this._entitiesArray.push(ent);
     67    return;
    8268};
    8369
    8470m.EntityCollection.prototype.preventQuickIter = function()
    8571{
    86     this._quickIter = false;
    87     this._entitiesArray = undefined;
     72    return;
    8873};
    8974
    9075m.EntityCollection.prototype.toIdArray = function()
    9176{
    92     return Object.keys(this._entities).map(function(n){return +n;});
     77    let ret = [];
     78    for (let id of this._entities.keys())
     79        ret.push(id);
     80    return ret;
    9381};
    9482
    9583m.EntityCollection.prototype.toEntityArray = function()
    9684{
    97     if (this._quickIter === true)
    98         return this._entitiesArray;
    99     var ret = [];
    100     for each (var ent in this._entities)
     85    let ret = [];
     86    for (let ent of this._entities.values())
    10187        ret.push(ent);
    10288    return ret;
    10389};
    10490
     91m.EntityCollection.prototype.values = function()
     92{
     93    return this._entities.values();
     94};
     95
    10596m.EntityCollection.prototype.toString = function()
    10697{
    10798    return "[EntityCollection " + this.toEntityArray().join(" ") + "]";
    10899};
    109100
     101m.EntityCollection.prototype.filter = function(filter, thisp)
     102{
     103    if (typeof(filter) == "function")
     104        filter = {"func": filter, "dynamicProperties": []};
     105   
     106    var ret = new Map();
     107    for (let [id, ent] of this._entities)
     108        if (filter.func.call(thisp, ent, id, this))
     109            ret.set(id, ent);
     110   
     111    return new m.EntityCollection(this._ai, ret, this._filters.concat([filter]));
     112};
     113
    110114/**
    111115 * Returns the (at most) n entities nearest to targetPos.
    112116 */
     
    113117m.EntityCollection.prototype.filterNearest = function(targetPos, n)
    114118{
    115119    // Compute the distance of each entity
    116     var data = []; // [id, ent, distance]
    117    
    118     if (this._quickIter === true)
    119     {
    120         for (var i in this._entitiesArray)
    121         {
    122             var ent = this._entitiesArray[i];
    123             if (ent.position() !== -1)
    124                 data.push([ent.id(), ent, m.SquareVectorDistance(targetPos, ent.position())]);
    125         }
    126     } else {
    127         for (var id in this._entities)
    128         {
    129             var ent = this._entities[id];
    130             if (ent.position() !== -1)
    131                 data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
    132         }
    133     }
     120    var data = []; // [ [id, ent, distance], ... ]
     121    for (let [id, ent] of this._entities)
     122        if (ent.position())
     123            data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
    134124
    135125    // Sort by increasing distance
    136126    data.sort(function (a, b) { return (a[2] - b[2]); });
     127    if (n === undefined)
     128        n = data.length;
     129    else
     130        n = Math.min(n, data.length);
    137131
    138132    // Extract the first n
    139     var ret = {};
    140     var length = Math.min(n, entData.length);
    141     for (var i = 0; i < length; ++i)
    142         ret[data[i][0]] = data[i][1];
     133    let ret = new Map();
     134    for (let i = 0; i < n; ++i)
     135        ret.set(data[i][0], data[i][1]);
    143136
    144137    return new m.EntityCollection(this._ai, ret);
    145138};
    146139
    147 m.EntityCollection.prototype.filter = function(filter, thisp)
    148 {
    149     if (typeof(filter) == "function")
    150         filter = {"func": filter, "dynamicProperties": []};
    151    
    152     var ret = {};
    153     if (this._quickIter === true)
    154     {
    155         for (var i in this._entitiesArray)
    156         {
    157             var ent = this._entitiesArray[i];
    158             var id = ent.id();
    159             if (filter.func.call(thisp, ent, id, this))
    160                 ret[id] = ent;
    161         }
    162     } else {
    163         for (var id in this._entities)
    164         {
    165             var ent = this._entities[id];
    166             if (filter.func.call(thisp, ent, id, this))
    167                 ret[id] = ent;
    168         }
    169     }
    170    
    171     return new m.EntityCollection(this._ai, ret, this._filters.concat([filter]));
    172 };
    173 
    174140m.EntityCollection.prototype.filter_raw = function(callback, thisp)
    175141{
    176     var ret = {};
    177     for (var id in this._entities)
     142    var ret = new Map();
     143    for (let [id, ent] of this._entities)
    178144    {
    179         var ent = this._entities[id];
    180         var val = this._entities[id]._entity;
     145        let val = ent._entity;
    181146        if (callback.call(thisp, val, id, this))
    182             ret[id] = ent;
     147            ret.set(id, ent);
    183148    }
    184149    return new m.EntityCollection(this._ai, ret);
    185150};
     
    186151
    187152m.EntityCollection.prototype.forEach = function(callback)
    188153{
    189     if (this._quickIter === true)
    190     {
    191         this._entitiesArray.forEach(callback);
    192         return this;
    193     }
    194     for (var id in this._entities)
    195     {
    196         callback(this._entities[id]);
    197     }
     154    for (let ent of this._entities.values())
     155        callback(ent);
    198156    return this;
    199157};
    200158
    201 m.EntityCollection.prototype.filterNearest = function(targetPos, n)
    202 {
    203     // Compute the distance of each entity
    204     var data = []; // [ [id, ent, distance], ... ]
    205     for (var id in this._entities)
    206     {
    207         var ent = this._entities[id];
    208         if (ent.position())
    209             data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
    210     }
    211    
    212     // Sort by increasing distance
    213     data.sort(function (a, b) { return (a[2] - b[2]); });
    214     if (n === undefined)
    215         n = this._length;
    216     // Extract the first n
    217     var ret = {};
    218     for each (var val in data.slice(0, n))
    219         ret[val[0]] = val[1];
    220    
    221     return new m.EntityCollection(this._ai, ret);
    222 };
    223 
    224159m.EntityCollection.prototype.move = function(x, z, queued)
    225160{
    226161    queued = queued || false;
     
    238173m.EntityCollection.prototype.moveIndiv = function(x, z, queued)
    239174{
    240175    queued = queued || false;
    241     for (var id in this._entities)
     176    for (let id of this._entities.keys())
    242177    {
    243178        // The following try {} finally {} block is a workaround for OOS problems in multiplayer games with AI players (check ticket #2000).
    244179        // It disables JIT compiling of this loop. Don't remove it unless you are sure that the underlying issue has been resolved!
    245180        // TODO: Check this again after the SpiderMonkey upgrade.
    246181        try {} finally {}
    247         Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this._entities[id].id()], "x": x, "z": z, "queued": queued});
     182        Engine.PostCommand(PlayerID,{"type": "walk", "entities": [id], "x": x, "z": z, "queued": queued});
    248183    }
    249184    return this;
    250185};
     
    265200{
    266201    var unitId;
    267202    if (typeof(unit) === "Entity")
    268     {
    269203        unitId = unit.id();
    270     }
    271204    else
    272     {
    273205        unitId = unit;
    274     }   
    275206    Engine.PostCommand(PlayerID,{"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});
    276207    return this;
    277208};
     
    288219{
    289220    var sumPos = [0, 0];
    290221    var count = 0;
    291     this.forEach(function(ent)
     222    for (let ent of this._entities.values())
    292223    {
    293         if (ent.position())
    294         {
    295             sumPos[0] += ent.position()[0];
    296             sumPos[1] += ent.position()[1];
    297             count ++;
    298         }
    299     });
     224        if (!ent.position())
     225            continue;
     226        sumPos[0] += ent.position()[0];
     227        sumPos[1] += ent.position()[1];
     228        count ++;
     229    }
     230
    300231    if (count === 0)
    301     {
    302232        return undefined;
    303     }
    304233    else
    305     {
    306234        return [sumPos[0]/count, sumPos[1]/count];
    307     }
    308235};
    309236
    310237// returns the average position from the sample first units.
     
    314241{
    315242    var sumPos = [0, 0];
    316243    var i = 0;
    317     for (var id in this._entities)
     244    for (let ent of this._entities.values())
    318245    {
    319         var ent = this._entities[id];
    320         if (ent.position())
    321         {
    322             sumPos[0] += ent.position()[0];
    323             sumPos[1] += ent.position()[1];
    324             i++;
    325         }
     246        if (!ent.position())
     247            continue;
     248        sumPos[0] += ent.position()[0];
     249        sumPos[1] += ent.position()[1];
     250        i++;
    326251        if (i === sample)
    327252            break;
    328253    }
    329     if (sample === 0)
    330     {
     254    if (i === 0)
    331255        return undefined;
    332     }
    333256    else
    334     {
    335257        return [sumPos[0]/i, sumPos[1]/i];
    336     }
    337258};
    338259
    339260
     
    340261// Removes an entity from the collection, returns true if the entity was a member, false otherwise
    341262m.EntityCollection.prototype.removeEnt = function(ent)
    342263{
    343     if (this._entities[ent.id()])
    344     {
    345         // Checking length may initialize it, so do it before deleting.
    346         if (this.length !== undefined)
    347             this._length--;
    348         if (this._quickIter === true)
    349             this._entitiesArray.splice(this._entitiesArray.indexOf(ent),1);
    350         delete this._entities[ent.id()];
    351         return true;
    352     }
    353     else
    354     {
     264    if (!this._entities.has(ent.id()))
    355265        return false;
    356     }
     266    this._entities.delete(ent.id());
     267    return true;
    357268};
    358269
    359270// Adds an entity to the collection, returns true if the entity was not member, false otherwise
    360271m.EntityCollection.prototype.addEnt = function(ent)
    361272{
    362     if (this._entities[ent.id()])
    363     {
     273    if (this._entities.has(ent.id()))
    364274        return false;
    365     }
    366     else
    367     {
    368         // Checking length may initialize it, so do it before adding.
    369         if (this.length !== undefined)
    370             this._length++;
    371         this._entities[ent.id()] = ent;
    372         if (this._quickIter === true)
    373             this._entitiesArray.push(ent);
    374         return true;
    375     }
     275    this._entities.set(ent.id(), ent);
     276    return true;
    376277};
    377278
    378279// Checks the entity against the filters, and adds or removes it appropriately, returns true if the
     
    383284m.EntityCollection.prototype.updateEnt = function(ent, force)
    384285{   
    385286    var passesFilters = true;
    386     for each (var filter in this._filters)
    387     {
     287    for each (let filter in this._filters)
    388288        passesFilters = passesFilters && filter.func(ent);
    389     }
    390289
    391290    if (passesFilters)
    392291    {
     
    395294        return this.addEnt(ent);
    396295    }
    397296    else
    398     {
    399297        return this.removeEnt(ent);
    400     }
    401298};
    402299
    403300m.EntityCollection.prototype.registerUpdates = function()
     
    413310m.EntityCollection.prototype.dynamicProperties = function()
    414311{
    415312    var ret = [];
    416     for each (var filter in this._filters)
    417     {
     313    for each (let filter in this._filters)
    418314        ret = ret.concat(filter.dynamicProperties);
    419     }
    420315
    421316    return ret;
    422317};
  • binaries/data/mods/public/simulation/ai/common-api/gamestate.js

     
    365365        return ent.owner === this.player;
    366366};
    367367
    368 m.GameState.prototype.getEntityById = function(id){
    369     if (this.entities._entities[id])
    370         return this.entities._entities[id];
     368m.GameState.prototype.getEntityById = function(id)
     369{
     370    if (this.entities._entities.has(+id))
     371        return this.entities._entities.get(+id);
    371372
    372373    return undefined;
    373374};
  • binaries/data/mods/public/simulation/ai/common-api/shared.js

     
    4242{
    4343    // serializing entities without using the class.
    4444    var entities = [];
    45     for each (let ent in this._entities)
     45    for (let ent of this._entities.values())
    4646        entities.push( ent._entity );
    4747
    4848    return {
     
    6666    this._entityMetadata = data.metadata;
    6767    this._derivedTemplates = {};
    6868
    69     this._entities = {};
     69    this._entities = new Map();
    7070    for (let ent of data.entities)
    71         this._entities[ent.id] = new m.Entity(this, ent);
     71        this._entities.set(ent.id, new m.Entity(this, ent));
    7272
    7373    this.isDeserialized = true;
    7474};
     
    152152
    153153    if (!deserialization)
    154154    {
    155         this._entities = {};
     155        this._entities = new Map();
    156156        for (var id in state.entities)
    157             this._entities[id] = new m.Entity(this, state.entities[id]);
     157            this._entities.set(+id, new m.Entity(this, state.entities[id]));
    158158    }
    159159    // entity collection updated on create/destroy event.
    160160    this.entities = new m.EntityCollection(this, this._entities);
     
    233233        if (!state.entities[evt.entity])
    234234            continue; // Sometimes there are things like foundations which get destroyed too fast
    235235
    236         this._entities[evt.entity] = new m.Entity(this, state.entities[evt.entity]);
    237         this.entities.addEnt(this._entities[evt.entity]);
     236        let entity = new m.Entity(this, state.entities[evt.entity]);
     237        this._entities.set(evt.entity, entity);
     238        this.entities.addEnt(entity);
    238239       
    239240        // Update all the entity collections since the create operation affects static properties as well as dynamic
    240241        for (let entCol of this._entityCollections.values())
    241             entCol.updateEnt(this._entities[evt.entity]);
     242            entCol.updateEnt(entity);
    242243    }
    243244    for (var i in RenamingEvents)
    244245    {
     
    254255    {
    255256        var evt = TrainingEvents[i];
    256257        // Apply metadata stored in training queues
    257         for each (var ent in evt.entities)
    258         {
    259             for (var key in evt.metadata)
    260             {
    261                 this.setMetadata(evt.owner, this._entities[ent], key, evt.metadata[key])
    262             }
    263         }
     258        for each (let entId in evt.entities)
     259            for (let key in evt.metadata)
     260                this.setMetadata(evt.owner, this._entities.get(entId), key, evt.metadata[key])
    264261    }
    265262    for (var i in ConstructionEvents)
    266263    {
    267264        var evt = ConstructionEvents[i];
    268265        // we'll move metadata.
    269         if (!this._entities[evt.entity])
     266        if (!this._entities.has(evt.entity))
    270267            continue;
    271         var ent = this._entities[evt.entity];
    272         var newEnt = this._entities[evt.newentity];
     268        var ent = this._entities.get(evt.entity);
     269        var newEnt = this._entities.get(evt.newentity);
    273270        if (this._entityMetadata[ent.owner()] && this._entityMetadata[ent.owner()][evt.entity] !== undefined)
    274271            for (var key in this._entityMetadata[ent.owner()][evt.entity])
    275             {
    276272                this.setMetadata(ent.owner(), newEnt, key, this._entityMetadata[ent.owner()][evt.entity][key])
    277             }
    278273        foundationFinished[evt.entity] = true;
    279274    }
    280275    for (var i in MetadataEvents)
    281276    {
    282277        var evt = MetadataEvents[i];
    283         if (!this._entities[evt.id])
     278        if (!this._entities.has(evt.id))
    284279            continue;   // might happen in some rare cases of foundations getting destroyed, perhaps.
    285280                        // Apply metadata (here for buildings for example)
    286281        for (var key in evt.metadata)
    287         {
    288             this.setMetadata(evt.owner, this._entities[evt.id], key, evt.metadata[key])
    289         }
     282            this.setMetadata(evt.owner, this._entities.get(evt.id), key, evt.metadata[key])
    290283    }
    291284   
    292285    for (var i = 0; i < DestroyEvents.length; ++i)
     
    296289        // the "deleted" object remains in memory, and any older reference to it will still reference it as if it were not "deleted".
    297290        // Worse, they might prevent it from being garbage collected, thus making it stay alive and consuming ram needlessly.
    298291        // So take care, and if you encounter a weird bug with deletion not appearing to work correctly, this is probably why.
    299         if (!this._entities[evt.entity])
     292        if (!this._entities.has(evt.entity))
    300293            continue;// probably should remove the event.
    301294
    302295        if (foundationFinished[evt.entity])
     
    305298        // The entity was destroyed but its data may still be useful, so
    306299        // remember the entity and this AI's metadata concerning it
    307300        evt.metadata = {};
    308         evt.entityObj = this._entities[evt.entity];
     301        evt.entityObj = this._entities.get(evt.entity);
    309302        for (var j in this._players)
    310303            evt.metadata[this._players[j]] = this._entityMetadata[this._players[j]][evt.entity];
    311304       
     305        let entity = this._entities.get(evt.entity);
    312306        for (let entCol of this._entityCollections.values())
    313             entCol.removeEnt(this._entities[evt.entity]);
    314         this.entities.removeEnt(this._entities[evt.entity]);
     307            entCol.removeEnt(entity);
     308        this.entities.removeEnt(entity);
    315309       
    316         delete this._entities[evt.entity];
     310        this._entities.delete(evt.entity);
    317311        for (var j in this._players)
    318312            delete this._entityMetadata[this._players[j]][evt.entity];
    319313    }
    320314
    321     for (var id in state.entities)
     315    for (let id in state.entities)
    322316    {
    323         var changes = state.entities[id];
    324 
    325         for (var prop in changes)
     317        let changes = state.entities[id];
     318        let entity = this._entities.get(+id);
     319        for (let prop in changes)
    326320        {
    327             this._entities[id]._entity[prop] = changes[prop];
    328            
    329             this.updateEntityCollections(prop, this._entities[id]);
     321            entity._entity[prop] = changes[prop];
     322            this.updateEntityCollections(prop, entity);
    330323        }
    331324    }
    332325
     
    334327    // this supersedes tech-related changes.
    335328    for (var id in state.changedEntityTemplateInfo)
    336329    {
    337         if (!this._entities[id])
     330        if (!this._entities.has(+id))
    338331            continue;   // dead, presumably.
    339332        var changes = state.changedEntityTemplateInfo[id];
     333        let entity = this._entities.get(+id);
    340334        for each (var change in changes)
    341             this._entities[id]._auraTemplateModif.set(change.variable, change.value);
     335            entity._auraTemplateModif.set(change.variable, change.value);
    342336    }
    343337    Engine.ProfileStop();
    344338};
  • binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js

     
    6464    var x = 0;
    6565    var y = 0;
    6666    var radius = 0;
    67     for (var entI in sharedScript._entities)
     67    for (let ent of sharedScript._entities.values())
    6868    {
    69         var ent = sharedScript._entities[entI];
    7069        if (ent.hasClass("ForestPlant") === true) {
    7170            pos = this.gamePosToMapPos(ent.position());
    7271            x = pos[0];
     
    700699            this.CCResourceMaps[resource].setMaxVal(255);
    701700        }
    702701    }
    703     for (var entI in sharedScript._entities)
     702    for (let ent of sharedScript._entities.values())
    704703    {
    705         var ent = sharedScript._entities[entI];
    706704        if (ent && ent.position() && ent.resourceSupplyType() && ent.resourceSupplyType().generic !== "treasure") {
    707705            var resource = ent.resourceSupplyType().generic;
    708706            var x = Math.floor(ent.position()[0] / 4);
     
    777775    }
    778776    for (var key in createEvents) {
    779777        var e = createEvents[key];
    780         if (e.entity){
    781             var ent = sharedScript._entities[e.entity];
     778        if (e.entity && sharedScript._entities.has(e.entity)){
     779            var ent = sharedScript._entities.get(e.entity);
    782780            if (ent && ent.position() && ent.resourceSupplyType() && ent.resourceSupplyType().generic !== "treasure"){
    783781                var resource = ent.resourceSupplyType().generic;
    784782               
  • binaries/data/mods/public/simulation/ai/petra/attackPlan.js

     
    228228    {
    229229        var moreAdvanced = undefined;
    230230        var enemyWonder = undefined;
    231         var wonders = gameState.getEnemyStructures().filter(API3.Filters.byClass("Wonder")).toEntityArray();
    232         for (var wonder of wonders)
     231        var wonders = gameState.getEnemyStructures().filter(API3.Filters.byClass("Wonder"));
     232        for (var wonder of wonders.values())
    233233        {
    234234            var progress = wonder.foundationProgress();
    235235            if (progress === undefined)
     
    12591259            if (this.isSiegeUnit(gameState, ourUnit))
    12601260            {
    12611261                // if siege units are attacked, we'll send some units to deal with enemies.
    1262                 var collec = this.unitCollection.filter(API3.Filters.not(API3.Filters.byClass("Siege"))).filterNearest(ourUnit.position(), 5).toEntityArray();
    1263                 for (var ent of collec)
     1262                var collec = this.unitCollection.filter(API3.Filters.not(API3.Filters.byClass("Siege"))).filterNearest(ourUnit.position(), 5);
     1263                for (var ent of collec.values())
    12641264                    if (!this.isSiegeUnit(gameState, ent))
    12651265                    {
    12661266                        ent.attack(attacker.id());
  • binaries/data/mods/public/simulation/ai/petra/baseManager.js

     
    934934        if(owner != 0 && !gameState.isPlayerAlly(owner))
    935935        {
    936936            // we're in enemy territory. If we're too close from the enemy, destroy us.
    937             var eEnts = gameState.getEnemyStructures().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
    938             for (var i in eEnts)
     937            var eEnts = gameState.getEnemyStructures().filter(API3.Filters.byClass("CivCentre"));
     938            for (var eEnt of eEnts.values())
    939939            {
    940                 var entPos = eEnts[i].position();
     940                var entPos = eEnt.position();
    941941                if (API3.SquareVectorDistance(entPos, this.anchor.position()) < 8000)
     942                {
    942943                    this.anchor.destroy();
     944                    break;
     945                }
    943946            }
    944947        }
    945948    }
  • binaries/data/mods/public/simulation/ai/petra/defenseManager.js

     
    6969        }
    7070        else if (target && target.hasClass("CivCentre"))
    7171        {
    72             var myBuildings = gameState.getOwnStructures().toEntityArray();
    73             for (let building of myBuildings)
     72            var myBuildings = gameState.getOwnStructures();
     73            for (let building of myBuildings.values())
    7474            {
    7575                if (API3.SquareVectorDistance(building.position(), entity.position()) > 30000)
    7676                    continue;
     
    9494
    9595    if (this.Config.personality.cooperative > 0.3)
    9696    {
    97         let ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray();
    98         for (let cc of ccEnts)
     97        let ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre"));
     98        for (let cc of ccEnts.values())
    9999        {
    100100            if (!gameState.isEntityExclusiveAlly(cc))
    101101                continue;
     
    106106        }
    107107    }
    108108
    109     var myBuildings = gameState.getOwnStructures().toEntityArray();
    110     for (let building of myBuildings)
     109    var myBuildings = gameState.getOwnStructures();
     110    for (let building of myBuildings.values())
    111111    {
    112112        if (building.foundationProgress() == 0)
    113113            continue;
     
    209209        // army in neutral territory // TODO check smaller distance with all our buildings instead of only ccs with big distance
    210210        var stillDangerous = false;
    211211        if (this.Config.personality.cooperative > 0.3)
    212             var bases = gameState.getAllyEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
     212            var bases = gameState.getAllyEntities().filter(API3.Filters.byClass("CivCentre"));
    213213        else
    214             var bases = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
    215         for (var i in bases)
     214            var bases = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre"));
     215        for (let base of bases.values())
    216216        {
    217             if (API3.SquareVectorDistance(bases[i].position(), army.foePosition) < 40000)
     217            if (API3.SquareVectorDistance(base.position(), army.foePosition) < 40000)
    218218            {
    219219                if(this.Config.debug > 1)
    220220                    API3.warn("army in neutral territory, but still near one of our CC");
  • binaries/data/mods/public/simulation/ai/petra/headquarters.js

     
    779779    var obstructions = m.createObstructionMap(gameState, 0, template);
    780780    obstructions.expandInfluences();
    781781
    782     var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray();
    783     var dpEnts = gameState.getOwnDropsites().filter(API3.Filters.not(API3.Filters.byClassesOr(["CivCentre", "Elephant"]))).toEntityArray();
     782    var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre"));
     783    var dpEnts = gameState.getOwnDropsites().filter(API3.Filters.not(API3.Filters.byClassesOr(["CivCentre", "Elephant"])));
    784784    var ccList = [];
    785     for (var cc of ccEnts)
     785    for (var cc of ccEnts.values())
    786786        ccList.push({"pos": cc.position(), "ally": gameState.isPlayerAlly(cc.owner())});
    787787    var dpList = [];
    788     for (var dp of dpEnts)
     788    for (var dp of dpEnts.values())
    789789        dpList.push({"pos": dp.position()});
    790790
    791791    var width = this.territoryMap.width;
     
    918918    // with the constraints that all CC have dist > 200 and at least one have dist < 400
    919919    // This needs at least 2 CC. Otherwise, go back to economic CC.
    920920
    921     var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray();
     921    var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre"));
    922922    var ccList = [];
    923923    var numAllyCC = 0;
    924     for (var cc of ccEnts)
     924    for (var cc of ccEnts.values())
    925925    {
    926926        var ally = gameState.isPlayerAlly(cc.owner());
    927927        ccList.push({"pos": cc.position(), "ally": ally});