]>
git.zerfleddert.de Git - micropolis/blob - src/sim/s_zone.c
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.
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.
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/>.
21 * ADDITIONAL TERMS per GNU GPL Section 7
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.
29 * Any propagation or conveyance of this program must include this
30 * copyright notice and these terms.
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.
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.
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
72 ZonePwrFlg
= SetZPower(); /* Set Power Bit in Map from PowerMap */
73 if (ZonePwrFlg
) PwrdZCnt
++;
76 if (CChr9
> PORTBASE
) { /* do Special Zones */
80 if (CChr9
< HOSPITAL
) {
81 DoResidential(ZonePwrFlg
);
84 if (CChr9
< COMBASE
) {
88 if (CChr9
< INDBASE
) {
89 DoCommercial(ZonePwrFlg
);
92 DoIndustrial(ZonePwrFlg
);
99 if (CChr9
== HOSPITAL
) {
101 if (!(CityTime
& 15)) RepairZone (HOSPITAL
, 3); /*post*/
106 if (CChr9
== CHURCH
) {
108 if (!(CityTime
& 15)) RepairZone (CHURCH
, 3); /*post*/
109 if (NeedChurch
== -1)
118 #define ASCBIT (ANIMBIT | CONDBIT | BURNBIT)
119 #define REGBIT (CONDBIT | BURNBIT)
121 SetSmoke(int ZonePower
)
123 static short AniThis
[8] = { T
, F
, T
, T
, F
, F
, T
, T
};
124 static short DX1
[8] = { -1, 0, 1, 0, 0, 0, 0, 1 };
125 static short DY1
[8] = { -1, 0, -1, -1, 0, 0, -1, -1 };
126 static short DX2
[8] = { -1, 0, 1, 1, 0, 0, 1, 1 };
127 static short DY2
[8] = { -1, 0, 0, -1, 0, 0, -1, 0 };
128 static short AniTabA
[8] = { 0, 0, 32, 40, 0, 0, 48, 56 };
129 static short AniTabB
[8] = { 0, 0, 36, 44, 0, 0, 52, 60 };
130 static short AniTabC
[8] = { IND1
, 0, IND2
, IND4
, 0, 0, IND6
, IND8
};
131 static short AniTabD
[8] = { IND1
, 0, IND3
, IND5
, 0, 0, IND7
, IND9
};
134 if (CChr9
< IZB
) return;
135 z
= (CChr9
- IZB
) >>3;
138 int xx
= SMapX
+ DX1
[z
];
139 int yy
= SMapY
+ DY1
[z
];
140 if (TestBounds(xx
, yy
)) {
142 if ((Map
[xx
][yy
] & LOMASK
) == AniTabC
[z
]) {
144 ASCBIT
| (SMOKEBASE
+ AniTabA
[z
]);
146 ASCBIT
| (SMOKEBASE
+ AniTabB
[z
]);
149 if ((Map
[xx
][yy
] & LOMASK
) > AniTabC
[z
]) {
161 DoIndustrial(int ZonePwrFlg
)
163 short tpop
, zscore
, TrfGood
;
166 SetSmoke(ZonePwrFlg
);
169 if (tpop
> Rand(5)) TrfGood
= MakeTraf(2);
173 DoIndOut(tpop
, Rand16() & 1);
177 if (!(Rand16() & 7)) {
178 zscore
= IValve
+ EvalInd(TrfGood
);
179 if (!ZonePwrFlg
) zscore
= -500;
180 if ((zscore
> -350) &&
181 (((short)(zscore
- 26380)) > ((short)Rand16Signed()))) {
182 DoIndIn(tpop
, Rand16() & 1);
185 if ((zscore
< 350) &&
186 (((short)(zscore
+ 26380)) < ((short)Rand16Signed())))
187 DoIndOut(tpop
, Rand16() & 1);
192 DoCommercial(int ZonePwrFlg
)
194 register short tpop
, TrfGood
;
195 short zscore
, locvalve
,value
;
200 if (tpop
> Rand(5)) TrfGood
= MakeTraf(1);
205 DoComOut(tpop
, value
);
209 if (!(Rand16() & 7)) {
210 locvalve
= EvalCom(TrfGood
);
211 zscore
= CValve
+ locvalve
;
212 if (!ZonePwrFlg
) zscore
= -500;
216 (((short)(zscore
- 26380)) > ((short)Rand16Signed()))) {
218 DoComIn(tpop
, value
);
221 if ((zscore
< 350) &&
222 (((short)(zscore
+ 26380)) < ((short)Rand16Signed()))) {
224 DoComOut(tpop
, value
);
230 DoResidential(int ZonePwrFlg
)
232 short tpop
, zscore
, locvalve
, value
, TrfGood
;
235 if (CChr9
== FREEZ
) tpop
= DoFreePop();
236 else tpop
= RZPop(CChr9
);
239 if (tpop
> Rand(35)) TrfGood
= MakeTraf(0);
244 DoResOut(tpop
, value
);
248 if ((CChr9
== FREEZ
) || (!(Rand16() & 7))) {
249 locvalve
= EvalRes(TrfGood
);
250 zscore
= RValve
+ locvalve
;
251 if (!ZonePwrFlg
) zscore
= -500;
253 if ((zscore
> -350) &&
254 (((short)(zscore
- 26380)) > ((short)Rand16Signed()))) {
255 if ((!tpop
) && (!(Rand16() & 3))) {
260 DoResIn(tpop
, value
);
263 if ((zscore
< 350) &&
264 (((short)(zscore
+ 26380)) < ((short)Rand16Signed()))) {
266 DoResOut(tpop
, value
);
275 ZonePlop(HOSPITAL
- 4);
279 if (NeedChurch
> 0) {
280 ZonePlop(CHURCH
- 4);
291 LVal
= LandValueMem
[SMapX
>>1][SMapY
>>1];
292 LVal
-= PollutionMem
[SMapX
>>1][SMapY
>>1];
293 if (LVal
< 30) return (0);
294 if (LVal
< 80) return (1);
295 if (LVal
< 150) return (2);
300 DoResIn(int pop
, int value
)
304 z
= PollutionMem
[SMapX
>>1][SMapY
>>1];
307 if (CChr9
== FREEZ
) {
313 if (PopDensity
[SMapX
>>1][SMapY
>>1] > 64) {
321 ResPlop((pop
/ 8) - 1, value
);
327 DoComIn(int pop
, int value
)
331 z
= LandValueMem
[SMapX
>>1][SMapY
>>1];
342 DoIndIn(int pop
, int value
)
353 RateOGMem
[SMapX
>>3][SMapY
>>3] += amount
<<2;
357 DoResOut(int pop
, int value
)
359 static short Brdr
[9] = {0,3,6,1,4,7,2,5,8};
360 register short x
, y
, loc
, z
;
364 ResPlop(((pop
- 24) / 8), value
);
370 Map
[SMapX
][SMapY
] = (FREEZ
| BLBNCNBIT
| ZONEBIT
);
371 for (x
= SMapX
- 1; x
<= SMapX
+ 1; x
++)
372 for (y
= SMapY
- 1; y
<= SMapY
+ 1; y
++)
373 if (x
>= 0 && x
< WORLD_X
&&
374 y
>= 0 && y
< WORLD_Y
) {
375 if ((Map
[x
][y
] & LOMASK
) != FREEZ
)
376 Map
[x
][y
] = LHTHR
+ value
+
383 for (x
= SMapX
- 1; x
<= SMapX
+ 1; x
++)
384 for (y
= SMapY
- 1; y
<= SMapY
+ 1; y
++) {
385 if (x
>= 0 && x
< WORLD_X
&&
386 y
>= 0 && y
< WORLD_Y
) {
387 loc
= Map
[x
][y
] & LOMASK
;
388 if ((loc
>= LHTHR
) && (loc
<= HHTHR
)) {
389 Map
[x
][y
] = Brdr
[z
] +
390 BLBNCNBIT
+ FREEZ
- 4;
400 DoComOut(int pop
, int value
)
403 ComPlop(pop
- 2, value
);
414 DoIndOut(int pop
, int value
)
417 IndPlop(pop
- 2, value
);
422 ZonePlop(INDCLR
- 4);
432 CzDen
= (((Ch9
- RZB
) / 9) % 4);
433 return ((CzDen
* 8) + 16);
441 if (Ch9
== COMCLR
) return (0);
442 CzDen
= (((Ch9
- CZB
) / 9) % 5) + 1;
451 if (Ch9
== INDCLR
) return (0);
452 CzDen
= (((Ch9
- IZB
) / 9) % 4) + 1;
457 BuildHouse(int value
)
459 short z
, score
, hscore
, BestLoc
;
460 static short ZeX
[9] = { 0,-1, 0, 1,-1, 1,-1, 0, 1};
461 static short ZeY
[9] = { 0,-1,-1,-1, 0, 0, 1, 1, 1};
465 for (z
= 1; z
< 9; z
++) {
466 int xx
= SMapX
+ ZeX
[z
];
467 int yy
= SMapY
+ ZeY
[z
];
468 if (TestBounds(xx
, yy
)) {
469 score
= EvalLot(xx
, yy
);
471 if (score
> hscore
) {
475 if ((score
== hscore
) && !(Rand16() & 7))
481 int xx
= SMapX
+ ZeX
[BestLoc
];
482 int yy
= SMapY
+ ZeY
[BestLoc
];
483 if (TestBounds(xx
, yy
)) {
484 Map
[xx
][yy
] = HOUSE
+ BLBNCNBIT
+ Rand(2) + (value
* 3);
490 ResPlop (int Den
, int Value
)
494 base
= (((Value
* 4) + Den
) * 9) + RZB
- 4;
499 ComPlop (int Den
, int Value
)
503 base
= (((Value
* 5) + Den
) * 9) + CZB
- 4;
508 IndPlop (int Den
, int Value
)
512 base
= (((Value
* 4) + Den
) * 9) + (IZB
- 4);
517 EvalLot (int x
, int y
)
520 static short DX
[4] = { 0, 1, 0,-1};
521 static short DY
[4] = {-1, 0, 1, 0};
523 /* test for clear lot */
524 z
= Map
[x
][y
] & LOMASK
;
525 if (z
&& ((z
< RESBASE
) || (z
> RESBASE
+ 8)))
528 for (z
= 0; z
< 4; z
++) {
531 if (TestBounds(xx
, yy
) &&
533 ((Map
[xx
][yy
] & LOMASK
) <= LASTROAD
)) {
534 score
++; /* look for road */
544 static short Zx
[9] = {-1, 0, 1,-1, 0, 1,-1, 0, 1};
545 static short Zy
[9] = {-1,-1,-1, 0, 0, 0, 1, 1, 1};
547 for (z
= 0; z
< 9; z
++) { /* check for fire */
548 int xx
= SMapX
+ Zx
[z
];
549 int yy
= SMapY
+ Zy
[z
];
550 if (TestBounds(xx
, yy
)) {
551 x
= Map
[xx
][yy
] & LOMASK
;
552 if ((x
>= FLOOD
) && (x
< ROADBASE
)) return (FALSE
);
555 for (z
= 0; z
< 9; z
++) {
556 int xx
= SMapX
+ Zx
[z
];
557 int yy
= SMapY
+ Zy
[z
];
558 if (TestBounds(xx
, yy
)) {
559 Map
[xx
][yy
] = base
+ BNCNBIT
;
563 CChr
= Map
[SMapX
][SMapY
];
565 Map
[SMapX
][SMapY
] |= ZONEBIT
+ BULLBIT
;
571 register short Value
;
573 if (traf
< 0) return (-3000);
575 Value
= LandValueMem
[SMapX
>>1][SMapY
>>1];
576 Value
-= PollutionMem
[SMapX
>>1][SMapY
>>1];
578 if (Value
< 0) Value
= 0; /* Cap at 0 */
579 else Value
= Value
<<5;
581 if (Value
> 6000) Value
= 6000; /* Cap at 6000 */
583 Value
= Value
- 3000;
592 if (traf
< 0) return (-3000);
593 Value
= ComRate
[SMapX
>>3][SMapY
>>3];
600 if (traf
< 0) return (-1000);
608 register short loc
, x
, y
;
611 for (x
= SMapX
- 1; x
<= SMapX
+ 1; x
++)
612 for (y
= SMapY
- 1; y
<= SMapY
+ 1; y
++) {
613 if (x
>= 0 && x
< WORLD_X
&&
614 y
>= 0 && y
< WORLD_Y
) {
615 loc
= Map
[x
][y
] & LOMASK
;
616 if ((loc
>= LHTHR
) && (loc
<= HHTHR
))
624 SetZPower(void) /* set bit in MapWord depending on powermap */
629 /* TestPowerBit was taking alot of time so I inlined it. -Don */
633 if (z
= TestPowerBit())
634 Map
[SMapX
][SMapY
] = CChr
| PWRBIT
;
636 Map
[SMapX
][SMapY
] = CChr
& (~PWRBIT
);
641 if ((CChr9
== NUCLEAR
) ||
642 (CChr9
== POWERPLANT
) ||
645 (PowerWrd
= POWERWORD(SMapX
, SMapY
)),
647 (PowerWrd
= (SMapX
>>4) + (SMapY
<<3)),
649 ((PowerWrd
< PWRMAPSIZE
) &&
650 (PowerMap
[PowerWrd
] & (1 << (SMapX
& 15)))))) {
651 Map
[SMapX
][SMapY
] = CChr
| PWRBIT
;
654 Map
[SMapX
][SMapY
] = CChr
& (~PWRBIT
);