forked from 0ad/0ad
wraitii
9d02495a96
Improve the AI gamestate to make better use of entity collections, should be very slightly faster, and it's cleaner. Remove enemy watchers that were no longer used. This was SVN commit r14574.
149 lines
5.3 KiB
JavaScript
149 lines
5.3 KiB
JavaScript
var AEGIS = function(m)
|
|
{
|
|
|
|
// other map functions
|
|
m.TERRITORY_PLAYER_MASK = 0x3F;
|
|
|
|
m.createObstructionMap = function(gameState, accessIndex, template){
|
|
var passabilityMap = gameState.getMap();
|
|
var territoryMap = gameState.ai.territoryMap;
|
|
|
|
// default values
|
|
var placementType = "land";
|
|
var buildOwn = true;
|
|
var buildAlly = true;
|
|
var buildNeutral = true;
|
|
var buildEnemy = false;
|
|
// If there is a template then replace the defaults
|
|
if (template){
|
|
placementType = template.buildPlacementType();
|
|
buildOwn = template.hasBuildTerritory("own");
|
|
buildAlly = template.hasBuildTerritory("ally");
|
|
buildNeutral = template.hasBuildTerritory("neutral");
|
|
buildEnemy = template.hasBuildTerritory("enemy");
|
|
}
|
|
|
|
var obstructionMask = gameState.getPassabilityClassMask("foundationObstruction") | gameState.getPassabilityClassMask("building-land");
|
|
|
|
if (placementType == "shore")
|
|
{
|
|
// TODO: this won't change much, should be cached, it's slow.
|
|
var obstructionTiles = new Uint8Array(passabilityMap.data.length);
|
|
var okay = false;
|
|
for (var x = 0; x < passabilityMap.width; ++x)
|
|
{
|
|
for (var y = 0; y < passabilityMap.height; ++y)
|
|
{
|
|
var i = x + y*passabilityMap.width;
|
|
var tilePlayer = (territoryMap.data[i] & m.TERRITORY_PLAYER_MASK);
|
|
|
|
if (gameState.ai.myIndex !== gameState.ai.accessibility.landPassMap[i])
|
|
{
|
|
obstructionTiles[i] = 0;
|
|
continue;
|
|
}
|
|
if (gameState.isPlayerEnemy(tilePlayer) && tilePlayer !== 0)
|
|
{
|
|
obstructionTiles[i] = 0;
|
|
continue;
|
|
}
|
|
if ((passabilityMap.data[i] & (gameState.getPassabilityClassMask("building-shore") | gameState.getPassabilityClassMask("default"))))
|
|
{
|
|
obstructionTiles[i] = 0;
|
|
continue;
|
|
}
|
|
|
|
okay = false;
|
|
var positions = [[0,1], [1,1], [1,0], [1,-1], [0,-1], [-1,-1], [-1,0], [-1,1]];
|
|
var available = 0;
|
|
for each (var stuff in positions)
|
|
{
|
|
var index = x + stuff[0] + (y+stuff[1])*passabilityMap.width;
|
|
var index2 = x + stuff[0]*2 + (y+stuff[1]*2)*passabilityMap.width;
|
|
var index3 = x + stuff[0]*3 + (y+stuff[1]*3)*passabilityMap.width;
|
|
var index4 = x + stuff[0]*4 + (y+stuff[1]*4)*passabilityMap.width;
|
|
|
|
if ((passabilityMap.data[index] & gameState.getPassabilityClassMask("default")) && gameState.ai.accessibility.getRegionSizei(index,true) > 500)
|
|
if ((passabilityMap.data[index2] & gameState.getPassabilityClassMask("default")) && gameState.ai.accessibility.getRegionSizei(index2,true) > 500)
|
|
if ((passabilityMap.data[index3] & gameState.getPassabilityClassMask("default")) && gameState.ai.accessibility.getRegionSizei(index3,true) > 500)
|
|
if ((passabilityMap.data[index4] & gameState.getPassabilityClassMask("default")) && gameState.ai.accessibility.getRegionSizei(index4,true) > 500) {
|
|
if (available < 2)
|
|
available++;
|
|
else
|
|
okay = true;
|
|
}
|
|
}
|
|
// checking for accessibility: if a neighbor is inaccessible, this is too. If it's not on the same "accessible map" as us, we crash-i~u.
|
|
var radius = 3;
|
|
for (var xx = -radius;xx <= radius; xx++)
|
|
for (var yy = -radius;yy <= radius; yy++)
|
|
{
|
|
var id = x + xx + (y+yy)*passabilityMap.width;
|
|
if (id > 0 && id < passabilityMap.data.length)
|
|
if (gameState.ai.terrainAnalyzer.map[id] === 0 || gameState.ai.terrainAnalyzer.map[id] == 30 || gameState.ai.terrainAnalyzer.map[id] == 40)
|
|
okay = false;
|
|
}
|
|
obstructionTiles[i] = okay ? 255 : 0;
|
|
}
|
|
}
|
|
} else {
|
|
var playerID = PlayerID;
|
|
|
|
var obstructionTiles = new Uint8Array(passabilityMap.data.length);
|
|
for (var i = 0; i < passabilityMap.data.length; ++i)
|
|
{
|
|
var tilePlayer = (territoryMap.data[i] & m.TERRITORY_PLAYER_MASK);
|
|
var invalidTerritory = (
|
|
(!buildOwn && tilePlayer == playerID) ||
|
|
(!buildAlly && gameState.isPlayerAlly(tilePlayer) && tilePlayer != playerID) ||
|
|
(!buildNeutral && tilePlayer == 0) ||
|
|
(!buildEnemy && gameState.isPlayerEnemy(tilePlayer) && tilePlayer != 0)
|
|
);
|
|
if (accessIndex)
|
|
var tileAccessible = (accessIndex === gameState.ai.accessibility.landPassMap[i]);
|
|
else
|
|
var tileAccessible = true;
|
|
if (placementType === "shore")
|
|
tileAccessible = true;
|
|
obstructionTiles[i] = (!tileAccessible || invalidTerritory || (passabilityMap.data[i] & obstructionMask)) ? 0 : 255;
|
|
}
|
|
}
|
|
|
|
var map = new API3.Map(gameState.sharedScript, obstructionTiles);
|
|
map.setMaxVal(255);
|
|
|
|
if (template && template.buildDistance()){
|
|
var minDist = template.buildDistance().MinDistance;
|
|
var category = template.buildDistance().FromCategory;
|
|
if (minDist !== undefined && category !== undefined){
|
|
gameState.getOwnStructures().forEach(function(ent) {
|
|
if (ent.buildCategory() === category && ent.position()){
|
|
var pos = ent.position();
|
|
var x = Math.round(pos[0] / gameState.cellSize);
|
|
var z = Math.round(pos[1] / gameState.cellSize);
|
|
map.addInfluence(x, z, minDist/gameState.cellSize, -255, 'constant');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return map;
|
|
};
|
|
|
|
|
|
m.createTerritoryMap = function(gameState) {
|
|
var map = gameState.ai.territoryMap;
|
|
|
|
var ret = new API3.Map(gameState.sharedScript, map.data);
|
|
|
|
ret.getOwner = function(p) {
|
|
return this.point(p) & m.TERRITORY_PLAYER_MASK;
|
|
}
|
|
ret.getOwnerIndex = function(p) {
|
|
return this.map[p] & m.TERRITORY_PLAYER_MASK;
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
return m;
|
|
}(AEGIS);
|