forked from mirrors/0ad
Petra: try to improve cart shipyard placement
This was SVN commit r15286.
This commit is contained in:
@@ -889,7 +889,7 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
return [-1, -1, -1];
|
||||
|
||||
// obstruction map
|
||||
var obstructions = m.createObstructionMap(gameState, 0);
|
||||
var obstructions = m.createObstructionMap(gameState, 0, template);
|
||||
obstructions.expandInfluences();
|
||||
|
||||
var width = this.territoryMap.width;
|
||||
@@ -906,8 +906,10 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
continue;
|
||||
if (obstructions.map[j] <= radius) // check room around
|
||||
continue;
|
||||
|
||||
var index = gameState.ai.accessibility.landPassMap[j];
|
||||
if (!this.allowedRegions[index])
|
||||
continue;
|
||||
|
||||
var pos = [j%width+0.5, Math.floor(j/width)+0.5];
|
||||
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
||||
// checking distances to other markets
|
||||
@@ -1445,9 +1447,7 @@ m.HQ.prototype.updateTerritories = function(gameState)
|
||||
continue;
|
||||
var distmin = Math.min();
|
||||
var baseID = undefined;
|
||||
var ix = j%width;
|
||||
var iy = Math.floor(j/width);
|
||||
var pos = [ix+0.5, iy+0.5];
|
||||
var pos = [j%width+0.5, Math.floor(j/width)+0.5];
|
||||
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
||||
for each (var base in this.baseManagers)
|
||||
{
|
||||
|
||||
@@ -459,7 +459,7 @@ m.NavalManager.prototype.buildNavalStructures = function(gameState, queues)
|
||||
if (gameState.countEntitiesAndQueuedByType(naval, true) < 1 && gameState.ai.HQ.canBuild(gameState, naval))
|
||||
{
|
||||
var sea = docks[0].getMetadata(PlayerID, "sea");
|
||||
queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, naval, { "sea" : sea }));
|
||||
queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, naval, { "sea": sea }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ m.ConstructionPlan.prototype.start = function(gameState)
|
||||
if (gameState.getTemplate(this.type).buildCategory() === "Dock")
|
||||
{
|
||||
// try to place it a bit inside the land if possible
|
||||
for (var d = -10; d <= 0; d += 2)
|
||||
for (var d = -10; d <= 2; d += 2)
|
||||
builders[0].construct(this.type, pos.x+d*Math.sin(pos.angle), pos.z+d*Math.cos(pos.angle), pos.angle, this.metadata);
|
||||
}
|
||||
else if (pos.x == pos.xx && pos.z == pos.zz)
|
||||
@@ -87,8 +87,12 @@ m.ConstructionPlan.prototype.start = function(gameState)
|
||||
// TODO for dock, we should allow building them outside territory, and we should check that we are along the right sea
|
||||
m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
{
|
||||
|
||||
var template = gameState.getTemplate(this.type);
|
||||
|
||||
if (template.buildCategory() === "Dock")
|
||||
return this.findDockPosition(gameState);
|
||||
|
||||
if (!this.position)
|
||||
{
|
||||
if (template.hasClass("CivCentre"))
|
||||
@@ -132,8 +136,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
// First, find all tiles that are far enough away from obstructions:
|
||||
|
||||
var obstructionMap = m.createObstructionMap(gameState, 0, template);
|
||||
if (template.buildCategory() !== "Dock")
|
||||
obstructionMap.expandInfluences();
|
||||
obstructionMap.expandInfluences();
|
||||
|
||||
//obstructionMap.dumpIm(template.buildCategory() + "_obstructions.png");
|
||||
|
||||
@@ -256,8 +259,6 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
if (template.hasClass("Fortress") || this.type === gameState.applyCiv("structures/{civ}_siege_workshop")
|
||||
|| this.type === gameState.applyCiv("structures/{civ}_elephant_stables"))
|
||||
radius = Math.floor(template.obstructionRadius() / cellSize) + 3;
|
||||
else if (template.buildCategory() === "Dock")
|
||||
radius = Math.ceil(template.obstructionRadius() / cellSize); // not used
|
||||
else if (template.resourceDropsiteTypes() === undefined && !template.hasClass("House") && !template.hasClass("Field"))
|
||||
radius = Math.ceil(template.obstructionRadius() / cellSize) + 1;
|
||||
else
|
||||
@@ -285,6 +286,128 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
var x = ((bestIdx % friendlyTiles.width) + 0.5) * cellSize;
|
||||
var z = (Math.floor(bestIdx / friendlyTiles.width) + 0.5) * cellSize;
|
||||
|
||||
if (template.hasClass("House") || template.hasClass("Field") || template.resourceDropsiteTypes() !== undefined)
|
||||
var secondBest = obstructionMap.findLowestNeighbor(x,z);
|
||||
else
|
||||
var secondBest = [x,z];
|
||||
|
||||
// default angle = 3*Math.PI/4;
|
||||
return { "x": x, "z": z, "angle": 3*Math.PI/4, "xx": secondBest[0], "zz": secondBest[1],
|
||||
"base": gameState.ai.HQ.basesMap.map[bestIdx] };
|
||||
};
|
||||
|
||||
// Placement of buildings with Dock build category
|
||||
// TODO for dock, we should allow building them outside territory, and we should check that we are along the right sea
|
||||
m.ConstructionPlan.prototype.findDockPosition = function(gameState)
|
||||
{
|
||||
var template = gameState.getTemplate(this.type);
|
||||
|
||||
var cellSize = gameState.cellSize; // size of each tile
|
||||
|
||||
// First, find all tiles that are far enough away from obstructions:
|
||||
|
||||
var obstructionMap = m.createObstructionMap(gameState, 0, template);
|
||||
//obstructionMap.dumpIm(template.buildCategory() + "_obstructions.png");
|
||||
|
||||
// Compute each tile's closeness to friendly structures:
|
||||
|
||||
var friendlyTiles = new API3.Map(gameState.sharedScript);
|
||||
|
||||
if (this.position) // If a position was specified then place the building as close to it as possible
|
||||
{
|
||||
var x = Math.floor(this.position[0] / cellSize);
|
||||
var z = Math.floor(this.position[1] / cellSize);
|
||||
friendlyTiles.addInfluence(x, z, 255);
|
||||
}
|
||||
else // No position was specified so try and find a sensible place to build
|
||||
{
|
||||
// give a small > 0 level as the result of addInfluence is constrained to be > 0
|
||||
// if we really need houses (i.e. townPhasing without enough village building), do not apply these constraints
|
||||
if (this.metadata && this.metadata.base !== undefined)
|
||||
{
|
||||
var base = this.metadata.base;
|
||||
for (var j = 0; j < friendlyTiles.map.length; ++j)
|
||||
if (gameState.ai.HQ.basesMap.map[j] === base)
|
||||
friendlyTiles.map[j] = 45;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var j = 0; j < friendlyTiles.map.length; ++j)
|
||||
if (gameState.ai.HQ.basesMap.map[j] !== 0)
|
||||
friendlyTiles.map[j] = 45;
|
||||
}
|
||||
|
||||
if (!gameState.ai.HQ.requireHouses || !template.hasClass("House"))
|
||||
{
|
||||
gameState.getOwnStructures().forEach(function(ent) {
|
||||
var pos = ent.position();
|
||||
var x = Math.round(pos[0] / cellSize);
|
||||
var z = Math.round(pos[1] / cellSize);
|
||||
|
||||
if (ent.resourceDropsiteTypes() && ent.resourceDropsiteTypes().indexOf("food") !== -1)
|
||||
{
|
||||
if (template.hasClass("Field"))
|
||||
friendlyTiles.addInfluence(x, z, 20, 50);
|
||||
else // If this is not a field add a negative influence because we want to leave this area for fields
|
||||
friendlyTiles.addInfluence(x, z, 20, -20);
|
||||
}
|
||||
else if (template.hasClass("GarrisonFortress") && ent.genericName() == "House")
|
||||
friendlyTiles.addInfluence(x, z, 30, -50);
|
||||
else if (template.hasClass("Military"))
|
||||
friendlyTiles.addInfluence(x, z, 10, -40);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// requires to be inside our territory, and inside our base territory if required
|
||||
// and if our first market, put it on border if possible to maximize distance with next market
|
||||
var favorBorder = template.hasClass("BarterMarket");
|
||||
var disfavorBorder = (template.buildCategory() === "Dock");
|
||||
var preferredBase = (this.metadata && this.metadata.preferredBase);
|
||||
if (this.metadata && this.metadata.base !== undefined)
|
||||
{
|
||||
var base = this.metadata.base;
|
||||
for (var j = 0; j < friendlyTiles.map.length; ++j)
|
||||
{
|
||||
if (gameState.ai.HQ.basesMap.map[j] !== base)
|
||||
friendlyTiles.map[j] = 0;
|
||||
else if (favorBorder && gameState.ai.HQ.borderMap.map[j] > 0)
|
||||
friendlyTiles.map[j] += 50;
|
||||
else if (disfavorBorder && gameState.ai.HQ.borderMap.map[j] === 0 && friendlyTiles.map[j] > 0)
|
||||
friendlyTiles.map[j] += 10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var j = 0; j < friendlyTiles.map.length; ++j)
|
||||
{
|
||||
if (gameState.ai.HQ.basesMap.map[j] === 0)
|
||||
friendlyTiles.map[j] = 0;
|
||||
else if (favorBorder && gameState.ai.HQ.borderMap.map[j] > 0)
|
||||
friendlyTiles.map[j] += 50;
|
||||
else if (disfavorBorder && gameState.ai.HQ.borderMap.map[j] === 0 && friendlyTiles.map[j] > 0)
|
||||
friendlyTiles.map[j] += 10;
|
||||
|
||||
if (preferredBase && gameState.ai.HQ.basesMap.map[j] === this.metadata.preferredBase)
|
||||
friendlyTiles.map[j] += 200;
|
||||
}
|
||||
}
|
||||
|
||||
var radius = 1; // not used
|
||||
|
||||
if (bestVal === undefined || bestVal === -1)
|
||||
{
|
||||
var bestTile = friendlyTiles.findBestTile(radius, obstructionMap);
|
||||
var bestIdx = bestTile[0];
|
||||
var bestVal = bestTile[1];
|
||||
}
|
||||
|
||||
if (bestVal <= 0)
|
||||
return false;
|
||||
|
||||
var x = ((bestIdx % friendlyTiles.width) + 0.5) * cellSize;
|
||||
var z = (Math.floor(bestIdx / friendlyTiles.width) + 0.5) * cellSize;
|
||||
|
||||
if (template.hasClass("House") || template.hasClass("Field") || template.resourceDropsiteTypes() !== undefined)
|
||||
var secondBest = obstructionMap.findLowestNeighbor(x,z);
|
||||
else
|
||||
@@ -296,33 +419,28 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
// for Dock placement, we need to improve the position of the building as the position given here
|
||||
// is only the position on the shore, while the need the position of the center of the building
|
||||
// We also need to find the angle of the building
|
||||
if (template.buildCategory() === "Dock")
|
||||
{
|
||||
var angle = this.getDockAngle(gameState, template, x, z);
|
||||
if (!angle)
|
||||
return false;
|
||||
if (template.get("Obstruction") && template.get("Obstruction/Static"))
|
||||
var radius = (+template.get("Obstruction/Static/@depth"))/2;
|
||||
else if (template.get("Obstruction") && template.get("Obstruction/Unit"))
|
||||
var radius = +template.get("Obstruction/Unit/@radius");
|
||||
else
|
||||
{
|
||||
warn("Error: try to place a building without obstruction " + this.type);
|
||||
var radius = 0;
|
||||
}
|
||||
// Position of the center of the building
|
||||
x = x + radius*Math.sin(angle);
|
||||
z = z + radius*Math.cos(angle);
|
||||
}
|
||||
var angle = this.getDockAngle(gameState, template, x, z);
|
||||
if (!angle)
|
||||
return false;
|
||||
if (template.get("Obstruction") && template.get("Obstruction/Static"))
|
||||
var radius = (+template.get("Obstruction/Static/@depth"))/2;
|
||||
else if (template.get("Obstruction") && template.get("Obstruction/Unit"))
|
||||
var radius = +template.get("Obstruction/Unit/@radius");
|
||||
else
|
||||
var angle = 3*Math.PI/4;
|
||||
{
|
||||
warn("Error: try to place a building without obstruction " + this.type);
|
||||
var radius = 0;
|
||||
}
|
||||
// Position of the center of the building
|
||||
x = x + radius*Math.sin(angle);
|
||||
z = z + radius*Math.cos(angle);
|
||||
|
||||
// default angle = 3*Math.PI/4;
|
||||
return { "x": x, "z": z, "angle": angle, "xx": secondBest[0], "zz": secondBest[1],
|
||||
"base": gameState.ai.HQ.basesMap.map[bestIdx], "access": access };
|
||||
};
|
||||
|
||||
// Algorithm taken from the function GetDockAngle in helpers/Commands.j
|
||||
// Algorithm taken from the function GetDockAngle in helpers/Commands.js
|
||||
m.ConstructionPlan.prototype.getDockAngle = function(gameState, template, x, z)
|
||||
{
|
||||
var radius = template.obstructionRadius();
|
||||
|
||||
@@ -348,7 +348,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
|
||||
var self = this;
|
||||
|
||||
// Check that the units recovered on the previous turn have been reloaded
|
||||
for each (var recov in this.recovered)
|
||||
for (var recov of this.recovered)
|
||||
{
|
||||
var ent = gameState.getEntityById(recov.entId);
|
||||
if (!ent) // entity destroyed
|
||||
@@ -383,7 +383,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
|
||||
|
||||
// Check that the units unloaded on the previous turn have been really unloaded
|
||||
var shipsToMove = {};
|
||||
for each (var entId in this.unloaded)
|
||||
for (var entId of this.unloaded)
|
||||
{
|
||||
var ent = gameState.getEntityById(entId);
|
||||
if (!ent) // entity destroyed
|
||||
|
||||
Reference in New Issue
Block a user