1
0
forked from mirrors/0ad

Cleanup TileClass prototype and use vector arguments for countInRadius, countMembersInRadius, countNonMembersInRadius, refs #4992.

This was SVN commit r21026.
This commit is contained in:
elexis
2018-01-27 04:37:00 +00:00
parent 2ac7d4fd32
commit 8585040f27
6 changed files with 48 additions and 57 deletions
@@ -260,11 +260,11 @@ for (var ix = 0; ix < mapSize; ix++)
let position = new Vector2D(ix, iz); let position = new Vector2D(ix, iz);
let h = g_Map.getHeight(position); let h = g_Map.getHeight(position);
if (h > 15 && h < 45 && clPlayer.countMembersInRadius(ix, iz, 1) == 0) if (h > 15 && h < 45 && clPlayer.countMembersInRadius(position, 1) == 0)
explorablePoints.push(position); explorablePoints.push(position);
if (h > 35 && randBool(0.1) || if (h > 35 && randBool(0.1) ||
h < 15 && randBool(0.05) && clHillDeco.countMembersInRadius(ix, iz, 1) == 0) h < 15 && randBool(0.05) && clHillDeco.countMembersInRadius(position, 1) == 0)
placeObject(Vector2D.add(position, new Vector2D(1, 1).mult(randFloat(0, 1))), pickRandom(aTrees), 0, randomAngle()); placeObject(Vector2D.add(position, new Vector2D(1, 1).mult(randFloat(0, 1))), pickRandom(aTrees), 0, randomAngle());
} }
@@ -269,7 +269,7 @@ for (let mapX = 0; mapX < mapSize; ++mapX)
for (let mapZ = 0; mapZ < mapSize; ++mapZ) for (let mapZ = 0; mapZ < mapSize; ++mapZ)
{ {
let position = new Vector2D(mapX, mapZ); let position = new Vector2D(mapX, mapZ);
let terrain = getCosricaSardiniaTerrain(mapX, mapZ); let terrain = getCosricaSardiniaTerrain(position);
if (!terrain) if (!terrain)
continue; continue;
@@ -279,13 +279,12 @@ for (let mapX = 0; mapX < mapSize; ++mapX)
clCliffs.add(position); clCliffs.add(position);
} }
function getCosricaSardiniaTerrain(mapX, mapZ) function getCosricaSardiniaTerrain(position)
{ {
let position = new Vector2D(mapX, mapZ); let isWater = clWater.countMembersInRadius(position, 3);
let isWater = clWater.countMembersInRadius(mapX, mapZ, 3); let isShore = clShore.countMembersInRadius(position, 2);
let isShore = clShore.countMembersInRadius(mapX, mapZ, 2); let isPassage = clPassage.countMembersInRadius(position, 2);
let isPassage = clPassage.countMembersInRadius(mapX, mapZ, 2); let isSettlement = clSettlement.countMembersInRadius(position, 2);
let isSettlement = clSettlement.countMembersInRadius(mapX, mapZ, 2);
if (isSettlement) if (isSettlement)
return undefined; return undefined;
@@ -308,7 +308,7 @@ for (var sandx = 0; sandx < mapSize; sandx += 4)
createObjectGroup(group, 0); createObjectGroup(group, 0);
} }
if (clPassage.countMembersInRadius(sandx, sandz, 2)) if (clPassage.countMembersInRadius(position, 2))
{ {
if (randBool(0.4)) if (randBool(0.4))
{ {
@@ -244,7 +244,7 @@ for (let ix = 1; ix < mapSize - 1; ++ix)
for (let iz = 1; iz < mapSize - 1; ++iz) for (let iz = 1; iz < mapSize - 1; ++iz)
{ {
let position = new Vector2D(ix, iz); let position = new Vector2D(ix, iz);
if (g_Map.validHeight(position) && clPyrenneans.countMembersInRadius(ix, iz, 1)) if (g_Map.validHeight(position) && clPyrenneans.countMembersInRadius(position, 1))
{ {
let height = g_Map.getHeight(position); let height = g_Map.getHeight(position);
let index = 1 / (1 + Math.max(0, height / 7)); let index = 1 / (1 + Math.max(0, height / 7));
@@ -280,7 +280,7 @@ for (let ix = 1; ix < mapSize - 1; ++ix)
for (let iz = 1; iz < mapSize - 1; ++iz) for (let iz = 1; iz < mapSize - 1; ++iz)
{ {
let position = new Vector2D(ix, iz); let position = new Vector2D(ix, iz);
if (g_Map.inMapBounds(position) && clPyrenneans.countMembersInRadius(ix, iz, 1)) if (g_Map.inMapBounds(position) && clPyrenneans.countMembersInRadius(position, 1))
{ {
let heightNeighbor = g_Map.getAverageHeight(position); let heightNeighbor = g_Map.getAverageHeight(position);
let index = 1 / (1 + Math.max(0, (g_Map.getHeight(position) - 10) / 7)); let index = 1 / (1 + Math.max(0, (g_Map.getHeight(position) - 10) / 7));
@@ -303,7 +303,7 @@ for (let ix = 1; ix < mapSize - 1; ++ix)
for (let iz = 1; iz < mapSize - 1; ++iz) for (let iz = 1; iz < mapSize - 1; ++iz)
{ {
let position = new Vector2D(ix, iz); let position = new Vector2D(ix, iz);
if (!g_Map.inMapBounds(position) || !clWater.countMembersInRadius(ix, iz, smoothDist)) if (!g_Map.inMapBounds(position) || !clWater.countMembersInRadius(position, smoothDist))
continue; continue;
let averageHeight = 0; let averageHeight = 0;
let todivide = 0; let todivide = 0;
@@ -360,26 +360,26 @@ for (let x = 0; x < mapSize; ++x)
let height = g_Map.getHeight(position); let height = g_Map.getHeight(position);
let heightDiff = g_Map.getSlope(position); let heightDiff = g_Map.getSlope(position);
if (clPyrenneans.countMembersInRadius(x, z, 2)) if (clPyrenneans.countMembersInRadius(position, 2))
{ {
let layer = terrainPerHeight.find(layer => height < layer.maxHeight); let layer = terrainPerHeight.find(layer => height < layer.maxHeight);
createTerrain(heightDiff > layer.steepness ? layer.terrainSteep : layer.terrainGround).place(position); createTerrain(heightDiff > layer.steepness ? layer.terrainSteep : layer.terrainGround).place(position);
} }
let terrainShore = getShoreTerrain(height, heightDiff, x, z); let terrainShore = getShoreTerrain(position, height, heightDiff);
if (terrainShore) if (terrainShore)
createTerrain(terrainShore).place(position); createTerrain(terrainShore).place(position);
} }
function getShoreTerrain(height, heightDiff, x, z) function getShoreTerrain(position, height, heightDiff)
{ {
if (height <= -14) if (height <= -14)
return tWater; return tWater;
if (height <= -2 && clWater.countMembersInRadius(x, z, 2)) if (height <= -2 && clWater.countMembersInRadius(position, 2))
return heightDiff < 2.5 ? tSand : tMidRangeCliffs; return heightDiff < 2.5 ? tSand : tMidRangeCliffs;
if (height <= 0 && clWater.countMembersInRadius(x, z, 3)) if (height <= 0 && clWater.countMembersInRadius(position, 3))
return heightDiff < 2.5 ? tSandTransition : tMidRangeCliffs; return heightDiff < 2.5 ? tSandTransition : tMidRangeCliffs;
return undefined; return undefined;
@@ -67,7 +67,7 @@ function AvoidTileClassConstraint(tileClass, distance)
AvoidTileClassConstraint.prototype.allows = function(position) AvoidTileClassConstraint.prototype.allows = function(position)
{ {
return this.tileClass.countMembersInRadius(position.x, position.y, this.distance) == 0; return this.tileClass.countMembersInRadius(position, this.distance) == 0;
}; };
/** /**
@@ -81,7 +81,7 @@ function StayInTileClassConstraint(tileClass, distance)
StayInTileClassConstraint.prototype.allows = function(position) StayInTileClassConstraint.prototype.allows = function(position)
{ {
return this.tileClass.countNonMembersInRadius(position.x, position.y, this.distance) == 0; return this.tileClass.countNonMembersInRadius(position, this.distance) == 0;
}; };
/** /**
@@ -98,8 +98,8 @@ function BorderTileClassConstraint(tileClass, distanceInside, distanceOutside)
BorderTileClassConstraint.prototype.allows = function(position) BorderTileClassConstraint.prototype.allows = function(position)
{ {
return this.tileClass.countMembersInRadius(position.x, position.y, this.distanceOutside) > 0 && return this.tileClass.countMembersInRadius(position, this.distanceOutside) > 0 &&
this.tileClass.countNonMembersInRadius(position.x, position.y, this.distanceInside) > 0; this.tileClass.countNonMembersInRadius(position, this.distanceInside) > 0;
}; };
/** /**
@@ -92,54 +92,46 @@ TileClass.prototype.remove = function(position)
this.rangeCount[position.y].add(position.x, -1); this.rangeCount[position.y].add(position.x, -1);
}; };
TileClass.prototype.countInRadius = function(cx, cy, radius, returnMembers) TileClass.prototype.countInRadius = function(position, radius, returnMembers)
{ {
var members = 0; let members = 0;
var nonMembers = 0; let nonMembers = 0;
var size = this.size; let radius2 = Math.square(radius);
var ymax = cy+radius; for (let y = position.y - radius; y <= position.y + radius; ++y)
var radius2 = radius*radius;
for (var y = cy-radius; y <= ymax; y++)
{ {
var iy = Math.floor(y); let iy = Math.floor(y);
if (radius >= 27) // Switchover point before RangeOp actually performs better than a straight algorithm if (radius >= 27) // Switchover point before RangeOp actually performs better than a straight algorithm
{ {
if(iy >= 0 && iy < size) if (iy >= 0 && iy < this.size)
{ {
var dy = y - cy; let dx = Math.sqrt(Math.square(radius) - Math.square(y - position.y));
var dx = Math.sqrt(radius*radius - dy*dy);
var lowerX = Math.floor(cx - dx); let minX = Math.max(Math.floor(position.x - dx), 0);
var upperX = Math.floor(cx + dx); let maxX = Math.min(Math.floor(position.x + dx), this.size - 1) + 1;
var minX = (lowerX > 0 ? lowerX : 0); let newMembers = this.rangeCount[iy].get(minX, maxX);
var maxX = (upperX < size ? upperX+1 : size);
var total = maxX - minX; members += newMembers;
var mem = this.rangeCount[iy].get(minX, maxX); nonMembers += maxX - minX - newMembers;
members += mem;
nonMembers += total - mem;
} }
} }
else // Simply check the tiles one by one to find the number else // Simply check the tiles one by one to find the number
{ {
var dy = (iy - cy); let dy = iy - position.y;
var xmin = Math.floor(cx - radius);
var xmax = Math.ceil(cx + radius); let xMin = Math.max(Math.floor(position.x - radius), 0);
xmin = (xmin >= 0) ? xmin : 0; let xMax = Math.max(Math.ceil(position.x + radius), this.size - 1);
xmax = ( xmax < size) ? xmax : size - 1;
for (var ix = xmin; ix <= xmax; ++ix) for (let ix = xMin; ix <= xMax; ++ix)
{ {
var dx = (ix - cx); let dx = ix - position.x;
if (dx*dx + dy*dy <= radius2) if (Math.square(dx) + Math.square(dy) <= radius2)
{ {
if (this.inclusionCount[ix] && this.inclusionCount[ix][iy] && this.inclusionCount[ix][iy] > 0) if (this.inclusionCount[ix] && this.inclusionCount[ix][iy] && this.inclusionCount[ix][iy] > 0)
members += 1; ++members;
else else
nonMembers += 1; ++nonMembers;
} }
} }
} }
@@ -151,12 +143,12 @@ TileClass.prototype.countInRadius = function(cx, cy, radius, returnMembers)
return nonMembers; return nonMembers;
}; };
TileClass.prototype.countMembersInRadius = function(cx, cy, radius) TileClass.prototype.countMembersInRadius = function(position, radius)
{ {
return this.countInRadius(cx, cy, radius, true); return this.countInRadius(position, radius, true);
}; };
TileClass.prototype.countNonMembersInRadius = function(cx, cy, radius) TileClass.prototype.countNonMembersInRadius = function(position, radius)
{ {
return this.countInRadius(cx, cy, radius, false); return this.countInRadius(position, radius, false);
}; };