mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
AI fix for building placement + some cleanings
This was SVN commit r16793.
This commit is contained in:
parent
c6ca83949c
commit
eeee79e7f3
3 changed files with 28 additions and 64 deletions
|
|
@ -9,7 +9,7 @@ var API3 = function(m)
|
|||
m.Map = function Map(sharedScript, type, originalMap, actualCopy)
|
||||
{
|
||||
// get the correct dimensions according to the map type
|
||||
var map = (type === "territory" || type === "resource") ? sharedScript.territoryMap : sharedScript.passabilityMap;
|
||||
let map = (type === "territory" || type === "resource") ? sharedScript.territoryMap : sharedScript.passabilityMap;
|
||||
this.width = map.width;
|
||||
this.height = map.height;
|
||||
this.cellSize = map.cellSize;
|
||||
|
|
@ -45,7 +45,7 @@ m.Map.prototype.gamePosToMapPos = function(p)
|
|||
|
||||
m.Map.prototype.point = function(p)
|
||||
{
|
||||
var q = this.gamePosToMapPos(p);
|
||||
let q = this.gamePosToMapPos(p);
|
||||
q[0] = q[0] >= this.width ? this.width-1 : (q[0] < 0 ? 0 : q[0]);
|
||||
q[1] = q[1] >= this.width ? this.width-1 : (q[1] < 0 ? 0 : q[1]);
|
||||
return this.map[q[0] + this.width * q[1]];
|
||||
|
|
@ -233,7 +233,7 @@ m.Map.prototype.multiplyInfluence = function(cx, cy, maxDist, strength, type)
|
|||
|
||||
// doesn't check for overflow.
|
||||
m.Map.prototype.setInfluence = function(cx, cy, maxDist, value = 0)
|
||||
{
|
||||
{
|
||||
var x0 = Math.max(0, cx - maxDist);
|
||||
var y0 = Math.max(0, cy - maxDist);
|
||||
var x1 = Math.min(this.width, cx + maxDist);
|
||||
|
|
@ -416,7 +416,7 @@ m.Map.prototype.isObstructedTile = function(kx, ky, radius)
|
|||
return true;
|
||||
for (let dy = 0; dy <= radius; ++dy)
|
||||
{
|
||||
let dxmax = Math.ceil(Math.sqrt(radius*radius - dy*dy));
|
||||
let dxmax = (dy == 0) ? radius : Math.ceil(Math.sqrt(radius*radius - (dy-0.5)*(dy-0.5)));
|
||||
let xp = kx + (ky + dy)*w;
|
||||
let xm = kx + (ky - dy)*w;
|
||||
for (let dx = -dxmax; dx <= dxmax; ++dx)
|
||||
|
|
@ -473,28 +473,6 @@ m.Map.prototype.findNearestObstructed = function(k, radius)
|
|||
return -1;
|
||||
};
|
||||
|
||||
// returns the point with the lowest (but still > radius) point in the immediate vicinity
|
||||
m.Map.prototype.findLowestNeighbor = function(x,y,radius)
|
||||
{
|
||||
var lowestPt = [0,0];
|
||||
var lowestcoeff = undefined;
|
||||
x = Math.floor(x/this.cellSize);
|
||||
y = Math.floor(y/this.cellSize);
|
||||
for (let xx = x-1; xx <= x+1; ++xx)
|
||||
{
|
||||
for (let yy = y-1; yy <= y+1; ++yy)
|
||||
{
|
||||
if (xx < 0 || xx >= this.width || yy < 0 || yy >= this.width)
|
||||
continue;
|
||||
if (lowestcoeff && this.map[xx+yy*this.width] > lowestcoeff)
|
||||
continue;
|
||||
lowestcoeff = this.map[xx+yy*this.width];
|
||||
lowestPt = [(xx+0.5)*4, (yy+0.5)*4];
|
||||
}
|
||||
}
|
||||
return lowestPt;
|
||||
};
|
||||
|
||||
m.Map.prototype.dumpIm = function(name = "default.png", threshold = this.maxVal)
|
||||
{
|
||||
Engine.DumpImage(name, this.map, this.width, this.height, threshold);
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ m.SharedScript.prototype.init = function(state, deserialization)
|
|||
/*
|
||||
var landPassMap = new Uint8Array(this.passabilityMap.data.length);
|
||||
var waterPassMap = new Uint8Array(this.passabilityMap.data.length);
|
||||
var obstructionMaskLand = this.passabilityClasses["default"];
|
||||
var obstructionMaskLand = this.passabilityClasses["default-terrain-only"];
|
||||
var obstructionMaskWater = this.passabilityClasses["ship-small"];
|
||||
for (var i = 0; i < this.passabilityMap.data.length; ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ m.ConstructionPlan.prototype.canStart = function(gameState)
|
|||
if (this.template.requiredTech() && !gameState.isResearched(this.template.requiredTech()))
|
||||
return false;
|
||||
|
||||
return (gameState.findBuilders(this.type).length != 0);
|
||||
return (gameState.findBuilders(this.type).length > 0);
|
||||
};
|
||||
|
||||
m.ConstructionPlan.prototype.start = function(gameState)
|
||||
|
|
@ -89,7 +89,7 @@ m.ConstructionPlan.prototype.start = function(gameState)
|
|||
builders[0].construct(this.type, pos.x+shift*sina, pos.z+shift*cosa, pos.angle, this.metadata);
|
||||
}
|
||||
}
|
||||
else if (pos.x == pos.xx && pos.z == pos.zz)
|
||||
else if (pos.xx === undefined || (pos.x == pos.xx && pos.z == pos.zz))
|
||||
builders[0].construct(this.type, pos.x, pos.z, pos.angle, this.metadata);
|
||||
else // try with the lowest, move towards us unless we're same
|
||||
{
|
||||
|
|
@ -123,7 +123,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
if (newpos && newpos.quality > 0)
|
||||
{
|
||||
let pos = newpos.pos;
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "xx": pos[0], "zz": pos[1], "base": this.metadata.base };
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "base": this.metadata.base };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
var pos = gameState.ai.HQ.findStrategicCCLocation(gameState, template);
|
||||
|
||||
if (pos)
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "xx": pos[0], "zz": pos[1], "base": 0 };
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "base": 0 };
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
var pos = gameState.ai.HQ.findDefensiveLocation(gameState, template);
|
||||
|
||||
if (pos)
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "xx": pos[0], "zz": pos[1], "base": pos[2] };
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "base": pos[2] };
|
||||
else if (!template.hasClass("Fortress") || gameState.civ() === "mace" || gameState.civ() === "maur" ||
|
||||
gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_fortress"), true)
|
||||
+ gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_army_camp"), true) > 0)
|
||||
|
|
@ -164,7 +164,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
if (!this.metadata)
|
||||
this.metadata = {};
|
||||
this.metadata.expectedGain = pos[3];
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "xx": pos[0], "zz": pos[1], "base": pos[2] };
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "base": pos[2] };
|
||||
}
|
||||
else if (!pos)
|
||||
return false;
|
||||
|
|
@ -191,13 +191,13 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
if (this.metadata && this.metadata.base !== undefined)
|
||||
{
|
||||
var base = this.metadata.base;
|
||||
for (var j = 0; j < placement.map.length; ++j)
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
if (gameState.ai.HQ.basesMap.map[j] == base)
|
||||
placement.map[j] = 45;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var j = 0; j < placement.map.length; ++j)
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
if (gameState.ai.HQ.basesMap.map[j] != 0)
|
||||
placement.map[j] = 45;
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
|
||||
if (template.hasClass("Farmstead"))
|
||||
{
|
||||
for (var j = 0; j < placement.map.length; ++j)
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
{
|
||||
var value = placement.map[j] - (gameState.sharedScript.resourceMaps["wood"].map[j])/3;
|
||||
placement.map[j] = value >= 0 ? value : 0;
|
||||
|
|
@ -256,7 +256,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
if (this.metadata && this.metadata.base !== undefined)
|
||||
{
|
||||
var base = this.metadata.base;
|
||||
for (var j = 0; j < placement.map.length; ++j)
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
{
|
||||
if (gameState.ai.HQ.basesMap.map[j] != base)
|
||||
placement.map[j] = 0;
|
||||
|
|
@ -267,8 +267,8 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
|
||||
if (placement.map[j] > 0)
|
||||
{
|
||||
var x = (j % placement.width + 0.5) * cellSize;
|
||||
var z = (Math.floor(j / placement.width) + 0.5) * cellSize;
|
||||
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]))
|
||||
placement.map[j] = 0;
|
||||
}
|
||||
|
|
@ -276,7 +276,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
}
|
||||
else
|
||||
{
|
||||
for (var j = 0; j < placement.map.length; ++j)
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
{
|
||||
if (gameState.ai.HQ.basesMap.map[j] == 0)
|
||||
placement.map[j] = 0;
|
||||
|
|
@ -290,8 +290,8 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
|
||||
if (placement.map[j] > 0)
|
||||
{
|
||||
var x = (j % placement.width + 0.5) * cellSize;
|
||||
var z = (Math.floor(j / placement.width) + 0.5) * cellSize;
|
||||
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]))
|
||||
placement.map[j] = 0;
|
||||
}
|
||||
|
|
@ -314,7 +314,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
else if (template.resourceDropsiteTypes() === undefined && !template.hasClass("House") && !template.hasClass("Field"))
|
||||
radius = Math.ceil((template.obstructionRadius() + 4) / obstructions.cellSize);
|
||||
else
|
||||
radius = Math.ceil(template.obstructionRadius() / obstructions.cellSize) + 1;
|
||||
radius = Math.ceil(template.obstructionRadius() / obstructions.cellSize);
|
||||
|
||||
if (template.hasClass("House") && !alreadyHasHouses)
|
||||
{
|
||||
|
|
@ -337,34 +337,20 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||
var x = ((bestIdx % obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
var z = (Math.floor(bestIdx / obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
|
||||
var xx = x;
|
||||
var zz = z;
|
||||
if (template.hasClass("House") || template.hasClass("Field") || template.resourceDropsiteTypes() !== undefined)
|
||||
{
|
||||
if (obstructions.cellSize != 4) // new pathFinder branch
|
||||
let secondBest = obstructions.findNearestObstructed(bestIdx, radius);
|
||||
if (secondBest >= 0)
|
||||
{
|
||||
let secondBest = obstructions.findNearestObstructed(bestIdx, radius);
|
||||
if (secondBest >= 0)
|
||||
{
|
||||
x = ((secondBest % obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
z = (Math.floor(secondBest / obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
xx = x;
|
||||
zz = z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obstructions.expandInfluences();
|
||||
let secondBest = obstructions.findLowestNeighbor(x,z);
|
||||
xx = secondBest[0];
|
||||
zz = secondBest[1];
|
||||
x = ((secondBest % obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
z = (Math.floor(secondBest / obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
}
|
||||
}
|
||||
|
||||
let territorypos = placement.gamePosToMapPos([x,z]);
|
||||
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, "xx": xx, "zz": zz, "base": gameState.ai.HQ.basesMap.map[territoryIndex] };
|
||||
return { "x": x, "z": z, "angle": 3*Math.PI/4, "base": gameState.ai.HQ.basesMap.map[territoryIndex] };
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -501,7 +487,7 @@ m.ConstructionPlan.prototype.findDockPosition = function(gameState)
|
|||
}
|
||||
}
|
||||
|
||||
return { "x": x, "z": z, "angle": bestAngle, "xx": x, "zz": z, "base": baseIndex, "access": bestLand };
|
||||
return { "x": x, "z": z, "angle": bestAngle, "base": baseIndex, "access": bestLand };
|
||||
};
|
||||
|
||||
// Algorithm taken from the function GetDockAngle in simulation/helpers/Commands.js
|
||||
|
|
|
|||
Loading…
Reference in a new issue