Micropolis
zone.cpp
Go to the documentation of this file.
1 /* zone.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 
91 void Micropolis::doZone(const Position &pos)
92 {
93  // Set Power Bit in Map from powerGridMap
94  bool zonePowerFlag = setZonePower(pos);
95 
96 
97  if (zonePowerFlag) {
99  } else {
101  }
102 
103  MapTile tile = map[pos.posX][pos.posY] & LOMASK;
104 
105  // Do special zones.
106  if ((tile > PORTBASE) &&
107  (tile < CHURCH1BASE)) {
108  doSpecialZone(pos, zonePowerFlag);
109  return;
110  }
111 
112  // Do residential zones.
113  if (tile < HOSPITAL) {
114  doResidential(pos, zonePowerFlag);
115  return;
116  }
117 
118  // Do hospitals and churches.
119  if ((tile < COMBASE) ||
120  ((tile >= CHURCH1BASE) &&
121  (tile <= CHURCH7LAST))) {
122  doHospitalChurch(pos);
123  return;
124  }
125 
126  // Do commercial zones.
127  if (tile < INDBASE) {
128  doCommercial(pos, zonePowerFlag);
129  return;
130  }
131 
132  // Do industrial zones.
133  if (tile < CHURCH1BASE) {
134  doIndustrial(pos, zonePowerFlag);
135  return;
136  }
137 
138  printf("UNEXPOECTED ZONE: %d !!!\n", tile);
139 }
140 
146 {
147  MapTile tile = map[pos.posX][pos.posY] & LOMASK;
148 
149  if (tile == HOSPITAL) {
150 
151  hospitalPop++;
152 
153  if (!(cityTime & 15)) {
154  repairZone(pos, HOSPITAL, 3);
155  }
156 
157  if (needHospital == -1) { // Too many hospitals!
158  if (!getRandom(20)) {
159  zonePlop(pos, RESBASE); // Remove hospital.
160  }
161  }
162 
163  } else if ((tile == CHURCH0) ||
164  (tile == CHURCH1) ||
165  (tile == CHURCH2) ||
166  (tile == CHURCH3) ||
167  (tile == CHURCH4) ||
168  (tile == CHURCH5) ||
169  (tile == CHURCH6) ||
170  (tile == CHURCH7)) {
171 
172  churchPop++;
173 
174  //printf("CHURCH %d %d %d %d\n", churchPop, pos.posX, pos.posY, tile);
175 
176  bool simulate = true;
177 
178  if (!(cityTime & 15)) {
179  repairZone(pos, tile, 3);
180  }
181 
182  if (needChurch == -1) { // Too many churches!
183  if (!getRandom(20)) {
184  zonePlop(pos, RESBASE); // Remove church.
185  simulate = false;
186  }
187  }
188 
189  if (simulate) {
190  //printf("SIM %d %d %d\n", pos.posX, pos.posY, tile);
191 
192  int churchNumber = 0;
193 
194  switch (tile) {
195  case CHURCH0:
196  churchNumber = 0;
197  break;
198  case CHURCH1:
199  churchNumber = 1;
200  break;
201  case CHURCH2:
202  churchNumber = 2;
203  break;
204  case CHURCH3:
205  churchNumber = 3;
206  break;
207  case CHURCH4:
208  churchNumber = 4;
209  break;
210  case CHURCH5:
211  churchNumber = 5;
212  break;
213  case CHURCH6:
214  churchNumber = 6;
215  break;
216  case CHURCH7:
217  churchNumber = 7;
218  break;
219  default:
220  assert(0); // Unexpected church tile
221  break;
222  }
223 
224  callback->simulateChurch(this, callbackVal, pos.posX, pos.posY, churchNumber);
225  }
226 
227  }
228 
229 }
230 
231 
232 #define ASCBIT (ANIMBIT | CONDBIT | BURNBIT)
233 #define REGBIT (CONDBIT | BURNBIT)
234 
235 void Micropolis::setSmoke(const Position &pos, bool zonePower)
236 {
237  static bool aniThis[8] = { true, false, true, true, false, false, true, true };
238  static short dx1[8] = { -1, 0, 1, 0, 0, 0, 0, 1 };
239  static short dy1[8] = { -1, 0, -1, -1, 0, 0, -1, -1 };
240  static short aniTabA[8] = { 0, 0, 32, 40, 0, 0, 48, 56 };
241  static short aniTabB[8] = { 0, 0, 36, 44, 0, 0, 52, 60 };
242  static short aniTabC[8] = { IND1, 0, IND2, IND4, 0, 0, IND6, IND8 };
243  static short aniTabD[8] = { IND1, 0, IND3, IND5, 0, 0, IND7, IND9 };
244 
245  MapTile tile = map[pos.posX][pos.posY] & LOMASK;
246 
247  if (tile < IZB) {
248  return;
249  }
250 
251  int z = (tile - IZB) >>3;
252  z = z & 7;
253 
254  if (aniThis[z]) {
255  int xx = pos.posX + dx1[z];
256  int yy = pos.posY + dy1[z];
257 
258  if (testBounds(xx, yy)) {
259 
260  if (zonePower) {
261 
264  if ((map[xx][yy] & LOMASK) == aniTabC[z]) {
265  map[xx][yy] = ASCBIT | (SMOKEBASE + aniTabA[z]);
266  map[xx][yy] = ASCBIT | (SMOKEBASE + aniTabB[z]);
267  }
268 
269  } else {
270 
272  if ((map[xx][yy] & LOMASK) > aniTabC[z]) {
273  map[xx][yy] = REGBIT | aniTabC[z];
274  map[xx][yy] = REGBIT | aniTabD[z];
275  }
276 
277  }
278 
279  }
280 
281  }
282 
283 }
284 
285 
291 {
292  if (needHospital > 0) {
293  zonePlop(pos, HOSPITAL - 4);
294  needHospital = 0;
295  return;
296  }
297 
298  if (needChurch > 0) {
299  int churchType = getRandom(7); // 0 to 7 inclusive
300  int tile;
301  if (churchType == 0) {
302  tile = CHURCH0;
303  } else {
304  tile = CHURCH1 + ((churchType - 1) * 9);
305  }
306 
307  //printf("NEW CHURCH tile %d x %d y %d type %d\n", tile, pos.posX, pos.posY, churchType);
308 
309  zonePlop(pos, tile - 4);
310  needChurch = 0;
311  return;
312  }
313 }
314 
322 {
323  short landVal;
324 
325  landVal = landValueMap.worldGet(pos.posX, pos.posY);
326  landVal -= pollutionDensityMap.worldGet(pos.posX, pos.posY);
327 
328  if (landVal < 30) {
329  return 0;
330  }
331 
332  if (landVal < 80) {
333  return 1;
334  }
335 
336  if (landVal < 150) {
337  return 2;
338  }
339 
340  return 3;
341 }
342 
343 
349 void Micropolis::incRateOfGrowth(const Position &pos, int amount)
350 {
351  int value = rateOfGrowthMap.worldGet(pos.posX, pos.posY);
352 
353  value = clamp(value + amount * 4, -200, 200);
354  rateOfGrowthMap.worldSet(pos.posX, pos.posY, value);
355 }
356 
357 
364 bool Micropolis::zonePlop(const Position &pos, int base)
365 {
366  short z, x;
367  static const short Zx[9] = {-1, 0, 1,-1, 0, 1,-1, 0, 1};
368  static const short Zy[9] = {-1,-1,-1, 0, 0, 0, 1, 1, 1};
369 
370  for (z = 0; z < 9; z++) { /* check for fire */
371  int xx = pos.posX + Zx[z];
372  int yy = pos.posY + Zy[z];
373 
374  if (testBounds(xx, yy)) {
375  x = map[xx][yy] & LOMASK;
376 
377  if ((x >= FLOOD) && (x < ROADBASE)) {
378  return false;
379  }
380 
381  }
382 
383  }
384 
385  for (z = 0; z < 9; z++) {
386  int xx = pos.posX + Zx[z];
387  int yy = pos.posY + Zy[z];
388 
389  if (testBounds(xx, yy)) {
390  map[xx][yy] = base + BNCNBIT;
391  }
392 
393  base++;
394  }
395 
396  setZonePower(pos);
397  map[pos.posX][pos.posY] |= ZONEBIT + BULLBIT;
398 
399  return true;
400 }
401 
408 {
409  short count = 0;
410 
411  for (short x = pos.posX - 1; x <= pos.posX + 1; x++) {
412  for (short y = pos.posY - 1; y <= pos.posY + 1; y++) {
413  if (x >= 0 && x < WORLD_W && y >= 0 && y < WORLD_H) {
414  MapTile tile = map[x][y] & LOMASK;
415  if (tile >= LHTHR && tile <= HHTHR) {
416  count++;
417  }
418  }
419  }
420  }
421 
422  return count;
423 }
424 
425 
432 {
433  MapValue mapValue = map[pos.posX][pos.posY];
434  MapTile tile = mapValue & LOMASK;
435 
436  if (tile == NUCLEAR || tile == POWERPLANT) {
437  map[pos.posX][pos.posY] = mapValue | PWRBIT;
438  return true;
439  }
440 
441  if (powerGridMap.worldGet(pos.posX, pos.posY)) {
442  map[pos.posX][pos.posY] = mapValue | PWRBIT;
443  return true;
444  } else {
445  map[pos.posX][pos.posY] = mapValue & (~PWRBIT);
446  return false;
447  }
448 }
449 
450 
457 void Micropolis::buildHouse(const Position &pos, int value)
458 {
459  short z, score, hscore, BestLoc;
460  static short ZeX[9] = { 0,-1, 0, 1,-1, 1,-1, 0, 1};
461  static short ZeY[9] = { 0,-1,-1,-1, 0, 0, 1, 1, 1};
462 
463  BestLoc = 0;
464  hscore = 0;
465 
466  for (z = 1; z < 9; z++) {
467  int xx = pos.posX + ZeX[z];
468  int yy = pos.posY + ZeY[z];
469 
470  if (testBounds(xx, yy)) {
471 
472  score = evalLot(xx, yy);
473 
475  if (score != 0) {
476 
477  if (score > hscore) {
478  hscore = score;
479  BestLoc = z;
480  }
481 
484  // trigger this code too.
485  if (score == hscore && !(getRandom16() & 7)) {
486  BestLoc = z;
487  }
488 
489  }
490 
491  }
492 
493  }
494 
495  if (BestLoc) {
496  int xx = pos.posX + ZeX[BestLoc];
497  int yy = pos.posY + ZeY[BestLoc];
498 
499  if (testBounds(xx, yy)) {
501  map[xx][yy] = HOUSE + BLBNCNBIT + getRandom(2) + value * 3;
502  }
503 
504  }
505 }
506 
507 
512 short Micropolis::evalLot(int x, int y)
513 {
514  short z, score;
515  static short DX[4] = { 0, 1, 0,-1};
516  static short DY[4] = {-1, 0, 1, 0};
517 
518  /* test for clear lot */
519  z = map[x][y] & LOMASK;
520 
521  if (z && (z < RESBASE || z > RESBASE + 8)) {
522  return -1;
523  }
524 
525  score = 1;
526 
527  for (z = 0; z < 4; z++) {
528  int xx = x + DX[z];
529  int yy = y + DY[z];
530 
531  if (testBounds(xx, yy) &&
532  map[xx][yy] != DIRT && (map[xx][yy] & LOMASK) <= LASTROAD) {
533  score++; /* look for road */
534  }
535 
536  }
537 
538  return score;
539 }
540 
546 void Micropolis::doResidential(const Position &pos, bool zonePower)
547 {
548  short tpop, zscore, locvalve, value, TrfGood;
549 
550  resZonePop++;
551 
552  MapTile tile = map[pos.posX][pos.posY] & LOMASK;
553 
554  if (tile == FREEZ) {
555  tpop = doFreePop(pos);
556  } else {
557  tpop = getResZonePop(tile);
558  }
559 
560  resPop += tpop;
561 
562  if (tpop > getRandom(35)) {
563  /* Try driving from residential to commercial */
564  TrfGood = makeTraffic(pos, ZT_COMMERCIAL);
565  } else {
566  TrfGood = 1;
567  }
568 
569  if (TrfGood == -1) {
570  value = getLandPollutionValue(pos);
571  doResOut(pos, tpop, value);
572  return;
573  }
574 
575  if (tile == FREEZ || !(getRandom16() & 7)) {
576 
577  locvalve = evalRes(pos, TrfGood);
578  zscore = resValve + locvalve;
579 
580  if (!zonePower) {
581  zscore = -500;
582  }
583 
584  if (zscore > -350 &&
585  ((short)(zscore - 26380) > ((short)getRandom16Signed()))) {
586 
587  if (!tpop && !(getRandom16() & 3)) {
588  makeHospital(pos);
589  return;
590  }
591 
592  value = getLandPollutionValue(pos);
593  doResIn(pos, tpop, value);
594  return;
595  }
596 
597  if (zscore < 350 &&
598  (((short)(zscore + 26380)) < ((short)getRandom16Signed()))) {
599  value = getLandPollutionValue(pos);
600  doResOut(pos, tpop, value);
601  }
602  }
603 }
604 
605 
612 void Micropolis::doResIn(const Position &pos, int pop, int value)
613 {
614  short pollution = pollutionDensityMap.worldGet(pos.posX, pos.posY);
615 
616  if (pollution > 128) {
617  return;
618  }
619 
620  MapTile tile = map[pos.posX][pos.posY] & LOMASK;
621 
622  if (tile == FREEZ) {
623 
624  if (pop < 8) {
625  buildHouse(pos, value);
626  incRateOfGrowth(pos, 1);
627  return;
628  }
629 
630  if (populationDensityMap.worldGet(pos.posX, pos.posY) > 64) {
631  resPlop(pos, 0, value);
632  incRateOfGrowth(pos, 8);
633  return;
634  }
635 
636  return;
637  }
638 
639  if (pop < 40) {
640  resPlop(pos, (pop / 8) - 1, value);
641  incRateOfGrowth(pos, 8);
642  }
643 
644 }
645 
646 
653 void Micropolis::doResOut(const Position &pos, int pop, int value)
654 {
655  static short Brdr[9] = {0,3,6,1,4,7,2,5,8};
656  short x, y, loc, z;
657 
658  if (!pop) {
659  return;
660  }
661 
662  if (pop > 16) {
663  resPlop(pos, (pop - 24) / 8, value);
664  incRateOfGrowth(pos, -8);
665  return;
666  }
667 
668  if (pop == 16) {
669  incRateOfGrowth(pos, -8);
670  map[pos.posX][pos.posY] = (FREEZ | BLBNCNBIT | ZONEBIT);
671  for (x = pos.posX - 1; x <= pos.posX + 1; x++) {
672  for (y = pos.posY - 1; y <= pos.posY + 1; y++) {
673  if (testBounds(x, y)) {
674  if ((map[x][y] & LOMASK) != FREEZ) {
675  map[x][y] = LHTHR + value + getRandom(2) + BLBNCNBIT;
676  }
677  }
678  }
679  }
680  }
681 
682  if (pop < 16) {
683  incRateOfGrowth(pos, -1);
684  z = 0;
685  for (x = pos.posX - 1; x <= pos.posX + 1; x++) {
686  for (y = pos.posY - 1; y <= pos.posY + 1; y++) {
687  if (testBounds(x, y)) {
688  loc = map[x][y] & LOMASK;
689  if ((loc >= LHTHR) && (loc <= HHTHR)) {
690  map[x][y] = Brdr[z] + BLBNCNBIT + FREEZ - 4;
691  return;
692  }
693  }
694  z++;
695  }
696  }
697  }
698 }
699 
700 
710 {
711  short CzDen = ((mapTile - RZB) / 9) % 4;
712 
713  return CzDen * 8 + 16;
714 }
715 
722 void Micropolis::resPlop(const Position &pos, int den, int value)
723 {
724  short base;
725 
726  base = ((value * 4 + den) * 9) + RZB - 4;
727  zonePlop(pos, base);
728 }
729 
730 
734 short Micropolis::evalRes(const Position &pos, int traf)
735 {
736  short value;
737 
738  if (traf < 0) {
739  return -3000;
740  }
741 
742  value = landValueMap.worldGet(pos.posX, pos.posY);
743  value -= pollutionDensityMap.worldGet(pos.posX, pos.posY);
744 
745  if (value < 0) {
746  value = 0; /* Cap at 0 */
747  } else {
748  value = min(value * 32, 6000); /* Cap at 6000 */
749  }
750 
751  value = value - 3000;
752 
753  return value;
754 }
755 
756 
763 void Micropolis::doCommercial(const Position &pos, bool zonePower)
764 {
765  short tpop, TrfGood;
766  short zscore, locvalve, value;
767 
768  MapTile tile = map[pos.posX][pos.posY] & LOMASK;
769 
770  comZonePop++;
771  tpop = getComZonePop(tile);
772  comPop += tpop;
773 
774  if (tpop > getRandom(5)) {
775  /* Try driving from commercial to industrial */
776  TrfGood = makeTraffic(pos, ZT_INDUSTRIAL);
777  } else {
778  TrfGood = 1;
779  }
780 
781  if (TrfGood == -1) {
782  value = getLandPollutionValue(pos);
783  doComOut(pos, tpop, value);
784  return;
785  }
786 
787  if (!(getRandom16() & 7)) {
788 
789  locvalve = evalCom(pos, TrfGood);
790  zscore = comValve + locvalve;
791 
792  if (!zonePower) {
793  zscore = -500;
794  }
795 
796  if (TrfGood &&
797  (zscore > -350) &&
798  (((short)(zscore - 26380)) > ((short)getRandom16Signed()))) {
799  value = getLandPollutionValue(pos);
800  doComIn(pos, tpop, value);
801  return;
802  }
803 
804  if ((zscore < 350) &&
805  (((short)(zscore + 26380)) < ((short)getRandom16Signed()))) {
806  value = getLandPollutionValue(pos);
807  doComOut(pos, tpop, value);
808  }
809 
810  }
811 
812 }
813 
814 
821 void Micropolis::doComIn(const Position &pos, int pop, int value)
822 {
823  short z;
824 
825  z = landValueMap.worldGet(pos.posX, pos.posY);
826  z = z >>5;
827 
828  if (pop > z) {
829  return;
830  }
831 
832  if (pop < 5) {
833  comPlop(pos, pop, value);
834  incRateOfGrowth(pos, 8);
835  }
836 }
837 
844 void Micropolis::doComOut(const Position &pos, int pop, int value)
845 {
846  if (pop > 1) {
847  comPlop(pos, pop - 2, value);
848  incRateOfGrowth(pos, -8);
849  return;
850  }
851 
852  if (pop == 1) {
853  zonePlop(pos, COMBASE);
854  incRateOfGrowth(pos, -8);
855  }
856 }
857 
858 
865 {
866  if (tile == COMCLR) {
867  return 0;
868  }
869 
870  short CzDen = ((tile - CZB) / 9) % 5 + 1;
871  return CzDen;
872 }
873 
874 
881 void Micropolis::comPlop(const Position &pos, int Den, int Value)
882 {
883  short base;
884 
885  base = ((Value * 5) + Den) * 9 + CZB - 4;
886  zonePlop(pos, base);
887 }
888 
889 
895 short Micropolis::evalCom(const Position &pos, int traf)
896 {
897  short Value;
898 
899  if (traf < 0) {
900  return -3000;
901  }
902 
903  Value = comRateMap.worldGet(pos.posX, pos.posY);
904 
905  return Value;
906 }
907 
908 
915 void Micropolis::doIndustrial(const Position &pos, bool zonePower)
916 {
917  short tpop, zscore, TrfGood;
918 
919  MapTile tile = map[pos.posX][pos.posY] & LOMASK;
920 
921  indZonePop++;
922  setSmoke(pos, zonePower);
923  tpop = getIndZonePop(tile);
924  indPop += tpop;
925 
926  if (tpop > getRandom(5)) {
927  /* Try driving from industrial to residential */
928  TrfGood = makeTraffic(pos, ZT_RESIDENTIAL);
929  } else {
930  TrfGood = 1;
931  }
932 
933  if (TrfGood == -1) {
934  doIndOut(pos, tpop, getRandom16() & 1);
935  return;
936  }
937 
938  if (!(getRandom16() & 7)) {
939  zscore = indValve + evalInd(TrfGood);
940 
941  if (!zonePower) {
942  zscore = -500;
943  }
944 
945  if (zscore > -350 &&
946  (((short)(zscore - 26380)) > ((short)getRandom16Signed()))) {
947  doIndIn(pos, tpop, getRandom16() & 1);
948  return;
949  }
950 
951  if (zscore < 350 &&
952  (((short)(zscore + 26380)) < ((short)getRandom16Signed()))) {
953  doIndOut(pos, tpop, getRandom16() & 1);
954  }
955  }
956 }
957 
958 
965 void Micropolis::doIndIn(const Position &pos, int pop, int value)
966 {
967  if (pop < 4) {
968  indPlop(pos, pop, value);
969  incRateOfGrowth(pos, 8);
970  }
971 }
972 
979 void Micropolis::doIndOut(const Position &pos, int pop, int value)
980 {
981  if (pop > 1) {
982  indPlop(pos, pop - 2, value);
983  incRateOfGrowth(pos, -8);
984  return;
985  }
986 
987  if (pop == 1) {
988  zonePlop(pos, INDBASE); // empty industrial zone
989  incRateOfGrowth(pos, -8);
990  }
991 }
992 
993 
1000 {
1001  if (tile == INDCLR) {
1002  return 0;
1003  }
1004 
1005  short CzDen = (((tile - IZB) / 9) % 4) + 1;
1006  return CzDen;
1007 }
1008 
1015 void Micropolis::indPlop(const Position &pos, int den, int value)
1016 {
1017  short base = ((value * 4) + den) * 9 + IND1;
1018  zonePlop(pos, base);
1019 }
1020 
1021 
1027 short Micropolis::evalInd(int traf)
1028 {
1029  if (traf < 0) {
1030  return -1000;
1031  }
1032 
1033  return 0;
1034 }
1035 
1036 
DATA worldGet(int x, int y) const
Definition: map_type.h:316
void worldSet(int x, int y, DATA val)
Definition: map_type.h:297
short getLandPollutionValue(const Position &pos)
Definition: zone.cpp:321
short indPop
Definition: micropolis.h:996
short getResZonePop(MapTile mapTile)
Definition: zone.cpp:709
short doFreePop(const Position &pos)
Definition: zone.cpp:407
short indZonePop
Number of industrial zones.
Definition: micropolis.h:1015
void makeHospital(const Position &pos)
Definition: zone.cpp:290
void resPlop(const Position &pos, int Den, int Value)
Definition: zone.cpp:722
void doZone(const Position &pos)
Definition: zone.cpp:91
void buildHouse(const Position &pos, int value)
Definition: zone.cpp:457
short getIndZonePop(MapTile tile)
Definition: zone.cpp:999
void doResidential(const Position &pos, bool zonePower)
Definition: zone.cpp:546
short poweredZoneCount
Number of powered tiles in all zone.
Definition: micropolis.h:2107
void doSpecialZone(const Position &pos, bool PwrOn)
Definition: simulate.cpp:1445
Callback * callback
Definition: micropolis.h:954
MapByte1 powerGridMap
Definition: micropolis.h:1281
void indPlop(const Position &pos, int den, int value)
Definition: zone.cpp:1015
short unpoweredZoneCount
Number of unpowered tiles in all zones.
Definition: micropolis.h:2108
bool setZonePower(const Position &pos)
Definition: zone.cpp:431
void comPlop(const Position &pos, int Den, int Value)
Definition: zone.cpp:881
short churchPop
Number of churches.
Definition: micropolis.h:1023
Quad cityTime
Definition: micropolis.h:1092
MapShort8 comRateMap
Definition: micropolis.h:1330
short makeTraffic(int x, int y, ZoneType dest)
Definition: traffic.cpp:118
short evalCom(const Position &pos, int traf)
Definition: zone.cpp:895
short resPop
Definition: micropolis.h:982
short getRandom(short range)
Definition: random.cpp:110
void doIndustrial(const Position &pos, bool zonePower)
Definition: zone.cpp:915
int getRandom16()
Definition: random.cpp:130
void setSmoke(const Position &pos, bool zonePower)
Definition: zone.cpp:235
bool zonePlop(const Position &pos, int base)
Definition: zone.cpp:364
short resZonePop
Number of residential zones.
Definition: micropolis.h:1013
short evalRes(const Position &pos, int traf)
Definition: zone.cpp:734
short evalInd(int traf)
Definition: zone.cpp:1027
void doIndIn(const Position &pos, int pop, int value)
Definition: zone.cpp:965
void doIndOut(const Position &pos, int pop, int value)
Definition: zone.cpp:979
void repairZone(const Position &pos, MapTile zCent, short zSize)
Definition: simulate.cpp:1404
void doResOut(const Position &pos, int pop, int value)
Definition: zone.cpp:653
void doComOut(const Position &pos, int pop, int value)
Definition: zone.cpp:844
short getComZonePop(MapTile tile)
Definition: zone.cpp:864
unsigned short * map[WORLD_W]
Definition: micropolis.h:1120
short hospitalPop
Number of hospitals.
Definition: micropolis.h:1022
void doResIn(const Position &pos, int pop, int value)
Definition: zone.cpp:612
void doHospitalChurch(const Position &pos)
Definition: zone.cpp:145
MapByte2 pollutionDensityMap
Pollution density map.
Definition: micropolis.h:1246
static bool testBounds(int wx, int wy)
Definition: micropolis.h:2378
int getRandom16Signed()
Definition: random.cpp:137
short comPop
Definition: micropolis.h:989
short needHospital
Definition: micropolis.h:1383
short evalLot(int x, int y)
Definition: zone.cpp:512
MapByte2 populationDensityMap
Population density map.
Definition: micropolis.h:1244
void incRateOfGrowth(const Position &pos, int amount)
Definition: zone.cpp:349
void doCommercial(const Position &pos, bool zonePower)
Definition: zone.cpp:763
MapByte2 landValueMap
Land value map.
Definition: micropolis.h:1247
short needChurch
Definition: micropolis.h:1390
MapShort8 rateOfGrowthMap
Definition: micropolis.h:1290
short comZonePop
Number of commercial zones.
Definition: micropolis.h:1014
void doComIn(const Position &pos, int pop, int value)
Definition: zone.cpp:821
int posY
Vertical coordnate of the position.
Definition: position.h:169
int posX
Horizontal coordinate of the position.
Definition: position.h:168
static const int WORLD_H
Definition: map_type.h:95
Header file for Micropolis game engine.
@ ZT_RESIDENTIAL
Residential zone.
Definition: micropolis.h:720
@ ZT_COMMERCIAL
Commercial zone.
Definition: micropolis.h:718
@ ZT_INDUSTRIAL
Industrial zone.
Definition: micropolis.h:719
@ NUCLEAR
'Center' tile nuclear power plant.
Definition: micropolis.h:604
@ PORTBASE
Top-left tile of the seaport.
Definition: micropolis.h:567
@ IZB
Center tile of first non-empty industry zone.
Definition: micropolis.h:542
@ POWERPLANT
'Center' tile of coal power plant.
Definition: micropolis.h:580
@ INDCLR
Center tile of empty industrial zone.
Definition: micropolis.h:537
@ DIRT
Clear tile.
Definition: micropolis.h:382
@ INDBASE
Top-left tile of empty industrial zone.
Definition: micropolis.h:536
@ IND1
Top-left tile of first non-empty industry zone.
Definition: micropolis.h:541
static T min(const T a, const T b)
Definition: micropolis.h:783
static T clamp(const T val, const T lower, const T upper)
Definition: micropolis.h:808
unsigned short MapTile
Definition: tool.h:108
@ 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
@ PWRBIT
bit 15, tile has power.
Definition: tool.h:120
@ BULLBIT
bit 12, tile is bulldozable.
Definition: tool.h:123
unsigned short MapValue
Definition: tool.h:94