Micropolis
disasters.cpp
Go to the documentation of this file.
1 /* disasters.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 
85 
93 {
94  /* Chance of disasters at lev 0 1 2 */
95  static const short DisChance[3] = {
96  10 * 48, // Game level 0
97  5 * 48, // Game level 1
98  60 // Game level 2
99  };
100  assert(LEVEL_COUNT == LENGTH_OF(DisChance));
101 
102  if (floodCount) {
103  floodCount--;
104  }
105 
106  if (disasterEvent != SC_NONE) {
108  }
109 
110  if (!enableDisasters) { // Disasters have been disabled
111  return;
112  }
113 
114  int x = gameLevel;
115  if (x > LEVEL_LAST) {
116  x = LEVEL_EASY;
117  }
118 
119  if (!getRandom(DisChance[x])) {
120  switch (getRandom(8)) {
121  case 0:
122  case 1:
123  setFire(); // 2/9 chance a fire breaks out
124  break;
125 
126  case 2:
127  case 3:
128  makeFlood(); // 2/9 chance for a flood
129  break;
130 
131  case 4:
132  // 1/9 chance nothing happens (was airplane crash,
133  // which EA removed after 9/11, and requested it be
134  // removed from this code)
135  break;
136 
137  case 5:
138  makeTornado(); // 1/9 chance tornado
139  break;
140 
141  case 6:
142  makeEarthquake(); // 1/9 chance earthquake
143  break;
144 
145  case 7:
146  case 8:
147  // 2/9 chance a scary monster arrives in a dirty town
148  if (pollutionAverage > /* 80 */ 60) {
149  makeMonster();
150  }
151  break;
152  }
153  }
154 }
155 
156 
159 {
160  switch (disasterEvent) {
161  case SC_DULLSVILLE:
162  break;
163 
164  case SC_SAN_FRANCISCO:
165  if (disasterWait == 1) {
166  makeEarthquake();
167  }
168  break;
169 
170  case SC_HAMBURG:
171  if (disasterWait % 10 == 0) {
172  makeFireBombs();
173  }
174  break;
175 
176  case SC_BERN:
177  break;
178 
179  case SC_TOKYO:
180  if (disasterWait == 1) {
181  makeMonster();
182  }
183  break;
184 
185  case SC_DETROIT:
186  break;
187 
188  case SC_BOSTON:
189  if (disasterWait == 1) {
190  makeMeltdown();
191  }
192  break;
193 
194  case SC_RIO:
195  if ((disasterWait % 24) == 0) {
196  makeFlood();
197  }
198  break;
199 
200  default:
201  NOT_REACHED();
202  break; // Never used
203  }
204 
205  if (disasterWait > 0) {
206  disasterWait--;
207  } else {
209  }
210 }
211 
212 
218 {
219  short x, y;
220 
221  for (x = 0; x < (WORLD_W - 1); x++) {
222  for (y = 0; y < (WORLD_H - 1); y++) {
223  if ((map[x][y] & LOMASK) == NUCLEAR) {
224  doMeltdown(Position(x, y));
225  return;
226  }
227  }
228  }
229 }
230 
231 
234 {
235  int crashX = getRandom(WORLD_W - 1);
236  int crashY = getRandom(WORLD_H - 1);
237  makeExplosion(crashX, crashY);
238  sendMessage(MESSAGE_FIREBOMBING, crashX, crashY, true, true);
239 }
240 
241 
244 {
245  int count = 2 + (getRandom16() & 1);
246 
247  while (count > 0) {
248  fireBomb();
249  count--;
250  }
251 
252  // TODO: Schedule periodic fire bombs over time, every few ticks.
253 }
254 
255 
258 {
259  short x, y, z;
260 
261  int strength = getRandom(700) + 300; // strength/duration of the earthquake
262 
263  doEarthquake(strength);
264 
266 
267  for (z = 0; z < strength; z++) {
268  x = getRandom(WORLD_W - 1);
269  y = getRandom(WORLD_H - 1);
270 
271  if (vulnerable(map[x][y])) {
272 
273  if ((z & 0x3) != 0) { // 3 of 4 times reduce to rubble
274  map[x][y] = randomRubble();
275  } else {
276  // 1 of 4 times start fire
277  map[x][y] = randomFire();
278  }
279  }
280  }
281 }
282 
283 
286 {
287  short x, y, z;
288 
289  x = getRandom(WORLD_W - 1);
290  y = getRandom(WORLD_H - 1);
291  z = map[x][y];
292 
293  if ((z & ZONEBIT) == 0) {
294  z = z & LOMASK;
295  if (z > LHTHR && z < LASTZONE) {
296  map[x][y] = randomFire();
297  sendMessage(MESSAGE_FIRE_REPORTED, x, y, true);
298  }
299  }
300 }
301 
302 
305 {
306  short t, x, y, z;
307 
308  for (t = 0; t < 40; t++) {
309  x = getRandom(WORLD_W - 1);
310  y = getRandom(WORLD_H - 1);
311  z = map[x][y];
312 
313  if ((!(z & ZONEBIT)) && (z & BURNBIT)) {
314  z = z & LOMASK;
315  if ((z > 21) && (z < LASTZONE)) {
316  map[x][y] = randomFire();
318  return;
319  }
320  }
321  }
322 }
323 
324 
331 {
332  int tem2 = tem & LOMASK;
333 
334  if (tem2 < RESBASE || tem2 > LASTZONE || (tem & ZONEBIT)) {
335  return false;
336  }
337 
338  return true;
339 }
340 
341 
347 {
348  static const short Dx[4] = { 0, 1, 0, -1 };
349  static const short Dy[4] = { -1, 0, 1, 0 };
350  short xx, yy, c;
351  short z, t, x, y;
352 
353  for (z = 0; z < 300; z++) {
354  x = getRandom(WORLD_W - 1);
355  y = getRandom(WORLD_H - 1);
356  c = map[x][y] & LOMASK;
357 
358  if (c > CHANNEL && c <= WATER_HIGH) { /* if riveredge */
359  for (t = 0; t < 4; t++) {
360  xx = x + Dx[t];
361  yy = y + Dy[t];
362  if (testBounds(xx, yy)) {
363  c = map[xx][yy];
364 
365  /* tile is floodable */
366  if (c == DIRT
367  || (c & (BULLBIT | BURNBIT)) == (BULLBIT | BURNBIT)) {
368  map[xx][yy] = FLOOD;
369  floodCount = 30;
370  sendMessage(MESSAGE_FLOODING_REPORTED, xx, yy, true);
371  return;
372  }
373  }
374  }
375  }
376  }
377 }
378 
379 
386 {
387  static const short Dx[4] = { 0, 1, 0, -1 };
388  static const short Dy[4] = { -1, 0, 1, 0 };
389 
390  if (floodCount > 0) {
391  // Flood is not over yet
392  for (int z = 0; z < 4; z++) {
393  if ((getRandom16() & 7) == 0) { // 12.5% chance
394  int xx = pos.posX + Dx[z];
395  int yy = pos.posY + Dy[z];
396  if (testBounds(xx, yy)) {
397  MapValue c = map[xx][yy];
398  MapTile t = c & LOMASK;
399 
400  if ((c & BURNBIT) == BURNBIT || c == DIRT
401  || (t >= WOODS5 && t < FLOOD)) {
402  if ((c & ZONEBIT) == ZONEBIT) {
403  fireZone(Position(xx, yy), c);
404  }
405  map[xx][yy] = FLOOD + getRandom(2);
406  }
407  }
408  }
409  }
410  } else {
411  if ((getRandom16() & 15) == 0) { // 1/16 chance
412  map[pos.posX][pos.posY] = DIRT;
413  }
414  }
415 }
416 
417 
void scenarioDisaster()
Definition: disasters.cpp:158
void makeMeltdown()
Definition: disasters.cpp:217
void makeEarthquake()
Definition: disasters.cpp:257
void doMeltdown(const Position &pos)
Definition: simulate.cpp:1682
void makeFireBombs()
Definition: disasters.cpp:243
GameLevel gameLevel
Difficulty level of the game (0..2)
Definition: micropolis.h:2334
void makeExplosion(int x, int y)
Definition: sprite.cpp:2020
void makeMonster()
Definition: sprite.cpp:1917
short cityCenterY
Y coordinate of city center.
Definition: micropolis.h:2045
short getRandom(short range)
Definition: random.cpp:110
bool vulnerable(int tem)
Definition: disasters.cpp:330
int getRandom16()
Definition: random.cpp:130
bool enableDisasters
Enable disasters.
Definition: micropolis.h:2346
void fireBomb()
Definition: disasters.cpp:233
void fireZone(const Position &pos, MapValue ch)
Definition: simulate.cpp:1357
void doDisasters()
Definition: disasters.cpp:92
short pollutionAverage
Definition: micropolis.h:1072
MapValue randomFire()
Definition: micropolis.h:2139
short disasterWait
Count-down timer for the disaster.
Definition: micropolis.h:2102
short cityCenterX
X coordinate of city center.
Definition: micropolis.h:2044
void setFire()
Definition: disasters.cpp:285
unsigned short * map[WORLD_W]
Definition: micropolis.h:1120
void makeTornado()
Definition: sprite.cpp:1996
void sendMessage(short Mnum, short x=NOWHERE, short y=NOWHERE, bool picture=false, bool important=false)
Definition: message.cpp:390
Scenario disasterEvent
The disaster for which a count-down is running.
Definition: micropolis.h:2101
void makeFire()
Definition: disasters.cpp:304
static bool testBounds(int wx, int wy)
Definition: micropolis.h:2378
short floodCount
Definition: micropolis.h:1512
void makeFlood()
Definition: disasters.cpp:346
MapValue randomRubble()
Definition: micropolis.h:2145
void doFlood(const Position &pos)
Definition: disasters.cpp:385
void doEarthquake(int strength)
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
static const int WORLD_W
Definition: map_type.h:90
Header file for Micropolis game engine.
@ SC_TOKYO
Tokyo (scary monster)
Definition: micropolis.h:704
@ SC_NONE
No scenario (free playing)
Definition: micropolis.h:698
@ SC_BOSTON
Boston (nuclear meltdown)
Definition: micropolis.h:706
@ SC_BERN
Bern (traffic)
Definition: micropolis.h:703
@ SC_SAN_FRANCISCO
San francisco (earthquake)
Definition: micropolis.h:701
@ SC_RIO
Rio (flooding)
Definition: micropolis.h:707
@ SC_HAMBURG
Hamburg (fire bombs)
Definition: micropolis.h:702
@ SC_DULLSVILLE
Dullsville (boredom)
Definition: micropolis.h:700
@ SC_DETROIT
Detroit (crime)
Definition: micropolis.h:705
@ WATER_HIGH
Last water tile (inclusive)
Definition: micropolis.h:393
@ LASTZONE
Also last tile nuclear power plant.
Definition: micropolis.h:605
@ NUCLEAR
'Center' tile nuclear power plant.
Definition: micropolis.h:604
@ DIRT
Clear tile.
Definition: micropolis.h:382
#define NOT_REACHED()
Definition: micropolis.h:847
@ LEVEL_EASY
Simple game level.
Definition: micropolis.h:763
@ LEVEL_LAST
Last game level value.
Definition: micropolis.h:770
@ LEVEL_COUNT
Number of game levels.
Definition: micropolis.h:767
#define LENGTH_OF(array)
Definition: micropolis.h:842
@ MESSAGE_FIRE_REPORTED
20: Fire reported !
Definition: text.h:132
@ MESSAGE_FIREBOMBING
30: Firebombing reported !
Definition: text.h:142
@ MESSAGE_FLOODING_REPORTED
Flooding reported !!
Definition: text.h:154
@ MESSAGE_EARTHQUAKE
Major earthquake reported !!!
Definition: text.h:135
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
@ BULLBIT
bit 12, tile is bulldozable.
Definition: tool.h:123
unsigned short MapValue
Definition: tool.h:94