]>
cvs.zerfleddert.de Git - micropolis/blob - src/sim/w_tool.c
   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  micropolis@laptop.org. 
   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. 
  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/>. 
  21  *             ADDITIONAL TERMS per GNU GPL Section 7 
  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. 
  29  * Any propagation or conveyance of this program must include this 
  30  * copyright notice and these terms. 
  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. 
  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. 
  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 
  65 short specialBase 
= CHURCH
; 
  93 short toolOffset
[] = { 
 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 */ 
 127 void DoSetWandState(SimView 
*view
, short state
); 
 128 void DoPendTool(SimView 
*view
, int tool
, int x
, int y
); 
 129 void EraserTo(SimView 
*view
, int x
, int y
); 
 130 void EraserStart(SimView 
*view
, int x
, int y
); 
 131 void DoShowZoneStatus(char *str
, char *s0
, char *s1
, char *s2
, char *s3
, char *s4
, int x
, int y
); 
 134 /*************************************************************************/ 
 139 setWandState(SimView 
*view
, short state
) 
 143     specialBase 
= -state
; 
 144     state 
= specialState
; 
 148   view
->tool_state 
= state
; 
 150   DoSetWandState(view
, state
); 
 155 putDownPark(SimView 
*view
, short mapH
, short mapV
) 
 159   if (TotalFunds 
- CostOf
[parkState
] >= 0) { 
 163       tile 
= FOUNTAIN 
| BURNBIT 
| BULLBIT 
| ANIMBIT
; 
 165       tile 
= (value 
+ WOODS2
) | BURNBIT 
| BULLBIT
; 
 167     if (Map
[mapH
][mapV
] == 0) { 
 168       Spend(CostOf
[parkState
]); 
 170       Map
[mapH
][mapV
] = tile
; 
 180 putDownNetwork(SimView 
*view
, short mapH
, short mapV
) 
 182   int tile 
= Map
[mapH
][mapV
] & LOMASK
; 
 184   if ((TotalFunds 
> 0) && tally(tile
)) { 
 185     Map
[mapH
][mapV
] = tile 
= 0; 
 190     if ((TotalFunds 
- CostOf
[view
->tool_state
]) >= 0) { 
 191       Map
[mapH
][mapV
] = TELEBASE 
| CONDBIT 
| BURNBIT 
| BULLBIT 
| ANIMBIT
; 
 192       Spend(CostOf
[view
->tool_state
]); 
 204 checkBigZone(short id
, short *deltaHPtr
, short *deltaVPtr
) 
 207   case POWERPLANT
:      /* check coal plant */ 
 208   case PORT
:            /* check sea port */ 
 209   case NUCLEAR
:         /* check nuc plant */ 
 210   case STADIUM
:         /* check stadium */ 
 211     *deltaHPtr 
= 0;     *deltaVPtr 
= 0;         return (4); 
 213   case POWERPLANT 
+ 1:  /* check coal plant */ 
 214   case COALSMOKE3
:      /* check coal plant, smoke */ 
 215   case COALSMOKE3 
+ 1:  /* check coal plant, smoke */ 
 216   case COALSMOKE3 
+ 2:  /* check coal plant, smoke */ 
 217   case PORT 
+ 1:        /* check sea port */ 
 218   case NUCLEAR 
+ 1:     /* check nuc plant */ 
 219   case STADIUM 
+ 1:     /* check stadium */ 
 220     *deltaHPtr 
= -1;    *deltaVPtr 
= 0;         return (4); 
 222   case POWERPLANT 
+ 4:  /* check coal plant */ 
 223   case PORT 
+ 4:        /* check sea port */ 
 224   case NUCLEAR 
+ 4:     /* check nuc plant */ 
 225   case STADIUM 
+ 4:     /* check stadium */ 
 226     *deltaHPtr 
= 0;     *deltaVPtr 
= -1;        return (4); 
 228   case POWERPLANT 
+ 5:  /* check coal plant */ 
 229   case PORT 
+ 5:        /* check sea port */ 
 230   case NUCLEAR 
+ 5:     /* check nuc plant */ 
 231   case STADIUM 
+ 5:     /* check stadium */ 
 232     *deltaHPtr 
= -1;    *deltaVPtr 
= -1;        return (4); 
 237     *deltaHPtr 
= 0;     *deltaVPtr 
= 0;         return (6); 
 239     *deltaHPtr 
= -1;    *deltaVPtr 
= 0;         return (6); 
 241     *deltaHPtr 
= -2;    *deltaVPtr 
= 0;         return (6); 
 243     *deltaHPtr 
= -3;    *deltaVPtr 
= 0;         return (6); 
 247     *deltaHPtr 
= 0;     *deltaVPtr 
= -1;        return (6); 
 249     *deltaHPtr 
= -1;    *deltaVPtr 
= -1;        return (6); 
 251     *deltaHPtr 
= -2;    *deltaVPtr 
= -1;        return (6); 
 253     *deltaHPtr 
= -3;    *deltaVPtr 
= -1;        return (6); 
 257     *deltaHPtr 
= 0;     *deltaVPtr 
= -2;        return (6); 
 259     *deltaHPtr 
= -1;    *deltaVPtr 
= -2;        return (6); 
 261     *deltaHPtr 
= -2;    *deltaVPtr 
= -2;        return (6); 
 263     *deltaHPtr 
= -3;    *deltaVPtr 
= -2;        return (6); 
 267     *deltaHPtr 
= 0;     *deltaVPtr 
= -3;        return (6); 
 269     *deltaHPtr 
= -1;    *deltaVPtr 
= -3;        return (6); 
 271     *deltaHPtr 
= -2;    *deltaVPtr 
= -3;        return (6); 
 273     *deltaHPtr 
= -3;    *deltaVPtr 
= -3;        return (6); 
 276     *deltaHPtr 
= 0;     *deltaVPtr 
= 0;         return (0); 
 282 tally(short tileValue
) 
 284   /* can we autobulldoze this tile? */ 
 285   if (((tileValue 
>= FIRSTRIVEDGE
) && 
 286        (tileValue 
<= LASTRUBBLE
)) ||  
 287       ((tileValue 
>= (POWERBASE 
+ 2)) && 
 288        (tileValue 
<= (POWERBASE 
+ 12))) || 
 289       ((tileValue 
>= TINYEXP
) && 
 290        (tileValue 
<= (LASTTINYEXP 
+ 2)))) { /* ??? */ 
 299 checkSize(short temp
) 
 301   /* check for the normal com, resl, ind 3x3 zones & the fireDept & PoliceDept */ 
 302   if (((temp 
>= (RESBASE 
- 1)) && (temp  
<= (PORTBASE 
- 1))) || 
 303       ((temp 
>= (LASTPOWERPLANT 
+ 1)) && (temp 
<= (POLICESTATION 
+ 4)))) { 
 305   } else if (((temp 
>= PORTBASE
) && (temp 
<= LASTPORT
)) || 
 306              ((temp 
>= COALBASE
) && (temp 
<= LASTPOWERPLANT
)) || 
 307              ((temp 
>= STADIUMBASE
) && (temp 
<= LASTZONE
))) { 
 318 check3x3border(short xMap
, short yMap
) 
 323   xPos 
= xMap
; yPos 
= yMap 
- 1; 
 324   for (cnt 
= 0; cnt 
< 3; cnt
++) { 
 325     /*** this will do the upper bordering row ***/ 
 326     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 330   xPos 
= xMap 
- 1; yPos 
= yMap
; 
 331   for (cnt 
= 0; cnt 
< 3; cnt
++) { 
 332     /*** this will do the left bordering row ***/ 
 333     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 337   xPos 
= xMap
; yPos 
= yMap 
+ 3; 
 338   for (cnt 
= 0; cnt 
< 3; cnt
++) { 
 339     /*** this will do the bottom bordering row ***/ 
 340     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 344   xPos 
= xMap 
+ 3; yPos 
= yMap
; 
 345   for (cnt 
= 0; cnt 
< 3; cnt
++) { 
 346     /*** this will do the right bordering row ***/ 
 347     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 354 check3x3(SimView 
*view
, short mapH
, short mapV
, short base
, short tool
) 
 356   register short rowNum
, columnNum
; 
 357   register short holdMapH
, holdMapV
; 
 364   if ((mapH 
< 0) || (mapH 
> (WORLD_X 
- 3)) || 
 365       (mapV 
< 0) || (mapV 
> (WORLD_Y 
- 3))) { 
 369   xPos 
= holdMapH 
= mapH
; 
 370   yPos 
= holdMapV 
= mapV
; 
 374   for (rowNum 
= 0; rowNum 
<= 2; rowNum
++) { 
 377     for (columnNum 
= 0; columnNum 
<= 2; columnNum
++) { 
 378       tileValue 
= Map
[mapH
++][mapV
] & LOMASK
; 
 381         /* if autoDoze is enabled, add up the cost of bulldozed tiles */ 
 382         if (tileValue 
!= 0) { 
 383           if (tally(tileValue
)) { 
 390         /* check and see if the tile is clear or not  */ 
 391         if (tileValue 
!= 0) { 
 403   cost 
+= CostOf
[tool
]; 
 405   if ((TotalFunds 
- cost
) < 0) { 
 411       (cost 
>= Expensive
) && 
 413       (view
->super_user 
== 0)) { 
 417   /* take care of the money situtation here */ 
 423   for (rowNum 
= 0; rowNum 
<= 2; rowNum
++) { 
 426     for (columnNum 
= 0; columnNum 
<= 2; columnNum
++) { 
 427       if (columnNum 
== 1 && rowNum 
== 1) { 
 428         Map
[mapH
++][mapV
] = base 
+ BNCNBIT 
+ ZONEBIT
; 
 430         Map
[mapH
++][mapV
] = base 
+ BNCNBIT
; 
 436   check3x3border(xPos
, yPos
); 
 445 check4x4border(short xMap
, short yMap
) 
 451   xPos 
= xMap
; yPos 
= yMap 
- 1; 
 452   for (cnt 
= 0; cnt 
< 4; cnt
++) { 
 453     /* this will do the upper bordering row */ 
 454     tilePtr 
= &Map
[xPos
][yPos
]; 
 455     ConnecTile(xPos
, yPos
, tilePtr
, 0); 
 459   xPos 
= xMap 
- 1; yPos 
= yMap
; 
 460   for (cnt 
= 0; cnt 
< 4; cnt
++) { 
 461     /* this will do the left bordering row */ 
 462     tilePtr 
= &Map
[xPos
][yPos
]; 
 463     ConnecTile(xPos
, yPos
, tilePtr
, 0); 
 467   xPos 
= xMap
; yPos 
= yMap 
+ 4; 
 468   for (cnt 
= 0; cnt 
< 4;cnt
++) { 
 469     /* this will do the bottom bordering row */ 
 470     tilePtr 
= &Map
[xPos
][yPos
]; 
 471     ConnecTile(xPos
, yPos
, tilePtr
, 0); 
 475   xPos 
= xMap 
+ 4; yPos 
= yMap
; 
 476   for (cnt 
= 0; cnt 
< 4; cnt
++) { 
 477     /* this will do the right bordering row */ 
 478     tilePtr 
= &Map
[xPos
][yPos
]; 
 479     ConnecTile(xPos
, yPos
, tilePtr
, 0); 
 486 check4x4(SimView 
*view
, short mapH
, short mapV
, 
 487          short base
, short aniFlag
, short tool
) 
 489   register short rowNum
, columnNum
; 
 498   if ((mapH 
< 0) || (mapH 
> (WORLD_X 
- 4)) || 
 499       (mapV 
< 0) || (mapV 
> (WORLD_Y 
- 4))) { 
 503   h 
= xMap 
= holdMapH 
= mapH
; 
 508   for (rowNum 
= 0; rowNum 
<= 3; rowNum
++) { 
 511     for (columnNum 
= 0; columnNum 
<= 3; columnNum
++) { 
 512       tileValue 
= Map
[mapH
++][mapV
] & LOMASK
; 
 515         /* if autoDoze is enabled, add up the cost of bulldozed tiles */ 
 516         if (tileValue 
!= 0) { 
 517           if (tally(tileValue
)) { 
 524         /* check and see if the tile is clear or not  */ 
 525         if (tileValue 
!= 0) { 
 537   cost 
+= CostOf
[tool
]; 
 539   if ((TotalFunds 
- cost
) < 0) { 
 545       (cost 
>= Expensive
) && 
 547       (view
->super_user 
== 0)) { 
 551   /* take care of the money situtation here */ 
 555   mapV 
= v
; holdMapH 
= h
; 
 557   for (rowNum 
= 0; rowNum 
<= 3; rowNum
++) { 
 560     for (columnNum 
= 0; columnNum 
<= 3; columnNum
++) { 
 561       if (columnNum 
== 1 && rowNum 
== 1) 
 562         Map
[mapH
++][mapV
] = base 
+ BNCNBIT 
+ ZONEBIT
; 
 563       else if (columnNum 
== 1 && rowNum 
== 2 && aniFlag
) 
 564         Map
[mapH
++][mapV
] = base 
+ BNCNBIT 
+ ANIMBIT
; 
 566         Map
[mapH
++][mapV
] = base 
+ BNCNBIT
; 
 571   check4x4border(xMap
, yMap
); 
 580 check6x6border(short xMap
, short yMap
) 
 585   xPos 
= xMap
; yPos 
= yMap 
- 1; 
 586   for (cnt 
= 0; cnt 
< 6; cnt
++) { 
 587     /* this will do the upper bordering row */ 
 588     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 592   xPos 
= xMap 
- 1; yPos 
= yMap
; 
 593   for (cnt
=0; cnt 
< 6; cnt
++) { 
 594     /* this will do the left bordering row */ 
 595     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 599   xPos 
= xMap
; yPos 
= yMap 
+ 6; 
 600   for (cnt 
= 0; cnt 
< 6; cnt
++) { 
 601     /* this will do the bottom bordering row */ 
 602     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 606   xPos 
= xMap 
+ 6; yPos 
= yMap
; 
 607   for (cnt 
= 0; cnt 
< 6; cnt
++) { 
 608     /* this will do the right bordering row */ 
 609     ConnecTile(xPos
, yPos
, &Map
[xPos
][yPos
], 0); 
 616 check6x6(SimView 
*view
, short mapH
, short mapV
, short base
, short tool
) 
 618   register short rowNum
, columnNum
; 
 627   if ((mapH 
< 0) || (mapH 
> (WORLD_X 
- 6)) || 
 628       (mapV 
< 0) || (mapV 
> (WORLD_Y 
- 6))) 
 631   h 
= xMap 
= holdMapH 
= mapH
; 
 636   for (rowNum 
= 0; rowNum 
<= 5; rowNum
++) { 
 639     for (columnNum 
= 0; columnNum 
<= 5; columnNum
++) { 
 640       tileValue 
= Map
[mapH
++][mapV
] & LOMASK
; 
 643         /* if autoDoze is enabled, add up the cost of bulldozed tiles */ 
 644         if (tileValue 
!= 0) { 
 645           if (tally(tileValue
)) { 
 652         /* check and see if the tile is clear or not  */ 
 653         if (tileValue 
!= 0) { 
 665   cost 
+= CostOf
[tool
]; 
 667   if ((TotalFunds 
- cost
) < 0) { 
 673       (cost 
>= Expensive
) && 
 675       (view
->super_user 
== 0)) { 
 679   /* take care of the money situtation here */ 
 683   mapV 
= v
; holdMapH 
= h
; 
 685   for (rowNum 
= 0; rowNum 
<= 5; rowNum
++) { 
 688     for (columnNum 
= 0; columnNum 
<= 5; columnNum
++) { 
 689       if (columnNum 
== 1 && rowNum 
== 1) { 
 690         Map
[mapH
++][mapV
] = base 
+ BNCNBIT 
+ ZONEBIT
; 
 692         Map
[mapH
++][mapV
] = base 
+ BNCNBIT
; 
 698   check6x6border(xMap
, yMap
); 
 706 /* search table for zone status string match */ 
 707 static short idArray
[28] = { 
 708   DIRT
, RIVER
, TREEBASE
, RUBBLE
, 
 709   FLOOD
, RADTILE
, FIRE
, ROADBASE
, 
 710   POWERBASE
, RAILBASE
, RESBASE
, COMBASE
, 
 711   INDBASE
, PORTBASE
, AIRPORTBASE
, COALBASE
, 
 712   FIRESTBASE
, POLICESTBASE
, STADIUMBASE
, NUCLEARBASE
, 
 713   827, 832, FOUNTAIN
, INDBASE2
, 
 714   FOOTBALLGAME1
, VBRDG0
, 952, 956 
 726   Clear, Water, Trees, Rubble,  
 727   Flood, Radioactive Waste, Fire, Road, 
 728   Power, Rail, Residential, Commercial, 
 729   Industrial, Port, AirPort, Coal Power, 
 730   Fire Department, Police Department, Stadium, Nuclear Power,  
 731   Draw Bridge, Radar Dish, Fountain, Industrial, 
 732   49er's 38  Bears 3, Draw Bridge, Ur 238 
 736 int getDensityStr(short catNo
, short mapH
, short mapV
) 
 742     z 
= PopDensity
[mapH 
>>1][mapV 
>>1]; 
 747     z 
= LandValueMem
[mapH 
>>1][mapV 
>>1]; 
 748     if (z 
< 30) return (4); 
 749     if (z 
< 80) return (5); 
 750     if (z 
< 150) return (6); 
 753     z 
= CrimeMem
[mapH 
>>1][mapV 
>>1]; 
 758     z 
= PollutionMem
[mapH 
>>1][mapV 
>>1]; 
 759     if ((z 
< 64) && (z 
> 0)) return (13); 
 764     z 
= RateOGMem
[mapH 
>>3][mapV 
>>3]; 
 765     if (z 
< 0) return (16); 
 766     if  (z 
== 0) return (17); 
 767     if  (z 
> 100) return (19); 
 775 doZoneStatus(short mapH
, short mapV
) 
 778   char statusStr
[5][256]; 
 784   tileNum 
= Map
[mapH
][mapV
] & LOMASK
; 
 786   if (tileNum 
>= COALSMOKE1 
&& tileNum 
< FOOTBALLGAME1
) 
 790   for (x 
= 1; x 
< 29 && found
; x
++) { 
 791     if (tileNum 
< idArray
[x
]) { 
 800   GetIndString(localStr
, 219, x
); 
 802   for (x 
= 0; x 
< 5; x
++) { 
 803     id 
= getDensityStr(x
, mapH
, mapV
); 
 806     if (id 
> 20) id 
= 20; 
 807     GetIndString(statusStr
[x
], 202, id
); 
 810   DoShowZoneStatus(localStr
, statusStr
[0], statusStr
[1], 
 811                    statusStr
[2], statusStr
[3], statusStr
[4], mapH
, mapV
); 
 816 DoShowZoneStatus(char *str
, char *s0
, char *s1
, char *s2
, char *s3
, char *s4
, 
 821   sprintf(buf
, "UIShowZoneStatus {%s} {%s} {%s} {%s} {%s} {%s} %d %d", 
 822           str
, s0
, s1
, s2
, s3
, s4
, x
, y
); 
 827 /* comefrom: processWand */ 
 829 put3x3Rubble(short x
, short y
) 
 831   register int xx
, yy
, zz
; 
 833   for (xx 
= x 
- 1; xx 
< x 
+ 2; xx
++) { 
 834     for (yy 
= y 
- 1; yy 
< y 
+ 2; yy
++)  { 
 835       if (TestBounds(xx
, yy
)) { 
 836         zz 
= Map
[xx
][yy
] & LOMASK
; 
 837         if ((zz 
!= RADTILE
) && (zz 
!= 0)) { 
 840              ? (TINYEXP 
+ Rand(2)) 
 850 /* comefrom: processWand */ 
 852 put4x4Rubble(short x
, short y
) 
 854   register int xx
, yy
, zz
; 
 856   for (xx 
= x 
- 1; xx 
< x 
+ 3; xx
++) { 
 857     for (yy 
= y 
- 1; yy 
< y 
+ 3; yy
++) { 
 858       if (TestBounds(xx
, yy
)) { 
 859         zz 
= Map
[xx
][yy
] & LOMASK
; 
 860         if ((zz 
!= RADTILE
) && (zz 
!= 0)) { 
 863              ? (TINYEXP 
+ Rand(2)) 
 873 /* comefrom: processWand */ 
 875 put6x6Rubble(short x
, short y
) 
 877   register int xx
, yy
, zz
; 
 879   for (xx 
= x 
- 1; xx 
< x 
+ 5; xx
++) { 
 880     for (yy 
= y 
- 1; yy 
< y 
+ 5; yy
++)  { 
 881       if (TestBounds(xx
, yy
)) { 
 882         zz 
= Map
[xx
][yy
] & LOMASK
; 
 883         if ((zz 
!= RADTILE
) && (zz 
!= 0)) { 
 886              ? (TINYEXP 
+ Rand(2)) 
 897 DidTool(SimView 
*view
, char *name
, short x
, short y
) 
 902     sprintf(buf
, "UIDidTool%s %s %d %d", 
 903             name
, Tk_PathName(view
->tkwin
), x
, y
); 
 910 DoSetWandState(SimView 
*view
, short state
) 
 914   sprintf(buf
, "UISetToolState %s %d", Tk_PathName(view
->tkwin
), state
); 
 919 /************************************************************************/ 
 924 query_tool(SimView 
*view
, short x
, short y
) 
 926   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
 927       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
 932   DidTool(view
, "Qry", x
, y
); 
 938 bulldozer_tool(SimView 
*view
, short x
, short y
) 
 940   unsigned short currTile
, temp
; 
 941   short zoneSize
, deltaH
, deltaV
; 
 944   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
 945       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
 949   currTile 
= Map
[x
][y
]; 
 950   temp 
= currTile 
& LOMASK
; 
 952   if (currTile 
& ZONEBIT
) { /* zone center bit is set */ 
 953     if (TotalFunds 
> 0) { 
 955       switch (checkSize(temp
)) { 
 957         MakeSound("city", "Explosion-High"); 
 963         MakeSound("city", "Explosion-Low"); 
 967         MakeSound("city", "Explosion-High"); 
 968         MakeSound("city", "Explosion-Low"); 
 976   } else if ((zoneSize 
= checkBigZone(temp
, &deltaH
, &deltaV
))) { 
 977     if (TotalFunds 
> 0) { 
 981         MakeSound("city", "Explosion-High"); 
 985         MakeSound("city", "Explosion-Low"); 
 986         put4x4Rubble(x 
+ deltaH
, y 
+ deltaV
); 
 990         MakeSound("city", "Explosion-High"); 
 991         MakeSound("city", "Explosion-Low"); 
 992         put6x6Rubble(x 
+ deltaH
, y 
+ deltaV
); 
 997     if (temp 
== RIVER 
|| temp 
== REDGE 
|| temp 
== CHANNEL
) { 
 998       if (TotalFunds 
>= 6) { 
 999         result 
= ConnecTile(x
, y
, &Map
[x
][y
], 1); 
1000         if (temp 
!= (Map
[x
][y
] & LOMASK
)) { 
1007       result 
= ConnecTile(x
, y
, &Map
[x
][y
], 1); 
1012     DidTool(view
, "Dozr", x
, y
); 
1019 road_tool(SimView 
*view
, short x
, short y
) 
1023   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1024       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1028   result 
= ConnecTile(x
, y
, &Map
[x
][y
], 2); 
1031     DidTool(view
, "Road", x
, y
); 
1038 rail_tool(SimView 
*view
, short x
, short y
) 
1042   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1043       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1047   result 
= ConnecTile(x
, y
, &Map
[x
][y
], 3); 
1050     DidTool(view
, "Rail", x
, y
); 
1057 wire_tool(SimView 
*view
, short x
, short y
) 
1061   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1062       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1066   result 
= ConnecTile(x
, y
, &Map
[x
][y
], 4); 
1069     DidTool(view
, "Wire", x
, y
); 
1076 park_tool(SimView 
*view
, short x
, short y
) 
1080   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1081       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) 
1084   result 
= putDownPark(view
, x
, y
); 
1086     DidTool(view
, "Park", x
, y
); 
1093 residential_tool(SimView 
*view
, short x
, short y
) 
1097   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1098       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1102   result 
= check3x3(view
, x
, y
, RESBASE
, residentialState
); 
1104     DidTool(view
, "Res", x
, y
); 
1111 commercial_tool(SimView 
*view
, short x
, short y
) 
1115   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1116       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1120   result 
= check3x3(view
, x
, y
, COMBASE
, commercialState
); 
1122     DidTool(view
, "Com", x
, y
); 
1129 industrial_tool(SimView 
*view
, short x
, short y
) 
1133   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1134       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1138   result 
= check3x3(view
, x
, y
, INDBASE
, industrialState
); 
1140     DidTool(view
, "Ind", x
, y
); 
1147 police_dept_tool(SimView 
*view
, short x
, short y
) 
1151   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1152       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1156   result 
= check3x3(view
, x
, y
, POLICESTBASE
, policeState
); 
1158     DidTool(view
, "Pol", x
, y
); 
1165 fire_dept_tool(SimView 
*view
, short x
, short y
) 
1169   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1170       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1174   result 
= check3x3(view
, x
, y
, FIRESTBASE
, fireState
); 
1176     DidTool(view
, "Fire", x
, y
); 
1183 stadium_tool(SimView 
*view
, short x
, short y
) 
1187   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1188       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1192   result 
= check4x4(view
, x
, y
, STADIUMBASE
, 0, stadiumState
); 
1194     DidTool(view
, "Stad", x
, y
); 
1201 coal_power_plant_tool(SimView 
*view
, short x
, short y
) 
1205   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1206       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1210   result 
= check4x4(view
, x
, y
, COALBASE
, 1, powerState
); 
1212     DidTool(view
, "Coal", x
, y
); 
1219 nuclear_power_plant_tool(SimView 
*view
, short x
, short y
) 
1223   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1224       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1228   result 
= check4x4(view
, x
, y
, NUCLEARBASE
, 1, nuclearState
); 
1230     DidTool(view
, "Nuc", x
, y
); 
1237 seaport_tool(SimView 
*view
, short x
, short y
) 
1241   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1242       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1246   result 
= check4x4(view
, x
, y
, PORTBASE
, 0, seaportState
); 
1248     DidTool(view
, "Seap", x
, y
); 
1255 airport_tool(SimView 
*view
, short x
, short y
) 
1259   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1260       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1264   result 
= check6x6(view
, x
, y
, AIRPORTBASE
, airportState
); 
1266     DidTool(view
, "Airp", x
, y
); 
1273 network_tool(SimView 
*view
, short x
, short y
) 
1277   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1278       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1282   result 
= putDownNetwork(view
, x
, y
); 
1284     DidTool(view
, "Net", x
, y
); 
1292 special_tool(SimView 
*view
, short x
, short y
) 
1296   if ((x 
< 0) || (x 
> (WORLD_X 
- 1)) || 
1297       (y 
< 0) || (y 
> (WORLD_Y 
- 1))) { 
1301   result 
= check3x3(view
, x
, y
, specialBase
, specialState
); 
1303     DidTool(view
, "Special", x
, y
); 
1310 ChalkTool(SimView 
*view
, short x
, short y
, short color
, short first
) 
1313     ChalkStart(view
, x
, y
, color
); 
1315     ChalkTo(view
, x
, y
); 
1317   DidTool(view
, "Chlk", x
, y
); 
1323 ChalkStart(SimView 
*view
, int x
, int y
, int color
) 
1328   for (ip 
= &sim
->overlay
; *ip 
!= NULL
; ip 
= &((*ip
)->next
)) ; 
1330   *ip 
= ink 
= NewInk(); 
1331   ink
->x 
= x
; ink
->y 
= y
; 
1333   StartInk(ink
, x
, y
); 
1334   view
->track_info 
= (char *)ink
; 
1337   view
->tool_event_time 
= view
->tool_last_event_time 
= 
1338     ((TkWindow 
*)view
->tkwin
)->dispPtr
->lastEventTime
; 
1343 ChalkTo(SimView 
*view
, int x
, int y
) 
1348   Ink 
*ink 
= (Ink 
*)view
->track_info
; 
1351   if (view
->x
->dpy
->motion_buffer
) { 
1352     XTimeCoord 
*coords 
= NULL
, *coord
; 
1355     view
->tool_last_event_time 
= view
->tool_event_time
; 
1356     view
->tool_event_time 
= 
1357       ((TkWindow 
*)view
->tkwin
)->dispPtr
->lastEventTime
; 
1359     coords 
= XGetMotionEvents(view
->x
->dpy
, 
1360                               Tk_WindowId(view
->tkwin
), 
1361                               view
->tool_last_event_time
, 
1362                               view
->tool_event_time
, 
1365 printf("got %d events at %x from %d to %d (%d elapsed)\n", 
1367        view
->tool_last_event_time
, view
->tool_event_time
, 
1368        view
->tool_event_time 
- view
->tool_last_event_time
); 
1371       lx 
= ink
->last_x
; ly 
= ink
->last_y
; 
1373       for (i 
= 0, coord 
= coords
; i 
< n
; i
++, coord
++) { 
1374         ViewToPixelCoords(view
, coord
->x
, coord
->y
, &x0
, &y0
); 
1375         lx 
= (lx 
+ lx 
+ lx 
+ x0
) >>2; 
1376         ly 
= (ly 
+ ly 
+ ly 
+ y0
) >>2; 
1378 printf("adding %d %d => %d %d => %d %d\n", 
1379        coord
->x
, coord
->y
, x0
, y0
, lx
, ly
); 
1381         AddInk(ink
, lx
, ly
); 
1386       XFree((char *)coords
); 
1398 EraserTool(SimView 
*view
, short x
, short y
, short first
) 
1401     EraserStart(view
, x
, y
); 
1403     EraserTo(view
, x
, y
); 
1405   DidTool(view
, "Eraser", x
, y
); 
1411 InkInBox(Ink 
*ink
, int left
, int top
, int right
, int bottom
) 
1413   if ((left 
<= ink
->right
) && 
1414       (right 
>= ink
->left
) && 
1415       (top 
<= ink
->bottom
) && 
1416       (bottom 
>= ink
->top
)) { 
1417     int x
, y
, lx
, ly
, i
; 
1419     if (ink
->length 
== 1) { 
1423     x 
= ink
->x
;  y 
= ink
->y
; 
1424     for (i 
= 1; i 
< ink
->length
; i
++) { 
1425       int ileft
, iright
, itop
, ibottom
; 
1428       x 
+= ink
->points
[i
].x
;  y 
+= ink
->points
[i
].y
; 
1429       if (x 
< lx
) { ileft 
= x
; iright 
= lx
; } 
1430       else { ileft 
= lx
; iright 
= x
; } 
1431       if (y 
< ly
) { itop 
= y
; ibottom 
= ly
; } 
1432       else { itop 
= ly
; ibottom 
= y
; } 
1433       if ((left 
<= iright
) && 
1446 EraserStart(SimView 
*view
, int x
, int y
) 
1448   EraserTo(view
, x
, y
); 
1453 EraserTo(SimView 
*view
, int x
, int y
) 
1457   for (ip 
= &sim
->overlay
; *ip 
!= NULL
;) { 
1459     if (InkInBox(ink
, x 
- 8, y 
- 8, x 
+ 8, y 
+ 8)) { 
1461       for (view 
= sim
->editor
; view 
!= NULL
; view 
= view
->next
) { 
1464         if ((ink
->right 
>= (vleft 
= (view
->pan_x 
- (view
->w_width 
/ 2)))) && 
1465             (ink
->left 
<= (vleft 
+ view
->w_width
)) && 
1466             (ink
->bottom 
>= (vtop 
= (view
->pan_y 
- (view
->w_height 
/ 2)))) && 
1467             (ink
->top 
<= (vtop 
+ view
->w_height
))) { 
1468           view
->overlay_mode 
= 0; 
1469           EventuallyRedrawView(view
); 
1477       ip 
= &((*ip
)->next
); 
1484 do_tool(SimView 
*view
, short state
, short x
, short y
, short first
) 
1489   case residentialState
: 
1490     result 
= residential_tool(view
, x 
>>4, y 
>>4); 
1492   case commercialState
: 
1493     result 
= commercial_tool(view
, x 
>>4, y 
>>4); 
1495   case industrialState
: 
1496     result 
= industrial_tool(view
, x 
>>4, y 
>>4); 
1499     result 
= fire_dept_tool(view
, x 
>>4, y 
>>4); 
1502     result 
= query_tool(view
, x 
>>4, y 
>>4); 
1505     result 
= police_dept_tool(view
, x 
>>4, y 
>>4); 
1508     result 
= wire_tool(view
, x 
>>4, y 
>>4); 
1511     result 
= bulldozer_tool(view
, x 
>>4, y 
>>4); 
1514     result 
= rail_tool(view
, x 
>>4, y 
>>4); 
1517     result 
= road_tool(view
, x 
>>4, y 
>>4); 
1520     result 
= ChalkTool(view
, x 
- 5, y 
+ 11, COLOR_WHITE
, first
); 
1523     result 
= EraserTool(view
, x
, y
, first
); 
1526     result 
= stadium_tool(view
, x 
>>4, y 
>>4); 
1529     result 
= park_tool(view
, x 
>>4, y 
>>4); 
1532     result 
= seaport_tool(view
, x 
>>4, y 
>>4); 
1535     result 
= coal_power_plant_tool(view
, x 
>>4, y 
>>4); 
1538     result 
= nuclear_power_plant_tool(view
, x 
>>4, y 
>>4); 
1541     result 
= airport_tool(view
, x 
>>4, y 
>>4); 
1544     result 
= network_tool(view
, x 
>>4, y 
>>4); 
1557 current_tool(SimView 
*view
, short x
, short y
, short first
) 
1559   return do_tool(view
, view
->tool_state
, x
, y
, first
); 
1564 DoTool(SimView 
*view
, short tool
, short x
, short y
) 
1568   result 
= do_tool(view
, tool
, x 
<<4, y 
<<4, 1); 
1573     MakeSoundOn(view
, "edit", "UhUh"); 
1574   } else if (result 
== -2) { 
1577     MakeSoundOn(view
, "edit", "Sorry"); 
1582   InvalidateEditors(); 
1587 ToolDown(SimView 
*view
, int x
, int y
) 
1591   ViewToPixelCoords(view
, x
, y
, &x
, &y
); 
1595   result 
= current_tool(view
, x
, y
, 1); 
1600     MakeSoundOn(view
, "edit", "UhUh"); 
1601   } else if (result 
== -2) { 
1604     MakeSoundOn(view
, "edit", "Sorry"); 
1605   } else if (result 
== -3) { 
1606     DoPendTool(view
, view
->tool_state
, x 
>>4, y 
>>4); 
1616 ToolUp(SimView 
*view
, int x
, int y
) 
1618   ToolDrag(view
, x
, y
); 
1623 ToolDrag(SimView 
*view
, int px
, int py
) 
1625   int x
, y
, dx
, dy
, adx
, ady
, lx
, ly
, dist
; 
1626   float i
, step
, tx
, ty
, dtx
, dty
, rx
, ry
; 
1628   ViewToPixelCoords(view
, px
, py
, &x
, &y
); 
1629   view
->tool_x 
= x
; view
->tool_y 
= y
; 
1631   if ((view
->tool_state 
== chalkState
) || 
1632       (view
->tool_state 
== eraserState
)) { 
1634     current_tool(view
, x
, y
, 0); 
1635     view
->last_x 
= x
; view
->last_y 
= y
; 
1639     dist 
= toolSize
[view
->tool_state
]; 
1642     lx 
= view
->last_x 
>> 4; 
1643     ly 
= view
->last_y 
>> 4; 
1648     if (dx 
== 0 && dy 
== 0) { 
1652     adx 
= ABS(dx
); ady 
= ABS(dy
); 
1660     rx 
= (dx 
< 0 ? 1 : 0); 
1661     ry 
= (dy 
< 0 ? 1 : 0); 
1664       for (i 
= 0.0; i 
<= 1 + step
; i 
+= step
) { 
1665         tx 
= (view
->last_x 
>>4) + i 
* dx
; 
1666         ty 
= (view
->last_y 
>>4) + i 
* dy
; 
1669         if (dtx 
>= 1 || dty 
>= 1) { 
1670           /* fill in corners */ 
1671           if ((dtx 
>= 1) && (dty 
>= 1)) { 
1673               current_tool(view
, ((int)(tx 
+ rx
)) <<4, ly 
<<4, 0); 
1675               current_tool(view
, lx 
<<4, ((int)(ty 
+ ry
)) <<4, 0); 
1678           lx 
= (int)(tx 
+ rx
); 
1679           ly 
= (int)(ty 
+ ry
); 
1680           current_tool(view
, lx 
<<4, ly 
<<4, 0); 
1684       for (i 
= 0.0; i 
<= 1 + step
; i 
+= step
) { 
1685         tx 
= (view
->last_x 
>>4) + i 
* dx
; 
1686         ty 
= (view
->last_y 
>>4) + i 
* dy
; 
1689         lx 
= (int)(tx 
+ rx
); 
1690         ly 
= (int)(ty 
+ ry
); 
1691         current_tool(view
, lx 
<<4, ly 
<<4, 0); 
1695     view
->last_x 
= (lx 
<<4) + 8; 
1696     view
->last_y 
= (ly 
<<4) + 8; 
1698   sim_skip 
= 0; /* update editors overlapping this one */ 
1705 DoPendTool(SimView 
*view
, int tool
, int x
, int y
) 
1709   sprintf(buf
, "DoPendTool %s %d %d %d", 
1710           Tk_PathName(view
->tkwin
), tool
, x
, y
);