Micropolis
generate.cpp
Go to the documentation of this file.
1 /* generate.cpp
2  *
3  * Micropolis, Unix Version. This game was released for the Unix platform
4  * in or about 1990 and has been modified for inclusion in the One Laptop
5  * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If
6  * you need assistance with this program, you may contact:
7  * http://wiki.laptop.org/go/Micropolis or email micropolis@laptop.org.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or (at
12  * your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details. You should have received a
18  * copy of the GNU General Public License along with this program. If
19  * not, see <http://www.gnu.org/licenses/>.
20  *
21  * ADDITIONAL TERMS per GNU GPL Section 7
22  *
23  * No trademark or publicity rights are granted. This license does NOT
24  * give you any right, title or interest in the trademark SimCity or any
25  * other Electronic Arts trademark. You may not distribute any
26  * modification of this program using the trademark SimCity or claim any
27  * affliation or association with Electronic Arts Inc. or its employees.
28  *
29  * Any propagation or conveyance of this program must include this
30  * copyright notice and these terms.
31  *
32  * If you convey this program (or any modifications of it) and assume
33  * contractual liability for the program to recipients of it, you agree
34  * to indemnify Electronic Arts for any liability that those contractual
35  * assumptions impose on Electronic Arts.
36  *
37  * You may not misrepresent the origins of this program; modified
38  * versions of the program must be marked as such and not identified as
39  * the original program.
40  *
41  * This disclaimer supplements the one included in the General Public
42  * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
43  * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
44  * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF
45  * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS
46  * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
47  * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
48  * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
49  * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
50  * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST
51  * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
52  * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
53  * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
54  * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
55  * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
56  * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME
57  * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
58  * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
59  * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
60  * NOT APPLY TO YOU.
61  */
62 
79 
80 
81 #include "micropolis.h"
82 
83 
85 
86 
93 {
95 }
96 
97 
103 {
104  cityFileName = "";
105 
106  generateMap(seed);
107  scenario = SC_NONE;
108  cityTime = 0;
109  initSimLoad = 2;
110  doInitialEval = false;
111 
112  initWillStuff();
113  resetMapState();
115  invalidateMaps();
116  updateFunds();
117  doSimInit();
118 
119  simUpdate();
120 
121  callback->didGenerateMap(this, callbackVal, seed);
122 }
123 
124 
130 {
131  generatedCitySeed = seed;
132 
133  seedRandom(seed);
134 
135  // Construct land.
136  if (terrainCreateIsland < 0) {
137  if (getRandom(100) < 10) { /* chance that island is generated */
138  makeIsland();
139  return;
140  }
141  }
142 
143  if (terrainCreateIsland == 1) {
144  makeNakedIsland();
145  } else {
146  clearMap();
147  }
148 
149  // Lay a river.
150  if (terrainCurveLevel != 0) {
151  int terrainXStart = 40 + getRandom(WORLD_W - 80);
152  int terrainYStart = 33 + getRandom(WORLD_H - 67);
153 
154  Position terrainPos(terrainXStart, terrainYStart);
155 
156  doRivers(terrainPos);
157  }
158 
159  // Lay a few lakes.
160  if (terrainLakeLevel != 0) {
161  makeLakes();
162  }
163 
164  smoothRiver();
165 
166  // And add trees.
167  if (terrainTreeLevel != 0) {
168  doTrees();
169  }
170 
171 }
172 
173 
176 {
177  short x, y;
178 
179  for (x = 0; x < WORLD_W; x++) {
180  for (y = 0; y < WORLD_H; y++) {
181  map[x][y] = DIRT;
182  }
183  }
184 }
185 
186 
189 {
190  short x, y;
191 
192  for (x = 0; x < WORLD_W; x++) {
193  for (y = 0; y < WORLD_H; y++) {
194  if (map[x][y] > WOODS) {
195  map[x][y] = DIRT;
196  }
197  }
198  }
199 }
200 
205 {
206  const int terrainIslandRadius = ISLAND_RADIUS;
207  int x, y;
208 
209  for (x = 0; x < WORLD_W; x++) {
210  for (y = 0; y < WORLD_H; y++) {
211  if ((x < 5) || (x >= WORLD_W - 5) ||
212  (y < 5) || (y >= WORLD_H - 5)) {
213  map[x][y] = RIVER;
214  } else {
215  map[x][y] = DIRT;
216  }
217  }
218  }
219 
220  for (x = 0; x < WORLD_W - 5; x += 2) {
221 
222  int mapY = getERandom(terrainIslandRadius);
223  plopBRiver(Position(x, mapY));
224 
225  mapY = (WORLD_H - 10) - getERandom(terrainIslandRadius);
226  plopBRiver(Position(x, mapY));
227 
228  plopSRiver(Position(x, 0));
229  plopSRiver(Position(x, WORLD_H - 6));
230  }
231 
232  for (y = 0; y < WORLD_H - 5; y += 2) {
233 
234  int mapX = getERandom(terrainIslandRadius);
235  plopBRiver(Position(mapX, y));
236 
237  mapX = (WORLD_W - 10) - getERandom(terrainIslandRadius);
238  plopBRiver(Position(mapX, y));
239 
240  plopSRiver(Position(0, y));
241  plopSRiver(Position(WORLD_W - 6, y));
242  }
243 
244 }
245 
246 
249 {
250  makeNakedIsland();
251  smoothRiver();
252  doTrees();
253 }
254 
255 
260 {
261  short numLakes;
262 
263  if (terrainLakeLevel < 0) {
264  numLakes = getRandom(10);
265  } else {
266  numLakes = terrainLakeLevel / 2;
267  }
268 
269  while (numLakes > 0) {
270  int x = getRandom(WORLD_W - 21) + 10;
271  int y = getRandom(WORLD_H - 20) + 10;
272 
273  makeSingleLake(Position(x, y));
274 
275  numLakes--;
276  }
277 }
278 
284 {
285  int numPlops = getRandom(12) + 2;
286 
287  while (numPlops > 0) {
288  Position plopPos(pos, getRandom(12) - 6, getRandom(12) - 6);
289 
290  if (getRandom(4)) {
291  plopSRiver(plopPos);
292  } else {
293  plopBRiver(plopPos);
294  }
295 
296  numPlops--;
297  }
298 }
299 
300 
310 void Micropolis::treeSplash(short xloc, short yloc)
311 {
312  short numTrees;
313 
314  if (terrainTreeLevel < 0) {
315  numTrees = getRandom(150) + 50;
316  } else {
317  numTrees = getRandom(100 + (terrainTreeLevel * 2)) + 50;
318  }
319 
320  Position treePos(xloc, yloc);
321 
322  while (numTrees > 0) {
324  treePos.move(dir);
325 
326  if (!treePos.testBounds()) {
327  return;
328  }
329 
330  if ((map[treePos.posX][treePos.posY] & LOMASK) == DIRT) {
331  map[treePos.posX][treePos.posY] = WOODS | BLBNBIT;
332  }
333 
334  numTrees--;
335  }
336 }
337 
338 
341 {
342  short Amount, x, xloc, yloc;
343 
344  if (terrainTreeLevel < 0) {
345  Amount = getRandom(100) + 50;
346  } else {
347  Amount = terrainTreeLevel + 3;
348  }
349 
350  for (x = 0; x < Amount; x++) {
351  xloc = getRandom(WORLD_W - 1);
352  yloc = getRandom(WORLD_H - 1);
353  treeSplash(xloc, yloc);
354  }
355 
356  smoothTrees();
357  smoothTrees();
358 }
359 
360 
361 void Micropolis::smoothRiver()
362 {
363  static short dx[4] = { -1, 0, 1, 0 };
364  static short dy[4] = { 0, 1, 0, -1 };
365  static short REdTab[16] = {
366  13 | BULLBIT, 13 | BULLBIT, 17 | BULLBIT, 15 | BULLBIT,
367  5 | BULLBIT, 2, 19 | BULLBIT, 17 | BULLBIT,
368  9 | BULLBIT, 11 | BULLBIT, 2, 13 | BULLBIT,
369  7 | BULLBIT, 9 | BULLBIT, 5 | BULLBIT, 2 };
370 
371  short bitIndex, z, xTemp, yTemp;
372  short temp, x, y;
373 
374  for (x = 0; x < WORLD_W; x++) {
375  for (y = 0; y < WORLD_H; y++) {
376 
377  if (map[x][y] == REDGE) {
378  bitIndex = 0;
379 
380  for (z = 0; z < 4; z++) {
381  bitIndex = bitIndex << 1;
382  xTemp = x + dx[z];
383  yTemp = y + dy[z];
384  if (testBounds(xTemp, yTemp) &&
385  ((map[xTemp][yTemp] & LOMASK) != DIRT) &&
386  (((map[xTemp][yTemp] & LOMASK) < WOODS_LOW) ||
387  ((map[xTemp][yTemp] & LOMASK) > WOODS_HIGH))) {
388  bitIndex++;
389  }
390  }
391 
392  temp = REdTab[bitIndex & 15];
393 
394  if ((temp != RIVER) &&
395  getRandom(1)) {
396  temp++;
397  }
398 
399  map[x][y] = temp;
400  }
401  }
402  }
403 }
404 
405 
406 bool Micropolis::isTree(MapValue cell)
407 {
408  if ((cell & LOMASK) >= WOODS_LOW && (cell & LOMASK) <= WOODS_HIGH) {
409  return true;
410  }
411 
412  return false;
413 }
414 
415 
416 void Micropolis::smoothTrees()
417 {
418  short x, y;
419  for (x = 0; x < WORLD_W; x++) {
420  for (y = 0; y < WORLD_H; y++) {
421  if (isTree(map[x][y])) {
422  smoothTreesAt(x, y, false);
423  }
424  }
425  }
426 }
427 
429 void Micropolis::smoothTreesAt(int x, int y, bool preserve)
430 {
431  ToolEffects effects(this);
432 
433  smoothTreesAt(x, y, preserve, &effects);
434  effects.modifyWorld();
435 }
436 
437 
441 void Micropolis::smoothTreesAt(int x, int y, bool preserve,
442  ToolEffects *effects)
443 {
444  static short dx[4] = { -1, 0, 1, 0 };
445  static short dy[4] = { 0, 1, 0, -1 };
446  static const short treeTable[16] = {
447  0, 0, 0, 34,
448  0, 0, 36, 35,
449  0, 32, 0, 33,
450  30, 31, 29, 37,
451  };
452 
453  if (!isTree(effects->getMapValue(x, y))) {
454  return;
455  }
456 
457  int bitIndex = 0;
458  int z;
459  for (z = 0; z < 4; z++) {
460  bitIndex = bitIndex << 1;
461  int xTemp = x + dx[z];
462  int yTemp = y + dy[z];
463  if (testBounds(xTemp, yTemp)
464  && isTree(effects->getMapValue(xTemp, yTemp))) {
465  bitIndex++;
466  }
467  }
468 
469  int temp = treeTable[bitIndex & 15];
470  if (temp) {
471  if (temp != WOODS) {
472  if ((x + y) & 1) {
473  temp = temp - 8;
474  }
475  }
476  effects->setMapValue(x, y, temp | BLBNBIT);
477  } else {
478  if (!preserve) {
479  effects->setMapValue(x, y, temp);
480  }
481  }
482 }
483 
484 
489 void Micropolis::doRivers(const Position &terrainPos)
490 {
491  Direction2 riverDir; // Global direction of the river
492  Direction2 terrainDir; // Local direction of the river
493 
494  riverDir = (Direction2)(DIR2_NORTH + (getRandom(3) * 2));
495  doBRiver(terrainPos, riverDir, riverDir);
496 
497  riverDir = rotate180(riverDir);
498  terrainDir = doBRiver(terrainPos, riverDir, riverDir);
499 
500  riverDir = (Direction2)(DIR2_NORTH + (getRandom(3) * 2));
501  doSRiver(terrainPos, riverDir, terrainDir);
502 }
503 
504 
513  Direction2 riverDir, Direction2 terrainDir)
514 {
515  int rate1, rate2;
516 
517  if (terrainCurveLevel < 0) {
518  rate1 = 100;
519  rate2 = 200;
520  } else {
521  rate1 = terrainCurveLevel + 10;
522  rate2 = terrainCurveLevel + 100;
523  }
524 
525  Position pos(riverPos);
526 
527  while (testBounds(pos.posX + 4, pos.posY + 4)) {
528  plopBRiver(pos);
529  if (getRandom(rate1) < 10) {
530  terrainDir = riverDir;
531  } else {
532  if (getRandom(rate2) > 90) {
533  terrainDir = rotate45(terrainDir);
534  }
535  if (getRandom(rate2) > 90) {
536  terrainDir = rotate45(terrainDir, 7);
537  }
538  }
539  pos.move(terrainDir);
540  }
541 
542  return terrainDir;
543 }
544 
553  Direction2 riverDir, Direction2 terrainDir)
554 {
555  int rate1, rate2;
556 
557  if (terrainCurveLevel < 0) {
558  rate1 = 100;
559  rate2 = 200;
560  } else {
561  rate1 = terrainCurveLevel + 10;
562  rate2 = terrainCurveLevel + 100;
563  }
564 
565  Position pos(riverPos);
566 
567  while (testBounds(pos.posX + 3, pos.posY + 3)) {
568  //printf("doSRiver %d %d td %d rd %d\n", pos.posX, pos.posY, terrainDir, riverDir);
569  plopSRiver(pos);
570  if (getRandom(rate1) < 10) {
571  terrainDir = riverDir;
572  } else {
573  if (getRandom(rate2) > 90) {
574  terrainDir = rotate45(terrainDir);
575  }
576  if (getRandom(rate2) > 90) {
577  terrainDir = rotate45(terrainDir, 7);
578  }
579  }
580  pos.move(terrainDir);
581  }
582 
583  return terrainDir;
584 }
585 
586 
593 void Micropolis::putOnMap(MapValue mChar, short xLoc, short yLoc)
594 {
595  if (mChar == 0) {
596  return;
597  }
598 
599  if (!testBounds(xLoc, yLoc)) {
600  return;
601  }
602 
603  MapValue temp = map[xLoc][yLoc];
604 
605  if (temp != DIRT) {
606  temp = temp & LOMASK;
607  if (temp == RIVER) {
608  if (mChar != CHANNEL) {
609  return;
610  }
611  }
612  if (temp == CHANNEL) {
613  return;
614  }
615  }
616  map[xLoc][yLoc] = mChar;
617 }
618 
624 {
625  short x, y;
626  static MapValue BRMatrix[9][9] = {
627  { 0, 0, 0, REDGE, REDGE, REDGE, 0, 0, 0 },
628  { 0, 0, REDGE, RIVER, RIVER, RIVER, REDGE, 0, 0 },
629  { 0, REDGE, RIVER, RIVER, RIVER, RIVER, RIVER, REDGE, 0 },
630  { REDGE, RIVER, RIVER, RIVER, RIVER, RIVER, RIVER, RIVER, REDGE },
631  { REDGE, RIVER, RIVER, RIVER, CHANNEL, RIVER, RIVER, RIVER, REDGE },
632  { REDGE, RIVER, RIVER, RIVER, RIVER, RIVER, RIVER, RIVER, REDGE },
633  { 0, REDGE, RIVER, RIVER, RIVER, RIVER, RIVER, REDGE, 0 },
634  { 0, 0, REDGE, RIVER, RIVER, RIVER, REDGE, 0, 0 },
635  { 0, 0, 0, REDGE, REDGE, REDGE, 0, 0, 0 },
636  };
637 
638  for (x = 0; x < 9; x++) {
639  for (y = 0; y < 9; y++) {
640  putOnMap(BRMatrix[y][x], pos.posX + x, pos.posY + y);
641  }
642  }
643 }
644 
645 
651 {
652  short x, y;
653  static MapValue SRMatrix[6][6] = {
654  { 0, 0, REDGE, REDGE, 0, 0 },
655  { 0, REDGE, RIVER, RIVER, REDGE, 0 },
656  { REDGE, RIVER, RIVER, RIVER, RIVER, REDGE },
657  { REDGE, RIVER, RIVER, RIVER, RIVER, REDGE },
658  { 0, REDGE, RIVER, RIVER, REDGE, 0 },
659  { 0, 0, REDGE, REDGE, 0, 0 },
660  };
661 
662  for (x = 0; x < 6; x++) {
663  for (y = 0; y < 6; y++) {
664  putOnMap(SRMatrix[y][x], pos.posX + x, pos.posY + y);
665  }
666  }
667 }
668 
669 
670 void Micropolis::smoothWater()
671 {
672  int x, y;
673  MapTile tile;
674  Direction2 dir;
675 
676  for (x = 0; x < WORLD_W; x++) {
677  for (y = 0; y < WORLD_H; y++) {
678 
679  tile = map[x][y] & LOMASK;
680 
681  /* If (x, y) is water: */
682  if (tile >= WATER_LOW && tile <= WATER_HIGH) {
683 
684  const Position pos(x, y);
685  for (dir = DIR2_BEGIN; dir < DIR2_END; dir = increment90(dir)) {
686 
687  /* If getting a tile off-map, condition below fails. */
688  // @note I think this may have been a bug, since it always uses DIR2_WEST instead of dir.
689  //tile = getTileFromMap(pos, DIR2_WEST, WATER_LOW);
690  tile = getTileFromMap(pos, dir, WATER_LOW);
691 
692  /* If nearest object is not water: */
693  if (tile < WATER_LOW || tile > WATER_HIGH) {
694  map[x][y] = REDGE; /* set river edge */
695  break; // Continue with next tile
696  }
697  }
698  }
699  }
700  }
701 
702  for (x = 0; x < WORLD_W; x++) {
703  for (y = 0; y < WORLD_H; y++) {
704 
705  tile = map[x][y] & LOMASK;
706 
707  /* If water which is not a channel: */
708  if (tile != CHANNEL && tile >= WATER_LOW && tile <= WATER_HIGH) {
709 
710  bool makeRiver = true; // make (x, y) a river
711 
712  const Position pos(x, y);
713  for (dir = DIR2_BEGIN; dir < DIR2_END; dir = increment90(dir)) {
714 
715  /* If getting a tile off-map, condition below fails. */
716  // @note I think this may have been a bug, since it always uses DIR2_WEST instead of dir.
717  //tile = getTileFromMap(pos, DIR2_WEST, WATER_LOW);
718  tile = getTileFromMap(pos, dir, WATER_LOW);
719 
720  /* If nearest object is not water: */
721  if (tile < WATER_LOW || tile > WATER_HIGH) {
722  makeRiver = false;
723  break;
724  }
725  }
726 
727  if (makeRiver) {
728  map[x][y] = RIVER; /* make it a river */
729  }
730  }
731  }
732  }
733 
734  for (x = 0; x < WORLD_W; x++) {
735  for (y = 0; y < WORLD_H; y++) {
736 
737  tile = map[x][y] & LOMASK;
738 
739  /* If woods: */
740  if (tile >= WOODS_LOW && tile <= WOODS_HIGH) {
741 
742  const Position pos(x, y);
743  for (dir = DIR2_BEGIN; dir < DIR2_END; dir = increment90(dir)) {
744 
745  /* If getting a tile off-map, condition below fails. */
746  // @note I think this may have been a bug, since it always uses DIR2_WEST instead of dir.
747  //tile = getTileFromMap(pos, DIR2_WEST, WATER_LOW);
748  tile = getTileFromMap(pos, dir, TILE_INVALID);
749 
750  if (tile == RIVER || tile == CHANNEL) {
751  map[x][y] = REDGE; /* make it water's edge */
752  break;
753  }
754  }
755  }
756  }
757  }
758 }
759 
760 
void makeSingleLake(const Position &pos)
Definition: generate.cpp:283
int terrainCreateIsland
Definition: micropolis.h:1735
bool doInitialEval
Need to perform initial city evaluation.
Definition: micropolis.h:2120
void generateSomeCity(int seed)
Definition: generate.cpp:102
void resetMapState()
Definition: initialize.cpp:131
void seedRandom(int seed)
Definition: random.cpp:177
void simUpdate()
Definition: micropolis.cpp:783
void doRivers(const Position &terrainPos)
Definition: generate.cpp:489
int terrainTreeLevel
Definition: micropolis.h:1717
void putOnMap(MapValue mChar, short xLoc, short yLoc)
Definition: generate.cpp:593
Scenario scenario
Scenario being played.
Definition: micropolis.h:2338
void generateSomeRandomCity()
Definition: generate.cpp:92
Direction2 doSRiver(const Position &riverPos, Direction2 riverDir, Direction2 terrainDir)
Definition: generate.cpp:552
Callback * callback
Definition: micropolis.h:954
MapTile getTileFromMap(const Position &pos, Direction2 dir, MapTile defaultTile)
Definition: traffic.cpp:407
std::string cityFileName
Filename of the last loaded city.
Definition: micropolis.h:1904
Quad cityTime
Definition: micropolis.h:1092
int terrainCurveLevel
Definition: micropolis.h:1729
short getRandom(short range)
Definition: random.cpp:110
int getRandom16()
Definition: random.cpp:130
void makeIsland()
Definition: generate.cpp:248
void resetEditorState()
Definition: initialize.cpp:141
void updateFunds()
Definition: update.cpp:127
void makeLakes()
Definition: generate.cpp:259
int generatedCitySeed
Definition: micropolis.h:1741
unsigned short * map[WORLD_W]
Definition: micropolis.h:1120
int terrainLakeLevel
Definition: micropolis.h:1723
void generateMap(int seed)
Definition: generate.cpp:129
void doTrees()
Definition: generate.cpp:340
Direction2 doBRiver(const Position &riverPos, Direction2 riverDir, Direction2 terrainDir)
Definition: generate.cpp:512
static bool testBounds(int wx, int wy)
Definition: micropolis.h:2378
void makeNakedIsland()
Definition: generate.cpp:204
void invalidateMaps()
void clearMap()
Definition: generate.cpp:175
void plopSRiver(const Position &pos)
Definition: generate.cpp:650
void treeSplash(short xloc, short yloc)
Definition: generate.cpp:310
void clearUnnatural()
Definition: generate.cpp:188
void initWillStuff()
Definition: initialize.cpp:85
void smoothTreesAt(int x, int y, bool preserve)
Definition: generate.cpp:429
short getERandom(short limit)
Definition: random.cpp:155
void plopBRiver(const Position &pos)
Definition: generate.cpp:623
void doSimInit()
Definition: simulate.cpp:286
int posY
Vertical coordnate of the position.
Definition: position.h:169
int posX
Horizontal coordinate of the position.
Definition: position.h:168
bool move(Direction2 dir)
Definition: position.cpp:161
bool testBounds()
Definition: position.h:177
void setMapValue(const Position &pos, MapValue mapVal)
Definition: tool.cpp:186
void modifyWorld()
Definition: tool.cpp:121
MapValue getMapValue(const Position &pos) const
Definition: tool.cpp:169
static const int WORLD_H
Definition: map_type.h:95
static const int WORLD_W
Definition: map_type.h:90
Header file for Micropolis game engine.
@ SC_NONE
No scenario (free playing)
Definition: micropolis.h:698
@ WATER_LOW
First water tile.
Definition: micropolis.h:392
@ WATER_HIGH
Last water tile (inclusive)
Definition: micropolis.h:393
@ DIRT
Clear tile.
Definition: micropolis.h:382
@ TILE_INVALID
Invalid tile (not used in the world map).
Definition: micropolis.h:689
static const int ISLAND_RADIUS
Definition: micropolis.h:239
static Direction2 rotate45(Direction2 dir, int count=1)
Definition: position.h:127
static Direction2 rotate180(Direction2 dir)
Definition: position.h:147
Direction2
Definition: position.h:86
@ DIR2_BEGIN
First valid direction.
Definition: position.h:97
@ DIR2_END
End-condition for directions.
Definition: position.h:98
@ DIR2_NORTH
Direction pointing north.
Definition: position.h:88
static Direction2 increment90(Direction2 dir)
Definition: position.h:117
unsigned short MapTile
Definition: tool.h:108
@ LOMASK
Mask for the Tiles part of the tile.
Definition: tool.h:129
@ BULLBIT
bit 12, tile is bulldozable.
Definition: tool.h:123
unsigned short MapValue
Definition: tool.h:94