|
|
1.1 ! root 1: /* w_tool.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: short specialBase = CHURCH; ! 66: int OverRide = 0; ! 67: int Expensive = 1000; ! 68: int Players = 1; ! 69: int Votes = 0; ! 70: int PendingTool = -1; ! 71: int PendingX; ! 72: int PendingY; ! 73: ! 74: ! 75: QUAD CostOf[] = { ! 76: 100, 100, 100, 500, ! 77: 0, 500, 5, 1, ! 78: 20, 10, 0, 0, ! 79: 5000, 10, 3000, 3000, ! 80: 5000, 10000, 100, 0, ! 81: }; ! 82: ! 83: ! 84: short toolSize[] = { ! 85: 3, 3, 3, 3, ! 86: 1, 3, 1, 1, ! 87: 1, 1, 0, 0, ! 88: 4, 1, 4, 4, ! 89: 4, 6, 1, 0, ! 90: }; ! 91: ! 92: ! 93: short toolOffset[] = { ! 94: 1, 1, 1, 1, ! 95: 0, 1, 0, 0, ! 96: 0, 0, 0, 0, ! 97: 1, 0, 1, 1, ! 98: 1, 1, 0, 0, ! 99: }; ! 100: ! 101: ! 102: QUAD toolColors[] = { ! 103: COLOR_LIGHTGREEN | (COLOR_LIGHTGREEN << 8), /* residentialState */ ! 104: COLOR_LIGHTBLUE | (COLOR_LIGHTBLUE << 8), /* commercialState */ ! 105: COLOR_YELLOW | (COLOR_YELLOW << 8), /* industrialState */ ! 106: COLOR_LIGHTGREEN | (COLOR_RED << 8), /* fireState */ ! 107: COLOR_ORANGE | (COLOR_ORANGE << 8), /* queryState */ ! 108: COLOR_LIGHTGREEN | (COLOR_LIGHTBLUE << 8), /* policeState */ ! 109: COLOR_DARKGRAY | (COLOR_YELLOW << 8), /* wireState */ ! 110: COLOR_LIGHTBROWN | (COLOR_LIGHTBROWN << 8), /* dozeState */ ! 111: COLOR_DARKGRAY | (COLOR_OLIVE << 8), /* rrState */ ! 112: COLOR_DARKGRAY | (COLOR_WHITE << 8), /* roadState */ ! 113: COLOR_LIGHTGRAY | (COLOR_LIGHTGRAY << 8), /* chalkState */ ! 114: COLOR_DARKGRAY | (COLOR_DARKGRAY << 8), /* eraserState */ ! 115: COLOR_LIGHTGRAY | (COLOR_LIGHTGREEN << 8), /* stadiumState */ ! 116: COLOR_LIGHTBROWN | (COLOR_LIGHTGREEN << 8), /* parkState */ ! 117: COLOR_LIGHTGRAY | (COLOR_LIGHTBLUE << 8), /* seaportState */ ! 118: COLOR_LIGHTGRAY | (COLOR_YELLOW << 8), /* powerState */ ! 119: COLOR_LIGHTGRAY | (COLOR_YELLOW << 8), /* nuclearState */ ! 120: COLOR_LIGHTGRAY | (COLOR_LIGHTBROWN << 8), /* airportState */ ! 121: COLOR_LIGHTGRAY | (COLOR_RED << 8), /* networkState */ ! 122: }; ! 123: ! 124: ! 125: Ink *NewInk(); ! 126: ! 127: short tally(short tileValue); ! 128: int DoSetWandState(SimView *view, short state); ! 129: ! 130: ! 131: /*************************************************************************/ ! 132: /* UTILITIES */ ! 133: ! 134: ! 135: setWandState(SimView *view, short state) ! 136: { ! 137: #if 0 ! 138: if (state < 0) { ! 139: specialBase = -state; ! 140: state = specialState; ! 141: } ! 142: #endif ! 143: ! 144: view->tool_state = state; ! 145: DoUpdateHeads(); ! 146: DoSetWandState(view, state); ! 147: } ! 148: ! 149: ! 150: int ! 151: putDownPark(SimView *view, short mapH, short mapV) ! 152: { ! 153: short value, tile; ! 154: ! 155: if (TotalFunds - CostOf[parkState] >= 0) { ! 156: value = Rand(4); ! 157: ! 158: if (value == 4) ! 159: tile = FOUNTAIN | BURNBIT | BULLBIT | ANIMBIT; ! 160: else ! 161: tile = (value + WOODS2) | BURNBIT | BULLBIT; ! 162: ! 163: if (Map[mapH][mapV] == 0) { ! 164: Spend(CostOf[parkState]); ! 165: UpdateFunds(); ! 166: Map[mapH][mapV] = tile; ! 167: return 1; ! 168: } ! 169: return -1; ! 170: } ! 171: return -2; ! 172: } ! 173: ! 174: ! 175: int ! 176: putDownNetwork(SimView *view, short mapH, short mapV) ! 177: { ! 178: int tile = Map[mapH][mapV] & LOMASK; ! 179: ! 180: if ((TotalFunds > 0) && tally(tile)) { ! 181: Map[mapH][mapV] = tile = 0; ! 182: Spend(1); ! 183: } ! 184: ! 185: if (tile == 0) { ! 186: if ((TotalFunds - CostOf[view->tool_state]) >= 0) { ! 187: Map[mapH][mapV] = TELEBASE | CONDBIT | BURNBIT | BULLBIT | ANIMBIT; ! 188: Spend(CostOf[view->tool_state]); ! 189: return 1; ! 190: } else { ! 191: return -2; ! 192: } ! 193: } else { ! 194: return -1; ! 195: } ! 196: } ! 197: ! 198: ! 199: short ! 200: checkBigZone(short id, short *deltaHPtr, short *deltaVPtr) ! 201: { ! 202: switch (id) { ! 203: case POWERPLANT: /* check coal plant */ ! 204: case PORT: /* check sea port */ ! 205: case NUCLEAR: /* check nuc plant */ ! 206: case STADIUM: /* check stadium */ ! 207: *deltaHPtr = 0; *deltaVPtr = 0; return (4); ! 208: ! 209: case POWERPLANT + 1: /* check coal plant */ ! 210: case COALSMOKE3: /* check coal plant, smoke */ ! 211: case COALSMOKE3 + 1: /* check coal plant, smoke */ ! 212: case COALSMOKE3 + 2: /* check coal plant, smoke */ ! 213: case PORT + 1: /* check sea port */ ! 214: case NUCLEAR + 1: /* check nuc plant */ ! 215: case STADIUM + 1: /* check stadium */ ! 216: *deltaHPtr = -1; *deltaVPtr = 0; return (4); ! 217: ! 218: case POWERPLANT + 4: /* check coal plant */ ! 219: case PORT + 4: /* check sea port */ ! 220: case NUCLEAR + 4: /* check nuc plant */ ! 221: case STADIUM + 4: /* check stadium */ ! 222: *deltaHPtr = 0; *deltaVPtr = -1; return (4); ! 223: ! 224: case POWERPLANT + 5: /* check coal plant */ ! 225: case PORT + 5: /* check sea port */ ! 226: case NUCLEAR + 5: /* check nuc plant */ ! 227: case STADIUM + 5: /* check stadium */ ! 228: *deltaHPtr = -1; *deltaVPtr = -1; return (4); ! 229: ! 230: /* check airport */ ! 231: /*** first row ***/ ! 232: case AIRPORT: ! 233: *deltaHPtr = 0; *deltaVPtr = 0; return (6); ! 234: case AIRPORT + 1: ! 235: *deltaHPtr = -1; *deltaVPtr = 0; return (6); ! 236: case AIRPORT + 2: ! 237: *deltaHPtr = -2; *deltaVPtr = 0; return (6); ! 238: case AIRPORT + 3: ! 239: *deltaHPtr = -3; *deltaVPtr = 0; return (6); ! 240: ! 241: /*** second row ***/ ! 242: case AIRPORT + 6: ! 243: *deltaHPtr = 0; *deltaVPtr = -1; return (6); ! 244: case AIRPORT + 7: ! 245: *deltaHPtr = -1; *deltaVPtr = -1; return (6); ! 246: case AIRPORT + 8: ! 247: *deltaHPtr = -2; *deltaVPtr = -1; return (6); ! 248: case AIRPORT + 9: ! 249: *deltaHPtr = -3; *deltaVPtr = -1; return (6); ! 250: ! 251: /*** third row ***/ ! 252: case AIRPORT + 12: ! 253: *deltaHPtr = 0; *deltaVPtr = -2; return (6); ! 254: case AIRPORT + 13: ! 255: *deltaHPtr = -1; *deltaVPtr = -2; return (6); ! 256: case AIRPORT + 14: ! 257: *deltaHPtr = -2; *deltaVPtr = -2; return (6); ! 258: case AIRPORT + 15: ! 259: *deltaHPtr = -3; *deltaVPtr = -2; return (6); ! 260: ! 261: /*** fourth row ***/ ! 262: case AIRPORT + 18: ! 263: *deltaHPtr = 0; *deltaVPtr = -3; return (6); ! 264: case AIRPORT + 19: ! 265: *deltaHPtr = -1; *deltaVPtr = -3; return (6); ! 266: case AIRPORT + 20: ! 267: *deltaHPtr = -2; *deltaVPtr = -3; return (6); ! 268: case AIRPORT + 21: ! 269: *deltaHPtr = -3; *deltaVPtr = -3; return (6); ! 270: ! 271: default: ! 272: *deltaHPtr = 0; *deltaVPtr = 0; return (0); ! 273: } ! 274: } ! 275: ! 276: ! 277: short ! 278: tally(short tileValue) ! 279: { ! 280: /* can we autobulldoze this tile? */ ! 281: if (((tileValue >= FIRSTRIVEDGE) && ! 282: (tileValue <= LASTRUBBLE)) || ! 283: ((tileValue >= (POWERBASE + 2)) && ! 284: (tileValue <= (POWERBASE + 12))) || ! 285: ((tileValue >= TINYEXP) && ! 286: (tileValue <= (LASTTINYEXP + 2)))) { /* ??? */ ! 287: return (1); ! 288: } else { ! 289: return (0); ! 290: } ! 291: } ! 292: ! 293: ! 294: short ! 295: checkSize(short temp) ! 296: { ! 297: /* check for the normal com, resl, ind 3x3 zones & the fireDept & PoliceDept */ ! 298: if (((temp >= (RESBASE - 1)) && (temp <= (PORTBASE - 1))) || ! 299: ((temp >= (LASTPOWERPLANT + 1)) && (temp <= (POLICESTATION + 4)))) { ! 300: return (3); ! 301: } else if (((temp >= PORTBASE) && (temp <= LASTPORT)) || ! 302: ((temp >= COALBASE) && (temp <= LASTPOWERPLANT)) || ! 303: ((temp >= STADIUMBASE) && (temp <= LASTZONE))) { ! 304: return (4); ! 305: } ! 306: return (0); ! 307: } ! 308: ! 309: ! 310: /* 3x3 */ ! 311: ! 312: ! 313: void ! 314: check3x3border(short xMap, short yMap) ! 315: { ! 316: short xPos, yPos; ! 317: short cnt; ! 318: ! 319: xPos = xMap; yPos = yMap - 1; ! 320: for (cnt = 0; cnt < 3; cnt++) { ! 321: /*** this will do the upper bordering row ***/ ! 322: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 323: xPos++; ! 324: } ! 325: ! 326: xPos = xMap - 1; yPos = yMap; ! 327: for (cnt = 0; cnt < 3; cnt++) { ! 328: /*** this will do the left bordering row ***/ ! 329: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 330: yPos++; ! 331: } ! 332: ! 333: xPos = xMap; yPos = yMap + 3; ! 334: for (cnt = 0; cnt < 3; cnt++) { ! 335: /*** this will do the bottom bordering row ***/ ! 336: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 337: xPos++; ! 338: } ! 339: ! 340: xPos = xMap + 3; yPos = yMap; ! 341: for (cnt = 0; cnt < 3; cnt++) { ! 342: /*** this will do the right bordering row ***/ ! 343: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 344: yPos++; ! 345: } ! 346: } ! 347: ! 348: ! 349: int ! 350: check3x3(SimView *view, short mapH, short mapV, short base, short tool) ! 351: { ! 352: register short rowNum, columnNum; ! 353: register short holdMapH, holdMapV; ! 354: short xPos, yPos; ! 355: short cost = 0; ! 356: short tileValue; ! 357: short flag; ! 358: ! 359: mapH--; mapV--; ! 360: if ((mapH < 0) || (mapH > (WORLD_X - 3)) || ! 361: (mapV < 0) || (mapV > (WORLD_Y - 3))) { ! 362: return -1; ! 363: } ! 364: ! 365: xPos = holdMapH = mapH; ! 366: yPos = holdMapV = mapV; ! 367: ! 368: flag = 1; ! 369: ! 370: for (rowNum = 0; rowNum <= 2; rowNum++) { ! 371: mapH = holdMapH; ! 372: ! 373: for (columnNum = 0; columnNum <= 2; columnNum++) { ! 374: tileValue = Map[mapH++][mapV] & LOMASK; ! 375: ! 376: if (autoBulldoze) { ! 377: /* if autoDoze is enabled, add up the cost of bulldozed tiles */ ! 378: if (tileValue != 0) { ! 379: if (tally(tileValue)) { ! 380: cost++; ! 381: } else { ! 382: flag = 0; ! 383: } ! 384: } ! 385: } else { ! 386: /* check and see if the tile is clear or not */ ! 387: if (tileValue != 0) { ! 388: flag = 0; ! 389: } ! 390: } ! 391: } ! 392: mapV++; ! 393: } ! 394: ! 395: if (flag == 0) { ! 396: return -1; ! 397: } ! 398: ! 399: cost += CostOf[tool]; ! 400: ! 401: if ((TotalFunds - cost) < 0) { ! 402: return -2; ! 403: } ! 404: ! 405: if ((Players > 1) && ! 406: (OverRide == 0) && ! 407: (cost >= Expensive) && ! 408: (view != NULL) && ! 409: (view->super_user == 0)) { ! 410: return -3; ! 411: } ! 412: ! 413: /* take care of the money situtation here */ ! 414: Spend(cost); ! 415: UpdateFunds(); ! 416: ! 417: mapV = holdMapV; ! 418: ! 419: for (rowNum = 0; rowNum <= 2; rowNum++) { ! 420: mapH = holdMapH; ! 421: ! 422: for (columnNum = 0; columnNum <= 2; columnNum++) { ! 423: if (columnNum == 1 && rowNum == 1) { ! 424: Map[mapH++][mapV] = base + BNCNBIT + ZONEBIT; ! 425: } else { ! 426: Map[mapH++][mapV] = base + BNCNBIT; ! 427: } ! 428: base++; ! 429: } ! 430: mapV++; ! 431: } ! 432: check3x3border(xPos, yPos); ! 433: return 1; ! 434: } ! 435: ! 436: ! 437: /* 4x4 */ ! 438: ! 439: ! 440: void ! 441: check4x4border(short xMap, short yMap) ! 442: { ! 443: Ptr tilePtr; ! 444: short xPos, yPos; ! 445: short cnt; ! 446: ! 447: xPos = xMap; yPos = yMap - 1; ! 448: for (cnt = 0; cnt < 4; cnt++) { ! 449: /* this will do the upper bordering row */ ! 450: tilePtr = (Ptr) &Map[xPos][yPos]; ! 451: ConnecTile(xPos, yPos, tilePtr, 0); ! 452: xPos++; ! 453: } ! 454: ! 455: xPos = xMap - 1; yPos = yMap; ! 456: for (cnt = 0; cnt < 4; cnt++) { ! 457: /* this will do the left bordering row */ ! 458: tilePtr = (Ptr) &Map[xPos][yPos]; ! 459: ConnecTile(xPos, yPos, tilePtr, 0); ! 460: yPos++; ! 461: } ! 462: ! 463: xPos = xMap; yPos = yMap + 4; ! 464: for (cnt = 0; cnt < 4;cnt++) { ! 465: /* this will do the bottom bordering row */ ! 466: tilePtr = (Ptr) &Map[xPos][yPos]; ! 467: ConnecTile(xPos, yPos, tilePtr, 0); ! 468: xPos++; ! 469: } ! 470: ! 471: xPos = xMap + 4; yPos = yMap; ! 472: for (cnt = 0; cnt < 4; cnt++) { ! 473: /* this will do the right bordering row */ ! 474: tilePtr = (Ptr) &Map[xPos][yPos]; ! 475: ConnecTile(xPos, yPos, tilePtr, 0); ! 476: yPos++; ! 477: } ! 478: } ! 479: ! 480: ! 481: short ! 482: check4x4(SimView *view, short mapH, short mapV, ! 483: short base, short aniFlag, short tool) ! 484: { ! 485: register short rowNum, columnNum; ! 486: short h, v; ! 487: short holdMapH; ! 488: short xMap, yMap; ! 489: short tileValue; ! 490: short flag; ! 491: short cost = 0; ! 492: ! 493: mapH--; mapV--; ! 494: if ((mapH < 0) || (mapH > (WORLD_X - 4)) || ! 495: (mapV < 0) || (mapV > (WORLD_Y - 4))) { ! 496: return -1; ! 497: } ! 498: ! 499: h = xMap = holdMapH = mapH; ! 500: v = yMap = mapV; ! 501: ! 502: flag = 1; ! 503: ! 504: for (rowNum = 0; rowNum <= 3; rowNum++) { ! 505: mapH = holdMapH; ! 506: ! 507: for (columnNum = 0; columnNum <= 3; columnNum++) { ! 508: tileValue = Map[mapH++][mapV] & LOMASK; ! 509: ! 510: if (autoBulldoze) { ! 511: /* if autoDoze is enabled, add up the cost of bulldozed tiles */ ! 512: if (tileValue != 0) { ! 513: if (tally(tileValue)) { ! 514: cost++; ! 515: } else { ! 516: flag = 0; ! 517: } ! 518: } ! 519: } else { ! 520: /* check and see if the tile is clear or not */ ! 521: if (tileValue != 0) { ! 522: flag = 0; ! 523: } ! 524: } ! 525: } ! 526: mapV++; ! 527: } ! 528: ! 529: if (flag == 0) { ! 530: return -1; ! 531: } ! 532: ! 533: cost += CostOf[tool]; ! 534: ! 535: if ((TotalFunds - cost) < 0) { ! 536: return -2; ! 537: } ! 538: ! 539: if ((Players > 1) && ! 540: (OverRide == 0) && ! 541: (cost >= Expensive) && ! 542: (view != NULL) && ! 543: (view->super_user == 0)) { ! 544: return -3; ! 545: } ! 546: ! 547: /* take care of the money situtation here */ ! 548: Spend(cost); ! 549: UpdateFunds(); ! 550: ! 551: mapV = v; holdMapH = h; ! 552: ! 553: for (rowNum = 0; rowNum <= 3; rowNum++) { ! 554: mapH = holdMapH; ! 555: ! 556: for (columnNum = 0; columnNum <= 3; columnNum++) { ! 557: if (columnNum == 1 && rowNum == 1) ! 558: Map[mapH++][mapV] = base + BNCNBIT + ZONEBIT; ! 559: else if (columnNum == 1 && rowNum == 2 && aniFlag) ! 560: Map[mapH++][mapV] = base + BNCNBIT + ANIMBIT; ! 561: else ! 562: Map[mapH++][mapV] = base + BNCNBIT; ! 563: base++; ! 564: } ! 565: mapV++; ! 566: } ! 567: check4x4border(xMap, yMap); ! 568: return 1; ! 569: } ! 570: ! 571: ! 572: /* 6x6 */ ! 573: ! 574: ! 575: void ! 576: check6x6border(short xMap, short yMap) ! 577: { ! 578: short xPos, yPos; ! 579: short cnt; ! 580: ! 581: xPos = xMap; yPos = yMap - 1; ! 582: for (cnt = 0; cnt < 6; cnt++) { ! 583: /* this will do the upper bordering row */ ! 584: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 585: xPos++; ! 586: } ! 587: ! 588: xPos = xMap - 1; yPos = yMap; ! 589: for (cnt=0; cnt < 6; cnt++) { ! 590: /* this will do the left bordering row */ ! 591: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 592: yPos++; ! 593: } ! 594: ! 595: xPos = xMap; yPos = yMap + 6; ! 596: for (cnt = 0; cnt < 6; cnt++) { ! 597: /* this will do the bottom bordering row */ ! 598: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 599: xPos++; ! 600: } ! 601: ! 602: xPos = xMap + 6; yPos = yMap; ! 603: for (cnt = 0; cnt < 6; cnt++) { ! 604: /* this will do the right bordering row */ ! 605: ConnecTile(xPos, yPos, &Map[xPos][yPos], 0); ! 606: yPos++; ! 607: } ! 608: } ! 609: ! 610: ! 611: short ! 612: check6x6(SimView *view, short mapH, short mapV, short base, short tool) ! 613: { ! 614: register short rowNum, columnNum; ! 615: short h, v; ! 616: short holdMapH; ! 617: short xMap, yMap; ! 618: short flag; ! 619: short tileValue; ! 620: short cost = 0; ! 621: ! 622: mapH--; mapV--; ! 623: if ((mapH < 0) || (mapH > (WORLD_X - 6)) || ! 624: (mapV < 0) || (mapV > (WORLD_Y - 6))) ! 625: return -1; ! 626: ! 627: h = xMap = holdMapH = mapH; ! 628: v = yMap = mapV; ! 629: ! 630: flag = 1; ! 631: ! 632: for (rowNum = 0; rowNum <= 5; rowNum++) { ! 633: mapH = holdMapH; ! 634: ! 635: for (columnNum = 0; columnNum <= 5; columnNum++) { ! 636: tileValue = Map[mapH++][mapV] & LOMASK; ! 637: ! 638: if (autoBulldoze) { ! 639: /* if autoDoze is enabled, add up the cost of bulldozed tiles */ ! 640: if (tileValue != 0) ! 641: if (tally(tileValue)) { ! 642: cost++; ! 643: } else { ! 644: flag = 0; ! 645: } ! 646: } else { ! 647: /* check and see if the tile is clear or not */ ! 648: if (tileValue != 0) { ! 649: flag = 0; ! 650: } ! 651: } ! 652: } ! 653: mapV++; ! 654: } ! 655: ! 656: if (flag == 0) { ! 657: return -1; ! 658: } ! 659: ! 660: cost += CostOf[tool]; ! 661: ! 662: if ((TotalFunds - cost) < 0) { ! 663: return -2; ! 664: } ! 665: ! 666: if ((Players > 1) && ! 667: (OverRide == 0) && ! 668: (cost >= Expensive) && ! 669: (view != NULL) && ! 670: (view->super_user == 0)) { ! 671: return -3; ! 672: } ! 673: ! 674: /* take care of the money situtation here */ ! 675: Spend(cost); ! 676: UpdateFunds(); ! 677: ! 678: mapV = v; holdMapH = h; ! 679: ! 680: for (rowNum = 0; rowNum <= 5; rowNum++) { ! 681: mapH = holdMapH; ! 682: ! 683: for (columnNum = 0; columnNum <= 5; columnNum++) { ! 684: if (columnNum == 1 && rowNum == 1) { ! 685: Map[mapH++][mapV] = base + BNCNBIT + ZONEBIT; ! 686: } else { ! 687: Map[mapH++][mapV] = base + BNCNBIT; ! 688: } ! 689: base++; ! 690: } ! 691: mapV++; ! 692: } ! 693: check6x6border(xMap, yMap); ! 694: return 1; ! 695: } ! 696: ! 697: ! 698: /* QUERY */ ! 699: ! 700: ! 701: /* search table for zone status string match */ ! 702: static short idArray[28] = { ! 703: DIRT, RIVER, TREEBASE, RUBBLE, ! 704: FLOOD, RADTILE, FIRE, ROADBASE, ! 705: POWERBASE, RAILBASE, RESBASE, COMBASE, ! 706: INDBASE, PORTBASE, AIRPORTBASE, COALBASE, ! 707: FIRESTBASE, POLICESTBASE, STADIUMBASE, NUCLEARBASE, ! 708: 827, 832, FOUNTAIN, INDBASE2, ! 709: FOOTBALLGAME1, VBRDG0, 952, 956 ! 710: }; ! 711: ! 712: /* ! 713: 0, 2, 21, 44, ! 714: 48, 52, 53, 64, ! 715: 208, 224, 240, 423, ! 716: 612, 693, 709, 745, ! 717: 761, 770, 779, 811, ! 718: 827, 832, 840, 844, ! 719: 932, 948, 952, 956 ! 720: ! 721: Clear, Water, Trees, Rubble, ! 722: Flood, Radioactive Waste, Fire, Road, ! 723: Power, Rail, Residential, Commercial, ! 724: Industrial, Port, AirPort, Coal Power, ! 725: Fire Department, Police Department, Stadium, Nuclear Power, ! 726: Draw Bridge, Radar Dish, Fountain, Industrial, ! 727: 49er's 38 Bears 3, Draw Bridge, Ur 238 ! 728: */ ! 729: ! 730: ! 731: int getDensityStr(short catNo, short mapH, short mapV) ! 732: { ! 733: int z; ! 734: ! 735: switch(catNo) { ! 736: case 0: ! 737: z = PopDensity[mapH >>1][mapV >>1]; ! 738: z = z >> 6; ! 739: z = z & 3; ! 740: return (z); ! 741: case 1: ! 742: z = LandValueMem[mapH >>1][mapV >>1]; ! 743: if (z < 30) return (4); ! 744: if (z < 80) return (5); ! 745: if (z < 150) return (6); ! 746: return (7); ! 747: case 2: ! 748: z = CrimeMem[mapH >>1][mapV >>1]; ! 749: z = z >> 6; ! 750: z = z & 3; ! 751: return (z + 8); ! 752: case 3: ! 753: z = PollutionMem[mapH >>1][mapV >>1]; ! 754: if ((z < 64) && (z > 0)) return (13); ! 755: z = z >> 6; ! 756: z = z & 3; ! 757: return (z + 12); ! 758: case 4: ! 759: z = RateOGMem[mapH >>3][mapV >>3]; ! 760: if (z < 0) return (16); ! 761: if (z == 0) return (17); ! 762: if (z > 100) return (19); ! 763: return (18); ! 764: } ! 765: } ! 766: ! 767: ! 768: doZoneStatus(short mapH, short mapV) ! 769: { ! 770: char localStr[256]; ! 771: char statusStr[5][256]; ! 772: short id; ! 773: short x; ! 774: short tileNum; ! 775: short found; ! 776: ! 777: tileNum = Map[mapH][mapV] & LOMASK; ! 778: ! 779: if (tileNum >= COALSMOKE1 && tileNum < FOOTBALLGAME1) ! 780: tileNum = COALBASE; ! 781: ! 782: found = 1; ! 783: for (x = 1; x < 29 && found; x++) { ! 784: if (tileNum < idArray[x]) { ! 785: found = 0; ! 786: } ! 787: } ! 788: x--; ! 789: ! 790: if (x < 1 || x > 28) ! 791: x = 28; ! 792: ! 793: GetIndString(localStr, 219, x); ! 794: ! 795: for (x = 0; x < 5; x++) { ! 796: id = getDensityStr(x, mapH, mapV); ! 797: id++; ! 798: if (id <= 0) id = 1; ! 799: if (id > 20) id = 20; ! 800: GetIndString(statusStr[x], 202, id); ! 801: } ! 802: ! 803: DoShowZoneStatus(localStr, statusStr[0], statusStr[1], ! 804: statusStr[2], statusStr[3], statusStr[4], mapH, mapV); ! 805: } ! 806: ! 807: ! 808: DoShowZoneStatus(char *str, char *s0, char *s1, char *s2, char *s3, char *s4, ! 809: int x, int y) ! 810: { ! 811: char buf[1024]; ! 812: ! 813: sprintf(buf, "UIShowZoneStatus {%s} {%s} {%s} {%s} {%s} {%s} %d %d", ! 814: str, s0, s1, s2, s3, s4, x, y); ! 815: Eval(buf); ! 816: } ! 817: ! 818: ! 819: /* comefrom: processWand */ ! 820: put3x3Rubble(short x, short y) ! 821: { ! 822: register xx, yy, zz; ! 823: ! 824: for (xx = x - 1; xx < x + 2; xx++) { ! 825: for (yy = y - 1; yy < y + 2; yy++) { ! 826: if (TestBounds(xx, yy)) { ! 827: zz = Map[xx][yy] & LOMASK; ! 828: if ((zz != RADTILE) && (zz != 0)) { ! 829: Map[xx][yy] = ! 830: (DoAnimation ! 831: ? (TINYEXP + Rand(2)) ! 832: : SOMETINYEXP) ! 833: | ANIMBIT | BULLBIT; ! 834: } ! 835: } ! 836: } ! 837: } ! 838: } ! 839: ! 840: ! 841: /* comefrom: processWand */ ! 842: put4x4Rubble(short x, short y) ! 843: { ! 844: register xx, yy, zz; ! 845: ! 846: for (xx = x - 1; xx < x + 3; xx++) { ! 847: for (yy = y - 1; yy < y + 3; yy++) { ! 848: if (TestBounds(xx, yy)) { ! 849: zz = Map[xx][yy] & LOMASK; ! 850: if ((zz != RADTILE) && (zz != 0)) { ! 851: Map[xx][yy] = ! 852: (DoAnimation ! 853: ? (TINYEXP + Rand(2)) ! 854: : SOMETINYEXP) ! 855: | ANIMBIT | BULLBIT; ! 856: } ! 857: } ! 858: } ! 859: } ! 860: } ! 861: ! 862: ! 863: /* comefrom: processWand */ ! 864: put6x6Rubble(short x, short y) ! 865: { ! 866: register xx, yy, zz; ! 867: ! 868: for (xx = x - 1; xx < x + 5; xx++) { ! 869: for (yy = y - 1; yy < y + 5; yy++) { ! 870: if (TestBounds(xx, yy)) { ! 871: zz = Map[xx][yy] & LOMASK; ! 872: if ((zz != RADTILE) && (zz != 0)) { ! 873: Map[xx][yy] = ! 874: (DoAnimation ! 875: ? (TINYEXP + Rand(2)) ! 876: : SOMETINYEXP) ! 877: | ANIMBIT | BULLBIT; ! 878: } ! 879: } ! 880: } ! 881: } ! 882: } ! 883: ! 884: ! 885: DidTool(SimView *view, char *name, short x, short y) ! 886: { ! 887: char buf[256]; ! 888: ! 889: if (view != NULL) { ! 890: sprintf(buf, "UIDidTool%s %s %d %d", ! 891: name, Tk_PathName(view->tkwin), x, y); ! 892: Eval(buf); ! 893: } ! 894: } ! 895: ! 896: ! 897: DoSetWandState(SimView *view, short state) ! 898: { ! 899: char buf[256]; ! 900: ! 901: sprintf(buf, "UISetToolState %s %d", Tk_PathName(view->tkwin), state); ! 902: Eval(buf); ! 903: } ! 904: ! 905: ! 906: /************************************************************************/ ! 907: /* TOOLS */ ! 908: ! 909: ! 910: int ! 911: query_tool(SimView *view, short x, short y) ! 912: { ! 913: if ((x < 0) || (x > (WORLD_X - 1)) || ! 914: (y < 0) || (y > (WORLD_Y - 1))) { ! 915: return -1; ! 916: } ! 917: ! 918: doZoneStatus(x, y); ! 919: DidTool(view, "Qry", x, y); ! 920: return 1; ! 921: } ! 922: ! 923: ! 924: int ! 925: bulldozer_tool(SimView *view, short x, short y) ! 926: { ! 927: unsigned short currTile, temp; ! 928: short zoneSize, deltaH, deltaV; ! 929: int result = 1; ! 930: ! 931: if ((x < 0) || (x > (WORLD_X - 1)) || ! 932: (y < 0) || (y > (WORLD_Y - 1))) { ! 933: return -1; ! 934: } ! 935: ! 936: currTile = Map[x][y]; ! 937: temp = currTile & LOMASK; ! 938: ! 939: if (currTile & ZONEBIT) { /* zone center bit is set */ ! 940: if (TotalFunds > 0) { ! 941: Spend(1); ! 942: switch (checkSize(temp)) { ! 943: case 3: ! 944: MakeSound("city", "Explosion-High"); ! 945: put3x3Rubble(x, y); ! 946: break; ! 947: ! 948: case 4: ! 949: put4x4Rubble(x, y); ! 950: MakeSound("city", "Explosion-Low"); ! 951: break; ! 952: ! 953: case 6: ! 954: MakeSound("city", "Explosion-High"); ! 955: MakeSound("city", "Explosion-Low"); ! 956: put6x6Rubble(x, y); ! 957: break; ! 958: ! 959: default: ! 960: break; ! 961: } ! 962: } ! 963: } else if ((zoneSize = checkBigZone(temp, &deltaH, &deltaV))) { ! 964: if (TotalFunds > 0) { ! 965: Spend(1); ! 966: switch (zoneSize) { ! 967: case 3: ! 968: MakeSound("city", "Explosion-High"); ! 969: break; ! 970: ! 971: case 4: ! 972: MakeSound("city", "Explosion-Low"); ! 973: put4x4Rubble(x + deltaH, y + deltaV); ! 974: break; ! 975: ! 976: case 6: ! 977: MakeSound("city", "Explosion-High"); ! 978: MakeSound("city", "Explosion-Low"); ! 979: put6x6Rubble(x + deltaH, y + deltaV); ! 980: break; ! 981: } ! 982: } ! 983: } else { ! 984: if (temp == RIVER || temp == REDGE || temp == CHANNEL) { ! 985: if (TotalFunds >= 6) { ! 986: result = ConnecTile(x, y, &Map[x][y], 1); ! 987: if (temp != (Map[x][y] & LOMASK)) { ! 988: Spend(5); ! 989: } ! 990: } else { ! 991: result = 0; ! 992: } ! 993: } else { ! 994: result = ConnecTile(x, y, &Map[x][y], 1); ! 995: } ! 996: } ! 997: UpdateFunds(); ! 998: if (result == 1) { ! 999: DidTool(view, "Dozr", x, y); ! 1000: } ! 1001: return result; ! 1002: } ! 1003: ! 1004: ! 1005: int ! 1006: road_tool(SimView *view, short x, short y) ! 1007: { ! 1008: int result; ! 1009: ! 1010: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1011: (y < 0) || (y > (WORLD_Y - 1))) { ! 1012: return -1; ! 1013: } ! 1014: ! 1015: result = ConnecTile(x, y, &Map[x][y], 2); ! 1016: UpdateFunds(); ! 1017: if (result == 1) { ! 1018: DidTool(view, "Road", x, y); ! 1019: } ! 1020: return result; ! 1021: } ! 1022: ! 1023: ! 1024: int ! 1025: rail_tool(SimView *view, short x, short y) ! 1026: { ! 1027: int result; ! 1028: ! 1029: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1030: (y < 0) || (y > (WORLD_Y - 1))) { ! 1031: return -1; ! 1032: } ! 1033: ! 1034: result = ConnecTile(x, y, &Map[x][y], 3); ! 1035: UpdateFunds(); ! 1036: if (result == 1) { ! 1037: DidTool(view, "Rail", x, y); ! 1038: } ! 1039: return result; ! 1040: } ! 1041: ! 1042: ! 1043: int ! 1044: wire_tool(SimView *view, short x, short y) ! 1045: { ! 1046: int result; ! 1047: ! 1048: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1049: (y < 0) || (y > (WORLD_Y - 1))) { ! 1050: return -1; ! 1051: } ! 1052: ! 1053: result = ConnecTile(x, y, &Map[x][y], 4); ! 1054: UpdateFunds(); ! 1055: if (result == 1) { ! 1056: DidTool(view, "Wire", x, y); ! 1057: } ! 1058: return result; ! 1059: } ! 1060: ! 1061: ! 1062: int ! 1063: park_tool(SimView *view, short x, short y) ! 1064: { ! 1065: int result; ! 1066: ! 1067: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1068: (y < 0) || (y > (WORLD_Y - 1))) ! 1069: return -1; ! 1070: ! 1071: result = putDownPark(view, x, y); ! 1072: if (result == 1) { ! 1073: DidTool(view, "Park", x, y); ! 1074: } ! 1075: return result; ! 1076: } ! 1077: ! 1078: ! 1079: int ! 1080: residential_tool(SimView *view, short x, short y) ! 1081: { ! 1082: int result; ! 1083: ! 1084: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1085: (y < 0) || (y > (WORLD_Y - 1))) { ! 1086: return -1; ! 1087: } ! 1088: ! 1089: result = check3x3(view, x, y, RESBASE, residentialState); ! 1090: if (result == 1) { ! 1091: DidTool(view, "Res", x, y); ! 1092: } ! 1093: return result; ! 1094: } ! 1095: ! 1096: ! 1097: int ! 1098: commercial_tool(SimView *view, short x, short y) ! 1099: { ! 1100: int result; ! 1101: ! 1102: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1103: (y < 0) || (y > (WORLD_Y - 1))) { ! 1104: return -1; ! 1105: } ! 1106: ! 1107: result = check3x3(view, x, y, COMBASE, commercialState); ! 1108: if (result == 1) { ! 1109: DidTool(view, "Com", x, y); ! 1110: } ! 1111: return result; ! 1112: } ! 1113: ! 1114: ! 1115: int ! 1116: industrial_tool(SimView *view, short x, short y) ! 1117: { ! 1118: int result; ! 1119: ! 1120: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1121: (y < 0) || (y > (WORLD_Y - 1))) { ! 1122: return -1; ! 1123: } ! 1124: ! 1125: result = check3x3(view, x, y, INDBASE, industrialState); ! 1126: if (result == 1) { ! 1127: DidTool(view, "Ind", x, y); ! 1128: } ! 1129: return result; ! 1130: } ! 1131: ! 1132: ! 1133: int ! 1134: police_dept_tool(SimView *view, short x, short y) ! 1135: { ! 1136: int result; ! 1137: ! 1138: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1139: (y < 0) || (y > (WORLD_Y - 1))) { ! 1140: return -1; ! 1141: } ! 1142: ! 1143: result = check3x3(view, x, y, POLICESTBASE, policeState); ! 1144: if (result == 1) { ! 1145: DidTool(view, "Pol", x, y); ! 1146: } ! 1147: return result; ! 1148: } ! 1149: ! 1150: ! 1151: int ! 1152: fire_dept_tool(SimView *view, short x, short y) ! 1153: { ! 1154: int result; ! 1155: ! 1156: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1157: (y < 0) || (y > (WORLD_Y - 1))) { ! 1158: return -1; ! 1159: } ! 1160: ! 1161: result = check3x3(view, x, y, FIRESTBASE, fireState); ! 1162: if (result == 1) { ! 1163: DidTool(view, "Fire", x, y); ! 1164: } ! 1165: return result; ! 1166: } ! 1167: ! 1168: ! 1169: int ! 1170: stadium_tool(SimView *view, short x, short y) ! 1171: { ! 1172: int result; ! 1173: ! 1174: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1175: (y < 0) || (y > (WORLD_Y - 1))) { ! 1176: return -1; ! 1177: } ! 1178: ! 1179: result = check4x4(view, x, y, STADIUMBASE, 0, stadiumState); ! 1180: if (result == 1) { ! 1181: DidTool(view, "Stad", x, y); ! 1182: } ! 1183: return result; ! 1184: } ! 1185: ! 1186: ! 1187: int ! 1188: coal_power_plant_tool(SimView *view, short x, short y) ! 1189: { ! 1190: int result; ! 1191: ! 1192: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1193: (y < 0) || (y > (WORLD_Y - 1))) { ! 1194: return -1; ! 1195: } ! 1196: ! 1197: result = check4x4(view, x, y, COALBASE, 1, powerState); ! 1198: if (result == 1) { ! 1199: DidTool(view, "Coal", x, y); ! 1200: } ! 1201: return result; ! 1202: } ! 1203: ! 1204: ! 1205: int ! 1206: nuclear_power_plant_tool(SimView *view, short x, short y) ! 1207: { ! 1208: int result; ! 1209: ! 1210: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1211: (y < 0) || (y > (WORLD_Y - 1))) { ! 1212: return -1; ! 1213: } ! 1214: ! 1215: result = check4x4(view, x, y, NUCLEARBASE, 1, nuclearState); ! 1216: if (result == 1) { ! 1217: DidTool(view, "Nuc", x, y); ! 1218: } ! 1219: return result; ! 1220: } ! 1221: ! 1222: ! 1223: int ! 1224: seaport_tool(SimView *view, short x, short y) ! 1225: { ! 1226: int result; ! 1227: ! 1228: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1229: (y < 0) || (y > (WORLD_Y - 1))) { ! 1230: return -1; ! 1231: } ! 1232: ! 1233: result = check4x4(view, x, y, PORTBASE, 0, seaportState); ! 1234: if (result == 1) { ! 1235: DidTool(view, "Seap", x, y); ! 1236: } ! 1237: return result; ! 1238: } ! 1239: ! 1240: ! 1241: int ! 1242: airport_tool(SimView *view, short x, short y) ! 1243: { ! 1244: int result; ! 1245: ! 1246: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1247: (y < 0) || (y > (WORLD_Y - 1))) { ! 1248: return -1; ! 1249: } ! 1250: ! 1251: result = check6x6(view, x, y, AIRPORTBASE, airportState); ! 1252: if (result == 1) { ! 1253: DidTool(view, "Airp", x, y); ! 1254: } ! 1255: return result; ! 1256: } ! 1257: ! 1258: ! 1259: int ! 1260: network_tool(SimView *view, short x, short y) ! 1261: { ! 1262: int result; ! 1263: ! 1264: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1265: (y < 0) || (y > (WORLD_Y - 1))) { ! 1266: return -1; ! 1267: } ! 1268: ! 1269: result = putDownNetwork(view, x, y); ! 1270: if (result == 1) { ! 1271: DidTool(view, "Net", x, y); ! 1272: } ! 1273: return result; ! 1274: } ! 1275: ! 1276: ! 1277: #if 0 ! 1278: int ! 1279: special_tool(SimView *view, short x, short y) ! 1280: { ! 1281: int result; ! 1282: ! 1283: if ((x < 0) || (x > (WORLD_X - 1)) || ! 1284: (y < 0) || (y > (WORLD_Y - 1))) { ! 1285: return -1; ! 1286: } ! 1287: ! 1288: result = check3x3(view, x, y, specialBase, specialState); ! 1289: if (result == 1) { ! 1290: DidTool(view, "Special", x, y); ! 1291: } ! 1292: return result; ! 1293: } ! 1294: #endif ! 1295: ! 1296: int ! 1297: ChalkTool(SimView *view, short x, short y, short color, short first) ! 1298: { ! 1299: if (first) { ! 1300: ChalkStart(view, x, y, color); ! 1301: } else { ! 1302: ChalkTo(view, x, y); ! 1303: } ! 1304: DidTool(view, "Chlk", x, y); ! 1305: return 1; ! 1306: } ! 1307: ! 1308: ! 1309: ChalkStart(SimView *view, int x, int y, int color) ! 1310: { ! 1311: Ink *ink; ! 1312: Ink **ip; ! 1313: ! 1314: for (ip = &sim->overlay; *ip != NULL; ip = &((*ip)->next)) ; ! 1315: ! 1316: *ip = ink = NewInk(); ! 1317: ink->x = x; ink->y = y; ! 1318: ink->color = color; ! 1319: StartInk(ink, x, y); ! 1320: view->track_info = (char *)ink; ! 1321: view->last_x = x; ! 1322: view->last_y = y; ! 1323: view->tool_event_time = view->tool_last_event_time = ! 1324: ((TkWindow *)view->tkwin)->dispPtr->lastEventTime; ! 1325: } ! 1326: ! 1327: ! 1328: ChalkTo(SimView *view, int x, int y) ! 1329: { ! 1330: int x0, y0, lx, ly; ! 1331: Ink *ink = (Ink *)view->track_info; ! 1332: ! 1333: #ifdef MOTIONBUFFER ! 1334: if (view->x->dpy->motion_buffer) { ! 1335: XTimeCoord *coords = NULL, *coord; ! 1336: int n = 0, i; ! 1337: ! 1338: view->tool_last_event_time = view->tool_event_time; ! 1339: view->tool_event_time = ! 1340: ((TkWindow *)view->tkwin)->dispPtr->lastEventTime; ! 1341: ! 1342: coords = XGetMotionEvents(view->x->dpy, ! 1343: Tk_WindowId(view->tkwin), ! 1344: view->tool_last_event_time, ! 1345: view->tool_event_time, ! 1346: &n); ! 1347: #if 0 ! 1348: printf("got %d events at %x from %d to %d (%d elapsed)\n", ! 1349: n, coords, ! 1350: view->tool_last_event_time, view->tool_event_time, ! 1351: view->tool_event_time - view->tool_last_event_time); ! 1352: #endif ! 1353: if (n) { ! 1354: lx = ink->last_x; ly = ink->last_y; ! 1355: ! 1356: for (i = 0, coord = coords; i < n; i++, coord++) { ! 1357: ViewToPixelCoords(view, coord->x, coord->y, &x0, &y0); ! 1358: lx = (lx + lx + lx + x0) >>2; ! 1359: ly = (ly + ly + ly + y0) >>2; ! 1360: #if 0 ! 1361: printf("adding %d %d => %d %d => %d %d\n", ! 1362: coord->x, coord->y, x0, y0, lx, ly); ! 1363: #endif ! 1364: AddInk(ink, lx, ly); ! 1365: } ! 1366: } ! 1367: ! 1368: if (coords) { ! 1369: XFree((char *)coords); ! 1370: } ! 1371: } ! 1372: #endif ! 1373: ! 1374: AddInk(ink, x, y); ! 1375: view->last_x = x; ! 1376: view->last_y = y; ! 1377: } ! 1378: ! 1379: ! 1380: int ! 1381: EraserTool(SimView *view, short x, short y, short first) ! 1382: { ! 1383: if (first) { ! 1384: EraserStart(view, x, y); ! 1385: } else { ! 1386: EraserTo(view, x, y); ! 1387: } ! 1388: DidTool(view, "Eraser", x, y); ! 1389: return 1; ! 1390: } ! 1391: ! 1392: ! 1393: InkInBox(Ink *ink, int left, int top, int right, int bottom) ! 1394: { ! 1395: if ((left <= ink->right) && ! 1396: (right >= ink->left) && ! 1397: (top <= ink->bottom) && ! 1398: (bottom >= ink->top)) { ! 1399: int x, y, lx, ly, i; ! 1400: ! 1401: if (ink->length == 1) { ! 1402: return 1; ! 1403: } ! 1404: ! 1405: x = ink->x; y = ink->y; ! 1406: for (i = 1; i < ink->length; i++) { ! 1407: int ileft, iright, itop, ibottom; ! 1408: ! 1409: lx = x; ly = y; ! 1410: x += ink->points[i].x; y += ink->points[i].y; ! 1411: if (x < lx) { ileft = x; iright = lx; } ! 1412: else { ileft = lx; iright = x; } ! 1413: if (y < ly) { itop = y; ibottom = ly; } ! 1414: else { itop = ly; ibottom = y; } ! 1415: if ((left <= iright) && ! 1416: (right >= ileft) && ! 1417: (top <= ibottom) && ! 1418: (bottom >= itop)) { ! 1419: return 1; ! 1420: } ! 1421: } ! 1422: } ! 1423: return 0; ! 1424: } ! 1425: ! 1426: ! 1427: EraserStart(SimView *view, int x, int y) ! 1428: { ! 1429: EraserTo(view, x, y); ! 1430: } ! 1431: ! 1432: ! 1433: EraserTo(SimView *view, int x, int y) ! 1434: { ! 1435: SimView *v; ! 1436: Ink **ip, *ink; ! 1437: ! 1438: for (ip = &sim->overlay; *ip != NULL;) { ! 1439: ink = *ip; ! 1440: if (InkInBox(ink, x - 8, y - 8, x + 8, y + 8)) { ! 1441: ! 1442: for (view = sim->editor; view != NULL; view = view->next) { ! 1443: int vleft, vtop; ! 1444: ! 1445: if ((ink->right >= (vleft = (view->pan_x - (view->w_width / 2)))) && ! 1446: (ink->left <= (vleft + view->w_width)) && ! 1447: (ink->bottom >= (vtop = (view->pan_y - (view->w_height / 2)))) && ! 1448: (ink->top <= (vtop + view->w_height))) { ! 1449: view->overlay_mode = 0; ! 1450: EventuallyRedrawView(view); ! 1451: } ! 1452: } ! 1453: ! 1454: *ip = ink->next; ! 1455: ! 1456: FreeInk(ink); ! 1457: } else { ! 1458: ip = &((*ip)->next); ! 1459: } ! 1460: } ! 1461: } ! 1462: ! 1463: ! 1464: int ! 1465: do_tool(SimView *view, short state, short x, short y, short first) ! 1466: { ! 1467: int result = 0; ! 1468: ! 1469: switch (state) { ! 1470: case residentialState: ! 1471: result = residential_tool(view, x >>4, y >>4); ! 1472: break; ! 1473: case commercialState: ! 1474: result = commercial_tool(view, x >>4, y >>4); ! 1475: break; ! 1476: case industrialState: ! 1477: result = industrial_tool(view, x >>4, y >>4); ! 1478: break; ! 1479: case fireState: ! 1480: result = fire_dept_tool(view, x >>4, y >>4); ! 1481: break; ! 1482: case queryState: ! 1483: result = query_tool(view, x >>4, y >>4); ! 1484: break; ! 1485: case policeState: ! 1486: result = police_dept_tool(view, x >>4, y >>4); ! 1487: break; ! 1488: case wireState: ! 1489: result = wire_tool(view, x >>4, y >>4); ! 1490: break; ! 1491: case dozeState: ! 1492: result = bulldozer_tool(view, x >>4, y >>4); ! 1493: break; ! 1494: case rrState: ! 1495: result = rail_tool(view, x >>4, y >>4); ! 1496: break; ! 1497: case roadState: ! 1498: result = road_tool(view, x >>4, y >>4); ! 1499: break; ! 1500: case chalkState: ! 1501: result = ChalkTool(view, x - 5, y + 11, COLOR_WHITE, first); ! 1502: break; ! 1503: case eraserState: ! 1504: result = EraserTool(view, x, y, first); ! 1505: break; ! 1506: case stadiumState: ! 1507: result = stadium_tool(view, x >>4, y >>4); ! 1508: break; ! 1509: case parkState: ! 1510: result = park_tool(view, x >>4, y >>4); ! 1511: break; ! 1512: case seaportState: ! 1513: result = seaport_tool(view, x >>4, y >>4); ! 1514: break; ! 1515: case powerState: ! 1516: result = coal_power_plant_tool(view, x >>4, y >>4); ! 1517: break; ! 1518: case nuclearState: ! 1519: result = nuclear_power_plant_tool(view, x >>4, y >>4); ! 1520: break; ! 1521: case airportState: ! 1522: result = airport_tool(view, x >>4, y >>4); ! 1523: break; ! 1524: case networkState: ! 1525: result = network_tool(view, x >>4, y >>4); ! 1526: break; ! 1527: ! 1528: default: ! 1529: result = 0; ! 1530: break; ! 1531: } ! 1532: ! 1533: return result; ! 1534: } ! 1535: ! 1536: ! 1537: int ! 1538: current_tool(SimView *view, short x, short y, short first) ! 1539: { ! 1540: return do_tool(view, view->tool_state, x, y, first); ! 1541: } ! 1542: ! 1543: ! 1544: DoTool(SimView *view, short tool, short x, short y) ! 1545: { ! 1546: int result; ! 1547: ! 1548: result = do_tool(view, tool, x <<4, y <<4, 1); ! 1549: ! 1550: if (result == -1) { ! 1551: ClearMes(); ! 1552: SendMes(34); ! 1553: MakeSoundOn(view, "edit", "UhUh"); ! 1554: } else if (result == -2) { ! 1555: ClearMes(); ! 1556: SendMes(33); ! 1557: MakeSoundOn(view, "edit", "Sorry"); ! 1558: } ! 1559: ! 1560: sim_skip = 0; ! 1561: view->skip = 0; ! 1562: InvalidateEditors(); ! 1563: } ! 1564: ! 1565: ! 1566: ToolDown(SimView *view, int x, int y) ! 1567: { ! 1568: int result; ! 1569: ! 1570: ViewToPixelCoords(view, x, y, &x, &y); ! 1571: view->last_x = x; ! 1572: view->last_y = y; ! 1573: ! 1574: result = current_tool(view, x, y, 1); ! 1575: ! 1576: if (result == -1) { ! 1577: ClearMes(); ! 1578: SendMes(34); ! 1579: MakeSoundOn(view, "edit", "UhUh"); ! 1580: } else if (result == -2) { ! 1581: ClearMes(); ! 1582: SendMes(33); ! 1583: MakeSoundOn(view, "edit", "Sorry"); ! 1584: } else if (result == -3) { ! 1585: DoPendTool(view, view->tool_state, x >>4, y >>4); ! 1586: } ! 1587: ! 1588: sim_skip = 0; ! 1589: view->skip = 0; ! 1590: view->invalid = 1; ! 1591: } ! 1592: ! 1593: ! 1594: ToolUp(SimView *view, int x, int y) ! 1595: { ! 1596: int result; ! 1597: ! 1598: result = ToolDrag(view, x, y); ! 1599: ! 1600: return (result); ! 1601: } ! 1602: ! 1603: ! 1604: ToolDrag(SimView *view, int px, int py) ! 1605: { ! 1606: int x, y, dx, dy, adx, ady, lx, ly, dist; ! 1607: float i, step, tx, ty, dtx, dty, rx, ry; ! 1608: ! 1609: ViewToPixelCoords(view, px, py, &x, &y); ! 1610: view->tool_x = x; view->tool_y = y; ! 1611: ! 1612: if ((view->tool_state == chalkState) || ! 1613: (view->tool_state == eraserState)) { ! 1614: ! 1615: current_tool(view, x, y, 0); ! 1616: view->last_x = x; view->last_y = y; ! 1617: ! 1618: } else { ! 1619: ! 1620: dist = toolSize[view->tool_state]; ! 1621: ! 1622: x >>= 4; y >>= 4; ! 1623: lx = view->last_x >> 4; ! 1624: ly = view->last_y >> 4; ! 1625: ! 1626: reset: ! 1627: ! 1628: dx = x - lx; ! 1629: dy = y - ly; ! 1630: ! 1631: if (dx == 0 && dy == 0) { ! 1632: return; ! 1633: } ! 1634: ! 1635: adx = ABS(dx); ady = ABS(dy); ! 1636: ! 1637: if (adx > ady) { ! 1638: step = .3 / adx; ! 1639: } else { ! 1640: step = .3 / ady; ! 1641: } ! 1642: ! 1643: rx = (dx < 0 ? 1 : 0); ! 1644: ry = (dy < 0 ? 1 : 0); ! 1645: ! 1646: if (dist == 1) { ! 1647: for (i = 0.0; i <= 1 + step; i += step) { ! 1648: tx = (view->last_x >>4) + i * dx; ! 1649: ty = (view->last_y >>4) + i * dy; ! 1650: dtx = ABS(tx - lx); ! 1651: dty = ABS(ty - ly); ! 1652: if (dtx >= 1 || dty >= 1) { ! 1653: /* fill in corners */ ! 1654: if ((dtx >= 1) && (dty >= 1)) { ! 1655: if (dtx > dty) { ! 1656: current_tool(view, ((int)(tx + rx)) <<4, ly <<4, 0); ! 1657: } else { ! 1658: current_tool(view, lx <<4, ((int)(ty + ry)) <<4, 0); ! 1659: } ! 1660: } ! 1661: lx = (int)(tx + rx); ! 1662: ly = (int)(ty + ry); ! 1663: current_tool(view, lx <<4, ly <<4, 0); ! 1664: } ! 1665: } ! 1666: } else { ! 1667: for (i = 0.0; i <= 1 + step; i += step) { ! 1668: tx = (view->last_x >>4) + i * dx; ! 1669: ty = (view->last_y >>4) + i * dy; ! 1670: dtx = ABS(tx - lx); ! 1671: dty = ABS(ty - ly); ! 1672: lx = (int)(tx + rx); ! 1673: ly = (int)(ty + ry); ! 1674: current_tool(view, lx <<4, ly <<4, 0); ! 1675: } ! 1676: } ! 1677: ! 1678: view->last_x = (lx <<4) + 8; ! 1679: view->last_y = (ly <<4) + 8; ! 1680: } ! 1681: sim_skip = 0; /* update editors overlapping this one */ ! 1682: view->skip = 0; ! 1683: view->invalid = 1; ! 1684: } ! 1685: ! 1686: ! 1687: DoPendTool(SimView *view, int tool, int x, int y) ! 1688: { ! 1689: char buf[256]; ! 1690: ! 1691: sprintf(buf, "DoPendTool %s %d %d %d", ! 1692: Tk_PathName(view->tkwin), tool, x, y); ! 1693: Eval(buf); ! 1694: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.