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