|
|
1.1 root 1: /* s_msg.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 [email protected].
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: QUAD LastCityPop;
66: short LastCategory;
67: short LastPicNum;
68: short autoGo;
69: short HaveLastMessage = 0;
70: char LastMessage[256];
71: int DoAutoGoto(short x, short y, char *msg);
72: int DoShowPicture(short id);
73:
74: /* comefrom: Simulate */
75: SendMessages(void)
76: {
77: register z;
78: short PowerPop;
79: float TM;
80:
81: if ((ScenarioID) && (ScoreType) && (ScoreWait)) {
82: ScoreWait--;
83: if (!ScoreWait)
84: DoScenarioScore(ScoreType);
85: }
86:
87: CheckGrowth();
88:
89: TotalZPop = ResZPop + ComZPop + IndZPop;
90: PowerPop = NuclearPop + CoalPop;
91:
92: z = CityTime & 63;
93:
94: switch(z) {
95:
96: case 1:
97: if ((TotalZPop >>2) >= ResZPop)
98: SendMes(1); /* need Res */
99: break;
100: case 5:
101: if ((TotalZPop >>3) >= ComZPop)
102: SendMes(2); /* need Com */
103: break;
104: case 10:
105: if ((TotalZPop >>3) >= IndZPop)
106: SendMes(3); /* need Ind */
107: break;
108: case 14:
109: if ((TotalZPop > 10) && ((TotalZPop <<1) > RoadTotal))
110: SendMes(4);
111: break;
112: case 18:
113: if ((TotalZPop > 50) && (TotalZPop > RailTotal))
114: SendMes(5);
115: break;
116: case 22:
117: if ((TotalZPop > 10) && (PowerPop == 0))
118: SendMes(6); /* need Power */
119: break;
120: case 26:
121: if ((ResPop > 500) && (StadiumPop == 0)) {
122: SendMes(7); /* need Stad */
123: ResCap = 1;
124: }
125: else
126: ResCap = 0;
127: break;
128: case 28:
129: if ((IndPop > 70) && (PortPop == 0)) {
130: SendMes(8);
131: IndCap = 1;
132: }
133: else IndCap = 0;
134: break;
135: case 30:
136: if ((ComPop > 100) && (APortPop == 0)) {
137: SendMes(9);
138: ComCap = 1;
139: }
140: else ComCap = 0;
141: break;
142: case 32:
143: TM = unPwrdZCnt + PwrdZCnt; /* dec score for unpowered zones */
144: if (TM)
145: if ((PwrdZCnt / TM) < .7)
146: SendMes(15);
147: break;
148: case 35:
149: if (PolluteAverage > /* 80 */ 60)
150: SendMes(-10);
151: break;
152: case 42:
153: if (CrimeAverage > 100)
154: SendMes(-11);
155: break;
156: case 45:
157: if ((TotalPop > 60) && (FireStPop == 0))
158: SendMes(13);
159: break;
160: case 48:
161: if ((TotalPop > 60) && (PolicePop == 0))
162: SendMes(14);
163: break;
164: case 51:
165: if (CityTax > 12)
166: SendMes(16);
167: break;
168: case 54:
169: if ((RoadEffect < 20) && (RoadTotal > 30))
170: SendMes(17);
171: break;
172: case 57:
173: if ((FireEffect < 700) && (TotalPop > 20))
174: SendMes(18);
175: break;
176: case 60:
177: if ((PoliceEffect < 700) && (TotalPop > 20))
178: SendMes(19);
179: break;
180: case 63:
181: if (TrafficAverage > 60)
182: SendMes(-12);
183: break;
184: }
185: }
186:
187:
188: /* comefrom: SendMessages */
189: CheckGrowth(void)
190: {
191: QUAD ThisCityPop;
192: short z;
193:
194: if (!(CityTime & 3)) {
195: z = 0;
196: ThisCityPop = ((ResPop) + (ComPop * 8L) + (IndPop * 8L)) * 20L;
197: if (LastCityPop) {
198: if ((LastCityPop < 2000) && (ThisCityPop >= 2000)) z = 35;
199: if ((LastCityPop < 10000) && (ThisCityPop >= 10000)) z = 36;
200: if ((LastCityPop < 50000L) && (ThisCityPop >= 50000L)) z = 37;
201: if ((LastCityPop < 100000L) && (ThisCityPop >= 100000L)) z = 38;
202: if ((LastCityPop < 500000L) && (ThisCityPop >= 500000L)) z = 39;
203: }
204: if (z)
205: if (z != LastCategory) {
206: SendMes(-z);
207: LastCategory = z;
208: }
209: LastCityPop = ThisCityPop;
210: }
211: }
212:
213:
214: /* comefrom: SendMessages */
215: DoScenarioScore(int type)
216: {
217: short z;
218:
219: z = -200; /* you lose */
220: switch(type) {
221: case 1: /* Dullsville */
222: if (CityClass >= 4) z = -100;
223: break;
224: case 2: /* San Francisco */
225: if (CityClass >= 4) z = -100;
226: break;
227: case 3: /* Hamburg */
228: if (CityClass >= 4) z = -100;
229: break;
230: case 4: /* Bern */
231: if (TrafficAverage < 80) z = -100;
232: break;
233: case 5: /* Tokyo */
234: if (CityScore > 500) z = -100;
235: break;
236: case 6: /* Detroit */
237: if (CrimeAverage < 60) z = -100;
238: break;
239: case 7: /* Boston */
240: if (CityScore > 500) z = -100;
241: break;
242: case 8: /* Rio de Janeiro */
243: if (CityScore > 500) z = -100;
244: break;
245: }
246: ClearMes();
247: SendMes(z);
248:
249: if (z == -200)
250: DoLoseGame();
251: }
252:
253:
254: ClearMes(void)
255: {
256: MessagePort = 0;
257: MesX = 0;
258: MesY = 0;
259: LastPicNum = 0;
260: }
261:
262:
263: /* comefrom: MakeEarthquake MakeFire MakeFire MakeFlood SendMessages
264: CheckGrowth DoScenarioScore DoPowerScan */
265: SendMes(int Mnum)
266: {
267: if (Mnum < 0) {
268: if (Mnum != LastPicNum) {
269: MessagePort = Mnum;
270: MesX = 0;
271: MesY = 0;
272: LastPicNum = Mnum;
273: return (1);
274: }
275: } else {
276: if (!(MessagePort)) {
277: MessagePort = Mnum;
278: MesX = 0;
279: MesY = 0;
280: return(1);
281: }
282: }
283: return(0);
284: }
285:
286:
287: /* comefrom: DoExplosion DoCopter ExplodeObject */
288: void SendMesAt(short Mnum, short x, short y)
289: {
290: if (SendMes(Mnum)) {
291: MesX = x;
292: MesY = y;
293: }
294: }
295:
296:
297: doMessage(void)
298: {
299: char messageStr[256];
300: short pictId;
301: short firstTime;
302:
303: messageStr[0] = 0;
304:
305: if (MessagePort) {
306: MesNum = MessagePort;
307: MessagePort = 0;
308: LastMesTime = TickCount();
309: firstTime = 1;
310: } else {
311: firstTime = 0;
312: if (MesNum == 0) return;
313: if (MesNum < 0) {
314: MesNum = -MesNum;
315: LastMesTime = TickCount();
316: } else if ((TickCount() - LastMesTime) > (60 * 30)) {
317: MesNum = 0;
318: return;
319: }
320: }
321: if (firstTime) {
322: switch ((MesNum < 0) ? -MesNum : MesNum) {
323: case 12:
324: if (Rand(5) == 1) {
325: MakeSound("city", "HonkHonk-Med");
326: } else if (Rand(5) == 1) {
327: MakeSound("city", "HonkHonk-Low");
328: } else if (Rand(5) == 1) {
329: MakeSound("city", "HonkHonk-High");
330: }
331: break;
332: case 11:
333: case 20:
334: case 22:
335: case 23:
336: case 24:
337: case 25:
338: case 26:
339: case 27:
340: MakeSound("city", "Siren");
341: break;
342: case 21:
343: MakeSound("city", "Monster -speed [MonsterSpeed]");
344: break;
345: case 30:
346: MakeSound("city", "Explosion-Low");
347: MakeSound("city", "Siren");
348: break;
349: case 43:
350: MakeSound("city", "Explosion-High");
351: MakeSound("city", "Explosion-Low");
352: MakeSound("city", "Siren");
353: break;
354: case 44:
355: MakeSound("city", "Siren");
356: break;
357: }
358: }
359:
360: if (MesNum >= 0) {
361: if (MesNum == 0)
362: return;
363:
364: if (MesNum > 60) {
365: MesNum = 0;
366: return;
367: }
368:
369: GetIndString(messageStr, 301, MesNum);
370: if (MesX || MesY) {
371: /* TODO: draw goto button */
372: }
373:
374: if (autoGo && (MesX || MesY)) {
375: DoAutoGoto(MesX, MesY, messageStr);
376: MesX = 0;
377: MesY = 0;
378: } else {
379: SetMessageField(messageStr);
380: }
381:
382: } else { /* picture message */
383: pictId = -(MesNum);
384:
385: if (pictId < 43)
386: GetIndString(messageStr, 301, pictId);
387: else
388: messageStr[0] = '\0';
389:
390: DoShowPicture(pictId);
391:
392: MessagePort = pictId; /* resend text message */
393:
394: if (autoGo && (MesX || MesY)) {
395:
396: DoAutoGoto(MesX, MesY, messageStr);
397: MesX = 0;
398: MesY = 0;
399: }
400: }
401: }
402:
403:
404: DoAutoGoto(short x, short y, char *msg)
405: {
406: char buf[256];
407:
408: SetMessageField(msg);
409: sprintf(buf, "UIAutoGoto %d %d", x, y);
410: Eval(buf);
411: }
412:
413:
414: SetMessageField(char *str)
415: {
416: char buf[256];
417:
418: if (!HaveLastMessage ||
419: strcmp(LastMessage, str)) {
420: strcpy(LastMessage, str);
421: HaveLastMessage = 1;
422: sprintf(buf, "UISetMessage {%s}", str);
423: Eval(buf);
424: }
425: }
426:
427:
428: DoShowPicture(short id)
429: {
430: char buf[256];
431:
432: sprintf(buf, "UIShowPicture %d", id);
433: Eval(buf);
434: }
435:
436:
437: DoLoseGame()
438: {
439: Eval("UILoseGame");
440: }
441:
442:
443: DoWinGame()
444: {
445: Eval("UIWinGame");
446: }
447:
448:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.