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) {
167 }
168 break;
169
170 case SC_HAMBURG:
171 if (disasterWait % 10 == 0) {
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();
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;
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()
void makeMeltdown()
void makeEarthquake()
void doMeltdown(const Position &pos)
void makeFireBombs()
GameLevel gameLevel
Difficulty level of the game (0..2)
void makeExplosion(int x, int y)
Definition sprite.cpp:2020
void makeMonster()
Definition sprite.cpp:1917
short cityCenterY
Y coordinate of city center.
short getRandom(short range)
Definition random.cpp:110
bool vulnerable(int tem)
int getRandom16()
Definition random.cpp:130
bool enableDisasters
Enable disasters.
void fireBomb()
void fireZone(const Position &pos, MapValue ch)
void doDisasters()
Definition disasters.cpp:92
short pollutionAverage
MapValue randomFire()
short disasterWait
Count-down timer for the disaster.
short cityCenterX
X coordinate of city center.
void setFire()
unsigned short * map[WORLD_W]
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.
void makeFire()
static bool testBounds(int wx, int wy)
short floodCount
void makeFlood()
MapValue randomRubble()
void doFlood(const Position &pos)
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:705
@ SC_NONE
No scenario (free playing)
Definition micropolis.h:699
@ SC_BOSTON
Boston (nuclear meltdown)
Definition micropolis.h:707
@ SC_BERN
Bern (traffic)
Definition micropolis.h:704
@ SC_SAN_FRANCISCO
San francisco (earthquake)
Definition micropolis.h:702
@ SC_RIO
Rio (flooding)
Definition micropolis.h:708
@ SC_HAMBURG
Hamburg (fire bombs)
Definition micropolis.h:703
@ SC_DULLSVILLE
Dullsville (boredom)
Definition micropolis.h:701
@ SC_DETROIT
Detroit (crime)
Definition micropolis.h:706
@ 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:848
@ LEVEL_EASY
Simple game level.
Definition micropolis.h:764
@ LEVEL_LAST
Last game level value.
Definition micropolis.h:771
@ LEVEL_COUNT
Number of game levels.
Definition micropolis.h:768
#define LENGTH_OF(array)
Definition micropolis.h:843
@ 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:101