2011-03-22 02:34:45 +01:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Constant definitions
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
const PI = Math.PI;
|
2011-05-02 00:29:58 +02:00
|
|
|
const TWO_PI = 2 * Math.PI;
|
2011-03-22 02:34:45 +01:00
|
|
|
const TERRAIN_SEPARATOR = "|";
|
2011-05-02 00:29:58 +02:00
|
|
|
const SEA_LEVEL = 20.0;
|
2011-04-21 16:13:13 +02:00
|
|
|
const CELL_SIZE = 4;
|
|
|
|
const HEIGHT_UNITS_PER_METRE = 732;
|
2011-05-02 00:29:58 +02:00
|
|
|
const MIN_MAP_SIZE = 128;
|
|
|
|
const MAX_MAP_SIZE = 512;
|
2011-04-21 16:13:13 +02:00
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Utility functions
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function fractionToTiles(f)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return getMapSize() * f;
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function tilesToFraction(t)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return t / getMapSize();
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function fractionToSize(f)
|
|
|
|
{
|
2011-03-28 00:00:49 +02:00
|
|
|
return getMapArea() * f;
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function sizeToFraction(s)
|
|
|
|
{
|
2011-03-28 00:00:49 +02:00
|
|
|
return s / getMapArea();
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-05-02 00:29:58 +02:00
|
|
|
function scaleByMapSize(min, max)
|
|
|
|
{
|
|
|
|
return min + ((max-min) * (getMapSize()-MIN_MAP_SIZE) / (MAX_MAP_SIZE-MIN_MAP_SIZE));
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function cos(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return Math.cos(x);
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function sin(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return Math.sin(x);
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function tan(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return Math.tan(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
function abs(x) {
|
|
|
|
return Math.abs(x);
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function round(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return Math.round(x);
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function lerp(a, b, t)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return a + (b-a) * t;
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function sqrt(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return Math.sqrt(x);
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function ceil(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return Math.ceil(x);
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function floor(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
return Math.floor(x);
|
|
|
|
}
|
|
|
|
|
2011-04-16 06:04:06 +02:00
|
|
|
function max(a, b)
|
2011-03-23 09:12:04 +01:00
|
|
|
{
|
2011-04-16 06:04:06 +02:00
|
|
|
return a > b ? a : b;
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-04-16 06:04:06 +02:00
|
|
|
function min(a, b)
|
2011-03-23 09:12:04 +01:00
|
|
|
{
|
2011-04-16 06:04:06 +02:00
|
|
|
return a < b ? a : b;
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function println(x)
|
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
print(x);
|
|
|
|
print("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
function argsToArray(x)
|
|
|
|
{
|
|
|
|
var numArgs = x.length;
|
|
|
|
if (numArgs != 1)
|
|
|
|
{
|
|
|
|
var ret = new Array(numArgs);
|
|
|
|
for (var i=0; i < numArgs; i++)
|
|
|
|
{
|
|
|
|
ret[i] = x[i];
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return x[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function chooseRand()
|
|
|
|
{
|
|
|
|
if (arguments.length==0)
|
|
|
|
{
|
2011-05-02 00:29:58 +02:00
|
|
|
throw("chooseRand: requires at least 1 argument");
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
var ar = argsToArray(arguments);
|
|
|
|
return ar[randInt(ar.length)];
|
|
|
|
}
|
|
|
|
|
2011-10-21 03:15:02 +02:00
|
|
|
// "Inside-out" implementation of Fisher-Yates shuffle
|
|
|
|
function shuffleArray(source)
|
|
|
|
{
|
|
|
|
if (!source.length)
|
|
|
|
return [];
|
|
|
|
|
|
|
|
var result = [source[0]];
|
|
|
|
for (var i = 1; i < source.length; i++)
|
|
|
|
{
|
|
|
|
var j = randInt(0, i);
|
|
|
|
result[i] = result[j];
|
|
|
|
result[j] = source[i];
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
function createAreas(centeredPlacer, painter, constraint, num, retryFactor)
|
|
|
|
{
|
|
|
|
if (retryFactor === undefined)
|
2011-03-23 09:12:04 +01:00
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
retryFactor = 10;
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
2011-03-22 02:34:45 +01:00
|
|
|
|
|
|
|
var maxFail = num * retryFactor;
|
|
|
|
var good = 0;
|
|
|
|
var bad = 0;
|
2011-03-23 09:12:04 +01:00
|
|
|
var result = [];
|
|
|
|
var halfSize = getMapSize()/2;
|
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
while(good < num && bad <= maxFail)
|
|
|
|
{
|
2011-03-23 09:12:04 +01:00
|
|
|
if (isCircularMap())
|
|
|
|
{ // Polar coordinates
|
|
|
|
var r = halfSize * Math.sqrt(randFloat()); // uniform distribution
|
|
|
|
var theta = randFloat(0, 2 * PI);
|
|
|
|
centeredPlacer.x = Math.floor(r * Math.cos(theta)) + halfSize;
|
2011-04-16 06:04:06 +02:00
|
|
|
centeredPlacer.z = Math.floor(r * Math.sin(theta)) + halfSize;
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Rectangular coordinates
|
|
|
|
centeredPlacer.x = randInt(getMapSize());
|
2011-04-16 06:04:06 +02:00
|
|
|
centeredPlacer.z = randInt(getMapSize());
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
2011-04-16 06:04:06 +02:00
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
var area = g_Map.createArea(centeredPlacer, painter, constraint);
|
|
|
|
if (area !== undefined)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
|
|
|
good++;
|
2011-03-23 09:12:04 +01:00
|
|
|
result.push(area);
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bad++;
|
|
|
|
}
|
|
|
|
}
|
2011-03-28 00:00:49 +02:00
|
|
|
return result;
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-05-02 00:29:58 +02:00
|
|
|
function createAreasInAreas(centeredPlacer, painter, constraint, num, retryFactor, areas)
|
|
|
|
{
|
|
|
|
if (retryFactor === undefined)
|
|
|
|
{
|
|
|
|
retryFactor = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
var maxFail = num * retryFactor;
|
|
|
|
var good = 0;
|
|
|
|
var bad = 0;
|
|
|
|
var result = [];
|
|
|
|
var numAreas = areas.length;
|
|
|
|
|
|
|
|
while(good < num && bad <= maxFail && numAreas)
|
|
|
|
{
|
|
|
|
// Choose random point from area
|
|
|
|
var i = randInt(numAreas);
|
|
|
|
var size = areas[i].points.length;
|
|
|
|
var pt = areas[i].points[randInt(size)];
|
|
|
|
centeredPlacer.x = pt.x;
|
|
|
|
centeredPlacer.z = pt.z;
|
|
|
|
|
|
|
|
var area = g_Map.createArea(centeredPlacer, painter, constraint);
|
|
|
|
if (area !== undefined)
|
|
|
|
{
|
|
|
|
good++;
|
|
|
|
result.push(area);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bad++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
function createObjectGroups(placer, player, constraint, num, retryFactor)
|
|
|
|
{
|
|
|
|
if (retryFactor === undefined)
|
2011-03-23 09:12:04 +01:00
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
retryFactor = 10;
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
2011-03-22 02:34:45 +01:00
|
|
|
|
|
|
|
var maxFail = num * retryFactor;
|
|
|
|
var good = 0;
|
|
|
|
var bad = 0;
|
2011-03-23 09:12:04 +01:00
|
|
|
var halfSize = getMapSize()/2;
|
2011-03-22 02:34:45 +01:00
|
|
|
while(good < num && bad <= maxFail)
|
|
|
|
{
|
2011-03-23 09:12:04 +01:00
|
|
|
if (isCircularMap())
|
|
|
|
{ // Polar coordinates
|
|
|
|
var r = halfSize * Math.sqrt(randFloat()); // uniform distribution
|
|
|
|
var theta = randFloat(0, 2 * PI);
|
|
|
|
placer.x = Math.floor(r * Math.cos(theta)) + halfSize;
|
2011-04-16 06:04:06 +02:00
|
|
|
placer.z = Math.floor(r * Math.sin(theta)) + halfSize;
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Rectangular coordinates
|
|
|
|
placer.x = randInt(getMapSize());
|
2011-04-16 06:04:06 +02:00
|
|
|
placer.z = randInt(getMapSize());
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
2011-03-22 02:34:45 +01:00
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
var result = createObjectGroup(placer, player, constraint);
|
|
|
|
if (result !== undefined)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
|
|
|
good++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bad++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return good;
|
|
|
|
}
|
|
|
|
|
2011-04-21 16:13:13 +02:00
|
|
|
function createObjectGroupsByAreas(placer, player, constraint, num, retryFactor, areas)
|
|
|
|
{
|
|
|
|
if (retryFactor === undefined)
|
|
|
|
{
|
|
|
|
retryFactor = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
var maxFail = num * retryFactor;
|
|
|
|
var good = 0;
|
|
|
|
var bad = 0;
|
|
|
|
var numAreas = areas.length;
|
|
|
|
|
2011-05-02 00:29:58 +02:00
|
|
|
while(good < num && bad <= maxFail && numAreas)
|
2011-04-21 16:13:13 +02:00
|
|
|
{
|
|
|
|
// Choose random point from area
|
|
|
|
var i = randInt(numAreas);
|
|
|
|
var size = areas[i].points.length;
|
|
|
|
var pt = areas[i].points[randInt(size)];
|
|
|
|
placer.x = pt.x;
|
|
|
|
placer.z = pt.z;
|
|
|
|
|
|
|
|
var result = createObjectGroup(placer, player, constraint);
|
|
|
|
if (result !== undefined)
|
|
|
|
{
|
|
|
|
good++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bad++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return good;
|
|
|
|
}
|
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
function createTerrain(terrain)
|
|
|
|
{
|
|
|
|
if (terrain instanceof Array)
|
|
|
|
{
|
|
|
|
var terrainList = [];
|
|
|
|
|
|
|
|
for (var i = 0; i < terrain.length; ++i)
|
2011-03-23 09:12:04 +01:00
|
|
|
{
|
2011-03-22 02:34:45 +01:00
|
|
|
terrainList.push(createTerrain(terrain[i]));
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
2011-03-22 02:34:45 +01:00
|
|
|
|
|
|
|
return new RandomTerrain(terrainList);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return createSimpleTerrain(terrain);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function createSimpleTerrain(terrain)
|
|
|
|
{
|
|
|
|
if (typeof(terrain) == "string")
|
|
|
|
{ // Split string by pipe | character, this allows specifying terrain + tree type in single string
|
|
|
|
var params = terrain.split(TERRAIN_SEPARATOR, 2);
|
|
|
|
|
|
|
|
if (params.length != 2)
|
|
|
|
{
|
|
|
|
return new SimpleTerrain(terrain);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return new SimpleTerrain(params[0], params[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-05-02 00:29:58 +02:00
|
|
|
throw("createSimpleTerrain expects string as input, received "+terrain);
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-16 06:04:06 +02:00
|
|
|
function placeObject(x, z, type, player, angle)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
2011-04-21 16:13:13 +02:00
|
|
|
g_Map.addObject(new Entity(type, player, x, z, angle));
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-04-16 06:04:06 +02:00
|
|
|
function placeTerrain(x, z, terrain)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
|
|
|
// convert terrain param into terrain object
|
2011-04-16 06:04:06 +02:00
|
|
|
g_Map.placeTerrain(x, z, createTerrain(terrain));
|
2011-03-22 02:34:45 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
function isCircularMap()
|
|
|
|
{
|
|
|
|
return (g_MapSettings.CircularMap ? true : false);
|
|
|
|
}
|
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Access global map variable
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
function createTileClass()
|
|
|
|
{
|
|
|
|
return g_Map.createTileClass();
|
|
|
|
}
|
|
|
|
|
|
|
|
function getTileClass(id)
|
|
|
|
{
|
|
|
|
// Check for valid class id
|
2011-03-23 09:12:04 +01:00
|
|
|
if (!g_Map.validClass(id))
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
2011-03-23 09:12:04 +01:00
|
|
|
return undefined;
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-03-23 09:12:04 +01:00
|
|
|
return g_Map.tileClasses[id];
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function createArea(placer, painter, constraint)
|
|
|
|
{
|
|
|
|
return g_Map.createArea(placer, painter, constraint);
|
|
|
|
}
|
|
|
|
|
|
|
|
function createObjectGroup(placer, player, constraint)
|
|
|
|
{
|
|
|
|
return g_Map.createObjectGroup(placer, player, constraint);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getMapSize()
|
|
|
|
{
|
|
|
|
return g_Map.size;
|
|
|
|
}
|
|
|
|
|
2011-03-28 00:00:49 +02:00
|
|
|
function getMapArea()
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
|
|
|
return g_Map.size*g_Map.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getNumPlayers()
|
|
|
|
{
|
|
|
|
return g_MapSettings.PlayerData.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCivCode(player)
|
|
|
|
{
|
|
|
|
return g_MapSettings.PlayerData[player].Civ;
|
|
|
|
}
|
|
|
|
|
2012-03-02 14:17:35 +01:00
|
|
|
function areAllies(player1, player2)
|
|
|
|
{
|
|
|
|
if ((g_MapSettings.PlayerData[player1].Team == undefined)||(g_MapSettings.PlayerData[player2].Team == undefined)||(g_MapSettings.PlayerData[player2].Team == -1)||(g_MapSettings.PlayerData[player1].Team == -1))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return (g_MapSettings.PlayerData[player1].Team === g_MapSettings.PlayerData[player2].Team);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getPlayerTeam(player)
|
|
|
|
{
|
|
|
|
return g_MapSettings.PlayerData[player].Team
|
|
|
|
}
|
|
|
|
|
|
|
|
function sortPlayers(source)
|
|
|
|
{
|
|
|
|
if (!source.length)
|
|
|
|
return [];
|
|
|
|
|
|
|
|
var result = new Array(0);
|
|
|
|
var team = new Array(5);
|
|
|
|
for (var q = 0; q < 5; q++)
|
|
|
|
{
|
|
|
|
team[q] = new Array(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = -1; i < 4; i++)
|
|
|
|
{
|
|
|
|
for (var j = 0; j < source.length; j++)
|
|
|
|
{
|
|
|
|
if (getPlayerTeam(j) == i)
|
|
|
|
{
|
|
|
|
team[i+1].unshift(j+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
team[i+1].pop();
|
|
|
|
result=result.concat(shuffleArray(team[i+1]))
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
function primeSortPlayers(source)
|
|
|
|
{
|
|
|
|
if (!source.length)
|
|
|
|
return [];
|
|
|
|
|
|
|
|
var prime = new Array(source.length);
|
|
|
|
|
|
|
|
for (var i = 0; i < round(source.length/2); i++)
|
|
|
|
{
|
|
|
|
prime[2*i]=source[i];
|
|
|
|
prime[2*i+1]=source[7-i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return prime;
|
|
|
|
}
|
|
|
|
|
2011-05-04 23:24:25 +02:00
|
|
|
function getStartingEntities(player)
|
|
|
|
{
|
2011-07-24 22:04:04 +02:00
|
|
|
var civ = getCivCode(player);
|
|
|
|
if (!g_CivData[civ] || (g_CivData[civ].SelectableInGameSetup !== undefined && !g_CivData[civ].SelectableInGameSetup) || !g_CivData[civ].StartEntities || !g_CivData[civ].StartEntities.length)
|
|
|
|
{
|
|
|
|
warn("Invalid or unimplemented civ '"+civ+"' specified, falling back to 'hele'");
|
|
|
|
civ = "hele";
|
|
|
|
}
|
2011-05-04 23:24:25 +02:00
|
|
|
|
2011-07-24 22:04:04 +02:00
|
|
|
return g_CivData[civ].StartEntities;
|
2011-05-04 23:24:25 +02:00
|
|
|
}
|
|
|
|
|
2011-04-16 06:04:06 +02:00
|
|
|
function getHeight(x, z)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
2011-04-16 06:04:06 +02:00
|
|
|
return g_Map.getHeight(x, z);
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
2011-04-16 06:04:06 +02:00
|
|
|
function setHeight(x, z, height)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
2011-04-16 06:04:06 +02:00
|
|
|
g_Map.setHeight(x, z, height);
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Utility functions for classes
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
// Add point to given class by id
|
2011-04-16 06:04:06 +02:00
|
|
|
function addToClass(x, z, id)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
|
|
|
var tileClass = getTileClass(id);
|
|
|
|
|
|
|
|
if (tileClass !== null)
|
2011-03-23 09:12:04 +01:00
|
|
|
{
|
2011-04-16 06:04:06 +02:00
|
|
|
tileClass.add(x, z);
|
2011-03-23 09:12:04 +01:00
|
|
|
}
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create a painter for the given class
|
|
|
|
function paintClass(id)
|
|
|
|
{
|
|
|
|
return new TileClassPainter(getTileClass(id));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create an avoid constraint for the given classes by the given distances
|
|
|
|
function avoidClasses(/*class1, dist1, class2, dist2, etc*/)
|
|
|
|
{
|
|
|
|
var ar = new Array(arguments.length/2);
|
2011-05-02 00:29:58 +02:00
|
|
|
for (var i = 0; i < arguments.length/2; i++)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
|
|
|
ar[i] = new AvoidTileClassConstraint(arguments[2*i], arguments[2*i+1]);
|
|
|
|
}
|
2011-05-02 00:29:58 +02:00
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
// Return single constraint
|
2011-05-02 00:29:58 +02:00
|
|
|
if (ar.length == 1)
|
|
|
|
{
|
|
|
|
return ar[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return new AndConstraint(ar);
|
|
|
|
}
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create a stay constraint for the given classes by the given distances
|
|
|
|
function stayClasses(/*class1, dist1, class2, dist2, etc*/)
|
|
|
|
{
|
|
|
|
var ar = new Array(arguments.length/2);
|
2011-05-02 00:29:58 +02:00
|
|
|
for (var i = 0; i < arguments.length/2; i++)
|
2011-03-22 02:34:45 +01:00
|
|
|
{
|
|
|
|
ar[i] = new StayInTileClassConstraint(arguments[2*i], arguments[2*i+1]);
|
|
|
|
}
|
2011-05-02 00:29:58 +02:00
|
|
|
|
2011-03-22 02:34:45 +01:00
|
|
|
// Return single constraint
|
2011-05-02 00:29:58 +02:00
|
|
|
if (ar.length == 1)
|
|
|
|
{
|
|
|
|
return ar[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return new AndConstraint(ar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a border constraint for the given classes by the given distances
|
|
|
|
function borderClasses(/*class1, idist1, odist1, class2, idist2, odist2, etc*/)
|
|
|
|
{
|
|
|
|
var ar = new Array(arguments.length/3);
|
|
|
|
for (var i = 0; i < arguments.length/3; i++)
|
|
|
|
{
|
|
|
|
ar[i] = new BorderTileClassConstraint(arguments[3*i], arguments[3*i+1], arguments[3*i+2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return single constraint
|
|
|
|
if (ar.length == 1)
|
|
|
|
{
|
|
|
|
return ar[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return new AndConstraint(ar);
|
|
|
|
}
|
2011-03-22 02:34:45 +01:00
|
|
|
}
|
2012-03-02 14:17:35 +01:00
|
|
|
|
|
|
|
// Checks if the given tile is in class "id"
|
|
|
|
function checkIfInClass(x, z, id)
|
|
|
|
{
|
|
|
|
var tileClass = getTileClass(id);
|
|
|
|
if (tileClass !== null)
|
|
|
|
{
|
|
|
|
if (tileClass.countMembersInRadius(x, z, 1) !== null)
|
|
|
|
{
|
|
|
|
return tileClass.countMembersInRadius(x, z, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Function to get the distance between 2 points
|
|
|
|
function getDistance(x1, z1, x2, z2)
|
|
|
|
{
|
|
|
|
return Math.pow(Math.pow(x1 - x2, 2) + Math.pow(z1 - z2, 2), 1/2)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the abgle between two points in radians. --Warning:This can cause sync problems in cross-platform multiplayer games--
|
|
|
|
function getAngle(x1, z1, x2, z2)
|
|
|
|
{
|
|
|
|
var vector = [x2 - x1, z2 - z1];
|
|
|
|
var output = 0;
|
|
|
|
if (vector[0] !== 0 || vector[1] !== 0)
|
|
|
|
{
|
|
|
|
var output = Math.acos(vector[0]/getDistance(x1, z1, x2, z2));
|
|
|
|
if (vector[1] > 0) {output = PI + (PI - Math.acos(vector[0]/getDistance(x1, z1, x2, z2)))};
|
|
|
|
};
|
|
|
|
return (output + PI/2) % (2*PI);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Returns the tangent of angle between the line that is created by two points and the X+ axis.
|
|
|
|
function getDirection(x1, z1, x2, z2)
|
|
|
|
{
|
|
|
|
if (x1 == x2)
|
|
|
|
{
|
|
|
|
return 100000;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return (z1-z2)/(x1-x2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getTerrainTexture(x, y)
|
|
|
|
{
|
|
|
|
return g_Map.texture[x][z];
|
|
|
|
}
|
|
|
|
|