mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-21 13:04:10 +00:00
petra: revisit the management of constructions for better performances and cleaner implementation
This was SVN commit r20409.
This commit is contained in:
@@ -342,11 +342,10 @@ m.Template = m.Class({
|
||||
return 1;
|
||||
},
|
||||
|
||||
"buildableEntities": function() {
|
||||
"buildableEntities": function(civ = this.civ()) {
|
||||
let templates = this.get("Builder/Entities/_string");
|
||||
if (!templates)
|
||||
return [];
|
||||
let civ = this.civ();
|
||||
return templates.replace(/\{civ\}/g, civ).split(/\s+/);
|
||||
},
|
||||
|
||||
|
||||
@@ -872,33 +872,6 @@ m.GameState.prototype.findResearchers = function(templateName, noRequirementChec
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get any buildable structure with a given class
|
||||
* TODO when several available, choose the best one
|
||||
*/
|
||||
m.GameState.prototype.findStructureWithClass = function(classes)
|
||||
{
|
||||
let entTemplates = new Set();
|
||||
for (let ent of this.getOwnUnits().values())
|
||||
{
|
||||
if (entTemplates.has(ent.templateName()))
|
||||
continue;
|
||||
let buildables = ent.buildableEntities();
|
||||
for (let buildable of buildables)
|
||||
{
|
||||
if (this.isTemplateDisabled(buildable))
|
||||
continue;
|
||||
let template = this.getTemplate(buildable);
|
||||
if (!template || !template.available(this))
|
||||
continue;
|
||||
if (MatchesClassList(template.classes(), classes))
|
||||
return buildable;
|
||||
}
|
||||
entTemplates.add(ent.templateName());
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
m.GameState.prototype.getEntityLimits = function()
|
||||
{
|
||||
return this.playerData.entityLimits;
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
var PETRA = function(m)
|
||||
{
|
||||
|
||||
/**
|
||||
* One task of this manager is to cache the list of structures we have builders for,
|
||||
* to avoid having to loop on all entities each time.
|
||||
* It also takes care of the structures we can't currently build and should not try to build endlessly.
|
||||
*/
|
||||
|
||||
m.BuildManager = function()
|
||||
{
|
||||
// List of buildings we have builders for, with number of possible builders.
|
||||
this.builderCounters = new Map();
|
||||
// List of buildings we can't currently build (because no room, no builder or whatever),
|
||||
// with time we should wait before trying again to build it.
|
||||
this.unbuildables = new Map();
|
||||
};
|
||||
|
||||
/** Initialization at start of game */
|
||||
m.BuildManager.prototype.init = function(gameState)
|
||||
{
|
||||
let civ = gameState.getPlayerCiv();
|
||||
for (let ent of gameState.getOwnUnits().values())
|
||||
this.incrementBuilderCounters(civ, ent, 1);
|
||||
};
|
||||
|
||||
m.BuildManager.prototype.incrementBuilderCounters = function(civ, ent, increment)
|
||||
{
|
||||
for (let buildable of ent.buildableEntities(civ))
|
||||
{
|
||||
if (this.builderCounters.has(buildable))
|
||||
{
|
||||
let count = this.builderCounters.get(buildable) + increment;
|
||||
if (count < 0)
|
||||
{
|
||||
API3.warning(" Petra error in incrementBuilderCounters for " + buildable + " with count < 0");
|
||||
continue;
|
||||
}
|
||||
this.builderCounters.set(buildable, count);
|
||||
}
|
||||
else if (increment > 0)
|
||||
this.builderCounters.set(buildable, increment);
|
||||
else
|
||||
API3.warning(" Petra error in incrementBuilderCounters for " + buildable + " not yet set");
|
||||
}
|
||||
};
|
||||
|
||||
/** Update the builders counters */
|
||||
m.BuildManager.prototype.checkEvents = function(gameState, events)
|
||||
{
|
||||
this.elapsedTime = gameState.ai.elapsedTime;
|
||||
let civ = gameState.getPlayerCiv();
|
||||
|
||||
for (let evt of events.Create)
|
||||
{
|
||||
let ent = gameState.getEntityById(evt.entity);
|
||||
if (ent && ent.isOwn(PlayerID) && ent.hasClass("Unit"))
|
||||
this.incrementBuilderCounters(civ, ent, 1);
|
||||
}
|
||||
|
||||
for (let evt of events.Destroy)
|
||||
{
|
||||
if (!evt.entityObj)
|
||||
continue;
|
||||
let ent = evt.entityObj;
|
||||
if (ent && ent.isOwn(PlayerID) && ent.hasClass("Unit"))
|
||||
this.incrementBuilderCounters(civ, ent, -1);
|
||||
}
|
||||
|
||||
for (let evt of events.OwnershipChanged) // capture events
|
||||
{
|
||||
let increment;
|
||||
if (evt.from == PlayerID)
|
||||
increment = -1;
|
||||
else if (evt.to == PlayerID)
|
||||
increment = 1;
|
||||
else
|
||||
continue;
|
||||
let ent = gameState.getEntityById(evt.entity);
|
||||
if (ent && ent.hasClass("Unit"))
|
||||
this.incrementBuilderCounters(civ, ent, increment);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the first buildable structure with a given class
|
||||
* TODO when several available, choose the best one
|
||||
*/
|
||||
m.BuildManager.prototype.findStructureWithClass = function(gameState, classes)
|
||||
{
|
||||
for (let [templateName, count] of this.builderCounters)
|
||||
{
|
||||
if (count == 0 || gameState.isTemplateDisabled(templateName))
|
||||
continue;
|
||||
let template = gameState.getTemplate(templateName);
|
||||
if (!template || !template.available(gameState))
|
||||
continue;
|
||||
if (MatchesClassList(template.classes(), classes))
|
||||
return templateName;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
m.BuildManager.prototype.hasBuilder = function(template)
|
||||
{
|
||||
let numBuilders = this.builderCounters.get(template);
|
||||
return numBuilders && numBuilders > 0;
|
||||
};
|
||||
|
||||
m.BuildManager.prototype.isUnbuildable = function(gameState, template)
|
||||
{
|
||||
return this.unbuildables.has(template) && this.unbuildables.get(template).time > gameState.ai.elapsedTime;
|
||||
};
|
||||
|
||||
m.BuildManager.prototype.setBuildable = function(template)
|
||||
{
|
||||
if (this.unbuildables.has(template))
|
||||
this.unbuildables.delete(template);
|
||||
};
|
||||
|
||||
/** Time is the duration in second that we will wait before checking again if it is buildable */
|
||||
m.BuildManager.prototype.setUnbuildable = function(gameState, template, time = 180, reason = "room")
|
||||
{
|
||||
if (!this.unbuildables.has(template))
|
||||
this.unbuildables.set(template, { "reason": reason, "time": gameState.ai.elapsedTime + time });
|
||||
else
|
||||
{
|
||||
let unbuildable = this.unbuildables.get(template);
|
||||
if (unbuildable.time < gameState.ai.elapsedTime + time)
|
||||
{
|
||||
unbuildable.reason = reason;
|
||||
unbuildable.time = gameState.ai.elapsedTime + time;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** Return the number of unbuildables due to missing room */
|
||||
m.BuildManager.prototype.numberMissingRoom = function(gameState)
|
||||
{
|
||||
let num = 0;
|
||||
for (let unbuildable of this.unbuildables.values())
|
||||
if (unbuildable.reason == "room" && unbuildable.time > gameState.ai.elapsedTime)
|
||||
++num;
|
||||
return num;
|
||||
};
|
||||
|
||||
/** Reset the unbuildables due to missing room */
|
||||
m.BuildManager.prototype.resetMissingRoom = function(gameState)
|
||||
{
|
||||
for (let [key, unbuildable] of this.unbuildables)
|
||||
if (unbuildable.reason == "room")
|
||||
this.unbuildables.delete(key);
|
||||
};
|
||||
|
||||
m.BuildManager.prototype.Serialize = function()
|
||||
{
|
||||
return {
|
||||
"builderCounters": this.builderCounters,
|
||||
"unbuildables": this.unbuildables
|
||||
};
|
||||
};
|
||||
|
||||
m.BuildManager.prototype.Deserialize = function(data)
|
||||
{
|
||||
for (let key in data)
|
||||
this[key] = data[key];
|
||||
};
|
||||
|
||||
return m;
|
||||
}(PETRA);
|
||||
@@ -31,8 +31,6 @@ m.HQ = function(Config)
|
||||
this.targetNumWorkers = this.Config.Economy.targetNumWorkers;
|
||||
this.supportRatio = this.Config.Economy.supportRatio;
|
||||
|
||||
this.stopBuilding = new Map(); // list of buildings to stop (temporarily) production because no room
|
||||
|
||||
this.fortStartTime = 180; // sentry defense towers, will start at fortStartTime + towerLapseTime
|
||||
this.towerStartTime = 0; // stone defense towers, will start as soon as available
|
||||
this.towerLapseTime = this.Config.Military.towerLapseTime;
|
||||
@@ -43,6 +41,7 @@ m.HQ = function(Config)
|
||||
|
||||
this.baseManagers = [];
|
||||
this.attackManager = new m.AttackManager(this.Config);
|
||||
this.buildManager = new m.BuildManager();
|
||||
this.defenseManager = new m.DefenseManager(this.Config);
|
||||
this.tradeManager = new m.TradeManager(this.Config);
|
||||
this.navalManager = new m.NavalManager(this.Config);
|
||||
@@ -134,6 +133,8 @@ m.HQ.prototype.getSeaBetweenIndices = function (gameState, index1, index2)
|
||||
|
||||
m.HQ.prototype.checkEvents = function (gameState, events, queues)
|
||||
{
|
||||
this.buildManager.checkEvents(gameState, events);
|
||||
|
||||
if (events.TerritoriesChanged.length || events.DiplomacyChanged.length)
|
||||
this.updateTerritories(gameState);
|
||||
|
||||
@@ -469,7 +470,7 @@ m.HQ.prototype.checkPhaseRequirements = function(gameState, queues)
|
||||
queue = entityReq.class === "Wonder" ? "wonder" : "economicBuilding";
|
||||
if (!queues[queue].hasQueuedUnits())
|
||||
{
|
||||
let structure = gameState.findStructureWithClass([entityReq.class]);
|
||||
let structure = this.buildManager.findStructureWithClass(gameState, [entityReq.class]);
|
||||
if (structure && this.canBuild(gameState, structure))
|
||||
plan = new m.ConstructionPlan(gameState, structure);
|
||||
}
|
||||
@@ -1533,11 +1534,11 @@ m.HQ.prototype.buildMoreHouses = function(gameState, queues)
|
||||
continue;
|
||||
|
||||
let count = gameState.getOwnStructures().filter(API3.Filters.byClass(entityReq.class)).length;
|
||||
if (count < entityReq.count && this.stopBuilding.has(houseTemplateName))
|
||||
if (count < entityReq.count && this.buildManager.isUnbuildable(gameState, houseTemplateName))
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("no room to place a house ... try to be less restrictive");
|
||||
this.stopBuilding.delete(houseTemplateName);
|
||||
this.buildManager.setBuildable(houseTemplateName);
|
||||
this.requireHouses = true;
|
||||
}
|
||||
needed = Math.max(needed, entityReq.count - count);
|
||||
@@ -1572,25 +1573,18 @@ m.HQ.prototype.buildMoreHouses = function(gameState, queues)
|
||||
let priority;
|
||||
if (freeSlots < 5)
|
||||
{
|
||||
if (this.stopBuilding.has(house))
|
||||
if (this.buildManager.isUnbuildable(gameState, house))
|
||||
{
|
||||
if (this.stopBuilding.get(house) > gameState.ai.elapsedTime)
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("no room to place a house ... try to improve with technology");
|
||||
this.researchManager.researchPopulationBonus(gameState, queues);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.stopBuilding.delete(house);
|
||||
priority = 2*this.Config.priorities.house;
|
||||
}
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("no room to place a house ... try to improve with technology");
|
||||
this.researchManager.researchPopulationBonus(gameState, queues);
|
||||
}
|
||||
else
|
||||
priority = 2*this.Config.priorities.house;
|
||||
}
|
||||
else
|
||||
priority = this.Config.priorities.house;
|
||||
|
||||
if (priority && priority != gameState.ai.queueManager.getPriority("house"))
|
||||
gameState.ai.queueManager.changePriority("house", priority);
|
||||
};
|
||||
@@ -1608,13 +1602,10 @@ m.HQ.prototype.checkBaseExpansion = function(gameState, queues)
|
||||
return;
|
||||
}
|
||||
// Then expand if we have not enough room available for buildings
|
||||
let nstopped = 0;
|
||||
for (let stopTime of this.stopBuilding.values())
|
||||
if (this.buildManager.numberMissingRoom(gameState) > 1)
|
||||
{
|
||||
if (stopTime === Infinity || stopTime < gameState.ai.elapsedTime || ++nstopped < 2)
|
||||
continue;
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("try to build a new base because not enough room to build " + uneval(this.stopBuilding));
|
||||
API3.warn("try to build a new base because not enough room to build ");
|
||||
this.buildNewBase(gameState, queues);
|
||||
return;
|
||||
}
|
||||
@@ -1985,29 +1976,31 @@ m.HQ.prototype.trainEmergencyUnits = function(gameState, positions)
|
||||
m.HQ.prototype.canBuild = function(gameState, structure, debug = false)
|
||||
{
|
||||
let type = gameState.applyCiv(structure);
|
||||
// available room to build it
|
||||
if (this.stopBuilding.has(type))
|
||||
{
|
||||
if (this.stopBuilding.get(type) > gameState.ai.elapsedTime)
|
||||
return false;
|
||||
this.stopBuilding.delete(type);
|
||||
}
|
||||
if (this.buildManager.isUnbuildable(gameState, type))
|
||||
return false;
|
||||
|
||||
if (gameState.isTemplateDisabled(type))
|
||||
{
|
||||
this.stopBuilding.set(type, Infinity);
|
||||
this.buildManager.setUnbuildable(gameState, type, Infinity, "disabled");
|
||||
return false;
|
||||
}
|
||||
|
||||
let template = gameState.getTemplate(type);
|
||||
if (!template)
|
||||
this.stopBuilding.set(type, Infinity);
|
||||
if (!template || !template.available(gameState))
|
||||
return false;
|
||||
|
||||
if (!gameState.findBuilder(type))
|
||||
{
|
||||
this.stopBuilding.set(type, gameState.ai.elapsedTime + 120);
|
||||
this.buildManager.setUnbuildable(gameState, type, Infinity, "notemplate");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!template.available(gameState))
|
||||
{
|
||||
this.buildManager.setUnbuildable(gameState, type, 30, "tech");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.buildManager.hasBuilder(type))
|
||||
{
|
||||
this.buildManager.setUnbuildable(gameState, type, 120, "nobuilder");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2017,7 +2010,7 @@ m.HQ.prototype.canBuild = function(gameState, structure, debug = false)
|
||||
let buildTerritories = template.buildTerritories();
|
||||
if (buildTerritories && (!buildTerritories.length || buildTerritories.length === 1 && buildTerritories[0] === "own"))
|
||||
{
|
||||
this.stopBuilding.set(type, gameState.ai.elapsedTime + 180);
|
||||
this.buildManager.setUnbuildable(gameState, type, 180, "room");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2027,29 +2020,13 @@ m.HQ.prototype.canBuild = function(gameState, structure, debug = false)
|
||||
let category = template.buildCategory();
|
||||
if (category && limits[category] !== undefined && gameState.getEntityCounts()[category] >= limits[category])
|
||||
{
|
||||
this.stopBuilding.set(type, gameState.ai.elapsedTime + 60);
|
||||
this.buildManager.setUnbuildable(gameState, type, 90, "limit");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
m.HQ.prototype.stopBuild = function(gameState, structure, time=180)
|
||||
{
|
||||
let type = gameState.applyCiv(structure);
|
||||
if (this.stopBuilding.has(type))
|
||||
this.stopBuilding.set(type, Math.max(this.stopBuilding.get(type), gameState.ai.elapsedTime + time));
|
||||
else
|
||||
this.stopBuilding.set(type, gameState.ai.elapsedTime + time);
|
||||
};
|
||||
|
||||
m.HQ.prototype.restartBuild = function(gameState, structure)
|
||||
{
|
||||
let type = gameState.applyCiv(structure);
|
||||
if (this.stopBuilding.has(type))
|
||||
this.stopBuilding.delete(type);
|
||||
};
|
||||
|
||||
m.HQ.prototype.updateTerritories = function(gameState)
|
||||
{
|
||||
const around = [ [-0.7,0.7], [0,1], [0.7,0.7], [1,0], [0.7,-0.7], [0,-1], [-0.7,-0.7], [-1,0] ];
|
||||
@@ -2162,9 +2139,7 @@ m.HQ.prototype.updateTerritories = function(gameState)
|
||||
if (!expansion)
|
||||
return;
|
||||
// We've increased our territory, so we may have some new room to build
|
||||
for (let [type, stopTime] of this.stopBuilding)
|
||||
if (stopTime !== Infinity)
|
||||
this.stopBuilding.delete(type);
|
||||
this.buildManager.resetMissingRoom(gameState);
|
||||
// And if sufficient expansion, check if building a new market would improve our present trade routes
|
||||
let cellArea = this.territoryMap.cellSize * this.territoryMap.cellSize;
|
||||
if (expansion * cellArea > 960)
|
||||
@@ -2492,7 +2467,6 @@ m.HQ.prototype.Serialize = function()
|
||||
"lastFailedGather": this.lastFailedGather,
|
||||
"supportRatio": this.supportRatio,
|
||||
"targetNumWorkers": this.targetNumWorkers,
|
||||
"stopBuilding": this.stopBuilding,
|
||||
"fortStartTime": this.fortStartTime,
|
||||
"towerStartTime": this.towerStartTime,
|
||||
"fortressStartTime": this.fortressStartTime,
|
||||
@@ -2522,6 +2496,7 @@ m.HQ.prototype.Serialize = function()
|
||||
API3.warn(" properties " + uneval(properties));
|
||||
API3.warn(" baseManagers " + uneval(baseManagers));
|
||||
API3.warn(" attackManager " + uneval(this.attackManager.Serialize()));
|
||||
API3.warn(" buildManager " + uneval(this.buildManager.Serialize()));
|
||||
API3.warn(" defenseManager " + uneval(this.defenseManager.Serialize()));
|
||||
API3.warn(" tradeManager " + uneval(this.tradeManager.Serialize()));
|
||||
API3.warn(" navalManager " + uneval(this.navalManager.Serialize()));
|
||||
@@ -2536,6 +2511,7 @@ m.HQ.prototype.Serialize = function()
|
||||
|
||||
"baseManagers": baseManagers,
|
||||
"attackManager": this.attackManager.Serialize(),
|
||||
"buildManager": this.buildManager.Serialize(),
|
||||
"defenseManager": this.defenseManager.Serialize(),
|
||||
"tradeManager": this.tradeManager.Serialize(),
|
||||
"navalManager": this.navalManager.Serialize(),
|
||||
@@ -2571,6 +2547,9 @@ m.HQ.prototype.Deserialize = function(gameState, data)
|
||||
this.attackManager.init(gameState);
|
||||
this.attackManager.Deserialize(gameState, data.attackManager);
|
||||
|
||||
this.buildManager = new m.BuildManager();
|
||||
this.buildManager.Deserialize(gameState, data.buildManager);
|
||||
|
||||
this.defenseManager = new m.DefenseManager(this.Config);
|
||||
this.defenseManager.Deserialize(gameState, data.defenseManager);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ m.ConstructionPlan.prototype.canStart = function(gameState)
|
||||
if (this.template.requiredTech() && !gameState.isResearched(this.template.requiredTech()))
|
||||
return false;
|
||||
|
||||
return gameState.findBuilder(this.type) !== undefined;
|
||||
return gameState.ai.HQ.buildManager.hasBuilder(this.type);
|
||||
};
|
||||
|
||||
m.ConstructionPlan.prototype.start = function(gameState)
|
||||
@@ -46,7 +46,7 @@ m.ConstructionPlan.prototype.start = function(gameState)
|
||||
let pos = this.findGoodPosition(gameState);
|
||||
if (!pos)
|
||||
{
|
||||
gameState.ai.HQ.stopBuild(gameState, this.type);
|
||||
gameState.ai.HQ.buildManager.setUnbuildable(gameState, this.type);
|
||||
Engine.ProfileStop();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ m.HQ.prototype.gameAnalysis = function(gameState)
|
||||
return;
|
||||
|
||||
this.attackManager.init(gameState);
|
||||
this.buildManager.init(gameState);
|
||||
this.navalManager.init(gameState);
|
||||
this.tradeManager.init(gameState);
|
||||
this.diplomacyManager.init(gameState);
|
||||
|
||||
@@ -347,9 +347,7 @@ m.TradeManager.prototype.checkEvents = function(gameState, events)
|
||||
let ent = evt.entityObj;
|
||||
if (!ent || !ent.hasClass("Market") || !gameState.isPlayerAlly(ent.owner()))
|
||||
continue;
|
||||
this.routeProspection = true;
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_market");
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_dock");
|
||||
this.activateProspection(gameState);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -359,9 +357,7 @@ m.TradeManager.prototype.checkEvents = function(gameState, events)
|
||||
let ent = gameState.getEntityById(evt.entity);
|
||||
if (!ent || ent.foundationProgress() !== undefined || !ent.hasClass("Market") || !gameState.isPlayerAlly(ent.owner()))
|
||||
continue;
|
||||
this.routeProspection = true;
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_market");
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_dock");
|
||||
this.activateProspection(gameState);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -374,24 +370,27 @@ m.TradeManager.prototype.checkEvents = function(gameState, events)
|
||||
let ent = gameState.getEntityById(evt.entity);
|
||||
if (!ent || ent.foundationProgress() !== undefined || !ent.hasClass("Market"))
|
||||
continue;
|
||||
this.routeProspection = true;
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_market");
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_dock");
|
||||
this.activateProspection(gameState);
|
||||
return true;
|
||||
}
|
||||
|
||||
// or if diplomacy changed
|
||||
if (events.DiplomacyChanged.length)
|
||||
{
|
||||
this.routeProspection = true;
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_market");
|
||||
gameState.ai.HQ.restartBuild(gameState, "structures/{civ}_dock");
|
||||
this.activateProspection(gameState);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
m.TradeManager.prototype.activateProspection = function(gameState)
|
||||
{
|
||||
this.routeProspection = true;
|
||||
gameState.ai.HQ.buildManager.setBuildable(gameState.applyCiv("structures/{civ}_market"));
|
||||
gameState.ai.HQ.buildManager.setBuildable(gameState.applyCiv("structures/{civ}_dock"));
|
||||
};
|
||||
|
||||
/**
|
||||
* fills the best trade route in this.tradeRoute and the best potential route in this.potentialTradeRoute
|
||||
* If an index is given, it returns the best route with this index or the best land route if index is a land index
|
||||
@@ -579,7 +578,7 @@ m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues)
|
||||
let marketPos = gameState.ai.HQ.findMarketLocation(gameState, template);
|
||||
if (!marketPos || marketPos[3] === 0) // marketPos[3] is the expected gain
|
||||
{ // no position found
|
||||
gameState.ai.HQ.stopBuild(gameState, "structures/{civ}_market");
|
||||
gameState.ai.HQ.buildManager.setUnbuildable(gameState, gameState.applyCiv("structures/{civ}_market"));
|
||||
return;
|
||||
}
|
||||
this.routeProspection = false;
|
||||
|
||||
Reference in New Issue
Block a user