Ticket #3455: _kalis_maps_v1.patch
File _kalis_maps_v1.patch, 104.4 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/maps/random/ambush.js
1 RMS.LoadLibrary("rmgen"); 2 3 InitMap(); 4 5 randomizeBiome(); 6 initMapSettings(); 7 initTileClasses(); 8 9 resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 2); 10 RMS.SetProgress(10); 11 12 var pos = randomStartingPositionPattern(); 13 addBases(pos.setup, pos.distance, pos.separation); 14 RMS.SetProgress(20); 15 16 addElements([ 17 { 18 "func": addBluffs, 19 "avoid": [ 20 g_TileClasses.bluff, 12, 21 g_TileClasses.hill, 5, 22 g_TileClasses.player, 35 23 ], 24 "sizes": ["normal", "big", "huge"], 25 "mixes": ["same"], 26 "amounts": ["tons"] 27 }, 28 { 29 "func": addHills, 30 "avoid": [ 31 g_TileClasses.bluff, 5, 32 g_TileClasses.hill, 15, 33 g_TileClasses.player, 20 34 ], 35 "sizes": ["normal", "big"], 36 "mixes": ["normal"], 37 "amounts": ["tons"] 38 } 39 ]); 40 RMS.SetProgress(30); 41 42 addElements([ 43 { 44 "func": addLayeredPatches, 45 "avoid": [ 46 g_TileClasses.bluff, 2, 47 g_TileClasses.dirt, 5, 48 g_TileClasses.forest, 2, 49 g_TileClasses.mountain, 2, 50 g_TileClasses.player, 12, 51 g_TileClasses.water, 3 52 ], 53 "sizes": ["normal"], 54 "mixes": ["normal"], 55 "amounts": ["normal"] 56 }, 57 { 58 "func": addDecoration, 59 "avoid": [ 60 g_TileClasses.bluff, 2, 61 g_TileClasses.forest, 2, 62 g_TileClasses.mountain, 2, 63 g_TileClasses.player, 12, 64 g_TileClasses.water, 3 65 ], 66 "sizes": ["normal"], 67 "mixes": ["normal"], 68 "amounts": ["normal"] 69 } 70 ]); 71 RMS.SetProgress(50); 72 73 addElements(shuffleArray([ 74 { 75 "func": addMetal, 76 "avoid": [ 77 g_TileClasses.berries, 5, 78 g_TileClasses.forest, 3, 79 g_TileClasses.mountain, 2, 80 g_TileClasses.player, 30, 81 g_TileClasses.rock, 10, 82 g_TileClasses.metal, 20, 83 g_TileClasses.water, 3 84 ], 85 "stay": [g_TileClasses.bluff, 5], 86 "sizes": ["normal"], 87 "mixes": ["same"], 88 "amounts": ["tons"] 89 }, 90 { 91 "func": addStone, 92 "avoid": [ 93 g_TileClasses.berries, 5, 94 g_TileClasses.forest, 3, 95 g_TileClasses.mountain, 2, 96 g_TileClasses.player, 30, 97 g_TileClasses.rock, 20, 98 g_TileClasses.metal, 10, 99 g_TileClasses.water, 3 100 ], 101 "stay": [g_TileClasses.bluff, 5], 102 "sizes": ["normal"], 103 "mixes": ["same"], 104 "amounts": ["tons"] 105 }, 106 { 107 "func": addForests, 108 "avoid": [ 109 g_TileClasses.metal, 3, 110 g_TileClasses.mountain, 5, 111 g_TileClasses.player, 20, 112 g_TileClasses.rock, 3, 113 g_TileClasses.water, 2 114 ], 115 "stay": [g_TileClasses.bluff, 5], 116 "sizes": ["big", "huge"], 117 "mixes": ["normal"], 118 "amounts": ["tons"] 119 } 120 ])); 121 RMS.SetProgress(70); 122 123 addElements(shuffleArray([ 124 { 125 "func": addBerries, 126 "avoid": [ 127 g_TileClasses.bluff, 5, g_TileClasses.forest, 5, 128 g_TileClasses.metal, 10, 129 g_TileClasses.mountain, 2, 130 g_TileClasses.player, 20, 131 g_TileClasses.rock, 10, 132 g_TileClasses.water, 3 133 ], 134 "sizes": ["tiny"], 135 "mixes": ["same"], 136 "amounts": ["scarce"] 137 }, 138 { 139 "func": addAnimals, 140 "avoid": [ 141 g_TileClasses.bluff, 5, 142 g_TileClasses.forest, 2, 143 g_TileClasses.metal, 2, 144 g_TileClasses.mountain, 1, 145 g_TileClasses.player, 20, 146 g_TileClasses.rock, 2, 147 g_TileClasses.water, 3 148 ], 149 "sizes": ["tiny"], 150 "mixes": ["same"], 151 "amounts": ["scarce"] 152 }, 153 { 154 "func": addStragglerTrees, 155 "avoid": [ 156 g_TileClasses.berries, 5, 157 g_TileClasses.bluff, 5, 158 g_TileClasses.forest, 7, 159 g_TileClasses.metal, 2, 160 g_TileClasses.mountain, 1, 161 g_TileClasses.player, 12, 162 g_TileClasses.rock, 2, 163 g_TileClasses.water, 5 164 ], 165 "sizes": ["tiny"], 166 "mixes": ["same"], 167 "amounts": ["many"] 168 } 169 ])); 170 RMS.SetProgress(90); 171 172 ExportMap(); -
binaries/data/mods/public/maps/random/ambush.json
1 { 2 "settings" : { 3 "Name" : "Ambush", 4 "Script" : "ambush.js", 5 "Description" : "High bluffs overlook the terrain below. Bountiful resources await on the cliffs, but beware of enemies planning an ambush.", 6 "BaseTerrain" : ["medit_sea_depths"], 7 "BaseHeight" : 2, 8 "Preview" : "ambush.png", 9 "CircularMap" : true 10 } 11 } -
binaries/data/mods/public/maps/random/empire.js
1 RMS.LoadLibrary("rmgen"); 2 InitMap(); 3 4 randomizeBiome(); 5 initMapSettings(); 6 initTileClasses(); 7 8 resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, randInt(5)); 9 RMS.SetProgress(10); 10 11 addBases("stronghold", 0.37, 0.04); 12 RMS.SetProgress(20); 13 14 // Change the starting angle and add the players again 15 var rotation = PI; 16 17 if (g_MapInfo.teams.length == 2) 18 rotation = PI / 2; 19 20 if (g_MapInfo.teams.length == 4) 21 rotation = PI + PI / 4; 22 23 g_MapInfo.startAngle = g_MapInfo.startAngle + rotation; 24 25 addBases("stronghold", 0.15, 0.04); 26 RMS.SetProgress(40); 27 28 addElements(shuffleArray([ 29 { 30 "func": addHills, 31 "avoid": [ 32 g_TileClasses.bluff, 5, 33 g_TileClasses.hill, 15, 34 g_TileClasses.mountain, 2, 35 g_TileClasses.plateau, 5, 36 g_TileClasses.player, 20, 37 g_TileClasses.valley, 2, 38 g_TileClasses.water, 2 39 ], 40 "sizes": g_AllSizes, 41 "mixes": g_AllMixes, 42 "amounts": ["tons"] 43 }, 44 { 45 "func": addMountains, 46 "avoid": [ 47 g_TileClasses.bluff, 20, 48 g_TileClasses.mountain, 25, 49 g_TileClasses.plateau, 20, 50 g_TileClasses.player, 20, 51 g_TileClasses.valley, 10, 52 g_TileClasses.water, 15 53 ], 54 "sizes": ["huge"], 55 "mixes": ["same", "similar"], 56 "amounts": ["tons"] 57 }, 58 { 59 "func": addPlateaus, 60 "avoid": [ 61 g_TileClasses.bluff, 20, 62 g_TileClasses.mountain, 25, 63 g_TileClasses.plateau, 20, 64 g_TileClasses.player, 40, 65 g_TileClasses.valley, 10, 66 g_TileClasses.water, 15 67 ], 68 "sizes": ["huge"], 69 "mixes": ["same", "similar"], 70 "amounts": ["tons"] 71 } 72 ])); 73 RMS.SetProgress(50); 74 75 addElements([ 76 { 77 "func": addLayeredPatches, 78 "avoid": [ 79 g_TileClasses.bluff, 2, 80 g_TileClasses.dirt, 5, 81 g_TileClasses.forest, 2, 82 g_TileClasses.mountain, 2, 83 g_TileClasses.plateau, 2, 84 g_TileClasses.player, 12, 85 g_TileClasses.water, 3 86 ], 87 "sizes": ["normal"], 88 "mixes": ["normal"], 89 "amounts": ["normal"] 90 }, 91 { 92 "func": addDecoration, 93 "avoid": [ 94 g_TileClasses.bluff, 2, 95 g_TileClasses.forest, 2, 96 g_TileClasses.mountain, 2, 97 g_TileClasses.plateau, 2, 98 g_TileClasses.player, 12, 99 g_TileClasses.water, 3 100 ], 101 "sizes": ["normal"], 102 "mixes": ["normal"], 103 "amounts": ["normal"] 104 } 105 ]); 106 RMS.SetProgress(60); 107 108 addElements(shuffleArray([ 109 { 110 "func": addMetal, 111 "avoid": [ 112 g_TileClasses.berries, 5, 113 g_TileClasses.bluff, 5, 114 g_TileClasses.forest, 3, 115 g_TileClasses.mountain, 2, 116 g_TileClasses.player, 30, 117 g_TileClasses.rock, 10, 118 g_TileClasses.metal, 20, 119 g_TileClasses.plateau, 2, 120 g_TileClasses.water, 3 121 ], 122 "sizes": ["normal"], 123 "mixes": ["same"], 124 "amounts": g_AllAmounts 125 }, 126 { 127 "func": addStone, 128 "avoid": [g_TileClasses.berries, 5, 129 g_TileClasses.bluff, 5, 130 g_TileClasses.forest, 3, 131 g_TileClasses.mountain, 2, 132 g_TileClasses.player, 30, 133 g_TileClasses.rock, 20, 134 g_TileClasses.metal, 10, 135 g_TileClasses.plateau, 2, 136 g_TileClasses.water, 3 137 ], 138 "sizes": ["normal"], 139 "mixes": ["same"], 140 "amounts": g_AllAmounts 141 }, 142 { 143 "func": addForests, 144 "avoid": [ 145 g_TileClasses.berries, 5, 146 g_TileClasses.bluff, 5, 147 g_TileClasses.forest, 18, 148 g_TileClasses.metal, 3, 149 g_TileClasses.mountain, 5, 150 g_TileClasses.plateau, 2, 151 g_TileClasses.player, 20, 152 g_TileClasses.rock, 3, 153 g_TileClasses.water, 2 154 ], 155 "sizes": g_AllSizes, 156 "mixes": g_AllMixes, 157 "amounts": ["few", "normal", "many", "tons"] 158 } 159 ])); 160 RMS.SetProgress(80); 161 162 addElements(shuffleArray([ 163 { 164 "func": addBerries, 165 "avoid": [ 166 g_TileClasses.berries, 30, 167 g_TileClasses.bluff, 5, 168 g_TileClasses.forest, 5, 169 g_TileClasses.metal, 10, 170 g_TileClasses.mountain, 2, 171 g_TileClasses.plateau, 2, 172 g_TileClasses.player, 20, 173 g_TileClasses.rock, 10, 174 g_TileClasses.water, 3 175 ], 176 "sizes": g_AllSizes, 177 "mixes": g_AllMixes, 178 "amounts": g_AllAmounts 179 }, 180 { 181 "func": addAnimals, 182 "avoid": [ 183 g_TileClasses.animals, 20, 184 g_TileClasses.bluff, 5, 185 g_TileClasses.forest, 2, 186 g_TileClasses.metal, 2, 187 g_TileClasses.mountain, 1, 188 g_TileClasses.plateau, 2, 189 g_TileClasses.player, 20, 190 g_TileClasses.rock, 2, 191 g_TileClasses.water, 3 192 ], 193 "sizes": g_AllSizes, 194 "mixes": g_AllMixes, 195 "amounts": g_AllAmounts 196 }, 197 { 198 "func": addStragglerTrees, 199 "avoid": [ 200 g_TileClasses.berries, 5, 201 g_TileClasses.bluff, 5, 202 g_TileClasses.forest, 7, 203 g_TileClasses.metal, 2, 204 g_TileClasses.mountain, 1, 205 g_TileClasses.plateau, 2, 206 g_TileClasses.player, 12, 207 g_TileClasses.rock, 2, 208 g_TileClasses.water, 5 209 ], 210 "sizes": g_AllSizes, 211 "mixes": g_AllMixes, 212 "amounts": g_AllAmounts 213 } 214 ])); 215 RMS.SetProgress(90); 216 217 ExportMap(); -
binaries/data/mods/public/maps/random/empire.json
1 { 2 "settings" : { 3 "Name" : "Empire", 4 "Script" : "empire.js", 5 "Description" : "A neighboring province has pledged alegiance to your rule. It's up to you to command them to victory.", 6 "BaseTerrain" : ["medit_sea_depths"], 7 "BaseHeight" : 2, 8 "Keywords": ["demo"], 9 "Preview" : "empire.png", 10 "CircularMap" : true 11 } 12 } -
binaries/data/mods/public/maps/random/frontier.js
1 RMS.LoadLibrary("rmgen"); 2 InitMap(); 3 4 randomizeBiome(); 5 initMapSettings(); 6 initTileClasses(); 7 8 RMS.SetProgress(10); 9 10 // Pick a random elevation with a bias towards lower elevations 11 var randElevation = randInt(30); 12 if (randElevation < 25) 13 randElevation = 1 + randInt(4); 14 15 resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, randElevation); 16 RMS.SetProgress(20); 17 18 var pos = randomStartingPositionPattern(); 19 addBases(pos.setup, pos.distance, pos.separation); 20 RMS.SetProgress(40); 21 22 var features = [ 23 { 24 "func": addBluffs, 25 "avoid": [ 26 g_TileClasses.bluff, 20, 27 g_TileClasses.hill, 10, 28 g_TileClasses.mountain, 20, 29 g_TileClasses.plateau, 15, 30 g_TileClasses.player, 30, 31 g_TileClasses.valley, 5, 32 g_TileClasses.water, 7 33 ], 34 "sizes": g_AllSizes, 35 "mixes": g_AllMixes, 36 "amounts": g_AllAmounts 37 }, 38 { 39 "func": addHills, 40 "avoid": [ 41 g_TileClasses.bluff, 5, 42 g_TileClasses.hill, 15, 43 g_TileClasses.mountain, 2, 44 g_TileClasses.plateau, 15, 45 g_TileClasses.player, 20, 46 g_TileClasses.valley, 2, 47 g_TileClasses.water, 2 48 ], 49 "sizes": g_AllSizes, 50 "mixes": g_AllMixes, 51 "amounts": g_AllAmounts 52 }, 53 { 54 "func": addMountains, 55 "avoid": [ 56 g_TileClasses.bluff, 20, 57 g_TileClasses.mountain, 25, 58 g_TileClasses.plateau, 15, 59 g_TileClasses.player, 20, 60 g_TileClasses.valley, 10, 61 g_TileClasses.water, 15 62 ], 63 "sizes": g_AllSizes, 64 "mixes": g_AllMixes, 65 "amounts": g_AllAmounts 66 }, 67 { 68 "func": addPlateaus, 69 "avoid": [ 70 g_TileClasses.bluff, 20, 71 g_TileClasses.mountain, 25, 72 g_TileClasses.plateau, 25, 73 g_TileClasses.plateau, 25, 74 g_TileClasses.player, 40, 75 g_TileClasses.valley, 10, 76 g_TileClasses.water, 15 77 ], 78 "sizes": g_AllSizes, 79 "mixes": g_AllMixes, 80 "amounts": g_AllAmounts 81 } 82 ]; 83 84 if (randElevation < 4) 85 features = features.push( 86 { 87 "func": addLakes, 88 "avoid": [ 89 g_TileClasses.bluff, 7, 90 g_TileClasses.hill, 2, 91 g_TileClasses.mountain, 15, 92 g_TileClasses.plateau, 10, 93 g_TileClasses.player, 20, 94 g_TileClasses.valley, 10, 95 g_TileClasses.water, 25 96 ], 97 "sizes": g_AllSizes, 98 "mixes": g_AllMixes, 99 "amounts": g_AllAmounts 100 } 101 ); 102 103 if (randElevation > 20) 104 features = features.push( 105 { 106 "func": addValleys, 107 "avoid": [ 108 g_TileClasses.bluff, 5, 109 g_TileClasses.hill, 5, 110 g_TileClasses.mountain, 25, 111 g_TileClasses.plateau, 20, 112 g_TileClasses.player, 40, 113 g_TileClasses.valley, 15, 114 g_TileClasses.water, 10 115 ], 116 "sizes": g_AllSizes, 117 "mixes": g_AllMixes, 118 "amounts": g_AllAmounts 119 } 120 ); 121 122 addElements(shuffleArray(features)); 123 RMS.SetProgress(50); 124 125 addElements([ 126 { 127 "func": addLayeredPatches, 128 "avoid": [ 129 g_TileClasses.bluff, 2, 130 g_TileClasses.dirt, 5, 131 g_TileClasses.forest, 2, 132 g_TileClasses.mountain, 2, 133 g_TileClasses.plateau, 2, 134 g_TileClasses.player, 12, 135 g_TileClasses.water, 3 136 ], 137 "sizes": ["normal"], 138 "mixes": ["normal"], 139 "amounts": ["normal"] 140 }, 141 { 142 "func": addDecoration, 143 "avoid": [ 144 g_TileClasses.bluff, 2, 145 g_TileClasses.forest, 2, 146 g_TileClasses.mountain, 2, 147 g_TileClasses.plateau, 2, 148 g_TileClasses.player, 12, 149 g_TileClasses.water, 3 150 ], 151 "sizes": ["normal"], 152 "mixes": ["normal"], 153 "amounts": ["normal"] 154 } 155 ]); 156 RMS.SetProgress(60); 157 158 addElements(shuffleArray([ 159 { 160 "func": addMetal, 161 "avoid": [ 162 g_TileClasses.berries, 5, 163 g_TileClasses.bluff, 5, 164 g_TileClasses.forest, 3, 165 g_TileClasses.mountain, 2, 166 g_TileClasses.plateau, 2, 167 g_TileClasses.player, 30, 168 g_TileClasses.rock, 10, 169 g_TileClasses.metal, 20, 170 g_TileClasses.water, 3 171 ], 172 "sizes": ["normal"], 173 "mixes": ["same"], 174 "amounts": g_AllAmounts 175 }, 176 { 177 "func": addStone, 178 "avoid": [g_TileClasses.berries, 5, 179 g_TileClasses.bluff, 5, 180 g_TileClasses.forest, 3, 181 g_TileClasses.mountain, 2, 182 g_TileClasses.plateau, 2, 183 g_TileClasses.player, 30, 184 g_TileClasses.rock, 20, 185 g_TileClasses.metal, 10, 186 g_TileClasses.water, 3 187 ], 188 "sizes": ["normal"], 189 "mixes": ["same"], 190 "amounts": g_AllAmounts 191 }, 192 { 193 "func": addForests, 194 "avoid": [ 195 g_TileClasses.berries, 5, 196 g_TileClasses.bluff, 5, 197 g_TileClasses.forest, 18, 198 g_TileClasses.metal, 3, 199 g_TileClasses.mountain, 5, 200 g_TileClasses.plateau, 5, 201 g_TileClasses.player, 20, 202 g_TileClasses.rock, 3, 203 g_TileClasses.water, 2 204 ], 205 "sizes": g_AllSizes, 206 "mixes": g_AllMixes, 207 "amounts": ["few", "normal", "many", "tons"] 208 } 209 ])); 210 RMS.SetProgress(70); 211 212 addElements(shuffleArray([ 213 { 214 "func": addBerries, 215 "avoid": [ 216 g_TileClasses.berries, 30, 217 g_TileClasses.bluff, 5, 218 g_TileClasses.forest, 5, 219 g_TileClasses.metal, 10, 220 g_TileClasses.mountain, 2, 221 g_TileClasses.plateau, 2, 222 g_TileClasses.player, 20, 223 g_TileClasses.rock, 10, 224 g_TileClasses.water, 3 225 ], 226 "sizes": g_AllSizes, 227 "mixes": g_AllMixes, 228 "amounts": g_AllAmounts 229 }, 230 { 231 "func": addAnimals, 232 "avoid": [ 233 g_TileClasses.animals, 20, 234 g_TileClasses.bluff, 5, 235 g_TileClasses.forest, 2, 236 g_TileClasses.metal, 2, 237 g_TileClasses.mountain, 1, 238 g_TileClasses.plateau, 2, 239 g_TileClasses.player, 20, 240 g_TileClasses.rock, 2, 241 g_TileClasses.water, 3 242 ], 243 "sizes": g_AllSizes, 244 "mixes": g_AllMixes, 245 "amounts": g_AllAmounts 246 }, 247 { 248 "func": addStragglerTrees, 249 "avoid": [ 250 g_TileClasses.berries, 5, 251 g_TileClasses.bluff, 5, 252 g_TileClasses.forest, 7, 253 g_TileClasses.metal, 2, 254 g_TileClasses.mountain, 1, 255 g_TileClasses.plateau, 2, 256 g_TileClasses.player, 12, 257 g_TileClasses.rock, 2, 258 g_TileClasses.water, 5 259 ], 260 "sizes": g_AllSizes, 261 "mixes": g_AllMixes, 262 "amounts": g_AllAmounts 263 } 264 ])); 265 RMS.SetProgress(90); 266 267 ExportMap(); -
binaries/data/mods/public/maps/random/frontier.json
1 { 2 "settings" : { 3 "Name" : "Frontier", 4 "Script" : "frontier.js", 5 "Description" : "A wild, unknown landscape awaits rival explorers.", 6 "BaseTerrain" : ["medit_sea_depths"], 7 "Preview" : "frontier.png", 8 "BaseHeight" : 2, 9 "CircularMap" : true 10 } 11 } -
binaries/data/mods/public/maps/random/harbor.js
1 RMS.LoadLibrary("rmgen"); 2 3 InitMap(); 4 5 randomizeBiome(); 6 initMapSettings(); 7 initTileClasses(); 8 9 resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 2); 10 RMS.SetProgress(10); 11 12 var players = addBases("radial", 0.38); 13 RMS.SetProgress(20); 14 15 addCenterLake(); 16 RMS.SetProgress(30); 17 18 if (g_MapInfo.mapSize >= 192) 19 { 20 addHarbors(players); 21 RMS.SetProgress(40); 22 } 23 24 addSpines(); 25 RMS.SetProgress(50); 26 27 addElements(shuffleArray([ 28 { 29 "func": addHills, 30 "avoid": [ 31 g_TileClasses.bluff, 5, 32 g_TileClasses.hill, 15, 33 g_TileClasses.mountain, 2, 34 g_TileClasses.plateau, 5, 35 g_TileClasses.player, 20, 36 g_TileClasses.spine, 5, 37 g_TileClasses.valley, 2, 38 g_TileClasses.water, 2 39 ], 40 "sizes": ["tiny", "small"], 41 "mixes": g_AllMixes, 42 "amounts": g_AllAmounts 43 }, 44 { 45 "func": addMountains, 46 "avoid": [ 47 g_TileClasses.bluff, 20, 48 g_TileClasses.mountain, 25, 49 g_TileClasses.plateau, 20, 50 g_TileClasses.player, 20, 51 g_TileClasses.spine, 20, 52 g_TileClasses.valley, 10, 53 g_TileClasses.water, 15 54 ], 55 "sizes": ["small"], 56 "mixes": g_AllMixes, 57 "amounts": g_AllAmounts 58 }, 59 { 60 "func": addPlateaus, 61 "avoid": [ 62 g_TileClasses.bluff, 20, 63 g_TileClasses.mountain, 25, 64 g_TileClasses.plateau, 20, 65 g_TileClasses.player, 40, 66 g_TileClasses.spine, 20, 67 g_TileClasses.valley, 10, 68 g_TileClasses.water, 15 69 ], 70 "sizes": ["small"], 71 "mixes": g_AllMixes, 72 "amounts": g_AllAmounts 73 } 74 ])); 75 RMS.SetProgress(60); 76 77 addElements([ 78 { 79 "func": addLayeredPatches, 80 "avoid": [ 81 g_TileClasses.bluff, 2, 82 g_TileClasses.dirt, 5, 83 g_TileClasses.forest, 2, 84 g_TileClasses.mountain, 2, 85 g_TileClasses.plateau, 2, 86 g_TileClasses.player, 12, 87 g_TileClasses.spine, 5, 88 g_TileClasses.water, 3 89 ], 90 "sizes": ["normal"], 91 "mixes": ["normal"], 92 "amounts": ["normal"] 93 }, 94 { 95 "func": addDecoration, 96 "avoid": [ 97 g_TileClasses.bluff, 2, 98 g_TileClasses.forest, 2, 99 g_TileClasses.mountain, 2, 100 g_TileClasses.plateau, 2, 101 g_TileClasses.player, 12, 102 g_TileClasses.spine, 5, 103 g_TileClasses.water, 3 104 ], 105 "sizes": ["normal"], 106 "mixes": ["normal"], 107 "amounts": ["normal"] 108 } 109 ]); 110 RMS.SetProgress(70); 111 112 addElements(shuffleArray([ 113 { 114 "func": addBerries, 115 "avoid": [ 116 g_TileClasses.berries, 30, 117 g_TileClasses.bluff, 5, 118 g_TileClasses.forest, 5, 119 g_TileClasses.metal, 10, 120 g_TileClasses.mountain, 2, 121 g_TileClasses.plateau, 2, 122 g_TileClasses.player, 20, 123 g_TileClasses.rock, 10, 124 g_TileClasses.spine, 2, 125 g_TileClasses.water, 3 126 ], 127 "sizes": g_AllSizes, 128 "mixes": g_AllMixes, 129 "amounts": g_AllAmounts 130 }, 131 { 132 "func": addAnimals, 133 "avoid": [ 134 g_TileClasses.animals, 20, 135 g_TileClasses.bluff, 5, 136 g_TileClasses.forest, 2, 137 g_TileClasses.metal, 2, 138 g_TileClasses.mountain, 1, 139 g_TileClasses.plateau, 2, 140 g_TileClasses.player, 20, 141 g_TileClasses.rock, 2, 142 g_TileClasses.spine, 2, 143 g_TileClasses.water, 3 144 ], 145 "sizes": g_AllSizes, 146 "mixes": g_AllMixes, 147 "amounts": g_AllAmounts 148 }, 149 { 150 "func": addStragglerTrees, 151 "avoid": [ 152 g_TileClasses.berries, 5, 153 g_TileClasses.bluff, 5, 154 g_TileClasses.forest, 7, 155 g_TileClasses.metal, 2, 156 g_TileClasses.mountain, 1, 157 g_TileClasses.plateau, 2, 158 g_TileClasses.player, 12, 159 g_TileClasses.rock, 2, 160 g_TileClasses.spine, 2, 161 g_TileClasses.water, 5 162 ], 163 "sizes": g_AllSizes, 164 "mixes": g_AllMixes, 165 "amounts": g_AllAmounts 166 } 167 ])); 168 RMS.SetProgress(80); 169 170 addElements(shuffleArray([ 171 { 172 "func": addBerries, 173 "avoid": [ 174 g_TileClasses.berries, 30, 175 g_TileClasses.bluff, 5, 176 g_TileClasses.forest, 5, 177 g_TileClasses.metal, 10, 178 g_TileClasses.mountain, 2, 179 g_TileClasses.player, 20, 180 g_TileClasses.rock, 10, 181 g_TileClasses.spine, 2, 182 g_TileClasses.water, 3 183 ], 184 "sizes": g_AllSizes, 185 "mixes": g_AllMixes, 186 "amounts": g_AllAmounts 187 }, 188 { 189 "func": addAnimals, 190 "avoid": [ 191 g_TileClasses.animals, 20, 192 g_TileClasses.bluff, 5, 193 g_TileClasses.forest, 0, 194 g_TileClasses.mountain, 1, 195 g_TileClasses.player, 20, 196 g_TileClasses.spine, 2, 197 g_TileClasses.water, 3 198 ], 199 "sizes": g_AllSizes, 200 "mixes": g_AllMixes, 201 "amounts": g_AllAmounts 202 }, 203 { 204 "func": addStragglerTrees, 205 "avoid": [ 206 g_TileClasses.berries, 5, 207 g_TileClasses.bluff, 5, 208 g_TileClasses.forest, 7, 209 g_TileClasses.metal, 1, 210 g_TileClasses.mountain, 1, 211 g_TileClasses.player, 12, 212 g_TileClasses.rock, 1, 213 g_TileClasses.spine, 2, 214 g_TileClasses.water, 5 215 ], 216 "sizes": g_AllSizes, 217 "mixes": g_AllMixes, 218 "amounts": ["normal", "many", "tons"] 219 } 220 ])); 221 RMS.SetProgress(90); 222 223 ExportMap(); 224 225 function addCenterLake() 226 { 227 var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); 228 229 var placer = new ChainPlacer(2, Math.floor(scaleByMapSize(2, 12)), Math.floor(scaleByMapSize(35, 160)), 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap, 0, [floor(g_MapInfo.mapSize * 0.17 * lSize)]); 230 var terrainPainter = new LayeredPainter([g_Terrains.shore, g_Terrains.water, g_Terrains.water], [1, 100]); 231 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -18, 10); 232 233 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.water)], avoidClasses(g_TileClasses.player, 20)); 234 235 var fDist = 50; 236 if (g_MapInfo.mapSize <= 192) 237 fDist = 20; 238 239 // create a bunch of fish 240 var group = new SimpleGroup([new SimpleObject(g_Gaia.fish, 20, 30, 0, fDist)], true, g_TileClasses.baseResource, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap); 241 createObjectGroup(group, 0, [avoidClasses(g_TileClasses.player, 5, g_TileClasses.hill, 3, g_TileClasses.mountain, 3), stayClasses(g_TileClasses.water, 5)]); 242 } 243 244 function addHarbors(players) 245 { 246 for (var i = 0; i < players.length; ++i) 247 { 248 var ix = round(fractionToTiles(players[i].x)); 249 var iz = round(fractionToTiles(players[i].z)); 250 var playerDistX = g_MapInfo.centerOfMap - ix; 251 var playerDistZ = g_MapInfo.centerOfMap - iz; 252 var offsetX = round(playerDistX / 2.5); 253 var offsetZ = round(playerDistZ / 2.5); 254 255 var placer = new ClumpPlacer(scaleByMapSize(1200, 1200), 0.5, 0.5, 1, ix + offsetX, iz + offsetZ); 256 var terrainPainter = new LayeredPainter([g_Terrains.shore, g_Terrains.water], [2]); 257 var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -11, 3); 258 259 createArea( 260 placer, 261 [ 262 terrainPainter, 263 elevationPainter, 264 paintClass(g_TileClasses.water) 265 ], 266 avoidClasses( 267 g_TileClasses.player, 15, 268 g_TileClasses.hill, 1 269 ) 270 ); 271 272 // create fish in harbor 273 var group = new SimpleGroup( 274 [new SimpleObject(g_Gaia.fish, 6, 6, 1, 20)], 275 true, g_TileClasses.baseResource, ix + offsetX, iz + offsetZ 276 ); 277 278 createObjectGroup(group, 0, [ 279 avoidClasses( 280 g_TileClasses.hill, 3, 281 g_TileClasses.mountain, 3 282 ), 283 stayClasses(g_TileClasses.water, 5) 284 ]); 285 } 286 } 287 288 function addSpines() 289 { 290 var spineTile = g_Terrains.dirt; 291 var elevation = 35; 292 293 if (g_MapInfo.biome == 2) 294 spineTile = g_Terrains.tier1Terrain; 295 296 if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6) 297 spineTile = g_Terrains.tier2Terrain; 298 299 if (g_MapInfo.biome == 8) 300 spineTile = g_Terrains.tier4Terrain; 301 302 var split = 1; 303 if (g_MapInfo.numPlayers <= 3 || (g_MapInfo.mapSize >= 320 && g_MapInfo.numPlayers <= 4)) 304 split = 2; 305 306 for (var i = 0; i < g_MapInfo.numPlayers * split; ++i) 307 { 308 var tang = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / (g_MapInfo.numPlayers * split); 309 310 var fx = fractionToTiles(0.5); 311 var fz = fractionToTiles(0.5); 312 var ix = round(fx); 313 var iz = round(fz); 314 315 var mStartCo = 0.12; 316 var mStopCo = 0.40; 317 var mSize = 0.5; 318 var mWaviness = 0.6; 319 var mOffset = 0.4; 320 var mTaper = -1.4; 321 322 // make small mountain dividers if we're on a small map 323 if (g_MapInfo.mapSize <= 192) 324 { 325 mSize = 0.02; 326 mTaper = -0.1; 327 elevation = 20; 328 } 329 330 var placer = new PathPlacer(fractionToTiles(0.5 + mStartCo * cos(tang)), fractionToTiles(0.5 + mStartCo * sin(tang)), fractionToTiles(0.5 + mStopCo * cos(tang)), fractionToTiles(0.5 + mStopCo * sin(tang)), scaleByMapSize(14, mSize), mWaviness, 0.1, mOffset, mTaper); 331 var terrainPainter = new LayeredPainter([g_Terrains.cliff, spineTile], [3]); 332 var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, elevation, 3); 333 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.spine)], avoidClasses(g_TileClasses.player, 5)); 334 } 335 336 addElements([ 337 { 338 "func": addDecoration, 339 "avoid": [ 340 g_TileClasses.bluff, 2, 341 g_TileClasses.forest, 2, 342 g_TileClasses.mountain, 2, 343 g_TileClasses.player, 12, 344 g_TileClasses.water, 3 345 ], 346 "stay": [g_TileClasses.spine, 5], 347 "sizes": ["normal"], 348 "mixes": ["normal"], 349 "amounts": ["normal"] 350 } 351 ]); 352 353 addElements([ 354 { 355 "func": addProps, 356 "avoid": [ 357 g_TileClasses.forest, 2, 358 g_TileClasses.player, 2, 359 g_TileClasses.prop, 20, 360 g_TileClasses.water, 3 361 ], 362 "stay": [g_TileClasses.spine, 8], 363 "sizes": ["normal"], 364 "mixes": ["normal"], 365 "amounts": ["scarce"] 366 } 367 ]); 368 } -
binaries/data/mods/public/maps/random/harbor.json
1 { 2 "settings" : { 3 "Name" : "Harbor", 4 "Script" : "harbor.js", 5 "Description" : "Players start with some light fishing opportunities in the calm waters of a sheltered harbor. A large bounty of seafood lays beyond the protective cliffs in the deep ocean. Small passages at the base of the cliffs make for tight fighting and easy fortification. Will you fight your way through the narrow passageways or take to the sea?", 6 "BaseTerrain" : ["medit_sea_depths"], 7 "BaseHeight" : 2, 8 "Preview" : "harbor.png", 9 "Keywords": ["naval"], 10 "CircularMap" : true 11 } 12 } -
binaries/data/mods/public/maps/random/hells_pass.js
1 RMS.LoadLibrary("rmgen"); 2 InitMap(); 3 4 randomizeBiome(); 5 initMapSettings(); 6 initTileClasses(); 7 8 resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1); 9 RMS.SetProgress(10); 10 11 addBases("line", 0.2, 0.08); 12 RMS.SetProgress(20); 13 14 placeBarriers(); 15 RMS.SetProgress(40); 16 17 addElements(shuffleArray([ 18 { 19 "func": addBluffs, 20 "avoid": [ 21 g_TileClasses.bluff, 20, 22 g_TileClasses.hill, 5, 23 g_TileClasses.mountain, 20, 24 g_TileClasses.plateau, 20, 25 g_TileClasses.player, 30, 26 g_TileClasses.spine, 15, 27 g_TileClasses.valley, 5, 28 g_TileClasses.water, 7 29 ], 30 "sizes": ["normal", "big"], 31 "mixes": ["varied"], 32 "amounts": ["few"] 33 }, 34 { 35 "func": addHills, 36 "avoid": [ 37 g_TileClasses.bluff, 5, 38 g_TileClasses.hill, 15, 39 g_TileClasses.mountain, 2, 40 g_TileClasses.plateau, 5, 41 g_TileClasses.player, 20, 42 g_TileClasses.spine, 15, 43 g_TileClasses.valley, 2, 44 g_TileClasses.water, 2 45 ], 46 "sizes": ["normal", "big"], 47 "mixes": ["varied"], 48 "amounts": ["few"] 49 }, 50 { 51 "func": addLakes, 52 "avoid": [ 53 g_TileClasses.bluff, 7, 54 g_TileClasses.hill, 2, 55 g_TileClasses.mountain, 15, 56 g_TileClasses.plateau, 10, 57 g_TileClasses.player, 20, 58 g_TileClasses.spine, 15, 59 g_TileClasses.valley, 10, 60 g_TileClasses.water, 25 61 ], 62 "sizes": ["big", "huge"], 63 "mixes": ["varied", "unique"], 64 "amounts": ["few"] 65 } 66 ])); 67 RMS.SetProgress(50); 68 69 addElements([ 70 { 71 "func": addLayeredPatches, 72 "avoid": [g_TileClasses.bluff, 2, 73 g_TileClasses.dirt, 5, 74 g_TileClasses.forest, 2, 75 g_TileClasses.mountain, 2, 76 g_TileClasses.plateau, 2, 77 g_TileClasses.player, 12, 78 g_TileClasses.spine, 5, 79 g_TileClasses.water, 3 80 ], 81 "sizes": ["normal"], 82 "mixes": ["normal"], 83 "amounts": ["normal"] 84 }, 85 { 86 "func": addDecoration, 87 "avoid": [g_TileClasses.bluff, 2, 88 g_TileClasses.forest, 2, 89 g_TileClasses.mountain, 2, 90 g_TileClasses.plateau, 2, 91 g_TileClasses.player, 12, 92 g_TileClasses.spine, 5, 93 g_TileClasses.water, 3 94 ], 95 "sizes": ["normal"], 96 "mixes": ["normal"], 97 "amounts": ["normal"] 98 } 99 ]); 100 RMS.SetProgress(60); 101 102 addElements(shuffleArray([ 103 { 104 "func": addMetal, 105 "avoid": [g_TileClasses.berries, 5, 106 g_TileClasses.bluff, 5, 107 g_TileClasses.forest, 3, 108 g_TileClasses.mountain, 2, 109 g_TileClasses.plateau, 2, 110 g_TileClasses.player, 30, 111 g_TileClasses.rock, 10, 112 g_TileClasses.metal, 20, 113 g_TileClasses.spine, 5, 114 g_TileClasses.water, 3 115 ], 116 "sizes": ["normal"], 117 "mixes": ["same"], 118 "amounts": g_AllAmounts 119 }, 120 { 121 "func": addStone, 122 "avoid": [ 123 g_TileClasses.berries, 5, 124 g_TileClasses.bluff, 5, 125 g_TileClasses.forest, 3, 126 g_TileClasses.mountain, 2, 127 g_TileClasses.plateau, 2, 128 g_TileClasses.player, 30, 129 g_TileClasses.rock, 20, 130 g_TileClasses.metal, 10, 131 g_TileClasses.spine, 5, 132 g_TileClasses.water, 3 133 ], 134 "sizes": ["normal"], 135 "mixes": ["same"], 136 "amounts": g_AllAmounts 137 }, 138 { 139 "func": addForests, 140 "avoid": [g_TileClasses.berries, 5, 141 g_TileClasses.bluff, 5, 142 g_TileClasses.forest, 18, 143 g_TileClasses.metal, 3, 144 g_TileClasses.mountain, 5, 145 g_TileClasses.plateau, 5, 146 g_TileClasses.player, 20, 147 g_TileClasses.rock, 3, 148 g_TileClasses.spine, 5, 149 g_TileClasses.water, 2 150 ], 151 "sizes": g_AllSizes, 152 "mixes": g_AllMixes, 153 "amounts": ["few", "normal", "many", "tons"] 154 } 155 ])); 156 RMS.SetProgress(80); 157 158 addElements(shuffleArray([ 159 { 160 "func": addBerries, 161 "avoid": [ 162 g_TileClasses.berries, 30, 163 g_TileClasses.bluff, 5, 164 g_TileClasses.forest, 5, 165 g_TileClasses.metal, 10, 166 g_TileClasses.mountain, 2, 167 g_TileClasses.plateau, 2, 168 g_TileClasses.player, 20, 169 g_TileClasses.rock, 10, 170 g_TileClasses.spine, 2, 171 g_TileClasses.water, 3 172 ], 173 "sizes": g_AllSizes, 174 "mixes": g_AllMixes, 175 "amounts": g_AllAmounts 176 }, 177 { 178 "func": addAnimals, 179 "avoid": [ 180 g_TileClasses.animals, 20, 181 g_TileClasses.bluff, 5, 182 g_TileClasses.forest, 2, 183 g_TileClasses.metal, 2, 184 g_TileClasses.mountain, 1, 185 g_TileClasses.plateau, 2, 186 g_TileClasses.player, 20, 187 g_TileClasses.rock, 2, 188 g_TileClasses.spine, 2, 189 g_TileClasses.water, 3 190 ], 191 "sizes": g_AllSizes, 192 "mixes": g_AllMixes, 193 "amounts": g_AllAmounts 194 }, 195 { 196 "func": addStragglerTrees, 197 "avoid": [ 198 g_TileClasses.berries, 5, 199 g_TileClasses.bluff, 5, 200 g_TileClasses.forest, 7, 201 g_TileClasses.metal, 2, 202 g_TileClasses.mountain, 1, 203 g_TileClasses.plateau, 2, 204 g_TileClasses.player, 12, 205 g_TileClasses.rock, 2, 206 g_TileClasses.spine, 2, 207 g_TileClasses.water, 5 208 ], 209 "sizes": g_AllSizes, 210 "mixes": g_AllMixes, 211 "amounts": g_AllAmounts 212 } 213 ])); 214 RMS.SetProgress(90); 215 216 ExportMap(); 217 218 // place the mountainous barriers between the teams 219 function placeBarriers() 220 { 221 var spineTerrain = g_Terrains.dirt; 222 223 if (g_MapInfo.biome == 2) 224 spineTerrain = g_Terrains.tier1Terrain; 225 226 if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6) 227 spineTerrain = g_Terrains.tier2Terrain; 228 229 if (g_MapInfo.biome == 8) 230 spineTerrain = g_Terrains.tier4Terrain; 231 232 // create mountain ranges 233 for (var i = 0; i < g_MapInfo.teams.length; ++i) 234 { 235 var tang = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.teams.length; 236 237 var fx = fractionToTiles(0.5); 238 var fz = fractionToTiles(0.5); 239 var ix = round(fx); 240 var iz = round(fz); 241 242 var mStartCo = 0.07; 243 var mStopCo = 0.42; 244 var mSize = 8; 245 var mWaviness = 0.6; 246 var mOffset = 0.5; 247 var mTaper = -1.5; 248 249 if (g_MapInfo.teams.length > 3 || g_MapInfo.mapSize <= 192) 250 { 251 mWaviness = 0.2; 252 mOffset = 0.2; 253 mTaper = -1; 254 } 255 256 if (g_MapInfo.teams.length >= 5) 257 { 258 mSize = 4; 259 mWaviness = 0.2; 260 mOffset = 0.2; 261 mTaper = -0.7; 262 } 263 264 // place barrier 265 var placer = new PathPlacer(fractionToTiles(0.5 + mStartCo * cos(tang)), fractionToTiles(0.5 + mStartCo * sin(tang)), fractionToTiles(0.5 + mStopCo * cos(tang)), fractionToTiles(0.5 + mStopCo * sin(tang)), scaleByMapSize(14, mSize), mWaviness, 0.1, mOffset, mTaper); 266 var terrainPainter = new LayeredPainter([g_Terrains.cliff, spineTerrain], [2]); 267 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 30, 2); 268 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.spine)], avoidClasses(g_TileClasses.player, 5, g_TileClasses.baseResource, 5)); 269 } 270 271 addElements([ 272 { 273 "func": addDecoration, 274 "avoid": [ 275 g_TileClasses.bluff, 2, 276 g_TileClasses.forest, 2, 277 g_TileClasses.mountain, 2, 278 g_TileClasses.player, 12, 279 g_TileClasses.water, 3 280 ], 281 "stay": [g_TileClasses.spine, 5], 282 "sizes": ["huge"], 283 "mixes": ["unique"], 284 "amounts": ["tons"] 285 } 286 ]); 287 288 addElements([ 289 { 290 "func": addProps, 291 "avoid": [ 292 g_TileClasses.forest, 2, 293 g_TileClasses.player, 2, 294 g_TileClasses.prop, 20, 295 g_TileClasses.water, 3 296 ], 297 "stay": [g_TileClasses.spine, 8], 298 "sizes": ["normal"], 299 "mixes": ["normal"], 300 "amounts": ["scarce"] 301 } 302 ]); 303 } -
binaries/data/mods/public/maps/random/hells_pass.json
1 { 2 "settings" : { 3 "Name" : "Hell's Pass", 4 "Script" : "hells_pass.js", 5 "Description" : "A narrow pass between steep mountains promotes tight, defensive combat. With bountiful resources far from the front-lines, teams may choose to support their exposed teammates financially, or retreat to more fertile, but less defensible ground.", 6 "BaseTerrain" : ["medit_sea_depths"], 7 "BaseHeight" : 1, 8 "Preview" : "hells_pass.png", 9 "CircularMap" : true 10 } 11 } -
binaries/data/mods/public/maps/random/lions_den.js
1 RMS.LoadLibrary("rmgen"); 2 InitMap(); 3 4 randomizeBiome(); 5 initMapSettings(); 6 initTileClasses(["step"]); 7 8 var topTerrain = g_Terrains.tier2Terrain; 9 10 resetTerrain(topTerrain, g_TileClasses.land, 50); 11 RMS.SetProgress(10); 12 13 var players = addBases("radial", 0.4, randFloat(0.05, 0.1)); 14 RMS.SetProgress(20); 15 16 createSunkenTerrain(players); 17 RMS.SetProgress(30); 18 19 addElements([ 20 { 21 "func": addLayeredPatches, 22 "avoid": [ 23 g_TileClasses.dirt, 5, 24 g_TileClasses.forest, 2, 25 g_TileClasses.mountain, 2, 26 g_TileClasses.player, 12, 27 g_TileClasses.step, 5 28 ], 29 "stay": [g_TileClasses.valley, 7], 30 "sizes": ["normal"], 31 "mixes": ["normal"], 32 "amounts": ["normal"] 33 }, 34 { 35 "func": addLayeredPatches, 36 "avoid": [ 37 g_TileClasses.dirt, 5, 38 g_TileClasses.forest, 2, 39 g_TileClasses.mountain, 2, 40 g_TileClasses.player, 12 41 ], 42 "stay": [g_TileClasses.settlement, 7], 43 "sizes": ["normal"], 44 "mixes": ["normal"], 45 "amounts": ["normal"] 46 }, 47 { 48 "func": addLayeredPatches, 49 "avoid": [ 50 g_TileClasses.dirt, 5, 51 g_TileClasses.forest, 2 52 ], 53 "stay": [g_TileClasses.player, 1], 54 "sizes": ["normal"], 55 "mixes": ["normal"], 56 "amounts": ["normal"] 57 }, 58 { 59 "func": addDecoration, 60 "avoid": [g_TileClasses.forest, 2], 61 "stay": [g_TileClasses.player, 1], 62 "sizes": ["normal"], 63 "mixes": ["normal"], 64 "amounts": ["normal"] 65 }, 66 { 67 "func": addDecoration, 68 "avoid": [ 69 g_TileClasses.forest, 2, 70 g_TileClasses.mountain, 2, 71 g_TileClasses.player, 12, 72 g_TileClasses.step, 2 73 ], 74 "stay": [g_TileClasses.valley, 7], 75 "sizes": ["normal"], 76 "mixes": ["normal"], 77 "amounts": ["normal"] 78 }, 79 { 80 "func": addDecoration, 81 "avoid": [ 82 g_TileClasses.forest, 2, 83 g_TileClasses.mountain, 2, 84 g_TileClasses.player, 12 85 ], 86 "stay": [g_TileClasses.settlement, 7], 87 "sizes": ["normal"], 88 "mixes": ["normal"], 89 "amounts": ["normal"] 90 }, 91 { 92 "func": addDecoration, 93 "avoid": [ 94 g_TileClasses.forest, 2, 95 g_TileClasses.mountain, 2, 96 g_TileClasses.player, 12 97 ], 98 "stay": [g_TileClasses.step, 7], 99 "sizes": ["normal"], 100 "mixes": ["normal"], 101 "amounts": ["scarce"] 102 } 103 ]); 104 RMS.SetProgress(40); 105 106 addElements(shuffleArray([ 107 { 108 "func": addMetal, 109 "avoid": [ 110 g_TileClasses.berries, 5, 111 g_TileClasses.forest, 3, 112 g_TileClasses.player, 30, 113 g_TileClasses.rock, 10, 114 g_TileClasses.metal, 20 115 ], 116 "stay": [g_TileClasses.settlement, 7], 117 "sizes": ["normal"], 118 "mixes": ["same"], 119 "amounts": ["tons"] 120 }, 121 { 122 "func": addMetal, 123 "avoid": [ 124 g_TileClasses.berries, 5, 125 g_TileClasses.forest, 3, 126 g_TileClasses.player, 10, 127 g_TileClasses.rock, 10, 128 g_TileClasses.metal, 20, 129 g_TileClasses.mountain, 5, 130 g_TileClasses.step, 5 131 ], 132 "stay": [g_TileClasses.valley, 7], 133 "sizes": ["normal"], 134 "mixes": ["same"], 135 "amounts": g_AllAmounts 136 }, 137 { 138 "func": addStone, 139 "avoid": [ 140 g_TileClasses.berries, 5, 141 g_TileClasses.forest, 3, 142 g_TileClasses.player, 30, 143 g_TileClasses.rock, 20, 144 g_TileClasses.metal, 10 145 ], 146 "stay": [g_TileClasses.settlement, 7], 147 "sizes": ["normal"], 148 "mixes": ["same"], 149 "amounts": ["tons"] 150 }, 151 { 152 "func": addStone, 153 "avoid": [ 154 g_TileClasses.berries, 5, 155 g_TileClasses.forest, 3, 156 g_TileClasses.player, 10, 157 g_TileClasses.rock, 20, 158 g_TileClasses.metal, 10, 159 g_TileClasses.mountain, 5, 160 g_TileClasses.step, 5 161 ], 162 "stay": [g_TileClasses.valley, 7], 163 "sizes": ["normal"], 164 "mixes": ["same"], 165 "amounts": g_AllAmounts 166 }, 167 { 168 "func": addForests, 169 "avoid": [ 170 g_TileClasses.berries, 5, 171 g_TileClasses.forest, 18, 172 g_TileClasses.metal, 3, 173 g_TileClasses.player, 20, 174 g_TileClasses.rock, 3 175 ], 176 "stay": [g_TileClasses.settlement, 7], 177 "sizes": ["normal", "big"], 178 "mixes": ["same"], 179 "amounts": ["tons"] 180 }, 181 { 182 "func": addForests, 183 "avoid": [ 184 g_TileClasses.berries, 3, 185 g_TileClasses.forest, 18, 186 g_TileClasses.metal, 3, 187 g_TileClasses.mountain, 5, 188 g_TileClasses.player, 5, 189 g_TileClasses.rock, 3, 190 g_TileClasses.step, 1 191 ], 192 "stay": [g_TileClasses.valley, 7], 193 "sizes": ["normal", "big"], 194 "mixes": ["same"], 195 "amounts": ["tons"] 196 } 197 ])); 198 RMS.SetProgress(60); 199 200 addElements(shuffleArray([ 201 { 202 "func": addBerries, 203 "avoid": [ 204 g_TileClasses.berries, 30, 205 g_TileClasses.forest, 5, 206 g_TileClasses.metal, 10, 207 g_TileClasses.player, 20, 208 g_TileClasses.rock, 10 209 ], 210 "stay": [g_TileClasses.settlement, 7], 211 "sizes": g_AllSizes, 212 "mixes": g_AllMixes, 213 "amounts": ["tons"] 214 }, 215 { 216 "func": addBerries, 217 "avoid": [ 218 g_TileClasses.berries, 30, 219 g_TileClasses.forest, 5, 220 g_TileClasses.metal, 10, 221 g_TileClasses.mountain, 5, 222 g_TileClasses.player, 10, 223 g_TileClasses.rock, 10, 224 g_TileClasses.step, 5 225 ], 226 "stay": [g_TileClasses.valley, 7], 227 "sizes": g_AllSizes, 228 "mixes": g_AllMixes, 229 "amounts": g_AllAmounts 230 }, 231 { 232 "func": addAnimals, 233 "avoid": [ 234 g_TileClasses.animals, 20, 235 g_TileClasses.forest, 0, 236 g_TileClasses.metal, 1, 237 g_TileClasses.player, 20, 238 g_TileClasses.rock, 1 239 ], 240 "stay": [g_TileClasses.settlement, 7], 241 "sizes": g_AllSizes, 242 "mixes": g_AllMixes, 243 "amounts": ["tons"] 244 }, 245 { 246 "func": addAnimals, 247 "avoid": [ 248 g_TileClasses.animals, 20, 249 g_TileClasses.forest, 0, 250 g_TileClasses.metal, 1, 251 g_TileClasses.mountain, 5, 252 g_TileClasses.player, 10, 253 g_TileClasses.rock, 1, 254 g_TileClasses.step, 5 255 ], 256 "stay": [g_TileClasses.valley, 7], 257 "sizes": g_AllSizes, 258 "mixes": g_AllMixes, 259 "amounts": g_AllAmounts 260 }, 261 { 262 "func": addStragglerTrees, 263 "avoid": [ 264 g_TileClasses.berries, 5, 265 g_TileClasses.forest, 7, 266 g_TileClasses.metal, 3, 267 g_TileClasses.player, 12, 268 g_TileClasses.rock, 3 269 ], 270 "stay": [g_TileClasses.settlement, 7], 271 "sizes": g_AllSizes, 272 "mixes": g_AllMixes, 273 "amounts": ["tons"] 274 }, 275 { 276 "func": addStragglerTrees, 277 "avoid": [ 278 g_TileClasses.berries, 5, 279 g_TileClasses.forest, 7, 280 g_TileClasses.metal, 3, 281 g_TileClasses.mountain, 5, 282 g_TileClasses.player, 10, 283 g_TileClasses.rock, 3, 284 g_TileClasses.step, 5 285 ], 286 "stay": [g_TileClasses.valley, 7], 287 "sizes": g_AllSizes, 288 "mixes": g_AllMixes, 289 "amounts": ["normal", "many", "tons"] 290 }, 291 { 292 "func": addStragglerTrees, 293 "avoid": [ 294 g_TileClasses.berries, 5, 295 g_TileClasses.forest, 3, 296 g_TileClasses.metal, 5, 297 g_TileClasses.rock, 5 298 ], 299 "stay": [g_TileClasses.player, 1], 300 "sizes": ["huge"], 301 "mixes": ["same"], 302 "amounts": ["tons"] 303 } 304 ])); 305 RMS.SetProgress(75); 306 307 addElements([ 308 { 309 "func": addDecoration, 310 "avoid": [ 311 g_TileClasses.valley, 4, 312 g_TileClasses.player, 4, 313 g_TileClasses.settlement, 4, 314 g_TileClasses.step, 4 315 ], 316 "stay": [g_TileClasses.land, 2], 317 "sizes": ["normal"], 318 "mixes": ["normal"], 319 "amounts": ["tons"] 320 } 321 ]); 322 RMS.SetProgress(80); 323 324 addElements([ 325 { 326 "func": addProps, 327 "avoid": [ 328 g_TileClasses.valley, 4, 329 g_TileClasses.player, 4, 330 g_TileClasses.settlement, 4, 331 g_TileClasses.step, 4 332 ], 333 "stay": [g_TileClasses.land, 2], 334 "sizes": ["normal"], 335 "mixes": ["normal"], 336 "amounts": ["scarce"] 337 } 338 ]); 339 RMS.SetProgress(85); 340 341 addElements([ 342 { 343 "func": addDecoration, 344 "avoid": [ 345 g_TileClasses.player, 4, 346 g_TileClasses.settlement, 4, 347 g_TileClasses.step, 4 348 ], 349 "stay": [g_TileClasses.mountain, 2], 350 "sizes": ["normal"], 351 "mixes": ["normal"], 352 "amounts": ["tons"] 353 } 354 ]); 355 RMS.SetProgress(90); 356 357 addElements([ 358 { 359 "func": addProps, 360 "avoid": [ 361 g_TileClasses.player, 4, 362 g_TileClasses.settlement, 4, 363 g_TileClasses.step, 4 364 ], 365 "stay": [g_TileClasses.mountain, 2], 366 "sizes": ["normal"], 367 "mixes": ["normal"], 368 "amounts": ["scarce"] 369 } 370 ]); 371 RMS.SetProgress(95); 372 373 ExportMap(); 374 375 // Create the sunken terrain 376 function createSunkenTerrain(players) 377 { 378 var base = g_Terrains.mainTerrain; 379 var middle = g_Terrains.dirt; 380 var lower = g_Terrains.tier2Terrain; 381 var road = g_Terrains.road; 382 383 if (g_MapInfo.biome == 2) 384 { 385 middle = g_Terrains.tier2Terrain; 386 lower = g_Terrains.tier1Terrain; 387 } 388 389 if (g_MapInfo.biome == 4) 390 { 391 middle = g_Terrains.shore; 392 lower = g_Terrains.tier4Terrain; 393 } 394 395 if (g_MapInfo.biome == 5) 396 { 397 middle = g_Terrains.tier1Terrain; 398 lower = g_Terrains.forestFloor1; 399 } 400 401 if (g_MapInfo.biome == 6) 402 { 403 middle = g_Terrains.tier2Terrain; 404 lower = g_Terrains.tier4Terrain; 405 } 406 407 if (g_MapInfo.biome == 7 || g_MapInfo.biome == 8) 408 road = g_Terrains.roadWild; 409 410 if (g_MapInfo.biome == 8) 411 middle = g_Terrains.shore; 412 413 var expSize = g_MapInfo.mapArea * 0.015 / (g_MapInfo.numPlayers / 4); 414 var expDist = 0.1 + (g_MapInfo.numPlayers / 200); 415 if (g_MapInfo.numPlayers == 2) 416 expSize = g_MapInfo.mapArea * 0.015 / 0.7; 417 418 var nRoad = 0.44; 419 var nExp = 0.425; 420 421 if (g_MapInfo.numPlayers < 4) 422 { 423 nRoad = 0.42; 424 nExp = 0.4; 425 } 426 427 // Create central valley 428 var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.26, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap); 429 var terrainPainter = new LayeredPainter([g_Terrains.cliff, lower], [3]); 430 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 0, 3); 431 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.valley)]); 432 433 // Create the center hill 434 var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.14, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap); 435 var terrainPainter = new LayeredPainter([g_Terrains.cliff, topTerrain], [3]); 436 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, g_MapInfo.mapHeight, 3); 437 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.mountain)]); 438 439 for(var i = 0; i < players.length; ++i) 440 { 441 var playerAngle = g_MapInfo.startAngle + i * TWO_PI / g_MapInfo.numPlayers; 442 var pX = round(fractionToTiles(0.5 + 0.4 * cos(playerAngle))); 443 var pZ = round(fractionToTiles(0.5 + 0.4 * sin(playerAngle))); 444 var expX = round(fractionToTiles(0.5 + expDist * cos(g_MapInfo.startAngle + (i + 0.75) * TWO_PI / g_MapInfo.numPlayers))); 445 var expZ = round(fractionToTiles(0.5 + expDist * sin(g_MapInfo.startAngle + (i + 0.75) * TWO_PI / g_MapInfo.numPlayers))); 446 var rearX = round(fractionToTiles(0.5 + 0.47 * cos(playerAngle))); 447 var rearZ = round(fractionToTiles(0.5 + 0.47 * sin(playerAngle))); 448 var prePlayerAngle = g_MapInfo.startAngle + (i - 0.5) * TWO_PI / g_MapInfo.numPlayers; 449 var preX = round(fractionToTiles(0.5 + nRoad * cos(prePlayerAngle))); 450 var preZ = round(fractionToTiles(0.5 + nRoad * sin(prePlayerAngle))); 451 var nextPlayerAngle = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.numPlayers; 452 var nextX = round(fractionToTiles(0.5 + nRoad * cos(nextPlayerAngle))); 453 var nextZ = round(fractionToTiles(0.5 + nRoad * sin(nextPlayerAngle))); 454 455 // Create path to expansion 456 var placer = new PathPlacer(pX, pZ, expX, expZ, scaleByMapSize(12, 12), 0.7, 0.5, 0.1, -1); 457 var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 4]); 458 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3); 459 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]); 460 461 // Create path to neighbor 462 var placer = new PathPlacer(rearX, rearZ, nextX, nextZ, scaleByMapSize(19, 19), 0.4, 0.5, 0.1, -0.6); 463 var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 6]); 464 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3); 465 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]); 466 467 // Create path to neighbor 468 var placer = new PathPlacer(rearX, rearZ, preX, preZ, scaleByMapSize(19, 19), 0.4, 0.5, 0.1, -0.6); 469 var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 6]); 470 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3); 471 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]); 472 473 // Create the den 474 var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.03, 0.9, 0.3, 1, pX, pZ); 475 var terrainPainter = new LayeredPainter([g_Terrains.cliff, base], [3]); 476 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 3); 477 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.valley)]); 478 479 // Create the expansion 480 var placer = new ClumpPlacer(expSize, 0.9, 0.3, 1, expX, expZ); 481 var terrainPainter = new LayeredPainter([g_Terrains.cliff, base], [3]); 482 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 3); 483 var area = createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.settlement)], [avoidClasses(g_TileClasses.settlement, 2)]); 484 var unpainter = new TileClassUnPainter(new TileClass(g_MapInfo.mapSize, g_TileClasses.mountain)); 485 unpainter.paint(area); 486 } 487 488 // Create the neighbor expansions 489 for (var i = 0; i < g_MapInfo.numPlayers; ++i) 490 { 491 var nextPlayerAngle = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.numPlayers; 492 var nextX = round(fractionToTiles(0.5 + nExp * cos(nextPlayerAngle))); 493 var nextZ = round(fractionToTiles(0.5 + nExp * sin(nextPlayerAngle))); 494 495 // Create the neightbor expansion 496 var placer = new ClumpPlacer(expSize, 0.9, 0.3, 1, nextX, nextZ); 497 var terrainPainter = new LayeredPainter([g_Terrains.cliff, lower], [3]); 498 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 0, 3); 499 var area = createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.settlement)]); 500 } 501 } -
binaries/data/mods/public/maps/random/lions_den.json
1 { 2 "settings" : { 3 "Name" : "Lion's Den", 4 "Script" : "lions_den.js", 5 "Description" : "High cliffs protect a player's main base. Venturing into the unknown can be risky, but necessary.", 6 "BaseTerrain" : ["medit_sea_depths"], 7 "BaseHeight" : 50, 8 "Preview" : "lions_den.png", 9 "Keywords": ["demo"], 10 "CircularMap" : true 11 } 12 } -
binaries/data/mods/public/maps/random/rmgen/gaia.js
1 const g_Props = { 2 "barrels": "actor|props/special/eyecandy/barrels_buried.xml", 3 "crate": "actor|props/special/eyecandy/crate_a.xml", 4 "cart": "actor|props/special/eyecandy/handcart_1_broken.xml", 5 "well": "actor|props/special/eyecandy/well_1_c.xml", 6 "skeleton": "actor|props/special/eyecandy/skeleton.xml", 7 "blood": "actor|props/units/blood_01.xml", 8 "bigBlood": "actor|props/units/blood_whale.xml" 9 }; 10 11 const g_DefaultDeviation = 0.1; 12 13 /** 14 * Create bluffs, i.e. a slope hill reachable from ground level. 15 * Fill it with wood, mines, animals and decoratives. 16 * 17 * @param {Array} constraint - where to place them 18 * @param {number} size - size of the bluffs (1.2 would be 120% of normal) 19 * @param {number} deviation - degree of deviation from the defined size (0.2 would be 20% plus/minus) 20 * @param {number} fill - size of map to fill (1.5 would be 150% of normal) 21 */ 22 function addBluffs(constraint, size, deviation, fill) 23 { 24 deviation = deviation || g_DefaultDeviation; 25 size = size || 1; 26 fill = fill || 1; 27 28 var count = fill * scaleByMapSize(15, 15); 29 var minSize = scaleByMapSize(5, 5); 30 var maxSize = scaleByMapSize(7, 7); 31 var elevation = 30; 32 var spread = scaleByMapSize(100, 100); 33 34 for (var i = 0; i < count; ++i) 35 { 36 var offset = getRandomDeviation(size, deviation); 37 38 var pMinSize = Math.floor(minSize * offset); 39 var pMaxSize = Math.floor(maxSize * offset); 40 var pSpread = Math.floor(spread * offset); 41 var pElevation = Math.floor(elevation * offset); 42 43 var placer = new ChainPlacer(pMinSize, pMaxSize, pSpread, 0.5); 44 var terrainPainter = new LayeredPainter([g_Terrains.cliff, g_Terrains.mainTerrain, g_Terrains.tier2Terrain], [2, 3]); 45 var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, pElevation, 2); 46 var rendered = createAreas(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.bluff)], constraint, 1); 47 48 // Find the bounding box of the bluff 49 if (rendered[0] === undefined) 50 continue; 51 52 var points = rendered[0].points; 53 54 var corners = findCorners(points); 55 var area = points.length; 56 57 // Seed an array the size of the bounding box 58 var bb = createBoundingBox(points, corners); 59 60 // Get a random starting position for the baseline and the endline 61 var angle = randInt(4); 62 var opAngle = angle - 2; 63 if (angle < 2) 64 opAngle = angle + 2; 65 66 // Find the edges of the bluff 67 var baseLine; 68 var endLine; 69 70 // If we can't access the bluff, try different angles 71 var retries = 0; 72 var bluffCat = 2; 73 while (bluffCat != 0 && retries < 5) 74 { 75 baseLine = findClearLine(bb, corners, angle); 76 endLine = findClearLine(bb, corners, opAngle); 77 78 bluffCat = unreachableBluff(bb, corners, baseLine, endLine); 79 ++angle; 80 if (angle > 3) 81 angle = 0; 82 83 opAngle = angle - 2; 84 if (angle < 2) 85 opAngle = angle + 2; 86 87 ++retries; 88 } 89 90 // Found a bluff that can't be accessed, so turn it into a plateau 91 if (retries == 5) 92 removeBluff(points); 93 94 // If we couldn't find the slope lines, turn it into a plateau 95 if (bluffCat == 1) 96 continue; 97 98 var ground = createTerrain(g_Terrains.mainTerrain); 99 100 var slopeLength = getDistance(baseLine.midX, baseLine.midZ, endLine.midX, endLine.midZ); 101 102 // Adjust the height of each point in the bluff 103 for (var p = 0; p < points.length; ++p) 104 { 105 var pt = points[p]; 106 var dist = distanceOfPointFromLine(baseLine.x1, baseLine.z1, baseLine.x2, baseLine.z2, pt.x, pt.z); 107 108 var curHeight = g_Map.getHeight(pt.x, pt.z); 109 var newHeight = curHeight - curHeight * (dist / slopeLength) - 2; 110 111 newHeight = Math.max(newHeight, endLine.height); 112 113 if (newHeight <= endLine.height + 2 && g_Map.validT(pt.x, pt.z) && g_Map.getTexture(pt.x, pt.z).indexOf('cliff') > -1) 114 ground.place(pt.x, pt.z); 115 116 g_Map.setHeight(pt.x, pt.z, newHeight); 117 } 118 119 // Smooth out the ground around the bluff 120 fadeToGround(bb, corners.minX, corners.minZ, endLine.height); 121 } 122 123 addElements([ 124 { 125 "func": addHills, 126 "avoid": [ 127 g_TileClasses.hill, 3, 128 g_TileClasses.player, 20, 129 g_TileClasses.valley, 2, 130 g_TileClasses.water, 2 131 ], 132 "stay": [g_TileClasses.bluff, 3], 133 "sizes": g_AllSizes, 134 "mixes": g_AllMixes, 135 "amounts": g_AllAmounts 136 } 137 ]); 138 139 addElements([ 140 { 141 "func": addLayeredPatches, 142 "avoid": [ 143 g_TileClasses.dirt, 5, 144 g_TileClasses.forest, 2, 145 g_TileClasses.mountain, 2, 146 g_TileClasses.player, 12, 147 g_TileClasses.water, 3 148 ], 149 "stay": [g_TileClasses.bluff, 5], 150 "sizes": ["normal"], 151 "mixes": ["normal"], 152 "amounts": ["normal"] 153 } 154 ]); 155 156 addElements([ 157 { 158 "func": addDecoration, 159 "avoid": [ 160 g_TileClasses.forest, 2, 161 g_TileClasses.player, 12, 162 g_TileClasses.water, 3 163 ], 164 "stay": [g_TileClasses.bluff, 5], 165 "sizes": ["normal"], 166 "mixes": ["normal"], 167 "amounts": ["normal"] 168 } 169 ]); 170 171 addElements([ 172 { 173 "func": addProps, 174 "avoid": [ 175 g_TileClasses.forest, 2, 176 g_TileClasses.player, 12, 177 g_TileClasses.prop, 40, 178 g_TileClasses.water, 3 179 ], 180 "stay": [ 181 g_TileClasses.bluff, 7, 182 g_TileClasses.mountain, 7 183 ], 184 "sizes": ["normal"], 185 "mixes": ["normal"], 186 "amounts": ["scarce"] 187 } 188 ]); 189 190 addElements(shuffleArray([ 191 { 192 "func": addForests, 193 "avoid": [ 194 g_TileClasses.berries, 5, 195 g_TileClasses.forest, 18, 196 g_TileClasses.metal, 5, 197 g_TileClasses.mountain, 5, 198 g_TileClasses.player, 20, 199 g_TileClasses.rock, 5, 200 g_TileClasses.water, 2 201 ], 202 "stay": [g_TileClasses.bluff, 6], 203 "sizes": g_AllSizes, 204 "mixes": g_AllMixes, 205 "amounts": ["normal", "many", "tons"] 206 }, 207 { 208 "func": addMetal, 209 "avoid": [ 210 g_TileClasses.berries, 5, 211 g_TileClasses.forest, 5, 212 g_TileClasses.mountain, 2, 213 g_TileClasses.player, 50, 214 g_TileClasses.rock, 15, 215 g_TileClasses.metal, 40, 216 g_TileClasses.water, 3 217 ], 218 "stay": [g_TileClasses.bluff, 6], 219 "sizes": ["normal"], 220 "mixes": ["same"], 221 "amounts": ["normal", "many", "tons"] 222 }, 223 { 224 "func": addStone, 225 "avoid": [ 226 g_TileClasses.berries, 5, 227 g_TileClasses.forest, 5, 228 g_TileClasses.mountain, 2, 229 g_TileClasses.player, 50, 230 g_TileClasses.rock, 40, 231 g_TileClasses.metal, 15, 232 g_TileClasses.water, 3 233 ], 234 "stay": [g_TileClasses.bluff, 6], 235 "sizes": ["normal"], 236 "mixes": ["same"], 237 "amounts": ["normal", "many", "tons"] 238 } 239 ])); 240 241 addElements(shuffleArray([ 242 { 243 "func": addStragglerTrees, 244 "avoid": [ 245 g_TileClasses.berries, 5, 246 g_TileClasses.forest, 10, 247 g_TileClasses.metal, 5, 248 g_TileClasses.mountain, 1, 249 g_TileClasses.player, 12, 250 g_TileClasses.rock, 5, 251 g_TileClasses.water, 5 252 ], 253 "stay": [g_TileClasses.bluff, 6], 254 "sizes": g_AllSizes, 255 "mixes": g_AllMixes, 256 "amounts": ["normal", "many", "tons"] 257 }, 258 { 259 "func": addAnimals, 260 "avoid": [ 261 g_TileClasses.animals, 20, 262 g_TileClasses.forest, 5, 263 g_TileClasses.mountain, 1, 264 g_TileClasses.player, 20, 265 g_TileClasses.rock, 5, 266 g_TileClasses.metal, 5, 267 g_TileClasses.water, 3 268 ], 269 "stay": [g_TileClasses.bluff, 6], 270 "sizes": g_AllSizes, 271 "mixes": g_AllMixes, 272 "amounts": ["normal", "many", "tons"] 273 }, 274 { 275 "func": addBerries, 276 "avoid": [ 277 g_TileClasses.berries, 50, 278 g_TileClasses.forest, 5, 279 g_TileClasses.metal, 10, 280 g_TileClasses.mountain, 2, 281 g_TileClasses.player, 20, 282 g_TileClasses.rock, 10, 283 g_TileClasses.water, 3 284 ], 285 "stay": [g_TileClasses.bluff, 6], 286 "sizes": g_AllSizes, 287 "mixes": g_AllMixes, 288 "amounts": ["normal", "many", "tons"] 289 } 290 ])); 291 } 292 293 /** 294 * Add grass, rocks and bushes. 295 */ 296 function addDecoration(constraint, size, deviation, fill) 297 { 298 deviation = deviation || g_DefaultDeviation; 299 size = size || 1; 300 fill = fill || 1; 301 302 var offset = getRandomDeviation(size, deviation); 303 var decorations = [ 304 [ 305 new SimpleObject(g_Decoratives.rockMedium, 1 * offset, 3 * offset, 0, 1 * offset) 306 ], 307 [ 308 new SimpleObject(g_Decoratives.rockLarge, 1 * offset, 2 * offset, 0, 1 * offset), 309 new SimpleObject(g_Decoratives.rockMedium, 1 * offset, 3 * offset, 0, 2 * offset) 310 ], 311 [ 312 new SimpleObject(g_Decoratives.grassShort, 1 * offset, 2 * offset, 0, 1 * offset, -PI / 8, PI / 8) 313 ], 314 [ 315 new SimpleObject(g_Decoratives.grass, 2 * offset, 4 * offset, 0, 1.8 * offset, -PI / 8, PI / 8), 316 new SimpleObject(g_Decoratives.grassShort, 3 * offset, 6 * offset, 1.2 * offset, 2.5 * offset, -PI / 8, PI / 8) 317 ], 318 [ 319 new SimpleObject(g_Decoratives.bushMedium, 1 * offset, 2 * offset, 0, 2 * offset), 320 new SimpleObject(g_Decoratives.bushSmall, 2 * offset, 4 * offset, 0, 2 * offset) 321 ] 322 ]; 323 324 var baseCount = 1; 325 if (g_MapInfo.biome == 7) 326 baseCount = 8; 327 328 var counts = [ 329 scaleByMapSize(16, 262), 330 scaleByMapSize(8, 131), 331 baseCount * scaleByMapSize(13, 200), 332 baseCount * scaleByMapSize(13, 200), 333 baseCount * scaleByMapSize(13, 200) 334 ]; 335 336 for (var i = 0; i < decorations.length; ++i) 337 { 338 var decorCount = Math.floor(counts[i] * fill); 339 var group = new SimpleGroup(decorations[i], true); 340 createObjectGroups(group, 0, constraint, decorCount, 5); 341 } 342 } 343 344 /** 345 * Create varying elevations. 346 * 347 * @param {Array} constraint - avoid/stay-classes 348 * 349 * @param {Object} el - the element to be rendered, for example: 350 * "class": g_TileClasses.hill, 351 * "painter": [g_Terrains.mainTerrain, g_Terrains.mainTerrain], 352 * "size": 1, 353 * "deviation": 0.2, 354 * "fill": 1, 355 * "count": scaleByMapSize(8, 8), 356 * "minSize": Math.floor(scaleByMapSize(5, 5)), 357 * "maxSize": Math.floor(scaleByMapSize(8, 8)), 358 * "spread": Math.floor(scaleByMapSize(20, 20)), 359 * "minElevation": 6, 360 * "maxElevation": 12, 361 * "steepness": 1.5 362 */ 363 364 function addElevation(constraint, el) 365 { 366 var deviation = el.deviation || g_DefaultDeviation; 367 var size = el.size || 1; 368 var fill = el.fill || 1; 369 370 var count = fill * el.count; 371 var minSize = el.minSize; 372 var maxSize = el.maxSize; 373 var spread = el.spread; 374 375 var elType = ELEVATION_MODIFY; 376 if (el.class == g_TileClasses.water) 377 elType = ELEVATION_SET; 378 379 var widths = []; 380 381 // Allow for shore and cliff rendering 382 for (var s = el.painter.length; s > 2; --s) 383 widths.push(1); 384 385 for (var i = 0; i < count; ++i) 386 { 387 var elevation = el.minElevation + randInt(el.maxElevation - el.minElevation); 388 var smooth = Math.floor(elevation / el.steepness); 389 390 var offset = getRandomDeviation(size, el.deviation); 391 var pMinSize = Math.floor(minSize * offset); 392 var pMaxSize = Math.floor(maxSize * offset); 393 var pSpread = Math.floor(spread * offset); 394 var pSmooth = Math.abs(Math.floor(smooth * offset)); 395 var pElevation = Math.floor(elevation * offset); 396 397 pElevation = Math.max(el.minElevation, Math.min(pElevation, el.maxElevation)); 398 399 pMinSize = Math.min(pMinSize, pMaxSize); 400 pMaxSize = Math.min(pMaxSize, el.maxSize); 401 pMinSize = Math.max(pMaxSize, el.minSize); 402 403 pSmooth = Math.max(pSmooth, 1); 404 405 var pWidths = widths.concat(pSmooth); 406 407 var placer = new ChainPlacer(pMinSize, pMaxSize, pSpread, 0.5); 408 var terrainPainter = new LayeredPainter(el.painter, [pWidths]); 409 var elevationPainter = new SmoothElevationPainter(elType, pElevation, pSmooth); 410 createAreas(placer, [terrainPainter, elevationPainter, paintClass(el.class)], constraint, 1); 411 } 412 } 413 414 /** 415 * Create rolling hills. 416 */ 417 function addHills(constraint, size, deviation, fill) 418 { 419 addElevation(constraint, { 420 "class": g_TileClasses.hill, 421 "painter": [g_Terrains.mainTerrain, g_Terrains.mainTerrain], 422 "size": size, 423 "deviation": deviation, 424 "fill": fill, 425 "count": scaleByMapSize(8, 8), 426 "minSize": Math.floor(scaleByMapSize(5, 5)), 427 "maxSize": Math.floor(scaleByMapSize(8, 8)), 428 "spread": Math.floor(scaleByMapSize(20, 20)), 429 "minElevation": 6, 430 "maxElevation": 12, 431 "steepness": 1.5 432 }); 433 } 434 435 /** 436 * Create random lakes with fish in it. 437 */ 438 function addLakes(constraint, size, deviation, fill) 439 { 440 var lakeTile = g_Terrains.water; 441 442 if (g_MapInfo.biome == 0 || g_MapInfo.biome == 1 || g_MapInfo.biome == 7) 443 lakeTile = g_Terrains.dirt; 444 445 if (g_MapInfo.biome == 5) 446 lakeTile = g_Terrains.tier2Terrain; 447 448 if (g_MapInfo.biome == 8) 449 lakeTile = g_Terrains.shore; 450 451 addElevation(constraint, { 452 "class": g_TileClasses.water, 453 "painter": [lakeTile, lakeTile], 454 "size": size, 455 "deviation": deviation, 456 "fill": fill, 457 "count": scaleByMapSize(6, 6), 458 "minSize": Math.floor(scaleByMapSize(7, 7)), 459 "maxSize": Math.floor(scaleByMapSize(9, 9)), 460 "spread": Math.floor(scaleByMapSize(70, 70)), 461 "minElevation": -15, 462 "maxElevation": -2, 463 "steepness": 1.5 464 }); 465 466 addElements([ 467 { 468 "func": addFish, 469 "avoid": [ 470 g_TileClasses.fish, 12, 471 g_TileClasses.hill, 8, 472 g_TileClasses.mountain, 8, 473 g_TileClasses.player, 8 474 ], 475 "stay": [g_TileClasses.water, 7], 476 "sizes": g_AllSizes, 477 "mixes": g_AllMixes, 478 "amounts": ["normal", "many", "tons"] 479 } 480 ]); 481 482 var group = new SimpleGroup([new SimpleObject(g_Decoratives.rockMedium, 1, 3, 1, 3)], true, g_TileClasses.dirt); 483 createObjectGroups(group, 0, [stayClasses(g_TileClasses.water, 1), borderClasses(g_TileClasses.water, 4, 3)], 1000, 100); 484 485 group = new SimpleGroup([new SimpleObject(g_Decoratives.reeds, 10, 15, 1, 3), new SimpleObject(g_Decoratives.rockMedium, 1, 3, 1, 3)], true, g_TileClasses.dirt); 486 createObjectGroups(group, 0, [stayClasses(g_TileClasses.water, 2), borderClasses(g_TileClasses.water, 4, 3)], 1000, 100); 487 } 488 489 /** 490 * Universal function to create layered patches. 491 */ 492 function addLayeredPatches(constraint, size, deviation, fill) 493 { 494 deviation = deviation || g_DefaultDeviation; 495 size = size || 1; 496 fill = fill || 1; 497 498 var minRadius = 1; 499 var maxRadius = Math.floor(scaleByMapSize(3, 5)); 500 var count = fill * scaleByMapSize(15, 45); 501 502 var sizes = [ 503 scaleByMapSize(3, 6), 504 scaleByMapSize(5, 10), 505 scaleByMapSize(8, 21) 506 ]; 507 508 for (var i = 0; i < sizes.length; ++i) 509 { 510 var offset = getRandomDeviation(size, deviation); 511 var patchMinRadius = Math.floor(minRadius * offset); 512 var patchMaxRadius = Math.floor(maxRadius * offset); 513 var patchSize = Math.floor(sizes[i] * offset); 514 var patchCount = count * offset; 515 516 if (patchMinRadius > patchMaxRadius) 517 patchMinRadius = patchMaxRadius; 518 519 var placer = new ChainPlacer(patchMinRadius, patchMaxRadius, patchSize, 0.5); 520 var painter = new LayeredPainter( 521 [ 522 [g_Terrains.mainTerrain, g_Terrains.tier1Terrain], 523 [g_Terrains.tier1Terrain, g_Terrains.tier2Terrain], 524 [g_Terrains.tier2Terrain, g_Terrains.tier3Terrain], 525 [g_Terrains.tier4Terrain] 526 ], 527 [1, 1] // widths 528 ); 529 createAreas(placer, [painter, paintClass(g_TileClasses.dirt)], constraint, patchCount); 530 } 531 } 532 533 /** 534 * Create steep mountains. 535 */ 536 function addMountains(constraint, size, deviation, fill) 537 { 538 addElevation(constraint, { 539 "class": g_TileClasses.mountain, 540 "painter": [g_Terrains.cliff, g_Terrains.hill], 541 "size": size, 542 "deviation": deviation, 543 "fill": fill, 544 "count": scaleByMapSize(8, 8), 545 "minSize": Math.floor(scaleByMapSize(2, 2)), 546 "maxSize": Math.floor(scaleByMapSize(4, 4)), 547 "spread": Math.floor(scaleByMapSize(100, 100)), 548 "minElevation": 100, 549 "maxElevation": 120, 550 "steepness": 4 551 }); 552 } 553 554 /** 555 * Create plateaus. 556 */ 557 function addPlateaus(constraint, size, deviation, fill) 558 { 559 var plateauTile = g_Terrains.dirt; 560 561 if (g_MapInfo.biome == 2) 562 plateauTile = g_Terrains.tier1Terrain; 563 564 if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6) 565 plateauTile = g_Terrains.tier2Terrain; 566 567 if (g_MapInfo.biome == 8) 568 plateauTile = g_Terrains.tier4Terrain; 569 570 addElevation(constraint, { 571 "class": g_TileClasses.plateau, 572 "painter": [g_Terrains.cliff, plateauTile], 573 "size": size, 574 "deviation": deviation, 575 "fill": fill, 576 "count": scaleByMapSize(15, 15), 577 "minSize": Math.floor(scaleByMapSize(2, 2)), 578 "maxSize": Math.floor(scaleByMapSize(4, 4)), 579 "spread": Math.floor(scaleByMapSize(200, 200)), 580 "minElevation": 20, 581 "maxElevation": 30, 582 "steepness": 8 583 }); 584 585 for (var i = 0; i < 40; ++i) 586 { 587 var placer = new ChainPlacer(3, 15, 1, 0.5); 588 var terrainPainter = new LayeredPainter([plateauTile, plateauTile], [3]); 589 var hillElevation = 4 + randInt(15); 590 var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, hillElevation, hillElevation - 2); 591 592 createAreas( 593 placer, 594 [ 595 terrainPainter, 596 elevationPainter, 597 paintClass(g_TileClasses.hill) 598 ], 599 [ 600 avoidClasses(g_TileClasses.hill, 7), 601 stayClasses(g_TileClasses.plateau, 7) 602 ], 603 1 604 ); 605 } 606 607 addElements([ 608 { 609 "func": addDecoration, 610 "avoid": [ 611 g_TileClasses.dirt, 15, 612 g_TileClasses.forest, 2, 613 g_TileClasses.player, 12, 614 g_TileClasses.water, 3 615 ], 616 "stay": [g_TileClasses.plateau, 8], 617 "sizes": ["normal"], 618 "mixes": ["normal"], 619 "amounts": ["tons"] 620 }, 621 { 622 "func": addProps, 623 "avoid": [ 624 g_TileClasses.forest, 2, 625 g_TileClasses.player, 12, 626 g_TileClasses.prop, 40, 627 g_TileClasses.water, 3 628 ], 629 "stay": [g_TileClasses.plateau, 8], 630 "sizes": ["normal"], 631 "mixes": ["normal"], 632 "amounts": ["scarce"] 633 } 634 ]); 635 } 636 637 /** 638 * Place less usual decoratives like barrels or crates. 639 */ 640 function addProps(constraint, size, deviation, fill) 641 { 642 deviation = deviation || g_DefaultDeviation; 643 size = size || 1; 644 fill = fill || 1; 645 646 var offset = getRandomDeviation(size, deviation); 647 648 var props = [ 649 [ 650 new SimpleObject(g_Props.skeleton, 1 * offset, 5 * offset, 0, 3 * offset + 2), 651 new SimpleObject(g_Props.blood, 1 * offset, 2 * offset, 0, 1 * offset + 3), 652 new SimpleObject(g_Props.bigBlood, 1 * offset, 3 * offset, 0, 2 * offset + 3) 653 ], 654 [ 655 new SimpleObject(g_Props.barrels, 1 * offset, 2 * offset, 2, 3 * offset + 2), 656 new SimpleObject(g_Props.cart, 0, 1 * offset, 5, 2.5 * offset + 5), 657 new SimpleObject(g_Props.crate, 1 * offset, 2 * offset, 2, 2 * offset + 2), 658 new SimpleObject(g_Props.well, 0, 1, 2, 2 * offset + 2) 659 ] 660 ]; 661 662 var baseCount = 1; 663 664 var counts = [ 665 scaleByMapSize(16, 262), 666 scaleByMapSize(8, 131), 667 baseCount * scaleByMapSize(13, 200), 668 baseCount * scaleByMapSize(13, 200), 669 baseCount * scaleByMapSize(13, 200) 670 ]; 671 672 // Add small props 673 for (var i = 0; i < props.length; ++i) 674 { 675 var propCount = Math.floor(counts[i] * fill); 676 var group = new SimpleGroup(props[i], true); 677 createObjectGroups(group, 0, constraint, propCount, 5); 678 } 679 680 // Add decorative trees 681 var trees = new SimpleObject(g_Decoratives.tree, 5 * offset, 30 * offset, 2, 3 * offset + 10); 682 createObjectGroups(new SimpleGroup([trees], true), 0, constraint, counts[0] * 5 * fill, 5); 683 } 684 685 /** 686 * Create rivers. 687 */ 688 function addRivers(constraint, size, deviation, fill) 689 { 690 deviation = deviation || g_DefaultDeviation; 691 size = size || 1; 692 fill = fill || 1; 693 694 var count = 5; 695 var minSize = scaleByMapSize(15, 15); 696 var maxSize = scaleByMapSize(15, 15); 697 var elevation = -2; 698 var spread = scaleByMapSize(5, 5); 699 700 for (var i = 0; i < count; ++i) 701 { 702 var offset = getRandomDeviation(size, deviation); 703 704 var startAngle = randFloat(0, 2 * PI); 705 var endAngle = startAngle + randFloat(PI * 0.5, PI * 1.5); 706 707 var startX = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.cos(startAngle)); 708 var startZ = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.sin(startAngle)); 709 710 var endX = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.cos(endAngle)); 711 var endZ = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.sin(endAngle)); 712 713 var pMinSize = Math.floor(minSize * offset); 714 var pMaxSize = Math.floor(maxSize * offset); 715 var pSpread = Math.floor(spread * offset); 716 717 var placer = new PathPlacer(startX, startZ, endX, endZ, 12, 0.25, 1, 0.05, 0.3); 718 var terrainPainter = new LayeredPainter([g_Terrains.water, g_Terrains.shore], [2]); 719 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, elevation, 2); 720 createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.water)], constraint); 721 } 722 } 723 724 /** 725 * Create valleys. 726 */ 727 function addValleys(constraint, size, deviation, fill) 728 { 729 if (g_MapInfo.mapHeight < 6) 730 return; 731 732 var minElevation = (-1 * g_MapInfo.mapHeight) / (size * (1 + deviation)) + 1; 733 if (minElevation < -1 * g_MapInfo.mapHeight) 734 minElevation = -1 * g_MapInfo.mapHeight; 735 736 var valleySlope = g_Terrains.tier1Terrain; 737 var valleyFloor = g_Terrains.tier4Terrain; 738 739 if (g_MapInfo.biome == 0) 740 { 741 valleySlope = g_Terrains.dirt; 742 valleyFloor = g_Terrains.tier2Terrain; 743 } 744 745 if (g_MapInfo.biome == 3) 746 { 747 valleySlope = g_Terrains.tier3Terrain; 748 valleyFloor = g_Terrains.dirt; 749 } 750 751 if (g_MapInfo.biome == 5) 752 { 753 valleySlope = g_Terrains.tier2Terrain; 754 valleyFloor = g_Terrains.dirt; 755 } 756 757 if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6) 758 valleyFloor = g_Terrains.tier2Terrain; 759 760 if (g_MapInfo.biome == 7) 761 valleySlope = g_Terrains.dirt; 762 763 if (g_MapInfo.biome == 8) 764 valleyFloor = g_Terrains.tier3Terrain; 765 766 addElevation(constraint, { 767 "class": g_TileClasses.valley, 768 "painter": [valleySlope, valleyFloor], 769 "size": size, 770 "deviation": deviation, 771 "fill": fill, 772 "count": scaleByMapSize(8, 8), 773 "minSize": Math.floor(scaleByMapSize(5, 5)), 774 "maxSize": Math.floor(scaleByMapSize(8, 8)), 775 "spread": Math.floor(scaleByMapSize(30, 30)), 776 "minElevation": minElevation, 777 "maxElevation": -2, 778 "steepness": 4 779 }); 780 } 781 782 /** 783 * Create huntable animals. 784 */ 785 function addAnimals(constraint, size, deviation, fill) 786 { 787 deviation = deviation || g_DefaultDeviation; 788 size = size || 1; 789 fill = fill || 1; 790 791 var groupOffset = getRandomDeviation(size, deviation); 792 793 var animals = [ 794 [new SimpleObject(g_Gaia.mainHuntableAnimal, 5 * groupOffset, 7 * groupOffset, 0, 4 * groupOffset)], 795 [new SimpleObject(g_Gaia.secondaryHuntableAnimal, 2 * groupOffset, 3 * groupOffset, 0, 2 * groupOffset)] 796 ]; 797 798 var counts = [scaleByMapSize(30, 30) * fill, scaleByMapSize(30, 30) * fill]; 799 800 for (var i = 0; i < animals.length; ++i) 801 { 802 var group = new SimpleGroup(animals[i], true, g_TileClasses.animals); 803 createObjectGroups(group, 0, constraint, Math.floor(counts[i]), 50); 804 } 805 } 806 807 /** 808 * Create fruits. 809 */ 810 function addBerries(constraint, size, deviation, fill) 811 { 812 deviation = deviation || g_DefaultDeviation; 813 size = size || 1; 814 fill = fill || 1; 815 816 var groupOffset = getRandomDeviation(size, deviation); 817 818 var count = scaleByMapSize(50, 50) * fill; 819 var berries = [[new SimpleObject(g_Gaia.fruitBush, 5 * groupOffset, 5 * groupOffset, 0, 3 * groupOffset)]]; 820 821 for (var i = 0; i < berries.length; ++i) 822 { 823 var group = new SimpleGroup(berries[i], true, g_TileClasses.berries); 824 createObjectGroups(group, 0, constraint, Math.floor(count), 40); 825 } 826 } 827 828 /** 829 * Create fish. 830 */ 831 function addFish(constraint, size, deviation, fill) 832 { 833 deviation = deviation || g_DefaultDeviation; 834 size = size || 1; 835 fill = fill || 1; 836 837 var groupOffset = getRandomDeviation(size, deviation); 838 839 var fish = [ 840 [new SimpleObject(g_Gaia.fish, 1 * groupOffset, 2 * groupOffset, 0, 2 * groupOffset)], 841 [new SimpleObject(g_Gaia.fish, 2 * groupOffset, 4 * groupOffset, 10 * groupOffset, 20 * groupOffset)] 842 ]; 843 844 var counts = [scaleByMapSize(40, 40) * fill, scaleByMapSize(40, 40) * fill]; 845 846 for (var i = 0; i < fish.length; ++i) 847 { 848 var group = new SimpleGroup(fish[i], true, g_TileClasses.fish); 849 createObjectGroups(group, 0, constraint, floor(counts[i]), 50); 850 } 851 } 852 853 /** 854 * Create dense forests. 855 */ 856 function addForests(constraint, size, deviation, fill) 857 { 858 deviation = deviation || g_DefaultDeviation; 859 size = size || 1; 860 fill = fill || 1; 861 862 // No forests for the african biome 863 if (g_MapInfo.biome == 6) 864 return; 865 866 var types = [ 867 [ 868 [g_Terrains.forestFloor2, g_Terrains.mainTerrain, g_Forests.forest1], 869 [g_Terrains.forestFloor2, g_Forests.forest1] 870 ], 871 [ 872 [g_Terrains.forestFloor2, g_Terrains.mainTerrain, g_Forests.forest2], 873 [g_Terrains.forestFloor1, g_Forests.forest2]], 874 [ 875 [g_Terrains.forestFloor1, g_Terrains.mainTerrain, g_Forests.forest1], 876 [g_Terrains.forestFloor2, g_Forests.forest1]], 877 [ 878 [g_Terrains.forestFloor1, g_Terrains.mainTerrain, g_Forests.forest2], 879 [g_Terrains.forestFloor1, g_Forests.forest2] 880 ] 881 ]; 882 883 for (var i = 0; i < types.length; ++i) 884 { 885 var offset = getRandomDeviation(size, deviation); 886 var minSize = floor(scaleByMapSize(3, 5) * offset); 887 var maxSize = Math.floor(scaleByMapSize(50, 50) * offset); 888 var forestCount = scaleByMapSize(10, 10) * fill; 889 890 var placer = new ChainPlacer(1, minSize, maxSize, 0.5); 891 var painter = new LayeredPainter(types[i], [2]); 892 createAreas(placer, [painter, paintClass(g_TileClasses.forest)], constraint, forestCount); 893 } 894 } 895 896 /** 897 * Create metal mines. 898 */ 899 function addMetal(constraint, size, deviation, fill) 900 { 901 deviation = deviation || g_DefaultDeviation; 902 size = size || 1; 903 fill = fill || 1; 904 905 var offset = getRandomDeviation(size, deviation); 906 var count = 1 + scaleByMapSize(20, 20) * fill; 907 var mines = [[new SimpleObject(g_Gaia.metalLarge, 1 * offset, 1 * offset, 0, 4 * offset)]]; 908 909 for (var i = 0; i < mines.length; ++i) 910 { 911 var group = new SimpleGroup(mines[i], true, g_TileClasses.metal); 912 createObjectGroups(group, 0, constraint, count, 100); 913 } 914 } 915 916 /** 917 * Create stone mines. 918 */ 919 function addStone(constraint, size, deviation, fill) 920 { 921 deviation = deviation || g_DefaultDeviation; 922 size = size || 1; 923 fill = fill || 1; 924 925 var offset = getRandomDeviation(size, deviation); 926 var count = 1 + scaleByMapSize(20, 20) * fill; 927 var mines = [ 928 [ 929 new SimpleObject(g_Gaia.stoneSmall, 0, 2 * offset, 0, 4 * offset), 930 new SimpleObject(g_Gaia.stoneLarge, 1 * offset, 1 * offset, 0, 4 * offset) 931 ], 932 [ 933 new SimpleObject(g_Gaia.stoneSmall, 2 * offset, 5 * offset, 1 * offset, 3 * offset) 934 ] 935 ]; 936 937 for (var i = 0; i < mines.length; ++i) 938 { 939 var group = new SimpleGroup(mines[i], true, g_TileClasses.rock); 940 createObjectGroups(group, 0, constraint, count, 100); 941 } 942 } 943 944 /** 945 * Create straggler trees. 946 */ 947 function addStragglerTrees(constraint, size, deviation, fill) 948 { 949 deviation = deviation || g_DefaultDeviation; 950 size = size || 1; 951 fill = fill || 1; 952 953 // Ensure minimum distribution on african biome 954 if (g_MapInfo.biome == 6) 955 { 956 fill = Math.max(fill, 2); 957 size = Math.max(size, 1); 958 } 959 960 var trees = [g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree4]; 961 962 var treesPerPlayer = 40; 963 var playerBonus = Math.max(1, (g_MapInfo.numPlayers - 3) / 2); 964 965 var offset = getRandomDeviation(size, deviation); 966 var treeCount = treesPerPlayer * playerBonus * fill; 967 var totalTrees = scaleByMapSize(treeCount, treeCount); 968 969 var count = Math.floor(totalTrees / trees.length) * fill; 970 var min = 1 * offset; 971 var max = 4 * offset; 972 var minDist = 1 * offset; 973 var maxDist = 5 * offset; 974 975 // More trees for the african biome 976 if (g_MapInfo.biome == 6) 977 { 978 min = 3 * offset; 979 max = 5 * offset; 980 minDist = 2 * offset + 1; 981 maxDist = 3 * offset + 2; 982 } 983 984 for (var i = 0; i < trees.length; ++i) 985 { 986 var treesMax = max; 987 988 // Don't clump fruit trees 989 if (i == 2 && (g_MapInfo.biome == 3 || g_MapInfo.biome == 5)) 990 treesMax = 1; 991 992 min = Math.min(min, treesMax); 993 994 var group = new SimpleGroup([new SimpleObject(trees[i], min, treesMax, minDist, maxDist)], true, g_TileClasses.forest); 995 createObjectGroups(group, 0, constraint, count); 996 } 997 } 998 999 /////////// 1000 // Terrain Helpers 1001 /////////// 1002 1003 /** 1004 * Determine if the endline of the bluff is within the tilemap. 1005 */ 1006 function unreachableBluff(bb, corners, baseLine, endLine) 1007 { 1008 // If we couldn't find a slope line 1009 if (typeof baseLine.midX === "undefined" || typeof endLine.midX === "undefined") 1010 return 1; 1011 1012 // If the end points aren't on the tilemap 1013 if ((!g_Map.validT(endLine.x1, endLine.z1) || checkIfInClass(endLine.x1, endLine.z1, g_TileClasses.player)) && 1014 (!g_Map.validT(endLine.x2, endLine.z2) || checkIfInClass(endLine.x2, endLine.z2, g_TileClasses.player))) 1015 return 2; 1016 1017 var minTilesInGroup = 1; 1018 var insideBluff = false; 1019 var outsideBluff = false; 1020 1021 // If there aren't enough points in each row 1022 for (var x = 0; x < bb.length; ++x) 1023 { 1024 var count = 0; 1025 for (var z = 0; z < bb[x].length; ++z) 1026 { 1027 if (!bb[x][z].isFeature) 1028 continue; 1029 1030 var valid = g_Map.validT(x + corners.minX, z + corners.minZ); 1031 1032 if (valid) 1033 ++count; 1034 1035 if (!insideBluff && valid) 1036 insideBluff = true; 1037 1038 if (outsideBluff && valid) 1039 return 3; 1040 } 1041 1042 // We're expecting the end of the bluff 1043 if (insideBluff && count < minTilesInGroup) 1044 outsideBluff = true; 1045 } 1046 1047 var insideBluff = false; 1048 var outsideBluff = false; 1049 1050 // If there aren't enough points in each column 1051 for (var z = 0; z < bb[0].length; ++z) 1052 { 1053 var count = 0; 1054 for (var x = 0; x < bb.length; ++x) 1055 { 1056 if (!bb[x][z].isFeature) 1057 continue; 1058 1059 var valid = g_Map.validT(x + corners.minX, z + corners.minZ); 1060 1061 if (valid) 1062 ++count; 1063 1064 if (!insideBluff && valid) 1065 insideBluff = true; 1066 1067 if (outsideBluff && valid) 1068 return 3; 1069 } 1070 1071 // We're expecting the end of the bluff 1072 if (insideBluff && count < minTilesInGroup) 1073 outsideBluff = true; 1074 } 1075 1076 // Bluff is reachable 1077 return 0; 1078 } 1079 1080 /** 1081 * Remove the bluff class and turn it into a plateau. 1082 */ 1083 function removeBluff(points) 1084 { 1085 for (var i = 0; i < points.length; ++i) 1086 addToClass(points[i].x, points[i].z, g_TileClasses.mountain); 1087 } 1088 1089 /** 1090 * Create an array of points the fill a bounding box around a terrain feature. 1091 */ 1092 function createBoundingBox(points, corners) 1093 { 1094 var bb = []; 1095 var width = corners.maxX - corners.minX + 1; 1096 var length = corners.maxZ - corners.minZ + 1; 1097 for (var w = 0; w < width; ++w) 1098 { 1099 bb[w] = []; 1100 for (var l = 0; l < length; ++l) 1101 { 1102 var curHeight = g_Map.getHeight(w + corners.minX, l + corners.minZ); 1103 bb[w][l] = { 1104 "height": curHeight, 1105 "isFeature": false 1106 }; 1107 } 1108 } 1109 1110 // Define the coordinates that represent the bluff 1111 for (var p = 0; p < points.length; ++p) 1112 { 1113 var pt = points[p]; 1114 bb[pt.x - corners.minX][pt.z - corners.minZ].isFeature = true; 1115 } 1116 1117 return bb; 1118 } 1119 1120 /** 1121 * Flattens the ground touching a terrain feature. 1122 */ 1123 function fadeToGround(bb, minX, minZ, elevation) 1124 { 1125 var ground = createTerrain(g_Terrains.mainTerrain); 1126 for (var x = 0; x < bb.length; ++x) 1127 for (var z = 0; z < bb[x].length; ++z) 1128 { 1129 var pt = bb[x][z]; 1130 if (!pt.isFeature && nextToFeature(bb, x, z)) 1131 { 1132 var newEl = smoothElevation(x + minX, z + minZ); 1133 g_Map.setHeight(x + minX, z + minZ, newEl); 1134 ground.place(x + minX, z + minZ); 1135 } 1136 } 1137 } 1138 1139 /** 1140 * Find a 45 degree line in a bounding box that does not intersect any terrain feature. 1141 */ 1142 function findClearLine(bb, corners, angle) 1143 { 1144 // Angle - 0: northwest; 1: northeast; 2: southeast; 3: southwest 1145 var z = corners.maxZ; 1146 var xOffset = -1; 1147 var zOffset = -1; 1148 1149 switch(angle) 1150 { 1151 case 1: 1152 xOffset = 1; 1153 break; 1154 case 2: 1155 xOffset = 1; 1156 zOffset = 1; 1157 z = corners.minZ; 1158 break; 1159 case 3: 1160 zOffset = 1; 1161 z = corners.minZ; 1162 break; 1163 } 1164 1165 var clearLine = {}; 1166 1167 for (var x = corners.minX; x <= corners.maxX; ++x) 1168 { 1169 var x2 = x; 1170 var z2 = z; 1171 1172 var clear = true; 1173 1174 while (x2 >= corners.minX && x2 <= corners.maxX && z2 >= corners.minZ && z2 <= corners.maxZ) 1175 { 1176 var bp = bb[x2 - corners.minX][z2 - corners.minZ]; 1177 if (bp.isFeature && g_Map.validT(x2, z2)) 1178 { 1179 clear = false; 1180 break; 1181 } 1182 1183 x2 = x2 + xOffset; 1184 z2 = z2 + zOffset; 1185 } 1186 1187 if (clear) 1188 { 1189 var lastX = x2 - xOffset; 1190 var lastZ = z2 - zOffset; 1191 var midX = Math.floor((x + lastX) / 2); 1192 var midZ = Math.floor((z + lastZ) / 2); 1193 clearLine = { 1194 "x1": x, 1195 "z1": z, 1196 "x2": lastX, 1197 "z2": lastZ, 1198 "midX": midX, 1199 "midZ": midZ, 1200 "height": g_MapInfo.mapHeight 1201 }; 1202 } 1203 1204 if (clear && (angle == 1 || angle == 2)) 1205 break; 1206 1207 if (!clear && (angle == 0 || angle == 3)) 1208 break; 1209 } 1210 1211 return clearLine; 1212 } 1213 1214 /** 1215 * Returns the corners of a bounding box. 1216 */ 1217 function findCorners(points) 1218 { 1219 // Find the bounding box of the terrain feature 1220 var minX = g_MapInfo.mapSize + 1; 1221 var minZ = g_MapInfo.mapSize + 1; 1222 var maxX = -1; 1223 var maxZ = -1; 1224 1225 for (var p = 0; p < points.length; ++p) 1226 { 1227 var pt = points[p]; 1228 1229 minX = Math.min(pt.x, minX); 1230 minZ = Math.min(pt.z, minZ); 1231 1232 maxX = Math.max(pt.x, maxX); 1233 maxZ = Math.max(pt.z, maxZ); 1234 } 1235 1236 return { 1237 "minX": minX, 1238 "minZ": minZ, 1239 "maxX": maxX, 1240 "maxZ": maxZ 1241 }; 1242 } 1243 1244 /** 1245 * Finds the average elevation around a point. 1246 */ 1247 function smoothElevation(x, z) 1248 { 1249 var min = g_Map.getHeight(x, z); 1250 1251 for (var xOffset = -1; xOffset <= 1; ++xOffset) 1252 for (var zOffset = -1; zOffset <= 1; ++zOffset) 1253 { 1254 var thisX = x + xOffset; 1255 var thisZ = z + zOffset; 1256 if (!g_Map.validT(thisX, thisZ)) 1257 continue; 1258 1259 var height = g_Map.getHeight(thisX, thisZ); 1260 if (height < min) 1261 min = height; 1262 } 1263 1264 return min; 1265 } 1266 1267 /** 1268 * Determines if a point in a bounding box array is next to a terrain feature. 1269 */ 1270 function nextToFeature(bb, x, z) 1271 { 1272 for (var xOffset = -1; xOffset <= 1; ++xOffset) 1273 for (var zOffset = -1; zOffset <= 1; ++zOffset) 1274 { 1275 var thisX = x + xOffset; 1276 var thisZ = z + zOffset; 1277 if (thisX < 0 || thisX >= bb.length || thisZ < 0 || thisZ >= bb[x].length || (thisX == 0 && thisZ == 0)) 1278 continue; 1279 1280 if (bb[thisX][thisZ].isFeature) 1281 return true; 1282 } 1283 1284 return false; 1285 } 1286 1287 /** 1288 * Returns a number within a random deviation of a base number. 1289 */ 1290 function getRandomDeviation(base, deviation) 1291 { 1292 deviation = Math.min(base, deviation); 1293 deviation = base + randInt(20 * deviation) / 10 - deviation; 1294 return deviation.toFixed(2); 1295 } -
binaries/data/mods/public/maps/random/rmgen/setup.js
1 const g_Amounts = { 2 "scarce": 0.2, 3 "few": 0.5, 4 "normal": 1, 5 "many": 1.75, 6 "tons": 3 7 }; 8 9 const g_Mixes = { 10 "same": 0, 11 "similar": 0.1, 12 "normal": 0.25, 13 "varied": 0.5, 14 "unique": 0.75 15 }; 16 17 const g_Sizes = { 18 "tiny": 0.5, 19 "small": 0.75, 20 "normal": 1, 21 "big": 1.25, 22 "huge": 1.5, 23 }; 24 25 const g_AllAmounts = Object.keys(g_Amounts); 26 const g_AllMixes = Object.keys(g_Mixes); 27 const g_AllSizes = Object.keys(g_Sizes); 28 29 const g_DefaultTileClasses = [ 30 "animals", 31 "baseResource", 32 "berries", 33 "bluff", 34 "bluffSlope", 35 "dirt", 36 "fish", 37 "food", 38 "forest", 39 "hill", 40 "land", 41 "map", 42 "metal", 43 "mountain", 44 "plateau", 45 "player", 46 "prop", 47 "ramp", 48 "rock", 49 "settlement", 50 "spine", 51 "valley", 52 "water" 53 ]; 54 55 var g_MapInfo; 56 var g_TileClasses; 57 58 var g_Terrains; 59 var g_Gaia; 60 var g_Decoratives; 61 var g_Forests; 62 63 /** 64 * Adds an array of elements to the map. 65 */ 66 function addElements(els) 67 { 68 for (var i = 0; i < els.length; ++i) 69 { 70 var stay = null; 71 if (els[i].stay !== undefined) 72 stay = els[i].stay; 73 74 els[i].func( 75 [avoidClasses.apply(null, els[i].avoid), stayClasses.apply(null, stay)], 76 pickSize(els[i].sizes), 77 pickMix(els[i].mixes), 78 pickAmount(els[i].amounts) 79 ); 80 } 81 } 82 83 /** 84 * Converts "amount" terms to numbers. 85 */ 86 function pickAmount(amounts) 87 { 88 var amount = amounts[randInt(amounts.length)]; 89 90 if (amount in g_Amounts) 91 return g_Amounts[amount]; 92 93 return g_Mixes.normal; 94 } 95 96 /** 97 * Converts "mix" terms to numbers. 98 */ 99 function pickMix(mixes) 100 { 101 var mix = mixes[randInt(mixes.length)]; 102 103 if (mix in g_Mixes) 104 return g_Mixes[mix]; 105 106 return g_Mixes.normal; 107 } 108 109 /** 110 * Converts "size" terms to numbers. 111 */ 112 function pickSize(sizes) 113 { 114 var size = sizes[randInt(sizes.length)]; 115 116 if (size in g_Sizes) 117 return g_Sizes[size]; 118 119 return g_Sizes.normal; 120 } 121 122 /** 123 * Paints the entire map with a single tile type. 124 */ 125 function resetTerrain(terrain, tc, elevation) 126 { 127 g_MapInfo.mapSize = getMapSize(); 128 g_MapInfo.mapArea = g_MapInfo.mapSize * g_MapInfo.mapSize; 129 g_MapInfo.centerOfMap = Math.floor(g_MapInfo.mapSize / 2); 130 g_MapInfo.mapRadius = -PI / 4; 131 132 var placer = new ClumpPlacer(g_MapInfo.mapArea, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap); 133 var terrainPainter = new LayeredPainter([terrain], []); 134 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, elevation, 1); 135 createArea(placer, [terrainPainter, elevationPainter, paintClass(tc)], null); 136 137 g_MapInfo.mapHeight = elevation; 138 } 139 140 /** 141 * Euclidian distance between two points. 142 */ 143 function euclid_distance(x1, z1, x2, z2) 144 { 145 return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(z2 - z1, 2)); 146 } 147 148 /** 149 * Chose starting locations for the given players. 150 * 151 * @param {string} type - "radial", "stacked", "stronghold", "random" 152 * @param {number} distance - radial distance from the center of the map 153 */ 154 function addBases(type, distance, groupedDistance) 155 { 156 type = type || "radial"; 157 distance = distance || 0.3; 158 groupedDistance = groupedDistance || 0.05; 159 160 var playerIDs = randomizePlayers(); 161 var players = {}; 162 163 switch(type) 164 { 165 case "line": 166 players = placeLine(playerIDs, distance, groupedDistance); 167 break; 168 case "radial": 169 players = placeRadial(playerIDs, distance); 170 break; 171 case "random": 172 players = placeRandom(playerIDs); 173 break; 174 case "stronghold": 175 players = placeStronghold(playerIDs, distance, groupedDistance); 176 break; 177 } 178 179 return players; 180 } 181 182 /** 183 * Create the base for a single player. 184 * 185 * @param {Object} - contains id, angle, x, z 186 * @param {boolean} - Whether or not iberian gets starting walls 187 */ 188 function createBase(player, walls) 189 { 190 // Get the x and z in tiles 191 var fx = fractionToTiles(player.x); 192 var fz = fractionToTiles(player.z); 193 var ix = round(fx); 194 var iz = round(fz); 195 addToClass(ix, iz, g_TileClasses.player); 196 addToClass(ix + 5, iz, g_TileClasses.player); 197 addToClass(ix, iz + 5, g_TileClasses.player); 198 addToClass(ix - 5, iz, g_TileClasses.player); 199 addToClass(ix, iz - 5, g_TileClasses.player); 200 201 // Create starting units 202 if ((walls || walls === undefined) && g_MapInfo.mapSize > 192) 203 placeCivDefaultEntities(fx, fz, player.id, g_MapInfo.mapRadius); 204 else 205 placeCivDefaultEntities(fx, fz, player.id, g_MapInfo.mapRadius, { 'iberWall': false }); 206 207 // Create the city patch 208 var cityRadius = scaleByMapSize(15, 25) / 3; 209 var placer = new ClumpPlacer(PI * cityRadius * cityRadius, 0.6, 0.3, 10, ix, iz); 210 var painter = new LayeredPainter([g_Terrains.roadWild, g_Terrains.road], [1]); 211 createArea(placer, painter, null); 212 213 // Custom base terrain function 214 215 // Create animals 216 for (var j = 0; j < 2; ++j) 217 { 218 var aAngle = randFloat(0, TWO_PI); 219 var aDist = 7; 220 var aX = round(fx + aDist * cos(aAngle)); 221 var aZ = round(fz + aDist * sin(aAngle)); 222 var group = new SimpleGroup( 223 [new SimpleObject(g_Gaia.chicken, 5, 5, 0, 2)], 224 true, g_TileClasses.baseResource, aX, aZ 225 ); 226 createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2)); 227 } 228 229 // Create berry bushes 230 var bbAngle = randFloat(0, TWO_PI); 231 var bbDist = 12; 232 var bbX = round(fx + bbDist * cos(bbAngle)); 233 var bbZ = round(fz + bbDist * sin(bbAngle)); 234 group = new SimpleGroup( 235 [new SimpleObject(g_Gaia.fruitBush, 5, 5, 0, 3)], 236 true, g_TileClasses.baseResource, bbX, bbZ 237 ); 238 createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2)); 239 240 // Create metal mine 241 var mAngle = bbAngle; 242 while(abs(mAngle - bbAngle) < PI / 3) 243 mAngle = randFloat(0, TWO_PI); 244 245 var mDist = 12; 246 var mX = round(fx + mDist * cos(mAngle)); 247 var mZ = round(fz + mDist * sin(mAngle)); 248 group = new SimpleGroup( 249 [new SimpleObject(g_Gaia.metalLarge, 1, 1, 0, 0)], 250 true, g_TileClasses.baseResource, mX, mZ 251 ); 252 createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2)); 253 254 // Create stone mines 255 mAngle += randFloat(PI / 8, PI / 4); 256 mX = round(fx + mDist * cos(mAngle)); 257 mZ = round(fz + mDist * sin(mAngle)); 258 group = new SimpleGroup( 259 [new SimpleObject(g_Gaia.stoneLarge, 1, 1, 0, 2)], 260 true, g_TileClasses.baseResource, mX, mZ 261 ); 262 createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2)); 263 264 var hillSize = PI * g_MapInfo.mapRadius * g_MapInfo.mapRadius; 265 266 // Create starting trees 267 var num = 5; 268 var tAngle = randFloat(0, TWO_PI); 269 var tDist = randFloat(12, 13); 270 var tX = round(fx + tDist * cos(tAngle)); 271 var tZ = round(fz + tDist * sin(tAngle)); 272 273 group = new SimpleGroup( 274 [new SimpleObject(g_Gaia.tree1, num, num, 0, 3)], 275 false, g_TileClasses.baseResource, tX, tZ 276 ); 277 createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2)); 278 279 // Create grass tufts 280 var num = hillSize / 250; 281 for (var j = 0; j < num; ++j) 282 { 283 var gAngle = randFloat(0, TWO_PI); 284 var gDist = g_MapInfo.mapRadius - (5 + randInt(7)); 285 var gX = round(fx + gDist * cos(gAngle)); 286 var gZ = round(fz + gDist * sin(gAngle)); 287 group = new SimpleGroup( 288 [new SimpleObject(g_Decoratives.grassShort, 2, 5, 0, 1, -PI / 8, PI / 8)], 289 false, g_TileClasses.baseResource, gX, gZ 290 ); 291 createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2)); 292 } 293 } 294 295 /** 296 * Return an array where each element is an array of playerIndices of a team. 297 */ 298 function getTeams(numPlayers) 299 { 300 // Group players by team 301 var teams = []; 302 for (var i = 0; i < numPlayers; ++i) 303 { 304 let team = getPlayerTeam(i); 305 if (team == -1) 306 continue; 307 308 if (!teams[team]) 309 teams[team] = []; 310 311 teams[team].push(i+1); 312 } 313 314 // Players without a team get a custom index 315 for (var i = 0; i < numPlayers; ++i) 316 if (getPlayerTeam(i) == -1) 317 teams.push([i+1]); 318 319 // Remove unused indices 320 return teams.filter(team => true); 321 } 322 323 /** 324 * Chose a random pattern for placing the bases of the players. 325 */ 326 function randomStartingPositionPattern() 327 { 328 var formats = ["radial"]; 329 330 // Enable stronghold if we have a few teams and a big enough map 331 if (g_MapInfo.teams.length >= 2 && g_MapInfo.numPlayers >= 4 && g_MapInfo.mapSize >= 256) 332 formats.push("stronghold"); 333 334 // Enable random if we have enough teams or enough players on a big enough map 335 if (g_MapInfo.mapSize >= 256 && (g_MapInfo.teams.length >= 3 || g_MapInfo.numPlayers > 4)) 336 formats.push("random"); 337 338 // Enable line if we have enough teams and players on a big enough map 339 if (g_MapInfo.teams.length >= 2 && g_MapInfo.numPlayers >= 4 && g_MapInfo.mapSize >= 384) 340 formats.push("line"); 341 342 return { 343 "setup": formats[randInt(formats.length)], 344 "distance": randFloat(0.2, 0.35), 345 "separation": randFloat(0.05, 0.1) 346 }; 347 } 348 349 /** 350 * Mix player indices but sort by team. 351 * 352 * @returns {Array} - every item is an array of player indices 353 */ 354 function randomizePlayers() 355 { 356 var playerIDs = []; 357 for (var i = 0; i < g_MapInfo.numPlayers; ++i) 358 playerIDs.push(i + 1); 359 360 return sortPlayers(playerIDs); 361 } 362 363 /** 364 * Place teams in a line-pattern. 365 * 366 * @param {Array} playerIDs - typically randomized indices of players of a single team 367 * @param {number} distance - radial distance from the center of the map 368 * @param {number} groupedDistance - distance between players 369 * 370 * @returns {Array} - contains id, angle, x, z for every player 371 */ 372 function placeLine(playerIDs, distance, groupedDistance) 373 { 374 var players = []; 375 376 for (var i = 0; i < g_MapInfo.teams.length; ++i) 377 { 378 var safeDist = distance; 379 if (distance + g_MapInfo.teams[i].length * groupedDistance > 0.45) 380 safeDist = 0.45 - g_MapInfo.teams[i].length * groupedDistance; 381 382 var teamAngle = g_MapInfo.startAngle + (i + 1) * TWO_PI / g_MapInfo.teams.length; 383 384 // Create player base 385 for (var p = 0; p < g_MapInfo.teams[i].length; ++p) 386 { 387 players[g_MapInfo.teams[i][p]] = { 388 "id": g_MapInfo.teams[i][p], 389 "angle": g_MapInfo.startAngle + (p + 1) * TWO_PI / g_MapInfo.teams[i].length, 390 "x": 0.5 + (safeDist + p * groupedDistance) * cos(teamAngle), 391 "z": 0.5 + (safeDist + p * groupedDistance) * sin(teamAngle) 392 }; 393 createBase(players[g_MapInfo.teams[i][p]], false); 394 } 395 } 396 397 return players; 398 } 399 400 /** 401 * Place players in a circle-pattern. 402 * 403 * @param {number} distance - radial distance from the center of the map 404 */ 405 function placeRadial(playerIDs, distance) 406 { 407 var players = new Array(g_MapInfo.numPlayers); 408 409 for (var i = 0; i < g_MapInfo.numPlayers; ++i) 410 { 411 var angle = g_MapInfo.startAngle + i * TWO_PI / g_MapInfo.numPlayers; 412 players[i] = { 413 "id": playerIDs[i], 414 "angle": angle, 415 "x": 0.5 + distance * cos(angle), 416 "z": 0.5 + distance * sin(angle) 417 }; 418 createBase(players[i]); 419 } 420 421 return players; 422 } 423 424 /** 425 * Chose arbitrary starting locations. 426 */ 427 function placeRandom(playerIDs) 428 { 429 var players = []; 430 var placed = []; 431 432 for (var i = 0; i < g_MapInfo.numPlayers; ++i) 433 { 434 var attempts = 0; 435 var playerAngle = randFloat(0, TWO_PI); 436 var distance = randFloat(0, 0.42); 437 var x = 0.5 + distance * cos(playerAngle); 438 var z = 0.5 + distance * sin(playerAngle); 439 440 var tooClose = false; 441 for (var j = 0; j < placed.length; ++j) 442 { 443 var sep = euclid_distance(x, z, placed[j].x, placed[j].z); 444 if (sep < 0.25) 445 { 446 tooClose = true; 447 break; 448 } 449 } 450 451 if (tooClose) 452 { 453 --i; 454 ++attempts; 455 456 // Reset if we're in what looks like an infinite loop 457 if (attempts > 100) 458 { 459 players = []; 460 placed = []; 461 i = -1; 462 attempts = 0; 463 } 464 465 continue; 466 } 467 468 players[i] = { 469 "id": playerIDs[i], 470 "angle": playerAngle, 471 "x": x, 472 "z": z 473 }; 474 475 placed.push(players[i]); 476 } 477 478 // Create the bases 479 for (var i = 0; i < g_MapInfo.numPlayers; ++i) 480 createBase(players[i]); 481 482 return players; 483 } 484 485 /** 486 * Place given players in a stronghold-pattern. 487 * 488 * @param distance - radial distance from the center of the map 489 * @param groupedDistance - distance between neighboring players 490 */ 491 function placeStronghold(playerIDs, distance, groupedDistance) 492 { 493 var players = []; 494 495 for (var i = 0; i < g_MapInfo.teams.length; ++i) 496 { 497 var teamAngle = g_MapInfo.startAngle + (i + 1) * TWO_PI / g_MapInfo.teams.length; 498 var fractionX = 0.5 + distance * cos(teamAngle); 499 var fractionZ = 0.5 + distance * sin(teamAngle); 500 501 // If we have a team of above average size, make sure they're spread out 502 if (g_MapInfo.teams[i].length > 4) 503 groupedDistance = randFloat(0.08, 0.12); 504 505 // If we have a team of below average size, make sure they're together 506 if (g_MapInfo.teams[i].length < 3) 507 groupedDistance = randFloat(0.04, 0.06); 508 509 // If we have a solo player, place them on the center of the team's location 510 if (g_MapInfo.teams[i].length == 1) 511 groupedDistance = 0; 512 513 // Create player base 514 for (var p = 0; p < g_MapInfo.teams[i].length; ++p) 515 { 516 var angle = g_MapInfo.startAngle + (p + 1) * TWO_PI / g_MapInfo.teams[i].length; 517 players[g_MapInfo.teams[i][p]] = { 518 "id": g_MapInfo.teams[i][p], 519 "angle": angle, 520 "x": fractionX + groupedDistance * cos(angle), 521 "z": fractionZ + groupedDistance * sin(angle) 522 }; 523 createBase(players[g_MapInfo.teams[i][p]], false); 524 } 525 } 526 527 return players; 528 } 529 530 /** 531 * Creates tileClass for the default classes and every class given. 532 * 533 * @param {Array} newClasses 534 * @returns {Object} - maps from classname to ID 535 */ 536 function initTileClasses(newClasses) 537 { 538 var classNames = g_DefaultTileClasses; 539 540 if (newClasses !== undefined) 541 classNames = classNames.concat(newClasses); 542 543 g_TileClasses = {}; 544 for (var className of classNames) 545 g_TileClasses[className] = createTileClass(); 546 } 547 548 /** 549 * Get biome-specific names of entities and terrain after randomization. 550 */ 551 function initBiome() 552 { 553 g_Terrains = { 554 "mainTerrain": rBiomeT1(), 555 "forestFloor1": rBiomeT2(), 556 "forestFloor2": rBiomeT3(), 557 "cliff": rBiomeT4(), 558 "tier1Terrain": rBiomeT5(), 559 "tier2Terrain": rBiomeT6(), 560 "tier3Terrain": rBiomeT7(), 561 "hill": rBiomeT8(), 562 "dirt": rBiomeT9(), 563 "road": rBiomeT10(), 564 "roadWild": rBiomeT11(), 565 "tier4Terrain": rBiomeT12(), 566 "shoreBlend": rBiomeT13(), 567 "shore": rBiomeT14(), 568 "water": rBiomeT15() 569 }; 570 571 g_Gaia = { 572 "tree1": rBiomeE1(), 573 "tree2": rBiomeE2(), 574 "tree3": rBiomeE3(), 575 "tree4": rBiomeE4(), 576 "tree5": rBiomeE5(), 577 "fruitBush": rBiomeE6(), 578 "chicken": rBiomeE7(), 579 "mainHuntableAnimal": rBiomeE8(), 580 "fish": rBiomeE9(), 581 "secondaryHuntableAnimal": rBiomeE10(), 582 "stoneLarge": rBiomeE11(), 583 "stoneSmall": rBiomeE12(), 584 "metalLarge": rBiomeE13() 585 }; 586 587 g_Decoratives = { 588 "grass": rBiomeA1(), 589 "grassShort": rBiomeA2(), 590 "reeds": rBiomeA3(), 591 "lillies": rBiomeA4(), 592 "rockLarge": rBiomeA5(), 593 "rockMedium": rBiomeA6(), 594 "bushMedium": rBiomeA7(), 595 "bushSmall": rBiomeA8(), 596 "tree": rBiomeA9() 597 }; 598 599 g_Forests = { 600 "forest1": [ 601 g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree1, 602 g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree2, 603 g_Terrains.forestFloor2 604 ], 605 "forest2": [ 606 g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree4, 607 g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree5, 608 g_Terrains.forestFloor1 609 ] 610 }; 611 } 612 613 /** 614 * Creates an object of commonly used functions. 615 */ 616 function initMapSettings() 617 { 618 initBiome(); 619 620 let numPlayers = getNumPlayers(); 621 g_MapInfo = { 622 "biome": biomeID, 623 "numPlayers": numPlayers, 624 "teams": getTeams(numPlayers), 625 "startAngle": randFloat(0, TWO_PI) 626 }; 627 } -
binaries/data/mods/public/maps/random/stronghold.js
1 RMS.LoadLibrary("rmgen"); 2 InitMap(); 3 4 randomizeBiome(); 5 initMapSettings(); 6 initTileClasses(); 7 8 resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 30); 9 RMS.SetProgress(20); 10 11 addBases("stronghold", randFloat(0.2, 0.35), randFloat(0.05, 0.1)); 12 RMS.SetProgress(30); 13 14 addElements(shuffleArray([ 15 { 16 "func": addBluffs, 17 "avoid": [ 18 g_TileClasses.bluff, 20, 19 g_TileClasses.hill, 5, 20 g_TileClasses.mountain, 20, 21 g_TileClasses.plateau, 20, 22 g_TileClasses.player, 30, 23 g_TileClasses.valley, 5, 24 g_TileClasses.water, 7 25 ], 26 "sizes": ["big", "huge"], 27 "mixes": g_AllMixes, 28 "amounts": g_AllAmounts 29 }, 30 { 31 "func": addHills, 32 "avoid": [ 33 g_TileClasses.bluff, 5, 34 g_TileClasses.hill, 15, 35 g_TileClasses.mountain, 2, 36 g_TileClasses.plateau, 2, 37 g_TileClasses.player, 20, 38 g_TileClasses.valley, 2, 39 g_TileClasses.water, 2 40 ], 41 "sizes": ["normal", "big"], 42 "mixes": g_AllMixes, 43 "amounts": g_AllAmounts 44 }, 45 { 46 "func": addMountains, 47 "avoid": [ 48 g_TileClasses.bluff, 20, 49 g_TileClasses.mountain, 25, 50 g_TileClasses.plateau, 20, 51 g_TileClasses.player, 20, 52 g_TileClasses.valley, 10, 53 g_TileClasses.water, 15 54 ], 55 "sizes": ["big", "huge"], 56 "mixes": g_AllMixes, 57 "amounts": g_AllAmounts 58 }, 59 { 60 "func": addPlateaus, 61 "avoid": [ 62 g_TileClasses.bluff, 20, 63 g_TileClasses.mountain, 25, 64 g_TileClasses.plateau, 25, 65 g_TileClasses.player, 40, 66 g_TileClasses.valley, 10, 67 g_TileClasses.water, 15 68 ], 69 "sizes": ["big", "huge"], 70 "mixes": g_AllMixes, 71 "amounts": g_AllAmounts 72 }, 73 { 74 "func": addValleys, 75 "avoid": [g_TileClasses.bluff, 5, 76 g_TileClasses.hill, 5, 77 g_TileClasses.mountain, 25, 78 g_TileClasses.plateau, 10, 79 g_TileClasses.player, 40, 80 g_TileClasses.valley, 15, 81 g_TileClasses.water, 10 82 ], 83 "sizes": ["normal", "big"], 84 "mixes": g_AllMixes, 85 "amounts": g_AllAmounts 86 } 87 ])); 88 RMS.SetProgress(60); 89 90 addElements([ 91 { 92 "func": addLayeredPatches, 93 "avoid": [ 94 g_TileClasses.bluff, 2, 95 g_TileClasses.dirt, 5, 96 g_TileClasses.forest, 2, 97 g_TileClasses.mountain, 2, 98 g_TileClasses.plateau, 2, 99 g_TileClasses.player, 12, 100 g_TileClasses.valley, 5, 101 g_TileClasses.water, 3 102 ], 103 "sizes": ["normal"], 104 "mixes": ["normal"], 105 "amounts": ["normal"] 106 }, 107 { 108 "func": addDecoration, 109 "avoid": [ 110 g_TileClasses.bluff, 2, 111 g_TileClasses.forest, 2, 112 g_TileClasses.mountain, 2, 113 g_TileClasses.plateau, 2, 114 g_TileClasses.player, 12, 115 g_TileClasses.water, 3 116 ], 117 "sizes": ["normal"], 118 "mixes": ["normal"], 119 "amounts": ["normal"] 120 } 121 ]); 122 RMS.SetProgress(70); 123 124 addElements(shuffleArray([ 125 { 126 "func": addMetal, 127 "avoid": [ 128 g_TileClasses.berries, 5, 129 g_TileClasses.bluff, 5, 130 g_TileClasses.forest, 3, 131 g_TileClasses.mountain, 2, 132 g_TileClasses.plateau, 2, 133 g_TileClasses.player, 30, 134 g_TileClasses.rock, 10, 135 g_TileClasses.metal, 20, 136 g_TileClasses.water, 3 137 ], 138 "sizes": ["normal"], 139 "mixes": ["same"], 140 "amounts": g_AllAmounts 141 }, 142 { 143 "func": addStone, 144 "avoid": [ 145 g_TileClasses.berries, 5, 146 g_TileClasses.bluff, 5, 147 g_TileClasses.forest, 3, 148 g_TileClasses.mountain, 2, 149 g_TileClasses.plateau, 2, 150 g_TileClasses.player, 30, 151 g_TileClasses.rock, 20, 152 g_TileClasses.metal, 10, 153 g_TileClasses.water, 3 154 ], 155 "sizes": ["normal"], 156 "mixes": ["same"], 157 "amounts": g_AllAmounts 158 }, 159 { 160 "func": addForests, 161 "avoid": [ 162 g_TileClasses.berries, 163 5, g_TileClasses.bluff, 164 5, g_TileClasses.forest, 165 18, g_TileClasses.metal, 3, 166 g_TileClasses.mountain, 5, 167 g_TileClasses.plateau, 5, 168 g_TileClasses.player, 20, 169 g_TileClasses.rock, 3, 170 g_TileClasses.water, 2 171 ], 172 "sizes": g_AllSizes, 173 "mixes": g_AllMixes, 174 "amounts": ["few", "normal", "many", "tons"] 175 } 176 ])); 177 RMS.SetProgress(80); 178 179 addElements(shuffleArray([ 180 { 181 "func": addBerries, 182 "avoid": [ 183 g_TileClasses.berries, 30, 184 g_TileClasses.bluff, 5, 185 g_TileClasses.forest, 5, 186 g_TileClasses.metal, 10, 187 g_TileClasses.mountain, 2, 188 g_TileClasses.plateau, 2, 189 g_TileClasses.player, 20, 190 g_TileClasses.rock, 10, 191 g_TileClasses.spine, 2, 192 g_TileClasses.water, 3 193 ], 194 "sizes": g_AllSizes, 195 "mixes": g_AllMixes, 196 "amounts": g_AllAmounts 197 }, 198 { 199 "func": addAnimals, 200 "avoid": [ 201 g_TileClasses.animals, 20, 202 g_TileClasses.bluff, 5, 203 g_TileClasses.forest, 2, 204 g_TileClasses.metal, 2, 205 g_TileClasses.mountain, 1, 206 g_TileClasses.plateau, 2, 207 g_TileClasses.player, 20, 208 g_TileClasses.rock, 2, 209 g_TileClasses.spine, 2, 210 g_TileClasses.water, 3 211 ], 212 "sizes": g_AllSizes, 213 "mixes": g_AllMixes, 214 "amounts": g_AllAmounts 215 }, 216 { 217 "func": addStragglerTrees, 218 "avoid": [ 219 g_TileClasses.berries, 5, 220 g_TileClasses.bluff, 5, 221 g_TileClasses.forest, 7, 222 g_TileClasses.metal, 2, 223 g_TileClasses.mountain, 1, 224 g_TileClasses.plateau, 2, 225 g_TileClasses.player, 12, 226 g_TileClasses.rock, 2, 227 g_TileClasses.spine, 2, 228 g_TileClasses.water, 5 229 ], 230 "sizes": g_AllSizes, 231 "mixes": g_AllMixes, 232 "amounts": g_AllAmounts 233 } 234 ])); 235 RMS.SetProgress(90); 236 237 ExportMap(); -
binaries/data/mods/public/maps/random/stronghold.json
1 { 2 "settings" : { 3 "Name" : "Stronghold", 4 "Script" : "stronghold.js", 5 "Description" : "Teams start off with nearly adjacent town centers, offering easy military and construction cooperation. With slivers of personal territory, teammates must rely on each other to defend their rear.", 6 "BaseTerrain" : ["medit_sea_depths"], 7 "BaseHeight" : 30, 8 "Preview" : "stronghold.png", 9 "CircularMap" : true 10 } 11 }