diff --git a/binaries/data/mods/public/maps/random/archipelago.js b/binaries/data/mods/public/maps/random/archipelago.js index d2bc0b0874..4968b47700 100644 --- a/binaries/data/mods/public/maps/random/archipelago.js +++ b/binaries/data/mods/public/maps/random/archipelago.js @@ -57,9 +57,9 @@ log("Initializing map..."); InitMap(); -var numPlayers = getNumPlayers(); -var mapSize = getMapSize(); -var mapArea = mapSize*mapSize; +const numPlayers = getNumPlayers(); +const mapSize = getMapSize(); +const mapArea = mapSize*mapSize; // create tile classes diff --git a/binaries/data/mods/public/maps/random/ardennes_forest.js b/binaries/data/mods/public/maps/random/ardennes_forest.js index 13d18bbff1..6f5826af7d 100644 --- a/binaries/data/mods/public/maps/random/ardennes_forest.js +++ b/binaries/data/mods/public/maps/random/ardennes_forest.js @@ -27,8 +27,8 @@ log("Initializing map..."); InitMap(); -var numPlayers = getNumPlayers(); -var mapSize = getMapSize(); +const numPlayers = getNumPlayers(); +const mapSize = getMapSize(); const tGrass = ["new_alpine_grass_b", "new_alpine_grass_c", "new_alpine_grass_d"]; const tPineForestFloor = "temp_forestfloor_pine"; @@ -537,7 +537,7 @@ for (var i = 0; i < sizes.length; i++) createAreas( placer, painter, - avoidClasses(clForest, 0, clHill, 2, clPlayer, 5), + avoidClasses(clForest, 1, clHill, 2, clPlayer, 5), scaleByMapSize(4, 12) ); } @@ -607,6 +607,17 @@ createObjectGroupsByAreas(group, 0, RMS.SetProgress(85); +// create berry bush +log("Creating berry bush..."); +group = new SimpleGroup( + [new SimpleObject(oBerryBush, 5,7, 0,4)], + true, clFood +); +createObjectGroups(group, 0, + avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), + randInt(3, 12) * numPlayers + 2, 50 +); + log("Creating decorative props..."); group = new SimpleGroup( [ diff --git a/binaries/data/mods/public/maps/random/atlas_mountains.js b/binaries/data/mods/public/maps/random/atlas_mountains.js index 25a07a2f73..30a8379107 100644 --- a/binaries/data/mods/public/maps/random/atlas_mountains.js +++ b/binaries/data/mods/public/maps/random/atlas_mountains.js @@ -1,15 +1,16 @@ RMS.LoadLibrary("rmgen"); // terrain textures -const tGrass = ["medit_rocks_grass", "medit_rocks_grass_shrubs", "medit_rocks_shrubs"]; -const tGrassPForest = "medit_grass_field_dry"; -const tGrassDForest = "medit_grass_field_dry"; +const tGrass = ["medit_rocks_grass_shrubs", "medit_rocks_shrubs"]; +const tForestFloor = "medit_grass_field_dry"; const tCliff = "medit_cliff_italia"; const tHill = ["medit_rocks_grass", "medit_rocks_grass_shrubs", "medit_rocks_shrubs"]; +const tGrassDirt = "medit_rocks_grass"; const tDirt = "medit_dirt"; const tRoad = "medit_city_tile"; const tRoadWild = "medit_city_tile"; -const tGrassPatch = "medit_grass_shrubs"; +const tGrass2 = "medit_rocks_grass_shrubs"; +const tGrassPatch = "medit_grass_wild"; const tShoreBlend = "medit_sand"; const tShore = "medit_sand"; const tWater = "medit_sand"; @@ -42,8 +43,8 @@ const aAleppoPine = "actor|flora/trees/aleppo_pine.xml"; // terrain + entity (for painting) -const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oCarob, tGrassDForest]; -const pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oAleppoPine, tGrassPForest]; +const pForest1 = [tForestFloor + TERRAIN_SEPARATOR + oCarob, tForestFloor]; +const pForest2 = [tForestFloor + TERRAIN_SEPARATOR + oAleppoPine, tForestFloor]; const BUILDING_ANGlE = -PI/4; @@ -53,16 +54,15 @@ log("Initializing map..."); InitMap(); -var numPlayers = getNumPlayers(); -var mapSize = getMapSize(); -var mapArea = mapSize*mapSize; +const numPlayers = getNumPlayers(); +const mapSize = getMapSize(); +const mapArea = mapSize*mapSize; // create tile classes var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); -var clWater = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); @@ -224,7 +224,7 @@ var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 16, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], - avoidClasses(clPlayer, 16, clWater, 5, clHill, 10), + avoidClasses(clPlayer, 20, clHill, 10), 6*scaleByMapSize(1, 4) * numPlayers ); @@ -239,7 +239,7 @@ elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 20, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], - avoidClasses(clPlayer, 16, clWater, 5, clHill, 7), + avoidClasses(clPlayer, 20, clHill, 7), 7*scaleByMapSize(1, 4) * numPlayers ); @@ -261,8 +261,8 @@ createAreas( RMS.SetProgress(25); // calculate desired number of trees for map (based on size) -const MIN_TREES = 500; -const MAX_TREES = 2500; +const MIN_TREES = 400; +const MAX_TREES = 2000; const P_FOREST = 0.7; var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); @@ -272,8 +272,8 @@ var numStragglers = totalTrees * (1.0 - P_FOREST); // create forests log("Creating forests..."); var types = [ - [[tGrassDForest, tGrass, pForestD], [tGrassDForest, pForestD]], - [[tGrassPForest, tGrass, pForestP], [tGrassPForest, pForestP]] + [[tForestFloor, tGrass, pForest1], [tForestFloor, pForest1]], + [[tForestFloor, tGrass, pForest2], [tForestFloor, pForest2]] ]; // some variation var size = numForest / (scaleByMapSize(2,8) * numPlayers); var num = floor(size / types.length); @@ -287,7 +287,7 @@ for (var i = 0; i < types.length; ++i) createAreas( placer, [painter, paintClass(clForest)], - avoidClasses(clPlayer, 14, clForest, 8, clHill, 1), + avoidClasses(clPlayer, 20, clForest, 8, clHill, 1), num ); } @@ -301,30 +301,33 @@ for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new LayeredPainter( - [tDirt,tDirt], // terrains - [1] // widths + [tGrassDirt,tDirt], // terrains + [2] // widths ); createAreas( placer, [painter, paintClass(clDirt)], - avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 10), - scaleByMapSize(15, 45) + avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 10), + scaleByMapSize(20, 60) ); } // create grass patches log("Creating grass patches..."); -var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]; +var sizes = [scaleByMapSize(3, 32), scaleByMapSize(5, 48), scaleByMapSize(8, 80)]; for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); - painter = new TerrainPainter(tGrass); + painter = new LayeredPainter( + [tGrass2,tGrassPatch], // terrains + [1] // widths + ); createAreas( placer, [painter, paintClass(clGrass)], - avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 10, clGrass, 15), - scaleByMapSize(15, 45) + avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 10, clGrass, 15), + scaleByMapSize(20, 60) ); } @@ -334,14 +337,14 @@ log("Creating stone mines..."); // create large stone quarries group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroups(group, 0, - [avoidClasses(clForest, 1, clPlayer, 9, clMetal, 10, clRock, 5, clHill, 2)], + [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 2)], scaleByMapSize(4,16), 100 ); // create small stone quarries group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroups(group, 0, - [avoidClasses(clForest, 1, clPlayer, 9, clMetal, 10, clRock, 5, clHill, 2)], + [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 2)], scaleByMapSize(4,16), 100 ); @@ -349,7 +352,7 @@ log("Creating metal mines..."); // create large metal quarries group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroups(group, 0, - [avoidClasses(clForest, 1, clPlayer, 9, clMetal, 10, clRock, 5, clHill, 2)], + [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 2)], scaleByMapSize(4,16), 100 ); @@ -363,7 +366,7 @@ group = new SimpleGroup( ); createObjectGroups( group, 0, - avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), + avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); @@ -377,7 +380,7 @@ group = new SimpleGroup( ); createObjectGroups( group, 0, - avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), + avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); @@ -390,7 +393,7 @@ group = new SimpleGroup( true, clFood ); createObjectGroups(group, 0, - avoidClasses(clWater, 0, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), + avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); @@ -403,10 +406,21 @@ group = new SimpleGroup( true, clFood ); createObjectGroups(group, 0, - avoidClasses(clWater, 0, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), + avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); +// create berry bush +log("Creating berry bush..."); +group = new SimpleGroup( + [new SimpleObject(oBerryBush, 5,7, 0,4)], + true, clFood +); +createObjectGroups(group, 0, + avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), + randInt(3, 12) * numPlayers + 2, 50 +); + // create food treasures log("Creating food treasures..."); group = new SimpleGroup( @@ -442,7 +456,7 @@ for (var i = 0; i < types.length; ++i) true, clForest ); createObjectGroups(group, 0, - avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 10, clMetal, 1, clRock, 1, clTreasure, 1), + avoidClasses(clForest, 1, clHill, 1, clPlayer, 10, clMetal, 1, clRock, 1, clTreasure, 1), num ); } @@ -450,7 +464,7 @@ for (var i = 0; i < types.length; ++i) // create hill trees log("Creating hill trees..."); var types = [aCarob, aAleppoPine]; // some variation -var num = floor(3 * numStragglers / types.length); +var num = floor(0.5 * numStragglers / types.length); for (var i = 0; i < types.length; ++i) { group = new SimpleGroup( @@ -471,7 +485,7 @@ group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); createObjectGroups(group, 0, - avoidClasses(clWater, 2, clHill, 2, clPlayer, 16, clDirt, 0), + avoidClasses(clHill, 2, clPlayer, 16, clDirt, 0), scaleByMapSize(13, 200) ); @@ -483,7 +497,7 @@ 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, 0, - avoidClasses(clWater, 3, clHill, 2, clPlayer, 16, clDirt, 1, clForest, 0), + avoidClasses(clHill, 2, clPlayer, 16, clDirt, 1, clForest, 0), scaleByMapSize(13, 200) ); @@ -495,7 +509,7 @@ group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroups(group, 0, - avoidClasses(clWater, 1, clHill, 1, clPlayer, 10, clDirt, 1), + avoidClasses(clHill, 1, clPlayer, 10, clDirt, 1), scaleByMapSize(13, 200), 50 ); diff --git a/binaries/data/mods/public/maps/random/cantabrian_highlands.js b/binaries/data/mods/public/maps/random/cantabrian_highlands.js index 0f300fd3bf..a4b2c39811 100644 --- a/binaries/data/mods/public/maps/random/cantabrian_highlands.js +++ b/binaries/data/mods/public/maps/random/cantabrian_highlands.js @@ -1,20 +1,21 @@ RMS.LoadLibrary("rmgen"); // terrain textures -const tGrass = ["temp_grass_long_b"]; -const tGrassPForest = "temp_forestfloor_pine"; -const tGrassDForest = "temp_forestfloor_a"; -const tCliff = ["temp_cliff_a", "temp_cliff_b"]; -const tGrassA = "temp_grass_d"; -const tGrassB = "temp_grass_c"; -const tGrassC = "temp_grass_clovers_2"; +const tGrass = ["temp_grass", "temp_grass", "temp_grass_d"]; +const tGrassPForest = "temp_plants_bog"; +const tGrassDForest = "temp_plants_bog"; +const tGrassA = "temp_grass_plants"; +const tGrassB = "temp_plants_bog"; +const tGrassC = "temp_mud_a"; +const tDirt = ["temp_plants_bog", "temp_mud_a"]; const tHill = ["temp_highlands", "temp_grass_long_b"]; -const tDirt = ["temp_dirt_gravel", "temp_dirt_gravel_b"]; +const tCliff = ["temp_cliff_a", "temp_cliff_b"]; const tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; -const tGrassPatch = "temp_grass_plants"; -const tShoreBlend = "temp_mud_plants"; -const tShore = "temp_mud_a"; +const tGrassPatchBlend = "temp_grass_long_b"; +const tGrassPatch = ["temp_grass_d", "temp_grass_clovers"]; +const tShoreBlend = "temp_grass_plants"; +const tShore = "temp_plants_bog"; const tWater = "temp_mud_a"; // gaia entities @@ -128,19 +129,19 @@ for (var i = 0; i < numPlayers; i++) // create the ramp 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, 1, rampX, rampZ); - var painter = new SmoothElevationPainter(ELEVATION_SET, elevation-6, 5); - createArea(placer, painter, null); - placer = new ClumpPlacer(75, 0.9, 0.5, 1, rampX, rampZ); - painter = new TerrainPainter(tGrass); - createArea(placer, painter, null); + var rampLength = 15; + var rampWidth = 12; + var rampX1 = round(fx + (rampDist + rampLength) * cos(rampAngle)); + var rampZ1 = round(fz + (rampDist + rampLength) * sin(rampAngle)); + var rampX2 = round(fx + (rampDist - 3) * cos(rampAngle)); + var rampZ2 = round(fz + (rampDist - 3) * sin(rampAngle)); + + createRamp (rampX1, rampZ1, rampX2, rampZ2, 3, 20, rampWidth, 2, tHill, tCliff, clPlayer) // create the city patch var cityRadius = radius/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); - painter = new LayeredPainter([tRoadWild, tRoad], [1]); + var painter = new LayeredPainter([tRoadWild, tRoad], [1]); createArea(placer, painter, null); // create starting units @@ -234,7 +235,7 @@ terrainPainter = new LayeredPainter( [tShoreBlend, tShore, tWater], // terrains [1,1] // widths ); -elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -7, 3); +elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -7, 6); var waterAreas = createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], @@ -292,7 +293,7 @@ terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); -elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 12, 2); +elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 16, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], @@ -362,7 +363,10 @@ var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80) for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); - painter = new TerrainPainter(tGrassPatch); + painter = new LayeredPainter( + [tGrassPatchBlend, tGrassPatch], // terrains + [1] // widths + ); createAreas( placer, painter, @@ -370,7 +374,7 @@ for (var i = 0; i < sizes.length; i++) scaleByMapSize(15, 45) ); } - +tGrassPatchBlend RMS.SetProgress(50); log("Creating stone mines..."); @@ -450,6 +454,17 @@ createObjectGroups(group, 0, 3 * numPlayers, 50 ); +// create berry bush +log("Creating berry bush..."); +group = new SimpleGroup( + [new SimpleObject(oBerryBush, 5,7, 0,4)], + true, clFood +); +createObjectGroups(group, 0, + avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), + randInt(1, 4) * numPlayers + 2, 50 +); + RMS.SetProgress(80); // create straggler trees diff --git a/binaries/data/mods/public/maps/random/rmgen/misc.js b/binaries/data/mods/public/maps/random/rmgen/misc.js index 53dcab9a47..586a054ec6 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]) + (endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var stepY = step*(endPoint[1]-startPoint[1])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + (endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var y = startPoint[1]; var checked = 0; for (var x = startPoint[0]; true; x += n*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); } } \ 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]) + (endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var stepY = step*(endPoint[1]-startPoint[1])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + (endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); var y = startPoint[1]; var checked = 0; for (var x = startPoint[0]; true; x += n*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) g_Map.setHeight(x, y, h); } } } } \ No newline at end of file