Annotation of micropolis/src/sim/w_tool.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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