Index: ps/trunk/binaries/data/mods/public/maps/random/corsica.json =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/corsica.json (revision 12247) +++ ps/trunk/binaries/data/mods/public/maps/random/corsica.json (revision 12248) @@ -1,13 +1,13 @@ { "settings" : { "Name" : "Corsica vs Sardinia", "Script" : "corsica.js", - "Description" : "The players start on two opposing islands, both with a very jagged relief that will make landing difficult.\n\nThe small and very mountainous island of Corsica has made it a disputed and undisputedly hard to conquer island. Originally occupied by the Torreans, it was later settled by Etruscans, Phocaeans and Syracusans who mainly established ports. Conquered by Carthage, it was taken from them during the first punic war and united in 238 BC with Sardinia to form the \"Corsica et Sardinia\" province. The Corsicans regularly revolted and over the course of a century, the island lost two thirds of its Corsican population.", + "Description" : "The players start on two opposing islands, both with a very jagged relief that will make landing difficult.\n\n\nCorsica is an island in the Mediterranean Sea. It is located west of Italy, southeast of the French mainland, and north of the island of Sardinia. Mountains comprise two-thirds of the island, forming a single chain. Sardinia is the second-largest island in the Mediterranean Sea (after Sicily and before Cyprus). Originally occupied by the Torreans, then marginally settled by Etruscans, Phocaeans and Syracusans. Rome conquered these two islands from Carthage during the first punic war and in 238 BC created the \"Corsica et Sardinia\" province. The Corsicans regularly revolted and over the course of a century, the island lost two thirds of its Corsican population.", "BaseTerrain" : ["medit_dirt", "medit_dirt_b", "medit_dirt_c"], "BaseHeight" : -8, "Keywords": ["naval"], "Preview" : "corsica.png", "CircularMap" : false, "XXXXXX" : "Optionally define other things here, like we would for a scenario" } } \ No newline at end of file Index: ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.json =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.json (nonexistent) +++ ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.json (revision 12248) @@ -0,0 +1,12 @@ +{ + "settings" : { + "Name" : "Pyrenean Sierra", + "Script" : "pyrenean_sierra.js", + "Description" : "High mountains separating the enemies.\n\n\nThe Pyreneans is a great mountain range located between modern France and Spain.", + "BaseTerrain" : ["alpine_dirt_grass_50"], + "BaseHeight" : -100, + "Preview" : "pyrenean_sierra.png", + "CircularMap" : true, + "XXXXXX" : "Optionally define other things here, like we would for a scenario" + } +} \ No newline at end of file Property changes on: ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.json ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.js (nonexistent) +++ ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.js (revision 12248) @@ -0,0 +1,908 @@ +RMS.LoadLibrary("rmgen"); + +// Some functions +// This is the basic SmoothElevationPainter with a random component thrown in. +function SemiRandomElevationPainter(elevation, blendRadius,roughness) +{ + this.elevation = elevation; + this.blendRadius = blendRadius; + if (!roughness) + this.roughness = 5; + else + this.roughness = roughness; +} + +SemiRandomElevationPainter.prototype.checkInArea = function(areaID, x, z) +{ + // Check given tile and its neighbors + return ( + (g_Map.validT(x, z) && g_Map.area[x][z] == areaID) + || (g_Map.validT(x-1, z) && g_Map.area[x-1][z] == areaID) + || (g_Map.validT(x, z-1) && g_Map.area[x][z-1] == areaID) + || (g_Map.validT(x-1, z-1) && g_Map.area[x-1][z-1] == areaID) + ); +}; + +SemiRandomElevationPainter.prototype.paint = function(area) +{ + var pointQ = []; + var pts = area.points; + var heightPts = []; + + var mapSize = getMapSize()+1; + + var saw = new Array(mapSize); + var dist = new Array(mapSize); + var gotHeightPt = new Array(mapSize); + var newHeight = new Array(mapSize); + + // init typed arrays + for (var i = 0; i < mapSize; ++i) + { + saw[i] = new Uint8Array(mapSize); // bool / uint8 + dist[i] = new Uint16Array(mapSize); // uint16 + gotHeightPt[i] = new Uint8Array(mapSize); // bool / uint8 + newHeight[i] = new Float32Array(mapSize); // float32 + } + + var length = pts.length; + var areaID = area.getID(); + + // get a list of all points + for (var i=0; i < length; i++) + { + var x = pts[i].x; + var z = pts[i].z; + + for (var dx=-1; dx <= 2; dx++) + { + var nx = x+dx; + for (var dz=-1; dz <= 2; dz++) + { + var nz = z+dz; + + if (g_Map.validH(nx, nz) && !gotHeightPt[nx][nz]) + { + gotHeightPt[nx][nz] = 1; + heightPts.push(new PointXZ(nx, nz)); + newHeight[nx][nz] = g_Map.height[nx][nz]; + } + } + } + } + + // push edge points + for (var i=0; i < length; i++) + { + var x = pts[i].x; + var z = pts[i].z; + for (var dx=-1; dx <= 2; dx++) + { + var nx = x+dx; + for (var dz=-1; dz <= 2; dz++) + { + var nz = z+dz; + + if (g_Map.validH(nx, nz) && !this.checkInArea(areaID, nx, nz) && !saw[nx][nz]) + { + saw[nx][nz]= 1; + dist[nx][nz] = 0; + pointQ.push(new PointXZ(nx, nz)); + } + } + } + } + + // do BFS inwards to find distances to edge + while(pointQ.length) + { + var pt = pointQ.shift(); + var px = pt.x; + var pz = pt.z; + var d = dist[px][pz]; + + // paint if in area + if (g_Map.validH(px, pz) && this.checkInArea(areaID, px, pz)) + { + if (d <= this.blendRadius) + { + var a = (d-1) / this.blendRadius; + newHeight[px][pz] += a*this.elevation + randFloat(-this.roughness,this.roughness); + } + else + { // also happens when blendRadius == 0 + newHeight[px][pz] += this.elevation + randFloat(-this.roughness,this.roughness); + } + } + // enqueue neighbours + for (var dx=-1; dx <= 1; dx++) + { + var nx = px+dx; + for (var dz=-1; dz <= 1; dz++) + { + var nz = pz+dz; + + if (g_Map.validH(nx, nz) && this.checkInArea(areaID, nx, nz) && !saw[nx][nz]) + { + saw[nx][nz] = 1; + dist[nx][nz] = d+1; + pointQ.push(new PointXZ(nx, nz)); + } + } + } + } + + length = heightPts.length; + + // smooth everything out + for (var i = 0; i < length; ++i) + { + var pt = heightPts[i]; + var px = pt.x; + var pz = pt.z; + + if (this.checkInArea(areaID, px, pz)) + { + var sum = 8 * newHeight[px][pz]; + var count = 8; + + for (var dx=-1; dx <= 1; dx++) + { + var nx = px+dx; + for (var dz=-1; dz <= 1; dz++) + { + var nz = pz+dz; + + if (g_Map.validH(nx, nz)) + { + sum += newHeight[nx][nz]; + count++; + } + } + } + + g_Map.height[px][pz] = sum/count; + } + } +}; + + +TILE_CENTERED_HEIGHT_MAP = true; + +var tGrassSpecific = ["new_alpine_grass_d","new_alpine_grass_d", "new_alpine_grass_e"]; +var tGrass = ["new_alpine_grass_d", "new_alpine_grass_b", "new_alpine_grass_e"]; +var tGrassMidRange = ["new_alpine_grass_b", "alpine_grass_a"]; +var tGrassHighRange = ["new_alpine_grass_a", "alpine_grass_a", "alpine_grass_rocky"]; +var tHighRocks = ["alpine_cliff_b", "alpine_cliff_c","alpine_cliff_c", "alpine_grass_rocky"]; +var tSnowedRocks = ["alpine_cliff_b", "alpine_cliff_snow"]; +var tTopSnow = ["alpine_snow_rocky","alpine_snow_a"]; +var tTopSnowOnly = ["alpine_snow_a"]; + +var tDirtyGrass = ["new_alpine_grass_d","alpine_grass_d","alpine_grass_c", "alpine_grass_b"]; +var tLushGrass = ["new_alpine_grass_a","new_alpine_grass_d"]; + +var tMidRangeCliffs = ["alpine_cliff_b","alpine_cliff_c"]; +var tHighRangeCliffs = ["alpine_mountainside","alpine_cliff_snow" ]; +var tPass = ["alpine_cliff_b", "alpine_cliff_c", "alpine_grass_rocky", "alpine_grass_rocky", "alpine_grass_rocky"]; + +var tSand = ["beach_c", "beach_d"]; +var tWetSand = ["sand_wet_a", "sand_wet_b"]; +var tSandTransition = ["beach_scrub_50_"]; +var tWater = ["sand_wet_a","sand_wet_b","sand_wet_b","sand_wet_b"]; + +var tGrassLandForest = "alpine_forrestfloor"; +var tGrassLandForest2 = "alpine_grass_d"; +var tForestTransition = ["new_alpine_grass_d", "new_alpine_grass_b","alpine_grass_d"]; + +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 tRoad = "new_alpine_citytile"; +var tRoadWild = "new_alpine_citytile"; +var tShore = "alpine_shore_rocks_icy"; + +// gaia entities +var oBeech = "gaia/flora_tree_euro_beech"; +var oPine = "gaia/flora_tree_aleppo_pine"; +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 aRain = "actor|particle/rain_shower.xml"; +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 pForestLand = [tGrassLandForest + TERRAIN_SEPARATOR + oPine,tGrassLandForest + TERRAIN_SEPARATOR + oBeech, + tGrassLandForest2 + TERRAIN_SEPARATOR + oPine,tGrassLandForest2 + TERRAIN_SEPARATOR + oBeech, + tGrassLandForest,tGrassLandForest2,tGrassLandForest2,tGrassLandForest2]; +var pForestLandLight = [tGrassLandForest + TERRAIN_SEPARATOR + oPine,tGrassLandForest + TERRAIN_SEPARATOR + oBeech, + tGrassLandForest2 + TERRAIN_SEPARATOR + oPine,tGrassLandForest2 + TERRAIN_SEPARATOR + oBeech, + tGrassLandForest,tGrassLandForest2,tForestTransition,tGrassLandForest2, + tGrassLandForest,tForestTransition,tGrassLandForest2,tForestTransition, + tGrassLandForest2,tGrassLandForest2,tGrassLandForest2,tGrassLandForest2]; +var pForestLandVeryLight = [ tGrassLandForest2 + TERRAIN_SEPARATOR + oPine,tGrassLandForest2 + TERRAIN_SEPARATOR + oBeech, + tForestTransition,tGrassLandForest2,tForestTransition,tForestTransition,tForestTransition, + tGrassLandForest,tForestTransition,tGrassLandForest2,tForestTransition, + tGrassLandForest2,tGrassLandForest2,tGrassLandForest2,tGrassLandForest2]; +const BUILDING_ANGlE = -PI/4; + +// initialize map + +log("Initializing map..."); + +InitMap(); + +var numPlayers = getNumPlayers(); +var mapSize = getMapSize(); +var mapArea = mapSize*mapSize; + +// create tile classes + +var clDirt = createTileClass(); +var clLush = createTileClass(); +var clRock = createTileClass(); +var clMetal = createTileClass(); +var clFood = createTileClass(); +var clBaseResource = createTileClass(); +var clSettlement = createTileClass(); +var clPass = createTileClass(); +var clPyrenneans = createTileClass(); +var clPass = createTileClass(); +var clPlayer = createTileClass(); +var clHill = createTileClass(); +var clForest = createTileClass(); +var clWater = createTileClass(); + +// Initial Terrain Creation +// I'll use very basic noised sinusoidal functions to give the terrain a way aspect +// It looks like we can't go higher than ≈ 75. Given this I'll lower the ground + +var baseHeight = -6; +setWaterHeight(8); + +// let's choose the angle of the pyreneans +var MoutainAngle = randFloat(0,TWO_PI); +var lololo = randFloat(-PI/12,-PI/12); // used by oceans + +var baseHeights = []; +for (var ix = 0; ix < mapSize; ix++) +{ + baseHeights.push([]); + for (var iz = 0; iz < mapSize; iz++) + { + if (g_Map.validT(ix,iz) && !checkIfInClass(ix,iz,clWater)) { + placeTerrain(ix, iz, tGrass); + setHeight(ix,iz,baseHeight +randFloat(-1,1) + scaleByMapSize(1,3)*(cos(ix/scaleByMapSize(5,30))+sin(iz/scaleByMapSize(5,30)))); + baseHeights[ix].push( baseHeight +randFloat(-1,1) + scaleByMapSize(1,3)*(cos(ix/scaleByMapSize(5,30))+sin(iz/scaleByMapSize(5,30))) ); + } else + baseHeights[ix].push(-100); + } +} + + +// randomize player order +var playerIDs = []; +for (var i = 0; i < numPlayers; i++) +{ + playerIDs.push(i+1); +} +playerIDs = primeSortPlayers(sortPlayers(playerIDs)); + +// place players +// TODO: sort players by team + +var playerX = new Array(numPlayers); +var playerZ = new Array(numPlayers); +var playerAngle = new Array(numPlayers); + +for (var i = 0; i < numPlayers; i++) +{ + if ( i%2 == 1) + playerAngle[i] = MoutainAngle+lololo + PI/2 + i/numPlayers*(PI/3) + (1-i/numPlayers)*(-PI/3); + else + playerAngle[i] = MoutainAngle + lololo - PI/2 + (i+1)/numPlayers*(PI/3) + (1-(i+1)/numPlayers)*(-PI/3); + playerX[i] = 0.5 + 0.35*cos(playerAngle[i]); + playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]); +} + +for (var i = 0; i < numPlayers; i++) +{ + var id = playerIDs[i]; + log("Creating base for player " + id + "..."); + + // some constants + var radius = scaleByMapSize(15,25); + var cliffRadius = 2; + var elevation = 20; + + // get the x and z in tiles + var fx = fractionToTiles(playerX[i]); + var fz = fractionToTiles(playerZ[i]); + ix = round(fx); + iz = round(fz); + addToClass(ix, iz, clPlayer); + addToClass(ix+5, iz, clPlayer); + addToClass(ix, iz+5, clPlayer); + addToClass(ix-5, iz, clPlayer); + addToClass(ix, iz-5, clPlayer); + + // create the city patch + var cityRadius = radius/3; + var placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); + var painter = new LayeredPainter([tRoadWild, tRoad], [1]); + createArea(placer, painter, null); + + // create starting units + placeCivDefaultEntities(fx, fz, id, BUILDING_ANGlE); + + // create animals + for (var j = 0; j < 2; ++j) + { + var aAngle = randFloat(0, TWO_PI); + var aDist = 7; + var aX = round(fx + aDist * cos(aAngle)); + var aZ = round(fz + aDist * sin(aAngle)); + var group = new SimpleGroup( + [new SimpleObject(oChicken, 5,5, 0,3)], + true, clBaseResource, aX, aZ + ); + createObjectGroup(group, 0); + } + + // create berry bushes + var bbAngle = randFloat(0, TWO_PI); + var bbDist = 12; + var bbX = round(fx + bbDist * cos(bbAngle)); + var bbZ = round(fz + bbDist * sin(bbAngle)); + group = new SimpleGroup( + [new SimpleObject(oBerryBush, 5,5, 0,3)], + true, clBaseResource, bbX, bbZ + ); + createObjectGroup(group, 0); + + // create metal mine + var mAngle = bbAngle; + while(abs(mAngle - bbAngle) < PI/3) + { + mAngle = randFloat(0, TWO_PI); + } + var mDist = 12; + var mX = round(fx + mDist * cos(mAngle)); + var mZ = round(fz + mDist * sin(mAngle)); + group = new SimpleGroup( + [new SimpleObject(oMetalLarge, 1,1, 0,0)], + true, clBaseResource, mX, mZ + ); + createObjectGroup(group, 0); + + // create stone mines + mAngle += randFloat(PI/8, PI/4); + mX = round(fx + mDist * cos(mAngle)); + mZ = round(fz + mDist * sin(mAngle)); + group = new SimpleGroup( + [new SimpleObject(oStoneLarge, 1,1, 0,2)], + true, clBaseResource, mX, mZ + ); + createObjectGroup(group, 0); + var hillSize = PI * radius * radius; + // create starting trees + var num = floor(hillSize / 100); + var tAngle = randFloat(-PI/3, 4*PI/3); + var tDist = randFloat(11, 13); + var tX = round(fx + tDist * cos(tAngle)); + var tZ = round(fz + tDist * sin(tAngle)); + group = new SimpleGroup( + [new SimpleObject(oPine, num, num, 0,5)], + false, clBaseResource, tX, tZ + ); + createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); + + // create grass tufts + var num = hillSize / 250; + for (var j = 0; j < num; j++) + { + var gAngle = randFloat(0, TWO_PI); + var gDist = radius - (5 + randInt(7)); + var gX = round(fx + gDist * cos(gAngle)); + var gZ = round(fz + gDist * sin(gAngle)); + group = new SimpleGroup( + [new SimpleObject(aGrassShort, 2,5, 0,1, -PI/8,PI/8)], + false, clBaseResource, gX, gZ + ); + createObjectGroup(group, 0); + } +} +RMS.SetProgress(30); + +log ("Creating the pyreneans..."); + +// This is the basic orientation of the pyreneans +var MountainStartX = fractionToTiles(0.5) + cos(MoutainAngle)*fractionToTiles(0.34); +var MountainStartZ = fractionToTiles(0.5) + sin(MoutainAngle)*fractionToTiles(0.34); +var MountainEndX = fractionToTiles(0.5) - cos(MoutainAngle)*fractionToTiles(0.34); +var MountainEndZ = fractionToTiles(0.5) - sin(MoutainAngle)*fractionToTiles(0.34); +var MountainHeight = scaleByMapSize(50,65); +// Number of peaks +var NumOfIterations = scaleByMapSize(100,1000); + +var randomNess = randFloat(-scaleByMapSize(1,12),scaleByMapSize(1,12)); + +for (var i = 0; i < NumOfIterations; i++) +{ + RMS.SetProgress(45 * i/NumOfIterations + 30 * (1-i/NumOfIterations)); + + var position = i/NumOfIterations; + var width = scaleByMapSize(15,55); + + var randHeight2 = randFloat(0,10) + MountainHeight; + + for (var dist = 0; dist < width*3; dist++) + { + var okDist = dist/3; + var S1x = round((MountainStartX * (1-position) + MountainEndX*position) + randomNess*cos(position*3.14*4) + cos(MoutainAngle+PI/2)*okDist); + var S1z = round((MountainStartZ * (1-position) + MountainEndZ*position) + randomNess*sin(position*3.14*4) + sin(MoutainAngle+PI/2)*okDist); + var S2x = round((MountainStartX * (1-position) + MountainEndX*position) + randomNess*cos(position*3.14*4) + cos(MoutainAngle-PI/2)*okDist); + var S2z = round((MountainStartZ * (1-position) + MountainEndZ*position) + randomNess*sin(position*3.14*4) + sin(MoutainAngle-PI/2)*okDist); + + // complicated sigmoid + // Ranges is 0-1, FormX is 0-1 too. + var FormX = (-2*(1-okDist/width)+1.9) - 4*(2*(1-okDist/width)-randFloat(0.9,1.1))*(2*(1-okDist/width)-randFloat(0.9,1.1))*(2*(1-okDist/width)-randFloat(0.9,1.1)); + var Formula = (1/(1 + Math.exp(FormX))); + + // If we're too far from the border, we flatten + Formula *= (0.2 - Math.max(0,abs(0.5 - position) - 0.3)) * 5; + + var randHeight = randFloat(-9,9) * Formula; + + var height = baseHeights[S1x][S1z]; + setHeight(S1x,S1z, height + randHeight2 * Formula + randHeight ); + var height = baseHeights[S2x][S2z]; + setHeight(S2x,S2z, height + randHeight2 * Formula + randHeight ); + if (getHeight(S1x,S1z) > 15) + addToClass(S1x,S1z, clPyrenneans); + if (getHeight(S2x,S2z) > 15) + addToClass(S2x,S2z, clPyrenneans); + } +} +// Allright now slight smoothing (decreasing with height) +for (var ix = 1; ix < mapSize-1; ix++) +{ + for (var iz = 1; iz < mapSize-1; iz++) + { + if (g_Map.validT(ix,iz) && checkIfInClass(ix,iz,clPyrenneans) ) { + var NB = getNeighborsHeight(ix,iz); + var index = 9/(1 + Math.max(0,getHeight(ix,iz)/7)); + setHeight(ix,iz, (getHeight(ix,iz)*(9-index) + NB*index)/9 ); + } + } +} +RMS.SetProgress(48); + +// Okay so the mountains are pretty much here. +// Making the passes + +var passWidth = scaleByMapSize(15,100) /1.8; +var S1x = round((MountainStartX * (0.35) + MountainEndX*0.65) + cos(MoutainAngle+PI/2)*passWidth); +var S1z = round((MountainStartZ * (0.35) + MountainEndZ*0.65) + sin(MoutainAngle+PI/2)*passWidth); +var S2x = round((MountainStartX * (0.35) + MountainEndX*0.65) + cos(MoutainAngle-PI/2)*passWidth); +var S2z = round((MountainStartZ * (0.35) + MountainEndZ*0.65) + sin(MoutainAngle-PI/2)*passWidth); +PassMaker(S1x, S1z, S2x, S2z, 4, 7, (getHeight(S1x,S1z) + getHeight(S2x,S2z))/2.0, MountainHeight-25, 2, clPass); + +S1x = round((MountainStartX * (0.65) + MountainEndX*0.35) + cos(MoutainAngle+PI/2)*passWidth); +S1z = round((MountainStartZ * (0.65) + MountainEndZ*0.35) + sin(MoutainAngle+PI/2)*passWidth); +S2x = round((MountainStartX * (0.65) + MountainEndX*0.35) + cos(MoutainAngle-PI/2)*passWidth); +S2z = round((MountainStartZ * (0.65) + MountainEndZ*0.35) + sin(MoutainAngle-PI/2)*passWidth); +PassMaker(S1x, S1z, S2x, S2z, 4, 7, (getHeight(S1x,S1z) + getHeight(S2x,S2z))/2.0, MountainHeight-25, 2, clPass); + +RMS.SetProgress(50); + +// Smoothing the mountains +for (var ix = 1; ix < mapSize-1; ix++) +{ + for (var iz = 1; iz < mapSize-1; iz++) + { + if ( g_Map.validT(ix,iz) && checkIfInClass(ix,iz,clPyrenneans) ) { + var NB = getNeighborsHeight(ix,iz); + var index = 9/(1 + Math.max(0,(getHeight(ix,iz)-10)/7)); + setHeight(ix,iz, (getHeight(ix,iz)*(9-index) + NB*index)/9 ); + baseHeights[ix][iz] = (getHeight(ix,iz)*(9-index) + NB*index)/9; + } + } +} + +log ("creating Oceans"); +// ALlright for hacky reasons I can't use a smooth Elevation Painter, that wouldn't work. +// I'll use a harsh one, and then smooth it out +var OceanX = fractionToTiles(0.5) + cos(MoutainAngle + lololo)*fractionToTiles(0.48); +var OceanZ = fractionToTiles(0.5) + sin(MoutainAngle + lololo)*fractionToTiles(0.48); + +var radius = fractionToTiles(0.18); +var size = radius*radius*PI; +var placer = new ClumpPlacer(size, 0.9, 0.05, 10, OceanX, OceanZ); +var elevationPainter = new ElevationPainter(-22); +createArea(placer, [paintClass(clWater),elevationPainter], null); + +OceanX = fractionToTiles(0.5) + cos(PI + MoutainAngle + lololo)*fractionToTiles(0.48); +OceanZ = fractionToTiles(0.5) + sin(PI + MoutainAngle + lololo)*fractionToTiles(0.48); + +radius = fractionToTiles(0.18); +size = radius*radius*PI; +placer = new ClumpPlacer(size, 0.9, 0.05, 10, OceanX, OceanZ); +elevationPainter = new ElevationPainter(-22); +createArea(placer, [paintClass(clWater),elevationPainter], null); + +// Smoothing around the water, then going a bit random +for (var ix = 1; ix < mapSize-1; ix++) +{ + for (var iz = 1; iz < mapSize-1; iz++) + { + if ( g_Map.validT(ix,iz) && getTileClass(clWater).countInRadius(ix,iz,5,true) > 0 ) { + // Allright smoothing + // I'll have to hack again. + + var averageHeight = 0; + var size = 5; + if (getTileClass(clPyrenneans).countInRadius(ix,iz,1,true) > 0) + size = 1; + else if (getTileClass(clPyrenneans).countInRadius(ix,iz,2,true) > 0) + size = 2; + else if (getTileClass(clPyrenneans).countInRadius(ix,iz,3,true) > 0) + size = 3; + else if (getTileClass(clPyrenneans).countInRadius(ix,iz,4,true) > 0) + size = 4; + var todivide = 0; + for (var xx = -size; xx <= size;xx++) + for (var yy = -size; yy <= size;yy++) { + if (g_Map.validT(ix + xx,iz + yy) && (xx != 0 || yy != 0)){ + averageHeight += getHeight(ix + xx,iz + yy) / (abs(xx)+abs(yy)); + todivide += 1/(abs(xx)+abs(yy)); + } + } + averageHeight += getHeight(ix,iz)*2; + averageHeight /= (todivide+2); + + setHeight(ix,iz, averageHeight ); + //baseHeights[ix][iz] = averageHeight; + } + if ( g_Map.validT(ix,iz) && getTileClass(clWater).countInRadius(ix,iz,4,true) > 0 && getTileClass(clWater).countInRadius(ix,iz,4) > 0 ) + setHeight(ix,iz, getHeight(ix,iz) + randFloat(-1,1)); + } +} +RMS.SetProgress(55); + +//create hills +log ("Creating hills..."); +placer = new ClumpPlacer(scaleByMapSize(60, 120), 0.3, 0.06, 5); +painter = new SemiRandomElevationPainter(7, 4,1); +var terrainPainter = new TerrainPainter(tGrassSpecific); +createAreas( placer, [painter,terrainPainter, paintClass(clHill)], avoidClasses(clWater, 5, clPlayer, 10, clBaseResource, 6, clPyrenneans, 2), scaleByMapSize(5, 35) ); + + +// create forests +log("Creating forests..."); +var types = [ [tForestTransition,pForestLandVeryLight, pForestLandLight, pForestLand]]; +var size = scaleByMapSize(40,115)*PI; +var num = floor(scaleByMapSize(8,40) / types.length); +for (var i = 0; i < types.length; ++i) +{ + placer = new ClumpPlacer(size, 0.2, 0.1, 1); + painter = new LayeredPainter( types[i], [scaleByMapSize(1,2),scaleByMapSize(3,6),scaleByMapSize(3,6)] ); + createAreas( placer, [painter, paintClass(clForest)], avoidClasses(clPlayer, 12, clPyrenneans,0, clForest, 7, clWater, 2), num); +} +RMS.SetProgress(60); + +log("Creating lone trees..."); +var num = scaleByMapSize(80,400); + +var group = new SimpleGroup([new SimpleObject(oPine, 1,2, 1,3),new SimpleObject(oBeech, 1,2, 1,3)], true, clForest); +createObjectGroups(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 8,clPyrenneans, 1), num, 20 ); + +// Painting +log("Painting the map"); + +var terrainGrass = createTerrain(tGrass); +var terrainGrassMidRange = createTerrain(tGrassMidRange); +var terrainGrassHighRange = createTerrain(tGrassHighRange); +var terrainRocks = createTerrain(tHighRocks); +var terrainRocksSnow = createTerrain(tSnowedRocks); +var terrainTopSnow = createTerrain(tTopSnow); +var terrainTopSnowOnly = createTerrain(tTopSnowOnly); +var terrainMidRangeCliff = createTerrain(tMidRangeCliffs); +var terrainHighRangeCliff = createTerrain(tHighRangeCliffs); +var terrainPass = createTerrain(tPass); +var terrainSand = createTerrain(tSand); +var terrainWetSand = createTerrain(tWetSand); +var terrainSandTransition = createTerrain(tSandTransition); +var terrainWater = createTerrain(tWater); +/* +// first pass: who's water? +for (var sandx = 0; sandx < mapSize; sandx++) +for (var sandz = 0; sandz < mapSize; sandz++) +if (getHeight(sandx,sandz) < 0) +addToClass(sandx,sandz,clWater); +*/ +// second pass: who's not water +for (var x = 0; x < mapSize; x++) { + for (var z = 0; z < mapSize; z++) { + var height = getHeight(x,z); + var heightDiff = getHeightDifference(x,z); + if (getTileClass(clPyrenneans).countInRadius(x,z,2,true) > 0) { + if (height < 6) { + if (heightDiff < 5) + terrainGrass.place(x,z); + else + terrainMidRangeCliff.place(x,z); + } else if (height >= 6 && height < 18) { + if (heightDiff < 8) + terrainGrassMidRange.place(x,z); + else + terrainMidRangeCliff.place(x,z); + } else if (height >= 18 && height < 30) { + if (heightDiff < 8) + terrainGrassHighRange.place(x,z); + else + terrainMidRangeCliff.place(x,z); + } else if (height >= 30 && height < MountainHeight-20) { + if (heightDiff < 8) + terrainRocks.place(x,z); + else + terrainHighRangeCliff.place(x,z); + } else if (height >= MountainHeight-20 && height < MountainHeight-10) { + if (heightDiff < 7) + terrainRocksSnow.place(x,z); + else + terrainHighRangeCliff.place(x,z); + } else if (height >= MountainHeight-10) { + if (heightDiff < 6) + terrainTopSnowOnly.place(x,z); + else + terrainTopSnow.place(x,z); + } + if (height >= 30 && getTileClass(clPass).countInRadius(x,z,2,true) > 0) + if (heightDiff < 5) + terrainPass.place(x,z); + } + if (height > -14 && height <= -2 && getTileClass(clWater).countInRadius(x,z,2,true) > 0) { + if (heightDiff < 2.5) + terrainSand.place(x,z); + else + terrainMidRangeCliff.place(x,z); + } else if (height > -14 && height <= 0 && getTileClass(clWater).countInRadius(x,z,3,true) > 0) { + if (heightDiff < 2.5) + terrainSandTransition.place(x,z); + else + terrainMidRangeCliff.place(x,z); + } else if (height <= -14) { + terrainWater.place(x,z); + } + } +} +// create dirt patches +log("Creating dirt patches..."); +var sizes = [scaleByMapSize(3, 20), scaleByMapSize(5, 40), scaleByMapSize(8, 60)]; +for (var i = 0; i < sizes.length; i++) +{ + placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); + painter = new TerrainPainter(tDirtyGrass); + createAreas( placer, [painter, paintClass(clDirt)], avoidClasses(clWater, 3, clForest, 0, clPyrenneans,5, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45) ); +} + +// create grass patches +log("Creating grass patches..."); +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(tLushGrass); + createAreas( placer, [painter,paintClass(clLush)], avoidClasses(clWater, 3, clForest, 0, clPyrenneans,5, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45) ); +} + + +RMS.SetProgress(70); + +// making more in dirt areas so as to appear different +log("Creating small grass tufts..."); +var group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); +createObjectGroups(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0, clPyrenneans,2), scaleByMapSize(13, 200) ); +createObjectGroups(group, 0, stayClasses(clDirt,1), scaleByMapSize(13, 200),10); + +log("Creating large grass tufts..."); +group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)] ); +createObjectGroups(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0, clPyrenneans,2), scaleByMapSize(13, 200) ); +createObjectGroups(group, 0, stayClasses(clDirt,1), scaleByMapSize(13, 200),10); +RMS.SetProgress(75); + +// create bushes +log("Creating bushes..."); +group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); +createObjectGroups(group, 0, avoidClasses(clWater, 2, clPlayer, 1, clPyrenneans, 1), scaleByMapSize(13, 200), 50 ); + +RMS.SetProgress(80); + +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(clWater, 3, clForest, 1, clPlayer, 10, clRock, 8, clPyrenneans, 1), scaleByMapSize(4,16), 100 ); + +// create small stone quarries +group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); +createObjectGroups(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 10, clRock, 8, clPyrenneans, 1), scaleByMapSize(4,16), 100 ); + +log("Creating metal mines..."); +group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); +createObjectGroups(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 10, clMetal, 8, clRock, 5, clPyrenneans, 1), scaleByMapSize(4,16), 100 ); + +RMS.SetProgress(85); + +log("Creating small decorative rocks..."); +group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); +createObjectGroups( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0), scaleByMapSize(16, 262), 50 ); + +log("Creating large decorative rocks..."); +group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); +createObjectGroups( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0), scaleByMapSize(8, 131), 50 ); + +RMS.SetProgress(90); + +log("Creating deer..."); +group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); +createObjectGroups(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 10, clPyrenneans, 1, clFood, 15), 3 * numPlayers, 50 ); + +log("Creating rabbit..."); +group = new SimpleGroup( [new SimpleObject(oRabbit, 2,3, 0,2)], true, clFood ); +createObjectGroups(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 10, clPyrenneans, 1, clFood,15), 3 * numPlayers, 50 ); + +log("Creating fish..."); +group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); +createObjectGroups(group, 0, [avoidClasses(clFood, 15), stayClasses(clWater, 6)], 20 * numPlayers, 60 ); + + +setSunElevation(randFloat(PI/5, PI / 3)); +setSunRotation(randFloat(0, TWO_PI)); +setWaterTint(0.1, 0.1, 0.3); // muddy brown +setWaterReflectionTint(0.2, 0.2, 0.5); // muddy brown +setWaterMurkiness(0.8); +setWaterReflectionTintStrength(0.3); + +//var rt = randInt(1,6); +//if (rt==1){ +// setSkySet("stormy"); +// setSunColour(0.36,0.38,0.45); +// setTerrainAmbientColour(0.52,0.575,0.6); +// setUnitsAmbientColour(0.52,0.575,0.6); +// setSunElevation(PI/7); + +// setWaterTint(0.1, 0.1, 0.2); // muddy brown +//} else { + setSkySet("cumulus"); + setSunColour(0.73,0.73,0.65); + setTerrainAmbientColour(0.45,0.45,0.50); + setUnitsAmbientColour(0.4,0.4,0.4); + setWaterTint(0.15, 0.15, 0.3); // muddy brown + setWaterReflectionTintStrength(0.15); +//} + +// Export map data + +ExportMap(); + + +function getNeighborsHeight(x1, z1) +{ + var toCheck = [ [-1,-1], [-1,0], [-1,1], [0,1], [1,1], [1,0], [1,-1], [0,-1] ]; + var height = 0; + for (i in toCheck) { + var xx = x1 + toCheck[i][0]; + var zz = z1 + toCheck[i][1]; + height += getHeight(round(xx),round(zz)); + } + height /= 8; + return height; +} +// Taken from Corsica vs Sardinia with tweaks +function PassMaker(x1, z1, x2, z2, startWidth, centerWidth, startElevation, centerElevation, smooth, tileclass, terrain) +{ + var mapSize = g_Map.size; + var stepNB = sqrt((x2-x1)*(x2-x1) + (z2-z1)*(z2-z1)) + 2; + + var startHeight = startElevation; + var finishHeight = centerElevation; + + for (var step = 0; step <= stepNB; step+=0.5) + { + var ix = ((stepNB-step)*x1 + x2*step) / stepNB; + var iz = ((stepNB-step)*z1 + z2*step) / stepNB; + + var width = (abs(step - stepNB/2.0) *startWidth + (stepNB/2 - abs(step - stepNB/2.0)) * centerWidth ) / (stepNB/2); + + + var oldDirection = [x2-x1, z2-z1]; + // let's get the perpendicular direction + var direction = [ -oldDirection[1],oldDirection[0] ]; + if (abs(direction[0]) > abs(direction[1])) + { + direction[1] = direction[1] / abs(direction[0]); + if (direction[0] > 0) + direction[0] = 1; + else + direction[0] = -1; + } else { + direction[0] = direction[0] / abs(direction[1]); + if (direction[1] > 0) + direction[1] = 1; + else + direction[1] = -1; + } + for (var po = -Math.floor(width/2.0); po <= Math.floor(width/2.0); po+=0.5) + { + var rx = po*direction[0]; + var rz = po*direction[1]; + + var relativeWidth = abs(po / Math.floor(width/2)); + var targetHeight = (abs(step - stepNB/2.0) *startHeight + (stepNB/2 - abs(step - stepNB/2.0)) * finishHeight ) / (stepNB/2); + if (round(ix + rx) < mapSize && round(iz + rz) < mapSize && round(ix + rx) >= 0 && round(iz + rz) >= 0) + { + // smoothing the sides + if ( abs(abs(po) - abs(Math.floor(width/2.0))) < smooth) + { + var localHeight = getHeight(round(ix + rx), round(iz + rz)); + var localPart = smooth - abs(abs(po) - abs(Math.floor(width/2.0))); + var targetHeight = (localHeight * localPart + targetHeight * (1/localPart) )/ (localPart + 1/localPart); + } + + g_Map.setHeight(round(ix + rx), round(iz + rz), targetHeight); + if (tileclass != null) + addToClass(round(ix + rx), round(iz + rz), tileclass); + if (terrain != null) + placeTerrain(round(ix + rx), round(iz + rz), terrain); + } + } + } +} +// no need for preliminary rounding +function getHeightDifference(x1, z1) +{ + x1 = round(x1); + z1 = round(z1); + var height = getHeight(x1,z1); + + if (!g_Map.validT(x1,z1)) + return 0; + // I wanna store the height difference with any neighbor + + var toCheck = [ [-1,-1], [-1,0], [-1,1], [0,1], [1,1], [1,0], [1,-1], [0,-1] ]; + + var diff = 0; + var todiv = 0; + for (i in toCheck) { + var xx = round(x1 + toCheck[i][0]); + var zz = round(z1 + toCheck[i][1]); + if (g_Map.validT(xx,zz)) { + diff += abs(getHeight(xx,zz) - height); + todiv++; + } + } + if (todiv > 0) + diff /= todiv; + return diff; +} + + Property changes on: ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.js ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/art/textures/ui/session/icons/mappreview/pyrenean_sierra.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/binaries/data/mods/public/art/textures/ui/session/icons/mappreview/pyrenean_sierra.png =================================================================== --- ps/trunk/binaries/data/mods/public/art/textures/ui/session/icons/mappreview/pyrenean_sierra.png (nonexistent) +++ ps/trunk/binaries/data/mods/public/art/textures/ui/session/icons/mappreview/pyrenean_sierra.png (revision 12248) Property changes on: ps/trunk/binaries/data/mods/public/art/textures/ui/session/icons/mappreview/pyrenean_sierra.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property