-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSTC-TorD FM 1.9.muf
1001 lines (936 loc) · 41.1 KB
/
STC-TorD FM 1.9.muf
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
( STC-TorD.muf -FUZZBALL- v1.9F, by Stelard Actek of StelTechCor @ FurryMUCK!
What can I say? One day, my second favourite place to hang out on Furry was
suddenly gone. The Palace of the Dragons' Truth or Dare pools have held a
special place in my heart for a long time. True, of late, I've not had much
fun there, due to a worrying streak of unoriginality and limpness among the
players, but still. A friend told me a coalition of furs had taken it upon
themselves to create a replacement area. The new command set I found there
was just close enough to the old one to be maddening, and missing some
features. Hence this, my solution, rendered in lovely Multiple User Forth.
Right, that's enough of that. To set the program up, simply create an action.
Anywhere, on anything. It can be a room or an object, or even yourself, but
the latter makes no sense unless you want to be the only person to play it.
Name your action [wait for it... *^.^*]
'Q;A;D;AOK;DOK;TIMER;PICK;HISTORY;SPIN;GRAB;RESET;RESTART;STATUS;ISWEEP;BOOT',
and link it to this program.
Now, that used to be it, but since the code enabling the two newest commands
-- ISWEEP and BOOT -- rely on the players and their homes being set JUMP_OK,
some steps need to be taken to ensure that all people in the playing area can
be idle swept and booted from the game if nessisary. To this end, you will
have to lock your newly created action and the entrace to the Truth or Dare
room [if you have one, that is] with a program which tests the JUMP_OK flag on
players and their homes. On FurryMUCK, Sweepable?.muf should be listed under
the PROGRAMS command.
Also, if you don't like the reminder delay being set to 5 minutes, set the
_RemindDelay property on your question to a STRING VALUE of the number of
minutes you want between game reminders. Decimals and values below 1 are not
acceptable.
That's it! This program stores all it's data on the action, so porters make
sure the program is set HARDUID.
The status of the game is stored on the action, so make sure that if you're
going to have several rooms setup like this, you have separate action sets
for each room. Also, for the same reasons, don't split the action up. Make
it one action, as above.
Last notes:
This is a final release. As far as I know, there are no bugs left. Though,
as they say, a program without bugs is one that hasn't crashed in a while.
If you have a problem, either page mail Stelard @ FurryMUCK! or email
[email protected]. Remeber to tell me WHAT you were doing, not
just the error message!
Uses:
lib/ansify
lib/dbidle
lib/look
.confirm
.tell
)
( @set <ref>=_docs:@list <ref>=1-54 )
lvar arg
lvar start-remind
$include ($lib/ansify) #85365 (on FM)
$include ($lib/dbidle) #142709 (on FM)
$include $lib/look
$ifdef __version<Muck2.2fb6.00
$abort Designed to compile only under Fuzzball 6.00b4 or greater!
$endif
$version 1.9
$def TD_Version "1.9F"
$def TD_PLastVer "STC-TorD"
$def TD_Def_Remind_Delay 5 (Default number of minutes to wait before)
(reminding the player with the question.)
$def TD_Def_Idle 5 (Default number of minutes a player may be)
(idle before they can be idle swept.)
$def TD_STATE_P 8
$def TD_STATE_Q 16
$def TD_STATE_A 32
$def TD_STATE_AOK 64
$def TD_PPlayer "_CurPlayer"
$def TD_PTarget "_CurTarget"
$def TD_PQuestion "_CurQuestion"
$def TD_PAnswer "_CurAnswer"
$def TD_PDarees "_CurDarees"
$def TD_PDares "_CurDares"
$def TD_PQCount "_QCount"
$def TD_PLastQ "_LastQ"
$def TD_PLastPlayer "_LastPlayer"
$def TD_PDareTargets "_DareTargets"
$def TD_PRemindDelay "_RemindDelay"
$def TD_PRemindOn? "_Reminders?"
$def TD_PVoteRemindY "_Reminders?/Yes"
$def TD_PVoteRemindN "_Reminders?/No"
$def TD_DDares "_CurDares/"
$def TD_DLastQ "_LastQ/"
$def TD_DDareTargets "_DareTargets/"
$def TD_DBootVotes "_BootVotes/"
: safematch ( s -- d )
dup not if pop #-1 else match then
;
: yes? ( s -- b )
dup "y" instring
swap "on" instring
or
;
: btos ( b -- s )
if "~&170ON" else "~&170OFF" then
;
: first_room ( d -- d )
begin
dup room? not while
location
repeat
;
: notify_room ( s -- )
trigger @ first_room #-1 rot ansi-notify-except
;
: pzafilter ( d -- b )
dup ok? if
dup player? over "Z" flag? or if
awake?
else
pop 0
then
else
pop 0
then
;
: pzanfilter ( d -- b )
dup ok? if
dup player? over "Z" flag? or if
dup me @ dbcmp not if
awake?
else
pop 0
then
else
pop 0
then
else
pop 0
then
;
: char-strip ( s -- s )
" " "!" subst
" " "?" subst
" " "." subst
" " "," subst
" " ";" subst
" " ":" subst
" " " " subst
;
: set-target ( d -- )
trigger @ TD_PTarget rot setprop
;
: set-daree ( d -- b )
trigger @ TD_PDarees 3 pick reflist_find if
0 exit
then
trigger @ TD_DDareTargets me @ intostr strcat 3 pick setprop
trigger @ TD_PDarees 3 pick reflist_add
trigger @ TD_DDares rot intostr "/Darer" strcat strcat me @ setprop
1
;
: get-targetstr ( -- s )
trigger @ TD_PTarget getprop dup dbref? if
name
else
pop "?"
then
;
: get-playerstr ( -- s )
trigger @ TD_PPlayer getprop dup dbref? if
name
else
pop "?"
then
;
: game-state ( -- i )
trigger @ TD_PTarget getprop dbref? not if
TD_STATE_P
else
trigger @ TD_PQuestion getpropstr not if
TD_STATE_Q
else
trigger @ TD_PAnswer getpropstr not if
TD_STATE_A
else
TD_STATE_AOK
then
then
then
;
lvar RemindDelay
: remind-loop ( -- )
trigger @ TD_PRemindOn? getpropval not if exit then
game-state
me @ location
trigger @ TD_PPlayer getprop
trigger @ TD_PRemindDelay getpropstr atoi dup 1 < if pop TD_Def_Remind_Delay then 60 * RemindDelay !
background
begin
RemindDelay @ sleep
dup pzafilter (player still awake, still player or zombie)
over trigger @ TD_PPlayer getprop = and (still player's turn)
me @ location 4 pick = and (i'm still in the t|d area)
game-state dup 6 pick = rot and (game is still in the same state. i.e. no questions asked/answered)
'pzanfilter me @ location .contents-filter array_make array_count 0 > and (i'm not the only one here)
trigger @ TD_PRemindOn? getpropval and (reminders are still on)
while
dup TD_STATE_P = if
"~&150<> " get-playerstr " needs to pick a questionee." strcat strcat notify_room pop
else
dup TD_STATE_Q = if
"~&150<> " get-playerstr " needs to ask a question." strcat strcat notify_room pop
else
TD_STATE_A = if
"~&150<> " get-targetstr " needs to answer the question." strcat strcat notify_room
else
"~&150<> " get-playerstr " hasn't accepted " get-targetstr "'s answer." strcat strcat strcat strcat notify_room
then
then
then
repeat
;
: parse-pose ( s -- s )
dup if
dup ansi_strlen 3 > if
dup strip "'" 1 strncmp not if
dup 4 ansi_strcut pop " " instr not if " " swap strcat then
then
then
". ,':!?-"
over strip 1 ansi_strcut pop instr not if " " swap strcat then
then
me @ name me @ "_prefs/prepose" getpropstr strcat swap strcat
;
: ask-question ( s -- )
dup 1 ansi_strcut swap ":" strcmp not if
swap pop parse-pose
else
pop me @ name " asks, \"~&170" strcat swap "~&160\"" strcat strcat
then
"~&150<> (" me @ name " asks " get-targetstr ") ~&160" 6 pick
strcat strcat strcat strcat strcat notify_room
trigger @ TD_PQuestion rot setprop
;
: give-dare ( s -- )
dup 1 ansi_strcut swap ":" strcmp not if
swap pop parse-pose
else
pop me @ name " dares, \"~&170" strcat swap "~&160\"" strcat strcat
then
trigger @ TD_DDareTargets me @ intostr strcat getprop
"~&150<> (" me @ name " dares " 4 pick dup dbref? if name else pop "?" then ") ~&160" 7 pick
strcat strcat strcat strcat strcat notify_room
trigger @ TD_DDares rot intostr "/Dare" strcat strcat rot setprop
;
( --------------------------------------------------------------------------- )
: prog-Q ( -- )
0 start-remind !
arg @ not if
trigger @ TD_PQuestion getpropstr dup not if
pop "~&150<> " get-playerstr " hasn't asked a question yet." strcat strcat ansi-tell
else
"~&150<> (" get-playerstr " asked " get-targetstr ") ~&160" 6 rotate
strcat strcat strcat strcat strcat ansi-tell
then
exit
then
trigger @ TD_PPlayer getprop dup dbref? if
me @ dbcmp not if
"~&150<> You can't ask a question until it is your turn!" ansi-tell
exit
then
else
pop "~&150<> You need to restart the game. Type ~&170RESTART~&150." ansi-tell
exit
then
arg @ "=" instr if
arg @ "=" split swap dup not if
"~&150<> You need to specify a player to question before that = sign." ansi-tell
exit
then
safematch dup pzanfilter if ( A player=question situation )
game-state TD_STATE_Q <= if start-remind ++ then
set-target
ask-question
else
pop
"~&150<> You can't ask someone who isn't here, is asleep, or doesn't exist." ansi-tell
then
else
arg @ " " instr if ( More than one word parameter )
trigger @ TD_PTarget getprop dbref? not if
arg @ char-strip " " explode
1 - swap safematch dup pzanfilter if (First word?)
set-target
else
pop 1 - dup 2 + rotate safematch dup pzanfilter if (Last word?)
set-target
else
pop begin (Other words?)
dup 0 = not while
1 - swap safematch dup pzanfilter if
set-target
else
pop
then
repeat
then
then
then
game-state TD_STATE_Q <= if start-remind ++ then
arg @ ask-question
else
arg @ safematch dup pzanfilter if ( The one word is a player name )
"~&150<> " me @ name " directs the question to " 4 pick name "." strcat strcat strcat strcat notify_room
game-state TD_STATE_P <= if start-remind ++ then
set-target
else ( The one word is a question )
game-state TD_STATE_Q <= if start-remind ++ then
arg @ ask-question
then
then
then
start-remind @ if remind-loop then
;
: prog-OK ( s -- )
"A" stringcmp not if
"~&150<> (" me @ name " accepts " get-targetstr "'s answer) ~&160" strcat strcat strcat strcat
arg @ dup if
dup 1 ansi_strcut swap ":" strcmp not if
swap pop parse-pose
else
pop me @ name " says, \"~&170" strcat swap "~&160\"" strcat strcat
then strcat
else
pop
then notify_room
game-state
trigger @ TD_PTarget getprop dup trigger @ TD_PPlayer rot setprop
trigger @ TD_PTarget remove_prop
trigger @ TD_PQuestion remove_prop
trigger @ TD_PAnswer remove_prop
trigger @ TD_PQCount getpropval 1 + dup trigger @ TD_PQCount rot setprop
trigger @ TD_DLastQ 4 rotate intostr strcat rot setprop
trigger @ TD_PLastPlayer me @ setprop
TD_STATE_AOK = if remind-loop then
else
arg @ not if
"~&150<> Declare who's dare complete? You must specify the daree." ansi-tell
exit
then
arg @ safematch dup pzanfilter not if
"~&150<> You can't end the dare of someone who isn't here, is asleep, or doesn't exist." ansi-tell
exit
then
trigger @ TD_PDarees 3 pick reflist_find not if
"~&150<> That person doesn't have a dare to clear." ansi-tell
exit
then
trigger @ TD_DDares 3 pick intostr strcat remove_prop
trigger @ TD_PDarees 3 pick reflist_del
"~&150<> " me @ name " declares " 4 rotate name "'s dare complete." strcat strcat strcat strcat notify_room
then
;
: prog-A ( -- )
arg @ not if
trigger @ TD_PAnswer getpropstr dup not if
pop "~&150<> " get-targetstr " hasn't answered yet." strcat strcat ansi-tell
else
"~&150<> (" get-targetstr " answered " get-playerstr ") ~&160" 6 rotate
strcat strcat strcat strcat strcat ansi-tell
then
exit
then
trigger @ TD_PTarget getprop dup dbref? if
me @ dbcmp not if
"~&150<> You can't answer a question you weren't asked!" ansi-tell
exit
then
else
pop
then
arg @ dup 1 ansi_strcut swap ":" strcmp not if
swap pop parse-pose
else
pop me @ name " answers, \"~&170" strcat swap "~&160\"" strcat strcat
then
"~&150<> (" me @ name " answers " trigger @ TD_PPlayer getprop name ") ~&160" 6 pick
strcat strcat strcat strcat strcat notify_room
game-state swap
trigger @ TD_PAnswer rot setprop
TD_STATE_A <= if remind-loop then
;
: prog-D ( -- )
arg @ not if
"~&110Invalid syntax! Type '~&170Q #HELP3~&110'." ansi-tell
exit
then
arg @ "=" instr if
arg @ "=" split swap dup not if
"~&150<> You need to specify a player to dare before that = sign." ansi-tell
exit
then
safematch dup pzanfilter if ( A player=dare situation )
set-daree not if
"~&150<> That person already has a dare to do." ansi-tell
exit
then
give-dare
else
pop
"~&150<> You can't dare someone who isn't here, or doesn't exist." ansi-tell
then
else
arg @ " " instr if ( More than one word parameter )
trigger @ TD_DDareTargets me @ intostr strcat getprop dbref? not if
arg @ char-strip " " explode
1 - swap safematch dup pzanfilter if (First word?)
set-daree not if
"~&150<> That person already has a dare to do." ansi-tell
exit
then
else
pop 1 - dup 2 + rotate safematch dup pzanfilter if (Last word?)
set-daree not if
"~&150<> That person already has a dare to do." ansi-tell
exit
then
else
pop begin (Other words?)
dup 0 = not while
1 - swap safematch dup pzanfilter if
set-daree not if
"~&150<> That person already has a dare to do." ansi-tell
exit
then
else
pop
then
repeat
then
then
then
arg @ give-dare
else
arg @ safematch dup pzanfilter if ( The one word is a player name )
dup set-daree not if
"~&150<> That person already has a dare to do." ansi-tell
exit
then
"~&150<> " me @ name " directs the dare to " 4 rotate name "." strcat strcat strcat strcat notify_room
else
arg @ give-dare
then
then
then
;
: prog-time ( -- )
arg @ "=" split swap atoi swap
"~&150<> " me @ name " sets a timer with the message: \"~&170" 4 pick "~&150\" for ~&170" 7 pick intostr "~&150 minutes."
strcat strcat strcat strcat strcat strcat notify_room
swap 60 * background sleep
"~&150<> A timer set by " me @ name " goes off with the message: \"~&170" 4 rotate "~&150\""
strcat strcat strcat strcat trigger @ location #-1 rot ansi-notify-except
;
: prog-pick ( -- )
trigger @ TD_PPlayer getprop dup dbref? if
me @ dbcmp not if
"~&150<> You can't pick a victim until it is your turn!" ansi-tell
exit
then
else
pop "~&150<> You need to restart the game. Type ~&170RESTART~&150." ansi-tell
exit
then
'pzanfilter me @ location .contents-filter array_make dup array_count dup 0 = if
"~&150<> There's no one else here..." ansi-tell pop
exit
else
over { trigger @ TD_PLastPlayer getprop dup dbref? not if pop #-1 then }list swap array_diff dup array_count dup 0 = if
pop pop
then
random swap % array_getitem
then
"~&150<> " me @ name "'s eyes scan around the room, eventually settling on " 4 pick name "!"
strcat strcat strcat strcat notify_room
game-state swap
set-target
TD_STATE_P <= if remind-loop then
;
: prog-hist ( -- )
"~&150<> History" ansi-tell
"~&170-~&130Player~&170--------------~&130Last~&170-~&130turn~&170--------------------------------------------------"
ansi-tell
'pzafilter me @ location .contents-filter
begin
dup 0 = not while
1 - swap dup ansify-name dup ansi_strlen " " swap strcut swap pop strcat " " swap strcat
trigger @ TD_DLastQ 4 rotate intostr strcat getpropval dup 0 = if
pop " -- NONE --"
else
trigger @ TD_PQCount getpropval swap - dup 1 = if
intostr " question ago"
else
intostr " questions ago"
then strcat
then "bold,cyan" textattr strcat .tell
repeat
"~&170--------------------------------------------------------------------------------" ansi-tell
;
: prog-spin ( -- )
'pzanfilter me @ location .contents-filter array_make dup array_count dup 0 = if
pop pop me @
else
random swap % array_getitem
then
"~&150<> " me @ name " spins the spinner, and it stops pointing at " 4 rotate name "!"
strcat strcat strcat strcat notify_room
;
: prog-grab ( -- )
"~&150<> " me @ name " ~&170grabs~&150 the Q!" strcat strcat notify_room
trigger @ TD_PPlayer getprop
trigger @ TD_PPlayer me @ setprop
trigger @ TD_PTarget remove_prop
trigger @ TD_PQuestion remove_prop
trigger @ TD_PAnswer remove_prop
me @ = not if remind-loop then
;
: prog-reset ( s -- )
"ET" instring if
"Are you sure you want to reset the game? (y/n)" "bold,red" textattr .confirm not if exit then
"~&150<> " me @ name " resets the game! Kerr-CHUNK!! (~&170History reset~&150)" strcat strcat notify_room
trigger @ TD_PQCount remove_prop
trigger @ TD_PLastQ remove_prop
trigger @ TD_PLastPlayer remove_prop
else
0 start-remind !
"Are you sure you want to restart the game? (y/n)" "bold,red" textattr .confirm not if exit then
"~&150<> " me @ name " restarts the game!" strcat strcat notify_room
'pzafilter me @ location .contents-filter dup 0 = if me @ else random over % 2 + pick then
"~&150<> The question zooms around the room, eventually settling on " over name "!" strcat strcat notify_room
trigger @ TD_PPlayer getprop dup dbref? if
dup pzafilter swap location me @ location = and not if
start-remind ++
then
else
pop start-remind ++
then
trigger @ TD_PPlayer rot setprop
trigger @ TD_PTarget remove_prop
trigger @ TD_PQuestion remove_prop
trigger @ TD_PAnswer remove_prop
trigger @ TD_PDarees remove_prop
trigger @ TD_PDares remove_prop
trigger @ TD_PDareTargets remove_prop
popn
start-remind @ if remind-loop then
then
;
: prog-stat ( -- )
"<> Game status" "bold,magenta" textattr .tell
"--------------" "bold,white" textattr .tell
" " .tell
"~&150Reminders are: " trigger @ TD_PRemindOn? getpropval btos strcat ansi-tell
" " .tell
"Question:" "bold,yellow" textattr .tell
"" arg ! prog-Q
" " .tell
trigger @ TD_PDarees getpropstr if
"Dares:" "bold,yellow" textattr .tell
trigger @ TD_PDarees array_get_reflist
foreach
swap pop
"~&150<> (" TD_DDares 3 pick intostr "/Darer" strcat strcat dup trigger @ swap getprop name
" to " 5 rotate name ") ~&160" trigger @ 6 rotate dup ansi_strlen 1 - ansi_strcut pop getpropstr
strcat strcat strcat strcat strcat ansi-tell
repeat
" " .tell
then
;
: prog-isweep ( -- )
arg @ not if
"<> Idle sweep who?" "bold,magenta" textattr .tell
exit
then
arg @ safematch dup pzanfilter not if
"<> You can only idle sweep a player or a zombie that is here, awake and not you." "bold,magenta" textattr .tell
exit
then
dup dup "z" flag? if
owner
then
db-leastidle TD_Def_Idle 60 * < if
"<> That person is not yet idle enough to idle swept." "bold,magenta" textattr .tell
exit
then
dup dup getlink 2 try
moveto
catch
pop
"<> Unfortunatly, due to limitations imposed by the programmer's M# Level," "bold,magenta" textattr .tell
"<> this player could not be swept home, as either they or their home is not" "bold,magenta" textattr .tell
"<> set JUMP_OK. Sorry for the inconvenience." "bold,magenta" textattr .tell
exit
endcatch
"~&150<> " swap dup ansify-name "~&150, ~&170" strcat swap db-mostidle 60 / intostr
"~&150 minutes idle, is idle swept home." strcat strcat strcat notify_room
;
: prog-boot ( -- )
arg @ not if
"<> Boot who from the game?" "bold,magenta" textattr .tell
exit
then
arg @ safematch dup pzanfilter not if
"<> You can only boot a player or a zombie that is here, awake and not you." "bold,magenta" textattr .tell
exit
then
dup "J" flag? over getlink "J" flag? and not if
"<> Unfortunatly, due to limitations imposed by the programmer's M# Level," "bold,magenta" textattr .tell
"<> this player could not be swept home, as either they or their home is not" "bold,magenta" textattr .tell
"<> set JUMP_OK. Sorry for the inconvenience." "bold,magenta" textattr .tell
exit
then
"~&150<> You vote to boot " over ansify-name "~&150 from the game." strcat strcat ansi-tell
TD_DBootVotes over intostr strcat dup trigger @ swap
over over getpropstr not if
"~&150<> The first vote has gone up to boot " 5 pick ansify-name "~&150 from the game." strcat strcat notify_room
"~&150<> Type ~&170\"BOOT " 5 pick ansify-name "~&170\"~&150 if you agree." strcat strcat notify_room
then
me @ reflist_add
'pzafilter me @ location .contents-filter array_make
over trigger @ swap array_get_reflist over
array_intersect trigger @ 4 pick 3 pick array_put_reflist
array_count swap array_count 0.75 * 0 round over <= if
trigger @ rot remove_prop
swap dup dup getlink moveto
ansify-name "~&150<> %s~&150, at ~&170%i~&150 votes, is booted from the game." fmtstring notify_room
then
;
( --------------------------------------------------------------------------- )
: vote-remind ( var[arg] -- )
arg @ " " split swap pop dup yes? not and not
trigger @ TD_PRemindOn? getpropval over = if
"~&150<> Reminders are already " swap btos "~&150." strcat strcat ansi-tell
exit
then
"~&150<> You vote to turn reminders " over btos "~&150." strcat strcat ansi-tell
dup if TD_PVoteRemindY else TD_PVoteRemindN then trigger @ swap over over getpropstr not if
"~&150<> The first vote has gone up to turn reminders " 4 pick btos "~&150." strcat strcat notify_room
"~&150<> Type ~&170\"Q #REMIND " 4 pick if "YES" else "NO" then "\"~&150 if you agree." strcat strcat notify_room
then
over over me @ reflist_add
'pzafilter me @ location .contents-filter array_make
3 pick 3 pick array_get_reflist over array_intersect 4 rotate 4 rotate 3 pick array_put_reflist
array_count swap array_count 0.75 * 0 round over <= if
trigger @ TD_PRemindOn? 4 pick setprop
trigger @ TD_PVoteRemindY remove_prop
trigger @ TD_PVoteRemindN remove_prop
swap btos swap "~&150<> At %i votes, reminders are turned %s~&150." fmtstring notify_room
then
;
( --------------------------------------------------------------------------- )
: help-header ( -- )
"~&120+----------------------+" ansi-tell
"~&120| ~&130STC-TorD.muf v1.9F ~&120|" ansi-tell
"~&120| ~&170>-*-< ~&110M2HL ~&170>-*-< ~&120| \\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/" ansi-tell
"~&120| ~&130by ~&150Stelard Actek ~&120| >~&110Stel~&120Tech~&140Cor~&130, MUFfing on request since ~&1701999~&120<" ansi-tell
"~&120| ~&130of ~&110Stel~&120Tech~&140Cor ~&120| /____________________________________________\\" ansi-tell
"~&120+----------------------+ (...~&170or something~&120...)" ansi-tell
" " .tell
;
: show-help ( -- )
arg @ dup ansi_strlen 1 - ansi_strcut swap pop atoi
dup 7 > if
"No such help page." .tell
exit
then
help-header
dup 1 <= if
"~&160How to play Truth or Dare:" ansi-tell
" " .tell
"~&160The aim of Truth or Dare is to embarrass those around you without getting" ansi-tell
"~&160embarrassed yourself. This is done through the artful use of questions or by" ansi-tell
"~&160the application of humiliating dares." ansi-tell
" " .tell
"~&160If the game room is empty, you'll have to RESET and RESTART the game first, the" ansi-tell
"~&160latter of which will select a player to go first for you. If the room is not" ansi-tell
"~&160empty, just sit down and wait for your turn." ansi-tell
" " .tell
"~&160Once it's your turn, you may use the Q command to ask a question of one of the" ansi-tell
"~&160other players. You should use PICK to select a target, or check the HISTORY and" ansi-tell
"~&160manually select someone who's not been asked yet or recently." ansi-tell
" " .tell
"~&160They should answer using the A command. If the answer fits your question, use" ansi-tell
"~&160AOK to acknowledge their answer, and it will be their turn to ask someone. If" ansi-tell
"~&160they answer with a request for a dare, use the D command to give them one, and" ansi-tell
"~&160then use AOK, so that the game may continue whilst they perform your dare." ansi-tell
" " .tell
"~&160That's it! There are other commands that you may find useful, so read the rest" ansi-tell
"~&160of the documentation too. (~&170Q #HELP2~&160)" ansi-tell
"~&160Alternatively, view the quick listing of available commands. (~&170Q #QUICK~&160)" ansi-tell
then
dup 2 = if
"~&160Since the disappearance of the Palace of the Dragons, and the establishment" ansi-tell
"~&160of Genetically Altered Perceptions, I've missed the Truth or Dare of old, and" ansi-tell
"~&160the muck commands that went with it. This is my attempt at emulating said" ansi-tell
"~&160commands, with only my memories and no knowledge of the old source code." ansi-tell
"~&160Apparently the old system was programmed using MPI, where as here I'm using" ansi-tell
"~&160Multiple User Forth, since I find it easier to comprehend." ansi-tell
" " .tell
"~&130Q ~&160Ah, now if this isn't the most important command," ansi-tell
"~&130Q <player> ~&170- ~&160I don't know what is. Q allows you to do multiple" ansi-tell
"~&130Q [<player>=]<question> ~&160things. On it's own, Q will display the last" ansi-tell
" ~&160question to be asked, who asked it and of whom." ansi-tell
" ~&160It can also be given a question, or a player to ask" ansi-tell
" ~&160that question of. So you can select a victim with Q," ansi-tell
" ~&160then ask the question, do it the other way around," ansi-tell
" ~&160or do both at once with by putting them together with" ansi-tell
" ~&160an equals sign. Note also that Q is smart enough to" ansi-tell
" ~&160pick names out of questions, hence, if you where to" ansi-tell
" ~&160ask such a mundane question as:" ansi-tell
" ~&160 \"What's the colour of my eyes, Ques?\"" ansi-tell
" ~&160and there is a player called Ques in the room, then" ansi-tell
" ~&160you don't have to specify the player name. You can" ansi-tell
" ~&160only ask a question if you have 'the Q'. < ^.^ >" ansi-tell
"~&130A [<answer>] ~&170- ~&160Type this to properly respond to a question you have" ansi-tell
" ~&160been asked. Or, type A on it's own to find what the" ansi-tell
" ~&160last answer was." ansi-tell
" " .tell
"~&160More information on page three (~&170Q #HELP3~&160)." ansi-tell
then
dup 3 = if
"~&130D <player> ~&170- ~&160Dares are the main reason we play, aren't they? So" ansi-tell
"~&130 [<player>=]<dare> ~&160this command is one you'll love to use. It functions" ansi-tell
" ~&160almost exactly like Q, even down to the point of" ansi-tell
" ~&160picking the target out of a sentence. However, the" ansi-tell
" ~&160main difference is that you can dare someone to do" ansi-tell
" ~&160something at any time, although convention dictates" ansi-tell
" ~&160you should only give a dare when asked for one. There" ansi-tell
" ~&160can be multiple dares running at any one time, but" ansi-tell
" ~&160you can only give dares to furs who don't already" ansi-tell
" ~&160have one." ansi-tell
"~&130AOK [<message>] ~&170- ~&160Accepts the answer given by whoever has been" ansi-tell
" ~&160questioned. Anyone can accept an answer, though it" ansi-tell
" ~&160should really only be done by the questioner." ansi-tell
" ~&160This has been left open, for situations where the" ansi-tell
" ~&160original questioner has idled or disconnected." ansi-tell
" ~&160You can supply an optional message, which will be" ansi-tell
" ~&160said, unless prefixed with a colon (':'), which will" ansi-tell
" ~&160cause the message to be posed." ansi-tell
"~&130DOK <player> ~&170- ~&160Fries somefur's brain! Don't type this! < ^.^ >" ansi-tell
" ~&160Seriously, in case you can't guess, this is the" ansi-tell
" ~&160command for accepting dares. Since there can be more" ansi-tell
" ~&160than one dare running at a time, you must specify a" ansi-tell
" ~&160fur to release from their agony. Once again, anyone" ansi-tell
" ~&160can accept a dare." ansi-tell
"~&130TIMER <minutes>=<msg> ~&170- ~&160Sets a timer, with a message, to go off in the" ansi-tell
" ~&160future. The message appears exactly once, after the" ansi-tell
" ~&160specified number of minutes have elapsed." ansi-tell
" " .tell
"~&160More information on page four (~&170Q #HELP4~&160)." ansi-tell
then
dup 4 = if
"~&130PICK ~&170- ~&160Randomly selects someone to ask a question of from" ansi-tell
" ~&160the room, and sets them up for a question. This" ansi-tell
" ~&160means that after running this command, you only have" ansi-tell
" ~&160to type Q <question>, rather than designating a" ansi-tell
" ~&160target first. Please note that PICK makes no" ansi-tell
" ~&160distinction between the fur who you got the Q off of," ansi-tell
" ~&160and that poor little kitty that's been sitting in the" ansi-tell
" ~&160corner waiting for a go for the last 30 consecutive" ansi-tell
" ~&160questions." ansi-tell
"~&130HISTORY ~&170- ~&160Lists the names of all in the room, and how long it's" ansi-tell
" ~&160been, in questions answered, since they last had a" ansi-tell
" ~&160chance to ask a question." ansi-tell
"~&130SPIN ~&170- ~&160Picks a fur at random, but does nothing. Handy for" ansi-tell
" ~&160those 'do this to someone' dares." ansi-tell
"~&130GRAB ~&170- ~&160Grab the Q. Simple as that. Has a 99.999% chance of" ansi-tell
" ~&160seriously miffing others if used without due cause." ansi-tell
"~&130RESET ~&170- ~&160Clears the history list and the last questions and" ansi-tell
" ~&160answers. Can be used at any time by anyone." ansi-tell
"~&130RESTART ~&170- ~&160Clears the dares, questions and answers, and picks" ansi-tell
" ~&160a new fur to ask a question, but leaves the history" ansi-tell
" ~&160list alone. As above for running." ansi-tell
"~&130STATUS ~&170- ~&160Shows the last question, who asked it and of whom," ansi-tell
" ~&160and any dares currently running." ansi-tell
" " .tell
"~&160More information on page five (~&170Q #HELP5~&160)." ansi-tell
then
dup 5 = if
"~&130ISWEEP <player> ~&170- ~&160For those who don't know, there exists on most MUCKs" ansi-tell
" ~&160a 'sweep' command, that basically gets rid of players" ansi-tell
" ~&160who have fallen asleep away from home. Since most" ansi-tell
" ~&160areas set up for Truth or Dare will have a limit on" ansi-tell
" ~&160the number of players allowed in that room, this" ansi-tell
" ~&160command will kick the designated player out and send" ansi-tell
" ~&160them home, if they are idle enough." ansi-tell
"~&130BOOT <player> ~&170- ~&160An unfortunately necessary command, this will put up" ansi-tell
" ~&160an anonymous vote to boot the designated player from" ansi-tell
" ~&160the game. 75% of the players in the room need to" ansi-tell
" ~&160agree. Please only use on rude and unruly players." ansi-tell
"~&130<ANYCOMMAND> #REMIND ?? ~&170- ~&160This turns the controversial reminder code on or off," ansi-tell
" ~&160depending on what you replaces ?? with. ~&170#REMIND YES" ansi-tell
" ~&160or ~&170#REMIND ON~&160 will turn it on, anything else will" ansi-tell
" ~&160turn it off. Like ~&130BOOT~&160, you need a 75% consensus to" ansi-tell
" ~&160change this setting." ansi-tell
"~&130<ANYCOMMAND> #QUICK ~&170- ~&160Quick listing of commands and uses." ansi-tell
"~&130<ANYCOMMAND> #HELP ~&170- ~&160Unleashes the Shadow. That BAAAD thing. Run and hide." ansi-tell
" " .tell
"~&160Version history on page six (~&170Q #HELP6~&160)." ansi-tell
"~&160Contact information on page seven (~&170Q #HELP7~&160)." ansi-tell
then
dup 6 = if
"~&130v1.0 ~&170- ~&110* ~&160Original release." ansi-tell
" ~&110* ~&160Had all the basics, including Q, A, AOK, D, DOK, SPIN, PICK, HISTORY," ansi-tell
" ~&160GRAB, RESTART and RESET. Help wasn't too helpful." ansi-tell
" " .tell
"~&130v1.1 ~&170- ~&110* ~&160Some small changes and bug fixes. I forget." ansi-tell
" " .tell
"~&130v1.2b ~&170- ~&110* ~&160Added a rather dodgey timer." ansi-tell
" ~&110* ~&160Added a quick command listing." ansi-tell
" ~&110* ~&160Added helpful help." ansi-tell
" ~&110* ~&160Added the STATUS command." ansi-tell
" ~&110* ~&160Fixed some small bugs." ansi-tell
" " .tell
"~&130v1.3b ~&170- ~&110* ~&160Moved to FuzzBall 6! This version and all following it will only run" ansi-tell
" ~&160on FuzzBall 6 or higher." ansi-tell
" ~&110* ~&160Changed the timer somewhat. Still didn't like it." ansi-tell
" ~&110* ~&160Used the new FuzzBall 6 primitives to tidy up the code somewhat." ansi-tell
" ~&110* ~&160Added colour." ansi-tell
" " .tell
"~&130v1.4b ~&170- ~&110* ~&160Decided the colour scheme looked stupid, and changed it." ansi-tell
" ~&110* ~&160Fixed some small bugs." ansi-tell
" " .tell
"~&130v1.5F ~&170- ~&110* ~&160Added the infamous Reminder Code!" ansi-tell
" ~&110* ~&160Added rudimentary BOOT and ISWEEP functions." ansi-tell
" ~&110* ~&160Decided I wouldn't be able to improve the game anymore until I got an" ansi-tell
" ~&170M3 bit ~&160(*snort*!), and declared Final Release." ansi-tell
" " .tell
"~&130v1.6F ~&170- ~&110* ~&160Got my furry rear kicked. Fixed the Reminder Code so it wouldn't" ansi-tell
" ~&160follow people out of the game. Oopsie." ansi-tell
" " .tell
"~&130v1.7F ~&170- ~&110* ~&160Fixed a timing issue with the Reminder Code, and made it" ansi-tell
" ~&160differentiate between players who have the Q and have done nothing," ansi-tell
" ~&160and players who have chosen a questionee, but not asked a question" ansi-tell
" ~&160yet." ansi-tell
" ~&110* ~&160Added this version history." ansi-tell
" " .tell
"~&130v1.8F ~&170- ~&110* ~&160Added the ability to toggle off the Reminder Code, since some people" ansi-tell
" ~&160seemed inordinately annoyed with it, whilst others seemed to like it." ansi-tell
" ~&110* ~&160Vowed to never declare Final Release ever again." ansi-tell
" " .tell
"~&130v1.9F ~&170- ~&110* ~&160Fixed a minor bug concerning name matching." ansi-tell
" " .tell
"~&160Contact information on page seven (~&170Q #HELP7~&160)." ansi-tell
then
dup 7 = if
" ~&160Questions? Problems? Suggestions? Ideas?" ansi-tell
" " .tell
" ~&160If so, contact your nearest StelTechCor office by mailing Stelard on" ansi-tell
" ~&160FurryMUCK, or by emailing [email protected]." ansi-tell
" " .tell
" ~&160For error reports, please tell what error you got, where you where, what" ansi-tell
" ~&160you typed to get the error, the date and approximate time. It would also" ansi-tell
" ~&160help to tell who owns the place you where, and how to get there." ansi-tell
" " .tell
" ~&160Thank you for your time." ansi-tell
" ~&110_____ ~&120_________ ~&140_____" ansi-tell
" ~&110/ ___/ ~&120/___ ___/ ~&140/ ___/" ansi-tell
" ~&110/ /__ ~&120/ / ~&140/ /" ansi-tell
" ~&110/__ / ~&120/ / ~&140/ /" ansi-tell
" ~&110___/ / ~&120/ / ~&140/ /___" ansi-tell
" ~&110/____/ tel ~&120/_/ ech ~&140/_____/ or" ansi-tell
then
" " .tell
;
( --------------------------------------------------------------------------- )
: show-quick ( -- )
help-header
"~&130Quick help:" ansi-tell
" " .tell
" ~&130Q [<player>]|[<player>=]<question>" ansi-tell
" ~&160Asks a player a question." ansi-tell
" ~&130A [<answer>]" ansi-tell
" ~&160Answers a question" ansi-tell
" ~&130D [<player>]|[<player>=]<question>" ansi-tell
" ~&160Gives a player a dare." ansi-tell
" ~&130AOK [<message>]" ansi-tell
" ~&160Declares an answer acceptable and passes the question on." ansi-tell
" ~&130DOK <player>" ansi-tell
" ~&160Declares a dare complete." ansi-tell
" ~&130TIMER <minutes>=<message>" ansi-tell
" ~&160Sets a timer with a message." ansi-tell
" ~&130PICK" ansi-tell
" ~&160Selects a player at random and directs the question to them." ansi-tell
" ~&130HISTORY" ansi-tell
" ~&160Shows who's had a go most recently." ansi-tell
" ~&130SPIN" ansi-tell
" ~&160Selects a player at random, and does nothing." ansi-tell
" ~&130GRAB" ansi-tell
" ~&160Makes it your turn to ask a question. Use sparingly." ansi-tell
" ~&130RESET" ansi-tell
" ~&160Clears the history list, dares, questions and answers." ansi-tell
" ~&130RESTART" ansi-tell
" ~&160Clears the dares, questions and answers, and picks a new player" ansi-tell
" ~&160to ask a question." ansi-tell
" ~&130STATUS" ansi-tell
" ~&160Shows the current game status." ansi-tell
" ~&130ISWEEP <player>" ansi-tell
" ~&160Sweeps an idle player." ansi-tell
" ~&130BOOT <player>" ansi-tell
" ~&160Holds a vote to boot a player from the game." ansi-tell
" " .tell
"~&160How to play on page one of the help (~&170Q #HELP~&160)" ansi-tell
;
( --------------------------------------------------------------------------- )
: main
strip arg !
me @ TD_PLastVer getpropstr dup if
TD_Version stringcmp dup 0 < if "newer" else "older" then swap if
"~&160This is a ~&170%s~&160 version of ~&130STC~&170-~&130TorD.muf~&160 than you have used before." fmtstring ansi-tell
"~&160For a list of changes, please look at help page six (~&170Q #HELP6~&160)." ansi-tell
"~&160This message will not appear again for this version." ansi-tell
me @ TD_PLastVer TD_Version setprop
exit
then
else
pop me @ TD_PLastVer TD_Version setprop
then
arg @ 2 ansi_strcut pop "#H" stringcmp not if show-help exit then
arg @ 2 ansi_strcut pop "#Q" stringcmp not if show-quick exit then
arg @ 2 ansi_strcut pop "#R" stringcmp not if vote-remind exit then
command @ "Q" stringcmp not if prog-Q exit then
command @ 1 ansi_strcut "OK" stringcmp not if prog-OK exit else pop then
command @ "A" stringcmp not if prog-A exit then
command @ "D" stringcmp not if prog-D exit then
command @ "TIME" instring if prog-time exit then
command @ "PICK" instring if prog-pick exit then
command @ "HIST" instring if prog-hist exit then
command @ "SPIN" instring if prog-spin exit then
command @ "GRAB" instring if prog-grab exit then
command @ 3 ansi_strcut swap "RES" stringcmp not if prog-reset exit else pop then
command @ "STAT" instring if prog-stat exit then
command @ "ISWEEP" instring if prog-isweep exit then
command @ "BOOT" instring if prog-boot exit then