Micropolis
tool.cpp
Go to the documentation of this file.
1 /* tool.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 
78 
79 
80 #include "micropolis.h"
81 
82 
84 
87 {
88  this->sim = mpolis;
89 
90  this->clear();
91 }
92 
93 ToolEffects::~ToolEffects()
94 {
95  /* free all frontend messages */
96  while(!this->frontendMessages.empty()) {
97  delete this->frontendMessages.back();
98  this->frontendMessages.pop_back();
99  }
100 }
101 
104 {
105  this->cost = 0;
106  this->modifications.clear();
107 
108  /* free all frontend messages */
109  while(!this->frontendMessages.empty()) {
110  delete this->frontendMessages.back();
111  this->frontendMessages.pop_back();
112  }
113 }
114 
122 {
123  WorldModificationsMap::const_iterator modIter;
124  FrontendMessages::const_iterator msgIter;
125  Micropolis *mpolis = this->sim;
126 
127  mpolis->spend(this->cost); // Spend the costs
128  mpolis->updateFunds();
129 
130  /* Modify the world. */
131  for (modIter = this->modifications.begin();
132  modIter != this->modifications.end(); modIter++) {
133  Position pos(modIter->first);
134  mpolis->map[pos.posX][pos.posY] = modIter->second;
135  }
136 
137  /* And finally send the messages. */
138  for (msgIter = this->frontendMessages.begin();
139  msgIter != this->frontendMessages.end(); msgIter++) {
140  (*msgIter)->sendMessage(mpolis);
141  }
142 
143  this->clear();
144 }
145 
153 {
154  if (this->sim->totalFunds < this->cost) {
155  return false; // Not enough money
156  }
157 
158  this->modifyWorld();
159  return true;
160 }
161 
170 {
171  WorldModificationsMap::const_iterator iter;
172 
173  iter = this->modifications.find(pos);
174  if (iter == this->modifications.end()) {
175  return this->sim->map[pos.posX][pos.posY];
176  }
177 
178  return (*iter).second;
179 }
180 
187 {
188  this->modifications[pos] = mapVal;
189 }
190 
192 // BuildingProperties
193 
194 BuildingProperties::BuildingProperties(int xs, int ys, MapTile base,
195  EditingTool tl, std::string tName, bool anim) :
196  sizeX(xs),
197  sizeY(ys),
198  baseTile(base),
199  tool(tl),
200  toolName(tName),
201  buildingIsAnimated(anim)
202 {
203 }
204 
205 BuildingProperties::~BuildingProperties()
206 {
207 }
208 
209 
211 
216 static const short gCostOf[] = {
217  100, 100, 100, 500, /* res, com, ind, fire */
218  500, 0, 5, 1, /* police, query, wire, bulldozer */
219  20, 10, 5000, 10, /* rail, road, stadium, park */
220  3000, 3000, 5000, 10000, /* seaport, coal, nuclear, airport */
221  100, 0, 0, 0, /* network, water, land, forest */
222  0,
223 };
224 
230 static const short gToolSize[] = {
231  3, 3, 3, 3,
232  3, 1, 1, 1,
233  1, 1, 4, 1,
234  4, 4, 4, 6,
235  1, 1, 1, 1,
236  0,
237 };
238 
239 
241 // Utilities
242 
243 
252 ToolResult Micropolis::putDownPark(short mapH, short mapV, ToolEffects *effects)
253 {
254  short value = getRandom(4);
255  MapValue tile = BURNBIT | BULLBIT;
256 
257  if (value == 4) {
258  tile |= FOUNTAIN | ANIMBIT;
259  } else {
260  tile |= value + WOODS2;
261  }
262 
263  if (effects->getMapValue(mapH, mapV) != DIRT) {
265  }
266 
267  effects->addCost(gCostOf[TOOL_PARK]);
268  effects->setMapValue(mapH, mapV, tile);
269 
270  return TOOLRESULT_OK;
271 }
272 
273 
282 ToolResult Micropolis::putDownNetwork(short mapH, short mapV,
283  ToolEffects *effects)
284 {
285  MapTile tile = effects->getMapTile(mapH, mapV);
286 
287  if (tile != DIRT && tally(tile)) {
288  effects->addCost(gCostOf[TOOL_BULLDOZER]);
289  effects->setMapValue(mapH, mapV, DIRT);
290  tile = DIRT;
291  }
292 
293  if (tile != DIRT) return TOOLRESULT_NEED_BULLDOZE;
294 
295  effects->setMapValue(mapH, mapV,
296  TELEBASE | CONDBIT | BURNBIT | BULLBIT | ANIMBIT);
297 
298  effects->addCost(gCostOf[TOOL_NETWORK]);
299 
300  return TOOLRESULT_OK;
301 }
302 
303 
310 ToolResult Micropolis::putDownWater(short mapH, short mapV,
311  ToolEffects *effects)
312 {
313  MapTile tile = effects->getMapTile(mapH, mapV);
314 
315  if (tile == RIVER) return TOOLRESULT_FAILED;
316 
317  effects->setMapValue(mapH, mapV, RIVER);
318 
319  effects->addCost(gCostOf[TOOL_WATER]);
320 
321  return TOOLRESULT_OK;
322 }
323 
324 
333 ToolResult Micropolis::putDownLand(short mapH, short mapV, ToolEffects *effects)
334 {
335  int tile = effects->getMapTile(mapH, mapV);
336 // static short dx[8] = { -1, 0, 1, -1, 1, -1, 0, 1, };
337 // static short dy[8] = { -1, -1, -1, 0, 0, 1, 1, 1, };
338 
339 
340  if (tile == DIRT) return TOOLRESULT_FAILED;
341 
342  effects->setMapValue(mapH, mapV, DIRT);
343 
344 // int i;
345 // for (i = 0; i < 8; i++) {
346 // int xx = mapH + dx[i];
347 // int yy = mapV + dy[i];
348 // if (testBounds(xx, yy)) {
349 // //smoothTreesAt(xx, yy, true);
350 // }
351 // }
352 
353  effects->addCost(gCostOf[TOOL_LAND]);
354 
355  return TOOLRESULT_OK;
356 }
357 
358 
366 ToolResult Micropolis::putDownForest(short mapH, short mapV,
367  ToolEffects *effects)
368 {
369  static short dx[8] = { -1, 0, 1, -1, 1, -1, 0, 1, };
370  static short dy[8] = { -1, -1, -1, 0, 0, 1, 1, 1, };
371 
372  effects->setMapValue(mapH, mapV, WOODS | BLBNBIT);
373 
374  int i;
375  for (i = 0; i < 8; i++) {
376  int xx = mapH + dx[i];
377  int yy = mapV + dy[i];
378  if (testBounds(xx, yy)) {
379  smoothTreesAt(xx, yy, true, effects);
380  }
381  }
382 
383  effects->addCost(gCostOf[TOOL_FOREST]);
384 
385  return TOOLRESULT_OK;
386 }
387 
388 
402 static short checkBigZone(MapTile id, short *deltaHPtr, short *deltaVPtr)
403 {
404  switch (id) {
405 
406  case POWERPLANT: /* check coal plant */
407  case PORT: /* check sea port */
408  case NUCLEAR: /* check nuc plant */
409  case STADIUM: /* check stadium */
410  *deltaHPtr = 0;
411  *deltaVPtr = 0;
412  return 4;
413 
414  case POWERPLANT + 1: /* check coal plant */
415  case COALSMOKE3: /* check coal plant, smoke */
416  case COALSMOKE3 + 1: /* check coal plant, smoke */
417  case COALSMOKE3 + 2: /* check coal plant, smoke */
418  case PORT + 1: /* check sea port */
419  case NUCLEAR + 1: /* check nuc plant */
420  case STADIUM + 1: /* check stadium */
421  *deltaHPtr = -1;
422  *deltaVPtr = 0;
423  return 4;
424 
425  case POWERPLANT + 4: /* check coal plant */
426  case PORT + 4: /* check sea port */
427  case NUCLEAR + 4: /* check nuc plant */
428  case STADIUM + 4: /* check stadium */
429  *deltaHPtr = 0;
430  *deltaVPtr = -1;
431  return 4;
432 
433  case POWERPLANT + 5: /* check coal plant */
434  case PORT + 5: /* check sea port */
435  case NUCLEAR + 5: /* check nuc plant */
436  case STADIUM + 5: /* check stadium */
437  *deltaHPtr = -1;
438  *deltaVPtr = -1;
439  return 4;
440 
441  case AIRPORT: /* check airport */
442  *deltaHPtr = 0;
443  *deltaVPtr = 0;
444  return 6;
445 
446  case AIRPORT + 1:
447  *deltaHPtr = -1;
448  *deltaVPtr = 0;
449  return 6;
450 
451  case AIRPORT + 2:
452  *deltaHPtr = -2;
453  *deltaVPtr = 0;
454  return 6;
455 
456  case AIRPORT + 3:
457  *deltaHPtr = -3;
458  *deltaVPtr = 0;
459  return 6;
460 
461  case AIRPORT + 6:
462  *deltaHPtr = 0;
463  *deltaVPtr = -1;
464  return 6;
465 
466  case AIRPORT + 7:
467  *deltaHPtr = -1;
468  *deltaVPtr = -1;
469  return 6;
470 
471  case AIRPORT + 8:
472  *deltaHPtr = -2;
473  *deltaVPtr = -1;
474  return 6;
475 
476  case AIRPORT + 9:
477  *deltaHPtr = -3;
478  *deltaVPtr = -1;
479  return 6;
480 
481  case AIRPORT + 12:
482  *deltaHPtr = 0;
483  *deltaVPtr = -2;
484  return 6;
485 
486  case AIRPORT + 13:
487  *deltaHPtr = -1;
488  *deltaVPtr = -2;
489  return 6;
490 
491  case AIRPORT + 14:
492  *deltaHPtr = -2;
493  *deltaVPtr = -2;
494  return 6;
495 
496  case AIRPORT + 15:
497  *deltaHPtr = -3;
498  *deltaVPtr = -2;
499  return 6;
500 
501  case AIRPORT + 18:
502  *deltaHPtr = 0;
503  *deltaVPtr = -3;
504  return 6;
505 
506  case AIRPORT + 19:
507  *deltaHPtr = -1;
508  *deltaVPtr = -3;
509  return 6;
510 
511  case AIRPORT + 20:
512  *deltaHPtr = -2;
513  *deltaVPtr = -3;
514  return 6;
515 
516  case AIRPORT + 21:
517  *deltaHPtr = -3;
518  *deltaVPtr = -3;
519  return 6;
520 
521  default:
522  *deltaHPtr = 0;
523  *deltaVPtr = 0;
524  return 0;
525 
526  }
527 }
528 
529 
535 bool Micropolis::tally(short tileValue)
536 {
537  return (tileValue >= FIRSTRIVEDGE && tileValue <= LASTRUBBLE) ||
538  (tileValue >= POWERBASE + 2 && tileValue <= POWERBASE + 12) ||
539  (tileValue >= TINYEXP && tileValue <= LASTTINYEXP + 2);
540 }
541 
542 
548 short Micropolis::checkSize(short tileValue)
549 {
550  // check for the normal com, resl, ind 3x3 zones & the fireDept & PoliceDept
551  if ((tileValue >= RESBASE - 1 && tileValue <= PORTBASE - 1) ||
552  (tileValue >= LASTPOWERPLANT + 1 && tileValue <= POLICESTATION + 4) ||
553  (tileValue >= CHURCH1BASE && tileValue <= CHURCH7LAST)) {
554  return 3;
555  }
556 
557  if ((tileValue >= PORTBASE && tileValue <= LASTPORT) ||
558  (tileValue >= COALBASE && tileValue <= LASTPOWERPLANT) ||
559  (tileValue >= STADIUMBASE && tileValue <= LASTZONE)) {
560  return 4;
561  }
562 
563  return 0;
564 }
565 
566 
575 void Micropolis::checkBorder(short xMap, short yMap, int sizeX, int sizeY,
576  ToolEffects *effects)
577 {
578  short cnt;
579 
580  /* this will do the upper bordering row */
581  for (cnt = 0; cnt < sizeX; cnt++) {
582  connectTile(xMap + cnt, yMap - 1, CONNECT_TILE_FIX, effects);
583  }
584 
585  /* this will do the left bordering row */
586  for (cnt = 0; cnt < sizeY; cnt++) {
587  connectTile(xMap - 1, yMap + cnt, CONNECT_TILE_FIX, effects);
588  }
589 
590  /* this will do the bottom bordering row */
591  for (cnt = 0; cnt < sizeX; cnt++) {
592  connectTile(xMap + cnt, yMap + sizeY, CONNECT_TILE_FIX, effects);
593  }
594 
595  /* this will do the right bordering row */
596  for (cnt = 0; cnt < sizeY; cnt++) {
597  connectTile(xMap + sizeX, yMap + cnt, CONNECT_TILE_FIX, effects);
598  }
599 }
600 
617 void Micropolis::putBuilding(int leftX, int topY, int sizeX, int sizeY,
618  MapTile baseTile, bool aniFlag,
619  ToolEffects *effects)
620 {
621  for (int dy = 0; dy < sizeY; dy++) {
622  int posY = topY + dy;
623 
624  for (int dx = 0; dx < sizeX; dx++) {
625  int posX = leftX + dx;
626 
627  MapValue tileValue = baseTile | BNCNBIT;
628  if (dx == 1) {
629  if (dy == 1) {
630  tileValue |= ZONEBIT;
631  } else if (dy == 2 && aniFlag) {
632  tileValue |= ANIMBIT;
633  }
634  }
635 
636  effects->setMapValue(posX, posY, tileValue);
637 
638  baseTile++;
639  }
640  }
641 }
642 
658  int sizeX, int sizeY,
659  ToolEffects *effects)
660 {
661  // Check that the entire site is on the map
662  if (leftX < 0 || leftX + sizeX > WORLD_W) {
663  return TOOLRESULT_FAILED;
664  }
665  if (topY < 0 || topY + sizeY > WORLD_H) {
666  return TOOLRESULT_FAILED;
667  }
668 
669  // Check whether the tiles are clear
670  for (int dy = 0; dy < sizeY; dy++) {
671  int posY = topY + dy;
672 
673  for (int dx = 0; dx < sizeX; dx++) {
674  int posX = leftX + dx;
675 
676  unsigned short tileValue = effects->getMapTile(posX, posY);
677 
678  if (tileValue == DIRT) { // DIRT tile is buidable
679  continue;
680  }
681 
682  if (!autoBulldoze) {
683  // No DIRT and no bull-dozer => not buildable
685  }
686  if (!tally(tileValue)) {
687  // tilevalue cannot be auto-bulldozed
689  }
690 
691  effects->setMapValue(posX, posY, DIRT);
692  effects->addCost(gCostOf[TOOL_BULLDOZER]);
693  }
694  }
695 
696  return TOOLRESULT_OK;
697 }
698 
699 
712  const BuildingProperties *buildingProps,
713  ToolEffects *effects)
714 {
715  mapH--; mapV--; // Move position to top-left
716 
717  ToolResult prepareResult = prepareBuildingSite(mapH, mapV,
718  buildingProps->sizeX,
719  buildingProps->sizeY,
720  effects);
721  if (prepareResult != TOOLRESULT_OK) {
722  return prepareResult;
723  }
724 
725  /* Preparation was ok, put down the building. */
726  effects->addCost(gCostOf[buildingProps->tool]);
727 
728  putBuilding(mapH, mapV, buildingProps->sizeX, buildingProps->sizeY,
729  buildingProps->baseTile, buildingProps->buildingIsAnimated,
730  effects);
731 
732  checkBorder(mapH, mapV,
733  buildingProps->sizeX, buildingProps->sizeY,
734  effects);
735 
736  return TOOLRESULT_OK;
737 }
738 
739 
740 /* Query */
741 
742 /* search table for zone status string match */
743 static short idArray[29] = {
744  DIRT, RIVER, TREEBASE, RUBBLE,
745  FLOOD, RADTILE, FIRE, ROADBASE,
746  POWERBASE, RAILBASE, RESBASE, COMBASE,
747  INDBASE, PORTBASE, AIRPORTBASE, COALBASE,
748  FIRESTBASE, POLICESTBASE, STADIUMBASE, NUCLEARBASE,
749  // FIXME: I think HBRDG_END should be HBRDG0...?
750  HBRDG0, RADAR0, FOUNTAIN, INDBASE2,
751  // FIXME: What are tiles 952 and 956?
752  FOOTBALLGAME1, VBRDG0, 952, 956,
753  9999, // a huge short
754 };
755 
756 /*
757  0, 2, 21, 44,
758  48, 52, 53, 64,
759  208, 224, 240, 423,
760  612, 693, 709, 745,
761  761, 770, 779, 811,
762  827, 832, 840, 844,
763  932, 948, 952, 956
764 
765  Clear, Water, Trees, Rubble,
766  Flood, Radioactive Waste, Fire, Road,
767  Power, Rail, Residential, Commercial,
768  Industrial, Port, AirPort, Coal Power,
769  Fire Department, Police Department, Stadium, Nuclear Power,
770  Draw Bridge, Radar Dish, Fountain, Industrial,
771  49er's 38 Bears 3, Draw Bridge, Ur 238, Unknown
772 */
773 
774 
788 int Micropolis::getDensity(short catNo, short mapH, short mapV)
789 {
790  int z;
791 
792  switch (catNo) {
793 
794  case 0:
795  default:
796  z = populationDensityMap.worldGet(mapH, mapV);
797  z = z >> 6;
798  z = z & 3;
799  return z + STR202_POPULATIONDENSITY_LOW;
800 
801  case 1:
802  z = landValueMap.worldGet(mapH, mapV);
803  if (z < 30) return STR202_LANDVALUE_SLUM;
804  if (z < 80) return STR202_LANDVALUE_LOWER_CLASS;
805  if (z < 150) return STR202_LANDVALUE_MIDDLE_CLASS;
807 
808  case 2:
809  z = crimeRateMap.worldGet(mapH, mapV);
810  z = z >> 6;
811  z = z & 3;
812  return z + STR202_CRIME_NONE;
813 
814  case 3:
815  z = pollutionDensityMap.worldGet(mapH, mapV);
816  if (z < 64 && z > 0) return 13;
817  z = z >> 6;
818  z = z & 3;
819  return z + STR202_POLLUTION_NONE;
820 
821  case 4:
822  z = rateOfGrowthMap.worldGet(mapH, mapV);
823  if (z < 0) return STR202_GROWRATE_DECLINING;
824  if (z == 0) return STR202_GROWRATE_STABLE;
825  if (z > 100) return STR202_GROWRATE_FASTGROWTH;
827 
828  }
829 }
830 
831 
838 void Micropolis::doZoneStatus(short mapH, short mapV)
839 {
840  int tileCategory;
841  int status[5];
842 
843  short tileNum = map[mapH][mapV] & LOMASK;
844 
845  if (tileNum >= COALSMOKE1 && tileNum < FOOTBALLGAME1) {
846  tileNum = COALBASE;
847  }
848 
849  // Find the category where the tile belongs to
850  // Note: If 'tileNum < idArray[i]', it belongs to category i-1
851  short i;
852  for (i = 1; i < 29; i++) {
853  if (tileNum < idArray[i]) {
854  break;
855  }
856  }
857 
858  i--;
859  // i contains the category that the tile belongs to (in theory 0..27).
860  // However, it is 0..26, since 956 is the first unused tile
861 
862  // FIXME: This needs to be fixed to support plug-in churches.
863 
864  // TODO: This should also return the bounding box and hot spot of
865  // the zone to the user interface, as well as other interesting
866  // information.
867 
868  // Code below looks buggy, 0 is a valid value (namely 'dirt'), and upper
869  // limit is not correctly checked either ('stri.219' has only 27 lines).
870 
871  // FIXME: This is strange... Normalize to zero based index.
872  if (i < 1 || i > 28) {
873  i = 28; // This breaks the program (when you click 'dirt')
874  }
875 
876  // Obtain the string index of the tile category.
877  // 'stri.219' has only 27 lines, so 0 <= i <= 26 is acceptable.
878  tileCategory = i + 1;
879 
880  for (i = 0; i < 5; i++) {
881  int id = clamp(getDensity(i, mapH, mapV) + 1, 1, 20);
882  status[i] = id;
883  }
884 
886  tileCategory,
887  status[0], status[1], status[2],
888  status[3], status[4],
889  mapH, mapV);
890 }
891 
892 
904  int tileCategoryIndex,
905  int populationDensityIndex,
906  int landValueIndex,
907  int crimeRateIndex,
908  int pollutionIndex,
909  int growthRateIndex,
910  int x,
911  int y)
912 {
913  callback->showZoneStatus(this, callbackVal, tileCategoryIndex, populationDensityIndex, landValueIndex, crimeRateIndex, pollutionIndex, growthRateIndex, x, y);
914 }
915 
916 
923 void Micropolis::putRubble(int x, int y, int size, ToolEffects *effects)
924 {
925  for (int xx = x; xx < x + size; xx++) {
926  for (int yy = y; yy < y + size; yy++) {
927 
928  if (testBounds(xx, yy)) {
929  int tile = effects->getMapTile(xx, yy);
930 
931  if (tile != RADTILE && tile != DIRT) {
932  tile = (doAnimation ? (TINYEXP + getRandom(2)) : SOMETINYEXP);
933  effects->setMapValue(xx, yy, tile | ANIMBIT | BULLBIT);
934  }
935  }
936  }
937  }
938 }
939 
940 
947 void Micropolis::didTool(std::string name, short x, short y)
948 {
949  std::string json;
950  json += "[";
951  json += name;
952  json += "\",";
953  json += std::to_string(x);
954  json += ",";
955  json += std::to_string(y);
956  json += "]";
957 
958  callback->didTool(this, callbackVal, name, x, y);
959 }
960 
961 
963 // Tools
964 
965 
973 {
974  if (!testBounds(x, y)) {
975  return TOOLRESULT_FAILED;
976  }
977 
978  doZoneStatus(x, y);
979  didTool("Qry", x, y);
980 
981  return TOOLRESULT_OK;
982 }
983 
984 ToolResult Micropolis::bulldozerTool(short x, short y)
985 {
986  ToolEffects effects(this);
987 
988  ToolResult result = bulldozerTool(x, y, &effects);
989 
990  if (result == TOOLRESULT_OK) {
991  effects.modifyWorld();
992  }
993 
994  return result;
995 }
996 
1010 ToolResult Micropolis::bulldozerTool(short x, short y, ToolEffects *effects)
1011 {
1012  ToolResult result = TOOLRESULT_OK;
1013 
1014  if (!testBounds(x, y)) {
1015  return TOOLRESULT_FAILED;
1016  }
1017 
1018  MapValue mapVal = effects->getMapValue(x, y);
1019  MapTile tile = mapVal & LOMASK;
1020 
1021  short zoneSize = 0; // size of the zone, 0 means invalid.
1022  short deltaH; // Amount of horizontal shift to the center tile of the zone.
1023  short deltaV; // Amount of vertical shift to the center tile of the zone.
1024  FrontendMessage *frontendMsg;
1025 
1026  if (mapVal & ZONEBIT) { /* zone center bit is set */
1027  zoneSize = checkSize(tile);
1028  deltaH = 0;
1029  deltaV = 0;
1030  } else {
1031  zoneSize = checkBigZone(tile, &deltaH, &deltaV);
1032  }
1033 
1034  if (zoneSize > 0) {
1035  effects->addCost(gCostOf[TOOL_BULLDOZER]);
1036 
1037  int dozeX = x;
1038  int dozeY = y;
1039  int centerX = x + deltaH;
1040  int centerY = y + deltaV;
1041 
1042  switch (zoneSize) {
1043 
1044  case 3:
1045  frontendMsg = new FrontendMessageMakeSound(
1046  "city", "Explosion-High", dozeX, dozeY);
1047  effects->addFrontendMessage(frontendMsg);
1048 
1049  putRubble(centerX - 1, centerY - 1, 3, effects);
1050  break;
1051 
1052  case 4:
1053  frontendMsg = new FrontendMessageMakeSound(
1054  "city", "Explosion-Low", dozeX, dozeY);
1055  effects->addFrontendMessage(frontendMsg);
1056 
1057  putRubble(centerX - 1, centerY - 1, 4, effects);
1058  break;
1059 
1060  case 6:
1061  frontendMsg = new FrontendMessageMakeSound(
1062  "city", "Explosion-High", dozeX, dozeY);
1063  effects->addFrontendMessage(frontendMsg);
1064 
1065  frontendMsg = new FrontendMessageMakeSound(
1066  "city", "Explosion-Low", dozeX, dozeY);
1067  effects->addFrontendMessage(frontendMsg);
1068 
1069  putRubble(centerX - 1, centerY - 1, 6, effects);
1070  break;
1071 
1072  default:
1073  NOT_REACHED();
1074  break;
1075 
1076  }
1077 
1078 
1079  if (result == TOOLRESULT_OK) {
1080  /* send 'didtool' message */
1081  frontendMsg = new FrontendMessageDidTool("Dozr", x, y);
1082  effects->addFrontendMessage(frontendMsg);
1083  }
1084 
1085  return result;
1086 
1087  }
1088 
1089 
1090  if (tile == RIVER || tile == REDGE || tile == CHANNEL) {
1091 
1092  result = connectTile(x, y, CONNECT_TILE_BULLDOZE, effects);
1093 
1094  if (tile != effects->getMapTile(x, y)) {
1095  effects->addCost(5);
1096  }
1097  } else {
1098  result = connectTile(x, y, CONNECT_TILE_BULLDOZE, effects);
1099  }
1100 
1101  if (result == TOOLRESULT_OK) {
1102  /* send 'didtool' message */
1103  frontendMsg = new FrontendMessageDidTool("Dozr", x, y);
1104  didTool("Dozr", x, y);
1105  effects->addFrontendMessage(frontendMsg);
1106  }
1107 
1108  return result;
1109 }
1110 
1111 
1120 ToolResult Micropolis::roadTool(short x, short y, ToolEffects *effects)
1121 {
1122  if (!testBounds(x, y)) {
1123  return TOOLRESULT_FAILED;
1124  }
1125 
1126  ToolResult result = connectTile(x, y, CONNECT_TILE_ROAD, effects);
1127 
1128  if (result == TOOLRESULT_OK) {
1129  /* send 'didtool' message */
1130  FrontendMessage *didToolMsg;
1131  didToolMsg = new FrontendMessageDidTool("Road", x, y);
1132  effects->addFrontendMessage(didToolMsg);
1133  }
1134 
1135  return result;
1136 }
1137 
1138 
1147 {
1148  if (!testBounds(x, y)) {
1149  return TOOLRESULT_FAILED;
1150  }
1151 
1152  ToolResult result = connectTile(x, y, CONNECT_TILE_RAILROAD, effects);
1153 
1154  if (result == TOOLRESULT_OK) {
1155  /* send 'didtool' message */
1156  FrontendMessage *didToolMsg;
1157  didToolMsg = new FrontendMessageDidTool("Rail", x, y);
1158  effects->addFrontendMessage(didToolMsg);
1159  }
1160 
1161  return result;
1162 }
1163 
1164 
1172 ToolResult Micropolis::wireTool(short x, short y, ToolEffects *effects)
1173 {
1174  if (!testBounds(x, y)) {
1175  return TOOLRESULT_FAILED;
1176  }
1177 
1178  ToolResult result = connectTile(x, y, CONNECT_TILE_WIRE, effects);
1179 
1180  if (result == TOOLRESULT_OK) {
1181  /* send 'didtool' message */
1182  FrontendMessage *didToolMsg;
1183  didToolMsg = new FrontendMessageDidTool("Wire", x, y);
1184  effects->addFrontendMessage(didToolMsg);
1185  }
1186 
1187  return result;
1188 }
1189 
1190 
1198 ToolResult Micropolis::parkTool(short x, short y, ToolEffects *effects)
1199 {
1200  if (!testBounds(x, y)) {
1201  return TOOLRESULT_FAILED;
1202  }
1203 
1204  ToolResult result = putDownPark(x, y, effects);
1205 
1206  if (result == TOOLRESULT_OK) {
1207  /* send 'didtool' message */
1208  FrontendMessage *didToolMsg;
1209  didToolMsg = new FrontendMessageDidTool("Park", x, y);
1210  effects->addFrontendMessage(didToolMsg);
1211  }
1212 
1213  return result;
1214 }
1215 
1216 
1226  const BuildingProperties *buildingProps,
1227  ToolEffects *effects)
1228 {
1229  ToolResult result = buildBuilding(x, y, buildingProps, effects);
1230 
1231  if (result == TOOLRESULT_OK) {
1232  /* send 'didtool' message */
1233  FrontendMessage *didToolMsg;
1234  didToolMsg = new FrontendMessageDidTool(buildingProps->toolName, x, y);
1235  effects->addFrontendMessage(didToolMsg);
1236  }
1237 
1238  return result;
1239 }
1240 
1243  BuildingProperties(3, 3, RESBASE, TOOL_RESIDENTIAL, "Res", false);
1244 
1247  BuildingProperties(3, 3, COMBASE, TOOL_COMMERCIAL, "Com", false);
1248 
1251  BuildingProperties(3, 3, INDBASE, TOOL_INDUSTRIAL, "Ind", false);
1252 
1255  BuildingProperties(3, 3, POLICESTBASE, TOOL_POLICESTATION, "Pol", false);
1256 
1259  BuildingProperties(3, 3, FIRESTBASE, TOOL_FIRESTATION, "Fire", false);
1260 
1263  BuildingProperties(4, 4, STADIUMBASE, TOOL_STADIUM, "Stad", false);
1264 
1267  BuildingProperties(4, 4, COALBASE, TOOL_COALPOWER, "Coal", false);
1268 
1271  BuildingProperties(4, 4, NUCLEARBASE, TOOL_NUCLEARPOWER, "Nuc", true);
1272 
1275  BuildingProperties(4, 4, PORTBASE, TOOL_SEAPORT, "Seap", false);
1276 
1279  BuildingProperties(6, 6, AIRPORTBASE, TOOL_AIRPORT, "Airp", false);
1280 
1281 
1287 {
1288  if (!testBounds(x, y)) {
1289  return TOOLRESULT_FAILED;
1290  }
1291 
1292  ToolResult result = putDownNetwork(x, y, effects);
1293 
1294  if (result == TOOLRESULT_OK) {
1295  /* send 'didtool' message */
1296  FrontendMessage *didToolMsg;
1297  didToolMsg = new FrontendMessageDidTool("Net", x, y);
1298  effects->addFrontendMessage(didToolMsg);
1299  }
1300 
1301  return result;
1302 }
1303 
1304 
1305 ToolResult Micropolis::waterTool(short x, short y, ToolEffects *effects)
1306 {
1307  if (!testBounds(x, y)) {
1308  return TOOLRESULT_FAILED;
1309  }
1310 
1311  ToolResult result = bulldozerTool(x, y, effects);
1312 
1313  if (result == TOOLRESULT_OK) {
1314  result = putDownWater(x, y, effects);
1315  }
1316 
1317  if (result == TOOLRESULT_OK) {
1318  /* send 'didtool' message */
1319  FrontendMessage *didToolMsg;
1320  didToolMsg = new FrontendMessageDidTool("Water", x, y);
1321  effects->addFrontendMessage(didToolMsg);
1322  }
1323 
1324  return result;
1325 }
1326 
1327 
1328 ToolResult Micropolis::landTool(short x, short y, ToolEffects *effects)
1329 {
1330  if (!testBounds(x, y)) {
1331  return TOOLRESULT_FAILED;
1332  }
1333 
1336  ToolResult result = bulldozerTool(x, y, effects);
1337 
1338  result = putDownLand(x, y, effects);
1339 
1340  if (result == TOOLRESULT_OK) {
1341  /* send 'didtool' message */
1342  FrontendMessage *didToolMsg;
1343  didToolMsg = new FrontendMessageDidTool("Land", x, y);
1344  effects->addFrontendMessage(didToolMsg);
1345  }
1346 
1347  return result;
1348 }
1349 
1350 
1351 ToolResult Micropolis::forestTool(short x, short y, ToolEffects *effects)
1352 {
1353  ToolResult result = TOOLRESULT_OK;
1354 
1355  if (!testBounds(x, y)) {
1356  return TOOLRESULT_FAILED;
1357  }
1358 
1359  MapValue tile = effects->getMapValue(x, y);
1360 
1361  if (isTree(tile)) {
1362  return TOOLRESULT_OK;
1363  }
1364 
1365  if ((tile & LOMASK) != DIRT) {
1367  result = bulldozerTool(x, y, effects);
1368  }
1369 
1370  tile = effects->getMapValue(x, y);
1371 
1372  if (tile == DIRT) {
1373  result = putDownForest(x, y, effects);
1374 
1375  if (result == TOOLRESULT_OK) {
1376  /* send 'didtool' message */
1377  FrontendMessage *didToolMsg;
1378  didToolMsg = new FrontendMessageDidTool("Forest", x, y);
1379  effects->addFrontendMessage(didToolMsg);
1380  }
1381 
1382  } else {
1383  result = TOOLRESULT_FAILED;
1384  }
1385 
1386  return result;
1387 }
1388 
1389 
1397 ToolResult Micropolis::doTool(EditingTool tool, short tileX, short tileY)
1398 {
1399  ToolEffects effects(this);
1400  ToolResult result;
1401 
1402  switch (tool) {
1403 
1404  case TOOL_RESIDENTIAL:
1405  result = buildBuildingTool(tileX, tileY, &residentialZoneBuilding,
1406  &effects);
1407  break;
1408 
1409  case TOOL_COMMERCIAL:
1410  result = buildBuildingTool(tileX, tileY, &commercialZoneBuilding,
1411  &effects);
1412  break;
1413 
1414  case TOOL_INDUSTRIAL:
1415  result = buildBuildingTool(tileX, tileY, &industrialZoneBuilding,
1416  &effects);
1417  break;
1418 
1419  case TOOL_FIRESTATION:
1420  result = buildBuildingTool(tileX, tileY, &fireStationBuilding,
1421  &effects);
1422  break;
1423 
1424  case TOOL_POLICESTATION:
1425  result = buildBuildingTool(tileX, tileY, &policeStationBuilding,
1426  &effects);
1427  break;
1428 
1429  case TOOL_QUERY:
1430  return queryTool(tileX, tileY);
1431 
1432  case TOOL_WIRE:
1433  result = wireTool(tileX, tileY, &effects);
1434  break;
1435 
1436  case TOOL_BULLDOZER:
1437  result = bulldozerTool(tileX, tileY, &effects);
1438  break;
1439 
1440  case TOOL_RAILROAD:
1441  result = railroadTool(tileX, tileY, &effects);
1442  break;
1443 
1444  case TOOL_ROAD:
1445  result = roadTool(tileX, tileY, &effects);
1446  break;
1447 
1448  case TOOL_STADIUM:
1449  result = buildBuildingTool(tileX, tileY, &stadiumBuilding,
1450  &effects);
1451  break;
1452 
1453  case TOOL_PARK:
1454  result = parkTool(tileX, tileY, &effects);
1455  break;
1456 
1457  case TOOL_SEAPORT:
1458  result = buildBuildingTool(tileX, tileY, &seaportBuilding,
1459  &effects);
1460  break;
1461 
1462  case TOOL_COALPOWER:
1463  result = buildBuildingTool(tileX, tileY, &coalPowerBuilding,
1464  &effects);
1465  break;
1466 
1467  case TOOL_NUCLEARPOWER:
1468  result = buildBuildingTool(tileX, tileY, &nuclearPowerBuilding,
1469  &effects);
1470  break;
1471 
1472  case TOOL_AIRPORT:
1473  result = buildBuildingTool(tileX, tileY, &airportBuilding,
1474  &effects);
1475  break;
1476 
1477  case TOOL_NETWORK:
1478  result = networkTool(tileX, tileY, &effects);
1479  break;
1480 
1481  case TOOL_WATER:
1482  result = waterTool(tileX, tileY, &effects);
1483  break;
1484 
1485  case TOOL_LAND:
1486  result = landTool(tileX, tileY, &effects);
1487  break;
1488 
1489  case TOOL_FOREST:
1490  result = forestTool(tileX, tileY, &effects);
1491  break;
1492 
1493  default:
1494  return TOOLRESULT_FAILED;
1495 
1496  }
1497 
1498  // Perform the effects of applying the tool if enough funds.
1499  if (result == TOOLRESULT_OK) {
1500  if (!effects.modifyIfEnoughFunding()) {
1501  return TOOLRESULT_NO_MONEY;
1502  }
1503  }
1504 
1505  return result;
1506 }
1507 
1508 
1509 void Micropolis::toolDown(EditingTool tool, short tileX, short tileY)
1510 {
1511  ToolResult result = doTool(tool, tileX, tileY);
1512 
1513  if (result == TOOLRESULT_NEED_BULLDOZE) {
1517  makeSound("interface", "UhUh", tileX <<4, tileY <<4);
1518 
1519  } else if (result == TOOLRESULT_NO_MONEY) {
1523  makeSound("interface", "Sorry", tileX <<4, tileY <<4);
1524  }
1525 
1526  simPass = 0;
1527  invalidateMaps();
1528 }
1529 
1539  short fromX, short fromY, short toX, short toY)
1540 {
1541  // Do not drag big tools.
1542  int toolSize = gToolSize[tool];
1543  if (toolSize > 1) {
1544  doTool(tool, toX, toY);
1545 
1546  simPass = 0; // update editors overlapping this one
1547  invalidateMaps();
1548  return;
1549  }
1550 
1551  short dirX = (toX > fromX) ? 1 : -1; // Horizontal step direction.
1552  short dirY = (toY > fromY) ? 1 : -1; // Vertical step direction.
1553 
1554 
1555  if (fromX == toX && fromY == toY) {
1556  return;
1557  }
1558 
1559  doTool(tool, fromX, fromY); // Ensure the start position is done.
1560 
1561  // Vertical line up or down
1562  if (fromX == toX && fromY != toY) {
1563 
1564  while (fromY != toY) {
1565  fromY += dirY;
1566  doTool(tool, fromX, fromY);
1567  }
1568 
1569  simPass = 0; // update editors overlapping this one
1570  invalidateMaps();
1571  return;
1572  }
1573 
1574  // Horizontal line left/right
1575  if (fromX != toX && fromY == toY) {
1576 
1577  while (fromX != toX) {
1578  fromX += dirX;
1579  doTool(tool, fromX, fromY);
1580  }
1581 
1582  simPass = 0; // update editors overlapping this one
1583  invalidateMaps();
1584  return;
1585  }
1586 
1587  // General case: both X and Y change.
1588 
1589  short dx = absoluteValue(fromX - toX); // number of horizontal steps.
1590  short dy = absoluteValue(fromY - toY); // number of vertical steps.
1591 
1592  short subX = 0; // Each X step is dy sub-steps.
1593  short subY = 0; // Each Y step is dx sub-steps.
1594  short numSubsteps = min(dx, dy); // Number of sub-steps we can do.
1595 
1596  while (fromX != toX || fromY != toY) {
1597  subX += numSubsteps;
1598  if (subX >= dy) {
1599  subX -= dy;
1600  fromX += dirX;
1601  doTool(tool, fromX, fromY);
1602  }
1603 
1604  subY += numSubsteps;
1605  if (subY >= dx) {
1606  subY -= dx;
1607  fromY += dirY;
1608  doTool(tool, fromX, fromY);
1609  }
1610  }
1611 
1612  simPass = 0;
1613  invalidateMaps();
1614 }
1615 
1616 
const int sizeX
Number of tiles in horizontal direction.
Definition: tool.h:330
const EditingTool tool
Tool needed for making the building.
Definition: tool.h:335
std::string toolName
Definition: tool.h:338
const int sizeY
Number of tiles in vertical direction.
Definition: tool.h:331
const bool buildingIsAnimated
Building has animated tiles.
Definition: tool.h:340
const MapTile baseTile
Tile value at top-left in the map.
Definition: tool.h:333
DATA worldGet(int x, int y) const
Definition: map_type.h:316
void toolDown(EditingTool tool, short tileX, short tileY)
Definition: tool.cpp:1509
void doZoneStatus(short mapH, short mapV)
Definition: tool.cpp:838
ToolResult buildBuilding(int mapH, int mapV, const BuildingProperties *bprops, ToolEffects *effects)
Definition: tool.cpp:711
bool tally(short tileValue)
Definition: tool.cpp:535
ToolResult wireTool(short x, short y, ToolEffects *effects)
Definition: tool.cpp:1172
ToolResult putDownNetwork(short mapH, short mapV, ToolEffects *effects)
Definition: tool.cpp:282
Callback * callback
Definition: micropolis.h:954
MapByte2 crimeRateMap
Crime rate map.
Definition: micropolis.h:1248
ToolResult networkTool(short x, short y, ToolEffects *effects)
Definition: tool.cpp:1286
ToolResult railroadTool(short x, short y, ToolEffects *effects)
Definition: tool.cpp:1146
void checkBorder(short xMap, short yMap, int sizeX, int sizeY, ToolEffects *effects)
Definition: tool.cpp:575
ToolResult queryTool(short x, short y)
Definition: tool.cpp:972
ToolResult connectTile(short x, short y, ConnectTileCommand cmd, ToolEffects *effects)
Definition: connect.cpp:133
short getRandom(short range)
Definition: random.cpp:110
bool doAnimation
Definition: micropolis.h:1887
ToolResult putDownLand(short mapH, short mapV, ToolEffects *effects)
Definition: tool.cpp:333
ToolResult putDownPark(short mapH, short mapV, ToolEffects *effects)
Definition: tool.cpp:252
ToolResult putDownForest(short mapH, short mapV, ToolEffects *effects)
Definition: tool.cpp:366
ToolResult parkTool(short x, short y, ToolEffects *effects)
Definition: tool.cpp:1198
void updateFunds()
Definition: update.cpp:127
ToolResult prepareBuildingSite(int leftX, int topY, int sizeX, int sizeY, ToolEffects *effects)
Definition: tool.cpp:657
short checkSize(short tileValue)
Definition: tool.cpp:548
unsigned short * map[WORLD_W]
Definition: micropolis.h:1120
ToolResult doTool(EditingTool tool, short tileX, short tileY)
Definition: tool.cpp:1397
void sendMessage(short Mnum, short x=NOWHERE, short y=NOWHERE, bool picture=false, bool important=false)
Definition: message.cpp:390
void makeSound(const std::string &channel, const std::string &sound, int x=-1, int y=-1)
MapByte2 pollutionDensityMap
Pollution density map.
Definition: micropolis.h:1246
int getDensity(short catNo, short mapH, short mapV)
Definition: tool.cpp:788
ToolResult putDownWater(short mapH, short mapV, ToolEffects *effects)
Definition: tool.cpp:310
void toolDrag(EditingTool tool, short fromX, short fromY, short toX, short toY)
Definition: tool.cpp:1538
void spend(int dollars)
static bool testBounds(int wx, int wy)
Definition: micropolis.h:2378
void invalidateMaps()
void putRubble(int x, int y, int size, ToolEffects *effects)
Definition: tool.cpp:923
ToolResult landTool(short x, short y, ToolEffects *effects)
Definition: tool.cpp:1328
MapByte2 populationDensityMap
Population density map.
Definition: micropolis.h:1244
MapByte2 landValueMap
Land value map.
Definition: micropolis.h:1247
MapShort8 rateOfGrowthMap
Definition: micropolis.h:1290
void putBuilding(int leftX, int topY, int sizeX, int sizeY, MapTile baseTile, bool aniFlag, ToolEffects *effects)
Definition: tool.cpp:617
void smoothTreesAt(int x, int y, bool preserve)
Definition: generate.cpp:429
void didTool(std::string name, short x, short y)
Definition: tool.cpp:947
ToolResult roadTool(short x, short y, ToolEffects *effects)
Definition: tool.cpp:1120
void doShowZoneStatus(int tileCategoryIndex, int populationDensityIndex, int landValueIndex, int crimeRateIndex, int pollutionIndex, int growthRateIndex, int x, int y)
Definition: tool.cpp:903
Quad totalFunds
Funds of the player.
Definition: micropolis.h:2315
bool autoBulldoze
Definition: micropolis.h:2323
ToolResult forestTool(short x, short y, ToolEffects *effects)
Definition: tool.cpp:1351
ToolResult buildBuildingTool(short x, short y, const BuildingProperties *bprops, ToolEffects *effects)
Definition: tool.cpp:1225
int posY
Vertical coordnate of the position.
Definition: position.h:169
int posX
Horizontal coordinate of the position.
Definition: position.h:168
FrontendMessages frontendMessages
Collected messages to send.
Definition: tool.h:228
Micropolis * sim
Simulator to get map values from, and to apply changes.
Definition: tool.h:225
void setMapValue(const Position &pos, MapValue mapVal)
Definition: tool.cpp:186
bool modifyIfEnoughFunding()
Definition: tool.cpp:152
WorldModificationsMap modifications
Collected world modifications.
Definition: tool.h:227
void addFrontendMessage(FrontendMessage *msg)
Definition: tool.h:313
MapTile getMapTile(const Position &pos) const
Definition: tool.h:242
void modifyWorld()
Definition: tool.cpp:121
void addCost(int amount)
Definition: tool.h:275
void clear()
Definition: tool.cpp:103
ToolEffects(Micropolis *sim)
Definition: tool.cpp:86
int cost
Accumulated costs.
Definition: tool.h:226
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.
@ CONNECT_TILE_FIX
Fix zone (connect wire, road, and rail).
Definition: micropolis.h:351
@ CONNECT_TILE_ROAD
Lay road and fix zone.
Definition: micropolis.h:353
@ CONNECT_TILE_WIRE
Lay wire and fix zone.
Definition: micropolis.h:355
@ CONNECT_TILE_RAILROAD
Lay rail and fix zone.
Definition: micropolis.h:354
@ CONNECT_TILE_BULLDOZE
Bulldoze and fix zone.
Definition: micropolis.h:352
@ LASTPOWERPLANT
Last tile of coal power plant.
Definition: micropolis.h:581
@ NUCLEARBASE
First tile nuclear power plant.
Definition: micropolis.h:603
@ COALBASE
First tile of coal power plant.
Definition: micropolis.h:579
@ FIRESTBASE
First tile of fire station.
Definition: micropolis.h:584
@ STADIUMBASE
First tile stadium.
Definition: micropolis.h:594
@ LASTZONE
Also last tile nuclear power plant.
Definition: micropolis.h:605
@ STADIUM
'Center tile' stadium.
Definition: micropolis.h:595
@ NUCLEAR
'Center' tile nuclear power plant.
Definition: micropolis.h:604
@ PORTBASE
Top-left tile of the seaport.
Definition: micropolis.h:567
@ PORT
Center tile of the seaport.
Definition: micropolis.h:568
@ COALSMOKE3
927 last animation tile for chimney at coal power plant (2, 1).
Definition: micropolis.h:644
@ POWERPLANT
'Center' tile of coal power plant.
Definition: micropolis.h:580
@ RADTILE
Radio-active contaminated tile.
Definition: micropolis.h:415
@ DIRT
Clear tile.
Definition: micropolis.h:382
@ INDBASE
Top-left tile of empty industrial zone.
Definition: micropolis.h:536
@ COALSMOKE1
919 last animation tile for chimney at coal power plant (2, 0).
Definition: micropolis.h:638
@ LASTPORT
Last tile of the seaport.
Definition: micropolis.h:569
#define NOT_REACHED()
Definition: micropolis.h:847
ToolResult
Definition: micropolis.h:363
@ TOOLRESULT_FAILED
Cannot build here.
Definition: micropolis.h:366
@ TOOLRESULT_OK
Build succeeded.
Definition: micropolis.h:367
@ TOOLRESULT_NEED_BULLDOZE
Clear the area first.
Definition: micropolis.h:365
@ TOOLRESULT_NO_MONEY
User has not enough money for tool.
Definition: micropolis.h:364
static T min(const T a, const T b)
Definition: micropolis.h:783
static const int NOWHERE
Definition: micropolis.h:233
static T clamp(const T val, const T lower, const T upper)
Definition: micropolis.h:808
static T absoluteValue(const T val)
Definition: micropolis.h:825
@ STR202_POPULATIONDENSITY_LOW
Low.
Definition: text.h:85
@ STR202_LANDVALUE_HIGH_CLASS
High.
Definition: text.h:93
@ STR202_GROWRATE_STABLE
Stable.
Definition: text.h:106
@ STR202_LANDVALUE_LOWER_CLASS
Lower Class.
Definition: text.h:91
@ STR202_LANDVALUE_SLUM
Slum.
Definition: text.h:90
@ STR202_GROWRATE_DECLINING
Declining.
Definition: text.h:105
@ STR202_LANDVALUE_MIDDLE_CLASS
Middle Class.
Definition: text.h:92
@ STR202_GROWRATE_SLOWGROWTH
Slow Growth.
Definition: text.h:107
@ STR202_GROWRATE_FASTGROWTH
Fast Growth.
Definition: text.h:108
@ STR202_CRIME_NONE
Safe.
Definition: text.h:95
@ STR202_POLLUTION_NONE
None.
Definition: text.h:100
@ MESSAGE_BULLDOZE_AREA_FIRST
Area must be bulldozed first.
Definition: text.h:146
@ MESSAGE_NOT_ENOUGH_FUNDS
Insufficient funds to build that.
Definition: text.h:145
static const BuildingProperties seaportBuilding
Definition: tool.cpp:1274
static const BuildingProperties industrialZoneBuilding
Definition: tool.cpp:1250
static short checkBigZone(MapTile id, short *deltaHPtr, short *deltaVPtr)
Definition: tool.cpp:402
static const BuildingProperties fireStationBuilding
Definition: tool.cpp:1258
static const BuildingProperties residentialZoneBuilding
Definition: tool.cpp:1242
static const short gCostOf[]
Definition: tool.cpp:216
static const BuildingProperties policeStationBuilding
Definition: tool.cpp:1254
static const BuildingProperties stadiumBuilding
Definition: tool.cpp:1262
static const short gToolSize[]
Definition: tool.cpp:230
static const BuildingProperties commercialZoneBuilding
Definition: tool.cpp:1246
static const BuildingProperties coalPowerBuilding
Definition: tool.cpp:1266
static const BuildingProperties nuclearPowerBuilding
Definition: tool.cpp:1270
static const BuildingProperties airportBuilding
Definition: tool.cpp:1278
unsigned short MapTile
Definition: tool.h:108
@ BURNBIT
bit 13, tile can be lit.
Definition: tool.h:122
@ LOMASK
Mask for the Tiles part of the tile.
Definition: tool.h:129
@ ZONEBIT
bit 10, tile is the center tile of the zone.
Definition: tool.h:125
@ CONDBIT
bit 14. tile can conduct electricity.
Definition: tool.h:121
@ BULLBIT
bit 12, tile is bulldozable.
Definition: tool.h:123
@ ANIMBIT
bit 11, tile is animated.
Definition: tool.h:124
unsigned short MapValue
Definition: tool.h:94
EditingTool
Definition: tool.h:142