|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.