Balances random map resources.

Attempts to avoid "invalid argument" errors in typed arrays by forcing
them to integer (see #658).
Removes script preloading from map generator (VFS is thread-safe now)
Removes thread checking from ScriptInterface file loading functions.
Adjusts starting entities in civ data.

This was SVN commit r9435.
This commit is contained in:
historic_bruno
2011-05-04 21:24:25 +00:00
parent d6b073df22
commit fffcdbbf21
16 changed files with 260 additions and 242 deletions
+5 -5
View File
@@ -131,14 +131,14 @@
},
{
"Template": "units/celt_support_female_citizen",
"Count": 3
"Count": 4
},
{
"Template": "units/celt_infantry_spearman_e",
"Count": 3
"Template": "units/celt_infantry_spearman_b",
"Count": 4
},
{
"Template": "units/celt_cavalry_swordsman_e"
}
"Template": "units/celt_cavalry_swordsman_b"
}
]
}
+6 -6
View File
@@ -146,18 +146,18 @@
"StartEntities":
[
{
"Template":"structures/hele_civil_centre"
"Template": "structures/hele_civil_centre"
},
{
"Template":"units/hele_support_female_citizen",
"Count":3
"Template": "units/hele_support_female_citizen",
"Count": 4
},
{
"Template":"units/hele_infantry_spearman_e",
"Count":3
"Template": "units/hele_infantry_spearman_b",
"Count": 4
},
{
"Template":"units/hele_cavalry_swordsman_e"
"Template": "units/hele_cavalry_swordsman_b"
}
]
}
+14
View File
@@ -85,5 +85,19 @@
],
"StartEntities":
[
{
"Template": "structures/iber_civil_centre"
},
{
"Template": "units/iber_support_female_citizen",
"Count": 4
},
{
"Template": "units/iber_infantry_spearman_b",
"Count": 4
},
{
"Template": "units/iber_cavalry_spearman_b"
}
]
}
@@ -9,6 +9,7 @@ const tGrassDirt50 = "medit_rocks_grass_shrubs";
const tGrassDirt25 = "medit_rocks_grass";
const tDirt = "medit_dirt_b";
const tCity = "medit_city_tile";
const tRocks = "medit_rocks";
const tGrassPatch = "medit_grass_wild";
const tShoreBlend = "medit_grass_field_brown";
const tShore = "medit_riparian_mud";
@@ -25,8 +26,9 @@ const oChicken = "gaia/fauna_chicken";
const oDeer = "gaia/fauna_deer";
const oFish = "gaia/fauna_fish";
const oSheep = "gaia/fauna_sheep";
const oStone = "gaia/geology_stone_mediterranean";
const oMetal = "gaia/geology_metal_mediterranean_slabs";
const oStoneLarge = "gaia/geology_stonemine_medit_quarry";
const oStoneSmall = "gaia/geology_stone_mediterranean";
const oMetalLarge = "gaia/geology_metal_mediterranean_slabs";
// decorative props
const aGrass = "actor|props/flora/grass_soft_large_tall.xml";
@@ -95,10 +97,10 @@ for (var i = 0; i < numPlayers; i++)
var iz = round(fz);
// calculate size based on the radius
var size = PI * radius * radius;
var hillSize = PI * radius * radius;
// create the hill
var placer = new ClumpPlacer(size, 0.95, 0.6, 10, ix, iz);
var placer = new ClumpPlacer(hillSize, 0.95, 0.6, 10, ix, iz);
var terrainPainter = new LayeredPainter(
[tCliff, tGrass], // terrains
[cliffRadius] // widths
@@ -123,38 +125,36 @@ for (var i = 0; i < numPlayers; i++)
createArea(placer, painter, null);
// create the city patch
var cityRadius = 5;
var cityRadius = radius/3;
placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
painter = new TerrainPainter(tCity);
painter = new LayeredPainter([tRocks, tCity], [1]);
createArea(placer, painter, null);
// get civ specific starting entities
var civEntities = getStartingEntities(i);
// create the TC
var civ = getCivCode(i);
var group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("structures/"+civ+"_civil_centre", 1,1, 0,0)],
[new SimpleObject(civEntities[0].Template, 1,1, 0,0)],
true, null, ix, iz
);
createObjectGroup(group, i+1);
// create starting units
var uDist = 7;
var uDist = 8;
var uAngle = playerAngle[i] + PI + randFloat(-PI/8, PI/8);
var ux = round(fx + uDist * cos(uAngle));
var uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("units/"+civ+"_support_female_citizen", 4,4, 1,2)],
true, null, ux, uz
);
createObjectGroup(group, i+1);
uAngle += PI/4;
ux = round(fx + uDist * cos(uAngle));
uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("units/"+civ+"_infantry_javelinist_a", 4,4, 1,2)],
true, null, ux, uz
);
createObjectGroup(group, i+1);
for (var j = 1; j < civEntities.length; ++j)
{
var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1);
var ux = round(fx + uDist * cos(uAngle));
var uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject(civEntities[j].Template, count,count, 1,ceil(count/2))],
true, null, ux, uz
);
createObjectGroup(group, i+1);
uAngle += PI/4;
}
// create animals
for (var j = 0; j < 2; ++j)
@@ -191,7 +191,7 @@ for (var i = 0; i < numPlayers; i++)
var mX = round(fx + mDist * cos(mAngle));
var mZ = round(fz + mDist * sin(mAngle));
group = new SimpleGroup(
[new SimpleObject(oMetal, 1,1, 0,0)],
[new SimpleObject(oMetalLarge, 1,1, 0,0)],
true, clBaseResource, mX, mZ
);
createObjectGroup(group, 0);
@@ -201,20 +201,29 @@ for (var i = 0; i < numPlayers; i++)
mX = round(fx + mDist * cos(mAngle));
mZ = round(fz + mDist * sin(mAngle));
group = new SimpleGroup(
[new SimpleObject(oStone, 5,5, 0,3)],
[new SimpleObject(oStoneLarge, 1,1, 0,2)],
true, clBaseResource, mX, mZ
);
createObjectGroup(group, 0);
// create starting straggler trees
group = new SimpleGroup(
[new SimpleObject(oOak, 5,5, 8,12)],
true, clBaseResource, ix, iz
);
createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
var num = hillSize / 100;
for (var j = 0; j < num; j++)
{
var tAngle = randFloat(0, TWO_PI);
var tDist = randFloat(6, radius - 2);
var tX = round(fx + tDist * cos(tAngle));
var tZ = round(fz + tDist * sin(tAngle));
group = new SimpleGroup(
[new SimpleObject(oOak, 1,3, 0,2)],
false, clBaseResource, tX, tZ
);
createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
}
// create grass tufts
for (var j = 0; j < 10; j++)
var num = hillSize / 250;
for (var j = 0; j < num; j++)
{
var gAngle = randFloat(0, TWO_PI);
var gDist = radius - (5 + randInt(7));
@@ -335,21 +344,21 @@ RMS.SetProgress(53);
log("Creating stone mines...");
// create stone
group = new SimpleGroup([new SimpleObject(oStone, 3,5, 0,8)], true, clRock);
group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,8), new SimpleObject(oStoneLarge, 0,1, 0,8)], true, clRock);
createObjectGroupsByAreas(group, 0,
[avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clRock, 10),
borderClasses(clHill, 1, 4)],
8 * numPlayers, 100,
scaleByMapSize(1,4) * numPlayers, 100,
hillAreas
);
log("Creating metal mines...");
// create metal
group = new SimpleGroup([new SimpleObject(oMetal, 1,1, 0,8)], true, clMetal);
group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,8)], true, clMetal);
createObjectGroupsByAreas(group, 0,
[avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clMetal, 10, clRock, 5),
borderClasses(clHill, 1, 4)],
scaleByMapSize(8,32) * numPlayers, 100,
scaleByMapSize(1,4) * numPlayers, 100,
hillAreas
);
hillAreas = [];
+51 -52
View File
@@ -39,8 +39,9 @@ const oChicken = "gaia/fauna_chicken";
const oDeer = "gaia/fauna_deer";
const oFish = "gaia/fauna_fish";
const oSheep = "gaia/fauna_sheep";
const oStone = "gaia/geology_stone_mediterranean";
const oMetal = "gaia/geology_metal_mediterranean_slabs";
const oStoneLarge = "gaia/geology_stonemine_medit_quarry";
const oStoneSmall = "gaia/geology_stone_mediterranean";
const oMetalLarge = "gaia/geology_metal_mediterranean_slabs";
// decorative props
const aBushLargeDry = "actor|props/flora/bush_medit_la_dry.xml";
@@ -137,16 +138,16 @@ function playerNearness(x, z)
log("Painting elevation...");
var noise0 = new Noise2D(4 * mapSize/128);
var noise1 = new Noise2D(8 * mapSize/128);
var noise2 = new Noise2D(15 * mapSize/128);
var noise0 = new Noise2D(scaleByMapSize(4, 16));
var noise1 = new Noise2D(scaleByMapSize(8, 32));
var noise2 = new Noise2D(scaleByMapSize(15, 60));
var noise2a = new Noise2D(20 * mapSize/128);
var noise2b = new Noise2D(35 * mapSize/128);
var noise2a = new Noise2D(scaleByMapSize(20, 80));
var noise2b = new Noise2D(scaleByMapSize(35, 140));
var noise3 = new Noise2D(4 * mapSize/128);
var noise4 = new Noise2D(6 * mapSize/128);
var noise5 = new Noise2D(11 * mapSize/128);
var noise3 = new Noise2D(scaleByMapSize(4, 16));
var noise4 = new Noise2D(scaleByMapSize(6, 24));
var noise5 = new Noise2D(scaleByMapSize(11, 44));
for (var ix = 0; ix <= mapSize; ix++)
{
@@ -226,13 +227,13 @@ for (var ix = 0; ix <= mapSize; ix++)
log("Painting terrain...");
var noise6 = new Noise2D(10 * mapSize/128);
var noise7 = new Noise2D(20 * mapSize/128);
var noise6 = new Noise2D(scaleByMapSize(10, 40));
var noise7 = new Noise2D(scaleByMapSize(20, 80));
var noise8 = new Noise2D(13 * mapSize/128);
var noise9 = new Noise2D(26 * mapSize/128);
var noise8 = new Noise2D(scaleByMapSize(13, 52));
var noise9 = new Noise2D(scaleByMapSize(26, 104));
var noise10 = new Noise2D(50 * mapSize/128);
var noise10 = new Noise2D(scaleByMapSize(50, 200));
for (var ix = 0; ix < mapSize; ix++)
{
@@ -251,6 +252,7 @@ for (var ix = 0; ix < mapSize; ix++)
// find min and max height
var maxH = Math.max(h00, h01, h10, h11);
var minH = Math.min(h00, h01, h10, h11);
var diffH = maxH - minH;
// figure out if we're at the top of a cliff using min adjacent height
var minAdjHeight = minH;
@@ -306,12 +308,12 @@ for (var ix = 0; ix < mapSize; ix++)
}
// cliffs
if (maxH - minH > 2.9 && minH > -7)
if (diffH > 2.9 && minH > -7)
{
t = tCliff;
addToClass(ix, iz, clCliff);
}
else if ((maxH - minH > 2.5 && minH > -5) || (maxH-minAdjHeight > 2.9 && minH > 0) )
else if ((diffH > 2.5 && minH > -5) || ((maxH - minAdjHeight) > 2.9 && minH > 0) )
{
if (minH < -1)
t = tCliff;
@@ -324,11 +326,12 @@ for (var ix = 0; ix < mapSize; ix++)
}
// forests
if (maxH - minH < 1 && minH > 1)
if (diffH < 1 && minH > 1)
{
var forestNoise = (noise6.get(x,z) + 0.5*noise7.get(x,z)) / 1.5 * pn - 0.59;
if (forestNoise > 0)
// Thin out trees a bit
if (forestNoise > 0 && randFloat() < 0.5)
{
if (minH > 5)
{
@@ -357,23 +360,23 @@ for (var ix = 0; ix < mapSize; ix++)
var grassNoise = (noise8.get(x,z) + 0.6*noise9.get(x,z)) / 1.6;
if (grassNoise < 0.3)
{
t = (maxH - minH > 1.2) ? tDirtCliff : tDirt;
t = (diffH > 1.2) ? tDirtCliff : tDirt;
}
else if (grassNoise < 0.34)
{
t = (maxH - minH > 1.2) ? tGrassCliff : tGrassDry;
if (maxH - minH < 0.5 && randFloat() < 0.02)
t = (diffH > 1.2) ? tGrassCliff : tGrassDry;
if (diffH < 0.5 && randFloat() < 0.02)
{
placeObject(ix+randFloat(), iz+randFloat(), aGrassDry, 0, randFloat(0, TWO_PI));
}
}
else if (grassNoise > 0.61)
{
t = ((maxH - minH) > 1.2 ? tGrassRock : tGrassShrubs);
t = (diffH > 1.2 ? tGrassRock : tGrassShrubs);
}
else
{
if ((maxH - minH) < 0.5 && randFloat() < 0.02)
if (diffH < 0.5 && randFloat() < 0.02)
{
placeObject(ix+randFloat(), iz+randFloat(), aGrass, 0, randFloat(0, TWO_PI));
}
@@ -401,35 +404,31 @@ for (var i = 1; i <= numPlayers; i++)
var painter = new LayeredPainter([tGrass, tCity], [1]);
createArea(placer, painter, null);
// create TC and starting units
// TODO: Get civ specific starting units
// get civ specific starting entities
var civEntities = getStartingEntities(i-1);
// create the TC
var civ = getCivCode(i-1);
var group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("structures/"+civ+"_civil_centre", 1,1, 0,0)],
[new SimpleObject(civEntities[0].Template, 1,1, 0,0)],
true, null, ix, iz
);
createObjectGroup(group, i);
// create starting units
var uDist = 7;
var uDist = 8;
var uAngle = randFloat(0, TWO_PI);
var ux = round(fx + uDist * cos(uAngle));
var uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("units/"+civ+"_support_female_citizen", 4,4, 1,2)],
true, null, ux, uz
);
createObjectGroup(group, i);
uAngle += PI/4;
ux = round(fx + uDist * cos(uAngle));
uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("units/"+civ+"_infantry_javelinist_a", 4,4, 1,2)],
true, null, ux, uz
);
createObjectGroup(group, i);
for (var j = 1; j < civEntities.length; ++j)
{
var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1);
var ux = round(fx + uDist * cos(uAngle));
var uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject(civEntities[j].Template, count,count, 1,ceil(count/2))],
true, null, ux, uz
);
createObjectGroup(group, i);
uAngle += PI/4;
}
// create animals
for (var j = 0; j < 2; ++j)
@@ -466,7 +465,7 @@ for (var i = 1; i <= numPlayers; i++)
var mX = round(fx + mDist * cos(mAngle));
var mZ = round(fz + mDist * sin(mAngle));
group = new SimpleGroup(
[new SimpleObject(oMetal, 1,1, 0,0)],
[new SimpleObject(oMetalLarge, 1,1, 0,0)],
true, clBaseResource, mX, mZ
);
createObjectGroup(group, 0);
@@ -476,7 +475,7 @@ for (var i = 1; i <= numPlayers; i++)
mX = round(fx + mDist * cos(mAngle));
mZ = round(fz + mDist * sin(mAngle));
group = new SimpleGroup(
[new SimpleObject(oStone, 5,5, 0,3)],
[new SimpleObject(oStoneLarge, 1,1, 0,2)],
true, clBaseResource, mX, mZ
);
createObjectGroup(group, 0);
@@ -536,20 +535,20 @@ createObjectGroups(group, 0,
log("Creating stone mines...");
// create stone
group = new SimpleGroup([new SimpleObject(oStone, 3,5, 0,2)], true, clStone);
group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,8), new SimpleObject(oStoneLarge, 0,1, 0,8)], true, clStone);
createObjectGroups(group, 0,
[avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clStone, 15),
borderClasses(clCliff, 0, 5)],
8 * numPlayers, 100
scaleByMapSize(1,4) * numPlayers, 100
);
log("Creating metal mines...");
// create metal
group = new SimpleGroup([new SimpleObject(oMetal, 1,1, 0,2)], true, clMetal);
group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,2)], true, clMetal);
createObjectGroups(group, 0,
[avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clMetal, 15, clStone, 5),
borderClasses(clCliff, 0, 5)],
scaleByMapSize(8,32) * numPlayers, 100
scaleByMapSize(1,4) * numPlayers, 100
);
log("Creating sheep...");
@@ -564,7 +563,7 @@ log("Creating fish...");
// create fish
group = new SimpleGroup([new SimpleObject(oFish, 1,1, 0,1)], true, clFood);
createObjectGroups(group, 0,
[borderClasses(clWater, 0, 7), avoidClasses(clFood, 8, clCliff, 0)],
[borderClasses(clWater, 7, 0), avoidClasses(clFood, 8, clCliff, 0)],
3 * numPlayers, 50
);
@@ -25,8 +25,9 @@ const oGazelle = "gaia/fauna_gazelle";
const oGiraffe = "gaia/fauna_giraffe";
const oGoat = "gaia/fauna_goat";
const oWildebeest = "gaia/fauna_wildebeest";
const oStone = "gaia/geology_stone_desert_small";
const oMetal = "gaia/geology_metal_desert_slabs";
const oStoneLarge = "gaia/geology_stonemine_desert_badlands_quarry";
const oStoneSmall = "gaia/geology_stone_desert_small";
const oMetalLarge = "gaia/geology_metal_desert_slabs";
const oDatePalm = "gaia/flora_tree_date_palm";
const oSDatePalm = "gaia/flora_tree_senegal_date_palm";
@@ -106,33 +107,31 @@ for (var i = 0; i < numPlayers; i++)
var painter = new LayeredPainter([tCity, tCityPlaza], [3]);
createArea(placer, painter, null);
// create the TC and citizens
var civ = getCivCode(i);
var group = new SimpleGroup( // elements (type, count, distance)
[new SimpleObject("structures/"+civ+"_civil_centre", 1,1, 0,0)],
true, null, ix, iz
// get civ specific starting entities
var civEntities = getStartingEntities(i);
// create the TC
var group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject(civEntities[0].Template, 1,1, 0,0)],
true, null, ix, iz
);
createObjectGroup(group, i+1);
// create starting units
var uDist = 7;
var uDist = 8;
var uAngle = playerAngle[i] + PI + randFloat(-PI/8, PI/8);
var ux = round(fx + uDist * cos(uAngle));
var uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("units/"+civ+"_support_female_citizen", 4,4, 1,2)],
true, null, ux, uz
);
createObjectGroup(group, i+1);
uAngle += PI/4;
ux = round(fx + uDist * cos(uAngle));
uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject("units/"+civ+"_infantry_javelinist_a", 4,4, 1,2)],
true, null, ux, uz
);
createObjectGroup(group, i+1);
for (var j = 1; j < civEntities.length; ++j)
{
var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1);
var ux = round(fx + uDist * cos(uAngle));
var uz = round(fz + uDist * sin(uAngle));
group = new SimpleGroup( // elements (type, min/max count, min/max distance)
[new SimpleObject(civEntities[j].Template, count,count, 1,ceil(count/2))],
true, null, ux, uz
);
createObjectGroup(group, i+1);
uAngle += PI/4;
}
// create animals
for (var j = 0; j < 2; ++j)
@@ -169,7 +168,7 @@ for (var i = 0; i < numPlayers; i++)
var mX = round(fx + mDist * cos(mAngle));
var mZ = round(fz + mDist * sin(mAngle));
group = new SimpleGroup(
[new SimpleObject(oMetal, 1,1, 0,0), new RandomObject(aBushes, 2,4, 0,2)],
[new SimpleObject(oMetalLarge, 1,1, 0,0), new RandomObject(aBushes, 2,4, 0,2)],
true, clBaseResource, mX, mZ
);
createObjectGroup(group, 0);
@@ -179,7 +178,7 @@ for (var i = 0; i < numPlayers; i++)
mX = round(fx + mDist * cos(mAngle));
mZ = round(fz + mDist * sin(mAngle));
group = new SimpleGroup(
[new SimpleObject(oStone, 5,5, 0,3), new RandomObject(aBushes, 2,4, 0,2)],
[new SimpleObject(oStoneLarge, 1,1, 0,2), new RandomObject(aBushes, 2,4, 0,2)],
true, clBaseResource, mX, mZ
);
createObjectGroup(group, 0);
@@ -228,7 +227,7 @@ log("Creating oasis...");
var oRadius = scaleByMapSize(14, 40);
placer = new ClumpPlacer(PI*oRadius*oRadius, 0.6, 0.15, 0, mapSize/2, mapSize/2);
painter = new LayeredPainter([[tSand, pForest], [tGrassSand25, pForestOasis], tGrassSand25, tShore, tWaterDeep], [2, 3, 1, 1]);
elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -12, 7);
elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -11, 8);
createArea(placer, [painter, elevationPainter, paintClass(clForest)], null);
// create oasis wildlife
@@ -240,7 +239,7 @@ for (var i = 0; i < num; ++i)
var r = 0;
var angle = TWO_PI / num * i;
do {
// Work outward until we find
// Work outward until constraint met
var gx = round(halfSize + r * cos(angle));
var gz = round(halfSize + r * sin(angle));
++r;
@@ -262,7 +261,7 @@ for (var i = 0; i < num; ++i)
var r = 0;
var angle = TWO_PI / num * i;
do {
// Work outward until we find
// Work outward until constraint met
var gx = round(halfSize + r * cos(angle));
var gz = round(halfSize + r * sin(angle));
++r;
@@ -310,22 +309,18 @@ RMS.SetProgress(70);
log("Creating stone mines...");
// create stone
group = new SimpleGroup([new SimpleObject(oStone, 3,5, 0,8), new RandomObject(aBushes, 2,4, 0,2)], true, clRock);
createObjectGroupsByAreas(group, 0,
[avoidClasses(clForest, 2, clPlayer, 0, clRock, 10),
borderClasses(clHill1, 0, 4)],
8 * numPlayers, 100,
hillAreas
group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,8), new SimpleObject(oStoneLarge, 0,1, 0,8), new RandomObject(aBushes, 2,4, 0,2)], true, clRock);
createObjectGroups(group, 0,
[avoidClasses(clForest, 2, clPlayer, 10, clRock, 10, clHill1, 0)],
scaleByMapSize(1,4) * numPlayers, 100
);
log("Creating metal mines...");
// create metal
group = new SimpleGroup([new SimpleObject(oMetal, 1,1, 0,8), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal);
createObjectGroupsByAreas(group, 0,
[avoidClasses(clForest, 2, clPlayer, 0, clMetal, 10, clRock, 5),
borderClasses(clHill1, 0, 4)],
scaleByMapSize(8,32) * numPlayers, 100,
hillAreas
group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,8), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal);
createObjectGroups(group, 0,
[avoidClasses(clForest, 2, clPlayer, 10, clMetal, 10, clRock, 5, clHill1, 0)],
scaleByMapSize(1,4) * numPlayers, 100
);
// create decorative rocks for hills
@@ -336,7 +331,7 @@ group = new SimpleGroup(
);
createObjectGroupsByAreas(group, 0,
borderClasses(clHill1, 0, 3),
scaleByMapSize(40,100), 100,
scaleByMapSize(40,200), 50,
hillAreas
);
@@ -387,6 +387,63 @@ function getCivCode(player)
return g_MapSettings.PlayerData[player].Civ;
}
function getStartingEntities(player)
{
// This is a temporary hack until map generator has a LoadCivData method
var civStartingEntities = {
"celt" : [
{
"Template": "structures/celt_civil_centre"
},
{
"Template": "units/celt_support_female_citizen",
"Count": 4
},
{
"Template": "units/celt_infantry_spearman_b",
"Count": 4
},
{
"Template": "units/celt_cavalry_swordsman_b"
}
],
"hele" : [
{
"Template": "structures/hele_civil_centre"
},
{
"Template": "units/hele_support_female_citizen",
"Count": 4
},
{
"Template": "units/hele_infantry_spearman_b",
"Count": 4
},
{
"Template": "units/hele_cavalry_swordsman_b"
}
],
"iber" : [
{
"Template": "structures/iber_civil_centre"
},
{
"Template": "units/iber_support_female_citizen",
"Count": 4
},
{
"Template": "units/iber_infantry_spearman_b",
"Count": 4
},
{
"Template": "units/iber_cavalry_spearman_b"
}
]
};
return civStartingEntities[getCivCode(player)];
}
function getHeight(x, z)
{
return g_Map.getHeight(x, z);
@@ -20,9 +20,9 @@ function Map(size, baseHeight)
for (var i = 0; i < size; i++)
{
this.texture[i] = new Uint16Array(size); // uint16 - texture IDs
this.terrainObjects[i] = new Array(size); // array of entities
this.area[i] = new Uint16Array(size); // uint16 - area IDs
this.texture[i] = new Uint16Array(Math.floor(size)); // uint16 - texture IDs // HACK: typed arrays require integer arguments
this.terrainObjects[i] = new Array(size); // array of entities
this.area[i] = new Uint16Array(Math.floor(size)); // uint16 - area IDs // HACK: typed arrays require integer arguments
for (var j = 0; j < size; j++)
{
@@ -35,7 +35,7 @@ function Map(size, baseHeight)
this.height = new Array(mapSize);
for (var i = 0; i < mapSize; i++)
{
this.height[i] = new Float32Array(mapSize); // float32
this.height[i] = new Float32Array(Math.floor(mapSize)); // float32 // HACK: typed arrays require integer arguments
for (var j = 0; j < mapSize; j++)
{ // Initialize height map to baseHeight
@@ -42,10 +42,6 @@ function InitMap()
log("Creating new map...");
var terrain = createTerrain(g_MapSettings.BaseTerrain);
// XXX: Temporary hack to keep typed arrays from complaining about invalid arguments,
// until SpiderMonkey gets upgraded
g_MapSettings.Size = Math.floor(g_MapSettings.Size);
g_Map = new Map(g_MapSettings.Size, g_MapSettings.BaseHeight);
g_Map.initTerrain(terrain);
}
@@ -69,8 +69,8 @@ LayeredPainter.prototype.paint = function(area)
// init typed arrays
for (var i = 0; i < size; ++i)
{
saw[i] = new Uint8Array(size); // bool / uint8
dist[i] = new Uint16Array(size); // uint16
saw[i] = new Uint8Array(Math.floor(size)); // bool / uint8 // HACK: typed arrays require integer arguments
dist[i] = new Uint16Array(Math.floor(size)); // uint16 // HACK: typed arrays require integer arguments
}
// Point queue (implemented with array)
@@ -221,10 +221,10 @@ SmoothElevationPainter.prototype.paint = function(area)
// init typed arrays
for (var i = 0; i < mapSize; ++i)
{
saw[i] = new Uint8Array(mapSize); // bool / uint8
dist[i] = new Uint16Array(mapSize); // uint16
gotHeightPt[i] = new Uint8Array(mapSize); // bool / uint8
newHeight[i] = new Float32Array(mapSize); // float32
saw[i] = new Uint8Array(Math.floor(mapSize)); // bool / uint8 // HACK: typed arrays require integer arguments
dist[i] = new Uint16Array(Math.floor(mapSize)); // uint16 // HACK: typed arrays require integer arguments
gotHeightPt[i] = new Uint8Array(Math.floor(mapSize)); // bool / uint8 // HACK: typed arrays require integer arguments
newHeight[i] = new Float32Array(Math.floor(mapSize)); // float32 // HACK: typed arrays require integer arguments
}
var length = pts.length;
@@ -35,7 +35,7 @@ ClumpPlacer.prototype.place = function(constraint)
var gotRet = new Array(size);
for (var i = 0; i < size; ++i)
{
gotRet[i] = new Uint8Array(size); // bool / uint8
gotRet[i] = new Uint8Array(Math.floor(size)); // bool / uint8 // HACK: typed arrays require integer arguments
}
var radius = sqrt(this.size / PI);
@@ -49,9 +49,9 @@ ClumpPlacer.prototype.place = function(constraint)
ctrlPts = Math.floor(radius * 2 * PI) + 1;
}
var noise = new Float32Array(intPerim); //float32
var ctrlCoords = new Float32Array(ctrlPts+1); //float32
var ctrlVals = new Float32Array(ctrlPts+1); //float32
var noise = new Float32Array(Math.floor(intPerim)); //float32 // HACK: typed arrays require integer arguments
var ctrlCoords = new Float32Array(Math.floor(ctrlPts+1)); //float32 // HACK: typed arrays require integer arguments
var ctrlVals = new Float32Array(Math.floor(ctrlPts+1)); //float32 // HACK: typed arrays require integer arguments
// Generate some interpolated noise
for (var i=0; i < ctrlPts; i++)
@@ -13,7 +13,7 @@ function RangeOp(size)
this.nn *= 2;
}
this.vals = new Int16Array(2*this.nn); // int16
this.vals = new Int16Array(Math.floor(2*this.nn)); // int16 // HACK: typed arrays require integer arguments
}
RangeOp.prototype.set = function(pos, amt)
@@ -78,7 +78,7 @@ function TileClass(size, id)
for (var i=0; i < size; ++i)
{
this.inclusionCount[i] = new Int16Array(size); //int16
this.inclusionCount[i] = new Int16Array(Math.floor(size)); //int16 // HACK: typed arrays require integer arguments
this.rangeCount[i] = new RangeOp(size);
}
}
+24 -59
View File
@@ -19,11 +19,10 @@
#include "MapGenerator.h"
#include "lib/file/vfs/vfs_path.h"
#include "lib/timer.h"
#include "lib/utf8.h"
#include "ps/CLogger.h"
// TODO: what's a good default? perhaps based on map size
#define RMS_RUNTIME_SIZE 96 * 1024 * 1024
@@ -49,9 +48,6 @@ void CMapGeneratorWorker::Initialize(const VfsPath& scriptFile, const std::strin
m_ScriptPath = scriptFile;
m_Settings = settings;
// Preload random map and library scripts
fs_util::ForEachFile(g_VFS, L"maps/random/", PreloadScript, (uintptr_t)this, L"*.js", fs_util::DIR_RECURSIVE);
// Launch the worker thread
int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this);
ENSURE(ret == 0);
@@ -121,20 +117,15 @@ bool CMapGeneratorWorker::Run()
return false;
}
// Find RMS file and run
ScriptFilesMap::iterator it = m_ScriptFiles.find(m_ScriptPath);
if (it != m_ScriptFiles.end())
// Load RMS
LOGMESSAGE(L"Loading RMS '%ls'", m_ScriptPath.string().c_str());
if (!m_ScriptInterface->LoadGlobalScriptFile(m_ScriptPath))
{
LOGMESSAGE(L"CMapGeneratorWorker::Run: Loading RMS '%ls'", m_ScriptPath.string().c_str());
// Note: we're not really accessing the file here
if (m_ScriptInterface->LoadGlobalScript(m_ScriptPath, it->second))
{
return true;
}
LOGERROR(L"CMapGeneratorWorker::Run: Failed to load RMS '%ls'", m_ScriptPath.string().c_str());
return false;
}
LOGERROR(L"CMapGeneratorWorker::Run: Failed to load RMS '%ls'", m_ScriptPath.string().c_str());
return false;
return true;
}
int CMapGeneratorWorker::GetProgress()
@@ -192,64 +183,38 @@ bool CMapGeneratorWorker::LoadScripts(const std::wstring& libraryName)
// Mark this as loaded, to prevent it recursively loading itself
m_LoadedLibraries.insert(libraryName);
LOGMESSAGE(L"Loading '%ls' library", libraryName.c_str());
VfsPath path = L"maps/random/" + libraryName + L"/";
VfsPaths pathnames;
std::wstring libraryPath = L"maps/random/" + libraryName + L"/";
// Iterate preloaded script map, running library scripts
for (ScriptFilesMap::iterator it = m_ScriptFiles.begin(); it != m_ScriptFiles.end(); ++it)
// Load all scripts in mapgen directory
Status ret = fs_util::GetPathnames(g_VFS, path, L"*.js", pathnames);
if (ret == INFO::OK)
{
std::wstring path = it->first.string();
if (path.find(libraryPath) == 0)
for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it)
{
// This script is part of the library, so load it
// Note: we're not really accessing the file here
if (m_ScriptInterface->LoadGlobalScript(path, it->second))
LOGMESSAGE(L"Loading map generator script '%ls'", it->string().c_str());
if (!m_ScriptInterface->LoadGlobalScriptFile(*it))
{
LOGMESSAGE(L"Successfully loaded library script '%ls'", path.c_str());
}
else
{
// Script failed to run
LOGERROR(L"Failed loading library script '%ls'", path.c_str());
LOGERROR(L"CMapGeneratorWorker::LoadScripts: Failed to load script '%ls'", it->string().c_str());
return false;
}
}
}
else
{
// Some error reading directory
wchar_t error[200];
LOGERROR(L"CMapGeneratorWorker::LoadScripts: Error reading scripts in directory '%ls': %ls", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error)));
return false;
}
return true;
}
Status CMapGeneratorWorker::PreloadScript(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{
CMapGeneratorWorker* self = (CMapGeneratorWorker*)cbData;
if (!VfsFileExists(g_VFS, pathname))
{
// This should never happen
LOGERROR(L"CMapGeneratorWorker::PreloadScript: File '%ls' does not exist", pathname.string().c_str());
return ERR::VFS_FILE_NOT_FOUND;
}
CVFSFile file;
PSRETURN ret = file.Load(g_VFS, pathname);
if (ret != PSRETURN_OK)
{
LOGERROR(L"CMapGeneratorWorker::PreloadScript: Failed to load file '%ls', error=%hs", pathname.string().c_str(), GetErrorString(ret));
return ERR::FAIL;
}
std::string content(file.GetBuffer(), file.GetBuffer() + file.GetBufferSize());
self->m_ScriptFiles.insert(std::make_pair(pathname, wstring_from_utf8(content)));
return INFO::OK;
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
CMapGenerator::CMapGenerator() : m_Worker(new CMapGeneratorWorker())
{
}
+2 -14
View File
@@ -23,11 +23,7 @@
#include "scriptinterface/ScriptInterface.h"
#include <boost/random/linear_congruential.hpp>
#include <boost/unordered_map.hpp>
#include <set>
typedef boost::unordered_map<VfsPath, std::wstring> ScriptFilesMap;
class CMapGeneratorWorker;
@@ -80,8 +76,6 @@ private:
* - Initialize and constructor/destructor must be called from the main thread.
* - ScriptInterface created and destroyed by thread
* - StructuredClone used to return JS map data - jsvals can't be used across threads/runtimes
* - VFS is not threadsafe, so preload all random map scripts in the main thread for later use
* by the worker
*/
class CMapGeneratorWorker
{
@@ -100,7 +94,7 @@ public:
/**
* Get status of the map generator thread
*
* @return Progress percentage 1-100 if active, 0 when finished, or -1 when
* @return Progress percentage 1-100 if active, 0 when finished, or -1 on error
*/
int GetProgress();
@@ -133,15 +127,9 @@ private:
shared_ptr<ScriptInterface::StructuredClone> m_MapData;
boost::rand48 m_MapGenRNG;
int m_Progress;
VfsPath m_ScriptPath;
ScriptInterface* m_ScriptInterface;
VfsPath m_ScriptPath;
std::string m_Settings;
// Since VFS is not threadsafe, use this map to store preloaded scripts
ScriptFilesMap m_ScriptFiles;
// callback for VFS preloading
static Status PreloadScript(const VfsPath& pathname, const FileInfo& fileInfo, const uintptr_t cbData);
// Thread
static void* RunThread(void* data);
@@ -808,8 +808,6 @@ bool ScriptInterface::LoadGlobalScript(const VfsPath& filename, const std::wstri
bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path)
{
ENSURE(ThreadUtil::IsMainThread()); // VFS isn't thread-safe
if (!VfsFileExists(g_VFS, path))
{
LOGERROR(L"File '%ls' does not exist", path.string().c_str());
@@ -896,8 +894,6 @@ CScriptValRooted ScriptInterface::ParseJSON(const std::string& string_utf8)
CScriptValRooted ScriptInterface::ReadJSONFile(const VfsPath& path)
{
ENSURE(ThreadUtil::IsMainThread()); // VFS isn't thread-safe
if (!VfsFileExists(g_VFS, path))
{
LOGERROR(L"File '%ls' does not exist", path.string().c_str());
+2 -3
View File
@@ -572,7 +572,7 @@ std::vector<std::string> CSimulation2::GetCivData()
PSRETURN ret = file.Load(g_VFS, *it);
if (ret != PSRETURN_OK)
{
LOGERROR(L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret));
LOGERROR(L"CSimulation2::GetCivData: Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret));
}
else
{
@@ -584,10 +584,9 @@ std::vector<std::string> CSimulation2::GetCivData()
{
// Some error reading directory
wchar_t error[200];
LOGERROR(L"Error reading directory '%ls': %hs", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error)));
LOGERROR(L"CSimulation2::GetCivData: Error reading directory '%ls': %ls", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error)));
}
// Convert from vector to array and stringify
return data;
}