diff --git a/binaries/data/mods/public/civs/celt.json b/binaries/data/mods/public/civs/celt.json index c1f1c1e2f3..df0a2a4596 100644 --- a/binaries/data/mods/public/civs/celt.json +++ b/binaries/data/mods/public/civs/celt.json @@ -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" + } ] } diff --git a/binaries/data/mods/public/civs/hele.json b/binaries/data/mods/public/civs/hele.json index 27099c9945..3ddde5bf7f 100644 --- a/binaries/data/mods/public/civs/hele.json +++ b/binaries/data/mods/public/civs/hele.json @@ -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" } ] } diff --git a/binaries/data/mods/public/civs/iber.json b/binaries/data/mods/public/civs/iber.json index 0b4ee01c04..57c110ae9a 100644 --- a/binaries/data/mods/public/civs/iber.json +++ b/binaries/data/mods/public/civs/iber.json @@ -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" + } ] } diff --git a/binaries/data/mods/public/maps/random/cantabrian_highlands.js b/binaries/data/mods/public/maps/random/cantabrian_highlands.js index dbad4ba296..d0a83c6ae3 100644 --- a/binaries/data/mods/public/maps/random/cantabrian_highlands.js +++ b/binaries/data/mods/public/maps/random/cantabrian_highlands.js @@ -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 = []; diff --git a/binaries/data/mods/public/maps/random/latium.js b/binaries/data/mods/public/maps/random/latium.js index 0ae3f7c9e6..0fa74aaeaa 100644 --- a/binaries/data/mods/public/maps/random/latium.js +++ b/binaries/data/mods/public/maps/random/latium.js @@ -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 ); diff --git a/binaries/data/mods/public/maps/random/neareastern_badlands.js b/binaries/data/mods/public/maps/random/neareastern_badlands.js index b49d1ef063..942e88fc3f 100644 --- a/binaries/data/mods/public/maps/random/neareastern_badlands.js +++ b/binaries/data/mods/public/maps/random/neareastern_badlands.js @@ -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 ); diff --git a/binaries/data/mods/public/maps/random/rmgen/library.js b/binaries/data/mods/public/maps/random/rmgen/library.js index 9428dc41fe..dd01206601 100644 --- a/binaries/data/mods/public/maps/random/rmgen/library.js +++ b/binaries/data/mods/public/maps/random/rmgen/library.js @@ -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); diff --git a/binaries/data/mods/public/maps/random/rmgen/map.js b/binaries/data/mods/public/maps/random/rmgen/map.js index 10796a3cfa..e856fbfac8 100644 --- a/binaries/data/mods/public/maps/random/rmgen/map.js +++ b/binaries/data/mods/public/maps/random/rmgen/map.js @@ -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 diff --git a/binaries/data/mods/public/maps/random/rmgen/mapgen.js b/binaries/data/mods/public/maps/random/rmgen/mapgen.js index 806c58efdb..ae7acbefdc 100644 --- a/binaries/data/mods/public/maps/random/rmgen/mapgen.js +++ b/binaries/data/mods/public/maps/random/rmgen/mapgen.js @@ -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); } diff --git a/binaries/data/mods/public/maps/random/rmgen/painter.js b/binaries/data/mods/public/maps/random/rmgen/painter.js index f78ea8fe75..15bc3b852d 100644 --- a/binaries/data/mods/public/maps/random/rmgen/painter.js +++ b/binaries/data/mods/public/maps/random/rmgen/painter.js @@ -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; diff --git a/binaries/data/mods/public/maps/random/rmgen/placer.js b/binaries/data/mods/public/maps/random/rmgen/placer.js index 7b0313f275..06cab194c6 100644 --- a/binaries/data/mods/public/maps/random/rmgen/placer.js +++ b/binaries/data/mods/public/maps/random/rmgen/placer.js @@ -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++) diff --git a/binaries/data/mods/public/maps/random/rmgen/tileclass.js b/binaries/data/mods/public/maps/random/rmgen/tileclass.js index fdea0895ab..3895c82cfd 100644 --- a/binaries/data/mods/public/maps/random/rmgen/tileclass.js +++ b/binaries/data/mods/public/maps/random/rmgen/tileclass.js @@ -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); } } diff --git a/source/graphics/MapGenerator.cpp b/source/graphics/MapGenerator.cpp index 3ca405ef86..57e4e713db 100644 --- a/source/graphics/MapGenerator.cpp +++ b/source/graphics/MapGenerator.cpp @@ -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()) { } diff --git a/source/graphics/MapGenerator.h b/source/graphics/MapGenerator.h index 5f045aba29..b183f3ff48 100644 --- a/source/graphics/MapGenerator.h +++ b/source/graphics/MapGenerator.h @@ -23,11 +23,7 @@ #include "scriptinterface/ScriptInterface.h" #include -#include -#include - -typedef boost::unordered_map 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 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); diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index 24c20bc115..81ba238a89 100644 --- a/source/scriptinterface/ScriptInterface.cpp +++ b/source/scriptinterface/ScriptInterface.cpp @@ -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()); diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index 11fc6ba5f3..b4eafa57eb 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -572,7 +572,7 @@ std::vector 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 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; }