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
93ToolEffects::~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
194BuildingProperties::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
205BuildingProperties::~BuildingProperties()
206{
207}
208
209
211
216static 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
230static 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
252ToolResult 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
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
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
333ToolResult 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
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
402static 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
535bool 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
548short 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
575void 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
617void 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 */
743static 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
788int 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;
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
838void 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
923void 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
947void 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
984ToolResult 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
1010ToolResult 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
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
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
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
1305ToolResult 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
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
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
1397ToolResult 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
1509void 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;
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
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
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
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;
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:955
MapByte2 crimeRateMap
Crime rate map.
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
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]
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.
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)
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.
MapByte2 landValueMap
Land value map.
MapShort8 rateOfGrowthMap
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.
bool autoBulldoze
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:848
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:784
static const int NOWHERE
Definition micropolis.h:233
static T clamp(const T val, const T lower, const T upper)
Definition micropolis.h:809
static T absoluteValue(const T val)
Definition micropolis.h:826
@ 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:101
EditingTool
Definition tool.h:142