diff --git a/binaries/data/mods/public/maps/random/cantabrian_highlands.js b/binaries/data/mods/public/maps/random/cantabrian_highlands.js index 54cd6f5300..dbad4ba296 100644 --- a/binaries/data/mods/public/maps/random/cantabrian_highlands.js +++ b/binaries/data/mods/public/maps/random/cantabrian_highlands.js @@ -4,10 +4,11 @@ RMS.LoadLibrary("rmgen"); const tGrass = ["medit_grass_field_a", "medit_grass_field_b"]; const tGrassForest = "medit_grass_wild"; const tCliff = ["medit_cliff_italia", "medit_cliff_italia_grass"]; -const tGrassDirt75 = "medit_dirt"; -const tGrassDirt50 = "medit_dirt_b"; -const tGrassDirt25 = "medit_dirt_c"; +const tGrassDirt75 = "medit_rocks_shrubs"; +const tGrassDirt50 = "medit_rocks_grass_shrubs"; +const tGrassDirt25 = "medit_rocks_grass"; const tDirt = "medit_dirt_b"; +const tCity = "medit_city_tile"; const tGrassPatch = "medit_grass_wild"; const tShoreBlend = "medit_grass_field_brown"; const tShore = "medit_riparian_mud"; @@ -20,8 +21,10 @@ const oApple = "gaia/flora_tree_apple"; const oPine = "gaia/flora_tree_pine"; const oAleppoPine = "gaia/flora_tree_aleppo_pine"; const oBerryBush = "gaia/flora_bush_berry"; -const oSheep = "gaia/fauna_sheep"; +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"; @@ -36,8 +39,8 @@ const aBushMedium = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; // terrain + entity (for painting) -const pForestD = [tGrassForest + TERRAIN_SEPARATOR + oOak, tGrassForest + TERRAIN_SEPARATOR + oOakLarge]; -const pForestP = [tGrassForest + TERRAIN_SEPARATOR + oPine, tGrassForest + TERRAIN_SEPARATOR + oAleppoPine]; +const pForestD = [tGrassForest + TERRAIN_SEPARATOR + oOak, tGrassForest + TERRAIN_SEPARATOR + oOakLarge, tGrassForest]; +const pForestP = [tGrassForest + TERRAIN_SEPARATOR + oPine, tGrassForest + TERRAIN_SEPARATOR + oAleppoPine, tGrassForest]; // initialize map @@ -64,28 +67,28 @@ var clSettlement = createTileClass(); // place players -var playerX = new Array(numPlayers+1); -var playerZ = new Array(numPlayers+1); -var playerAngle = new Array(numPlayers+1); +var playerX = new Array(numPlayers); +var playerZ = new Array(numPlayers); +var playerAngle = new Array(numPlayers); -var startAngle = randFloat() * 2 * PI; -for (var i = 1; i <= numPlayers; i++) +var startAngle = randFloat(0, TWO_PI); +for (var i = 0; i < numPlayers; i++) { - playerAngle[i] = startAngle + i*2*PI/numPlayers; + playerAngle[i] = startAngle + i*TWO_PI/numPlayers; playerX[i] = 0.5 + 0.35*cos(playerAngle[i]); playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]); } -for (var i = 1; i <= numPlayers; i++) +for (var i = 0; i < numPlayers; i++) { - log("Creating base for player " + i + "..."); + log("Creating base for player " + (i + 1) + "..."); // some constants - var radius = 17; + var radius = scaleByMapSize(15,25); var cliffRadius = 2; var elevation = 20; - // get the x and y in tiles + // get the x and z in tiles var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); @@ -95,7 +98,7 @@ for (var i = 1; i <= numPlayers; i++) var size = PI * radius * radius; // create the hill - var placer = new ClumpPlacer(size, 0.95, 0.6, 0, ix, iz); + var placer = new ClumpPlacer(size, 0.95, 0.6, 10, ix, iz); var terrainPainter = new LayeredPainter( [tCliff, tGrass], // terrains [cliffRadius] // widths @@ -108,40 +111,72 @@ for (var i = 1; i <= numPlayers; i++) createArea(placer, [terrainPainter, elevationPainter, paintClass(clPlayer)], null); // create the ramp - var rampAngle = playerAngle[i] + PI + (2*randFloat()-1)*PI/8; + var rampAngle = playerAngle[i] + PI + randFloat(-PI/8, PI/8); var rampDist = radius; var rampX = round(fx + rampDist * cos(rampAngle)); var rampZ = round(fz + rampDist * sin(rampAngle)); - placer = new ClumpPlacer(100, 0.9, 0.5, 0, rampX, rampZ); + placer = new ClumpPlacer(100, 0.9, 0.5, 1, rampX, rampZ); var painter = new SmoothElevationPainter(ELEVATION_SET, elevation-6, 5); createArea(placer, painter, null); - placer = new ClumpPlacer(75, 0.9, 0.5, 0, rampX, rampZ); + placer = new ClumpPlacer(75, 0.9, 0.5, 1, rampX, rampZ); painter = new TerrainPainter(tGrass); createArea(placer, painter, null); - // create the central dirt patch - placer = new ClumpPlacer(PI*3.5*3.5, 0.3, 0.1, 0, ix, iz); - painter = new LayeredPainter( - [tGrassDirt75, tGrassDirt50, tGrassDirt25, tDirt], // terrains - [1,1,1] // widths - ); + // create the city patch + var cityRadius = 5; + placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); + painter = new TerrainPainter(tCity); createArea(placer, painter, null); - // create the TC and citizens - var civ = getCivCode(i - 1); + // 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("units/"+civ+"_support_female_citizen", 3,3, 5,5)], + [new SimpleObject("structures/"+civ+"_civil_centre", 1,1, 0,0)], true, null, ix, iz ); - createObjectGroup(group, i); + createObjectGroup(group, i+1); + + // create starting units + var uDist = 7; + 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); + + // create animals + for (var j = 0; j < 2; ++j) + { + var aAngle = randFloat(0, TWO_PI); + var aDist = 7; + var aX = round(fx + aDist * cos(aAngle)); + var aZ = round(fz + aDist * sin(aAngle)); + group = new SimpleGroup( + [new SimpleObject(oChicken, 5,5, 0,3)], + true, clBaseResource, aX, aZ + ); + createObjectGroup(group, 0); + } // create berry bushes - var bbAngle = randFloat()*2*PI; - var bbDist = 9; + var bbAngle = randFloat(0, TWO_PI); + var bbDist = 12; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); group = new SimpleGroup( - [new SimpleObject(oBerryBush, 5,5, 0,2)], + [new SimpleObject(oBerryBush, 5,5, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); @@ -150,9 +185,9 @@ for (var i = 1; i <= numPlayers; i++) var mAngle = bbAngle; while(abs(mAngle - bbAngle) < PI/3) { - mAngle = randFloat()*2*PI; + mAngle = randFloat(0, TWO_PI); } - var mDist = 11; + var mDist = radius - 4; var mX = round(fx + mDist * cos(mAngle)); var mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( @@ -166,7 +201,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, 2,2, 0,1)], + [new SimpleObject(oStone, 5,5, 0,3)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); @@ -181,15 +216,15 @@ for (var i = 1; i <= numPlayers; i++) // create grass tufts for (var j = 0; j < 10; j++) { - var gAngle = randFloat()*2*PI; - var gDist = 6 + randInt(9); + var gAngle = randFloat(0, TWO_PI); + var gDist = radius - (5 + randInt(7)); var gX = round(fx + gDist * cos(gAngle)); var gZ = round(fz + gDist * sin(gAngle)); group = new SimpleGroup( [new SimpleObject(aGrassShort, 2,5, 0,1, -PI/8,PI/8)], false, clBaseResource, gX, gZ ); - createObjectGroup(group, undefined); + createObjectGroup(group, 0); } } @@ -197,7 +232,8 @@ RMS.SetProgress(5); // create lakes log("Creating lakes..."); -placer = new ClumpPlacer(mapArea * 0.003, 0.8, 0.1, 0); +var numLakes = round(scaleByMapSize(1,4) * numPlayers); +placer = new ClumpPlacer(scaleByMapSize(100,250), 0.8, 0.1, 10); terrainPainter = new LayeredPainter( [tShoreBlend, tShore, tWater], // terrains [1,1] // widths @@ -207,17 +243,29 @@ var waterAreas = createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 2, clWater, 20), - round(1.3 * numPlayers) + numLakes ); // create reeds log("Creating reeds..."); group = new SimpleGroup( - [new SimpleObject(aReeds, 5,10, 0,4), new SimpleObject(aLillies, 1,1, 0,4)], true + [new SimpleObject(aReeds, 5,10, 0,4), new SimpleObject(aLillies, 0,1, 0,4)], true ); -createObjectGroupsByAreas(group, undefined, - [new BorderTileClassConstraint(clWater, 3, 0), stayClasses(clWater, 1)], - 10 * numPlayers, 100, +createObjectGroupsByAreas(group, 0, + [borderClasses(clWater, 3, 0), stayClasses(clWater, 1)], + numLakes, 100, + waterAreas +); + +// create fish +log("Creating fish..."); +group = new SimpleGroup( + [new SimpleObject(oFish, 1,1, 0,1)], + true, clFood +); +createObjectGroupsByAreas(group, 0, + borderClasses(clWater, 2, 0), avoidClasses(clFood, 8), + numLakes, 50, waterAreas ); waterAreas = []; @@ -226,20 +274,20 @@ RMS.SetProgress(22); // create bumps log("Creating bumps..."); -placer = new ClumpPlacer(mapArea * 0.000229 + 10, 0.3, 0.06, 0); +placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1); painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2); createAreas( placer, painter, avoidClasses(clWater, 2, clPlayer, 0), - 44 + scaleByMapSize(100, 200) ); RMS.SetProgress(25); // create hills log("Creating hills..."); -placer = new ClumpPlacer(mapArea * 0.000688 + 20, 0.2, 0.1, 0); +placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, [tGrass,tGrass,tGrassDirt75]], // terrains [2] // widths @@ -249,28 +297,28 @@ var hillAreas = createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 2, clWater, 5, clHill, 15), - 3 * numPlayers + scaleByMapSize(1, 4) * numPlayers ); RMS.SetProgress(30); // calculate desired number of trees for map (based on size) -const MIN_TREES = 300; -const MAX_TREES = 1500; +const MIN_TREES = 500; +const MAX_TREES = 2500; const P_FOREST = 0.7; -var totalTrees = MIN_TREES + (MAX_TREES - MIN_TREES) / 384 * (mapSize - 128); +var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); // create forests log("Creating forests..."); var types = [pForestD, pForestP]; // some variation -var size = numForest / (2 * numPlayers); +var size = numForest / (scaleByMapSize(2,8) * numPlayers); var num = floor(size / types.length); for (var i = 0; i < types.length; ++i) { - placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 0); + placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1); painter = new LayeredPainter( [[tGrassForest, tGrass, types[i]], [tGrassForest, types[i]]], // terrains [2] // widths @@ -285,23 +333,23 @@ for (var i = 0; i < types.length; ++i) RMS.SetProgress(53); -log("Placing stone mines..."); +log("Creating stone mines..."); // create stone -group = new SimpleGroup([new SimpleObject(oStone, 2,2, 0,8)], true, clRock); +group = new SimpleGroup([new SimpleObject(oStone, 3,5, 0,8)], true, clRock); createObjectGroupsByAreas(group, 0, - [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clRock, 15), - new BorderTileClassConstraint(clHill, 0, 4)], - 4 * numPlayers, 100, + [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clRock, 10), + borderClasses(clHill, 1, 4)], + 8 * numPlayers, 100, hillAreas ); -log("Placing metal mines..."); +log("Creating metal mines..."); // create metal group = new SimpleGroup([new SimpleObject(oMetal, 1,1, 0,8)], true, clMetal); createObjectGroupsByAreas(group, 0, - [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clMetal, 15, clRock, 5), - new BorderTileClassConstraint(clHill, 0, 4)], - 4 * numPlayers, 100, + [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clMetal, 10, clRock, 5), + borderClasses(clHill, 1, 4)], + scaleByMapSize(8,32) * numPlayers, 100, hillAreas ); hillAreas = []; @@ -311,7 +359,7 @@ log("Creating dirt patches..."); var sizes = [0.000183, 0.000321, 0.000458]; for (var i = 0; i < sizes.length; i++) { - placer = new ClumpPlacer(mapArea * sizes[i], 0.3, 0.06, 0); + placer = new ClumpPlacer(mapArea * sizes[i], 0.3, 0.06, 0.5); painter = new LayeredPainter( [[tGrass,tGrassDirt75],[tGrassDirt75,tGrassDirt50], [tGrassDirt50,tGrassDirt25]], // terrains [1,1] // widths @@ -320,7 +368,7 @@ for (var i = 0; i < sizes.length; i++) placer, [painter, paintClass(clDirt)], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), - 11 + scaleByMapSize(15, 45) ); } @@ -329,24 +377,16 @@ log("Creating grass patches..."); var sizes = [0.000115, 0.000206, 0.000298]; for (var i = 0; i < sizes.length; i++) { - placer = new ClumpPlacer(mapArea * sizes[i], 0.3, 0.06, 0); + placer = new ClumpPlacer(mapArea * sizes[i], 0.3, 0.06, 0.5); painter = new TerrainPainter(tGrassPatch); createAreas( placer, painter, avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), - 11 + scaleByMapSize(15, 45) ); } -// create settlements -// log("Creating settlements..."); -// group = new SimpleGroup([new SimpleObject("gaia/special_settlement", 1,1, 0,0)], true, clSettlement); -// createObjectGroups(group, 0, - // avoidClasses(clWater, 0, clForest, 0, clPlayer, 15, clHill, 0, clRock, 5, clSettlement, 35), - // 2 * numPlayers, 50 -// ); - RMS.SetProgress(60); // create small decorative rocks @@ -356,7 +396,7 @@ group = new SimpleGroup( true ); createObjectGroups( - group, undefined, + group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), mapArea/1000, 50 ); @@ -368,7 +408,7 @@ group = new SimpleGroup( true ); createObjectGroups( - group, undefined, + group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), mapArea/2000, 50 ); @@ -416,7 +456,7 @@ log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); -createObjectGroups(group, undefined, +createObjectGroups(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), mapArea * 0.000763 ); @@ -428,7 +468,7 @@ log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)] ); -createObjectGroups(group, undefined, +createObjectGroups(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), mapArea * 0.000763 ); @@ -440,7 +480,7 @@ log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); -createObjectGroups(group, undefined, +createObjectGroups(group, 0, avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), mapArea * 0.000763, 50 ); diff --git a/binaries/data/mods/public/maps/random/latium.js b/binaries/data/mods/public/maps/random/latium.js index 0ec502a2b9..0ae3f7c9e6 100644 --- a/binaries/data/mods/public/maps/random/latium.js +++ b/binaries/data/mods/public/maps/random/latium.js @@ -11,6 +11,7 @@ const tBeachWet = "medit_sand_wet"; const tBeachDry = "medit_sand"; const tBeachGrass = "medit_rocks_grass"; const tBeachCliff = "medit_dirt"; +const tCity = "medit_city_tile"; const tGrassDry = ["medit_grass_field_brown", "medit_grass_field_dry", "medit_grass_field_b"]; const tGrass = ["medit_grass_field_dry", "medit_grass_field_brown", "medit_grass_field_b"]; const tGrassLush = ["grass_temperate_dry_tufts", "medit_grass_flowers"]; @@ -34,6 +35,9 @@ const oOak = "gaia/flora_tree_oak"; const oPalm = "gaia/flora_tree_medit_fan_palm"; const oPine = "gaia/flora_tree_aleppo_pine"; const oPoplar = "gaia/flora_tree_poplar"; +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"; @@ -45,23 +49,18 @@ const aBushMedDry = "actor|props/flora/bush_medit_me_dry.xml"; const aBushMed = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const aBushSmallDry = "actor|props/flora/bush_medit_sm_dry.xml"; -const aGrass = "actor|props/flora/grass_medit_field.xml"; -const aGrassDry = "actor|props/flora/grass_soft_dry_small.xml"; -const aRockLarge = "actor|geology/stone_granite_greek_large.xml"; -const aRockMed = "actor|geology/stone_granite_greek_med.xml"; -const aRockSmall = "actor|geology/stone_granite_greek_small.xml"; +const aGrass = "actor|props/flora/grass_soft_large_tall.xml"; +const aGrassDry = "actor|props/flora/grass_soft_dry_large_tall.xml"; +const aRockLarge = "actor|geology/stone_granite_large.xml"; +const aRockMed = "actor|geology/stone_granite_med.xml"; +const aRockSmall = "actor|geology/stone_granite_small.xml"; const aWaterLog = "actor|props/flora/water_log.xml"; // terrain + entity (for painting) -var pPalmForest = tForestFloor+TERRAIN_SEPARATOR+oPalm; -var pPineForest = tForestFloor+TERRAIN_SEPARATOR+oPine; -var pCarobForest = tForestFloor+TERRAIN_SEPARATOR+oCarob; -var pBeechForest = tForestFloor+TERRAIN_SEPARATOR+oBeech; -var pPoplarForest = tForestFloor+TERRAIN_SEPARATOR+oLombardyPoplar; -var tPalmForest = [pPalmForest, tGrass]; -var tPineForest = [pPineForest, tGrass]; -var tMainForest = [pCarobForest, pBeechForest, tGrass, tGrass]; -var tPoplarForest = [pPoplarForest, tGrass]; +var pPalmForest = [tForestFloor+TERRAIN_SEPARATOR+oPalm, tGrass]; +var pPineForest = [tForestFloor+TERRAIN_SEPARATOR+oPine, tGrass]; +var pPoplarForest = [tForestFloor+TERRAIN_SEPARATOR+oLombardyPoplar, tGrass]; +var pMainForest = [tForestFloor+TERRAIN_SEPARATOR+oCarob, tForestFloor+TERRAIN_SEPARATOR+oBeech, tGrass, tGrass]; // initialize map @@ -87,80 +86,27 @@ var clSettlement = createTileClass(); // Place players -log("Placing players..."); +log("Creating players..."); var playerX = new Array(numPlayers+1); var playerZ = new Array(numPlayers+1); var numLeftPlayers = ceil(numPlayers/2); -for (var i=1; i <= numLeftPlayers; i++) +for (var i = 1; i <= numLeftPlayers; i++) { - playerX[i] = 0.28 + (2*randFloat()-1)*0.01; - playerZ[i] = (0.5+i-1)/numLeftPlayers + (2*randFloat()-1)*0.01; + playerX[i] = 0.28 + randFloat(-0.01, 0.01); + playerZ[i] = (0.5+i-1)/numLeftPlayers + randFloat(-0.01, 0.01); } -for (var i=numLeftPlayers+1; i <= numPlayers; i++) +for (var i = numLeftPlayers+1; i <= numPlayers; i++) { - playerX[i] = 0.72 + (2*randFloat()-1)*0.01; - playerZ[i] = (0.5+i-numLeftPlayers-1)/numLeftPlayers + (2*randFloat()-1)*0.01; -} - -for (var i=1; i <= numPlayers; i++) -{ - log("Creating base for player " + i + "..."); - - // get fractional locations in tiles - var ix = round(fractionToTiles(playerX[i])); - var iz = round(fractionToTiles(playerZ[i])); - addToClass(ix, iz, clPlayer); - - // create TC and starting units - // TODO: Get civ specific starting units - var civ = getCivCode(i - 1); - placeObject(ix, iz, "structures/"+civ + "_civil_centre", i, PI*3/4); - var group = new SimpleGroup( - [new SimpleObject("units/"+civ+"_support_female_citizen", 3,3, 5,5)], - true, null, ix, iz - ); - createObjectGroup(group, i); - - // create starting berry bushes - var bbAngle = randFloat()*2*PI; - var bbDist = 9; - var bbX = round(ix + bbDist * cos(bbAngle)); - var bbZ = round(iz + bbDist * sin(bbAngle)); - group = new SimpleGroup( - [new SimpleObject(oBerryBush, 5,5, 0,2)], - true, clBaseResource, bbX, bbZ - ); - createObjectGroup(group, 0); - - // create starting mines - var mAngle = bbAngle; - while(abs(mAngle - bbAngle) < PI/3) { - mAngle = randFloat()*2*PI; - } - var mDist = 9; - var mX = round(ix + mDist * cos(mAngle)); - var mZ = round(iz + mDist * sin(mAngle)); - group = new SimpleGroup( - [new SimpleObject(oStone, 2,2, 0,3), - new SimpleObject(oMetal, 1,1, 0,3)], - true, clBaseResource, mX, mZ - ); - createObjectGroup(group, 0); - - // create starting straggler trees - group = new SimpleGroup( - [new SimpleObject(oPalm, 3,3, 7,10)], - true, clBaseResource, ix, iz - ); - createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); + playerX[i] = 0.72 + randFloat(-0.01, 0.01); + playerZ[i] = (0.5+i-numLeftPlayers-1)/numLeftPlayers + randFloat(-0.01, 0.01); } function distanceToPlayers(x, z) { var r = 10000; - for (var i=1; i <= numPlayers; i++) + for (var i = 1; i <= numPlayers; i++) { var dx = x - playerX[i]; var dz = z - playerZ[i]; @@ -202,9 +148,9 @@ var noise3 = new Noise2D(4 * mapSize/128); var noise4 = new Noise2D(6 * mapSize/128); var noise5 = new Noise2D(11 * mapSize/128); -for (var ix=0; ix<=mapSize; ix++) +for (var ix = 0; ix <= mapSize; ix++) { - for (var iz=0; iz<=mapSize; iz++) + for (var iz = 0; iz <= mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); @@ -288,9 +234,9 @@ var noise9 = new Noise2D(26 * mapSize/128); var noise10 = new Noise2D(50 * mapSize/128); -for (var ix=0; ix 1) { - var forestNoise = (noise6.get(x,z) + 0.5*noise7.get(x,z)) / 1.5 * pn; - forestNoise -= 0.59; + var forestNoise = (noise6.get(x,z) + 0.5*noise7.get(x,z)) / 1.5 * pn - 0.59; if (forestNoise > 0) { @@ -390,17 +335,17 @@ for (var ix=0; ix 1.2) ? tGrassCliff : tGrassDry; - if (maxH - minH < 0.5 && randFloat() < 0.03) + if (maxH - minH < 0.5 && randFloat() < 0.02) { - placeObject(ix+randFloat(), iz+randFloat(), aGrassDry, 0, randFloat()*2*PI); + placeObject(ix+randFloat(), iz+randFloat(), aGrassDry, 0, randFloat(0, TWO_PI)); } } else if (grassNoise > 0.61) @@ -428,9 +373,9 @@ for (var ix=0; ix= 0 && z >= 0 && x < this.size && z < this.size; + if (g_MapSettings.CircularMap) + { // Within map circle + var halfSize = 0.5*this.size; + var dx = (x - halfSize); + var dz = (z - halfSize); + return Math.sqrt(dx*dx + dz*dz) < (halfSize - 1.5); + } + else + { // Within map square + return x >= 0 && z >= 0 && x < this.size && z < this.size; + } }; // Check bounds on height map (size + 1 by size + 1) @@ -114,7 +124,7 @@ Map.prototype.getTexture = function(x, z) { if (!this.validT(x, z)) { - error("getTexture: invalid tile position ("+x+", "+z+")"); + throw("getTexture: invalid tile position ("+x+", "+z+")"); } return this.IDToName[this.texture[x][z]]; @@ -124,7 +134,7 @@ Map.prototype.setTexture = function(x, z, texture) { if (!this.validT(x, z)) { - error("setTexture: invalid tile position ("+x+", "+z+")"); + throw("setTexture: invalid tile position ("+x+", "+z+")"); } this.texture[x][z] = this.getTextureID(texture); @@ -134,7 +144,7 @@ Map.prototype.getHeight = function(x, z) { if (!this.validH(x, z)) { - error("getHeight: invalid vertex position ("+x+", "+z+")"); + throw("getHeight: invalid vertex position ("+x+", "+z+")"); } return this.height[x][z]; @@ -144,7 +154,7 @@ Map.prototype.setHeight = function(x, z, height) { if (!this.validH(x, z)) { - error("setHeight: invalid vertex position ("+x+", "+z+")"); + throw("setHeight: invalid vertex position ("+x+", "+z+")"); } this.height[x][z] = height; @@ -154,7 +164,7 @@ Map.prototype.getTerrainObjects = function(x, z) { if (!this.validT(x, z)) { - error("getTerrainObjects: invalid tile position ("+x+", "+z+")"); + throw("getTerrainObjects: invalid tile position ("+x+", "+z+")"); } return this.terrainObjects[x][z]; @@ -164,7 +174,7 @@ Map.prototype.setTerrainObject = function(x, z, object) { if (!this.validT(x, z)) { - error("setTerrainObject: invalid tile position ("+x+", "+z+")"); + throw("setTerrainObject: invalid tile position ("+x+", "+z+")"); } this.terrainObjects[x][z] = object; diff --git a/binaries/data/mods/public/maps/random/rmgen/mapgen.js b/binaries/data/mods/public/maps/random/rmgen/mapgen.js index 097a48e251..806c58efdb 100644 --- a/binaries/data/mods/public/maps/random/rmgen/mapgen.js +++ b/binaries/data/mods/public/maps/random/rmgen/mapgen.js @@ -35,7 +35,7 @@ function InitMap() if (g_MapSettings === undefined) { // Should never get this far, failed settings would abort prior to loading scripts - error("InitMapGen: settings missing"); + throw("InitMapGen: settings missing"); } // Create new map diff --git a/binaries/data/mods/public/maps/random/rmgen/painter.js b/binaries/data/mods/public/maps/random/rmgen/painter.js index 5c7a5e4893..f78ea8fe75 100644 --- a/binaries/data/mods/public/maps/random/rmgen/painter.js +++ b/binaries/data/mods/public/maps/random/rmgen/painter.js @@ -47,7 +47,9 @@ ElevationPainter.prototype.paint = function(area) function LayeredPainter(terrainArray, widths) { if (!(terrainArray instanceof Array)) - error("terrains must be an array!"); + { + throw("LayeredPainter: terrains must be an array!"); + } this.terrains = []; for (var i = 0; i < terrainArray.length; ++i) @@ -187,12 +189,20 @@ function SmoothElevationPainter(type, elevation, blendRadius) this.blendRadius = blendRadius; if (type != ELEVATION_SET && type != ELEVATION_MODIFY) - error("SmoothElevationPainter: invalid type '"+type+"'"); + { + throw("SmoothElevationPainter: invalid type '"+type+"'"); + } } SmoothElevationPainter.prototype.checkInArea = function(areaID, x, z) { - return (g_Map.validT(x, z) && g_Map.area[x][z] == areaID); + // Check given tile and its neighbors + return ( + (g_Map.validT(x, z) && g_Map.area[x][z] == areaID) + || (g_Map.validT(x-1, z) && g_Map.area[x-1][z] == areaID) + || (g_Map.validT(x, z-1) && g_Map.area[x][z-1] == areaID) + || (g_Map.validT(x-1, z-1) && g_Map.area[x-1][z-1] == areaID) + ); }; SmoothElevationPainter.prototype.paint = function(area) @@ -255,12 +265,7 @@ SmoothElevationPainter.prototype.paint = function(area) { var nz = z+dz; - if (g_Map.validH(nx, nz) - && !this.checkInArea(areaID, nx, nz) - && !this.checkInArea(areaID, nx-1, nz) - && !this.checkInArea(areaID, nx, nz-1) - && !this.checkInArea(areaID, nx-1, nz-1) - && !saw[nx][nz]) + if (g_Map.validH(nx, nz) && !this.checkInArea(areaID, nx, nz) && !saw[nx][nz]) { saw[nx][nz]= 1; dist[nx][nz] = 0; @@ -279,9 +284,7 @@ SmoothElevationPainter.prototype.paint = function(area) var d = dist[px][pz]; // paint if in area - if (g_Map.validH(px, pz) - && (this.checkInArea(areaID, px, pz) || this.checkInArea(areaID, px-1, pz) - || this.checkInArea(areaID, px, pz-1) || this.checkInArea(areaID, px-1, pz-1))) + if (g_Map.validH(px, pz) && this.checkInArea(areaID, px, pz)) { if (d <= this.blendRadius) { @@ -316,10 +319,7 @@ SmoothElevationPainter.prototype.paint = function(area) { var nz = pz+dz; - if (g_Map.validH(nx, nz) - && (this.checkInArea(areaID, nx, nz) || this.checkInArea(areaID, nx-1, nz) - || this.checkInArea(areaID, nx, nz-1) || this.checkInArea(areaID, nx-1, nz-1)) - && !saw[nx][nz]) + if (g_Map.validH(nx, nz) && this.checkInArea(areaID, nx, nz) && !saw[nx][nz]) { saw[nx][nz] = 1; dist[nx][nz] = d+1; @@ -338,8 +338,7 @@ SmoothElevationPainter.prototype.paint = function(area) var px = pt.x; var pz = pt.z; - if ((this.checkInArea(areaID, px, pz) || this.checkInArea(areaID, px-1, pz) - || this.checkInArea(areaID, px, pz-1) || this.checkInArea(areaID, px-1, pz-1))) + if (this.checkInArea(areaID, px, pz)) { var sum = 8 * newHeight[px][pz]; var count = 8; diff --git a/binaries/data/mods/public/maps/random/rmgen/placer.js b/binaries/data/mods/public/maps/random/rmgen/placer.js index efaed67bd9..7b0313f275 100644 --- a/binaries/data/mods/public/maps/random/rmgen/placer.js +++ b/binaries/data/mods/public/maps/random/rmgen/placer.js @@ -137,7 +137,9 @@ function RectPlacer(x1, z1, x2, z2) this.z2 = z2; if (x1 > x2 || z1 > z2) - error("RectPlacer: incorrect bounds on rect"); + { + throw("RectPlacer: incorrect bounds on rect"); + } } RectPlacer.prototype.place = function(constraint) @@ -201,13 +203,13 @@ function SimpleObject(type, minCount, maxCount, minDistance, maxDistance, minAng this.maxAngle = (maxAngle !== undefined ? maxAngle : 2*PI); if (minCount > maxCount) - error("SimpleObject: minCount must be less than or equal to maxCount"); + warn("SimpleObject: minCount should be less than or equal to maxCount"); if (minDistance > maxDistance) - error("SimpleObject: minDistance must be less than or equal to maxDistance"); + warn("SimpleObject: minDistance should be less than or equal to maxDistance"); if (minAngle > maxAngle) - error("SimpleObject: minAngle must be less than or equal to maxAngle"); + warn("SimpleObject: minAngle should be less than or equal to maxAngle"); } SimpleObject.prototype.place = function(cx, cz, player, avoidSelf, constraint) @@ -277,6 +279,108 @@ SimpleObject.prototype.place = function(cx, cz, player, avoidSelf, constraint) return resultObjs; }; +///////////////////////////////////////////////////////////////////////////////////////// +// RandomObject +// +// Class specifying entities that can be placed on the map, selected randomly +// +// types: Array of entity template names +// minCount,maxCount: The number of objects to place +// minDistance,maxDistance: The distance between placed objects +// minAngle,maxAngle: The variation in angle of placed objects (optional) +// +///////////////////////////////////////////////////////////////////////////////////////// + +function RandomObject(types, minCount, maxCount, minDistance, maxDistance, minAngle, maxAngle) +{ + this.types = types; + this.minCount = minCount; + this.maxCount = maxCount; + this.minDistance = minDistance; + this.maxDistance = maxDistance; + this.minAngle = (minAngle !== undefined ? minAngle : 0); + this.maxAngle = (maxAngle !== undefined ? maxAngle : 2*PI); + + if (minCount > maxCount) + warn("RandomObject: minCount should be less than or equal to maxCount"); + + if (minDistance > maxDistance) + warn("RandomObject: minDistance should be less than or equal to maxDistance"); + + if (minAngle > maxAngle) + warn("RandomObject: minAngle should be less than or equal to maxAngle"); +} + +RandomObject.prototype.place = function(cx, cz, player, avoidSelf, constraint) +{ + var failCount = 0; + var count = randInt(this.minCount, this.maxCount); + var resultObjs = []; + + for (var i=0; i < count; i++) + { + while(true) + { + var distance = randFloat(this.minDistance, this.maxDistance); + var direction = randFloat(0, 2*PI); + + var x = cx + 0.5 + distance*cos(direction); + var z = cz + 0.5 + distance*sin(direction); + var fail = false; // reset place failure flag + + if (!g_Map.validT(x, z)) + { + fail = true; + } + else + { + if (avoidSelf) + { + var length = resultObjs.length; + for (var i = 0; (i < length) && !fail; i++) + { + var dx = x - resultObjs[i].x; + var dy = z - resultObjs[i].z; + + if ((dx*dx + dy*dy) < 1) + { + fail = true; + } + } + } + + if (!fail) + { + if (!constraint.allows(Math.floor(x), Math.floor(z))) + { + fail = true; + } + else + { // if we got here, we're good + var angle = randFloat(this.minAngle, this.maxAngle); + + //Randomly select entity + var type = this.types[randInt(this.types.length)]; + resultObjs.push(new Entity(type, player, x, z, angle)); + break; + } + } + } + + if (fail) + { + failCount++; + if (failCount > 20) // TODO: Make this adjustable + { + return undefined; + } + } + } + } + + return resultObjs; +}; + ///////////////////////////////////////////////////////////////////////////////////////// // SimpleGroup // @@ -335,3 +439,58 @@ SimpleGroup.prototype.place = function(player, constraint) return true; }; +///////////////////////////////////////////////////////////////////////////////////////// +// RandomGroup +// +// Class for placing group of a random simple object +// +// elements: Array of SimpleObjects +// avoidSelf: Objects will not overlap +// tileClass: Optional tile class to add with these objects +// x,z: Tile coordinates of center of placer +// +///////////////////////////////////////////////////////////////////////////////////////// + +function RandomGroup(elements, avoidSelf, tileClass, x, z) +{ + this.elements = elements; + this.tileClass = (tileClass !== undefined ? getTileClass(tileClass) : undefined); + this.avoidSelf = (avoidSelf !== undefined ? avoidSelf : false); + this.x = (x !== undefined ? x : -1); + this.z = (z !== undefined ? z : -1); +} + +RandomGroup.prototype.place = function(player, constraint) +{ + var resultObjs = []; + + // Pick one of the object placers at random + var placer = this.elements[randInt(this.elements.length)]; + + var objs = placer.place(this.x, this.z, player, this.avoidSelf, constraint); + if (objs === undefined) + { // Failure + return false; + } + else + { + for (var j = 0; j < objs.length; ++j) + { + resultObjs.push(objs[j]); + } + } + + // Add placed objects to map + var length = resultObjs.length; + for (var i=0; i < length; i++) + { + g_Map.addObject(resultObjs[i]); + + if (this.tileClass !== undefined) + { // Round object position to integer + this.tileClass.add(Math.floor(resultObjs[i].tileX), Math.floor(resultObjs[i].tileZ)); + } + } + + return true; +}; diff --git a/binaries/data/mods/public/maps/random/rmgen/random.js b/binaries/data/mods/public/maps/random/rmgen/random.js index e0a0907927..5dd34e01e0 100644 --- a/binaries/data/mods/public/maps/random/rmgen/random.js +++ b/binaries/data/mods/public/maps/random/rmgen/random.js @@ -1,3 +1,4 @@ +// TODO: rename/change these functions, so the bounds are more clear /* * Return a random floating point number using Math.random library @@ -20,7 +21,7 @@ function randFloat() } else { - error("randFloat() received invalid number of arguments: "+arguments.length); + error("randFloat: invalid number of arguments: "+arguments.length); return undefined; } } @@ -47,7 +48,7 @@ function randInt() } else { - error("randInt() received invalid number of arguments: "+arguments.length); + error("randInt: invalid number of arguments: "+arguments.length); return undefined; } } diff --git a/binaries/data/mods/public/maps/random/rmgen/terrain.js b/binaries/data/mods/public/maps/random/rmgen/terrain.js index 6276d71c15..a5c6f4cd31 100644 --- a/binaries/data/mods/public/maps/random/rmgen/terrain.js +++ b/binaries/data/mods/public/maps/random/rmgen/terrain.js @@ -32,7 +32,7 @@ function SimpleTerrain(texture, treeType) { if (texture === undefined) { - error("SimpleTerrain: texture not defined"); + throw("SimpleTerrain: texture not defined"); } this.texture = texture; @@ -64,7 +64,7 @@ function RandomTerrain(terrains) { if (!(terrains instanceof Array) || !terrains.length) { - error("Invalid terrains array"); + throw("RandomTerrain: Invalid terrains array"); } this.terrains = terrains;