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