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