]> git.zerfleddert.de Git - micropolis/blame_incremental - src/sim/w_sim.c
correctly resize editor window to be in sync with the mini map
[micropolis] / src / sim / w_sim.c
... / ...
CommitLineData
1/* w_sim.c
2 *
3 * Micropolis, Unix Version. This game was released for the Unix platform
4 * in or about 1990 and has been modified for inclusion in the One Laptop
5 * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If
6 * you need assistance with this program, you may contact:
7 * http://wiki.laptop.org/go/Micropolis or email micropolis@laptop.org.
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. You should have received a
18 * copy of the GNU General Public License along with this program. If
19 * not, see <http://www.gnu.org/licenses/>.
20 *
21 * ADDITIONAL TERMS per GNU GPL Section 7
22 *
23 * No trademark or publicity rights are granted. This license does NOT
24 * give you any right, title or interest in the trademark SimCity or any
25 * other Electronic Arts trademark. You may not distribute any
26 * modification of this program using the trademark SimCity or claim any
27 * affliation or association with Electronic Arts Inc. or its employees.
28 *
29 * Any propagation or conveyance of this program must include this
30 * copyright notice and these terms.
31 *
32 * If you convey this program (or any modifications of it) and assume
33 * contractual liability for the program to recipients of it, you agree
34 * to indemnify Electronic Arts for any liability that those contractual
35 * assumptions impose on Electronic Arts.
36 *
37 * You may not misrepresent the origins of this program; modified
38 * versions of the program must be marked as such and not identified as
39 * the original program.
40 *
41 * This disclaimer supplements the one included in the General Public
42 * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
43 * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
44 * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF
45 * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS
46 * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
47 * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
48 * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
49 * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
50 * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST
51 * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
52 * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
53 * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
54 * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
55 * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
56 * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME
57 * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
58 * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
59 * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
60 * NOT APPLY TO YOU.
61 */
62#include "sim.h"
63
64
65Tcl_HashTable SimCmds;
66
67
68#define SIMCMD_CALL(proc) \
69 int SimCmd##proc(ARGS) { proc(); return (TCL_OK); }
70
71#define SIMCMD_CALL_KICK(proc) \
72 int SimCmd##proc(ARGS) { proc(); Kick(); return (TCL_OK); }
73
74#define SIMCMD_CALL_INT(proc) \
75 int SimCmd##proc(ARGS) { \
76 int val; \
77 if (argc != 3) return (TCL_ERROR); \
78 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK)) return (TCL_ERROR); \
79 proc(val); \
80 return (TCL_OK); \
81 }
82
83#define SIMCMD_CALL_STR(proc) \
84 int SimCmd##proc(ARGS) { \
85 if (argc != 3) return (TCL_ERROR); \
86 proc(argv[2]); \
87 return (TCL_OK); \
88 }
89
90#define SIMCMD_CALL_TILEXY(proc) \
91 int SimCmd##proc(ARGS) { \
92 int x, y; \
93 if (argc != 4) return (TCL_ERROR); \
94 if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) || \
95 (x < 0) || (x >= WORLD_X)) return (TCL_ERROR); \
96 if ((Tcl_GetInt(interp, argv[3], &y) != TCL_OK) || \
97 (y < 0) || (y >= WORLD_Y)) return (TCL_ERROR); \
98 proc(x, y); \
99 return (TCL_OK); \
100 }
101
102#define SIMCMD_ACCESS_INT(var) \
103 int SimCmd##var(ARGS) { \
104 int val; \
105 if ((argc != 2) && (argc != 3)) return (TCL_ERROR); \
106 if (argc == 3) { \
107 if (Tcl_GetInt(interp, argv[2], &val) != TCL_OK) return (TCL_ERROR); \
108 var = val; \
109 } \
110 sprintf(interp->result, "%d", var); \
111 return (TCL_OK); \
112 }
113
114#define SIMCMD_GET_INT(var) \
115 int SimCmd##var(ARGS) { \
116 sprintf(interp->result, "%d", var); \
117 return (TCL_OK); \
118 }
119
120#define SIMCMD_GET_STR(var) \
121 int SimCmd##var(ARGS) { \
122 sprintf(interp->result, "%s", var); \
123 return (TCL_OK); \
124 }
125
126
127SIMCMD_CALL_KICK(GameStarted)
128SIMCMD_CALL_KICK(InitGame)
129SIMCMD_CALL(SaveCity)
130SIMCMD_CALL(ReallyQuit)
131SIMCMD_CALL_KICK(UpdateHeads)
132SIMCMD_CALL_KICK(UpdateMaps)
133SIMCMD_CALL_KICK(UpdateEditors)
134SIMCMD_CALL_KICK(RedrawMaps)
135SIMCMD_CALL_KICK(RedrawEditors)
136SIMCMD_CALL_KICK(UpdateGraphs)
137SIMCMD_CALL_KICK(UpdateEvaluation)
138SIMCMD_CALL_KICK(UpdateBudget)
139SIMCMD_CALL_KICK(UpdateBudgetWindow)
140SIMCMD_CALL_KICK(DoBudget)
141SIMCMD_CALL_KICK(DoBudgetFromMenu)
142SIMCMD_CALL_KICK(Pause)
143SIMCMD_CALL_KICK(Resume)
144SIMCMD_CALL(StartBulldozer)
145SIMCMD_CALL(StopBulldozer)
146SIMCMD_CALL(MakeFire)
147SIMCMD_CALL(MakeFlood)
148SIMCMD_CALL(MakeTornado)
149SIMCMD_CALL(MakeEarthquake)
150SIMCMD_CALL(MakeMonster)
151SIMCMD_CALL(MakeMeltdown)
152SIMCMD_CALL(FireBomb)
153SIMCMD_CALL(SoundOff)
154SIMCMD_CALL(GenerateNewCity)
155SIMCMD_CALL_INT(GenerateSomeCity)
156SIMCMD_ACCESS_INT(LakeLevel)
157SIMCMD_ACCESS_INT(TreeLevel)
158SIMCMD_ACCESS_INT(CurveLevel)
159SIMCMD_ACCESS_INT(CreateIsland)
160SIMCMD_CALL_KICK(SmoothTrees)
161SIMCMD_CALL_KICK(SmoothWater)
162SIMCMD_CALL_KICK(SmoothRiver)
163SIMCMD_CALL_KICK(ClearMap)
164SIMCMD_CALL_KICK(ClearUnnatural)
165SIMCMD_CALL_INT(LoadScenario)
166SIMCMD_CALL_STR(LoadCity)
167SIMCMD_CALL_STR(SaveCityAs)
168SIMCMD_CALL_TILEXY(MakeExplosion)
169SIMCMD_CALL(EraseOverlay)
170SIMCMD_ACCESS_INT(OverRide)
171SIMCMD_ACCESS_INT(Expensive)
172SIMCMD_ACCESS_INT(Players)
173SIMCMD_ACCESS_INT(Votes)
174SIMCMD_ACCESS_INT(BobHeight)
175SIMCMD_ACCESS_INT(PendingTool)
176SIMCMD_ACCESS_INT(PendingX)
177SIMCMD_ACCESS_INT(PendingY)
178SIMCMD_GET_STR(Displays)
179
180
181int SimCmdCityName(ARGS)
182{
183 if ((argc != 2) && (argc != 3)) {
184 return (TCL_ERROR);
185 }
186
187 if (argc == 3) {
188 setCityName(argv[2]);
189 }
190
191 sprintf(interp->result, "%s", CityName);
192 return (TCL_OK);
193}
194
195
196int SimCmdCityFileName(ARGS)
197{
198 if ((argc != 2) && (argc != 3)) {
199 return (TCL_ERROR);
200 }
201
202 if (argc == 3) {
203 if (CityFileName != NULL) {
204 ckfree(CityFileName);
205 CityFileName = NULL;
206 }
207 if (argv[2][0] != '\0') {
208 CityFileName = (char *)ckalloc(strlen(argv[0]) + 1);
209 strcpy(CityFileName, argv[2]);
210 }
211 }
212
213 sprintf(interp->result, "%s", CityFileName ? CityFileName : "");
214 return (TCL_OK);
215}
216
217
218int SimCmdGameLevel(ARGS)
219{
220 int level;
221
222 if ((argc != 2) && (argc != 3)) {
223 return (TCL_ERROR);
224 }
225
226 if (argc == 3) {
227 if ((Tcl_GetInt(interp, argv[2], &level) != TCL_OK) ||
228 (level < 0) || (level > 2)) {
229 return (TCL_ERROR);
230 }
231 SetGameLevelFunds(level);
232 }
233
234 sprintf(interp->result, "%d", GameLevel);
235 return (TCL_OK);
236}
237
238
239int SimCmdSpeed(ARGS)
240{
241 int speed;
242
243 if ((argc != 2) && (argc != 3)) {
244 return (TCL_ERROR);
245 }
246
247 if (argc == 3) {
248 if ((Tcl_GetInt(interp, argv[2], &speed) != TCL_OK) ||
249 (speed < 0) || (speed > 7)) {
250 return (TCL_ERROR);
251 }
252 setSpeed(speed); Kick();
253 }
254
255 sprintf(interp->result, "%d", SimSpeed);
256 return (TCL_OK);
257}
258
259
260int SimCmdSkips(ARGS)
261{
262 int skips;
263
264 if ((argc != 2) && (argc != 3)) {
265 return (TCL_ERROR);
266 }
267
268 if (argc == 3) {
269 if ((Tcl_GetInt(interp, argv[2], &skips) != TCL_OK) ||
270 (skips < 0)) {
271 return (TCL_ERROR);
272 }
273 setSkips(skips); Kick();
274 }
275
276 sprintf(interp->result, "%d", sim_skips);
277
278 return (TCL_OK);
279}
280
281
282int SimCmdSkip(ARGS)
283{
284 int skip;
285
286 if ((argc != 2) && (argc != 3)) {
287 return (TCL_ERROR);
288 }
289
290 if (argc == 3) {
291 if ((Tcl_GetInt(interp, argv[2], &skip) != TCL_OK) ||
292 (skip < 0)) {
293 return (TCL_ERROR);
294 }
295 sim_skip = skip;
296 }
297
298 sprintf(interp->result, "%d", sim_skip);
299
300 return (TCL_OK);
301}
302
303
304int SimCmdDelay(ARGS)
305{
306 int delay;
307
308 if ((argc != 2) && (argc != 3)) {
309 return (TCL_ERROR);
310 }
311
312 if (argc == 3) {
313 if ((Tcl_GetInt(interp, argv[2], &delay) != TCL_OK) ||
314 (delay < 0)) {
315 return (TCL_ERROR);
316 }
317 sim_delay = delay; Kick();
318 }
319
320 sprintf(interp->result, "%d", sim_delay);
321 return (TCL_OK);
322}
323
324
325int SimCmdWorldX(ARGS)
326{
327 int val;
328
329 if (argc != 2) {
330 return (TCL_ERROR);
331 }
332
333 sprintf(interp->result, "%d", WORLD_X);
334 return (TCL_OK);
335}
336
337
338int SimCmdWorldY(ARGS)
339{
340 int val;
341
342 if (argc != 2) {
343 return (TCL_ERROR);
344 }
345
346 sprintf(interp->result, "%d", WORLD_Y);
347 return (TCL_OK);
348}
349
350
351int SimCmdHeatSteps(ARGS)
352{
353 int steps;
354
355 if ((argc != 2) && (argc != 3)) {
356 return (TCL_ERROR);
357 }
358
359 if (argc == 3) {
360 if ((Tcl_GetInt(interp, argv[2], &steps) != TCL_OK) ||
361 (steps < 0)) {
362 return (TCL_ERROR);
363 }
364 heat_steps = steps; Kick();
365 }
366
367 sprintf(interp->result, "%d", heat_steps);
368 return (TCL_OK);
369}
370
371
372int SimCmdHeatFlow(ARGS)
373{
374 int flow;
375
376 if ((argc != 2) && (argc != 3)) {
377 return (TCL_ERROR);
378 }
379
380 if (argc == 3) {
381 if (Tcl_GetInt(interp, argv[2], &flow) != TCL_OK) {
382 return (TCL_ERROR);
383 }
384 heat_flow = flow;
385 }
386
387 sprintf(interp->result, "%d", heat_flow);
388 return (TCL_OK);
389}
390
391
392int SimCmdHeatRule(ARGS)
393{
394 int rule;
395
396 if ((argc != 2) && (argc != 3)) {
397 return (TCL_ERROR);
398 }
399
400 if (argc == 3) {
401 if (Tcl_GetInt(interp, argv[2], &rule) != TCL_OK) {
402 return (TCL_ERROR);
403 }
404 heat_rule = rule;
405 }
406
407 sprintf(interp->result, "%d", heat_rule);
408 return (TCL_OK);
409}
410
411
412#ifdef CAM
413
414int SimCmdJustCam(ARGS)
415{
416 int cam;
417
418 if ((argc != 2) && (argc != 3)) {
419 return (TCL_ERROR);
420 }
421
422 if (argc == 3) {
423 if (Tcl_GetInt(interp, argv[2], &cam) != TCL_OK) {
424 return (TCL_ERROR);
425 }
426 sim_just_cam = cam;
427 }
428
429 sprintf(interp->result, "%d", sim_just_cam);
430 return (TCL_OK);
431}
432
433#endif
434
435
436#ifdef NET
437
438int SimCmdListenTo(ARGS)
439{
440 int port, sock;
441
442 if (argc != 3) {
443 return (TCL_ERROR);
444 }
445
446 if (Tcl_GetInt(interp, argv[2], &port) != TCL_OK) {
447 return (TCL_ERROR);
448 }
449
450#ifdef NET
451 sock = udp_listen(port);
452#endif
453
454 sprintf(interp->result, "%d", sock);
455
456 return (TCL_OK);
457}
458
459
460int SimCmdHearFrom(ARGS)
461{
462 int sock;
463
464 if (argc != 3) {
465 return (TCL_ERROR);
466 }
467
468 if ((argv[2][0] != 'f') ||
469 (argv[2][1] != 'i') ||
470 (argv[2][2] != 'l') ||
471 (argv[2][3] != 'e') ||
472 (Tcl_GetInt(interp, argv[2] + 4, &sock) != TCL_OK)) {
473 return (TCL_ERROR);
474 }
475
476#ifdef NET
477 udp_hear(sock);
478#endif
479
480 return (TCL_OK);
481}
482
483#endif /* NET */
484
485
486int SimCmdFunds(ARGS)
487{
488 int funds;
489
490 if ((argc != 2) && (argc != 3)) {
491 return (TCL_ERROR);
492 }
493
494 if (argc == 3) {
495 if ((Tcl_GetInt(interp, argv[2], &funds) != TCL_OK) ||
496 (funds < 0)) {
497 return (TCL_ERROR);
498 }
499 TotalFunds = funds;
500 MustUpdateFunds = 1;
501 Kick();
502 }
503
504 sprintf(interp->result, "%d", TotalFunds);
505 return (TCL_OK);
506}
507
508
509int SimCmdTaxRate(ARGS)
510{
511 int tax;
512
513 if ((argc != 2) && (argc != 3)) {
514 return (TCL_ERROR);
515 }
516
517 if (argc == 3) {
518 if ((Tcl_GetInt(interp, argv[2], &tax) != TCL_OK) ||
519 (tax < 0) || (tax > 20)) {
520 return (TCL_ERROR);
521 }
522 CityTax = tax;
523 drawBudgetWindow(); Kick();
524 }
525
526 sprintf(interp->result, "%d", CityTax);
527 return (TCL_OK);
528}
529
530
531int SimCmdFireFund(ARGS)
532{
533 int percent;
534
535 if ((argc != 2) && (argc != 3)) {
536 return (TCL_ERROR);
537 }
538
539 if (argc == 3) {
540 if ((Tcl_GetInt(interp, argv[2], &percent) != TCL_OK) ||
541 (percent < 0) || (percent > 100)) {
542 return (TCL_ERROR);
543 }
544 firePercent = percent / 100.0;
545 FireSpend = (fireMaxValue * percent) / 100;
546 UpdateFundEffects(); Kick();
547 }
548
549 sprintf(interp->result, "%d", (int)(firePercent * 100.0));
550 return (TCL_OK);
551}
552
553
554int SimCmdPoliceFund(ARGS)
555{
556 int percent;
557
558 if ((argc != 2) && (argc != 3)) {
559 return (TCL_ERROR);
560 }
561
562 if (argc == 3) {
563 if ((Tcl_GetInt(interp, argv[2], &percent) != TCL_OK) ||
564 (percent < 0) || (percent > 100)) {
565 return (TCL_ERROR);
566 }
567 policePercent = percent / 100.0;
568 PoliceSpend = (policeMaxValue * percent) / 100;
569 UpdateFundEffects(); Kick();
570 }
571
572 sprintf(interp->result, "%d", (int)(policePercent * 100.0));
573 return (TCL_OK);
574}
575
576
577int SimCmdRoadFund(ARGS)
578{
579 int percent;
580
581 if ((argc != 2) && (argc != 3)) {
582 return (TCL_ERROR);
583 }
584
585 if (argc == 3) {
586 if ((Tcl_GetInt(interp, argv[2], &percent) != TCL_OK) ||
587 (percent < 0) || (percent > 100)) {
588 return (TCL_ERROR);
589 }
590 roadPercent = percent / 100.0;
591 RoadSpend = (roadMaxValue * percent) / 100;
592 UpdateFundEffects(); Kick();
593 }
594
595 sprintf(interp->result, "%d", (int)(roadPercent * 100.0));
596 return (TCL_OK);
597}
598
599
600int SimCmdYear(ARGS)
601{
602 int year;
603
604 if ((argc != 2) && (argc != 3)) {
605 return (TCL_ERROR);
606 }
607
608 if (argc == 3) {
609 if ((Tcl_GetInt(interp, argv[2], &year) != TCL_OK)) {
610 return (TCL_ERROR);
611 }
612 SetYear(year);
613 }
614
615 sprintf(interp->result, "%d", CurrentYear());
616 return (TCL_OK);
617}
618
619
620int SimCmdAutoBudget(ARGS)
621{
622 int val;
623
624 if ((argc != 2) && (argc != 3)) {
625 return (TCL_ERROR);
626 }
627
628 if (argc == 3) {
629 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK) ||
630 (val < 0) || (val > 1)) {
631 return (TCL_ERROR);
632 }
633 autoBudget = val;
634 MustUpdateOptions = 1; Kick();
635 UpdateBudget();
636 }
637
638 sprintf(interp->result, "%d", autoBudget);
639 return (TCL_OK);
640}
641
642
643int SimCmdAutoGoto(ARGS)
644{
645 int val;
646
647 if ((argc != 2) && (argc != 3)) {
648 return (TCL_ERROR);
649 }
650
651 if (argc == 3) {
652 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK) ||
653 (val < 0) || (val > 1)) {
654 return (TCL_ERROR);
655 }
656 autoGo = val;
657 MustUpdateOptions = 1; Kick();
658 }
659
660 sprintf(interp->result, "%d", autoGo);
661 return (TCL_OK);
662}
663
664
665int SimCmdAutoBulldoze(ARGS)
666{
667 int val;
668
669 if ((argc != 2) && (argc != 3)) {
670 return (TCL_ERROR);
671 }
672
673 if (argc == 3) {
674 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK) ||
675 (val < 0) || (val > 1)) {
676 return (TCL_ERROR);
677 }
678 autoBulldoze = val;
679 MustUpdateOptions = 1; Kick();
680 }
681
682 sprintf(interp->result, "%d", autoBulldoze);
683 return (TCL_OK);
684}
685
686
687int SimCmdDisasters(ARGS)
688{
689 int val;
690
691 if ((argc != 2) && (argc != 3)) {
692 return (TCL_ERROR);
693 }
694
695 if (argc == 3) {
696 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK) ||
697 (val < 0) || (val > 1)) {
698 return (TCL_ERROR);
699 }
700 NoDisasters = val ? 0 : 1;
701 MustUpdateOptions = 1; Kick();
702 }
703
704 sprintf(interp->result, "%d", NoDisasters ? 0 : 1);
705 return (TCL_OK);
706}
707
708
709int SimCmdSound(ARGS)
710{
711 int val;
712
713 if ((argc != 2) && (argc != 3)) {
714 return (TCL_ERROR);
715 }
716
717 if (argc == 3) {
718 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK) ||
719 (val < 0) || (val > 1)) {
720 return (TCL_ERROR);
721 }
722 UserSoundOn = val;
723 MustUpdateOptions = 1; Kick();
724 }
725
726 sprintf(interp->result, "%d", UserSoundOn);
727 return (TCL_OK);
728}
729
730
731int SimCmdFlush(ARGS)
732{
733 int style;
734
735 if (argc != 2) {
736 return (TCL_ERROR);
737 }
738
739 return (TCL_OK);
740}
741
742
743int SimCmdFlushStyle(ARGS)
744{
745 int style;
746
747 if ((argc != 2) && (argc != 3)) {
748 return (TCL_ERROR);
749 }
750
751 if (argc == 3) {
752 if ((Tcl_GetInt(interp, argv[2], &style) != TCL_OK) ||
753 (style < 0)) {
754 return (TCL_ERROR);
755 }
756 FlushStyle = style;
757 }
758
759 sprintf(interp->result, "%d", FlushStyle);
760 return (TCL_OK);
761}
762
763
764int SimCmdDonDither(ARGS)
765{
766 int dd;
767
768 if ((argc != 2) && (argc != 3)) {
769 return (TCL_ERROR);
770 }
771
772 if (argc == 3) {
773 if ((Tcl_GetInt(interp, argv[2], &dd) != TCL_OK) ||
774 (dd < 0)) {
775 return (TCL_ERROR);
776 }
777 DonDither = dd;
778 }
779
780 sprintf(interp->result, "%d", DonDither);
781 return (TCL_OK);
782}
783
784
785int SimCmdDoOverlay(ARGS)
786{
787 int dd;
788
789 if ((argc != 2) && (argc != 3)) {
790 return (TCL_ERROR);
791 }
792
793 if (argc == 3) {
794 if ((Tcl_GetInt(interp, argv[2], &dd) != TCL_OK) ||
795 (dd < 0)) {
796 return (TCL_ERROR);
797 }
798 DoOverlay = dd;
799 }
800
801 sprintf(interp->result, "%d", DoOverlay);
802 return (TCL_OK);
803}
804
805
806int SimCmdMonsterGoal(ARGS)
807{
808 SimSprite *sprite;
809 int x, y;
810
811 if (argc != 4) {
812 return (TCL_ERROR);
813 }
814
815 if (Tcl_GetInt(interp, argv[2], &x) != TCL_OK) {
816 return (TCL_ERROR);
817 }
818 if (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) {
819 return (TCL_ERROR);
820 }
821 if ((sprite = GetSprite(GOD)) == NULL) {
822 MakeMonster();
823 if ((sprite = GetSprite(GOD)) == NULL)
824 return (TCL_ERROR);
825 }
826 sprite->dest_x = x;
827 sprite->dest_y = y;
828 sprite->control = -2;
829 sprite->count = -1;
830
831 return (TCL_OK);
832}
833
834
835int SimCmdHelicopterGoal(ARGS)
836{
837 int x, y;
838 SimSprite *sprite;
839
840 if (argc != 4) {
841 return (TCL_ERROR);
842 }
843
844 if (Tcl_GetInt(interp, argv[2], &x) != TCL_OK) {
845 return (TCL_ERROR);
846 }
847 if (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) {
848 return (TCL_ERROR);
849 }
850
851 if ((sprite = GetSprite(COP)) == NULL) {
852 GenerateCopter(x, y);
853 if ((sprite = GetSprite(COP)) == NULL) {
854 return (TCL_ERROR);
855 }
856 }
857 sprite->dest_x = x;
858 sprite->dest_y = y;
859
860 return (TCL_OK);
861}
862
863
864int SimCmdMonsterDirection(ARGS)
865{
866 int dir;
867 SimSprite *sprite;
868
869 if (argc != 3) {
870 return (TCL_ERROR);
871 }
872
873 if ((Tcl_GetInt(interp, argv[2], &dir) != TCL_OK) ||
874 (dir < -1) || (dir > 7)) {
875 return (TCL_ERROR);
876 }
877 if ((sprite = GetSprite(GOD)) == NULL) {
878 MakeMonster();
879 if ((sprite = GetSprite(GOD)) == NULL) {
880 return (TCL_ERROR);
881 }
882 }
883 sprite->control = dir;
884
885 return (TCL_OK);
886}
887
888
889int SimCmdTile(ARGS)
890{
891 int x, y, tile;
892
893 if ((argc != 4) && (argc != 5)) {
894 return (TCL_ERROR);
895 }
896 if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
897 (x < 0) ||
898 (x >= WORLD_X) ||
899 (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) ||
900 (y < 0) ||
901 (y >= WORLD_Y)) {
902 return (TCL_ERROR);
903 }
904 if (argc == 5) {
905 if (Tcl_GetInt(interp, argv[4], &tile) != TCL_OK) {
906 return (TCL_ERROR);
907 }
908 Map[x][y] = tile;
909 }
910 sprintf(interp->result, "%d", Map[x][y]);
911 return (TCL_OK);
912}
913
914
915int SimCmdFill(ARGS)
916{
917 int tile, x, y;
918
919 if (argc != 3) {
920 return (TCL_ERROR);
921 }
922 if (Tcl_GetInt(interp, argv[2], &tile) != TCL_OK) {
923 return (TCL_ERROR);
924 }
925 for (x = 0; x < WORLD_X; x++) {
926 for (y = 0; y < WORLD_Y; y++) {
927 Map[x][y] = tile;
928 }
929 }
930 sprintf(interp->result, "%d", tile);
931 return (TCL_OK);
932}
933
934
935int SimCmdDynamicData(ARGS)
936{
937 int index, val;
938
939 if ((argc != 3) && (argc != 4)) {
940 return (TCL_ERROR);
941 }
942
943 if ((Tcl_GetInt(interp, argv[2], &index) != TCL_OK) ||
944 (index < 0) ||
945 (index >= 32)) {
946 return (TCL_ERROR);
947 }
948
949 if (argc == 4) {
950 int val;
951
952 if (Tcl_GetInt(interp, argv[3], &val) != TCL_OK) {
953 return (TCL_ERROR);
954 }
955 DynamicData[index] = val;
956 NewMapFlags[DYMAP] = 1;
957 Kick();
958 }
959
960 sprintf(interp->result, "%d", DynamicData[index]);
961 return (TCL_OK);
962}
963
964
965int SimCmdResetDynamic(ARGS)
966{
967 int i;
968
969 for (i = 0; i < 16; i++) {
970 DynamicData[i] = (i & 1) ? 99999 : -99999;
971 }
972 NewMapFlags[DYMAP] = 1;
973 Kick();
974 return (TCL_OK);
975}
976
977
978int SimCmdPerformance(ARGS)
979{
980 SimView *view;
981
982 PerformanceTiming = 1;
983 FlushTime = 0.0;
984 for (view = sim->editor; view != NULL; view = view->next) {
985 view->updates = 0;
986 view->update_real = view->update_user = view->update_system = 0.0;
987 }
988 return (TCL_OK);
989}
990
991
992int SimCmdCollapseMotion(ARGS)
993{
994 int val;
995
996 if ((argc != 2) && (argc != 3)) {
997 return (TCL_ERROR);
998 }
999
1000 if (argc == 3) {
1001 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK)) {
1002 return (TCL_ERROR);
1003 }
1004 tkCollapseMotion = val;
1005 }
1006
1007 sprintf(interp->result, "%d", tkCollapseMotion);
1008 return (TCL_OK);
1009}
1010
1011
1012int SimCmdUpdate(ARGS)
1013{
1014 sim_update();
1015 return (TCL_OK);
1016}
1017
1018
1019int SimCmdLandValue(ARGS)
1020{
1021 int val;
1022
1023 if (argc != 2) {
1024 return (TCL_ERROR);
1025 }
1026
1027 sprintf(interp->result, "%d", LVAverage);
1028 return (TCL_OK);
1029}
1030
1031
1032int SimCmdTraffic(ARGS)
1033{
1034 int val;
1035
1036 if (argc != 2) {
1037 return (TCL_ERROR);
1038 }
1039
1040 sprintf(interp->result, "%d", AverageTrf());
1041 return (TCL_OK);
1042}
1043
1044
1045int SimCmdCrime(ARGS)
1046{
1047 int val;
1048
1049 if (argc != 2) {
1050 return (TCL_ERROR);
1051 }
1052
1053 sprintf(interp->result, "%d", CrimeAverage);
1054 return (TCL_OK);
1055}
1056
1057
1058int SimCmdUnemployment(ARGS)
1059{
1060 int val;
1061
1062 if (argc != 2) {
1063 return (TCL_ERROR);
1064 }
1065
1066 sprintf(interp->result, "%d", GetUnemployment());
1067 return (TCL_OK);
1068}
1069
1070
1071int SimCmdFires(ARGS)
1072{
1073 int val;
1074
1075 if (argc != 2) {
1076 return (TCL_ERROR);
1077 }
1078
1079 sprintf(interp->result, "%d", GetFire());
1080 return (TCL_OK);
1081}
1082
1083
1084int SimCmdPollution(ARGS)
1085{
1086 int val;
1087
1088 if (argc != 2) {
1089 return (TCL_ERROR);
1090 }
1091
1092 sprintf(interp->result, "%d", PolluteAverage);
1093 return (TCL_OK);
1094}
1095
1096
1097int SimCmdPolMaxX(ARGS)
1098{
1099 int val;
1100
1101 if (argc != 2) {
1102 return (TCL_ERROR);
1103 }
1104
1105 sprintf(interp->result, "%d", (PolMaxX <<4) + 8);
1106 return (TCL_OK);
1107}
1108
1109
1110int SimCmdPolMaxY(ARGS)
1111{
1112 int val;
1113
1114 if (argc != 2) {
1115 return (TCL_ERROR);
1116 }
1117
1118 sprintf(interp->result, "%d", (PolMaxY <<4) + 8);
1119 return (TCL_OK);
1120}
1121
1122
1123int SimCmdTrafMaxX(ARGS)
1124{
1125 int val;
1126
1127 if (argc != 2) {
1128 return (TCL_ERROR);
1129 }
1130
1131 sprintf(interp->result, "%d", TrafMaxX);
1132 return (TCL_OK);
1133}
1134
1135
1136int SimCmdTrafMaxY(ARGS)
1137{
1138 int val;
1139
1140 if (argc != 2) {
1141 return (TCL_ERROR);
1142 }
1143
1144 sprintf(interp->result, "%d", TrafMaxY);
1145 return (TCL_OK);
1146}
1147
1148
1149int SimCmdMeltX(ARGS)
1150{
1151 int val;
1152
1153 if (argc != 2) {
1154 return (TCL_ERROR);
1155 }
1156
1157 sprintf(interp->result, "%d", (MeltX <<4) + 8);
1158 return (TCL_OK);
1159}
1160
1161
1162int SimCmdMeltY(ARGS)
1163{
1164 int val;
1165
1166 if (argc != 2) {
1167 return (TCL_ERROR);
1168 }
1169
1170 sprintf(interp->result, "%d", (MeltY <<4) + 8);
1171 return (TCL_OK);
1172}
1173
1174
1175int SimCmdCrimeMaxX(ARGS)
1176{
1177 int val;
1178
1179 if (argc != 2) {
1180 return (TCL_ERROR);
1181 }
1182
1183 sprintf(interp->result, "%d", (CrimeMaxX <<4) + 8);
1184 return (TCL_OK);
1185}
1186
1187
1188int SimCmdCrimeMaxY(ARGS)
1189{
1190 int val;
1191
1192 if (argc != 2) {
1193 return (TCL_ERROR);
1194 }
1195
1196 sprintf(interp->result, "%d", (CrimeMaxY <<4) + 8);
1197 return (TCL_OK);
1198}
1199
1200
1201int SimCmdCenterX(ARGS)
1202{
1203 int val;
1204
1205 if (argc != 2) {
1206 return (TCL_ERROR);
1207 }
1208
1209 sprintf(interp->result, "%d", (CCx <<4) + 8);
1210 return (TCL_OK);
1211}
1212
1213
1214int SimCmdCenterY(ARGS)
1215{
1216 int val;
1217
1218 if (argc != 2) {
1219 return (TCL_ERROR);
1220 }
1221
1222 sprintf(interp->result, "%d", (CCy <<4) + 8);
1223 return (TCL_OK);
1224}
1225
1226
1227int SimCmdFloodX(ARGS)
1228{
1229 int val;
1230
1231 if (argc != 2) {
1232 return (TCL_ERROR);
1233 }
1234
1235 sprintf(interp->result, "%d", (FloodX <<4) + 8);
1236 return (TCL_OK);
1237}
1238
1239
1240int SimCmdFloodY(ARGS)
1241{
1242 int val;
1243
1244 if (argc != 2) {
1245 return (TCL_ERROR);
1246 }
1247
1248 sprintf(interp->result, "%d", (FloodY <<4) + 8);
1249 return (TCL_OK);
1250}
1251
1252
1253int SimCmdCrashX(ARGS)
1254{
1255 int val;
1256
1257 if (argc != 2) {
1258 return (TCL_ERROR);
1259 }
1260
1261 sprintf(interp->result, "%d", (CrashX <<4) + 8);
1262 return (TCL_OK);
1263}
1264
1265
1266int SimCmdCrashY(ARGS)
1267{
1268 int val;
1269
1270 if (argc != 2) {
1271 return (TCL_ERROR);
1272 }
1273
1274 sprintf(interp->result, "%d", (CrashY <<4) + 8);
1275 return (TCL_OK);
1276}
1277
1278
1279int SimCmdDollars(ARGS)
1280{
1281 int val;
1282
1283 if (argc != 2) {
1284 return (TCL_ERROR);
1285 }
1286
1287 makeDollarDecimalStr(argv[1], interp->result);
1288 return (TCL_OK);
1289}
1290
1291
1292int SimCmdDoAnimation(ARGS)
1293{
1294 int val;
1295
1296 if ((argc != 2) && (argc != 3)) {
1297 return (TCL_ERROR);
1298 }
1299
1300 if (argc == 3) {
1301 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK)) {
1302 return (TCL_ERROR);
1303 }
1304 DoAnimation = val;
1305 MustUpdateOptions = 1; Kick();
1306 }
1307
1308 sprintf(interp->result, "%d", DoAnimation);
1309 return (TCL_OK);
1310}
1311
1312
1313int SimCmdDoMessages(ARGS)
1314{
1315 int val;
1316
1317 if ((argc != 2) && (argc != 3)) {
1318 return (TCL_ERROR);
1319 }
1320
1321 if (argc == 3) {
1322 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK)) {
1323 return (TCL_ERROR);
1324 }
1325 DoMessages = val;
1326 MustUpdateOptions = 1; Kick();
1327 }
1328
1329 sprintf(interp->result, "%d", DoMessages);
1330 return (TCL_OK);
1331}
1332
1333
1334int SimCmdDoNotices(ARGS)
1335{
1336 int val;
1337
1338 if ((argc != 2) && (argc != 3)) {
1339 return (TCL_ERROR);
1340 }
1341
1342 if (argc == 3) {
1343 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK)) {
1344 return (TCL_ERROR);
1345 }
1346 DoNotices = val;
1347 MustUpdateOptions = 1; Kick();
1348 }
1349
1350 sprintf(interp->result, "%d", DoNotices);
1351 return (TCL_OK);
1352}
1353
1354
1355int SimCmdRand(ARGS)
1356{
1357 int val, r;
1358
1359 if ((argc != 2) && (argc != 3)) {
1360 return (TCL_ERROR);
1361 }
1362
1363 if (argc == 3) {
1364 if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK)) {
1365 return (TCL_ERROR);
1366 }
1367 r = Rand(val);
1368 } else {
1369 r = Rand16();
1370 }
1371
1372 sprintf(interp->result, "%d", r);
1373 return (TCL_OK);
1374}
1375
1376
1377int SimCmdPlatform(ARGS)
1378{
1379
1380#ifdef MSDOS
1381 sprintf(interp->result, "msdos");
1382#else
1383 sprintf(interp->result, "unix");
1384#endif
1385
1386 return (TCL_OK);
1387}
1388
1389
1390int SimCmdVersion(ARGS)
1391{
1392 sprintf(interp->result, MicropolisVersion);
1393
1394 return (TCL_OK);
1395}
1396
1397
1398int SimCmdOpenWebBrowser(ARGS)
1399{
1400 int result = 1;
1401 char buf[512];
1402
1403 if ((argc != 3) ||
1404 (strlen(argv[2]) > 255)) {
1405 return (TCL_ERROR);
1406 }
1407
1408 sprintf(buf,
1409 "netscape -no-about-splash '%s' &",
1410 argv[2]);
1411
1412 result = system(buf);
1413
1414 sprintf(interp->result, "%d", result);
1415
1416 return (TCL_OK);
1417}
1418
1419
1420int SimCmdQuoteURL(ARGS)
1421{
1422 int result = 1;
1423 char buf[2048];
1424 char *from, *to;
1425 int ch;
1426 static char *hexDigits =
1427 "0123456789ABCDEF";
1428
1429 if ((argc != 3) ||
1430 (strlen(argv[2]) > 255)) {
1431 return (TCL_ERROR);
1432 }
1433
1434 from = argv[2];
1435 to = buf;
1436
1437 while ((ch = *(from++)) != '\0') {
1438 if ((ch < 32) ||
1439 (ch >= 128) ||
1440 (ch == '+') ||
1441 (ch == '%') ||
1442 (ch == '&') ||
1443 (ch == '<') ||
1444 (ch == '>') ||
1445 (ch == '"') ||
1446 (ch == '\'')) {
1447 *to++ = '%';
1448 *to++ = hexDigits[(ch >> 4) & 0x0f];
1449 *to++ = hexDigits[ch & 0x0f];
1450 } else if (ch == 32) {
1451 *to++ = '+';
1452 } else {
1453 *to++ = ch;
1454 } // if
1455 } // while
1456
1457 *to = '\0';
1458
1459 sprintf(interp->result, "%s", buf);
1460
1461 return (TCL_OK);
1462}
1463
1464
1465int SimCmdNeedRest(ARGS)
1466{
1467 int needRest;
1468
1469 if ((argc != 2) && (argc != 3)) {
1470 return (TCL_ERROR);
1471 }
1472
1473 if (argc == 3) {
1474 if (Tcl_GetInt(interp, argv[2], &needRest) != TCL_OK) {
1475 return (TCL_ERROR);
1476 }
1477 NeedRest = needRest;
1478 }
1479
1480 sprintf(interp->result, "%d", NeedRest);
1481 return (TCL_OK);
1482}
1483
1484
1485int SimCmdMultiPlayerMode(ARGS)
1486{
1487 /* This is read-only because it's specified on
1488 the command line and effects how the user
1489 interface is initialized. */
1490
1491 if (argc != 2) {
1492 return (TCL_ERROR);
1493 }
1494
1495 sprintf(interp->result, "%d", MultiPlayerMode);
1496 return (TCL_OK);
1497}
1498
1499
1500int SimCmdSugarMode(ARGS)
1501{
1502 /* This is read-only because it's specified on
1503 the command line and effects how the user
1504 interface is initialized. */
1505
1506 if (argc != 2) {
1507 return (TCL_ERROR);
1508 }
1509
1510 sprintf(interp->result, "%d", SugarMode);
1511 return (TCL_OK);
1512}
1513
1514
1515/************************************************************************/
1516
1517int
1518SimCmd(CLIENT_ARGS)
1519{
1520 Tcl_HashEntry *ent;
1521 int result = TCL_OK;
1522 int (*cmd)();
1523
1524 if (argc < 2) {
1525 return TCL_ERROR;
1526 }
1527
1528 if (ent = Tcl_FindHashEntry(&SimCmds, argv[1])) {
1529 cmd = (int (*)())ent->clientData;
1530 result = cmd(interp, argc, argv);
1531 } else {
1532 result = TCL_ERROR;
1533 }
1534 return result;
1535}
1536
1537
1538sim_command_init()
1539{
1540 int new;
1541
1542 Tcl_CreateCommand(tk_mainInterp, "sim", SimCmd,
1543 (ClientData)MainWindow, (void (*)()) NULL);
1544
1545 Tcl_InitHashTable(&SimCmds, TCL_STRING_KEYS);
1546
1547#define SIM_CMD(name) HASHED_CMD(Sim, name)
1548
1549 SIM_CMD(GameStarted);
1550 SIM_CMD(InitGame);
1551 SIM_CMD(SaveCity);
1552 SIM_CMD(ReallyQuit);
1553 SIM_CMD(UpdateHeads);
1554 SIM_CMD(UpdateMaps);
1555 SIM_CMD(RedrawEditors);
1556 SIM_CMD(RedrawMaps);
1557 SIM_CMD(UpdateEditors);
1558 SIM_CMD(UpdateGraphs);
1559 SIM_CMD(UpdateEvaluation);
1560 SIM_CMD(UpdateBudget);
1561 SIM_CMD(UpdateBudgetWindow);
1562 SIM_CMD(DoBudget);
1563 SIM_CMD(DoBudgetFromMenu);
1564 SIM_CMD(Pause);
1565 SIM_CMD(Resume);
1566 SIM_CMD(StartBulldozer);
1567 SIM_CMD(StopBulldozer);
1568 SIM_CMD(MakeFire);
1569 SIM_CMD(MakeFlood);
1570 SIM_CMD(MakeTornado);
1571 SIM_CMD(MakeEarthquake);
1572 SIM_CMD(MakeMonster);
1573 SIM_CMD(MakeMeltdown);
1574 SIM_CMD(FireBomb);
1575 SIM_CMD(SoundOff);
1576 SIM_CMD(GenerateNewCity);
1577 SIM_CMD(GenerateSomeCity);
1578 SIM_CMD(TreeLevel);
1579 SIM_CMD(LakeLevel);
1580 SIM_CMD(CurveLevel);
1581 SIM_CMD(CreateIsland);
1582 SIM_CMD(ClearMap);
1583 SIM_CMD(ClearUnnatural);
1584 SIM_CMD(SmoothTrees);
1585 SIM_CMD(SmoothWater);
1586 SIM_CMD(SmoothRiver);
1587 SIM_CMD(LoadScenario);
1588 SIM_CMD(LoadCity);
1589 SIM_CMD(SaveCityAs);
1590 SIM_CMD(MakeExplosion);
1591 SIM_CMD(CityName);
1592 SIM_CMD(CityFileName);
1593 SIM_CMD(GameLevel);
1594 SIM_CMD(Speed);
1595 SIM_CMD(Skips);
1596 SIM_CMD(Skip);
1597 SIM_CMD(WorldX);
1598 SIM_CMD(WorldY);
1599 SIM_CMD(Delay);
1600 SIM_CMD(HeatSteps);
1601 SIM_CMD(HeatFlow);
1602 SIM_CMD(HeatRule);
1603#ifdef CAM
1604 SIM_CMD(JustCam);
1605#endif
1606#ifdef NET
1607 SIM_CMD(ListenTo);
1608 SIM_CMD(HearFrom);
1609#endif
1610 SIM_CMD(Funds);
1611 SIM_CMD(TaxRate);
1612 SIM_CMD(FireFund);
1613 SIM_CMD(PoliceFund);
1614 SIM_CMD(RoadFund);
1615 SIM_CMD(Year);
1616 SIM_CMD(AutoBudget);
1617 SIM_CMD(AutoGoto);
1618 SIM_CMD(AutoBulldoze);
1619 SIM_CMD(Disasters);
1620 SIM_CMD(Sound);
1621 SIM_CMD(Flush);
1622 SIM_CMD(FlushStyle);
1623 SIM_CMD(DonDither);
1624 SIM_CMD(DoOverlay);
1625 SIM_CMD(MonsterGoal);
1626 SIM_CMD(HelicopterGoal);
1627 SIM_CMD(MonsterDirection);
1628 SIM_CMD(EraseOverlay);
1629 SIM_CMD(Tile);
1630 SIM_CMD(Fill);
1631 SIM_CMD(DynamicData);
1632 SIM_CMD(ResetDynamic);
1633 SIM_CMD(Performance);
1634 SIM_CMD(CollapseMotion);
1635 SIM_CMD(Update);
1636 SIM_CMD(OverRide);
1637 SIM_CMD(Expensive);
1638 SIM_CMD(Players);
1639 SIM_CMD(Votes);
1640 SIM_CMD(BobHeight);
1641 SIM_CMD(PendingTool);
1642 SIM_CMD(PendingX);
1643 SIM_CMD(PendingY);
1644 SIM_CMD(Displays);
1645 SIM_CMD(LandValue);
1646 SIM_CMD(Traffic);
1647 SIM_CMD(Crime);
1648 SIM_CMD(Unemployment);
1649 SIM_CMD(Fires);
1650 SIM_CMD(Pollution);
1651 SIM_CMD(PolMaxX);
1652 SIM_CMD(PolMaxY);
1653 SIM_CMD(TrafMaxX);
1654 SIM_CMD(TrafMaxY);
1655 SIM_CMD(MeltX);
1656 SIM_CMD(MeltY);
1657 SIM_CMD(CrimeMaxX);
1658 SIM_CMD(CrimeMaxY);
1659 SIM_CMD(CenterX);
1660 SIM_CMD(CenterY);
1661 SIM_CMD(FloodX);
1662 SIM_CMD(FloodY);
1663 SIM_CMD(CrashX);
1664 SIM_CMD(CrashY);
1665 SIM_CMD(Dollars);
1666 SIM_CMD(DoAnimation);
1667 SIM_CMD(DoMessages);
1668 SIM_CMD(DoNotices);
1669 SIM_CMD(Rand);
1670 SIM_CMD(Platform);
1671 SIM_CMD(Version);
1672 SIM_CMD(OpenWebBrowser);
1673 SIM_CMD(QuoteURL);
1674 SIM_CMD(NeedRest);
1675 SIM_CMD(MultiPlayerMode);
1676 SIM_CMD(SugarMode);
1677}
Impressum, Datenschutz