|
|
1.1 root 1: /* w_con.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: short _RoadTable[16] = {
66: 66, 67, 66, 68,
67: 67, 67, 69, 73,
68: 66, 71, 66, 72,
69: 70, 75, 74, 76
70: };
71:
72: short _RailTable[16] = {
73: 226, 227, 226, 228,
74: 227, 227, 229, 233,
75: 226, 231, 226, 232,
76: 230, 235, 234, 236
77: };
78:
79: short _WireTable[16] = {
80: 210, 211, 210, 212,
81: 211, 211, 213, 217,
82: 210, 215, 210, 216,
83: 214, 219, 218, 220
84: };
85:
86:
87: #define NeutralizeRoad(Tile) \
88: if (((Tile &= LOMASK) >= 64) && \
89: ((Tile & LOMASK) <= 207)) { \
90: Tile = (Tile & 0x000F) + 64; \
91: }
92:
93:
94: /* comefrom: check3Border check4Border check5Border processWand */
95: int
96: ConnecTile(short x, short y, short *TileAdrPtr, short Command)
97: {
98: short Tile;
99: int result = 1;
100:
101: /* make sure the array subscripts are in bounds */
102: if (!TestBounds(x, y)) {
103: return (0);
104: }
105:
106: /* AutoDoze */
107: if ((Command >= 2) && (Command <= 4)) {
108:
109: if ((autoBulldoze != 0) &&
110: (TotalFunds > 0) &&
111: ((Tile = (*TileAdrPtr)) & BULLBIT)) {
112: NeutralizeRoad(Tile);
113: /* Maybe this should check BULLBIT instead of checking tile values? */
114: if (((Tile >= TINYEXP) && (Tile <= LASTTINYEXP)) ||
115: ((Tile < 64) && (Tile != 0))) {
116: Spend(1);
117: (*TileAdrPtr) = 0;
118: }
119: }
120: }
121:
122: switch (Command) {
123:
124: case 0: /* Fix zone */
125: _FixZone(x, y, TileAdrPtr);
126: break;
127:
128: case 1: /* Doze zone */
129: result = _LayDoze(x, y, TileAdrPtr);
130: _FixZone(x, y, TileAdrPtr);
131: break;
132:
133: case 2: /* Lay Road */
134: result = _LayRoad(x, y, TileAdrPtr);
135: _FixZone(x, y, TileAdrPtr);
136: break;
137:
138: case 3: /* Lay Rail */
139: result = _LayRail(x, y, TileAdrPtr);
140: _FixZone(x, y, TileAdrPtr);
141: break;
142:
143: case 4: /* Lay Wire */
144: result = _LayWire(x, y, TileAdrPtr);
145: _FixZone(x, y, TileAdrPtr);
146: break;
147:
148: }
149:
150: return result;
151: }
152:
153: /* comefrom: ConnecTile */
154: int
155: _LayDoze(int x, int y, short *TileAdrPtr)
156: {
157: short Tile;
158:
159: if (!(TotalFunds)) {
160: return -2; /* no mas dinero. */
161: }
162:
163: Tile = (*TileAdrPtr);
164:
165: if (!(Tile & BULLBIT)) {
166: return 0; /* Check dozeable bit. */
167: }
168:
169: NeutralizeRoad(Tile);
170:
171: switch (Tile) {
172: case HBRIDGE:
173: case VBRIDGE:
174: case BRWV:
175: case BRWH:
176: case HBRDG0:
177: case HBRDG1:
178: case HBRDG2:
179: case HBRDG3:
180: case VBRDG0:
181: case VBRDG1:
182: case VBRDG2:
183: case VBRDG3:
184: case HPOWER:
185: case VPOWER:
186: case HRAIL:
187: case VRAIL: /* Dozing over water, replace with water. */
188: (*TileAdrPtr) = RIVER;
189: break;
190:
191: default: /* Dozing on land, replace with land. Simple, eh? */
192: (*TileAdrPtr) = DIRT;
193: break;
194: }
195:
196: Spend(1); /* Costs $1.00....*/
197: return 1;
198: }
199:
200:
201: /* comefrom: ConnecTile */
202: int
203: _LayRoad(int x, int y, short *TileAdrPtr)
204: {
205: short Tile;
206: int cost = 10;
207:
208: if (TotalFunds < 10) {
209: return -2;
210: }
211:
212: Tile = (*TileAdrPtr) & LOMASK;
213:
214: switch (Tile) {
215:
216: case DIRT:
217: (*TileAdrPtr) = ROADS | BULLBIT | BURNBIT;
218: break;
219:
220: case RIVER: /* Road on Water */
221: case REDGE:
222: case CHANNEL: /* Check how to build bridges, if possible. */
223: if (TotalFunds < 50) {
224: return -2;
225: }
226:
227: cost = 50;
228:
229: if (x < (WORLD_X - 1)) {
230: Tile = TileAdrPtr[WORLD_Y];
231: NeutralizeRoad(Tile);
232: if ((Tile == VRAILROAD) ||
233: (Tile == HBRIDGE) ||
234: ((Tile >= ROADS) &&
235: (Tile <= HROADPOWER))) {
236: (*TileAdrPtr) = HBRIDGE | BULLBIT;
237: break;
238: }
239: }
240:
241: if (x > 0) {
242: Tile = TileAdrPtr[-WORLD_Y];
243: NeutralizeRoad(Tile);
244: if ((Tile == VRAILROAD) ||
245: (Tile == HBRIDGE) ||
246: ((Tile >= ROADS) &&
247: (Tile <= INTERSECTION))) {
248: (*TileAdrPtr) = HBRIDGE | BULLBIT;
249: break;
250: }
251: }
252:
253: if (y < (WORLD_Y - 1)) {
254: Tile = TileAdrPtr[1];
255: NeutralizeRoad(Tile);
256: if ((Tile == HRAILROAD) ||
257: (Tile == VROADPOWER) ||
258: ((Tile >= VBRIDGE) &&
259: (Tile <= INTERSECTION))) {
260: (*TileAdrPtr) = VBRIDGE | BULLBIT;
261: break;
262: }
263: }
264:
265: if (y > 0) {
266: Tile = TileAdrPtr[-1];
267: NeutralizeRoad(Tile);
268: if ((Tile == HRAILROAD) ||
269: (Tile == VROADPOWER) ||
270: ((Tile >= VBRIDGE) &&
271: (Tile <= INTERSECTION))) {
272: (*TileAdrPtr) = VBRIDGE | BULLBIT;
273: break;
274: }
275: }
276:
277: /* Can't do road... */
278: return 0;
279:
280: case LHPOWER: /* Road on power */
281: (*TileAdrPtr) = VROADPOWER | CONDBIT | BURNBIT | BULLBIT;
282: break;
283:
284: case LVPOWER: /* Road on power #2 */
285: (*TileAdrPtr) = HROADPOWER | CONDBIT | BURNBIT | BULLBIT;
286: break;
287:
288: case LHRAIL: /* Road on rail */
289: (*TileAdrPtr) = HRAILROAD | BURNBIT | BULLBIT;
290: break;
291:
292: case LVRAIL: /* Road on rail #2 */
293: (*TileAdrPtr) = VRAILROAD | BURNBIT | BULLBIT;
294: break;
295:
296: default: /* Can't do road */
297: return 0;
298:
299: }
300:
301: Spend(cost);
302:
303: return 1;
304: }
305:
306:
307: /* comefrom: ConnecTile */
308: int
309: _LayRail(int x, int y, short *TileAdrPtr)
310: {
311: short Tile;
312: int cost = 20;
313:
314: if (TotalFunds < 20) {
315: return -2;
316: }
317:
318: Tile = (*TileAdrPtr) & LOMASK;
319: NeutralizeRoad(Tile);
320:
321: switch (Tile) {
322: case 0: /* Rail on Dirt */
323: (*TileAdrPtr) = 226 | BULLBIT | BURNBIT;
324: break;
325:
326: case 2: /* Rail on Water */
327: case 3:
328: case 4: /* Check how to build underwater tunnel, if possible. */
329: if (TotalFunds < 100) {
330: return -2;
331: }
332: cost = 100;
333:
334: if (x < (WORLD_X - 1)) {
335: Tile = TileAdrPtr[WORLD_Y];
336: NeutralizeRoad(Tile);
337: if ((Tile == 221) || (Tile == 224) || ((Tile >= 226) && (Tile <= 237))) {
338: (*TileAdrPtr) = 224 | BULLBIT;
339: break;
340: }
341: }
342:
343: if (x > 0) {
344: Tile = TileAdrPtr[-WORLD_Y];
345: NeutralizeRoad(Tile);
346: if ((Tile == 221) || (Tile == 224) || ((Tile > 225) && (Tile < 238))) {
347: (*TileAdrPtr) = 224 | BULLBIT;
348: break;
349: }
350: }
351:
352: if (y < (WORLD_Y - 1)) {
353: Tile = TileAdrPtr[1];
354: NeutralizeRoad(Tile);
355: if ((Tile == 222) || (Tile == 238) || ((Tile > 224) && (Tile < 237))) {
356: (*TileAdrPtr) = 225 | BULLBIT;
357: break;
358: }
359: }
360:
361: if (y > 0) {
362: Tile = TileAdrPtr[-1];
363: NeutralizeRoad(Tile);
364: if ((Tile == 222) || (Tile == 238) || ((Tile > 224) && (Tile < 237))) {
365: (*TileAdrPtr) = 225 | BULLBIT;
366: break;
367: }
368: }
369:
370: /* Can't do rail... */
371: return 0;
372:
373: case 210: /* Rail on power */
374: (*TileAdrPtr) = 222 | CONDBIT | BURNBIT | BULLBIT;
375: break;
376:
377: case 211: /* Rail on power #2 */
378: (*TileAdrPtr) = 221 | CONDBIT | BURNBIT | BULLBIT;
379: break;
380:
381: case 66: /* Rail on road */
382: (*TileAdrPtr) = 238 | BURNBIT | BULLBIT;
383: break;
384:
385: case 67: /* Rail on road #2 */
386: (*TileAdrPtr) = 237 | BURNBIT | BULLBIT;
387: break;
388:
389: default: /* Can't do rail */
390: return 0;
391: }
392:
393: Spend(cost);
394: return 1;
395: }
396:
397:
398: /* comefrom: ConnecTile */
399: int
400: _LayWire(int x, int y, short *TileAdrPtr)
401: {
402: short Tile;
403: int cost = 5;
404:
405: if (TotalFunds < 5) {
406: return -2;
407: }
408:
409: Tile = (*TileAdrPtr) & LOMASK;
410: NeutralizeRoad(Tile);
411:
412: switch (Tile) {
413: case 0: /* Wire on Dirt */
414: (*TileAdrPtr) = 210 | CONDBIT | BURNBIT | BULLBIT;
415: break;
416:
417: case 2: /* Wire on Water */
418: case 3:
419: case 4: /* Check how to lay underwater wire, if possible. */
420: if (TotalFunds < 25)
421: return -2;
422: cost = 25;
423:
424: if (x < (WORLD_X - 1)) {
425: Tile = TileAdrPtr[WORLD_Y];
426: if (Tile & CONDBIT) {
427: NeutralizeRoad(Tile);
428: if ((Tile != 77) && (Tile != 221) && (Tile != 208)) {
429: (*TileAdrPtr) = 209 | CONDBIT | BULLBIT;
430: break;
431: }
432: }
433: }
434:
435: if (x > 0) {
436: Tile = TileAdrPtr[-WORLD_Y];
437: if (Tile & CONDBIT) {
438: NeutralizeRoad(Tile);
439: if ((Tile != 77) && (Tile != 221) && (Tile != 208)) {
440: (*TileAdrPtr) = 209 | CONDBIT | BULLBIT;
441: break;
442: }
443: }
444: }
445:
446: if (y < (WORLD_Y - 1)) {
447: Tile = TileAdrPtr[1];
448: if (Tile & CONDBIT) {
449: NeutralizeRoad(Tile);
450: if ((Tile != 78) && (Tile != 222) && (Tile != 209)) {
451: (*TileAdrPtr) = 208 | CONDBIT | BULLBIT;
452: break;
453: }
454: }
455: }
456:
457: if (y > 0) {
458: Tile = TileAdrPtr[-1];
459: if (Tile & CONDBIT) {
460: NeutralizeRoad(Tile);
461: if ((Tile != 78) && (Tile != 222) && (Tile != 209)) {
462: (*TileAdrPtr) = 208 | CONDBIT | BULLBIT;
463: break;
464: }
465: }
466: }
467:
468: /* Can't do wire... */
469: return 0;
470:
471: case 66: /* Wire on Road */
472: (*TileAdrPtr) = 77 | CONDBIT | BURNBIT | BULLBIT;
473: break;
474:
475: case 67: /* Wire on Road #2 */
476: (*TileAdrPtr) = 78 | CONDBIT | BURNBIT | BULLBIT;
477: break;
478:
479: case 226: /* Wire on rail */
480: (*TileAdrPtr) = 221 | CONDBIT | BURNBIT | BULLBIT;
481: break;
482:
483: case 227: /* Wire on rail #2 */
484: (*TileAdrPtr) = 222 | CONDBIT | BURNBIT | BULLBIT;
485: break;
486:
487: default: /* Can't do wire */
488: return 0;
489: }
490:
491: Spend(cost);
492: return 1;
493: }
494:
495:
496: /* comefrom: ConnecTile */
497: _FixZone(int x, int y, short *TileAdrPtr)
498: {
499: _FixSingle(x,y, &TileAdrPtr[0]);
500:
501: if (y > 0) {
502: _FixSingle(x, y-1, &TileAdrPtr[-1]);
503: }
504:
505: if (x < (WORLD_X - 1)) {
506: _FixSingle(x+1, y, &TileAdrPtr[WORLD_Y]);
507: }
508:
509: if (y < (WORLD_Y - 1)) {
510: _FixSingle(x, y+1, &TileAdrPtr[1]);
511: }
512:
513: if (x > 0) {
514: _FixSingle(x-1, y, &TileAdrPtr[-WORLD_Y]);
515: }
516:
517: }
518:
519:
520: /* comefrom: _FixZone */
521: _FixSingle(int x, int y, short *TileAdrPtr)
522: {
523: short Tile;
524: short adjTile = 0;
525:
526: Tile = (*TileAdrPtr) & LOMASK;
527: NeutralizeRoad(Tile);
528: if ((Tile >= 66) && (Tile <= 76)) { /* Cleanup Road */
529:
530: if (y > 0) {
531: Tile = TileAdrPtr[-1];
532: NeutralizeRoad(Tile);
533: if (((Tile == 237) || ((Tile >= 64) && (Tile <= 78))) &&
534: (Tile != 77) && (Tile != 238) && (Tile != 64))
535: adjTile |= 0x0001;
536: }
537:
538: if (x < (WORLD_X - 1)) {
539: Tile = TileAdrPtr[WORLD_Y];
540: NeutralizeRoad(Tile);
541: if (((Tile == 238) || ((Tile >= 64) && (Tile <= 78))) &&
542: (Tile != 78) && (Tile != 237) && (Tile != 65))
543: adjTile |= 0x0002;
544: }
545:
546: if (y < (WORLD_Y - 1)) {
547: Tile = TileAdrPtr[1];
548: NeutralizeRoad(Tile);
549: if (((Tile == 237) || ((Tile >= 64) && (Tile <= 78))) &&
550: (Tile != 77) && (Tile != 238) && (Tile != 64))
551: adjTile |= 0x0004;
552: }
553:
554: if (x > 0) {
555: Tile = TileAdrPtr[-WORLD_Y];
556: NeutralizeRoad(Tile);
557: if (((Tile == 238) || ((Tile >= 64) && (Tile <= 78))) &&
558: (Tile != 78) && (Tile != 237) && (Tile != 65))
559: adjTile |= 0x0008;
560: }
561:
562: (*TileAdrPtr) = _RoadTable[adjTile] | BULLBIT | BURNBIT;
563: return;
564: }
565:
566: if ((Tile >= 226) && (Tile <= 236)) { /* Cleanup Rail */
567:
568: if (y > 0) {
569: Tile = TileAdrPtr[-1];
570: NeutralizeRoad(Tile);
571: if ((Tile >= 221) && (Tile <= 238) &&
572: (Tile != 221) && (Tile != 237) && (Tile != 224))
573: adjTile |= 0x0001;
574: }
575:
576: if (x < (WORLD_X - 1)) {
577: Tile = TileAdrPtr[WORLD_Y];
578: NeutralizeRoad(Tile);
579: if ((Tile >= 221) && (Tile <= 238) &&
580: (Tile != 222) && (Tile != 238) && (Tile != 225))
581: adjTile |= 0x0002;
582: }
583:
584: if (y < (WORLD_Y - 1)) {
585: Tile = TileAdrPtr[1];
586: NeutralizeRoad(Tile);
587: if ((Tile >= 221) && (Tile <= 238) &&
588: (Tile != 221) && (Tile != 237) && (Tile != 224))
589: adjTile |= 0x0004;
590: }
591:
592: if (x > 0) {
593: Tile = TileAdrPtr[-WORLD_Y];
594: NeutralizeRoad(Tile);
595: if ((Tile >= 221) && (Tile <= 238) &&
596: (Tile != 222) && (Tile != 238) && (Tile != 225))
597: adjTile |= 0x0008;
598: }
599:
600: (*TileAdrPtr) = _RailTable[adjTile] | BULLBIT | BURNBIT;
601: return;
602: }
603:
604: if ((Tile >= 210) && (Tile <= 220)) { /* Cleanup Wire */
605:
606: if (y > 0) {
607: Tile = TileAdrPtr[-1];
608: if (Tile & CONDBIT) {
609: NeutralizeRoad(Tile);
610: if ((Tile != 209) && (Tile != 78) && (Tile != 222))
611: adjTile |= 0x0001;
612: }
613: }
614:
615: if (x < (WORLD_X - 1)) {
616: Tile = TileAdrPtr[WORLD_Y];
617: if (Tile & CONDBIT) {
618: NeutralizeRoad(Tile);
619: if ((Tile != 208) && (Tile != 77) && (Tile != 221))
620: adjTile |= 0x0002;
621: }
622: }
623:
624: if (y < (WORLD_Y - 1)) {
625: Tile = TileAdrPtr[1];
626: if (Tile & CONDBIT) {
627: NeutralizeRoad(Tile);
628: if ((Tile != 209) && (Tile != 78) && (Tile != 222))
629: adjTile |= 0x0004;
630: }
631: }
632:
633: if (x > 0) {
634: Tile = TileAdrPtr[-WORLD_Y];
635: if (Tile & CONDBIT) {
636: NeutralizeRoad(Tile);
637: if ((Tile != 208) && (Tile != 77) && (Tile != 221))
638: adjTile |= 0x0008;
639: }
640: }
641:
642: (*TileAdrPtr) = _WireTable[adjTile] | BULLBIT | BURNBIT | CONDBIT;
643: return;
644: }
645: }
646:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.