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