Petra: improve dynamic management of guard units

Summary:
Petra will not add guards when it has a low population, and will remove
any citizen-soldier guards so they can be used for other tasks.
Petra will also use a healer queue for training healer guards, and this
is done mainly so that Petra doesn't clog the villager queue with
healers, as villages should always have a higher priority. Also this
queue could be used in the future for training healer units for other
purposes.

Patch by Sandarac

Differential Revision: https://code.wildfiregames.com/D165
This was SVN commit r19262.
This commit is contained in:
mimo 2017-03-02 18:37:40 +00:00
parent c5d515721d
commit aadf9d70f6
3 changed files with 35 additions and 9 deletions

View file

@ -81,6 +81,7 @@ m.Config = function(difficulty)
"villager": 30, // should be slightly lower than the citizen soldier one to not get all the food
"citizenSoldier": 60,
"trader": 50,
"healer": 20,
"ships": 70,
"house": 350,
"dropsites": 200,
@ -176,6 +177,7 @@ m.Config.prototype.setConfig = function(gameState)
this.Economy.popForTown = 55;
this.Economy.popForMarket = 60;
this.priorities.defenseBuilding = 60;
this.priorities.healer = 10;
}
}

View file

@ -262,11 +262,34 @@ m.GameTypeManager.prototype.buildWonder = function(gameState, queues)
};
/**
* Try to keep some military units guarding any criticalEnts.
* Try to keep some military units guarding any criticalEnts, if we can afford it.
* If we have too low a population and require units for other needs, remove guards so they can be reassigned.
* TODO: Swap citizen soldier guards with champions if they become available.
*/
m.GameTypeManager.prototype.manageCriticalEntGuards = function(gameState)
{
let numWorkers = gameState.getOwnEntitiesByRole("worker", true).length;
if (numWorkers < 20)
{
for (let data of this.criticalEnts.values())
for (let guardId of data.guards.keys())
{
let guardEnt = gameState.getEntityById(guardId);
if (!guardEnt || !guardEnt.hasClass("CitizenSoldier") ||
guardEnt.getMetadata(PlayerID, "role") !== "criticalEntGuard")
continue;
guardEnt.removeGuard();
guardEnt.setMetadata(PlayerID, "plan", -1);
guardEnt.setMetadata(PlayerID, "role", undefined);
this.guardEnts.delete(guardId);
--data.guardsAssigned;
if (guardEnt.getMetadata(PlayerID, "guardedEnt"))
guardEnt.setMetadata(PlayerID, "guardedEnt", undefined);
}
}
for (let [id, data] of this.criticalEnts)
{
let criticalEnt = gameState.getEntityById(id);
@ -291,7 +314,7 @@ m.GameTypeManager.prototype.manageCriticalEntGuards = function(gameState)
break;
}
if (data.guardsAssigned >= militaryGuardsPerCriticalEnt)
if (data.guardsAssigned >= militaryGuardsPerCriticalEnt || numWorkers <= 25)
break;
for (let entity of gameState.ai.HQ.attackManager.outOfPlan.values())
@ -362,7 +385,7 @@ m.GameTypeManager.prototype.trainCriticalEntHealer = function(gameState, queues,
let template = gameState.applyCiv("units/{civ}_support_healer_b");
queues.villager.addPlan(new m.TrainingPlan(gameState, template, { "role": "criticalEntHealer", "base": 0 }, 1, 1));
queues.healer.addPlan(new m.TrainingPlan(gameState, template, { "role": "criticalEntHealer", "base": 0 }, 1, 1));
++this.criticalEnts.get(id).healersAssigned;
};
@ -418,6 +441,10 @@ m.GameTypeManager.prototype.assignGuardToCriticalEnt = function(gameState, guard
guardEnt.guard(criticalEnt, queued);
let guardRole = guardEnt.getMetadata(PlayerID, "role") === "criticalEntHealer" ? "healer" : "guard";
this.criticalEnts.get(criticalEntId).guards.set(guardEnt.id(), guardRole);
// Switch this guard ent to the criticalEnt's base
if (criticalEnt.hasClass("Wonder") && criticalEnt.getMetadata(PlayerID, "base") !== undefined)
guardEnt.setMetadata(PlayerID, "base", criticalEnt.getMetadata(PlayerID, "base"));
}
else
gameState.ai.HQ.navalManager.requireTransport(gameState, guardEnt, guardEntAccess, criticalEntAccess, criticalEnt.position());
@ -452,13 +479,10 @@ m.GameTypeManager.prototype.update = function(gameState, events, queues)
ent.setStance("aggressive");
if (data.healersAssigned < this.healersPerCriticalEnt &&
this.guardEnts.size < gameState.getPopulationMax() / 10)
this.guardEnts.size < Math.min(gameState.getPopulationMax() / 10, gameState.getPopulation() / 4))
this.trainCriticalEntHealer(gameState, queues, id);
}
// Assign military guards if we can afford it
if (gameState.getPopulation() > 30)
this.manageCriticalEntGuards(gameState);
this.manageCriticalEntGuards(gameState);
}
}
};

View file

@ -426,7 +426,7 @@ m.QueueManager.prototype.checkPausedQueues = function(gameState)
toBePaused = (q !== "citizenSoldier" && q !== "villager" && q !== "emergency");
else if (numWorkers < workersMin * 2 / 3)
toBePaused = (q === "civilCentre" || q === "economicBuilding" ||
q === "militaryBuilding" || q === "defenseBuilding" ||
q === "militaryBuilding" || q === "defenseBuilding" || q === "healer" ||
q === "majorTech" || q === "minorTech" || q.indexOf("plan_") !== -1);
else if (numWorkers < workersMin)
toBePaused = (q === "civilCentre" || q === "defenseBuilding" ||