diff --git a/binaries/data/mods/public/maps/random/mainland.js b/binaries/data/mods/public/maps/random/mainland.js index 34ed3e90e7..c05f34cd34 100644 --- a/binaries/data/mods/public/maps/random/mainland.js +++ b/binaries/data/mods/public/maps/random/mainland.js @@ -236,7 +236,7 @@ createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 20, clHill, 15), - scaleByMapSize(1, 4) * numPlayers + scaleByMapSize(3, 15) ); diff --git a/binaries/data/mods/public/maps/random/persian_highlands.js b/binaries/data/mods/public/maps/random/persian_highlands.js index 15cb8e451b..8974371d26 100644 --- a/binaries/data/mods/public/maps/random/persian_highlands.js +++ b/binaries/data/mods/public/maps/random/persian_highlands.js @@ -1,16 +1,33 @@ RMS.LoadLibrary("rmgen"); -const tCity = "desert_city_tile_plaza"; -const tDirtMain = ["desert_dirt_persia_1", "desert_dirt_persia_2", "grass_field_dry"]; -const tLakebed1 = ["desert_lakebed_dry_b", "desert_lakebed_dry"]; -const tLakebed2 = ["desert_lakebed_dry_b", "desert_lakebed_dry", "desert_shore_stones", "desert_shore_stones"]; -const tPebbles = "desert_pebbles_rough"; -const tCliff = ["desert_cliff_persia_1", "desert_cliff_persia_2"]; -const tForestFloor = "medit_grass_field_dry"; -const tRocky = "desert_dirt_persia_rocky"; -const tRocks = "desert_dirt_persia_rocks"; -const tGrass = "grass_field_dry"; -const tHill = "desert_cliff_persia_base"; +const tCity = "desert_city_tile_pers_dirt"; +var random_season = randInt(0,1); +if (random_season) //summer +{ + var tDirtMain = ["desert_dirt_persia_1", "desert_dirt_persia_2", "grass_field_dry"]; + var tLakebed1 = ["desert_lakebed_dry_b", "desert_lakebed_dry"]; + var tLakebed2 = ["desert_lakebed_dry_b", "desert_lakebed_dry", "desert_shore_stones", "desert_shore_stones"]; + var tPebbles = "desert_pebbles_rough"; + var tCliff = ["desert_cliff_persia_1", "desert_cliff_persia_crumbling"]; + var tForestFloor = "medit_grass_field_dry"; + var tRocky = "desert_dirt_persia_rocky"; + var tRocks = "desert_dirt_persia_rocks"; + var tGrass = "grass_field_dry"; + var tHill = "desert_cliff_persia_base"; +} +else //spring +{ + var tDirtMain = ["desert_grass_a", "desert_grass_a", "desert_grass_a", "desert_plants_a"]; + var tLakebed1 = ["desert_lakebed_dry_b", "desert_lakebed_dry"]; + var tLakebed2 = "desert_grass_a_sand"; + var tPebbles = "desert_pebbles_rough"; + var tCliff = ["desert_cliff_persia_1", "desert_cliff_persia_crumbling"]; + var tForestFloor = "desert_plants_b_persia"; + var tRocky = "desert_plants_b_persia"; + var tRocks = "desert_plants_a"; + var tGrass = "desert_dirt_persia_rocky"; + var tHill = "desert_cliff_persia_base"; +} // gaia entities const oGrapesBush = "gaia/flora_bush_grapes"; @@ -60,6 +77,15 @@ var clFood = createTileClass(); var clBaseResource = createTileClass(); var clCP = createTileClass(); +for (var ix = 0; ix < mapSize; ix++) +{ + for (var iz = 0; iz < mapSize; iz++) + { + var x = ix / (mapSize + 1.0); + var z = iz / (mapSize + 1.0); + placeTerrain(ix, iz, tDirtMain); + } +} var playerIDs = []; for (var i = 0; i < numPlayers; i++) @@ -209,30 +235,35 @@ RMS.SetProgress(25); // create centeral plateau log("Creating centeral plateau..."); +var halfSize = mapSize / 2; var oRadius = scaleByMapSize(18, 68); -placer = new ClumpPlacer(PI*oRadius*oRadius, 0.6, 0.15, 0, mapSize/2, mapSize/2); -painter = new LayeredPainter([tLakebed2, tLakebed1], [8]); +placer = new ChainPlacer(2, floor(scaleByMapSize(5, 13)), floor(scaleByMapSize(35, 200)), 1, halfSize, halfSize, 0, [floor(oRadius)]); +painter = new LayeredPainter([tLakebed2, tLakebed1], [6]); var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -10, 8); -createArea(placer, [painter, elevationPainter, paintClass(clCP)], null); +createArea(placer, [painter, elevationPainter, paintClass(clCP)], avoidClasses(clPlayer, 18)); RMS.SetProgress(30); - // create hills log("Creating hills..."); -placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.5); -var terrainPainter = new LayeredPainter( - [tCliff, tHill], // terrains - [2] // widths -); -var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 22, 2); -createAreas( - placer, - [terrainPainter, elevationPainter, paintClass(clHill)], - avoidClasses(clPlayer, 7, clCP, 5, clHill, 10), - scaleByMapSize(1, 4) * numPlayers * 3 -); +var numHills = scaleByMapSize(20, 80) +for (var i = 0; i < numHills; ++i) +{ + + createMountain( + floor(scaleByMapSize(40, 60)), + floor(scaleByMapSize(3, 4)), + floor(scaleByMapSize(6, 12)), + floor(scaleByMapSize(4, 10)), + avoidClasses(clPlayer, 7, clCP, 5, clHill, floor(scaleByMapSize(18, 25))), + randInt(mapSize), + randInt(mapSize), + tCliff, + clHill, + 14 + ); +} RMS.SetProgress(35); @@ -299,23 +330,23 @@ log("Creating centeral stone mines..."); // create large stone quarries group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clRock); createObjectGroups(group, 0, - stayClasses(clCP, 3), - 5*scaleByMapSize(10,30), 100 + stayClasses(clCP, 6), + 5*scaleByMapSize(5,30), 50 ); // create small stone quarries group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3), new RandomObject(aBushes, 2,4, 0,2)], true, clRock); createObjectGroups(group, 0, - stayClasses(clCP, 3), - 5*scaleByMapSize(10,30), 100 + stayClasses(clCP, 6), + 5*scaleByMapSize(5,30), 50 ); log("Creating centeral metal mines..."); // create large metal quarries group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal); createObjectGroups(group, 0, - stayClasses(clCP, 3), - 5*scaleByMapSize(10,30), 100 + stayClasses(clCP, 6), + 5*scaleByMapSize(5,30), 50 ); RMS.SetProgress(60); @@ -392,23 +423,6 @@ createObjectGroups(group, 0, 3 * numPlayers, 50 ); -RMS.SetProgress(85); - -// create dead trees -log("Creating dead trees..."); -var types = [oTamarix]; // some variation -var num = floor(numStragglers / types.length); -for (var i = 0; i < types.length; ++i) -{ - group = new SimpleGroup( - [new SimpleObject(types[i], 1,1, 0,3)], - true, clForest - ); - createObjectGroups(group, 0, - [avoidClasses(clMetal, 1, clRock, 1), stayClasses(clCP, 2)], - num - ); -} RMS.SetProgress(90); @@ -428,5 +442,20 @@ for (var i = 0; i < types.length; ++i) ); } -setSunColour(0.733, 0.746, 0.574); +if (!random_season) + setTerrainAmbientColour(0.329412, 0.419608, 0.501961); + +setSunColour(1.0, 0.796, 0.374); +setSunElevation(PI / 6); +setSunRotation(-1.86532); + +setFogFactor(0.2); +setFogThickness(0.0); +setFogColor(0.852, 0.746, 0.493); + +setPPEffect("hdr"); +setPPContrast(0.75); +setPPSaturation(0.45); +setPPBloom(0.3); + ExportMap(); \ No newline at end of file diff --git a/binaries/data/mods/public/maps/random/pheonician_levant.js b/binaries/data/mods/public/maps/random/pheonician_levant.js index a07f28e3a6..30bb33f7c0 100644 --- a/binaries/data/mods/public/maps/random/pheonician_levant.js +++ b/binaries/data/mods/public/maps/random/pheonician_levant.js @@ -106,6 +106,10 @@ for (var i = 0; i < numPlayers; i++) var ix = floor(fx); var iz = floor(fz); addToClass(ix, iz, clPlayer); + addToClass(ix+5, iz, clPlayer); + addToClass(ix, iz+5, clPlayer); + addToClass(ix-5, iz, clPlayer); + addToClass(ix, iz-5, clPlayer); // create the city patch var cityRadius = radius/3; @@ -256,7 +260,7 @@ createAreas( // create hills log("Creating hills..."); -placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); +placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.5); var terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths @@ -280,8 +284,8 @@ var numStragglers = totalTrees * (1.0 - P_FOREST); // create forests log("Creating forests..."); -var num = scaleByMapSize(10,30); -placer = new ClumpPlacer(numForest / num, 0.15, 0.1, 0.5); +var num = scaleByMapSize(10,42); +placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), numForest / (num * floor(scaleByMapSize(2,5))), 0.5); painter = new TerrainPainter([tForestFloor, pForest]); createAreas(placer, [painter, paintClass(clForest)], avoidClasses(clPlayer, 20, clForest, 10, clWater, 1, clHill, 1, clBaseResource, 3), @@ -297,10 +301,10 @@ RMS.SetProgress(50); // create grass patches log("Creating grass patches..."); -var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]; +var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]; for (var i = 0; i < sizes.length; i++) { - placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); + placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5); painter = new LayeredPainter( [[tGrass,tRocksShrubs],[tRocksShrubs,tRocksGrass], [tRocksGrass,tGrass]], // terrains [1,1] // widths @@ -317,10 +321,10 @@ RMS.SetProgress(55); // create dirt patches log("Creating dirt patches..."); -var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]; +var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]; for (var i = 0; i < sizes.length; i++) { - placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); + placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5); painter = new LayeredPainter( [[tDirt,tDirtB],[tDirt,tMainDirt], [tDirtB,tMainDirt]], // terrains [1,1] // widths @@ -506,5 +510,21 @@ setWaterReflectionTint(0.31,0.769,0.894); setWaterWaviness(3); setWaterMurkiness(0.8); setWaterReflectionTintStrength(0.1); + +setTerrainAmbientColour(0.57, 0.58, 0.55); +setUnitsAmbientColour(0.447059, 0.509804, 0.54902); + +setSunElevation(0.671884); +setSunRotation(-0.582913); + +setFogFactor(0.2); +setFogThickness(0.15); +setFogColor(0.8, 0.7, 0.6); + +setPPEffect("hdr"); +setPPContrast(0.53); +setPPSaturation(0.47); +setPPBloom(0.52); + // Export map data ExportMap(); diff --git a/binaries/data/mods/public/maps/random/rmgen/library.js b/binaries/data/mods/public/maps/random/rmgen/library.js index b8098a6f0c..26c01cd3c1 100644 --- a/binaries/data/mods/public/maps/random/rmgen/library.js +++ b/binaries/data/mods/public/maps/random/rmgen/library.js @@ -229,7 +229,7 @@ function createObjectGroups(placer, player, constraint, num, retryFactor) var maxFail = num * retryFactor; var good = 0; var bad = 0; - var halfSize = getMapSize()/2; + var halfSize = getMapSize()/2 - 3; while(good < num && bad <= maxFail) { if (isCircularMap()) @@ -334,14 +334,14 @@ function createSimpleTerrain(terrain) function placeObject(x, z, type, player, angle) { - g_Map.addObject(new Entity(type, player, x, z, angle)); + if (g_Map.validT(x, z, 3)) + g_Map.addObject(new Entity(type, player, x, z, angle)); } function placeTerrain(x, z, terrain) { // convert terrain param into terrain object g_Map.placeTerrain(x, z, createTerrain(terrain)); - } function isCircularMap() diff --git a/binaries/data/mods/public/maps/random/rmgen/map.js b/binaries/data/mods/public/maps/random/rmgen/map.js index 8e32fb7137..bc94a25e33 100644 --- a/binaries/data/mods/public/maps/random/rmgen/map.js +++ b/binaries/data/mods/public/maps/random/rmgen/map.js @@ -106,13 +106,13 @@ Map.prototype.validT = function(x, z, distance) { if (g_MapSettings.CircularMap) { // Within map circle - if (distance == undefined) - var halfSize = Math.floor(0.5*this.size); - else - var halfSize = Math.floor(0.5*this.size)-distance; + var halfSize = Math.floor(0.5*this.size); var dx = (x - halfSize); var dz = (z - halfSize); - return Math.round(Math.sqrt(dx*dx + dz*dz)) < halfSize - 1; + if (distance === undefined) + return Math.round(Math.sqrt(dx*dx + dz*dz)) < halfSize - 1; + else + return Math.round(Math.sqrt(dx*dx + dz*dz)) < halfSize - distance - 1; } else { // Within map square @@ -197,7 +197,7 @@ Map.prototype.getTerrainObjects = function(x, z) Map.prototype.setTerrainObject = function(x, z, object) { - if (!this.validT(x, z)) + if (!this.validT(x, z, 2)) { throw("setTerrainObject: invalid tile position ("+x+", "+z+")"); } diff --git a/binaries/data/mods/public/maps/random/rmgen/misc.js b/binaries/data/mods/public/maps/random/rmgen/misc.js index be36e8a53a..7d762bf53f 100644 --- a/binaries/data/mods/public/maps/random/rmgen/misc.js +++ b/binaries/data/mods/public/maps/random/rmgen/misc.js @@ -1 +1 @@ -///////////////////////////////////////////////////////////////////////////////////////// // passageMaker // // Function for creating shallow water between two given points by changing the heiight of all tiles in // the path with height less than or equal to "maxheight" to "height" // // x1,z1: Starting point of path // x2,z2: Ending point of path // width: Width of the shallow // maxheight: Maximum height that it changes // height: Height of the shallow // smooth: smooth elevation in borders // tileclass: (Optianal) - Adds those tiles to the class given // terrain: (Optional) - Changes the texture of the elevated land // ///////////////////////////////////////////////////////////////////////////////////////// function passageMaker(x1, z1, x2, z2, width, maxheight, height, smooth, tileclass, terrain, riverheight) { var tchm = TILE_CENTERED_HEIGHT_MAP; TILE_CENTERED_HEIGHT_MAP = true; var mapSize = g_Map.size; for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var a = z1-z2; var b = x2-x1; var c = (z1*(x1-x2))-(x1*(z1-z2)); var dis = abs(a*ix + b*iz + c)/sqrt(a*a + b*b); var k = (a*ix + b*iz + c)/(a*a + b*b); var my = iz-(b*k); var inline = 0; if (b == 0) { dis = abs(ix-x1); if ((iz <= Math.max(z1,z2))&&(iz >= Math.min(z1,z2))) { inline = 1; } } else { if ((my <= Math.max(z1,z2))&&(my >= Math.min(z1,z2))) { inline = 1; } } if ((dis <= width)&&(inline)) { if(g_Map.getHeight(ix, iz) <= maxheight) { if (dis > width - smooth) { g_Map.setHeight(ix, iz, ((width - dis)*(height)+(riverheight)*(smooth - width + dis))/(smooth)); } else if (dis <= width - smooth) { g_Map.setHeight(ix, iz, height); } if (tileclass !== undefined) { addToClass(ix, iz, tileclass); } if (terrain !== undefined) { placeTerrain(ix, iz, terrain); } } } } } TILE_CENTERED_HEIGHT_MAP = tchm; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //rndRiver is a fuction that creates random values useful for making a jagged river. // //it works the same as sin or cos function. the only difference is that it's period is 1 instead of 2*pi //it needs the "seed" parameter to use it to make random curves that don't get broken. //seed must be created using randFloat(). or else it won't work // // f: Input: Same as angle in a sine function // seed: Random Seed: Best to implement is to use randFloat() // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function rndRiver(f, seed) { var rndRq = seed; var rndRw = rndRq; var rndRe = 0; var rndRr = f-floor(f); var rndRa = 0; for (var rndRx=0; rndRx<=floor(f); rndRx++) { rndRw = 10*(rndRw-floor(rndRw)); } if (rndRx%2==0) { var rndRs = -1; } else { var rndRs = 1; } rndRe = (floor(rndRw))%5; if (rndRe==0) { rndRa = (rndRs)*2.3*(rndRr)*(rndRr-1)*(rndRr-0.5)*(rndRr-0.5); } else if (rndRe==1) { rndRa = (rndRs)*2.6*(rndRr)*(rndRr-1)*(rndRr-0.3)*(rndRr-0.7); } else if (rndRe==2) { rndRa = (rndRs)*22*(rndRr)*(rndRr-1)*(rndRr-0.2)*(rndRr-0.3)*(rndRr-0.3)*(rndRr-0.8); } else if (rndRe==3) { rndRa = (rndRs)*180*(rndRr)*(rndRr-1)*(rndRr-0.2)*(rndRr-0.2)*(rndRr-0.4)*(rndRr-0.6)*(rndRr-0.6)*(rndRr-0.8); } else if (rndRe==4) { rndRa = (rndRs)*2.6*(rndRr)*(rndRr-1)*(rndRr-0.5)*(rndRr-0.7); } return rndRa; } ///////////////////////////////////////////////////////////////////////////////////////// // createStartingPlayerEntities // // Creates the starting player entities // fx&fz: position of player base // playerid: id of player // civEntities: use getStartingEntities(id-1) fo this one // BUILDING_ANGlE: angle of main base building // /////////////////////////////////////////////////////////////////////////////////////////// function createStartingPlayerEntities(fx, fz, playerid, civEntities, BUILDING_ANGlE) { var uDist = 6; var uSpace = 2; placeObject(fx, fz, civEntities[0].Template, playerid, BUILDING_ANGlE); for (var j = 1; j < civEntities.length; ++j) { var uAngle = BUILDING_ANGlE - PI * (2-j) / 2; var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); for (var numberofentities = 0; numberofentities < count; numberofentities++) { var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); placeObject(ux, uz, civEntities[j].Template, playerid, uAngle); } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // placeCivDefaultEntities // // Creates the default starting player entities depending on the players civ // fx&fy: position of player base // playerid: id of player // angle: angle of main base building, optional, default is BUILDING_ANGlE // kwargs: Takes some optional keyword arguments to tweek things // 'iberWall': may be false, 'walls' (default) or 'towers'. Determines the defensive structures Iberians get as civ bonus // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function placeCivDefaultEntities(fx, fz, playerid, angle, kwargs) { // Unpack kwargs kwargs = (kwargs || {}); var iberWall = 'walls'; if (getMapSize() <= 128) iberWall = false; if ('iberWall' in kwargs) iberWall = kwargs['iberWall']; // Place default civ starting entities var civ = g_MapSettings.PlayerData[playerid-1].Civ; var civEntities = getStartingEntities(playerid-1); var uDist = 6; var uSpace = 2; placeObject(fx, fz, civEntities[0].Template, playerid, angle); for (var j = 1; j < civEntities.length; ++j) { var uAngle = angle - PI * (2-j) / 2; var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); for (var numberofentities = 0; numberofentities < count; numberofentities++) { var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); placeObject(ux, uz, civEntities[j].Template, playerid, uAngle); } } // Add defensive structiures for Iberians as their civ bonus if (civ == 'iber' && iberWall != false) { if (iberWall == 'towers') placePolygonalWall(fx, fz, 15, ['entry'], 'tower', civ, playerid, angle, 7); else placeGenericFortress(fx, fz, 20/*radius*/, playerid); } } ///////////////////////////////////////////////////////////////////////////////////////// // paintTerrainBasedOnHeight // // paints the tiles which have a height between minheight and maxheight with the given terrain // minheight: minimum height of the tile // maxheight: maximum height of the tile // mode: accepts 4 values. 0 means the it will select tiles with height more than minheight and less than maxheight. // 1 means it selects tiles with height more than or equal to minheight and less than max height. 2 means more than // minheight and less than or equal to maxheight. 3 means more than or equal to minheight and less than or equal to maxheight // terrain: intended terrain texture // /////////////////////////////////////////////////////////////////////////////////////////// function paintTerrainBasedOnHeight(minheight, maxheight, mode, terrain) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { placeTerrain(qx, qz, terrain); } } } } } ///////////////////////////////////////////////////////////////////////////////////////// // paintTileClassBasedOnHeight and unPaintTileClassBasedOnHeight // // paints or unpaints the tiles which have a height between minheight and maxheight with the given tile class // minheight: minimum height of the tile // maxheight: maximum height of the tile // mode: accepts 4 values. 0 means the it will select tiles with height more than minheight and less than maxheight. // 1 means it selects tiles with height more than or equal to minheight and less than max height. 2 means more than // minheight and less than or equal to maxheight. 3 means more than or equal to minheight and less than or equal to maxheight // tileclass: intended tile class // /////////////////////////////////////////////////////////////////////////////////////////// function paintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { addToClass(qx, qz, tileclass); } } } } } function unPaintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { removeFromClass(qx, qz, tileclass); } } } } } ///////////////////////////////////////////////////////////////////////////////////////// // getTIPIADBON // // "get The Intended Point In A Direction Based On Height" // gets the N'th point with a specific height in a line and returns it as a [x, y] array // startPoint: [x, y] array defining the start point // endPoint: [x, y] array defining the ending point // heightRange: [min, max] array defining the range which the height of the intended point can be. includes both "min" and "max" // step: how much tile units per turn should the search go. more value means faster but less accurate // n: how many points to skip before ending the search. skips """n-1 points""". // /////////////////////////////////////////////////////////////////////////////////////////// function getTIPIADBON(startPoint, endPoint, heightRange, step, n) { var stepX = step*(endPoint[0]-startPoint[0])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + step*(endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var stepY = step*(endPoint[1]-startPoint[1])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + step*(endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var y = startPoint[1]; var checked = 0; for (var x = startPoint[0]; true; x += stepX) { if ((floor(x) < g_Map.size)||(floor(y) < g_Map.size)) { if ((g_Map.getHeight(floor(x), floor(y)) <= heightRange[1])&&(g_Map.getHeight(floor(x), floor(y)) >= heightRange[0])) { ++checked; } if (checked >= n) { return [x, y]; } } y += stepY; if ((y > endPoint[1])&&(stepY>0)) break; if ((y < endPoint[1])&&(stepY<0)) break; if ((x > endPoint[1])&&(stepX>0)) break; if ((x < endPoint[1])&&(stepX<0)) break; } return undefined; } ///////////////////////////////////////////////////////////////////////////////////////// // doIntersect // // determines if two lines with the width "width" intersect or collide with each other // x1, y1, x2, y2: determine the position of the first line // x3, y3, x4, y4: determine the position of the second line // width: determines the width of the lines // /////////////////////////////////////////////////////////////////////////////////////////// function checkIfIntersect (x1, y1, x2, y2, x3, y3, x4, y4, width) { if (x1 == x2) { if (((x3 - x1) < width) || ((x4 - x2) < width)) return true; } else { var m = (y1 - y2) / (x1 - x2); var b = y1 - m * x1; var m2 = sqrt(m * m + 1) if ((Math.abs((y3 - x3 * m - b)/m2) < width) || (Math.abs((y4 - x4 * m - b)/m2) < width)) return true; //neccessary for some situations. if (x3 == x4) { if (((x1 - x3) < width) || ((x2 - x4) < width)) return true; } else { var m = (y3 - y4) / (x3 - x4); var b = y3 - m * x3; var m2 = sqrt(m * m + 1) if ((Math.abs((y1 - x1 * m - b)/m2) < width) || (Math.abs((y2 - x2 * m - b)/m2) < width)) return true; } } var s = ((x1 - x2) * (y3 - y1) - (y1 - y2) * (x3 - x1)), p = ((x1 - x2) * (y4 - y1) - (y1 - y2) * (x4 - x1)); if ((s * p) <= 0) { s = ((x3 - x4) * (y1 - y3) - (y3 - y4) * (x1 - x3)); p = ((x3 - x4) * (y2 - y3) - (y3 - y4) * (x2 - x3)); if ((s * p) <= 0) return true; } return false; } ///////////////////////////////////////////////////////////////////////////////////////// // distanceOfPointFromLine // // returns the distance of a point from a line // x1, y1, x2, y2: determine the position of the line // x3, y3: determine the position of the point // /////////////////////////////////////////////////////////////////////////////////////////// function distanceOfPointFromLine (x1, y1, x2, y2, x3, y3) { if (x1 == x2) { return x3 - x1; } else { var m = (y1 - y2) / (x1 - x2); var b = y1 - m * x1; var m2 = sqrt(m * m + 1) return Math.abs((y3 - x3 * m - b)/m2); } } ///////////////////////////////////////////////////////////////////////////////////////// // createRamp // // creates a ramp from point (x1, y1) to (x2, y2). // x1, y1, x2, y2: determine the position of the start and end of the ramp // minHeight, maxHeight: determine the height levels of the start and end point // width: determines the width of the ramp // smoothLevel: determines the smooth level around the edges of the ramp // mainTerrain: (Optional) determines the terrain texture for the ramp // edgeTerrain: (Optional) determines the terrain texture for the edges // tileclass: (Optional) adds the ramp to this tile class // /////////////////////////////////////////////////////////////////////////////////////////// function createRamp (x1, y1, x2, y2, minHeight, maxHeight, width, smoothLevel, mainTerrain, edgeTerrain, tileclass) { var halfWidth = width / 2; var mapSize = g_Map.size; if (y1 == y2) { var x3 = x2; var y3 = y2 + halfWidth; } else { var m = (x1 - x2) / (y1 - y2); var b = y2 + m * x2; var x3 = x2 + halfWidth; var y3 = - m * x3 + b; } var minBoundX = (x1 <= x2 ? (x1 > halfWidth ? x1 - halfWidth : 0) : (x2 > halfWidth ? x2 - halfWidth : 0)); var maxBoundX = (x1 >= x2 ? (x1 < mapSize - halfWidth ? x1 + halfWidth : mapSize) : (x2 < mapSize - halfWidth ? x2 + halfWidth : mapSize)); var minBoundY = (y1 <= y2 ? (y1 > halfWidth ? y1 - halfWidth : 0) : (y2 > halfWidth ? y2 - halfWidth : 0)); var maxBoundY = (y1 >= y2 ? (x1 < mapSize - halfWidth ? y1 + halfWidth : mapSize) : (y2 < mapSize - halfWidth ? y2 + halfWidth : mapSize)); for (var x = minBoundX; x < maxBoundX; ++x) { for (var y = minBoundY; y < maxBoundY; ++y) { var lDist = distanceOfPointFromLine(x3, y3, x2, y2, x, y); var sDist = distanceOfPointFromLine(x1, y1, x2, y2, x, y); var rampLength = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); if (lDist <= rampLength && sDist <= halfWidth) { var h = ((rampLength - lDist) * maxHeight + lDist * minHeight) / rampLength; if (sDist >= halfWidth - smoothLevel) { h = (h - minHeight) * (halfWidth - sDist) / smoothLevel + minHeight; if (edgeTerrain !== undefined) placeTerrain(x, y, edgeTerrain); } else { if (mainTerrain !== undefined) placeTerrain(x, y, mainTerrain); } if (tileclass !== undefined) addToClass(x, y, tileclass); if((g_Map.getHeight(floor(x), floor(y)) < h) && (h <= maxHeight)) g_Map.setHeight(x, y, h); } } } } \ No newline at end of file +///////////////////////////////////////////////////////////////////////////////////////// // passageMaker // // Function for creating shallow water between two given points by changing the heiight of all tiles in // the path with height less than or equal to "maxheight" to "height" // // x1,z1: Starting point of path // x2,z2: Ending point of path // width: Width of the shallow // maxheight: Maximum height that it changes // height: Height of the shallow // smooth: smooth elevation in borders // tileclass: (Optianal) - Adds those tiles to the class given // terrain: (Optional) - Changes the texture of the elevated land // ///////////////////////////////////////////////////////////////////////////////////////// function passageMaker(x1, z1, x2, z2, width, maxheight, height, smooth, tileclass, terrain, riverheight) { var tchm = TILE_CENTERED_HEIGHT_MAP; TILE_CENTERED_HEIGHT_MAP = true; var mapSize = g_Map.size; for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var a = z1-z2; var b = x2-x1; var c = (z1*(x1-x2))-(x1*(z1-z2)); var dis = abs(a*ix + b*iz + c)/sqrt(a*a + b*b); var k = (a*ix + b*iz + c)/(a*a + b*b); var my = iz-(b*k); var inline = 0; if (b == 0) { dis = abs(ix-x1); if ((iz <= Math.max(z1,z2))&&(iz >= Math.min(z1,z2))) { inline = 1; } } else { if ((my <= Math.max(z1,z2))&&(my >= Math.min(z1,z2))) { inline = 1; } } if ((dis <= width)&&(inline)) { if(g_Map.getHeight(ix, iz) <= maxheight) { if (dis > width - smooth) { g_Map.setHeight(ix, iz, ((width - dis)*(height)+(riverheight)*(smooth - width + dis))/(smooth)); } else if (dis <= width - smooth) { g_Map.setHeight(ix, iz, height); } if (tileclass !== undefined) { addToClass(ix, iz, tileclass); } if (terrain !== undefined) { placeTerrain(ix, iz, terrain); } } } } } TILE_CENTERED_HEIGHT_MAP = tchm; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //rndRiver is a fuction that creates random values useful for making a jagged river. // //it works the same as sin or cos function. the only difference is that it's period is 1 instead of 2*pi //it needs the "seed" parameter to use it to make random curves that don't get broken. //seed must be created using randFloat(). or else it won't work // // f: Input: Same as angle in a sine function // seed: Random Seed: Best to implement is to use randFloat() // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function rndRiver(f, seed) { var rndRq = seed; var rndRw = rndRq; var rndRe = 0; var rndRr = f-floor(f); var rndRa = 0; for (var rndRx=0; rndRx<=floor(f); rndRx++) { rndRw = 10*(rndRw-floor(rndRw)); } if (rndRx%2==0) { var rndRs = -1; } else { var rndRs = 1; } rndRe = (floor(rndRw))%5; if (rndRe==0) { rndRa = (rndRs)*2.3*(rndRr)*(rndRr-1)*(rndRr-0.5)*(rndRr-0.5); } else if (rndRe==1) { rndRa = (rndRs)*2.6*(rndRr)*(rndRr-1)*(rndRr-0.3)*(rndRr-0.7); } else if (rndRe==2) { rndRa = (rndRs)*22*(rndRr)*(rndRr-1)*(rndRr-0.2)*(rndRr-0.3)*(rndRr-0.3)*(rndRr-0.8); } else if (rndRe==3) { rndRa = (rndRs)*180*(rndRr)*(rndRr-1)*(rndRr-0.2)*(rndRr-0.2)*(rndRr-0.4)*(rndRr-0.6)*(rndRr-0.6)*(rndRr-0.8); } else if (rndRe==4) { rndRa = (rndRs)*2.6*(rndRr)*(rndRr-1)*(rndRr-0.5)*(rndRr-0.7); } return rndRa; } ///////////////////////////////////////////////////////////////////////////////////////// // createStartingPlayerEntities // // Creates the starting player entities // fx&fz: position of player base // playerid: id of player // civEntities: use getStartingEntities(id-1) fo this one // BUILDING_ANGlE: angle of main base building // /////////////////////////////////////////////////////////////////////////////////////////// function createStartingPlayerEntities(fx, fz, playerid, civEntities, BUILDING_ANGlE) { var uDist = 6; var uSpace = 2; placeObject(fx, fz, civEntities[0].Template, playerid, BUILDING_ANGlE); for (var j = 1; j < civEntities.length; ++j) { var uAngle = BUILDING_ANGlE - PI * (2-j) / 2; var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); for (var numberofentities = 0; numberofentities < count; numberofentities++) { var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); placeObject(ux, uz, civEntities[j].Template, playerid, uAngle); } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // placeCivDefaultEntities // // Creates the default starting player entities depending on the players civ // fx&fy: position of player base // playerid: id of player // angle: angle of main base building, optional, default is BUILDING_ANGlE // kwargs: Takes some optional keyword arguments to tweek things // 'iberWall': may be false, 'walls' (default) or 'towers'. Determines the defensive structures Iberians get as civ bonus // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function placeCivDefaultEntities(fx, fz, playerid, angle, kwargs) { // Unpack kwargs kwargs = (kwargs || {}); var iberWall = 'walls'; if (getMapSize() <= 128) iberWall = false; if ('iberWall' in kwargs) iberWall = kwargs['iberWall']; // Place default civ starting entities var civ = g_MapSettings.PlayerData[playerid-1].Civ; var civEntities = getStartingEntities(playerid-1); var uDist = 6; var uSpace = 2; placeObject(fx, fz, civEntities[0].Template, playerid, angle); for (var j = 1; j < civEntities.length; ++j) { var uAngle = angle - PI * (2-j) / 2; var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); for (var numberofentities = 0; numberofentities < count; numberofentities++) { var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); placeObject(ux, uz, civEntities[j].Template, playerid, uAngle); } } // Add defensive structiures for Iberians as their civ bonus if (civ == 'iber' && iberWall != false) { if (iberWall == 'towers') placePolygonalWall(fx, fz, 15, ['entry'], 'tower', civ, playerid, angle, 7); else placeGenericFortress(fx, fz, 20/*radius*/, playerid); } } ///////////////////////////////////////////////////////////////////////////////////////// // paintTerrainBasedOnHeight // // paints the tiles which have a height between minheight and maxheight with the given terrain // minheight: minimum height of the tile // maxheight: maximum height of the tile // mode: accepts 4 values. 0 means the it will select tiles with height more than minheight and less than maxheight. // 1 means it selects tiles with height more than or equal to minheight and less than max height. 2 means more than // minheight and less than or equal to maxheight. 3 means more than or equal to minheight and less than or equal to maxheight // terrain: intended terrain texture // /////////////////////////////////////////////////////////////////////////////////////////// function paintTerrainBasedOnHeight(minheight, maxheight, mode, terrain) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { placeTerrain(qx, qz, terrain); } } } } } ///////////////////////////////////////////////////////////////////////////////////////// // paintTileClassBasedOnHeight and unPaintTileClassBasedOnHeight // // paints or unpaints the tiles which have a height between minheight and maxheight with the given tile class // minheight: minimum height of the tile // maxheight: maximum height of the tile // mode: accepts 4 values. 0 means the it will select tiles with height more than minheight and less than maxheight. // 1 means it selects tiles with height more than or equal to minheight and less than max height. 2 means more than // minheight and less than or equal to maxheight. 3 means more than or equal to minheight and less than or equal to maxheight // tileclass: intended tile class // /////////////////////////////////////////////////////////////////////////////////////////// function paintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { addToClass(qx, qz, tileclass); } } } } } function unPaintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { removeFromClass(qx, qz, tileclass); } } } } } ///////////////////////////////////////////////////////////////////////////////////////// // getTIPIADBON // // "get The Intended Point In A Direction Based On Height" // gets the N'th point with a specific height in a line and returns it as a [x, y] array // startPoint: [x, y] array defining the start point // endPoint: [x, y] array defining the ending point // heightRange: [min, max] array defining the range which the height of the intended point can be. includes both "min" and "max" // step: how much tile units per turn should the search go. more value means faster but less accurate // n: how many points to skip before ending the search. skips """n-1 points""". // /////////////////////////////////////////////////////////////////////////////////////////// function getTIPIADBON(startPoint, endPoint, heightRange, step, n) { var stepX = step*(endPoint[0]-startPoint[0])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + step*(endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var stepY = step*(endPoint[1]-startPoint[1])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + step*(endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var y = startPoint[1]; var checked = 0; for (var x = startPoint[0]; true; x += stepX) { if ((floor(x) < g_Map.size)||(floor(y) < g_Map.size)) { if ((g_Map.getHeight(floor(x), floor(y)) <= heightRange[1])&&(g_Map.getHeight(floor(x), floor(y)) >= heightRange[0])) { ++checked; } if (checked >= n) { return [x, y]; } } y += stepY; if ((y > endPoint[1])&&(stepY>0)) break; if ((y < endPoint[1])&&(stepY<0)) break; if ((x > endPoint[1])&&(stepX>0)) break; if ((x < endPoint[1])&&(stepX<0)) break; } return undefined; } ///////////////////////////////////////////////////////////////////////////////////////// // doIntersect // // determines if two lines with the width "width" intersect or collide with each other // x1, y1, x2, y2: determine the position of the first line // x3, y3, x4, y4: determine the position of the second line // width: determines the width of the lines // /////////////////////////////////////////////////////////////////////////////////////////// function checkIfIntersect (x1, y1, x2, y2, x3, y3, x4, y4, width) { if (x1 == x2) { if (((x3 - x1) < width) || ((x4 - x2) < width)) return true; } else { var m = (y1 - y2) / (x1 - x2); var b = y1 - m * x1; var m2 = sqrt(m * m + 1) if ((Math.abs((y3 - x3 * m - b)/m2) < width) || (Math.abs((y4 - x4 * m - b)/m2) < width)) return true; //neccessary for some situations. if (x3 == x4) { if (((x1 - x3) < width) || ((x2 - x4) < width)) return true; } else { var m = (y3 - y4) / (x3 - x4); var b = y3 - m * x3; var m2 = sqrt(m * m + 1) if ((Math.abs((y1 - x1 * m - b)/m2) < width) || (Math.abs((y2 - x2 * m - b)/m2) < width)) return true; } } var s = ((x1 - x2) * (y3 - y1) - (y1 - y2) * (x3 - x1)), p = ((x1 - x2) * (y4 - y1) - (y1 - y2) * (x4 - x1)); if ((s * p) <= 0) { s = ((x3 - x4) * (y1 - y3) - (y3 - y4) * (x1 - x3)); p = ((x3 - x4) * (y2 - y3) - (y3 - y4) * (x2 - x3)); if ((s * p) <= 0) return true; } return false; } ///////////////////////////////////////////////////////////////////////////////////////// // distanceOfPointFromLine // // returns the distance of a point from a line // x1, y1, x2, y2: determine the position of the line // x3, y3: determine the position of the point // /////////////////////////////////////////////////////////////////////////////////////////// function distanceOfPointFromLine (x1, y1, x2, y2, x3, y3) { if (x1 == x2) { return x3 - x1; } else { var m = (y1 - y2) / (x1 - x2); var b = y1 - m * x1; var m2 = sqrt(m * m + 1) return Math.abs((y3 - x3 * m - b)/m2); } } ///////////////////////////////////////////////////////////////////////////////////////// // createRamp // // creates a ramp from point (x1, y1) to (x2, y2). // x1, y1, x2, y2: determine the position of the start and end of the ramp // minHeight, maxHeight: determine the height levels of the start and end point // width: determines the width of the ramp // smoothLevel: determines the smooth level around the edges of the ramp // mainTerrain: (Optional) determines the terrain texture for the ramp // edgeTerrain: (Optional) determines the terrain texture for the edges // tileclass: (Optional) adds the ramp to this tile class // /////////////////////////////////////////////////////////////////////////////////////////// function createRamp (x1, y1, x2, y2, minHeight, maxHeight, width, smoothLevel, mainTerrain, edgeTerrain, tileclass) { var halfWidth = width / 2; var mapSize = g_Map.size; if (y1 == y2) { var x3 = x2; var y3 = y2 + halfWidth; } else { var m = (x1 - x2) / (y1 - y2); var b = y2 + m * x2; var x3 = x2 + halfWidth; var y3 = - m * x3 + b; } var minBoundX = (x1 <= x2 ? (x1 > halfWidth ? x1 - halfWidth : 0) : (x2 > halfWidth ? x2 - halfWidth : 0)); var maxBoundX = (x1 >= x2 ? (x1 < mapSize - halfWidth ? x1 + halfWidth : mapSize) : (x2 < mapSize - halfWidth ? x2 + halfWidth : mapSize)); var minBoundY = (y1 <= y2 ? (y1 > halfWidth ? y1 - halfWidth : 0) : (y2 > halfWidth ? y2 - halfWidth : 0)); var maxBoundY = (y1 >= y2 ? (x1 < mapSize - halfWidth ? y1 + halfWidth : mapSize) : (y2 < mapSize - halfWidth ? y2 + halfWidth : mapSize)); for (var x = minBoundX; x < maxBoundX; ++x) { for (var y = minBoundY; y < maxBoundY; ++y) { var lDist = distanceOfPointFromLine(x3, y3, x2, y2, x, y); var sDist = distanceOfPointFromLine(x1, y1, x2, y2, x, y); var rampLength = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); if (lDist <= rampLength && sDist <= halfWidth) { var h = ((rampLength - lDist) * maxHeight + lDist * minHeight) / rampLength; if (sDist >= halfWidth - smoothLevel) { h = (h - minHeight) * (halfWidth - sDist) / smoothLevel + minHeight; if (edgeTerrain !== undefined) placeTerrain(x, y, edgeTerrain); } else { if (mainTerrain !== undefined) placeTerrain(x, y, mainTerrain); } if (tileclass !== undefined) addToClass(x, y, tileclass); if((g_Map.getHeight(floor(x), floor(y)) < h) && (h <= maxHeight)) g_Map.setHeight(x, y, h); } } } } ///////////////////////////////////////////////////////////////////////////////////////// // createMountain // // creates a mountain using a tecnique very similar to chain placer. // /////////////////////////////////////////////////////////////////////////////////////////// function createMountain(maxHeight, minRadius, maxRadius, numCircles, constraint, x, z, terrain, tileclass, fcc, q) { fcc = (fcc !== undefined ? fcc : 0); q = (q !== undefined ? q : []); // Preliminary bounds check if (!g_Map.inMapBounds(x, z) || !constraint.allows(x, z)) { return; } var size = getMapSize(); var queueEmpty = (q.length ? false : true); var gotRet = new Array(size); for (var i = 0; i < size; ++i) { gotRet[i] = new Array(size); for (var j = 0; j < size; ++j) { gotRet[i][j] = -1; } } --size; if (minRadius < 1) minRadius = 1; if (minRadius > maxRadius) minRadius = maxRadius; var edges = [[x, z]] var circles = []; var pointHeights = [] for (var ix = sx; ix <= lx; ++ix) { pointHeights.push([]); for (var iz = sz; iz <= lz; ++iz) { pointHeights.push(g_Map.getHeight(ix, iz)); } } for (var i = 0; i < numCircles; ++i) { var badPoint = false; var point = edges[randInt(edges.length)]; var cx = point[0], cz = point[1]; if (queueEmpty) { var radius = randInt(minRadius, maxRadius); } else { var radius = q.pop(); queueEmpty = (q.length ? false : true); } var sx = cx - radius, lx = cx + radius; var sz = cz - radius, lz = cz + radius; sx = (sx < 0 ? 0 : sx); sz = (sz < 0 ? 0 : sz); lx = (lx > size ? size : lx); lz = (lz > size ? size : lz); var radius2 = radius * radius; var dx, dz, distance2; //log (uneval([sx, sz, lx, lz])); for (var ix = sx; ix <= lx; ++ix) { for (var iz = sz; iz <= lz; ++ iz) { dx = ix - cx; dz = iz - cz; distance2 = dx * dx + dz * dz if (dx * dx + dz * dz <= radius2) { if (g_Map.inMapBounds(ix, iz)) { if (!constraint.allows(ix, iz)) { badPoint = true; break; } var state = gotRet[ix][iz]; if (state == -1) { gotRet[ix][iz] = -2; } else if (state >= 0) { var s = edges.splice(state, 1); gotRet[ix][iz] = -2; var edgesLength = edges.length; for (var k = state; k < edges.length; ++k) { --gotRet[edges[k][0]][edges[k][1]]; } } } } } if (badPoint) break; } if (badPoint) continue; else circles.push([cx, cz, radius]); for (var ix = sx; ix <= lx; ++ix) { for (var iz = sz; iz <= lz; ++ iz) { if (fcc) if ((x - ix) > fcc || (ix - x) > fcc || (z - iz) > fcc || (iz - z) > fcc) continue; if (gotRet[ix][iz] == -2) { if (ix > 0) { if (gotRet[ix-1][iz] == -1) { edges.push([ix, iz]); gotRet[ix][iz] = edges.length - 1; continue; } } if (iz > 0) { if (gotRet[ix][iz-1] == -1) { edges.push([ix, iz]); gotRet[ix][iz] = edges.length - 1; continue; } } if (ix < size) { if (gotRet[ix+1][iz] == -1) { edges.push([ix, iz]); gotRet[ix][iz] = edges.length - 1; continue; } } if (iz < size) { if (gotRet[ix][iz+1] == -1) { edges.push([ix, iz]); gotRet[ix][iz] = edges.length - 1; continue; } } } } } } var numFinalCircles = circles.length; for (var i = 0; i < numFinalCircles; ++i) { var point = circles[i]; var cx = point[0], cz = point[1], radius = point[2]; var sx = cx - radius, lx = cx + radius; var sz = cz - radius, lz = cz + radius; sx = (sx < 0 ? 0 : sx); sz = (sz < 0 ? 0 : sz); lx = (lx > size ? size : lx); lz = (lz > size ? size : lz); var radius2 = radius * radius; var dx, dz, distance2; var clumpHeight = (radius/maxRadius)*maxHeight*randFloat(0.8,1.2); for (var ix = sx; ix <= lx; ++ix) { for (var iz = sz; iz <= lz; ++ iz) { dx = ix - cx; dz = iz - cz; distance2 = dx * dx + dz * dz; var newHeight = round((Math.sin(PI*(2*((radius - sqrt(distance2))/radius)/3 - 1/6)) + 0.5) * 2 / 3 *clumpHeight) + randInt(0,2); if (dx * dx + dz * dz <= radius2) { if (g_Map.getHeight(ix, iz) < newHeight) g_Map.setHeight(ix, iz, newHeight); else if (g_Map.getHeight(ix, iz) >= newHeight && g_Map.getHeight(ix, iz) < newHeight + 4) g_Map.setHeight(ix, iz, newHeight + 4); if (terrain !== undefined) placeTerrain(ix, iz, terrain); if (tileclass !== undefined) addToClass(ix, iz, tileclass); } } } } } \ No newline at end of file diff --git a/binaries/data/mods/public/maps/random/rmgen/placer.js b/binaries/data/mods/public/maps/random/rmgen/placer.js index 6a0237c595..ff4ce76edc 100644 --- a/binaries/data/mods/public/maps/random/rmgen/placer.js +++ b/binaries/data/mods/public/maps/random/rmgen/placer.js @@ -612,7 +612,8 @@ SimpleGroup.prototype.place = function(player, constraint) length = resultObjs.length; for (var i=0; i < length; i++) { - g_Map.addObject(resultObjs[i]); + if (g_Map.validT(round(resultObjs[i].position.x/CELL_SIZE), round(resultObjs[i].position.z/CELL_SIZE), 3)) + g_Map.addObject(resultObjs[i]); if (this.tileClass !== undefined) { // Convert position to integer number of tiles diff --git a/binaries/data/mods/public/maps/random/rmgen/terrain.js b/binaries/data/mods/public/maps/random/rmgen/terrain.js index 5a760fcf23..201868781e 100644 --- a/binaries/data/mods/public/maps/random/rmgen/terrain.js +++ b/binaries/data/mods/public/maps/random/rmgen/terrain.js @@ -43,7 +43,7 @@ SimpleTerrain.prototype = new Terrain(); SimpleTerrain.prototype.constructor = SimpleTerrain; SimpleTerrain.prototype.placeNew = function(x, z) { - if (this.treeType !== undefined) + if (this.treeType !== undefined && g_Map.validT(round(x), round(z), 3)) { g_Map.terrainObjects[x][z] = new Entity(this.treeType, 0, x+0.5, z+0.5, randFloat()*TWO_PI); }