]>
git.zerfleddert.de Git - micropolis/blob - src/sim/s_zone.c
4ba6cdee1d5686202908f408c2413dc9b77c6c9a
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
67 void ZonePlop (int base
);
68 void IndPlop (int Den
, int Value
);
69 void ComPlop (int Den
, int Value
);
70 void ResPlop (int Den
, int Value
);
71 int EvalLot (int x
, int y
);
72 void BuildHouse(int value
);
73 void DoIndOut(int pop
, int value
);
74 void DoComOut(int pop
, int value
);
75 void DoResOut(int pop
, int value
);
76 void IncROG(int amount
);
77 void DoIndIn(int pop
, int value
);
78 void DoComIn(int pop
, int value
);
79 void DoResIn(int pop
, int value
);
81 void DoResidential(int ZonePwrFlg
);
82 int EvalRes (int traf
);
83 int EvalCom (int traf
);
85 void DoCommercial(int ZonePwrFlg
);
86 void DoIndustrial(int ZonePwrFlg
);
87 int EvalInd (int traf
);
88 void DoHospChur(void);
95 ZonePwrFlg
= SetZPower(); /* Set Power Bit in Map from PowerMap */
96 if (ZonePwrFlg
) PwrdZCnt
++;
99 if (CChr9
> PORTBASE
) { /* do Special Zones */
100 DoSPZone(ZonePwrFlg
);
103 if (CChr9
< HOSPITAL
) {
104 DoResidential(ZonePwrFlg
);
107 if (CChr9
< COMBASE
) {
111 if (CChr9
< INDBASE
) {
112 DoCommercial(ZonePwrFlg
);
115 DoIndustrial(ZonePwrFlg
);
123 if (CChr9
== HOSPITAL
) {
125 if (!(CityTime
& 15)) RepairZone (HOSPITAL
, 3); /*post*/
130 if (CChr9
== CHURCH
) {
132 if (!(CityTime
& 15)) RepairZone (CHURCH
, 3); /*post*/
133 if (NeedChurch
== -1)
142 #define ASCBIT (ANIMBIT | CONDBIT | BURNBIT)
143 #define REGBIT (CONDBIT | BURNBIT)
146 SetSmoke(int ZonePower
)
148 static short AniThis
[8] = { T
, F
, T
, T
, F
, F
, T
, T
};
149 static short DX1
[8] = { -1, 0, 1, 0, 0, 0, 0, 1 };
150 static short DY1
[8] = { -1, 0, -1, -1, 0, 0, -1, -1 };
152 static short DX2
[8] = { -1, 0, 1, 1, 0, 0, 1, 1 };
153 static short DY2
[8] = { -1, 0, 0, -1, 0, 0, -1, 0 };
155 static short AniTabA
[8] = { 0, 0, 32, 40, 0, 0, 48, 56 };
156 static short AniTabB
[8] = { 0, 0, 36, 44, 0, 0, 52, 60 };
157 static short AniTabC
[8] = { IND1
, 0, IND2
, IND4
, 0, 0, IND6
, IND8
};
158 static short AniTabD
[8] = { IND1
, 0, IND3
, IND5
, 0, 0, IND7
, IND9
};
161 if (CChr9
< IZB
) return;
162 z
= (CChr9
- IZB
) >>3;
165 int xx
= SMapX
+ DX1
[z
];
166 int yy
= SMapY
+ DY1
[z
];
167 if (TestBounds(xx
, yy
)) {
169 if ((Map
[xx
][yy
] & LOMASK
) == AniTabC
[z
]) {
171 ASCBIT
| (SMOKEBASE
+ AniTabA
[z
]);
173 ASCBIT
| (SMOKEBASE
+ AniTabB
[z
]);
176 if ((Map
[xx
][yy
] & LOMASK
) > AniTabC
[z
]) {
189 DoIndustrial(int ZonePwrFlg
)
191 short tpop
, zscore
, TrfGood
;
194 SetSmoke(ZonePwrFlg
);
197 if (tpop
> Rand(5)) TrfGood
= MakeTraf(2);
201 DoIndOut(tpop
, Rand16() & 1);
205 if (!(Rand16() & 7)) {
206 zscore
= IValve
+ EvalInd(TrfGood
);
207 if (!ZonePwrFlg
) zscore
= -500;
208 if ((zscore
> -350) &&
209 (((short)(zscore
- 26380)) > ((short)Rand16Signed()))) {
210 DoIndIn(tpop
, Rand16() & 1);
213 if ((zscore
< 350) &&
214 (((short)(zscore
+ 26380)) < ((short)Rand16Signed())))
215 DoIndOut(tpop
, Rand16() & 1);
221 DoCommercial(int ZonePwrFlg
)
223 register short tpop
, TrfGood
;
224 short zscore
, locvalve
,value
;
229 if (tpop
> Rand(5)) TrfGood
= MakeTraf(1);
234 DoComOut(tpop
, value
);
238 if (!(Rand16() & 7)) {
239 locvalve
= EvalCom(TrfGood
);
240 zscore
= CValve
+ locvalve
;
241 if (!ZonePwrFlg
) zscore
= -500;
245 (((short)(zscore
- 26380)) > ((short)Rand16Signed()))) {
247 DoComIn(tpop
, value
);
250 if ((zscore
< 350) &&
251 (((short)(zscore
+ 26380)) < ((short)Rand16Signed()))) {
253 DoComOut(tpop
, value
);
260 DoResidential(int ZonePwrFlg
)
262 short tpop
, zscore
, locvalve
, value
, TrfGood
;
265 if (CChr9
== FREEZ
) tpop
= DoFreePop();
266 else tpop
= RZPop(CChr9
);
269 if (tpop
> Rand(35)) TrfGood
= MakeTraf(0);
274 DoResOut(tpop
, value
);
278 if ((CChr9
== FREEZ
) || (!(Rand16() & 7))) {
279 locvalve
= EvalRes(TrfGood
);
280 zscore
= RValve
+ locvalve
;
281 if (!ZonePwrFlg
) zscore
= -500;
283 if ((zscore
> -350) &&
284 (((short)(zscore
- 26380)) > ((short)Rand16Signed()))) {
285 if ((!tpop
) && (!(Rand16() & 3))) {
290 DoResIn(tpop
, value
);
293 if ((zscore
< 350) &&
294 (((short)(zscore
+ 26380)) < ((short)Rand16Signed()))) {
296 DoResOut(tpop
, value
);
306 ZonePlop(HOSPITAL
- 4);
310 if (NeedChurch
> 0) {
311 ZonePlop(CHURCH
- 4);
323 LVal
= LandValueMem
[SMapX
>>1][SMapY
>>1];
324 LVal
-= PollutionMem
[SMapX
>>1][SMapY
>>1];
325 if (LVal
< 30) return (0);
326 if (LVal
< 80) return (1);
327 if (LVal
< 150) return (2);
333 DoResIn(int pop
, int value
)
337 z
= PollutionMem
[SMapX
>>1][SMapY
>>1];
340 if (CChr9
== FREEZ
) {
346 if (PopDensity
[SMapX
>>1][SMapY
>>1] > 64) {
354 ResPlop((pop
/ 8) - 1, value
);
361 DoComIn(int pop
, int value
)
365 z
= LandValueMem
[SMapX
>>1][SMapY
>>1];
377 DoIndIn(int pop
, int value
)
389 RateOGMem
[SMapX
>>3][SMapY
>>3] += amount
<<2;
394 DoResOut(int pop
, int value
)
396 static short Brdr
[9] = {0,3,6,1,4,7,2,5,8};
397 register short x
, y
, loc
, z
;
401 ResPlop(((pop
- 24) / 8), value
);
407 Map
[SMapX
][SMapY
] = (FREEZ
| BLBNCNBIT
| ZONEBIT
);
408 for (x
= SMapX
- 1; x
<= SMapX
+ 1; x
++)
409 for (y
= SMapY
- 1; y
<= SMapY
+ 1; y
++)
410 if (x
>= 0 && x
< WORLD_X
&&
411 y
>= 0 && y
< WORLD_Y
) {
412 if ((Map
[x
][y
] & LOMASK
) != FREEZ
)
413 Map
[x
][y
] = LHTHR
+ value
+
420 for (x
= SMapX
- 1; x
<= SMapX
+ 1; x
++)
421 for (y
= SMapY
- 1; y
<= SMapY
+ 1; y
++) {
422 if (x
>= 0 && x
< WORLD_X
&&
423 y
>= 0 && y
< WORLD_Y
) {
424 loc
= Map
[x
][y
] & LOMASK
;
425 if ((loc
>= LHTHR
) && (loc
<= HHTHR
)) {
426 Map
[x
][y
] = Brdr
[z
] +
427 BLBNCNBIT
+ FREEZ
- 4;
438 DoComOut(int pop
, int value
)
441 ComPlop(pop
- 2, value
);
453 DoIndOut(int pop
, int value
)
456 IndPlop(pop
- 2, value
);
461 ZonePlop(INDCLR
- 4);
472 CzDen
= (((Ch9
- RZB
) / 9) % 4);
473 return ((CzDen
* 8) + 16);
482 if (Ch9
== COMCLR
) return (0);
483 CzDen
= (((Ch9
- CZB
) / 9) % 5) + 1;
493 if (Ch9
== INDCLR
) return (0);
494 CzDen
= (((Ch9
- IZB
) / 9) % 4) + 1;
500 BuildHouse(int value
)
502 short z
, score
, hscore
, BestLoc
;
503 static short ZeX
[9] = { 0,-1, 0, 1,-1, 1,-1, 0, 1};
504 static short ZeY
[9] = { 0,-1,-1,-1, 0, 0, 1, 1, 1};
508 for (z
= 1; z
< 9; z
++) {
509 int xx
= SMapX
+ ZeX
[z
];
510 int yy
= SMapY
+ ZeY
[z
];
511 if (TestBounds(xx
, yy
)) {
512 score
= EvalLot(xx
, yy
);
514 if (score
> hscore
) {
518 if ((score
== hscore
) && !(Rand16() & 7))
524 int xx
= SMapX
+ ZeX
[BestLoc
];
525 int yy
= SMapY
+ ZeY
[BestLoc
];
526 if (TestBounds(xx
, yy
)) {
527 Map
[xx
][yy
] = HOUSE
+ BLBNCNBIT
+ Rand(2) + (value
* 3);
534 ResPlop (int Den
, int Value
)
538 base
= (((Value
* 4) + Den
) * 9) + RZB
- 4;
544 ComPlop (int Den
, int Value
)
548 base
= (((Value
* 5) + Den
) * 9) + CZB
- 4;
554 IndPlop (int Den
, int Value
)
558 base
= (((Value
* 4) + Den
) * 9) + (IZB
- 4);
564 EvalLot (int x
, int y
)
567 static short DX
[4] = { 0, 1, 0,-1};
568 static short DY
[4] = {-1, 0, 1, 0};
570 /* test for clear lot */
571 z
= Map
[x
][y
] & LOMASK
;
572 if (z
&& ((z
< RESBASE
) || (z
> RESBASE
+ 8)))
575 for (z
= 0; z
< 4; z
++) {
578 if (TestBounds(xx
, yy
) &&
580 ((Map
[xx
][yy
] & LOMASK
) <= LASTROAD
)) {
581 score
++; /* look for road */
592 static short Zx
[9] = {-1, 0, 1,-1, 0, 1,-1, 0, 1};
593 static short Zy
[9] = {-1,-1,-1, 0, 0, 0, 1, 1, 1};
595 for (z
= 0; z
< 9; z
++) { /* check for fire */
596 int xx
= SMapX
+ Zx
[z
];
597 int yy
= SMapY
+ Zy
[z
];
598 if (TestBounds(xx
, yy
)) {
599 x
= Map
[xx
][yy
] & LOMASK
;
600 if ((x
>= FLOOD
) && (x
< ROADBASE
)) return;
603 for (z
= 0; z
< 9; z
++) {
604 int xx
= SMapX
+ Zx
[z
];
605 int yy
= SMapY
+ Zy
[z
];
606 if (TestBounds(xx
, yy
)) {
607 Map
[xx
][yy
] = base
+ BNCNBIT
;
611 CChr
= Map
[SMapX
][SMapY
];
613 Map
[SMapX
][SMapY
] |= ZONEBIT
+ BULLBIT
;
620 register short Value
;
622 if (traf
< 0) return (-3000);
624 Value
= LandValueMem
[SMapX
>>1][SMapY
>>1];
625 Value
-= PollutionMem
[SMapX
>>1][SMapY
>>1];
627 if (Value
< 0) Value
= 0; /* Cap at 0 */
628 else Value
= Value
<<5;
630 if (Value
> 6000) Value
= 6000; /* Cap at 6000 */
632 Value
= Value
- 3000;
642 if (traf
< 0) return (-3000);
643 Value
= ComRate
[SMapX
>>3][SMapY
>>3];
651 if (traf
< 0) return (-1000);
660 register short loc
, x
, y
;
663 for (x
= SMapX
- 1; x
<= SMapX
+ 1; x
++)
664 for (y
= SMapY
- 1; y
<= SMapY
+ 1; y
++) {
665 if (x
>= 0 && x
< WORLD_X
&&
666 y
>= 0 && y
< WORLD_Y
) {
667 loc
= Map
[x
][y
] & LOMASK
;
668 if ((loc
>= LHTHR
) && (loc
<= HHTHR
))
677 SetZPower(void) /* set bit in MapWord depending on powermap */
684 /* TestPowerBit was taking alot of time so I inlined it. -Don */
688 if (z
= TestPowerBit())
689 Map
[SMapX
][SMapY
] = CChr
| PWRBIT
;
691 Map
[SMapX
][SMapY
] = CChr
& (~PWRBIT
);
696 if ((CChr9
== NUCLEAR
) ||
697 (CChr9
== POWERPLANT
) ||
700 (PowerWrd
= POWERWORD(SMapX
, SMapY
)),
702 (PowerWrd
= (SMapX
>>4) + (SMapY
<<3)),
704 ((PowerWrd
< PWRMAPSIZE
) &&
705 (PowerMap
[PowerWrd
] & (1 << (SMapX
& 15)))))) {
706 Map
[SMapX
][SMapY
] = CChr
| PWRBIT
;
709 Map
[SMapX
][SMapY
] = CChr
& (~PWRBIT
);