ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/chat.ext
Revision: 1.9
Committed: Thu Mar 1 13:01:37 2007 UTC (17 years, 2 months ago) by pippijn
Branch: MAIN
Changes since 1.8: +127 -123 lines
Log Message:
cointoss in perl

File Contents

# User Rev Content
1 root 1.1 #! perl
2     #CONVERSION: PARTIAL
3    
4     # implement a replacement for the built-in say/chat/shout/tell/reply commands
5     # adds ignore/unignore functionality
6    
7     use NPC_Dialogue;
8     use POSIX (); # for strftime only
9    
10     sub clean_timeouts($) {
11     my ($player) = @_;
12     my $NOW = time;
13    
14     for my $hash (@$player{qw(ext_ignore_shout ext_ignore_tell)}) {
15     while (my ($k, $v) = each %$hash) {
16     if ($v < $NOW) {
17     $player->message ("Your ignore on $k has expired.", cf::NDI_GREEN | cf::NDI_UNIQUE);
18     delete $hash->{$k};
19     } elsif (!cf::player::exists $k) {
20     $player->message ("Your ignore on $k is no longer valid (no such user).", cf::NDI_GREEN | cf::NDI_UNIQUE);
21     delete $hash->{$k};
22     }
23     }
24     }
25     }
26    
27 root 1.2 cf::player->attach (
28     prio => -1000,
29 root 1.1 on_login => sub {
30     my ($pl) = @_;
31    
32     clean_timeouts $pl->ob;
33     },
34 root 1.2 );
35 root 1.1
36     cf::register_command listen => sub {
37 pippijn 1.9 my ($pl, $msg) = @_;
38     my $player = cf::player::find_active $pl->name;
39 root 1.1
40     if ($msg ne "") {
41     my $prev_listen = $player->listening;
42     $player->listening ($msg);
43     if ($prev_listen == $player->listening) {
44 pippijn 1.9 $pl->message ("Your verbose level stayed $prev_listen.", cf::NDI_UNIQUE);
45 root 1.1 } else {
46 pippijn 1.9 $pl->message ("Your verbose level is now " . $player->listening . ". (previously: $prev_listen)", cf::NDI_UNIQUE);
47 root 1.1 }
48     } else {
49 pippijn 1.9 $pl->message ("Your verbose level is " . $player->listening . ".", cf::NDI_UNIQUE);
50 root 1.1 }
51 pippijn 1.9 };
52    
53     cf::register_command cointoss => sub {
54     my ($pl, $msg) = @_;
55 pippijn 1.4
56 pippijn 1.9 my $name = $pl->name;
57    
58     if (int rand 2) {
59     for my $other ( grep { $pl->on_same_map_as ($_->ob) } cf::player::list ) {
60     next
61     if $other->ob == $pl;
62     $other->ob->message ("$name flips a coin.... Heads!", cf::NDI_GREY | cf::NDI_UNIQUE);
63     }
64    
65     $pl->message ("You flip a coin.... Heads!", cf::NDI_GREY | cf::NDI_UNIQUE);
66     } else {
67     for my $other ( grep { $pl->on_same_map_as ($_->ob) } cf::player::list ) {
68     next
69     if $other->ob == $pl;
70     $other->ob->message ("$name flips a coin.... Tails!", cf::NDI_GREY | cf::NDI_UNIQUE);
71     }
72    
73     $pl->message ("You flip a coin.... Tails!", cf::NDI_GREY | cf::NDI_UNIQUE);
74     }
75 root 1.1 };
76    
77 pippijn 1.4 my $emotes = {
78     growl => {
79     noparams => {
80 pippijn 1.5 other => "<self> growls.",
81     self => "Grrrrrrrrr....",
82 pippijn 1.4 },
83     params => {
84     },
85     self => {
86     },
87     },
88     giggle => {
89     noparams => {
90 pippijn 1.5 other => "<self> giggles.",
91     self => "You giggle.",
92 pippijn 1.4 },
93     params => {
94     },
95     self => {
96     },
97     },
98     shiver => {
99     noparams => {
100 pippijn 1.5 other => "<self> shivers uncomfortably.",
101     self => "Brrrrrrrrr.",
102 pippijn 1.4 },
103     params => {
104     },
105     self => {
106     },
107     },
108     chuckle => {
109     noparams => {
110 pippijn 1.5 other => "<self> chuckles politely.",
111     self => "You chuckle politely",
112 pippijn 1.4 },
113     params => {
114     },
115     self => {
116     },
117     },
118     sigh => {
119     noparams => {
120 pippijn 1.5 other => "<self> sighs loudly.",
121     self => "You sigh.",
122 pippijn 1.4 },
123     params => {
124     },
125     self => {
126     },
127     },
128     scream => {
129     noparams => {
130 pippijn 1.5 other => "<self> screams at the top of his lungs!",
131     self => "ARRRRRRRRRRGH!!!!!",
132 pippijn 1.4 },
133     params => {
134     },
135     self => {
136     },
137     },
138     puke => {
139     noparams => {
140 pippijn 1.5 other => "<self> pukes.",
141     self => "Bleaaaaaghhhhhhh!",
142 pippijn 1.4 },
143     params => {
144 pippijn 1.5 target => "<self> pukes on your clothes!",
145     other => "<self> pukes on <other>.",
146     self => "You puke on <other>.",
147 pippijn 1.4 },
148     self => {
149 pippijn 1.5 other => "<self> pukes on his clothes.",
150     self => "You puke on yourself.",
151 pippijn 1.4 },
152     },
153     strut => {
154     noparams => {
155 pippijn 1.5 other => "<self> struts proudly.",
156     self => "Strut your stuff.",
157 pippijn 1.4 },
158     params => {
159     },
160     self => {
161     },
162     },
163     cringe => {
164     noparams => {
165 pippijn 1.5 other => "<self> cringes in terror!",
166     self => "You cringe in terror.",
167 pippijn 1.4 },
168     params => {
169 pippijn 1.5 target => "<self> cringes away from <other> in mortal terror.",
170     self => "You cringe away from <other>.",
171 pippijn 1.4 },
172     self => {
173     },
174     },
175     hiccup => {
176     noparams => {
177 pippijn 1.5 other => "<self> hiccups.",
178     self => "*HIC*",
179 pippijn 1.4 },
180     params => {
181     },
182     self => {
183     },
184     },
185     clap => {
186     noparams => {
187 pippijn 1.5 other => "<self> gives a round of applause.",
188     self => "Clap, clap, clap.",
189 pippijn 1.4 },
190     params => {
191     },
192     self => {
193     },
194     },
195     kiss => {
196     noparams => {
197 pippijn 1.5 other => "<self> makes a weird facial contortion",
198     self => "All the lonely people..",
199 pippijn 1.4 },
200     params => {
201 pippijn 1.5 target => "<self> kisses you.",
202     other => "<self> kisses <other>.",
203     self => "You kiss <other>.",
204 pippijn 1.4 },
205     self => {
206     },
207     },
208     wink => {
209     noparams => {
210 pippijn 1.5 other => "<self> winks suggestively.",
211     self => "Have you got something in your eye?",
212 pippijn 1.4 },
213     params => {
214 pippijn 1.5 target => "<self> winks at <other>.",
215     self => "You wink suggestively at <other>.",
216 pippijn 1.4 },
217     self => {
218 pippijn 1.5 other => "<self> winks at himself - something strange is going on...",
219     self => "You wink at yourself?? What are you up to?",
220 pippijn 1.4 },
221     },
222     pout => {
223     noparams => {
224 pippijn 1.5 other => "<self> pouts.",
225     self => "Aww, don't take it so hard.",
226 pippijn 1.4 },
227     params => {
228     },
229     self => {
230     },
231     },
232     cackle => {
233     noparams => {
234 pippijn 1.5 other => "<self> throws back his head and cackles with insane glee!",
235     self => "You cackle gleefully.",
236 pippijn 1.4 },
237     params => {
238     },
239     self => {
240     },
241     },
242     sniff => {
243     noparams => {
244 pippijn 1.5 other => "<self> sniffs sadly.",
245     self => "You sniff sadly. *SNIFF*",
246 pippijn 1.4 },
247     params => {
248 pippijn 1.5 target => "<self> sniffs you.",
249     other => "<self> sniffs <other>",
250     self => "You sniff <other>.",
251 pippijn 1.4 },
252     self => {
253 pippijn 1.5 other => "<self> sniffs himself.",
254     self => "You sniff yourself.",
255 pippijn 1.4 },
256     },
257     nod => {
258     noparams => {
259 pippijn 1.5 other => "<self> nods solemnly.",
260     self => "You nod solemnly.",
261 pippijn 1.4 },
262     params => {
263 pippijn 1.5 target => "<self> nods solemnly to you.",
264     other => "<self> nods solemnly to <other>.",
265     self => "You nod solemnly to <other>.",
266 pippijn 1.4 },
267     self => {
268     },
269     },
270     frown => {
271     noparams => {
272 pippijn 1.5 other => "<self> frowns.",
273     self => "What's bothering you?",
274 pippijn 1.4 },
275     params => {
276 pippijn 1.5 target => "<self> frowns darkly at you.",
277     other => "<self> frowns darkly at <other>.",
278     self => "You frown darkly at <other>.",
279 pippijn 1.4 },
280     self => {
281 pippijn 1.5 other => "<self> frowns at himself.",
282     self => "You frown at yourself.",
283 pippijn 1.4 },
284     },
285     snicker => {
286     noparams => {
287 pippijn 1.5 other => "<self> snickers softly.",
288     self => "You snicker softly.",
289 pippijn 1.4 },
290     params => {
291     },
292     self => {
293     },
294     },
295     shrug => {
296     noparams => {
297 pippijn 1.5 other => "<self> shrugs helplessly.",
298     self => "You shrug.",
299 pippijn 1.4 },
300     params => {
301 pippijn 1.5 target => "<self> shrugs at you.",
302     other => "<self> shrugs at <other>.",
303     self => "You shrug at <other>.",
304 pippijn 1.4 },
305     self => {
306     },
307     },
308     bleed => {
309     noparams => {
310 pippijn 1.5 other => "<self> is bleeding all over the carpet - got a spare tourniquet?",
311     self => "You bleed all over your nice new armour.",
312 pippijn 1.4 },
313     params => {
314 pippijn 1.5 target => "<self> slashes his wrist and bleeds all over <other>.",
315     self => "You slash your wrist and bleed all over <other>",
316 pippijn 1.4 },
317     self => {
318 pippijn 1.5 other => "<self> performs some satanic ritual while wiping his blood on himself.",
319     self => "Very impressive! You wipe your blood all over yourself.",
320 pippijn 1.4 },
321     },
322     twiddle => {
323     noparams => {
324 pippijn 1.5 other => "<self> patiently twiddles his thumbs.",
325     self => "You patiently twiddle your thumbs.",
326 pippijn 1.4 },
327     params => {
328     },
329     self => {
330     },
331     },
332     spit => {
333     noparams => {
334 pippijn 1.5 other => "<self> spits over his left shoulder.",
335     self => "You spit over your left shoulder.",
336 pippijn 1.4 },
337     params => {
338 pippijn 1.5 target => "<self> spits in your face!",
339     other => "<self> spits in <other>'s face.",
340     self => "You spit on <other>.",
341 pippijn 1.4 },
342     self => {
343 pippijn 1.5 other => "<self> drools all over himself.",
344     self => "You drool all over yourself.",
345 pippijn 1.4 },
346     },
347     glare => {
348     noparams => {
349 pippijn 1.5 other => "<self> glares around him.",
350     self => "You glare at nothing in particular.",
351 pippijn 1.4 },
352     params => {
353 pippijn 1.5 target => "<self> glares icily at you, you feel cold to your bones.",
354     other => "<self> glares at <other>.",
355     self => "You glare icily at <other>.",
356 pippijn 1.4 },
357     self => {
358 pippijn 1.5 other => "<self> glares at his feet, what is bothering him?",
359     self => "You glare icily at your feet, they are suddenly very cold.",
360 pippijn 1.4 },
361     },
362     bow => {
363     noparams => {
364 pippijn 1.5 other => "<self> bows deeply.",
365     self => "You bow deeply.",
366 pippijn 1.4 },
367     params => {
368 pippijn 1.5 target => "<self> bows before you.",
369     other => "<self> bows before <other>.",
370     self => "You bow before <other>.",
371 pippijn 1.4 },
372     self => {
373 pippijn 1.5 other => "<self> folds up like a jackknife and kisses his own toes.",
374     self => "You kiss your toes.",
375 pippijn 1.4 },
376     },
377     dance => {
378     noparams => {
379 pippijn 1.5 other => "<self> expresses himself through interpretive dance.",
380     self => "You dance with glee.",
381 pippijn 1.4 },
382     params => {
383 pippijn 1.5 target => "<self> grabs you, and begins dancing!",
384     other => "Yipe! <self> and <other> are doing the Macarena!",
385     self => "You grab <other> and begin doing the Cha-Cha!",
386 pippijn 1.4 },
387     self => {
388 pippijn 1.5 other => "<self> embraces himself and begins to dance!",
389     self => "You skip and dance around by yourself.",
390 pippijn 1.4 },
391     },
392     snore => {
393     noparams => {
394 pippijn 1.5 other => "<self> snores loudly.",
395     self => "Zzzzzzzzzzzzzzz.",
396 pippijn 1.4 },
397     params => {
398     },
399     self => {
400     },
401     },
402     blush => {
403     noparams => {
404 pippijn 1.5 other => "<self> blushes.",
405     self => "Your cheeks are burning.",
406 pippijn 1.4 },
407     params => {
408     },
409     self => {
410     },
411     },
412     snap => {
413     noparams => {
414 pippijn 1.5 other => "<self> snaps his fingers.",
415     self => "PRONTO! you snap your fingers.",
416 pippijn 1.4 },
417     params => {
418     },
419     self => {
420     },
421     },
422     wave => {
423     noparams => {
424 pippijn 1.5 other => "<self> waves happily.",
425     self => "You wave.",
426 pippijn 1.4 },
427     params => {
428 pippijn 1.5 target => "<self> waves goodbye to you. Have a good journey.",
429     other => "<self> waves goodbye to <other>.",
430     self => "You wave goodbye to <other>.",
431 pippijn 1.4 },
432     self => {
433 pippijn 1.5 other => "<self> waves goodbye to himself.",
434     self => "Are you going on adventures as well??",
435 pippijn 1.4 },
436     },
437     smile => {
438     noparams => {
439 pippijn 1.5 other => "<self> smiles happily.",
440     self => "You smile happily.",
441 pippijn 1.4 },
442     params => {
443 pippijn 1.5 target => "<self> smiles at you.",
444     other => "<self> beams a smile at <other>.",
445     self => "You smile at <other>.",
446 pippijn 1.4 },
447     self => {
448     },
449     },
450     sneeze => {
451     noparams => {
452 pippijn 1.5 other => "<self> sneezes.",
453     self => "Gesundheit!",
454 pippijn 1.4 },
455     params => {
456 pippijn 1.5 target => "<self> sneezes on you, you feel the snot cover you. EEEEEEW.",
457     other => "<self> sneezes on <other> and a film of snot covers him.",
458     self => "You sneeze at <other> and a film of snot shoots onto him.",
459 pippijn 1.4 },
460     self => {
461 pippijn 1.5 other => "<self> sneezes, and covers himself in a slimy substance.",
462     self => "You sneeze on yourself, what a mess!",
463 pippijn 1.4 },
464     },
465     bounce => {
466     noparams => {
467 pippijn 1.5 other => "<self> bounces around.",
468     self => "BOIINNNNNNGG!",
469 pippijn 1.4 },
470     params => {
471 pippijn 1.5 target => "<self> bounces around the room with you.",
472     other => "<self> bounces around the room with <other>.",
473     self => "You bounce around the room with <other>.",
474 pippijn 1.4 },
475     self => {
476     },
477     },
478     shake => {
479     noparams => {
480 pippijn 1.5 other => "<self> shakes his head.",
481     self => "You shake your head.",
482 pippijn 1.4 },
483     params => {
484 pippijn 1.5 target => "<self> shakes your hand.",
485     other => "<self> shakes <other>'s hand.",
486     self => "You shake <other>'s hand.",
487 pippijn 1.4 },
488     self => {
489 pippijn 1.5 other => "<self> shakes and quivers like a bowlful of jelly.",
490     self => "You are shaken by yourself.",
491 pippijn 1.4 },
492     },
493     lick => {
494     noparams => {
495 pippijn 1.5 other => "<self> licks his mouth and smiles.",
496     self => "You lick your mouth and smile.",
497 pippijn 1.4 },
498     params => {
499 pippijn 1.5 target => "<self> licks you.",
500     other => "<self> licks <other>.",
501     self => "You lick <other>.",
502 pippijn 1.4 },
503     self => {
504 pippijn 1.5 other => "<self> licks himself - YUCK.",
505     self => "You lick yourself.",
506 pippijn 1.4 },
507     },
508     flip => {
509     noparams => {
510 pippijn 1.5 other => "<self> flips head over heels.",
511     self => "You flip head over heels.",
512 pippijn 1.4 },
513     params => {
514     },
515     self => {
516     },
517     },
518     think => {
519     noparams => {
520 pippijn 1.5 other => "<self> closes his eyes and thinks really hard.",
521     self => "Anything in particular that you'd care to think about?",
522 pippijn 1.4 },
523     params => {
524     },
525     self => {
526     },
527     },
528     yawn => {
529     noparams => {
530 pippijn 1.5 other => "<self> yawns sleepily.",
531     self => "You open up your yap and let out a big breeze of stale air.",
532 pippijn 1.4 },
533     params => {
534     },
535     self => {
536     },
537     },
538     laugh => {
539     noparams => {
540 pippijn 1.5 other => "<self> falls down laughing.",
541     self => "You fall down laughing.",
542 pippijn 1.4 },
543     params => {
544 pippijn 1.5 target => "<self> looks at you and falls down on the ground laughing.",
545     other => "<self> looks at <other> and falls down on the ground laughing.",
546     self => "You take one look at <other> and fall down laughing.",
547 pippijn 1.4 },
548     self => {
549 pippijn 1.5 other => "<self> is laughing at something.",
550     self => "Laugh at yourself all you want, the others won't understand.",
551 pippijn 1.4 },
552     },
553     burp => {
554     noparams => {
555 pippijn 1.5 other => "<self> burps loudly.",
556     self => "You burp loudly.",
557 pippijn 1.4 },
558     params => {
559     },
560     self => {
561     },
562     },
563     gasp => {
564     noparams => {
565 pippijn 1.5 other => "<self> gasps in astonishment.",
566     self => "You gasp in astonishment.",
567 pippijn 1.4 },
568     params => {
569     },
570     self => {
571     },
572     },
573     smirk => {
574     noparams => {
575 pippijn 1.5 other => "<self> smirks.",
576     self => "You smirk.",
577 pippijn 1.4 },
578     params => {
579     },
580     self => {
581     },
582     },
583     cry => {
584     noparams => {
585 pippijn 1.5 other => "<self> bursts into tears.",
586     self => "Waaaaaaahhh..",
587 pippijn 1.4 },
588     params => {
589 pippijn 1.5 target => "<self> cries on your shoulder.",
590     other => "<self> cries on <other>'s shoulder.",
591     self => "You cry on <other>'s shoulder.",
592 pippijn 1.4 },
593     self => {
594 pippijn 1.5 other => "<self> sobs quietly to himself.",
595     self => "You cry to yourself.",
596 pippijn 1.4 },
597     },
598     sulk => {
599     noparams => {
600 pippijn 1.5 other => "<self> sulks in the corner.",
601     self => "You sulk.",
602 pippijn 1.4 },
603     params => {
604     },
605     self => {
606     },
607     },
608     whistle => {
609     noparams => {
610 pippijn 1.5 other => "<self> whistles appreciatively.",
611     self => "You whistle appreciatively.",
612 pippijn 1.4 },
613     params => {
614 pippijn 1.5 target => "<self> whistles at <other>.",
615     self => "You whistle at <other>.",
616 pippijn 1.4 },
617     self => {
618 pippijn 1.5 other => "<self> whistles to himself in boredom.",
619     self => "You whistle while you work.",
620 pippijn 1.4 },
621     },
622     groan => {
623     noparams => {
624 pippijn 1.5 other => "<self> groans loudly.",
625     self => "You groan loudly.",
626 pippijn 1.4 },
627     params => {
628     },
629     self => {
630     },
631     },
632     cough => {
633     noparams => {
634 pippijn 1.5 other => "<self> coughs loudly.",
635     self => "Yuck, try to cover your mouth next time!",
636 pippijn 1.4 },
637     params => {
638     },
639     self => {
640     },
641     },
642     grin => {
643     noparams => {
644 pippijn 1.5 other => "<self> grins evilly.",
645     self => "You grin evilly.",
646 pippijn 1.4 },
647     params => {
648 pippijn 1.5 target => "<self> grins evilly at you.",
649     other => "<self> grins evilly at <other>.",
650     self => "You grin at <other>.",
651 pippijn 1.4 },
652     self => {
653     },
654     },
655     };
656 pippijn 1.7
657 pippijn 1.4 for my $emotion (keys %$emotes) {
658     cf::register_command $emotion => sub {
659 pippijn 1.9 my ($pl, $tname) = @_;
660 pippijn 1.4
661     cf::async {
662 pippijn 1.9 my $name = $pl->name;
663 pippijn 1.4
664     if ($tname eq $name) {
665     my $emote = $emotes->{$emotion}->{self};
666 pippijn 1.7
667     $emote->{other} = "You look away from <self>."
668     if !$emote->{other};
669     $emote->{self} = "My god! Is that LEGAL?"
670     if !$emote->{self};
671    
672 pippijn 1.4 $emote->{other} =~ s/<self>/$name/;
673    
674 pippijn 1.9 for my $other ( grep { $pl->on_same_map_as ($_->ob) } cf::player::list ) {
675 pippijn 1.4 next
676 pippijn 1.9 if $other->ob == $pl;
677 pippijn 1.4 $other->ob->message ($emote->{other}, cf::NDI_GREY | cf::NDI_UNIQUE);
678     }
679    
680 pippijn 1.9 $pl->message ($emote->{self}, cf::NDI_GREY | cf::NDI_UNIQUE);
681 pippijn 1.4 } elsif ($tname) {
682     my $target = cf::player::find $tname
683 pippijn 1.9 or return $pl->reply (undef, "$tname is not around.");
684 pippijn 1.4
685     my $emote = $emotes->{$emotion}->{params};
686 pippijn 1.7
687     $emote->{other} = "<self> is eyeing <other> quizzically."
688     if !$emote->{other};
689     $emote->{self} = "You are still nuts."
690     if !$emote->{self};
691     $emote->{target} = "You get the distinct feeling that <other> is nuts."
692     if !$emote->{target};
693    
694 pippijn 1.4 $emote->{self} =~ s/<other>/$tname/;
695     $emote->{target} =~ s/<self>/$name/;
696     $emote->{other} =~ s/<other>/$tname/;
697     $emote->{other} =~ s/<self>/$name/;
698    
699 pippijn 1.9 for my $other ( grep { $pl->on_same_map_as ($_->ob) } cf::player::list ) {
700 pippijn 1.4 next
701 pippijn 1.9 if $other->ob == $pl or $other == $target;
702 pippijn 1.4 $other->ob->message ($emote->{other}, cf::NDI_GREY | cf::NDI_UNIQUE);
703     }
704    
705     $target->ob->message ($emote->{target}, cf::NDI_GREY | cf::NDI_UNIQUE);
706 pippijn 1.9 $pl->message ($emote->{self}, cf::NDI_GREY | cf::NDI_UNIQUE);
707 pippijn 1.4 } else {
708     my $emote = $emotes->{$emotion}->{noparams};
709     $emote->{other} =~ s/<self>/$name/;
710 pippijn 1.7
711     $emote->{other} = "<self> dances with glee."
712     if !$emote->{other};
713     $emote->{self} = "You are a nut."
714     if !$emote->{self};
715 pippijn 1.4
716 pippijn 1.9 for my $other ( grep { $pl->on_same_map_as ($_->ob) } cf::player::list ) {
717 pippijn 1.4 next
718 pippijn 1.9 if $other->ob == $pl;
719 pippijn 1.4 $other->ob->message ($emote->{other}, cf::NDI_GREY | cf::NDI_UNIQUE);
720     }
721    
722 pippijn 1.9 $pl->message ($emote->{self}, cf::NDI_GREY | cf::NDI_UNIQUE);
723 pippijn 1.4 }
724     };
725     };
726     }
727    
728 pippijn 1.8 cf::register_command me => sub {
729 pippijn 1.9 my ($pl, $msg) = @_;
730 pippijn 1.8
731 pippijn 1.9 my $name = $pl->name;
732 pippijn 1.8
733     $_->ob->message ("* $name $msg", cf::NDI_GREY | cf::NDI_UNIQUE)
734 pippijn 1.9 for grep $pl->on_same_map_as ($_->ob), cf::player::list;
735 pippijn 1.8 };
736    
737 root 1.1 cf::register_command say => sub {
738 pippijn 1.9 my ($pl, $msg) = @_;
739 root 1.1
740     utf8::decode $msg;
741    
742 pippijn 1.9 return if $pl->contr->invoke (cf::EVENT_PLAYER_SAY, $msg);
743 root 1.1
744     if ($msg) {
745 pippijn 1.9 my $name = $pl->name;
746 root 1.1
747     utf8::encode $msg; # ->message not yet utf8-ified
748     $_->ob->message ("$name says: $msg", cf::NDI_GREY | cf::NDI_UNIQUE)
749 pippijn 1.9 for grep $pl->on_same_map_as ($_->ob), cf::player::list;
750 root 1.1 utf8::decode $msg;
751    
752     # npcs, magic_ears etc.
753     # first find all objects and theirt-level inventories
754     # within a 5x5 square # that have something resembling
755     # dialogue or support on_say.
756 pippijn 1.9 my ($map, $x, $y) = ($pl->map, $pl->x - 2, $pl->y - 2);
757 root 1.1
758     for my $npc (
759 pippijn 1.9 grep +($_->invoke (cf::EVENT_OBJECT_SAY, $pl->contr, $msg) && return) || NPC_Dialogue::has_dialogue $_,
760 root 1.1 map +($_, $_->inv),
761     grep $_,
762     map $map->at ($x + $_ % 5, $y + (int $_ / 5)),
763     0..24
764     ) {
765     # if some listener teleported us somewhere else, stop right here
766 pippijn 1.9 last unless $map->path == $pl->map->path;
767 root 1.1
768 pippijn 1.9 my $dialog = new NPC_Dialogue ob => $pl, npc => $npc;
769 root 1.1 my ($reply, @kw) = $dialog->tell ($msg);
770    
771     if (defined $reply) {
772     if ($npc->type == cf::MAGIC_EAR) {
773     if (length $reply) {
774     $_->ob->message ($reply, cf::NDI_BROWN | cf::NDI_UNIQUE)
775 pippijn 1.9 for grep $pl->on_same_map_as ($_->ob), cf::player::list;
776 root 1.1 }
777     $npc->use_trigger;
778     } else {
779     if (length $reply) {
780     $_->ob->message ($npc->name . " says: $reply", cf::NDI_BROWN | cf::NDI_UNIQUE)
781 pippijn 1.9 for grep $pl->on_same_map_as ($_->ob), cf::player::list;
782 root 1.1 }
783     }
784     }
785    
786     if (@kw) {
787     $_->ob->message ("[further topics: " . (join ", ", @kw) . "]", cf::NDI_BROWN | cf::NDI_UNIQUE)
788 pippijn 1.9 for grep $pl->on_same_map_as ($_->ob), cf::player::list;
789 root 1.1 }
790     }
791    
792     } else {
793 pippijn 1.9 $pl->message ("What do you want to say?", cf::NDI_UNIQUE);
794 root 1.1 }
795     };
796    
797     cf::register_command chat => sub {
798 pippijn 1.9 my ($pl, $msg) = @_;
799 root 1.1
800     utf8::decode $msg;
801    
802 pippijn 1.9 return if $pl->contr->invoke (cf::EVENT_PLAYER_CHAT, $msg);
803 root 1.1
804     if ($msg) {
805 pippijn 1.9 my $name = $pl->name;
806 root 1.1 my $NOW = time;
807    
808     utf8::encode $msg; # ->message not yet utf8-ified
809     cf::LOG cf::llevDebug, sprintf "QBERT [%s] %s\n", $name, $msg;
810     ext::schmorp_irc::do_notice (sprintf "[%s] %s", $name, $msg);
811    
812     $_->ob->message ("$name chats: $msg", cf::NDI_BLUE)
813     for grep { $_->ob->{ext_ignore_shout}{$name} < $NOW && $_->listening >= 10 } cf::player::list;
814    
815     } else {
816 pippijn 1.9 $pl->message ("Chat what?", cf::NDI_UNIQUE);
817 root 1.1 }
818     };
819    
820     cf::register_command shout => sub {
821 pippijn 1.9 my ($pl, $msg) = @_;
822 root 1.1
823     utf8::decode $msg;
824    
825 pippijn 1.9 return if $pl->contr->invoke (cf::EVENT_PLAYER_SHOUT, $msg);
826 root 1.1
827     if ($msg) {
828     my $NOW = time;
829 pippijn 1.9 my $name = $pl->name;
830 root 1.1
831     cf::LOG cf::llevDebug, sprintf "QBERT {%s} %s\n", $name, $msg;
832     ext::schmorp_irc::do_notice (sprintf "\007\0034{%s} %s\n", $name, $msg);
833    
834     utf8::encode $msg; # ->message not yet utf8-ified
835     $_->ob->message ("$name shouts: $msg", cf::NDI_RED)
836     for grep { $_->ob->{ext_ignore_shout}{$name} < $NOW && $_->listening >= 2 } cf::player::list;
837    
838     } else {
839 pippijn 1.9 $pl->message ("Shout what?", cf::NDI_UNIQUE);
840 root 1.1 }
841     };
842    
843     cf::register_command tell => sub {
844 pippijn 1.9 my ($pl, $args) = @_;
845 root 1.1 my ($target, $msg) = split /\s+/, $args, 2;
846    
847     utf8::decode $msg;
848    
849 pippijn 1.9 return if $pl->contr->invoke (cf::EVENT_PLAYER_TELL, $target, $msg);
850 root 1.1
851 pippijn 1.9 my $name = $pl->name;
852 root 1.1
853     if ($target =~ /irc\//) {
854     my (undef, $nick) = split /\//, $target, 2;
855 pippijn 1.9 $pl->message ("You tell $target: $args");
856 root 1.1 ext::schmorp_irc::do_notice (sprintf "(%s) %s: %s\n", $name, $nick, $msg);
857 root 1.3 } elsif (my $other = cf::player::find_active $target) {
858 root 1.1
859     if ($msg) {
860     if ($target eq $name) {
861 pippijn 1.9 $pl->message ("You are talking to yourself, you freak!", cf::NDI_UNIQUE);
862 root 1.1 } elsif ($other->ob->{ext_ignore_tell}{$name} >= time) {
863 pippijn 1.9 $pl->message ("$target ignores what you say. Give up on it.", cf::NDI_UNIQUE);
864 root 1.1 } else {
865     utf8::encode $msg; # ->message not yet utf8-ified
866     cf::LOG cf::llevDebug, sprintf "TELL [%s>%s] %s\n", $name, $target, $msg;
867    
868 pippijn 1.9 $pl->message ("You tell $target: $msg");
869 root 1.1 $other->ob->message ("$name tells you: $msg");
870     $other->ob->{ext_last_tell} = $name;
871     }
872     } else {
873 pippijn 1.9 $pl->message ("What do you want to tell $target?", cf::NDI_UNIQUE);
874 root 1.1 }
875    
876     } else {
877 pippijn 1.9 $pl->message ("No such player. Your message: $msg", cf::NDI_UNIQUE);
878 root 1.1 }
879     };
880    
881     cf::register_command reply => sub {
882 pippijn 1.9 my ($pl, $args) = @_;
883     my $name = $pl->name;
884 root 1.1
885     utf8::decode $args;
886    
887 pippijn 1.9 return if $pl->contr->invoke (cf::EVENT_PLAYER_TELL, $pl->{ext_last_tell}, $args);
888 root 1.1
889 pippijn 1.9 if ($pl->{ext_last_tell} =~ /irc\//) {
890     my (undef, $nick) = split /\//, $pl->{ext_last_tell}, 2;
891     $pl->message ("You tell " . $pl->{ext_last_tell} . ": $args");
892 root 1.1 ext::schmorp_irc::do_notice (sprintf "(%s) %s: %s\n", $name, $nick, $args);
893 pippijn 1.9 } elsif (my $other = cf::player::find_active $pl->{ext_last_tell}) {
894 root 1.1
895     if ($args) {
896     $other->ob->{ext_ignore_tell}{$name} >= time
897     or delete $other->ob->{ext_ignore_tell}{$name};
898    
899     if ($other->ob->{ext_ignore_tell}{$name} < time) {
900     utf8::encode $args; # ->message not yet utf8-ified
901     cf::LOG cf::llevDebug, sprintf "TELL [%s>%s] %s\n", $name, $other->ob->name, $args;
902    
903 pippijn 1.9 $pl->message ("You tell " . $other->ob->name . ": $args");
904 root 1.1 $other->ob->message ("$name tells you: $args");
905 pippijn 1.9 $pl->{ext_last_tell} = $other->ob->name;
906 root 1.1 } else {
907 pippijn 1.9 $pl->message ($other->ob->name . " ignores what you say. Give up on it.", cf::NDI_UNIQUE);
908 root 1.1 }
909     } else {
910 pippijn 1.9 $pl->message ("What do you want to tell ".$other->ob->name."?", cf::NDI_UNIQUE);
911 root 1.1 }
912    
913     } else {
914 pippijn 1.9 $pl->message ("Can't reply, player left. Your message: $args".$pl->{ext_last_tell}, cf::NDI_UNIQUE);
915 root 1.1 }
916     };
917    
918     cf::register_command ignore => sub {
919 pippijn 1.9 my ($pl, $args) = @_;
920 root 1.1 my ($target, $type, $timeout) = split /\s+/, $args;
921    
922     if ($args eq "list") {
923 pippijn 1.9 clean_timeouts $pl;
924 root 1.1
925 pippijn 1.9 if ((my @ignored_tell = sort keys %{$pl->{ext_ignore_tell}})
926     + (my @ignored_shout = sort keys %{$pl->{ext_ignore_shout}})) {
927     $pl->message ("Currently ignoring private messages from: ", cf::NDI_UNIQUE);
928     $pl->message ((join ", ", @ignored_tell), cf::NDI_UNIQUE);
929     $pl->message ("Currently ignoring shouts from: ", cf::NDI_UNIQUE);
930     $pl->message ((join ", ", @ignored_shout), cf::NDI_UNIQUE);
931     $pl->message ("To stop ignoring one, use unignore.", cf::NDI_UNIQUE);
932 root 1.1 } else {
933 pippijn 1.9 $pl->message ("Not ignoring anyone", cf::NDI_UNIQUE);
934 root 1.1 }
935    
936     } elsif ($target && $type) {
937    
938     $timeout ne "" or $timeout = 24;
939     my $absolute_timeout = time + $timeout * 3600;
940    
941     if (cf::player::exists $target) {
942     if ($type eq "tell") {
943 pippijn 1.9 $pl->message ("Now ignoring private messages from $target for $timeout hours.", cf::NDI_UNIQUE);
944     $pl->{ext_ignore_tell}{$target} = $absolute_timeout;
945 root 1.1 } elsif ($type eq "shout") {
946 pippijn 1.9 $pl->message ("Now ignoring shouts from $target for $timeout hours.", cf::NDI_UNIQUE);
947     $pl->{ext_ignore_shout}{$target} = $absolute_timeout;
948 root 1.1 } elsif ($type eq "all") {
949 pippijn 1.9 $pl->message ("Now ignoring everything from $target for $timeout hours.", cf::NDI_UNIQUE);
950     $pl->{ext_ignore_tell}{$target} = $absolute_timeout;
951     $pl->{ext_ignore_shout}{$target} = $absolute_timeout;
952 root 1.1 } else {
953 pippijn 1.9 $pl->message ("You need to specify tell, shout or all.", cf::NDI_UNIQUE);
954 root 1.1 }
955     } else {
956 pippijn 1.9 $pl->message ("No such player: $target", cf::NDI_UNIQUE);
957 root 1.1 }
958    
959     } else {
960 pippijn 1.9 $pl->message ("Usage: ignore <player> <tell|shout|all> <timeout>\n"
961 root 1.1 . "will ignore a player for <timeout> hours.\n"
962     . "Usage: ignore list\n"
963     . "will show you a list of players currently ignored.", cf::NDI_UNIQUE);
964     }
965     };
966    
967     cf::register_command unignore => sub {
968 pippijn 1.9 my ($pl, $args) = @_;
969 root 1.1 my ($target, $type) = split /\s+/, $args;
970    
971     if ($args eq "") {
972 pippijn 1.9 if ($pl->{ext_ignore_tell}) {
973     $pl->message ("Currently ignoring private messages from: ", cf::NDI_UNIQUE);
974     $pl->message ((join ", ", sort keys %{ $pl->{ext_ignore_tell} }), cf::NDI_UNIQUE);
975     $pl->message ("Currently ignoring shouts from: ", cf::NDI_UNIQUE);
976     $pl->message ((join ", ", sort keys %{ $pl->{ext_ignore_shout} }), cf::NDI_UNIQUE);
977 root 1.1 } else {
978 pippijn 1.9 $pl->message ("Not ignoring anyone", cf::NDI_UNIQUE);
979 root 1.1 }
980     } else {
981     if (cf::player::exists $target) {
982     if ($type eq "tell") {
983 pippijn 1.9 $pl->message ("Not ignoring private messages from $target anymore.", cf::NDI_UNIQUE);
984     delete $pl->{ext_ignore_tell} {$target};
985 root 1.1 } elsif ($type eq "shout") {
986 pippijn 1.9 $pl->message ("Not ignoring shouts from $target anymore.", cf::NDI_UNIQUE);
987     delete $pl->{ext_ignore_shout}{$target};
988 root 1.1 } elsif ($type eq "all") {
989 pippijn 1.9 $pl->message ("Not ignoring anything from $target anymore.", cf::NDI_UNIQUE);
990     delete $pl->{ext_ignore_tell} {$target};
991     delete $pl->{ext_ignore_shout}{$target};
992 root 1.1 } else {
993 pippijn 1.9 $pl->message ("You need to specify tell, shout or all.", cf::NDI_UNIQUE);
994 root 1.1 }
995     } else {
996 pippijn 1.9 $pl->message ("No such player or ambiguous name: $target", cf::NDI_UNIQUE);
997 root 1.1 }
998     }
999     };
1000    
1001     cf::register_command seen => sub {
1002 pippijn 1.9 my ($pl, $args) = @_;
1003 root 1.1
1004     if (my ($login) = $args =~ /(\S+)/) {
1005 pippijn 1.9 if ($login eq $pl->name) {
1006     $pl->message ("Very funny, $login. Ha. Ha.", cf::NDI_UNIQUE);
1007 root 1.3 } elsif (cf::player::find_active $login) {
1008 pippijn 1.9 $pl->message ("$login is right here on this server!", cf::NDI_UNIQUE);
1009 root 1.1 } elsif (cf::player::exists $login
1010     and stat sprintf "%s/%s/%s/%s.pl", cf::localdir, cf::playerdir, ($login) x 2) {
1011     my $time = (stat _)[9];
1012    
1013 pippijn 1.9 $pl->message ("$login was last seen here "
1014 root 1.1 . (POSIX::strftime "%Y-%m-%d %H:%M:%S +0000", gmtime $time)
1015     . " which was " . (int +(time - $time) / 3600) . " hours ago.", cf::NDI_UNIQUE);
1016     } else {
1017 pippijn 1.9 $pl->message ("No player named $login is known to me.", cf::NDI_UNIQUE);
1018 root 1.1 }
1019     } else {
1020 pippijn 1.9 $pl->message ("Usage: seen <player>", cf::NDI_UNIQUE);
1021 root 1.1 }
1022     };
1023