]>
Commit | Line | Data |
---|---|---|
1 | /* s_disast.c | |
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 | #include "sim.h" | |
63 | ||
64 | ||
65 | /* Disasters */ | |
66 | ||
67 | ||
68 | short ShakeNow; | |
69 | short FloodCnt; | |
70 | short FloodX, FloodY; | |
71 | ||
72 | void SetFire(void); | |
73 | int Vunerable(int tem); | |
74 | void ScenarioDisaster(void); | |
75 | ||
76 | /* comefrom: Simulate */ | |
77 | void | |
78 | DoDisasters(void) | |
79 | { | |
80 | /* Chance of disasters at lev 0 1 2 */ | |
81 | static short DisChance[3] = { 10*48, 5*48, 60}; | |
82 | register short x; | |
83 | ||
84 | if (FloodCnt) FloodCnt--; | |
85 | if (DisasterEvent) | |
86 | ScenarioDisaster(); | |
87 | ||
88 | x = GameLevel; | |
89 | if (x > 2) x = 0; | |
90 | ||
91 | if (NoDisasters) return; /*post*/ | |
92 | if (!Rand(DisChance[x])) { | |
93 | x = Rand(8); | |
94 | switch (x) { | |
95 | case 0: | |
96 | case 1: | |
97 | SetFire(); | |
98 | break; | |
99 | case 2: | |
100 | case 3: | |
101 | MakeFlood(); | |
102 | break; | |
103 | case 4: | |
104 | MakeAirCrash(); | |
105 | break; | |
106 | case 5: | |
107 | MakeTornado(); | |
108 | break; | |
109 | case 6: | |
110 | MakeEarthquake(); | |
111 | break; | |
112 | case 7: | |
113 | case 8: | |
114 | if (PolluteAverage > /* 80 */ 60) MakeMonster(); | |
115 | break; | |
116 | } | |
117 | } | |
118 | } | |
119 | ||
120 | ||
121 | /* comefrom: DoDisasters */ | |
122 | void | |
123 | ScenarioDisaster(void) | |
124 | { | |
125 | switch (DisasterEvent) { | |
126 | case 1: /* Dullsville */ | |
127 | break; | |
128 | case 2: /* San Francisco */ | |
129 | if (DisasterWait == 1) MakeEarthquake(); | |
130 | break; | |
131 | case 3: /* Hamburg */ | |
132 | DropFireBombs(); | |
133 | break; | |
134 | case 4: /* Bern */ | |
135 | break; | |
136 | case 5: /* Tokyo */ | |
137 | if (DisasterWait == 1) MakeMonster(); | |
138 | break; | |
139 | case 6: /* Detroit */ | |
140 | break; | |
141 | case 7: /* Boston */ | |
142 | if (DisasterWait == 1) MakeMeltdown(); | |
143 | break; | |
144 | case 8: /* Rio */ | |
145 | if ((DisasterWait % 24) == 0) MakeFlood(); | |
146 | break; | |
147 | } | |
148 | if (DisasterWait) DisasterWait--; | |
149 | else DisasterEvent = 0; | |
150 | } | |
151 | ||
152 | ||
153 | /* comefrom: ScenarioDisaster */ | |
154 | void | |
155 | MakeMeltdown(void) | |
156 | { | |
157 | short x, y; | |
158 | ||
159 | for (x = 0; x < (WORLD_X - 1); x ++) { | |
160 | for (y = 0; y < (WORLD_Y - 1); y++) { | |
161 | /* TILE_IS_NUCLEAR(Map[x][y]) */ | |
162 | if ((Map[x][y] & LOMASK) == NUCLEAR) { | |
163 | DoMeltdown(x, y); | |
164 | return; | |
165 | } | |
166 | } | |
167 | } | |
168 | } | |
169 | ||
170 | ||
171 | void | |
172 | FireBomb(void) | |
173 | { | |
174 | CrashX = Rand(WORLD_X - 1); | |
175 | CrashY = Rand(WORLD_Y - 1); | |
176 | MakeExplosion(CrashX, CrashY); | |
177 | ClearMes(); | |
178 | SendMesAt(-30, CrashX, CrashY); | |
179 | } | |
180 | ||
181 | ||
182 | /* comefrom: DoDisasters ScenarioDisaster */ | |
183 | void | |
184 | MakeEarthquake(void) | |
185 | { | |
186 | register short x, y, z; | |
187 | short time; | |
188 | ||
189 | DoEarthQuake(); | |
190 | ||
191 | SendMesAt(-23, CCx, CCy); | |
192 | time = Rand(700) + 300; | |
193 | for (z = 0; z < time; z++) { | |
194 | x = Rand(WORLD_X - 1); | |
195 | y = Rand(WORLD_Y - 1); | |
196 | if ((x < 0) || (x > (WORLD_X - 1)) || | |
197 | (y < 0) || (y > (WORLD_Y - 1))) | |
198 | continue; | |
199 | /* TILE_IS_VULNERABLE(Map[x][y]) */ | |
200 | if (Vunerable(Map[x][y])) { | |
201 | if (z & 0x3) | |
202 | Map[x][y] = (RUBBLE + BULLBIT) + (Rand16() & 3); | |
203 | else | |
204 | Map[x][y] = (FIRE + ANIMBIT) + (Rand16() & 7); | |
205 | } | |
206 | } | |
207 | } | |
208 | ||
209 | ||
210 | /* comefrom: DoDisasters */ | |
211 | void | |
212 | SetFire(void) | |
213 | { | |
214 | register short x, y, z; | |
215 | ||
216 | x = Rand(WORLD_X - 1); | |
217 | y = Rand(WORLD_Y - 1); | |
218 | z = Map[x][y]; | |
219 | /* TILE_IS_ARSONABLE(z) */ | |
220 | if (!(z & ZONEBIT)) { | |
221 | z = z & LOMASK; | |
222 | if ((z > LHTHR) && (z < LASTZONE)) { | |
223 | Map[x][y] = FIRE + ANIMBIT + (Rand16() & 7); | |
224 | CrashX = x; CrashY = y; | |
225 | SendMesAt(-20, x, y); | |
226 | } | |
227 | } | |
228 | } | |
229 | ||
230 | ||
231 | /* comefrom: DoDisasters */ | |
232 | void | |
233 | MakeFire(void) | |
234 | { | |
235 | short t, x, y, z; | |
236 | for (t = 0; t < 40; t++) { | |
237 | x = Rand(WORLD_X - 1); | |
238 | y = Rand(WORLD_Y - 1); | |
239 | z = Map[x][y]; | |
240 | /* !(z & BURNBIT) && TILE_IS_ARSONABLE(z) */ | |
241 | if ((!(z & ZONEBIT)) && (z & BURNBIT)) { | |
242 | z = z & LOMASK; | |
243 | if ((z > 21) && (z < LASTZONE)) { | |
244 | Map[x][y] = FIRE + ANIMBIT + (Rand16() & 7); | |
245 | SendMesAt(20, x, y); | |
246 | return; | |
247 | } | |
248 | } | |
249 | } | |
250 | } | |
251 | ||
252 | ||
253 | /* comefrom: MakeEarthquake */ | |
254 | int | |
255 | Vunerable(int tem) | |
256 | { | |
257 | register int tem2; | |
258 | ||
259 | tem2 = tem & LOMASK; | |
260 | if ((tem2 < RESBASE) || | |
261 | (tem2 > LASTZONE) || | |
262 | (tem & ZONEBIT)) | |
263 | return(FALSE); | |
264 | return(TRUE); | |
265 | } | |
266 | ||
267 | ||
268 | /* comefrom: DoDisasters ScenarioDisaster */ | |
269 | void | |
270 | MakeFlood(void) | |
271 | { | |
272 | static short Dx[4] = { 0, 1, 0,-1}; | |
273 | static short Dy[4] = {-1, 0, 1, 0}; | |
274 | register short xx, yy, c; | |
275 | short z, t, x, y; | |
276 | ||
277 | for (z = 0; z < 300; z++) { | |
278 | x = Rand(WORLD_X - 1); | |
279 | y = Rand(WORLD_Y - 1); | |
280 | c = Map[x][y] & LOMASK; /* XXX: & LOMASK */ | |
281 | /* TILE_IS_RIVER_EDGE(c) */ | |
282 | if ((c > 4) && (c < 21)) /* if riveredge */ | |
283 | for (t = 0; t < 4; t++) { | |
284 | xx = x + Dx[t]; | |
285 | yy = y + Dy[t]; | |
286 | if (TestBounds(xx, yy)) { | |
287 | c = Map[xx][yy]; | |
288 | /* TILE_IS_FLOODABLE(c) */ | |
289 | if ((c == 0) || ((c & BULLBIT) && (c & BURNBIT))) { | |
290 | Map[xx][yy] = FLOOD; | |
291 | FloodCnt = 30; | |
292 | SendMesAt(-42, xx, yy); | |
293 | FloodX = xx; FloodY = yy; | |
294 | return; | |
295 | } | |
296 | } | |
297 | } | |
298 | } | |
299 | } | |
300 | ||
301 | ||
302 | /* comefrom: MapScan */ | |
303 | void | |
304 | DoFlood(void) | |
305 | { | |
306 | static short Dx[4] = { 0, 1, 0,-1}; | |
307 | static short Dy[4] = {-1, 0, 1, 0}; | |
308 | register short z, c, xx, yy, t; | |
309 | ||
310 | if (FloodCnt) | |
311 | for (z = 0; z < 4; z++) { | |
312 | if (!(Rand16() & 7)) { | |
313 | xx = SMapX + Dx[z]; | |
314 | yy = SMapY + Dy[z]; | |
315 | if (TestBounds(xx, yy)) { | |
316 | c = Map[xx][yy]; | |
317 | t = c & LOMASK; | |
318 | /* TILE_IS_FLOODABLE2(c) */ | |
319 | if ((c & BURNBIT) || | |
320 | (c == 0) || | |
321 | ((t >= WOODS5 /* XXX */) && (t < FLOOD))) { | |
322 | if (c & ZONEBIT) | |
323 | FireZone(xx, yy, c); | |
324 | Map[xx][yy] = FLOOD + Rand(2); | |
325 | } | |
326 | } | |
327 | } | |
328 | } | |
329 | else | |
330 | if (!(Rand16() & 15)) | |
331 | Map[SMapX][SMapY] = 0; | |
332 | } |