Annotation of micropolis/src/sim/s_sim.c, revision 1.1.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.