1 | RMS.LoadLibrary("rmgen");
|
---|
2 |
|
---|
3 | // initialize map
|
---|
4 | log("Initializing map...");
|
---|
5 | InitMap();
|
---|
6 |
|
---|
7 |
|
---|
8 | // Setup tile classes
|
---|
9 | var clPlayer = createTileClass();
|
---|
10 | var clPath = createTileClass();
|
---|
11 | var clHill = createTileClass();
|
---|
12 | var clForest = createTileClass();
|
---|
13 | // var clWater = createTileClass();
|
---|
14 | // var clRock = createTileClass();
|
---|
15 | // var clFood = createTileClass();
|
---|
16 | var clBaseResource = createTileClass();
|
---|
17 |
|
---|
18 | // Setup Templates
|
---|
19 | var templateStone = "gaia/geology_stone_temperate"
|
---|
20 | var templateStoneMine = "gaia/geology_stonemine_temperate_quarry";
|
---|
21 | var templateMetal = "gaia/geology_metal_temperate";
|
---|
22 | var templateMetalMine = "gaia/geology_metal_temperate_slabs";
|
---|
23 | var startingResourcees = ["gaia/flora_tree_oak_large", "gaia/flora_bush_temperate", templateStoneMine,
|
---|
24 | "gaia/flora_bush_grapes", "gaia/flora_tree_apple", "gaia/flora_bush_berry", templateMetalMine, "gaia/flora_bush_badlands"];
|
---|
25 |
|
---|
26 | // Setup terrain
|
---|
27 | var terrainWood = ['temp_grass_mossy|gaia/flora_tree_oak', 'temp_forestfloor_pine|gaia/flora_tree_pine', 'temp_mud_plants|gaia/flora_tree_dead',
|
---|
28 | 'temp_plants_bog|gaia/flora_tree_oak_large', 'temp_plants_bog|gaia/flora_tree_pine_animated',
|
---|
29 | "temp_dirt_gravel_plants|gaia/flora_tree_aleppo_pine", 'temp_forestfloor_autumn|gaia/flora_tree_carob']; //'temp_forestfloor_autumn|gaia/flora_tree_fig'
|
---|
30 | var terrainWoodBorder = ['temp_grass_plants|gaia/flora_tree_euro_beech', 'temp_grass_mossy|gaia/flora_tree_poplar', 'temp_grass_mossy|gaia/flora_tree_poplar_lombardy',
|
---|
31 | 'temp_grass_long|gaia/flora_bush_temperate', 'temp_mud_plants|gaia/flora_bush_temperate', 'temp_mud_plants|gaia/flora_bush_badlands',
|
---|
32 | 'temp_grass_long|gaia/flora_tree_apple', 'temp_grass_clovers|gaia/flora_bush_berry', 'temp_grass_clovers_2|gaia/flora_bush_grapes',
|
---|
33 | 'temp_grass_plants|gaia/fauna_deer', "temp_grass_long_b|gaia/fauna_rabbit", "temp_grass_plants"];
|
---|
34 | var terrainBase = ['temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
|
---|
35 | 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
|
---|
36 | 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
|
---|
37 | 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
|
---|
38 | 'temp_grass_b|gaia/fauna_pig', 'temp_dirt_gravel|gaia/fauna_chicken'];
|
---|
39 | var terrainBaseBorder = ["temp_grass_b", "temp_grass_b", "temp_grass", "temp_grass_c", "temp_grass_mossy"];
|
---|
40 | var terrainPath = ['temp_road', "temp_road_overgrown", 'temp_grass_b'];
|
---|
41 | var terrainHill = ["temp_highlands", "temp_highlands", "temp_highlands", "temp_dirt_gravel_b", "temp_cliff_a"];
|
---|
42 | var terrainHillBorder = ["temp_highlands", "temp_highlands", "temp_highlands", "temp_dirt_gravel_b", "temp_dirt_gravel_plants",
|
---|
43 | "temp_highlands", "temp_highlands", "temp_highlands", "temp_dirt_gravel_b", "temp_dirt_gravel_plants",
|
---|
44 | "temp_highlands", "temp_highlands", "temp_highlands", "temp_cliff_b", "temp_dirt_gravel_plants",
|
---|
45 | "temp_highlands", "temp_highlands", "temp_highlands", "temp_cliff_b", "temp_dirt_gravel_plants",
|
---|
46 | "temp_highlands|gaia/fauna_goat"];
|
---|
47 |
|
---|
48 |
|
---|
49 | // Setup map
|
---|
50 | var mapSize = getMapSize();
|
---|
51 | var mapRadius = mapSize/2;
|
---|
52 | var playableMapRadius = mapRadius - 5;
|
---|
53 | var mapCenterX = mapRadius;
|
---|
54 | var mapCenterZ = mapRadius;
|
---|
55 |
|
---|
56 | // Setup players and bases
|
---|
57 | var numPlayers = getNumPlayers();
|
---|
58 | var baseRadius = 20;
|
---|
59 | var minPlayerRadius = min(mapRadius-1.5*baseRadius, 5*mapRadius/8);
|
---|
60 | var maxPlayerRadius = min(mapRadius-baseRadius, 3*mapRadius/4);
|
---|
61 | const BUILDING_ANlE = -PI/4;
|
---|
62 | var playerStartLocX = new Array(numPlayers);
|
---|
63 | var playerStartLocZ = new Array(numPlayers);
|
---|
64 | var playerAngle = new Array(numPlayers);
|
---|
65 | var playerAngleStart = randFloat(0, 2*PI);
|
---|
66 | var playerAngleAddAvrg = 2*PI / numPlayers;
|
---|
67 | var playerAngleMaxOff = playerAngleAddAvrg/4;
|
---|
68 |
|
---|
69 | // Setup eyecandy
|
---|
70 | var templateEC = "other/unfinished_greek_temple";
|
---|
71 | var radiusEC = max(mapRadius/8, baseRadius/2);
|
---|
72 |
|
---|
73 | // Setup paths
|
---|
74 | var pathSucsessRadius = baseRadius/2;
|
---|
75 | var pathAngleOff = PI/2;
|
---|
76 | var pathWidth = 5; // This is not really the path's sickness in tiles but the number of tiles in the clumbs of the path
|
---|
77 |
|
---|
78 | // Setup additional resources
|
---|
79 | var resourceRadius = 2*mapRadius/3; // 3*mapRadius/8;
|
---|
80 | var resourcePerPlayer = [templateStone, templateMetalMine];
|
---|
81 |
|
---|
82 | // Setup woods
|
---|
83 | var maxTreeDensity = min(256*256/mapSize/mapSize, 1); // Has to be tweeked but works ok
|
---|
84 | var bushChance = 1/3; // 1 means 50% chance in deepest wood, 0.5 means 25% chance in deepest wood
|
---|
85 | RMS.SetProgress(2);
|
---|
86 | // Place bases
|
---|
87 | for (var i=0; i < numPlayers; i++)
|
---|
88 | {
|
---|
89 | var civ = g_MapSettings.PlayerData[i].Civ;
|
---|
90 | var startEntities = getStartingEntities(i);
|
---|
91 | playerAngle[i] = (playerAngleStart + i*playerAngleAddAvrg + randFloat(0, playerAngleMaxOff))%(2*PI);
|
---|
92 | var x = round(mapCenterX + randFloat(minPlayerRadius, maxPlayerRadius)*cos(playerAngle[i]));
|
---|
93 | var z = round(mapCenterZ + randFloat(minPlayerRadius, maxPlayerRadius)*sin(playerAngle[i]));
|
---|
94 | playerStartLocX[i] = x;
|
---|
95 | playerStartLocZ[i] = z;
|
---|
96 | // Place starting entities
|
---|
97 | createStartingPlayerEntities(x, z, i+1, startEntities, BUILDING_ANlE)
|
---|
98 | // Place base texture
|
---|
99 | var placer = new ClumpPlacer(2*baseRadius*baseRadius, 2/3, 1/8, 10, x, z);
|
---|
100 | var painter = [new LayeredPainter([terrainBaseBorder, terrainBase], [baseRadius/4]), paintClass(clPlayer)];
|
---|
101 | createArea(placer, painter);
|
---|
102 | // Place starting resources
|
---|
103 | var distToSL = 10;
|
---|
104 | var resStartAngle = playerAngle[i] + PI;
|
---|
105 | var resAddAngle = 2*PI / startingResourcees.length;
|
---|
106 | for (var rIndex = 0; rIndex < startingResourcees.length; rIndex++)
|
---|
107 | {
|
---|
108 | var angleOff = randFloat(-resAddAngle/2, resAddAngle/2);
|
---|
109 | var placeX = x + distToSL*cos(resStartAngle + rIndex*resAddAngle + angleOff);
|
---|
110 | var placeZ = z + distToSL*sin(resStartAngle + rIndex*resAddAngle + angleOff);
|
---|
111 | placeObject(placeX, placeZ, startingResourcees[rIndex], 0, randFloat(0, 2*PI));
|
---|
112 | addToClass(round(placeX), round(placeZ), clBaseResource);
|
---|
113 | };
|
---|
114 | };
|
---|
115 |
|
---|
116 | RMS.SetProgress(10);
|
---|
117 |
|
---|
118 | // Place paths
|
---|
119 | var doublePaths = true;
|
---|
120 | if (numPlayers > 4)
|
---|
121 | doublePaths = false;
|
---|
122 | var doublePathMayPlayers = 4;
|
---|
123 | if (doublePaths == true)
|
---|
124 | var maxI = numPlayers+1
|
---|
125 | else
|
---|
126 | var maxI = numPlayers;
|
---|
127 | for (var i = 0; i < maxI; i++)
|
---|
128 | {
|
---|
129 | if (doublePaths == true)
|
---|
130 | var minJ = 0
|
---|
131 | else
|
---|
132 | var minJ = i+1;
|
---|
133 | for (var j = minJ; j < numPlayers+1; j++)
|
---|
134 | {
|
---|
135 | // Setup start and target coordinates
|
---|
136 | if (i < numPlayers)
|
---|
137 | {
|
---|
138 | var x = playerStartLocX[i];
|
---|
139 | var z = playerStartLocZ[i];
|
---|
140 | }
|
---|
141 | else
|
---|
142 | {
|
---|
143 | var x = mapCenterX;
|
---|
144 | var z = mapCenterZ;
|
---|
145 | };
|
---|
146 | if (j < numPlayers)
|
---|
147 | {
|
---|
148 | var targetX = playerStartLocX[j];
|
---|
149 | var targetZ = playerStartLocZ[j];
|
---|
150 | }
|
---|
151 | else
|
---|
152 | {
|
---|
153 | var targetX = mapCenterX;
|
---|
154 | var targetZ = mapCenterZ;
|
---|
155 | };
|
---|
156 | // Prepare path placement
|
---|
157 | var angle = getAngle(x, z, targetX, targetZ);
|
---|
158 | x += round(pathSucsessRadius*cos(angle));
|
---|
159 | z += round(pathSucsessRadius*sin(angle));
|
---|
160 | var targetReached = false;
|
---|
161 | var tries = 0;
|
---|
162 | // Placing paths
|
---|
163 | while (targetReached == false && tries < 2*mapSize)
|
---|
164 | {
|
---|
165 | var placer = new ClumpPlacer(pathWidth, 1, 1, 1, x, z);
|
---|
166 | var painter = [new TerrainPainter(terrainPath), new ElevationPainter(-randFloat()), paintClass(clPath)];
|
---|
167 | createArea(placer, painter, avoidClasses(clHill, 0, clBaseResource, 4));
|
---|
168 | // addToClass(x, z, clPath); // Not needed...
|
---|
169 | // Set vars for next loop
|
---|
170 | angle = getAngle(x, z, targetX, targetZ);
|
---|
171 | if (doublePaths == true) // Bended paths
|
---|
172 | {
|
---|
173 | x += round(cos(angle + randFloat(-pathAngleOff/2, 3*pathAngleOff/2)));
|
---|
174 | z += round(sin(angle + randFloat(-pathAngleOff/2, 3*pathAngleOff/2)));
|
---|
175 | }
|
---|
176 | else // Straight paths
|
---|
177 | {
|
---|
178 | x += round(cos(angle + randFloat(-pathAngleOff, pathAngleOff)));
|
---|
179 | z += round(sin(angle + randFloat(-pathAngleOff, pathAngleOff)));
|
---|
180 | };
|
---|
181 | if (getDistance(x, z, targetX, targetZ) < pathSucsessRadius)
|
---|
182 | targetReached = true;
|
---|
183 | tries++;
|
---|
184 |
|
---|
185 | };
|
---|
186 | };
|
---|
187 | };
|
---|
188 |
|
---|
189 | RMS.SetProgress(50);
|
---|
190 |
|
---|
191 | // Place expansion resources
|
---|
192 | for (var i=0; i < numPlayers; i++)
|
---|
193 | {
|
---|
194 | for (var rIndex = 0; rIndex < resourcePerPlayer.length; rIndex++)
|
---|
195 | {
|
---|
196 | if (numPlayers > 1)
|
---|
197 | var angleDist = (playerAngle[(i+1)%numPlayers] - playerAngle[i] + 2*PI)%(2*PI);
|
---|
198 | else
|
---|
199 | var angleDist = 2*PI;
|
---|
200 | var placeX = round(mapCenterX + resourceRadius*cos(playerAngle[i] + (rIndex+1)*angleDist/(resourcePerPlayer.length+1)));
|
---|
201 | var placeZ = round(mapCenterX + resourceRadius*sin(playerAngle[i] + (rIndex+1)*angleDist/(resourcePerPlayer.length+1)));
|
---|
202 | placeObject(placeX, placeZ, resourcePerPlayer[rIndex], 0, randFloat(0, 2*PI));
|
---|
203 | var placer = new ClumpPlacer(40, 1/2, 1/8, 1, placeX, placeZ);
|
---|
204 | var painter = [new LayeredPainter([terrainHillBorder, terrainHill], [1]), new ElevationPainter(1+randFloat()), paintClass(clHill)];
|
---|
205 | createArea(placer, painter);
|
---|
206 | };
|
---|
207 | };
|
---|
208 |
|
---|
209 | RMS.SetProgress(60);
|
---|
210 |
|
---|
211 | // Place eyecandy
|
---|
212 | placeObject(mapCenterX, mapCenterZ, templateEC, 0, randFloat(0, 2*PI));
|
---|
213 | var placer = new ClumpPlacer(radiusEC*radiusEC, 1/2, 1/8, 1, mapCenterX, mapCenterZ);
|
---|
214 | var painter = [new LayeredPainter([terrainHillBorder, terrainHill], [radiusEC/4]), new ElevationPainter(1+randFloat()), paintClass(clHill)];
|
---|
215 | createArea(placer, painter);
|
---|
216 |
|
---|
217 | // Woods and general hight map
|
---|
218 | for (var x = 0; x < mapSize; x++)
|
---|
219 | {
|
---|
220 | for (var z = 0;z < mapSize;z++)
|
---|
221 | {
|
---|
222 | // Some variables
|
---|
223 | var radius = Math.pow(Math.pow(mapCenterX - x, 2) + Math.pow(mapCenterZ - z, 2), 1/2);
|
---|
224 | var minDistToSL = mapSize;
|
---|
225 | for (var i=0; i < numPlayers; i++)
|
---|
226 | minDistToSL = min(minDistToSL, getDistance(playerStartLocX[i], playerStartLocZ[i], x, z))
|
---|
227 | // Woods tile based
|
---|
228 | var tDensFactSL = max(min((minDistToSL - baseRadius) / baseRadius, 1), 0);
|
---|
229 | var tDensFactRad = abs((resourceRadius - radius) / resourceRadius);
|
---|
230 | var tDensFactEC = max(min((radius - radiusEC) / radiusEC, 1), 0);
|
---|
231 | var tDensActual = maxTreeDensity * tDensFactSL * tDensFactRad * tDensFactEC;
|
---|
232 | if (randFloat() < tDensActual && radius < playableMapRadius)
|
---|
233 | {
|
---|
234 | if (tDensActual < bushChance*randFloat()*maxTreeDensity)
|
---|
235 | {
|
---|
236 | var placer = new ClumpPlacer(1, 1.0, 1.0, 1, x, z);
|
---|
237 | var painter = [new TerrainPainter(terrainWoodBorder), new ElevationPainter(randFloat()), paintClass(clForest)];
|
---|
238 | createArea(placer, painter, avoidClasses(clPath, 1, clHill, 0));
|
---|
239 | }
|
---|
240 | else
|
---|
241 | {
|
---|
242 | var placer = new ClumpPlacer(1, 1.0, 1.0, 1, x, z);
|
---|
243 | var painter = [new TerrainPainter(terrainWood), new ElevationPainter(randFloat()), paintClass(clForest)];
|
---|
244 | createArea(placer, painter, avoidClasses(clPath, 2, clHill, 1));
|
---|
245 | };
|
---|
246 | };
|
---|
247 | // General hight map
|
---|
248 | var hVarMiddleHill = mapSize/64 * (1+cos(3*PI/2 * radius/mapRadius));
|
---|
249 | var hVarHills = 5*(1+sin(x/10)*sin(z/10));
|
---|
250 | setHeight(x, z, getHeight(x, z) + hVarMiddleHill + hVarHills + 1);
|
---|
251 | };
|
---|
252 | };
|
---|
253 |
|
---|
254 | RMS.SetProgress(95);
|
---|
255 |
|
---|
256 |
|
---|
257 | // Export map data
|
---|
258 | ExportMap();
|
---|