diff --git a/binaries/data/mods/public/maps/random/aegean_sea.js b/binaries/data/mods/public/maps/random/aegean_sea.js index 8baf736608..dc20fe7291 100644 --- a/binaries/data/mods/public/maps/random/aegean_sea.js +++ b/binaries/data/mods/public/maps/random/aegean_sea.js @@ -366,7 +366,7 @@ RMS.SetProgress(60); //create the undersea bumps log("Creating undersea bumps..."); placer = new ClumpPlacer(scaleByMapSize(40, 100), 0.3, 0.06, 1); -painter = new SmoothElevationPainter(ELEVATION_SET, -1.1, 3); +painter = new SmoothElevationPainter(ELEVATION_SET, -1.6, 3); createAreas( placer, [painter, paintClass(clCorals)], @@ -392,7 +392,7 @@ createAreas( //paint the seabed paintTerrainBasedOnHeight(-20, -3, 3, tSeaDepths); paintTerrainBasedOnHeight(-3, -2, 2, tCorals2); -paintTerrainBasedOnHeight(-2, -1, 2, tCorals1); +paintTerrainBasedOnHeight(-2, -1.5, 2, tCorals1); log("Creating island stone mines..."); // create island large stone quarries diff --git a/binaries/data/mods/public/maps/random/alpine_valley.js b/binaries/data/mods/public/maps/random/alpine_valley.js index 6c0599ad59..9e7460ee34 100644 --- a/binaries/data/mods/public/maps/random/alpine_valley.js +++ b/binaries/data/mods/public/maps/random/alpine_valley.js @@ -1,17 +1,22 @@ +//we still have got some problems in 4269 + RMS.LoadLibrary("rmgen"); TILE_CENTERED_HEIGHT_MAP = true; -var rt = randInt(1,2); -if (rt == 1) + +//set up the random terrain +var random_terrain = randInt(1,2); + +//late spring +if (random_terrain == 1) { - var tGrass = ["alpine_dirt_grass_50"]; - var tGrassPForest = "alpine_forrestfloor"; - var tGrassDForest = "alpine_forrestfloor"; + var tPrimary = ["alpine_dirt_grass_50"]; + var tForestFloor = "alpine_forrestfloor"; var tCliff = ["alpine_cliff_a", "alpine_cliff_b", "alpine_cliff_c"]; - var tGrassA = "alpine_grass_rocky"; - var tGrassB = ["alpine_grass_snow_50", "alpine_dirt_snow"]; - var tGrassC = ["alpine_snow_a", "alpine_snow_b"]; - var tDirt = ["alpine_dirt", "alpine_grass_d"]; + var tSecondary = "alpine_grass_rocky"; + var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; + var tSnowLimited = ["alpine_snow_rocky"]; + var tDirt = "alpine_dirt"; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var tShore = "alpine_shore_rocks_grass_50"; @@ -22,23 +27,29 @@ if (rt == 1) var oBerryBush = "gaia/flora_bush_berry"; var oChicken = "gaia/fauna_chicken"; var oDeer = "gaia/fauna_deer"; - var oGoat = "gaia/fauna_goat"; - var oFish = "gaia/fauna_fish"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; + + // decorative props + var aGrass = "actor|props/flora/grass_soft_small_tall.xml"; + var aGrassShort = "actor|props/flora/grass_soft_large.xml"; + var aRockLarge = "actor|geology/stone_granite_med.xml"; + var aRockMedium = "actor|geology/stone_granite_med.xml"; + var aBushMedium = "actor|props/flora/bush_medit_me.xml"; + var aBushSmall = "actor|props/flora/bush_medit_sm.xml"; } else +//winter { - var tGrass = ["alpine_snow_a", "alpine_snow_b"]; - var tGrassPForest = "alpine_forrestfloor_snow"; - var tGrassDForest = "alpine_forrestfloor_snow"; - var tCliff = ["alpine_cliff_a", "alpine_cliff_b"]; - var tGrassA = "alpine_grass_snow_50"; - var tGrassB = ["alpine_grass_snow_50", "alpine_dirt_snow"]; - var tGrassC = ["alpine_snow_rocky"]; - var tDirt = ["alpine_dirt_snow", "alpine_snow_a"]; + var tPrimary = ["alpine_snow_a", "alpine_snow_b"]; + var tForestFloor = "alpine_forrestfloor_snow"; + var tCliff = ["alpine_cliff_snow"]; + var tSecondary = "alpine_grass_snow_50"; + var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; + var tSnowLimited = ["alpine_snow_a", "alpine_snow_b"]; + var tDirt = "alpine_dirt"; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var tShore = "alpine_shore_rocks_icy"; @@ -49,39 +60,34 @@ else var oBerryBush = "gaia/flora_bush_berry"; var oChicken = "gaia/fauna_chicken"; var oDeer = "gaia/fauna_deer"; - var oGoat = "gaia/fauna_goat"; - var oFish = "gaia/fauna_fish"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; + + // decorative props + var aGrass = "actor|props/flora/grass_soft_dry_small_tall.xml"; + var aGrassShort = "actor|props/flora/grass_soft_dry_large.xml"; + var aRockLarge = "actor|geology/stone_granite_med.xml"; + var aRockMedium = "actor|geology/stone_granite_med.xml"; + var aBushMedium = "actor|props/flora/bush_medit_me_dry.xml"; + var aBushSmall = "actor|props/flora/bush_medit_sm_dry.xml"; } -// decorative props -var aGrass = "actor|props/flora/grass_soft_small_tall.xml"; -var aGrassShort = "actor|props/flora/grass_soft_large.xml"; -var aRockLarge = "actor|geology/stone_granite_med.xml"; -var aRockMedium = "actor|geology/stone_granite_med.xml"; -var aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; -var aLillies = "actor|props/flora/water_lillies.xml"; -var aBushMedium = "actor|props/flora/bush_medit_me.xml"; -var aBushSmall = "actor|props/flora/bush_medit_sm.xml"; -var pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oPine, tGrassDForest]; -var pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oPine, tGrassPForest]; +//other constants +const pForest = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor]; const BUILDING_ANGlE = -PI/4; // initialize map - 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(); @@ -92,15 +98,15 @@ var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clSettlement = createTileClass(); -var clPass = createTileClass(); +//cover the ground with the primary terrain chosen in the beginning 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, tGrass); + placeTerrain(ix, iz, tPrimary); } } @@ -113,7 +119,6 @@ for (var i = 0; i < numPlayers; i++) playerIDs = sortPlayers(playerIDs); // place players - var playerX = new Array(numPlayers); var playerZ = new Array(numPlayers); var playerAngle = new Array(numPlayers); @@ -236,17 +241,140 @@ for (var i = 0; i < numPlayers; i++) RMS.SetProgress(20); -//create hills -log ("Creating hills..."); -for (var i = 0; i < scaleByMapSize(15,40); i++) +//place the mountains +var points = []; + +var edgesConncetedToPoints = []; + +//we want the points near the start locations be the first ones. hence we use two "for" blocks +for (var i = 0; i < numPlayers; ++i) { - var ix = randInt(1, mapSize - 1); - var iz = randInt(1, mapSize - 1); - var ix2 = randInt(1, mapSize - 1); - var iz2 = randInt(1, mapSize - 1); - var placer = new PathPlacer(ix, iz, ix2, iz2, scaleByMapSize(7,13), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.1); + playerAngle[i] = startAngle + (i+0.5)*TWO_PI/numPlayers; + points.push([round(fractionToTiles(0.5 + 0.49 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.49 * sin(playerAngle[i])))]); +} + +//the order of the other points doesn't matter +for (var i = 0; i < numPlayers; ++i) +{ + playerAngle[i] = startAngle + (i+0.7)*TWO_PI/numPlayers; + points.push([round(fractionToTiles(0.5 + 0.34 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.34 * sin(playerAngle[i])))]); + playerAngle[i] = startAngle + (i+0.3)*TWO_PI/numPlayers; + points.push([round(fractionToTiles(0.5 + 0.34 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.34 * sin(playerAngle[i])))]); + playerAngle[i] = startAngle + (i+0.5)*TWO_PI/numPlayers; + points.push([round(fractionToTiles(0.5 + 0.18 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.18 * sin(playerAngle[i])))]); +} + +//add the center of the map +points.push([round(fractionToTiles(0.5)), round(fractionToTiles(0.5))]); + +var numPoints = numPlayers * 4 + 1; + +for (var i = 0; i < numPoints; ++i) +{ + edgesConncetedToPoints.push(0); +} + +//we are making a planar graph where every edge is a straight line. +var possibleEdges = []; + +//add all of the possible combinations +for (var i = 0; i < numPoints; ++i) +{ + for (var j = numPlayers; j < numPoints; ++j) + { + if (j > i) + possibleEdges.push([i,j]); + } +} + +//we need a matrix so that we can prevent the mountain ranges from bocking a player +var matrix = [] + +for (var i = 0; i < numPoints; ++i) +{ + matrix.push([]); + for (var j = 0; j < numPoints; ++j) + { + if (i < numPlayers && j < numPlayers && i != j && (i == j - 1 || i == j + 1) ) + matrix[i].push(true); + else + matrix[i].push(false); + } +} + +//find and place the edges +while (possibleEdges.length > 0) +{ + var index = randInt(0, possibleEdges.length - 1); + + //ensure that a point is connected to a maximum of 3 others + if (edgesConncetedToPoints[possibleEdges[index][0]] > 2 || edgesConncetedToPoints[possibleEdges[index][1]] > 2) + { + possibleEdges.splice(index,1); + continue; + } + + //dfs + var q = [possibleEdges[index][0]]; + + matrix[possibleEdges[index][0]][possibleEdges[index][1]] = true; + matrix[possibleEdges[index][1]][possibleEdges[index][0]] = true; + var selected, accept = true, tree = [], backtree = []; + while (q.length > 0) + { + selected = q.shift(); + //log ("Selected " + selected + " from the queue"); + if (tree.indexOf(selected) == -1) + { + //log ("First time of then new tree.") + tree.push(selected); + backtree.push(-1); + } + + for (var i = 0; i < numPoints; ++i) + { + if (matrix[selected][i]) + { + //log ("Current tree is:" + "[" + tree.toString() + "]"); + //log ("Checking " + i + ", comparing with " + selected); + if (i == backtree[tree.indexOf(selected)]) + { + //log (i + " is a child of " + selected); + continue; + } + else if (tree.indexOf(i) == -1) + { + tree.push(i); + backtree.push(selected); + q.unshift(i); + //log ("Added " + i + " to the queue"); + //log ("Current tree is:" + "[" + tree.toString() + "]"); + } + else + { + //log (i + " already exists in the tree. Not Accepting."); + accept = false; + matrix[possibleEdges[index][0]][possibleEdges[index][1]] = false; + matrix[possibleEdges[index][1]][possibleEdges[index][0]] = false; + break; + } + } + } + } + + if (!accept) + { + possibleEdges.splice(index,1); + continue; + } + + var ix = points[possibleEdges[index][0]][0]; + var iz = points[possibleEdges[index][0]][1]; + var ix2 = points[possibleEdges[index][1]][0]; + var iz2 = points[possibleEdges[index][1]][1]; + var placer = new PathPlacer(ix, iz, ix2, iz2, scaleByMapSize(9,15), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.1, 0.1); var terrainPainter = new LayeredPainter( - [tCliff, tGrass], // terrains + [tCliff, tPrimary], // terrains [3] // widths ); var elevationPainter = new SmoothElevationPainter( @@ -254,67 +382,70 @@ for (var i = 0; i < scaleByMapSize(15,40); i++) 30, // elevation 2 // blend radius ); - createArea(placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 15)); -} - -//create passages -log ("Creating passages..."); -for (var i = 0; i < numPlayers; i++) -{ - if (i+1 == numPlayers) + accept = createArea(placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 20)); + + if (accept == null) { - var placer = new PathPlacer(fractionToTiles(playerX[i]), fractionToTiles(playerZ[i]), fractionToTiles(playerX[0]), fractionToTiles(playerZ[0]), scaleByMapSize(12,25), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0); + matrix[possibleEdges[index][0]][possibleEdges[index][1]] = false; + matrix[possibleEdges[index][1]][possibleEdges[index][0]] = false; + possibleEdges.splice(index,1); + continue; } else { - var placer = new PathPlacer(fractionToTiles(playerX[i]), fractionToTiles(playerZ[i]), fractionToTiles(playerX[i+1]), fractionToTiles(playerZ[i+1]), scaleByMapSize(12,25), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0); + placer = new ClumpPlacer(floor(PI*scaleByMapSize(9,15)*scaleByMapSize(9,15)/4), 0.95, 0.6, 10, ix, iz); + var terrainPainter = new LayeredPainter( + [tCliff, tPrimary], // terrains + [3] // widths + ); + var elevationPainter = new SmoothElevationPainter( + ELEVATION_SET, // type + 30, // elevation + 2 // blend radius + ); + createArea(placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 5)); + + placer = new ClumpPlacer(floor(PI*scaleByMapSize(9,15)*scaleByMapSize(9,15)/4), 0.95, 0.6, 10, ix2, iz2); + var terrainPainter = new LayeredPainter( + [tCliff, tPrimary], // terrains + [3] // widths + ); + var elevationPainter = new SmoothElevationPainter( + ELEVATION_SET, // type + 30, // elevation + 2 // blend radius + ); + createArea(placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 5)); } - var terrainPainter = new LayeredPainter( - [tGrass, tGrass], // terrains - [1] // widths - ); - var elevationPainter = new SmoothElevationPainter( - ELEVATION_SET, // type - 3, // elevation - 2 // blend radius - ); - createArea(placer, [terrainPainter, elevationPainter, paintClass(clPass)], null); + + log (possibleEdges[index][0] + ", " + possibleEdges[index][1]); + + for (var i = 0; i < possibleEdges.length; ++i) + { + if (possibleEdges[index][0] != possibleEdges[i][0] && possibleEdges[index][1] != possibleEdges[i][0] && + possibleEdges[index][0] != possibleEdges[i][1] && possibleEdges[index][1] != possibleEdges[i][1]) + { + + if (checkIfIntersect (points[possibleEdges[index][0]][0], points[possibleEdges[index][0]][1], + points[possibleEdges[index][1]][0], points[possibleEdges[index][1]][1], points[possibleEdges[i][0]][0], + points[possibleEdges[i][0]][1], points[possibleEdges[i][1]][0], points[possibleEdges[i][1]][1], scaleByMapSize(9,15) + scaleByMapSize(10,15))) + { + possibleEdges.splice(i,1); + --i; + if (index > i) + --index; + } + } + } + + edgesConncetedToPoints[possibleEdges[index][0]] += 1; + edgesConncetedToPoints[possibleEdges[index][1]] += 1; + + possibleEdges.splice(index,1); } -//create rivers -log ("Creating rivers..."); -for (var m = 0; m < scaleByMapSize(1,3)*randInt(3,4); m++) -{ - var tang = randFloat(0, TWO_PI); - var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05); - var terrainPainter = new LayeredPainter( - [tShore, tWater, tWater], // terrains - [1, 3] // widths - ); - var elevationPainter = new SmoothElevationPainter( - ELEVATION_SET, // type - -4, // elevation - 4 // blend radius - ); - createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 15)); - placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); - var painter = new LayeredPainter([tWater, tWater], [1]); - var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 4); - createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 15)); -} -paintTerrainBasedOnHeight(3.1, 40, 0, tCliff); - -for (var i = 0; i < numPlayers; i++) -{ - if (i+1 == numPlayers) - { - passageMaker(fractionToTiles(playerX[i]), fractionToTiles(playerZ[i]), fractionToTiles(playerX[0]), fractionToTiles(playerZ[0]), 6, -2, -2, 2, undefined ,undefined , -4) - } - else - { - passageMaker(fractionToTiles(playerX[i]), fractionToTiles(playerZ[i]), fractionToTiles(playerX[i+1]), fractionToTiles(playerZ[i+1]), 6, -2, -2, 2,undefined ,undefined , -4) - } -} +paintTerrainBasedOnHeight(3.1, 29, 0, tCliff); +paintTerrainBasedOnHeight(29, 30, 3, tSnowLimited); // create bumps log("Creating bumps..."); @@ -329,22 +460,20 @@ createAreas( // create hills log("Creating hills..."); -placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); -terrainPainter = new LayeredPainter( - [tGrass, tCliff, tGrass], // terrains - [1, 2] // widths +placer = new ClumpPlacer(scaleByMapSize(40, 150), 0.2, 0.1, 1); +var terrainPainter = new LayeredPainter( + [tCliff, tSnowLimited], // terrains + [2] // widths ); -elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 27, 2); +var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 30, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], - avoidClasses(clPlayer, 12, clHill, 15, clWater, 2, clPass, 1), - scaleByMapSize(1, 4) * numPlayers + avoidClasses(clPlayer, 20, clHill, 14), + scaleByMapSize(10, 80) * numPlayers ); - // calculate desired number of trees for map (based on size) - var MIN_TREES = 500; var MAX_TREES = 3000; var P_FOREST = 0.7; @@ -356,12 +485,9 @@ 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, tPrimary, pForest], [tForestFloor, pForest]] ]; // some variation - - var size = numForest / (scaleByMapSize(2,8) * numPlayers); var num = floor(size / types.length); @@ -375,7 +501,7 @@ for (var i = 0; i < types.length; ++i) createAreas( placer, [painter, paintClass(clForest)], - avoidClasses(clPlayer, 12, clForest, 10, clHill, 0, clWater, 2, clPass, 1), + avoidClasses(clPlayer, 12, clForest, 10, clHill, 0, clWater, 2), num ); } @@ -389,8 +515,8 @@ for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new LayeredPainter( - [[tGrass,tGrassA],[tGrassA,tGrassB], [tGrassB,tGrassC]], // terrains - [1,1] // widths + [[tDirt,tHalfSnow], [tHalfSnow,tSnowLimited]], // terrains + [2] // widths ); createAreas( placer, @@ -406,7 +532,7 @@ 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(tGrassB); + painter = new TerrainPainter(tSecondary); createAreas( placer, painter, @@ -480,6 +606,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 +); + // create rabbit log("Creating rabbit..."); group = new SimpleGroup( @@ -491,17 +628,6 @@ createObjectGroups(group, 0, 3 * numPlayers, 50 ); -// create fish -log("Creating fish..."); -group = new SimpleGroup( - [new SimpleObject(oFish, 2,3, 0,2)], - true, clFood -); -createObjectGroups(group, 0, - [avoidClasses(clFood, 20), stayClasses(clWater, 6)], - 11 * numPlayers, 60 -); - RMS.SetProgress(85); @@ -558,17 +684,15 @@ createObjectGroups(group, 0, planetm * scaleByMapSize(13, 200), 50 ); - - -var rt = randInt(1,3) -if (rt==1){ -setSkySet("cirrus"); +random_terrain = randInt(1,3) +if (random_terrain==1){ + setSkySet("cirrus"); } -else if (rt ==2){ -setSkySet("cumulus"); +else if (random_terrain ==2){ + setSkySet("cumulus"); } -else if (rt ==3){ -setSkySet("sunny"); +else if (random_terrain ==3){ + setSkySet("sunny"); } setSunRotation(randFloat(0, TWO_PI)); setSunElevation(randFloat(PI/ 5, PI / 3)); diff --git a/binaries/data/mods/public/maps/random/rmgen/misc.js b/binaries/data/mods/public/maps/random/rmgen/misc.js index 09b3029b5b..32c73b5035 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 doIntersect (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; } 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; } \ 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; } 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; } \ No newline at end of file