-
Notifications
You must be signed in to change notification settings - Fork 0
/
actors.inf
3048 lines (2914 loc) · 113 KB
/
actors.inf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
! =========== PSI ACTORS =============
! How many directions should be used for pathfinding (1-12)?
! 4, 8, 10 and 12 are reasonable values. (4=only N,S,E,W)
Constant SEARCHNRDIRS=10;
[ MPD_CheckDirection person direction loc dest exitval d;
! return non-zero if possible (directly or through open door(=destination)
! or by opening door first (=-destination)) to go in <direction> from loc
loc=superparent(person);
d=loc.direction;
if(metaclass(d)~=Object) return 0;
if(d ofclass Room) return d;
if(d has door && (dest=d.door_to(loc,true)) ofclass Room){
if(d provides pass_door)
exitval=d.pass_door(person);
else if(d has open)
exitval=dest;
else if(d hasnt locked)
exitval=-dest;
else ! Must be a locked door
if(loc==location)
print "^",(The) person," tries to open ", (the) d,
", only to find it locked.^";
}
return exitval;
];
[ MovePersonDir person dir silent dest;
dest=MPD_CheckDirection(person, dir);
if(dest==true) rtrue; ! The movement succeeded, but we shall print nothing
Comments.make_busy(person);
if(dest) {
! print "YES! dest=",dest,"!^";
if(silent==false && TestScope(person)) {
if(dest<0)
print "^",(The) person," opens ",(the) superparent(person).dir,".^";
else
print "^",(The) person," walks ", (address) (dir.&name)-->1, ".^";
}
if(dest>0) {
move person to dest;
} else {
if(person ofclass Walker)
person.mission_substep--;
give parent(person).dir open;
! move person to -dest;
rtrue;
}
if(silent==false && TestScope(person)) {
if(person provides introduction && person.introduction(true)) return true;
else print "^",(The) person," appears.^";
}
rtrue;
}
! print "NO! dest=",dest,"!^";
rfalse;
];
[ SelectMission person t n i r nonnil;
if(person.mission_queue>0) {
r=person.mission_queue;
person.mission_queue=-1;
}
else {
t=person.#mission_list/2;
n=0; ! *** Sum of the weight of all possible missions
for(i=0:i<t:i=i+2)
if(person.&mission_list-->i>0 &&
person.&mission_list-->i~=person.last_mission)
nonnil++;
for(i=0:i<t:i=i+2)
if(person.&mission_list-->i &&
((person.&mission_list-->i)~=person.last_mission || nonnil==1))
n=n+person.&mission_list-->(i+1);
if(n==0) {
! print "^",(The) person,i," starts to walk but stops again.^";
rtrue;
}
r=random(n);
! print (The) person,": Vald vikt: ",r," av totalt ",n," foerdelat paa ",
! nonnil," uppdrag.^";
for(i=0:i<t:i=i+2)
if((person.&mission_list-->i)~=person.last_mission || nonnil==1)
if((r=r-person.&mission_list-->(i+1))<1) break;
r=person.&mission_list-->i;
}
! print (The) person, " chooses mission ",r,"!^";
person.mission_nr=r;
person.last_mission=r;
person.mission_step=Mission_index-->r+1;
person.mission_substep=-1;
person.path_nr=-1;
];
[ EnqueueMission person mission;
! print (The) person, ": plans to do mission ",mission," soon!^";
person.mission_queue=mission;
];
Constant misTalkToHenkel 10;
Constant misResearch 11;
Constant misSnack 12;
Constant misGotoWilliams 13;
Constant misReadBook 14;
Constant misGotoLoo 15;
Constant misGotoCellarStore 16;
Constant misGotoKitchen 17;
Constant misGotoSchwartz 18;
Constant misGotoJohn 19;
Constant misGotoJohnSelf 20;
Constant misGotoPetra 21;
Constant misGotoPetraSelf 22;
Constant Max_mission_tries 3;
Constant actGoTo 1;
Constant actWaitTurns 2;
Constant actClose 3;
Constant actLock 4;
Constant actUnlock 5;
Constant actPushOutAndClose 6;
Constant actLeaveStore 7;
Array Missions table
[; 0;
misTalkToHenkel;
actGoTo Entrance;
actWaitTurns 2 5;
0;
misResearch;
actGoTo NLab;
actWaitTurns 3 7;
0;
misSnack;
actGoTo Kitchen;
actWaitTurns 6 7;
actGoTo Dinnerhall;
actWaitTurns 6 8;
0;
misGotoWilliams;
actGoTo WilliamsOffice;
actWaitTurns 1 3;
0;
misGotoSchwartz;
actGoTo Office1;
actWaitTurns 1 4;
0;
misGotoJohn;
actGoTo JohnsOffice;
actWaitTurns 2 4;
0;
misGotoJohnSelf;
actGoTo JohnsOffice;
actWaitTurns 3 7;
0;
misGotoPetra;
actGoTo PetrasOffice;
actWaitTurns 2 4;
0;
misGotoPetraSelf;
actGoTo PetrasOffice;
actWaitTurns 3 7;
0;
misReadBook;
actGoTo Library;
actWaitTurns 5 8;
0;
misGotoLoo;
actGoTo Bathroom;
actPushOutAndClose;
actLock BathroomDoor;
actWaitTurns 2 8;
actUnlock BathroomDoor;
0;
misGotoCellarStore;
actGoTo CellarStore;
actWaitTurns 8 10;
actLeaveStore;
0;
misGotoKitchen;
actGoTo Kitchen;
0;
$ffff;
];
Array Mission_index table 100;
Constant USEPATHTIMES 7;
Constant PATHSTOSTORE=40;
Constant PATHINDEXWORDS=5;! From, To, LastUsed, TimesUsed, SearchID
Constant PATHINDEXSIZE=PATHINDEXWORDS*PATHSTOSTORE;
Constant PATHMAXLENGTH=23; ! Including a trailing zero
Constant PATHSPACESIZE=(PATHMAXLENGTH+1)*PATHSTOSTORE;
Array Path_index-->PATHINDEXSIZE;
Array Paths->PATHSPACESIZE;
Constant MAXQ 100;
Array SearchQ --> MAXQ;
global SearchID;
global StartQ;
global EndQ;
[ FindPath a b act actloc i n k to d go z store p length;
! Finds the nearest path from a to b, handling closed but not locked doors
! of class AutoDoor. Can handle arbitrarily long paths. If PATHSTOSTORE
! is less than the number of actors simultaneously following paths, the
! program gets slow, but still works correct, assuming that the actors do
! the mandatory path ID verification every turn.
! Uses breadth-first searching with a queue, and stores and retrieves the
! PATHSTOSTORE most recently used paths. The path number and id is put in
! the path-related properties of the object act. (usually an actor).
! Notes: If there is no possible path, or the nearest path between the two
! rooms is longer than PATHMAXLENGTH - 1, or the queue gets full, the
! routine will not find a path, and return true.
! Paths that are found obsolete by the NPC:s are discarded using KillPath(n)
#IFDEF DEBUG;
if(PathInfo)
{
print "^Searching for a path for ",(name) act," from ",
(name) a, " to ", (name) b, ".^";
print "State before searching:^";
for(k=0:k<PATHSTOSTORE:k++)
print "Path #",k, " from ",(name) Path_index-->k, " to ",
(name) Path_index-->(k+PATHSTOSTORE), ". Used ",
Path_index-->(k+3*PATHSTOSTORE)," times, last: ",
Path_index-->(k+2*PATHSTOSTORE),".^";
}
#ENDIF;
if((a ofclass Room)==false || (b ofclass Room)==false) {
#IFDEF DEBUG;
if(PathInfo)
print "The Startlocation and/or Destination is not of class Room!^";
#ENDIF;
rtrue;
}
! 'store' holds the oldest path this far, k holds the turn it was used
! z holds the found path
k=turns+1;
store=-1;
z=-1;
for(i=0:i<PATHSTOSTORE:i++)
{
if(Path_index-->(i+3*PATHSTOSTORE)>=USEPATHTIMES)
KillPath(i);
else if(act~=player) ! Never use stored path for player
if(Path_index-->i==a && Path_index-->(i+PATHSTOSTORE)==b)
{
z=i;
break;
}
if(Path_index-->(i+2*PATHSTOSTORE)<k)
{
store=i;
k=Path_index-->(i+2*PATHSTOSTORE);
}
}
#IFDEF DEBUG;
if(PathInfo)
{
if(z>=0)
print "Retrieved the wanted path from slot #",z,"!^";
else
{
if(store>=0)
print "The oldest path is in slot #",store,".^";
else
print "Serious error: None marked as oldest, none found!^";
}
}
#ENDIF;
if(z>=0) ! Give the actor info about the path he is on, and return
{
Path_index-->(z+2*PATHSTOSTORE)=turns; ! Update the last use of path.
(Path_index-->(z+3*PATHSTOSTORE))++; ! Update the number of times used.
act.path_nr=z; ! Lets the actor remember what path he is on...
act.path_id=Path_index-->(z+4*PATHSTOSTORE); ! ...and its SearchID
rfalse; ! All OK, returning
}
! *** The sought path was not in store, so we have to find it, and store it.
if(store<0) store=0; ! This condition should never be true!!!
! temploc=location; ! To be able to restore 'location' if we change it.
if(++SearchID>255)
{
SearchID=1;
objectloop(i ofclass Room)
i.path_id=0;
}
StartQ=0;
EndQ=1;
z=0;
SearchQ-->StartQ=a;
actloc=superparent(act);
length=0;
a.path_id=SearchID;
a.path_length=length;
a.path_from=0;
a.path_dir=0;
.scan;
if(++n>200) { ! Any value higher than the number of legal rooms
! location=temploc;
"ERROR: Too many nodes! Call the programmer!!!^^^";
}
if(StartQ==EndQ) {! The Q is empty or full. If it is full, the Q is too small
! location=temploc;
#IFDEF DEBUG;
if(PathInfo)
"There is no path!!!^^^";
#ENDIF;
rtrue;
}
i=SearchQ-->StartQ;
if(StartQ++>MAXQ) StartQ=0;
if(i==b)
{ ! Maalnoden naadd!!!
i=store*PATHMAXLENGTH+b.path_length;
Paths->(i--)=0; ! Marks the end of the path
k=b;
while(k~=a)
{
Paths->(i--)=k.path_dir;
k=k.path_from;
}
Path_index-->(store)=a;
Path_index-->(store+PATHSTOSTORE)=b;
Path_index-->(store+2*PATHSTOSTORE)=turns; ! Update the last use of path.
Path_index-->(store+3*PATHSTOSTORE)=1; ! Set the number of times used.
Path_index-->(store+4*PATHSTOSTORE)=SearchID; ! Set the SearchID of path
act.path_nr=store; ! Lets the actor remember what path he is on...
act.path_id=SearchID; ! ...and its SearchID
#IFDEF DEBUG;
if(PathInfo)
{
print "Found a ",b.path_length," node(s) long path, checking ",n,
" nodes, ",z," directions and ",p,
" doors. The path was stored in slot #",store,".^";
to=a;
print "Path: ";
for(k=store*PATHMAXLENGTH: Paths->k>0: k++)
{
d=to;
to=to.(Paths->k);
print (address) (Paths->k).&name-->1;
if(to has door)
{
print " through door #",to;
to=to.door_to(d,true); ! Fake location and keep quiet
}
if(to~=b)
print ", ";
}
print ".^";
}
#ENDIF;
rfalse;
}
if(i.path_id~=SearchID)
"MAJOR SYSTEM ERROR!!!^^^"; ! Noden haar ej markerats som besoekt
if((length=i.path_length+1)>=PATHMAXLENGTH)
jump scan; ! Entering this node would mean a too long path.
for(d=7: d<7+SEARCHNRDIRS: d++)
{
z++;
go=0;
if((to=i.d) ofclass Room && to.path_id~=SearchID &&
(act~=player || to has visited))
go=1;
else if((to ofclass AutoDoor) && ! Try to pass doors that are either
(i~=actloc || to hasnt locked || ! out of sight or unlocked, or say
(to provides pass_door && to.pass_door(act,true)))) ! it's OK.
{
p++;
to=to.door_to(i,true);
if((to ofclass Room) && to.path_id~=SearchID &&
(act~=player || to has visited))
go=1;
}
if(go)
{
to.path_id=SearchID;
to.path_from=i;
to.path_dir=d;
to.path_length=length;
SearchQ-->EndQ=to;
if(EndQ++>MAXQ) EndQ=0;
}
}
jump scan;
];
[ KillPath x;
if(x<0 || x>=PATHSTOSTORE)
rtrue;
Path_index-->x=0;
Path_index-->(x+PATHSTOSTORE)=0;
Path_index-->(x+2*PATHSTOSTORE)=0;
Path_index-->(x+3*PATHSTOSTORE)=0;
Path_index-->(x+4*PATHSTOSTORE)=0;
];
Class Talker
with
present 0,
available 0,
silent 0;
Class Walker class Talker
with
speed 100,
mission_list 0 0,
mission_nr -1,
mission_queue -1,
last_mission -1,
last_substep -1,
same_substep_turns 0,
mission_action -1,
mission_step -1,
mission_substep -1,
mission_waitturns -1,
path_nr -1,
path_id -1,
freeze_one_turn false,
followpath false,
pathdest 0,
domission true,
daemon_running false, ! To remember if the daemon was running before walk
startup [;
self.daemon_running=true;
StartDaemon(self);
],
shutdown [;
self.daemon_running=false;
StopDaemon(self);
],
endofpath [;
self.followpath=false;
self.mission_nr=-1;
self.mission_action=-1;
if(self.daemon_running==false)
StopDaemon(self);
rtrue;
],
move [ dir;
return MovePersonDir(self,dir);
],
daemon [;
if(self.freeze_one_turn) {
self.freeze_one_turn=false;
rtrue;
}
if(self.followpath) {
! print (The) self, " is walking...^";
self.walk();
}
else {
if(self.domission) {
! print "Missioning...^";
if(self.pursuemission()==true)
self.mission_nr=-1;
}
}
],
walk [ dest exitval;
dest=self.pathdest;
if(self in dest) {
self.endofpath();
rfalse;
}
else {
self.mission_nr=1;
self.mission_action=actGoTo;
exitval=(self.pursuemission());
if(exitval==true && self~=player && TestScope(self) &&
self.same_substep_turns<4) {
Comments.make_busy(self);
print "^",(The) self," sighs deeply and says ~I'm sorry, I can't \
stand around here all day. Got work to do, you know.~^";
}
if(self in dest || exitval==true)
self.endofpath();
}
],
pursuemission [ r destination eatsteps did_something laps;
! Returns true if it fails to do anything
if(self.mission_action==actGoTo && random(100)>self.speed) rfalse;
laps=0;
do {
did_something=true;
if(self.mission_nr<1 || self.mission_nr>Mission_index-->0) {
! print "Selecting new mission at beginning!^";
! print "Current: ",self.mission_nr," of ",Mission_index-->0,"^";
SelectMission(self);
}
! print (The) self, " has selected mission ",self.mission_nr,"!^";
eatsteps=0;
if(self.followpath)
self.mission_action=actGoTo;
else
self.mission_action=Missions-->self.mission_step;
! print "^",(The) self," does action ",self.mission_action,".^";
switch(self.mission_action) {
actGoTo:
if(self.followpath)
destination=self.pathdest;
else
destination=Missions-->(self.mission_step+1);
! print (The) self, " wants to go to ", (name) destination,".^";
if(self in destination) {
self.path_nr=-1;
eatsteps=2;
did_something=false;
! print "On target!!!^";
}
else {
if(self.path_nr>=0 &&
(self.path_id==Path_index-->(self.path_nr+4*PATHSTOSTORE)) &&
Paths->self.mission_substep>0)
{
! *** Is on a path that has not been overwritten, is not at EOP
if(self.move(Paths->(self.mission_substep++))==false) {
#IFDEF DEBUG;
if(PathInfo)
print (The) self," tries to go in direction ",
Paths->(self.mission_substep-1),
" but fails.^";
#ENDIF;
KillPath(self.path_nr); ! The world has changed--path no good
did_something=false;
}
}
else {
! *** Doesn't have a place to go. Either he has never had a path,
! *** or the path has been overwritten, or the environment has
! *** changed. In any case, find a path!
if(self.path_nr>=0 &&
self.path_id==Path_index-->(self.path_nr+4*PATHSTOSTORE))
! *** The path exists but ends up in the wrong place
KillPath(self.path_nr);
if(FindPath(parent(self), destination, self)==0)
! *** Found a path
self.mission_substep=self.path_nr*PATHMAXLENGTH;
else
self.mission_nr=-1; ! *** Didn't find a path
did_something=false;
}
}
jump EndSwitch;
actClose:
r=Missions-->(self.mission_step+1);
if(r has door && r has open) {
give r ~open;
if(TestScope(r)) {
Comments.make_busy(self);
print "^",(The) self," closes ",(the) r,".^";
}
}
else
did_something=false;
eatsteps=2;
actLock:
r=Missions-->(self.mission_step+1);
if(r has door) {
if(r has open) {
if(TestScope(r)) {
Comments.make_busy(self);
print "^Looking rather irritated, ",(the) self,
" closes and locks ", (the) r,".^";
}
}
else {
if(r hasnt locked) {
if(TestScope(self)) {
Comments.make_busy(self);
print "^",(The) self, " locks ",(the) r,".^";
}
else
if(TestScope(r))
print "^A click is heard from ",(the) r,".^";
}
else
did_something=false;
}
give r ~open;
give r locked;
eatsteps=2;
}
else
did_something=false;
actUnlock:
r=Missions-->(self.mission_step+1);
if(r has door) {
if(r has locked) {
if(TestScope(self)) {
Comments.make_busy(self);
print "^",(The) self, " unlocks ",(the) r,".^";
}
else
if(TestScope(r))
print "^A click is heard from ", (the) r,".^";
}
else
did_something=false;
give r ~locked;
}
else
did_something=false;
eatsteps=2;
actPushOutAndClose:
did_something=false;
objectloop(r has animate && r in Bathroom && r~=player && r~=self) {
MovePersonDir(r,n_to);
did_something=true;
}
if(TestScope(self)) {
Comments.make_busy(self);
if(BathroomDoor hasnt open)
print "^",(The) self," opens the door again and urges you to \
leave.^";
else
print "^",(The) self," says ~Do you mind?~ and pushes you out \
into the corridor.^";
PlayerTo(Corridor12,2);
did_something=true;
}
if(BathroomDoor has open) {
give BathroomDoor ~open;
did_something=true;
if(location==Corridor12) {
Comments.make_busy(self);
print "^",(The) self," closes ",(the) BathroomDoor,".^";
}
}
eatsteps=1;
actLeaveStore:
if(self in CellarStore) {
objectloop(r has animate && r in CellarStore &&
r~=player && r~=self){
MovePersonDir(r,n_to);
give HeavyDoor open;
}
if(location==CellarStore) {
Comments.make_busy(self);
print "^~All right, time to leave!~ says ",(the) self,", \
and waits behind to turn out the lights as you leave \
the room.^";
PlayerTo(CCorridorI,2);
give HeavyDoor open;
}
if(HeavyDoor.pass_door(self) ofclass Room) {
give HeavyDoor open;
MovePersonDir(self,n_to,true);
}
r=0;
if(Candle in BoltPocket && Candle hasnt general) r=Candle;
if(Soap in BoltPocket && Soap hasnt general) r=Soap;
if(r>0) {
move r to CCorridorI;
give HeavyDoor locked;
}
if(location==CCorridorI) {
Comments.make_busy(self);
print "^",(The) self," releases ",(the) HeavyDoor;
if(r>0)
print " but it won't close. ", (The) self,
" finds ", (the) r, " in the bolt pocket \
and throws it on the ground.";
else print ", which swings shut.";
if(HeavyDoor has locked)
print " A click is heard from the door.^";
else
new_line;
}
did_something=true;
eatsteps=1;
}
else {
did_something=false;
eatsteps=1;
}
actWaitTurns:
if(self.mission_substep<0) {
r=Missions-->(self.mission_step+1)+
random(Missions-->(self.mission_step+2)-
Missions-->(self.mission_step+1)+1)-1;
self.mission_waitturns=r;
self.mission_substep=r;
}
else if(--(self.mission_substep)<1) {
eatsteps=3;
}
default:
#IFDEF DEBUG;
if(PathInfo)
print (The) self, " yells for daddy on step ",
self.mission_step, ".^";
#ENDIF;
self.mission_nr=-1;
did_something=false;
.EndSwitch;
}
if(self.followpath==false) {
! print "Mission step: ",self.mission_step;
! print " Next mission step: ",self.mission_step+eatsteps,"^";
self.mission_step=self.mission_step+eatsteps;
if(eatsteps~=0) self.mission_substep=-1;
if(Missions-->self.mission_step==0) {
! *** Mission finished
! print "Finished!!!^";
self.mission_nr=-1;
}
}
} until (did_something || ++laps>Max_mission_tries);
if(self.mission_nr>0 && self.mission_action==actGoTo) {
if(self.last_substep==self.mission_substep) {
if(++self.same_substep_turns>3 && self~=player) {
if(self.same_substep_turns==4)
if(TestScope(self)) {
Comments.make_busy(self);
print "^~You're sort of childish, you know that?~ says ",
(the) self,".^";
}
rtrue;
}
else if(self.same_substep_turns>1 && self==player) {
give tw_waiting on; ! To stop the automatic walk
rtrue;
}
}
else
self.same_substep_turns=0;
}
self.last_substep=self.mission_substep;
if(laps>Max_mission_tries) {
#IFDEF DEBUG;
print "^DEBUG: ",(The) self," has freaked out on mission#",
self.mission_nr,", step#", self.mission_step,"!^";
#ENDIF;
self.mission_nr=-1;
rtrue;
}
else
rfalse;
];
Walker PlayerObject "yourself"
with number 0, after $ffff, life $ffff,
time_out $ffff,
describe $ffff, capacity MAX_CARRIED,
parse_name 0, short_name 0, orders 0,
! Above is standard, below follows new definitions of the player object
name "i",
dirty false,
absorbed_radiation 0,
castle_trespass 0,
ufo_delay 2,
move [ dir;
print "^>go ",(address) dir.&name-->1,"^";
<<Go dir>>;
! PlayerTo(dest,2);
],
endofpath [;
self.Walker::endofpath();
give tw_waiting on;
],
check_water [x;
if(x ofclass Water)
player.waterquant=player.waterquant+x.quantity;
],
waterquant 0,
description [x i;
if(self.dirty)
"You are quite dirty after climbing the chimney.";
i=false; objectloop(x in self && x has worn) i=true;
if(i==false) "You are a responsible father and husband, \
not a porn star. Put on some clothes!";
print "You've looked worse";
if(location<Road)
", but the day has just begun.";
if(location<CabinHall2)
". You have an unpleasant hunch this may change during the day.";
if(IronDoor has open)
". Not much though.";
".";
],
showknife [p;
if(StuckKnife has general) "Some people learn from their mistakes. You don't.";
move StuckKnife to location;
remove Knife;
print_ret (The) p, " takes the knife and throws it \
up into the air, catching it again without even \
looking. Then ", (PronounNom) p, " suddenly throws \
the knife at the wall right next to you, where it digs \
deep into the wood. ~I guess there are a lot of things \
you don't know about me,~ ", (PronounNom) p, " laughs.";
],
! This react_before disambiguates the players movements, and
! checks special scope rules in the cableway station.
react_before [near_cabin;
near_cabin=TestScope(Cabin);
Threaten:
if(second==Knife && noun==Williams or Petra or John or Schwartz) {
self.showknife(noun);
rtrue;
}
Show:
if(noun==Knife && second==Williams or Petra or John or Schwartz) {
self.showknife(second);
rtrue;
}
ThrowAt:
if(near_cabin) return self.cabin_react_before(false, true);
if(noun==Knife && second==Williams or Petra or John or Schwartz) {
self.showknife(second);
rtrue;
}
MyRemove, Take:
if(near_cabin) {
if(player in CabinLadder && noun==d_obj) <<GetOff CabinLadder>>;
if(noun==Bow && Bow in CabinRoof && player in location) rfalse;
return self.cabin_react_before();
}
PutOn:
if(near_cabin) {
if(noun==Bow && second==CabinRoof && player in location) rfalse;
return self.cabin_react_before();
}
Ask, Tell, Examine:
if(near_cabin) rfalse;
Listen:
if(near_cabin) rfalse;
if(noun==0 && car has on && car in location)
"All you hear is the dreadful sound of the car stereo.";
if(player in OuterLivingRoom && Dog in Terrace && TerraceWindow hasnt open)
rtrue;
Drop:
if(metaclass(noun)~=Object) rfalse;
if(player in LowerWire) <<PutOn noun LowerWire>>;
if(player in UpperWire) <<PutOn noun UpperWire>>;
if(player in CabinLadder) <<PutOn noun CabinLadder>>;
if(near_cabin) return self.cabin_react_before();
GetOff:
if(player in LowerWire && noun==0) <<GetOff LowerWire>>;
if(player in UpperWire && noun==0) <<GetOff UpperWire>>;
if(player in CabinRoof && noun==0) <<GetOff CabinRoof>>;
if(player in CabinLadder && noun==0) <<GetOff CabinLadder>>;
if(near_cabin) return self.cabin_react_before();
Jump:
if(player in LowerWire && (noun==d_obj || noun==0)) <<GetOff LowerWire>>;
if(player in UpperWire && (noun==d_obj || noun==0)) <<GetOff UpperWire>>;
if(near_cabin) return self.cabin_react_before();
if(TestScope(SmokeDetector)) "You still can't reach the smoke detector.";
Go:
if(metaclass(noun)~=Object) rfalse;
if(player in LowerWire) {
if(noun==d_obj) <<GetOff LowerWire>>;
if(noun==n_obj) <<Go LowerWire>>;
if(noun~=LowerWire) "By flying? You'd better step down from the wire first.";
}
if(player in UpperWire) {
if(noun==d_obj) <<GetOff UpperWire>>;
if(noun==s_obj) <<Go UpperWire>>;
if(noun~=UpperWire) "By flying? You'd better step down from the wire first.";
}
if(player in CabinRoof) {
if(noun==d_obj) <<GetOff CabinRoof>>;
"You have to get off the cable car roof first.";
}
if(player in CabinLadder) {
if(noun==d_obj) <<GetOff CabinLadder>>;
if(noun==u_obj) <<Climb CabinLadder>>;
"This ladder has two main directions, up and down.";
}
if(player in Cabin) {
if(noun==u_obj) <<Climb CabinLadder>>;
"You have to leave the cable car first.";
}
if(near_cabin) return self.cabin_react_before();
Exit:
if(player in car && noun==0) <<Exit Car>>;
if(player in car && noun==Car) {
if(Car has on) {
print "(turning off the car engine first)^^";
give Car ~on;
}
if(Car hasnt open) {
print "(opening the car door first)^^";
give Car open;
}
}
if(player in LowerWire && noun==0) <<GetOff LowerWire>>;
if(player in UpperWire && noun==0) <<GetOff UpperWire>>;
if(player in CabinRoof && noun==0) <<GetOff CabinRoof>>;
if(player in CabinLadder && noun==0) <<GetOff CabinLadder>>;
if(player in Cabin) {
if(Cabin.number==2 or 19) {
print "The cable car is still in the terminal, about to start. \
Are you sure you want to leave it now?^^>>";
if(YesOrNo()==false) {
META=1;
rtrue;
}
}
}
if(near_cabin) return self.cabin_react_before();
default:
if(near_cabin) return self.cabin_react_before();
],
cabin_react_before [x y;
if(CabinReachable(noun, true, x)==false) rtrue;
if(CabinReachable(second, true, y)==false) rtrue;
rfalse;
],
react_after [;
Exit:
if(noun==Car) {
if(Car has open) {
print "(closing the car door)^^";
give Car ~open;
}
}
],
before [x y;
#IFDEF DEBUG;
Burn:
print "[~burn me~ changed for debugging only]^";
META=1;
print "^---BEGINNING OF NEW COMMENTS---";
Comments.make_comments();
"^------END OF NEW COMMENTS------";
#ENDIF;
Take: "Nice try.";
Ask, Tell, Answer: