mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-21 07:43:59 -07:00
petra: allow elephant stables for all civs, and some internal cleanups
This was SVN commit r20399.
This commit is contained in:
parent
bff1f33bfd
commit
2ead236afe
3 changed files with 60 additions and 55 deletions
|
|
@ -56,7 +56,7 @@ m.Config = function(difficulty)
|
|||
"gaul": [ "structures/{civ}_rotarymill", "structures/{civ}_tavern" ],
|
||||
"iber": [ "structures/{civ}_monument" ],
|
||||
"mace": [ "structures/{civ}_library", "structures/{civ}_theatron" ],
|
||||
"maur": [ "structures/{civ}_elephant_stables", "structures/{civ}_pillar_ashoka" ],
|
||||
"maur": [ "structures/{civ}_pillar_ashoka" ],
|
||||
"pers": [ "structures/{civ}_apadana", "structures/{civ}_hall"],
|
||||
"ptol": [ "structures/{civ}_library" ],
|
||||
"rome": [ "structures/{civ}_army_camp" ],
|
||||
|
|
|
|||
|
|
@ -1758,44 +1758,38 @@ m.HQ.prototype.constructTrainingBuildings = function(gameState, queues)
|
|||
if (numBarracks == 0)
|
||||
{
|
||||
gameState.ai.queueManager.changePriority("militaryBuilding", 2*this.Config.priorities.militaryBuilding);
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
let plan = new m.ConstructionPlan(gameState, "structures/{civ}_barracks", metadata);
|
||||
let plan = new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "militaryBase": true });
|
||||
plan.queueToReset = "militaryBuilding";
|
||||
queues.militaryBuilding.addPlan(plan);
|
||||
return;
|
||||
}
|
||||
if (numStables == 0)
|
||||
{
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_stables", metadata));
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_stables", { "militaryBase": true }));
|
||||
return;
|
||||
}
|
||||
|
||||
// Second barracks and stables
|
||||
if (numBarracks == 1 && gameState.getPopulation() > this.Config.Military.popForBarracks2)
|
||||
{
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", metadata));
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "militaryBase": true }));
|
||||
return;
|
||||
}
|
||||
if (numStables == 1 && gameState.getPopulation() > this.Config.Military.popForBarracks2)
|
||||
{
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_stables", metadata));
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_stables", { "militaryBase": true }));
|
||||
return;
|
||||
}
|
||||
|
||||
// Then 3rd barracks/stables if needed
|
||||
if (numBarracks == 2 && numStables == -1 && gameState.getPopulation() > this.Config.Military.popForBarracks2 + 30)
|
||||
{
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", metadata));
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "militaryBase": true }));
|
||||
return;
|
||||
}
|
||||
if (numBarracks == -1 && numStables == 2 && gameState.getPopulation() > this.Config.Military.popForBarracks2 + 30)
|
||||
{
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_stables", metadata));
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_stables", { "militaryBase": true }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1806,11 +1800,15 @@ m.HQ.prototype.constructTrainingBuildings = function(gameState, queues)
|
|||
if (this.currentPhase < 3)
|
||||
return;
|
||||
|
||||
let numWorkshop = this.canBuild(gameState, "structures/{civ}_siege_workshop") ? gameState.getOwnEntitiesByClass("Workshop", true).length : -1;
|
||||
if (numWorkshop == 0)
|
||||
if (this.canBuild(gameState, "structures/{civ}_elephant_stables") && !gameState.getOwnEntitiesByClass("ElephantStables", true).hasEntities())
|
||||
{
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_siege_workshop", metadata));
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_elephant_stables", { "militaryBase": true }));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.canBuild(gameState, "structures/{civ}_siege_workshop") && !gameState.getOwnEntitiesByClass("Workshop", true).hasEntities())
|
||||
{
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_siege_workshop", { "militaryBase": true }));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1832,10 +1830,7 @@ m.HQ.prototype.constructTrainingBuildings = function(gameState, queues)
|
|||
if (!template)
|
||||
continue;
|
||||
if (template.hasDefensiveFire() || template.trainableEntities())
|
||||
{
|
||||
let metadata = { "preferredBase": this.findBestBaseForMilitary(gameState) };
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced, metadata));
|
||||
}
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced, { "militaryBase": true }));
|
||||
else // not a military building, but still use this queue
|
||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced));
|
||||
return;
|
||||
|
|
@ -1844,23 +1839,32 @@ m.HQ.prototype.constructTrainingBuildings = function(gameState, queues)
|
|||
};
|
||||
|
||||
/**
|
||||
* Construct military building in bases nearest to the ennemies TODO revisit as the nearest one may not be accessible
|
||||
* Find base nearest to ennemies for military buildings.
|
||||
*/
|
||||
m.HQ.prototype.findBestBaseForMilitary = function(gameState)
|
||||
{
|
||||
let ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray();
|
||||
let bestBase = 1;
|
||||
let bestBase;
|
||||
let enemyFound = false;
|
||||
let distMin = Math.min();
|
||||
for (let cce of ccEnts)
|
||||
{
|
||||
if (gameState.isPlayerAlly(cce.owner()))
|
||||
continue;
|
||||
if (enemyFound && !gameState.isPlayerEnemy(cce.owner()))
|
||||
continue;
|
||||
let access = m.getLandAccess(gameState, cce);
|
||||
let isEnemy = gameState.isPlayerEnemy(cce.owner());
|
||||
for (let cc of ccEnts)
|
||||
{
|
||||
if (cc.owner() != PlayerID)
|
||||
continue;
|
||||
if (m.getLandAccess(gameState, cc) != access)
|
||||
continue;
|
||||
let dist = API3.SquareVectorDistance(cc.position(), cce.position());
|
||||
if (dist > distMin)
|
||||
if (!enemyFound && isEnemy)
|
||||
enemyFound = true;
|
||||
else if (dist > distMin)
|
||||
continue;
|
||||
bestBase = cc.getMetadata(PlayerID, "base");
|
||||
distMin = dist;
|
||||
|
|
@ -2449,7 +2453,8 @@ m.HQ.prototype.update = function(gameState, queues, events)
|
|||
this.garrisonManager.update(gameState, events);
|
||||
this.defenseManager.update(gameState, events);
|
||||
|
||||
this.constructTrainingBuildings(gameState, queues);
|
||||
if (gameState.ai.playedTurn % 3 == 0)
|
||||
this.constructTrainingBuildings(gameState, queues);
|
||||
|
||||
if (this.Config.difficulty > 0)
|
||||
this.buildDefenses(gameState, queues);
|
||||
|
|
|
|||
|
|
@ -109,10 +109,11 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
if (template.buildPlacementType() === "shore")
|
||||
return this.findDockPosition(gameState);
|
||||
|
||||
let HQ = gameState.ai.HQ;
|
||||
if (template.hasClass("Storehouse") && this.metadata.base)
|
||||
{
|
||||
// recompute the best dropsite location in case some conditions have changed
|
||||
let base = gameState.ai.HQ.getBaseByID(this.metadata.base);
|
||||
let base = HQ.getBaseByID(this.metadata.base);
|
||||
let type = this.metadata.type ? this.metadata.type : "wood";
|
||||
let newpos = base.findBestDropsiteLocation(gameState, type);
|
||||
if (newpos && newpos.quality > 0)
|
||||
|
|
@ -130,10 +131,10 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
if (this.metadata && this.metadata.resource)
|
||||
{
|
||||
let proximity = this.metadata.proximity ? this.metadata.proximity : undefined;
|
||||
pos = gameState.ai.HQ.findEconomicCCLocation(gameState, template, this.metadata.resource, proximity);
|
||||
pos = HQ.findEconomicCCLocation(gameState, template, this.metadata.resource, proximity);
|
||||
}
|
||||
else
|
||||
pos = gameState.ai.HQ.findStrategicCCLocation(gameState, template);
|
||||
pos = HQ.findStrategicCCLocation(gameState, template);
|
||||
|
||||
if (pos)
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "base": 0 };
|
||||
|
|
@ -141,7 +142,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
}
|
||||
else if (template.hasClass("DefenseTower") || template.hasClass("Fortress") || template.hasClass("ArmyCamp"))
|
||||
{
|
||||
let pos = gameState.ai.HQ.findDefensiveLocation(gameState, template);
|
||||
let pos = HQ.findDefensiveLocation(gameState, template);
|
||||
if (pos)
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "base": pos[2] };
|
||||
// if this fortress is our first one, just try the standard placement
|
||||
|
|
@ -150,7 +151,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
}
|
||||
else if (template.hasClass("Market")) // Docks (i.e. NavalMarket) are done before
|
||||
{
|
||||
let pos = gameState.ai.HQ.findMarketLocation(gameState, template);
|
||||
let pos = HQ.findMarketLocation(gameState, template);
|
||||
if (pos && pos[2] > 0)
|
||||
{
|
||||
if (!this.metadata)
|
||||
|
|
@ -184,17 +185,17 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
{
|
||||
let base = this.metadata.base;
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
if (gameState.ai.HQ.basesMap.map[j] == base)
|
||||
if (HQ.basesMap.map[j] == base)
|
||||
placement.map[j] = 45;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
if (gameState.ai.HQ.basesMap.map[j] !== 0)
|
||||
if (HQ.basesMap.map[j] != 0)
|
||||
placement.map[j] = 45;
|
||||
}
|
||||
|
||||
if (!gameState.ai.HQ.requireHouses || !template.hasClass("House"))
|
||||
if (!HQ.requireHouses || !template.hasClass("House"))
|
||||
{
|
||||
gameState.getOwnStructures().forEach(function(ent) {
|
||||
let pos = ent.position();
|
||||
|
|
@ -236,7 +237,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
{
|
||||
let value = placement.map[j] - gameState.sharedScript.resourceMaps.wood.map[j]/3;
|
||||
placement.map[j] = value >= 0 ? value : 0;
|
||||
if (gameState.ai.HQ.borderMap.map[j] & m.fullBorder_Mask)
|
||||
if (HQ.borderMap.map[j] & m.fullBorder_Mask)
|
||||
placement.map[j] /= 2; // we need space around farmstead, so disfavor map border
|
||||
}
|
||||
}
|
||||
|
|
@ -246,24 +247,24 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
// and if our first market, put it on border if possible to maximize distance with next market
|
||||
let favorBorder = template.hasClass("BarterMarket");
|
||||
let disfavorBorder = gameState.currentPhase() > 1 && !template.hasDefensiveFire();
|
||||
let preferredBase = this.metadata && this.metadata.preferredBase;
|
||||
let militaryBase = this.metadata && this.metadata.militaryBase ? HQ.findBestBaseForMilitary(gameState) : undefined;
|
||||
if (this.metadata && this.metadata.base !== undefined)
|
||||
{
|
||||
let base = this.metadata.base;
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
{
|
||||
if (gameState.ai.HQ.basesMap.map[j] != base)
|
||||
if (HQ.basesMap.map[j] != base)
|
||||
placement.map[j] = 0;
|
||||
else if (favorBorder && gameState.ai.HQ.borderMap.map[j] & m.border_Mask)
|
||||
placement.map[j] += 50;
|
||||
else if (disfavorBorder && !(gameState.ai.HQ.borderMap.map[j] & m.fullBorder_Mask) && placement.map[j] > 0)
|
||||
placement.map[j] += 10;
|
||||
|
||||
if (placement.map[j] > 0)
|
||||
else if (placement.map[j] > 0)
|
||||
{
|
||||
if (favorBorder && HQ.borderMap.map[j] & m.border_Mask)
|
||||
placement.map[j] += 50;
|
||||
else if (disfavorBorder && !(HQ.borderMap.map[j] & m.fullBorder_Mask))
|
||||
placement.map[j] += 10;
|
||||
|
||||
let x = (j % placement.width + 0.5) * cellSize;
|
||||
let z = (Math.floor(j / placement.width) + 0.5) * cellSize;
|
||||
if (gameState.ai.HQ.isNearInvadingArmy([x, z]))
|
||||
if (HQ.isNearInvadingArmy([x, z]))
|
||||
placement.map[j] = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -272,22 +273,21 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
{
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
{
|
||||
if (gameState.ai.HQ.basesMap.map[j] === 0)
|
||||
if (HQ.basesMap.map[j] == 0)
|
||||
placement.map[j] = 0;
|
||||
else if (favorBorder && gameState.ai.HQ.borderMap.map[j] & m.border_Mask)
|
||||
placement.map[j] += 50;
|
||||
else if (disfavorBorder && !(gameState.ai.HQ.borderMap.map[j] & m.fullBorder_Mask) && placement.map[j] > 0)
|
||||
placement.map[j] += 10;
|
||||
|
||||
if (preferredBase && gameState.ai.HQ.basesMap.map[j] == this.metadata.preferredBase)
|
||||
placement.map[j] += 200;
|
||||
|
||||
if (placement.map[j] > 0)
|
||||
else if (placement.map[j] > 0)
|
||||
{
|
||||
if (favorBorder && HQ.borderMap.map[j] & m.border_Mask)
|
||||
placement.map[j] += 50;
|
||||
else if (disfavorBorder && !(HQ.borderMap.map[j] & m.fullBorder_Mask))
|
||||
placement.map[j] += 10;
|
||||
|
||||
let x = (j % placement.width + 0.5) * cellSize;
|
||||
let z = (Math.floor(j / placement.width) + 0.5) * cellSize;
|
||||
if (gameState.ai.HQ.isNearInvadingArmy([x, z]))
|
||||
if (HQ.isNearInvadingArmy([x, z]))
|
||||
placement.map[j] = 0;
|
||||
else if (militaryBase && HQ.basesMap.map[j] == militaryBase)
|
||||
placement.map[j] += 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -333,7 +333,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
let territorypos = placement.gamePosToMapPos([x, z]);
|
||||
let territoryIndex = territorypos[0] + territorypos[1]*placement.width;
|
||||
// default angle = 3*Math.PI/4;
|
||||
return { "x": x, "z": z, "angle": 3*Math.PI/4, "base": gameState.ai.HQ.basesMap.map[territoryIndex] };
|
||||
return { "x": x, "z": z, "angle": 3*Math.PI/4, "base": HQ.basesMap.map[territoryIndex] };
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue