Annotation of micropolis/res/micropolis.tcl, revision 1.1.1.1

1.1       root        1: #######################################################################
                      2: # Micropolis.tcl, by Don Hopkins.
                      3: # Copyright (C) 2002 by Electronic Arts.
                      4: # This file defines the user interface of Micropolis. 
                      5: # Modify at your own risk!
                      6: ########################################################################
                      7: # Micropolis, Unix Version.  This game was released for the Unix platform
                      8: # in or about 1990 and has been modified for inclusion in the One Laptop
                      9: # Per Child program.  Copyright (C) 1989 - 2007 Electronic Arts Inc.  If
                     10: # you need assistance with this program, you may contact:
                     11: #   http://wiki.laptop.org/go/Micropolis  or email  [email protected].
                     12: # 
                     13: # This program is free software: you can redistribute it and/or modify
                     14: # it under the terms of the GNU General Public License as published by
                     15: # the Free Software Foundation, either version 3 of the License, or (at
                     16: # your option) any later version.
                     17: # 
                     18: # This program is distributed in the hope that it will be useful, but
                     19: # WITHOUT ANY WARRANTY; without even the implied warranty of
                     20: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     21: # General Public License for more details.  You should have received a
                     22: # copy of the GNU General Public License along with this program.  If
                     23: # not, see <http://www.gnu.org/licenses/>.
                     24: # 
                     25: #             ADDITIONAL TERMS per GNU GPL Section 7
                     26: # 
                     27: # No trademark or publicity rights are granted.  This license does NOT
                     28: # give you any right, title or interest in the trademark SimCity or any
                     29: # other Electronic Arts trademark.  You may not distribute any
                     30: # modification of this program using the trademark SimCity or claim any
                     31: # affliation or association with Electronic Arts Inc. or its employees.
                     32: # 
                     33: # Any propagation or conveyance of this program must include this
                     34: # copyright notice and these terms.
                     35: # 
                     36: # If you convey this program (or any modifications of it) and assume
                     37: # contractual liability for the program to recipients of it, you agree
                     38: # to indemnify Electronic Arts for any liability that those contractual
                     39: # assumptions impose on Electronic Arts.
                     40: # 
                     41: # You may not misrepresent the origins of this program; modified
                     42: # versions of the program must be marked as such and not identified as
                     43: # the original program.
                     44: # 
                     45: # This disclaimer supplements the one included in the General Public
                     46: # License.  TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
                     47: # PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
                     48: # OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK.  THE ENTIRE RISK OF
                     49: # SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU.  ELECTRONIC ARTS
                     50: # DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
                     51: # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
                     52: # FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
                     53: # RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
                     54: # USAGE, OR TRADE PRACTICE.  ELECTRONIC ARTS DOES NOT WARRANT AGAINST
                     55: # INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
                     56: # MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
                     57: # UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
                     58: # WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
                     59: # CORRECTED.  NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
                     60: # ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY.  SOME
                     61: # JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
                     62: # WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
                     63: # CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
                     64: # NOT APPLY TO YOU.
                     65: 
                     66: 
                     67: ########################################################################
                     68: # Libraries
                     69: ########################################################################
                     70: 
                     71: 
                     72: set errorInfo {}
                     73: set auto_noexec 1
                     74: 
                     75: source $tk_library/wish.tcl
                     76: 
                     77: 
                     78: ########################################################################
                     79: # Globals
                     80: ########################################################################
                     81: 
                     82: 
                     83: set UniqueID 0
                     84: set State uninitialized
                     85: set CityName "Micropolis"
                     86: set GameLevel 0
                     87: set SimHome [pwd]
                     88: set CityLibDir $SimHome/cities
                     89: set CityDir $CityLibDir
                     90: set OldBudget 0
                     91: set BudgetRoadFund 0
                     92: set BudgetFireFund 0
                     93: set BudgetPoliceFund 0
                     94: set BudgetTaxRate 0
                     95: set DemandRes 0
                     96: set DemandCom 0
                     97: set DemandInd 0
                     98: set Priority 2
                     99: set Time 3
                    100: set AutoGoto 1
                    101: set AutoBudget 1
                    102: set Disasters 1
                    103: set AutoBulldoze 1
                    104: set Sound 1
                    105: set DoAnimation 1
                    106: set DoMessages 1
                    107: set DoNotices 1
                    108: set ShapePies 1
                    109: set SoundServers {}
                    110: set AudioChannels {mode edit fancy warning intercom}
                    111: set BudgetTimeout 30
                    112: set BudgetTimer 0
                    113: set BudgetTimerActive 0
                    114: set BudgetsVisible 0
                    115: set EvaluationsVisible 0
                    116: set SplashScreenDelay 5000
                    117: set Scenario -1
                    118: set Chatting 0
                    119: set ChatServer "localhost"
                    120: set ChatSocket 6667
                    121: set ChatConnection {}
                    122: set NickName "nickname"
                    123: set UserName "username"
                    124: set ServerName "servername"
                    125: set RealName "realname"
                    126: set ChannelName "#Micropolis"
                    127: set HomeDir ""
                    128: set ResourceDir ""
                    129: set HostName ""
                    130: set LocalHostName "[exec hostname]"
                    131: set SaveCityWin ""
                    132: set MapHistory {}
                    133: set MapHistoryNum -1
                    134: set HelpLoaded 0
                    135: set QueryX 0
                    136: set QueryY 0
                    137: set FreeVotes 0
                    138: set ShowingPicture 300
                    139: set MaxLines 500
                    140: set ShrinkLines 250
                    141: set ShowingParms {}
                    142: set VoteNames {UseThisMap Ask Zone}
                    143: set VotesForUseThisMap {}
                    144: set VotesForAsk {}
                    145: set VotesForZone {}
                    146: set VotesForBudget {}
                    147: set CurrentDate {}
                    148: 
                    149: set HeadWindows {}
                    150: set EditorWindows {}
                    151: set MapWindows {}
                    152: set GraphWindows {}
                    153: set BudgetWindows {}
                    154: set EvaluationWindows {}
                    155: set SplashWindows {}
                    156: set ScenarioWindows {}
                    157: set FileWindows {}
                    158: set AskWindows {}
                    159: set PlayerWindows {}
                    160: set NoticeWindows {}
                    161: set HelpWindows {}
                    162: set FrobWindows {}
                    163: 
                    164: set HeadPanelWidth 360
                    165: set HeadPanelHeight 200
                    166: 
                    167: set MapPanelWidth 360
                    168: set MapPanelHeight 330
                    169: 
                    170: set NoticePanelWidth 360
                    171: set NoticePanelHeight 250
                    172: 
                    173: set SplashPanelWidth 1200
                    174: set SplashPanelHeight 900
                    175: 
                    176: set ScenarioPanelWidth 420
                    177: set ScenarioPanelHeight 440
                    178: 
                    179: set SugarURI ""
                    180: set SugarNickName ""
                    181: set SugarShared 0
                    182: set SugarActivated 0
                    183: set SugarBuddies {}
                    184: 
                    185: set SubWindows {
                    186:   {editor EditorWindows}
                    187:   {map MapWindows}
                    188:   {graph GraphWindows}
                    189:   {budget BudgetWindows}
                    190:   {evaluation EvaluationWindows}
                    191:   {scenario ScenarioWindows}
                    192:   {splash SplashWindows}
                    193:   {file FileWindows}
                    194:   {ask AskWindows}
                    195:   {player PlayerWindows}
                    196:   {notice NoticeWindows}
                    197:   {help HelpWindows}
                    198:   {frob FrobWindows}
                    199:   {head HeadWindows}
                    200: }
                    201: 
                    202: 
                    203: #   0           1               2               3       4         5   6   7   8         9       10   11       12      13
                    204: #   type       id              callback        param   var       x   y   w   h         normal  over disabled checked checkedover
                    205: #   ----------- --------------- --------------- ------- ------- --- --- --- ---         ------- ---- -------- ------- -----------
                    206: set ScenarioButtons {
                    207:   { button     load            DoLoad          ""      ""       70 238 157  90         ""      @images/button1hilite.xpm "" }
                    208:   { button     generate        DoGenerate      ""      ""       62 392 157  90         ""      @images/button2hilite.xpm "" }
                    209:   { button     quit            DoQuit          ""      ""       68 544 157  90         ""      @images/button3hilite.xpm "" }
                    210:   { button     about           DoAbout         ""      ""      101 705 157  90         ""      @images/button4hilite.xpm "" }
                    211:   { checkbox   easy            DoLevel         0       ""      982 106 190  70         ""      @images/checkbox1hilite.xpm "" @images/checkbox1checked.xpm @images/checkbox1hilitechecked.xpm }
                    212:   { checkbox   medium          DoLevel         1       ""      982 176 190  70         ""      @images/checkbox2hilite.xpm "" @images/checkbox2checked.xpm @images/checkbox2hilitechecked.xpm }
                    213:   { checkbox   hard            DoLevel         2       ""      982 246 190  70         ""      @images/checkbox3hilite.xpm "" @images/checkbox3checked.xpm @images/checkbox3hilitechecked.xpm }
                    214:   { button     left            DoLeft          ""      ""      540 375  50  50         ""      @images/lefthilite.xpm @images/leftdisabled.xpm }
                    215:   { button     right           DoRight         ""      ""      841 375  50  50         ""      @images/righthilite.xpm @images/rightdisabled.xpm }
                    216:   { button     play            DoPlay          ""      ""      625 376 180  50         ""      @images/playhilite.xpm "" }
                    217:   { button     scenario1       DoPickScenario  "1"     ""      310 451 209 188         ""      @images/scenario1hilite.xpm "" }
                    218:   { button     scenario2       DoPickScenario  "2"     ""      519 451 209 188         ""      @images/scenario2hilite.xpm "" }
                    219:   { button     scenario3       DoPickScenario  "3"     ""      727 450 209 188         ""      @images/scenario3hilite.xpm "" }
                    220:   { button     scenario4       DoPickScenario  "4"     ""      936 450 209 188         ""      @images/scenario4hilite.xpm "" }
                    221:   { button     scenario5       DoPickScenario  "5"     ""      310 639 209 188         ""      @images/scenario5hilite.xpm "" }
                    222:   { button     scenario6       DoPickScenario  "8"     ""      519 639 209 188         ""      @images/scenario6hilite.xpm "" }
                    223:   { button     scenario7       DoPickScenario  "7"     ""      728 638 209 188         ""      @images/scenario7hilite.xpm "" }
                    224:   { button     scenario8       DoPickScenario  "6"     ""      937 638 209 188         ""      @images/scenario8hilite.xpm "" }
                    225: }
                    226: 
                    227: # Disabled until we handle mouse events on the map itself.
                    228: #   { button   map             DoMap           ""      ""      516  30 396 338         ""      @images/maphilite.xpm }
                    229: 
                    230: 
                    231: ########################################################################
                    232: # Fonts
                    233: 
                    234: 
                    235: set FontInfo {
                    236:   {Big {
                    237:        {-*-dejavu lgc sans-medium-r-normal-*-90-*}
                    238:   }}
                    239:   {Large {
                    240:        {-*-dejavu lgc sans-medium-r-normal-*-80-*}
                    241:   }}
                    242:   {Medium {
                    243:        {-*-dejavu lgc sans-medium-r-normal-*-70-*}
                    244:   }}
                    245:   {Small {
                    246:        {-*-dejavu lgc sans-medium-r-normal-*-60-*}
                    247:   }}
                    248:   {Narrow {
                    249:        {-*-dejavu lgc sans-medium-r-normal-*-60-*}
                    250:   }}
                    251:   {Tiny {
                    252:        {-*-dejavu lgc sans-medium-r-normal-*-60-*}
                    253:   }}
                    254:   {Text {
                    255:        {-*-dejavu lgc sans-medium-r-normal-*-70-*}
                    256:   }}
                    257:   {Message {
                    258:        {-*-dejavu lgc sans-medium-r-normal-*-70-*}
                    259:   }}
                    260:   {Alert {
                    261:        {-*-dejavu lgc sans-medium-r-normal-*-70-*}
                    262:   }}
                    263: }
                    264: 
                    265: 
                    266: ########################################################################
                    267: 
                    268: 
                    269: set MapTitles {
                    270:   {Micropolis Overall Map}
                    271:   {Residential Zone Map}
                    272:   {Commercial Zone Map}
                    273:   {Industrial Zone Map}
                    274:   {Power Grid Map}
                    275:   {Transportation Map}
                    276:   {Population Density Map}
                    277:   {Rate of Growth Map}
                    278:   {Traffic Density Map}
                    279:   {Pollution Desity Map}
                    280:   {Crime Rate Map}
                    281:   {Land Value Map}
                    282:   {Fire Coverage Map}
                    283:   {Police Coverage Map}
                    284:   {Dynamic Filter Map}
                    285: }
                    286: 
                    287: 
                    288: set EditorPallets {
                    289:   leftframe.tools.palletres
                    290:   leftframe.tools.palletcom
                    291:   leftframe.tools.palletind
                    292:   leftframe.tools.palletfire
                    293:   leftframe.tools.palletquery
                    294:   leftframe.tools.palletpolice
                    295:   leftframe.tools.palletwire
                    296:   leftframe.tools.palletbulldozer
                    297:   leftframe.tools.palletrail
                    298:   leftframe.tools.palletroad
                    299:   leftframe.tools.palletchalk
                    300:   leftframe.tools.palleteraser
                    301:   leftframe.tools.palletstadium
                    302:   leftframe.tools.palletpark
                    303:   leftframe.tools.palletseaport
                    304:   leftframe.tools.palletcoal
                    305:   leftframe.tools.palletnuclear
                    306:   leftframe.tools.palletairport
                    307: }
                    308: 
                    309: 
                    310: set EditorPalletImages { 
                    311:   res com ind fire qry pol
                    312:   wire dozr rail road chlk ersr
                    313:   stad park seap coal nuc airp
                    314: }
                    315: 
                    316: 
                    317: set EditorPalletSounds { 
                    318:   Res Com Ind Fire Query Police
                    319:   Wire Bulldozer Rail Road Chalk Eraser
                    320:   Stadium Park Seaport Coal Nuclear Airport
                    321: }
                    322: 
                    323: 
                    324: set GraphPallets {
                    325:   leftframe.left.res
                    326:   leftframe.left.com
                    327:   leftframe.left.ind
                    328:   leftframe.right.money
                    329:   leftframe.right.crime
                    330:   leftframe.right.pollution
                    331: }
                    332: 
                    333: 
                    334: set GraphPalletImages { 
                    335:   res com ind mony crim poll
                    336: }
                    337: 
                    338: 
                    339: set GraphYearPallets {
                    340:   leftframe.year.year10
                    341:   leftframe.year.year120
                    342: }
                    343: 
                    344: 
                    345: set GraphYearPalletImages { 10 120 }
                    346: 
                    347: 
                    348: set ToolInfo {
                    349:   {     {a}    {Residential Zone}      {$100}}
                    350:   {     {a}    {Commercial Zone}       {$100}}
                    351:   {     {an}   {Industrial Zone}       {$100}}
                    352:   {     {a}    {Fire Station}          {$500}}
                    353:   {     {a}    {Query}                 {free}}
                    354:   {     {a}    {Police Station}        {$500}}
                    355:   {     {a}    {Wire}                  {$5}}
                    356:   {     {a}    {Bulldozer}             {$1}}
                    357:   {     {a}    {Rail}                  {$20}}
                    358:   {     {a}    {Road}                  {$10}}
                    359:   {     {a}    {Chalk}                 {free}}
                    360:   {     {an}   {Eraser}                {free}}
                    361:   {     {a}    {Stadium}               {$5,000}}
                    362:   {     {a}    {Park}                  {$20}}
                    363:   {     {a}    {Seaport}               {$3,000}}
                    364:   {     {a}    {Coal Power Plant}      {$3,000}}
                    365:   {     {a}    {Nuclear Power Plant}   {$5,000}}
                    366:   {     {an}   {Airport}               {$10,000}}
                    367:   {     {a}    {Network}               {$1,000}}
                    368: }
                    369: 
                    370: 
                    371: set DynamicDataNames {
                    372:   {Population Density}
                    373:   {Rate of Growth}
                    374:   {Traffic Density}
                    375:   {Pollution Density}
                    376:   {Crime Rate}
                    377:   {Land Value}
                    378:   {Police Coverage}
                    379:   {Fire Coverage}
                    380: }
                    381: 
                    382: ########################################################################
                    383: # Initialization
                    384: ########################################################################
                    385: 
                    386: 
                    387: wm title . {Micropolis Root}
                    388: 
                    389: 
                    390: if {"[sim Platform]" == "msdos"} {
                    391:   sim DoAnimation 0
                    392:   set DoAnimation 0
                    393:   set ShapePies 0
                    394: } else {
                    395:   sim DoAnimation 1
                    396:   set DoAnimation 1
                    397:   set ShapePies 1
                    398: }
                    399: 
                    400: sprite explosion 7
                    401: sprite tornado 6
                    402: sprite airplane 3
                    403: sprite helicopter 2
                    404: sprite monster 5
                    405: sprite ship 4
                    406: sprite bus 8
                    407: sprite train 1
                    408: 
                    409: sim ResetDynamic
                    410: 
                    411: # The next three lines have no effect on the OLPC, where we don't provide
                    412: # the font in res (because it's already in the system fonts).  These lines
                    413: # are for other systems that lack the font.
                    414: set FontPath "[pwd]/res/dejavu-lgc"
                    415: system "xset -fp $FontPath >&/dev/null"
                    416: system "xset +fp $FontPath >&/dev/null"
                    417: 
                    418: 
                    419: ########################################################################
                    420: # Messages
                    421: ########################################################################
                    422: 
                    423: 
                    424: proc Message {id color title msg {props {}}} {
                    425:   global Messages
                    426:   set Messages($id) [list $color $title $msg $props]
                    427: }
                    428: 
                    429: 
                    430: Message 1 #7f7fff {DULLSVILLE, USA  1900} \
                    431: {Things haven't changed much around here in the last hundred years or so and the residents are beginning to get bored.  They think Dullsville could be the next great city with the right leader. 
                    432: 
                    433: It is your job to attract new growth and development, turning Dullsville into a Metropolis within 30 years.}
                    434: 
                    435: Message 2 #7f7fff {SAN FRANCISCO, CA.  1906} \
                    436: {Damage from the earthquake was minor compared to that of the ensuing fires, which took days to control.  1500 people died.
                    437: 
                    438: Controlling the fires should be your initial concern.  Then clear the rubble and start rebuilding.  You have 5 years.}
                    439:        
                    440: Message 3 #7f7fff {HAMBURG, GERMANY  1944} \
                    441: {Allied fire-bombing of German cities in WWII caused tremendous damage and loss of life.  People living in the inner cities were at greatest risk.
                    442: 
                    443: You must control the firestorms during the bombing and then rebuild the city after the war.  You have 5 years.}
                    444: 
                    445: Message 4 #7f7fff {BERN, SWITZERLAND  1965} \
                    446: {The roads here are becoming more congested every day, and the residents are upset.  They demand that you do something about it.
                    447: 
                    448: Some have suggested a mass transit system as the answer, but this would require major rezoning in the downtown area.  You have 10 years.}
                    449: 
                    450: Message 5 #7f7fff {TOKYO, JAPAN  1957} \
                    451: {A large reptilian creature has been spotted heading for Tokyo bay.  It seems to be attracted to the heavy levels of industrial pollution there.
                    452: 
                    453: Try to control the fires, then rebuild the industrial center.  You have 5 years.}
                    454: 
                    455: Message 6 #7f7fff {DETROIT, MI.  1972} \
                    456: {By 1970, competition from overseas and other economic factors pushed the once "automobile capital of the world" into recession.  Plummeting land values and unemployment then increased crime in the inner-city to chronic levels.
                    457: 
                    458: You have 10 years to reduce crime and rebuild the industrial base of the city.}
                    459: 
                    460: Message 7 #7f7fff {BOSTON, MA.  2010} \
                    461: {A major meltdown is about to occur at one of the new downtown nuclear reactors.  The area in the vicinity of the reactor will be severly contaminated by radiation, forcing you to restructure the city around it.
                    462: 
                    463: You have 5 years to get the situation under control.}
                    464: 
                    465: Message 8 #7f7fff {RIO DE JANEIRO, BRAZIL  2047} \
                    466: {In the mid-21st century, the greenhouse effect raised global temperatures 6 degrees F.  Polar icecaps melted and raised sea levels worldwide.  Coastal areas were devastated by flood and erosion.
                    467: 
                    468: You have 10 years to turn this swamp back into a city again.}
                    469: 
                    470: Message 9 #ffa500 {Query Zone Status} \
                    471: {
                    472: Zone:      %s
                    473: Density:    %s
                    474: Value:     %s
                    475: Crime:     %s
                    476: Pollution:  %s
                    477: Growth:            %s} \
                    478: {{view {PanView $v $QueryX $QueryY}}}
                    479: 
                    480: Message 10 #ff4f4f {POLLUTION ALERT!} \
                    481: {Pollution in your city has exceeded the maximum allowable amounts established by the Micropolis Pollution Agency.  You are running the risk of grave ecological consequences.
                    482: 
                    483: Either clean up your act or open a gas mask concession at city hall.} \
                    484: {{view {PanView $v [sim PolMaxX] [sim PolMaxY]}}}
                    485: 
                    486: Message 11 #ff4f4f {CRIME ALERT!} \
                    487: {Crime in your city is our of hand.  Angry mobs are looting and vandalizing the central city.  The president will send in the national guard soon if you cannot control the problem.} \
                    488: {{view {PanView $v [sim CrimeMaxX] [sim CrimeMaxY]}}}
                    489: 
                    490: Message 12 #ff4f4f {TRAFFIC WARNING!} \
                    491: {Traffic in this city is horrible.  The city gridlock is expanding.  The commuters are getting militant.
                    492: 
                    493: Either build more roads and rails or get a bulletproof limo.} \
                    494: {{view {PanView $v [sim TrafMaxX] [sim TrafMaxY]}}}
                    495: 
                    496: Message 20 #ff4f4f {FIRE REPORTED!} \
                    497: "A fire has been reported!" \
                    498: {{view {PanView $v [sim CrashX] [sim CrashY]}}}
                    499: 
                    500: Message 21 #ff4f4f {MONSTER ATTACK!} \
                    501: "A large reptilian creature has been spotted in the water.  It seems to be attracted to areas of high pollution.  There is a trail of destruction wherever it goes.  \
                    502: All you can do is wait till he leaves, then rebuild from the rubble." \
                    503: {{view {FollowView $v monster}}}
                    504: 
                    505: # XXX: write more text
                    506: Message 22 #ff4f4f {TORNADO ALERT!} \
                    507: {A tornado has been reported!  There's nothing you can do to stop it, so you'd better prepare to clean up after the disaster!} \
                    508: {{view {FollowView $v tornado}}}
                    509: 
                    510: # XXX: write more text
                    511: Message 23 #ff4f4f {EARTHQUAKE!} \
                    512: {A major earthquake has occurred!  Put out the fires as quickly as possible, before they spread, then reconnect the power grid and rebuild the city.} \
                    513: {{view {PanView $v [sim CenterX] [sim CenterY]}}}
                    514: 
                    515: # XXX: write more text
                    516: Message 24 #ff4f4f {PLANE CRASH!} \
                    517: {A plane has crashed!} \
                    518: {{view {PanView $v [sim CrashX] [sim CrashY]}}}
                    519: 
                    520: # XXX: write more text
                    521: Message 25 #ff4f4f {SHIPWRECK!} \
                    522: {A ship has wrecked!} \
                    523: {{view {PanView $v [sim CrashX] [sim CrashY]}}}
                    524: 
                    525: # XXX: write more text
                    526: Message 26 #ff4f4f {TRAIN CRASH!} \
                    527: {A train has crashed!} \
                    528: {{view {PanView $v [sim CrashX] [sim CrashY]}}}
                    529: 
                    530: # XXX: write more text
                    531: Message 27 #ff4f4f {HELICOPTER CRASH!} \
                    532: {A helicopter has crashed!} \
                    533: {{view {PanView $v [sim CrashX] [sim CrashY]}}}
                    534: 
                    535: Message 30 #ff4f4f {FIREBOMBING REPORTED!} \
                    536: {Firebombs are falling!!} \
                    537: {{view {PanView $v [sim CrashX] [sim CrashY]}}}
                    538: 
                    539: Message 35 #7fff7f {TOWN} \
                    540: {Congratulations, your village has grown to town status.  You now have 2,000 citizens.} \
                    541: {{view {PanView $v [sim CenterX] [sim CenterY]}}}
                    542: 
                    543: Message 36 #7fff7f {CITY} \
                    544: {Your town has grown into a full sized city, with a current population of 10,000.  Keep up the good work!} \
                    545: {{view {PanView $v [sim CenterX] [sim CenterY]}}}
                    546: 
                    547: Message 37 #7fff7f {CAPITAL} \
                    548: {Your city has become a capital.  The current population here is 50,000.  Your political future looks bright.} \
                    549: {{view {PanView $v [sim CenterX] [sim CenterY]}}}
                    550: 
                    551: Message 38 #7fff7f {METROPOLIS} \
                    552: {Your capital city has now achieved the status of metropolis.  The current population is 100,000.  With your management skills, you should seriously consider running for governor.} \
                    553: {{view {PanView $v [sim CenterX] [sim CenterY]}}}
                    554: 
                    555: Message 39 #7fff7f {MEGALOPOLIS} \
                    556: {Congratulation, you have reached the highest category of urban development, the megalopolis.
                    557: 
                    558: If you manage to reach this level, send us email at [email protected] or send us a copy of your city.  We might do something interesting with it.} \
                    559: {{view {PanView $v [sim CenterX] [sim CenterY]}}}
                    560: 
                    561: Message 40 #7fff7f {MEGALINIUM} \
                    562: {Congratulation, you have reached the end of time!
                    563: 
                    564: Because of the toroidal nature of the the Micropolis Space/Time Continuum, your city has wrapped back in time to 1900!} \
                    565: {{view {PanView $v [sim CenterX] [sim CenterY]}}}
                    566: 
                    567: # XXX: write more text
                    568: Message 41 #ff4f4f {HEAVY TRAFFIC!} \
                    569: {Sky Watch One
                    570: reporting heavy traffic!} \
                    571: {{view {FollowView $v helicopter}}}
                    572: 
                    573: # XXX: write more text
                    574: Message 42 #ff4f4f {FLOODING REPORTED!} \
                    575: {Flooding has been been reported along the water's edge!} \
                    576: {{view {PanView $v [sim FloodX] [sim FloodY]}}}
                    577: 
                    578: Message 43 #ff4f4f {NUCLEAR MELTDOWN!} \
                    579: {A nuclear meltdown has occured at your power plant.  You are advised to avoid the area until the radioactive isotopes decay.
                    580: 
                    581: Many generations will confront this problem before it goes away, so don't hold your breath.} \
                    582: {{view {PanView $v [sim MeltX] [sim MeltY]}}}
                    583: 
                    584: 
                    585: Message 44 #ff4f4f {RIOTS!} \
                    586: {The citizens are rioting in the streets, setting cars and houses on fire, and bombing government buildings and businesses!
                    587: 
                    588: All media coverage is blacked out, while the fascist pigs beat the poor citizens into submission.}
                    589: 
                    590: Message 46 #ff4f4f {NO SOUND SERVER!} \
                    591: {There is no sound server running on your X11 display "%s".  You won't hear any noise unless you run a sound server, and turn the sound back on in the "Options" menu.}
                    592: 
                    593: Message 48 #7f7fff {Start a New City} \
                    594: {Build your very own city from the ground up, starting with this map of uninhabited land.}
                    595: 
                    596: Message 49 #7f7fff {Restore a Saved City} \
                    597: {This city was saved in the file named: %s}
                    598: 
                    599: Message 100 #7fff7f {YOU'RE A WINNER!} \
                    600: {Your mayorial skill and city planning expertise have earned you the KEY TO THE CITY.  Local residents will erect monuments to your glory and name their first-born children after you.  Why not run for governor?} \
                    601: {{middle {@images/key2city.xpm}}}
                    602: 
                    603: Message 200 #ff4f4f {IMPEACHMENT NOTICE!} \
                    604: {The entire population of this city has finally had enough of your inept planning and incompetant management.  An angry mob -- led by your mother -- has been spotted in the vicinity of city hall.
                    605: 
                    606: You should seriously consider taking an extended vacation -- NOW.  (Or read the manual and try again.)}
                    607: 
                    608: Message 300 #ffd700 {About Micropolis} \
                    609: "Micropolis Version [sim Version] Copyright (C) 2007
                    610:     by Electronic Arts.
                    611: Based on the Original Micropolis Concept and Design
                    612:     by Will Wright.
                    613: TCL/Tk User Interface Designed and Created
                    614:     by Don Hopkins, DUX Software.
                    615: Ported to Linux, Optimized and Adapted for OLPC
                    616:     by Don Hopkins.
                    617: Licensed under the GNU General Public License, 
                    618:     version 3, with additional conditions." 
                    619: 
                    620: 
                    621: ########################################################################
                    622: # Options
                    623: ########################################################################
                    624: 
                    625: 
                    626: option add *CheckButton.relief         flat
                    627: option add *Dialog.cursor              top_left_arrow
                    628: option add *Entry.relief               sunken
                    629: option add *Frame.borderWidth          0
                    630: option add *Listbox.relief             sunken
                    631: option add *Scrollbar.relief           sunken
                    632: option add *RadioButton.anchor         w
                    633: option add *RadioButton.relief         flat
                    634: 
                    635: option add *background                 #b0b0b0
                    636: option add *foreground                 #000000
                    637: option add *activeBackground           #d0d0d0
                    638: option add *activeForeground           #000000
                    639: option add *disabledForeground         ""
                    640: option add *selectBackground           #d0d0d0
                    641: option add *selectForeground           #000000
                    642: #option add *selector                  #ffff80
                    643: option add *selector                   #bf0000
                    644: 
                    645: option add *Scrollbar.Background       #b0b0b0
                    646: option add *Scrollbar.Foreground       #d0d0d0
                    647: option add *Interval.Background        #b0b0b0
                    648: option add *Interval.Foreground                #000000
                    649: option add *Interval.activeForeground  #d0d0d0
                    650: option add *Interval.sliderForeground  #b0b0b0
                    651: option add *Scale.activeForeground     #d0d0d0
                    652: option add *Scale.sliderForeground     #b0b0b0
                    653: option add *PieMenu.activeBackground   #b0b0b0
                    654: 
                    655: option add Mwm*Micropolis.clientDecoration -maximize
                    656: 
                    657: 
                    658: ########################################################################
                    659: # Global Bindings
                    660: ########################################################################
                    661: 
                    662: 
                    663: bind all <Help> {HandleHelp %W %x %y %X %Y}
                    664: bind all <Shift-ButtonPress> {HandleHelp %W %x %y %X %Y}
                    665: bind all <Meta-ButtonPress> {HandleHelp %W %x %y %X %Y}
                    666: bind all <Shift-Meta-ButtonPress> {HandleHelp %W %x %y %X %Y}
                    667: 
                    668: 
                    669: ########################################################################
                    670: # Utilities
                    671: ########################################################################
                    672: 
                    673: 
                    674: proc echo {args} {
                    675:   puts stdout $args
                    676:   flush stdout
                    677: } 
                    678: 
                    679: 
                    680: proc Unique {} {
                    681:   global UniqueID
                    682:   set id $UniqueID
                    683:   incr UniqueID
                    684:   return $id
                    685: }
                    686: 
                    687: 
                    688: proc tkerror {err} {
                    689:     global errorInfo
                    690:     puts stderr "$errorInfo"
                    691: }
                    692: 
                    693: 
                    694: proc ident {i} {
                    695:   return "$i"
                    696: }
                    697: 
                    698: proc NoFunction {args} {}
                    699: 
                    700: 
                    701: proc LinkWindow {fromname to} {
                    702:   global WindowLinks
                    703:   set WindowLinks($fromname) $to
                    704: }
                    705: 
                    706: 
                    707: proc WindowLink {fromname} {
                    708:   global WindowLinks
                    709:   set to ""
                    710:   catch {set to $WindowLinks($fromname)}
                    711:   return $to
                    712: }
                    713: 
                    714: 
                    715: proc DeleteWindow {sym name win} {
                    716:   set head [WindowLink $win.head]
                    717:   LinkWindow $head.$sym {}
                    718:   global $name
                    719:   set wins [eval ident "\$$name"]
                    720:   set i [lsearch $wins $win]
                    721:   if {$i != -1} {
                    722:     set $name [lreplace $wins $i $i]
                    723:   }
                    724:   destroy $win
                    725: }
                    726: 
                    727: 
                    728: proc Font {win name} {
                    729:   global FontInfo FontCache HeadWindows
                    730:   set scr [winfo screen $win]
                    731:   set font ""
                    732:   catch {
                    733:     set font $FontCache($scr,$name)
                    734:   }
                    735:   if {"$font" == ""} {
                    736:     set label ""
                    737:     catch {
                    738:       set label $FontCache($scr)
                    739:     }
                    740:     if {"$label" == ""} {
                    741:       foreach head $HeadWindows {
                    742:        if {"[winfo screen $head]" == "$scr"} {
                    743:          set label $head.fontlabel
                    744:          label $label -text "X11 Sucks" -font fixed
                    745:          set FontCache($scr) $label
                    746:        }
                    747:       }
                    748:     }
                    749: 
                    750:     set fonts [keylget FontInfo $name]
                    751:     foreach font $fonts {
                    752:       #echo "Configuring font $font on $label"
                    753:       if {[catch "$label config -font \"$font\""] == 0} {
                    754:         #echo "yow!"
                    755:        break
                    756:       } else {
                    757:         #echo "oops!"
                    758:        set font ""
                    759:       }
                    760:     }
                    761:     if {"$font" == ""} {
                    762:       #set font 8x16
                    763:       # OLCP default font
                    764:       set font 6x13
                    765:     }
                    766:     set FontCache($scr,$name) $font
                    767:   }
                    768:   return $font
                    769: }
                    770: 
                    771: 
                    772: proc Color {win color mono} {
                    773:   if {[winfo screendepth $win] == 1} {
                    774:     return $mono
                    775:   } else {
                    776:     return $color
                    777:   }
                    778: }
                    779: 
                    780: 
                    781: ########################################################################
                    782: # Window Definition Functions
                    783: ########################################################################
                    784: 
                    785: 
                    786: proc MakeWindow.head {{display ":0"}} {
                    787:   global ResourceDir
                    788:   source $ResourceDir/whead.tcl
                    789:   return $win
                    790: }
                    791: 
                    792: 
                    793: proc MakeWindow.editor {head {display ":0"}} {
                    794:   global ResourceDir
                    795:   source $ResourceDir/weditor.tcl
                    796:   return $win
                    797: }
                    798: 
                    799: 
                    800: proc MakeWindow.map {head {display ":0"}} {
                    801:   global ResourceDir
                    802:   source $ResourceDir/wmap.tcl
                    803:   return $win
                    804: }
                    805: 
                    806: 
                    807: proc MakeWindow.graph {head {display ":0"}} {
                    808:   global ResourceDir
                    809:   source $ResourceDir/wgraph.tcl
                    810:   return $win
                    811: }
                    812: 
                    813: 
                    814: proc MakeWindow.budget {head {display ":0"}} {
                    815:   global ResourceDir
                    816:   source $ResourceDir/wbudget.tcl
                    817:   return $win
                    818: }
                    819: 
                    820: 
                    821: proc MakeWindow.evaluation {head {display ":0"}} {
                    822:   global ResourceDir
                    823:   source $ResourceDir/weval.tcl
                    824:   return $win
                    825: }
                    826: 
                    827: 
                    828: proc MakeWindow.splash {head {display ":0"}} {
                    829:   global ResourceDir
                    830:   source $ResourceDir/wsplash.tcl
                    831:   return $win
                    832: }
                    833: 
                    834: 
                    835: proc MakeWindow.scenario {head {display ":0"}} {
                    836:   global ResourceDir
                    837:   source $ResourceDir/wscen.tcl
                    838:   return $win
                    839: }
                    840: 
                    841: 
                    842: proc MakeWindow.file {head {display ":0"}} {
                    843:   global ResourceDir
                    844:   source $ResourceDir/wfile.tcl
                    845:   return $win
                    846: }
                    847: 
                    848: 
                    849: proc MakeWindow.ask {head {display ":0"}} {
                    850:   global ResourceDir
                    851:   source $ResourceDir/wask.tcl
                    852:   return $win
                    853: }
                    854: 
                    855: 
                    856: proc MakeWindow.player {head {display ":0"}} {
                    857:   global ResourceDir
                    858:   source $ResourceDir/wplayer.tcl
                    859:   return $win
                    860: }
                    861: 
                    862: 
                    863: proc MakeWindow.notice {head {display ":0"}} {
                    864:   global ResourceDir
                    865:   source $ResourceDir/wnotice.tcl
                    866:   return $win
                    867: }
                    868: 
                    869: proc MakeWindow.help {head {display ":0"}} {
                    870:   global ResourceDir
                    871:   source $ResourceDir/whelp.tcl
                    872:   return $win
                    873: }
                    874: 
                    875: proc MakeWindow.frob {head {display ":0"}} {
                    876:   global ResourceDir
                    877:   source $ResourceDir/wfrob.tcl
                    878:   return $win
                    879: }
                    880: 
                    881: 
                    882: ########################################################################
                    883: # Sound Support
                    884: ########################################################################
                    885: 
                    886: 
                    887: proc UIInitializeSound {} {
                    888: }
                    889: 
                    890: 
                    891: proc UIShutDownSound {} {
                    892: }
                    893: 
                    894: 
                    895: proc UIDoSoundOn {win cmd} {
                    896:   global Sound SoundServers
                    897:   if {$Sound} {
                    898:     set win [WindowLink [winfo toplevel $win].head]
                    899:     if {[lsearch $SoundServers $win] != -1} {
                    900:       set cmd "send -quick -server $win Sound sound $cmd"
                    901:       if {[catch $cmd]} {
                    902:        # XXX: Lost a sound server...
                    903:        LostSoundServer $win
                    904:       }
                    905:     }
                    906:   }
                    907: }
                    908: 
                    909: 
                    910: proc UIDoSound {cmd} {
                    911:   global Sound SoundServers
                    912:   if {$Sound} {
                    913:     foreach win $SoundServers {
                    914:       set foo "send -quick -server $win Sound $cmd"
                    915:       if {[catch $foo]} {
                    916:        # XXX: Lost a sound server...
                    917:         LostSoundServer $win
                    918:       }
                    919:     }
                    920:   }
                    921: }
                    922: 
                    923: 
                    924: proc KillSoundServers {} {
                    925:   global SoundServers
                    926:   foreach win $SoundServers {
                    927:     set foo "send -quick -server $win Sound KillSoundServer"
                    928:     catch $foo
                    929:   }
                    930:   set SoundServers {}
                    931: }
                    932: 
                    933: 
                    934: proc UISetChannelVolume {win chan vol} {
                    935:   UIDoSoundOn $win "channel $chan -volume $vol"
                    936: }
                    937: 
                    938: 
                    939: proc EchoPlaySound {soundspec} {
                    940:   # Temporary workaround to tell Python Sugar app to play sound.
                    941:   global Sound
                    942:   if {$Sound} {
                    943:     echo PlaySound [lindex $soundspec 0]
                    944:   }
                    945: }
                    946: 
                    947: 
                    948: proc UIMakeSoundOn {win chan sound {opts ""}} {
                    949:   # Send message to Python to play sound.
                    950:   EchoPlaySound $sound
                    951: 
                    952:   #UIDoSoundOn $win "play $sound -replay -channel $chan $opts"
                    953: }
                    954: 
                    955: 
                    956: proc UIStartSoundOn {win chan sound {opts ""}} {
                    957:   # Send message to Python to play sound.
                    958:   EchoPlaySound $sound
                    959: 
                    960:   #UIDoSoundOn $win "play $sound -replay -channel $chan -repeat 100 $opts"
                    961: }
                    962: 
                    963: 
                    964: proc UIStopSoundOn {win chan sound {opts ""}} {
                    965:   UIDoSoundOn $win "stop $sound"
                    966: }
                    967: 
                    968: 
                    969: proc UIMakeSound {chan sound {opts ""}} {
                    970:   # Send message to Python to play sound.
                    971:   EchoPlaySound $sound
                    972: 
                    973:   #UIDoSound "sound play $sound -replay -channel $chan $opts"
                    974: }
                    975: 
                    976: 
                    977: proc UIStartSound {chan sound {opts ""}} {
                    978:   # Send message to Python to play sound.
                    979:   EchoPlaySound $sound
                    980: 
                    981:   #UIDoSound "sound play $sound -channel $chan -repeat 100 $opts"
                    982: }
                    983: 
                    984: 
                    985: proc UIStopSound {chan sound {opts ""}} {
                    986:   UIDoSound "sound stop $sound"
                    987: }
                    988: 
                    989: 
                    990: proc SetupSoundServer {win} {
                    991:   AddSoundServer $win
                    992: }
                    993: 
                    994: 
                    995: proc AddSoundServer {win} {
                    996:   global SoundServers
                    997:   set i [lsearch $SoundServers $win]
                    998:   if {$i < 0} {
                    999:     set SoundServers [linsert $SoundServers 0 $win]
                   1000:   }
                   1001: }
                   1002: 
                   1003: 
                   1004: proc LostSoundServer {win} {
                   1005:   DeleteSoundServer $win
                   1006: #  UIShowPictureOn [WindowLink $win.head] 46 [winfo screen $win]
                   1007: }
                   1008: 
                   1009: 
                   1010: proc DeleteSoundServer {win} {
                   1011:   global SoundServers
                   1012:   set i [lsearch $SoundServers $win]
                   1013:   if {$i >= 0} {
                   1014:     set SoundServers [lreplace $SoundServers $i $i]
                   1015:   }
                   1016: }
                   1017: 
                   1018: 
                   1019: proc UISoundOff {} {
                   1020: }
                   1021: 
                   1022: 
                   1023: proc MonsterSpeed {} {
                   1024:   return [expr "[sim Rand 40] + 70"]
                   1025: }
                   1026: 
                   1027: 
                   1028: proc ExplosionPitch {} {
                   1029:   return [expr "[sim Rand 20] + 90"]
                   1030: }
                   1031: 
                   1032: 
                   1033: proc HonkPitch {} {
                   1034:   return [expr "[sim Rand 20] + 90"]
                   1035: }
                   1036: 
                   1037: 
                   1038: ########################################################################
                   1039: # Global Window Handlers
                   1040: 
                   1041: 
                   1042: proc WithdrawAll {} {
                   1043:   WithdrawHeads
                   1044:   WithdrawEditors
                   1045:   WithdrawMaps
                   1046:   WithdrawGraphs
                   1047:   WithdrawBudgets
                   1048:   WithdrawEvaluations
                   1049:   WithdrawSplashes
                   1050:   WithdrawScenarios
                   1051:   WithdrawFiles
                   1052:   WithdrawAsks
                   1053:   WithdrawPlayers
                   1054:   WithdrawNotices
                   1055:   WithdrawHelps
                   1056:   WithdrawFrobs
                   1057: }
                   1058: 
                   1059: 
                   1060: proc ShowInitial {} {
                   1061:   ShowHeads
                   1062:   ShowEditors
                   1063:   ShowMaps
                   1064:   EnableMaps
                   1065: }
                   1066: 
                   1067: 
                   1068: ########################################################################
                   1069: # Head Window Handlers
                   1070: 
                   1071: 
                   1072: proc PrepHead {head} {
                   1073:   global State
                   1074:   InitHeadMenus $head
                   1075:   case $State {
                   1076:     uninitialized {
                   1077:     }
                   1078:     splash {
                   1079:       WithdrawHeadOf $head
                   1080:       ShowSplashOf $head
                   1081:     }
                   1082:     scenario {
                   1083:       after 1000 "WithdrawSplashOf $head"
                   1084:       WithdrawHeadOf $head
                   1085:       ShowScenarioOf $head
                   1086:       sim UpdateMaps
                   1087:     }
                   1088:     play {
                   1089:       WithdrawSplashOf $head
                   1090:       WithdrawScenarioOf $head
                   1091:       ShowHeadOf $head
                   1092:       ShowEditorOf $head
                   1093:       ShowMapOf $head
                   1094:       EnableMaps
                   1095:       ReShowPictureOn $head
                   1096:       InitHead $head
                   1097:       InitHeadMenus $head
                   1098:     }
                   1099:   }
                   1100: }
                   1101: 
                   1102: 
                   1103: proc ShowHeadOf {head} {
                   1104:   wm deiconify $head
                   1105: }
                   1106: 
                   1107: 
                   1108: proc WithdrawHeadOf {head} {
                   1109:   wm withdraw $head
                   1110: }
                   1111: 
                   1112: 
                   1113: proc ShowHeads {} {
                   1114:   global HeadWindows
                   1115:   foreach win $HeadWindows {
                   1116:     ShowHeadOf $win
                   1117:   }
                   1118: }
                   1119: 
                   1120: 
                   1121: proc WithdrawHeads {} {
                   1122:   global HeadWindows
                   1123:   foreach win $HeadWindows {
                   1124:     wm withdraw $win
                   1125:   }
                   1126: }
                   1127: 
                   1128: 
                   1129: proc DeleteHeadWindow {head} {
                   1130:   UIQuit $head
                   1131: }
                   1132: 
                   1133: 
                   1134: proc InitHeads {} {
                   1135:   global HeadWindows
                   1136:   foreach win $HeadWindows {
                   1137:     InitHead $win
                   1138:   }
                   1139: }
                   1140: 
                   1141: 
                   1142: proc InitHead {win} {
                   1143:   set w [WindowLink $win.text]
                   1144:   $w configure -state normal
                   1145:   $w delete 0.0 end
                   1146:   $w insert end "\n"
                   1147:   $w configure -state disabled
                   1148: 
                   1149:   if {[sim MultiPlayerMode]} {
                   1150:     set w [WindowLink $win.entry]
                   1151:     $w delete 0 end
                   1152:     global ${w}.value
                   1153:     set ${w}.value ""
                   1154:   }
                   1155: 
                   1156:   sim UpdateHeads
                   1157:   UIUpdateRunning
                   1158: }
                   1159: 
                   1160: 
                   1161: proc InitAllHeadMenus {} {
                   1162:   global HeadWindows
                   1163: 
                   1164:   foreach win $HeadWindows {
                   1165:     InitHeadMenus $win
                   1166:   }
                   1167: }
                   1168: 
                   1169: 
                   1170: proc InitHeadMenus {win} {
                   1171:   global State
                   1172:   set m0 [WindowLink $win.m0]
                   1173:   set m1 [WindowLink $win.m1]
                   1174:   set m2 [WindowLink $win.m2]
                   1175:   set m3 [WindowLink $win.m3]
                   1176:   set m4 [WindowLink $win.m4]
                   1177:   set b0 [WindowLink $win.b0]
                   1178:   set b1 [WindowLink $win.b1]
                   1179:   set b2 [WindowLink $win.b2]
                   1180:   set b3 [WindowLink $win.b3]
                   1181:   set b4 [WindowLink $win.b4]
                   1182:   case $State {
                   1183:     uninitialized {
                   1184:     }
                   1185:     splash {
                   1186:     }
                   1187:     scenario {
                   1188:       $m0 unpost
                   1189:       $m1 unpost
                   1190:       $m2 unpost
                   1191:       $m3 unpost
                   1192:       $m4 unpost
                   1193:       $m0 disable 1
                   1194:       $m0 disable 2
                   1195:       # When in multi player mode there is an extra menu
                   1196:       # item to add another player, before the quit item,
                   1197:       # so compensate for it here.
                   1198:       if {[sim MultiPlayerMode]} {
                   1199:         $m0 disable 4
                   1200:       } else {
                   1201:         $m0 disable 3
                   1202:       }
                   1203:       $b0 config -state normal
                   1204:       $b2 config -state disabled
                   1205:       $b4 config -state disabled
                   1206:     }
                   1207:     play {
                   1208:       $m0 enable 1
                   1209:       $m0 enable 2
                   1210:       # When in multi player mode there is an extra menu
                   1211:       # item to add another player, before the quit item,
                   1212:       # so compensate for it here.
                   1213:       if {[sim MultiPlayerMode]} {
                   1214:         $m0 enable 4
                   1215:       } else {
                   1216:         $m0 enable 3
                   1217:       }
                   1218:       $b0 config -state normal
                   1219:       $b2 config -state normal
                   1220:       $b4 config -state normal
                   1221:     }
                   1222:   }
                   1223: }
                   1224: 
                   1225: 
                   1226: proc UIDisaster {win cmd action} {
                   1227:   AskQuestion [Color $win #ff0000 #ffffff] "Cause a Disaster" \
                   1228:     "Oh no! Do you really want to $action" \
                   1229:     "{No way!} Disaster.No {WithdrawAsks}" \
                   1230:     "" \
                   1231:     "{I guess so.} Disaster.Yes {WithdrawAsks ; $cmd}"
                   1232: }
                   1233: 
                   1234: 
                   1235: proc CrushHead {head} {
                   1236:   global SubWindows VoteNames
                   1237: 
                   1238:   foreach foo $VoteNames {
                   1239:     global VotesFor$foo
                   1240:     set votes [eval ident \$VotesFor$foo]
                   1241:     set i [lsearch $votes $head]
                   1242:     if {$i != -1} {
                   1243:       set VotesFor$foo [lreplace $votes $i $i]
                   1244:     }
                   1245:   }
                   1246: 
                   1247:   foreach foo $SubWindows {
                   1248:     set sym [lindex $foo 0]
                   1249:     set name [lindex $foo 1]
                   1250:     global $name
                   1251:     set wins [eval ident "\$$name"]
                   1252:     foreach win $wins {
                   1253:       if {[WindowLink $win.head] == $head} {
                   1254:        DeleteWindow $sym $name $win
                   1255:       }
                   1256:     }
                   1257:   }
                   1258: }
                   1259: 
                   1260: 
                   1261: proc ChatDown {win} {
                   1262:   tk_butDown $win
                   1263: }
                   1264: 
                   1265: 
                   1266: proc ChatUp {win} {
                   1267:   tk_butUp $win
                   1268: 
                   1269:   global Chatting
                   1270: 
                   1271:   if {$Chatting} {
                   1272:     CloseChat
                   1273:   } else {
                   1274:     OpenChat
                   1275:   }
                   1276: }
                   1277: 
                   1278: 
                   1279: proc OpenChat {} {
                   1280:   global Chatting
                   1281:   global ChatServer
                   1282:   global ChatSocket
                   1283:   global ChatConnection
                   1284: 
                   1285:   DoSendMessage "Opening Connection to Chat Server $ChatServer socket $ChatSocket ..." status
                   1286: 
                   1287:   set ChatConnection {}
                   1288:   catch {
                   1289:     set ChatConnection [connect $ChatServer $ChatSocket]
                   1290:   }
                   1291: 
                   1292:   if {$ChatConnection == {}} then {
                   1293:     DoSendMessage "Sorry, I could not open a connection to chat server $ChatServer socket $ChatSocket." status
                   1294:     set Chatting 0
                   1295:   } else {
                   1296:     filehandler $ChatConnection r "ReceiveChat"
                   1297:     set Chatting 1
                   1298:   }
                   1299: 
                   1300:   global NickName
                   1301:   global UserName
                   1302:   global HostName
                   1303:   global ServerName
                   1304:   global RealName
                   1305:   global ChannelName
                   1306:   catch {
                   1307:     puts $ChatConnection "USER $UserName $HostName $ServerName $RealName\r\n" nonewline
                   1308:     puts $ChatConnection "NICK $NickName\r\n" nonewline
                   1309:     puts $ChatConnection "JOIN $ChannelName\r\n" nonewline
                   1310:     flush $ChatConnection
                   1311:   }
                   1312: }
                   1313: 
                   1314: 
                   1315: proc ReceiveChat {mode f} {
                   1316: #    DoSendMessage "ReceiveChat: MODE $mode F $f"
                   1317:     set msg ""
                   1318:     gets $f msg
                   1319: 
                   1320:     if {[string first {:} $msg]} {
                   1321:        set msg ": $msg"
                   1322:     }
                   1323: 
                   1324:     set from [lindex $msg 0]
                   1325:     set cmd [string tolower [lindex $msg 1]]
                   1326: 
                   1327:     set handled 0
                   1328: 
                   1329:     if {($cmd == "privmsg") ||
                   1330:         ($cmd == "notice")} then {
                   1331:       set handled 1
                   1332:       set chan [lindex $msg 2]
                   1333:       set i [expr "[string length $from] + 1 + [string length $cmd] + 1 + [string length $chan] + 2"]
                   1334:       set j [expr "[string length $msg] - 2"]
                   1335:       set line [string range $msg $i $j]
                   1336:       set chan [string range $chan 1 [string length $chan]]
                   1337:       set from [string range $from 1 [expr "[string length $from] - 1"]]
                   1338:       set from [split $from {!}]
                   1339:       set from [lindex $from 0]
                   1340:       DoSendMessage "$from> $line"
                   1341:     }
                   1342: 
                   1343:     if {$handled == 0} {
                   1344:        set msg [string range $msg \
                   1345:                  [expr "[string length $from] + 1"] \
                   1346:                  [expr "[string length $msg] - 2"]]
                   1347:        DoSendMessage $msg
                   1348:     }
                   1349: }
                   1350: 
                   1351: 
                   1352: proc SendChatMessage {msg win} {
                   1353:     global ChatConnection ChannelName NickName
                   1354: 
                   1355:     if {"$msg" == ""} {
                   1356:        return
                   1357:     }
                   1358: 
                   1359:     if {[string range $msg 0 0] == "/"} {
                   1360:        set cmd [string range $msg 1 [string length $msg]]
                   1361:         DoSendMessage "$NickName> \[$cmd\]"
                   1362:        set cmd "$cmd\r\n"
                   1363:     } else {
                   1364:        set cmd "PRIVMSG $ChannelName :$msg\r\n"
                   1365:         DoSendMessage "$NickName> $msg"
                   1366:     }
                   1367:     
                   1368: 
                   1369:     set result 1
                   1370: 
                   1371:     catch {
                   1372:        puts $ChatConnection $cmd nonewline
                   1373:        flush $ChatConnection
                   1374:        set result 0
                   1375:     }
                   1376: 
                   1377:     if {$result} {
                   1378:        DoSendMessage "IRC Broke the connection"
                   1379:        CloseChat
                   1380:     }
                   1381: }
                   1382: 
                   1383: 
                   1384: proc CloseChat {} {
                   1385:   global Chatting
                   1386:   global ChatServer
                   1387:   global ChatSocket
                   1388:   global ChatConnection
                   1389: 
                   1390:   DoSendMessage "Closing Connection to Chat Server." status
                   1391: 
                   1392:   catch {
                   1393:     puts $ChatConnection "QUIT\r\n" nonewline
                   1394:     flush $ChatConnection
                   1395:     $ChatConnection close
                   1396:   }
                   1397: 
                   1398:   set ChatConnection {}
                   1399:   set Chatting 0
                   1400: }
                   1401: 
                   1402: 
                   1403: proc DoEnterMessage {win var} {
                   1404:   global Chatting
                   1405:   global $var
                   1406:   set msg [eval ident "\$\{$var\}"]
                   1407: 
                   1408:   if {$Chatting} then {
                   1409:     SendChatMessage $msg $win
                   1410:   } else {
                   1411:     DoSendMessage $msg
                   1412:   }
                   1413:   $win delete 0 end
                   1414: }
                   1415: 
                   1416: 
                   1417: proc DoEvalMessage {win var} {
                   1418:   global $var
                   1419:   set command [eval ident "\$\{$var\}"]
                   1420:   $win delete 0 end
                   1421:   DoSendMessage "Evaluating TCL: $command"
                   1422:   catch {uplevel #0 $command} result
                   1423:   DoSendMessage "Result: $result"
                   1424: }
                   1425: 
                   1426: 
                   1427: proc DoSendMessage {msg {tag message}} {
                   1428:   global HeadWindows
                   1429:   foreach win $HeadWindows {
                   1430:     appendWithTag [WindowLink $win.text] $tag "$msg"
                   1431:   }
                   1432: }
                   1433: 
                   1434: 
                   1435: proc UISetMessage {msg {tag status}} {
                   1436:   global DoMessages EditorWindows HeadWindows
                   1437: 
                   1438:   if {$DoMessages == 0} {
                   1439:       return
                   1440:   }
                   1441: 
                   1442:   foreach win $EditorWindows {
                   1443:     [WindowLink $win.message] configure -text "$msg"
                   1444:   }
                   1445: 
                   1446:   foreach win $HeadWindows {
                   1447:     appendWithTag [WindowLink $win.text] $tag "$msg"
                   1448:   }
                   1449: }
                   1450: 
                   1451: 
                   1452: 
                   1453: 
                   1454: proc appendWithTag {w tag text} {
                   1455:     global MaxLines
                   1456:     global ShrinkLines
                   1457: 
                   1458:     set start [$w index end]
                   1459:     $w configure -state normal
                   1460:     if {$start > $MaxLines} then {
                   1461:        $w delete 0.0 $ShrinkLines.0
                   1462:        set start [$w index end]
                   1463:     }
                   1464:     $w insert end "${text}\n"
                   1465:     $w tag add $tag $start {end - 1 char}
                   1466:     $w configure -state disabled
                   1467:     $w yview -pickplace {end - 1 char}
                   1468: }
                   1469: 
                   1470: 
                   1471: ########################################################################
                   1472: # Budget Window Handlers
                   1473: 
                   1474: 
                   1475: proc ShowBudgetOf {head} {
                   1476:   set win [WindowLink $head.budget]
                   1477:   if {$win == {}} {
                   1478:     set win [MakeWindow.budget $head [winfo screen $head]]
                   1479:   }
                   1480:   wm deiconify $win
                   1481:   wm raise $win
                   1482:   update idletasks
                   1483:   sim UpdateBudget
                   1484: }
                   1485: 
                   1486: 
                   1487: proc ShowBudgets {} {
                   1488:   global HeadWindows BudgetsVisible
                   1489:   set BudgetsVisible 1
                   1490:   foreach win $HeadWindows {
                   1491:     ShowBudgetOf $win
                   1492:   }
                   1493: }
                   1494: 
                   1495: 
                   1496: proc WithdrawBudgets {} {
                   1497:   global BudgetWindows BudgetsVisible
                   1498:   foreach win $BudgetWindows {
                   1499:     wm withdraw $win
                   1500:   }
                   1501:   StopBudgetTimer
                   1502:   set BudgetsVisible 0
                   1503: }
                   1504: 
                   1505: 
                   1506: proc BudgetContinue {{win ""}} {
                   1507:   global OldBudget BudgetRoadFund BudgetFireFund BudgetPoliceFund BudgetTaxRate
                   1508:   set OldBudget 0
                   1509:   if {([sim RoadFund] != $BudgetRoadFund) ||
                   1510:       ([sim FireFund] != $BudgetFireFund) ||
                   1511:       ([sim PoliceFund] != $BudgetPoliceFund) ||
                   1512:       ([sim TaxRate] != $BudgetTaxRate)} {
                   1513:     UISetMessage "The budget was changed."
                   1514:   } else {
                   1515:     UISetMessage "The budget wasn't changed."
                   1516:   }
                   1517:   WithdrawBudgets
                   1518:   sim Resume
                   1519:   MakeRunningSound
                   1520: }
                   1521: 
                   1522: 
                   1523: proc BudgetReset {{win ""}} {
                   1524:   global OldBudget BudgetRoadFund BudgetFireFund BudgetPoliceFund BudgetTaxRate
                   1525:   if {([sim RoadFund] != $BudgetRoadFund) ||
                   1526:       ([sim FireFund] != $BudgetFireFund) ||
                   1527:       ([sim PoliceFund] != $BudgetPoliceFund) ||
                   1528:       ([sim TaxRate] != $BudgetTaxRate)} {
                   1529:     UISetMessage "The budget was reset."
                   1530:     if {[sim Players] > 1} {
                   1531:       UIMakeSound edit Sorry
                   1532:     }
                   1533:   } else {
                   1534:     UISetMessage "The budget was reset."
                   1535:   }
                   1536:   sim RoadFund $BudgetRoadFund
                   1537:   sim FireFund $BudgetFireFund
                   1538:   sim PoliceFund $BudgetPoliceFund 
                   1539:   sim TaxRate $BudgetTaxRate
                   1540:   set OldBudget 0
                   1541:   ChangeBudget
                   1542: }
                   1543: 
                   1544: 
                   1545: proc BudgetCancel {{win ""}} {
                   1546:   BudgetReset
                   1547:   WithdrawBudgets
                   1548:   sim Resume
                   1549:   MakeRunningSound
                   1550: }
                   1551: 
                   1552: 
                   1553: proc SetTaxRate {rate} {
                   1554:   sim TaxRate $rate
                   1555: }
                   1556: 
                   1557: 
                   1558: proc BudgetSetTaxRate {rate} {
                   1559:   SetTaxRate $rate
                   1560:   ChangeBudget
                   1561: }
                   1562: 
                   1563: 
                   1564: proc BudgetSetRoadFund {percent} {
                   1565:   sim RoadFund $percent
                   1566:   ChangeBudget
                   1567: }
                   1568: 
                   1569: 
                   1570: proc BudgetSetFireFund {percent} {
                   1571:   sim FireFund $percent
                   1572:   ChangeBudget
                   1573: }
                   1574: 
                   1575: 
                   1576: proc BudgetSetPoliceFund {percent} {
                   1577:   sim PoliceFund $percent
                   1578:   ChangeBudget
                   1579: }
                   1580: 
                   1581: 
                   1582: proc UIShowBudgetAndWait {} {
                   1583:   global OldBudget BudgetRoadFund BudgetFireFund BudgetPoliceFund BudgetTaxRate
                   1584:   if {$OldBudget == 0} {
                   1585:     set BudgetRoadFund [sim RoadFund]
                   1586:     set BudgetFireFund [sim FireFund]
                   1587:     set BudgetPoliceFund [sim PoliceFund]
                   1588:     set BudgetTaxRate [sim TaxRate]
                   1589:     set OldBudget 1
                   1590:   }
                   1591:   ShowBudgets
                   1592:   UISetMessage "Pausing to set the budget ..."
                   1593:   sim Pause
                   1594:   MakeRunningSound
                   1595:   StartBudgetTimer
                   1596:   InitVotesForBudget
                   1597:   sim UpdateBudget
                   1598:   sim UpdateBudgetWindow
                   1599: }
                   1600: 
                   1601: 
                   1602: proc ToggleBudgetTimer {} {
                   1603:   global BudgetTimerActive
                   1604:   if {$BudgetTimerActive} {
                   1605:     StopBudgetTimer
                   1606:   } else {
                   1607:     StartBudgetTimer
                   1608:   }
                   1609: }
                   1610: 
                   1611: 
                   1612: proc StopBudgetTimer {} {
                   1613:   global BudgetTimerActive
                   1614:   set BudgetTimerActive 0
                   1615:   UpdateBudgetTimer
                   1616: }
                   1617: 
                   1618: 
                   1619: proc StartBudgetTimer {} {
                   1620:   global BudgetTimerActive BudgetTimer BudgetTimeout
                   1621:   set me [Unique]
                   1622:   set BudgetTimerActive $me
                   1623:   set BudgetTimer $BudgetTimeout
                   1624:   UpdateBudgetTimer
                   1625:   after 1000 TickBudgetTimer $me
                   1626: }
                   1627: 
                   1628: 
                   1629: proc RestartBudgetTimer {} {
                   1630:   global BudgetTimerActive
                   1631:   if {$BudgetTimerActive} {
                   1632:     StopBudgetTimer
                   1633:     StartBudgetTimer
                   1634:   }
                   1635: }
                   1636: 
                   1637: 
                   1638: proc UpdateBudgetTimer {} {
                   1639:   global BudgetWindows BudgetTimerActive BudgetTimer
                   1640:   if {$BudgetTimerActive} {
                   1641:     set text [format "Auto Cancel In %d Seconds (click to disable)" $BudgetTimer]
                   1642:   } else {
                   1643:     set text [format "Enable Auto Cancel (currently disabled)"]
                   1644:   }
                   1645:   foreach win $BudgetWindows {
                   1646:     set t [WindowLink $win.timer]
                   1647:     $t config -text "$text"
                   1648:   }
                   1649: }
                   1650: 
                   1651: 
                   1652: proc TickBudgetTimer {me} {
                   1653:   global BudgetTimerActive BudgetTimer BudgetTimeout
                   1654:   if {$BudgetTimerActive == $me} {
                   1655:     incr BudgetTimer -1
                   1656:     if {$BudgetTimer < 0} {
                   1657:       StopBudgetTimer
                   1658:       UpdateBudgetTimer
                   1659:       FireBudgetTimer
                   1660:     } else {
                   1661:       UpdateBudgetTimer
                   1662:       after 1000 TickBudgetTimer $me
                   1663:     }
                   1664:   }
                   1665: }
                   1666: 
                   1667: 
                   1668: proc FireBudgetTimer {} {
                   1669:   BudgetCancel
                   1670: }
                   1671: 
                   1672: 
                   1673: proc funds {n} {
                   1674:   sim Funds $n
                   1675: }
                   1676: 
                   1677: 
                   1678: proc ToggleAutoBudget {} {
                   1679:   global AutoBudget
                   1680:   if {$AutoBudget} {
                   1681:       #echo "ToggleAutoBudget found on, clearing"
                   1682:       sim AutoBudget 0
                   1683:   } else {
                   1684:       #echo "ToggleAutoBudget found off, setting"
                   1685:       sim AutoBudget 1
                   1686:   }
                   1687: }
                   1688: 
                   1689: 
                   1690: proc UIUpdateBudget {} {
                   1691:   UpdateAutoBudget
                   1692: }
                   1693: 
                   1694: 
                   1695: proc UpdateAutoBudget {} {
                   1696:   global BudgetWindows AutoBudget
                   1697:   if {[sim AutoBudget]} {
                   1698:     set text "Disable Auto Budget (currently enabled)"
                   1699:   } else {
                   1700:     set text "Enable Auto Budget (currently disabled)"
                   1701:   }
                   1702:   #echo "UpdateAutoBudget $AutoBudget $text"
                   1703:   foreach win $BudgetWindows {
                   1704:     set t [WindowLink $win.autobudget]
                   1705:     $t config -text "$text"
                   1706:   }
                   1707: }
                   1708: 
                   1709: 
                   1710: proc UISetBudget {cashflow previous current collected taxrate} {
                   1711:   global BudgetWindows BudgetsVisible
                   1712: 
                   1713:   #echo "UISetBudgetValues $taxrate $BudgetsVisible"
                   1714: 
                   1715:   if {$BudgetsVisible} {
                   1716: 
                   1717:     foreach win $BudgetWindows {
                   1718:       set w [WindowLink $win.cashflow]
                   1719:       set old [lindex [$w configure -text] 4]
                   1720:       if {$old != $cashflow} {
                   1721:        $w configure -text $cashflow
                   1722:       }
                   1723:       set w [WindowLink $win.previous]
                   1724:       set old [lindex [$w configure -text] 4]
                   1725:       if {$old != $previous} {
                   1726:        $w configure -text $previous
                   1727:       }
                   1728:       set w [WindowLink $win.current]
                   1729:       set old [lindex [$w configure -text] 4]
                   1730:       if {$old != $current} {
                   1731:        $w configure -text $current
                   1732:       }
                   1733:       set w [WindowLink $win.collected]
                   1734:       set old [lindex [$w configure -text] 4]
                   1735:       if {$old != $collected} {
                   1736:        $w configure -text $collected
                   1737:       }
                   1738: 
                   1739:       set w [WindowLink $win.taxrate]
                   1740:       set old [$w get]
                   1741:       if {$old != $taxrate} {
                   1742:        $w set $taxrate
                   1743:       }
                   1744: 
                   1745:       set w [WindowLink $win.taxlabel]
                   1746:       set old [lindex [$w configure -text] 4]
                   1747:       set new "$taxrate%"
                   1748:       if {$old != $new} {
                   1749:        $w configure -text $new
                   1750:       }
                   1751:     }
                   1752:   }
                   1753: 
                   1754:   global HeadWindows
                   1755:   foreach win $HeadWindows {
                   1756: 
                   1757:     set w [WindowLink $win.taxrate]
                   1758:     set old [$w get]
                   1759:     if {$old != $taxrate} {
                   1760:       # FIXME: this might not work if the slider is disabled in multi player mode.
                   1761:       $w set $taxrate
                   1762:     }
                   1763: 
                   1764:     set w [WindowLink $win.taxlabel]
                   1765:     set old [lindex [$w configure -text] 4]
                   1766:     set new "Tax Rate: $taxrate%"
                   1767:     if {$old != $new} {
                   1768:       $w configure -text $new
                   1769:     }
                   1770:   }
                   1771: }
                   1772: 
                   1773: 
                   1774: proc UISetBudgetValues {roadgot roadwant roadpercent policegot policewant policepercent firegot firewant firepercent} {
                   1775:   global BudgetWindows BudgetsVisible
                   1776: 
                   1777:   if {$BudgetsVisible == 0} {
                   1778:       return;
                   1779:   }
                   1780: 
                   1781:   foreach win $BudgetWindows {
                   1782:     set w [WindowLink $win.fire].request
                   1783:     set old [lindex [$w configure -text] 4]
                   1784:     set new "$firepercent% of $firewant = $firegot"
                   1785:     if {$old != $new} {
                   1786:       $w configure -text $new
                   1787:     }
                   1788:     set w [WindowLink $win.fire].fund
                   1789:     set old [$w get]
                   1790:     if {$old != $firepercent} {
                   1791:       $w set $firepercent
                   1792:     }
                   1793: 
                   1794:     set w [WindowLink $win.police].request
                   1795:     set old [lindex [$w configure -text] 4]
                   1796:     set new "$policepercent% of $policewant = $policegot"
                   1797:     if {$old != $new} {
                   1798:       $w configure -text $new
                   1799:     }
                   1800:     set w [WindowLink $win.police].fund
                   1801:     set old [$w get]
                   1802:     if {$old != $policepercent} {
                   1803:       $w set $policepercent
                   1804:     }
                   1805: 
                   1806:     set w [WindowLink $win.road].request
                   1807:     set old [lindex [$w configure -text] 4]
                   1808:     set new "$roadpercent% of $roadwant = $roadgot"
                   1809:     if {$old != $new} {
                   1810:       $w configure -text $new
                   1811:     }
                   1812:     set w [WindowLink $win.road].fund
                   1813:     set old [$w get]
                   1814:     if {$old != $roadpercent} {
                   1815:       $w set $roadpercent
                   1816:     }
                   1817:   }
                   1818: }
                   1819: 
                   1820: 
                   1821: proc ChangeBudget {} {
                   1822:   global VotesForBudget
                   1823:   if {"$VotesForBudget" != ""} {
                   1824:     InitVotesForBudget
                   1825:   }
                   1826:   RestartBudgetTimer
                   1827: }
                   1828: 
                   1829: 
                   1830: proc InitVotesForBudget {} {
                   1831:   global VotesForBudget BudgetWindows
                   1832:   set VotesForBudget {}
                   1833:   foreach win $BudgetWindows {
                   1834:     [WindowLink $win.vote] config -relief raised
                   1835:   }
                   1836:   UpdateVotesForBudget
                   1837: }
                   1838: 
                   1839: 
                   1840: proc UpdateVotesForBudget {} {
                   1841:   global BudgetWindows
                   1842:   UpdateVotesFor Budget $BudgetWindows
                   1843: }
                   1844: 
                   1845: 
                   1846: proc UpdateTaxRateSliders {} {
                   1847:   global HeadWindows
                   1848:   set players [sim Players]
                   1849:   foreach win $HeadWindows {
                   1850:     set slider [WindowLink $win.taxrate]
                   1851:     #echo "UpdateTaxRateSliders players $players win $win slider $slider"
                   1852:     if {$players == 1} {
                   1853:       $slider configure -state normal
                   1854:     } else {
                   1855:       $slider configure -state disabled
                   1856:     }
                   1857:   }
                   1858: }
                   1859: 
                   1860: 
                   1861: ########################################################################
                   1862: # Evaluation Window Handlers
                   1863: 
                   1864: 
                   1865: proc ToggleEvaluationOf {head} {
                   1866:   global State
                   1867:   if {"$State" != "play"} {
                   1868:     return
                   1869:   }
                   1870: 
                   1871:   set mapped 0
                   1872:   set win [WindowLink $head.evaluation]
                   1873:   if {$win != ""} {
                   1874:     set mapped [winfo ismapped $win]
                   1875:   }
                   1876: 
                   1877:   if {$mapped} {
                   1878:     WithdrawEvaluationOf $head
                   1879:   } else {
                   1880:     ShowEvaluationOf $head
                   1881:   }
                   1882: 
                   1883: }
                   1884: 
                   1885: 
                   1886: proc WithdrawEvaluationOf {head} {
                   1887:   set win [WindowLink $head.evaluation]
                   1888:   if {"$win" != ""} {
                   1889:     pack unpack $win
                   1890:   }
                   1891: }
                   1892: 
                   1893: 
                   1894: proc ShowEvaluationOf {head} {
                   1895:   set win [WindowLink $head.evaluation]
                   1896:   if {$win == {}} {
                   1897:     set win [MakeWindow.evaluation $head [winfo screen $head]]
                   1898:   }
                   1899:   #wm raise $win
                   1900:   #wm deiconify $win
                   1901:   set parent [WindowLink $win.parent]
                   1902:   #pack append [WindowLink $head.col2]\
                   1903:   #  $parent {top frame nw fill}
                   1904:   pack append $parent\
                   1905:     $win {top frame nw fillx}
                   1906:   update idletasks
                   1907:   sim UpdateEvaluation
                   1908: }
                   1909: 
                   1910: 
                   1911: proc WithdrawEvaluations {} {
                   1912:   global EvaluationWindows EvaluationsVisible
                   1913:   foreach win $EvaluationWindows {
                   1914:     #wm withdraw $win
                   1915:     #set parent [WindowLink $win.parent]
                   1916:     #pack unpack $parent
                   1917:     pack unpack $win
                   1918:   }
                   1919:   set EvaluationsVisible 0
                   1920: }
                   1921: 
                   1922: 
                   1923: proc EvaluationVisible {w v} {
                   1924:     global EvaluationsVisible
                   1925:     global [set var $w.visible]
                   1926:     
                   1927:     set $var $v
                   1928: 
                   1929:     if ($v) {
                   1930:        set EvaluationsVisible [expr "$EvaluationsVisible + 1"]
                   1931:     } else {
                   1932:        set EvaluationsVisible [expr "$EvaluationsVisible - 1"]
                   1933:     }
                   1934: }
                   1935: 
                   1936: 
                   1937: proc UISetEvaluation {changed score ps0 ps1 ps2 ps3 pv0 pv1 pv2 pv3 pop delta assessed cityclass citylevel goodyes goodno title} {
                   1938:   global EvaluationWindows EvaluationsVisible CurrentDate
                   1939: 
                   1940:   set class [string tolower $cityclass]
                   1941:   UISetMessage "$CurrentDate: Score $score, $class population $pop."
                   1942: 
                   1943:   if {$EvaluationsVisible} {
                   1944: 
                   1945:     foreach win $EvaluationWindows {
                   1946: 
                   1947:       global [set var $win.visible]
                   1948:       set visible [eval ident "\$\{$var\}"]
                   1949: 
                   1950:       if {$visible} {
                   1951: 
                   1952:        # TODO: set evaluation window and icon title
                   1953:        #wm title $win "$title"
                   1954:        #wm iconname $win "$title"
                   1955: 
                   1956:        set w [WindowLink $win.goodjob]
                   1957:        set old [lindex [$w configure -text] 4]
                   1958:        set new "$goodyes\n$goodno"
                   1959:        if {$old != $new} {
                   1960:          $w configure -text $new
                   1961:        }
                   1962: 
                   1963:        set w [WindowLink $win.problemnames]
                   1964:        set old [lindex [$w configure -text] 4]
                   1965:        set new "$ps0\n$ps1\n$ps2\n$ps3"
                   1966:        if {$old != $new} {
                   1967:          $w configure -text $new
                   1968:        }
                   1969: 
                   1970:        set w [WindowLink $win.problempercents]
                   1971:        set old [lindex [$w configure -text] 4]
                   1972:        set new "$pv0\n$pv1\n$pv2\n$pv3"
                   1973:        if {$old != $new} {
                   1974:          $w configure -text $new
                   1975:        }
                   1976: 
                   1977:        set w [WindowLink $win.stats]
                   1978:        set old [lindex [$w configure -text] 4]
                   1979:        set new "$pop\n$delta\n\n$assessed\n$cityclass\n$citylevel"
                   1980:        if {$old != $new} {
                   1981:          $w configure -text $new
                   1982:        }
                   1983: 
                   1984:        set w [WindowLink $win.score]
                   1985:        set old [lindex [$w configure -text] 4]
                   1986:        set new "$score\n$changed"
                   1987:        if {$old != $new} {
                   1988:          $w configure -text $new
                   1989:        }
                   1990:       }
                   1991:     }
                   1992:   }
                   1993: }
                   1994: 
                   1995: 
                   1996: ########################################################################
                   1997: # File Window Handlers
                   1998: 
                   1999: 
                   2000: proc ShowFileOf {head} {
                   2001:   set win [WindowLink $head.file]
                   2002:   if {$win == {}} {
                   2003:     set win [MakeWindow.file $head [winfo screen $head]]
                   2004:   }
                   2005:   wm deiconify $win
                   2006:   wm raise $win
                   2007:   return $win
                   2008: }
                   2009: 
                   2010: 
                   2011: proc ShowFiles {} {
                   2012:   global HeadWindows
                   2013:   foreach win $HeadWindows {
                   2014:     ShowFileOf $win
                   2015:   }
                   2016: }
                   2017: 
                   2018: 
                   2019: proc WithdrawFiles {} {
                   2020:   global FileWindows
                   2021:   foreach win $FileWindows {
                   2022:     wm withdraw $win
                   2023:   }
                   2024: }
                   2025: 
                   2026: 
                   2027: proc DoFileDialog {win Message Path Pattern FileName ActionOk ActionCancel} {
                   2028:   ShowFileDialog $win "$Path" "$Pattern"
                   2029:   $win.message1 configure -text "$Message"
                   2030:   $win.path.path delete 0 end
                   2031:   $win.path.path insert 0 $Path
                   2032:   $win.file.file delete 0 end
                   2033:   $win.file.file insert 0 "$FileName"
                   2034:   $win.frame1.ok config -command "
                   2035:       $ActionOk \[$win.file.file get\] \[$win.path.path get\]
                   2036:       wm withdraw $win"
                   2037:   $win.frame1.rescan config -command "
                   2038:       ShowFileDialog $win \[$win.path.path get\] $Pattern"
                   2039:   $win.frame1.cancel config -command "
                   2040:       $ActionCancel
                   2041:       wm withdraw $win"
                   2042:   bind $win.files.files "<Double-Button-1>" "\
                   2043:     FileSelectDouble $win %W %y $Pattern \"
                   2044:        $ActionOk \[$win.file.file get\] \[$win.path.path get\]\""
                   2045:   bind $win.path.path <Return> "
                   2046:     ShowFileDialog $win \[$win.path.path get\] $Pattern
                   2047:     $win.file.file cursor 0
                   2048:     focus $win.file.file"
                   2049:   bind $win.file.file <Return> "\
                   2050:     $ActionOk \[$win.file.file get\] \[$win.path.path get]
                   2051:     wm withdraw $win"
                   2052: }
                   2053: 
                   2054: 
                   2055: proc BindSelectOne {win Y} {
                   2056:   set Nearest [$win nearest $Y]
                   2057:   if {$Nearest >= 0} {
                   2058:     $win select from $Nearest
                   2059:     $win select to $Nearest
                   2060:   }
                   2061: }
                   2062: 
                   2063: 
                   2064: proc FileSelect {win widget Y} {
                   2065:   BindSelectOne $widget $Y
                   2066:   set Nearest [$widget nearest $Y]
                   2067:   if {$Nearest >= 0} {
                   2068:     set Path [$win.path.path get]
                   2069:     set TmpEntry [$widget get $Nearest]
                   2070:     if {[string compare "/" [string index $TmpEntry \
                   2071:           [expr [string length $TmpEntry]-1]]] == 0 || \
                   2072:         [string compare "@" [string index $TmpEntry \
                   2073:           [expr [string length $TmpEntry]-1]]] == 0} {
                   2074:       # handle directories, and symbolic links to directories
                   2075:       set FileName [string range $TmpEntry 0 \
                   2076:             [expr [string length $TmpEntry]-2]]
                   2077:       # whoops / or @ is part of the name
                   2078:       if {[MiscIsDir $Path/$FileName] != 1} {
                   2079:         set FileName $TmpEntry
                   2080:       }
                   2081:     } {
                   2082:       if {[string compare "*" [string index $TmpEntry \
                   2083:             [expr [string length $TmpEntry]-1]]] == 0} {
                   2084:         # handle executable filenames
                   2085:         set FileName [string range $TmpEntry 0 \
                   2086:               [expr [string length $TmpEntry]-2]]
                   2087:         # whoops * is part of the name
                   2088:         if {[file executable $Path/$FileName] != 1} {
                   2089:           set FileName $TmpEntry
                   2090:         }
                   2091:       } {
                   2092:         # a ordinary filename
                   2093:         set FileName $TmpEntry
                   2094:       }
                   2095:     }
                   2096:     # enter the selected filename into the filename field
                   2097:     if {[MiscIsDir $Path/$FileName] != 1} {
                   2098:       $win.file.file delete 0 end
                   2099:       $win.file.file insert 0 $FileName
                   2100:     }
                   2101:   }
                   2102: }
                   2103: 
                   2104: 
                   2105: proc FileSelectDouble {win widget Y Pattern Action} {
                   2106:   BindSelectOne $widget $Y
                   2107:   set Nearest [$widget nearest $Y]
                   2108:   if {$Nearest >= 0} {
                   2109:     set Path [$win.path.path get]
                   2110:     set TmpEntry [$widget get $Nearest]
                   2111:     if {[string compare $TmpEntry "../"] == 0} {
                   2112:       # go up one directory
                   2113:       set TmpEntry \
                   2114:         [string trimright [string trimright [string trim $Path] /] @]
                   2115:       if {[string length $TmpEntry] <= 0} {
                   2116:         return
                   2117:       }
                   2118:       set Path [file dirname $TmpEntry]
                   2119:       $win.path.path delete 0 end
                   2120:       $win.path.path insert 0 $Path
                   2121:       ShowFileDialog $win $Path $Pattern
                   2122:     } {
                   2123:       if {[string compare "/" [string index $TmpEntry \
                   2124:             [expr [string length $TmpEntry]-1]]] == 0 || \
                   2125:           [string compare "@" [string index $TmpEntry \
                   2126:             [expr [string length $TmpEntry]-1]]] == 0} {
                   2127:         # handle directorys, and symbolic links to directorys
                   2128:         set FileName [string range $TmpEntry 0 \
                   2129:               [expr [string length $TmpEntry]-2]]
                   2130:         # whoops / or @ is part of the name
                   2131:         if {[MiscIsDir $Path/$FileName] != 1} {
                   2132:           set FileName $TmpEntry
                   2133:         }
                   2134:       } {
                   2135:         if {[string compare "*" [string index $TmpEntry \
                   2136:               [expr [string length $TmpEntry]-1]]] == 0} {
                   2137:           # handle executable filenames
                   2138:           set FileName [string range $TmpEntry 0 \
                   2139:                 [expr [string length $TmpEntry]-2]]
                   2140:           # whoops * is part of the name
                   2141:           if {[file executable $Path/$FileName] != 1} {
                   2142:             set FileName $TmpEntry
                   2143:           }
                   2144:         } {
                   2145:           # a ordinary filename
                   2146:           set FileName $TmpEntry
                   2147:         }
                   2148:       }
                   2149:       # change directory
                   2150:       if {[MiscIsDir $Path/$FileName] == 1} {
                   2151:         if {[string compare "/" [string index $Path \
                   2152:               [expr [string length $Path]-1]]] == 0} {
                   2153:            append Path $FileName
                   2154:         } {
                   2155:           append Path / $FileName
                   2156:         }
                   2157:         $win.path.path delete 0 end
                   2158:         $win.path.path insert 0 $Path
                   2159:         ShowFileDialog $win $Path $Pattern
                   2160:       } {
                   2161:         # enter the selected filename into the filename field
                   2162:        $win.file.file delete 0 end
                   2163:        $win.file.file insert 0 "$FileName"
                   2164:         if {[string length $Action] > 0} {
                   2165:           eval $Action
                   2166:         }
                   2167:         wm withdraw $win
                   2168:       }
                   2169:     }
                   2170:   }
                   2171: }
                   2172: 
                   2173: 
                   2174: proc NameComplete {win Type} {
                   2175: 
                   2176:   set NewFile ""
                   2177:   set Matched ""
                   2178: 
                   2179:   if {[string compare $Type path] == 0} {
                   2180:     set DirName [file dirname [$win.path.path get]]
                   2181:     set FileName [file tail [$win.path.path get]]
                   2182:   } {
                   2183:     set DirName [file dirname [$win.path.path get]/]
                   2184:     set FileName [file tail [$win.file.file get]]
                   2185:   }
                   2186: 
                   2187:   set FoundCounter 0
                   2188:   if {[MiscIsDir $DirName] == 1} {
                   2189:     catch "exec ls $DirName/" Result
                   2190:     set Counter 0
                   2191:     set ListLength [llength $Result]
                   2192:     # go through list
                   2193:     while {$Counter < $ListLength} {
                   2194:       if {[string length $FileName] == 0} {
                   2195:         if {$FoundCounter == 0} {
                   2196:           set NewFile [lindex $Result $Counter]
                   2197:         } {
                   2198:           set Counter1 0
                   2199:           set TmpFile1 $NewFile
                   2200:           set TmpFile2 [lindex $Result $Counter]
                   2201:           set Length1 [string length $TmpFile1]
                   2202:           set Length2 [string length $TmpFile2]
                   2203:           set NewFile ""
                   2204:           if {$Length1 > $Length2} {
                   2205:             set Length1 $Length2
                   2206:           }
                   2207:           while {$Counter1 < $Length1} {
                   2208:             if {[string compare [string index $TmpFile1 $Counter1] \
                   2209:                   [string index $TmpFile2 $Counter1]] == 0} {
                   2210:               append NewFile [string index $TmpFile1 $Counter1]
                   2211:             } {
                   2212:               break
                   2213:             }
                   2214:             incr Counter1 1
                   2215:           }
                   2216:         }
                   2217:         incr FoundCounter 1
                   2218:       } {
                   2219:         if {[regexp "^$FileName" [lindex $Result $Counter] \
                   2220:               Matched] == 1} {
                   2221:           if {$FoundCounter == 0} {
                   2222:             set NewFile [lindex $Result $Counter]
                   2223:           } {
                   2224:             set Counter1 0
                   2225:             set TmpFile1 $NewFile
                   2226:             set TmpFile2 [lindex $Result $Counter]
                   2227:             set Length1 [string length $TmpFile1]
                   2228:             set Length2 [string length $TmpFile2]
                   2229:             set NewFile ""
                   2230:             if {$Length1 > $Length2} {
                   2231:               set Length1 $Length2
                   2232:             }
                   2233:             while {$Counter1 < $Length1} {
                   2234:               if {[string compare [string index $TmpFile1 $Counter1] \
                   2235:                     [string index $TmpFile2 $Counter1]] == 0} {
                   2236:                 append NewFile [string index $TmpFile1 $Counter1]
                   2237:               } {
                   2238:                 break
                   2239:               }
                   2240:               incr Counter1 1
                   2241:             }
                   2242:           }
                   2243:           incr FoundCounter 1
                   2244:         }
                   2245:       }
                   2246:       incr Counter 1
                   2247:     }
                   2248:   }
                   2249: 
                   2250:   if {$FoundCounter == 1} {
                   2251:     if {[MiscIsDir $DirName/$NewFile] == 1} {
                   2252:       if {[string compare $DirName "/"] == 0} {
                   2253:         $win.path.path delete 0 end
                   2254:         $win.path.path insert 0 "/[string trim [string trim $NewFile /] @]/"
                   2255:       } {
                   2256:         $win.path.path delete 0 end
                   2257:         $win.path.path insert 0 "[string trimright $DirName /]/[string trim [string trim $NewFile /] @]/"
                   2258:       }
                   2259:     } {
                   2260:       $win.path.path delete 0 end
                   2261:       $win.path.path insert 0 \
                   2262:         "[string trim [string trimright $DirName /] @]/"
                   2263:       $win.file.file delete 0 end
                   2264:       $win.file.file insert 0 "$NewFile"
                   2265:     }
                   2266:   } {
                   2267:     if {[MiscIsDir $DirName/$NewFile] == 1 ||
                   2268:         [string compare $Type path] == 0} {
                   2269:       $win.path.path delete 0 end
                   2270:       $win.path.path insert 0 \
                   2271:         "[string trimright $DirName /]/[string trim [string trim $NewFile /] @]"
                   2272:     } {
                   2273:       $win.path.path delete 0 end
                   2274:       $win.path.path insert 0 "$DirName"
                   2275:       if {[string length $NewFile] > 0} {
                   2276:         $win.file.file delete 0 end
                   2277:         $win.file.file insert 0 "$NewFile"
                   2278:       }
                   2279:     }
                   2280:   }
                   2281: }
                   2282: 
                   2283: 
                   2284: proc ShowFileDialog {win Path Pattern} {
                   2285:   busy $win {
                   2286:     set Path [lindex [split $Path] 0]
                   2287:     if {[$win.files.files size] > 0} {
                   2288:       $win.files.files delete 0 end
                   2289:     }
                   2290:     # read directory
                   2291:     if {[catch "exec ls -F $Path" Result]} {
                   2292:       set ElementList {}
                   2293:     }
                   2294:     if {[string match $Result "* not found"]} {
                   2295:       set ElementList {}
                   2296:     }
                   2297:     set ElementList [lsort $Result]
                   2298: 
                   2299:     # insert ..
                   2300:     if {[string compare $Path "/"]} {
                   2301:       $win.files.files insert end "../"
                   2302:     }
                   2303: 
                   2304:     # walk through list
                   2305:     foreach Counter $ElementList {
                   2306:       # insert filename
                   2307:       if {[string match $Pattern $Counter] == 1} {
                   2308:        if {[string compare $Counter "../"] &&
                   2309:            [string compare $Counter "./"]} {
                   2310:          $win.files.files insert end $Counter
                   2311:        }
                   2312:       } else {
                   2313:         set fn $Path/[string trim [string trim [string trim $Counter /] @] *]
                   2314:        if {[MiscIsDir $fn]} {
                   2315:          $win.files.files insert end $Counter
                   2316:        }
                   2317:       }
                   2318:     }
                   2319:   }
                   2320: }
                   2321: 
                   2322: 
                   2323: proc MiscIsDir {PathName} {
                   2324: 
                   2325:   if {[file isdirectory $PathName] == 1} {
                   2326:     return 1
                   2327:   } {
                   2328:     catch "file type $PathName" Type
                   2329:     if {[string compare $Type link] == 0} {
                   2330:       set LinkName [file readlink $PathName]
                   2331:       catch "file type $LinkName" Type
                   2332:       while {[string compare $Type link] == 0} {
                   2333:         set LinkName [file readlink $LinkName]
                   2334:       }
                   2335:       return [file isdirectory $LinkName]
                   2336:     }
                   2337:   }
                   2338:   return 0
                   2339: }
                   2340: 
                   2341: 
                   2342: proc busy {win cmds} {
                   2343:     set busy {}
                   2344:     set list [winfo children $win]
                   2345:     set busy $list
                   2346:     while {$list != ""} {
                   2347:        set next {}
                   2348:        foreach w $list {
                   2349:            set class [winfo class $w]
                   2350:            set cursor [lindex [$w config -cursor] 4]
                   2351:            if {[winfo toplevel $w] == $w} {
                   2352:                lappend busy [list $w $cursor]
                   2353:            }
                   2354:            set next [concat $next [winfo children $w]]
                   2355:        }
                   2356:        set list $next
                   2357:     }
                   2358: 
                   2359:     foreach w $busy {
                   2360:        catch {[lindex $w 0] config -cursor watch}
                   2361:     }
                   2362: 
                   2363:     update idletasks
                   2364: 
                   2365:     set error [catch {uplevel eval [list $cmds]} result]
                   2366: 
                   2367:     foreach w $busy {
                   2368:        catch {[lindex $w 0] config -cursor [lindex $w 1]}
                   2369:     }
                   2370: 
                   2371:     if $error {
                   2372:        error $result
                   2373:     } else {
                   2374:        return $result
                   2375:     }
                   2376: }
                   2377: 
                   2378: 
                   2379: ########################################################################
                   2380: # Editor Window Handlers
                   2381: 
                   2382: proc ShowEditorOf {head} {
                   2383:   global EditorWindows
                   2384:   set found 0
                   2385:   foreach win $EditorWindows {
                   2386:     if {[WindowLink $win.head] == $head} {
                   2387:       set parent [WindowLink $win.parent]
                   2388:       #pack append [WindowLink $head.col2]\
                   2389:       #  $parent {top frame nw expand fill}
                   2390:       pack append $parent\
                   2391:        $win {top frame nw expand fill}
                   2392:       set found 1
                   2393:     }
                   2394:   }
                   2395:   if {$found == 0} {
                   2396:     NewEditorOf $head
                   2397:   } else {
                   2398:     update idletasks
                   2399:     sim UpdateEditors
                   2400:     sim UpdateMaps
                   2401:   }
                   2402: }
                   2403: 
                   2404: 
                   2405: proc NewEditorOf {head} {
                   2406:   set win [MakeWindow.editor $head [winfo screen $head]]
                   2407:   #wm deiconify $win
                   2408:   set parent [WindowLink $win.parent]
                   2409:   pack append $parent\
                   2410:     $win {top frame nw expand fill}
                   2411:   update idletasks
                   2412:   sim UpdateEditors
                   2413:   sim UpdateMaps
                   2414: }
                   2415: 
                   2416: 
                   2417: proc ShowEditors {} {
                   2418:   global HeadWindows
                   2419:   foreach win $HeadWindows {
                   2420:     ShowEditorOf $win
                   2421:   }
                   2422: }
                   2423: 
                   2424: 
                   2425: proc WithdrawEditors {} {
                   2426:   global EditorWindows
                   2427:   foreach win $EditorWindows {
                   2428:     #set parent [WindowLink $win.parent]
                   2429:     #pack unpack $parent
                   2430:     pack unpack $win
                   2431:   }
                   2432: }
                   2433: 
                   2434: 
                   2435: proc InitEditors {} {
                   2436:   global EditorWindows
                   2437:   foreach win $EditorWindows {
                   2438:     InitEditor $win
                   2439:   }
                   2440: }
                   2441: 
                   2442: 
                   2443: proc InitEditor {win} {
                   2444:   set e [WindowLink $win.view]
                   2445:   UISetToolState $win 7
                   2446:   $e ToolState 7
                   2447:   set size [$e size]
                   2448:   $e Pan 960 800
                   2449:   $e AutoGoing 0
                   2450:   global $e.TrackState
                   2451:   set $e.TrackState {}
                   2452: }
                   2453: 
                   2454: 
                   2455: proc SetEditorAutoGoto {win val} {
                   2456:   global AutoGoto.$win
                   2457:   set AutoGoto.$win $val
                   2458:   set e [WindowLink $win.view]
                   2459:   $e AutoGoto $val
                   2460: }
                   2461: 
                   2462: 
                   2463: proc SetEditorControls {win val} {
                   2464:   global Controls.$win
                   2465:   set Controls.$win $val
                   2466:   if {$val} {
                   2467:     pack append $win $win.leftframe {left frame center filly} 
                   2468:   } else {
                   2469:     pack unpack $win.leftframe
                   2470:   }
                   2471: }
                   2472: 
                   2473: 
                   2474: proc SetEditorOverlay {win val} {
                   2475:   global Overlay.$win
                   2476:   set Overlay.$win $val
                   2477:   set e [WindowLink $win.view]
                   2478:   $e ShowOverlay $val
                   2479: }
                   2480: 
                   2481: 
                   2482: proc SetEditorDynamicFilter {win val} {
                   2483:   global DynamicFilter.$win
                   2484:   set DynamicFilter.$win $val
                   2485:   set e [WindowLink $win.view]
                   2486:   $e DynamicFilter $val
                   2487:   if {$val == 1} then {
                   2488:     ShowFrobOf [WindowLink $win.head]
                   2489:   }
                   2490: }
                   2491: 
                   2492: 
                   2493: proc SetEditorSkip {win val} {
                   2494:   set e [WindowLink $win.view]
                   2495:   $e Skip $val
                   2496: }
                   2497: 
                   2498: 
                   2499: proc EditorToolDown {mod w x y} {
                   2500:   global [set var $w.TrackState]
                   2501: 
                   2502:   $w ToolMode 1
                   2503: 
                   2504:   case [$w ToolState] in \
                   2505:     7 { # bulldozer
                   2506:       UIMakeSoundOn $w edit Rumble "-repeat 4"
                   2507:     } \
                   2508:     10 { # chalk
                   2509:       StartChalk $w
                   2510:     }
                   2511: 
                   2512:   case $mod in \
                   2513:     constrain {
                   2514:       set $var [list constrain_start $x $y]
                   2515:       $w ToolConstrain $x $y
                   2516:     } \
                   2517:     default {
                   2518:       set $var none
                   2519:     }
                   2520:   EditorTool ToolDown $w $x $y
                   2521:   sim NeedRest 5
                   2522: }
                   2523: 
                   2524: 
                   2525: proc EditorToolDrag {w x y} {
                   2526:   EditorTool ToolDrag $w $x $y
                   2527:   sim NeedRest 5
                   2528: }
                   2529: 
                   2530: 
                   2531: proc EditorToolUp {w x y} {
                   2532:   global [set var $w.TrackState]
                   2533:   $w ToolMode 0
                   2534: 
                   2535:   case [$w ToolState] in \
                   2536:     7 { # bulldozer
                   2537:      UIStopSoundOn $w edit 1
                   2538:     } \
                   2539:     10 { # chalk
                   2540:       StopChalk $w
                   2541:     }
                   2542: 
                   2543:   EditorTool ToolUp $w $x $y
                   2544:   set $var {}
                   2545:   $w ToolConstrain -1 -1
                   2546:   sim UpdateMaps
                   2547:   sim UpdateEditors
                   2548:   sim NeedRest 5
                   2549: }
                   2550: 
                   2551: 
                   2552: proc EditorTool {action w x y} {
                   2553:   global [set var $w.TrackState]
                   2554:   set state [eval ident "\$\{$var\}"]
                   2555:   case [lindex $state 0] in \
                   2556:     constrain_start {
                   2557:       set x0 [lindex $state 1]
                   2558:       set y0 [lindex $state 2]
                   2559:       set dx [expr "$x - $x0"]
                   2560:       set dy [expr "$y - $y0"]
                   2561:       if [expr "($dx > 16) || ($dx < -16)"] then {
                   2562:         $w ToolConstrain -1 $y0
                   2563:         set $var none
                   2564:       } else {
                   2565:        if [expr "($dy > 16) || ($dy < -16)"] then {
                   2566:          $w ToolConstrain $x0 -1
                   2567:          set $var none
                   2568:        }
                   2569:       }
                   2570:     }
                   2571:   $w $action $x $y
                   2572: }
                   2573: 
                   2574: 
                   2575: proc StartChalk {w} {
                   2576:   sim CollapseMotion 0
                   2577: }
                   2578: 
                   2579: 
                   2580: proc StopChalk {w} {
                   2581:   sim CollapseMotion 1
                   2582: }
                   2583: 
                   2584: 
                   2585: proc EditorPanDown {mod w x y} {
                   2586:   global [set var $w.TrackState]
                   2587:   $w ToolMode -1
                   2588:   case $mod in \
                   2589:     constrain {
                   2590:       set $var [list constrain_start $x $y]
                   2591:       $w ToolConstrain $x $y
                   2592:     } \
                   2593:     default {
                   2594:       set $var none
                   2595:     }
                   2596:   EditorTool PanStart $w $x $y
                   2597: }
                   2598: 
                   2599: 
                   2600: proc EditorPanDrag {w x y} {
                   2601:   EditorTool PanTo $w $x $y
                   2602: }
                   2603: 
                   2604: 
                   2605: proc EditorPanUp {w x y} {
                   2606:   $w AutoGoing 0
                   2607:   $w ToolMode 0
                   2608:   EditorTool PanTo $w $x $y
                   2609:   $w ToolConstrain -1 -1
                   2610:   sim UpdateMaps
                   2611:   sim UpdateEditors
                   2612: }
                   2613: 
                   2614: 
                   2615: proc EditorKeyDown {w k} {
                   2616:   $w KeyDown $k
                   2617: }
                   2618: 
                   2619: 
                   2620: proc EditorKeyUp {w k} {
                   2621:   $w KeyUp $k
                   2622: }
                   2623: 
                   2624: 
                   2625: proc BindEditorButtons {win} {
                   2626:   set w [WindowLink $win.top]
                   2627: 
                   2628:   bind $win <1> "CancelPie $win ; EditorToolDown none %W %x %y"
                   2629:   bind $win <B1-Motion> {EditorToolDrag %W %x %y}
                   2630:   bind $win <ButtonRelease-1> {EditorToolUp %W %x %y}
                   2631: 
                   2632:   bind $win <Control-1> "CancelPie $win ; EditorToolDown constrain %W %x %y"
                   2633:   bind $win <Control-B1-Motion> {EditorToolDrag %W %x %y}
                   2634:   bind $win <Control-ButtonRelease-1> {EditorToolUp %W %x %y}
                   2635: 
                   2636:   bind $win <2> "CancelPie $win ; EditorPanDown none %W %x %y"
                   2637:   bind $win <B2-Motion> {EditorPanDrag %W %x %y}
                   2638:   bind $win <ButtonRelease-2> {EditorPanUp %W %x %y}
                   2639: 
                   2640:   bind $win <Control-2> "CancelPie $win ; EditorPanDown constrain %W %x %y"
                   2641:   bind $win <Control-B2-Motion> {EditorPanDrag %W %x %y}
                   2642:   bind $win <Control-ButtonRelease-2> {EditorPanUp %W %x %y}
                   2643: 
                   2644:   InitPie $win $w.toolpie
                   2645: }
                   2646: 
                   2647: 
                   2648: proc UISetFunds {funds} {
                   2649:   global HeadWindows
                   2650:   foreach win $HeadWindows {
                   2651:     [WindowLink $win.funds] configure -text "$funds"
                   2652:   }
                   2653: }
                   2654: 
                   2655: 
                   2656: proc UISetDate {date month year} {
                   2657:   global HeadWindows
                   2658:   global CurrentDate
                   2659:   
                   2660:   set CurrentDate "$date"
                   2661: 
                   2662:   foreach win $HeadWindows {
                   2663:     [WindowLink $win.date] Set $month $year
                   2664:   }
                   2665: }
                   2666: 
                   2667: 
                   2668: proc SetPriority {index} {
                   2669:   case $index { \
                   2670:     {0} {
                   2671:       sim Delay 500000
                   2672:       sim Skips 0
                   2673:     } \
                   2674:     {1} {
                   2675:       sim Delay 100000
                   2676:       sim Skips 0
                   2677:     } \
                   2678:     {2} {
                   2679:       sim Delay 25000
                   2680:       sim Skips 0
                   2681:     } \
                   2682:     {3} {
                   2683:       sim Delay 5000
                   2684:       sim Skips 20
                   2685:     } \
                   2686:     {4} {
                   2687:       sim Delay 5
                   2688:       sim Skips 500
                   2689:     }
                   2690:   }
                   2691: }
                   2692: 
                   2693: 
                   2694: proc UISetDemand {r c i} {
                   2695:   global HeadWindows DemandRes DemandCom DemandInd
                   2696: 
                   2697:   set DemandRes $r
                   2698:   set DemandCom $c
                   2699:   set DemandInd $i
                   2700: 
                   2701:   if {$r <= 0} then {set ry0 32} else {set ry0 24}
                   2702:   set ry1 [expr "$ry0 - $r"]
                   2703:   if {$c <= 0} then {set cy0 32} else {set cy0 24}
                   2704:   set cy1 [expr "$cy0 - $c"]
                   2705:   if {$i <= 0} then {set iy0 32} else {set iy0 24}
                   2706:   set iy1 [expr "$iy0 - $i"]
                   2707: 
                   2708:   foreach win $HeadWindows {
                   2709:     set can [WindowLink $win.demand]
                   2710: #    $can coords r 8 $ry0 14 $ry1
                   2711: #    $can coords c 17 $cy0 23 $cy1
                   2712: #    $can coords i 26 $iy0 32 $iy1
                   2713:     $can coords r 49 $ry0 55 $ry1
                   2714:     $can coords c 58 $cy0 64 $cy1
                   2715:     $can coords i 67 $iy0 73 $iy1
                   2716:   }
                   2717: }
                   2718: 
                   2719: 
                   2720: proc UISetOptions {autobudget autogoto autobulldoze disasters sound animation messages notices} {
                   2721:   global AutoBudget AutoGoto AutoBulldoze Disasters Sound
                   2722:   set AutoBudget $autobudget
                   2723:   set AutoGoto $autogoto
                   2724:   set AutoBulldoze $autobulldoze
                   2725:   set Disasters $disasters
                   2726:   set Sound $sound
                   2727:   set DoAnimation $animation
                   2728:   set DoMessages $messages
                   2729:   set DoNotices $notices
                   2730: }
                   2731: 
                   2732: 
                   2733: proc UIDidToolRes {win x y} {
                   2734:   UIMakeSoundOn $win edit O "-speed 140"
                   2735: }
                   2736: 
                   2737: 
                   2738: proc UIDidToolCom {win x y} {
                   2739:   UIMakeSoundOn $win edit A "-speed 140"
                   2740: }
                   2741: 
                   2742: 
                   2743: proc UIDidToolInd {win x y} {
                   2744:   UIMakeSoundOn $win edit E "-speed 140"
                   2745: }
                   2746: 
                   2747: 
                   2748: proc UIDidToolFire {win x y} {
                   2749:   UIMakeSoundOn $win edit O "-speed 130"
                   2750: }
                   2751: 
                   2752: 
                   2753: proc UIDidToolQry {win x y} {
                   2754:   UIMakeSoundOn $win edit E "-speed 200"
                   2755: }
                   2756: 
                   2757: 
                   2758: proc UIDidToolPol {win x y} {
                   2759:   UIMakeSoundOn $win edit E "-speed 130"
                   2760: }
                   2761: 
                   2762: 
                   2763: proc UIDidToolWire {win x y} {
                   2764:   UIMakeSoundOn $win edit O "-speed 120"
                   2765: }
                   2766: 
                   2767: 
                   2768: proc UIDidToolDozr {win x y} {
                   2769:   UIMakeSoundOn $win edit Rumble
                   2770: }
                   2771: 
                   2772: 
                   2773: proc UIDidToolRail {win x y} {
                   2774:   UIMakeSoundOn $win edit O "-speed 100"
                   2775: }
                   2776: 
                   2777: 
                   2778: proc UIDidToolRoad {win x y} {
                   2779:   UIMakeSoundOn $win edit E "-speed 100"
                   2780: }
                   2781: 
                   2782: 
                   2783: proc UIDidToolChlk {win x y} {
                   2784: }
                   2785: 
                   2786: 
                   2787: proc UIDidToolEraser {win x y} {
                   2788: }
                   2789: 
                   2790: 
                   2791: proc UIDidToolStad {win x y} {
                   2792:   UIMakeSoundOn $win edit O "-speed 90"
                   2793: }
                   2794: 
                   2795: 
                   2796: proc UIDidToolPark {win x y} {
                   2797:   UIMakeSoundOn $win edit A "-speed 130"
                   2798: }
                   2799: 
                   2800: 
                   2801: proc UIDidToolSeap {win x y} {
                   2802:   UIMakeSoundOn $win edit E "-speed 90"
                   2803: }
                   2804: 
                   2805: 
                   2806: proc UIDidToolCoal {win x y} {
                   2807:   UIMakeSoundOn $win edit O "-speed 75"
                   2808: }
                   2809: 
                   2810: 
                   2811: proc UIDidToolNuc {win x y} {
                   2812:   UIMakeSoundOn $win edit E "-speed 75"
                   2813: }
                   2814: 
                   2815: 
                   2816: proc UIDidToolAirp {win x y} {
                   2817:   UIMakeSoundOn $win edit A "-speed 50"
                   2818: }
                   2819: 
                   2820: 
                   2821: proc UISetToolState {w state} {
                   2822:   global EditorPallets EditorPalletImages ToolInfo
                   2823:   set win [WindowLink $w.top]
                   2824:   #echo "UISETTOOLSTATE w $w win $win $state"
                   2825:   ExclusivePallet $state $win $EditorPallets ic $EditorPalletImages \
                   2826:        raised sunken {NoFunction}
                   2827:        {NoFunction}
                   2828:   set c1 [WindowLink $w.cost1]
                   2829:   if {"$c1" != ""} {
                   2830:     set info [lindex $ToolInfo $state]
                   2831:     set cost1 [lindex $info 1]
                   2832:     set cost2 [lindex $info 2]
                   2833:     $c1 configure -text "$cost1"
                   2834:     [WindowLink $w.cost2] configure -text "$cost2"
                   2835:   }
                   2836: }
                   2837: 
                   2838: 
                   2839: proc UIShowZoneStatus {zone density value crime pollution growth x y} {
                   2840:   global QueryX QueryY
                   2841:   set QueryX [expr "8 + 16 * $x"]
                   2842:   set QueryY [expr "8 + 16 * $y"]
                   2843:   UIShowPicture 9 [list $zone $density $value $crime $pollution $growth]
                   2844: }
                   2845: 
                   2846: 
                   2847: ########################################################################
                   2848: # Map Window Handlers
                   2849: 
                   2850: 
                   2851: proc ShowMapOf {head} {
                   2852:   global MapWindows
                   2853:   set found 0
                   2854:   foreach win $MapWindows {
                   2855:     if {"[WindowLink $win.head]" == "$head"} {
                   2856:       global MapPanelWidth MapPanelHeight
                   2857:       #place configure $win -x 0 -y 0 -width $MapPanelWidth -height $MapPanelHeight
                   2858:       #[WindowLink $win.parent] configure -width $MapPanelWidth -height $MapPanelHeight
                   2859:       set parent [WindowLink $win.parent]
                   2860:       pack append [WindowLink $head.w2] \
                   2861:          $win {top frame nw expand fill}
                   2862:       set found 1
                   2863:     }
                   2864:   }
                   2865:   if {$found == 0} {
                   2866:     NewMapOf $head
                   2867:   } else {
                   2868:     update idletasks
                   2869:     sim UpdateMaps
                   2870:   }
                   2871: }
                   2872: 
                   2873: 
                   2874: proc NewMapOf {head} {
                   2875:   set win [MakeWindow.map $head [winfo screen $head]]
                   2876:   global MapPanelWidth MapPanelHeight
                   2877:   #place configure $win -x 0 -y 0 -width $MapPanelWidth -height $MapPanelHeight
                   2878:   #[WindowLink $win.parent] configure -width $MapPanelWidth -height $MapPanelHeight
                   2879:   set parent [WindowLink $win.parent]
                   2880:   #pack append [WindowLink $head.col1]\
                   2881:   #  $parent {top frame nw fillx}
                   2882:   pack append [WindowLink $head.w2] \
                   2883:       $win {top frame nw expand fill}
                   2884:   sim UpdateMaps
                   2885: }
                   2886: 
                   2887: 
                   2888: proc ShowMaps {} {
                   2889:   global HeadWindows
                   2890:   foreach win $HeadWindows {
                   2891:     ShowMapOf $win
                   2892:   }
                   2893: }
                   2894: 
                   2895: 
                   2896: proc WithdrawMaps {} {
                   2897:   global MapWindows
                   2898:   foreach win $MapWindows {
                   2899:     #place forget $win
                   2900:     pack unpack $win
                   2901:   }
                   2902: }
                   2903: 
                   2904: 
                   2905: proc InitMaps {} {
                   2906:   global MapWindows
                   2907:   foreach win $MapWindows {
                   2908:     InitMap $win
                   2909:   }
                   2910: }
                   2911: 
                   2912: 
                   2913: proc InitMap {win} {
                   2914:   SetMapState $win 0
                   2915: }
                   2916: 
                   2917: 
                   2918: proc EnableMaps {} {
                   2919:   global MapWindows
                   2920:   foreach win $MapWindows {
                   2921:     EnableMap $win
                   2922:   }
                   2923: }
                   2924: 
                   2925: 
                   2926: proc EnableMap {win} {
                   2927:   [WindowLink $win.view] ShowEditors 1
                   2928:   [WindowLink $win.zones] config -state normal
                   2929:   [WindowLink $win.overlays] config -state normal
                   2930: }
                   2931: 
                   2932: 
                   2933: proc DisableMaps {} {
                   2934:   global MapWindows
                   2935:   foreach win $MapWindows {
                   2936:     DisableMap $win
                   2937:   }
                   2938: }
                   2939: 
                   2940: 
                   2941: proc DisableMap {win} {
                   2942:   [WindowLink $win.view] ShowEditors 0
                   2943:   [WindowLink $win.zones] config -state disabled
                   2944:   [WindowLink $win.overlays] config -state disabled
                   2945: }
                   2946: 
                   2947: 
                   2948: proc SetMapState {win state} {
                   2949:   set m [WindowLink $win.view]
                   2950:   $m MapState $state
                   2951:   if {$state == 14} then {
                   2952:     ShowFrobOf [WindowLink $win.head]
                   2953:   }
                   2954: }
                   2955: 
                   2956: 
                   2957: proc MapPanDown {w x y} {
                   2958:   $w PanStart $x $y
                   2959: }
                   2960: 
                   2961: 
                   2962: proc MapPanDrag {w x y} {
                   2963:   $w PanTo $x $y
                   2964: }
                   2965: 
                   2966: 
                   2967: proc MapPanUp {w x y} {
                   2968:   $w PanTo $x $y
                   2969:   sim UpdateMaps
                   2970:   sim UpdateEditors
                   2971: }
                   2972: 
                   2973: 
                   2974: proc UISetMapState {w state} {
                   2975:   global MapTitles
                   2976:   #set win [winfo toplevel $w]
                   2977:   set win [WindowLink $w.win]
                   2978:   set m [WindowLink $win.view]
                   2979:   set title [lindex $MapTitles $state]
                   2980: 
                   2981:   # TODO: set map text field header to title
                   2982:   #wm title $win "$title"
                   2983:   #wm iconname $win "$title"
                   2984: 
                   2985:   global [set var MapState.$win]
                   2986:   set $var $state
                   2987: 
                   2988:   case $state { \
                   2989:     {6 8 9 10 11 12 13} {
                   2990:       [WindowLink $win.legend] config -bitmap "@images/legendmm.xpm"
                   2991:     } \
                   2992:     {7} {
                   2993:       [WindowLink $win.legend] config -bitmap "@images/legendpm.xpm"
                   2994:     } \
                   2995:     {0 1 2 3 4 5 14} {
                   2996:       [WindowLink $win.legend] config -bitmap "@images/legendn.xpm"
                   2997:     }
                   2998:   }
                   2999: }
                   3000: 
                   3001: 
                   3002: ########################################################################
                   3003: # Graph Window Handlers
                   3004: 
                   3005: 
                   3006: proc ToggleGraphOf {head} {
                   3007:   global State
                   3008:   if {"$State" != "play"} {
                   3009:     return
                   3010:   }
                   3011: 
                   3012:   set mapped 0
                   3013:   set win [WindowLink $head.graph]
                   3014:   if {$win != ""} {
                   3015:     set mapped [winfo ismapped $win]
                   3016:   }
                   3017: 
                   3018:   if {$mapped} {
                   3019:     WithdrawGraphOf $head
                   3020:   } else {
                   3021:     ShowGraphOf $head
                   3022:   }
                   3023: 
                   3024: }
                   3025: 
                   3026: 
                   3027: proc WithdrawGraphOf {head} {
                   3028:   set win [WindowLink $head.graph]
                   3029:   if {"$win" != ""} {
                   3030:     pack unpack $win
                   3031:   }
                   3032: }
                   3033: 
                   3034: 
                   3035: proc ShowGraphOf {head} {
                   3036:   set win [WindowLink $head.graph]
                   3037:   if {$win == {}} {
                   3038:     set win [MakeWindow.graph $head [winfo screen $head]]
                   3039:   }
                   3040:   #wm deiconify $win
                   3041:   #wm raise $win
                   3042:   set parent [WindowLink $win.parent]
                   3043:   pack append $parent\
                   3044:     $win {top frame nw fillx}
                   3045:   update idletasks
                   3046:   sim UpdateGraphs
                   3047: }
                   3048: 
                   3049: 
                   3050: proc WithdrawGraphs {} {
                   3051:   global GraphWindows
                   3052:   foreach win $GraphWindows {
                   3053:     #wm withdraw $win
                   3054:     pack unpack $win
                   3055:   }
                   3056: }
                   3057: 
                   3058: 
                   3059: proc InitGraphs {} {
                   3060:   global GraphWindows
                   3061:   foreach win $GraphWindows {
                   3062:     InitGraph $win
                   3063:   }
                   3064: }
                   3065: 
                   3066: 
                   3067: proc InitGraph {win} {
                   3068:   UISetGraphState $win 1 1 1 1 1 1 0
                   3069: }
                   3070: 
                   3071: 
                   3072: proc UISetGraphState {win t0 t1 t2 t3 t4 t5 range} {
                   3073:   set g [WindowLink $win.graphview]
                   3074:   GraphPalletMask $win [expr "$t0 + ($t1<<1) + ($t2<<2) + ($t3<<3) + ($t4<<4) + ($t5<<5)"]
                   3075:   GraphYearPallet $win $range
                   3076: }
                   3077: 
                   3078: 
                   3079: ########################################################################
                   3080: # Splash Window Handlers
                   3081: 
                   3082: 
                   3083: proc ShowSplashOf {head} {
                   3084:   set win [WindowLink $head.splash]
                   3085:   if {$win == {}} {
                   3086:     set win [MakeWindow.splash $head [winfo screen $head]]
                   3087:   }
                   3088:   set splashscreen [WindowLink $win.splashscreen]
                   3089:   set success 0
                   3090:   catch {$splashscreen config -bitmap "@images/splashscreen.xpm"; set success 1}
                   3091:   if {$success} {
                   3092:     wm deiconify $win
                   3093:     global SplashScreenDelay
                   3094:     after $SplashScreenDelay "UIPickScenarioMode"
                   3095:   } else {
                   3096:     UIPickScenarioMode
                   3097:   }
                   3098: }
                   3099: 
                   3100: 
                   3101: proc WithdrawSplashOf {head} {
                   3102:   set win WindowLink $head.splash]
                   3103:   wm withdraw $win
                   3104: }
                   3105: 
                   3106: 
                   3107: proc ShowSplashes {} {
                   3108:   global HeadWindows
                   3109:   foreach win $HeadWindows {
                   3110:     ShowSplashOf $win
                   3111:   }
                   3112: }
                   3113: 
                   3114: 
                   3115: proc WithdrawSplashes {} {
                   3116:   global SplashWindows
                   3117:   foreach win $SplashWindows {
                   3118:     wm withdraw $win
                   3119:     set splashscreen [WindowLink $win.splashscreen]
                   3120:     $splashscreen config -bitmap ""
                   3121:   }
                   3122: }
                   3123: 
                   3124: 
                   3125: proc InitSplashes {} {
                   3126: }
                   3127: 
                   3128: 
                   3129: proc InitSplash {win} {
                   3130: }
                   3131: 
                   3132: 
                   3133: proc DeleteSplashWindow {win} {
                   3134:   # TODO
                   3135: }
                   3136: 
                   3137: 
                   3138: ########################################################################
                   3139: # Scenario Window Handlers
                   3140: 
                   3141: 
                   3142: proc ShowScenarioOf {head} {
                   3143:   set win [WindowLink $head.scenario]
                   3144:   if {$win == {}} {
                   3145:     set win [MakeWindow.scenario $head [winfo screen $head]]
                   3146:   }
                   3147:   # TODO: load background bitmap
                   3148:   wm deiconify $win
                   3149: }
                   3150: 
                   3151: 
                   3152: proc WithdrawScenarioOf {head} {
                   3153:   set win WindowLink $head.scenario]
                   3154:   wm withdraw $win
                   3155: }
                   3156: 
                   3157: 
                   3158: proc ShowScenarios {} {
                   3159:   global HeadWindows
                   3160:   foreach win $HeadWindows {
                   3161:     ShowScenarioOf $win
                   3162:   }
                   3163: }
                   3164: 
                   3165: 
                   3166: proc WithdrawScenarios {} {
                   3167:   global ScenarioWindows
                   3168:   foreach win $ScenarioWindows {
                   3169:     wm withdraw $win
                   3170:     # TODO: flush background bitmap
                   3171:   }
                   3172: }
                   3173: 
                   3174: 
                   3175: proc InitScenarios {} {
                   3176:   global MapHistory MapHistoryNum
                   3177:   if {$MapHistoryNum < 1} {
                   3178:     set prev disabled
                   3179:   } else {
                   3180:     set prev normal
                   3181:   }
                   3182:   if {$MapHistoryNum == ([llength $MapHistory] - 1)} {
                   3183:     set next disabled
                   3184:   } else {
                   3185:     set next normal
                   3186:   }
                   3187:   global ScenarioWindows
                   3188:   foreach win $ScenarioWindows {
                   3189:     # TODO
                   3190:     #[WindowLink $win.previous] config -state $prev
                   3191:     #[WindowLink $win.next] config -state $next
                   3192:   }
                   3193: }
                   3194: 
                   3195: 
                   3196: proc InitScenario {win} {
                   3197:   global MapHistory MapHistoryNum
                   3198:   if {$MapHistoryNum < 1} {
                   3199:     set prev disabled
                   3200:   } else {
                   3201:     set prev normal
                   3202:   }
                   3203: 
                   3204:   if {$MapHistoryNum == ([llength $MapHistory] - 1)} {
                   3205:     set next disabled
                   3206:   } else {
                   3207:     set next normal
                   3208:   }
                   3209: 
                   3210:   # TODO
                   3211:   #[WindowLink $win.previous] config -state $prev
                   3212:   #[WindowLink $win.next] config -state $next
                   3213: 
                   3214:   LinkWindow $win.scenarioTarget -1
                   3215:   LinkWindow $win.scenarioTargetDown -1
                   3216: 
                   3217:   global ScenarioButtons
                   3218:   set i 0
                   3219:   set len [llength $ScenarioButtons]
                   3220:   while {$i < $len} {
                   3221:     set data [lindex $ScenarioButtons $i]
                   3222:     set type [lindex $data 0]
                   3223:     set id [lindex $data 1]
                   3224:     #echo "DATA $data"
                   3225:     #echo "ID $id"
                   3226: 
                   3227:     LinkWindow $win.$id.over 0
                   3228:     LinkWindow $win.$id.enabled 1
                   3229:     LinkWindow $win.$id.checked 0
                   3230:     #echo "SETTING WIN $win ID $id"
                   3231: 
                   3232:     set i [expr "$i + 1"]
                   3233:   }
                   3234: 
                   3235:   UpdateLevelSelection $win
                   3236:   UpdateLeftRightEnabled $win
                   3237: }
                   3238: 
                   3239: 
                   3240: proc UpdateLevelSelection {win} {
                   3241:   #echo UpdateLevelSelection
                   3242:   global GameLevel
                   3243:   if {$GameLevel == 0} then {
                   3244:     LinkWindow $win.easy.checked 1
                   3245:     LinkWindow $win.medium.checked 0
                   3246:     LinkWindow $win.hard.checked 0
                   3247:   }
                   3248:   if {$GameLevel == 1} then {
                   3249:     LinkWindow $win.easy.checked 0
                   3250:     LinkWindow $win.medium.checked 1
                   3251:     LinkWindow $win.hard.checked 0
                   3252:   }
                   3253:   if {$GameLevel == 2} then {
                   3254:     LinkWindow $win.easy.checked 0
                   3255:     LinkWindow $win.medium.checked 0
                   3256:     LinkWindow $win.hard.checked 1
                   3257:   }
                   3258: 
                   3259:   UpdateScenarioButtonID $win easy
                   3260:   UpdateScenarioButtonID $win medium
                   3261:   UpdateScenarioButtonID $win hard
                   3262: 
                   3263: }
                   3264: 
                   3265: 
                   3266: proc UpdateLeftRightEnabled {win} {
                   3267:   #echo UpdateLeftRightEnabled
                   3268: 
                   3269:   global MapHistory MapHistoryNum
                   3270:   if {$MapHistoryNum < 1} {
                   3271:     LinkWindow $win.left.enabled 0
                   3272:   } else {
                   3273:     LinkWindow $win.left.enabled 1
                   3274:   }
                   3275: 
                   3276:   if {$MapHistoryNum == ([llength $MapHistory] - 1)} {
                   3277:     LinkWindow $win.right.enabled 0
                   3278:   } else {
                   3279:     LinkWindow $win.right.enabled 1
                   3280:   }
                   3281: 
                   3282:   UpdateScenarioButtonID $win left
                   3283:   UpdateScenarioButtonID $win right
                   3284: }
                   3285: 
                   3286: 
                   3287: proc UpdateScenarioButtonID {win id} {
                   3288: 
                   3289:   global ScenarioButtons
                   3290:   set i 0
                   3291:   set len [llength $ScenarioButtons]
                   3292:   while {$i < $len} {
                   3293:     set data [lindex $ScenarioButtons $i]
                   3294:     set id 
                   3295:     if {$id == [lindex $data 1]} then {
                   3296:       UpdateScenarioButton $win $data
                   3297:       break
                   3298:     }
                   3299: 
                   3300:     set i [expr "$i + 1"]
                   3301:   }
                   3302: }
                   3303: 
                   3304: 
                   3305: proc UpdateScenarioButton {win data} {
                   3306:   set type [lindex $data 0]
                   3307:   set id [lindex $data 1]
                   3308:   set over [WindowLink $win.$id.over]
                   3309:   set enabled [WindowLink $win.$id.enabled]
                   3310:   set checked [WindowLink $win.$id.checked]
                   3311:   #echo "WIN $win TYPE $type ID $id OVER $over ENABLED $enabled CHECKED $checked"
                   3312:   if {$enabled} {
                   3313:     if {$checked} {
                   3314:       if {$over} {
                   3315:         set bm [lindex $data 13]
                   3316:       } else {
                   3317:         set bm [lindex $data 12]
                   3318:       }
                   3319:     } else {
                   3320:       if {$over} {
                   3321:         set bm [lindex $data 10]
                   3322:       } else {
                   3323:         set bm [lindex $data 9]
                   3324:       }
                   3325:     }
                   3326:   } else {
                   3327:     set bm [lindex $data 11]
                   3328:   }
                   3329: 
                   3330:   [WindowLink $win.canvas] itemconfig $id -bitmap $bm
                   3331: }
                   3332: 
                   3333: 
                   3334: proc DoEnterCityName {win} {
                   3335: }
                   3336: 
                   3337: 
                   3338: proc InitVotesForUseThisMap {} {
                   3339:   # TODO: Disabled for new scenario window.
                   3340:   return
                   3341: 
                   3342:   global VotesForUseThisMap ScenarioWindows
                   3343:   set VotesForUseThisMap {}
                   3344:   foreach win $ScenarioWindows {
                   3345:     [WindowLink $win.vote] config -relief raised
                   3346:   }
                   3347:   UpdateVotesForUseThisMap
                   3348: }
                   3349: 
                   3350: 
                   3351: proc UpdateVotesForUseThisMap {} {
                   3352:   global ScenarioWindows
                   3353:   UpdateVotesFor UseThisMap $ScenarioWindows
                   3354: }
                   3355: 
                   3356: 
                   3357: proc UIUseThisMap {} {
                   3358:   global CityName GameLevel Scenario
                   3359:   WithdrawAll
                   3360:   # special handling for scenarios?
                   3361:   if {$GameLevel != -1} {
                   3362:     sim GameLevel $GameLevel
                   3363:   }
                   3364:   sim CityName $CityName
                   3365:   UINewGame
                   3366:   UIPlayGame
                   3367:   if {$Scenario != -1} {
                   3368:     UIShowPicture $Scenario
                   3369:   }
                   3370: }
                   3371: 
                   3372: 
                   3373: proc HandleScenarioDown {win x y} {
                   3374:   #echo HandleScenarioDown $win $x $y
                   3375:   HandleScenarioMove $win $x $y
                   3376:   set w [WindowLink $win.w]
                   3377:   set target [WindowLink $w.scenarioTarget]
                   3378:   LinkWindow $w.scenarioTargetDown $target
                   3379: }
                   3380: 
                   3381: 
                   3382: proc HandleScenarioUp {win x y} {
                   3383:   #echo HandleScenarioUp $win $x $y
                   3384:   HandleScenarioMove $win $x $y
                   3385:   global ScenarioButtons
                   3386:   set w [WindowLink $win.w]
                   3387:   set target [WindowLink $w.scenarioTarget]
                   3388:   set targetDown [WindowLink $w.scenarioTargetDown]
                   3389:   if {($target != -1) &&
                   3390:       ($target == $targetDown)} {
                   3391:     set data [lindex $ScenarioButtons $target]
                   3392:     set type [lindex $data 0]
                   3393:     set id [lindex $data 1]
                   3394:     set callback [lindex $data 2]
                   3395:     set param [lindex $data 3]
                   3396:     set var [lindex $data 4]
                   3397:     set xx [lindex $data 5]
                   3398:     set yy [lindex $data 6]
                   3399:     set ww [lindex $data 7]
                   3400:     set hh [lindex $data 8]
                   3401:     set normal [lindex $data 9]
                   3402:     set over [lindex $data 10]
                   3403:     set disabled [lindex $data 11]
                   3404:     if {$type == "button"} {
                   3405:       #echo callback $callback w $w param $param
                   3406:       eval "$callback $w {$param}"
                   3407:     } else {
                   3408:       if {$type == "checkbox"} {
                   3409:         #echo checkbox callback $callback w $w param $param
                   3410:        eval "$callback $w {$param}"
                   3411:       }
                   3412:     }
                   3413:   }
                   3414: }
                   3415: 
                   3416: 
                   3417: proc HandleScenarioMove {win x y} {
                   3418:   #echo HandleScenarioMove $win $x $y
                   3419:   global ScenarioButtons
                   3420:   set w [WindowLink $win.w]
                   3421:   set target [WindowLink $w.scenarioTarget]
                   3422:   set found -1
                   3423:   set i 0
                   3424:   set len [llength $ScenarioButtons]
                   3425:   while {$i < $len} {
                   3426:     set data [lindex $ScenarioButtons $i]
                   3427:     set type [lindex $data 0]
                   3428:     set id [lindex $data 1]
                   3429:     set callback [lindex $data 2]
                   3430:     set param [lindex $data 3]
                   3431:     set var [lindex $data 4]
                   3432:     set xx [lindex $data 5]
                   3433:     set yy [lindex $data 6]
                   3434:     set ww [lindex $data 7]
                   3435:     set hh [lindex $data 8]
                   3436: 
                   3437:     set enabled [WindowLink $w.$id.enabled]
                   3438:     set checked [WindowLink $w.$id.checked]
                   3439: 
                   3440:     #echo "ID $id ENABLED $enabled CHECKED $checked w $w id $id"
                   3441: 
                   3442:     if {($enabled != 0) &&
                   3443:         ($x >= $xx) &&
                   3444:        ($x < ($xx + $ww)) &
                   3445:        ($y >= $yy) &&
                   3446:        ($y < ($yy + $hh))} {
                   3447:       set found $i
                   3448:       break
                   3449:     }
                   3450: 
                   3451:     set i [expr "$i + 1"]
                   3452:   }
                   3453: 
                   3454:   if {$found != $target} {
                   3455: 
                   3456:     if {$found == -1} {
                   3457:       if {$target != -1} { 
                   3458: 
                   3459:        #echo OUT $w $found $xx $yy $normal
                   3460:        LinkWindow $w.scenarioTarget -1
                   3461: 
                   3462:         set targetdata [lindex $ScenarioButtons $target]
                   3463:        set targetid [lindex $targetdata 1]
                   3464:        LinkWindow $w.$targetid.over 0
                   3465:         UpdateScenarioButton $w $targetdata
                   3466: 
                   3467:       }
                   3468:     } else {
                   3469: 
                   3470:       #echo IN $w $found $xx $yy $over
                   3471:       LinkWindow $w.scenarioTarget $found
                   3472:       LinkWindow $w.$id.over 1
                   3473: 
                   3474:       if {$target != -1} {
                   3475:         set targetdata [lindex $ScenarioButtons $target]
                   3476:        set targetid [lindex $targetdata 1]
                   3477:        LinkWindow $w.$targetid.over 0
                   3478:        UpdateScenarioButton $w $targetdata
                   3479:       }
                   3480: 
                   3481:       UpdateScenarioButton $w $data
                   3482: 
                   3483:     }
                   3484:   }
                   3485: }
                   3486: 
                   3487: proc DoLoad {win param} {
                   3488:   #echo DOLOAD $win $param
                   3489:   UILoadCity $win
                   3490: }
                   3491: 
                   3492: 
                   3493: proc DoGenerate {win param} {
                   3494:   #echo DOGENERATE $win $param
                   3495:   UIGenerateNewCity
                   3496: }
                   3497: 
                   3498: 
                   3499: proc DoQuit {win param} {
                   3500:   #echo DOQUIT $win $param
                   3501:   UIQuit $win
                   3502: }
                   3503: 
                   3504: 
                   3505: proc DoAbout {win param} {
                   3506:   #echo DOABOUT $win $param
                   3507:   MakeHistory "DoLoadCity cities/about.cty"
                   3508: }
                   3509: 
                   3510: 
                   3511: proc DoMap {win param} {
                   3512:   #echo DOMAP $win $param
                   3513: }
                   3514: 
                   3515: 
                   3516: proc DoLevel {win param} {
                   3517:   #echo DOLEVEL $win $param
                   3518:   DoSetGameLevel $param
                   3519: }
                   3520: 
                   3521: 
                   3522: proc DoLeft {win param} {
                   3523:   #echo DOLEFT $win $param
                   3524:   PrevHistory
                   3525: }
                   3526: 
                   3527: 
                   3528: proc DoRight {win param} {
                   3529:   #echo DORIGHT $win $param
                   3530:  NextHistory
                   3531: }
                   3532: 
                   3533: 
                   3534: proc DoPlay {win param} {
                   3535:   #echo DOPLAY $win $param
                   3536:   UIUseThisMap
                   3537: }
                   3538: 
                   3539: 
                   3540: proc DoPickScenario {win param} {
                   3541:   #echo DOPICKSCENARIO $win $param
                   3542:   UILoadScenario $param
                   3543: }
                   3544: 
                   3545: 
                   3546: ########################################################################
                   3547: # Undo/Redo Facility
                   3548: 
                   3549: 
                   3550: proc InitHistory {} {
                   3551:   global MapHistory
                   3552:   global MapHistoryNum
                   3553:   set MapHistory {}
                   3554:   set MapHistoryNum -1
                   3555: }
                   3556: 
                   3557: 
                   3558: proc MakeHistory {cmd} {
                   3559:   global MapHistory
                   3560:   set len [llength $MapHistory]
                   3561:   if {($len == 0) ||
                   3562:       ($cmd != [lindex $MapHistory [expr $len-1]])} {
                   3563:     lappend MapHistory $cmd
                   3564:   } else {
                   3565:     incr len -1
                   3566:   }
                   3567:   GotoHistory $len
                   3568: }
                   3569: 
                   3570: 
                   3571: proc GotoHistory {i} {
                   3572:   global MapHistory
                   3573:   global MapHistoryNum
                   3574:   InitVotesForUseThisMap
                   3575:   if {$i != $MapHistoryNum} {
                   3576:     set MapHistoryNum $i
                   3577:     set cmd [lindex $MapHistory $i]
                   3578:     eval $cmd
                   3579:   }
                   3580:   if {$MapHistoryNum == 0} {
                   3581:     set prev disabled
                   3582:   } else {
                   3583:     set prev normal
                   3584:   }
                   3585:   if {$MapHistoryNum == ([llength $MapHistory] - 1)} {
                   3586:     set next disabled
                   3587:   } else {
                   3588:     set next normal
                   3589:   }
                   3590: 
                   3591:   global ScenarioWindows
                   3592:   foreach win $ScenarioWindows {
                   3593:     UpdateLeftRightEnabled $win
                   3594:   }
                   3595: 
                   3596: }
                   3597: 
                   3598: 
                   3599: proc NextHistory {} {
                   3600:   global MapHistory
                   3601:   global MapHistoryNum
                   3602:   set len [llength $MapHistory]
                   3603:   set i [expr "$MapHistoryNum + 1"]
                   3604:   if {$i < $len} {
                   3605:     GotoHistory $i
                   3606:   }
                   3607: }
                   3608: 
                   3609: 
                   3610: proc PrevHistory {} {
                   3611:   global MapHistory
                   3612:   global MapHistoryNum
                   3613:   set i [expr "$MapHistoryNum - 1"]
                   3614:   if {$i >= 0} {
                   3615:     GotoHistory $i
                   3616:   }
                   3617: }
                   3618: 
                   3619: 
                   3620: ########################################################################
                   3621: # Ask Window Handlers
                   3622: 
                   3623: proc ShowAskOf {head} {
                   3624:   set win [WindowLink $head.ask]
                   3625:   if {$win == {}} {
                   3626:     set win [MakeWindow.ask $head [winfo screen $head]]
                   3627:   }
                   3628:   wm deiconify $win
                   3629:   wm raise $win
                   3630:   return $win
                   3631: }
                   3632: 
                   3633: 
                   3634: proc ShowAsks {} {
                   3635:   global HeadWindows
                   3636:   foreach win $HeadWindows {
                   3637:     ShowAskOf $win
                   3638:   }
                   3639: }
                   3640: 
                   3641: 
                   3642: proc WithdrawAsks {} {
                   3643:   global AskWindows
                   3644:   foreach win $AskWindows {
                   3645:     wm withdraw $win
                   3646:   }
                   3647: }
                   3648: 
                   3649: 
                   3650: proc WithdrawAskOf {win} {
                   3651:   set ask [WindowLink $win.ask]
                   3652:   if {"$ask" != ""} {
                   3653:     wm withdraw $ask
                   3654:   }
                   3655: }
                   3656: 
                   3657: 
                   3658: proc AskQuestion {color title text left middle right} {
                   3659:   global HeadWindows
                   3660:   foreach win $HeadWindows {
                   3661:     AskQuestionOn $win $color $title $text $left $middle $right
                   3662:   }
                   3663: }
                   3664: 
                   3665: 
                   3666: proc AskQuestionOn {head color title text left middle right} {
                   3667:   ShowAskOf $head
                   3668: 
                   3669:   set win [WindowLink $head.ask]
                   3670:   set t [WindowLink $win.title]
                   3671:   $t configure -text $title
                   3672:   $t configure -background $color
                   3673: 
                   3674:   set t [WindowLink $win.text]
                   3675:   $t configure -state normal
                   3676:   $t delete 0.0 end
                   3677:   $t insert end "${text}\n"
                   3678:   $t configure -state disabled
                   3679: 
                   3680:   set bf [WindowLink $win.frame]
                   3681:   set l [WindowLink $win.left]
                   3682:   set m [WindowLink $win.middle]
                   3683:   set r [WindowLink $win.vote]
                   3684:   set rf [WindowLink $win.voteframe]
                   3685: 
                   3686:   if {$left != ""} {
                   3687:     $l config \
                   3688:        -text [lindex $left 0] \
                   3689:        -command [format [lindex $left 2] $head]
                   3690:     SetHelp $l [lindex $left 1]
                   3691:     pack append $bf $l {left frame center}
                   3692:   } else {
                   3693:     pack unpack $l
                   3694:   }
                   3695: 
                   3696:   if {$middle != ""} {
                   3697:     $m config \
                   3698:        -text [lindex $middle 0] \
                   3699:        -command [format [lindex $middle 2] $head]
                   3700:     SetHelp $m [lindex $middle 1]
                   3701:     pack append $bf $m {left frame center expand}
                   3702:   } else {
                   3703:     pack unpack $m
                   3704:   }
                   3705: 
                   3706:   if {$right != ""} {
                   3707:     set notify [format [lindex $right 2] $head]
                   3708:     set preview [format [lindex $right 3] $head]
                   3709:     set cmd [list DoVote $win Ask $notify $preview]
                   3710:     $r config \
                   3711:        -text [lindex $right 0] \
                   3712:        -command $cmd
                   3713:     SetHelp $r [lindex $right 1]
                   3714:     pack append $bf $rf {right frame center}
                   3715:   } else {
                   3716:     pack unpack $rf
                   3717:   }
                   3718: 
                   3719:   InitVotesForAsk
                   3720: }
                   3721: 
                   3722: 
                   3723: proc BindVotingButton {win but name} {
                   3724:   set w [WindowLink $win.top]
                   3725: 
                   3726:   bind $but <Any-Enter> "VoteButtonEnter $win $but"
                   3727:   bind $but <Any-Leave> "VoteButtonLeave $win $but"
                   3728:   bind $but <1> "VoteButtonDown $win $but $name"
                   3729:   bind $but <ButtonRelease-1> "VoteButtonUp $win $but $name"
                   3730:   bind $but <2> "VoteButtonDown $win $but $name"
                   3731:   bind $but <ButtonRelease-2> "VoteButtonUp $win $but $name"
                   3732:   bind $but <3> "VoteButtonDown $win $but $name"
                   3733:   bind $but <ButtonRelease-3> "VoteButtonUp $win $but $name"
                   3734: }
                   3735: 
                   3736: 
                   3737: proc VoteButtonEnter {win but} {
                   3738:   global tk_priv
                   3739:   set screen [winfo screen $but]
                   3740:   if {[lindex [$but config -state] 4] != "disabled"} {
                   3741:     $but config -state active
                   3742:     set tk_priv(window@$screen) $but
                   3743:   } else {
                   3744:     set tk_priv(window@$screen) ""
                   3745:   }
                   3746: }
                   3747: 
                   3748: 
                   3749: proc VoteButtonLeave {win but} {
                   3750:   global tk_priv
                   3751:   if {[lindex [$but config -state] 4] != "disabled"} {
                   3752:     $but config -state normal
                   3753:   }
                   3754:   set screen [winfo screen $but]
                   3755:   set tk_priv(window@$screen) ""
                   3756: }
                   3757: 
                   3758: 
                   3759: proc VoteButtonDown {win but name} {
                   3760:   global tk_priv
                   3761:   set screen [winfo screen $but]
                   3762:   set rel [lindex [$but config -relief] 4]
                   3763:   set tk_priv(relief@$screen) $rel
                   3764:   if {[lindex [$but config -state] 4] != "disabled"} {
                   3765:     set head [WindowLink $win.head]
                   3766:     if {[IsVotingFor $head $name]} {
                   3767:       $but config -relief raised
                   3768:     } else {
                   3769:       $but config -relief sunken
                   3770:     }
                   3771:   }
                   3772: }
                   3773: 
                   3774: 
                   3775: proc VoteButtonUp {win but name} {
                   3776:   global tk_priv
                   3777:   set screen [winfo screen $but]
                   3778:   $but config -relief $tk_priv(relief@$screen)
                   3779:   if {($but == $tk_priv(window@$screen))
                   3780:        && ([lindex [$but config -state] 4] != "disabled")} {
                   3781:     uplevel #0 [list $but invoke]
                   3782:     set head [WindowLink $win.head]
                   3783:     if {[IsVotingFor $head $name]} {
                   3784:       $but config -relief sunken
                   3785:     } else {
                   3786:       $but config -relief raised
                   3787:     }
                   3788:   }
                   3789: }
                   3790: 
                   3791: 
                   3792: proc PressVoteButton {win but name} {
                   3793:   global tk_priv
                   3794:   uplevel #0 [list $but invoke]
                   3795:   set head [WindowLink $win.head]
                   3796:   if {[IsVotingFor $head $name]} {
                   3797:     $but config -relief sunken
                   3798:   } else {
                   3799:     $but config -relief raised
                   3800:   }
                   3801: }
                   3802: 
                   3803: 
                   3804: proc IsVotingFor {win name} {
                   3805:   global VotesFor$name
                   3806:   set votes [eval ident "\$\{VotesFor$name\}"]
                   3807:   if {[lsearch $votes $win] == -1} {
                   3808:     return 0
                   3809:   } else {
                   3810:     return 1
                   3811:   }
                   3812: }
                   3813: 
                   3814: 
                   3815: proc DoVote {win name notify preview} {
                   3816:   global VotesFor$name
                   3817:   set votes [eval ident "\$\{VotesFor$name\}"]
                   3818: 
                   3819:   set win [WindowLink $win.head]
                   3820:   set i [lsearch $votes $win]
                   3821:   if {$i == -1} {
                   3822:     lappend VotesFor$name $win
                   3823:   } else {
                   3824:     set VotesFor$name [lreplace $votes $i $i]
                   3825:   }
                   3826:   UpdateVotesFor$name
                   3827:   set votes [eval ident "\$\{VotesFor$name\}"]
                   3828:   if {[llength $votes] >= [NeededVotes]} {
                   3829:     eval "$notify"
                   3830:   } else {
                   3831:     eval "$preview"
                   3832:   }
                   3833: }
                   3834: 
                   3835: 
                   3836: proc UpdateVotesFor {name wins} {
                   3837:   global VotesFor$name
                   3838:   set votes [eval llength "\$\{VotesFor$name\}"]
                   3839:   set needed [NeededVotes]
                   3840: 
                   3841:   foreach win $wins {
                   3842:     set head [WindowLink $win.head]
                   3843:     if {[IsVotingFor $head $name]} {
                   3844:       set border [expr "($needed - $votes) * 1"]
                   3845:       set pad [expr "6 - $border"]
                   3846:       [WindowLink $win.vote] config -padx $pad -pady $pad
                   3847:       [WindowLink $win.voteframe] config -borderwidth $border
                   3848:     } else {
                   3849:       set border [expr "($needed - $votes - 1) * 1"]
                   3850:       set pad [expr "6 - $border"]
                   3851:       [WindowLink $win.vote] config -padx $pad -pady $pad
                   3852:       [WindowLink $win.voteframe] config -borderwidth $border
                   3853:     }
                   3854:   }
                   3855: }
                   3856: 
                   3857: 
                   3858: proc InitVotesForAsk {} {
                   3859:   global VotesForAsk AskWindows
                   3860:   set VotesForAsk {}
                   3861:   foreach win $AskWindows {
                   3862:     [WindowLink $win.vote] config -relief raised
                   3863:   }
                   3864:   sim PendingTool -1
                   3865:   UpdateVotesForAsk
                   3866: }
                   3867: 
                   3868: 
                   3869: proc UpdateVotesForAsk {} {
                   3870:   global AskWindows
                   3871:   UpdateVotesFor Ask $AskWindows
                   3872: }
                   3873: 
                   3874: 
                   3875: ########################################################################
                   3876: # Player Window Handlers
                   3877: 
                   3878: proc ShowPlayerOf {head} {
                   3879:   set win [WindowLink $head.player]
                   3880:   if {$win == {}} {
                   3881:     set win [MakeWindow.player $head [winfo screen $head]]
                   3882:   }
                   3883:   wm deiconify $win
                   3884:   wm raise $win
                   3885:   return $win
                   3886: }
                   3887: 
                   3888: 
                   3889: proc ShowPlayers {} {
                   3890:   global HeadWindows
                   3891:   foreach win $HeadWindows {
                   3892:     ShowPlayerOf $win
                   3893:   }
                   3894: }
                   3895: 
                   3896: 
                   3897: proc WithdrawPlayers {} {
                   3898:   global PlayerWindows
                   3899:   foreach win $PlayerWindows {
                   3900:     wm withdraw $win
                   3901:   }
                   3902: }
                   3903: 
                   3904: 
                   3905: proc UpdatePlayers {} {
                   3906:   # TODO: Disabled for new scenario window.
                   3907:   return
                   3908: 
                   3909:   global HeadWindows PlayerWindows
                   3910: 
                   3911:   set players ""
                   3912:   foreach win $HeadWindows {
                   3913:     set server [winfo screen $win]
                   3914: #    if {[string first : $server] == 0} {
                   3915: #      set server "[exec hostname]:0"
                   3916: #    }
                   3917:     lappend players $server
                   3918:   }
                   3919: 
                   3920:   sim Players [llength $players]
                   3921: 
                   3922:   foreach win $PlayerWindows {
                   3923:     set list [WindowLink $win.players]
                   3924:     $list delete 0 end
                   3925:     eval "$list insert 0 $players"
                   3926:   }
                   3927: 
                   3928:   UpdateVotesForUseThisMap
                   3929:   UpdateVotesForAsk
                   3930:   UpdateVotesForBudget
                   3931:   UpdateTaxRateSliders
                   3932: }
                   3933: 
                   3934: 
                   3935: proc UIShowPlayer {win} {
                   3936:   ShowPlayerOf $win
                   3937: }
                   3938: 
                   3939: 
                   3940: proc DoNewPlayer {win} {
                   3941:   set field [WindowLink $win.display]
                   3942:   set dpy [$field get]
                   3943:   if {"$dpy" != ""} {
                   3944:     $field delete 0 end
                   3945:     sim Flush
                   3946:     update idletasks
                   3947:     if {[AddPlayer $dpy] != ""} {
                   3948:       wm withdraw $win
                   3949:     }
                   3950:   }
                   3951: }
                   3952: 
                   3953: ########################################################################
                   3954: # Notice Window Handlers
                   3955: 
                   3956: 
                   3957: proc ShowNoticeOf {head} {
                   3958:   set win [WindowLink $head.notice]
                   3959:   if {$win == {}} {
                   3960:     set win [MakeWindow.notice $head [winfo screen $head]]
                   3961:   }
                   3962:   global NoticePanelWidth NoticePanelHeight
                   3963:   #place configure $win -x 0 -y 0 -width $NoticePanelWidth -height $NoticePanelHeight
                   3964:   pack append [WindowLink $head.w3] \
                   3965:       $win {bottom frame sw expand fill}
                   3966:   return $win
                   3967: }
                   3968: 
                   3969: 
                   3970: proc ShowNotices {} {
                   3971:   global HeadWindows
                   3972:   foreach win $HeadWindows {
                   3973:     ShowNoticeOf $win
                   3974:   }
                   3975: }
                   3976: 
                   3977: 
                   3978: proc WithdrawNotices {} {
                   3979:   global NoticeWindows
                   3980:   foreach win $NoticeWindows {
                   3981:     #place forget $win
                   3982:     pack unpack $win
                   3983:   }
                   3984: }
                   3985: 
                   3986: 
                   3987: proc ReShowPictureOn {{head ""}} {
                   3988:   global ShowingPicture ShowingParms
                   3989:   UIShowPictureOn $head $ShowingPicture $ShowingParms
                   3990: }
                   3991: 
                   3992: 
                   3993: proc UIShowPicture {id {parms ""}} {
                   3994:   UIShowPictureOn "" $id $parms
                   3995: }
                   3996: 
                   3997: 
                   3998: proc UIShowPictureOn {where id {parms ""}} {
                   3999:   global DoNotices Messages ShowingPicture ShowingParms
                   4000:   if {$DoNotices == 0} {
                   4001:       return
                   4002:   }
                   4003: 
                   4004:   set ShowingPicture $id
                   4005:   set ShowingParms $parms
                   4006:   set msg $Messages($id)
                   4007:   set color [lindex $msg 0]
                   4008:   set title [lindex $msg 1]
                   4009:   set body [lindex $msg 2]
                   4010:   if {$parms != ""} {
                   4011:     set cmd "format {$body} $parms"
                   4012:     set body [uplevel #0 $cmd]
                   4013:   }
                   4014:   set props [lindex $msg 3]
                   4015:   if {"$where" == ""} {
                   4016:     global HeadWindows
                   4017:     set where $HeadWindows
                   4018:   }
                   4019:   foreach head $where {
                   4020:     NoticeMessageOn $head "$title" $color "$body" Medium $props
                   4021:   }
                   4022: }
                   4023: 
                   4024: 
                   4025: proc NoticeMessageOn {head title color text font props} {
                   4026:   ShowNoticeOf $head
                   4027:   set win [WindowLink $head.notice]
                   4028: 
                   4029:   set t [WindowLink $win.title]
                   4030:   $t configure -text $title -background $color
                   4031: 
                   4032:   set t [WindowLink $win.text]
                   4033:   $t configure -state normal -font [Font $head $font]
                   4034:   $t delete 0.0 end
                   4035:   $t insert end "${text}\n"
                   4036:   $t configure -state disabled
                   4037: 
                   4038:   set left ""
                   4039:   catch {set left [keylget props left]}
                   4040:   set l [WindowLink $win.left]
                   4041:   if {$left != ""} {
                   4042:     $l config -bitmap $left
                   4043:     place $l -in $t -anchor sw -relx .05 -rely .95
                   4044:   } else {
                   4045:     place forget $l
                   4046:   }
                   4047: 
                   4048:   set middle ""
                   4049:   catch {set middle [keylget props middle]}
                   4050:   set m [WindowLink $win.middle]
                   4051:   if {$middle != ""} {
                   4052:     $m config -bitmap $middle
                   4053:     place $m -in $t -anchor s -relx .5 -rely .95
                   4054:   } else {
                   4055:     place forget $m
                   4056:   }
                   4057: 
                   4058:   set right ""
                   4059:   catch {set right [keylget props right]}
                   4060:   set r [WindowLink $win.right]
                   4061:   if {$right != ""} {
                   4062:     $r config -bitmap $right
                   4063:     place $r -in $t -anchor se -relx .95 -rely .95
                   4064:   } else {
                   4065:     place forget $r
                   4066:   }
                   4067: 
                   4068:   set view ""
                   4069:   catch {set view [keylget props view]}
                   4070:   set vf [WindowLink $win.viewframe]
                   4071:   global v
                   4072:   set v [WindowLink $win.view]
                   4073:   set bg [WindowLink $win.background]
                   4074:   if {$view != ""} {
                   4075:     uplevel #0 "$view"
                   4076:     pack unpack $t
                   4077:     pack append $bg $vf {left frame center fill}
                   4078:     pack append $bg $t {right frame center fill expand}
                   4079:   } else {
                   4080:     pack unpack $vf
                   4081:   }
                   4082: }
                   4083: 
                   4084: 
                   4085: proc UIPopUpMessage {msg} {
                   4086:   DoSendMessage $msg
                   4087: }
                   4088: 
                   4089: 
                   4090: proc ComeToMe {view} {
                   4091:   set win [winfo toplevel $view]
                   4092: 
                   4093:   set xy [$view Pan]
                   4094:   set x [expr "[lindex $xy 0] >>4"]
                   4095:   set y [expr "[lindex $xy 1] >>4"]
                   4096: 
                   4097:   ComeTo $win $x $y
                   4098: }
                   4099: 
                   4100: 
                   4101: proc ComeTo {win x y} {
                   4102:   global EditorWindows
                   4103:   set head [WindowLink $win.head]
                   4104:   set myeds {}
                   4105:   set myautoeds {}
                   4106:   foreach ed $EditorWindows {
                   4107:     if {"[WindowLink $ed.head]" == "$head"} {
                   4108:       lappend myeds $ed
                   4109:       set view [WindowLink $ed.view]
                   4110:       if {[$view AutoGoto]} {
                   4111:         lappend myautoeds $ed
                   4112:       }
                   4113:     }
                   4114:   }
                   4115:   if {[llength $myautoeds]} {
                   4116:     UIAutoGotoOn $x $y $myautoeds
                   4117:   } else {
                   4118:     if {[llength $myeds]} {
                   4119:       UIAutoGotoOn $x $y $myeds
                   4120:     }
                   4121:   }
                   4122: }
                   4123: 
                   4124: 
                   4125: proc FollowView {view id} {
                   4126:   $view Follow $id
                   4127: 
                   4128:   set skips 999999
                   4129:   if {[sim DoAnimation]} {
                   4130:     set head [WindowLink [winfo toplevel $view].head]
                   4131:     global EditorWindows
                   4132:     foreach win $EditorWindows {
                   4133:       if {"[WindowLink $win.head]" == "$head"} {
                   4134:        set s [[WindowLink $win.view] Skip]
                   4135:        set skips [min $skips $s]
                   4136:       }
                   4137:     }
                   4138: 
                   4139:     if {$skips == 999999} {
                   4140:       set skips 0
                   4141:     }
                   4142:   }
                   4143: 
                   4144:   $view Skip $skips
                   4145:   $view Update
                   4146: }
                   4147: 
                   4148: 
                   4149: proc PanView {view x y} {
                   4150:   FollowView $view ""
                   4151:   $view Pan $x $y
                   4152: }
                   4153: 
                   4154: 
                   4155: ########################################################################
                   4156: # Help Window Handlers
                   4157: 
                   4158: 
                   4159: proc ShowHelpOf {head} {
                   4160:   set win [WindowLink $head.help]
                   4161:   if {$win == {}} {
                   4162:     set win [MakeWindow.help $head [winfo screen $head]]
                   4163:   }
                   4164:   wm deiconify $win
                   4165:   wm raise $win
                   4166:   return $win
                   4167: }
                   4168: 
                   4169: 
                   4170: proc ShowHelps {} {
                   4171:   global HeadWindows
                   4172:   foreach win $HeadWindows {
                   4173:     ShowHelpOf $win
                   4174:   }
                   4175: }
                   4176: 
                   4177: 
                   4178: proc WithdrawHelps {} {
                   4179:   global HelpWindows
                   4180:   foreach win $HelpWindows {
                   4181:     wm withdraw $win
                   4182:   }
                   4183: }
                   4184: 
                   4185: 
                   4186: ########################################################################
                   4187: # Frob Window Handlers
                   4188: 
                   4189: 
                   4190: proc ShowFrobOf {head} {
                   4191:   set win [WindowLink $head.frob]
                   4192:   if {$win == {}} {
                   4193:     set win [MakeWindow.frob $head [winfo screen $head]]
                   4194:   }
                   4195:   wm deiconify $win
                   4196:   wm raise $win
                   4197: 
                   4198:   return $win
                   4199: }
                   4200: 
                   4201: 
                   4202: proc ShowFrobs {} {
                   4203:   global HeadWindows
                   4204:   foreach win $HeadWindows {
                   4205:     ShowFrobOf $win
                   4206:   }
                   4207: }
                   4208: 
                   4209: 
                   4210: proc WithdrawFrobs {} {
                   4211:   global FrobWindows
                   4212:   foreach win $FrobWindows {
                   4213:     wm withdraw $win
                   4214:   }
                   4215: }
                   4216: 
                   4217: 
                   4218: proc UISetDynamic {i min max} {
                   4219:   sim DynamicData [expr "$i*2"] $min
                   4220:   sim DynamicData [expr "$i*2+1"] $max
                   4221: }
                   4222: 
                   4223: 
                   4224: ########################################################################
                   4225: # Help Handler
                   4226: 
                   4227: 
                   4228: proc LoadHelp {} {
                   4229:   global ResourceDir
                   4230: 
                   4231:   source $ResourceDir/help.tcl
                   4232: }
                   4233: 
                   4234: proc HandleHelp {win x y rootx rooty} {
                   4235:   global HelpLoaded HelpWidgets Messages
                   4236: 
                   4237:   if {$HelpLoaded == 0} {
                   4238:     LoadHelp
                   4239:     set HelpLoaded 1
                   4240:   }
                   4241: 
                   4242:   set orig $win
                   4243:   set head [WindowLink [winfo toplevel $win].head]
                   4244:   set id ""
                   4245:   while {1} {
                   4246:     catch {set id $HelpWidgets($win)}
                   4247:     if {$id != ""} {
                   4248:       break
                   4249:     }
                   4250:     set list [split $win .]
                   4251:     set len [expr "[llength $list] - 2"]
                   4252:     set list [lrange $list 0 $len]
                   4253:     if {[llength $list] <= 1} {
                   4254:       set id Window
                   4255:       break
                   4256:     }
                   4257:     set win [join $list .]
                   4258:   }
                   4259:   if [info exists Messages($id)] {
                   4260:     UIShowHelpOn $head $id
                   4261:   } else {
                   4262:     UIShowHelpOn $head Window
                   4263:   }
                   4264: }
                   4265: 
                   4266: 
                   4267: proc UIShowHelpOn {win id {parms ""}} {
                   4268:   global Messages ShowingPicture ShowingParms ResourceDir
                   4269:   set head [WindowLink $win.head]
                   4270:   set msg $Messages($id)
                   4271:   set color [lindex $msg 0]
                   4272:   set title [lindex $msg 1]
                   4273:   set body [lindex $msg 2]
                   4274:   if {$parms != ""} {
                   4275:     set cmd "format {$body} $parms"
                   4276:     set body [uplevel #0 $cmd]
                   4277:   }
                   4278:   set props [lindex $msg 3]
                   4279: 
                   4280:   ShowHelpOf $head
                   4281:   set win [WindowLink $head.help]
                   4282: 
                   4283:   set t [WindowLink $win.title]
                   4284:   $t configure -text $title -background $color
                   4285: 
                   4286:   set t [WindowLink $win.text]
                   4287:   $t configure -state normal -font [Font $head Large]
                   4288:   $t delete 0.0 end
                   4289:   $t insert end "${body}\n"
                   4290:   FormatHTML $ResourceDir/doc/$id.html $t
                   4291:   $t configure -state disabled
                   4292: }
                   4293: 
                   4294: 
                   4295: proc FormatHTML {filename text} {
                   4296:   set f ""
                   4297:   catch {
                   4298:     set f [open $filename]
                   4299:     set line ""
                   4300:     set header ""
                   4301:     set title ""
                   4302:     gets $f header
                   4303:     gets $f title
                   4304: 
                   4305:     while {[gets $f line] >= 0} {
                   4306:       if {"$line" == "</body>"} {
                   4307:        break
                   4308:       }
                   4309:       if {([string index $line 0] == "#") || ([string length $line] == 0)} {
                   4310:        continue
                   4311:       }
                   4312:       $text insert end "$line\n"
                   4313:     }
                   4314:   }
                   4315:   if {$f != ""} {
                   4316:     close $f
                   4317:   }
                   4318: }
                   4319: 
                   4320: 
                   4321: proc SetHelp {win id} {
                   4322:   global HelpWidgets
                   4323:   set HelpWidgets($win) $id
                   4324: }
                   4325: 
                   4326: 
                   4327: proc Help {id title {msg {}} {props {}}} {
                   4328:   Message $id #7f7fff $title $msg $props
                   4329: }
                   4330: 
                   4331: ########################################################################
                   4332: # Pie Menu Handlers
                   4333: 
                   4334: 
                   4335: # Set up the bindings to pop up $pie when the right button is clicked in $win
                   4336: proc InitPie {win pie} {
                   4337:   bind $win <Motion> {}
                   4338:   bind $win <3> "PieMenuDown $win $pie $pie Initial %X %Y"
                   4339:   bind $win <B3-Motion> {}
                   4340:   bind $win <B3-ButtonRelease> {}
                   4341: }
                   4342: 
                   4343: 
                   4344: # Set up the bindings to continue tracking $pie
                   4345: # Get this: we keep the tracking machine state in the bindings!
                   4346: proc ActivatePie {win root pie state} {
                   4347:   bind $win <Motion> "PieMenuMotion $win $root $pie $state %X %Y"
                   4348:   bind $win <3> "PieMenuDown $win $root $pie $state %X %Y"
                   4349:   bind $win <B3-Motion> "PieMenuMotion $win $root $pie $state %X %Y"
                   4350:   bind $win <B3-ButtonRelease> "PieMenuUp $win $root $pie $state %X %Y"
                   4351: }
                   4352: 
                   4353: 
                   4354: # Cancel and reset a pie menu
                   4355: proc CancelPie {win} {
                   4356:   set binding [bind $win <3>]
                   4357:   set root [lindex $binding 2]
                   4358:   set pie [lindex $binding 3]
                   4359:   set state [lindex $binding 4]
                   4360:   if {"$state" != "Initial"} {
                   4361:     catch {$root ungrab $win}
                   4362:     $pie unpost
                   4363:     $pie activate none
                   4364:     UIMakeSoundOn $win fancy Oop
                   4365:   }
                   4366:   InitPie $win $root
                   4367: }
                   4368: 
                   4369: 
                   4370: # Handle pie menu button down
                   4371: proc PieMenuDown {win root pie state x y} {
                   4372:   case $state {
                   4373:     Initial {
                   4374:       ActivatePie $win $root $pie FirstDown
                   4375:       update idletasks
                   4376:       catch {$root grab $win}
                   4377:       $pie activate none
                   4378:       $pie post $x $y
                   4379:       PreviewPieMenu $win $pie $x $y
                   4380:       update idletasks
                   4381:     }
                   4382:     ClickedUp {
                   4383:       TrackPieMenu $pie $x $y
                   4384:       ActivatePie $win $root $pie SecondDown
                   4385:     }
                   4386:     SelectedUp {
                   4387:       $pie activate none
                   4388:       #$pie post $x $y
                   4389:       $pie defer
                   4390:       PreviewPieMenu $win $pie $x $y
                   4391:       ActivatePie $win $root $pie SecondDown
                   4392:     }
                   4393:     FirstDown { # error
                   4394:       CancelPie $win
                   4395:     }
                   4396:     SecondDown { # error
                   4397:       CancelPie $win
                   4398:     }
                   4399:   }
                   4400: }
                   4401: 
                   4402: 
                   4403: # Handle pie menu button motion
                   4404: proc PieMenuMotion {win root pie state x y} {
                   4405:   case $state {
                   4406:     FirstDown {
                   4407:       TrackPieMenu $pie $x $y
                   4408:       $pie defer
                   4409:     }
                   4410:     ClickedUp {
                   4411:       $pie activate none
                   4412:       #$pie post $x $y
                   4413:     }
                   4414:     SecondDown {
                   4415:       TrackPieMenu $pie $x $y
                   4416:       $pie defer
                   4417:     }
                   4418:     SelectedUp {
                   4419:       $pie activate none
                   4420:       #$pie post $x $y
                   4421:     }
                   4422:     Initial { # error
                   4423:       CancelPie $win
                   4424:     }
                   4425:   }
                   4426: }
                   4427: 
                   4428: 
                   4429: # Handle pie menu button up
                   4430: proc PieMenuUp {win root pie state x y} {
                   4431:   case $state {
                   4432:     FirstDown {
                   4433:       TrackPieMenu $pie $x $y
                   4434:       set active [$pie index active]
                   4435:       if {$active == "none"} {
                   4436:        $pie show
                   4437:         catch {$root grab $win}
                   4438:         ActivatePie $win $root $pie ClickedUp
                   4439:       } else {
                   4440:         set label [lindex [$pie entryconfig $active -label] 4]
                   4441:         set submenu [lindex [$pie entryconfig $active -piemenu] 4]
                   4442:        UIMakeSoundOn $win mode $label
                   4443:        if {$submenu == {}} {
                   4444:          set reward [$pie pending]
                   4445:          catch {$root ungrab $win}
                   4446:          $pie unpost
                   4447:           $pie activate none
                   4448:           if {$reward} {
                   4449:            sim Funds [expr "[sim Funds] + 5"]
                   4450:            UIMakeSoundOn $win fancy Aaah
                   4451:          }
                   4452:          eval [lindex [$pie entryconfig $active -command] 4]
                   4453:           InitPie $win $root   
                   4454:        } else {
                   4455:          $pie unpost
                   4456:           $pie activate none
                   4457:           $submenu activate none
                   4458:           $submenu post $x $y
                   4459:          PreviewPieMenu $win $submenu $x $y
                   4460:           catch {$root grab $win}
                   4461:          ActivatePie $win $root $submenu SelectedUp
                   4462:        }
                   4463:       }
                   4464:     }
                   4465:     SecondDown {
                   4466:       TrackPieMenu $pie $x $y
                   4467:       set active [$pie index active]
                   4468:       if {$active == "none"} {
                   4469:        CancelPie $win
                   4470:       } else {
                   4471:         set label [lindex [$pie entryconfig $active -label] 4]
                   4472:         set submenu [lindex [$pie entryconfig $active -piemenu] 4]
                   4473:        UIMakeSoundOn $win mode $label
                   4474:        if {$submenu == {}} {
                   4475:          set reward [$pie pending]
                   4476:          catch {$root ungrab $win}
                   4477:          $pie unpost
                   4478:           $pie activate none
                   4479:           if {$reward} {
                   4480:            sim Funds [expr "[sim Funds] + 5"]
                   4481:            UIMakeSoundOn $win fancy Aaah
                   4482:          }
                   4483:          eval [lindex [$pie entryconfig $active -command] 4]
                   4484:          InitPie $win $root
                   4485:        } else {
                   4486:          $pie unpost
                   4487:           $pie activate none
                   4488:           $submenu activate none
                   4489:           $submenu post $x $y
                   4490:          PreviewPieMenu $win $submenu $x $y
                   4491:           catch {$root grab $win}
                   4492:          ActivatePie $win $root $submenu SelectedUp
                   4493:        }
                   4494:       }
                   4495:     }
                   4496:     Initial { # error
                   4497:       CancelPie $win
                   4498:     }
                   4499:     ClickedUp { # error
                   4500:       CancelPie $win
                   4501:     }
                   4502:     SelectedUp { # error
                   4503:       CancelPie $win
                   4504:     }
                   4505:   }
                   4506: }
                   4507: 
                   4508: 
                   4509: # Track the selected item
                   4510: proc TrackPieMenu {pie x y} {
                   4511:   $pie activate @$x,$y
                   4512: }
                   4513: 
                   4514: 
                   4515: proc PreviewPieMenu {win pie x y} {
                   4516:   set preview [lindex [$pie config -preview] 4]
                   4517:   if {"$preview" != ""} {
                   4518:     set rx [winfo rootx $win]
                   4519:     set ry [winfo rooty $win]
                   4520:     set x [expr "$x - $rx"]
                   4521:     set y [expr "$y - $ry"]
                   4522:     eval [format $preview $x $y]
                   4523:   }
                   4524: }
                   4525: 
                   4526: 
                   4527: ########################################################################
                   4528: # Pallet Handlers
                   4529: 
                   4530: 
                   4531: proc ExclusivePallet {state parent children prefix images inactive active cmd} {
                   4532:   #echo "ExclusivePallet state $state parent $parent children $children prefix $prefix images $images inactive $inactive active $active cmd $cmd"
                   4533:   set i 0
                   4534:   foreach child $children {
                   4535:     set name [lindex $images $i]
                   4536:     if {$i == $state} then {
                   4537:       $parent.$child config \
                   4538:          -bitmap "@images/${prefix}${name}hi.xpm" \
                   4539:          -relief $active
                   4540:     } else {
                   4541:       $parent.$child config \
                   4542:          -bitmap "@images/${prefix}${name}.xpm" \
                   4543:          -relief $inactive
                   4544:     }
                   4545:     incr i
                   4546:   }
                   4547:   eval [concat $cmd $state]
                   4548: }
                   4549: 
                   4550: 
                   4551: proc NonExclusivePallet {mask parent children prefix images
                   4552:                         inactive active cmd} {
                   4553:   set i 0
                   4554:   foreach child $children {
                   4555:     set name [lindex $images $i]
                   4556:     if {$mask & (1<<$i)} then {
                   4557:       $parent.$child config \
                   4558:          -bitmap "@images/${prefix}${name}hi.xpm" \
                   4559:          -relief $active
                   4560:     } else {
                   4561:       $parent.$child config \
                   4562:          -bitmap "@images/${prefix}${name}.xpm" \
                   4563:          -relief $inactive
                   4564:     }
                   4565:     incr i
                   4566:   }
                   4567:   eval [concat $cmd $mask]
                   4568: }
                   4569: 
                   4570: 
                   4571: proc EditorPallet {win state} {
                   4572:   global EditorPalletSounds
                   4573:   UIMakeSoundOn $win mode [lindex $EditorPalletSounds $state]
                   4574:   EditorSetTool $win $state
                   4575: }
                   4576: 
                   4577: 
                   4578: proc EditorSetTool {win state} {
                   4579:   global EditorPallets
                   4580:   global EditorPalletImages
                   4581:   ExclusivePallet $state $win $EditorPallets ic $EditorPalletImages \
                   4582:        flat raised "$win.centerframe.view ToolState"
                   4583: }
                   4584: 
                   4585: 
                   4586: proc GraphPallet {win state} {
                   4587:   set mask [[WindowLink $win.graphview] Mask]
                   4588:   set mask [expr "$mask ^ (1<<$state)"]
                   4589:   GraphPalletMask $win $mask
                   4590: }
                   4591: 
                   4592: 
                   4593: proc GraphPalletMask {win mask} {
                   4594:   global GraphPallets
                   4595:   global GraphPalletImages
                   4596:   NonExclusivePallet $mask $win $GraphPallets gr $GraphPalletImages \
                   4597:        flat flat "SetGraphState $win"
                   4598: }
                   4599: 
                   4600: 
                   4601: proc GraphYearPallet {win state} {
                   4602:   global GraphYearPallets
                   4603:   global GraphYearPalletImages
                   4604:   ExclusivePallet $state $win $GraphYearPallets gr $GraphYearPalletImages \
                   4605:        flat flat "SetGraphYearState $win"
                   4606: }
                   4607: 
                   4608: 
                   4609: proc SetGraphYearState {win state} {
                   4610:   set graph [WindowLink $win.graphview]
                   4611:   if {$state == 0} {
                   4612:     $graph Range 10
                   4613:   } else {
                   4614:     $graph Range 120
                   4615:   }
                   4616: }
                   4617: 
                   4618: 
                   4619: proc SetGraphState {win mask} {
                   4620:   global GraphPallets
                   4621:   set graph [WindowLink $win.graphview]
                   4622:   $graph Mask $mask
                   4623: }
                   4624: 
                   4625: 
                   4626: ########################################################################
                   4627: # Button Handlers
                   4628: 
                   4629: proc sim_butEnter {w} {
                   4630:   global tk_priv
                   4631:   set screen [winfo screen $w]
                   4632:   set tk_priv(window@$screen) $w
                   4633: }
                   4634: 
                   4635: 
                   4636: proc sim_butLeave {w} {
                   4637:   global tk_priv
                   4638:   set screen [winfo screen $w]
                   4639:   set tk_priv(window@$screen) ""
                   4640: }
                   4641: 
                   4642: 
                   4643: proc sim_butDown {w} {
                   4644:   global tk_priv
                   4645:   set screen [winfo screen $w]
                   4646:   set pict [lindex [$w config -bitmap] 4]
                   4647:   set tk_priv(relief@$screen) $pict
                   4648:   $w config -bitmap [lindex [split $pict .] 0]hi.xpm
                   4649:   update idletasks
                   4650: }
                   4651: 
                   4652: 
                   4653: proc sim_butUp {w} {
                   4654:   global tk_priv
                   4655:   set screen [winfo screen $w]
                   4656:   $w config -bitmap $tk_priv(relief@$screen)
                   4657:   update idletasks
                   4658:   if {$w == $tk_priv(window@$screen)} {
                   4659:     uplevel #0 [list $w invoke]
                   4660:   }
                   4661: }
                   4662: 
                   4663: 
                   4664: proc BindSimButton {w} {
                   4665:   bind $w <Any-Enter> {sim_butEnter %W}
                   4666:   bind $w <Any-Leave> {sim_butLeave %W}
                   4667:   bind $w <1> {sim_butDown %W}
                   4668:   bind $w <ButtonRelease-1> {sim_butUp %W}
                   4669:   bind $w <2> {sim_butDown %W}
                   4670:   bind $w <ButtonRelease-2> {sim_butUp %W}
                   4671:   bind $w <3> {sim_butDown %W}
                   4672:   bind $w <ButtonRelease-3> {sim_butUp %W}
                   4673: }
                   4674: 
                   4675: 
                   4676: ########################################################################
                   4677: # Internal Callbacks
                   4678: 
                   4679: 
                   4680: proc UIStartMicropolis {homedir resourcedir hostname} {
                   4681:   global HomeDir ResourceDir HostName HeadWindows
                   4682:   set HomeDir $homedir
                   4683:   set ResourceDir $resourcedir
                   4684:   set HostName $hostname
                   4685:   sim InitGame
                   4686:   sim GameStarted
                   4687:   update
                   4688: 
                   4689:   foreach display [sim Displays] {
                   4690:     if {"[AddPlayer $display]" == ""} {
                   4691:       echo Couldn't add a player on $display ...
                   4692:     }
                   4693:   }
                   4694: 
                   4695:   if {"$HeadWindows" == ""} {
                   4696:     echo Micropolis is exiting because it couldn't connect to any players.
                   4697:     sim ReallyQuit
                   4698:   }
                   4699: }
                   4700: 
                   4701: 
                   4702: proc UISelectCity {win} {
                   4703:   AskQuestion [Color $win #ff0000 #ffffff] "Choose Another City" \
                   4704:     "Do you want to abandon this city and choose another one?" \
                   4705:     "{Keep playing.} SelectCity.No {RejectPlan}" \
                   4706:     "" \
                   4707:     "{Another city!} SelectCity.Yes {UIPickScenarioMode}"
                   4708: }
                   4709: 
                   4710: 
                   4711: proc UIQuit {head} {
                   4712:   if {[sim Players] == 1} {
                   4713:     set l "{Keep playing.} Quit.No {RejectPlan}"
                   4714:     set m ""
                   4715:     set r "{I quit!} Quit.IQuit {DoReallyQuit %s}"
                   4716:   } else {
                   4717:     set l "{Keep playing.} Quit.No {RejectPlan}"
                   4718:     set m "{I quit!} Quit.IResign {DoIResign %s}"
                   4719:     set r "{Everyone quit!} Quit.AllQuit {DoReallyQuit %s}"
                   4720:   }
                   4721:   AskQuestion [Color $head #ff0000 #ffffff] "Quit Playing Micropolis" \
                   4722:     "Do you want to quit playing Micropolis?" \
                   4723:     $l $m $r
                   4724: }
                   4725: 
                   4726: 
                   4727: proc DoIResign {head} {
                   4728:   global VotesForAsk
                   4729:   set display [winfo screen $head]
                   4730:   CrushHead $head
                   4731:   DecRefDisplay $display
                   4732:   UISetMessage "The player on X11 Display $display has resigned."
                   4733:   UpdatePlayers
                   4734:   if {([sim Players] == 0) ||
                   4735:       ([llength $VotesForAsk] >= [sim Players])} {
                   4736:     sim ReallyQuit
                   4737:   }
                   4738: }
                   4739: 
                   4740: 
                   4741: proc DoReallyQuit {head} {
                   4742:   echo QuitMicropolis
                   4743:   sim ReallyQuit
                   4744: }
                   4745: 
                   4746: 
                   4747: proc UISplashMode {} {
                   4748:   global State
                   4749:   set State splash
                   4750:   sim Pause
                   4751:   WithdrawAll
                   4752:   InitSplashes
                   4753:   ShowSplashes
                   4754: }
                   4755: 
                   4756: 
                   4757: proc UIPickScenarioMode {} {
                   4758:   global State
                   4759:   global CityLibDir
                   4760:   set State scenario
                   4761:   sim Pause
                   4762:   WithdrawAll
                   4763:   InitHistory
                   4764:   UIGenerateCityNow
                   4765:   InitScenarios
                   4766:   InitVotesForUseThisMap
                   4767:   ShowScenarios
                   4768: }
                   4769: 
                   4770: 
                   4771: proc ForcePickScenarioMode {} {
                   4772:   global State
                   4773:   if {"$State" != "scenario"} {
                   4774:     UIPickScenarioMode
                   4775:   }
                   4776: }
                   4777: 
                   4778: 
                   4779: proc UIGenerateCityNow {} {
                   4780:   global CityName GameLevel
                   4781:   sim CityName NowHere
                   4782:   sim GameLevel 0
                   4783:   UIGenerateNewCity
                   4784: }
                   4785: 
                   4786: 
                   4787: proc UIGenerateNewCity {} {
                   4788:   global CityName GameLevel
                   4789:   if {$GameLevel == -1} {
                   4790:     set GameLevel 0
                   4791:   }
                   4792:   MakeHistory "DoNewCity NowHere $GameLevel [sim Rand] [sim TreeLevel] [sim LakeLevel] [sim CurveLevel] [sim CreateIsland]"
                   4793: }
                   4794: 
                   4795: 
                   4796: proc DoNewCity {name level {r ""} {tl -1} {ll -1} {cl -1} {ci -1}} {
                   4797:   global Scenario
                   4798:   set Scenario -1
                   4799:   sim TreeLevel $tl
                   4800:   sim LakeLevel $ll
                   4801:   sim CurveLevel $cl
                   4802:   sim CreateIsland $ci
                   4803:   if {"$r" == ""} {
                   4804:     sim GenerateNewCity
                   4805:   } else {
                   4806:     sim GenerateSomeCity $r
                   4807:   }
                   4808:   sim CityName $name
                   4809:   sim GameLevel $level
                   4810:   UIShowPicture 48
                   4811: }
                   4812: 
                   4813: 
                   4814: proc UIDidGenerateNewCity {} {
                   4815:   sim Update
                   4816: }
                   4817: 
                   4818: 
                   4819: proc IncRefDisplay {display} {
                   4820:   global DisplayRegistry
                   4821:   if ![info exists DisplayRegistry($display)] {
                   4822:     set DisplayRegistry($display) 0
                   4823:   }
                   4824:   incr DisplayRegistry($display)
                   4825: }
                   4826: 
                   4827: 
                   4828: proc DecRefDisplay {display} {
                   4829:   global DisplayRegistry
                   4830:   incr DisplayRegistry($display) -1
                   4831:   if {$DisplayRegistry($display) <= 0} {
                   4832:     CloseDisplay $display
                   4833:   }
                   4834: }
                   4835: 
                   4836: 
                   4837: proc CloseDisplay {display} {
                   4838: }
                   4839: 
                   4840: 
                   4841: proc DoStopMicropolis {} {
                   4842:   KillSoundServers
                   4843:   destroy .
                   4844: }
                   4845: 
                   4846: 
                   4847: proc AddPlayer {display} {
                   4848:   set i [string first : $display]
                   4849:   if {$i == 0} {
                   4850:   } else {
                   4851:     if {$i == -1} {
                   4852:       set display "$display:0"
                   4853:     }
                   4854:   }
                   4855: 
                   4856:   echo Adding a player on $display ...
                   4857: 
                   4858:   set head [MakeWindow.head $display]
                   4859: 
                   4860:   if {"$head" != ""} {
                   4861:     set display [winfo screen $head]
                   4862:     IncRefDisplay $display
                   4863:     PrepHead $head
                   4864:     UISetMessage "Added a player on X11 Display \"$display\"."
                   4865:     UpdatePlayers
                   4866:   } else {
                   4867:     UISetMessage "Couldn't add a player on X11 Display \"$display\"!"
                   4868:   }
                   4869:   return $head
                   4870: }
                   4871: 
                   4872: 
                   4873: proc FireBomb {} {
                   4874:   sim FireBomb
                   4875: }
                   4876: 
                   4877: proc DropFireBombs {} {
                   4878:   FireBomb
                   4879:   after 300 FireBomb
                   4880:   after 600 FireBomb
                   4881:   after 900 FireBomb
                   4882: }
                   4883: 
                   4884: 
                   4885: proc UIMakeMonster {} {
                   4886:   sim MakeMonster [sim Rand 120] [sim Rand 100]
                   4887: }
                   4888: 
                   4889: 
                   4890: proc melt {} {
                   4891:   sim HeatSteps 1
                   4892:   sim HeatFlow -7
                   4893:   sim HeatRule 0
                   4894: }
                   4895: 
                   4896: 
                   4897: proc eco {} {
                   4898:   sim HeatSteps 1
                   4899:   sim HeatFlow 19
                   4900:   sim HeatRule 1
                   4901: }
                   4902: 
                   4903: 
                   4904: proc oops {} {
                   4905:   sim HeatSteps 0
                   4906: }
                   4907: 
                   4908: 
                   4909: proc TogglePause {} {
                   4910:   global State
                   4911: 
                   4912:   if {"$State" != "play" || [sim Speed]} {
                   4913:     sim Speed 0
                   4914:   } else {
                   4915:     sim Speed 3
                   4916:   }
                   4917:   MakeRunningSound
                   4918: }
                   4919: 
                   4920: 
                   4921: proc SetSpeedTime {time} {
                   4922:   sim Speed $time
                   4923:   MakeRunningSound
                   4924: }
                   4925: 
                   4926: 
                   4927: proc MakeRunningSound {} {
                   4928:   global State
                   4929: 
                   4930:   if {"$State" == "play" && [sim Speed]} {
                   4931:     UIMakeSound edit Boing "-speed 1[sim Speed]0"
                   4932:   } else {
                   4933:     UIMakeSound edit Boing "-speed 90"
                   4934:   }
                   4935: }
                   4936: 
                   4937: 
                   4938: proc SayDemands {} {
                   4939:   global DemandRes DemandCom DemandInd
                   4940:   set slope 3
                   4941:   set r [expr "100 + ($DemandRes * $slope)"]
                   4942:   set c [expr "100 + ($DemandCom * $slope)"]
                   4943:   set i [expr "100 + ($DemandInd * $slope)"]
                   4944:   after 020 "UIMakeSound edit O \"-speed $r\""
                   4945:   after 220 "UIMakeSound edit A \"-speed $c\""
                   4946:   after 440 "UIMakeSound edit E \"-speed $i\""
                   4947: }
                   4948: 
                   4949: 
                   4950: proc UISaveCity {win} {
                   4951:   global SaveCityWin
                   4952:   set SaveCityWin $win
                   4953:   sim SaveCity
                   4954: }
                   4955: 
                   4956: 
                   4957: proc UISaveCityAs {{win ""}} {
                   4958:   global SaveCityWin
                   4959:   if {"$win" == ""} {set win $SaveCityWin}
                   4960:   set SaveCityWin $win
                   4961: 
                   4962:   global CityDir
                   4963:   set file [ShowFileOf $win]
                   4964:   DoFileDialog $file "Choose a File to Save the City" $CityDir "*.cty" "" \
                   4965:        "UIDoReallySaveCity" ""
                   4966: }
                   4967: 
                   4968: 
                   4969: proc UIDoReallySaveCity {name path} {
                   4970:   global CityDir
                   4971:   if {![string match *.cty $name]} {
                   4972:     set name $name.cty
                   4973:   }
                   4974:   set CityDir $path
                   4975:   sim SaveCityAs $path/$name
                   4976: }
                   4977: 
                   4978: 
                   4979: proc UIDidSaveCity {} {
                   4980:   DoSendMessage "Saved the city in \"[sim CityFileName]\"." status
                   4981: }
                   4982: 
                   4983: 
                   4984: proc UIDidntSaveCity {msg} {
                   4985:   DoSendMessage $msg alert
                   4986:   UIMakeSound warning Sorry "-speed 85"
                   4987: }
                   4988: 
                   4989: 
                   4990: proc UILoadScenario {scen} {
                   4991:   MakeHistory "DoScenario $scen"
                   4992: }
                   4993: 
                   4994: 
                   4995: proc DoScenario {scen} {
                   4996:   global Scenario
                   4997:   set Scenario $scen
                   4998:   sim LoadScenario $scen
                   4999:   UIShowPicture $scen
                   5000: }
                   5001: 
                   5002: 
                   5003: proc UIDidLoadScenario {} {
                   5004: }
                   5005: 
                   5006: 
                   5007: proc UIStartScenario {id} {
                   5008:   global Scenario
                   5009:   set Scenario $id
                   5010:   UILoadScenario $id
                   5011:   UIPlayGame
                   5012:   UIShowPicture $id
                   5013: }
                   5014: 
                   5015: 
                   5016: proc UIPlayNewCity {} {
                   5017:   UIGenerateNewCity
                   5018:   UIPlayGame
                   5019: }
                   5020: 
                   5021: 
                   5022: proc UIStartLoad {} {
                   5023:   UIPlayGame
                   5024: }
                   5025: 
                   5026: 
                   5027: proc UIReallyStartGame {} {
                   5028:   #UIPickScenarioMode
                   5029:   UISplashMode
                   5030: }
                   5031: 
                   5032: 
                   5033: proc UIPlayGame {} {
                   5034:   global State
                   5035:   global Priority
                   5036:   set State play
                   5037:   sim Resume
                   5038:   sim Speed 3
                   5039:   sim AutoGoto 1
                   5040:   SetPriority $Priority
                   5041:   InitHeads
                   5042:   InitAllHeadMenus
                   5043:   ShowInitial
                   5044:   sim NeedRest 10
                   5045: }
                   5046: 
                   5047: 
                   5048: proc UISetSpeed {speed} {
                   5049:   global Time State
                   5050:   set Time $speed
                   5051:   if {"$State" == "play"} {
                   5052:     UISetMessage [lindex {
                   5053:       {Time pauses.}
                   5054:       {Time flows slow.}
                   5055:       {Time flows medium.}
                   5056:       {Time flows fast.}
                   5057:     } $speed]
                   5058:   }
                   5059:   UIUpdateRunning
                   5060: }
                   5061: 
                   5062: 
                   5063: proc UIUpdateRunning {} {
                   5064:   global HeadWindows Time State
                   5065: 
                   5066:        if {($State == "play") && $Time} {
                   5067:     set pict "@images/micropolisg.xpm"
                   5068:   } else {
                   5069:     set pict "@images/micropoliss.xpm"
                   5070:   }
                   5071: 
                   5072:   foreach win $HeadWindows {
                   5073:     set can [WindowLink $win.demand]
                   5074:     $can itemconfig micropolis -bitmap $pict
                   5075:   }
                   5076: }
                   5077: 
                   5078: 
                   5079: proc DoSetGameLevel {level} {
                   5080:   sim GameLevel $level
                   5081: }
                   5082: 
                   5083: 
                   5084: proc UISetGameLevel {level} {
                   5085:   global GameLevel
                   5086:   set GameLevel $level
                   5087:   global ScenarioWindows
                   5088:   foreach win $ScenarioWindows {
                   5089:     UpdateLevelSelection $win
                   5090:   }
                   5091: }
                   5092: 
                   5093: 
                   5094: proc UISetCityName {name} {
                   5095:   global EditorWindows
                   5096:   global CityName
                   5097:   set CityName $name
                   5098:   set title "Micropolis Editor on $name"
                   5099:   foreach win $EditorWindows {
                   5100:     # TODO: set editor window and icon title
                   5101:     #wm title $win "$title"
                   5102:     #wm iconname $win "$title"
                   5103:   }
                   5104: }
                   5105: 
                   5106: 
                   5107: proc UILoadCity {win} {
                   5108:   # if changed, r-u-sure?
                   5109:   global CityDir
                   5110:   set file [ShowFileOf $win]
                   5111:   DoFileDialog $file "Choose a City to Load" $CityDir "*.cty" "" \
                   5112:        "UIDoLoadCity" ""
                   5113: }
                   5114: 
                   5115: 
                   5116: proc UIDoLoadCity {name path} {
                   5117:   global CityDir
                   5118:   set CityDir $path
                   5119:   if {![string match *.cty $name]} {
                   5120:     set name $name.cty
                   5121:   }
                   5122:   MakeHistory "DoLoadCity $path/$name"
                   5123: }
                   5124: 
                   5125: 
                   5126: proc DoLoadCity {filename} {
                   5127:   sim LoadCity $filename
                   5128: }
                   5129: 
                   5130: proc UIDidLoadCity {} {
                   5131:   global State GameLevel Scenario
                   5132:   set Scenario -1
                   5133:   set GameLevel -1
                   5134:   if {$State == "play"} {
                   5135:     UIPlayGame
                   5136:   } else {
                   5137:     UIShowPicture 49 [sim CityFileName]
                   5138:   }
                   5139: }
                   5140: 
                   5141: 
                   5142: proc UIDidntLoadCity {msg} {
                   5143:   DoSendMessage $msg alert
                   5144:   UIMakeSound warning Sorry "-speed 85"
                   5145:   UIShowPicture 49 [sim CityFileName]
                   5146:   sim Fill 0
                   5147:   sim UpdateMaps
                   5148: }
                   5149: 
                   5150: 
                   5151: proc UINewGame {} {
                   5152:   global OldBudget
                   5153:   set OldBudget 0
                   5154:   sim InitGame
                   5155:   sim EraseOverlay
                   5156:   InitEditors
                   5157:   InitMaps
                   5158:   InitGraphs
                   5159:   update
                   5160:   sim UpdateMaps
                   5161: }
                   5162: 
                   5163: 
                   5164: proc UIDidPan {w x y} {
                   5165:   if {[$w ToolMode] == 1} {
                   5166:     EditorToolDrag $w $x $y
                   5167:   }
                   5168:   update idletasks
                   5169: }
                   5170: 
                   5171: 
                   5172: proc UIDidStopPan {win} {
                   5173:   UIMakeSoundOn $win fancy Skid "-volume 25"
                   5174:   $win TweakCursor
                   5175: }
                   5176: 
                   5177: 
                   5178: proc UIEarthQuake {} {
                   5179: }
                   5180: 
                   5181: 
                   5182: proc UIAutoGoto {x y {except {}}} {
                   5183:   global EditorWindows
                   5184:   set didOne 0
                   5185:   set x [expr "$x * 16 + 8"]
                   5186:   set y [expr "$y * 16 + 8"]
                   5187:   foreach win $EditorWindows {
                   5188:     if {"$win" != "$except"} {
                   5189:       set view [WindowLink $win.view]
                   5190:       if {[$view AutoGoto]} {
                   5191:         set didOne 1
                   5192:         $view AutoGoal $x $y
                   5193:       }
                   5194:     }
                   5195:   }
                   5196:   if {$didOne} {
                   5197:     sim UpdateMaps
                   5198:   }
                   5199: }
                   5200: 
                   5201: 
                   5202: proc UIAutoGotoOn {x y eds} {
                   5203:   set x [expr "$x * 16 + 8"]
                   5204:   set y [expr "$y * 16 + 8"]
                   5205:   foreach win $eds {
                   5206:     [WindowLink $win.view] AutoGoal $x $y
                   5207:   }
                   5208:   sim UpdateMaps
                   5209: }
                   5210: 
                   5211: 
                   5212: proc DoLeaveGame {head} {
                   5213: }
                   5214: 
                   5215: 
                   5216: proc UILoseGame {} {
                   5217:   UIPickScenarioMode
                   5218:   UIShowPicture 200
                   5219: }
                   5220: 
                   5221: 
                   5222: proc UIWinGame {} {
                   5223:   UIShowPicture 100
                   5224: }
                   5225: 
                   5226: 
                   5227: proc DoPendTool {view tool x y} {
                   5228:   global HeadWindows ToolInfo VotesForAsk
                   5229: 
                   5230:   set win [WindowLink $view.top]
                   5231:   set head [WindowLink $win.head]
                   5232: 
                   5233:   if {($tool == [sim PendingTool]) &&
                   5234:       ($x == [sim PendingX]) &&
                   5235:       ($y == [sim PendingY])} {
                   5236:     if {[lsearch $VotesForAsk $head] != -1} {
                   5237:       # you can only vote once
                   5238:       UIMakeSound edit Oop
                   5239:     } else {
                   5240:       UIMakeSound edit Boing
                   5241:       set ask [WindowLink $head.ask]
                   5242:       PressVoteButton $ask [WindowLink $ask.vote] Ask
                   5243:     }
                   5244:   } else {
                   5245:     UIAutoGoto $x $y $win
                   5246: 
                   5247:     UIMakeSound edit Boing
                   5248:     set info [lindex $ToolInfo $tool]
                   5249:     set a [lindex $info 0]
                   5250:     set name [lindex $info 1]
                   5251:     set cost [lindex $info 2]
                   5252:     set title "Build $a $name"
                   5253:     set question "Do you support the plan to build $a $name for $cost?"
                   5254:     AskQuestion [Color $win #00ff00 #ffffff] "$title" \
                   5255:        "$question" \
                   5256:        "{Veto plan.} Plan.Veto
                   5257:           {RejectPlan}" \
                   5258:        "{Goto plan.} Plan.Goto
                   5259:           {ComeTo %s $x $y}" \
                   5260:        "{Support plan!} Plan.Support
                   5261:           {SupportPlan $view %s $tool $x $y}
                   5262:           {PreviewSupportPlan $view %s $tool $x $y}"
                   5263:     set VotesForAsk $head
                   5264:     set ask [WindowLink $head.ask]
                   5265:     [WindowLink $ask.vote] config -relief sunken
                   5266: 
                   5267:     UpdateVotesForAsk
                   5268: 
                   5269:     sim PendingTool $tool
                   5270:     sim PendingX $x
                   5271:     sim PendingY $y
                   5272:     sim Votes [llength $VotesForAsk]
                   5273:   }
                   5274: }
                   5275: 
                   5276: 
                   5277: proc RejectPlan {} {
                   5278:   sim PendingTool -1
                   5279:   if {[sim Players] > 1} {
                   5280:     UIMakeSound edit Sorry
                   5281:   }
                   5282:   WithdrawAsks
                   5283: }
                   5284: 
                   5285: 
                   5286: proc NeededVotes {} {
                   5287:   global FreeVotes
                   5288:   set players [sim Players]
                   5289:   set needed [expr "$players - $FreeVotes"]
                   5290:   return [max 0 $needed]
                   5291: }
                   5292: 
                   5293: 
                   5294: proc SupportPlan {view h tool x y} {
                   5295:   global VotesForAsk
                   5296:   sim Votes [llength $VotesForAsk]
                   5297:   sim PendingTool -1
                   5298:   sim OverRide 1
                   5299:   $view DoTool $tool $x $y
                   5300:   sim OverRide 0
                   5301:   WithdrawAsks
                   5302:   UIMakeSound edit Aaah
                   5303: }
                   5304: 
                   5305: 
                   5306: proc PreviewSupportPlan {view h tool x y} {
                   5307:   global VotesForAsk
                   5308:   sim Votes [llength $VotesForAsk]
                   5309: }
                   5310: 
                   5311: 
                   5312: proc SugarStartUp {uri} {
                   5313:   global SugarURI
                   5314:   set SugarURI $uri
                   5315: 
                   5316:   # TODO: Load the city file at the given URI, or configure according to URI parameters. 
                   5317: }
                   5318: 
                   5319: 
                   5320: proc SugarNickName {nick} {
                   5321:   global SugarNickName
                   5322:   set SugarNickName $nick
                   5323: }
                   5324: 
                   5325: 
                   5326: proc SugarActivate {} {
                   5327:   global SugarActivated
                   5328:   set SugarActivated 1
                   5329: }
                   5330: 
                   5331: 
                   5332: proc SugarDeactivate {} {
                   5333:   global SugarActivated
                   5334:   set SugarActivated 0
                   5335: }
                   5336: 
                   5337: 
                   5338: proc SugarShare {} {
                   5339:   global SugarShared
                   5340:   set SugarShared 1
                   5341: }
                   5342: 
                   5343: 
                   5344: proc SugarBuddyAdd {key nick color address} {
                   5345:   global SugarBuddies
                   5346:   set buddy [list $key $nick $color $address]
                   5347:   lappend SugarBuddies $buddy
                   5348: }
                   5349: 
                   5350: 
                   5351: proc SugarBuddyDel {key nick color address} {
                   5352:   global SugarBuddies
                   5353:   set buddy [list $key $nick $color $address]
                   5354:   set i [lsearch $wins $win]
                   5355:   if {$i != -1} {
                   5356:     set SugarBuddies [lreplace $wins $i $i]
                   5357:   }
                   5358: }
                   5359: 
                   5360: 
                   5361: proc SugarQuit {} {
                   5362:   sim ReallyQuit
                   5363: }
                   5364: 
                   5365: 
                   5366: ########################################################################

unix.superglobalmegacorp.com

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