ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/chat.ext
Revision: 1.47
Committed: Sun Jan 25 23:56:13 2009 UTC (15 years, 3 months ago) by root
Branch: MAIN
Changes since 1.46: +19 -15 lines
Log Message:
*** empty log message ***

File Contents

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