Ticket #2370: ECasMaps.diff
File ECasMaps.diff, 26.2 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/simulation/ai/common-api/entity.js
680 680 var ress = undefined; 681 681 // this is an abuse of "_ai" but it works. 682 682 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"]); 684 684 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"]); 686 686 687 687 if (ress == undefined) 688 688 return undefined; -
binaries/data/mods/public/simulation/ai/common-api/entitycollection.js
4 4 m.EntityCollection = function(sharedAI, entities, filters) 5 5 { 6 6 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(); 8 15 this._filters = filters || []; 9 16 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 be14 // expensive for large collections15 this._length = undefined;16 17 Object.defineProperty(this, "length", { 17 18 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; 25 20 } 26 21 }); 27 22 this.frozen = false; … … 35 30 return { 36 31 "ents": this.toIdArray(), 37 32 "frozen": this.frozen, 38 "quickIter": this._quickIter,39 33 "filters": filters 40 34 }; 41 35 }; … … 43 37 m.EntityCollection.prototype.Deserialize = function(data, sharedAI) 44 38 { 45 39 this._ai = sharedAI; 46 for each (var id indata.ents)47 this._entities [id] = sharedAI._entities[id];40 for (let id of data.ents) 41 this._entities.set(id, sharedAI._entities.get(id)); 48 42 49 for each (var f indata.filters)43 for (let f of data.filters) 50 44 this._filters.push(eval(f)); 51 45 52 46 if (data.frozen) … … 53 47 this.freeze; 54 48 else 55 49 this.defreeze; 56 57 if (data.quickIter)58 this.allowQuickIter();59 else60 this.preventQuickIter();61 50 }; 62 51 63 52 // If an entitycollection is frozen, it will never automatically add a unit. … … 75 64 76 65 m.EntityCollection.prototype.allowQuickIter = function() 77 66 { 78 this._quickIter = true; 79 this._entitiesArray = []; 80 for each (var ent in this._entities) 81 this._entitiesArray.push(ent); 67 return; 82 68 }; 83 69 84 70 m.EntityCollection.prototype.preventQuickIter = function() 85 71 { 86 this._quickIter = false; 87 this._entitiesArray = undefined; 72 return; 88 73 }; 89 74 90 75 m.EntityCollection.prototype.toIdArray = function() 91 76 { 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; 93 81 }; 94 82 95 83 m.EntityCollection.prototype.toEntityArray = function() 96 84 { 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()) 101 87 ret.push(ent); 102 88 return ret; 103 89 }; 104 90 91 m.EntityCollection.prototype.values = function() 92 { 93 return this._entities.values(); 94 }; 95 105 96 m.EntityCollection.prototype.toString = function() 106 97 { 107 98 return "[EntityCollection " + this.toEntityArray().join(" ") + "]"; 108 99 }; 109 100 101 m.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 110 114 /** 111 115 * Returns the (at most) n entities nearest to targetPos. 112 116 */ … … 113 117 m.EntityCollection.prototype.filterNearest = function(targetPos, n) 114 118 { 115 119 // 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())]); 134 124 135 125 // Sort by increasing distance 136 126 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); 137 131 138 132 // 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]); 143 136 144 137 return new m.EntityCollection(this._ai, ret); 145 138 }; 146 139 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 174 140 m.EntityCollection.prototype.filter_raw = function(callback, thisp) 175 141 { 176 var ret = {};177 for ( var id inthis._entities)142 var ret = new Map(); 143 for (let [id, ent] of this._entities) 178 144 { 179 var ent = this._entities[id]; 180 var val = this._entities[id]._entity; 145 let val = ent._entity; 181 146 if (callback.call(thisp, val, id, this)) 182 ret [id] = ent;147 ret.set(id, ent); 183 148 } 184 149 return new m.EntityCollection(this._ai, ret); 185 150 }; … … 186 151 187 152 m.EntityCollection.prototype.forEach = function(callback) 188 153 { 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); 198 156 return this; 199 157 }; 200 158 201 m.EntityCollection.prototype.filterNearest = function(targetPos, n)202 {203 // Compute the distance of each entity204 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 distance213 data.sort(function (a, b) { return (a[2] - b[2]); });214 if (n === undefined)215 n = this._length;216 // Extract the first n217 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 224 159 m.EntityCollection.prototype.move = function(x, z, queued) 225 160 { 226 161 queued = queued || false; … … 238 173 m.EntityCollection.prototype.moveIndiv = function(x, z, queued) 239 174 { 240 175 queued = queued || false; 241 for ( var id in this._entities)176 for (let id of this._entities.keys()) 242 177 { 243 178 // The following try {} finally {} block is a workaround for OOS problems in multiplayer games with AI players (check ticket #2000). 244 179 // It disables JIT compiling of this loop. Don't remove it unless you are sure that the underlying issue has been resolved! 245 180 // TODO: Check this again after the SpiderMonkey upgrade. 246 181 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}); 248 183 } 249 184 return this; 250 185 }; … … 265 200 { 266 201 var unitId; 267 202 if (typeof(unit) === "Entity") 268 {269 203 unitId = unit.id(); 270 }271 204 else 272 {273 205 unitId = unit; 274 }275 206 Engine.PostCommand(PlayerID,{"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false}); 276 207 return this; 277 208 }; … … 288 219 { 289 220 var sumPos = [0, 0]; 290 221 var count = 0; 291 this.forEach(function(ent)222 for (let ent of this._entities.values()) 292 223 { 293 if ( ent.position())294 {295 296 297 298 299 }); 224 if (!ent.position()) 225 continue; 226 sumPos[0] += ent.position()[0]; 227 sumPos[1] += ent.position()[1]; 228 count ++; 229 } 230 300 231 if (count === 0) 301 {302 232 return undefined; 303 }304 233 else 305 {306 234 return [sumPos[0]/count, sumPos[1]/count]; 307 }308 235 }; 309 236 310 237 // returns the average position from the sample first units. … … 314 241 { 315 242 var sumPos = [0, 0]; 316 243 var i = 0; 317 for ( var id in this._entities)244 for (let ent of this._entities.values()) 318 245 { 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++; 326 251 if (i === sample) 327 252 break; 328 253 } 329 if (sample === 0) 330 { 254 if (i === 0) 331 255 return undefined; 332 }333 256 else 334 {335 257 return [sumPos[0]/i, sumPos[1]/i]; 336 }337 258 }; 338 259 339 260 … … 340 261 // Removes an entity from the collection, returns true if the entity was a member, false otherwise 341 262 m.EntityCollection.prototype.removeEnt = function(ent) 342 263 { 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())) 355 265 return false; 356 } 266 this._entities.delete(ent.id()); 267 return true; 357 268 }; 358 269 359 270 // Adds an entity to the collection, returns true if the entity was not member, false otherwise 360 271 m.EntityCollection.prototype.addEnt = function(ent) 361 272 { 362 if (this._entities[ent.id()]) 363 { 273 if (this._entities.has(ent.id())) 364 274 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; 376 277 }; 377 278 378 279 // Checks the entity against the filters, and adds or removes it appropriately, returns true if the … … 383 284 m.EntityCollection.prototype.updateEnt = function(ent, force) 384 285 { 385 286 var passesFilters = true; 386 for each (var filter in this._filters) 387 { 287 for each (let filter in this._filters) 388 288 passesFilters = passesFilters && filter.func(ent); 389 }390 289 391 290 if (passesFilters) 392 291 { … … 395 294 return this.addEnt(ent); 396 295 } 397 296 else 398 {399 297 return this.removeEnt(ent); 400 }401 298 }; 402 299 403 300 m.EntityCollection.prototype.registerUpdates = function() … … 413 310 m.EntityCollection.prototype.dynamicProperties = function() 414 311 { 415 312 var ret = []; 416 for each (var filter in this._filters) 417 { 313 for each (let filter in this._filters) 418 314 ret = ret.concat(filter.dynamicProperties); 419 }420 315 421 316 return ret; 422 317 }; -
binaries/data/mods/public/simulation/ai/common-api/gamestate.js
365 365 return ent.owner === this.player; 366 366 }; 367 367 368 m.GameState.prototype.getEntityById = function(id){ 369 if (this.entities._entities[id]) 370 return this.entities._entities[id]; 368 m.GameState.prototype.getEntityById = function(id) 369 { 370 if (this.entities._entities.has(+id)) 371 return this.entities._entities.get(+id); 371 372 372 373 return undefined; 373 374 }; -
binaries/data/mods/public/simulation/ai/common-api/shared.js
42 42 { 43 43 // serializing entities without using the class. 44 44 var entities = []; 45 for each (let ent in this._entities)45 for (let ent of this._entities.values()) 46 46 entities.push( ent._entity ); 47 47 48 48 return { … … 66 66 this._entityMetadata = data.metadata; 67 67 this._derivedTemplates = {}; 68 68 69 this._entities = {};69 this._entities = new Map(); 70 70 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)); 72 72 73 73 this.isDeserialized = true; 74 74 }; … … 152 152 153 153 if (!deserialization) 154 154 { 155 this._entities = {};155 this._entities = new Map(); 156 156 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])); 158 158 } 159 159 // entity collection updated on create/destroy event. 160 160 this.entities = new m.EntityCollection(this, this._entities); … … 233 233 if (!state.entities[evt.entity]) 234 234 continue; // Sometimes there are things like foundations which get destroyed too fast 235 235 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); 238 239 239 240 // Update all the entity collections since the create operation affects static properties as well as dynamic 240 241 for (let entCol of this._entityCollections.values()) 241 entCol.updateEnt( this._entities[evt.entity]);242 entCol.updateEnt(entity); 242 243 } 243 244 for (var i in RenamingEvents) 244 245 { … … 254 255 { 255 256 var evt = TrainingEvents[i]; 256 257 // 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]) 264 261 } 265 262 for (var i in ConstructionEvents) 266 263 { 267 264 var evt = ConstructionEvents[i]; 268 265 // we'll move metadata. 269 if (!this._entities [evt.entity])266 if (!this._entities.has(evt.entity)) 270 267 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); 273 270 if (this._entityMetadata[ent.owner()] && this._entityMetadata[ent.owner()][evt.entity] !== undefined) 274 271 for (var key in this._entityMetadata[ent.owner()][evt.entity]) 275 {276 272 this.setMetadata(ent.owner(), newEnt, key, this._entityMetadata[ent.owner()][evt.entity][key]) 277 }278 273 foundationFinished[evt.entity] = true; 279 274 } 280 275 for (var i in MetadataEvents) 281 276 { 282 277 var evt = MetadataEvents[i]; 283 if (!this._entities [evt.id])278 if (!this._entities.has(evt.id)) 284 279 continue; // might happen in some rare cases of foundations getting destroyed, perhaps. 285 280 // Apply metadata (here for buildings for example) 286 281 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]) 290 283 } 291 284 292 285 for (var i = 0; i < DestroyEvents.length; ++i) … … 296 289 // the "deleted" object remains in memory, and any older reference to it will still reference it as if it were not "deleted". 297 290 // Worse, they might prevent it from being garbage collected, thus making it stay alive and consuming ram needlessly. 298 291 // 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)) 300 293 continue;// probably should remove the event. 301 294 302 295 if (foundationFinished[evt.entity]) … … 305 298 // The entity was destroyed but its data may still be useful, so 306 299 // remember the entity and this AI's metadata concerning it 307 300 evt.metadata = {}; 308 evt.entityObj = this._entities [evt.entity];301 evt.entityObj = this._entities.get(evt.entity); 309 302 for (var j in this._players) 310 303 evt.metadata[this._players[j]] = this._entityMetadata[this._players[j]][evt.entity]; 311 304 305 let entity = this._entities.get(evt.entity); 312 306 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); 315 309 316 delete this._entities[evt.entity];310 this._entities.delete(evt.entity); 317 311 for (var j in this._players) 318 312 delete this._entityMetadata[this._players[j]][evt.entity]; 319 313 } 320 314 321 for ( varid in state.entities)315 for (let id in state.entities) 322 316 { 323 varchanges = state.entities[id];324 325 for ( varprop in changes)317 let changes = state.entities[id]; 318 let entity = this._entities.get(+id); 319 for (let prop in changes) 326 320 { 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); 330 323 } 331 324 } 332 325 … … 334 327 // this supersedes tech-related changes. 335 328 for (var id in state.changedEntityTemplateInfo) 336 329 { 337 if (!this._entities [id])330 if (!this._entities.has(+id)) 338 331 continue; // dead, presumably. 339 332 var changes = state.changedEntityTemplateInfo[id]; 333 let entity = this._entities.get(+id); 340 334 for each (var change in changes) 341 this._entities[id]._auraTemplateModif.set(change.variable, change.value);335 entity._auraTemplateModif.set(change.variable, change.value); 342 336 } 343 337 Engine.ProfileStop(); 344 338 }; -
binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js
64 64 var x = 0; 65 65 var y = 0; 66 66 var radius = 0; 67 for ( var entI in sharedScript._entities)67 for (let ent of sharedScript._entities.values()) 68 68 { 69 var ent = sharedScript._entities[entI];70 69 if (ent.hasClass("ForestPlant") === true) { 71 70 pos = this.gamePosToMapPos(ent.position()); 72 71 x = pos[0]; … … 700 699 this.CCResourceMaps[resource].setMaxVal(255); 701 700 } 702 701 } 703 for ( var entI in sharedScript._entities)702 for (let ent of sharedScript._entities.values()) 704 703 { 705 var ent = sharedScript._entities[entI];706 704 if (ent && ent.position() && ent.resourceSupplyType() && ent.resourceSupplyType().generic !== "treasure") { 707 705 var resource = ent.resourceSupplyType().generic; 708 706 var x = Math.floor(ent.position()[0] / 4); … … 777 775 } 778 776 for (var key in createEvents) { 779 777 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); 782 780 if (ent && ent.position() && ent.resourceSupplyType() && ent.resourceSupplyType().generic !== "treasure"){ 783 781 var resource = ent.resourceSupplyType().generic; 784 782 -
binaries/data/mods/public/simulation/ai/petra/attackPlan.js
228 228 { 229 229 var moreAdvanced = undefined; 230 230 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()) 233 233 { 234 234 var progress = wonder.foundationProgress(); 235 235 if (progress === undefined) … … 1259 1259 if (this.isSiegeUnit(gameState, ourUnit)) 1260 1260 { 1261 1261 // 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()) 1264 1264 if (!this.isSiegeUnit(gameState, ent)) 1265 1265 { 1266 1266 ent.attack(attacker.id()); -
binaries/data/mods/public/simulation/ai/petra/baseManager.js
934 934 if(owner != 0 && !gameState.isPlayerAlly(owner)) 935 935 { 936 936 // 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()) 939 939 { 940 var entPos = eEnt s[i].position();940 var entPos = eEnt.position(); 941 941 if (API3.SquareVectorDistance(entPos, this.anchor.position()) < 8000) 942 { 942 943 this.anchor.destroy(); 944 break; 945 } 943 946 } 944 947 } 945 948 } -
binaries/data/mods/public/simulation/ai/petra/defenseManager.js
69 69 } 70 70 else if (target && target.hasClass("CivCentre")) 71 71 { 72 var myBuildings = gameState.getOwnStructures() .toEntityArray();73 for (let building of myBuildings )72 var myBuildings = gameState.getOwnStructures(); 73 for (let building of myBuildings.values()) 74 74 { 75 75 if (API3.SquareVectorDistance(building.position(), entity.position()) > 30000) 76 76 continue; … … 94 94 95 95 if (this.Config.personality.cooperative > 0.3) 96 96 { 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()) 99 99 { 100 100 if (!gameState.isEntityExclusiveAlly(cc)) 101 101 continue; … … 106 106 } 107 107 } 108 108 109 var myBuildings = gameState.getOwnStructures() .toEntityArray();110 for (let building of myBuildings )109 var myBuildings = gameState.getOwnStructures(); 110 for (let building of myBuildings.values()) 111 111 { 112 112 if (building.foundationProgress() == 0) 113 113 continue; … … 209 209 // army in neutral territory // TODO check smaller distance with all our buildings instead of only ccs with big distance 210 210 var stillDangerous = false; 211 211 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")); 213 213 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()) 216 216 { 217 if (API3.SquareVectorDistance(base s[i].position(), army.foePosition) < 40000)217 if (API3.SquareVectorDistance(base.position(), army.foePosition) < 40000) 218 218 { 219 219 if(this.Config.debug > 1) 220 220 API3.warn("army in neutral territory, but still near one of our CC"); -
binaries/data/mods/public/simulation/ai/petra/headquarters.js
779 779 var obstructions = m.createObstructionMap(gameState, 0, template); 780 780 obstructions.expandInfluences(); 781 781 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"]))); 784 784 var ccList = []; 785 for (var cc of ccEnts )785 for (var cc of ccEnts.values()) 786 786 ccList.push({"pos": cc.position(), "ally": gameState.isPlayerAlly(cc.owner())}); 787 787 var dpList = []; 788 for (var dp of dpEnts )788 for (var dp of dpEnts.values()) 789 789 dpList.push({"pos": dp.position()}); 790 790 791 791 var width = this.territoryMap.width; … … 918 918 // with the constraints that all CC have dist > 200 and at least one have dist < 400 919 919 // This needs at least 2 CC. Otherwise, go back to economic CC. 920 920 921 var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")) .toEntityArray();921 var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")); 922 922 var ccList = []; 923 923 var numAllyCC = 0; 924 for (var cc of ccEnts )924 for (var cc of ccEnts.values()) 925 925 { 926 926 var ally = gameState.isPlayerAlly(cc.owner()); 927 927 ccList.push({"pos": cc.position(), "ally": ally});