Index: binaries/data/mods/public/simulation/ai/common-api/entity.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api/entity.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/common-api/entity.js	(copie de travail)
@@ -680,9 +680,9 @@
 			var ress = undefined;
 			// this is an abuse of "_ai" but it works.
 			if (this.unitAIState().split(".")[1] === "GATHER" && this.unitAIOrderData()[0]["target"] !== undefined)
-				ress = this._ai._entities[this.unitAIOrderData()[0]["target"]];
+				ress = this._ai._entities.get(this.unitAIOrderData()[0]["target"]);
 			else if (this.unitAIOrderData()[1] !== undefined && this.unitAIOrderData()[1]["target"] !== undefined)
-				ress = this._ai._entities[this.unitAIOrderData()[1]["target"]];
+				ress = this._ai._entities.get(this.unitAIOrderData()[1]["target"]);
 
 			if (ress == undefined)
 				return undefined;
Index: binaries/data/mods/public/simulation/ai/common-api/entitycollection.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api/entitycollection.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/common-api/entitycollection.js	(copie de travail)
@@ -4,24 +4,19 @@
 m.EntityCollection = function(sharedAI, entities, filters)
 {
 	this._ai = sharedAI;
-	this._entities = entities || {};
+	if (entities && !(entities instanceof Map))
+	{
+		this._entities = new Map();
+		for (let key in entities)
+			this._entities.set(+key, entities[key]);
+	}
+	else
+		this._entities = entities || new Map();
 	this._filters = filters || [];
 	
-	this._quickIter = false;	// will make the entity collection store an array (not associative) of entities used when calling "foreach".
-	// probably should not be usde for very dynamic entity collections.
-
-	// Compute length lazily on demand, since it can be
-	// expensive for large collections
-	this._length = undefined;
 	Object.defineProperty(this, "length", {
 		get: function () {
-			if (this._length === undefined)
-			{
-				this._length = 0;
-				for (var id in entities)
-					++this._length;
-			}
-			return this._length;
+			return this._entities.size;
 		}
 	});
 	this.frozen = false;
@@ -35,7 +30,6 @@
 	return {
 		"ents": this.toIdArray(),
 		"frozen": this.frozen,
-		"quickIter": this._quickIter,
 		"filters": filters
 	};
 };
@@ -43,10 +37,10 @@
 m.EntityCollection.prototype.Deserialize = function(data, sharedAI)
 {
 	this._ai = sharedAI;
-	for each (var id in data.ents)
-		this._entities[id] = sharedAI._entities[id];
+	for (let id of data.ents)
+		this._entities.set(id, sharedAI._entities.get(id));
 
-	for each (var f in data.filters)
+	for (let f of data.filters)
 		this._filters.push(eval(f));
 
 	if (data.frozen)
@@ -53,11 +47,6 @@
 		this.freeze;
 	else
 		this.defreeze;
-
-	if (data.quickIter)
-		this.allowQuickIter();
-	else
-		this.preventQuickIter();
 };
 
 // If an entitycollection is frozen, it will never automatically add a unit.
@@ -75,38 +64,53 @@
 
 m.EntityCollection.prototype.allowQuickIter = function()
 {
-	this._quickIter = true;
-	this._entitiesArray = [];
-	for each (var ent in this._entities)
-		this._entitiesArray.push(ent);
+	return;
 };
 
 m.EntityCollection.prototype.preventQuickIter = function()
 {
-	this._quickIter = false;
-	this._entitiesArray = undefined;
+	return;
 };
 
 m.EntityCollection.prototype.toIdArray = function()
 {
-	return Object.keys(this._entities).map(function(n){return +n;});
+	let ret = [];
+	for (let id of this._entities.keys())
+		ret.push(id);
+	return ret;
 };
 
 m.EntityCollection.prototype.toEntityArray = function()
 {
-	if (this._quickIter === true)
-		return this._entitiesArray;
-	var ret = [];
-	for each (var ent in this._entities)
+	let ret = [];
+	for (let ent of this._entities.values())
 		ret.push(ent);
 	return ret;
 };
 
+m.EntityCollection.prototype.values = function()
+{
+	return this._entities.values();
+};
+
 m.EntityCollection.prototype.toString = function()
 {
 	return "[EntityCollection " + this.toEntityArray().join(" ") + "]";
 };
 
+m.EntityCollection.prototype.filter = function(filter, thisp)
+{
+	if (typeof(filter) == "function")
+		filter = {"func": filter, "dynamicProperties": []};
+	
+	var ret = new Map();
+	for (let [id, ent] of this._entities)
+		if (filter.func.call(thisp, ent, id, this))
+			ret.set(id, ent);
+	
+	return new m.EntityCollection(this._ai, ret, this._filters.concat([filter]));
+};
+
 /**
  * Returns the (at most) n entities nearest to targetPos.
  */
@@ -113,73 +117,34 @@
 m.EntityCollection.prototype.filterNearest = function(targetPos, n)
 {
 	// Compute the distance of each entity
-	var data = []; // [id, ent, distance]
-	
-	if (this._quickIter === true)
-	{
-		for (var i in this._entitiesArray)
-		{
-			var ent = this._entitiesArray[i];
-			if (ent.position() !== -1)
-				data.push([ent.id(), ent, m.SquareVectorDistance(targetPos, ent.position())]);
-		}
-	} else {
-		for (var id in this._entities)
-		{
-			var ent = this._entities[id];
-			if (ent.position() !== -1)
-				data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
-		}
-	}
+	var data = []; // [ [id, ent, distance], ... ]
+	for (let [id, ent] of this._entities)
+		if (ent.position())
+			data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
 
 	// Sort by increasing distance
 	data.sort(function (a, b) { return (a[2] - b[2]); });
+	if (n === undefined)
+		n = data.length;
+	else
+		n = Math.min(n, data.length);
 
 	// Extract the first n
-	var ret = {};
-	var length = Math.min(n, entData.length);
-	for (var i = 0; i < length; ++i)
-		ret[data[i][0]] = data[i][1];
+	let ret = new Map();
+	for (let i = 0; i < n; ++i)
+		ret.set(data[i][0], data[i][1]);
 
 	return new m.EntityCollection(this._ai, ret);
 };
 
-m.EntityCollection.prototype.filter = function(filter, thisp)
-{
-	if (typeof(filter) == "function")
-		filter = {"func": filter, "dynamicProperties": []};
-	
-	var ret = {};
-	if (this._quickIter === true)
-	{
-		for (var i in this._entitiesArray)
-		{
-			var ent = this._entitiesArray[i];
-			var id = ent.id();
-			if (filter.func.call(thisp, ent, id, this))
-				ret[id] = ent;
-		}
-	} else {
-		for (var id in this._entities)
-		{
-			var ent = this._entities[id];
-			if (filter.func.call(thisp, ent, id, this))
-				ret[id] = ent;
-		}
-	}
-	
-	return new m.EntityCollection(this._ai, ret, this._filters.concat([filter]));
-};
-
 m.EntityCollection.prototype.filter_raw = function(callback, thisp)
 {
-	var ret = {};
-	for (var id in this._entities)
+	var ret = new Map();
+	for (let [id, ent] of this._entities)
 	{
-		var ent = this._entities[id];
-		var val = this._entities[id]._entity;
+		let val = ent._entity;
 		if (callback.call(thisp, val, id, this))
-			ret[id] = ent;
+			ret.set(id, ent);
 	}
 	return new m.EntityCollection(this._ai, ret);
 };
@@ -186,41 +151,11 @@
 
 m.EntityCollection.prototype.forEach = function(callback)
 {
-	if (this._quickIter === true)
-	{
-		this._entitiesArray.forEach(callback);
-		return this;
-	}
-	for (var id in this._entities)
-	{
-		callback(this._entities[id]);
-	}
+	for (let ent of this._entities.values())
+		callback(ent);
 	return this;
 };
 
-m.EntityCollection.prototype.filterNearest = function(targetPos, n)
-{
-	// Compute the distance of each entity
-	var data = []; // [ [id, ent, distance], ... ]
-	for (var id in this._entities)
-	{
-		var ent = this._entities[id];
-		if (ent.position())
-			data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
-	}
-	
-	// Sort by increasing distance
-	data.sort(function (a, b) { return (a[2] - b[2]); });
-	if (n === undefined)
-		n = this._length;
-	// Extract the first n
-	var ret = {};
-	for each (var val in data.slice(0, n))
-		ret[val[0]] = val[1];
-	
-	return new m.EntityCollection(this._ai, ret);
-};
-
 m.EntityCollection.prototype.move = function(x, z, queued)
 {
 	queued = queued || false;
@@ -238,13 +173,13 @@
 m.EntityCollection.prototype.moveIndiv = function(x, z, queued)
 {
 	queued = queued || false;
-	for (var id in this._entities)
+	for (let id of this._entities.keys())
 	{
 		// The following try {} finally {} block is a workaround for OOS problems in multiplayer games with AI players (check ticket #2000).
 		// It disables JIT compiling of this loop. Don't remove it unless you are sure that the underlying issue has been resolved!
 		// TODO: Check this again after the SpiderMonkey upgrade.
 		try {} finally {}
-		Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this._entities[id].id()], "x": x, "z": z, "queued": queued});
+		Engine.PostCommand(PlayerID,{"type": "walk", "entities": [id], "x": x, "z": z, "queued": queued});
 	}
 	return this;
 };
@@ -265,13 +200,9 @@
 {
 	var unitId;
 	if (typeof(unit) === "Entity")
-	{
 		unitId = unit.id();
-	}
 	else
-	{
 		unitId = unit;
-	}	
 	Engine.PostCommand(PlayerID,{"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});
 	return this;
 };
@@ -288,23 +219,19 @@
 {
 	var sumPos = [0, 0];
 	var count = 0;
-	this.forEach(function(ent)
+	for (let ent of this._entities.values())
 	{
-		if (ent.position())
-		{
-			sumPos[0] += ent.position()[0];
-			sumPos[1] += ent.position()[1];
-			count ++;
-		}
-	});
+		if (!ent.position())
+			continue;
+		sumPos[0] += ent.position()[0];
+		sumPos[1] += ent.position()[1];
+		count ++;
+	}
+
 	if (count === 0)
-	{
 		return undefined;
-	}
 	else
-	{
 		return [sumPos[0]/count, sumPos[1]/count];
-	}
 };
 
 // returns the average position from the sample first units.
@@ -314,26 +241,20 @@
 {
 	var sumPos = [0, 0];
 	var i = 0;
-	for (var id in this._entities)
+	for (let ent of this._entities.values())
 	{
-		var ent = this._entities[id];
-		if (ent.position())
-		{
-			sumPos[0] += ent.position()[0];
-			sumPos[1] += ent.position()[1];
-			i++;
-		}
+		if (!ent.position())
+			continue;
+		sumPos[0] += ent.position()[0];
+		sumPos[1] += ent.position()[1];
+		i++;
 		if (i === sample)
 			break;
 	}
-	if (sample === 0)
-	{
+	if (i === 0)
 		return undefined;
-	}
 	else
-	{
 		return [sumPos[0]/i, sumPos[1]/i];
-	}
 };
 
 
@@ -340,39 +261,19 @@
 // Removes an entity from the collection, returns true if the entity was a member, false otherwise
 m.EntityCollection.prototype.removeEnt = function(ent)
 {
-	if (this._entities[ent.id()])
-	{
-		// Checking length may initialize it, so do it before deleting.
-		if (this.length !== undefined)
-			this._length--;
-		if (this._quickIter === true)
-			this._entitiesArray.splice(this._entitiesArray.indexOf(ent),1);
-		delete this._entities[ent.id()];
-		return true;
-	}
-	else
-	{
+	if (!this._entities.has(ent.id()))
 		return false;
-	}
+	this._entities.delete(ent.id());
+	return true;
 };
 
 // Adds an entity to the collection, returns true if the entity was not member, false otherwise
 m.EntityCollection.prototype.addEnt = function(ent)
 {
-	if (this._entities[ent.id()])
-	{
+	if (this._entities.has(ent.id()))
 		return false;
-	}
-	else
-	{
-		// Checking length may initialize it, so do it before adding.
-		if (this.length !== undefined)
-			this._length++;
-		this._entities[ent.id()] = ent;
-		if (this._quickIter === true)
-			this._entitiesArray.push(ent);
-		return true;
-	}
+	this._entities.set(ent.id(), ent);
+	return true;
 };
 
 // Checks the entity against the filters, and adds or removes it appropriately, returns true if the
@@ -383,10 +284,8 @@
 m.EntityCollection.prototype.updateEnt = function(ent, force)
 {	
 	var passesFilters = true;
-	for each (var filter in this._filters)
-	{
+	for each (let filter in this._filters)
 		passesFilters = passesFilters && filter.func(ent);
-	}
 
 	if (passesFilters)
 	{
@@ -395,9 +294,7 @@
 		return this.addEnt(ent);
 	}
 	else
-	{
 		return this.removeEnt(ent);
-	}
 };
 
 m.EntityCollection.prototype.registerUpdates = function()
@@ -413,10 +310,8 @@
 m.EntityCollection.prototype.dynamicProperties = function()
 {
 	var ret = [];
-	for each (var filter in this._filters)
-	{
+	for each (let filter in this._filters)
 		ret = ret.concat(filter.dynamicProperties);
-	}
 
 	return ret;
 };
Index: binaries/data/mods/public/simulation/ai/common-api/gamestate.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api/gamestate.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/common-api/gamestate.js	(copie de travail)
@@ -365,9 +365,10 @@
 		return ent.owner === this.player;
 };
 
-m.GameState.prototype.getEntityById = function(id){
-	if (this.entities._entities[id])
-		return this.entities._entities[id];
+m.GameState.prototype.getEntityById = function(id)
+{
+	if (this.entities._entities.has(+id))
+		return this.entities._entities.get(+id);
 
 	return undefined;
 };
Index: binaries/data/mods/public/simulation/ai/common-api/shared.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api/shared.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/common-api/shared.js	(copie de travail)
@@ -42,7 +42,7 @@
 {
 	// serializing entities without using the class.
 	var entities = []; 
-	for each (let ent in this._entities) 
+	for (let ent of this._entities.values()) 
 		entities.push( ent._entity );
 
 	return {
@@ -66,9 +66,9 @@
 	this._entityMetadata = data.metadata;
 	this._derivedTemplates = {};
 
-	this._entities = {};
+	this._entities = new Map();
 	for (let ent of data.entities)
-		this._entities[ent.id] = new m.Entity(this, ent); 
+		this._entities.set(ent.id, new m.Entity(this, ent)); 
 
 	this.isDeserialized = true;
 };
@@ -152,9 +152,9 @@
 
 	if (!deserialization)
 	{
-		this._entities = {};
+		this._entities = new Map();
 		for (var id in state.entities)
-			this._entities[id] = new m.Entity(this, state.entities[id]);
+			this._entities.set(+id, new m.Entity(this, state.entities[id]));
 	}
 	// entity collection updated on create/destroy event.
 	this.entities = new m.EntityCollection(this, this._entities);
@@ -233,12 +233,13 @@
 		if (!state.entities[evt.entity])
 			continue; // Sometimes there are things like foundations which get destroyed too fast
 
-		this._entities[evt.entity] = new m.Entity(this, state.entities[evt.entity]);
-		this.entities.addEnt(this._entities[evt.entity]);
+		let entity = new m.Entity(this, state.entities[evt.entity]);
+		this._entities.set(evt.entity, entity);
+		this.entities.addEnt(entity);
 		
 		// Update all the entity collections since the create operation affects static properties as well as dynamic
 		for (let entCol of this._entityCollections.values())
-			entCol.updateEnt(this._entities[evt.entity]);
+			entCol.updateEnt(entity);
 	}
 	for (var i in RenamingEvents)
 	{
@@ -254,39 +255,31 @@
 	{
 		var evt = TrainingEvents[i];
 		// Apply metadata stored in training queues
-		for each (var ent in evt.entities)
-		{
-			for (var key in evt.metadata)
-			{
-				this.setMetadata(evt.owner, this._entities[ent], key, evt.metadata[key])
-			}
-		}
+		for each (let entId in evt.entities)
+			for (let key in evt.metadata)
+				this.setMetadata(evt.owner, this._entities.get(entId), key, evt.metadata[key])
 	}
 	for (var i in ConstructionEvents)
 	{
 		var evt = ConstructionEvents[i];
 		// we'll move metadata.
-		if (!this._entities[evt.entity])
+		if (!this._entities.has(evt.entity))
 			continue;
-		var ent = this._entities[evt.entity];
-		var newEnt = this._entities[evt.newentity];
+		var ent = this._entities.get(evt.entity);
+		var newEnt = this._entities.get(evt.newentity);
 		if (this._entityMetadata[ent.owner()] && this._entityMetadata[ent.owner()][evt.entity] !== undefined)
 			for (var key in this._entityMetadata[ent.owner()][evt.entity])
-			{
 				this.setMetadata(ent.owner(), newEnt, key, this._entityMetadata[ent.owner()][evt.entity][key])
-			}
 		foundationFinished[evt.entity] = true;
 	}
 	for (var i in MetadataEvents)
 	{
 		var evt = MetadataEvents[i];
-		if (!this._entities[evt.id])
+		if (!this._entities.has(evt.id))
 			continue;	// might happen in some rare cases of foundations getting destroyed, perhaps.
 						// Apply metadata (here for buildings for example)
 		for (var key in evt.metadata)
-		{
-			this.setMetadata(evt.owner, this._entities[evt.id], key, evt.metadata[key])
-		}
+			this.setMetadata(evt.owner, this._entities.get(evt.id), key, evt.metadata[key])
 	}
 	
 	for (var i = 0; i < DestroyEvents.length; ++i)
@@ -296,7 +289,7 @@
 		// the "deleted" object remains in memory, and any older reference to it will still reference it as if it were not "deleted".
 		// Worse, they might prevent it from being garbage collected, thus making it stay alive and consuming ram needlessly.
 		// So take care, and if you encounter a weird bug with deletion not appearing to work correctly, this is probably why.
-		if (!this._entities[evt.entity])
+		if (!this._entities.has(evt.entity))
 			continue;// probably should remove the event.
 
 		if (foundationFinished[evt.entity])
@@ -305,28 +298,28 @@
 		// The entity was destroyed but its data may still be useful, so
 		// remember the entity and this AI's metadata concerning it
 		evt.metadata = {};
-		evt.entityObj = this._entities[evt.entity];
+		evt.entityObj = this._entities.get(evt.entity);
 		for (var j in this._players)
 			evt.metadata[this._players[j]] = this._entityMetadata[this._players[j]][evt.entity];
 		
+		let entity = this._entities.get(evt.entity);
 		for (let entCol of this._entityCollections.values())
-			entCol.removeEnt(this._entities[evt.entity]);
-		this.entities.removeEnt(this._entities[evt.entity]);
+			entCol.removeEnt(entity);
+		this.entities.removeEnt(entity);
 		
-		delete this._entities[evt.entity];
+		this._entities.delete(evt.entity);
 		for (var j in this._players)
 			delete this._entityMetadata[this._players[j]][evt.entity];
 	}
 
-	for (var id in state.entities)
+	for (let id in state.entities)
 	{
-		var changes = state.entities[id];
-
-		for (var prop in changes)
+		let changes = state.entities[id];
+		let entity = this._entities.get(+id);
+		for (let prop in changes)
 		{
-			this._entities[id]._entity[prop] = changes[prop];
-			
-			this.updateEntityCollections(prop, this._entities[id]);
+			entity._entity[prop] = changes[prop];
+			this.updateEntityCollections(prop, entity);
 		}
 	}
 
@@ -334,11 +327,12 @@
 	// this supersedes tech-related changes.
 	for (var id in state.changedEntityTemplateInfo)
 	{
-		if (!this._entities[id])
+		if (!this._entities.has(+id))
 			continue;	// dead, presumably.
 		var changes = state.changedEntityTemplateInfo[id];
+		let entity = this._entities.get(+id);
 		for each (var change in changes)
-			this._entities[id]._auraTemplateModif.set(change.variable, change.value);
+			entity._auraTemplateModif.set(change.variable, change.value);
 	}
 	Engine.ProfileStop();
 };
Index: binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js	(copie de travail)
@@ -64,9 +64,8 @@
 	var x = 0;
 	var y = 0;
 	var radius = 0;
-	for (var entI in sharedScript._entities)
+	for (let ent of sharedScript._entities.values())
 	{
-		var ent = sharedScript._entities[entI];
 		if (ent.hasClass("ForestPlant") === true) {
 			pos = this.gamePosToMapPos(ent.position());
 			x = pos[0];
@@ -700,9 +699,8 @@
 			this.CCResourceMaps[resource].setMaxVal(255);
 		}
 	}
-	for (var entI in sharedScript._entities)
+	for (let ent of sharedScript._entities.values())
 	{
-		var ent = sharedScript._entities[entI];
 		if (ent && ent.position() && ent.resourceSupplyType() && ent.resourceSupplyType().generic !== "treasure") {
 			var resource = ent.resourceSupplyType().generic;
 			var x = Math.floor(ent.position()[0] / 4);
@@ -777,8 +775,8 @@
 	}
 	for (var key in createEvents) {
 		var e = createEvents[key];
-		if (e.entity){
-			var ent = sharedScript._entities[e.entity];
+		if (e.entity && sharedScript._entities.has(e.entity)){
+			var ent = sharedScript._entities.get(e.entity);
 			if (ent && ent.position() && ent.resourceSupplyType() && ent.resourceSupplyType().generic !== "treasure"){
 				var resource = ent.resourceSupplyType().generic;
 				
Index: binaries/data/mods/public/simulation/ai/petra/attackPlan.js
===================================================================
--- binaries/data/mods/public/simulation/ai/petra/attackPlan.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/petra/attackPlan.js	(copie de travail)
@@ -228,8 +228,8 @@
 	{
 		var moreAdvanced = undefined;
 		var enemyWonder = undefined;
-		var wonders = gameState.getEnemyStructures().filter(API3.Filters.byClass("Wonder")).toEntityArray();
-		for (var wonder of wonders)
+		var wonders = gameState.getEnemyStructures().filter(API3.Filters.byClass("Wonder"));
+		for (var wonder of wonders.values())
 		{
 			var progress = wonder.foundationProgress();
 			if (progress === undefined)
@@ -1259,8 +1259,8 @@
 			if (this.isSiegeUnit(gameState, ourUnit))
 			{
 				// if siege units are attacked, we'll send some units to deal with enemies.
-				var collec = this.unitCollection.filter(API3.Filters.not(API3.Filters.byClass("Siege"))).filterNearest(ourUnit.position(), 5).toEntityArray();
-				for (var ent of collec)
+				var collec = this.unitCollection.filter(API3.Filters.not(API3.Filters.byClass("Siege"))).filterNearest(ourUnit.position(), 5);
+				for (var ent of collec.values())
 					if (!this.isSiegeUnit(gameState, ent))
 					{
 						ent.attack(attacker.id());
Index: binaries/data/mods/public/simulation/ai/petra/baseManager.js
===================================================================
--- binaries/data/mods/public/simulation/ai/petra/baseManager.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/petra/baseManager.js	(copie de travail)
@@ -934,12 +934,15 @@
 		if(owner != 0 && !gameState.isPlayerAlly(owner))
 		{
 			// we're in enemy territory. If we're too close from the enemy, destroy us.
-			var eEnts = gameState.getEnemyStructures().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
-			for (var i in eEnts)
+			var eEnts = gameState.getEnemyStructures().filter(API3.Filters.byClass("CivCentre"));
+			for (var eEnt of eEnts.values())
 			{
-				var entPos = eEnts[i].position();
+				var entPos = eEnt.position();
 				if (API3.SquareVectorDistance(entPos, this.anchor.position()) < 8000)
+				{
 					this.anchor.destroy();
+					break;
+				}
 			}
 		}
 	}
Index: binaries/data/mods/public/simulation/ai/petra/defenseManager.js
===================================================================
--- binaries/data/mods/public/simulation/ai/petra/defenseManager.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/petra/defenseManager.js	(copie de travail)
@@ -69,8 +69,8 @@
 		}
 		else if (target && target.hasClass("CivCentre"))
 		{
-			var myBuildings = gameState.getOwnStructures().toEntityArray();
-			for (let building of myBuildings)
+			var myBuildings = gameState.getOwnStructures();
+			for (let building of myBuildings.values())
 			{
 				if (API3.SquareVectorDistance(building.position(), entity.position()) > 30000)
 					continue;
@@ -94,8 +94,8 @@
 
 	if (this.Config.personality.cooperative > 0.3)
 	{
-		let ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray();
-		for (let cc of ccEnts)
+		let ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre"));
+		for (let cc of ccEnts.values())
 		{
 			if (!gameState.isEntityExclusiveAlly(cc))
 				continue;
@@ -106,8 +106,8 @@
 		}
 	}
 
-	var myBuildings = gameState.getOwnStructures().toEntityArray();
-	for (let building of myBuildings)
+	var myBuildings = gameState.getOwnStructures();
+	for (let building of myBuildings.values())
 	{
 		if (building.foundationProgress() == 0)
 			continue;
@@ -209,12 +209,12 @@
 		// army in neutral territory // TODO check smaller distance with all our buildings instead of only ccs with big distance
 		var stillDangerous = false;
 		if (this.Config.personality.cooperative > 0.3)
-			var bases = gameState.getAllyEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
+			var bases = gameState.getAllyEntities().filter(API3.Filters.byClass("CivCentre"));
 		else
-			var bases = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
-	 	for (var i in bases)
+			var bases = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre"));
+	 	for (let base of bases.values())
 		{
-			if (API3.SquareVectorDistance(bases[i].position(), army.foePosition) < 40000)
+			if (API3.SquareVectorDistance(base.position(), army.foePosition) < 40000)
 			{
 				if(this.Config.debug > 1)
 					API3.warn("army in neutral territory, but still near one of our CC");
Index: binaries/data/mods/public/simulation/ai/petra/headquarters.js
===================================================================
--- binaries/data/mods/public/simulation/ai/petra/headquarters.js	(révision 16027)
+++ binaries/data/mods/public/simulation/ai/petra/headquarters.js	(copie de travail)
@@ -779,13 +779,13 @@
 	var obstructions = m.createObstructionMap(gameState, 0, template);
 	obstructions.expandInfluences();
 
-	var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray();
-	var dpEnts = gameState.getOwnDropsites().filter(API3.Filters.not(API3.Filters.byClassesOr(["CivCentre", "Elephant"]))).toEntityArray();
+	var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre"));
+	var dpEnts = gameState.getOwnDropsites().filter(API3.Filters.not(API3.Filters.byClassesOr(["CivCentre", "Elephant"])));
 	var ccList = [];
-	for (var cc of ccEnts)
+	for (var cc of ccEnts.values())
 		ccList.push({"pos": cc.position(), "ally": gameState.isPlayerAlly(cc.owner())});
 	var dpList = [];
-	for (var dp of dpEnts)
+	for (var dp of dpEnts.values())
 		dpList.push({"pos": dp.position()});
 
 	var width = this.territoryMap.width;
@@ -918,10 +918,10 @@
 	// with the constraints that all CC have dist > 200 and at least one have dist < 400
 	// This needs at least 2 CC. Otherwise, go back to economic CC.
 
-	var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray();
+	var ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre"));
 	var ccList = [];
 	var numAllyCC = 0;
-	for (var cc of ccEnts)
+	for (var cc of ccEnts.values())
 	{
 		var ally = gameState.isPlayerAlly(cc.owner());
 		ccList.push({"pos": cc.position(), "ally": ally});
