Ticket #2944: wallgen_full_2015-08-16c.diff
File wallgen_full_2015-08-16c.diff, 170.3 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/globalscripts/Templates.js
function GetTemplateDataHelper(template, player) 251 251 "templates": { 252 252 "tower": template.WallSet.Templates.Tower, 253 253 "gate": template.WallSet.Templates.Gate, 254 "fort": template.WallSet.Templates.Fort || "structures/{civ}_fortress", 254 255 "long": template.WallSet.Templates.WallLong, 255 256 "medium": template.WallSet.Templates.WallMedium, 256 257 "short": template.WallSet.Templates.WallShort, … … function GetTemplateDataHelper(template, player) 258 259 "maxTowerOverlap": +template.WallSet.MaxTowerOverlap, 259 260 "minTowerOverlap": +template.WallSet.MinTowerOverlap, 260 261 }; 262 if (template.WallSet.Templates.WallEnd) 263 ret.wallSet.templates.end = template.WallSet.Templates.WallEnd; 264 if (template.WallSet.Templates.WallCurveQuarter) 265 ret.wallSet.templates.quarterCurve = template.WallSet.Templates.WallCurveQuarter; 266 if (template.WallSet.Templates.WallCurveEighth) 267 ret.wallSet.templates.eighthCurve = template.WallSet.Templates.WallCurveEighth; 261 268 } 262 269 263 270 if (template.WallPiece) 264 ret.wallPiece = {"length": +template.WallPiece.Length}; 271 ret.wallPiece = { 272 "length": +template.WallPiece.Length, 273 "angle": +(template.WallPiece.Orientation || 1) * Math.PI, 274 "indent": +(template.WallPiece.Indent || 0), 275 "bend": +(template.WallPiece.Bend || 0) * Math.PI, 276 }; 265 277 266 278 return ret; 267 279 } -
binaries/data/mods/public/maps/random/belgian_uplands.js
var mapSize = getMapSize(); 21 21 // Heightmap functionality 22 22 ////////// 23 23 24 // Some general heightmap settings25 const MIN_HEIGHT = - SEA_LEVEL; // 20, should be set in the libs!26 const MAX_HEIGHT = 0xFFFF/HEIGHT_UNITS_PER_METRE - SEA_LEVEL; // A bit smaler than 90, should be set in the libs!27 28 24 // Add random heightmap generation functionality 29 25 function getRandomReliefmap(minHeight, maxHeight) 30 26 { … … function getRandomReliefmap(minHeight, maxHeight) 35 31 if (maxHeight > MAX_HEIGHT) 36 32 warn("getRandomReliefmap: Argument maxHeight is smaler then the supported maximum height of " + MAX_HEIGHT + " (const MAX_HEIGHT): " + maxHeight) 37 33 var reliefmap = []; 38 for (var x = 0; x <= mapSize; x++)34 for (var x = 0; x <= mapSize; ++x) 39 35 { 40 36 reliefmap.push([]); 41 for (var y = 0; y <= mapSize; y++)37 for (var y = 0; y <= mapSize; ++y) 42 38 { 43 39 reliefmap[x].push(randFloat(minHeight, maxHeight)); 44 40 } … … function getRandomReliefmap(minHeight, maxHeight) 50 46 function setReliefmap(reliefmap) 51 47 { 52 48 // g_Map.height = reliefmap; 53 for (var x = 0; x <= mapSize; x++)49 for (var x = 0; x <= mapSize; ++x) 54 50 { 55 for (var y = 0; y <= mapSize; y++)51 for (var y = 0; y <= mapSize; ++y) 56 52 { 57 53 setHeight(x, y, reliefmap[x][y]); 58 54 } … … function getMinAndMaxHeight(reliefmap) 65 61 var height = {}; 66 62 height.min = Infinity; 67 63 height.max = -Infinity; 68 for (var x = 0; x <= mapSize; x++)64 for (var x = 0; x <= mapSize; ++x) 69 65 { 70 for (var y = 0; y <= mapSize; y++)66 for (var y = 0; y <= mapSize; ++y) 71 67 { 72 68 if (reliefmap[x][y] < height.min) 73 69 height.min = reliefmap[x][y]; … … function getRescaledReliefmap(reliefmap, minHeight, maxHeight) 89 85 if (maxHeight > MAX_HEIGHT) 90 86 warn("getRescaledReliefmap: Argument maxHeight is smaler then the supported maximum height of " + MAX_HEIGHT + " (const MAX_HEIGHT): " + maxHeight) 91 87 var oldHeightRange = getMinAndMaxHeight(reliefmap); 92 for (var x = 0; x <= mapSize; x++)88 for (var x = 0; x <= mapSize; ++x) 93 89 { 94 for (var y = 0; y <= mapSize; y++)90 for (var y = 0; y <= mapSize; ++y) 95 91 { 96 92 newReliefmap[x][y] = minHeight + (reliefmap[x][y] - oldHeightRange.min) / (oldHeightRange.max - oldHeightRange.min) * (maxHeight - minHeight); 97 93 } … … function getHeightErrosionedReliefmap(reliefmap, strength) 105 101 var newReliefmap = deepcopy(reliefmap); 106 102 strength = (strength || 1.0); // Values much higher then 1 (1.32+ for an 8 tile map, 1.45+ for a 12 tile map, 1.62+ @ 20 tile map, 0.99 @ 4 tiles) will result in a resonance disaster/self interference 107 103 var map = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]]; // Default 108 for (var x = 0; x <= mapSize; x++)104 for (var x = 0; x <= mapSize; ++x) 109 105 { 110 for (var y = 0; y <= mapSize; y++)106 for (var y = 0; y <= mapSize; ++y) 111 107 { 112 108 var div = 0; 113 for (var i = 0; i < map.length; i++)109 for (var i = 0; i < map.length; ++i) 114 110 newReliefmap[x][y] += strength / map.length * (reliefmap[(x + map[i][0] + mapSize + 1) % (mapSize + 1)][(y + map[i][1] + mapSize + 1) % (mapSize + 1)] - reliefmap[x][y]); // Not entirely sure if scaling with map.length is perfect but tested values seam to indicate it is 115 111 } 116 112 } … … var terreins = ["temp_grass_plants|gaia/flora_tree_euro_beech", "temp_grass_moss 173 169 "temp_grass_long|gaia/flora_tree_apple", "temp_grass_clovers|gaia/flora_bush_berry", "temp_grass_clovers_2|gaia/flora_bush_grapes", 174 170 "temp_grass_plants|gaia/fauna_deer", "temp_grass_long_b|gaia/fauna_rabbit"]; 175 171 var numTerreins = terreins.length; 176 for (var i = 0; i < numTerreins; i++)172 for (var i = 0; i < numTerreins; ++i) 177 173 terreins.push("temp_grass_plants"); 178 174 textueByHeight.push({"upperHeightLimit": waterHeightAdjusted + 5/6 * (heightRange.max - waterHeightAdjusted), "terrain": terreins}); 179 175 // Unpassable woods … … var enoughTiles = false; 200 196 var tries = 0; 201 197 while (!goodStartPositionsFound) 202 198 { 203 tries++;199 ++tries; 204 200 log("Starting giant while loop try " + tries); 205 201 // Generate reliefmap 206 202 var myReliefmap = getRandomReliefmap(heightRange.min, heightRange.max); 207 for (var i = 0; i < 50 + mapSize/4; i++) // Cycles depend on mapsize (more cycles -> bigger structures)203 for (var i = 0; i < 50 + mapSize/4; ++i) // Cycles depend on mapsize (more cycles -> bigger structures) 208 204 myReliefmap = getHeightErrosionedReliefmap(myReliefmap, 1); 209 205 myReliefmap = getRescaledReliefmap(myReliefmap, heightRange.min, heightRange.max); 210 206 setReliefmap(myReliefmap); … … while (!goodStartPositionsFound) 217 213 var lowerHeightLimit = textueByHeight[3].upperHeightLimit; 218 214 var upperHeightLimit = textueByHeight[6].upperHeightLimit; 219 215 // Check for valid points by height 220 for (var x = distToBorder + minTerrainDistToBorder; x < mapSize - distToBorder - minTerrainDistToBorder; x++)216 for (var x = distToBorder + minTerrainDistToBorder; x < mapSize - distToBorder - minTerrainDistToBorder; ++x) 221 217 { 222 for (var y = distToBorder + minTerrainDistToBorder; y < mapSize - distToBorder - minTerrainDistToBorder; y++)218 for (var y = distToBorder + minTerrainDistToBorder; y < mapSize - distToBorder - minTerrainDistToBorder; ++y) 223 219 { 224 220 var actualHeight = getHeight(x, y); 225 221 if (actualHeight > lowerHeightLimit && actualHeight < upperHeightLimit) 226 222 { 227 223 // Check for points within a valid area by height (rectangular since faster) 228 224 var isPossible = true; 229 for (var offX = - neededDistance; offX <= neededDistance; offX++)225 for (var offX = - neededDistance; offX <= neededDistance; ++offX) 230 226 { 231 for (var offY = - neededDistance; offY <= neededDistance; offY++)227 for (var offY = - neededDistance; offY <= neededDistance; ++offY) 232 228 { 233 229 var testHeight = getHeight(x + offX, y + offY); 234 230 if (testHeight <= lowerHeightLimit || testHeight >= upperHeightLimit) … … while (!goodStartPositionsFound) 252 248 // Reduce to tiles in a circle of mapSize / 2 distance to the center (to avoid players placed in corners) 253 249 var possibleStartPositionsTemp = []; 254 250 var maxDistToCenter = mapSize / 2; 255 for (var i = 0; i < possibleStartPositions.length; i++)251 for (var i = 0; i < possibleStartPositions.length; ++i) 256 252 { 257 253 var deltaX = possibleStartPositions[i][0] - mapSize / 2; 258 254 var deltaY = possibleStartPositions[i][1] - mapSize / 2; … … while (!goodStartPositionsFound) 270 266 var maxDistToResources = distToBorder; // Has to be <= distToBorder! 271 267 var minNumLowTiles = 10; 272 268 var minNumHighTiles = 10; 273 for (var i = 0; i < possibleStartPositions.length; i++)269 for (var i = 0; i < possibleStartPositions.length; ++i) 274 270 { 275 271 var numLowTiles = 0; 276 272 var numHighTiles = 0; 277 for (var dx = - maxDistToResources; dx < maxDistToResources; dx++)273 for (var dx = - maxDistToResources; dx < maxDistToResources; ++dx) 278 274 { 279 for (var dy = - maxDistToResources; dy < maxDistToResources; dy++)275 for (var dy = - maxDistToResources; dy < maxDistToResources; ++dy) 280 276 { 281 277 var testHeight = getHeight(possibleStartPositions[i][0] + dx, possibleStartPositions[i][1] + dy); 282 278 if (testHeight < lowerHeightLimit) 283 numLowTiles++;279 ++numLowTiles; 284 280 if (testHeight > upperHeightLimit) 285 numHighTiles++;281 ++numHighTiles; 286 282 if (numLowTiles > minNumLowTiles && numHighTiles > minNumHighTiles) 287 283 break; 288 284 } … … while (!goodStartPositionsFound) 311 307 // Get some random start location derivations. NOTE: Itterating over all possible derivations is just to much (valid points ** numPlayers) 312 308 var maxTries = 100000; // floor(800000 / (Math.pow(numPlayers, 2) / 2)); 313 309 var possibleDerivations = []; 314 for (var i = 0; i < maxTries; i++)310 for (var i = 0; i < maxTries; ++i) 315 311 { 316 312 var vector = []; 317 for (var p = 0; p < numPlayers; p++)313 for (var p = 0; p < numPlayers; ++p) 318 314 vector.push(randInt(possibleStartPositions.length)); 319 315 possibleDerivations.push(vector); 320 316 } 321 317 322 318 // Choose the start location derivation with the greatest minimum distance between players 323 319 var maxMinDist = 0; 324 for (var d = 0; d < possibleDerivations.length; d++)320 for (var d = 0; d < possibleDerivations.length; ++d) 325 321 { 326 322 var minDist = 2 * mapSize; 327 for (var p1 = 0; p1 < numPlayers - 1; p1++)323 for (var p1 = 0; p1 < numPlayers - 1; ++p1) 328 324 { 329 for (var p2 = p1 + 1; p2 < numPlayers; p2++)325 for (var p2 = p1 + 1; p2 < numPlayers; ++p2) 330 326 { 331 327 if (p1 != p2) 332 328 { … … if (mapSize > 500) 372 368 propDensity = 1/4; 373 369 else if (mapSize > 400) 374 370 propDensity = 3/4; 375 for(var x = minTerrainDistToBorder; x < mapSize - minTerrainDistToBorder; x++)371 for(var x = minTerrainDistToBorder; x < mapSize - minTerrainDistToBorder; ++x) 376 372 { 377 for (var y = minTerrainDistToBorder; y < mapSize - minTerrainDistToBorder; y++)373 for (var y = minTerrainDistToBorder; y < mapSize - minTerrainDistToBorder; ++y) 378 374 { 379 375 var textureMinHeight = heightRange.min; 380 for (var i = 0; i < textueByHeight.length; i++)376 for (var i = 0; i < textueByHeight.length; ++i) 381 377 { 382 378 if (getHeight(x, y) >= textureMinHeight && getHeight(x, y) <= textueByHeight[i].upperHeightLimit) 383 379 { … … RMS.SetProgress(90); 497 493 // Place players and start resources 498 494 //////// 499 495 500 for (var p = 0; p < numPlayers; p++)496 for (var p = 0; p < numPlayers; ++p) 501 497 { 502 498 var actualX = possibleStartPositions[bestDerivation[p]][0]; 503 499 var actualY = possibleStartPositions[bestDerivation[p]][1]; … … for (var p = 0; p < numPlayers; p++) 509 505 { 510 506 var uAngle = BUILDING_ANGlE - PI * (2-j) / 2; 511 507 var count = 4; 512 for (var numberofentities = 0; numberofentities < count; numberofentities++)508 for (var numberofentities = 0; numberofentities < count; ++numberofentities) 513 509 { 514 510 var ux = actualX + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); 515 511 var uz = actualY + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); … … timeArray.push(new Date().getTime()); 531 527 // Calculate progress percentage with the time checks 532 528 var generationTime = timeArray[timeArray.length - 1] - timeArray[0]; 533 529 log("Total generation time (ms): " + generationTime); 534 for (var i = 0; i < timeArray.length; i++)530 for (var i = 0; i < timeArray.length; ++i) 535 531 { 536 532 var timeSinceStart = timeArray[i] - timeArray[0]; 537 533 var progressPercentage = 100 * timeSinceStart / generationTime; -
binaries/data/mods/public/maps/random/rmgen/library.js
4 4 ///////////////////////////////////////////////////////////////////////////////////////////// 5 5 6 6 const PI = Math.PI; 7 const TWO_PI = 2 * Math.PI; 7 const TWO_PI = 2 * Math.PI; // mathematically known as 'tau' 8 8 const TERRAIN_SEPARATOR = "|"; 9 const SEA_LEVEL = 20.0;9 const SEA_LEVEL = 160.0; 10 10 const CELL_SIZE = 4; 11 11 const HEIGHT_UNITS_PER_METRE = 92; 12 12 const MIN_MAP_SIZE = 128; 13 13 const MAX_MAP_SIZE = 512; 14 14 const FALLBACK_CIV = "athen"; 15 // Constants needed for heightmap_manipulation.js 16 const MAX_HEIGHT_RANGE = 0xFFFF / HEIGHT_UNITS_PER_METRE // Engine limit, Roughly 700 meters 17 const MIN_HEIGHT = - SEA_LEVEL; 18 const MAX_HEIGHT = MAX_HEIGHT_RANGE - SEA_LEVEL; 19 // Entity template structure keys that might change, for easier mod support 20 const STARTING_ENTITY_KEY = "StartEntities"; 21 const START_ENTITY_TEMPLATE_PATH_KEY = "Template" 22 const BUILDER_TEMPLATEPATH_KEYS = ["Builder", "Entities", "_string"]; 23 const PRODUCTION_TEMPLATEPATH_KEYS = ["ProductionQueue", "Entities", "_string"]; 24 const CIV_PLACEHOLDER_STRING = "{civ}"; 15 25 16 26 ///////////////////////////////////////////////////////////////////////////////////////////// 17 27 // Utility functions … … function argsToArray(x) 103 113 if (numArgs != 1) 104 114 { 105 115 var ret = new Array(numArgs); 106 for (var i=0; i < numArgs; i++)116 for (var i=0; i < numArgs; ++i) 107 117 { 108 118 ret[i] = x[i]; 109 119 } … … function shuffleArray(source) 132 142 return []; 133 143 134 144 var result = [source[0]]; 135 for (var i = 1; i < source.length; i++)145 for (var i = 1; i < source.length; ++i) 136 146 { 137 147 var j = randInt(0, i); 138 148 result[i] = result[j]; … … function createAreas(centeredPlacer, painter, constraint, num, retryFactor) 172 182 var area = g_Map.createArea(centeredPlacer, painter, constraint); 173 183 if (area !== undefined) 174 184 { 175 good++;185 ++good; 176 186 result.push(area); 177 187 } 178 188 else 179 189 { 180 bad++;190 ++bad; 181 191 } 182 192 } 183 193 return result; … … function createAreasInAreas(centeredPlacer, painter, constraint, num, retryFacto 208 218 var area = g_Map.createArea(centeredPlacer, painter, constraint); 209 219 if (area !== undefined) 210 220 { 211 good++;221 ++good; 212 222 result.push(area); 213 223 } 214 224 else 215 225 { 216 bad++;226 ++bad; 217 227 } 218 228 } 219 229 return result; … … function createObjectGroups(placer, player, constraint, num, retryFactor) 248 258 var result = createObjectGroup(placer, player, constraint); 249 259 if (result !== undefined) 250 260 { 251 good++;261 ++good; 252 262 } 253 263 else 254 264 { 255 bad++;265 ++bad; 256 266 } 257 267 } 258 268 return good; … … function createObjectGroupsByAreas(placer, player, constraint, num, retryFactor, 282 292 var result = createObjectGroup(placer, player, constraint); 283 293 if (result !== undefined) 284 294 { 285 good++;295 ++good; 286 296 } 287 297 else 288 298 { 289 bad++;299 ++bad; 290 300 } 291 301 } 292 302 return good; … … function getNumPlayers() 394 404 return g_MapSettings.PlayerData.length - 1; 395 405 } 396 406 407 // Takes nothing, returns an array of strings representing all available civilizations 408 function getCivList() 409 { 410 var raw_civData = RMS.GetCivData(); 411 var civList = []; 412 for (var i = 0; i < raw_civData.length; ++i) 413 civList.push(JSON.parse(raw_civData[i]).Code); 414 415 return civList; 416 } 417 418 // Takes nothing, returns an associative array with civ strings as keys containing all unpacked civ data (Templates need to be unpacked with RMS.GetTemplate() if needed) 419 function getFullCivData() 420 { 421 var rawCivData = RMS.GetCivData(); 422 var unpackedCivData = {}; 423 for (var i = 0; i < rawCivData.length; ++i) 424 { 425 var singleCivData = JSON.parse(rawCivData[i]); 426 unpackedCivData[singleCivData.Code] = singleCivData; 427 } 428 429 return unpackedCivData; 430 } 431 432 // Takes a player number (0-7, so Gaia excluded). Returns this players civ string 433 // ToDo: If the player number is to high an error will occur (and the fallback won't be reached)! 397 434 function getCivCode(player) 398 435 { 399 436 if (g_MapSettings.PlayerData[player+1].Civ) 400 437 return g_MapSettings.PlayerData[player+1].Civ; 401 438 402 warn(" undefined civ specified for player " + (player + 1) + ", falling back to '" + FALLBACK_CIV + "'");439 warn("Undefined civ specified for player " + (player + 1) + ", falling back to '" + FALLBACK_CIV + "'"); 403 440 return FALLBACK_CIV; 404 441 } 405 442 443 // Takes an entity path and a key list to get the templates value 444 function getTemplateValue(entPath, key_list) 445 { 446 var subdata = RMS.GetTemplate(entPath); 447 for (var i = 0; i < key_list.length; ++i) 448 { 449 if (!subdata[key_list[i]]) 450 {return false}; 451 subdata = subdata[key_list[i]]; 452 } 453 return subdata; 454 } 455 456 // Returns a list of all templates paths available to the given civ 457 function getTempatePathList(civ) 458 { 459 var templatePaths = getFullCivData(); 460 if (!templatePaths[civ]) 461 { 462 warn("getTempatePathList: Unknown civ '" + civ + "' not in " + Object.keys(templatePaths)); 463 return false; 464 } 465 templatePaths = templatePaths[civ]; 466 467 if (!templatePaths[STARTING_ENTITY_KEY]) 468 { 469 warn("getTempatePathList: Civ has no starting entities as defined in STARTING_ENTITY_KEY (" + STARTING_ENTITY_KEY + "): " + Object.keys(templatePaths)); 470 return false; 471 } 472 templatePaths = templatePaths[STARTING_ENTITY_KEY]; 473 474 for (var i = 0; i < templatePaths.length; ++i) 475 { 476 if (!templatePaths[i][START_ENTITY_TEMPLATE_PATH_KEY]) 477 { 478 warn("getTempatePathList: Starting entity list item has no template as defined in START_ENTITY_TEMPLATE_PATH_KEY (" + START_ENTITY_TEMPLATE_PATH_KEY + "): " + Object.keys(templatePaths)); 479 return false; 480 } 481 templatePaths[i] = templatePaths[i][START_ENTITY_TEMPLATE_PATH_KEY]; 482 } 483 var foundNew = 1; 484 while (foundNew > 0) 485 { 486 foundNew = 0; 487 var methods = [BUILDER_TEMPLATEPATH_KEYS, PRODUCTION_TEMPLATEPATH_KEYS]; 488 for (var m = 0; m < methods.length; ++m) 489 { 490 for (var t = 0; t < templatePaths.length; ++t) 491 { 492 var pathsToCheck = getTemplateValue(templatePaths[t], methods[m]); 493 if (typeof(pathsToCheck) === typeof("")) 494 { 495 pathsToCheck = pathsToCheck.split(/\s+/); 496 for (var c = 0; c < pathsToCheck.length; ++c) 497 { 498 var actualPath = pathsToCheck[c].replace(CIV_PLACEHOLDER_STRING, civ); 499 if (templatePaths.indexOf(actualPath) == -1 && RMS.TemplateExists(actualPath)) 500 { 501 templatePaths.push(actualPath); 502 ++foundNew; 503 } 504 } 505 } 506 } 507 } 508 } 509 return templatePaths; 510 } 511 406 512 function areAllies(player1, player2) 407 513 { 408 514 if ((g_MapSettings.PlayerData[player1+1].Team === undefined) || (g_MapSettings.PlayerData[player2+1].Team === undefined) || (g_MapSettings.PlayerData[player2+1].Team == -1) || (g_MapSettings.PlayerData[player1+1].Team == -1)) … … function sortPlayers(source) 434 540 435 541 var result = new Array(0); 436 542 var team = new Array(5); 437 for (var q = 0; q < 5; q++)543 for (var q = 0; q < 5; ++q) 438 544 { 439 545 team[q] = new Array(1); 440 546 } 441 547 442 for (var i = -1; i < 4; i++)548 for (var i = -1; i < 4; ++i) 443 549 { 444 for (var j = 0; j < source.length; j++)550 for (var j = 0; j < source.length; ++j) 445 551 { 446 552 if (getPlayerTeam(j) == i) 447 553 { … … function primeSortPlayers(source) 461 567 462 568 var prime = new Array(source.length); 463 569 464 for (var i = 0; i < round(source.length/2); i++)570 for (var i = 0; i < round(source.length/2); ++i) 465 571 { 466 572 prime[2*i]=source[i]; 467 573 prime[2*i+1]=source[source.length-1-i]; … … function unPaintClass(id) 535 641 function avoidClasses(/*class1, dist1, class2, dist2, etc*/) 536 642 { 537 643 var ar = new Array(arguments.length/2); 538 for (var i = 0; i < arguments.length/2; i++)644 for (var i = 0; i < arguments.length/2; ++i) 539 645 { 540 646 ar[i] = new AvoidTileClassConstraint(arguments[2*i], arguments[2*i+1]); 541 647 } … … function avoidClasses(/*class1, dist1, class2, dist2, etc*/) 555 661 function stayClasses(/*class1, dist1, class2, dist2, etc*/) 556 662 { 557 663 var ar = new Array(arguments.length/2); 558 for (var i = 0; i < arguments.length/2; i++)664 for (var i = 0; i < arguments.length/2; ++i) 559 665 { 560 666 ar[i] = new StayInTileClassConstraint(arguments[2*i], arguments[2*i+1]); 561 667 } … … function stayClasses(/*class1, dist1, class2, dist2, etc*/) 575 681 function borderClasses(/*class1, idist1, odist1, class2, idist2, odist2, etc*/) 576 682 { 577 683 var ar = new Array(arguments.length/3); 578 for (var i = 0; i < arguments.length/3; i++)684 for (var i = 0; i < arguments.length/3; ++i) 579 685 { 580 686 ar[i] = new BorderTileClassConstraint(arguments[3*i], arguments[3*i+1], arguments[3*i+2]); 581 687 } … … function getTerrainTexture(x, y) 642 748 { 643 749 return g_Map.getTexture(x, y); 644 750 } 645 -
binaries/data/mods/public/maps/random/rmgen/misc.js
function passageMaker(x1, z1, x2, z2, width, maxheight, height, smooth, tileclas 20 20 var tchm = TILE_CENTERED_HEIGHT_MAP; 21 21 TILE_CENTERED_HEIGHT_MAP = true; 22 22 var mapSize = g_Map.size; 23 for (var ix = 0; ix < mapSize; ix++)23 for (var ix = 0; ix < mapSize; ++ix) 24 24 { 25 for (var iz = 0; iz < mapSize; iz++)25 for (var iz = 0; iz < mapSize; ++iz) 26 26 { 27 27 var a = z1-z2; 28 28 var b = x2-x1; … … function rndRiver(f, seed) 92 92 var rndRe = 0; 93 93 var rndRr = f-floor(f); 94 94 var rndRa = 0; 95 for (var rndRx=0; rndRx<=floor(f); rndRx++)95 for (var rndRx=0; rndRx<=floor(f); ++rndRx) 96 96 { 97 97 rndRw = 10*(rndRw-floor(rndRw)); 98 98 } … … function createStartingPlayerEntities(fx, fz, playerid, civEntities, BUILDING_AN 148 148 { 149 149 var uAngle = BUILDING_ANGlE - PI * (2-j) / 2; 150 150 var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); 151 for (var numberofentities = 0; numberofentities < count; numberofentities++)151 for (var numberofentities = 0; numberofentities < count; ++numberofentities) 152 152 { 153 153 var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); 154 154 var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); … … function createStartingPlayerEntities(fx, fz, playerid, civEntities, BUILDING_AN 157 157 } 158 158 } 159 159 160 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 160 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 161 161 // placeCivDefaultEntities 162 162 // 163 163 // Creates the default starting player entities depending on the players civ 164 164 // fx&fy: position of player base 165 165 // playerid: id of player 166 166 // angle: angle of main base building, optional, default is BUILDING_ANGlE 167 // kwargs: Takes some optional keyword arguments to tweek things168 // 'iberWall': may be false, 'walls' (default) or 'towers'. Determines the defensive structures Iberians get as civ bonus167 // kwargs: Optional. Takes an associative array with keyword arguments to tweak things: 168 // Known keys: 'iberWall': may be false, 'walls' (default) or 'towers'. Determines the defensive structures Iberians get as civ bonus 169 169 // 170 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 170 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 171 171 function placeCivDefaultEntities(fx, fz, playerid, angle, kwargs) 172 172 { 173 173 // Unpack kwargs … … function placeCivDefaultEntities(fx, fz, playerid, angle, kwargs) 187 187 { 188 188 var uAngle = angle - PI * (2-j) / 2; 189 189 var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); 190 for (var numberofentities = 0; numberofentities < count; numberofentities++)190 for (var numberofentities = 0; numberofentities < count; ++numberofentities) 191 191 { 192 192 var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); 193 193 var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); … … function placeCivDefaultEntities(fx, fz, playerid, angle, kwargs) 221 221 function paintTerrainBasedOnHeight(minheight, maxheight, mode, terrain) 222 222 { 223 223 var mSize = g_Map.size; 224 for (var qx = 0; qx < mSize; qx++)224 for (var qx = 0; qx < mSize; ++qx) 225 225 { 226 for (var qz = 0; qz < mSize; qz++)226 for (var qz = 0; qz < mSize; ++qz) 227 227 { 228 228 if (mode == 0) 229 229 { … … function paintTerrainBasedOnHeight(minheight, maxheight, mode, terrain) 273 273 function paintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) 274 274 { 275 275 var mSize = g_Map.size; 276 for (var qx = 0; qx < mSize; qx++)276 for (var qx = 0; qx < mSize; ++qx) 277 277 { 278 for (var qz = 0; qz < mSize; qz++)278 for (var qz = 0; qz < mSize; ++qz) 279 279 { 280 280 if (mode == 0) 281 281 { … … function paintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) 313 313 function unPaintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) 314 314 { 315 315 var mSize = g_Map.size; 316 for (var qx = 0; qx < mSize; qx++)316 for (var qx = 0; qx < mSize; ++qx) 317 317 { 318 for (var qz = 0; qz < mSize; qz++)318 for (var qz = 0; qz < mSize; ++qz) 319 319 { 320 320 if (mode == 0) 321 321 { … … function createMountain(maxHeight, minRadius, maxRadius, numCircles, constraint, 617 617 618 618 for (var ix = sx; ix <= lx; ++ix) 619 619 { 620 for (var iz = sz; iz <= lz; ++ 620 for (var iz = sz; iz <= lz; ++iz) 621 621 { 622 622 dx = ix - cx; 623 623 dz = iz - cz; … … function createMountain(maxHeight, minRadius, maxRadius, numCircles, constraint, 666 666 667 667 for (var ix = sx; ix <= lx; ++ix) 668 668 { 669 for (var iz = sz; iz <= lz; ++ 669 for (var iz = sz; iz <= lz; ++iz) 670 670 { 671 671 if (fcc) 672 672 if ((x - ix) > fcc || (ix - x) > fcc || (z - iz) > fcc || (iz - z) > fcc) … … function createMountain(maxHeight, minRadius, maxRadius, numCircles, constraint, 737 737 738 738 for (var ix = sx; ix <= lx; ++ix) 739 739 { 740 for (var iz = sz; iz <= lz; ++ 740 for (var iz = sz; iz <= lz; ++iz) 741 741 { 742 742 dx = ix - cx; 743 743 dz = iz - cz; -
binaries/data/mods/public/maps/random/rmgen/wall_builder.js
27 27 // maxTrys 28 28 // Add treasures to wall style "others" 29 29 // Adjust documentation 30 // Perhaps rename "endLeft" to "start" and "endRight" to "end" 31 // ?Use available civ-type wall elements rather than palisades: Remove "endLeft" and "endRight" as default wall elements and adjust default palisade fortress types? 32 // ?Remove "endRight", "endLeft" and adjust generic fortress types palisades? 33 // ?Think of something to enable splitting walls into two walls so more complex walls can be build and roads can have branches/crossroads? 30 // ?Use available civ-type wall elements rather than palisades: Remove "end" as a default wall element and adjust default palisade fortress types? 31 // ?Adjust generic fortress types palisades? 32 // ?Think of something to enable splitting walls into two walls so more complex walls can be built? 34 33 // ?Readjust placement angle for wall elements with bending when used in linear/circular walls by their bending? 35 34 35 /** 36 * Set some globals for this module 37 */ 38 var g_WallStyles = {}; 39 var g_WallStyleList = []; 40 var g_CivData = getFullCivData(); 41 var g_CivList = Object.keys(g_CivData); 42 var g_FortressTypes = {}; 43 var g_FortressTypeKeys = ["tiny", "small", "medium", "normal", "large", "veryLarge", "giant"]; 36 44 37 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 38 // WallElement class definition 39 // 40 // Concept: If placed unrotated the wall's course is towards positive Y (top) with "outside" right (+X) and "inside" left (-X) like unrotated entities has their drop-points right (in rmgen) 41 // The course of the wall will be changed by corners (bending != 0) and so the "inside"/"outside" direction 42 // 43 // type Descriptive string, example: "wallLong". NOTE: Not really needed. Mainly for custom wall elements and to get the wall element type in code 44 // entity Optional. Template name string of the entity to be placed, example: "structures/cart_wall_long". Default is undefined (No entity placed) 45 // angle Optional. The angle (float) added to place the entity so "outside" is right when the wall element is placed unrotated. Default is 0 46 // width Optional. How far this wall element lengthens the wall (float), if unrotated the Y space needed. Default is 0 47 // indent Optional. The lateral indentation of the entity, drawn "inside" (positive values) or pushed "outside" (negative values). Default is 0 48 // bending Optional. How the course of the wall is changed after this element, positive is bending "in"/left/counter clockwise (like entity placement) 49 // NOTE: Bending is not supported by all placement functions (see there) 50 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 51 function WallElement(type, entity, angle, width, indent, bending) 45 /** 46 * Basic Initialisation 47 * 48 * Fetches wallsets from {civ}.json files, and then uses them to load 49 * basic wall elements 50 */ 51 for (let civ of g_CivList) 52 52 { 53 this.type = type; 54 // Default wall element type documentation: 55 // Lengthening straight blocking (mainly left/right symmetric) wall elements (Walls and wall fortifications) 56 // "wall" A blocking straight wall element that mainly lengthens the wall, self-explanatory 57 // "wallShort" self-explanatory 58 // "wallLong" self-explanatory 59 // "tower" A blocking straight wall element with damage potential (but for palisades) that slightly lengthens the wall, example: wall tower, palisade tower(No attack) 60 // "wallFort" A blocking straight wall element with massive damage potential that lengthens the wall, example: fortress, palisade fort 61 // Lengthening straight non/custom blocking (mainly left/right symmetric) wall elements (Gates and entries) 62 // "gate" A blocking straight wall element with passability determined by owner, example: gate (Functionality not yet implemented) 63 // "entry" A non-blocking straight wall element (same width as gate) but without an actual template or just a flag/column/obelisk 64 // "entryTower" A non-blocking straight wall element (same width as gate) represented by a single (maybe indented) template, example: defence tower, wall tower, outpost, watchtower 65 // "entryFort" A non-blocking straight wall element represented by a single (maybe indented) template, example: fortress, palisade fort 66 // Bending wall elements (Wall corners) 67 // "cornerIn" A wall element bending the wall by PI/2 "inside" (left, +, see above), example: wall tower, palisade curve 68 // "cornerOut" A wall element bending the wall by PI/2 "outside" (right, -, see above), example: wall tower, palisade curve 69 // "cornerHalfIn" A wall element bending the wall by PI/4 "inside" (left, +, see above), example: wall tower, palisade curve. NOTE: Not yet implemented 70 // "cornerHalfOut" A wall element bending the wall by PI/4 "outside" (right, -, see above), example: wall tower, palisade curve. NOTE: Not yet implemented 71 // Zero length straight indented (mainly left/right symmetric) wall elements (Outposts/watchtowers and non-defensive base structures) 72 // "outpost" A zero-length wall element without bending far indented so it stands outside the wall, example: outpost, defence tower, watchtower 73 // "house" A zero-length wall element without bending far indented so it stands inside the wall that grants population bonus, example: house, hut, longhouse 74 // "barracks" A zero-length wall element without bending far indented so it stands inside the wall that grants unit production, example: barracks, tavern, ... 75 this.entity = entity; 76 this.angle = (angle !== undefined) ? angle : 0*PI; 77 this.width = (width !== undefined) ? width : 0; 78 this.indent = (indent !== undefined) ? indent : 0; 79 this.bending = (bending !== undefined) ? bending : 0*PI; 53 let civInfo = g_CivData[civ]; 54 if (!civInfo.WallSets) 55 continue; 56 57 for (let path of civInfo.WallSets) 58 { 59 let style = path.split("/")[1].split("_"); 60 style = (style[0]=="wallset") ? style[1] : style[0]+"_"+style[2]; 61 62 if (g_WallStyleList.indexOf(style) == -1) 63 { 64 g_WallStyleList.push(style); 65 g_WallStyles[style] = {}; 66 let wallset = GetTemplateDataHelper(RMS.GetTemplate(path)).wallSet; 67 for (let element in wallset.templates) 68 setWallElement(style, element, wallset.templates[element].replace("{civ}",civ)) 69 g_WallStyles[style]["@overlap"] = wallset.minTowerOverlap * getWallElement(style, "tower").length; 70 } 71 } 80 72 } 81 73 82 74 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … function WallElement(type, entity, angle, width, indent, bending) 86 78 // It's mainly the abstract shape defined in a Fortress instances wall because different styles can be used for it (see wallStyles) 87 79 // 88 80 // type Descriptive string, example: "tiny". Not really needed (WallTool.wallTypes["type string"] is used). Mainly for custom wall elements 89 // wall Optional. Array of wall element strings. Can be set afterwards. Default is an e pty array.81 // wall Optional. Array of wall element strings. Can be set afterwards. Default is an empty array. 90 82 // Example: ["entrance", "wall", "cornerIn", "wall", "gate", "wall", "entrance", "wall", "cornerIn", "wall", "gate", "wall", "cornerIn", "wall"] 91 83 // centerToFirstElement Optional. Object with properties "x" and "y" representing a vector from the visual center to the first wall element. Default is undefined 92 84 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 93 85 function Fortress(type, wall, centerToFirstElement) 94 86 { 95 this.type = type; // Only usefull to get the type of the actual fortress 96 this.wall = (wall !== undefined) ? wall : []; 97 this.centerToFirstElement = undefined; 98 } 99 100 101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 102 // wallStyles data structure for default wall styles 103 // 104 // A wall style is an associative array with all wall elements of that style in it associated with the wall element type string 105 // wallStyles holds all the wall styles within an associative array with the civ string or another descriptive strings as key 106 // Examples: "athen", "rome_siege", "palisades", "fence", "road" 107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 108 var wallStyles = {}; 109 110 // Generic civ dependent wall style definition. "rome_siege" needs some tweek... 111 var wallScaleByType = {"athen" : 1.5, "brit" : 1.5, "cart" : 1.8, "gaul" : 1.5, "iber" : 1.5, "mace" : 1.5, "maur": 1.5, "pers" : 1.5, "ptol" : 1.5, "rome" : 1.5, "sele" : 1.5, "spart" : 1.5, "rome_siege" : 1.5}; 112 for (var style in wallScaleByType) 113 { 114 var civ = style; 115 if (style == "rome_siege") 116 civ = "rome"; 117 wallStyles[style] = {}; 118 // Default wall elements 119 wallStyles[style]["tower"] = new WallElement("tower", "structures/" + style + "_wall_tower", PI, wallScaleByType[style]); 120 wallStyles[style]["endLeft"] = new WallElement("endLeft", "structures/" + style + "_wall_tower", PI, wallScaleByType[style]); // Same as tower. To be compatible with palisades... 121 wallStyles[style]["endRight"] = new WallElement("endRight", "structures/" + style + "_wall_tower", PI, wallScaleByType[style]); // Same as tower. To be compatible with palisades... 122 wallStyles[style]["cornerIn"] = new WallElement("cornerIn", "structures/" + style + "_wall_tower", 5*PI/4, 0, 0.35*wallScaleByType[style], PI/2); // 2^0.5 / 4 ~= 0.35 ~= 1/3 123 wallStyles[style]["cornerOut"] = new WallElement("cornerOut", "structures/" + style + "_wall_tower", 3*PI/4, 0.71*wallScaleByType[style], 0, -PI/2); // // 2^0.5 / 2 ~= 0.71 ~= 2/3 124 wallStyles[style]["wallShort"] = new WallElement("wallShort", "structures/" + style + "_wall_short", 0*PI, 2*wallScaleByType[style]); 125 wallStyles[style]["wall"] = new WallElement("wall", "structures/" + style + "_wall_medium", 0*PI, 4*wallScaleByType[style]); 126 wallStyles[style]["wallMedium"] = new WallElement("wall", "structures/" + style + "_wall_medium", 0*PI, 4*wallScaleByType[style]); 127 wallStyles[style]["wallLong"] = new WallElement("wallLong", "structures/" + style + "_wall_long", 0*PI, 6*wallScaleByType[style]); 128 // Gate and entrance wall elements 129 var gateWidth = 6*wallScaleByType[style]; 130 wallStyles[style]["gate"] = new WallElement("gate", "structures/" + style + "_wall_gate", PI, gateWidth); 131 wallStyles[style]["entry"] = new WallElement("entry", undefined, 0*PI, gateWidth); 132 wallStyles[style]["entryTower"] = new WallElement("entryTower", "structures/" + civ + "_defense_tower", PI, gateWidth, -4*wallScaleByType[style]); 133 wallStyles[style]["entryFort"] = new WallElement("entryFort", "structures/" + civ + "_fortress", 0*PI, 8*wallScaleByType[style], 6*wallScaleByType[style]); 134 // Defensive wall elements with 0 width outside the wall 135 wallStyles[style]["outpost"] = new WallElement("outpost", "structures/" + civ + "_outpost", PI, 0, -4*wallScaleByType[style]); 136 wallStyles[style]["defenseTower"] = new WallElement("defenseTower", "structures/" + civ + "_defense_tower", PI, 0, -4*wallScaleByType[style]); 137 // Base buildings wall elements with 0 width inside the wall 138 wallStyles[style]["barracks"] = new WallElement("barracks", "structures/" + civ + "_barracks", PI, 0, 4.5*wallScaleByType[style]); 139 wallStyles[style]["civilCentre"] = new WallElement("civilCentre", "structures/" + civ + "_civil_centre", PI, 0, 4.5*wallScaleByType[style]); 140 wallStyles[style]["farmstead"] = new WallElement("farmstead", "structures/" + civ + "_farmstead", PI, 0, 4.5*wallScaleByType[style]); 141 wallStyles[style]["field"] = new WallElement("field", "structures/" + civ + "_field", PI, 0, 4.5*wallScaleByType[style]); 142 wallStyles[style]["fortress"] = new WallElement("fortress", "structures/" + civ + "_fortress", PI, 0, 4.5*wallScaleByType[style]); 143 wallStyles[style]["house"] = new WallElement("house", "structures/" + civ + "_house", PI, 0, 4.5*wallScaleByType[style]); 144 wallStyles[style]["market"] = new WallElement("market", "structures/" + civ + "_market", PI, 0, 4.5*wallScaleByType[style]); 145 wallStyles[style]["storehouse"] = new WallElement("storehouse", "structures/" + civ + "_storehouse", PI, 0, 4.5*wallScaleByType[style]); 146 wallStyles[style]["temple"] = new WallElement("temple", "structures/" + civ + "_temple", PI, 0, 4.5*wallScaleByType[style]); 147 // Generic space/gap wall elements 148 wallStyles[style]["space1"] = new WallElement("space1", undefined, 0*PI, wallScaleByType[style]); 149 wallStyles[style]["space2"] = new WallElement("space2", undefined, 0*PI, 2*wallScaleByType[style]); 150 wallStyles[style]["space3"] = new WallElement("space3", undefined, 0*PI, 3*wallScaleByType[style]); 151 wallStyles[style]["space4"] = new WallElement("space4", undefined, 0*PI, 4*wallScaleByType[style]); 87 this.type = type; 88 this.wall = wall || []; 89 this.centerToFirstElement = centerToFirstElement || undefined; 152 90 } 153 // Add wall fortresses for all generic styles154 wallStyles["athen"]["wallFort"] = new WallElement("wallFort", "structures/athen_fortress", 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);155 wallStyles["brit"]["wallFort"] = new WallElement("wallFort", "structures/brit_fortress", PI, 2.8);156 wallStyles["cart"]["wallFort"] = new WallElement("wallFort", "structures/cart_fortress", PI, 5.1, 1.6);157 wallStyles["gaul"]["wallFort"] = new WallElement("wallFort", "structures/gaul_fortress", PI, 4.2, 1.5);158 wallStyles["iber"]["wallFort"] = new WallElement("wallFort", "structures/iber_fortress", PI, 5, 0.2);159 wallStyles["mace"]["wallFort"] = new WallElement("wallFort", "structures/mace_fortress", 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);160 wallStyles["maur"]["wallFort"] = new WallElement("wallFort", "structures/maur_fortress", PI, 5.5);161 wallStyles["pers"]["wallFort"] = new WallElement("wallFort", "structures/pers_fortress", PI, 5.6/*5.5*/, 1.9/*1.7*/);162 wallStyles["ptol"]["wallFort"] = new WallElement("wallFort", "structures/ptol_fortress", 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);163 wallStyles["rome"]["wallFort"] = new WallElement("wallFort", "structures/rome_fortress", PI, 6.3, 2.1);164 wallStyles["sele"]["wallFort"] = new WallElement("wallFort", "structures/sele_fortress", 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);165 wallStyles["spart"]["wallFort"] = new WallElement("wallFort", "structures/spart_fortress", 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);166 // Adjust "rome_siege" style167 wallStyles["rome_siege"]["wallFort"] = new WallElement("wallFort", "structures/rome_army_camp", PI, 7.2, 2);168 wallStyles["rome_siege"]["entryFort"] = new WallElement("entryFort", "structures/rome_army_camp", PI, 12, 7);169 wallStyles["rome_siege"]["house"] = new WallElement("house", "structures/rome_tent", PI, 0, 4);170 171 // Add special wall styles not well to implement generic (and to show how custom styles can be added)172 173 // Add wall style "palisades"174 wallScaleByType["palisades"] = 0.55;175 wallStyles["palisades"] = {};176 wallStyles["palisades"]["wall"] = new WallElement("wall", "other/palisades_rocks_medium", 0*PI, 2.3);177 wallStyles["palisades"]["wallMedium"] = new WallElement("wall", "other/palisades_rocks_medium", 0*PI, 2.3);178 wallStyles["palisades"]["wallLong"] = new WallElement("wall", "other/palisades_rocks_long", 0*PI, 3.5);179 wallStyles["palisades"]["wallShort"] = new WallElement("wall", "other/palisades_rocks_short", 0*PI, 1.2);180 wallStyles["palisades"]["tower"] = new WallElement("tower", "other/palisades_rocks_tower", -PI/2, 0.7);181 wallStyles["palisades"]["wallFort"] = new WallElement("wallFort", "other/palisades_rocks_fort", PI, 1.7);182 wallStyles["palisades"]["gate"] = new WallElement("gate", "other/palisades_rocks_gate", PI, 3.6);183 wallStyles["palisades"]["entry"] = new WallElement("entry", undefined, wallStyles["palisades"]["gate"].angle, wallStyles["palisades"]["gate"].width);184 wallStyles["palisades"]["entryTower"] = new WallElement("entryTower", "other/palisades_rocks_watchtower", 0*PI, wallStyles["palisades"]["gate"].width, -3);185 wallStyles["palisades"]["entryFort"] = new WallElement("entryFort", "other/palisades_rocks_fort", PI, 6, 3);186 wallStyles["palisades"]["cornerIn"] = new WallElement("cornerIn", "other/palisades_rocks_curve", 3*PI/4, 2.1, 0.7, PI/2);187 wallStyles["palisades"]["cornerOut"] = new WallElement("cornerOut", "other/palisades_rocks_curve", 5*PI/4, 2.1, -0.7, -PI/2);188 wallStyles["palisades"]["outpost"] = new WallElement("outpost", "other/palisades_rocks_outpost", PI, 0, -2);189 wallStyles["palisades"]["house"] = new WallElement("house", "other/celt_hut", PI, 0, 5);190 wallStyles["palisades"]["barracks"] = new WallElement("barracks", "structures/gaul_tavern", PI, 0, 5);191 wallStyles["palisades"]["endRight"] = new WallElement("endRight", "other/palisades_rocks_end", -PI/2, 0.2);192 wallStyles["palisades"]["endLeft"] = new WallElement("endLeft", "other/palisades_rocks_end", PI/2, 0.2);193 194 // Add special wall style "road"195 // NOTE: This is not a wall style in the common sense. Use with care!196 wallStyles["road"] = {};197 wallStyles["road"]["short"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_short.xml", PI/2, 4.5);198 wallStyles["road"]["long"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_long.xml", PI/2, 9.5);199 wallStyles["road"]["cornerLeft"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_corner.xml", -PI/2, 4.5-2*1.25, 1.25, PI/2); // Correct width by -2*indent to fit xStraicht/corner200 wallStyles["road"]["cornerRight"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_corner.xml", 0*PI, 4.5-2*1.25, -1.25, -PI/2); // Correct width by -2*indent to fit xStraicht/corner201 wallStyles["road"]["curveLeft"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_curve_small.xml", -PI/2, 4.5+2*0.2, -0.2, PI/2); // Correct width by -2*indent to fit xStraicht/corner202 wallStyles["road"]["curveRight"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_curve_small.xml", 0*PI, 4.5+2*0.2, 0.2, -PI/2); // Correct width by -2*indent to fit xStraicht/corner203 wallStyles["road"]["start"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_end.xml", PI/2, 2);204 wallStyles["road"]["end"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_end.xml", -PI/2, 2);205 wallStyles["road"]["xStraight"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_intersect_x.xml", 0*PI, 4.5);206 wallStyles["road"]["xLeft"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_intersect_x.xml", 0*PI, 4.5, 0, PI/2);207 wallStyles["road"]["xRight"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_intersect_x.xml", 0*PI, 4.5, 0, -PI/2);208 wallStyles["road"]["tLeft"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_intersect_T.xml", PI, 4.5, 1.25);209 wallStyles["road"]["tRight"] = new WallElement("road", "actor|props/special/eyecandy/road_temperate_intersect_T.xml", 0*PI, 4.5, -1.25);210 211 // Add special wall element collection "other"212 // NOTE: This is not a wall style in the common sense. Use with care!213 wallStyles["other"] = {};214 wallStyles["other"]["fence"] = new WallElement("fence", "other/fence_long", -PI/2, 3.1);215 wallStyles["other"]["fence_medium"] = new WallElement("fence", "other/fence_long", -PI/2, 3.1);216 wallStyles["other"]["fence_short"] = new WallElement("fence_short", "other/fence_short", -PI/2, 1.5);217 wallStyles["other"]["fence_stone"] = new WallElement("fence_stone", "other/fence_stone", -PI/2, 2.5);218 wallStyles["other"]["palisade"] = new WallElement("palisade", "other/palisades_rocks_short", 0, 1.2);219 wallStyles["other"]["column"] = new WallElement("column", "other/column_doric", 0, 1);220 wallStyles["other"]["obelisk"] = new WallElement("obelisk", "other/obelisk", 0, 2);221 wallStyles["other"]["spike"] = new WallElement("spike", "other/palisades_angle_spike", -PI/2, 1);222 wallStyles["other"]["bench"] = new WallElement("bench", "other/bench", PI/2, 1.5);223 wallStyles["other"]["benchForTable"] = new WallElement("benchForTable", "other/bench", 0, 0.5);224 wallStyles["other"]["table"] = new WallElement("table", "other/table_rectangle", 0, 1);225 wallStyles["other"]["table_square"] = new WallElement("table_square", "other/table_square", PI/2, 1);226 wallStyles["other"]["flag"] = new WallElement("flag", "special/rallypoint", PI, 1);227 wallStyles["other"]["standing_stone"] = new WallElement("standing_stone", "gaia/special_ruins_standing_stone", PI, 1);228 wallStyles["other"]["settlement"] = new WallElement("settlement", "gaia/special_settlement", PI, 6);229 wallStyles["other"]["gap"] = new WallElement("gap", undefined, 0, 2);230 wallStyles["other"]["gapSmall"] = new WallElement("gapSmall", undefined, 0, 1);231 wallStyles["other"]["gapLarge"] = new WallElement("gapLarge", undefined, 0, 4);232 wallStyles["other"]["cornerIn"] = new WallElement("cornerIn", undefined, 0, 0, 0, PI/2);233 wallStyles["other"]["cornerOut"] = new WallElement("cornerOut", undefined, 0, 0, 0, -PI/2);234 235 91 236 92 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 237 // fortressTypes data structure for some default fortress types93 // g_FortressTypes data structure for some default fortress types (defined above) 238 94 // 239 95 // A fortress type is just an instance of the Fortress class with actually something in it 240 96 // fortressTypes holds all the fortresses within an associative array with a descriptive string as key (e.g. matching the map size) 241 97 // Examples: "tiny", "veryLarge" 242 98 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 243 var fortressTypes = {}; 244 // Setup some default fortress types 245 // Add fortress type "tiny" 246 fortressTypes["tiny"] = new Fortress("tiny"); 247 var wallPart = ["gate", "tower", "wallShort", "cornerIn", "wallShort", "tower"]; 248 fortressTypes["tiny"].wall = wallPart.concat(wallPart, wallPart, wallPart); 249 // Add fortress type "small" 250 fortressTypes["small"] = new Fortress("small"); 251 var wallPart = ["gate", "tower", "wall", "cornerIn", "wall", "tower"]; 252 fortressTypes["small"].wall = wallPart.concat(wallPart, wallPart, wallPart); 253 // Add fortress type "medium" 254 fortressTypes["medium"] = new Fortress("medium"); 255 var wallPart = ["gate", "tower", "wallLong", "cornerIn", "wallLong", "tower"]; 256 fortressTypes["medium"].wall = wallPart.concat(wallPart, wallPart, wallPart); 257 // Add fortress type "normal" 258 fortressTypes["normal"] = new Fortress("normal"); 259 var wallPart = ["gate", "tower", "wall", "cornerIn", "wall", "cornerOut", "wall", "cornerIn", "wall", "tower"]; 260 fortressTypes["normal"].wall = wallPart.concat(wallPart, wallPart, wallPart); 261 // Add fortress type "large" 262 fortressTypes["large"] = new Fortress("large"); 263 var wallPart = ["gate", "tower", "wallLong", "cornerIn", "wallLong", "cornerOut", "wallLong", "cornerIn", "wallLong", "tower"]; 264 fortressTypes["large"].wall = wallPart.concat(wallPart, wallPart, wallPart); 265 // Add fortress type "veryLarge" 266 fortressTypes["veryLarge"] = new Fortress("veryLarge"); 267 var wallPart = ["gate", "tower", "wall", "cornerIn", "wall", "cornerOut", "wallLong", "cornerIn", "wallLong", "cornerOut", "wall", "cornerIn", "wall", "tower"]; 268 fortressTypes["veryLarge"].wall = wallPart.concat(wallPart, wallPart, wallPart); 269 // Add fortress type "giant" 270 fortressTypes["giant"] = new Fortress("giant"); 271 var wallPart = ["gate", "tower", "wallLong", "cornerIn", "wallLong", "cornerOut", "wallLong", "cornerIn", "wallLong", "cornerOut", "wallLong", "cornerIn", "wallLong", "tower"]; 272 fortressTypes["giant"].wall = wallPart.concat(wallPart, wallPart, wallPart); 99 100 // Set some default fortress types 101 for (let key of g_FortressTypeKeys) 102 g_FortressTypes[key] = new Fortress(key); 103 104 g_FortressTypes["tiny"].wall = ["gate", "tower", "short", "cornerIn", "short", "tower"]; 105 g_FortressTypes["small"].wall = ["gate", "tower", "medium", "cornerIn", "medium", "tower"]; 106 g_FortressTypes["medium"].wall = ["gate", "tower", "long", "cornerIn", "long", "tower"]; 107 g_FortressTypes["normal"].wall = ["gate", "tower", "medium", "cornerIn", "medium", "cornerOut", "medium", "cornerIn", "medium", "tower"]; 108 g_FortressTypes["large"].wall = ["gate", "tower", "long", "cornerIn", "long", "cornerOut", "long", "cornerIn", "long", "tower"]; 109 g_FortressTypes["veryLarge"].wall = ["gate", "tower", "medium", "cornerIn", "medium", "cornerOut", "long", "cornerIn", "long", "cornerOut", "medium", "cornerIn", "medium", "tower"]; 110 g_FortressTypes["giant"].wall = ["gate", "tower", "long", "cornerIn", "long", "cornerOut", "long", "cornerIn", "long", "cornerOut", "long", "cornerIn", "long", "tower"]; 111 112 for (let type in g_FortressTypes) 113 { 114 let wallPart = g_FortressTypes[type].wall; 115 g_FortressTypes[type].wall = wallPart.concat(wallPart, wallPart, wallPart); 116 } 273 117 274 118 // Setup some better looking semi default fortresses for "palisades" style 275 var fortressTypeKeys = ["tiny", "small", "medium", "normal", "large", "veryLarge", "giant"]; 276 for (var i = 0; i < fortressTypeKeys.length; i++) 119 for (let fortType of g_FortressTypeKeys) 277 120 { 278 var newKey = fort ressTypeKeys[i]+ "Palisades";279 var oldWall = fortressTypes[fortressTypeKeys[i]].wall;280 fortressTypes[newKey] = new Fortress(newKey);121 var newKey = fortType + "Palisades"; 122 var oldWall = g_FortressTypes[fortType].wall; 123 g_FortressTypes[newKey] = new Fortress(newKey); 281 124 var fillTowersBetween = ["wallShort", "wall", "wallLong", "endLeft", "endRight", "cornerIn", "cornerOut"]; 282 for (var j = 0; j < oldWall.length; j++)125 for (var j = 0; j < oldWall.length; ++j) 283 126 { 284 fortressTypes[newKey].wall.push(oldWall[j]); // Only works if the first element is not in fillTowersBetween (e.g. entry or gate like it should be)127 g_FortressTypes[newKey].wall.push(oldWall[j]); // Only works if the first element is not in fillTowersBetween (e.g. entry or gate like it should be) 285 128 if (j+1 < oldWall.length) 286 129 if (fillTowersBetween.indexOf(oldWall[j]) > -1 && fillTowersBetween.indexOf(oldWall[j+1]) > -1) // ... > -1 means "exists" here 287 fortressTypes[newKey].wall.push("tower");130 g_FortressTypes[newKey].wall.push("tower"); 288 131 } 289 132 } 290 133 291 134 // Setup some balanced (to civ type fortresses) semi default fortresses for "palisades" style 292 135 // TODO 293 136 294 // Add some "fortress types" for roads (will only work with style "road")295 // ["start", "short", "xRight", "xLeft", "cornerLeft", "xStraight", "long", "xLeft", "xRight", "cornerRight", "tRight", "tLeft", "xRight", "xLeft", "curveLeft", "xStraight", "curveRight", "end"];296 var wall = ["short", "curveLeft", "short", "curveLeft", "short", "curveLeft", "short", "curveLeft"];297 fortressTypes["road01"] = new Fortress("road01", wall);298 var wall = ["short", "cornerLeft", "short", "cornerLeft", "short", "cornerLeft", "short", "cornerLeft"];299 fortressTypes["road02"] = new Fortress("road02", wall);300 var wall = ["xStraight", "curveLeft", "xStraight", "curveLeft", "xStraight", "curveLeft", "xStraight", "curveLeft"];301 fortressTypes["road03"] = new Fortress("road03", wall);302 var wall = ["start", "curveLeft", "tRight", "cornerLeft", "tRight", "curveRight", "short", "xRight", "curveLeft", "xRight", "short", "cornerLeft", "tRight", "short",303 "curveLeft", "short", "tRight", "cornerLeft", "short", "xRight", "curveLeft", "xRight", "short", "curveRight", "tRight", "cornerLeft", "tRight", "curveLeft", "end"];304 fortressTypes["road04"] = new Fortress("road04", wall);305 var wall = ["start", "tLeft", "short", "xRight",306 "curveLeft", "xRight", "tRight", "cornerLeft", "tRight",307 "curveLeft", "short", "tRight", "cornerLeft", "xRight",308 "cornerLeft", "xRight", "short", "tRight", "curveLeft", "end"];309 fortressTypes["road05"] = new Fortress("road05", wall);310 311 137 312 138 /////////////////////////////// 313 139 // Define some helper functions 314 140 /////////////////////////////// 315 141 142 /** 143 * Get a wall element of a style. 144 * 145 * Valid elements: 146 * long, medium, short, start, end, cornerIn, cornerOut, tower, fort, gate 147 * 148 * Kept for backwards compatibility: 149 * wallLong, wallMedium, wall, wallShort, endLeft, endRight, entry, entryTower, entryFort 150 * 151 * If an element of the form `gap{x}` is requested, where `{x}` is a number, 152 * then a non-blocking gap of `x` length is returned. 153 * 154 * If an element of the form `turn{x}` is requested where `{x}` is either 155 * `out` or `in` (case in-sensitive), then a 90 degree (PI/2 radians) bend 156 * with zero length is returned in the specified direction. 157 * 158 * You can specify a normal structure (ie. `house`, `apadana` `barracks`) 159 * and the function will attempt to return the appropriate civ's building 160 * of that type with appropriate indentation away from the wall. 161 * @todo do something about the arbitrary-ness of the indent. 162 * 163 * If after all that, the function still can't work out what's requested, 164 * it returns a wall tower. 165 * 166 * @param style The style from which this element should come from 167 * @param element The element to fetch 168 * @return The wall element requested. Or a tower element. 169 */ 170 function getWallElement(style="athen_stone", element) 171 { 172 if (g_WallStyleList.indexOf(style) < 0) 173 { 174 warn("getWallElement: Style '"+style+"' not recognised. (Falling back to '" + FALLBACK_CIV + "_stone'.)"); 175 style = FALLBACK_CIV + "_stone"; 176 } 177 if (g_WallStyles[style][element]) 178 return g_WallStyles[style][element]; 179 180 // Attempt to derive any unknown elements. 181 // Defaults to a wall tower piece 182 var wallset = g_WallStyles[style]; 183 var civ = style.split("_")[0]; 184 var ret = clone(wallset.tower); 185 186 // We use clone() so we don't change the attributes of the object we're referencing 187 switch (element) 188 { 189 190 case "cornerIn": 191 if (wallset.quarterCurve) 192 ret = clone(wallset.quarterCurve); 193 else 194 { 195 ret.angle += PI/4 196 ret.indent = ret.length * 0.25; 197 ret.length = 0; 198 } 199 ret.bend = PI/2; 200 break; 201 202 case "cornerOut": 203 if (wallset.quarterCurve) 204 { 205 ret = clone(wallset.quarterCurve); 206 ret.angle += PI/2; 207 ret.indent -= ret.indent*2; 208 } 209 else 210 { 211 ret.angle -= PI/4; 212 ret.length *= 0.71; 213 } 214 ret.bend = -PI/2; 215 break; 216 217 case "wallShort": 218 warn("getWallElement: Deprecated use of 'wallShort' (please use 'short')"); 219 ret = clone(wallset.short); 220 break; 221 222 case "wallMedium": 223 case "wall": 224 warn("getWallElement: Deprecated use of '"+element+"' (please use 'medium')"); 225 ret = clone(wallset.medium); 226 break; 227 228 case "wallLong": 229 warn("getWallElement: Deprecated use of 'wallLong' (please use 'long')"); 230 ret = clone(wallset.long); 231 break; 232 233 case "entry": 234 ret.entPath = undefined; 235 ret.length = clone(g_WallStyles[style].gate.length); 236 break; 237 238 case "entryTower": 239 ret.entPath = (g_CivList.indexOf(civ) > -1) ? "structures/"+civ+"_defense_tower" : "other/palisades_rocks_watchtower"; 240 ret.indent = ret.length * -3; 241 ret.length = clone(g_WallStyles[style].gate.length); 242 break; 243 244 case "entryFort": 245 ret = clone(g_WallStyles[style].fort); 246 ret.angle -= PI; 247 ret.length *= 1.5; 248 ret.indent = ret.length; 249 break; 250 251 case "endLeft": 252 warn("getWallElement: Deprecated use of 'endLeft' (please use 'start')"); 253 case "start": 254 if (wallset.end) 255 { 256 ret = clone(wallset.end); 257 ret.angle += PI; 258 } 259 break; 260 261 case "endRight": 262 warn("getWallElement: Deprecated use of 'endRight' (please use 'end')"); 263 case "end": 264 if (wallset.end) 265 ret = clone(wallset.end); 266 break; 267 268 default: 269 if (g_CivList.indexOf(civ) == -1) 270 civ = FALLBACK_CIV; 271 // Is it a structure? 272 var entPath = "structures/"+civ+"_"+element; 273 if (RMS.TemplateExists(entPath)) 274 { 275 if (["outpost", "defense_tower"].indexOf(element) > -1) 276 ret.indent = ret.length * -3; 277 else 278 ret.indent = ret.length * 3.5; 279 ret.entPath = entPath; 280 ret.length = 0; 281 } 282 else if (element.slice(0, 3) === "gap") // A gap? 283 { 284 ret.entPath = undefined; 285 ret.angle = 0; 286 ret.length = +element.slice(3); 287 } 288 else if (element.slice(0, 4) === "turn") // A bend? 289 { 290 let dir = element.slice(4).toLowerCase(); 291 if (dir === "out" || dir === "in") 292 { 293 ret.entPath = undefined; 294 ret.angle = PI/2; 295 ret.length = 0; 296 if (dir === "out") 297 ret.angle -= ret.angle; 298 } 299 else 300 warn("Unrecognised turn direction given: '"+dir+"' ("+ style+")."); 301 } 302 else // Or... I give up. 303 warn("Unrecognised wall element: '"+element+"' ("+ style+"). Defaulting to 'tower'."); 304 } 305 306 // Cache to save having to calculate this element again 307 g_WallStyles[style][element] = ret; 308 309 return ret; 310 } 311 312 /** 313 * Set a wall element of a style. 314 * 315 * @param style The style to which this element belongs 316 * @param element The element to add 317 * @param path The template path to read values from 318 */ 319 function setWallElement(style, element, path) 320 { 321 var template = RMS.GetTemplate(path); 322 template = GetTemplateDataHelper(template); 323 324 if (!g_WallStyles[style]) 325 g_WallStyles[style] = {}; 326 327 var length = (template.wallPiece) ? template.wallPiece.length : template.obstruction.shape.width; 328 g_WallStyles[style][element] = { 329 "entPath": path, 330 "angle": (template.wallPiece) ? template.wallPiece.angle : PI, 331 "length": length / CELL_SIZE, 332 "indent": (template.wallPiece) ? template.wallPiece.indent / CELL_SIZE : 0, 333 "bend": (template.wallPiece) ? template.wallPiece.bend : 0 334 }; 335 } 336 316 337 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 317 338 // getWallAlignment 318 339 // … … fortressTypes["road05"] = new Fortress("road05", wall); 320 341 // Placing the first wall element at startX/startY placed with an angle given by orientation 321 342 // An alignment can be used to get the "center" of a "wall" (more likely used for fortresses) with getCenterToFirstElement 322 343 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 323 function getWallAlignment(startX, startY, wall , style, orientation)344 function getWallAlignment(startX, startY, wall=[], style="athen_stone", orientation=0) 324 345 { 325 // Graciously handle arguments326 if (wall === undefined)327 wall = [];328 if (!wallStyles.hasOwnProperty(style))329 {330 warn("Function getWallAlignment: Unknown style: " + style + ' (falling back to "athen")');331 style = "athen";332 }333 orientation = (orientation || 0);334 335 346 var alignment = []; 336 347 var wallX = startX; 337 348 var wallY = startY; 338 for (var i = 0; i < wall.length; i++) 349 350 for (var i = 0; i < wall.length; ++i) 339 351 { 340 var element = wallStyles[style][wall[i]];352 var element = getWallElement(style, wall[i]); 341 353 if (element === undefined && i == 0) 342 warn("No valid wall element: " + wall[i]); 354 { 355 warn("Not a valid wall element: style = " + style + ", wall[" +i+ "] = " +wall[i]+ "; .entPath = " +element.entPath+ ", .length = " +element.length+ ", .angle = " +element.angle+ ", .indent = " +element.indent+ ", .bend = " +element.bend); 356 continue; 357 } 358 343 359 // Indentation 344 360 var placeX = wallX - element.indent * cos(orientation); 345 361 var placeY = wallY - element.indent * sin(orientation); 362 346 363 // Add wall elements entity placement arguments to the alignment 347 alignment.push({"x": placeX, "y": placeY, "entity": element.entity, "angle":orientation + element.angle}); 364 alignment.push({"x": placeX, "y": placeY, "entPath": element.entPath, "angle":orientation + element.angle}); 365 348 366 // Preset vars for the next wall element 349 367 if (i+1 < wall.length) 350 368 { 351 orientation += element.bend ing;352 var nextElement = wallStyles[style][wall[i+1]];369 orientation += element.bend; 370 var nextElement = getWallElement(style, wall[i+1]); 353 371 if (nextElement === undefined) 354 warn("No valid wall element: " + wall[i+1]); 355 var distance = (element.width + nextElement.width)/2; 372 { 373 warn("Not a valid wall element: style = " + style + ", wall[" +(i+1)+ "] = " +wall[i+1]+ "; .entPath = " +nextElement.entPath+ ", .length = " +nextElement.length+ ", .angle = " +nextElement.angle+ ", .indent = " +nextElement.indent+ ", .bend = " +nextElement.bend); 374 continue; 375 } 376 377 var distance = (element.length + nextElement.length)/2 - getOverlap(style); 356 378 // Corrections for elements with indent AND bending 357 379 var indent = element.indent; 358 var bend ing = element.bending;359 if (bend ing!== 0 && indent !== 0)380 var bend = element.bend; 381 if (bend !== 0 && indent !== 0) 360 382 { 361 383 // Indent correction to adjust distance 362 distance += indent*sin(bend ing);384 distance += indent*sin(bend); 363 385 // Indent correction to normalize indentation 364 386 wallX += indent * cos(orientation); 365 387 wallY += indent * sin(orientation); 366 388 } 389 367 390 // Set the next coordinates of the next element in the wall without indentation adjustment 368 391 wallX -= distance * sin(orientation); 369 392 wallY += distance * cos(orientation); … … function getWallAlignment(startX, startY, wall, style, orientation) 383 406 function getCenterToFirstElement(alignment) 384 407 { 385 408 var centerToFirstElement = {"x": 0, "y": 0}; 386 for (var i = 0; i < alignment.length; i++)409 for (var i = 0; i < alignment.length; ++i) 387 410 { 388 411 centerToFirstElement.x -= alignment[i].x/alignment.length; 389 412 centerToFirstElement.y -= alignment[i].y/alignment.length; … … function getCenterToFirstElement(alignment) 395 418 // getWallLength 396 419 // 397 420 // NOTE: Does not support bending wall elements like corners! 398 // e.g. used by placeIrregularPolygonalWall399 421 ////////////////////////////////////////////////////////////////// 400 function getWallLength( wall, style)422 function getWallLength(style, wall=[]) 401 423 { 402 424 // Graciously handle arguments 403 if (wall === undefined) 404 wall = []; 405 if (!wallStyles.hasOwnProperty(style)) 425 if (g_WallStyleList.indexOf(style) < 0) 406 426 { 407 warn(" Function getWallLength: Unknown style: " + style + ' (falling back to "athen")');408 style = "athen";427 warn("getWallLength: Unknown style: '" + style + "'. (Falling back to '" + FALLBACK_CIV + "_stone')."); 428 style = FALLBACK_CIV +"_stone"; 409 429 } 410 430 411 431 var length = 0; 412 for (var i = 0; i < wall.length; i++)413 {414 length += wallStyles[style][wall[i]].width;415 } 432 var overlap = getOverlap(style); 433 for (let element of wall) 434 length += getWallElement(style, element).length - overlap; 435 416 436 return length; 417 437 } 418 438 439 function getOverlap(style) 440 { 441 if (!style || g_WallStyleList.indexOf(style) == -1) 442 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 443 return g_WallStyles[style]["@overlap"]; 444 } 445 419 446 420 447 ///////////////////////////////////////////// 421 448 // Define the different wall placer functions … … function getWallLength(wall, style) 427 454 // Places a wall with wall elements attached to another like determined by WallElement properties. 428 455 // 429 456 // startX, startY Where the first wall element should be placed 430 // wall Array of wall element type strings. Example: ["endLeft", "wallLong", "tower", "wallLong", "endRight"]457 // wall Array of wall element types. Example: ["start", "long", "tower", "long", "end"] 431 458 // style Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia 432 459 // playerId Optional. Number of the player the wall will be placed for. Default is 0 (gaia) 433 460 // orientation Optional. Angle the first wall element is placed. Default is 0 … … function getWallLength(wall, style) 435 462 // It will then be build towards top/positive Y (if no bending wall elements like corners are used) 436 463 // Raising orientation means the wall is rotated counter-clockwise like placeObject 437 464 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 438 function placeWall(startX , startY, wall, style, playerId, orientation)465 function placeWall(startX=0, startY=0, wall=[], style, playerId=0, orientation=0) 439 466 { 440 // Graciously handle arguments 441 if (wall === undefined) 442 wall = []; 443 playerId = (playerId || 0); 444 if (!wallStyles.hasOwnProperty(style)) 445 { 446 if (playerId == 0) 447 style = (style || "palisades"); 448 else 449 style = (getCivCode(playerId-1)); 450 } 451 orientation = (orientation || 0); 467 if (!style || g_WallStyleList.indexOf(style) == -1) 468 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 452 469 453 470 // Get wall alignment 454 471 var AM = getWallAlignment(startX, startY, wall, style, orientation); 472 455 473 // Place the wall 456 for (var iWall = 0; iWall < wall.length; iWall++)474 for (var iWall = 0; iWall < wall.length; ++iWall) 457 475 { 458 var ent ity = AM[iWall].entity;459 if (ent ity!== undefined)460 placeObject(AM[iWall].x, AM[iWall].y, ent ity, playerId, AM[iWall].angle);476 var entPath = AM[iWall].entPath; 477 if (entPath !== undefined) 478 placeObject(AM[iWall].x, AM[iWall].y, entPath, playerId, AM[iWall].angle); 461 479 } 462 480 } 463 481 … … function placeWall(startX, startY, wall, style, playerId, orientation) 472 490 // playerId Optional. Number of the player the wall will be placed for. Default is 0 (gaia) 473 491 // orientation Optional. Angle the first wall element (should be a gate or entrance) is placed. Default is 0 474 492 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 475 function placeCustomFortress(centerX, centerY, fortress, style, playerId , orientation)493 function placeCustomFortress(centerX, centerY, fortress, style, playerId=0, orientation=0) 476 494 { 477 495 // Graciously handle arguments 478 fortress = (fortress || fortressTypes["medium"]); 479 playerId = (playerId || 0); 480 if (!wallStyles.hasOwnProperty(style)) 481 { 482 if (playerId == 0) 483 style = (style || "palisades"); 484 else 485 style = (getCivCode(playerId-1)); 486 } 487 orientation = (orientation || 0); 496 fortress = fortress || g_FortressTypes["medium"]; 497 if (!style || g_WallStyleList.indexOf(style) == -1) 498 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 488 499 489 500 // Calculate center if fortress.centerToFirstElement is undefined (default) 490 501 var centerToFirstElement = fortress.centerToFirstElement; … … function placeCustomFortress(centerX, centerY, fortress, style, playerId, orient 501 512 // 502 513 // Like placeCustomFortress just it takes type (a fortress type string, has to be in fortressTypes) instead of an instance of Fortress 503 514 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 504 function placeFortress(centerX, centerY, type , style, playerId, orientation)515 function placeFortress(centerX, centerY, type="medium", style, playerId=0, orientation=0) 505 516 { 506 517 // Graciously handle arguments 507 type = (type || "medium"); 508 playerId = (playerId || 0); 509 if (!wallStyles.hasOwnProperty(style)) 510 { 511 if (playerId == 0) 512 style = (style || "palisades"); 513 else 514 style = (getCivCode(playerId-1)); 515 } 516 orientation = (orientation || 0); 518 if (!style || g_WallStyleList.indexOf(style) == -1) 519 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 517 520 518 521 // Call placeCustomFortress with the given arguments 519 placeCustomFortress(centerX, centerY, fortressTypes[type], style, playerId, orientation);522 placeCustomFortress(centerX, centerY, g_FortressTypes[type], style, playerId, orientation); 520 523 } 521 524 522 525 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … function placeFortress(centerX, centerY, type, style, playerId, orientation) 526 529 // 527 530 // startX/startY Coordinate of the approximate beginning of the wall (Not the place of the first wall element) 528 531 // targetX/targetY Coordinate of the approximate ending of the wall (Not the place of the last wall element) 529 // wallPart Optional. An array of NON-BENDING wall element type strings. Default is ["tower", "wallLong"]532 // wallPart Optional. An array of NON-BENDING wall element types. Default is ["tower", "wallLong"] 530 533 // style Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia 531 534 // playerId Optional. Integer number of the player. Default is 0 (gaia) 532 535 // endWithFirst Optional. A boolean value. If true the 1st wall element in the wallPart array will finalize the wall. Default is true 533 536 // 534 537 // TODO: Maybe add angle offset for more generic looking? 535 538 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 536 function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, playerId , endWithFirst)539 function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, playerId=0, endWithFirst=true) 537 540 { 538 541 // Setup optional arguments to the default 539 wallPart = (wallPart || ["tower", "wallLong"]); 540 playerId = (playerId || 0); 541 if (!wallStyles.hasOwnProperty(style)) 542 { 543 if (playerId == 0) 544 style = (style || "palisades"); 545 else 546 style = (getCivCode(playerId-1)); 547 } 548 endWithFirst = typeof endWithFirst == "undefined" ? true : endWithFirst; 542 wallPart = wallPart || ["tower", "long"]; 543 if (!style || g_WallStyleList.indexOf(style) == -1) 544 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 549 545 550 546 // Check arguments 551 for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++) 552 { 553 var bending = wallStyles[style][wallPart[elementIndex]].bending; 554 if (bending != 0) 555 warn("Bending is not supported by placeLinearWall but a bending wall element is used: " + wallPart[elementIndex] + " -> wallStyles[style][wallPart[elementIndex]].entity"); 556 } 547 for (let element of wallPart) 548 if (getWallElement(style, element).bend != 0) 549 warn("Bending is not supported by placeLinearWall but the following bending wall element was used: " + element); 550 557 551 // Setup number of wall parts 558 552 var totalLength = getDistance(startX, startY, targetX, targetY); 559 var wallPartLength = 0; 560 for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++) 561 wallPartLength += wallStyles[style][wallPart[elementIndex]].width; 553 var wallPartLength = getWallLength(style, wallPart); 562 554 var numParts = 0; 563 555 if (endWithFirst == true) 564 numParts = ceil((totalLength - wallStyles[style][wallPart[0]].width) / wallPartLength);556 numParts = ceil((totalLength - getWallElement(style, wallPart[0]).length) / wallPartLength); 565 557 else 566 558 numParts = ceil(totalLength / wallPartLength); 559 567 560 // Setup scale factor 568 561 var scaleFactor = 1; 569 562 if (endWithFirst == true) 570 scaleFactor = totalLength / (numParts * wallPartLength + wallStyles[style][wallPart[0]].width);563 scaleFactor = totalLength / (numParts * wallPartLength + getWallElement(style, wallPart[0]).length); 571 564 else 572 565 scaleFactor = totalLength / (numParts * wallPartLength); 566 573 567 // Setup angle 574 568 var wallAngle = getAngle(startX, startY, targetX, targetY); // NOTE: function "getAngle()" is about to be changed... 575 569 var placeAngle = wallAngle - PI/2; 576 570 // Place wall entities 577 571 var x = startX; 578 572 var y = startY; 579 for (var partIndex = 0; partIndex < numParts; partIndex++)573 for (var partIndex = 0; partIndex < numParts; ++partIndex) 580 574 { 581 for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)575 for (var elementIndex = 0; elementIndex < wallPart.length; ++elementIndex) 582 576 { 583 var wallEle = wallStyles[style][wallPart[elementIndex]]; 584 // Width correction 585 x += scaleFactor * wallEle.width/2 * cos(wallAngle); 586 y += scaleFactor * wallEle.width/2 * sin(wallAngle); 577 let wallEle = getWallElement(style, wallPart[elementIndex]); 578 let wallLength = (wallEle.length - getOverlap(style)) / 2; 579 let distX = scaleFactor * wallLength * cos(wallAngle); 580 let distY = scaleFactor * wallLength * sin(wallAngle); 581 // Length correction 582 x += distX; 583 y += distY; 587 584 // Indent correction 588 varplaceX = x - wallEle.indent * sin(wallAngle);589 varplaceY = y + wallEle.indent * cos(wallAngle);585 let placeX = x - wallEle.indent * sin(wallAngle); 586 let placeY = y + wallEle.indent * cos(wallAngle); 590 587 // Placement 591 var entity = wallEle.entity; 592 if (entity !== undefined) 593 placeObject(placeX, placeY, entity, playerId, placeAngle + wallEle.angle); 594 x += scaleFactor * wallEle.width/2 * cos(wallAngle); 595 y += scaleFactor * wallEle.width/2 * sin(wallAngle); 588 let entPath = wallEle.entPath; 589 if (entPath !== undefined) 590 placeObject(placeX, placeY, entPath, playerId, placeAngle + wallEle.angle); 591 // Prep for next object 592 x += distX; 593 y += distY; 596 594 } 597 595 } 598 596 if (endWithFirst == true) 599 597 { 600 var wallEle = wallStyles[style][wallPart[0]]; 601 x += scaleFactor * wallEle.width/2 * cos(wallAngle); 602 y += scaleFactor * wallEle.width/2 * sin(wallAngle); 603 var entity = wallEle.entity; 604 if (entity !== undefined) 605 placeObject(x, y, entity, playerId, placeAngle + wallEle.angle); 598 var wallEle = getWallElement(style, wallPart[0]); 599 let wallLength = (wallEle.length - getOverlap(style)) / 2; 600 x += scaleFactor * wallLength * cos(wallAngle); 601 y += scaleFactor * wallLength * sin(wallAngle); 602 var entPath = wallEle.entPath; 603 if (entPath !== undefined) 604 placeObject(x, y, entPath, playerId, placeAngle + wallEle.angle); 606 605 } 607 606 } 608 607 … … function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, play 615 614 // 616 615 // centerX/Y Coordinates of the circle's center 617 616 // radius How wide the circle should be (approximate, especially if maxBendOff != 0) 618 // wallPart Optional. An array of NON-BENDING wall element type strings. Default is ["tower", "wallLong"]617 // wallPart Optional. An array of NON-BENDING wall element types. Default is ["tower", "wallLong"] 619 618 // style Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia 620 619 // playerId Optional. Integer number of the player. Default is 0 (gaia) 621 620 // orientation Optional. Where the open part of the (circular) arc should face (if maxAngle is < 2*PI). Default is 0 … … function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, play 624 623 // maxBendOff Optional. How irregular the circle should be. 0 means regular circle, PI/2 means very irregular. Default is 0 (regular circle) 625 624 // 626 625 // NOTE: Don't use wall elements with bending like corners! 627 // TODO: Perhaps add eccentricity and maxBendOff functionality (untill now an unused argument) 626 // TODO: Perhaps add eccentricity 627 // TODO: Check if maxBendOff parameter works in all cases 628 628 // TODO: Perhaps add functionality for spirals 629 629 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 630 function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId , orientation, maxAngle, endWithFirst, maxBendOff)630 function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId=0, orientation=0, maxAngle=TWO_PI, endWithFirst, maxBendOff=0) 631 631 { 632 632 // Setup optional arguments to the default 633 wallPart = (wallPart || ["tower", "wallLong"]); 634 playerId = (playerId || 0); 635 if (!wallStyles.hasOwnProperty(style)) 636 { 637 if (playerId == 0) 638 style = (style || "palisades"); 639 else 640 style = (getCivCode(playerId-1)); 641 } 642 orientation = (orientation || 0); 643 maxAngle = (maxAngle || 2*PI); 633 wallPart = wallPart || ["tower", "long"]; 634 if (!style || g_WallStyleList.indexOf(style) == -1) 635 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 644 636 if (endWithFirst === undefined) 645 637 { 646 if (maxAngle >= 2*PI - 0.001) // Can this be done better?638 if (maxAngle >= TWO_PI - 0.001) // Can this be done better? 647 639 endWithFirst = false; 648 640 else 649 641 endWithFirst = true; 650 642 } 651 maxBendOff = (maxBendOff || 0);652 643 653 644 // Check arguments 654 645 if (maxBendOff > PI/2 || maxBendOff < 0) 655 warn("placeCircularWall maxBendOff sould satisfy 0 < maxBendOff < PI/2 (~1.5) but it is: " + maxBendOff); 656 for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++) 657 { 658 var bending = wallStyles[style][wallPart[elementIndex]].bending; 659 if (bending != 0) 660 warn("Bending is not supported by placeCircularWall but a bending wall element is used: " + wallPart[elementIndex]); 661 } 646 warn("placeCircularWall maxBendOff should satisfy 0 < maxBendOff < PI/2 (~1.5) but it is: " + maxBendOff); 647 for (let element of wallPart) 648 if (getWallElement(style, element).bend != 0) 649 warn("Bending is not supported by placeCircularWall but the following bending wall element was used: " + element); 650 662 651 // Setup number of wall parts 663 652 var totalLength = maxAngle * radius; 664 var wallPartLength = 0; 665 for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++) 666 wallPartLength += wallStyles[style][wallPart[elementIndex]].width; 653 var wallPartLength = getWallLength(style, wallPart); 667 654 var numParts = 0; 668 655 if (endWithFirst == true) 669 656 { 670 numParts = ceil((totalLength - wallStyles[style][wallPart[0]].width) / wallPartLength);657 numParts = ceil((totalLength - getWallElement(style, wallPart[0]).length) / wallPartLength); 671 658 } 672 659 else 673 660 { … … function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, 676 663 // Setup scale factor 677 664 var scaleFactor = 1; 678 665 if (endWithFirst == true) 679 scaleFactor = totalLength / (numParts * wallPartLength + wallStyles[style][wallPart[0]].width);666 scaleFactor = totalLength / (numParts * wallPartLength + getWallElement(style, wallPart[0]).length); 680 667 else 681 668 scaleFactor = totalLength / (numParts * wallPartLength); 682 669 // Place wall entities 683 670 var actualAngle = orientation + (2*PI - maxAngle) / 2; 684 671 var x = centerX + radius*cos(actualAngle); 685 672 var y = centerY + radius*sin(actualAngle); 686 for ( var partIndex = 0; partIndex < numParts; partIndex++)673 for (let partIndex = 0; partIndex < numParts; ++partIndex) 687 674 { 688 for ( var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)675 for (let wallEle of wallPart) 689 676 { 690 var wallEle = wallStyles[style][wallPart[elementIndex]];677 wallEle = getWallElement(style, wallEle); 691 678 // Width correction 692 var addAngle = scaleFactor * wallEle.width/ radius;693 vartargetX = centerX + radius * cos(actualAngle + addAngle);694 vartargetY = centerY + radius * sin(actualAngle + addAngle);695 varplaceX = x + (targetX - x)/2;696 varplaceY = y + (targetY - y)/2;697 varplaceAngle = actualAngle + addAngle/2;679 let addAngle = scaleFactor * (wallEle.length - getOverlap(style)) / radius; 680 let targetX = centerX + radius * cos(actualAngle + addAngle); 681 let targetY = centerY + radius * sin(actualAngle + addAngle); 682 let placeX = x + (targetX - x)/2; 683 let placeY = y + (targetY - y)/2; 684 let placeAngle = actualAngle + addAngle/2; 698 685 // Indent correction 699 686 placeX -= wallEle.indent * cos(placeAngle); 700 687 placeY -= wallEle.indent * sin(placeAngle); 701 688 // Placement 702 var ent ity = wallEle.entity;703 if (ent ity!== undefined)704 placeObject(placeX, placeY, ent ity, playerId, placeAngle + wallEle.angle);689 var entPath = wallEle.entPath; 690 if (entPath !== undefined) 691 placeObject(placeX, placeY, entPath, playerId, placeAngle + wallEle.angle); 705 692 // Prepare for the next wall element 706 693 actualAngle += addAngle; 707 694 x = centerX + radius*cos(actualAngle); … … function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, 710 697 } 711 698 if (endWithFirst == true) 712 699 { 713 var wallEle = wallStyles[style][wallPart[0]];714 var addAngle = scaleFactor * wallEle. width / radius;700 var wallEle = getWallElement(style, wallPart[0]); 701 var addAngle = scaleFactor * wallEle.length / radius; 715 702 var targetX = centerX + radius * cos(actualAngle + addAngle); 716 703 var targetY = centerY + radius * sin(actualAngle + addAngle); 717 704 var placeX = x + (targetX - x)/2; 718 705 var placeY = y + (targetY - y)/2; 719 706 var placeAngle = actualAngle + addAngle/2; 720 placeObject(placeX, placeY, wallEle.ent ity, playerId, placeAngle + wallEle.angle);707 placeObject(placeX, placeY, wallEle.entPath, playerId, placeAngle + wallEle.angle); 721 708 } 722 709 } 723 710 … … function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, 728 715 // 729 716 // centerX/Y Coordinates of the polygon's center 730 717 // radius How wide the circle should be in which the polygon fits 731 // wallPart Optional. An array of NON-BENDING wall element type strings. Default is ["wallLong", "tower"]718 // wallPart Optional. An array of NON-BENDING wall element types. Default is ["wallLong", "tower"] 732 719 // cornerWallElement Optional. Wall element to be placed at the polygon's corners. Default is "tower" 733 720 // style Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia 734 721 // playerId Optional. Integer number of the player. Default is 0 (gaia) … … function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, 741 728 // TODO: Check some arguments 742 729 // TODO: Add eccentricity and perhaps make it just call placeIrregularPolygonalWall with irregularity = 0 743 730 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 744 function placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElement, style, playerId , orientation, numCorners, skipFirstWall)731 function placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElement, style, playerId=0, orientation=0, numCorners=8, skipFirstWall=true) 745 732 { 746 733 // Setup optional arguments to the default 747 wallPart = (wallPart || ["wallLong", "tower"]); 748 cornerWallElement = (cornerWallElement || "tower"); // Don't use wide elements for this. Not supported well... 749 playerId = (playerId || 0); 750 if (!wallStyles.hasOwnProperty(style)) 751 { 752 if (playerId == 0) 753 style = (style || "palisades"); 754 else 755 style = (getCivCode(playerId-1)); 756 } 757 orientation = (orientation || 0); 758 numCorners = (numCorners || 8); 759 skipFirstWall = (skipFirstWall || true); 760 734 wallPart = wallPart || ["long", "tower"]; 735 cornerWallElement = cornerWallElement || "tower"; // Don't use wide elements for this. Not supported well... 736 if (!style || g_WallStyleList.indexOf(style) == -1) 737 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 738 761 739 // Setup angles 762 var angleAdd = 2*PI/numCorners;740 var angleAdd = TWO_PI/numCorners; 763 741 var angleStart = orientation - angleAdd/2; 742 764 743 // Setup corners 765 744 var corners = []; 766 for ( var i = 0; i < numCorners; i++)745 for (let i = 0; i < numCorners; ++i) 767 746 corners.push([centerX + radius*cos(angleStart + i*angleAdd), centerY + radius*sin(angleStart + i*angleAdd)]); 747 768 748 // Place Corners and walls 769 for ( var i = 0; i < numCorners; i++)749 for (let i = 0; i < numCorners; ++i) 770 750 { 771 varangleToCorner = getAngle(corners[i][0], corners[i][1], centerX, centerY);772 placeObject(corners[i][0], corners[i][1], wallStyles[style][cornerWallElement].entity, playerId, angleToCorner);751 let angleToCorner = getAngle(corners[i][0], corners[i][1], centerX, centerY); 752 placeObject(corners[i][0], corners[i][1], getWallElement(style, cornerWallElement).entPath, playerId, angleToCorner); 773 753 if (!(skipFirstWall && i == 0)) 774 754 { 755 let cornerLength = getWallElement(style, cornerWallElement).length / 2; 756 let cornerAngle = angleToCorner + angleAdd / 2; 757 let cornerX = cornerLength * sin(cornerAngle); 758 let cornerY = cornerLength * cos(cornerAngle); 775 759 placeLinearWall( 776 760 // Adjustment to the corner element width (approximately) 777 corners[i][0] + wallStyles[style][cornerWallElement].width/2 * sin(angleToCorner + angleAdd/2), // startX778 corners[i][1] - wallStyles[style][cornerWallElement].width/2 * cos(angleToCorner + angleAdd/2), // startY779 corners[(i+1)%numCorners][0] - wallStyles[style][cornerWallElement].width/2 * sin(angleToCorner + angleAdd/2), // targetX780 corners[(i+1)%numCorners][1] + wallStyles[style][cornerWallElement].width/2 * cos(angleToCorner + angleAdd/2), // targetY761 corners[i][0] + cornerX, // startX 762 corners[i][1] - cornerY, // startY 763 corners[(i+1)%numCorners][0] - cornerX, // targetX 764 corners[(i+1)%numCorners][1] + cornerY, // targetY 781 765 wallPart, style, playerId); 782 766 } 783 767 } … … function placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElemen 794 778 // style Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia 795 779 // playerId Optional. Integer number of the player. Default is 0 (gaia) 796 780 // orientation Optional. Angle from the center to the first linear wall part placed. Default is 0 (towards positive X/right) 797 // numCorners Optional. How many corners the polygon will have. Default is 8 (matching a civ centers territory)781 // numCorners Optional. How many corners the polygon will have. Default is randomly chosen from 'tween 5 & 7 inclusive 798 782 // irregularity Optional. How irregular the polygon will be. 0 means regular, 1 means VERY irregular. Default is 0.5 799 // skipFirstWall Optional. Boolean. If the first linear wall part will be left opened as entrance. Default is true783 // skipFirstWall Optional. Boolean. If the first linear wall part will be left opened as entrance. Default is false 800 784 // wallPartsAssortment Optional. An array of wall part arrays to choose from for each linear wall connecting the corners. Default is hard to describe ^^ 801 785 // 802 786 // NOTE: wallPartsAssortment is put to the end because it's hardest to set … … function placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElemen 805 789 // TODO: Check some arguments 806 790 // TODO: Perhaps add eccentricity 807 791 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 808 function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement , style, playerId, orientation, numCorners, irregularity, skipFirstWall, wallPartsAssortment)792 function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement="tower", style, playerId=0, orientation=0, numCorners, irregularity=0.5, skipFirstWall=false, wallPartsAssortment) 809 793 { 810 794 // Setup optional arguments 811 playerId = (playerId || 0); 812 if (!wallStyles.hasOwnProperty(style)) 813 { 814 if (playerId == 0) 815 style = (style || "palisades"); 816 else 817 style = (getCivCode(playerId-1)); 818 } 819 795 if (!style || g_WallStyleList.indexOf(style) == -1) 796 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 797 numCorners = (numCorners || randInt(5, 7)); 798 820 799 // Generating a generic wall part assortment with each wall part including 1 gate lengthened by walls and towers 821 800 // NOTE: It might be a good idea to write an own function for that... 822 var defaultWallPartsAssortment = [[" wallShort"], ["wall"], ["wallLong"], ["gate", "tower", "wallShort"]];801 var defaultWallPartsAssortment = [["short"], ["medium"], ["long"], ["gate", "tower", "short"]]; 823 802 var centeredWallPart = ["gate"]; 824 var extandingWallPartAssortment = [["tower", " wallLong"], ["tower", "wall"]];803 var extandingWallPartAssortment = [["tower", "long"], ["tower", "medium"]]; 825 804 defaultWallPartsAssortment.push(centeredWallPart); 826 for (var i = 0; i < extandingWallPartAssortment.length; i++)805 for (var i = 0; i < extandingWallPartAssortment.length; ++i) 827 806 { 828 807 var wallPart = centeredWallPart; 829 for (var j = 0; j < radius; j++)808 for (var j = 0; j < radius; ++j) 830 809 { 831 810 if (j%2 == 0) 832 811 wallPart = wallPart.concat(extandingWallPartAssortment[i]); … … function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement 841 820 } 842 821 // Setup optional arguments to the default 843 822 wallPartsAssortment = (wallPartsAssortment || defaultWallPartsAssortment); 844 cornerWallElement = (cornerWallElement || "tower"); // Don't use wide elements for this. Not supported well... 845 style = (style || "palisades"); 846 playerId = (playerId || 0); 847 orientation = (orientation || 0); 848 numCorners = (numCorners || randInt(5, 7)); 849 irregularity = (irregularity || 0.5); 850 skipFirstWall = (skipFirstWall || false); 823 851 824 // Setup angles 852 var angleToCover = 2*PI;825 var angleToCover = TWO_PI; 853 826 var angleAddList = []; 854 for (var i = 0; i < numCorners; i++)827 for (var i = 0; i < numCorners; ++i) 855 828 { 856 829 // Randomize covered angles. Variety scales down with raising angle though... 857 830 angleAddList.push(angleToCover/(numCorners-i) * (1 + randFloat(-irregularity, irregularity))); … … function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement 860 833 // Setup corners 861 834 var corners = []; 862 835 var angleActual = orientation - angleAddList[0]/2; 863 for (var i = 0; i < numCorners; i++)836 for (var i = 0; i < numCorners; ++i) 864 837 { 865 838 corners.push([centerX + radius*cos(angleActual), centerY + radius*sin(angleActual)]); 866 839 if (i < numCorners - 1) … … function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement 869 842 // Setup best wall parts for the different walls (a bit confusing naming...) 870 843 var wallPartLengths = []; 871 844 var maxWallPartLength = 0; 872 for ( var partIndex = 0; partIndex < wallPartsAssortment.length; partIndex++)845 for (let wallPart of wallPartsAssortment) 873 846 { 874 var length = wallPartLengths[partIndex];875 wallPartLengths.push( getWallLength(wallPartsAssortment[partIndex], style));847 var length = getWallLength(style, wallPart); 848 wallPartLengths.push(length); 876 849 if (length > maxWallPartLength) 877 850 maxWallPartLength = length; 878 851 } 852 879 853 var wallPartList = []; // This is the list of the wall parts to use for the walls between the corners, not to confuse with wallPartsAssortment! 880 for (var i = 0; i < numCorners; i++)854 for (var i = 0; i < numCorners; ++i) 881 855 { 882 var bestWallPart = []; // This is a simp elwall part not a wallPartsAssortment!883 var bestWallLength = 99999999;856 var bestWallPart = []; // This is a simple wall part not a wallPartsAssortment! 857 var bestWallLength = Number.MAX_VALUE; 884 858 // NOTE: This is not exactly like the length the wall will be in the end. Has to be tweaked... 885 859 var wallLength = getDistance(corners[i][0], corners[i][1], corners[(i+1)%numCorners][0], corners[(i+1)%numCorners][1]); 886 860 var numWallParts = ceil(wallLength/maxWallPartLength); 887 for (var partIndex = 0; partIndex < wallPartsAssortment.length; partIndex++)861 for (var partIndex = 0; partIndex < wallPartsAssortment.length; ++partIndex) 888 862 { 889 863 var linearWallLength = numWallParts*wallPartLengths[partIndex]; 890 864 if (linearWallLength < bestWallLength && linearWallLength > wallLength) … … function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement 895 869 } 896 870 wallPartList.push(bestWallPart); 897 871 } 872 898 873 // Place Corners and walls 899 for (var i = 0; i < numCorners; i++)874 for (var i = 0; i < numCorners; ++i) 900 875 { 901 876 var angleToCorner = getAngle(corners[i][0], corners[i][1], centerX, centerY); 902 placeObject(corners[i][0], corners[i][1], wallStyles[style][cornerWallElement].entity, playerId, angleToCorner);877 placeObject(corners[i][0], corners[i][1], getWallElement(style, cornerWallElement).entPath, playerId, angleToCorner); 903 878 if (!(skipFirstWall && i == 0)) 904 879 { 880 let cornerLength = getWallElement(style, cornerWallElement).length / 2; 905 881 placeLinearWall( 906 882 // Adjustment to the corner element width (approximately) 907 corners[i][0] + wallStyles[style][cornerWallElement].width/2* sin(angleToCorner + angleAddList[i]/2), // startX908 corners[i][1] - wallStyles[style][cornerWallElement].width/2* cos(angleToCorner + angleAddList[i]/2), // startY909 corners[(i+1)%numCorners][0] - wallStyles[style][cornerWallElement].width/2* sin(angleToCorner + angleAddList[(i+1)%numCorners]/2), // targetX910 corners[(i+1)%numCorners][1] + wallStyles[style][cornerWallElement].width/2* cos(angleToCorner + angleAddList[(i+1)%numCorners]/2), // targetY883 corners[i][0] + cornerLength * sin(angleToCorner + angleAddList[i]/2), // startX 884 corners[i][1] - cornerLength * cos(angleToCorner + angleAddList[i]/2), // startY 885 corners[(i+1)%numCorners][0] - cornerLength * sin(angleToCorner + angleAddList[(i+1)%numCorners]/2), // targetX 886 corners[(i+1)%numCorners][1] + cornerLength * cos(angleToCorner + angleAddList[(i+1)%numCorners]/2), // targetY 911 887 wallPartList[i], style, playerId, false); 912 888 } 913 889 } … … function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement 920 896 // This is the default Iberian civ bonus starting wall 921 897 // 922 898 // centerX/Y The approximate center coordinates of the fortress 923 // radius The approximate radius of the wall to be placed899 // radius Optional. The approximate radius of the wall to be placed. Default is 20 924 900 // playerId Optional. Integer number of the player. Default is 0 (gaia) 925 901 // style Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia 926 // irregularity Optional. Float between 0 (circle) and 1 (very spiky), default is 1/2902 // irregularity Optional. Float between 0 (circle) and 1 (very spiky), default is 0.5 927 903 // gateOccurence Optional. Integer number, every n-th walls will be a gate instead. Default is 3 928 904 // maxTrys Optional. How often the function tries to find a better fitting shape at max. Default is 100 929 905 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 930 function placeGenericFortress(centerX, centerY, radius , playerId, style, irregularity, gateOccurence, maxTrys)906 function placeGenericFortress(centerX, centerY, radius=20, playerId=0, style, irregularity=0.5, gateOccurence=3, maxTrys=100) 931 907 { 932 908 // Setup optional arguments 933 radius = (radius || 20); 934 playerId = (playerId || 0); 935 if (!wallStyles.hasOwnProperty(style)) 936 { 937 if (playerId == 0) 938 style = (style || "palisades"); 939 else 940 style = (getCivCode(playerId-1)); 941 } 942 irregularity = (irregularity || 1/2); 943 gateOccurence = (gateOccurence || 3); 944 maxTrys = (maxTrys || 100); 909 if (!style || g_WallStyleList.indexOf(style) == -1) 910 style = (playerId == 0) ? "palisade" : getCivCode(playerId-1)+"_stone"; 945 911 946 912 // Setup some vars 947 913 var startAngle = randFloat(0, 2*PI); 948 914 var actualOffX = radius*cos(startAngle); 949 915 var actualOffY = radius*sin(startAngle); 950 916 var actualAngle = startAngle; 951 var pointDistance = wallStyles[style]["wallLong"].width + wallStyles[style]["tower"].width;917 var pointDistance = getWallLength(style, ["long", "tower"]); 952 918 // Searching for a well fitting point derivation 953 919 var tries = 0; 954 920 var bestPointDerivation = undefined; 955 921 var minOverlap = 1000; 956 922 var overlap = undefined; 957 while (tries < maxTrys && minOverlap > wallStyles[style]["tower"].width / 10)923 while (tries < maxTrys && minOverlap > getOverlap(style)) 958 924 { 959 925 var pointDerivation = []; 960 926 var distanceToTarget = 1000; … … function placeGenericFortress(centerX, centerY, radius, playerId, style, irregul 963 929 { 964 930 var indent = randFloat(-irregularity*pointDistance, irregularity*pointDistance); 965 931 var tmpAngle = getAngle(actualOffX, actualOffY, 966 (radius + indent)*cos(actualAngle + (pointDistance / radius)),967 (radius + indent)*sin(actualAngle + (pointDistance / radius)));932 (radius + indent)*cos(actualAngle + pointDistance / radius), 933 (radius + indent)*sin(actualAngle + pointDistance / radius)); 968 934 actualOffX += pointDistance*cos(tmpAngle); 969 935 actualOffY += pointDistance*sin(tmpAngle); 970 936 actualAngle = getAngle(0, 0, actualOffX, actualOffY); … … function placeGenericFortress(centerX, centerY, radius, playerId, style, irregul 982 948 } 983 949 } 984 950 } 985 tries++;951 ++tries; 986 952 } 987 953 log("placeGenericFortress: Reduced overlap to " + minOverlap + " after " + tries + " tries"); 988 954 // Place wall 989 for (var pointIndex = 0; pointIndex < bestPointDerivation.length; pointIndex++)955 for (var pointIndex = 0; pointIndex < bestPointDerivation.length; ++pointIndex) 990 956 { 991 957 var startX = centerX + bestPointDerivation[pointIndex][0]; 992 958 var startY = centerY + bestPointDerivation[pointIndex][1]; 993 959 var targetX = centerX + bestPointDerivation[(pointIndex + 1) % bestPointDerivation.length][0]; 994 960 var targetY = centerY + bestPointDerivation[(pointIndex + 1) % bestPointDerivation.length][1]; 995 961 var angle = getAngle(startX, startY, targetX, targetY); 996 var wallElement = " wallLong";962 var wallElement = "long"; 997 963 if ((pointIndex + 1) % gateOccurence == 0) 998 964 wallElement = "gate"; 999 var entity = wallStyles[style][wallElement].entity; 1000 if (entity) 965 966 var entPath = getWallElement(style, wallElement).entPath; 967 if (entPath) 1001 968 { 1002 969 placeObject(startX + (getDistance(startX, startY, targetX, targetY)/2)*cos(angle), // placeX 1003 970 startY + (getDistance(startX, startY, targetX, targetY)/2)*sin(angle), // placeY 1004 ent ity, playerId, angle - PI/2 + wallStyles[style][wallElement].angle);971 entPath, playerId, angle - PI/2 + getWallElement(style, wallElement).angle); 1005 972 } 1006 973 // Place tower 1007 974 var startX = centerX + bestPointDerivation[(pointIndex + bestPointDerivation.length - 1) % bestPointDerivation.length][0]; 1008 975 var startY = centerY + bestPointDerivation[(pointIndex + bestPointDerivation.length - 1) % bestPointDerivation.length][1]; 1009 976 var angle = getAngle(startX, startY, targetX, targetY); 1010 placeObject(centerX + bestPointDerivation[pointIndex][0], centerY + bestPointDerivation[pointIndex][1], wallStyles[style]["tower"].entity, playerId, angle - PI/2 + wallStyles[style]["tower"].angle); 977 978 var tower = getWallElement(style, "tower"); 979 placeObject(centerX + bestPointDerivation[pointIndex][0], centerY + bestPointDerivation[pointIndex][1], tower.entPath, playerId, angle - PI/2 + tower.angle); 1011 980 } 1012 981 } -
binaries/data/mods/public/maps/random/schwarzwald.js
var playerAngleMaxOff = playerAngleAddAvrg/4; 131 131 // Setup paths 132 132 var pathSucsessRadius = baseRadius/2; 133 133 var pathAngleOff = PI/2; 134 var pathWidth = 10; // This is not really the path's thickness in tiles but the number of tiles in the clum bs of the path134 var pathWidth = 10; // This is not really the path's thickness in tiles but the number of tiles in the clumps of the path 135 135 136 136 // Setup additional resources 137 137 var resourceRadius = 2*mapRadius/3; // 3*mapRadius/8; … … HeightPlacer.prototype.place = function (constraint) { 159 159 constraint = (constraint || new NullConstraint()); 160 160 161 161 var ret = []; 162 for (var x = 0; x < g_Map.size; x++) {163 for (var y = 0; y < g_Map.size; y++) {162 for (var x = 0; x < g_Map.size; ++x) { 163 for (var y = 0; y < g_Map.size; ++y) { 164 164 if (g_Map.height[x][y] >= this.lowerBound && g_Map.height[x][y] <= this.upperBound && constraint.allows(x, y)) { 165 165 ret.push(new PointXZ(x, y)); 166 166 } … … function getOrderOfPointsForShortestClosePath(points) 179 179 var distances = []; 180 180 if (points.length <= 3) 181 181 { 182 for (var i = 0; i < points.length; i++)182 for (var i = 0; i < points.length; ++i) 183 183 order.push(i); 184 184 185 185 return order; … … function getOrderOfPointsForShortestClosePath(points) 187 187 188 188 // Just add the first 3 points 189 189 var pointsToAdd = deepcopy(points); 190 for (var i = 0; i < min(points.length, 3); i ++)190 for (var i = 0; i < min(points.length, 3); i) 191 191 { 192 192 order.push(i); 193 193 pointsToAdd.shift(i); … … function getOrderOfPointsForShortestClosePath(points) 198 198 199 199 // Add remaining points so the path lengthens the least 200 200 var numPointsToAdd = pointsToAdd.length; 201 for (var i = 0; i < numPointsToAdd; i++)201 for (var i = 0; i < numPointsToAdd; ++i) 202 202 { 203 203 var indexToAddTo = undefined; 204 204 var minEnlengthen = Infinity; 205 205 var minDist1 = 0; 206 206 var minDist2 = 0; 207 for (var k = 0; k < order.length; k++)207 for (var k = 0; k < order.length; ++k) 208 208 { 209 209 var dist1 = getDistance(pointsToAdd[0][0], pointsToAdd[0][1], points[order[k]][0], points[order[k]][1]); 210 210 var dist2 = getDistance(pointsToAdd[0][0], pointsToAdd[0][1], points[order[(k + 1) % order.length]][0], points[order[(k + 1) % order.length]][1]); … … function getOrderOfPointsForShortestClosePath(points) 232 232 // 233 233 //////////////// 234 234 235 // Some heightmap constants236 const MIN_HEIGHT = - SEA_LEVEL; // -20237 const MAX_HEIGHT = 0xFFFF/HEIGHT_UNITS_PER_METRE - SEA_LEVEL; // A bit smaller than 90238 239 235 // Get the diferrence between minimum and maxumum height 240 236 function getMinAndMaxHeight(reliefmap) 241 237 { 242 238 var height = {}; 243 239 height.min = Infinity; 244 240 height.max = - Infinity; 245 for (var x = 0; x < reliefmap.length; x++)241 for (var x = 0; x < reliefmap.length; ++x) 246 242 { 247 for (var y = 0; y < reliefmap[x].length; y++)243 for (var y = 0; y < reliefmap[x].length; ++y) 248 244 { 249 245 if (reliefmap[x][y] < height.min) 250 246 height.min = reliefmap[x][y]; … … function rescaleHeightmap(minHeight, maxHeight, heightmap) 264 260 var oldHeightRange = getMinAndMaxHeight(heightmap); 265 261 var max_x = heightmap.length; 266 262 var max_y = heightmap[0].length; 267 for (var x = 0; x < max_x; x++)268 for (var y = 0; y < max_y; y++)263 for (var x = 0; x < max_x; ++x) 264 for (var y = 0; y < max_y; ++y) 269 265 heightmap[x][y] = minHeight + (heightmap[x][y] - oldHeightRange.min) / (oldHeightRange.max - oldHeightRange.min) * (maxHeight - minHeight); 270 266 } 271 267 … … function getStartLocationsByHeightmap(hightRange, maxTries, minDistToBorder, num 288 284 heightmap = (heightmap || g_Map.height); 289 285 290 286 var validStartLocTiles = []; 291 for (var x = minDistToBorder; x < heightmap.length - minDistToBorder; x++)292 for (var y = minDistToBorder; y < heightmap[0].length - minDistToBorder; y++)287 for (var x = minDistToBorder; x < heightmap.length - minDistToBorder; ++x) 288 for (var y = minDistToBorder; y < heightmap[0].length - minDistToBorder; ++y) 293 289 if (heightmap[x][y] > hightRange.min && heightmap[x][y] < hightRange.max) // Has the right hight 294 290 validStartLocTiles.push([x, y]); 295 291 296 292 var maxMinDist = 0; 297 for (var tries = 0; tries < maxTries; tries++)293 for (var tries = 0; tries < maxTries; ++tries) 298 294 { 299 295 var startLoc = []; 300 296 var minDist = heightmap.length; 301 for (var p = 0; p < numberOfPlayers; p++)297 for (var p = 0; p < numberOfPlayers; ++p) 302 298 startLoc.push(validStartLocTiles[randInt(validStartLocTiles.length)]); 303 for (var p1 = 0; p1 < numberOfPlayers - 1; p1++)299 for (var p1 = 0; p1 < numberOfPlayers - 1; ++p1) 304 300 { 305 for (var p2 = p1 + 1; p2 < numberOfPlayers; p2++)301 for (var p2 = p1 + 1; p2 < numberOfPlayers; ++p2) 306 302 { 307 303 var dist = getDistance(startLoc[p1][0], startLoc[p1][1], startLoc[p2][0], startLoc[p2][1]); 308 304 if (dist < minDist) … … function derivateEntitiesByHeight(hightRange, startLoc, entityList, maxTries, mi 340 336 341 337 var placements = deepcopy(startLoc); 342 338 var validTiles = []; 343 for (var x = minDistance; x < heightmap.length - minDistance; x++)344 for (var y = minDistance; y < heightmap[0].length - minDistance; y++)339 for (var x = minDistance; x < heightmap.length - minDistance; ++x) 340 for (var y = minDistance; y < heightmap[0].length - minDistance; ++y) 345 341 if (heightmap[x][y] > hightRange.min && heightmap[x][y] < hightRange.max) // Has the right hight 346 342 validTiles.push([x, y]); 347 343 348 344 if (!validTiles.length) 349 345 return; 350 346 351 for (var tries = 0; tries < maxTries; tries++)347 for (var tries = 0; tries < maxTries; ++tries) 352 348 { 353 349 var tile = validTiles[randInt(validTiles.length)]; 354 350 var isValid = true; 355 for (var p = 0; p < placements.length; p++)351 for (var p = 0; p < placements.length; ++p) 356 352 { 357 353 if (getDistance(placements[p][0], placements[p][1], tile[0], tile[1]) < minDistance) 358 354 { … … function setBaseTerrainDiamondSquare(minHeight, maxHeight, smoothness, initialHe 395 391 var newHeightmap = []; 396 392 var oldWidth = initialHeightmap.length; 397 393 // Square 398 for (var x = 0; x < 2 * oldWidth - 1; x++)394 for (var x = 0; x < 2 * oldWidth - 1; ++x) 399 395 { 400 396 newHeightmap.push([]); 401 for (var y = 0; y < 2 * oldWidth - 1; y++)397 for (var y = 0; y < 2 * oldWidth - 1; ++y) 402 398 { 403 399 if (x % 2 === 0 && y % 2 === 0) // Old tile 404 400 newHeightmap[x].push(initialHeightmap[x/2][y/2]); … … function setBaseTerrainDiamondSquare(minHeight, maxHeight, smoothness, initialHe 412 408 } 413 409 } 414 410 // Diamond 415 for (var x = 0; x < 2 * oldWidth - 1; x++)411 for (var x = 0; x < 2 * oldWidth - 1; ++x) 416 412 { 417 for (var y = 0; y < 2 * oldWidth - 1; y++)413 for (var y = 0; y < 2 * oldWidth - 1; ++y) 418 414 { 419 415 if (newHeightmap[x][y] === undefined) 420 416 { … … function setBaseTerrainDiamondSquare(minHeight, maxHeight, smoothness, initialHe 452 448 453 449 // Cut initialHeightmap to fit target width 454 450 var shift = [floor((newHeightmap.length - heightmap.length) / 2), floor((newHeightmap[0].length - heightmap[0].length) / 2)]; 455 for (var x = 0; x < heightmap.length; x++)456 for (var y = 0; y < heightmap[0].length; y++)451 for (var x = 0; x < heightmap.length; ++x) 452 for (var y = 0; y < heightmap[0].length; ++y) 457 453 heightmap[x][y] = newHeightmap[x][y]; 458 454 } 459 455 … … function decayErrodeHeightmap(strength, heightmap) 474 470 var map = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]]; // smoother 475 471 var max_x = heightmap.length; 476 472 var max_y = heightmap[0].length; 477 for (var x = 0; x < max_x; x++)478 for (var y = 0; y < max_y; y++)479 for (var i = 0; i < map.length; i++)473 for (var x = 0; x < max_x; ++x) 474 for (var y = 0; y < max_y; ++y) 475 for (var i = 0; i < map.length; ++i) 480 476 heightmap[x][y] += strength / map.length * (referenceHeightmap[(x + map[i][0] + max_x) % max_x][(y + map[i][1] + max_y) % max_y] - referenceHeightmap[x][y]); // Not entirely sure if scaling with map.length is perfect but tested values seam to indicate it is 481 477 } 482 478 … … function rectangularSmoothToHeight(center, dx, dy, targetHeight, strength, heigh 490 486 heightmap = (heightmap || g_Map.height); 491 487 492 488 var heightmapWin = []; 493 for (var wx = 0; wx < 2 * dx + 1; wx++)489 for (var wx = 0; wx < 2 * dx + 1; ++wx) 494 490 { 495 491 heightmapWin.push([]); 496 for (var wy = 0; wy < 2 * dy + 1; wy++)492 for (var wy = 0; wy < 2 * dy + 1; ++wy) 497 493 { 498 494 var actualX = x - dx + wx; 499 495 var actualY = y - dy + wy; … … function rectangularSmoothToHeight(center, dx, dy, targetHeight, strength, heigh 503 499 heightmapWin[wx].push(targetHeight); 504 500 } 505 501 } 506 for (var wx = 0; wx < 2 * dx + 1; wx++)502 for (var wx = 0; wx < 2 * dx + 1; ++wx) 507 503 { 508 for (var wy = 0; wy < 2 * dy + 1; wy++)504 for (var wy = 0; wy < 2 * dy + 1; ++wy) 509 505 { 510 506 var actualX = x - dx + wx; 511 507 var actualY = y - dy + wy; … … var initialReliefmap = [[heightRange.max, heightRange.max, heightRange.max], [he 550 546 551 547 setBaseTerrainDiamondSquare(heightRange.min, heightRange.max, 0.5, initialReliefmap, g_Map.height); 552 548 // Apply simple erosion 553 for (var i = 0; i < 5; i++)549 for (var i = 0; i < 5; ++i) 554 550 decayErrodeHeightmap(0.5); 555 551 rescaleHeightmap(heightRange.min, heightRange.max); 556 552 … … var heighLimits = [ 582 578 var startLocations = getStartLocationsByHeightmap({'min': heighLimits[4], 'max': heighLimits[5]}); 583 579 var playerHeight = (heighLimits[4] + heighLimits[5]) / 2; 584 580 585 for (var i=0; i < numPlayers; i++)581 for (var i=0; i < numPlayers; ++i) 586 582 { 587 583 playerAngle[i] = (playerAngleStart + i*playerAngleAddAvrg + randFloat(0, playerAngleMaxOff))%(2*PI); 588 584 var x = round(mapCenterX + randFloat(minPlayerRadius, maxPlayerRadius)*cos(playerAngle[i])); … … for (var i=0; i < numPlayers; i++) 604 600 var distToSL = 15; 605 601 var resStartAngle = playerAngle[i] + PI; 606 602 var resAddAngle = 2*PI / startingResources.length; 607 for (var rIndex = 0; rIndex < startingResources.length; rIndex++)603 for (var rIndex = 0; rIndex < startingResources.length; ++rIndex) 608 604 { 609 605 var angleOff = randFloat(-resAddAngle/2, resAddAngle/2); 610 606 var placeX = x + distToSL*cos(resStartAngle + rIndex*resAddAngle + angleOff); … … if (doublePaths === true) 644 640 var maxI = numPlayers+1; 645 641 else 646 642 var maxI = numPlayers; 647 for (var i = 0; i < maxI; i++)643 for (var i = 0; i < maxI; ++i) 648 644 { 649 645 if (doublePaths === true) 650 646 var minJ = 0; 651 647 else 652 648 var minJ = i+1; 653 for (var j = minJ; j < numPlayers+1; j++)649 for (var j = minJ; j < numPlayers+1; ++j) 654 650 { 655 651 // Setup start and target coordinates 656 652 if (i < numPlayers) … … for (var i = 0; i < maxI; i++) 700 696 } 701 697 if (getDistance(x, z, targetX, targetZ) < pathSucsessRadius) 702 698 targetReached = true; 703 tries++;699 ++tries; 704 700 705 701 } 706 702 } … … RMS.SetProgress(90); 761 757 762 758 // place trees 763 759 log("Planting trees..."); 764 for (var x = 0; x < mapSize; x++)760 for (var x = 0; x < mapSize; ++x) 765 761 { 766 for (var z = 0; z < mapSize;z++)762 for (var z = 0; z < mapSize; ++z) 767 763 { 768 764 // Some variables 769 765 var radius = Math.pow(Math.pow(mapCenterX - x - 0.5, 2) + Math.pow(mapCenterZ - z - 0.5, 2), 1/2); // The 0.5 is a correction for the entities placed on the center of tiles 770 766 var minDistToSL = mapSize; 771 for (var i=0; i < numPlayers; i++)767 for (var i=0; i < numPlayers; ++i) 772 768 minDistToSL = min(minDistToSL, getDistance(playerStartLocX[i], playerStartLocZ[i], x, z)); 773 769 // Woods tile based 774 770 var tDensFactSL = max(min((minDistToSL - baseRadius) / baseRadius, 1), 0); -
binaries/data/mods/public/maps/random/wall_demo.js
const distToOtherWalls = 10; 61 61 var buildableMapSize = mapSize - 2 * distToMapBorder; 62 62 var actualX = distToMapBorder; 63 63 var actualY = distToMapBorder; 64 // Wall styles are chosen by strings so the civ strings got by getCivCode() can be used 65 // Other styles may be present as well but besides the civ styles only 'palisades' includes all wall element types (yet) 66 const wallStyleList = ["athen", "brit", "cart", "gaul", "iber", "mace", "maur", "pers", "ptol", "rome", "sele", "spart", "rome_siege", "palisades"]; 67 64 var wallStyleList = g_WallStyleList; 68 65 69 66 //////////////////////////////////////// 70 67 // Custom wall placement (element based) 71 68 //////////////////////////////////////// 72 var wall = [' endLeft', 'wallLong', 'tower', 'wall', 'outpost', 'wall', 'cornerOut', 'wall', 'cornerIn', 'wall', 'house', 'endRight', 'entryTower', 'endLeft', 'wallShort', 'barracks', 'gate', 'tower', 'wall', 'wallFort', 'wall', 'endRight'];73 for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)69 var wall = ['start', 'long', 'tower', 'tower', 'tower', 'medium', 'outpost', 'medium', 'cornerOut', 'medium', 'cornerIn', 'medium', 'house', 'end', 'entryTower', 'start', 'short', 'barracks', 'gate', 'tower', 'medium', 'fort', 'medium', 'end']; 70 for (var styleIndex = 0; styleIndex < wallStyleList.length; ++styleIndex) 74 71 { 75 72 var startX = actualX + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the first wall element 76 73 var startY = actualY; // Y coordinate of the first wall element 77 var style = wallStyleList[styleIndex]; // //The wall's style like 'cart', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'78 var orientation = styleIndex * PI/64; // Orientation of the first wall element. 0 means 'outside' or 'front' is right (positive X, like object placement)74 var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades' 75 var orientation = PI/16 * sin(styleIndex * PI/4); // Orientation of the first wall element. 0 means 'outside' or 'front' is right (positive X, like object placement in Atlas) 79 76 // That means the wall will be build towards top (positive Y) if no corners are used 80 77 var playerId = 0; // Owner of the wall (like in placeObject). 0 is Gaia, 1 is Player 1 (default color blue), ... 81 placeWall(startX, startY, wall, style, playerId, orientation); // Actually plac ingthe wall78 placeWall(startX, startY, wall, style, playerId, orientation); // Actually place the wall 82 79 } 83 80 actualX = distToMapBorder; // Reset actualX 84 81 actualY += 80 + distToOtherWalls; // Increase actualY for next wall placement method 85 82 83 86 84 ////////////////////////////////////////////////////////////// 87 85 // Default fortress placement (chosen by fortress type string) 88 86 ////////////////////////////////////////////////////////////// 89 87 var fortressRadius = 15; // The space the fortresses take in average. Just for design of this map 90 for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)88 for (var styleIndex = 0; styleIndex < wallStyleList.length; ++styleIndex) 91 89 { 92 90 var centerX = actualX + fortressRadius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the fortress 93 91 var centerY = actualY + fortressRadius; // Y coordinate of the center of the fortress … … for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++) 99 97 placeObject(centerX, centerY, 'other/obelisk', 0, 0*PI); // Place visual marker to see the center of the fortress 100 98 } 101 99 actualX = distToMapBorder; // Reset actualX 102 actualY += 2 * fortressRadius + 2 * distToOtherWalls; // Increase actualY for next wall placement method 100 actualY += 2 * fortressRadius + distToOtherWalls; // Increase actualY for next wall placement method 101 102 ////////////////////////////////////////////////////////////// 103 // 'generic' fortress placement (iberian wall circuit code) 104 ////////////////////////////////////////////////////////////// 105 var radius = min((mapSize - actualY - distToOtherWalls) / 3, (buildableMapSize / wallStyleList.length - distToOtherWalls) / 2); // The radius of wall circle 106 for (var styleIndex = 0; styleIndex < wallStyleList.length; ++styleIndex) 107 { 108 var centerX = actualX + radius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the fortress 109 var centerY = actualY + radius; // Y coordinate of the center of the fortress 110 var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades' 111 var playerId = 0; // Owner of the wall. 0 is Gaia, 1 is Player 1 (default color blue), ... 112 placeGenericFortress(centerX, centerY, radius, playerId, style); // Actually place the fortress 113 placeObject(centerX, centerY, 'other/obelisk', 0, 0*PI); // Place visual marker to see the center of the fortress 114 } 115 actualX = distToMapBorder; // Reset actualX 116 actualY += 2 * radius + distToOtherWalls; // Increase actualY for next wall placement method 103 117 104 118 ////////////////////////// 105 119 // Circular wall placement … … actualY += 2 * fortressRadius + 2 * distToOtherWalls; // Increase actualY for ne 108 122 var radius = min((mapSize - actualY - distToOtherWalls) / 3, (buildableMapSize / wallStyleList.length - distToOtherWalls) / 2); // The radius of wall circle 109 123 var centerY = actualY + radius; // Y coordinate of the center of the wall circle 110 124 var orientation = 0; // Where the wall circle will be open if maxAngle < 2*PI, see below. Otherwise where the first wall element will be placed 111 for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)125 for (var styleIndex = 0; styleIndex < wallStyleList.length; ++styleIndex) 112 126 { 113 127 var centerX = actualX + radius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the wall circle 114 128 var playerId = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ... 115 var wallPart = ['tower', ' wall', 'house']; // List of wall elements the wall will be build of. Optional, default id ['wall']129 var wallPart = ['tower', 'medium', 'house']; // List of wall elements the wall will be build of. Optional, default id ['wall'] 116 130 var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades' 117 131 var maxAngle = PI/2 * (styleIndex%3 + 2); // How far the wall should circumvent the center 118 132 placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, orientation, maxAngle); // Actually placing the wall … … for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++) 122 136 actualX = distToMapBorder; // Reset actualX 123 137 actualY += 2 * radius + distToOtherWalls; // Increase actualY for next wall placement method 124 138 125 /////////////////////////// 126 // Polygonal wall placement127 /////////////////////////// 139 /////////////////////////////////// 140 // Regular Polygonal wall placement 141 /////////////////////////////////// 128 142 // NOTE: Don't use bending wall elements like corners here! 129 143 var radius = min((mapSize - actualY - distToOtherWalls) / 2, (buildableMapSize / wallStyleList.length - distToOtherWalls) / 2); // The radius of wall polygons 130 144 var centerY = actualY + radius; // Y coordinate of the center of the wall polygon 131 145 var orientation = 0; // Where the wall circle will be open if ???, see below. Otherwise where the first wall will be placed 132 for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)146 for (var styleIndex = 0; styleIndex < wallStyleList.length; ++styleIndex) 133 147 { 134 148 var centerX = actualX + radius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the wall circle 135 149 var playerId = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ... 136 150 var cornerWallElement = 'tower'; // With wall element type will be uset for the corners of the polygon 137 var wallPart = [' wall', 'tower']; // List of wall elements the wall will be build of. Optional, default id ['wall']151 var wallPart = ['medium', 'tower']; // List of wall elements the wall will be build of. Optional, default id ['wall'] 138 152 var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades' 139 153 var numCorners = (styleIndex)%6 + 3; // How many corners the plogon will have 140 154 var skipFirstWall = true; // If the wall should be open towards orientation … … for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++) 145 159 actualX = distToMapBorder; // Reset actualX 146 160 actualY += 2 * radius + distToOtherWalls; // Increase actualY for next wall placement method 147 161 162 ///////////////////////////////////// 163 // Irregular Polygonal wall placement 164 ///////////////////////////////////// 165 // NOTE: Don't use bending wall elements like corners here! 166 var radius = min((mapSize - actualY - distToOtherWalls) / 2, (buildableMapSize / wallStyleList.length - distToOtherWalls) / 2); // The radius of wall polygons 167 var centerY = actualY + radius; // Y coordinate of the center of the wall polygon 168 var orientation = 0; // Where the wall circle will be open if ???, see below. Otherwise where the first wall will be placed 169 for (var styleIndex = 0; styleIndex < wallStyleList.length; ++styleIndex) 170 { 171 var centerX = actualX + radius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the wall circle 172 var playerId = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ... 173 var cornerWallElement = 'tower'; // With wall element type will be uset for the corners of the polygon 174 var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades' 175 var numCorners = (styleIndex)%6 + 3; // How many corners the plogon will have 176 var skipFirstWall = true; // If the wall should be open towards orientation 177 placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement, style, playerId, orientation, numCorners, undefined, skipFirstWall); 178 placeObject(centerX, centerY, 'other/obelisk', 0, 0*PI); // Place visual marker to see the center of the wall circle 179 orientation += PI/16; // Increasing orientation to see how rotation works (like for object placement) 180 } 181 actualX = distToMapBorder; // Reset actualX 182 actualY += 2 * radius + distToOtherWalls; // Increase actualY for next wall placement method 183 184 148 185 //////////////////////// 149 186 // Linear wall placement 150 187 //////////////////////// 151 188 // NOTE: Don't use bending wall elements like corners here! 152 189 var maxWallLength = (mapSize - actualY - distToMapBorder - distToOtherWalls); // Just for this maps design. How long the longest wall will be 153 190 var numWallsPerStyle = floor(buildableMapSize / distToOtherWalls / wallStyleList.length); // Just for this maps design. How many walls of the same style will be placed 154 for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)191 for (var styleIndex = 0; styleIndex < wallStyleList.length; ++styleIndex) 155 192 { 156 for (var wallIndex = 0; wallIndex < numWallsPerStyle; wallIndex++)193 for (var wallIndex = 0; wallIndex < numWallsPerStyle; ++wallIndex) 157 194 { 158 var startX = actualX + (styleIndex * numWallsPerStyle + wallIndex) * distToOtherWalls; // X coordinate the wall will start from195 var startX = actualX + (styleIndex * numWallsPerStyle + wallIndex) * buildableMapSize/wallStyleList.length/numWallsPerStyle; // X coordinate the wall will start from 159 196 var startY = actualY; // Y coordinate the wall will start from 160 197 var endX = startX; // X coordinate the wall will end 161 198 var endY = actualY + (wallIndex + 1) * maxWallLength/numWallsPerStyle; // Y coordinate the wall will end 162 199 var playerId = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ... 163 var wallPart = ['tower', ' wall']; // List of wall elements the wall will be build of200 var wallPart = ['tower', 'medium']; // List of wall elements the wall will be build of 164 201 var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades' 165 202 placeLinearWall(startX, startY, endX, endY, wallPart, style, playerId); // Actually placing the wall 166 203 // placeObject(startX, startY, 'other/obelisk', 0, 0*PI); // Place visual marker to see where exsactly the wall begins 167 204 // placeObject(endX, endY, 'other/obelisk', 0, 0*PI); // Place visual marker to see where exsactly the wall ends 168 205 } 169 206 } 170 actualX = distToMapBorder; // Reset actualX171 actualY += maxWallLength + distToOtherWalls; // Increase actualY for next wall placement method172 207 173 208 174 209 // Export map data -
binaries/data/mods/public/maps/random/wall_demo.json
2 2 "settings" : { 3 3 "Name" : "Wall Demo", 4 4 "Script" : "wall_demo.js", 5 "Description" : "A demonstration of wall placement methods/code in random maps. Very large map size is recommended.",5 "Description" : "A demonstration of wall placement methods/code in random maps. Giant map size is recommended!", 6 6 "BaseTerrain" : ["grass1"], 7 7 "BaseHeight" : 0, 8 8 "Keywords": ["demo"], 9 9 "CircularMap" : false, 10 "RevealMap": true, 10 11 "XXXXXX" : "Optionally define other things here, like we would for a scenario" 11 12 } 12 13 } 14 No newline at end of file -
binaries/data/mods/public/simulation/components/WallPiece.js
WallPiece.prototype.Schema = 6 6 "</a:example>" + 7 7 "<element name='Length'>" + 8 8 "<ref name='nonNegativeDecimal'/>" + 9 "</element>"; 9 "</element>" + 10 "<optional>" + 11 "<element name='Orientation'>" + 12 "<ref name='nonNegativeDecimal'/>" + 13 "</element>" + 14 "</optional>" + 15 "<optional>" + 16 "<element name='Indent'>" + 17 "<data type='decimal'/>" + 18 "</element>" + 19 "</optional>" + 20 "<optional>" + 21 "<element name='Bend'>" + 22 "<data type='decimal'/>" + 23 "</element>" + 24 "</optional>"; 10 25 11 26 12 27 WallPiece.prototype.Init = function() -
binaries/data/mods/public/simulation/components/WallSet.js
WallSet.prototype.Schema = 21 21 "<element name='WallShort' a:help='Template name of the short wall segment'>" + 22 22 "<text/>" + 23 23 "</element>" + 24 "<optional>" + 25 "<element name='WallCurveQuarter'>" + 26 "<text/>" + 27 "</element>" + 28 "</optional>" + 29 "<optional>" + 30 "<element name='WallCurveEighth'>" + 31 "<text/>" + 32 "</element>" + 33 "</optional>" + 34 "<optional>" + 35 "<element name='WallEnd'>" + 36 "<text/>" + 37 "</element>" + 38 "</optional>" + 39 "<optional>" + 40 "<element name='Fort'>" + 41 "<text/>" + 42 "</element>" + 43 "</optional>" + 24 44 "</interleave>" + 25 45 "</element>" + 26 46 "<element name='MinTowerOverlap' a:help='Maximum fraction that wall segments are allowed to overlap towers, where 0 signifies no overlap and 1 full overlap'>" + -
binaries/data/mods/public/simulation/data/civs/athen.json
109 109 "Special":"Train heroes and research technology pertaining to heroes." 110 110 } 111 111 ], 112 "WallSets": 113 [ 114 "other/wallset_palisade", 115 "structures/athen_wallset_stone" 116 ], 112 117 "StartEntities": 113 118 [ 114 119 { -
binaries/data/mods/public/simulation/data/civs/brit.json
87 87 "Special": "" 88 88 } 89 89 ], 90 "WallSets": 91 [ 92 "other/wallset_palisade", 93 "structures/brit_wallset_stone" 94 ], 90 95 "StartEntities": 91 96 [ 92 97 { -
binaries/data/mods/public/simulation/data/civs/cart.json
112 112 "Special":"Hire Iberian mercenaries." 113 113 } 114 114 ], 115 "WallSets": 116 [ 117 "other/wallset_palisade", 118 "structures/cart_wallset_stone" 119 ], 115 120 "StartEntities": 116 121 [ 117 122 { -
binaries/data/mods/public/simulation/data/civs/gaul.json
87 87 "Special": "" 88 88 } 89 89 ], 90 "WallSets": 91 [ 92 "other/wallset_palisade", 93 "structures/gaul_wallset_stone" 94 ], 90 95 "StartEntities": 91 96 [ 92 97 { -
binaries/data/mods/public/simulation/data/civs/iber.json
85 85 "Special": "Defensive Aura - Gives all Iberian units and buildings within vision range of the monument a 10-15% attack boost. Build Limit: Only 5 may be built per map." 86 86 } 87 87 ], 88 "WallSets": 89 [ 90 "other/wallset_palisade", 91 "structures/iber_wallset_stone" 92 93 ], 88 94 "StartEntities": 89 95 [ 90 96 { -
binaries/data/mods/public/simulation/data/civs/mace.json
114 114 "Special":"Constructs and upgrades all Macedonian siege engines." 115 115 } 116 116 ], 117 "WallSets": 118 [ 119 "other/wallset_palisade", 120 "structures/mace_wallset_stone" 121 122 ], 117 123 "StartEntities": 118 124 [ 119 125 { -
binaries/data/mods/public/simulation/data/civs/maur.json
94 94 "Special":"Contentment: +10% Health and +10% resource gathering rates for all citizens and allied citizens within its range. Can be built anywhere except in enemy territory. Max Built: 10." 95 95 } 96 96 ], 97 "WallSets": 98 [ 99 "other/wallset_palisade", 100 "structures/maur_wallset_stone" 101 102 ], 97 103 "StartEntities": 98 104 [ 99 105 { -
binaries/data/mods/public/simulation/data/civs/pers.json
104 104 "Special": "Train heroes and Persian Immortals. Gives a slow trickle of all resources as 'Satrapy Tribute.'" 105 105 } 106 106 ], 107 "WallSets": 108 [ 109 "other/wallset_palisade", 110 "structures/pers_wallset_stone" 111 112 ], 107 113 "StartEntities": 108 114 [ 109 115 { -
binaries/data/mods/public/simulation/data/civs/ptol.json
113 113 "Special":"When built along the shoreline, removes shroud of darkness over all the water, revealing all the coast lines on the map. Limit: 1." 114 114 } 115 115 ], 116 "WallSets": 117 [ 118 "other/wallset_palisade", 119 "structures/ptol_wallset_stone" 120 121 ], 116 122 "StartEntities": 117 123 [ 118 124 { -
binaries/data/mods/public/simulation/data/civs/rome.json
89 89 "Special": "Can be built in neutral and enemy territory to strangle enemy towns." 90 90 } 91 91 ], 92 "WallSets": 93 [ 94 "structures/rome_wallset_stone", 95 "structures/rome_wallset_siege" 96 97 ], 92 98 "StartEntities": 93 99 [ 94 100 { -
binaries/data/mods/public/simulation/data/civs/sele.json
114 114 "Special":"This is the Seleucid expansion building, similar to Civic Centers for other factions. It is weaker and carries a smaller territory influence, but is cheaper and built faster." 115 115 } 116 116 ], 117 "WallSets": 118 [ 119 "other/wallset_palisade", 120 "structures/sele_wallset_stone" 121 122 ], 117 123 "StartEntities": 118 124 [ 119 125 { -
binaries/data/mods/public/simulation/data/civs/spart.json
105 105 "Special":"Train heroes and Spartiates and research technologies related to them." 106 106 } 107 107 ], 108 "WallSets": 109 [ 110 "other/wallset_palisade", 111 "structures/spart_wallset_stone" 112 113 ], 108 114 "StartEntities": 109 115 [ 110 116 { -
binaries/data/mods/public/simulation/templates/other/palisades_rocks_curve.xml
25 25 <VisualActor> 26 26 <Actor>props/special/palisade_rocks_curve.xml</Actor> 27 27 </VisualActor> 28 <WallPiece> 29 <Length>8.0</Length> 30 <Orientation>0.75</Orientation> 31 <Indent>2.8</Indent> 32 <Bend>0.5</Bend> 33 </WallPiece> 28 34 </Entity> -
binaries/data/mods/public/simulation/templates/other/palisades_rocks_end.xml
25 25 <VisualActor> 26 26 <Actor>props/special/palisade_rocks_end.xml</Actor> 27 27 </VisualActor> 28 <WallPiece> 29 <Length>0.8</Length> 30 <Orientation>1.5</Orientation> 31 </WallPiece> 28 32 </Entity> -
binaries/data/mods/public/simulation/templates/other/palisades_rocks_fort.xml
8 8 <Icon>structures/palisade_fort.png</Icon> 9 9 <Classes datatype="tokens">Palisade</Classes> 10 10 </Identity> 11 <WallPiece> 12 <Length>8.0</Length> 13 </WallPiece> 11 14 </Entity> -
binaries/data/mods/public/simulation/templates/other/palisades_rocks_long.xml
39 39 </VisualActor> 40 40 <TerritoryInfluence disable=""/> 41 41 <WallPiece> 42 <Length>1 1.0</Length>42 <Length>14.0</Length> 43 43 </WallPiece> 44 44 </Entity> -
binaries/data/mods/public/simulation/templates/other/palisades_rocks_medium.xml
38 38 </VisualActor> 39 39 <TerritoryInfluence disable=""/> 40 40 <WallPiece> 41 <Length> 8.0</Length>41 <Length>9.2</Length> 42 42 </WallPiece> 43 43 </Entity> -
binaries/data/mods/public/simulation/templates/other/palisades_rocks_short.xml
37 37 <FoundationActor>structures/fndn_1x1pal.xml</FoundationActor> 38 38 </VisualActor> 39 39 <WallPiece> 40 <Length>4. 0</Length>40 <Length>4.8</Length> 41 41 </WallPiece> 42 42 </Entity> -
binaries/data/mods/public/simulation/templates/other/wallset_palisade.xml
13 13 <Templates> 14 14 <Tower>other/palisades_rocks_tower</Tower> 15 15 <Gate>other/palisades_rocks_gate</Gate> 16 <Fort>other/palisades_rocks_fort</Fort> 16 17 <WallLong>other/palisades_rocks_long</WallLong> 17 18 <WallMedium>other/palisades_rocks_medium</WallMedium> 18 19 <WallShort>other/palisades_rocks_short</WallShort> 20 <WallCurveQuarter>other/palisades_rocks_curve</WallCurveQuarter> 21 <WallEnd>other/palisades_rocks_end</WallEnd> 19 22 </Templates> 20 23 </WallSet> 21 24 </Entity> -
binaries/data/mods/public/simulation/templates/structures/athen_fortress.xml
25 25 <VisualActor> 26 26 <Actor>structures/athenians/fortress_up.xml</Actor> 27 27 </VisualActor> 28 <WallPiece> 29 <Length>24.0</Length> 30 <Indent>7.6</Indent> 31 </WallPiece> 28 32 </Entity> -
binaries/data/mods/public/simulation/templates/structures/athen_wall_gate.xml
20 20 <Actor>structures/hellenes/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>3 8.0</Length>23 <Length>35.4</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/athen_wall_long.xml
17 17 <Actor>structures/hellenes/wall_long.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>3 7.0</Length>20 <Length>36.2</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/athen_wall_medium.xml
17 17 <Actor>structures/hellenes/wall_medium.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>24. 0</Length>20 <Length>24.2</Length> 21 21 </WallPiece> 22 </Entity> 23 No newline at end of file 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/athen_wall_short.xml
17 17 <Actor>structures/hellenes/wall_short.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>1 3.0</Length>20 <Length>12.3</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/athen_wall_tower.xml
16 16 <Actor>structures/hellenes/wall_tower.xml</Actor> 17 17 </VisualActor> 18 18 <WallPiece> 19 <Length>7. 5</Length>19 <Length>7.1</Length> 20 20 </WallPiece> 21 </Entity> 22 No newline at end of file 21 </Entity> -
binaries/data/mods/public/simulation/templates/structures/brit_fortress.xml
54 54 <Actor>structures/britons/fortress_briton.xml</Actor> 55 55 <FoundationActor>structures/fndn_5x5.xml</FoundationActor> 56 56 </VisualActor> 57 <WallPiece> 58 <Length>28</Length> 59 </WallPiece> 57 60 </Entity> -
binaries/data/mods/public/simulation/templates/structures/brit_wall_gate.xml
27 27 <Actor>structures/celts/wall_gate.xml</Actor> 28 28 </VisualActor> 29 29 <WallPiece> 30 <Length> 25.0</Length>30 <Length>37.0</Length> 31 31 </WallPiece> 32 32 </Entity> -
binaries/data/mods/public/simulation/templates/structures/brit_wall_long.xml
36 36 <Actor>structures/celts/wall_long.xml</Actor> 37 37 </VisualActor> 38 38 <WallPiece> 39 <Length>3 7.0</Length>39 <Length>36.6</Length> 40 40 </WallPiece> 41 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/brit_wall_medium.xml
33 33 <Actor>structures/celts/wall_medium.xml</Actor> 34 34 </VisualActor> 35 35 <WallPiece> 36 <Length>2 5.0</Length>36 <Length>24.6</Length> 37 37 </WallPiece> 38 38 </Entity> -
binaries/data/mods/public/simulation/templates/structures/brit_wall_short.xml
20 20 <Actor>structures/celts/wall_short.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>1 3.0</Length>23 <Length>12.5</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/brit_wall_tower.xml
20 20 <Actor>structures/celts/wall_tower.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length> 9.0</Length>23 <Length>8.7</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/cart_fortress.xml
31 31 <VisualActor> 32 32 <Actor>structures/carthaginians/fortress.xml</Actor> 33 33 </VisualActor> 34 <WallPiece> 35 <Length>25.0</Length> 36 <Indent>6.4</Indent> 37 </WallPiece> 34 38 </Entity> -
binaries/data/mods/public/simulation/templates/structures/cart_wall_gate.xml
20 20 <Actor>structures/carthaginians/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length> 25.0</Length>23 <Length>43.8</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/cart_wall_long.xml
36 36 <Actor>structures/carthaginians/wall_long.xml</Actor> 37 37 </VisualActor> 38 38 <WallPiece> 39 <Length>4 6.0</Length>39 <Length>43.7</Length> 40 40 </WallPiece> 41 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/cart_wall_medium.xml
30 30 <Actor>structures/carthaginians/wall_medium.xml</Actor> 31 31 </VisualActor> 32 32 <WallPiece> 33 <Length> 30.0</Length>33 <Length>29.3</Length> 34 34 </WallPiece> 35 35 </Entity> -
binaries/data/mods/public/simulation/templates/structures/cart_wall_short.xml
17 17 <Actor>structures/carthaginians/wall_short.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>1 6.0</Length>20 <Length>14.7</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/cart_wall_tower.xml
20 20 <FoundationActor>structures/fndn_3x3.xml</FoundationActor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>11. 0</Length>23 <Length>11.8</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/gaul_fortress.xml
34 34 <VisualActor> 35 35 <Actor>structures/gauls/fortress_gallic.xml</Actor> 36 36 </VisualActor> 37 <WallPiece> 38 <Length>16.8</Length> 39 <Indent>5.8</Indent> 40 </WallPiece> 37 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/gaul_wall_gate.xml
27 27 <Actor>structures/celts/wall_gate.xml</Actor> 28 28 </VisualActor> 29 29 <WallPiece> 30 <Length> 25.0</Length>30 <Length>37.0</Length> 31 31 </WallPiece> 32 32 </Entity> -
binaries/data/mods/public/simulation/templates/structures/gaul_wall_long.xml
36 36 <Actor>structures/celts/wall_long.xml</Actor> 37 37 </VisualActor> 38 38 <WallPiece> 39 <Length>3 7.0</Length>39 <Length>36.6</Length> 40 40 </WallPiece> 41 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/gaul_wall_medium.xml
33 33 <Actor>structures/celts/wall_medium.xml</Actor> 34 34 </VisualActor> 35 35 <WallPiece> 36 <Length>2 5.0</Length>36 <Length>24.6</Length> 37 37 </WallPiece> 38 38 </Entity> -
binaries/data/mods/public/simulation/templates/structures/gaul_wall_short.xml
20 20 <Actor>structures/celts/wall_short.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>1 3.0</Length>23 <Length>12.6</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/gaul_wall_tower.xml
20 20 <Actor>structures/celts/wall_tower.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length> 9.0</Length>23 <Length>8.7</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/iber_fortress.xml
37 37 <VisualActor> 38 38 <Actor>structures/iberians/fortress.xml</Actor> 39 39 </VisualActor> 40 <WallPiece> 41 <Length>24.5</Length> 42 </WallPiece> 40 43 </Entity> -
binaries/data/mods/public/simulation/templates/structures/iber_wall_long.xml
36 36 <Actor>structures/iberians/wall_long.xml</Actor> 37 37 </VisualActor> 38 38 <WallPiece> 39 <Length>36. 0</Length>39 <Length>36.4</Length> 40 40 </WallPiece> 41 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/iber_wall_medium.xml
33 33 <Actor>structures/iberians/wall_medium.xml</Actor> 34 34 </VisualActor> 35 35 <WallPiece> 36 <Length>24. 0</Length>36 <Length>24.4</Length> 37 37 </WallPiece> 38 38 </Entity> -
binaries/data/mods/public/simulation/templates/structures/iber_wall_short.xml
20 20 <Actor>structures/iberians/wall_short.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>12. 0</Length>23 <Length>12.4</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/iber_wall_tower.xml
21 21 <Actor>structures/iberians/wall_tower.xml</Actor> 22 22 </VisualActor> 23 23 <WallPiece> 24 <Length>10 </Length>24 <Length>10.8</Length> 25 25 </WallPiece> 26 26 </Entity> -
binaries/data/mods/public/simulation/templates/structures/mace_fortress.xml
40 40 <VisualActor> 41 41 <Actor>structures/macedonians/fortress_up.xml</Actor> 42 42 </VisualActor> 43 <WallPiece> 44 <Length>24.0</Length> 45 <Indent>7.6</Indent> 46 </WallPiece> 43 47 </Entity> -
binaries/data/mods/public/simulation/templates/structures/mace_wall_gate.xml
20 20 <Actor>structures/hellenes/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>3 8.0</Length>23 <Length>35.4</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/mace_wall_long.xml
17 17 <Actor>structures/hellenes/wall_long.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>3 7.0</Length>20 <Length>36.2</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/mace_wall_medium.xml
17 17 <Actor>structures/hellenes/wall_medium.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>24. 0</Length>20 <Length>24.2</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/mace_wall_short.xml
17 17 <Actor>structures/hellenes/wall_short.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>1 3.0</Length>20 <Length>12.3</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/mace_wall_tower.xml
16 16 <Actor>structures/hellenes/wall_tower.xml</Actor> 17 17 </VisualActor> 18 18 <WallPiece> 19 <Length>7. 5</Length>19 <Length>7.1</Length> 20 20 </WallPiece> 21 </Entity> 22 No newline at end of file 21 </Entity> -
binaries/data/mods/public/simulation/templates/structures/maur_fortress.xml
28 28 <VisualActor> 29 29 <Actor>structures/mauryans/fortress.xml</Actor> 30 30 </VisualActor> 31 <WallPiece> 32 <Length>22.0</Length> 33 </WallPiece> 31 34 </Entity> -
binaries/data/mods/public/simulation/templates/structures/maur_wall_gate.xml
20 20 <Actor>structures/mauryans/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>3 7.0</Length>23 <Length>36.7</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/maur_wall_long.xml
42 42 <Actor>structures/mauryans/wall_long.xml</Actor> 43 43 </VisualActor> 44 44 <WallPiece> 45 <Length>3 5.0</Length>45 <Length>36.6</Length> 46 46 </WallPiece> 47 47 </Entity> -
binaries/data/mods/public/simulation/templates/structures/maur_wall_medium.xml
36 36 <Actor>structures/mauryans/wall_medium.xml</Actor> 37 37 </VisualActor> 38 38 <WallPiece> 39 <Length>24. 0</Length>39 <Length>24.4</Length> 40 40 </WallPiece> 41 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/maur_wall_short.xml
23 23 <Actor>structures/mauryans/wall_short.xml</Actor> 24 24 </VisualActor> 25 25 <WallPiece> 26 <Length>1 3.0</Length>26 <Length>12.4</Length> 27 27 </WallPiece> 28 28 </Entity> -
binaries/data/mods/public/simulation/templates/structures/maur_wall_tower.xml
25 25 <Actor>structures/mauryans/wall_tower.xml</Actor> 26 26 </VisualActor> 27 27 <WallPiece> 28 <Length> 9.5</Length>28 <Length>7.8</Length> 29 29 </WallPiece> 30 30 </Entity> -
binaries/data/mods/public/simulation/templates/structures/pers_fortress.xml
20 20 <VisualActor> 21 21 <Actor>structures/persians/fortress.xml</Actor> 22 22 </VisualActor> 23 <WallPiece> 24 <Length>24.5</Length> 25 <Indent>7.6</Indent> 26 </WallPiece> 23 27 </Entity> -
binaries/data/mods/public/simulation/templates/structures/pers_wall_tower.xml
16 16 <Actor>structures/persians/wall_tower.xml</Actor> 17 17 </VisualActor> 18 18 <WallPiece> 19 <Length> 8.5</Length>19 <Length>7.5</Length> 20 20 </WallPiece> 21 21 </Entity> -
binaries/data/mods/public/simulation/templates/structures/ptol_fortress.xml
31 31 <VisualActor> 32 32 <Actor>structures/ptolemies/fortress.xml</Actor> 33 33 </VisualActor> 34 <WallPiece> 35 <Length>24.0</Length> 36 <Indent>8.7</Indent> 37 </WallPiece> 34 38 </Entity> -
binaries/data/mods/public/simulation/templates/structures/ptol_wall_gate.xml
20 20 <Actor>structures/ptolemies/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>38. 0</Length>23 <Length>38.8</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/ptol_wall_medium.xml
30 30 <Actor>structures/ptolemies/wall_medium.xml</Actor> 31 31 </VisualActor> 32 32 <WallPiece> 33 <Length>2 6.0</Length>33 <Length>25.0</Length> 34 34 </WallPiece> 35 35 </Entity> -
binaries/data/mods/public/simulation/templates/structures/ptol_wall_short.xml
17 17 <Actor>structures/ptolemies/wall_short.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>1 4.0</Length>20 <Length>16.0</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/ptol_wall_tower.xml
16 16 <Actor>structures/ptolemies/wall_tower.xml</Actor> 17 17 </VisualActor> 18 18 <WallPiece> 19 <Length> 10</Length>19 <Length>9.0</Length> 20 20 </WallPiece> 21 </Entity> 22 No newline at end of file 21 </Entity> -
binaries/data/mods/public/simulation/templates/structures/ptol_wallset_stone.xml
14 14 <WallShort>structures/ptol_wall_short</WallShort> 15 15 </Templates> 16 16 <MaxTowerOverlap>0.90</MaxTowerOverlap> 17 <MinTowerOverlap>0. 05</MinTowerOverlap>17 <MinTowerOverlap>0.10</MinTowerOverlap> 18 18 </WallSet> 19 19 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_army_camp.xml
101 101 <Actor>structures/romans/camp.xml</Actor> 102 102 <FoundationActor>structures/fndn_8x8.xml</FoundationActor> 103 103 </VisualActor> 104 <WallPiece> 105 <Length>29.5</Length> 106 <Indent>8</Indent> 107 </WallPiece> 104 108 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_fortress.xml
23 23 <VisualActor> 24 24 <Actor>structures/romans/fortress.xml</Actor> 25 25 </VisualActor> 26 <WallPiece> 27 <Length>25.0</Length> 28 <Indent>8.4</Indent> 29 </WallPiece> 26 30 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_siege_wall_tower.xml
43 43 <Actor>structures/romans/siege_wall_tower.xml</Actor> 44 44 </VisualActor> 45 45 <WallPiece> 46 <Length> 6.0</Length>46 <Length>5.5</Length> 47 47 </WallPiece> 48 48 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_wall_gate.xml
20 20 <Actor>structures/romans/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>3 7.0</Length>23 <Length>36.8</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_wall_long.xml
36 36 <Actor>structures/romans/wall_long.xml</Actor> 37 37 </VisualActor> 38 38 <WallPiece> 39 <Length>3 7.0</Length>39 <Length>36.8</Length> 40 40 </WallPiece> 41 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_wall_medium.xml
33 33 <Actor>structures/romans/wall_medium.xml</Actor> 34 34 </VisualActor> 35 35 <WallPiece> 36 <Length>2 5.0</Length>36 <Length>24.8</Length> 37 37 </WallPiece> 38 38 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_wall_short.xml
20 20 <Actor>structures/romans/wall_short.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>1 3.0</Length>23 <Length>12.9</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_wall_tower.xml
16 16 <Actor>structures/romans/wall_tower.xml</Actor> 17 17 </VisualActor> 18 18 <WallPiece> 19 <Length> 9.5</Length>19 <Length>10</Length> 20 20 </WallPiece> 21 21 </Entity> -
binaries/data/mods/public/simulation/templates/structures/rome_wallset_siege.xml
13 13 <Templates> 14 14 <Tower>structures/rome_siege_wall_tower</Tower> 15 15 <Gate>structures/rome_siege_wall_gate</Gate> 16 <Fort>structures/rome_army_camp</Fort> 16 17 <WallLong>structures/rome_siege_wall_long</WallLong> 17 18 <WallMedium>structures/rome_siege_wall_medium</WallMedium> 18 19 <WallShort>structures/rome_siege_wall_short</WallShort> -
binaries/data/mods/public/simulation/templates/structures/sele_fortress.xml
34 34 <VisualActor> 35 35 <Actor>structures/seleucids/fortress.xml</Actor> 36 36 </VisualActor> 37 <WallPiece> 38 <Length>23</Length> 39 <Indent>7.8</Indent> 40 </WallPiece> 37 41 </Entity> -
binaries/data/mods/public/simulation/templates/structures/sele_wall_gate.xml
20 20 <Actor>structures/hellenes/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>3 8.0</Length>23 <Length>35.4</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/sele_wall_long.xml
17 17 <Actor>structures/hellenes/wall_long.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>3 7.0</Length>20 <Length>36.2</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/sele_wall_medium.xml
17 17 <Actor>structures/hellenes/wall_medium.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>24. 0</Length>20 <Length>24.2</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/sele_wall_short.xml
17 17 <Actor>structures/hellenes/wall_short.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>1 3.0</Length>20 <Length>12.3</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/sele_wall_tower.xml
16 16 <Actor>structures/hellenes/wall_tower.xml</Actor> 17 17 </VisualActor> 18 18 <WallPiece> 19 <Length>7. 5</Length>19 <Length>7.1</Length> 20 20 </WallPiece> 21 </Entity> 22 No newline at end of file 21 </Entity> -
binaries/data/mods/public/simulation/templates/structures/spart_fortress.xml
25 25 <VisualActor> 26 26 <Actor>structures/spartans/fortress_up.xml</Actor> 27 27 </VisualActor> 28 <WallPiece> 29 <Length>24.0</Length> 30 <Indent>7.6</Indent> 31 </WallPiece> 28 32 </Entity> -
binaries/data/mods/public/simulation/templates/structures/spart_wall_gate.xml
20 20 <Actor>structures/hellenes/wall_gate.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>3 8.0</Length>23 <Length>35.4</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/spart_wall_long.xml
17 17 <Actor>structures/hellenes/wall_long.xml</Actor> 18 18 </VisualActor> 19 19 <WallPiece> 20 <Length>3 7.0</Length>20 <Length>36.2</Length> 21 21 </WallPiece> 22 22 </Entity> -
binaries/data/mods/public/simulation/templates/structures/spart_wall_medium.xml
20 20 <Actor>structures/hellenes/wall_medium.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>24. 0</Length>23 <Length>24.2</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/spart_wall_short.xml
20 20 <Actor>structures/hellenes/wall_short.xml</Actor> 21 21 </VisualActor> 22 22 <WallPiece> 23 <Length>1 3.0</Length>23 <Length>12.3</Length> 24 24 </WallPiece> 25 25 </Entity> -
binaries/data/mods/public/simulation/templates/structures/spart_wall_tower.xml
16 16 <Actor>structures/hellenes/wall_tower.xml</Actor> 17 17 </VisualActor> 18 18 <WallPiece> 19 <Length>7. 5</Length>19 <Length>7.1</Length> 20 20 </WallPiece> 21 </Entity> 22 No newline at end of file 21 </Entity>