Annotation of micropolis/src/sim/s_sim.c, revision 1.1

1.1     ! root        1: /* s_sim.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: /* Simulation */
        !            66: 
        !            67: 
        !            68: short ValveFlag;
        !            69: short CrimeRamp, PolluteRamp ;
        !            70: short RValve, CValve, IValve;
        !            71: short ResCap, ComCap, IndCap;
        !            72: short CashFlow;
        !            73: float EMarket = 4.0;
        !            74: short DisasterEvent;
        !            75: short DisasterWait;
        !            76: short ScoreType;
        !            77: short ScoreWait;
        !            78: short PwrdZCnt;
        !            79: short unPwrdZCnt;
        !            80: short NewPower; /* post */
        !            81: short AvCityTax;
        !            82: short Scycle = 0;
        !            83: short Fcycle = 0;
        !            84: short Spdcycle = 0;
        !            85: short DoInitialEval = 0;
        !            86: short MeltX, MeltY;
        !            87: 
        !            88: 
        !            89: /* comefrom: doEditWindow scoreDoer doMapInFront graphDoer doNilEvent */
        !            90: SimFrame(void)
        !            91: {
        !            92:   short i;
        !            93: 
        !            94:   if (SimSpeed == 0)
        !            95:     return;
        !            96: 
        !            97:   if (++Spdcycle > 1023)
        !            98:     Spdcycle = 0;
        !            99: 
        !           100:   if (SimSpeed == 1 && Spdcycle % 5)
        !           101:     return;
        !           102: 
        !           103:   if (SimSpeed == 2 && Spdcycle % 3)
        !           104:     return;
        !           105: 
        !           106:   if (++Fcycle > 1023) Fcycle = 0;
        !           107: /*  if (InitSimLoad) Fcycle = 0; */
        !           108:   Simulate(Fcycle & 15);
        !           109: }
        !           110: 
        !           111: 
        !           112: /* comefrom: SimFrame */
        !           113: Simulate(int mod16)
        !           114: {
        !           115:   static short SpdPwr[4] = { 1,  2,  4,  5 };
        !           116:   static short SpdPtl[4] = { 1,  2,  7, 17 };
        !           117:   static short SpdCri[4] = { 1,  1,  8, 18 };
        !           118:   static short SpdPop[4] = { 1,  1,  9, 19 };
        !           119:   static short SpdFir[4] = { 1,  1, 10, 20 };
        !           120:   short x;
        !           121: 
        !           122:   x = SimSpeed;
        !           123:   if (x > 3) x = 3;
        !           124: 
        !           125:   switch (mod16)  {
        !           126:     case 0:
        !           127:       if (++Scycle > 1023) Scycle = 0; /* this is cosmic */
        !           128:       if (DoInitialEval) {
        !           129:        DoInitialEval = 0;
        !           130:        CityEvaluation();
        !           131:       }
        !           132:       CityTime++;
        !           133:       AvCityTax += CityTax;            /* post */
        !           134:       if (!(Scycle & 1)) SetValves();
        !           135:       ClearCensus();
        !           136:       break;
        !           137:     case 1:
        !           138:       MapScan(0, 1 * WORLD_X / 8);
        !           139:       break;
        !           140:     case 2:
        !           141:       MapScan(1 * WORLD_X / 8, 2 * WORLD_X / 8);
        !           142:       break;
        !           143:     case 3:
        !           144:       MapScan(2 * WORLD_X / 8, 3 * WORLD_X / 8);
        !           145:       break;
        !           146:     case 4:
        !           147:       MapScan(3 * WORLD_X / 8, 4 * WORLD_X / 8);
        !           148:       break;
        !           149:     case 5:
        !           150:       MapScan(4 * WORLD_X / 8, 5 * WORLD_X / 8);
        !           151:       break;
        !           152:     case 6:
        !           153:       MapScan(5 * WORLD_X / 8, 6 * WORLD_X / 8);
        !           154:       break;
        !           155:     case 7:
        !           156:       MapScan(6 * WORLD_X / 8, 7 * WORLD_X / 8);
        !           157:       break;
        !           158:     case 8:
        !           159:       MapScan(7 * WORLD_X / 8, WORLD_X);
        !           160:       break;
        !           161:     case 9:
        !           162:       if (!(CityTime % CENSUSRATE)) TakeCensus();
        !           163:       if (!(CityTime % (CENSUSRATE * 12))) Take2Census();
        !           164: 
        !           165:       if (!(CityTime % TAXFREQ))  {
        !           166:        CollectTax();
        !           167:        CityEvaluation();
        !           168:       }
        !           169:       break;
        !           170:     case 10:
        !           171:       if (!(Scycle % 5)) DecROGMem();
        !           172:       DecTrafficMem();
        !           173:       NewMapFlags[TDMAP] = 1;
        !           174:       NewMapFlags[RDMAP] = 1;
        !           175:       NewMapFlags[ALMAP] = 1;
        !           176:       NewMapFlags[REMAP] = 1;
        !           177:       NewMapFlags[COMAP] = 1;
        !           178:       NewMapFlags[INMAP] = 1;
        !           179:       NewMapFlags[DYMAP] = 1;
        !           180:       SendMessages();
        !           181:       break;
        !           182:     case 11:
        !           183:       if (!(Scycle % SpdPwr[x])) {
        !           184:        DoPowerScan();
        !           185:        NewMapFlags[PRMAP] = 1;
        !           186:        NewPower = 1; /* post-release change */
        !           187:       }
        !           188:       break;
        !           189:     case 12:
        !           190:       if (!(Scycle % SpdPtl[x])) PTLScan();
        !           191:       break;
        !           192:     case 13:
        !           193:       if (!(Scycle % SpdCri[x])) CrimeScan();
        !           194:       break;
        !           195:     case 14:
        !           196:       if (!(Scycle % SpdPop[x])) PopDenScan();
        !           197:       break;
        !           198:     case 15:
        !           199:       if (!(Scycle % SpdFir[x])) FireAnalysis();
        !           200:       DoDisasters();   
        !           201:       break;
        !           202:   }
        !           203: }
        !           204: 
        !           205: 
        !           206: /* comefrom: Simulate */
        !           207: DoSimInit(void)
        !           208: {
        !           209:   Fcycle = 0;
        !           210:   Scycle = 0;
        !           211: 
        !           212:   if (InitSimLoad == 2)                        /* if new city    */
        !           213:     InitSimMemory();
        !           214: 
        !           215:   if (InitSimLoad == 1)                        /* if city just loaded  */
        !           216:     SimLoadInit();
        !           217: 
        !           218:   SetValves();
        !           219:   ClearCensus();
        !           220: #if 1
        !           221:   MapScan(0, WORLD_X); /* XXX are you sure ??? */
        !           222: #endif
        !           223:   DoPowerScan();
        !           224:   NewPower = 1;                /* post rel */
        !           225:   PTLScan();
        !           226:   CrimeScan();
        !           227:   PopDenScan();
        !           228:   FireAnalysis();
        !           229:   NewMap = 1;
        !           230:   doAllGraphs();
        !           231:   NewGraph = 1;
        !           232:   TotalPop = 1;
        !           233:   DoInitialEval = 1;
        !           234: }
        !           235: 
        !           236: 
        !           237: /* comefrom: SimLoadInit */
        !           238: DoNilPower(void)
        !           239: {
        !           240:   register short x, y, z;
        !           241: 
        !           242:   for (x = 0; x < WORLD_X; x++)
        !           243:     for (y = 0; y < WORLD_Y; y++) {
        !           244:       z = Map[x][y];
        !           245:       if (z & ZONEBIT) {
        !           246:        SMapX = x;
        !           247:        SMapY = y;
        !           248:        CChr = z;
        !           249:        SetZPower();
        !           250:       }
        !           251:     }
        !           252: }
        !           253: 
        !           254: 
        !           255: /* comefrom: Simulate */
        !           256: DecTrafficMem(void)            /* tends to empty TrfDensity   */
        !           257: {
        !           258:   register short x, y, z;
        !           259: 
        !           260:   for (x = 0; x < HWLDX; x++)
        !           261:     for (y = 0; y < HWLDY; y++)
        !           262:       if (z = TrfDensity[x][y]) {
        !           263:        if (z > 24) {
        !           264:          if (z > 200) TrfDensity[x][y] = z - 34;
        !           265:          else TrfDensity[x][y] = z - 24;
        !           266:        }
        !           267:        else TrfDensity[x][y] = 0;
        !           268:       }
        !           269: }
        !           270: 
        !           271: 
        !           272: /* comefrom: Simulate */
        !           273: DecROGMem(void)                        /* tends to empty RateOGMem   */
        !           274: {
        !           275:   register short x, y, z;
        !           276: 
        !           277:   for (x = 0; x < SmX; x++)
        !           278:     for (y = 0; y < SmY; y++)  {
        !           279:       z = RateOGMem[x][y];
        !           280:       if (z == 0) continue;
        !           281:       if (z > 0)  {
        !           282:        --RateOGMem[x][y];
        !           283:        if (z > 200) RateOGMem[x][y] = 200;    /* prevent overflow */
        !           284:        continue;
        !           285:       }
        !           286:       if (z < 0)  {
        !           287:        ++RateOGMem[x][y];
        !           288:        if (z < -200) RateOGMem[x][y] = -200;
        !           289:       }
        !           290:     }
        !           291: }
        !           292: 
        !           293: 
        !           294: /* comefrom: DoSimInit */
        !           295: InitSimMemory(void)
        !           296: {      
        !           297:   register short x, z;
        !           298: 
        !           299:   z = 0;
        !           300:   SetCommonInits();
        !           301:   for (x = 0; x < 240; x++)  {
        !           302:     ResHis[x] = z;
        !           303:     ComHis[x] = z;
        !           304:     IndHis[x] = z;
        !           305:     MoneyHis[x] = 128;
        !           306:     CrimeHis[x] = z;
        !           307:     PollutionHis[x] = z;
        !           308:   }
        !           309:   CrimeRamp = z;
        !           310:   PolluteRamp = z;
        !           311:   TotalPop = z;
        !           312:   RValve = z;
        !           313:   CValve = z;
        !           314:   IValve = z;
        !           315:   ResCap = z;
        !           316:   ComCap = z;
        !           317:   IndCap = z;
        !           318: 
        !           319:   EMarket = 6.0;
        !           320:   DisasterEvent = 0;
        !           321:   ScoreType = 0;
        !           322: 
        !           323:   /* This clears powermem */
        !           324:   PowerStackNum = z;           
        !           325:   DoPowerScan();
        !           326:   NewPower = 1;                /* post rel */  
        !           327: 
        !           328:   InitSimLoad = 0;
        !           329: }
        !           330: 
        !           331: 
        !           332: /* comefrom: DoSimInit */
        !           333: SimLoadInit(void)
        !           334: {
        !           335:   static short DisTab[9] = { 0, 2, 10, 5, 20, 3, 5, 5, 2 * 48};
        !           336:   static short ScoreWaitTab[9] = { 0, 30 * 48, 5 * 48, 5 * 48, 10 * 48,
        !           337:                                   5 * 48, 10 * 48, 5 * 48, 10 * 48 };
        !           338:   register int z;
        !           339: 
        !           340:   z = 0;
        !           341:   EMarket = (float)MiscHis[1];
        !           342:   ResPop = MiscHis[2];
        !           343:   ComPop = MiscHis[3];
        !           344:   IndPop = MiscHis[4];
        !           345:   RValve = MiscHis[5];
        !           346:   CValve = MiscHis[6];
        !           347:   IValve = MiscHis[7];
        !           348:   CrimeRamp = MiscHis[10];
        !           349:   PolluteRamp = MiscHis[11];
        !           350:   LVAverage = MiscHis[12];
        !           351:   CrimeAverage = MiscHis[13];
        !           352:   PolluteAverage = MiscHis[14];
        !           353:   GameLevel = MiscHis[15];
        !           354: 
        !           355:   if (CityTime < 0) CityTime = 0;
        !           356:   if (!EMarket) EMarket = 4.0;
        !           357:   if ((GameLevel > 2) || (GameLevel < 0)) GameLevel = 0;
        !           358:   SetGameLevel(GameLevel);
        !           359: 
        !           360:   SetCommonInits();
        !           361: 
        !           362:   CityClass = MiscHis[16];
        !           363:   CityScore = MiscHis[17];
        !           364: 
        !           365:   if ((CityClass > 5) || (CityClass < 0)) CityClass = 0;
        !           366:   if ((CityScore > 999) || (CityScore < 1)) CityScore = 500;
        !           367: 
        !           368:   ResCap = 0;
        !           369:   ComCap = 0;
        !           370:   IndCap = 0;
        !           371: 
        !           372:   AvCityTax = (CityTime % 48) * 7;  /* post */
        !           373: 
        !           374:   for (z = 0; z < PWRMAPSIZE; z++)
        !           375:     PowerMap[z] = ~0; /* set power Map */
        !           376:   DoNilPower();
        !           377: 
        !           378:   if (ScenarioID > 8) ScenarioID = 0;
        !           379: 
        !           380:   if (ScenarioID) {
        !           381:     DisasterEvent = ScenarioID;
        !           382:     DisasterWait = DisTab[DisasterEvent];
        !           383:     ScoreType = DisasterEvent;
        !           384:     ScoreWait = ScoreWaitTab[DisasterEvent];
        !           385:   } else {
        !           386:     DisasterEvent = 0;
        !           387:     ScoreType = 0;
        !           388:   }
        !           389: 
        !           390:   RoadEffect = 32;
        !           391:   PoliceEffect = 1000; /*post*/
        !           392:   FireEffect = 1000;
        !           393:   InitSimLoad = 0;
        !           394: }
        !           395: 
        !           396: 
        !           397: /* comefrom: InitSimMemory SimLoadInit */
        !           398: SetCommonInits(void)
        !           399: {
        !           400:   EvalInit();
        !           401:   RoadEffect = 32;
        !           402:   PoliceEffect = 1000;
        !           403:   FireEffect = 1000;
        !           404:   TaxFlag = 0;
        !           405:   TaxFund = 0;
        !           406: /*
        !           407:   if ((GameLevel > 2) || (GameLevel < 0)) GameLevel = 0;
        !           408:   setGameLevel(GameLevel);
        !           409: */
        !           410: }
        !           411: 
        !           412: 
        !           413: /* comefrom: Simulate DoSimInit */
        !           414: SetValves(void)
        !           415: {
        !           416:   static short TaxTable[21] = {
        !           417:     200, 150, 120, 100, 80, 50, 30, 0, -10, -40, -100,
        !           418:     -150, -200, -250, -300, -350, -400, -450, -500, -550, -600 };
        !           419:   float Employment, Migration, Births, LaborBase, IntMarket;
        !           420:   float Rratio, Cratio, Iratio, temp;
        !           421:   float NormResPop, PjResPop, PjComPop, PjIndPop;
        !           422:   register short z;
        !           423: 
        !           424:   MiscHis[1] = (short)EMarket;
        !           425:   MiscHis[2] = ResPop;
        !           426:   MiscHis[3] = ComPop;
        !           427:   MiscHis[4] = IndPop;
        !           428:   MiscHis[5] = RValve;
        !           429:   MiscHis[6] = CValve;
        !           430:   MiscHis[7] = IValve;
        !           431:   MiscHis[10] = CrimeRamp;
        !           432:   MiscHis[11] = PolluteRamp;
        !           433:   MiscHis[12] = LVAverage;
        !           434:   MiscHis[13] = CrimeAverage;
        !           435:   MiscHis[14] = PolluteAverage;
        !           436:   MiscHis[15] = GameLevel;
        !           437:   MiscHis[16] = CityClass;
        !           438:   MiscHis[17] = CityScore;
        !           439: 
        !           440:   NormResPop = ResPop / 8;
        !           441:   LastTotalPop = TotalPop;
        !           442:   TotalPop = NormResPop + ComPop + IndPop;
        !           443: 
        !           444:   if (NormResPop) Employment = ((ComHis[1] + IndHis[1]) / NormResPop);
        !           445:   else Employment = 1;
        !           446: 
        !           447:   Migration = NormResPop * (Employment - 1);
        !           448:   Births = NormResPop * (.02);                         /* Birth Rate  */
        !           449:   PjResPop = NormResPop + Migration + Births;  /* Projected Res.Pop  */
        !           450: 
        !           451:   if (temp = (ComHis[1] + IndHis[1])) LaborBase = (ResHis[1] / temp);
        !           452:   else LaborBase = 1;
        !           453:   if (LaborBase > 1.3) LaborBase = 1.3;
        !           454:   if (LaborBase < 0) LaborBase = 0;  /* LB > 1 - .1  */
        !           455: 
        !           456:   for (z = 0; z < 2; z++)
        !           457:     temp = ResHis[z] + ComHis[z] + IndHis[z];
        !           458:   IntMarket = (NormResPop + ComPop + IndPop) / 3.7;
        !           459: 
        !           460:   PjComPop = IntMarket * LaborBase;                    
        !           461: 
        !           462:   z = GameLevel;                       /* New ExtMarket */
        !           463:   temp = 1;
        !           464:   switch (z)  {
        !           465:   case 0:
        !           466:     temp = 1.2;
        !           467:     break;
        !           468:   case 1:
        !           469:     temp = 1.1;
        !           470:     break;
        !           471:   case 2:
        !           472:     temp = .98;
        !           473:     break;
        !           474:   }
        !           475: 
        !           476:   PjIndPop = IndPop * LaborBase * temp;
        !           477:   if (PjIndPop < 5) PjIndPop = 5;
        !           478: 
        !           479:   if (NormResPop) Rratio = (PjResPop / NormResPop); /* projected -vs- actual */
        !           480:   else Rratio = 1.3;
        !           481:   if (ComPop) Cratio = (PjComPop / ComPop);
        !           482:   else Cratio = PjComPop;
        !           483:   if (IndPop) Iratio = (PjIndPop / IndPop);
        !           484:   else Iratio = PjIndPop;
        !           485: 
        !           486:   if (Rratio > 2) Rratio = 2;
        !           487:   if (Cratio > 2) Cratio = 2;
        !           488:   if (Iratio > 2) Iratio = 2;
        !           489: 
        !           490:   z = CityTax + GameLevel;
        !           491:   if (z > 20) z = 20;
        !           492:   Rratio = ((Rratio -1) * 600) + TaxTable[z]; /* global tax/Glevel effects */
        !           493:   Cratio = ((Cratio -1) * 600) + TaxTable[z];
        !           494:   Iratio = ((Iratio -1) * 600) + TaxTable[z];
        !           495: 
        !           496:   if (Rratio > 0)              /* ratios are velocity changes to valves  */
        !           497:     if (RValve <  2000) RValve += Rratio;
        !           498:   if (Rratio < 0)
        !           499:     if (RValve > -2000) RValve += Rratio;
        !           500:   if (Cratio > 0)
        !           501:     if (CValve <  1500) CValve += Cratio;
        !           502:   if (Cratio < 0)
        !           503:     if (CValve > -1500) CValve += Cratio;
        !           504:   if (Iratio > 0)
        !           505:     if (IValve <  1500) IValve += Iratio;
        !           506:   if (Iratio < 0)
        !           507:     if (IValve > -1500) IValve += Iratio;
        !           508: 
        !           509:   if (RValve >  2000) RValve =  2000;
        !           510:   if (RValve < -2000) RValve = -2000;
        !           511:   if (CValve >  1500) CValve =  1500;
        !           512:   if (CValve < -1500) CValve = -1500;
        !           513:   if (IValve >  1500) IValve =  1500;
        !           514:   if (IValve < -1500) IValve = -1500;
        !           515: 
        !           516:   if ((ResCap) && (RValve > 0)) RValve = 0;    /* Stad, Prt, Airprt  */
        !           517:   if ((ComCap) && (CValve > 0)) CValve = 0;
        !           518:   if ((IndCap) && (IValve > 0)) IValve = 0;
        !           519:   ValveFlag = 1;
        !           520: }
        !           521: 
        !           522: 
        !           523: /* comefrom: Simulate DoSimInit */
        !           524: ClearCensus(void)
        !           525: {
        !           526:   register short x, y, z;
        !           527: 
        !           528:   z = 0;
        !           529:   PwrdZCnt = z;
        !           530:   unPwrdZCnt = z;
        !           531:   FirePop = z;
        !           532:   RoadTotal = z;
        !           533:   RailTotal = z;
        !           534:   ResPop = z;
        !           535:   ComPop = z;
        !           536:   IndPop = z;
        !           537:   ResZPop = z;
        !           538:   ComZPop = z;
        !           539:   IndZPop = z;
        !           540:   HospPop = z;
        !           541:   ChurchPop = z;
        !           542:   PolicePop = z;
        !           543:   FireStPop = z;
        !           544:   StadiumPop = z;
        !           545:   CoalPop = z;
        !           546:   NuclearPop = z;
        !           547:   PortPop = z;
        !           548:   APortPop = z;
        !           549:   PowerStackNum = z;           /* Reset before Mapscan */
        !           550:   for (x = 0; x < SmX; x++)
        !           551:     for (y = 0; y < SmY; y++) {
        !           552:       FireStMap[x][y] = z;
        !           553:       PoliceMap[x][y] = z;
        !           554:     }
        !           555: }
        !           556: 
        !           557: 
        !           558: /* comefrom: Simulate */
        !           559: TakeCensus(void)
        !           560: {
        !           561:   short x;
        !           562: 
        !           563:   /* put census#s in Historical Graphs and scroll data  */
        !           564:   ResHisMax = 0;
        !           565:   ComHisMax = 0;
        !           566:   IndHisMax = 0;
        !           567:   for (x = 118; x >= 0; x--)   {
        !           568:     if ((ResHis[x + 1] = ResHis[x]) > ResHisMax) ResHisMax = ResHis[x];
        !           569:     if ((ComHis[x + 1] = ComHis[x]) > ComHisMax) ComHisMax = ComHis[x];
        !           570:     if ((IndHis[x + 1] = IndHis[x]) > IndHisMax) IndHisMax = IndHis[x];
        !           571:     CrimeHis[x + 1] = CrimeHis[x];
        !           572:     PollutionHis[x + 1] = PollutionHis[x];
        !           573:     MoneyHis[x + 1] = MoneyHis[x];
        !           574:   }
        !           575: 
        !           576:   Graph10Max = ResHisMax;
        !           577:   if (ComHisMax > Graph10Max) Graph10Max = ComHisMax;
        !           578:   if (IndHisMax > Graph10Max) Graph10Max = IndHisMax;
        !           579: 
        !           580:   ResHis[0] = ResPop / 8;
        !           581:   ComHis[0] = ComPop;
        !           582:   IndHis[0] = IndPop;
        !           583: 
        !           584:   CrimeRamp += (CrimeAverage - CrimeRamp) / 4;
        !           585:   CrimeHis[0] = CrimeRamp;
        !           586: 
        !           587:   PolluteRamp += (PolluteAverage - PolluteRamp) / 4;
        !           588:   PollutionHis[0] = PolluteRamp;
        !           589: 
        !           590:   x = (CashFlow / 20) + 128;   /* scale to 0..255  */
        !           591:   if (x < 0) x = 0;
        !           592:   if (x > 255) x = 255;
        !           593: 
        !           594:   MoneyHis[0] = x;
        !           595:   if (CrimeHis[0] > 255) CrimeHis[0] = 255;
        !           596:   if (PollutionHis[0] > 255) PollutionHis[0] = 255;
        !           597: 
        !           598:   ChangeCensus(); /* XXX: if 10 year graph view */
        !           599: 
        !           600:   if (HospPop < (ResPop >>8)) NeedHosp = TRUE;
        !           601:   if (HospPop > (ResPop >>8)) NeedHosp = -1;
        !           602:   if (HospPop == (ResPop >>8)) NeedHosp = FALSE;
        !           603: 
        !           604:   if (ChurchPop < (ResPop >>8)) NeedChurch = TRUE;
        !           605:   if (ChurchPop > (ResPop >>8)) NeedChurch = -1;
        !           606:   if (ChurchPop == (ResPop >>8)) NeedChurch = FALSE;
        !           607: }
        !           608: 
        !           609: 
        !           610: /* comefrom: Simulate */
        !           611: Take2Census(void)    /* Long Term Graphs */
        !           612: {
        !           613:   short x;
        !           614: 
        !           615:   Res2HisMax = 0;
        !           616:   Com2HisMax = 0;
        !           617:   Ind2HisMax = 0;
        !           618:   for (x = 238; x >= 120; x--) {
        !           619:     if ((ResHis[x + 1] = ResHis[x]) > Res2HisMax) Res2HisMax = ResHis[x];
        !           620:     if ((ComHis[x + 1] = ComHis[x]) > Com2HisMax) Com2HisMax = ComHis[x];
        !           621:     if ((IndHis[x + 1] = IndHis[x]) > Ind2HisMax) Ind2HisMax = IndHis[x];
        !           622:     CrimeHis[x + 1] = CrimeHis[x];
        !           623:     PollutionHis[x + 1] = PollutionHis[x];
        !           624:     MoneyHis[x + 1] = MoneyHis[x];
        !           625:   }
        !           626:   Graph120Max = Res2HisMax;
        !           627:   if (Com2HisMax > Graph120Max) Graph120Max = Com2HisMax;
        !           628:   if (Ind2HisMax > Graph120Max) Graph120Max = Ind2HisMax;
        !           629: 
        !           630:   ResHis[120] = ResPop / 8;
        !           631:   ComHis[120] = ComPop;
        !           632:   IndHis[120] = IndPop;
        !           633:   CrimeHis[120] = CrimeHis[0] ;
        !           634:   PollutionHis[120] = PollutionHis[0];
        !           635:   MoneyHis[120] = MoneyHis[0];
        !           636:   ChangeCensus(); /* XXX: if 120 year graph view */
        !           637: }
        !           638: 
        !           639: 
        !           640: /* comefrom: Simulate */
        !           641: CollectTax(void)
        !           642: {      
        !           643:   static float RLevels[3] = { 0.7, 0.9, 1.2 };
        !           644:   static float FLevels[3] = { 1.4, 1.2, 0.8 };
        !           645:   short z;
        !           646: 
        !           647:   CashFlow = 0;
        !           648:   if (!TaxFlag) { /* if the Tax Port is clear  */
        !           649:     /* XXX: do something with z */
        !           650:     z = AvCityTax / 48;  /* post */
        !           651:     AvCityTax = 0;                     
        !           652:     PoliceFund = PolicePop * 100;
        !           653:     FireFund   = FireStPop * 100;
        !           654:     RoadFund   = (RoadTotal + (RailTotal * 2)) * RLevels[GameLevel];
        !           655:     TaxFund = (((QUAD)TotalPop * LVAverage) / 120) *
        !           656:              CityTax * FLevels[GameLevel];
        !           657:     if (TotalPop) {    /* if there are people to tax  */
        !           658:       CashFlow = TaxFund - (PoliceFund + FireFund + RoadFund);
        !           659: 
        !           660:       DoBudget();
        !           661:     } else {
        !           662:       RoadEffect = 32;
        !           663:       PoliceEffect = 1000;
        !           664:       FireEffect = 1000;
        !           665:     }
        !           666:   }
        !           667: }
        !           668: 
        !           669: 
        !           670: UpdateFundEffects(void)
        !           671: {
        !           672:   if (RoadFund)
        !           673:     RoadEffect = (short)(((float)RoadSpend /
        !           674:                          (float)RoadFund) * 32.0);
        !           675:   else
        !           676:     RoadEffect = 32;
        !           677: 
        !           678:   if (PoliceFund)
        !           679:     PoliceEffect = (short)(((float)PoliceSpend /
        !           680:                            (float)PoliceFund) * 1000.0);
        !           681:   else
        !           682:     PoliceEffect = 1000;
        !           683: 
        !           684:   if (FireFund)
        !           685:     FireEffect = (short)(((float)FireSpend /
        !           686:                          (float)FireFund) * 1000.0);
        !           687:   else
        !           688:     FireEffect = 1000;
        !           689: 
        !           690:   drawCurrPercents();
        !           691: }
        !           692: 
        !           693: 
        !           694: /* comefrom: Simulate DoSimInit */
        !           695: MapScan(int x1, int x2)
        !           696: {
        !           697:   register short x, y;
        !           698: 
        !           699:   for (x = x1; x < x2; x++)  {
        !           700:     for (y = 0; y < WORLD_Y; y++) {
        !           701:       if (CChr = Map[x][y]) {
        !           702:        CChr9 = CChr & LOMASK;  /* Mask off status bits  */
        !           703:        if (CChr9 >= FLOOD) {
        !           704:          SMapX = x;
        !           705:          SMapY = y;
        !           706:          if (CChr9 < ROADBASE) {
        !           707:            if (CChr9 >= FIREBASE) {
        !           708:              FirePop++;
        !           709:              if (!(Rand16() & 3)) DoFire();    /* 1 in 4 times */
        !           710:              continue;
        !           711:            }
        !           712:            if (CChr9 < RADTILE)  DoFlood();
        !           713:            else DoRadTile();
        !           714:            continue;
        !           715:          }
        !           716: 
        !           717:          if (NewPower && (CChr & CONDBIT))
        !           718:            SetZPower();
        !           719: 
        !           720:          if ((CChr9 >= ROADBASE) &&
        !           721:              (CChr9 < POWERBASE)) {
        !           722:            DoRoad();
        !           723:            continue;
        !           724:          }
        !           725: 
        !           726:          if (CChr & ZONEBIT) { /* process Zones */
        !           727:            DoZone();
        !           728:            continue;
        !           729:          }
        !           730: 
        !           731:          if ((CChr9 >= RAILBASE) &&
        !           732:              (CChr9 < RESBASE)) {
        !           733:            DoRail();
        !           734:            continue;
        !           735:          }
        !           736:          if ((CChr9 >= SOMETINYEXP) &&
        !           737:              (CChr9 <= LASTTINYEXP))  /* clear AniRubble */
        !           738:            Map[x][y] = RUBBLE + (Rand16() & 3) + BULLBIT;
        !           739:        }
        !           740:       }
        !           741:     }
        !           742:   }
        !           743: }
        !           744: 
        !           745: 
        !           746: /* comefrom: MapScan */
        !           747: DoRail(void)
        !           748: {
        !           749:   RailTotal++;
        !           750:   GenerateTrain(SMapX, SMapY);
        !           751:   if (RoadEffect < 30) /* Deteriorating  Rail  */
        !           752:     if (!(Rand16() & 511))
        !           753:       if (!(CChr & CONDBIT))
        !           754:        if (RoadEffect < (Rand16() & 31)) {
        !           755:          if (CChr9 < (RAILBASE + 2))
        !           756:            Map[SMapX][SMapY] = RIVER;
        !           757:          else
        !           758:            Map[SMapX][SMapY] = RUBBLE + (Rand16() & 3) + BULLBIT;
        !           759:          return;
        !           760:        }
        !           761: }
        !           762: 
        !           763: 
        !           764: /* comefrom: MapScan */
        !           765: DoRadTile(void)
        !           766: {
        !           767:   if (!(Rand16() & 4095)) Map[SMapX][SMapY] = 0; /* Radioactive decay */
        !           768: }
        !           769: 
        !           770: 
        !           771: /* comefrom: MapScan */
        !           772: DoRoad(void)
        !           773: {
        !           774:   register short Density, tden, z;
        !           775:   static short DenTab[3] = { ROADBASE, LTRFBASE, HTRFBASE };
        !           776: 
        !           777:   RoadTotal++;
        !           778: /*  GenerateBus(SMapX, SMapY); */
        !           779:   if (RoadEffect < 30) /* Deteriorating Roads */
        !           780:     if (!(Rand16() & 511))
        !           781:       if (!(CChr & CONDBIT))
        !           782:        if (RoadEffect < (Rand16() & 31)) {
        !           783:          if (((CChr9 & 15) < 2) || ((CChr9 & 15) == 15))
        !           784:            Map[SMapX][SMapY] = RIVER;
        !           785:          else
        !           786:            Map[SMapX][SMapY] = RUBBLE + (Rand16() & 3) + BULLBIT;
        !           787:          return;
        !           788:        }
        !           789: 
        !           790:   if (!(CChr & BURNBIT)) { /* If Bridge */
        !           791:     RoadTotal += 4;                    
        !           792:     if (DoBridge())  return;
        !           793:   }
        !           794:   if (CChr9 < LTRFBASE) tden = 0;
        !           795:   else if (CChr9 < HTRFBASE) tden = 1;
        !           796:   else {
        !           797:     RoadTotal++;
        !           798:     tden = 2;
        !           799:   }
        !           800: 
        !           801:   Density = (TrfDensity[SMapX >>1][SMapY >>1]) >>6;  /* Set Traf Density  */
        !           802:   if (Density > 1) Density--;
        !           803:   if (tden != Density) { /* tden 0..2   */
        !           804:     z = ((CChr9 - ROADBASE) & 15) + DenTab[Density];
        !           805:     z += CChr & (ALLBITS - ANIMBIT);
        !           806:     if (Density) z += ANIMBIT;
        !           807:     Map[SMapX][SMapY] = z;
        !           808:   }
        !           809: }
        !           810: 
        !           811: 
        !           812: /* comefrom: MapScan */
        !           813: DoBridge(void)
        !           814: {
        !           815:   static short HDx[7] = { -2,  2, -2, -1,  0,  1,  2 };
        !           816:   static short HDy[7] = { -1, -1,  0,  0,  0,  0,  0 };
        !           817:   static short HBRTAB[7] = {
        !           818:     HBRDG1 | BULLBIT, HBRDG3 | BULLBIT, HBRDG0 | BULLBIT,
        !           819:     RIVER, BRWH | BULLBIT, RIVER, HBRDG2 | BULLBIT };
        !           820:   static short HBRTAB2[7] = {
        !           821:     RIVER, RIVER, HBRIDGE | BULLBIT, HBRIDGE | BULLBIT, HBRIDGE | BULLBIT,
        !           822:     HBRIDGE | BULLBIT, HBRIDGE | BULLBIT };
        !           823:   static short VDx[7] = {  0,  1,  0,  0,  0,  0,  1 };
        !           824:   static short VDy[7] = { -2, -2, -1,  0,  1,  2,  2 };
        !           825:   static short VBRTAB[7] = {
        !           826:     VBRDG0 | BULLBIT, VBRDG1 | BULLBIT, RIVER, BRWV | BULLBIT,
        !           827:     RIVER, VBRDG2 | BULLBIT, VBRDG3 | BULLBIT };
        !           828:   static short VBRTAB2[7] = {
        !           829:     VBRIDGE | BULLBIT, RIVER, VBRIDGE | BULLBIT, VBRIDGE | BULLBIT,
        !           830:     VBRIDGE | BULLBIT, VBRIDGE | BULLBIT, RIVER };
        !           831:   register z, x, y, MPtem;
        !           832: 
        !           833:   if (CChr9 == BRWV) { /*  Vertical bridge close */
        !           834:     if ((!(Rand16() & 3)) &&
        !           835:        (GetBoatDis() > 340))
        !           836:       for (z = 0; z < 7; z++) { /* Close  */
        !           837:        x = SMapX + VDx[z];
        !           838:        y = SMapY + VDy[z];
        !           839:        if (TestBounds(x, y))
        !           840:          if ((Map[x][y] & LOMASK) == (VBRTAB[z] & LOMASK))
        !           841:            Map[x][y] = VBRTAB2[z];
        !           842:       }
        !           843:     return (TRUE);
        !           844:   }
        !           845:   if (CChr9 == BRWH) { /*  Horizontal bridge close  */
        !           846:     if ((!(Rand16() & 3)) &&
        !           847:        (GetBoatDis() > 340))
        !           848:       for (z = 0; z < 7; z++) { /* Close  */
        !           849:        x = SMapX + HDx[z];
        !           850:        y = SMapY + HDy[z];
        !           851:        if (TestBounds(x, y))
        !           852:          if ((Map[x][y] & LOMASK) == (HBRTAB[z] & LOMASK))
        !           853:            Map[x][y] = HBRTAB2[z];
        !           854:       }
        !           855:     return (TRUE);
        !           856:   }
        !           857: 
        !           858:   if ((GetBoatDis() < 300) || (!(Rand16() & 7))) {
        !           859:     if (CChr9 & 1) {
        !           860:       if (SMapX < (WORLD_X - 1))
        !           861:        if (Map[SMapX + 1][SMapY] == CHANNEL) { /* Vertical open */
        !           862:          for (z = 0; z < 7; z++) {
        !           863:            x = SMapX + VDx[z];
        !           864:            y = SMapY + VDy[z];
        !           865:            if (TestBounds(x, y))  {
        !           866:              MPtem = Map[x][y];
        !           867:              if ((MPtem == CHANNEL) ||
        !           868:                  ((MPtem & 15) == (VBRTAB2[z] & 15)))
        !           869:                Map[x][y] = VBRTAB[z];
        !           870:            }
        !           871:          }
        !           872:          return (TRUE);
        !           873:        }
        !           874:       return (FALSE);
        !           875:     } else {
        !           876:       if (SMapY > 0)
        !           877:        if (Map[SMapX][SMapY - 1] == CHANNEL) { /* Horizontal open  */
        !           878:          for (z = 0; z < 7; z++) {
        !           879:            x = SMapX + HDx[z];
        !           880:            y = SMapY + HDy[z];
        !           881:            if (TestBounds(x, y)) {
        !           882:              MPtem = Map[x][y];
        !           883:              if (((MPtem & 15) == (HBRTAB2[z] & 15)) ||
        !           884:                  (MPtem == CHANNEL))
        !           885:                Map[x][y] = HBRTAB[z];
        !           886:            }
        !           887:          }
        !           888:          return (TRUE);
        !           889:        }
        !           890:       return (FALSE);
        !           891:     }
        !           892:   }
        !           893:   return (FALSE);
        !           894: }
        !           895: 
        !           896: 
        !           897: int
        !           898: GetBoatDis(void)
        !           899: {
        !           900:   register int dist, mx, my, dx, dy;
        !           901:   SimSprite *sprite;
        !           902: 
        !           903:   dist = 99999;
        !           904:   mx = (SMapX <<4) + 8;
        !           905:   my = (SMapY <<4) + 8;
        !           906: 
        !           907:   for (sprite = sim->sprite; sprite != NULL; sprite = sprite->next) {
        !           908:     if ((sprite->type == SHI) &&
        !           909:        (sprite->frame != 0)) {
        !           910:       if ((dx = sprite->x + sprite->x_hot - mx) < 0) dx = -dx;
        !           911:       if ((dy = sprite->y + sprite->y_hot - my) < 0) dy = -dy;
        !           912:       dx += dy;
        !           913:       if (dx < dist) dist = dx;
        !           914:     }
        !           915:   }
        !           916:   return (dist);
        !           917: }
        !           918: 
        !           919: 
        !           920: /* comefrom: MapScan */
        !           921: DoFire(void)
        !           922: {
        !           923:   static short DX[4] = { -1,  0,  1,  0 };
        !           924:   static short DY[4] = {  0, -1,  0,  1 };
        !           925:   register short z, Xtem, Ytem, Rate, c;
        !           926: 
        !           927:   for (z = 0; z < 4; z++) {
        !           928:     if (!(Rand16() & 7)) {
        !           929:       Xtem = SMapX + DX[z];
        !           930:       Ytem = SMapY + DY[z];
        !           931:       if (TestBounds(Xtem, Ytem)) {
        !           932:        c = Map[Xtem][Ytem];
        !           933:        if (c & BURNBIT) {
        !           934:          if (c & ZONEBIT) {
        !           935:            FireZone(Xtem, Ytem, c);
        !           936:            if ((c & LOMASK) > IZB)  { /*  Explode  */
        !           937:              MakeExplosionAt((Xtem <<4) + 8, (Ytem <<4) + 8);
        !           938:            }
        !           939:          }
        !           940:          Map[Xtem][Ytem] = FIRE + (Rand16() & 3) + ANIMBIT;
        !           941:        }
        !           942:       }
        !           943:     }
        !           944:   }
        !           945:   z = FireRate[SMapX >>3][SMapY >>3];
        !           946:   Rate = 10;
        !           947:   if (z) {
        !           948:     Rate = 3;
        !           949:     if (z > 20) Rate = 2;
        !           950:     if (z > 100) Rate = 1;
        !           951:   }
        !           952:   if (!Rand(Rate))
        !           953:     Map[SMapX][SMapY] = RUBBLE + (Rand16() & 3) + BULLBIT;
        !           954: }
        !           955: 
        !           956: 
        !           957: /* comefrom: DoFire MakeFlood */
        !           958: FireZone(int Xloc, int Yloc, int ch)
        !           959: {
        !           960:   register short Xtem, Ytem;
        !           961:   short x, y, XYmax;
        !           962: 
        !           963:   RateOGMem[Xloc >>3][Yloc >>3] -= 20;
        !           964: 
        !           965:   ch = ch & LOMASK;
        !           966:   if (ch < PORTBASE)
        !           967:     XYmax = 2;
        !           968:   else
        !           969:     if (ch == AIRPORT)
        !           970:       XYmax = 5;
        !           971:     else
        !           972:       XYmax = 4;
        !           973: 
        !           974:   for (x = -1; x < XYmax; x++)
        !           975:     for (y = -1; y < XYmax; y++) {
        !           976:       Xtem = Xloc + x;
        !           977:       Ytem = Yloc + y;
        !           978:       if ((Xtem < 0) || (Xtem > (WORLD_X - 1)) ||
        !           979:          (Ytem < 0) || (Ytem > (WORLD_Y - 1)))
        !           980:        continue;
        !           981:       if ((short)(Map[Xtem][Ytem] & LOMASK) >= ROADBASE) /* post release */
        !           982:        Map[Xtem][Ytem] |= BULLBIT;
        !           983:     }
        !           984: }
        !           985: 
        !           986: 
        !           987: /* comefrom: DoSPZone DoHospChur */
        !           988: RepairZone(short ZCent, short zsize)
        !           989: {
        !           990:   short cnt;
        !           991:   register short x, y, ThCh;
        !           992: 
        !           993:   zsize--;
        !           994:   cnt = 0;
        !           995:   for (y = -1; y < zsize; y++)
        !           996:     for (x = -1; x < zsize; x++) {
        !           997:       int xx = SMapX + x;
        !           998:       int yy = SMapY + y;
        !           999:       cnt++;
        !          1000:       if (TestBounds(xx, yy)) {
        !          1001:        ThCh = Map[xx][yy];
        !          1002:        if (ThCh & ZONEBIT) continue;
        !          1003:        if (ThCh & ANIMBIT) continue;
        !          1004:        ThCh = ThCh & LOMASK;
        !          1005:        if ((ThCh < RUBBLE) || (ThCh >= ROADBASE)) {
        !          1006:          Map[xx][yy] = ZCent - 3 - zsize + cnt + CONDBIT + BURNBIT;
        !          1007:        }
        !          1008:       }
        !          1009:     }
        !          1010: }
        !          1011: 
        !          1012: 
        !          1013: /* comefrom: DoZone */
        !          1014: DoSPZone(short PwrOn)
        !          1015: {
        !          1016:   static short MltdwnTab[3] = { 30000, 20000, 10000 };  /* simadj */
        !          1017:   register z;
        !          1018: 
        !          1019:   switch (CChr9) {
        !          1020: 
        !          1021:   case POWERPLANT:
        !          1022:     CoalPop++;
        !          1023:     if (!(CityTime & 7))
        !          1024:       RepairZone(POWERPLANT, 4); /* post */
        !          1025:     PushPowerStack();
        !          1026:     CoalSmoke(SMapX, SMapY);
        !          1027:     return;
        !          1028: 
        !          1029:   case NUCLEAR:
        !          1030:     if (!NoDisasters && !Rand(MltdwnTab[GameLevel])) {
        !          1031:       DoMeltdown(SMapX, SMapY);
        !          1032:       return;
        !          1033:     }
        !          1034:     NuclearPop++;
        !          1035:     if (!(CityTime & 7))
        !          1036:       RepairZone(NUCLEAR, 4); /* post */
        !          1037:     PushPowerStack();
        !          1038:     return;
        !          1039: 
        !          1040:   case FIRESTATION:
        !          1041:     FireStPop++;
        !          1042:     if (!(CityTime & 7))
        !          1043:       RepairZone(FIRESTATION, 3); /* post */
        !          1044: 
        !          1045:     if (PwrOn)
        !          1046:       z = FireEffect;                  /* if powered get effect  */
        !          1047:     else
        !          1048:       z = FireEffect >>1;              /* from the funding ratio  */
        !          1049: 
        !          1050:     if (!FindPRoad())
        !          1051:       z = z >>1;                       /* post FD's need roads  */
        !          1052: 
        !          1053:     FireStMap[SMapX >>3][SMapY >>3] += z;
        !          1054:     return;
        !          1055: 
        !          1056:   case POLICESTATION:
        !          1057:     PolicePop++;
        !          1058:     if (!(CityTime & 7))
        !          1059:       RepairZone(POLICESTATION, 3); /* post */
        !          1060: 
        !          1061:     if (PwrOn)
        !          1062:       z = PoliceEffect;
        !          1063:     else
        !          1064:       z = PoliceEffect >>1;
        !          1065: 
        !          1066:     if (!FindPRoad())
        !          1067:       z = z >>1; /* post PD's need roads */
        !          1068: 
        !          1069:     PoliceMap[SMapX >>3][SMapY >>3] += z;
        !          1070:     return;
        !          1071: 
        !          1072:   case STADIUM:
        !          1073:     StadiumPop++;
        !          1074:     if (!(CityTime & 15))
        !          1075:       RepairZone(STADIUM, 4);
        !          1076:     if (PwrOn)
        !          1077:       if (!((CityTime + SMapX + SMapY) & 31)) {        /* post release */
        !          1078:        DrawStadium(FULLSTADIUM);
        !          1079:        Map[SMapX + 1][SMapY] = FOOTBALLGAME1 + ANIMBIT;
        !          1080:        Map[SMapX + 1][SMapY + 1] = FOOTBALLGAME2 + ANIMBIT;
        !          1081:       }
        !          1082:     return;
        !          1083: 
        !          1084:  case FULLSTADIUM:
        !          1085:     StadiumPop++;
        !          1086:     if (!((CityTime + SMapX + SMapY) & 7))     /* post release */
        !          1087:       DrawStadium(STADIUM);
        !          1088:     return;
        !          1089: 
        !          1090:  case AIRPORT:
        !          1091:     APortPop++;
        !          1092:     if (!(CityTime & 7))
        !          1093:       RepairZone(AIRPORT, 6);
        !          1094: 
        !          1095:     if (PwrOn) { /* post */
        !          1096:       if ((Map[SMapX + 1][SMapY - 1] & LOMASK) == RADAR)
        !          1097:        Map[SMapX + 1][SMapY - 1] = RADAR + ANIMBIT + CONDBIT + BURNBIT;
        !          1098:     } else
        !          1099:       Map[SMapX + 1][SMapY - 1] = RADAR + CONDBIT + BURNBIT;
        !          1100: 
        !          1101:     if (PwrOn)
        !          1102:       DoAirport();
        !          1103:     return;
        !          1104: 
        !          1105:  case PORT:
        !          1106:     PortPop++;
        !          1107:     if ((CityTime & 15) == 0) {
        !          1108:       RepairZone(PORT, 4);
        !          1109:     }
        !          1110:     if (PwrOn &&
        !          1111:        (GetSprite(SHI) == NULL)) {
        !          1112:       GenerateShip();
        !          1113:     }
        !          1114:     return;
        !          1115:   }
        !          1116: }
        !          1117: 
        !          1118: 
        !          1119: /* comefrom: DoSPZone */
        !          1120: DrawStadium(int z)
        !          1121: {
        !          1122:   register int x, y;
        !          1123: 
        !          1124:   z = z - 5;
        !          1125:   for (y = (SMapY - 1); y < (SMapY + 3); y++)
        !          1126:     for (x = (SMapX - 1); x < (SMapX + 3); x++)
        !          1127:       Map[x][y] = (z++) | BNCNBIT;
        !          1128:   Map[SMapX][SMapY] |= ZONEBIT | PWRBIT;
        !          1129: }
        !          1130: 
        !          1131: 
        !          1132: /* comefrom: DoSPZone */
        !          1133: DoAirport(void)
        !          1134: {
        !          1135:   if (!(Rand(5))) {
        !          1136:     GeneratePlane(SMapX, SMapY);
        !          1137:     return;
        !          1138:   }
        !          1139:   if (!(Rand(12)))
        !          1140:     GenerateCopter(SMapX, SMapY);
        !          1141: }
        !          1142: 
        !          1143: 
        !          1144: /* comefrom: DoSPZone */
        !          1145: CoalSmoke(int mx, int my)
        !          1146: {
        !          1147:   static short SmTb[4] = { COALSMOKE1, COALSMOKE2, COALSMOKE3, COALSMOKE4 };
        !          1148:   static short dx[4] = {  1,  2,  1,  2 };
        !          1149:   static short dy[4] = { -1, -1,  0,  0 };
        !          1150:   register short x;
        !          1151: 
        !          1152:   for (x = 0; x < 4; x++)
        !          1153:     Map[mx + dx[x]][my + dy[x]] =
        !          1154:       SmTb[x] | ANIMBIT | CONDBIT | PWRBIT | BURNBIT;
        !          1155: }
        !          1156: 
        !          1157: 
        !          1158: /* comefrom: DoSPZone MakeMeltdown */
        !          1159: DoMeltdown(int SX, int SY)
        !          1160: {
        !          1161:   register x, y, z, t;
        !          1162: 
        !          1163:   MeltX = SX; MeltY = SY;
        !          1164: 
        !          1165:   MakeExplosion(SX - 1, SY - 1);
        !          1166:   MakeExplosion(SX - 1, SY + 2);
        !          1167:   MakeExplosion(SX + 2, SY - 1);
        !          1168:   MakeExplosion(SX + 2, SY + 2);
        !          1169: 
        !          1170:   for (x = (SX - 1); x < (SX + 3); x++)
        !          1171:     for (y = (SY - 1); y < (SY + 3); y++)
        !          1172:       Map[x][y] = FIRE + (Rand16() & 3) + ANIMBIT;
        !          1173: 
        !          1174:   for (z = 0; z < 200; z++)  {
        !          1175:     x = SX - 20 + Rand(40);
        !          1176:     y = SY - 15 + Rand(30);
        !          1177:     if ((x < 0) || (x >= WORLD_X) ||
        !          1178:        (y < 0) || (y >= WORLD_Y))
        !          1179:       continue;
        !          1180:     t = Map[x][y];
        !          1181:     if (t & ZONEBIT)
        !          1182:       continue;
        !          1183:     if ((t & BURNBIT) || (t == 0))
        !          1184:       Map[x][y] = RADTILE;
        !          1185:   }
        !          1186: 
        !          1187:   ClearMes();
        !          1188:   SendMesAt(-43, SX, SY);
        !          1189: }
        !          1190: 
        !          1191: 
        !          1192: #define RANDOM_RANGE 0xffff
        !          1193: 
        !          1194: short
        !          1195: Rand(short range)
        !          1196: {
        !          1197:   int maxMultiple, rnum;
        !          1198: 
        !          1199:   range++;
        !          1200:   maxMultiple = RANDOM_RANGE / range;
        !          1201:   maxMultiple *= range;
        !          1202:   while ((rnum = Rand16()) >= maxMultiple)
        !          1203:     continue;
        !          1204:   return (rnum % range);
        !          1205: }
        !          1206: 
        !          1207: 
        !          1208: int
        !          1209: Rand16(void)
        !          1210: {
        !          1211:   return (sim_rand());
        !          1212: }
        !          1213: 
        !          1214: 
        !          1215: int
        !          1216: Rand16Signed(void)
        !          1217: {
        !          1218:   int i = sim_rand();
        !          1219: 
        !          1220:   if (i > 32767) {
        !          1221:     i = 32767 - i;
        !          1222:   }
        !          1223:   return (i);
        !          1224: }
        !          1225: 
        !          1226: 
        !          1227: RandomlySeedRand()
        !          1228: {
        !          1229:   struct timeval time;
        !          1230: 
        !          1231:   gettimeofday(&time, NULL);
        !          1232: 
        !          1233:   SeedRand(time.tv_usec ^ time.tv_sec ^ sim_rand());
        !          1234: }
        !          1235: 
        !          1236: 
        !          1237: SeedRand(int seed)
        !          1238: {
        !          1239:   sim_srand(seed);
        !          1240: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.