Ticket #658: RMS_JS_Implementation.2.patch
File RMS_JS_Implementation.2.patch, 145.9 KB (added by , 13 years ago) |
---|
-
binaries/data/mods/public/gui/gamesetup/gamesetup.js
75 75 76 76 // Init map types 77 77 var mapTypes = getGUIObjectByName("mapTypeSelection"); 78 mapTypes.list = ["Scenario" ]; // TODO: May offer saved game type for multiplayer games?79 mapTypes.list_data = ["scenario" ];78 mapTypes.list = ["Scenario", "Random"]; // TODO: May offer saved game type for multiplayer games? 79 mapTypes.list_data = ["scenario", "random"]; 80 80 81 81 // Setup controls for host only 82 82 if (g_IsController) -
binaries/data/mods/public/maps/mapgen/area.js
1 function Area(points) 2 { 3 this.points = (points !== undefined ? points : []); 4 } -
binaries/data/mods/public/maps/mapgen/constraint.js
1 2 /////////////////////////////////////////////////////////////////////////// 3 // NullConstraints: No constraint - always return true 4 /////////////////////////////////////////////////////////////////////////// 5 function NullConstraint() {} 6 7 NullConstraint.prototype.allows = function(x, y) 8 { 9 return true; 10 }; 11 12 /////////////////////////////////////////////////////////////////////////// 13 // AndConstraints: Check multiple constraints 14 /////////////////////////////////////////////////////////////////////////// 15 function AndConstraint(constraints) 16 { 17 this.constraints = constraints; 18 } 19 20 AndConstraint.prototype.allows = function(x, y) 21 { 22 for (var i=0; i < this.constraints.length; ++i) 23 { 24 if (!this.constraints[i].allows(x, y)) 25 return false; 26 } 27 28 return true; 29 }; 30 31 /////////////////////////////////////////////////////////////////////////// 32 // AvoidAreaConstraint 33 /////////////////////////////////////////////////////////////////////////// 34 function AvoidAreaConstraint(area) 35 { 36 this.area = area; 37 } 38 39 AvoidAreaConstraint.prototype.allows = function(x, y) 40 { 41 return g_Map.area[x][y] != this.area; 42 }; 43 44 /////////////////////////////////////////////////////////////////////////// 45 // AvoidTextureConstraint 46 /////////////////////////////////////////////////////////////////////////// 47 function AvoidTextureConstraint(textureID) 48 { 49 this.textureID = textureID; 50 } 51 52 AvoidTextureConstraint.prototype.allows = function(x, y) 53 { 54 return g_Map.texture[x][y] != this.textureID; 55 }; 56 57 /////////////////////////////////////////////////////////////////////////// 58 // AvoidTileClassConstraint 59 /////////////////////////////////////////////////////////////////////////// 60 function AvoidTileClassConstraint(tileClassID, distance) 61 { 62 this.tileClass = getTileClass(tileClassID); 63 this.distance = distance; 64 } 65 66 AvoidTileClassConstraint.prototype.allows = function(x, y) 67 { 68 return this.tileClass.countMembersInRadius(x, y, this.distance) == 0; 69 }; 70 71 /////////////////////////////////////////////////////////////////////////// 72 // StayInTileClassConstraint 73 /////////////////////////////////////////////////////////////////////////// 74 function StayInTileClassConstraint(tileClassID, distance) 75 { 76 this.tileClass = getTileClass(tileClassID); 77 this.distance = distance; 78 } 79 80 StayInTileClassConstraint.prototype.allows = function(x, y) 81 { 82 return this.tileClass.countNonMembersInRadius(x, y, this.distance) == 0; 83 }; 84 85 /////////////////////////////////////////////////////////////////////////// 86 // BorderTileClassConstraint 87 /////////////////////////////////////////////////////////////////////////// 88 function BorderTileClassConstraint(tileClassID, distanceInside, distanceOutside) 89 { 90 this.tileClass = getTileClass(tileClassID); 91 this.distanceInside = distanceInside; 92 this.distanceOutside = distanceOutside; 93 } 94 95 BorderTileClassConstraint.prototype.allows = function(x, y) 96 { 97 return (this.tileClass.countMembersInRadius(x, y, this.distanceOutside) > 0 98 && this.tileClass.countNonMembersInRadius(x, y, this.distanceInside) > 0); 99 }; -
binaries/data/mods/public/maps/mapgen/library.js
1 2 // PI 3 const PI = Math.PI; 4 5 const SEA_LEVEL = 20.0; 6 7 const TERRAIN_SEPARATOR = "|"; 8 9 const TILES_PER_PATCH = 16; 10 11 ///////////////////////////////////////////////////////////////////////////////////////////// 12 // Utility functions 13 ///////////////////////////////////////////////////////////////////////////////////////////// 14 15 function fractionToTiles(f) { 16 return getMapSize() * f; 17 } 18 19 function tilesToFraction(t) { 20 return t / getMapSize(); 21 } 22 23 function fractionToSize(f) { 24 return getMapSize() * getMapSize() * f; 25 } 26 27 function sizeToFraction(s) { 28 return s / getMapSize() / getMapSize(); 29 } 30 31 function cos(x) { 32 return Math.cos(x); 33 } 34 35 function sin(x) { 36 return Math.sin(x); 37 } 38 39 function tan(x) { 40 return Math.tan(x); 41 } 42 43 function abs(x) { 44 return Math.abs(x); 45 } 46 47 function round(x) { 48 return Math.round(x); 49 } 50 51 function lerp(a, b, t) { 52 return a + (b-a) * t; 53 } 54 55 function sqrt(x) { 56 return Math.sqrt(x); 57 } 58 59 function ceil(x) { 60 return Math.ceil(x); 61 } 62 63 function floor(x) { 64 return Math.floor(x); 65 } 66 67 function max(x, y) { 68 return x > y ? x : y; 69 } 70 71 function min(x, y) { 72 return x < y ? x : y; 73 } 74 75 function println(x) { 76 print(x); 77 print("\n"); 78 } 79 80 function argsToArray(x) { 81 if (x.length!=1) { 82 var ret = new Array(); 83 for (var i=0; i<x.length; i++) { 84 ret[i] = x[i]; 85 } 86 return ret; 87 } 88 else { 89 return x[0]; 90 } 91 } 92 93 function chooseRand() { 94 if (arguments.length==0) { 95 error("chooseRand: requires at least 1 argument"); 96 } 97 var ar = argsToArray(arguments); 98 return ar[randInt(ar.length)]; 99 } 100 101 function createAreas(centeredPlacer, painter, constraint, num, retryFactor) 102 { 103 if (retryFactor === undefined) 104 retryFactor = 10; 105 106 var maxFail = num * retryFactor; 107 var good = 0; 108 var bad = 0; 109 var ret = []; 110 while(good < num && bad <= maxFail) 111 { 112 centeredPlacer.x = randInt(getMapSize()); 113 centeredPlacer.y = randInt(getMapSize()); 114 var r = g_Map.createArea(centeredPlacer, painter, constraint); 115 if (r !== undefined) 116 { 117 good++; 118 ret.push(r); 119 } 120 else 121 { 122 bad++; 123 } 124 } 125 126 return ret; 127 } 128 129 function createObjectGroups(placer, player, constraint, num, retryFactor) 130 { 131 if (retryFactor === undefined) 132 retryFactor = 10; 133 134 var maxFail = num * retryFactor; 135 var good = 0; 136 var bad = 0; 137 while(good < num && bad <= maxFail) 138 { 139 placer.x = randInt(getMapSize()); 140 placer.y = randInt(getMapSize()); 141 var r = createObjectGroup(placer, player, constraint); 142 143 if (r !== undefined) 144 { 145 good++; 146 } 147 else 148 { 149 bad++; 150 } 151 } 152 return good; 153 } 154 155 function createTerrain(terrain) 156 { 157 if (terrain instanceof Array) 158 { 159 var terrainList = []; 160 161 for (var i = 0; i < terrain.length; ++i) 162 terrainList.push(createTerrain(terrain[i])); 163 164 return new RandomTerrain(terrainList); 165 } 166 else 167 { 168 return createSimpleTerrain(terrain); 169 } 170 } 171 172 function createSimpleTerrain(terrain) 173 { 174 if (typeof(terrain) == "string") 175 { // Split string by pipe | character, this allows specifying terrain + tree type in single string 176 var params = terrain.split(TERRAIN_SEPARATOR, 2); 177 178 if (params.length != 2) 179 { 180 return new SimpleTerrain(terrain); 181 } 182 else 183 { 184 return new SimpleTerrain(params[0], params[1]); 185 } 186 } 187 else 188 { 189 error("createSimpleTerrain expects string as input, received "+terrain); 190 return undefined; 191 } 192 } 193 194 function placeObject(type, player, x, y, angle) 195 { 196 g_Map.addObjects(new Entity(type, player, x, y, angle)); 197 } 198 199 function placeTerrain(x, y, terrain) 200 { 201 // convert terrain param into terrain object 202 g_Map.placeTerrain(x, y, createTerrain(terrain)); 203 204 } 205 206 ///////////////////////////////////////////////////////////////////////////////////////////// 207 // Access global map variable 208 ///////////////////////////////////////////////////////////////////////////////////////////// 209 210 function createTileClass() 211 { 212 return g_Map.createTileClass(); 213 } 214 215 function getTileClass(id) 216 { 217 // Check for valid class id 218 if (id < 1 || id > g_Map.tileClasses.length) 219 { 220 //error("Invalid tile class id: "+id); 221 return null; 222 } 223 224 return g_Map.tileClasses[id - 1]; 225 } 226 227 function createArea(placer, painter, constraint) 228 { 229 return g_Map.createArea(placer, painter, constraint); 230 } 231 232 function createObjectGroup(placer, player, constraint) 233 { 234 return g_Map.createObjectGroup(placer, player, constraint); 235 } 236 237 function getMapSize() 238 { 239 return g_Map.size; 240 } 241 242 function getNumPlayers() 243 { 244 return g_MapSettings.PlayerData.length; 245 } 246 247 function getCivCode(player) 248 { 249 return g_MapSettings.PlayerData[player].Civ; 250 } 251 252 function getHeight(x, y) 253 { 254 g_Map.getHeight(x, y); 255 } 256 257 function setHeight(x, y, height) 258 { 259 g_Map.setHeight(x, y, height); 260 } 261 262 ///////////////////////////////////////////////////////////////////////////////////////////// 263 // Utility functions for classes 264 ///////////////////////////////////////////////////////////////////////////////////////////// 265 266 267 // Add point to given class by id 268 function addToClass(x, y, id) 269 { 270 var tileClass = getTileClass(id); 271 272 if (tileClass !== null) 273 tileClass.add(x, y); 274 } 275 276 // Create a painter for the given class 277 function paintClass(id) 278 { 279 return new TileClassPainter(getTileClass(id)); 280 } 281 282 // Create an avoid constraint for the given classes by the given distances 283 function avoidClasses(/*class1, dist1, class2, dist2, etc*/) 284 { 285 var ar = new Array(arguments.length/2); 286 for (var i=0; i < arguments.length/2; i++) 287 { 288 ar[i] = new AvoidTileClassConstraint(arguments[2*i], arguments[2*i+1]); 289 } 290 // Return single constraint 291 return new AndConstraint(ar); 292 } -
binaries/data/mods/public/maps/mapgen/map.js
1 ////////////////////////////////////////////////////////////////////// 2 // Map 3 ////////////////////////////////////////////////////////////////////// 4 5 function Map(size, baseHeight) 6 { 7 // Size must be 0 to 1024, divisible by 16 8 this.size = size; 9 10 // Create 2D arrays for texture, object, and area maps 11 this.texture = new Array(size); 12 this.terrainObjects = new Array(size); 13 this.area = new Array(size); 14 15 for (var i=0; i < size; i++) 16 { 17 this.texture[i] = new Uint16Array(size); // uint16 18 this.terrainObjects[i] = new Array(size); // entity 19 this.area[i] = new Array(size); // area 20 21 for (var j = 0; j < size; j++) 22 { 23 this.terrainObjects[i][j] = []; 24 } 25 } 26 27 var mapSize = size+1; 28 29 // Create 2D array for heightmap 30 this.height = new Array(mapSize); 31 for (var i=0; i < mapSize; i++) 32 { 33 this.height[i] = new Float32Array(mapSize); 34 for (var j=0; j < mapSize; j++) 35 { // Initialize height map to baseHeight 36 this.height[i][j] = baseHeight; 37 } 38 } 39 40 // Create name <-> id maps for textures 41 this.nameToID = {}; 42 this.IDToName = []; //string 43 44 // Other arrays 45 this.objects = []; //object 46 this.areas = []; //area 47 this.tileClasses = []; //int 48 49 // Starting entity ID 50 this.entityCount = 150; 51 } 52 53 Map.prototype.initTerrain = function(baseTerrain) 54 { 55 // Initialize base terrain 56 var size = this.size; 57 for (var i=0; i < size; i++) 58 { 59 for (var j=0; j < size; j++) 60 { 61 baseTerrain.place(i, j); 62 } 63 } 64 }; 65 66 // Return ID of texture (by name) 67 Map.prototype.getID = function(texture) 68 { 69 if (texture in (this.nameToID)) 70 { 71 return this.nameToID[texture]; 72 } 73 74 // Add new texture 75 var id = this.IDToName.length; 76 this.nameToID[texture] = id; 77 this.IDToName[id] = texture; 78 79 return id; 80 }; 81 82 // Return next free entity ID 83 Map.prototype.getEntityID = function() 84 { 85 return this.entityCount++; 86 } 87 88 // Check bounds 89 Map.prototype.validT = function(x, y) 90 { 91 return x >= 0 && y >= 0 && x < this.size && y < this.size; 92 }; 93 94 // Check bounds on height map (size + 1 by size + 1) 95 Map.prototype.validH = function(x, y) 96 { 97 return x >= 0 && y >= 0 && x <= this.size && y <= this.size; 98 }; 99 100 // Check bounds on tile class 101 Map.prototype.validClass = function(c) 102 { 103 return c >= 0 && c < this.tileClasses.length; 104 }; 105 106 Map.prototype.getTexture = function(x, y) 107 { 108 if (!this.validT(x, y)) 109 error("getTexture: invalid tile position ("+x+", "+y+")"); 110 111 return this.IDToName[this.texture[x][y]]; 112 }; 113 114 Map.prototype.setTexture = function(x, y, texture) 115 { 116 if (!this.validT(x, y)) 117 error("setTexture: invalid tile position ("+x+", "+y+")"); 118 119 this.texture[x][y] = this.getID(texture); 120 }; 121 122 Map.prototype.getHeight = function(x, y) 123 { 124 if (!this.validH(x, y)) 125 error("getHeight: invalid vertex position ("+x+", "+y+")"); 126 127 return this.height[x][y]; 128 }; 129 130 Map.prototype.setHeight = function(x, y, height) 131 { 132 if (!this.validH(x, y)) 133 error("setHeight: invalid vertex position ("+x+", "+y+")"); 134 135 this.height[x][y] = height; 136 }; 137 138 Map.prototype.getTerrainObjects = function(x, y) 139 { 140 if (!this.validT(x, y)) 141 error("getTerrainObjects: invalid tile position ("+x+", "+y+")"); 142 143 return this.terrainObjects[x][y]; 144 }; 145 146 Map.prototype.setTerrainObjects = function(x, y, objects) 147 { 148 if (!this.validT(x, y)) 149 error("setTerrainObjects: invalid tile position ("+x+", "+y+")"); 150 151 this.terrainObjects[x][y] = objects; 152 }; 153 154 Map.prototype.placeTerrain = function(x, y, terrain) 155 { 156 terrain.place(x, y); 157 }; 158 159 Map.prototype.addObjects = function(obj) 160 { 161 this.objects = this.objects.concat(obj); 162 }; 163 164 Map.prototype.createArea = function(placer, painter, constraint) 165 { 166 // Check for multiple painters 167 if (painter instanceof Array) 168 { 169 var painterArray = painter; 170 painter = new MultiPainter(painterArray); 171 } 172 173 // Check for null constraint 174 if (constraint === undefined || constraint === null) 175 { 176 constraint = new NullConstraint(); 177 } 178 else if (constraint instanceof Array) 179 { // Check for multiple constraints 180 var constraintArray = constraint; 181 constraint = new AndConstraint(constraintArray); 182 } 183 184 var points = placer.place(constraint); 185 if (!points) 186 return undefined; 187 188 var a = new Area(points); 189 for (var i=0; i < points.length; i++) 190 { 191 this.area[points[i].x][points[i].y] = a; 192 } 193 194 painter.paint(a); 195 this.areas.push(a); 196 197 return a; 198 }; 199 200 Map.prototype.createObjectGroup = function(placer, player, constraint) 201 { 202 // Check for null constraint 203 if (constraint === undefined || constraint === null) 204 { 205 constraint = new NullConstraint(); 206 } 207 else if (constraint instanceof Array) 208 { // Check for multiple constraints 209 var constraintArray = constraint; 210 constraint = new AndConstraint(constraintArray); 211 } 212 213 return placer.place(player, constraint); 214 }; 215 216 Map.prototype.createTileClass = function() 217 { 218 this.tileClasses.push(new TileClass(this.size)); 219 220 return this.tileClasses.length; 221 }; 222 223 // Get height taking into account terrain curvature 224 Map.prototype.getExactHeight = function(x, y) 225 { 226 var xi = min(floor(x), this.size); 227 var yi = min(floor(y), this.size); 228 var xf = x - xi; 229 var yf = y - yi; 230 231 var h00 = this.height[xi][yi]; 232 var h01 = this.height[xi][yi+1]; 233 var h10 = this.height[xi+1][yi]; 234 var h11 = this.height[xi+1][yi+1]; 235 236 return ( 1 - yf ) * ( ( 1 - xf ) * h00 + xf * h10 ) + yf * ( ( 1 - xf ) * h01 + xf * h11 ) ; 237 }; 238 239 Map.prototype.getMapData = function() 240 { 241 var data = {}; 242 243 // Build entity array 244 var entities = []; 245 246 // Terrain objects first (trees) 247 var size = this.size; 248 for (var x=0; x < size; ++x) 249 { 250 for (var y=0; y < size; ++y) 251 { 252 if (this.terrainObjects[x][y].length) 253 entities = entities.concat(this.terrainObjects[x][y]); 254 } 255 } 256 257 // Now other entities 258 for (var n in this.objects) 259 { 260 entities = entities.concat(this.objects[n]); 261 } 262 263 // Convert from tiles to map coordinates 264 for (var n in entities) 265 { 266 var e = entities[n]; 267 e.x *= 4; 268 e.y *= 4; 269 270 entities[n] = e; 271 } 272 data["entities"] = entities; 273 274 // Terrain 275 data["size"] = this.size; 276 277 // Convert 2D heightmap array to flat array 278 // Flat because it's easier to handle by the engine 279 var mapSize = size+1; 280 var height16 = new Array(mapSize*mapSize); // uint16 281 for (var x=0; x < mapSize; x++) 282 { 283 for (var y=0; y < mapSize; y++) 284 { 285 var intHeight = ((this.height[x][y] + SEA_LEVEL) * 256.0 / 0.35)|0; // floor 286 287 if (intHeight > 65000) 288 intHeight = 65000; 289 else if (intHeight < 0) 290 intHeight = 0; 291 292 height16[y*mapSize + x] = intHeight; 293 } 294 } 295 data["height"] = height16; 296 data["seaLevel"] = SEA_LEVEL; 297 298 // Get array of textures used in this map 299 var textureNames = []; 300 for (var name in this.nameToID) 301 textureNames.push(name); 302 303 data["textureNames"] = textureNames; 304 data["numTextures"] = textureNames.length; 305 306 // Convert 2D tile data to flat array, reodering into patches as expected by MapReader 307 var tiles = new Array(size*size); 308 var patches = size/16; 309 for (var x=0; x < size; x++) 310 { 311 var patchX = floor(x/16); 312 var offX = x%16; 313 for (var y=0; y < size; y++) 314 { 315 var patchY = floor(y/16); 316 var offY = y%16; 317 tiles[(patchY*patches + patchX)*256 + (offY*16 + offX)] = this.texture[x][y]; 318 } 319 } 320 data["tileData"] = tiles; 321 322 return data; 323 }; -
binaries/data/mods/public/maps/mapgen/mapgen.js
1 // TODO: Since there's only one map anyway, just use this global variable 2 var g_Map; 3 4 // Map settings - once initialized, has all the game setup data, including player array 5 var g_MapSettings = { 6 Size : 13, 7 Seed : 0, 8 BaseTerrain: "grass1_spring", 9 BaseHeight: 0, 10 PlayerData : [ {}, {} ] 11 }; 12 13 var g_Environment = { 14 SkySet: "cirrus", 15 SunColour: {r: 1.47461, g: 1.47461, b: 1.47461}, 16 SunElevation: 0.951868, 17 SunRotation: -0.532844, 18 TerrainAmbientColour: {r: 0.337255, g: 0.403922, b: 0.466667}, 19 UnitsAmbientColour: {r: 0.501961, g: 0.501961, b: 0.501961}, 20 Water: { 21 WaterBody: { 22 Type: "default", 23 Colour: {r: 0.294118, g: 0.34902, b: 0.694118}, 24 Height: 17.6262, 25 Shininess: 150, 26 Waviness: 8, 27 Murkiness: 0.458008, 28 Tint: {r: 0.447059, g: 0.411765, b: 0.321569}, 29 ReflectionTint: {r: 0.619608, g: 0.584314, b: 0.47451}, 30 ReflectionTintStrength: 0.298828 31 } 32 } 33 }; 34 35 var g_Camera = { 36 Position: {x: 100, y: 150, z: -100}, 37 Rotation: 0, 38 Declination: 0.523599 39 }; 40 41 function InitMapGen(settings) 42 { 43 if (settings === undefined || settings == {}) 44 { 45 warn("InitMapGen: settings missing"); 46 } 47 else 48 { 49 g_MapSettings = settings; 50 } 51 52 // Init RNG with seed value 53 seedRand(g_MapSettings.Seed); 54 55 // Create new map 56 log("Creating new map..."); 57 var terrain = createTerrain(g_MapSettings.BaseTerrain); 58 59 g_Map = new Map(g_MapSettings.Size * TILES_PER_PATCH, g_MapSettings.BaseHeight); 60 g_Map.initTerrain(terrain); 61 } 62 63 function SaveMap() 64 { 65 log("Saving map..."); 66 67 // Get necessary data from map 68 var data = g_Map.getMapData(); 69 70 // Add environment and camera settings 71 g_Environment.Water.WaterBody.Height = SEA_LEVEL - 0.1; 72 data.Environment = g_Environment; 73 data.Camera = g_Camera; 74 75 return data; 76 } -
binaries/data/mods/public/maps/mapgen/noise.js
1 // Utility function used in both noises as an ease curve 2 function easeCurve(t) 3 { 4 return t*t*t*(t*(t*6-15)+10); 5 } 6 7 // Find mod of number but only positive values 8 function modPos(num, m) 9 { 10 var p = num % m; 11 if (p < 0) 12 p += m; 13 14 return p; 15 } 16 17 ///////////////////////////////////////////////////////////////////// 18 // Noise2D 19 ///////////////////////////////////////////////////////////////////// 20 21 function Noise2D(freq) 22 { 23 freq = floor(freq); 24 this.freq = freq; 25 this.grads = new Array(freq); 26 27 for (var i=0; i < freq; ++i) 28 { 29 this.grads[i] = new Array(freq); 30 for (var j=0; j < freq; ++j) 31 { 32 var a = randFloat() * 2 * PI; 33 34 this.grads[i][j] = new Vector2D(cos(a), sin(a)); 35 } 36 } 37 } 38 39 Noise2D.prototype.get = function(x, y) 40 { 41 x *= this.freq; 42 y *= this.freq; 43 44 var ix = modPos(floor(x), this.freq); 45 var iy = modPos(floor(y), this.freq); 46 47 var fx = x - ix; 48 var fy = y - iy; 49 50 var ix1 = (ix+1) % this.freq; 51 var iy1 = (iy+1) % this.freq; 52 53 var s = this.grads[ix][iy].dot(new Vector2D(fx, fy)); 54 var t = this.grads[ix1][iy].dot(new Vector2D(fx-1, fy)); 55 var u = this.grads[ix][iy1].dot(new Vector2D(fx, fy-1)); 56 var v = this.grads[ix1][iy1].dot(new Vector2D(fx-1, fy-1)); 57 58 var ex = easeCurve(fx); 59 var ey = easeCurve(fy); 60 var a = s + ex*(t-s); 61 var b = u + ex*(v-u); 62 return (a + ey*(b-a)) * 0.5 + 0.5; 63 }; 64 65 ///////////////////////////////////////////////////////////////////// 66 // Noise3D 67 ///////////////////////////////////////////////////////////////////// 68 69 function Noise3D(freq, vfreq) 70 { 71 freq = floor(freq); 72 vfreq = floor(vfreq); 73 this.freq = freq; 74 this.vfreq = vfreq; 75 this.grads = new Array(freq); 76 77 for (var i=0; i < freq; ++i) 78 { 79 this.grads[i] = new Array(freq); 80 for (var j=0; j < freq; ++j) 81 { 82 this.grads[i][j] = new Array(vfreq); 83 for(var k=0; k < vfreq; ++k) 84 { 85 var v = new Vector3D(); 86 do 87 { 88 v.set(2*randFloat()-1, 2*randFloat()-1, 2*randFloat()-1); 89 } 90 while(v.lengthSquared() > 1 || v.lengthSquared() < 0.1); 91 92 v.normalize(); 93 94 this.grads[i][j][k] = v; 95 } 96 } 97 } 98 } 99 100 Noise3D.prototype.get = function(x, y, z) 101 { 102 x *= this.freq; 103 y *= this.freq; 104 z *= this.vfreq; 105 106 var ix =modPos(floor(x), this.freq); 107 var iy = modPos(floor(y), this.freq); 108 var iz = modPos(floor(z), this.vfreq); 109 110 var fx = x - ix; 111 var fy = y - iy; 112 var fz = z - iz; 113 114 var ix1 = (ix+1) % this.freq; 115 var iy1 = (iy+1) % this.freq; 116 var iz1 = (iz+1) % this.vfreq; 117 118 var s0 = this.grads[ix][iy][iz].dot(new Vector3D(fx, fy, fz)); 119 var t0 = this.grads[ix1][iy][iz].dot(new Vector3D(fx-1, fy, fz)); 120 var u0 = this.grads[ix][iy1][iz].dot(new Vector3D(fx, fy-1, fz)); 121 var v0 = this.grads[ix1][iy1][iz].dot(new Vector3D(fx-1, fy-1, fz)); 122 123 var s1 = this.grads[ix][iy][iz1].dot(new Vector3D(fx, fy, fz-1)); 124 var t1 = this.grads[ix1][iy][iz1].dot(new Vector3D(fx-1, fy, fz-1)); 125 var u1 = this.grads[ix][iy1][iz1].dot(new Vector3D(fx, fy-1, fz-1)); 126 var v1 = this.grads[ix1][iy1][iz1].dot(new Vector3D(fx-1, fy-1, fz-1)); 127 128 var ex = easeCurve(fx); 129 var ey = easeCurve(fy); 130 var ez = easeCurve(fz); 131 132 var a0 = s0 + ex*(t0-s0); 133 var b0 = u0 + ex*(v0-u0); 134 var c0 = a0 + ey*(b0-a0); 135 136 var a1 = s1 + ex*(t1-s1); 137 var b1 = u1 + ex*(v1-u1); 138 var c1 = a1 + ey*(b1-a1); 139 140 return (c0 + ez*(c1-c0)) * 0.5 + 0.5; 141 }; -
binaries/data/mods/public/maps/mapgen/painter.js
1 const ELEVATION_SET = 0; 2 const ELEVATION_MODIFY = 1; 3 4 ///////////////////////////////////////////////////////////////////////////// 5 // ElevationPainter 6 ///////////////////////////////////////////////////////////////////////////// 7 8 function ElevationPainter(elevation) 9 { 10 this.elevation = elevation; 11 this.DX = [0, 1, 1, 0]; 12 this.DY = [0, 0, 1, 1]; 13 } 14 15 ElevationPainter.prototype.paint = function(area) 16 { 17 var length = area.points.length; 18 var elevation = this.elevation; 19 20 for (var i=0; i < length; i++) 21 { 22 var pt = area.points[i]; 23 24 for (var j=0; j < 4; j++) 25 { 26 g_Map.height[pt.x+this.DX[j]][pt.y+this.DY[j]] = elevation; 27 } 28 } 29 }; 30 31 ///////////////////////////////////////////////////////////////////////////// 32 // LayeredPainter 33 ///////////////////////////////////////////////////////////////////////////// 34 35 function LayeredPainter(terrainArray, widths) 36 { 37 if (!(terrainArray instanceof Array)) 38 error("terrains must be an array!"); 39 40 this.terrains = []; 41 for (var i = 0; i < terrainArray.length; ++i) 42 this.terrains.push(createTerrain(terrainArray[i])); 43 44 this.widths = widths; 45 } 46 47 LayeredPainter.prototype.paint = function(area) 48 { 49 var size = getMapSize(); 50 var saw = new Array(size); 51 var dist = new Array(size); 52 53 // init typed arrays 54 for (var i = 0; i < size; ++i) 55 { 56 saw[i] = new Uint8Array(size); // bool / uint8 57 dist[i] = new Uint16Array(size); // uint16 58 } 59 60 // Point queue (implemented with array) 61 var pointQ = []; 62 63 // push edge points 64 var pts = area.points; 65 var length = pts.length; 66 67 for (var i=0; i < length; i++) 68 { 69 var x = pts[i].x; 70 var y = pts[i].y; 71 72 for (var dx=-1; dx <= 1; dx++) 73 { 74 var nx = x+dx; 75 for (var dy=-1; dy <= 1; dy++) 76 { 77 var ny = y+dy; 78 79 if (g_Map.validT(nx, ny) && g_Map.area[nx][ny] && g_Map.area[nx][ny] != area && !saw[nx][ny]) 80 { 81 saw[nx][ny] = 1; 82 dist[nx][ny] = 0; 83 pointQ.push(new Point(nx, ny)); 84 } 85 } 86 } 87 } 88 89 // do BFS inwards to find distances to edge 90 while (pointQ.length) 91 { 92 var pt = pointQ.shift(); // Pop queue 93 var px = pt.x; 94 var py = pt.y; 95 var d = dist[px][py]; 96 97 // paint if in area 98 if (g_Map.area[px][py] == area) 99 { 100 var w=0; 101 var i=0; 102 103 //~ while (i < this.widths.length && w < d) 104 //~ { 105 //~ w += this.widths[i]; 106 //~ ++i; 107 //~ } 108 for (; i < this.widths.length; i++) 109 { 110 w += this.widths[i]; 111 if (w >= d) 112 { 113 break; 114 } 115 } 116 this.terrains[i].place(px, py); 117 } 118 119 // enqueue neighbours 120 for (var dx=-1; dx<=1; dx++) 121 { 122 var nx = px+dx; 123 for (var dy=-1; dy<=1; dy++) 124 { 125 var ny = py+dy; 126 127 if (g_Map.validT(nx, ny) && g_Map.area[nx][ny] && g_Map.area[nx][ny] == area && !saw[nx][ny]) 128 { 129 saw[nx][ny] = 1; 130 dist[nx][ny] = d+1; 131 pointQ.push(new Point(nx, ny)); 132 } 133 } 134 } 135 } 136 }; 137 138 ///////////////////////////////////////////////////////////////////////////// 139 // MultiPainter 140 ///////////////////////////////////////////////////////////////////////////// 141 142 function MultiPainter(painters) 143 { 144 this.painters = painters; 145 } 146 147 MultiPainter.prototype.paint = function(area) 148 { 149 for (var i=0; i < this.painters.length; i++) 150 { 151 this.painters[i].paint(area); 152 } 153 }; 154 155 ///////////////////////////////////////////////////////////////////////////// 156 // SmoothElevationPainter 157 ///////////////////////////////////////////////////////////////////////////// 158 159 function SmoothElevationPainter(type, elevation, blendRadius) 160 { 161 this.type = type; 162 this.elevation = elevation; 163 this.blendRadius = blendRadius; 164 165 if (type != ELEVATION_SET && type != ELEVATION_MODIFY) 166 error("SmoothElevationPainter: invalid type '"+type+"'"); 167 } 168 169 SmoothElevationPainter.prototype.checkInArea = function(area, x, y) 170 { 171 if (g_Map.validT(x, y)) 172 { 173 return (g_Map.area[x][y] && g_Map.area[x][y] == area); 174 } 175 else 176 { 177 return false; 178 } 179 }; 180 181 SmoothElevationPainter.prototype.paint = function(area) 182 { 183 var pointQ = []; 184 var pts = area.points; 185 var heightPts = []; 186 187 var mapSize = getMapSize()+1; 188 189 var saw = new Array(mapSize); 190 var dist = new Array(mapSize); 191 var gotHeightPt = new Array(mapSize); 192 var newHeight = new Array(mapSize); 193 194 // init typed arrays 195 for (var i = 0; i < mapSize; ++i) 196 { 197 saw[i] = new Uint8Array(mapSize); // bool / uint8 198 dist[i] = new Uint16Array(mapSize); // uint16 199 gotHeightPt[i] = new Uint8Array(mapSize); // bool / uint8 200 newHeight[i] = new Float32Array(mapSize); // float32 201 } 202 203 var length = pts.length; 204 205 // get a list of all points 206 for (var i=0; i < length; i++) 207 { 208 var x = pts[i].x; 209 var y = pts[i].y; 210 211 for (var dx=-1; dx <= 2; dx++) 212 { 213 var nx = x+dx; 214 for (var dy=-1; dy <= 2; dy++) 215 { 216 var ny = y+dy; 217 218 if (g_Map.validH(nx, ny) && !gotHeightPt[nx][ny]) 219 { 220 gotHeightPt[nx][ny] = 1; 221 heightPts.push(new Point(nx, ny)); 222 newHeight[nx][ny] = g_Map.height[nx][ny]; 223 } 224 } 225 } 226 } 227 228 // push edge points 229 for (var i=0; i < length; i++) 230 { 231 var x = pts[i].x, y = pts[i].y; 232 for (var dx=-1; dx <= 2; dx++) 233 { 234 var nx = x+dx; 235 for (var dy=-1; dy <= 2; dy++) 236 { 237 var ny = y+dy; 238 239 if (g_Map.validH(nx, ny) 240 && !this.checkInArea(area, nx, ny) 241 && !this.checkInArea(area, nx-1, ny) 242 && !this.checkInArea(area, nx, ny-1) 243 && !this.checkInArea(area, nx-1, ny-1) 244 && !saw[nx][ny]) 245 { 246 saw[nx][ny]= 1; 247 dist[nx][ny] = 0; 248 pointQ.push(new Point(nx, ny)); 249 } 250 } 251 } 252 } 253 254 // do BFS inwards to find distances to edge 255 while(pointQ.length) 256 { 257 var pt = pointQ.shift(); 258 var px = pt.x; 259 var py = pt.y; 260 var d = dist[px][py]; 261 262 // paint if in area 263 if (g_Map.validH(px, py) 264 && (this.checkInArea(area, px, py) || this.checkInArea(area, px-1, py) 265 || this.checkInArea(area, px, py-1) || this.checkInArea(area, px-1, py-1))) 266 { 267 if (d <= this.blendRadius) 268 { 269 var a = (d-1) / this.blendRadius; 270 if (this.type == ELEVATION_SET) 271 { 272 newHeight[px][py] = a*this.elevation + (1-a)*g_Map.height[px][py]; 273 } 274 else 275 { // type == MODIFY 276 newHeight[px][py] += a*this.elevation; 277 } 278 } 279 else 280 { // also happens when blendRadius == 0 281 if (this.type == ELEVATION_SET) 282 { 283 newHeight[px][py] = this.elevation; 284 } 285 else 286 { // type == MODIFY 287 newHeight[px][py] += this.elevation; 288 } 289 } 290 } 291 292 // enqueue neighbours 293 for (var dx=-1; dx <= 1; dx++) 294 { 295 var nx = px+dx; 296 for (var dy=-1; dy <= 1; dy++) 297 { 298 var ny = py+dy; 299 300 if (g_Map.validH(nx, ny) 301 && (this.checkInArea(area, nx, ny) || this.checkInArea(area, nx-1, ny) 302 || this.checkInArea(area, nx, ny-1) || this.checkInArea(area, nx-1, ny-1)) 303 && !saw[nx][ny]) 304 { 305 saw[nx][ny] = 1; 306 dist[nx][ny] = d+1; 307 pointQ.push(new Point(nx, ny)); 308 } 309 } 310 } 311 } 312 313 length = heightPts.length; 314 315 // smooth everything out 316 for (var i = 0; i < length; ++i) 317 { 318 var pt = heightPts[i]; 319 var px = pt.x; 320 var py = pt.y; 321 322 if ((this.checkInArea(area, px, py) || this.checkInArea(area, px-1, py) 323 || this.checkInArea(area, px, py-1) || this.checkInArea(area, px-1, py-1))) 324 { 325 var sum = 8 * newHeight[px][py]; 326 var count = 8; 327 328 for (var dx=-1; dx <= 1; dx++) 329 { 330 var nx = px+dx; 331 for (var dy=-1; dy <= 1; dy++) 332 { 333 var ny = py+dy; 334 335 if (g_Map.validH(nx, ny)) 336 { 337 sum += newHeight[nx][ny]; 338 count++; 339 } 340 } 341 } 342 343 g_Map.height[px][py] = sum/count; 344 } 345 } 346 }; 347 348 ///////////////////////////////////////////////////////////////////////////// 349 // TerrainPainter 350 ///////////////////////////////////////////////////////////////////////////// 351 352 function TerrainPainter(terrain) 353 { 354 this.terrain = createTerrain(terrain); 355 } 356 357 TerrainPainter.prototype.paint = function(area) 358 { 359 var length = area.points.length; 360 for (var i=0; i < length; i++) 361 { 362 var pt = area.points[i]; 363 this.terrain.place(pt.x, pt.y); 364 } 365 }; 366 367 ///////////////////////////////////////////////////////////////////////////// 368 // TileClassPainter 369 ///////////////////////////////////////////////////////////////////////////// 370 371 function TileClassPainter(tileClass) 372 { 373 this.tileClass = tileClass; 374 } 375 376 TileClassPainter.prototype.paint = function(area) 377 { 378 var length = area.points.length; 379 for (var i=0; i < length; i++) 380 { 381 var pt = area.points[i]; 382 this.tileClass.add(pt.x, pt.y); 383 } 384 }; -
binaries/data/mods/public/maps/mapgen/placer.js
1 2 ///////////////////////////////////////////////////////////////////////////////////////// 3 // ClumpPlacer 4 ///////////////////////////////////////////////////////////////////////////////////////// 5 6 function ClumpPlacer(size, coherence, smoothness, failFraction, x, y) 7 { 8 this.size = size; 9 this.coherence = coherence; 10 this.smoothness = smoothness; 11 this.failFraction = (failFraction !== undefined ? failFraction : 0); 12 this.x = (x !== undefined ? x : -1); 13 this.y = (y !== undefined ? y : -1); 14 } 15 16 ClumpPlacer.prototype.place = function(constraint) 17 { 18 if (!g_Map.validT(this.x, this.y) || !constraint.allows(this.x, this.y)) 19 { 20 return false; 21 } 22 23 var retVec = []; 24 25 var size = getMapSize(); 26 var gotRet = new Array(size); 27 for (var i = 0; i < size; ++i) 28 { 29 gotRet[i] = new Uint8Array(size); // bool / uint8 30 } 31 32 var radius = sqrt(this.size / PI); 33 var perim = 4 * radius * 2 * PI; 34 var intPerim = ceil(perim); 35 36 var ctrlPts = 1 + Math.floor(1.0/Math.max(this.smoothness,1.0/intPerim)); 37 38 if (ctrlPts > radius * 2 * PI) 39 ctrlPts = Math.floor(radius * 2 * PI) + 1; 40 41 var noise = new Float32Array(intPerim); //float32 42 var ctrlCoords = new Float32Array(ctrlPts+1); //float32 43 var ctrlVals = new Float32Array(ctrlPts+1); //float32 44 45 for (var i=0; i < ctrlPts; i++) 46 { 47 ctrlCoords[i] = i * perim / ctrlPts; 48 ctrlVals[i] = 2.0*randFloat(); 49 } 50 51 var c = 0; 52 var looped = 0; 53 for (var i=0; i < intPerim; i++) 54 { 55 if (ctrlCoords[(c+1) % ctrlPts] < i && !looped) 56 { 57 c = (c+1) % ctrlPts; 58 if (c==ctrlPts-1) 59 looped = 1; 60 } 61 62 var t = (i - ctrlCoords[c]) / ((looped ? perim : ctrlCoords[(c+1)%ctrlPts]) - ctrlCoords[c]); 63 var v0 = ctrlVals[(c+ctrlPts-1)%ctrlPts]; 64 var v1 = ctrlVals[c]; 65 var v2 = ctrlVals[(c+1)%ctrlPts]; 66 var v3 = ctrlVals[(c+2)%ctrlPts]; 67 var P = (v3 - v2) - (v0 - v1); 68 var Q = (v0 - v1) - P; 69 var R = v2 - v0; 70 var S = v1; 71 72 noise[i] = P*t*t*t + Q*t*t + R*t + S; 73 } 74 75 var failed = 0; 76 for (var p=0; p < intPerim; p++) 77 { 78 var th = 2 * PI * p / perim; 79 var r = radius * (1 + (1-this.coherence)*noise[p]); 80 var s = sin(th); 81 var c = cos(th); 82 var xx=this.x; 83 var yy=this.y; 84 85 for (var k=0; k < r; k++) 86 { 87 var i = Math.floor(xx); 88 var j = Math.floor(yy); 89 if (g_Map.validT(i, j) && constraint.allows(i, j)) 90 { 91 if (!gotRet[i][j]) 92 { // Only include each point once 93 gotRet[i][j] = 1; 94 retVec.push(new Point(i, j)); 95 } 96 } 97 else 98 { 99 failed++; 100 } 101 xx += s; 102 yy += c; 103 } 104 } 105 106 return ((failed > this.size*this.failFraction) ? undefined : retVec); 107 }; 108 109 ///////////////////////////////////////////////////////////////////////////////////////// 110 // RectPlacer 111 ///////////////////////////////////////////////////////////////////////////////////////// 112 113 function RectPlacer(x1, y1, x2, y2) 114 { 115 this.x1 = x1; 116 this.y1 = y1; 117 this.x2 = x2; 118 this.y2 = y2; 119 120 if (x1 > x2 || y1 > y2) 121 error("RectPlacer: incorrect bounds on rect"); 122 } 123 124 RectPlacer.prototype.place = function(constraint) 125 { 126 var ret = []; 127 128 var x2 = this.x2; 129 var y2 = this.y2; 130 131 for (var x=this.x1; x < x2; x++) 132 { 133 for (var y=this.y1; y < y2; y++) 134 { 135 if (g_Map.validT(x, y) && constraint.allows(x, y)) 136 { 137 ret.push(new Point(x, y)); 138 } 139 else 140 { 141 return undefined; 142 } 143 } 144 } 145 146 return ret; 147 148 }; 149 150 ///////////////////////////////////////////////////////////////////////////////////////// 151 // ObjectGroupPlacer 152 ///////////////////////////////////////////////////////////////////////////////////////// 153 154 function ObjectGroupPlacer() {} 155 156 ///////////////////////////////////////////////////////////////////////////////////////// 157 // SimpleGroup 158 ///////////////////////////////////////////////////////////////////////////////////////// 159 160 function SimpleObject(type, minCount, maxCount, minDistance, maxDistance, minAngle, maxAngle) 161 { 162 this.type = type; 163 this.minCount = minCount; 164 this.maxCount = maxCount; 165 this.minDistance = minDistance; 166 this.maxDistance = maxDistance; 167 this.minAngle = (minAngle !== undefined ? minAngle : 0); 168 this.maxAngle = (maxAngle !== undefined ? maxAngle : 2*PI); 169 170 if (minCount > maxCount) 171 error("SimpleObject: minCount must be less than or equal to maxCount"); 172 173 if (minDistance > maxDistance) 174 error("SimpleObject: minDistance must be less than or equal to maxDistance"); 175 176 if (minAngle > maxAngle) 177 error("SimpleObject: minAngle must be less than or equal to maxAngle"); 178 } 179 180 SimpleObject.prototype.place = function(cx, cy, player, avoidSelf, constraint) 181 { 182 var failCount = 0; 183 var count = randInt(this.minCount, this.maxCount); 184 var resultObjs = []; 185 186 for (var i=0; i < count; i++) 187 { 188 while(true) 189 { 190 var distance = randFloat(this.minDistance, this.maxDistance); 191 var direction = randFloat(0, 2*PI); 192 193 var x = cx + 0.5 + distance*cos(direction); 194 var y = cy + 0.5 + distance*sin(direction); 195 var fail = false; // reset place failure flag 196 197 if (x < 0 || y < 0 || x > g_Map.size || y > g_Map.size) 198 { 199 fail = true; 200 } 201 else 202 { 203 if (avoidSelf) 204 { 205 var length = resultObjs.length; 206 for (var i = 0; (i < length) && !fail; i++) 207 { 208 var dx = x - resultObjs[i].x; 209 var dy = y - resultObjs[i].y; 210 211 if ((dx*dx + dy*dy) < 1) 212 { 213 fail = true; 214 } 215 } 216 } 217 218 if (!fail) 219 { 220 if (!constraint.allows(Math.floor(x), Math.floor(y))) 221 { 222 fail = true; 223 } 224 else 225 { // if we got here, we're good 226 var angle = randFloat(this.minAngle, this.maxAngle); 227 resultObjs.push(new Entity(this.type, player, x, y, angle)); 228 break; 229 } 230 } 231 } 232 233 if (fail) 234 { 235 failCount++; 236 if (failCount > 20) // TODO: Make this adjustable 237 { 238 return undefined; 239 } 240 } 241 } 242 } 243 244 return resultObjs; 245 }; 246 247 function SimpleGroup(elements, avoidSelf, tileClass, x, y) 248 { 249 this.elements = elements; 250 this.tileClass = (tileClass !== undefined ? getTileClass(tileClass) : null); 251 this.avoidSelf = (avoidSelf !== undefined ? avoidSelf : false); 252 this.x = (x !== undefined ? x : -1); 253 this.y = (y !== undefined ? y : -1); 254 } 255 256 SimpleGroup.prototype.place = function(player, constraint) 257 { 258 var resultObjs = []; 259 260 // Try placement of objects 261 var length = this.elements.length; 262 for (var i=0; i < length; i++) 263 { 264 var objs = this.elements[i].place(this.x, this.y, player, this.avoidSelf, constraint); 265 if (objs === undefined) 266 { // Failure 267 return false; 268 } 269 else 270 { 271 resultObjs = resultObjs.concat(objs); 272 } 273 } 274 275 // Add placed objects to map 276 length = resultObjs.length; 277 for (var i=0; i < length; i++) 278 { 279 g_Map.addObjects(resultObjs[i]); 280 281 if (this.tileClass !== null) 282 { // Round object position to integer 283 this.tileClass.add(Math.floor(resultObjs[i].x), Math.floor(resultObjs[i].y)); 284 } 285 } 286 287 return true; 288 }; 289 -
binaries/data/mods/public/maps/mapgen/point.js
1 function Point(x, y) 2 { 3 this.x = (x !== undefined ? x : 0); 4 this.y = (y !== undefined ? y : 0); 5 } -
binaries/data/mods/public/maps/mapgen/random.js
1 2 //~ function randFloat() 3 //~ { 4 //~ if (arguments.length == 0) 5 //~ { 6 //~ return Generator.RandFloat0(); 7 //~ } 8 //~ else if (arguments.length == 2) 9 //~ { 10 //~ return Generator.RandFloat2(arguments[0], arguments[1]); 11 //~ } 12 //~ else 13 //~ { 14 //~ return undefined; 15 //~ } 16 //~ } 17 18 //~ function randInt() 19 //~ { 20 //~ if (arguments.length == 1) 21 //~ { 22 //~ return Generator.RandInt1(arguments[0]); 23 //~ } 24 //~ else if (arguments.length == 2) 25 //~ { 26 //~ return Generator.RandInt2(arguments[0], arguments[1]); 27 //~ } 28 //~ else 29 //~ { 30 //~ return undefined; 31 //~ } 32 //~ } -
binaries/data/mods/public/maps/mapgen/terrain.js
1 ////////////////////////////////////////////////////////////////////// 2 // Terrain 3 ////////////////////////////////////////////////////////////////////// 4 5 function Terrain() {} 6 7 Terrain.prototype.place = function(x, y) 8 { 9 // Clear old array 10 g_Map.terrainObjects[x][y] = []; 11 12 this.placeNew(x, y); 13 }; 14 15 Terrain.prototype.placeNew = function() {}; 16 17 ////////////////////////////////////////////////////////////////////// 18 // SimpleTerrain 19 ////////////////////////////////////////////////////////////////////// 20 21 function SimpleTerrain(texture, treeType) 22 { 23 if (texture === undefined) 24 error("SimpleTerrain: texture not defined"); 25 26 this.texture = texture; 27 this.treeType = treeType; 28 } 29 30 SimpleTerrain.prototype = new Terrain(); 31 SimpleTerrain.prototype.constructor = SimpleTerrain; 32 SimpleTerrain.prototype.placeNew = function(x, y) 33 { 34 if (this.treeType !== undefined) 35 g_Map.terrainObjects[x][y].push(new Entity(this.treeType, 0, x+0.5, y+0.5, randFloat()*PI)); 36 37 g_Map.texture[x][y] = g_Map.getID(this.texture); 38 }; 39 40 ////////////////////////////////////////////////////////////////////// 41 // RandomTerrain 42 ////////////////////////////////////////////////////////////////////// 43 44 function RandomTerrain(terrains) 45 { 46 if (!(terrains instanceof Array) || !terrains.length) 47 error("Invalid terrains array"); 48 49 this.terrains = terrains; 50 } 51 52 RandomTerrain.prototype = new Terrain(); 53 RandomTerrain.prototype.constructor = RandomTerrain; 54 RandomTerrain.prototype.placeNew = function(x, y) 55 { 56 this.terrains[randInt(this.terrains.length)].placeNew(x, y); 57 }; -
binaries/data/mods/public/maps/mapgen/tileclass.js
1 ////////////////////////////////////////////////////////////////////// 2 // RangeOp 3 ////////////////////////////////////////////////////////////////////// 4 5 function RangeOp(size) 6 { 7 // Get smallest power of 2 which is greater than or equal to size 8 this.nn = 1; 9 while (this.nn < size) { 10 this.nn *= 2; 11 } 12 13 this.vals = new Int16Array(2*this.nn); // int16 14 } 15 16 RangeOp.prototype.set = function(pos, amt) 17 { 18 this.add(pos, amt - this.vals[this.nn + pos]); 19 }; 20 21 RangeOp.prototype.add = function(pos, amt) 22 { 23 for(var s = this.nn; s >= 1; s /= 2) 24 { 25 this.vals[s + pos] += amt; 26 pos = Math.floor(pos/2); 27 } 28 }; 29 30 RangeOp.prototype.get = function(start, end) 31 { 32 var ret = 0; 33 var i; 34 var nn = this.nn; 35 36 // Count from start to end by powers of 2 37 for (i = 1; start+i <= end; i *= 2) 38 { 39 if (start & i) 40 { // For each bit in start 41 ret += this.vals[nn/i + Math.floor(start/i)]; 42 start += i; 43 } 44 } 45 46 // 47 while(i >= 1) 48 { 49 if(start+i <= end) 50 { 51 ret += this.vals[nn/i + Math.floor(start/i)]; 52 start += i; 53 } 54 i /= 2; 55 } 56 57 return ret; 58 }; 59 60 61 ////////////////////////////////////////////////////////////////////// 62 // TileClass 63 ////////////////////////////////////////////////////////////////////// 64 65 function TileClass(size) 66 { 67 this.size = size; 68 this.inclusionCount = new Array(size); 69 this.rangeCount = new Array(size); 70 71 for (var i=0; i < size; ++i) 72 { 73 this.inclusionCount[i] = new Int16Array(size); //int16 74 this.rangeCount[i] = new RangeOp(size); 75 } 76 } 77 78 TileClass.prototype.add = function(x, y) 79 { 80 if (!this.inclusionCount[x][y]) 81 { 82 this.rangeCount[y].add(x, 1); 83 } 84 85 this.inclusionCount[x][y]++; 86 }; 87 88 TileClass.prototype.remove = function(x, y) 89 { 90 this.inclusionCount[x][y]--; 91 if(!this.inclusionCount[x][y]) 92 { 93 this.rangeCount[y].add(x, -1); 94 } 95 }; 96 97 TileClass.prototype.countInRadius = function(cx, cy, radius, returnMembers) 98 { 99 var members = 0; 100 var nonMembers = 0; 101 var size = this.size; 102 103 var ymax = cy+radius; 104 105 for (var y = cy-radius; y <= ymax; y++) 106 { 107 var iy = Math.floor(y); 108 if(iy >= 0 && iy < size) 109 { 110 var dy = y - cy; 111 var dx = Math.sqrt(radius*radius - dy*dy); 112 113 var lowerX = Math.floor(cx - dx); 114 var upperX = Math.floor(cx + dx); 115 116 var minX = (lowerX > 0 ? lowerX : 0); 117 var maxX = (upperX < size ? upperX+1 : size); 118 119 var total = maxX - minX; 120 var mem = this.rangeCount[iy].get(minX, maxX); 121 122 members += mem; 123 nonMembers += total - mem; 124 } 125 } 126 127 if (returnMembers) 128 return members; 129 else 130 return nonMembers; 131 }; 132 133 TileClass.prototype.countMembersInRadius = function(cx, cy, radius) 134 { 135 return this.countInRadius(cx, cy, radius, true); 136 }; 137 138 TileClass.prototype.countNonMembersInRadius = function(cx, cy, radius) 139 { 140 return this.countInRadius(cx, cy, radius, false); 141 }; -
binaries/data/mods/public/maps/mapgen/vector.js
1 ///////////////////////////////////////////////////////////////////// 2 // Vector2D 3 ///////////////////////////////////////////////////////////////////// 4 5 // TODO: Type errors if v not instanceof Vector classes 6 // TODO: Possible implement in C++ 7 8 function Vector2D(x, y) 9 { 10 if (arguments.length == 2) 11 { 12 this.set(x, y); 13 } 14 else 15 { 16 this.set(0, 0); 17 } 18 } 19 20 Vector2D.prototype.set = function(x, y) 21 { 22 this.x = x; 23 this.y = y; 24 }; 25 26 Vector2D.prototype.add = function(v) 27 { 28 return new Vector2D(this.x + v.x, this.y + v.y); 29 }; 30 31 Vector2D.prototype.sub = function(v) 32 { 33 return new Vector2D(this.x - v.x, this.y - v.y); 34 }; 35 36 Vector2D.prototype.mult = function(f) 37 { 38 return new Vector2D(this.x * f, this.y * f); 39 }; 40 41 Vector2D.prototype.div = function(f) 42 { 43 return new Vector2D(this.x / f, this.y / f); 44 }; 45 46 Vector2D.prototype.dot = function(v) 47 { 48 return this.x * v.x + this.y * v.y; 49 }; 50 51 Vector2D.prototype.lengthSquared = function() 52 { 53 return this.dot(this); 54 }; 55 56 Vector2D.prototype.length = function() 57 { 58 return sqrt(this.lengthSquared()); 59 }; 60 61 Vector2D.prototype.normalize = function() 62 { 63 var mag = this.length(); 64 65 this.x /= mag; 66 this.y /= mag; 67 }; 68 69 ///////////////////////////////////////////////////////////////////// 70 // Vector3D 71 ///////////////////////////////////////////////////////////////////// 72 73 function Vector3D(x, y, z) 74 { 75 if (arguments.length == 3) 76 { 77 this.set(x, y, z); 78 } 79 else 80 { 81 this.set(0, 0, 0); 82 } 83 } 84 85 Vector3D.prototype.set = function(x, y, z) 86 { 87 this.x = x; 88 this.y = y; 89 this.z = z; 90 }; 91 92 Vector3D.prototype.add = function(v) 93 { 94 return new Vector3D(this.x + v.x, this.y + v.y, this.z + v.z); 95 }; 96 97 Vector3D.prototype.sub = function(v) 98 { 99 return new Vector3D(this.x - v.x, this.y - v.y, this.z - v.z); 100 }; 101 102 Vector3D.prototype.mult = function(f) 103 { 104 return new Vector3D(this.x * f, this.y * f, this.z * f); 105 }; 106 107 Vector3D.prototype.div = function(f) 108 { 109 return new Vector3D(this.x / f, this.y / f, this.z / f); 110 }; 111 112 Vector3D.prototype.dot = function(v) 113 { 114 return this.x * v.x + this.y * v.y + this.z * v.z; 115 }; 116 117 Vector3D.prototype.lengthSquared = function() 118 { 119 return this.dot(this); 120 }; 121 122 Vector3D.prototype.length = function() 123 { 124 return sqrt(this.lengthSquared()); 125 }; 126 127 Vector3D.prototype.normalize = function() 128 { 129 var mag = this.length(); 130 131 this.x /= mag; 132 this.y /= mag; 133 this.z /= mag; 134 }; 135 -
binaries/data/mods/public/maps/random/cantabrian_highlands.js
1 // constants2 1 3 const SIZE = 208; 4 const NUM_PLAYERS = 4; 2 // terrain textures 3 const tGrass = ["medit_grass_field_a", "medit_grass_field_b"]; 4 const tGrassForest = "medit_grass_wild"; 5 const tCliff = ["medit_cliff_italia", "medit_cliff_italia_grass"]; 6 const tForest = "medit_grass_field_a"; 7 const tGrassDirt75 = "medit_dirt"; 8 const tGrassDirt50 = "medit_dirt_b"; 9 const tGrassDirt25 = "medit_dirt_c"; 10 const tDirt = "medit_dirt_b"; 11 const tGrassPatch = "medit_grass_wild"; 12 const tShore = "medit_rocks"; 13 const tShoreBlend = "medit_rocks_grass"; 14 const tWater = "medit_rocks_wet"; 5 15 16 // gaia entities 17 const oTree = "gaia/flora_tree_oak"; 18 const oTreeLarge = "gaia/flora_tree_oak"; 19 const oBerryBush = "gaia/flora_bush_berry"; 20 const oSheep = "gaia/fauna_sheep"; 21 const oDeer = "gaia/fauna_deer"; 22 const oMine = "gaia/geology_stone_temperate"; 6 23 7 const tGrass = ["grass_temperate_pasture_a", "grass_temperate_pasture_b"]; 8 const tGrassForest = "grass_temperate_a"; 9 const tCliff = ["cliff_temperate_granite", "cliff_temperate_brown"]; 10 const tForest = "forestfloor_temperate_a"; 11 const tGrassDirt75 = "grass_temperate_dirt_2"; 12 const tGrassDirt50 = "grass_temperate_dirt_b"; 13 const tGrassDirt25 = "grass_temperate_dry_dirt"; 14 const tDirt = "dirt_temperate_b_dry"; 15 const tGrassPatch = "grass_temperate_field_wild"; 16 const tShore = "shoreline_temperate_rocks"; 17 const tShoreBlend = "shoreline_temperate_rocks_dirt"; 18 const tWater = "sand_temperate_vegetation"; 24 // decorative props 25 const aGrass = "actor|props/flora/grass_temp_field.xml"; 26 const aGrassShort = "actor|props/flora/grass_field_lush_short.xml"; 27 const aReeds = "actor|props/flora/grass_temp_field_dry.xml"; 28 const aRockLarge = "actor|geology/stone_granite_large.xml"; 29 const aRockMedium = "actor|geology/stone_granite_med.xml"; 30 const aBushMedium = "actor|props/flora/bush_tempe_me.xml"; 31 const aBushSmall = "actor|props/flora/bush_tempe_sm.xml"; 19 32 20 const oTree = "flora_tree_oak"; 21 const oTreeLarge = "flora_tree_oak"; 22 const oBerryBush = "flora_bush_berry"; 23 const oSheep = "fauna_sheep"; 24 const oDeer = "fauna_deer"; 25 const oMine = "geology_stone_temperate"; 26 const oGrass = "props/flora/grass_temp_field.xml"; 27 const oGrassShort = "props/flora/grass_field_lush_short.xml"; 28 const oReeds = "props/flora/grass_temp_field_dry.xml"; 29 const oRockLarge = "geology/stone_granite_large.xml"; 30 const oRockMedium = "flora_bush_temperate"; 31 const oBushMedium = "props/flora/bush_tempe_me.xml"; 32 const oBushSmall = "props/flora/bush_tempe_sm.xml"; 33 log("Initializing map..."); 33 34 34 // initialize map 35 var numPlayers = getNumPlayers(); 36 var mapSize = getMapSize(); 35 37 36 println("Initializing map...");37 init(SIZE, tGrass, 3);38 39 38 // create tile classes 40 39 41 clPlayer = createTileClass(); 42 clHill = createTileClass(); 43 clForest = createTileClass(); 44 clWater = createTileClass(); 45 clSettlement = createTileClass(); 46 clDirt = createTileClass(); 47 clRock = createTileClass(); 48 clFood = createTileClass(); 49 clBaseResource = createTileClass(); 40 var clPlayer = createTileClass(); 41 var clHill = createTileClass(); 42 var clForest = createTileClass(); 43 var clWater = createTileClass(); 44 var clDirt = createTileClass(); 45 var clRock = createTileClass(); 46 var clFood = createTileClass(); 47 var clBaseResource = createTileClass(); 50 48 51 49 // place players 52 50 53 playerX = new Array(NUM_PLAYERS+1);54 playerY = new Array(NUM_PLAYERS+1);55 playerAngle = new Array(NUM_PLAYERS+1);51 var playerX = new Array(numPlayers+1); 52 var playerY = new Array(numPlayers+1); 53 var playerAngle = new Array(numPlayers+1); 56 54 57 startAngle = randFloat() * 2 * PI; 58 for(i=1; i<=NUM_PLAYERS; i++) { 59 playerAngle[i] = startAngle + i*2*PI/NUM_PLAYERS; 55 var startAngle = randFloat() * 2 * PI; 56 for (var i=1; i<=numPlayers; i++) 57 { 58 playerAngle[i] = startAngle + i*2*PI/numPlayers; 60 59 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]); 61 60 playerY[i] = 0.5 + 0.35*sin(playerAngle[i]); 62 61 } 63 62 64 for(i=1; i<=NUM_PLAYERS; i++) { 65 println("Creating base for player " + i + "..."); 63 for (var i=1; i<=numPlayers; i++) 64 { 65 log("Creating base for player " + i + "..."); 66 66 67 67 // some constants 68 radius = 17;69 cliffRadius = 2;70 elevation = 20;68 var radius = 17; 69 var cliffRadius = 2; 70 var elevation = 20; 71 71 72 72 // get the x and y in tiles 73 fx = fractionToTiles(playerX[i]);74 fy = fractionToTiles(playerY[i]);75 ix = round(fx);76 iy = round(fy);73 var fx = fractionToTiles(playerX[i]); 74 var fy = fractionToTiles(playerY[i]); 75 var ix = round(fx); 76 var iy = round(fy); 77 77 78 78 // calculate size based on the radius 79 size = PI * radius * radius;79 var size = PI * radius * radius; 80 80 81 81 // create the hill 82 placer = new ClumpPlacer(size, 0.95, 0.6, 0, ix, iy);83 terrainPainter = new LayeredPainter(84 [ cliffRadius], // widths85 [ tCliff, tGrass] // terrains82 var placer = new ClumpPlacer(size, 0.95, 0.6, 0, ix, iy); 83 var terrainPainter = new LayeredPainter( 84 [tCliff, tGrass], // terrains 85 [cliffRadius] // widths 86 86 ); 87 elevationPainter = new SmoothElevationPainter(87 var elevationPainter = new SmoothElevationPainter( 88 88 ELEVATION_SET, // type 89 89 elevation, // elevation 90 90 cliffRadius // blend radius … … 92 92 createArea(placer, [terrainPainter, elevationPainter, paintClass(clPlayer)], null); 93 93 94 94 // create the ramp 95 rampAngle = playerAngle[i] + PI + (2*randFloat()-1)*PI/8;96 rampDist = radius - 1;97 rampX = round(fx + rampDist * cos(rampAngle));98 rampY = round(fy + rampDist * sin(rampAngle));95 var rampAngle = playerAngle[i] + PI + (2*randFloat()-1)*PI/8; 96 var rampDist = radius - 1; 97 var rampX = round(fx + rampDist * cos(rampAngle)); 98 var rampY = round(fy + rampDist * sin(rampAngle)); 99 99 placer = new ClumpPlacer(100, 0.9, 0.5, 0, rampX, rampY); 100 painter = new SmoothElevationPainter(ELEVATION_SET, elevation-6, 5);100 var painter = new SmoothElevationPainter(ELEVATION_SET, elevation-6, 5); 101 101 createArea(placer, painter, null); 102 102 placer = new ClumpPlacer(75, 0.9, 0.5, 0, rampX, rampY); 103 103 painter = new TerrainPainter(tGrass); … … 106 106 // create the central dirt patch 107 107 placer = new ClumpPlacer(PI*3.5*3.5, 0.3, 0.1, 0, ix, iy); 108 108 painter = new LayeredPainter( 109 [ 1,1,1], // widths110 [ tGrassDirt75, tGrassDirt50, tGrassDirt25, tDirt] // terrains109 [tGrassDirt75, tGrassDirt50, tGrassDirt25, tDirt], // terrains 110 [1,1,1] // widths 111 111 ); 112 112 createArea(placer, painter, null); 113 113 114 // create the TC and the "villies" 115 group = new SimpleGroup( 116 [ // elements (type, count, distance) 117 new SimpleObject("hele_civil_centre", 1,1, 0,0), 118 new SimpleObject("hele_infantry_javelinist_b", 3,3, 5,5) 119 ], 120 true, null, ix, iy 114 // create the TC and citizens 115 var civ = getCivCode(i - 1); 116 var group = new SimpleGroup( // elements (type, min/max count, min/max distance) 117 [new SimpleObject("structures/"+civ+"_civil_centre", 1,1, 0,0), new SimpleObject("units/"+civ+"_support_female_citizen", 3,3, 5,5)], 118 true, null, ix, iy 121 119 ); 122 120 createObjectGroup(group, i); 123 121 124 // Create the Settlement under the TC125 group = new SimpleGroup(126 [new SimpleObject("special_settlement", 1,1, 0,0)],127 true, null, ix, iy128 );129 createObjectGroup(group, 0);130 131 122 // create berry bushes 132 bbAngle = randFloat()*2*PI;133 bbDist = 9;134 bbX = round(fx + bbDist * cos(bbAngle));135 bbY = round(fy + bbDist * sin(bbAngle));123 var bbAngle = randFloat()*2*PI; 124 var bbDist = 9; 125 var bbX = round(fx + bbDist * cos(bbAngle)); 126 var bbY = round(fy + bbDist * sin(bbAngle)); 136 127 group = new SimpleGroup( 137 128 [new SimpleObject(oBerryBush, 5,5, 0,2)], 138 129 true, clBaseResource, bbX, bbY … … 140 131 createObjectGroup(group, 0); 141 132 142 133 // create mines 143 mAngle = bbAngle; 144 while(abs(mAngle - bbAngle) < PI/3) { 134 var mAngle = bbAngle; 135 while(abs(mAngle - bbAngle) < PI/3) 136 { 145 137 mAngle = randFloat()*2*PI; 146 138 } 147 mDist = 9;148 mX = round(fx + mDist * cos(mAngle));149 mY = round(fy + mDist * sin(mAngle));139 var mDist = 9; 140 var mX = round(fx + mDist * cos(mAngle)); 141 var mY = round(fy + mDist * sin(mAngle)); 150 142 group = new SimpleGroup( 151 143 [new SimpleObject(oMine, 4,4, 0,2)], 152 144 true, clBaseResource, mX, mY … … 161 153 createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); 162 154 163 155 // create grass tufts 164 for(j=0; j<10; j++) { 165 gAngle = randFloat()*2*PI; 166 gDist = 6 + randInt(9); 167 gX = round(fx + gDist * cos(gAngle)); 168 gY = round(fy + gDist * sin(gAngle)); 169 group = new SimpleGroup([new SimpleObject(oGrassShort, 3,6, 0,1, -PI/8,PI/8)], 170 false, clBaseResource, gX, gY); 171 createObjectGroup(group, 0); 156 for (var j=0; j < 10; j++) 157 { 158 var gAngle = randFloat()*2*PI; 159 var gDist = 6 + randInt(9); 160 var gX = round(fx + gDist * cos(gAngle)); 161 var gY = round(fy + gDist * sin(gAngle)); 162 group = new SimpleGroup( 163 [new SimpleObject(aGrassShort, 3,6, 0,1, -PI/8,PI/8)], 164 false, clBaseResource, gX, gY 165 ); 166 createObjectGroup(group, undefined); 172 167 } 173 168 } 174 169 175 170 // create lakes 176 println("Creating lakes..."); 171 log("Creating lakes..."); 172 //console.profile(); 177 173 placer = new ClumpPlacer(140, 0.8, 0.1, 0); 178 174 terrainPainter = new LayeredPainter( 179 [ 1,1], // widths180 [ tShoreBlend, tShore, tWater] // terrains175 [tShoreBlend, tShore, tWater], // terrains 176 [1,1] // widths 181 177 ); 182 178 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -7, 3); 183 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clWater)], 179 createAreas( 180 placer, 181 [terrainPainter, elevationPainter, paintClass(clWater)], 184 182 avoidClasses(clPlayer, 2, clWater, 20), 185 round(1.3 * NUM_PLAYERS)183 round(1.3 * numPlayers) 186 184 ); 185 //console.profileEnd(); 187 186 188 187 // create bumps 189 println("Creating bumps...");188 log("Creating bumps..."); 190 189 placer = new ClumpPlacer(10, 0.3, 0.06, 0); 191 190 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2); 192 createAreas(placer, painter, 191 createAreas( 192 placer, 193 painter, 193 194 avoidClasses(clWater, 2, clPlayer, 0), 194 SIZE*SIZE/100195 mapSize*mapSize/100 195 196 ); 196 197 197 198 // create hills 198 println("Creating hills...");199 log("Creating hills..."); 199 200 placer = new ClumpPlacer(30, 0.2, 0.1, 0); 200 201 terrainPainter = new LayeredPainter( 201 [ 3], // widths202 [ tCliff, [tGrass,tGrass,tGrassDirt75]] // terrains202 [tCliff, [tGrass,tGrass,tGrassDirt75]], // terrains 203 [3] // widths 203 204 ); 204 205 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 12, 2); 205 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill)], 206 createAreas( 207 placer, 208 [terrainPainter, elevationPainter, paintClass(clHill)], 206 209 avoidClasses(clPlayer, 2, clWater, 5, clHill, 15), 207 2 * NUM_PLAYERS210 2 * numPlayers 208 211 ); 209 212 210 213 // create forests 211 println("Creating forests...");214 log("Creating forests..."); 212 215 placer = new ClumpPlacer(32, 0.1, 0.1, 0); 213 painter = new LayeredPainter([2], [[tGrassForest, tGrass, tForest], 214 [tGrassForest, tForest]]); 215 createAreas(placer, [painter, paintClass(clForest)], 216 painter = new LayeredPainter( 217 [[tGrassForest, tGrass, tForest], [tGrassForest, tForest]], // terrains 218 [2] // widths 219 ); 220 createAreas( 221 placer, 222 [painter, paintClass(clForest)], 216 223 avoidClasses(clPlayer, 1, clWater, 3, clForest, 10, clHill, 0), 217 6 * NUM_PLAYERS224 6 * numPlayers 218 225 ); 219 226 220 227 // create dirt patches 221 println("Creating dirt patches...");228 log("Creating dirt patches..."); 222 229 var sizes = [8,14,20]; 223 for(i=0; i<sizes.length; i++) { 230 for (i=0; i<sizes.length; i++) 231 { 224 232 placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0); 225 painter = new LayeredPainter([1,1], [ 226 [tGrass,tGrassDirt75],[tGrassDirt75,tGrassDirt50], 227 [tGrassDirt50,tGrassDirt25]]); 228 createAreas(placer, [painter, paintClass(clDirt)], 233 painter = new LayeredPainter( 234 [[tGrass,tGrassDirt75],[tGrassDirt75,tGrassDirt50], [tGrassDirt50,tGrassDirt25]], // terrains 235 [1,1] // widths 236 ); 237 createAreas( 238 placer, 239 [painter, paintClass(clDirt)], 229 240 avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), 230 SIZE*SIZE/4000241 mapSize*mapSize/4000 231 242 ); 232 243 } 233 244 234 245 // create grass patches 235 println("Creating grass patches...");246 log("Creating grass patches..."); 236 247 var sizes = [5,9,13]; 237 for(i=0; i<sizes.length; i++) { 248 for (i=0; i<sizes.length; i++) 249 { 238 250 placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0); 239 251 painter = new TerrainPainter(tGrassPatch); 240 createAreas(placer, painter, 252 createAreas( 253 placer, 254 painter, 241 255 avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), 242 SIZE*SIZE/4000256 mapSize*mapSize/4000 243 257 ); 244 258 } 245 259 246 260 // create mines 247 println("Creating mines..."); 248 group = new SimpleGroup([new SimpleObject(oMine, 4,6, 0,2)], true, clRock); 249 createObjectGroups(group, 0, 261 log("Creating mines..."); 262 group = new SimpleGroup( 263 [new SimpleObject(oMine, 4,6, 0,2)], 264 true, clRock 265 ); 266 createObjectGroups( 267 group, 0, 250 268 [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clRock, 13), 251 269 new BorderTileClassConstraint(clHill, 0, 4)], 252 3 * NUM_PLAYERS, 100270 3 * numPlayers, 100 253 271 ); 254 272 255 // create settlements256 println("Creating settlements...");257 group = new SimpleGroup([new SimpleObject("special_settlement", 1,1, 0,0)], true, clSettlement);258 createObjectGroups(group, 0,259 avoidClasses(clWater, 0, clForest, 0, clPlayer, 15, clHill, 0, clRock, 5, clSettlement, 35),260 2 * NUM_PLAYERS, 50261 );262 263 273 // create small decorative rocks 264 println("Creating large decorative rocks..."); 265 group = new SimpleGroup([new SimpleObject(oRockMedium, 1,3, 0,1)], true); 266 createObjectGroups(group, 0, 267 avoidClasses(clForest, 0, clPlayer, 0, clHill, 0, clSettlement, 3), 268 SIZE*SIZE/1000, 50 274 log("Creating large decorative rocks..."); 275 group = new SimpleGroup( 276 [new SimpleObject(aRockMedium, 1,3, 0,1)], 277 true 269 278 ); 279 createObjectGroups( 280 group, undefined, 281 avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), 282 mapSize*mapSize/1000, 50 283 ); 270 284 271 285 // create large decorative rocks 272 println("Creating large decorative rocks..."); 273 group = new SimpleGroup([new SimpleObject(oRockLarge, 1,2, 0,1), 274 new SimpleObject(oRockMedium, 1,3, 0,2)], true); 275 createObjectGroups(group, 0, 276 avoidClasses(clForest, 0, clPlayer, 0, clHill, 0, clSettlement, 5), 277 SIZE*SIZE/2000, 50 286 log("Creating large decorative rocks..."); 287 group = new SimpleGroup( 288 [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], 289 true 278 290 ); 291 createObjectGroups( 292 group, undefined, 293 avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), 294 mapSize*mapSize/2000, 50 295 ); 279 296 280 297 // create deer 281 println("Creating deer..."); 282 group = new SimpleGroup([new SimpleObject(oDeer, 5,7, 0,4)], true, clFood); 298 log("Creating deer..."); 299 group = new SimpleGroup( 300 [new SimpleObject(oDeer, 5,7, 0,4)], 301 true, clFood 302 ); 283 303 createObjectGroups(group, 0, 284 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20 , clSettlement, 5),285 3 * NUM_PLAYERS, 50304 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20), 305 3 * numPlayers, 50 286 306 ); 287 307 288 308 // create sheep 289 println("Creating sheep..."); 290 group = new SimpleGroup([new SimpleObject(oSheep, 2,3, 0,2)], true, clFood); 309 log("Creating sheep..."); 310 group = new SimpleGroup( 311 [new SimpleObject(oSheep, 2,3, 0,2)], 312 true, clFood 313 ); 291 314 createObjectGroups(group, 0, 292 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20 , clSettlement, 5),293 3 * NUM_PLAYERS, 50315 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20), 316 3 * numPlayers, 50 294 317 ); 295 318 296 319 // create straggler trees 297 println("Creating straggler trees..."); 298 group = new SimpleGroup([new SimpleObject(oTree, 1,1, 0,0)], true); 320 log("Creating straggler trees..."); 321 group = new SimpleGroup( 322 [new SimpleObject(oTree, 1,1, 0,0)], 323 true 324 ); 299 325 createObjectGroups(group, 0, 300 avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 1 , clSettlement, 2),301 SIZE*SIZE/1100326 avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 1), 327 mapSize*mapSize/1100 302 328 ); 303 329 304 330 // create small grass tufts 305 println("Creating small grass tufts..."); 306 group = new SimpleGroup([new SimpleObject(oGrassShort, 3,6, 0,1, -PI/8,PI/8)]); 307 createObjectGroups(group, 0, 331 log("Creating small grass tufts..."); 332 group = new SimpleGroup( 333 [new SimpleObject(aGrassShort, 3,6, 0,1, -PI/8,PI/8)] 334 ); 335 createObjectGroups(group, undefined, 308 336 avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), 309 SIZE*SIZE/90337 mapSize*mapSize/90 310 338 ); 311 339 312 340 // create large grass tufts 313 println("Creating large grass tufts..."); 314 group = new SimpleGroup([new SimpleObject(oGrass, 20,30, 0,1.8, -PI/8,PI/8), 315 new SimpleObject(oGrassShort, 20,30, 1.2,2.5, -PI/8,PI/8)]); 316 createObjectGroups(group, 0, 341 log("Creating large grass tufts..."); 342 group = new SimpleGroup( 343 [new SimpleObject(aGrass, 20,30, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 20,30, 1.2,2.5, -PI/8,PI/8)] 344 ); 345 createObjectGroups(group, undefined, 317 346 avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), 318 SIZE*SIZE/900347 mapSize*mapSize/900 319 348 ); 320 349 321 350 // create bushes 322 println("Creating bushes..."); 323 group = new SimpleGroup([new SimpleObject(oBushSmall, 2,4, 0,2)]); 324 createObjectGroups(group, 0, 351 log("Creating bushes..."); 352 group = new SimpleGroup( 353 [new SimpleObject(aBushSmall, 2,4, 0,2)] 354 ); 355 createObjectGroups(group, undefined, 325 356 avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), 326 SIZE*SIZE/2000, 50357 mapSize*mapSize/2000, 50 327 358 ); 328 359 329 360 // create reeds 330 println("Creating reeds..."); 331 group = new SimpleGroup([new SimpleObject(oReeds, 5,10, 0,1.5, -PI/8,PI/8)]); 332 createObjectGroups(group, 0, 361 log("Creating reeds..."); 362 group = new SimpleGroup( 363 [new SimpleObject(aReeds, 5,10, 0,1.5, -PI/8,PI/8)] 364 ); 365 createObjectGroups(group, undefined, 333 366 [new BorderTileClassConstraint(clWater, 3, 0), new StayInTileClassConstraint(clWater, 1)], 334 10 * NUM_PLAYERS, 100367 10 * numPlayers, 100 335 368 ); 336 -
binaries/data/mods/public/maps/random/cantabrian_highlands.json
1 { 2 "settings" : { 3 "Name" : "Cantabrian Highlands", 4 "Script" : "cantabrian_highlands.js", 5 "Description" : "A test of the Cantabrian Highlands script", 6 "BaseTerrain" : ["medit_grass_field_a", "medit_grass_field_b"], 7 "BaseHeight" : 3, 8 "RevealMap": true, 9 "GameType": "endless", 10 "XXXXXX" : "Optionally define other things here, like we would for a scenario" 11 } 12 } 13 No newline at end of file -
binaries/data/mods/public/maps/random/latium.js
Property changes on: binaries\data\mods\public\maps\random\cantabrian_highlands.json ___________________________________________________________________ Added: svn:eol-style + native
1 const SIZE = 176;2 const NUM_PLAYERS = 4;3 const WATER_WIDTH = .2;4 5 // Terrain and object constants6 7 tOceanDepths = "ocean_medit_depths";8 tOceanRockDeep = "ocean_medit_rock_deep";9 tOceanRockShallow = "ocean_medit_rock_shallow";10 tOceanCoral = "ocean_medit_coral";11 tBeachWet = "beach_medit_wet";12 tBeachDry = "beach_medit_dry";13 tBeachGrass = "beach_medit_grass_50";14 tBeachCliff = "cliff_medit_beach";15 tGrassDry = ["grass_mediterranean_dry_a", "grass_mediterranean_dry_b", "grass_mediterranean_dry_c"];16 tGrass = ["grass_mediterranean_green_50", "grass_mediterranean_green_flowers"];17 tGrassLush = ["grass_temperate_dry_tufts", "grass_mediterranean_green_flowers"];18 tGrassShrubs = ["grass_mediterranean_green_shrubs", "grass_mediterranean_green_flowers"];19 tGrassRock = ["grass_mediterranean_green_rock"];20 tDirt = "dirt_medit_a";21 tDirtGrass = "dirt_medit_grass_50";22 tDirtCliff = "cliff_medit_dirt";23 tGrassCliff = "cliff_medit_grass_a";24 tCliff = ["cliff_medit_face_b", "cliff_medit_face_b", "cliff_medit_foliage_a"];25 tForestFloor = "forestfloor_medit_dirt";26 27 oPalm = "flora_tree_medit_fan_palm";28 oLombardyPoplar = "flora_tree_poplar_lombardy";29 oOak = "flora_tree_oak";30 oPoplar = "flora_tree_poplar";31 oCarob = "flora_tree_carob";32 oBeech = "flora_tree_euro_beech";33 oPine = "flora_tree_aleppo_pine";34 oBerryBush = "flora_bush_berry";35 oSheep = "fauna_sheep";36 oStone = "geology_stone_greek";37 oMetal = "geology_metal_greek";38 oBushLargeDry = "props/flora/bush_medit_la_dry.xml";39 oBushLarge = "props/flora/bush_medit_la.xml";40 oBushMedDry = "props/flora/bush_medit_me_dry.xml";41 oBushMed = "props/flora/bush_medit_me.xml";42 oBushSmall = "props/flora/bush_medit_sm.xml"43 oBushSmallDry = "props/flora/bush_medit_sm_dry.xml"44 oGrass = "props/flora/grass_medit_field.xml";45 oGrassDry = "props/flora/grass_soft_dry_small.xml";46 oRockLarge = "geology/stone_granite_greek_large.xml";47 oRockMed = "geology/stone_granite_greek_med.xml";48 oRockSmall = "geology/stone_granite_greek_small.xml";49 oWaterLog = "props/flora/water_log.xml";50 51 tPalmForest = [tForestFloor+"|"+oPalm, tGrass];52 tPineForest = [tForestFloor+"|"+oPine, tGrass];53 tMainForest = [tForestFloor+"|"+oCarob, tForestFloor+"|"+oBeech, tGrass, tGrass];54 tPoplarForest = [tForestFloor+"|"+oLombardyPoplar, tGrass];55 56 // Initialize world57 58 init(SIZE, tGrass, 0);59 60 // Create classes61 62 clWater = createTileClass();63 clCliff = createTileClass();64 clForest = createTileClass();65 clMetal = createTileClass();66 clStone = createTileClass();67 clFood = createTileClass();68 clPlayer = createTileClass();69 clBaseResource = createTileClass();70 clSettlement = createTileClass();71 72 // Place players73 74 println("Placing players...");75 76 playerX = new Array(NUM_PLAYERS+1);77 playerY = new Array(NUM_PLAYERS+1);78 79 numLeftPlayers = Math.floor(NUM_PLAYERS/2);80 for(i=1; i<=numLeftPlayers; i++) {81 playerX[i] = 0.28 + (2*randFloat()-1)*0.01;82 playerY[i] = (0.5+i-1)/numLeftPlayers + (2*randFloat()-1)*0.01;83 }84 for(i=numLeftPlayers+1; i<=NUM_PLAYERS; i++) {85 playerX[i] = 0.72 + (2*randFloat()-1)*0.01;86 playerY[i] = (0.5+i-numLeftPlayers-1)/numLeftPlayers + (2*randFloat()-1)*0.01;87 }88 89 for(i=1; i<=NUM_PLAYERS; i++) {90 // get fractional locations in tiles91 ix = round(fractionToTiles(playerX[i]));92 iy = round(fractionToTiles(playerY[i]));93 addToClass(ix, iy, clPlayer);94 95 // create TC and starting units96 placeObject("special_settlement", i, ix, iy, PI*3/4);97 placeObject("hele_civil_centre", i, ix, iy, PI*3/4);98 group = new SimpleGroup(99 [new SimpleObject("hele_infantry_javelinist_b", 3,3, 5,5)],100 true, null, ix, iy101 );102 createObjectGroup(group, i);103 104 // create starting berry bushes105 bbAngle = randFloat()*2*PI;106 bbDist = 9;107 bbX = round(ix + bbDist * cos(bbAngle));108 bbY = round(iy + bbDist * sin(bbAngle));109 group = new SimpleGroup(110 [new SimpleObject(oBerryBush, 5,5, 0,2)],111 true, clBaseResource, bbX, bbY112 );113 createObjectGroup(group, 0);114 115 // create starting mines116 mAngle = bbAngle;117 while(abs(mAngle - bbAngle) < PI/3) {118 mAngle = randFloat()*2*PI;119 }120 mDist = 9;121 mX = round(ix + mDist * cos(mAngle));122 mY = round(iy + mDist * sin(mAngle));123 group = new SimpleGroup(124 [new SimpleObject(oStone, 2,2, 0,3),125 new SimpleObject(oMetal, 2,2, 0,3)],126 true, clBaseResource, mX, mY127 );128 createObjectGroup(group, 0);129 130 // create starting straggler trees131 group = new SimpleGroup(132 [new SimpleObject(oPalm, 3,3, 7,10)],133 true, clBaseResource, ix, iy134 );135 createObjectGroup(group, 0, avoidClasses(clBaseResource,2));136 }137 138 function distanceToPlayers(x, y) {139 var r = 10000;140 for(var i=1; i<=NUM_PLAYERS; i++) {141 var dx = x-playerX[i];142 var dy = y-playerY[i];143 r = min(r, dx*dx + dy*dy);144 }145 return Math.sqrt(r);146 }147 148 function playerNearness(x, y) {149 var d = fractionToTiles(distanceToPlayers(x,y));150 if(d < 13) return 0;151 else if(d < 19) return (d-13)/(19-13);152 else return 1;153 }154 155 function max(x, y) {156 return x > y ? x : y;157 }158 159 function min(x, y) {160 return x < y ? x : y;161 }162 163 // Paint elevation164 165 println("Painting elevation...");166 167 noise0 = new Noise2D(4 * SIZE/128);168 noise1 = new Noise2D(8 * SIZE/128);169 noise2 = new Noise2D(15 * SIZE/128);170 171 noise2a = new Noise2D(20 * SIZE/128);172 noise2b = new Noise2D(35 * SIZE/128);173 174 noise3 = new Noise2D(4 * SIZE/128);175 noise4 = new Noise2D(6 * SIZE/128);176 noise5 = new Noise2D(11 * SIZE/128);177 178 for(ix=0; ix<=SIZE; ix++) {179 for(iy=0; iy<=SIZE; iy++) {180 x = ix / (SIZE + 1.0);181 y = iy / (SIZE + 1.0);182 pn = playerNearness(x, y);183 184 h = 0;185 distToWater = 0;186 187 h = 32 * (x-.5);188 189 190 // add the rough shape of the water191 if(x < WATER_WIDTH) {192 h = max(-16.0, -28.0*(WATER_WIDTH-x)/WATER_WIDTH);193 }194 else if(x > 1.0-WATER_WIDTH) {195 h = max(-16.0, -28.0*(x-(1.0-WATER_WIDTH))/WATER_WIDTH);196 }197 else {198 distToWater = (0.5 - WATER_WIDTH - Math.abs(x-0.5));199 u = 1 - Math.abs(x-0.5) / (0.5-WATER_WIDTH);200 h = 12*u;201 }202 203 // add some base noise204 baseNoise = 16*noise0.eval(x,y) + 8*noise1.eval(x,y) + 4*noise2.eval(x,y) - (16+8+4)/2;205 if( baseNoise < 0 ) {206 baseNoise *= pn;207 baseNoise *= max(0.1, distToWater / (0.5-WATER_WIDTH));208 }209 oldH = h;210 h += baseNoise;211 212 // add some higher-frequency noise on land213 if( oldH > 0 )214 {215 h += (0.4*noise2a.eval(x,y) + 0.2*noise2b.eval(x,y)) * min(oldH/10.0, 1.0);216 }217 218 // create cliff noise219 if( h > -10 )220 {221 cliffNoise = (1*noise3.eval(x,y) + 0.5*noise4.eval(x,y)) / 1.5;222 if(h < 1) {223 u = 1 - .3*((h-1)/-10);224 cliffNoise *= u;225 }226 cliffNoise += .05 * distToWater / (0.5 - WATER_WIDTH);227 if(cliffNoise > .6) {228 u = 0.8 * (cliffNoise-.6);229 cliffNoise += u * noise5.eval(x,y);230 cliffNoise /= (1+u);231 }232 cliffNoise -= 0.59;233 cliffNoise *= pn;234 if(cliffNoise > 0) {235 h += 19 * min(cliffNoise, 0.045) / 0.045;236 }237 }238 239 // set the height240 setHeight(ix, iy, h);241 }242 }243 244 // Paint base terrain245 246 println("Painting terrain...");247 248 noise6 = new Noise2D(10 * SIZE/128);249 noise7 = new Noise2D(20 * SIZE/128);250 251 noise8 = new Noise2D(13 * SIZE/128);252 noise9 = new Noise2D(26 * SIZE/128);253 254 noise10 = new Noise2D(50 * SIZE/128);255 256 for(ix=0; ix<SIZE; ix++) {257 for(iy=0; iy<SIZE; iy++) {258 x = ix / (SIZE + 1.0);259 y = iy / (SIZE + 1.0);260 pn = playerNearness(x, y);261 262 // get heights of surrounding vertices263 h00 = getHeight(ix, iy);264 h01 = getHeight(ix, iy+1);265 h10 = getHeight(ix+1, iy);266 h11 = getHeight(ix+1, iy+1);267 268 // find min and max height269 maxH = max(h00, h01, h10, h11);270 minH = min(h00, h01, h10, h11);271 272 // figure out if we're at the top of a cliff using min adjacent height273 minAdjHeight = minH;274 if(maxH > 15) {275 for(nx=max(ix-1, 0); nx<=min(ix+2, SIZE); nx++) {276 for(ny=max(iy-1, 0); ny<=min(iy+2, SIZE); ny++) {277 minAdjHeight = min(minAdjHeight, getHeight(nx, ny));278 }279 }280 }281 282 // choose a terrain based on elevation283 t = tGrass;284 285 // water286 if(maxH < -12) {287 t = tOceanDepths;288 }289 else if(maxH < -8.8) {290 t = tOceanRockDeep;291 }292 else if(maxH < -4.7) {293 t = tOceanCoral;294 }295 else if(maxH < -2.8) {296 t = tOceanRockShallow;297 }298 else if(maxH < .9 && minH < .35) {299 t = tBeachWet;300 }301 else if(maxH < 1.5 && minH < .9) {302 t = tBeachDry;303 }304 else if(maxH < 2.3 && minH < 1.3) {305 t = tBeachGrass;306 }307 308 if(minH < 0) {309 addToClass(ix, iy, clWater);310 }311 312 // cliffs313 if(maxH - minH > 2.9 && minH > -7) {314 t = tCliff;315 addToClass(ix, iy, clCliff);316 }317 else if((maxH - minH > 2.5 && minH > -5) || (maxH-minAdjHeight > 2.9 && minH > 0) ) {318 if(minH < -1) t = tCliff;319 else if(minH < .5) t = tBeachCliff;320 else t = [tDirtCliff, tGrassCliff, tGrassCliff, tGrassRock, tCliff];321 addToClass(ix, iy, clCliff);322 }323 324 // forests325 if(maxH - minH < 1 && minH > 1) {326 forestNoise = (noise6.eval(x,y) + 0.5*noise7.eval(x,y)) / 1.5 * pn;327 forestNoise -= 0.59;328 if(forestNoise > 0) {329 if(minH > 5) {330 typeNoise = noise10.eval(x,y);331 if(typeNoise < .43 && forestNoise < .05) t = tPoplarForest;332 else if(typeNoise < .63) t = tMainForest;333 else t = tPineForest;334 addToClass(ix, iy, clForest);335 }336 else if(minH < 3) {337 t = tPalmForest;338 addToClass(ix, iy, clForest);339 }340 }341 }342 343 // grass variations344 if(t==tGrass)345 {346 grassNoise = (noise8.eval(x,y) + .6*noise9.eval(x,y)) / 1.6;347 if(grassNoise < .3) {348 t = (maxH - minH > 1.2) ? tDirtCliff : tDirt;349 }350 else if(grassNoise < .34) {351 t = (maxH - minH > 1.2) ? tGrassCliff : tGrassDry;352 if(maxH - minH < .5 && randFloat() < .03) {353 placeObject(oGrassDry, 0, ix+randFloat(), iy+randFloat(), randFloat()*2*Math.PI);354 }355 }356 else if(grassNoise > .61) {357 t = (maxH - minH > 1.2) ? tGrassRock : tGrassShrubs;358 }359 else {360 if(maxH - minH < .5 && randFloat() < .05) {361 placeObject(oGrass, 0, ix+randFloat(), iy+randFloat(), randFloat()*2*Math.PI);362 }363 }364 }365 366 placeTerrain(ix, iy, t);367 }368 }369 370 println("Placing object groups...");371 372 // create settlements373 group = new SimpleGroup([new SimpleObject("special_settlement", 1,1, 0,0)], true, clSettlement);374 createObjectGroups(group, 0,375 avoidClasses(clWater, 5, clForest, 4, clPlayer, 25, clCliff, 4, clSettlement, 35),376 2 * NUM_PLAYERS, 50377 );378 379 // create straggler trees380 trees = [oCarob, oBeech, oLombardyPoplar, oLombardyPoplar, oPine]381 for(t in trees) {382 group = new SimpleGroup([new SimpleObject(trees[t], 1,1, 0,1)], true, clForest);383 createObjectGroups(group, 0,384 avoidClasses(clWater, 5, clCliff, 0, clForest, 1, clSettlement, 4, clPlayer, 15),385 SIZE*SIZE/7000, 50386 );387 }388 389 // create cypresses390 group = new SimpleGroup([391 new SimpleObject("flora/trees/cypress2.xml", 1,3, 0,3),392 new SimpleObject("flora/trees/cypress1.xml", 0,2, 0,2)]);393 createObjectGroups(group, 0,394 avoidClasses(clWater, 4, clCliff, 2, clForest, 1, clSettlement, 4, clPlayer, 15),395 SIZE*SIZE/3500, 50396 );397 398 // create bushes399 group = new SimpleGroup([400 new SimpleObject(oBushSmall, 0,2, 0,2),401 new SimpleObject(oBushSmallDry, 0,2, 0,2),402 new SimpleObject(oBushMed, 0,1, 0,2),403 new SimpleObject(oBushMedDry, 0,1, 0,2)]);404 createObjectGroups(group, 0,405 avoidClasses(clWater, 4, clCliff, 2),406 SIZE*SIZE/1800, 50407 );408 409 // create rocks410 group = new SimpleGroup([411 new SimpleObject(oRockSmall, 0,3, 0,2),412 new SimpleObject(oRockMed, 0,2, 0,2),413 new SimpleObject(oRockLarge, 0,1, 0,2)]);414 createObjectGroups(group, 0,415 avoidClasses(clWater, 0, clCliff, 0),416 SIZE*SIZE/1800, 50417 );418 419 // create stone420 group = new SimpleGroup([new SimpleObject(oStone, 2,3, 0,2)], true, clStone);421 createObjectGroups(group, 0,422 [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clStone, 15, clSettlement, 4),423 new BorderTileClassConstraint(clCliff, 0, 5)],424 3 * NUM_PLAYERS, 100425 );426 427 // create metal428 group = new SimpleGroup([new SimpleObject(oMetal, 2,3, 0,2)], true, clMetal);429 createObjectGroups(group, 0,430 [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clMetal, 15, clStone, 5, clSettlement, 4),431 new BorderTileClassConstraint(clCliff, 0, 5)],432 3 * NUM_PLAYERS, 100433 );434 435 // create sheep436 group = new SimpleGroup([new SimpleObject(oSheep, 2,4, 0,2)], true, clFood);437 createObjectGroups(group, 0,438 avoidClasses(clWater, 5, clForest, 1, clCliff, 1, clPlayer, 20,439 clMetal, 2, clStone, 2, clFood, 8, clSettlement, 4),440 3 * NUM_PLAYERS, 100441 );442 443 // create berry bushes444 group = new SimpleGroup([new SimpleObject(oBerryBush, 5,7, 0,3)], true, clFood);445 createObjectGroups(group, 0,446 avoidClasses(clWater, 5, clForest, 1, clCliff, 1, clPlayer, 20,447 clMetal, 2, clStone, 2, clFood, 8, clSettlement, 4),448 1.5 * NUM_PLAYERS, 100449 ); -
binaries/data/mods/public/maps/random/latium.js
1 const WATER_WIDTH = 0.2; 2 3 // terrain textures 4 const tOceanDepths = "medit_sea_depths"; 5 const tOceanRockDeep = "medit_sea_coral_deep"; 6 const tOceanRockShallow = "medit_rocks_wet"; 7 const tOceanCoral = "medit_sea_coral_plants"; 8 const tBeachWet = "medit_sand_wet"; 9 const tBeachDry = "medit_sand"; 10 const tBeachGrass = "beach_medit_grass_50"; 11 const tBeachCliff = "cliff_medit_beach"; 12 const tGrassDry = ["medit_grass_field_brown", "medit_grass_field_dry", "medit_grass_field_b"]; 13 const tGrass = ["medit_grass_field", "medit_grass_field_a", "medit_grass_flowers"]; 14 const tGrassLush = ["grass_temperate_dry_tufts", "medit_grass_flowers"]; 15 const tGrassShrubs = ["medit_grass_shrubs", "medit_grass_flowers"]; 16 const tGrassRock = ["medit_rocks_grass"]; 17 const tDirt = "medit_dirt"; 18 const tDirtGrass = "medit_dirt_b"; 19 const tDirtCliff = "medit_cliff_italia"; 20 const tGrassCliff = "medit_cliff_italia_grass"; 21 const tCliff = ["medit_cliff_italia", "medit_cliff_italia", "medit_cliff_italia_grass"]; 22 const tForestFloor = "forestfloor_medit_dirt"; 23 24 // gaia entities 25 const oBeech = "gaia/flora_tree_euro_beech"; 26 const oBerryBush = "gaia/flora_bush_berry"; 27 const oCarob = "gaia/flora_tree_carob"; 28 const oCypress1 = "gaia/flora_tree_cypress"; 29 const oCypress2 = "gaia/flora_tree_cypress"; 30 const oLombardyPoplar = "gaia/flora_tree_poplar_lombardy"; 31 const oOak = "gaia/flora_tree_oak"; 32 const oPalm = "gaia/flora_tree_medit_fan_palm"; 33 const oPine = "gaia/flora_tree_aleppo_pine"; 34 const oPoplar = "gaia/flora_tree_poplar"; 35 const oSheep = "gaia/fauna_sheep"; 36 const oStone = "gaia/geology_stone_greek"; 37 const oMetal = "gaia/geology_metal_greek"; 38 39 // decorative props 40 const aBushLargeDry = "actor|props/flora/bush_medit_la_dry.xml"; 41 const aBushLarge = "actor|props/flora/bush_medit_la.xml"; 42 const aBushMedDry = "actor|props/flora/bush_medit_me_dry.xml"; 43 const aBushMed = "actor|props/flora/bush_medit_me.xml"; 44 const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; 45 const aBushSmallDry = "actor|props/flora/bush_medit_sm_dry.xml"; 46 const aGrass = "actor|props/flora/grass_medit_field.xml"; 47 const aGrassDry = "actor|props/flora/grass_soft_dry_small.xml"; 48 const aRockLarge = "actor|geology/stone_granite_greek_large.xml"; 49 const aRockMed = "actor|geology/stone_granite_greek_med.xml"; 50 const aRockSmall = "actor|geology/stone_granite_greek_small.xml"; 51 const aWaterLog = "actor|props/flora/water_log.xml"; 52 53 // forests - we have the option of specifying terrain and tree type in one string, using TERRAIN_SEPARATOR 54 var tPalmForest = [tForestFloor+TERRAIN_SEPARATOR+oPalm, tGrass]; 55 var tPineForest = [tForestFloor+TERRAIN_SEPARATOR+oPine, tGrass]; 56 var tMainForest = [tForestFloor+TERRAIN_SEPARATOR+oCarob, tForestFloor+TERRAIN_SEPARATOR+oBeech, tGrass, tGrass]; 57 var tPoplarForest = [tForestFloor+TERRAIN_SEPARATOR+oLombardyPoplar, tGrass]; 58 59 // Initialize world 60 61 log("Initializing map..."); 62 63 var numPlayers = getNumPlayers(); 64 var mapSize = getMapSize(); 65 66 // Create classes 67 68 var clWater = createTileClass(); 69 var clCliff = createTileClass(); 70 var clForest = createTileClass(); 71 var clMetal = createTileClass(); 72 var clStone = createTileClass(); 73 var clFood = createTileClass(); 74 var clPlayer = createTileClass(); 75 var clBaseResource = createTileClass(); 76 77 // Place players 78 79 log("Placing players..."); 80 81 var playerX = new Array(numPlayers+1); 82 var playerY = new Array(numPlayers+1); 83 84 var numLeftPlayers = floor(numPlayers/2); 85 for (var i=1; i <= numLeftPlayers; i++) 86 { 87 playerX[i] = 0.28 + (2*randFloat()-1)*0.01; 88 playerY[i] = (0.5+i-1)/numLeftPlayers + (2*randFloat()-1)*0.01; 89 } 90 for (var i=numLeftPlayers+1; i <= numPlayers; i++) 91 { 92 playerX[i] = 0.72 + (2*randFloat()-1)*0.01; 93 playerY[i] = (0.5+i-numLeftPlayers-1)/numLeftPlayers + (2*randFloat()-1)*0.01; 94 } 95 96 for (var i=1; i <= numPlayers; i++) 97 { 98 log("Creating base for player " + i + "..."); 99 100 // get fractional locations in tiles 101 var ix = round(fractionToTiles(playerX[i])); 102 var iy = round(fractionToTiles(playerY[i])); 103 addToClass(ix, iy, clPlayer); 104 105 // create TC and starting units 106 // TODO: Get civ specific starting units 107 var civ = getCivCode(i - 1); 108 placeObject("structures/"+civ + "_civil_centre", i, ix, iy, PI*3/4); 109 var group = new SimpleGroup( 110 [new SimpleObject("units/"+civ+"_support_female_citizen", 3,3, 5,5)], 111 true, null, ix, iy 112 ); 113 createObjectGroup(group, i); 114 115 // create starting berry bushes 116 var bbAngle = randFloat()*2*PI; 117 var bbDist = 9; 118 var bbX = round(ix + bbDist * cos(bbAngle)); 119 var bbY = round(iy + bbDist * sin(bbAngle)); 120 group = new SimpleGroup( 121 [new SimpleObject(oBerryBush, 5,5, 0,2)], 122 true, clBaseResource, bbX, bbY 123 ); 124 createObjectGroup(group, 0); 125 126 // create starting mines 127 var mAngle = bbAngle; 128 while(abs(mAngle - bbAngle) < PI/3) { 129 mAngle = randFloat()*2*PI; 130 } 131 var mDist = 9; 132 var mX = round(ix + mDist * cos(mAngle)); 133 var mY = round(iy + mDist * sin(mAngle)); 134 group = new SimpleGroup( 135 [new SimpleObject(oStone, 2,2, 0,3), 136 new SimpleObject(oMetal, 2,2, 0,3)], 137 true, clBaseResource, mX, mY 138 ); 139 createObjectGroup(group, 0); 140 141 // create starting straggler trees 142 group = new SimpleGroup( 143 [new SimpleObject(oPalm, 3,3, 7,10)], 144 true, clBaseResource, ix, iy 145 ); 146 createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); 147 } 148 149 function distanceToPlayers(x, y) 150 { 151 var r = 10000; 152 for (var i=1; i <= numPlayers; i++) 153 { 154 var dx = x - playerX[i]; 155 var dy = y - playerY[i]; 156 r = min(r, dx*dx + dy*dy); 157 } 158 return sqrt(r); 159 } 160 161 function playerNearness(x, y) 162 { 163 var d = fractionToTiles(distanceToPlayers(x,y)); 164 165 if (d < 13) 166 return 0; 167 else if (d < 19) 168 return (d-13)/(19-13); 169 else 170 return 1; 171 } 172 173 // Paint elevation 174 175 log("Painting elevation..."); 176 177 var noise0 = new Noise2D(4 * mapSize/128); 178 var noise1 = new Noise2D(8 * mapSize/128); 179 var noise2 = new Noise2D(15 * mapSize/128); 180 181 var noise2a = new Noise2D(20 * mapSize/128); 182 var noise2b = new Noise2D(35 * mapSize/128); 183 184 var noise3 = new Noise2D(4 * mapSize/128); 185 var noise4 = new Noise2D(6 * mapSize/128); 186 var noise5 = new Noise2D(11 * mapSize/128); 187 188 for (var ix=0; ix<=mapSize; ix++) 189 { 190 for (var iy=0; iy<=mapSize; iy++) 191 { 192 var x = ix / (mapSize + 1.0); 193 var y = iy / (mapSize + 1.0); 194 var pn = playerNearness(x, y); 195 196 var h = 0; 197 var distToWater = 0; 198 199 h = 32 * (x - 0.5); 200 201 // add the rough shape of the water 202 if (x < WATER_WIDTH) 203 { 204 h = max(-16.0, -28.0*(WATER_WIDTH-x)/WATER_WIDTH); 205 } 206 else if (x > 1.0-WATER_WIDTH) 207 { 208 h = max(-16.0, -28.0*(x-(1.0-WATER_WIDTH))/WATER_WIDTH); 209 } 210 else 211 { 212 distToWater = (0.5 - WATER_WIDTH - abs(x-0.5)); 213 var u = 1 - abs(x-0.5) / (0.5-WATER_WIDTH); 214 h = 12*u; 215 } 216 217 // add some base noise 218 var baseNoise = 16*noise0.get(x,y) + 8*noise1.get(x,y) + 4*noise2.get(x,y) - (16+8+4)/2; 219 if ( baseNoise < 0 ) 220 { 221 baseNoise *= pn; 222 baseNoise *= max(0.1, distToWater / (0.5-WATER_WIDTH)); 223 } 224 var oldH = h; 225 h += baseNoise; 226 227 // add some higher-frequency noise on land 228 if ( oldH > 0 ) 229 { 230 h += (0.4*noise2a.get(x,y) + 0.2*noise2b.get(x,y)) * min(oldH/10.0, 1.0); 231 } 232 233 // create cliff noise 234 if ( h > -10 ) 235 { 236 var cliffNoise = (noise3.get(x,y) + 0.5*noise4.get(x,y)) / 1.5; 237 if (h < 1) 238 { 239 var u = 1 - 0.3*((h-1)/-10); 240 cliffNoise *= u; 241 } 242 cliffNoise += 0.05 * distToWater / (0.5 - WATER_WIDTH); 243 if (cliffNoise > 0.6) 244 { 245 var u = 0.8 * (cliffNoise - 0.6); 246 cliffNoise += u * noise5.get(x,y); 247 cliffNoise /= (1 + u); 248 } 249 cliffNoise -= 0.59; 250 cliffNoise *= pn; 251 if (cliffNoise > 0) 252 { 253 h += 19 * min(cliffNoise, 0.045) / 0.045; 254 } 255 } 256 257 // set the height 258 setHeight(ix, iy, h); 259 } 260 } 261 262 // Paint base terrain 263 264 log("Painting terrain..."); 265 266 var noise6 = new Noise2D(10 * mapSize/128); 267 var noise7 = new Noise2D(20 * mapSize/128); 268 269 var noise8 = new Noise2D(13 * mapSize/128); 270 var noise9 = new Noise2D(26 * mapSize/128); 271 272 var noise10 = new Noise2D(50 * mapSize/128); 273 274 for (var ix=0; ix<mapSize; ix++) 275 { 276 for (var iy=0; iy<mapSize; iy++) 277 { 278 var x = ix / (mapSize + 1.0); 279 var y = iy / (mapSize + 1.0); 280 var pn = playerNearness(x, y); 281 282 // get heights of surrounding vertices 283 var h00 = getHeight(ix, iy); 284 var h01 = getHeight(ix, iy+1); 285 var h10 = getHeight(ix+1, iy); 286 var h11 = getHeight(ix+1, iy+1); 287 288 // find min and max height 289 var maxH = Math.max(h00, h01, h10, h11); 290 var minH = Math.min(h00, h01, h10, h11); 291 292 // figure out if we're at the top of a cliff using min adjacent height 293 var minAdjHeight = minH; 294 if (maxH > 15) 295 { 296 var maxNx = min(ix+2, mapSize); 297 var maxNy = min(iy+2, mapSize); 298 for (var nx=max(ix-1, 0); nx <= maxNx; nx++) 299 { 300 for (var ny=max(iy-1, 0); ny <= maxNy; ny++) 301 { 302 minAdjHeight = min(minAdjHeight, getHeight(nx, ny)); 303 } 304 } 305 } 306 307 // choose a terrain based on elevation 308 var t = tGrass; 309 310 // water 311 if (maxH < -12) 312 { 313 t = tOceanDepths; 314 } 315 else if (maxH < -8.8) 316 { 317 t = tOceanRockDeep; 318 } 319 else if (maxH < -4.7) 320 { 321 t = tOceanCoral; 322 } 323 else if (maxH < -2.8) 324 { 325 t = tOceanRockShallow; 326 } 327 else if (maxH < 0.9 && minH < 0.35) 328 { 329 t = tBeachWet; 330 } 331 else if (maxH < 1.5 && minH < 0.9) 332 { 333 t = tBeachDry; 334 } 335 else if (maxH < 2.3 && minH < 1.3) 336 { 337 t = tBeachGrass; 338 } 339 340 if (minH < 0) 341 { 342 addToClass(ix, iy, clWater); 343 } 344 345 // cliffs 346 if (maxH - minH > 2.9 && minH > -7) 347 { 348 t = tCliff; 349 addToClass(ix, iy, clCliff); 350 } 351 else if ((maxH - minH > 2.5 && minH > -5) || (maxH-minAdjHeight > 2.9 && minH > 0) ) 352 { 353 if (minH < -1) 354 t = tCliff; 355 else if (minH < 0.5) 356 t = tBeachCliff; 357 else 358 t = [tDirtCliff, tGrassCliff, tGrassCliff, tGrassRock, tCliff]; 359 360 addToClass(ix, iy, clCliff); 361 } 362 363 // forests 364 if (maxH - minH < 1 && minH > 1) 365 { 366 var forestNoise = (noise6.get(x,y) + 0.5*noise7.get(x,y)) / 1.5 * pn; 367 forestNoise -= 0.59; 368 369 if (forestNoise > 0) 370 { 371 if (minH > 5) 372 { 373 var typeNoise = noise10.get(x,y); 374 375 if (typeNoise < 0.43 && forestNoise < 0.05) 376 t = tPoplarForest; 377 else if (typeNoise < 0.63) 378 t = tMainForest; 379 else 380 t = tPineForest; 381 382 addToClass(ix, iy, clForest); 383 } 384 else if (minH < 3) 385 { 386 t = tPalmForest; 387 addToClass(ix, iy, clForest); 388 } 389 } 390 } 391 392 // grass variations 393 if (t == tGrass) 394 { 395 var grassNoise = (noise8.get(x,y) + 0.6*noise9.get(x,y)) / 1.6; 396 if (grassNoise < 0.3) 397 { 398 t = (maxH - minH > 1.2) ? tDirtCliff : tDirt; 399 } 400 else if (grassNoise < 0.34) 401 { 402 t = (maxH - minH > 1.2) ? tGrassCliff : tGrassDry; 403 if (maxH - minH < 0.5 && randFloat() < 0.03) 404 { 405 placeObject(aGrassDry, 0, ix+randFloat(), iy+randFloat(), randFloat()*2*PI); 406 } 407 } 408 else if (grassNoise > 0.61) 409 { 410 t = ((maxH - minH) > 1.2 ? tGrassRock : tGrassShrubs); 411 } 412 else 413 { 414 if ((maxH - minH) < 0.5 && randFloat() < 0.05) 415 { 416 placeObject(aGrass, 0, ix+randFloat(), iy+randFloat(), randFloat()*2*PI); 417 } 418 } 419 } 420 421 placeTerrain(ix, iy, t); 422 } 423 } 424 425 log("Placing straggler trees..."); 426 // create straggler trees 427 var trees = [oCarob, oBeech, oLombardyPoplar, oLombardyPoplar, oPine]; 428 for (var t in trees) 429 { 430 group = new SimpleGroup([new SimpleObject(trees[t], 1,1, 0,1)], true, clForest); 431 createObjectGroups(group, 0, 432 avoidClasses(clWater, 5, clCliff, 0, clForest, 1, clPlayer, 15), 433 mapSize*mapSize/7000, 50 434 ); 435 } 436 437 log("Placing cypress trees..."); 438 // create cypresses 439 group = new SimpleGroup( 440 [new SimpleObject(oCypress2, 1,3, 0,3), 441 new SimpleObject(oCypress1, 0,2, 0,2)] 442 ); 443 createObjectGroups(group, 0, 444 avoidClasses(clWater, 4, clCliff, 2, clForest, 1, clPlayer, 15), 445 mapSize*mapSize/3500, 50 446 ); 447 448 log("Placing bushes..."); 449 // create bushes 450 group = new SimpleGroup( 451 [new SimpleObject(aBushSmall, 0,2, 0,2), new SimpleObject(aBushSmallDry, 0,2, 0,2), 452 new SimpleObject(aBushMed, 0,1, 0,2), new SimpleObject(aBushMedDry, 0,1, 0,2)] 453 ); 454 createObjectGroups(group, 0, 455 avoidClasses(clWater, 4, clCliff, 2), 456 mapSize*mapSize/1800, 50 457 ); 458 459 log("Placing rocks..."); 460 // create rocks 461 group = new SimpleGroup( 462 [new SimpleObject(aRockSmall, 0,3, 0,2), new SimpleObject(aRockMed, 0,2, 0,2), 463 new SimpleObject(aRockLarge, 0,1, 0,2)] 464 ); 465 createObjectGroups(group, 0, 466 avoidClasses(clWater, 0, clCliff, 0), 467 mapSize*mapSize/1800, 50 468 ); 469 470 log("Placing stone mines..."); 471 // create stone 472 group = new SimpleGroup([new SimpleObject(oStone, 2,3, 0,2)], true, clStone); 473 createObjectGroups(group, 0, 474 [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clStone, 15), 475 new BorderTileClassConstraint(clCliff, 0, 5)], 476 3 * numPlayers, 100 477 ); 478 479 log("Placing metal mines..."); 480 // create metal 481 group = new SimpleGroup([new SimpleObject(oMetal, 2,3, 0,2)], true, clMetal); 482 createObjectGroups(group, 0, 483 [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clMetal, 15, clStone, 5), 484 new BorderTileClassConstraint(clCliff, 0, 5)], 485 3 * numPlayers, 100 486 ); 487 488 log("Placing sheep..."); 489 // create sheep 490 group = new SimpleGroup([new SimpleObject(oSheep, 2,4, 0,2)], true, clFood); 491 createObjectGroups(group, 0, 492 avoidClasses(clWater, 5, clForest, 1, clCliff, 1, clPlayer, 20, clMetal, 2, clStone, 2, clFood, 8), 493 3 * numPlayers, 100 494 ); 495 496 log("Placing berry bushes..."); 497 // create berry bushes 498 group = new SimpleGroup([new SimpleObject(oBerryBush, 5,7, 0,3)], true, clFood); 499 createObjectGroups(group, 0, 500 avoidClasses(clWater, 5, clForest, 1, clCliff, 1, clPlayer, 20, clMetal, 2, clStone, 2, clFood, 8), 501 1.5 * numPlayers, 100 502 ); -
binaries/data/mods/public/maps/random/latium.json
Property changes on: binaries\data\mods\public\maps\random\latium.js ___________________________________________________________________ Added: svn:eol-style + native
1 { 2 "settings" : { 3 "Name" : "Latium", 4 "Script" : "latium.js", 5 "Description" : "A test of the Latium script", 6 "BaseTerrain" : ["medit_grass_field", "medit_grass_field_a", "medit_grass_flowers"], 7 "BaseHeight" : 0, 8 "RevealMap": true, 9 "GameType": "endless", 10 "XXXXXX" : "Optionally define other things here, like we would for a scenario" 11 } 12 } 13 No newline at end of file -
binaries/data/mods/public/maps/random/neareastern_badlands.js
Property changes on: binaries\data\mods\public\maps\random\latium.json ___________________________________________________________________ Added: svn:eol-style + native
1 // constants2 3 const SIZE = 208;4 const NUM_PLAYERS = 4;5 6 const tSand = "desert_rough";7 const tDunes = "desert_wave";8 const tFineSand = "desert_sahara";9 const tCliff = "cliff_desert";10 const tForest = "grass_sand_75|flora/trees/palm_b.xml";11 const tGrassSand75 = "grass_sand_75";12 const tGrassSand50 = "grass_sand_50";13 const tGrassSand25 = "grass_sand_25_2";14 const tDirt = "dirt_hard";15 const tDirtCracks = "dirt_cracks";16 const tShore = "sand";17 const tWater = "water_2";18 const tWaterDeep = "water_3";19 20 const oTree = "flora/trees/palm_b.xml";21 const oBerryBush = "flora_bush_berry";22 const oBush = "props/flora/bush_dry_a.xml";23 const oSheep = "fauna_sheep";24 const oDeer = "fauna_deer";25 const oMine = "geology_stone_light";26 const oDecorativeRock = "geology/gray1.xml";27 28 // some utility functions to save typing29 30 function paintClass(cl) {31 return new TileClassPainter(cl);32 }33 34 function avoidClasses(/*class1, dist1, class2, dist2, etc*/) {35 var ar = new Array(arguments.length/2);36 for(var i=0; i<arguments.length/2; i++) {37 ar[i] = new AvoidTileClassConstraint(arguments[2*i], arguments[2*i+1]);38 }39 return ar;40 }41 42 // initialize map43 44 println("Initializing map...");45 init(SIZE, tSand, 10);46 47 // create tile classes48 49 clPlayer = createTileClass();50 clHill1 = createTileClass();51 clHill2 = createTileClass();52 clHill3 = createTileClass();53 clForest = createTileClass();54 clWater = createTileClass();55 clPatch = createTileClass();56 clRock = createTileClass();57 clFood = createTileClass();58 clBaseResource = createTileClass();59 60 // place players61 62 playerX = new Array(NUM_PLAYERS);63 playerY = new Array(NUM_PLAYERS);64 playerAngle = new Array(NUM_PLAYERS);65 66 startAngle = randFloat() * 2 * PI;67 for(i=0; i<NUM_PLAYERS; i++) {68 playerAngle[i] = startAngle + i*2*PI/NUM_PLAYERS;69 playerX[i] = 0.5 + 0.39*cos(playerAngle[i]);70 playerY[i] = 0.5 + 0.39*sin(playerAngle[i]);71 }72 73 for(i=0; i<NUM_PLAYERS; i++) {74 println("Creating base for player " + i + "...");75 76 // some constants77 radius = 20;78 cliffRadius = 2;79 elevation = 30;80 81 // get the x and y in tiles82 fx = fractionToTiles(playerX[i]);83 fy = fractionToTiles(playerY[i]);84 ix = round(fx);85 iy = round(fy);86 87 // calculate size based on the radius88 size = PI * radius * radius;89 90 // create the hill91 placer = new ClumpPlacer(size, 0.9, 0.5, 0, ix, iy);92 createArea(placer, paintClass(clPlayer), null);93 94 // create the central road patch95 placer = new ClumpPlacer(PI*2*2, 0.6, 0.3, 0.5, ix, iy);96 painter = new TerrainPainter(tDirt);97 createArea(placer, painter, null);98 99 // create the TC and the villies100 group = new SimpleGroup(101 [ // elements (type, count, distance)102 new SimpleObject("hele_civil_centre", 1,1, 0,0),103 new SimpleObject("hele_infantry_spearman_b", 3,3, 5,5)104 ],105 true, null, ix, iy106 );107 createObjectGroup(group, i);108 109 // create berry bushes110 bbAngle = randFloat()*2*PI;111 bbDist = 10;112 bbX = round(fx + bbDist * cos(bbAngle));113 bbY = round(fy + bbDist * sin(bbAngle));114 group = new SimpleGroup(115 [new SimpleObject(oSheep, 5,5, 0,2)],116 true, clBaseResource, bbX, bbY117 );118 createObjectGroup(group, 0);119 120 // create mines121 mAngle = bbAngle;122 while(abs(mAngle - bbAngle) < PI/3) {123 mAngle = randFloat()*2*PI;124 }125 mDist = 12;126 mX = round(fx + mDist * cos(mAngle));127 mY = round(fy + mDist * sin(mAngle));128 group = new SimpleGroup(129 [new SimpleObject(oMine, 3,3, 0,2)],130 true, clBaseResource, mX, mY131 );132 createObjectGroup(group, 0);133 134 // create starting straggler trees135 group = new SimpleGroup(136 [new SimpleObject(oTree, 2,2, 6,12)],137 true, null, ix, iy138 );139 createObjectGroup(group, 0, avoidClasses(clBaseResource,1));140 }141 142 // create patches143 println("Creating sand patches...");144 placer = new ClumpPlacer(30, 0.2, 0.1, 0);145 painter = new LayeredPainter([1], [[tSand, tFineSand], tFineSand]);146 createAreas(placer, [painter, paintClass(clPatch)],147 avoidClasses(clPatch, 5),148 (SIZE*SIZE)/600149 );150 151 println("Creating dirt patches...");152 placer = new ClumpPlacer(10, 0.2, 0.1, 0);153 painter = new TerrainPainter([tSand, tDirt]);154 createAreas(placer, [painter, paintClass(clPatch)],155 avoidClasses(clPatch, 5),156 (SIZE*SIZE)/600157 );158 159 // create the oasis160 println("Creating water...");161 placer = new ClumpPlacer(1200, 0.6, 0.1, 0, SIZE/2, SIZE/2);162 painter = new LayeredPainter([6,1], [[tSand, tForest], tShore, tWaterDeep]);163 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -10, 5);164 createArea(placer, [painter, elevationPainter, paintClass(clForest)], null);165 166 // create hills167 println("Creating level 1 hills...");168 placer = new ClumpPlacer(150, 0.25, 0.1, 0.3);169 terrainPainter = new LayeredPainter(170 [1], // widths171 [tCliff, tSand] // terrains172 );173 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);174 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill1)],175 avoidClasses(clForest, 2, clPlayer, 0, clHill1, 16),176 (SIZE*SIZE)/3800, 100177 );178 179 println("Creating small level 1 hills...");180 placer = new ClumpPlacer(60, 0.25, 0.1, 0.3);181 terrainPainter = new LayeredPainter(182 [1], // widths183 [tCliff, tSand] // terrains184 );185 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);186 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill1)],187 avoidClasses(clForest, 2, clPlayer, 0, clHill1, 3),188 (SIZE*SIZE)/2800, 100189 );190 191 println("Creating level 2 hills...");192 placer = new ClumpPlacer(60, 0.2, 0.1, 0.9);193 terrainPainter = new LayeredPainter(194 [1], // widths195 [tCliff, tSand] // terrains196 );197 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);198 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill2)],199 [avoidClasses(clHill2, 1), new StayInTileClassConstraint(clHill1, 0)],200 (SIZE*SIZE)/2800, 200201 );202 203 println("Creating level 3 hills...");204 placer = new ClumpPlacer(25, 0.2, 0.1, 0.9);205 terrainPainter = new LayeredPainter(206 [1], // widths207 [tCliff, tSand] // terrains208 );209 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);210 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill3)],211 [avoidClasses(clHill3, 1), new StayInTileClassConstraint(clHill2, 0)],212 (SIZE*SIZE)/9000, 300213 );214 215 // create forests216 println("Creating forests...");217 placer = new ClumpPlacer(25, 0.15, 0.1, 0.3);218 painter = new TerrainPainter([tSand, tForest]);219 createAreas(placer, [painter, paintClass(clForest)],220 avoidClasses(clWater, 0, clPlayer, 1, clForest, 20, clHill1, 0),221 (SIZE*SIZE)/4000, 50222 );223 224 // create mines225 println("Creating mines...");226 group = new SimpleGroup([new SimpleObject(oMine, 4,6, 0,2)], true, clRock);227 createObjectGroups(group, 0,228 [avoidClasses(clWater, 2, clForest, 2, clPlayer, 0, clRock, 13),229 new BorderTileClassConstraint(clHill1, 0, 4)],230 (SIZE*SIZE)/4000, 100231 );232 233 // create decorative rocks for hills234 println("Creating decorative rocks...");235 group = new SimpleGroup([new SimpleObject(oDecorativeRock, 1,1, 0,0)], true);236 createObjectGroups(group, 0,237 new BorderTileClassConstraint(clHill1, 0, 3),238 (SIZE*SIZE)/2000, 100239 );240 241 // create deer242 println("Creating deer...");243 group = new SimpleGroup([new SimpleObject(oDeer, 5,7, 0,4)], true, clFood);244 createObjectGroups(group, 0,245 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill1, 0, clFood, 25),246 (SIZE*SIZE)/5000, 50247 );248 249 // create sheep250 println("Creating sheep...");251 group = new SimpleGroup([new SimpleObject(oSheep, 1,3, 0,2)], true, clFood);252 createObjectGroups(group, 0,253 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill1, 0, clFood, 15),254 (SIZE*SIZE)/5000, 50255 );256 257 // create straggler trees258 println("Creating straggler trees...");259 group = new SimpleGroup([new SimpleObject(oTree, 1,1, 0,0)], true);260 createObjectGroups(group, 0,261 avoidClasses(clWater, 0, clForest, 0, clHill1, 0, clPlayer, 0),262 SIZE*SIZE/1500263 );264 265 266 // create bushes267 println("Creating bushes...");268 group = new SimpleGroup([new SimpleObject(oBush, 2,3, 0,2)]);269 createObjectGroups(group, 0,270 avoidClasses(clWater, 3, clHill1, 0, clPlayer, 0, clForest, 0),271 SIZE*SIZE/1000272 );273 274 // create bushes275 println("Creating more decorative rocks...");276 group = new SimpleGroup([new SimpleObject(oDecorativeRock, 1,2, 0,2)]);277 createObjectGroups(group, 0,278 avoidClasses(clWater, 3, clHill1, 0, clPlayer, 0, clForest, 0),279 SIZE*SIZE/1000280 );281 No newline at end of file -
binaries/data/mods/public/maps/random/neareastern_badlands.js
1 2 // terrain textures 3 const tSand = "desert_dirt_rough"; 4 const tDunes = "desert_sand_dunes_100"; 5 const tFineSand = "desert_sand_smooth"; 6 const tCliff = "desert_cliff_badlands"; 7 const tGrassSand75 = "desert_grass_a"; 8 const tGrassSand50 = "desert_grass_a_sand"; 9 const tGrassSand25 = "desert_grass_a_stones"; 10 const tDirt = "desert_dirt_rough"; 11 const tDirtCracks = "desert_dirt_cracks"; 12 const tShore = "desert_sand_wet"; 13 const tWater = "desert_shore_stones"; 14 const tWaterDeep = "desert_shore_stones_wet"; 15 16 // gaia entities 17 const oBerryBush = "gaia/flora_bush_berry"; 18 const oSheep = "gaia/fauna_sheep"; 19 const oDeer = "gaia/fauna_deer"; 20 const oMine = "gaia/geology_stone_desert_small"; 21 const oTree = "gaia/flora_tree_medit_fan_palm"; 22 23 // decorative props 24 const aBush = "actor|props/flora/bush_dry_a.xml"; 25 const aDecorativeRock = "actor|geology/gray1.xml"; 26 27 var tForest = tGrassSand75 + TERRAIN_SEPARATOR + oTree; 28 29 // initialize map 30 31 log("Initializing map..."); 32 33 var numPlayers = getNumPlayers(); 34 var mapSize = getMapSize(); 35 36 // create tile classes 37 38 var clPlayer = createTileClass(); 39 var clHill1 = createTileClass(); 40 var clHill2 = createTileClass(); 41 var clHill3 = createTileClass(); 42 var clForest = createTileClass(); 43 var clWater = createTileClass(); 44 var clPatch = createTileClass(); 45 var clRock = createTileClass(); 46 var clFood = createTileClass(); 47 var clBaseResource = createTileClass(); 48 49 // place players 50 51 var playerX = new Array(numPlayers); 52 var playerY = new Array(numPlayers); 53 var playerAngle = new Array(numPlayers); 54 55 var startAngle = randFloat() * 2 * PI; 56 for (var i=0; i < numPlayers; i++) 57 { 58 playerAngle[i] = startAngle + i*2*PI/numPlayers; 59 playerX[i] = 0.5 + 0.39*cos(playerAngle[i]); 60 playerY[i] = 0.5 + 0.39*sin(playerAngle[i]); 61 } 62 63 for (var i=0; i < numPlayers; i++) 64 { 65 log("Creating base for player " + (i + 1) + "..."); 66 67 // some constants 68 var radius = 20; 69 70 // get the x and y in tiles 71 var fx = fractionToTiles(playerX[i]); 72 var fy = fractionToTiles(playerY[i]); 73 var ix = round(fx); 74 var iy = round(fy); 75 76 // calculate size based on the radius 77 var size = PI * radius * radius; 78 79 // create the hill 80 log("Creating hill for player " + (i + 1) + "..."); 81 var placer = new ClumpPlacer(size, 0.9, 0.5, 0, ix, iy); 82 createArea(placer, paintClass(clPlayer), null); 83 84 // create the central road patch 85 log("Creating central road for player " + (i + 1) + "..."); 86 placer = new ClumpPlacer(PI*2*2, 0.6, 0.3, 0.5, ix, iy); 87 var painter = new TerrainPainter(tDirt); 88 createArea(placer, painter, null); 89 90 // create the TC and citizens 91 log("Creating TC/citizens for player " + (i + 1) + "..."); 92 var civ = getCivCode(i); 93 var group = new SimpleGroup( 94 [ // elements (type, count, distance) 95 new SimpleObject("structures/"+civ+"_civil_centre", 1,1, 0,0), 96 new SimpleObject("units/"+civ+"_support_female_citizen", 3,3, 5,5) 97 ], 98 true, null, ix, iy 99 ); 100 createObjectGroup(group, i+1); 101 102 // create berry bushes 103 log("Creating berry bushes for player " + (i + 1) + "..."); 104 var bbAngle = randFloat()*2*PI; 105 var bbDist = 10; 106 var bbX = round(fx + bbDist * cos(bbAngle)); 107 var bbY = round(fy + bbDist * sin(bbAngle)); 108 group = new SimpleGroup( 109 [new SimpleObject(oSheep, 5,5, 0,2)], 110 true, clBaseResource, bbX, bbY 111 ); 112 createObjectGroup(group, 0); 113 114 // create mines 115 log("Creating mines for player " + (i + 1) + "..."); 116 var mAngle = bbAngle; 117 while(abs(mAngle - bbAngle) < PI/3) { 118 mAngle = randFloat()*2*PI; 119 } 120 var mDist = 12; 121 var mX = round(fx + mDist * cos(mAngle)); 122 var mY = round(fy + mDist * sin(mAngle)); 123 group = new SimpleGroup( 124 [new SimpleObject(oMine, 3,3, 0,2)], 125 true, clBaseResource, mX, mY 126 ); 127 createObjectGroup(group, 0); 128 129 // create starting straggler trees 130 log("Creating trees for player " + (i + 1) + "..."); 131 group = new SimpleGroup( 132 [new SimpleObject(oTree, 2,2, 6,12)], 133 true, null, ix, iy 134 ); 135 createObjectGroup(group, 0, avoidClasses(clBaseResource,1)); 136 } 137 138 // create patches 139 log("Creating sand patches..."); 140 var placer = new ClumpPlacer(30, 0.2, 0.1, 0); 141 var painter = new LayeredPainter([[tSand, tFineSand], tFineSand], [1]); 142 createAreas(placer, [painter, paintClass(clPatch)], 143 avoidClasses(clPatch, 5), 144 (mapSize*mapSize)/600 145 ); 146 147 log("Creating dirt patches..."); 148 placer = new ClumpPlacer(10, 0.2, 0.1, 0); 149 painter = new TerrainPainter([tSand, tDirt]); 150 createAreas(placer, [painter, paintClass(clPatch)], 151 avoidClasses(clPatch, 5), 152 (mapSize*mapSize)/600 153 ); 154 155 // create the oasis 156 log("Creating water..."); 157 placer = new ClumpPlacer(1200, 0.6, 0.1, 0, mapSize/2, mapSize/2); 158 painter = new LayeredPainter([[tSand, tForest], tShore, tWaterDeep], [6,1]); 159 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -10, 5); 160 createArea(placer, [painter, elevationPainter, paintClass(clForest)], null); 161 162 // create hills 163 log("Creating level 1 hills..."); 164 placer = new ClumpPlacer(150, 0.25, 0.1, 0.3); 165 var terrainPainter = new LayeredPainter( 166 [tCliff, tSand], // terrains 167 [1] // widths 168 ); 169 var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1); 170 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill1)], 171 avoidClasses(clForest, 2, clPlayer, 0, clHill1, 16), 172 (mapSize*mapSize)/3800, 100 173 ); 174 175 log("Creating small level 1 hills..."); 176 placer = new ClumpPlacer(60, 0.25, 0.1, 0.3); 177 terrainPainter = new LayeredPainter( 178 [tCliff, tSand], // terrains 179 [1] // widths 180 ); 181 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1); 182 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill1)], 183 avoidClasses(clForest, 2, clPlayer, 0, clHill1, 3), 184 (mapSize*mapSize)/2800, 100 185 ); 186 187 log("Creating level 2 hills..."); 188 placer = new ClumpPlacer(60, 0.2, 0.1, 0.9); 189 terrainPainter = new LayeredPainter( 190 [tCliff, tSand], // terrains 191 [1] // widths 192 ); 193 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1); 194 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill2)], 195 [avoidClasses(clHill2, 1), new StayInTileClassConstraint(clHill1, 0)], 196 (mapSize*mapSize)/2800, 200 197 ); 198 199 log("Creating level 3 hills..."); 200 placer = new ClumpPlacer(25, 0.2, 0.1, 0.9); 201 terrainPainter = new LayeredPainter( 202 [tCliff, tSand], // terrains 203 [1] // widths 204 ); 205 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1); 206 createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill3)], 207 [avoidClasses(clHill3, 1), new StayInTileClassConstraint(clHill2, 0)], 208 (mapSize*mapSize)/9000, 300 209 ); 210 211 // create forests 212 log("Creating forests..."); 213 placer = new ClumpPlacer(25, 0.15, 0.1, 0.3); 214 painter = new TerrainPainter([tSand, tForest]); 215 createAreas(placer, [painter, paintClass(clForest)], 216 avoidClasses(clWater, 0, clPlayer, 1, clForest, 20, clHill1, 0), 217 (mapSize*mapSize)/4000, 50 218 ); 219 220 // create mines 221 log("Creating mines..."); 222 group = new SimpleGroup([new SimpleObject(oMine, 4,6, 0,2)], true, clRock); 223 createObjectGroups(group, 0, 224 [avoidClasses(clWater, 2, clForest, 2, clPlayer, 0, clRock, 13), 225 new BorderTileClassConstraint(clHill1, 0, 4)], 226 (mapSize*mapSize)/4000, 100 227 ); 228 229 // create decorative rocks for hills 230 log("Creating decorative rocks..."); 231 group = new SimpleGroup([new SimpleObject(aDecorativeRock, 1,1, 0,0)], true); 232 createObjectGroups(group, undefined, 233 new BorderTileClassConstraint(clHill1, 0, 3), 234 (mapSize*mapSize)/2000, 100 235 ); 236 237 // create deer 238 log("Creating deer..."); 239 group = new SimpleGroup([new SimpleObject(oDeer, 5,7, 0,4)], true, clFood); 240 createObjectGroups(group, 0, 241 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill1, 0, clFood, 25), 242 (mapSize*mapSize)/5000, 50 243 ); 244 245 // create sheep 246 log("Creating sheep..."); 247 group = new SimpleGroup([new SimpleObject(oSheep, 1,3, 0,2)], true, clFood); 248 createObjectGroups(group, 0, 249 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill1, 0, clFood, 15), 250 (mapSize*mapSize)/5000, 50 251 ); 252 253 // create straggler trees 254 log("Creating straggler trees..."); 255 group = new SimpleGroup([new SimpleObject(oTree, 1,1, 0,0)], true); 256 createObjectGroups(group, 0, 257 avoidClasses(clWater, 0, clForest, 0, clHill1, 0, clPlayer, 0), 258 mapSize*mapSize/1500 259 ); 260 261 262 // create bushes 263 log("Creating bushes..."); 264 group = new SimpleGroup([new SimpleObject(aBush, 2,3, 0,2)]); 265 createObjectGroups(group, undefined, 266 avoidClasses(clWater, 3, clHill1, 0, clPlayer, 0, clForest, 0), 267 mapSize*mapSize/1000 268 ); 269 270 // create bushes 271 log("Creating more decorative rocks..."); 272 group = new SimpleGroup([new SimpleObject(aDecorativeRock, 1,2, 0,2)]); 273 createObjectGroups(group, undefined, 274 avoidClasses(clWater, 3, clHill1, 0, clPlayer, 0, clForest, 0), 275 mapSize*mapSize/1000 276 ); 277 No newline at end of file -
binaries/data/mods/public/maps/random/neareastern_badlands.json
Property changes on: binaries\data\mods\public\maps\random\neareastern_badlands.js ___________________________________________________________________ Added: svn:eol-style + native
1 { 2 "settings" : { 3 "Name" : "Neareastern Badlands", 4 "Script" : "neareastern_badlands.js", 5 "Description" : "A test of the Neareastern Badlands script", 6 "BaseTerrain" : "desert_rough", 7 "BaseHeight" : 10, 8 "RevealMap": true, 9 "GameType": "endless", 10 "XXXXXX" : "Optionally define other things here, like we would for a scenario" 11 } 12 } 13 No newline at end of file -
binaries/data/mods/public/maps/random/new_rms_test.js
Property changes on: binaries\data\mods\public\maps\random\neareastern_badlands.json ___________________________________________________________________ Added: svn:eol-style + native
1 // New format RMS test 2 3 -
binaries/data/mods/public/maps/random/new_rms_test.json
Property changes on: binaries\data\mods\public\maps\random\new_rms_test.js ___________________________________________________________________ Added: svn:eol-style + native
1 { 2 "settings" : { 3 "Name" : "New RMS Test", 4 "Script" : "new_rms_test.js", 5 "Description" : "A test of the new integrated random map generator!", 6 "BaseTerrain" : "grass1_spring", 7 "BaseHeight" : 0, 8 "RevealMap": true, 9 "GameType": "endless", 10 "XXXXXX" : "Optionally define other things here, like we would for a scenario" 11 } 12 } 13 No newline at end of file -
source/graphics/Entity.h
Property changes on: binaries\data\mods\public\maps\random\new_rms_test.json ___________________________________________________________________ Added: svn:eol-style + native
1 /* Copyright (C) 2010 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_ENTITY 19 #define INCLUDED_ENTITY 20 21 // Struct for parsing random map data 22 struct Entity 23 { 24 std::wstring templateName; 25 u16 entityID; 26 u16 playerID; 27 float positionX; 28 float positionZ; 29 float orientationY; 30 bool isActor; 31 }; 32 33 34 #endif 35 No newline at end of file -
source/graphics/MapGenerator.cpp
Property changes on: source\graphics\Entity.h ___________________________________________________________________ Added: svn:eol-style + native
1 /* Copyright (C) 2010 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "precompiled.h" 19 20 #include "MapGenerator.h" 21 22 #include "lib/timer.h" 23 #include "ps/CLogger.h" 24 25 #define LOG_CATEGORY L"graphics" 26 27 namespace MapGenRNG 28 { 29 boost::mt19937 g_RNG; 30 31 static JSFunctionSpec global_functions[] = { 32 JS_FS("seedRand", SeedRand, 1, 0), 33 JS_FS("randInt", RandInt, 1, 0), 34 JS_FS("randFloat", RandFloat, 0, 0), 35 JS_FS_END 36 }; 37 }//namespace MapGenRNG 38 39 40 CMapGenerator::CMapGenerator() : m_ScriptInterface("Generator") 41 { 42 // Register global functions 43 JSObject* globalObj = JSVAL_TO_OBJECT(m_ScriptInterface.GetGlobalObject()); 44 if (!JS_DefineFunctions(m_ScriptInterface.GetContext(), globalObj, MapGenRNG::global_functions)) 45 { 46 LOGERROR(L"GenerateMap: Error defining global functions"); 47 } 48 49 // load mapgen libraries 50 LoadLibraries(); 51 } 52 53 CScriptValRooted CMapGenerator::GenerateMap(const CStrW& scriptFile, const CScriptValRooted& settings) 54 { 55 TIMER(L"GenerateMap"); 56 57 // Init map generator 58 jsval global = m_ScriptInterface.GetGlobalObject(); 59 60 if (!m_ScriptInterface.CallFunctionVoid(global, "InitMapGen", settings)) 61 { 62 LOGERROR(L"GenerateMap: Error calling 'InitMapGen' library function"); 63 return CScriptValRooted(); 64 } 65 66 // Load RMS 67 // Check for blank file, this allows creating blank terrains 68 if (scriptFile.length()) 69 { 70 LoadScript(scriptFile); 71 } 72 73 // Run save function 74 CScriptValRooted ret; 75 if (!m_ScriptInterface.CallFunction(global, "SaveMap", ret)) 76 { 77 LOGERROR(L"GenerateMap: Error calling 'SaveMap' library function"); 78 return CScriptValRooted(); 79 } 80 81 return ret; 82 } 83 84 void CMapGenerator::LoadLibraries() 85 { 86 VfsPaths pathnames; 87 88 // Load all scripts in mapgen directory 89 if (fs_util::GetPathnames(g_VFS, VfsPath(L"maps/mapgen/"), L"*.js", pathnames) < 0) 90 LOGERROR(L"Error reading scripts in directory: maps/mapgen/"); 91 92 for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it) 93 { 94 LoadScript(it->string()); 95 } 96 } 97 98 CScriptValRooted CMapGenerator::LoadScript(const std::wstring& filename) 99 { 100 LOGMESSAGE(L"Loading map generator script '%ls'", filename.c_str()); 101 102 VfsPath path(filename); 103 104 if (!FileExists(g_VFS, path)) 105 { 106 LOGERROR(L"Script file '%ls' does not exist", filename.c_str()); 107 return CScriptValRooted(); 108 } 109 110 CVFSFile file; 111 112 PSRETURN ret = file.Load(g_VFS, path); 113 114 if (ret != PSRETURN_OK) 115 { 116 LOGERROR(L"Failed to load script '%ls': %hs", filename.c_str(), GetErrorString(ret)); 117 return CScriptValRooted(); 118 } 119 120 CScriptValRooted retVal; 121 if (!m_ScriptInterface.Eval(file.GetAsString().c_str(), retVal)) 122 { 123 LOGERROR(L"Failed to eval script '%ls'", filename.c_str()); 124 return CScriptValRooted(); 125 } 126 127 return retVal; 128 } 129 130 ScriptInterface& CMapGenerator::GetScriptInterface() 131 { 132 return m_ScriptInterface; 133 } 134 135 ////////////////////////////////////////////////////////////////////////////// 136 137 JSBool MapGenRNG::SeedRand(JSContext *cx, uintN argc, jsval *vp) 138 { 139 uint32 seed = 0; 140 141 if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/u", &seed)) 142 { 143 JS_ReportError(cx, "seedRand() cannot convert argument to integer"); 144 return JS_FALSE; 145 } 146 147 g_RNG.seed(seed); 148 149 JS_SET_RVAL(cx, vp, JSVAL_VOID); /* return undefined */ 150 return JS_TRUE; 151 } 152 153 JSBool MapGenRNG::RandInt(JSContext *cx, uintN argc, jsval *vp) 154 { 155 int32 min, max, result; 156 157 if (argc == 1) 158 { 159 if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/i", &max)) 160 { 161 JS_ReportError(cx, "randInt() cannot convert argument to integer"); 162 return JS_FALSE; 163 } 164 165 result = randInt(max); 166 } 167 else if (argc == 2) 168 { 169 if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/i/i", &min, &max)) 170 { 171 JS_ReportError(cx, "randInt() cannot convert arguments to integers"); 172 return JS_FALSE; 173 } 174 175 result = min + randInt(max - min + 1); 176 } 177 else 178 { 179 JS_ReportError(cx, "randInt() received invalid number of arguments: %u", argc); 180 return JS_FALSE; 181 } 182 183 JS_SET_RVAL(cx, vp, INT_TO_JSVAL(result)); 184 return JS_TRUE; 185 } 186 187 JSBool MapGenRNG::RandFloat(JSContext *cx, uintN argc, jsval *vp) 188 { 189 float min, max, result; 190 191 if (argc == 0) 192 { 193 result = randFloat(); 194 } 195 else if (argc == 2) 196 { 197 if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/d/d", &min, &max)) 198 { 199 JS_ReportError(cx, "randFloat() cannot convert arguments to doubles"); 200 return JS_FALSE; 201 } 202 203 result = min + randFloat() * (max - min); 204 } 205 else 206 { 207 JS_ReportError(cx, "randFloat() received invalid number of arguments: %u", argc); 208 return JS_FALSE; 209 } 210 211 JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(result)); 212 return JS_TRUE; 213 } 214 215 int32 MapGenRNG::randInt(int32 max) 216 { 217 return g_RNG() % max; 218 } 219 220 float MapGenRNG::randFloat() 221 { 222 return float(g_RNG()) * (1.0f/4294967296.0f); 223 } -
source/graphics/MapGenerator.h
Property changes on: source\graphics\MapGenerator.cpp ___________________________________________________________________ Added: svn:eol-style + native
1 /* Copyright (C) 2010 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_MAPGENERATOR 19 #define INCLUDED_MAPGENERATOR 20 21 #include "lib/res/handle.h" 22 #include "ps/CStr.h" 23 #include "ps/FileIo.h" 24 #include "scriptinterface/ScriptInterface.h" 25 #include "js/jsapi.h" 26 27 #include <boost/random/mersenne_twister.hpp> 28 29 class CMapGenerator 30 { 31 32 public: 33 // constructor 34 CMapGenerator(); 35 36 CScriptValRooted GenerateMap(const CStrW& scriptFile, const CScriptValRooted& settings); 37 38 ScriptInterface& GetScriptInterface(); 39 40 private: 41 42 void LoadLibraries(); 43 44 CScriptValRooted LoadScript(const std::wstring& filename); 45 46 ScriptInterface m_ScriptInterface; 47 48 }; 49 50 namespace MapGenRNG 51 { 52 JSBool SeedRand(JSContext *cx, uintN argc, jsval *vp); 53 JSBool RandInt(JSContext *cx, uintN argc, jsval *vp); 54 JSBool RandFloat(JSContext *cx, uintN argc, jsval *vp); 55 56 int32 randInt(int32 max); 57 float randFloat(); 58 }//namespace MapGenRNG 59 60 #endif 61 No newline at end of file -
source/graphics/MapReader.cpp
Property changes on: source\graphics\MapGenerator.h ___________________________________________________________________ Added: svn:eol-style + native
21 21 22 22 #include "graphics/Camera.h" 23 23 #include "graphics/CinemaTrack.h" 24 #include "graphics/Entity.h" 24 25 #include "graphics/GameView.h" 26 #include "graphics/MapGenerator.h" 25 27 #include "graphics/Patch.h" 26 28 #include "graphics/Terrain.h" 27 29 #include "graphics/TerrainTextureEntry.h" … … 125 127 RegMemFun(this, &CMapReader::DelayLoadFinished, L"CMapReader::DelayLoadFinished", 5); 126 128 } 127 129 130 // LoadRandomMap: try to load the map data; reinitialise the scene to new data if successful 131 void CMapReader::LoadRandomMap(const CStrW& scriptFile, const CScriptValRooted& settings, CTerrain *pTerrain_, 132 WaterManager* pWaterMan_, SkyManager* pSkyMan_, 133 CLightEnv *pLightEnv_, CGameView *pGameView_, CCinemaManager* pCinema_, CTriggerManager* pTrigMan_, 134 CSimulation2 *pSimulation2_, int playerID_) 135 { 136 // latch parameters (held until DelayedLoadFinished) 137 m_ScriptFile = scriptFile; 138 m_ScriptSettings = settings; 139 pTerrain = pTerrain_; 140 pLightEnv = pLightEnv_; 141 pGameView = pGameView_; 142 pWaterMan = pWaterMan_; 143 pSkyMan = pSkyMan_; 144 pCinema = pCinema_; 145 pTrigMan = pTrigMan_; 146 pSimulation2 = pSimulation2_; 147 m_PlayerID = playerID_; 148 149 m_CameraStartupTarget = INVALID_ENTITY; 150 151 // delete all existing entities 152 if (pSimulation2) 153 pSimulation2->ResetState(); 154 155 only_xml = false; 156 157 // copy random map settings (before entity creation) 158 RegMemFun(this, &CMapReader::LoadRMSettings, L"CMapReader::LoadRMSettings", 50); 159 160 // load player settings script (must be done before reading map) 161 RegMemFun(this, &CMapReader::LoadPlayerSettings, L"CMapReader::LoadPlayerSettings", 50); 162 163 // load map generator with random map script 164 RegMemFun(this, &CMapReader::GenerateMap, L"CMapReader::GenerateMap", 2000); 165 166 // parse RMS results into terrain structure 167 RegMemFun(this, &CMapReader::ParseTerrain, L"CMapReader::ParseTerrain", 500); 168 169 // parse RMS results into environment settings 170 RegMemFun(this, &CMapReader::ParseEnvironment, L"CMapReader::ParseEnvironment", 5); 171 172 // parse RMS results into camera settings 173 RegMemFun(this, &CMapReader::ParseCamera, L"CMapReader::ParseCamera", 5); 174 175 // parse RMS results into entities 176 RegMemFun(this, &CMapReader::ParseEntities, L"CMapReader::ParseEntities", 1000); 177 178 // apply data to the world 179 RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5); 180 181 // load map settings script (must be done after reading map) 182 RegMemFun(this, &CMapReader::LoadMapSettings, L"CMapReader::LoadMapSettings", 5); 183 184 RegMemFun(this, &CMapReader::DelayLoadFinished, L"CMapReader::DelayLoadFinished", 5); 185 } 186 128 187 // UnpackMap: unpack the given data from the raw data stream into local variables 129 188 int CMapReader::UnpackMap() 130 189 { … … 1340 1399 1341 1400 return 0; 1342 1401 } 1402 1403 int CMapReader::LoadRMSettings() 1404 { 1405 // copy random map settings over to sim 1406 pSimulation2->SetMapSettings(m_ScriptSettings); 1407 1408 return 0; 1409 } 1410 1411 int CMapReader::GenerateMap() 1412 { 1413 CMapGenerator mapGen; 1414 1415 CStrW scriptPath; 1416 1417 if (m_ScriptFile.length()) 1418 scriptPath = L"maps/random/"+m_ScriptFile; 1419 1420 // Copy map settings from simulator to mapgen context 1421 CScriptValRooted scriptSettings(mapGen.GetScriptInterface().GetContext(), mapGen.GetScriptInterface().CloneValueFromOtherContext(pSimulation2->GetScriptInterface(), m_ScriptSettings.get())); 1422 1423 CScriptValRooted mapData = mapGen.GenerateMap(scriptPath, scriptSettings); 1424 1425 // No map data, something bad happened 1426 if(mapData.undefined()) 1427 throw PSERROR_File_ReadFailed("CMapReader::GenerateMap() failed to generate map"); 1428 1429 // Copy data from mapgen to simulator context 1430 m_MapData = CScriptValRooted(pSimulation2->GetScriptInterface().GetContext(), pSimulation2->GetScriptInterface().CloneValueFromOtherContext(mapGen.GetScriptInterface(), mapData.get())); 1431 1432 return 0; 1433 }; 1434 1435 1436 int CMapReader::ParseTerrain() 1437 { 1438 // TODO: Progressive loading 1439 1440 // parse terrain from map data 1441 1442 #define GET_TERRAIN_PROPERTY(prop, out)\ 1443 if (!pSimulation2->GetScriptInterface().GetProperty(m_MapData.get(), #prop, out))\ 1444 LOGERROR(L"CMapReader::ParseTerrain() failed to get '%hs' property", #prop);\ 1445 1446 size_t size; 1447 GET_TERRAIN_PROPERTY(size, size) 1448 1449 m_PatchesPerSide = size / PATCH_SIZE; 1450 1451 // flat heightmap of u16 data 1452 GET_TERRAIN_PROPERTY(height, m_Heightmap) 1453 1454 // load textures 1455 GET_TERRAIN_PROPERTY(numTextures, num_terrain_tex) 1456 1457 std::vector<std::string> textureNames; 1458 GET_TERRAIN_PROPERTY(textureNames, textureNames) 1459 1460 while (cur_terrain_tex < num_terrain_tex) 1461 { 1462 debug_assert(CTerrainTextureManager::IsInitialised()); // we need this for the terrain properties (even when graphics are disabled) 1463 CTerrainTextureEntry* texentry = g_TexMan.FindTexture(textureNames[cur_terrain_tex]); 1464 m_TerrainTextures.push_back(texentry); 1465 1466 cur_terrain_tex++; 1467 //LDR_CHECK_TIMEOUT(cur_terrain_tex, num_terrain_tex); 1468 } 1469 1470 // build tile data 1471 m_Tiles.resize(SQR(size)); 1472 1473 std::vector<u16> tileData; 1474 GET_TERRAIN_PROPERTY(tileData, tileData) 1475 1476 size_t i; 1477 CMapIO::STileDesc tileDesc = {0, 0xFFFF, 0}; 1478 for (i = 0; i < tileData.size(); ++i) 1479 { 1480 tileDesc.m_Tex1Index = tileData[i]; 1481 1482 m_Tiles[i] = tileDesc; 1483 } 1484 1485 // reset generator state 1486 cur_terrain_tex = 0; 1487 1488 #undef GET_TERRAIN_PROPERTY 1489 1490 return 0; 1491 } 1492 1493 int CMapReader::ParseEntities() 1494 { 1495 // parse entities from map data 1496 std::vector<Entity> entities; 1497 1498 if (!pSimulation2->GetScriptInterface().GetProperty(m_MapData.get(), "entities", entities)) 1499 LOGWARNING(L"CMapReader::ParseEntities() failed to get 'entities' property"); 1500 1501 size_t entity_idx = 0; 1502 size_t num_entities = entities.size(); 1503 1504 Entity currEnt; 1505 1506 while (entity_idx < num_entities) 1507 { 1508 // Get current entity struct 1509 currEnt = entities[entity_idx]; 1510 1511 entity_id_t ent = pSimulation2->AddEntity(currEnt.templateName, currEnt.entityID); 1512 // Check that entity was added 1513 if (ent == INVALID_ENTITY) 1514 { 1515 LOGERROR(L"Failed to load entity template '%ls'", currEnt.templateName.c_str()); 1516 } 1517 else 1518 { 1519 CmpPtr<ICmpPosition> cmpPosition(*pSimulation2, ent); 1520 if (!cmpPosition.null()) 1521 { 1522 cmpPosition->JumpTo(entity_pos_t::FromFloat(currEnt.positionX), entity_pos_t::FromFloat(currEnt.positionZ)); 1523 cmpPosition->SetYRotation(entity_angle_t::FromFloat(currEnt.orientationY)); 1524 // TODO: other parts of the position 1525 } 1526 1527 CmpPtr<ICmpOwnership> cmpOwner(*pSimulation2, ent); 1528 if (!cmpOwner.null()) 1529 cmpOwner->SetOwner(currEnt.playerID); 1530 1531 if (boost::algorithm::ends_with(currEnt.templateName, L"civil_centre")) 1532 { 1533 // HACK: we special-case civil centre files to initialise the camera. 1534 // This ought to be based on a more generic mechanism for indicating 1535 // per-player camera start locations. 1536 if (m_CameraStartupTarget == INVALID_ENTITY && currEnt.playerID == m_PlayerID && !cmpPosition.null()) 1537 m_CameraStartupTarget = ent; 1538 1539 } 1540 } 1541 1542 entity_idx++; 1543 } 1544 1545 return 0; 1546 } 1547 1548 int CMapReader::ParseEnvironment() 1549 { 1550 // parse environment settings from map data 1551 1552 #define GET_ENVIRONMENT_PROPERTY(val, prop, out)\ 1553 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ 1554 LOGWARNING(L"CMapReader::ParseEnvironment() failed to get '%hs' property", #prop);\ 1555 1556 CScriptValRooted envObj; 1557 GET_ENVIRONMENT_PROPERTY(m_MapData.get(), Environment, envObj) 1558 1559 if (envObj.undefined()) 1560 { 1561 LOGWARNING(L"CMapReader::ParseEnvironment(): Environment settings not found"); 1562 return 0; 1563 } 1564 1565 std::wstring skySet; 1566 GET_ENVIRONMENT_PROPERTY(envObj.get(), SkySet, skySet) 1567 pSkyMan->SetSkySet(skySet); 1568 1569 GET_ENVIRONMENT_PROPERTY(envObj.get(), SunColour, m_LightEnv.m_SunColor) 1570 GET_ENVIRONMENT_PROPERTY(envObj.get(), SunElevation, m_LightEnv.m_Elevation) 1571 GET_ENVIRONMENT_PROPERTY(envObj.get(), SunRotation, m_LightEnv.m_Rotation) 1572 GET_ENVIRONMENT_PROPERTY(envObj.get(), TerrainAmbientColour, m_LightEnv.m_TerrainAmbientColor) 1573 GET_ENVIRONMENT_PROPERTY(envObj.get(), UnitsAmbientColour, m_LightEnv.m_UnitsAmbientColor) 1574 1575 1576 // Water properties 1577 CScriptValRooted waterObj; 1578 GET_ENVIRONMENT_PROPERTY(envObj.get(), Water, waterObj) 1579 1580 CScriptValRooted waterBodyObj; 1581 GET_ENVIRONMENT_PROPERTY(waterObj.get(), WaterBody, waterBodyObj) 1582 1583 // Water level - necessary 1584 float waterHeight; 1585 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Height, waterHeight) 1586 1587 CmpPtr<ICmpWaterManager> cmpWaterMan(*pSimulation2, SYSTEM_ENTITY); 1588 debug_assert(!cmpWaterMan.null()); 1589 cmpWaterMan->SetWaterLevel(entity_pos_t::FromFloat(waterHeight)); 1590 1591 // If we have graphics, get rest of settings 1592 if (pWaterMan) 1593 { 1594 std::wstring waterType; 1595 // TODO: Water type unimplemented 1596 //GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Type, waterType) 1597 1598 RGBColor waterColour; 1599 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Colour, waterColour) 1600 pWaterMan->m_WaterColor = CColor(waterColour.X, waterColour.Y, waterColour.Z, 1.0f); 1601 1602 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Shininess, pWaterMan->m_Shininess) 1603 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Waviness, pWaterMan->m_Waviness) 1604 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Murkiness, pWaterMan->m_Murkiness) 1605 1606 RGBColor waterTint; 1607 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Tint, waterTint) 1608 pWaterMan->m_WaterTint = CColor(waterTint.X, waterTint.Y, waterTint.Z, 1.0f); 1609 1610 RGBColor reflectTint; 1611 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), ReflectionTint, reflectTint) 1612 pWaterMan->m_ReflectionTint = CColor(reflectTint.X, reflectTint.Y, reflectTint.Z, 1.0f); 1613 1614 GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), ReflectionTintStrength, pWaterMan->m_ReflectionTintStrength) 1615 } 1616 1617 m_LightEnv.CalculateSunDirection(); 1618 1619 #undef GET_ENVIRONMENT_PROPERTY 1620 1621 return 0; 1622 } 1623 1624 int CMapReader::ParseCamera() 1625 { 1626 // parse camera settings from map data 1627 // defaults if we don't find camera 1628 float declination = DEGTORAD(30.f), rotation = DEGTORAD(-45.f); 1629 CVector3D translation = CVector3D(100, 150, -100); 1630 1631 #define GET_CAMERA_PROPERTY(val, prop, out)\ 1632 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ 1633 LOGWARNING(L"CMapReader::ParseCamera() failed to get '%hs' property", #prop);\ 1634 1635 CScriptValRooted cameraObj; 1636 GET_CAMERA_PROPERTY(m_MapData.get(), Camera, cameraObj) 1637 1638 if (!cameraObj.undefined()) 1639 { // If camera property exists, read values 1640 CFixedVector3D pos; 1641 GET_CAMERA_PROPERTY(cameraObj.get(), Position, pos) 1642 translation = pos; 1643 1644 GET_CAMERA_PROPERTY(cameraObj.get(), Rotation, rotation) 1645 GET_CAMERA_PROPERTY(cameraObj.get(), Declination, declination) 1646 } 1647 #undef GET_CAMERA_PROPERTY 1648 1649 if (pGameView) 1650 { 1651 pGameView->GetCamera()->m_Orientation.SetXRotation(declination); 1652 pGameView->GetCamera()->m_Orientation.RotateY(rotation); 1653 pGameView->GetCamera()->m_Orientation.Translate(translation); 1654 pGameView->GetCamera()->UpdateFrustum(); 1655 } 1656 1657 return 0; 1658 } -
source/graphics/MapReader.h
82 82 // clean up everything used during delayed load 83 83 int DelayLoadFinished(); 84 84 85 // Copy random map settings over to sim 86 int LoadRMSettings(); 87 88 // Generate random map 89 int GenerateMap(); 90 91 // Parse script data into terrain 92 int ParseTerrain(); 93 94 // Parse script data into entities 95 int ParseEntities(); 96 97 // Parse script data into environment 98 int ParseEnvironment(); 99 100 // Parse script data into camera 101 int ParseCamera(); 102 103 85 104 // size of map 86 105 ssize_t m_PatchesPerSide; 87 106 // heightmap for map … … 95 114 // startup script 96 115 CStrW m_Script; 97 116 117 // random map data 118 CStrW m_ScriptFile; 119 CScriptValRooted m_ScriptSettings; 120 CScriptValRooted m_MapData; 121 98 122 // state latched by LoadMap and held until DelayedLoadFinished 99 123 CFileUnpacker unpacker; 100 124 CTerrain* pTerrain; -
source/ps/Game.cpp
144 144 } 145 145 else if (mapType == "random") 146 146 { 147 // TODO: Coming in another patch 147 // Load random map attributes 148 std::wstring scriptFile; 149 CScriptValRooted settings; 150 151 m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "script", scriptFile); 152 m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "settings", settings); 153 154 m_World->RegisterInit(scriptFile, settings, m_PlayerID); 148 155 } 149 156 150 157 -
source/ps/GameSetup/GameSetup.cpp
711 711 712 712 static bool Autostart(const CmdLineArgs& args); 713 713 714 void Init(const CmdLineArgs& args, int flags)714 void Init(const CmdLineArgs& args, int UNUSED(flags)) 715 715 { 716 716 h_mgr_init(); 717 717 … … 871 871 872 872 ScriptInterface& scriptInterface = g_Game->GetSimulation2()->GetScriptInterface(); 873 873 CScriptValRooted attrs; 874 scriptInterface.Eval("({})", attrs); 875 scriptInterface.SetProperty(attrs.get(), "mapType", std::string("scenario"), false); 876 scriptInterface.SetProperty(attrs.get(), "map", std::string(autostartMap), false); 874 scriptInterface.Eval("({settings: { Size: 208, Seed: 0, BaseTerrain: 'grass1_spring', BaseHeight: 0, PlayerData: [{Civ:'hele'},{Civ:'hele'}], RevealMap: false, LockTeams: false, GameType: 'conquest' } })", attrs); 875 if (args.Has("autostart-random")) 876 { 877 scriptInterface.SetProperty(attrs.get(), "script", std::string(autostartMap), false); 878 scriptInterface.SetProperty(attrs.get(), "mapType", std::string("random"), false); 879 } 880 else 881 { 882 scriptInterface.SetProperty(attrs.get(), "map", std::string(autostartMap), false); 883 scriptInterface.SetProperty(attrs.get(), "mapType", std::string("scenario"), false); 884 } 877 885 878 886 CScriptValRooted mpInitData; 879 887 g_GUI->GetScriptInterface().Eval("({isNetworked:true, playerAssignments:{}})", mpInitData); -
source/ps/World.cpp
94 94 } 95 95 } 96 96 97 void CWorld::RegisterInit(const CStrW& scriptFile, const CScriptValRooted& settings, int playerID) 98 { 99 // If scriptFile is empty, a blank map will be generated using settings (no RMS run) 100 CMapReader* reader = 0; 101 102 try 103 { 104 reader = new CMapReader; 105 CTriggerManager* pTriggerManager = NULL; 106 reader->LoadRandomMap(scriptFile, settings, m_Terrain, 107 CRenderer::IsInitialised() ? g_Renderer.GetWaterManager() : NULL, 108 CRenderer::IsInitialised() ? g_Renderer.GetSkyManager() : NULL, 109 &g_LightEnv, m_pGame->GetView(), 110 m_pGame->GetView() ? m_pGame->GetView()->GetCinema() : NULL, 111 pTriggerManager, m_pGame->GetSimulation2(), playerID); 112 // fails immediately, or registers for delay loading 113 } 114 catch (PSERROR_File& err) 115 { 116 delete reader; 117 LOGERROR(L"Failed to generate random map %ls: %hs", scriptFile.c_str(), err.what()); 118 throw PSERROR_Game_World_MapLoadFailed(); 119 } 120 } 121 122 97 123 /** 98 124 * Destructor. 99 125 * -
source/ps/World.h
25 25 #define INCLUDED_WORLD 26 26 27 27 #include "ps/Errors.h" 28 #include "scriptinterface/ScriptInterface.h" 28 29 29 30 #ifndef ERROR_GROUP_GAME_DEFINED 30 31 #define ERROR_GROUP_GAME_DEFINED … … 74 75 */ 75 76 void RegisterInit(const CStrW& mapFile, int playerID); 76 77 78 void RegisterInit(const CStrW& scriptFile, const CScriptValRooted& settings, int playerID); 79 77 80 /** 78 81 * Get the pointer to the terrain object. 79 82 * -
source/scriptinterface/ScriptConversions.cpp
22 22 #include "ps/utf16string.h" 23 23 #include "ps/CLogger.h" 24 24 #include "ps/CStr.h" 25 #include "graphics/Color.h" 26 #include "graphics/Entity.h" 25 27 26 28 #include "js/jsapi.h" 27 29 … … 70 72 return true; 71 73 } 72 74 75 template<> bool ScriptInterface::FromJSVal<u64>(JSContext* cx, jsval v, u64& out) 76 { 77 uint32 ret; 78 WARN_IF_NOT(JSVAL_IS_NUMBER(v), v); 79 if (!JS_ValueToECMAUint32(cx, v, &ret)) 80 return false; 81 out = ret; 82 return true; 83 } 84 73 85 template<> bool ScriptInterface::FromJSVal<u32>(JSContext* cx, jsval v, u32& out) 74 86 { 75 87 uint32 ret; … … 80 92 return true; 81 93 } 82 94 95 template<> bool ScriptInterface::FromJSVal<u16>(JSContext* cx, jsval v, u16& out) 96 { 97 uint16 ret; 98 WARN_IF_NOT(JSVAL_IS_NUMBER(v), v); 99 if (!JS_ValueToUint16(cx, v, &ret)) 100 return false; 101 out = ret; 102 return true; 103 } 104 83 105 // NOTE: we can't define a jsval specialisation, because that conflicts with integer types 84 106 template<> bool ScriptInterface::FromJSVal<CScriptVal>(JSContext* UNUSED(cx), jsval v, CScriptVal& out) 85 107 { … … 268 290 { 269 291 return FromJSVal_vector(cx, v, out); 270 292 } 293 294 template<> bool ScriptInterface::FromJSVal<std::vector<u16> >(JSContext* cx, jsval v, std::vector<u16>& out) 295 { 296 return FromJSVal_vector(cx, v, out); 297 } 298 299 template<> bool ScriptInterface::FromJSVal<std::vector<std::string> >(JSContext* cx, jsval v, std::vector<std::string>& out) 300 { 301 return FromJSVal_vector(cx, v, out); 302 } 303 304 305 template<> bool ScriptInterface::FromJSVal<Entity>(JSContext* cx, jsval v, Entity& out) 306 { 307 JSObject* obj; 308 if (!JS_ValueToObject(cx, v, &obj) || obj == NULL) 309 FAIL("Argument must be an object"); 310 311 jsval name, id, player, x, z, orient, actor; 312 313 if(!JS_GetProperty(cx, obj, "isActor", &actor) || !FromJSVal(cx, actor, out.isActor)) 314 FAIL("Failed to read Entity.isActor property"); 315 316 if (!out.isActor) 317 if(!JS_GetProperty(cx, obj, "player", &player) || !FromJSVal(cx, player, out.playerID)) 318 FAIL("Failed to read Entity.player property"); 319 320 if (!JS_GetProperty(cx, obj, "name", &name) || !FromJSVal(cx, name, out.templateName)) 321 FAIL("Failed to read Entity.name property"); 322 if (!JS_GetProperty(cx, obj, "id", &id) || !FromJSVal(cx, id, out.entityID)) 323 FAIL("Failed to read Entity.id property"); 324 if (!JS_GetProperty(cx, obj, "x", &x) || !FromJSVal(cx, x, out.positionX)) 325 FAIL("Failed to read Entity.x property"); 326 if (!JS_GetProperty(cx, obj, "y", &z) || !FromJSVal(cx, z, out.positionZ)) 327 FAIL("Failed to read Entity.y property"); 328 if (!JS_GetProperty(cx, obj, "orientation", &orient) || !FromJSVal(cx, orient, out.orientationY)) 329 FAIL("Failed to read Entity.orientation property"); 330 331 return true; 332 } 333 334 template<> bool ScriptInterface::FromJSVal<std::vector<Entity> >(JSContext* cx, jsval v, std::vector<Entity>& out) 335 { 336 return FromJSVal_vector(cx, v, out); 337 } 338 339 template<> bool ScriptInterface::FromJSVal<RGBColor>(JSContext* cx, jsval v, RGBColor& out) 340 { 341 JSObject* obj; 342 if (!JS_ValueToObject(cx, v, &obj) || obj == NULL) 343 FAIL("Argument must be an object"); 344 345 jsval r, g, b; 346 if (!JS_GetProperty(cx, obj, "r", &r) || !FromJSVal(cx, r, out.X)) 347 FAIL("Failed to read RGBColor.r property"); 348 if (!JS_GetProperty(cx, obj, "g", &g) || !FromJSVal(cx, g, out.Y)) 349 FAIL("Failed to read RGBColor.g property"); 350 if (!JS_GetProperty(cx, obj, "b", &b) || !FromJSVal(cx, b, out.Z)) 351 FAIL("Failed to read RGBColor.b property"); 352 353 return true; 354 } 355 No newline at end of file -
source/scriptinterface/ScriptInterface.cpp
36 36 37 37 #include "valgrind.h" 38 38 39 const int RUNTIME_SIZE = 16* 1024 * 1024; // TODO: how much memory is needed?39 const int RUNTIME_SIZE = 32 * 1024 * 1024; // TODO: how much memory is needed? 40 40 const int STACK_CHUNK_SIZE = 8192; 41 41 42 42 #if ENABLE_SCRIPT_PROFILING … … 280 280 | JSOPTION_VAROBJFIX // "recommended" (fixes variable scoping) 281 281 282 282 // Enable all the JIT features: 283 //| JSOPTION_JIT283 | JSOPTION_JIT 284 284 // | JSOPTION_METHODJIT 285 285 // | JSOPTION_PROFILING 286 286 );