ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/chat.ext
Revision: 1.54
Committed: Thu Apr 22 12:50:24 2010 UTC (14 years, 1 month ago) by root
Branch: MAIN
Changes since 1.53: +2 -2 lines
Log Message:
update to use newer cf::rndm and AE::Now

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.54 my $coin = (cf::rndm 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 root 1.54 my ($i, $j, $k, $l) = map +(cf::rndm $_), 5, 5, 5, 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 root 1.50 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.50 hug => {
234     noparams => {
235     other => "<self> makes weird body movements.",
236     self => "All the lonely people...",
237     },
238     params => {
239 root 1.51 target => "<self> suddenly grabs you and gives you a bear hug.",
240 root 1.50 other => "<self> hugs <other>.",
241     self => "You hug <other>.",
242     },
243     self => {
244     other => "<self> tries to hug G<himself|herself>, but stumbles and now feels stupid.",
245     self => "You try and fail to hug yourself.",
246     },
247     },
248 root 1.37 smother => {
249     noparams => {
250     other => "<self> makes weird facial contortions",
251 root 1.50 self => "All the lonely people...",
252 root 1.37 },
253     params => {
254     target => "<self> smothers you with kisses.",
255     other => "<self> smothers <other> with kisses.",
256     self => "You smother <other> with kisses.",
257     },
258     self => {
259     },
260     },
261 pippijn 1.4 wink => {
262     noparams => {
263 pippijn 1.5 other => "<self> winks suggestively.",
264     self => "Have you got something in your eye?",
265 pippijn 1.4 },
266     params => {
267 pippijn 1.11 target => "<self> winks at you.",
268     other => "<self> winks at <other>.",
269 pippijn 1.5 self => "You wink suggestively at <other>.",
270 pippijn 1.4 },
271     self => {
272 root 1.44 other => "<self> winks at G<him|her>self - something strange is going on...",
273 pippijn 1.5 self => "You wink at yourself?? What are you up to?",
274 pippijn 1.4 },
275     },
276     pout => {
277     noparams => {
278 pippijn 1.5 other => "<self> pouts.",
279     self => "Aww, don't take it so hard.",
280 pippijn 1.4 },
281     params => {
282     },
283     self => {
284     },
285     },
286     cackle => {
287     noparams => {
288 root 1.44 other => "<self> throws back G<his|her> head and cackles with insane glee!",
289 pippijn 1.5 self => "You cackle gleefully.",
290 pippijn 1.4 },
291     params => {
292     },
293     self => {
294     },
295     },
296     sniff => {
297     noparams => {
298 pippijn 1.5 other => "<self> sniffs sadly.",
299     self => "You sniff sadly. *SNIFF*",
300 pippijn 1.4 },
301     params => {
302 pippijn 1.5 target => "<self> sniffs you.",
303     other => "<self> sniffs <other>",
304     self => "You sniff <other>.",
305 pippijn 1.4 },
306     self => {
307 root 1.44 other => "<self> sniffs G<him|her>self.",
308 pippijn 1.5 self => "You sniff yourself.",
309 pippijn 1.4 },
310     },
311     nod => {
312     noparams => {
313 pippijn 1.5 other => "<self> nods solemnly.",
314     self => "You nod solemnly.",
315 pippijn 1.4 },
316     params => {
317 root 1.44 target => "<self> nods solemnly at you.",
318     other => "<self> nods solemnly at <other>.",
319     self => "You nod solemnly at <other>.",
320 pippijn 1.4 },
321     self => {
322     },
323     },
324     frown => {
325     noparams => {
326 pippijn 1.5 other => "<self> frowns.",
327     self => "What's bothering you?",
328 pippijn 1.4 },
329     params => {
330 pippijn 1.5 target => "<self> frowns darkly at you.",
331     other => "<self> frowns darkly at <other>.",
332     self => "You frown darkly at <other>.",
333 pippijn 1.4 },
334     self => {
335 root 1.44 other => "<self> frowns at G<him|her>self.",
336 pippijn 1.5 self => "You frown at yourself.",
337 pippijn 1.4 },
338     },
339     snicker => {
340     noparams => {
341 pippijn 1.5 other => "<self> snickers softly.",
342     self => "You snicker softly.",
343 pippijn 1.4 },
344     params => {
345     },
346     self => {
347     },
348     },
349     shrug => {
350     noparams => {
351 pippijn 1.5 other => "<self> shrugs helplessly.",
352     self => "You shrug.",
353 pippijn 1.4 },
354     params => {
355 pippijn 1.5 target => "<self> shrugs at you.",
356     other => "<self> shrugs at <other>.",
357     self => "You shrug at <other>.",
358 pippijn 1.4 },
359     self => {
360     },
361     },
362     bleed => {
363     noparams => {
364 pippijn 1.5 other => "<self> is bleeding all over the carpet - got a spare tourniquet?",
365     self => "You bleed all over your nice new armour.",
366 pippijn 1.4 },
367     params => {
368 root 1.44 target => "<self> slashes G<his|her> wrist and bleeds all over you.",
369     other => "<self> slashes G<his|her> wrist and bleeds all over <other>.",
370 pippijn 1.5 self => "You slash your wrist and bleed all over <other>",
371 pippijn 1.4 },
372     self => {
373 root 1.44 other => "<self> performs some satanic ritual while wiping G<his|her> blood on G<him|her>self.",
374 pippijn 1.5 self => "Very impressive! You wipe your blood all over yourself.",
375 pippijn 1.4 },
376     },
377     twiddle => {
378     noparams => {
379 root 1.44 other => "<self> patiently twiddles G<his|her> thumbs.",
380 pippijn 1.5 self => "You patiently twiddle your thumbs.",
381 pippijn 1.4 },
382     params => {
383     },
384     self => {
385     },
386     },
387     spit => {
388     noparams => {
389 root 1.44 other => "<self> spits over G<his|her> left shoulder.",
390 pippijn 1.5 self => "You spit over your left shoulder.",
391 pippijn 1.4 },
392     params => {
393 pippijn 1.5 target => "<self> spits in your face!",
394     other => "<self> spits in <other>'s face.",
395     self => "You spit on <other>.",
396 pippijn 1.4 },
397     self => {
398 root 1.44 other => "<self> drools all over G<him|her>self.",
399 pippijn 1.5 self => "You drool all over yourself.",
400 pippijn 1.4 },
401     },
402     glare => {
403     noparams => {
404 root 1.44 other => "<self> glares around G<him|her>.",
405 pippijn 1.5 self => "You glare at nothing in particular.",
406 pippijn 1.4 },
407     params => {
408 pippijn 1.5 target => "<self> glares icily at you, you feel cold to your bones.",
409     other => "<self> glares at <other>.",
410     self => "You glare icily at <other>.",
411 pippijn 1.4 },
412     self => {
413 root 1.44 other => "<self> glares at G<his|her> feet, what is bothering G<him|her>?",
414 pippijn 1.5 self => "You glare icily at your feet, they are suddenly very cold.",
415 pippijn 1.4 },
416     },
417     bow => {
418     noparams => {
419 pippijn 1.5 other => "<self> bows deeply.",
420     self => "You bow deeply.",
421 pippijn 1.4 },
422     params => {
423 pippijn 1.5 target => "<self> bows before you.",
424     other => "<self> bows before <other>.",
425     self => "You bow before <other>.",
426 pippijn 1.4 },
427     self => {
428 root 1.44 other => "<self> folds up like a jackknife and kisses G<his|her> own toes.",
429 pippijn 1.5 self => "You kiss your toes.",
430 pippijn 1.4 },
431     },
432     dance => {
433     noparams => {
434 root 1.44 other => "<self> expresses G<him|her>self through interpretive dance.",
435 pippijn 1.5 self => "You dance with glee.",
436 pippijn 1.4 },
437     params => {
438 pippijn 1.5 target => "<self> grabs you, and begins dancing!",
439     other => "Yipe! <self> and <other> are doing the Macarena!",
440     self => "You grab <other> and begin doing the Cha-Cha!",
441 pippijn 1.4 },
442     self => {
443 root 1.44 other => "<self> embraces G<him|her>self and begins to dance!",
444 pippijn 1.5 self => "You skip and dance around by yourself.",
445 pippijn 1.4 },
446     },
447     snore => {
448     noparams => {
449 pippijn 1.5 other => "<self> snores loudly.",
450     self => "Zzzzzzzzzzzzzzz.",
451 pippijn 1.4 },
452     params => {
453     },
454     self => {
455     },
456     },
457     blush => {
458     noparams => {
459 pippijn 1.5 other => "<self> blushes.",
460     self => "Your cheeks are burning.",
461 pippijn 1.4 },
462     params => {
463     },
464     self => {
465     },
466     },
467     snap => {
468     noparams => {
469 root 1.44 other => "<self> snaps G<his|her> fingers.",
470 pippijn 1.5 self => "PRONTO! you snap your fingers.",
471 pippijn 1.4 },
472     params => {
473     },
474     self => {
475     },
476     },
477     wave => {
478     noparams => {
479 pippijn 1.5 other => "<self> waves happily.",
480     self => "You wave.",
481 pippijn 1.4 },
482     params => {
483 pippijn 1.5 target => "<self> waves goodbye to you. Have a good journey.",
484     other => "<self> waves goodbye to <other>.",
485     self => "You wave goodbye to <other>.",
486 pippijn 1.4 },
487     self => {
488 root 1.44 other => "<self> waves goodbye to G<him|her>self.",
489 pippijn 1.5 self => "Are you going on adventures as well??",
490 pippijn 1.4 },
491     },
492     smile => {
493     noparams => {
494 pippijn 1.5 other => "<self> smiles happily.",
495     self => "You smile happily.",
496 pippijn 1.4 },
497     params => {
498 pippijn 1.5 target => "<self> smiles at you.",
499     other => "<self> beams a smile at <other>.",
500     self => "You smile at <other>.",
501 pippijn 1.4 },
502     self => {
503     },
504     },
505     sneeze => {
506     noparams => {
507 pippijn 1.5 other => "<self> sneezes.",
508     self => "Gesundheit!",
509 pippijn 1.4 },
510     params => {
511 pippijn 1.5 target => "<self> sneezes on you, you feel the snot cover you. EEEEEEW.",
512 root 1.44 other => "<self> sneezes on <other> and a film of snot covers G<him|her>.",
513     self => "You sneeze at <other> and a film of snot shoots onto G<him|her>.",
514 pippijn 1.4 },
515     self => {
516 root 1.44 other => "<self> sneezes, and covers G<him|her>self in a slimy substance.",
517 pippijn 1.5 self => "You sneeze on yourself, what a mess!",
518 pippijn 1.4 },
519     },
520     bounce => {
521     noparams => {
522 pippijn 1.5 other => "<self> bounces around.",
523     self => "BOIINNNNNNGG!",
524 pippijn 1.4 },
525     params => {
526 pippijn 1.5 target => "<self> bounces around the room with you.",
527     other => "<self> bounces around the room with <other>.",
528     self => "You bounce around the room with <other>.",
529 pippijn 1.4 },
530     self => {
531     },
532     },
533     shake => {
534     noparams => {
535 root 1.44 other => "<self> shakes G<his|her> head.",
536 pippijn 1.5 self => "You shake your head.",
537 pippijn 1.4 },
538     params => {
539 pippijn 1.5 target => "<self> shakes your hand.",
540     other => "<self> shakes <other>'s hand.",
541     self => "You shake <other>'s hand.",
542 pippijn 1.4 },
543     self => {
544 pippijn 1.5 other => "<self> shakes and quivers like a bowlful of jelly.",
545     self => "You are shaken by yourself.",
546 pippijn 1.4 },
547     },
548     lick => {
549     noparams => {
550 root 1.44 other => "<self> licks G<his|her> mouth and smiles.",
551 pippijn 1.5 self => "You lick your mouth and smile.",
552 pippijn 1.4 },
553     params => {
554 pippijn 1.5 target => "<self> licks you.",
555     other => "<self> licks <other>.",
556     self => "You lick <other>.",
557 pippijn 1.4 },
558     self => {
559 root 1.44 other => "<self> licks G<him|her>self - YUCK.",
560 pippijn 1.5 self => "You lick yourself.",
561 pippijn 1.4 },
562     },
563     flip => {
564     noparams => {
565 pippijn 1.5 other => "<self> flips head over heels.",
566     self => "You flip head over heels.",
567 pippijn 1.4 },
568     params => {
569     },
570     self => {
571     },
572     },
573     think => {
574     noparams => {
575 root 1.44 other => "<self> closes G<his|her> eyes and thinks really hard.",
576 pippijn 1.5 self => "Anything in particular that you'd care to think about?",
577 pippijn 1.4 },
578     params => {
579     },
580     self => {
581     },
582     },
583     yawn => {
584     noparams => {
585 pippijn 1.5 other => "<self> yawns sleepily.",
586     self => "You open up your yap and let out a big breeze of stale air.",
587 pippijn 1.4 },
588     params => {
589     },
590     self => {
591     },
592     },
593     laugh => {
594     noparams => {
595 pippijn 1.5 other => "<self> falls down laughing.",
596     self => "You fall down laughing.",
597 pippijn 1.4 },
598     params => {
599 pippijn 1.5 target => "<self> looks at you and falls down on the ground laughing.",
600     other => "<self> looks at <other> and falls down on the ground laughing.",
601     self => "You take one look at <other> and fall down laughing.",
602 pippijn 1.4 },
603     self => {
604 pippijn 1.5 other => "<self> is laughing at something.",
605     self => "Laugh at yourself all you want, the others won't understand.",
606 pippijn 1.4 },
607     },
608     burp => {
609     noparams => {
610 pippijn 1.5 other => "<self> burps loudly.",
611     self => "You burp loudly.",
612 pippijn 1.4 },
613     params => {
614     },
615     self => {
616     },
617     },
618     gasp => {
619     noparams => {
620 pippijn 1.5 other => "<self> gasps in astonishment.",
621     self => "You gasp in astonishment.",
622 pippijn 1.4 },
623     params => {
624     },
625     self => {
626     },
627     },
628     smirk => {
629     noparams => {
630 pippijn 1.5 other => "<self> smirks.",
631     self => "You smirk.",
632 pippijn 1.4 },
633     params => {
634     },
635     self => {
636     },
637     },
638     cry => {
639     noparams => {
640 pippijn 1.5 other => "<self> bursts into tears.",
641     self => "Waaaaaaahhh..",
642 pippijn 1.4 },
643     params => {
644 pippijn 1.5 target => "<self> cries on your shoulder.",
645     other => "<self> cries on <other>'s shoulder.",
646     self => "You cry on <other>'s shoulder.",
647 pippijn 1.4 },
648     self => {
649 root 1.44 other => "<self> sobs quietly to G<him|her>self.",
650 pippijn 1.5 self => "You cry to yourself.",
651 pippijn 1.4 },
652     },
653     sulk => {
654     noparams => {
655 pippijn 1.5 other => "<self> sulks in the corner.",
656     self => "You sulk.",
657 pippijn 1.4 },
658     params => {
659     },
660     self => {
661     },
662     },
663     whistle => {
664     noparams => {
665 pippijn 1.5 other => "<self> whistles appreciatively.",
666     self => "You whistle appreciatively.",
667 pippijn 1.4 },
668     params => {
669 pippijn 1.5 target => "<self> whistles at <other>.",
670     self => "You whistle at <other>.",
671 pippijn 1.4 },
672     self => {
673 root 1.44 other => "<self> whistles to G<him|her>self in boredom.",
674 pippijn 1.5 self => "You whistle while you work.",
675 pippijn 1.4 },
676     },
677     groan => {
678     noparams => {
679 pippijn 1.5 other => "<self> groans loudly.",
680     self => "You groan loudly.",
681 pippijn 1.4 },
682     params => {
683     },
684     self => {
685     },
686     },
687     cough => {
688     noparams => {
689 pippijn 1.5 other => "<self> coughs loudly.",
690     self => "Yuck, try to cover your mouth next time!",
691 pippijn 1.4 },
692     params => {
693     },
694     self => {
695     },
696     },
697     grin => {
698     noparams => {
699 pippijn 1.5 other => "<self> grins evilly.",
700     self => "You grin evilly.",
701 pippijn 1.4 },
702     params => {
703 pippijn 1.5 target => "<self> grins evilly at you.",
704     other => "<self> grins evilly at <other>.",
705     self => "You grin at <other>.",
706 pippijn 1.4 },
707     self => {
708     },
709     },
710     };
711 pippijn 1.7
712 pippijn 1.4 for my $emotion (keys %$emotes) {
713     cf::register_command $emotion => sub {
714 root 1.29 my ($ob, $tname) = @_;
715    
716     my $pl = $ob->contr;
717 pippijn 1.4
718     cf::async {
719 root 1.29 my $name = $ob->name;
720 root 1.33 $Coro::current->{desc} = "emote handler for $name";
721 pippijn 1.4
722     if ($tname eq $name) {
723 root 1.29 my %emote = %{ $emotes->{$emotion}->{self} || {} };
724 pippijn 1.7
725 root 1.29 $emote{other} ||= "You look away from <self>.";
726     $emote{self} ||= "My god! Is that LEGAL?";
727 pippijn 1.7
728 root 1.29 $emote{other} =~ s/<self>/$name/;
729 root 1.44
730     $_ = $pl->expand_cfpod ($_)
731     for values %emote;
732 pippijn 1.4
733 root 1.44 send_msg $_, $cf::CHAT_CHANNEL, $emote{other}, cf::NDI_GREY | cf::NDI_VERBATIM, "msg_chat"
734 root 1.29 for grep { $ob->on_same_map_as ($_->ob) && $_ != $ob} cf::player::list;
735 pippijn 1.4
736 root 1.44 $pl->send_msg ($emote{self}, cf::NDI_GREY | cf::NDI_REPLY | cf::NDI_VERBATIM);
737 pippijn 1.4 } elsif ($tname) {
738     my $target = cf::player::find $tname
739 root 1.34 or return send_msg $pl, tell_channel $tname, "$tname is not around.", cf::NDI_DK_ORANGE | cf::NDI_REPLY, "msg_chat";
740 pippijn 1.4
741 root 1.29 my %emote = %{ $emotes->{$emotion}->{params} || {} };
742 pippijn 1.7
743 root 1.29 $emote{other} ||= "<self> is eyeing <other> quizzically.";
744     $emote{self} ||= "You are still nuts.";
745 root 1.38 $emote{target} ||= "You get the distinct feeling that <self> is nuts.";
746 root 1.29
747     $emote{self} =~ s/<other>/$tname/;
748     $emote{target} =~ s/<self>/$name/;
749     $emote{other} =~ s/<other>/$tname/;
750     $emote{other} =~ s/<self>/$name/;
751 pippijn 1.4
752 root 1.44 $_ = $pl->expand_cfpod ($_)
753     for values %emote;
754    
755     send_msg $_, $cf::CHAT_CHANNEL, $emote{other}, cf::NDI_GREY | cf::NDI_VERBATIM, "msg_chat"
756 root 1.29 for grep { $_ != $pl && $_ != $target && $ob->on_same_map_as ($_->ob) } cf::player::list;
757 pippijn 1.4
758 root 1.44 send_msg $target, tell_channel $name, $emote{target}, cf::NDI_GREY | cf::NDI_VERBATIM, "msg_shout";
759     $pl->send_msg (tell_channel $tname, $emote{self}, cf::NDI_GREY | cf::NDI_REPLY | cf::NDI_VERBATIM);
760 pippijn 1.4 } else {
761 root 1.29 my %emote = %{ $emotes->{$emotion}->{noparams} || {} };
762 pippijn 1.7
763 root 1.29 $emote{other} ||= "<self> dances with glee.";
764     $emote{self} ||= "You are a nut.";
765 pippijn 1.4
766 root 1.29 $emote{other} =~ s/<self>/$name/;
767    
768 root 1.44 $_ = $pl->expand_cfpod ($_)
769     for values %emote;
770    
771     send_msg $_, $cf::CHAT_CHANNEL, $emote{other}, cf::NDI_GREY | cf::NDI_VERBATIM, "msg_chat"
772 root 1.29 for grep { $ob->on_same_map_as ($_->ob) && $_ != $pl } cf::player::list;
773 pippijn 1.4
774 root 1.44 $pl->send_msg ($cf::CHAT_CHANNEL, $emote{self}, cf::NDI_GREY | cf::NDI_REPLY | cf::NDI_VERBATIM);
775 pippijn 1.4 }
776     };
777     };
778     }
779    
780 root 1.1 cf::register_command say => sub {
781 root 1.23 my ($ob, $msg) = @_;
782 root 1.1
783     utf8::decode $msg;
784    
785 root 1.23 return if $ob->contr->invoke (cf::EVENT_PLAYER_SAY, $msg);
786 root 1.1
787     if ($msg) {
788 root 1.23 my $name = $ob->name;
789     my @plonmap = grep $ob->on_same_map_as ($_->ob), cf::player::list;
790 root 1.1
791 root 1.40 send_msg $_, $cf::SAY_CHANNEL => "$name says: $msg", cf::NDI_GREY, "msg_say"
792 root 1.35 for grep $_ != $ob->contr, @plonmap;
793 root 1.40 $ob->contr->send_msg ($cf::SAY_CHANNEL => "$name says: $msg", cf::NDI_GREY | cf::NDI_REPLY);
794 root 1.1
795 root 1.52 my @npc;
796    
797 root 1.1 # npcs, magic_ears etc.
798 root 1.16 # first find all objects and their first-level inventories
799     # within a 5x5 square that have something resembling
800 root 1.1 # dialogue or support on_say.
801 root 1.52 # we prefer the nearest items NOT in the player, otherwise in player.
802     my ($map, $x, $y) = ($ob->map, $ob->x, $ob->y);
803    
804 root 1.53 for my $dir (
805     0,
806     1, 3, 5, 7,
807     2, 4, 6, 8,
808     9 .. cf::SIZEOFFREE2
809     ) {
810 root 1.52 @npc = grep $_->should_invoke (cf::EVENT_OBJECT_SAY) || $_->has_dialogue,
811     map +($_, $_->inv),
812     grep $_ != $ob,
813     $map->at ($x, $y, $dir)
814     and last;
815     }
816    
817     unless (@npc) {
818     # nothing found, try the player inventory
819     @npc = grep $_->should_invoke (cf::EVENT_OBJECT_SAY) || $_->has_dialogue,
820     $ob->inv;
821     }
822    
823     for my $npc (@npc) {
824     return if $npc->invoke (cf::EVENT_OBJECT_SAY);
825 root 1.1
826     # if some listener teleported us somewhere else, stop right here
827 root 1.23 last unless $map->path == $ob->map->path;
828 root 1.1
829 root 1.52 if ($npc->has_dialogue) {
830     my $dialog = new NPC_Dialogue pl => $ob->contr, npc => $npc;
831     my ($reply, @kw) = $dialog->tell ($msg);
832    
833     if (defined $reply) {
834     if ($npc->type == cf::MAGIC_EAR) {
835     send_msg $_, $cf::SAY_CHANNEL => $reply, cf::NDI_BROWN, "msg_say"
836     for @plonmap;
837     } else {
838     send_msg $_, $cf::SAY_CHANNEL => $npc->name . " says: $reply", cf::NDI_BROWN, "msg_say"
839     for @plonmap;
840     }
841     }
842 root 1.1
843 root 1.52 if (@kw) {
844     $_->send_msg ($cf::SAY_CHANNEL => "[further topics: " . (join ", ", @kw) . "]", cf::NDI_BROWN)
845 root 1.46 for @plonmap;
846 root 1.1 }
847     }
848     }
849    
850     } else {
851 root 1.40 $ob->send_msg ($cf::SAY_CHANNEL => "What do you want to say?", cf::NDI_GREY | cf::NDI_REPLY);
852 root 1.1 }
853     };
854    
855 root 1.47
856     sub _chat {
857 root 1.27 my ($ob, $msg) = @_;
858 root 1.1
859 root 1.27 my $pl = $ob->contr;
860    
861     return if $pl->invoke (cf::EVENT_PLAYER_CHAT, $msg);
862 root 1.1
863     if ($msg) {
864 root 1.28 my $name = $ob->name;
865 root 1.1 my $NOW = time;
866    
867 root 1.48 cf::LOG cf::llevDebug, sprintf "QBERT %s\n", $msg;
868 root 1.49 send_irc ("%s", $msg);
869 root 1.1
870 root 1.47 send_msg $_, $cf::CHAT_CHANNEL => $msg, cf::NDI_BLUE | cf::NDI_DEF | ($_ == $pl ? cf::NDI_REPLY : 0), "msg_chat"
871 root 1.43 for grep { $_->ob->{ext_ignore_shout}{$name} < $NOW } cf::player::list;
872 root 1.1
873     } else {
874 root 1.40 $pl->send_msg ($cf::CHAT_CHANNEL => "Chat what?", cf::NDI_BLUE | cf::NDI_DEF | cf::NDI_REPLY);
875 root 1.1 }
876 root 1.47 }
877    
878     cf::register_command chat => sub {
879     my ($ob, $msg) = @_;
880    
881     utf8::decode $msg;
882     _chat $ob, $ob->name . " chats: $msg";
883     };
884    
885     cf::register_command me => sub {
886     my ($ob, $msg) = @_;
887    
888     utf8::decode $msg;
889     _chat $ob, "* " . $ob->name . " $msg";
890 root 1.1 };
891    
892     cf::register_command shout => sub {
893 root 1.28 my ($ob, $msg) = @_;
894 root 1.1
895     utf8::decode $msg;
896    
897 root 1.27 my $pl = $ob->contr;
898    
899     return if $pl->invoke (cf::EVENT_PLAYER_SHOUT, $msg);
900 root 1.1
901     if ($msg) {
902     my $NOW = time;
903 root 1.28 my $name = $ob->name;
904 root 1.1
905     cf::LOG cf::llevDebug, sprintf "QBERT {%s} %s\n", $name, $msg;
906 elmex 1.20 send_irc ("\007\0034{%s} %s\n", $name, $msg);
907 root 1.1
908 root 1.40 send_msg $_, $cf::CHAT_CHANNEL => "$name shouts: $msg", cf::NDI_RED | cf::NDI_DEF | ($_ == $pl ? cf::NDI_REPLY : 0), "msg_shout"
909 root 1.43 for grep { $_->ob->{ext_ignore_shout}{$name} < $NOW } cf::player::list;
910 root 1.1
911     } else {
912 root 1.40 $pl->send_msg ($cf::CHAT_CHANNEL => "Shout what?", cf::NDI_RED | cf::NDI_DEF | cf::NDI_REPLY);
913 root 1.1 }
914     };
915    
916     cf::register_command tell => sub {
917 root 1.21 my ($ob, $args) = @_;
918 root 1.1 my ($target, $msg) = split /\s+/, $args, 2;
919    
920     utf8::decode $msg;
921    
922 root 1.21 my $pl = $ob->contr;
923     my $ns = $pl->ns
924     or return;
925     my $name = $ob->name;
926    
927     return if $pl->invoke (cf::EVENT_PLAYER_TELL, $target, $msg);
928    
929 root 1.29 my $pl_channel = tell_channel $target;
930 root 1.1
931     if ($target =~ /irc\//) {
932     my (undef, $nick) = split /\//, $target, 2;
933 root 1.29 $ns->send_msg ($pl_channel => "You tell $target: $args", cf::NDI_DK_ORANGE | cf::NDI_DEF | cf::NDI_REPLY);
934 elmex 1.20 send_irc ("(%s) %s: %s\n", $name, $nick, $msg);
935 root 1.29
936 root 1.3 } elsif (my $other = cf::player::find_active $target) {
937 root 1.29 my $other_channel = tell_channel $name;
938 root 1.1
939     if ($msg) {
940     if ($target eq $name) {
941 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);
942 root 1.1 } elsif ($other->ob->{ext_ignore_tell}{$name} >= time) {
943 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);
944 root 1.1 } else {
945 root 1.25 return if $other->invoke (cf::EVENT_PLAYER_TOLD, $pl, $msg);
946 root 1.1 cf::LOG cf::llevDebug, sprintf "TELL [%s>%s] %s\n", $name, $target, $msg;
947    
948 root 1.29 $ns->send_msg ($pl_channel => "You tell $target: $msg", cf::NDI_DK_ORANGE | cf::NDI_DEF | cf::NDI_REPLY);
949 root 1.34 send_msg $other, $other_channel => "$name tells you: $msg", cf::NDI_DK_ORANGE | cf::NDI_DEF, "msg_tell";
950 root 1.1 }
951     } else {
952 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);
953 root 1.1 }
954    
955     } else {
956 root 1.29 $ns->send_msg ($pl_channel => "No such player. Your message: $msg", cf::NDI_DK_ORANGE | cf::NDI_DEF | cf::NDI_REPLY);
957 root 1.1 }
958     };
959    
960     cf::register_command ignore => sub {
961 pippijn 1.9 my ($pl, $args) = @_;
962 root 1.1 my ($target, $type, $timeout) = split /\s+/, $args;
963    
964 root 1.45 cf::async {
965     if ($args eq "list") {
966     clean_timeouts $pl;
967    
968     if ((my @ignored_tell = sort keys %{$pl->{ext_ignore_tell}})
969     + (my @ignored_shout = sort keys %{$pl->{ext_ignore_shout}})) {
970     $pl->message ("Currently ignoring private messages from: ", cf::NDI_REPLY);
971     $pl->message ((join ", ", @ignored_tell), cf::NDI_REPLY);
972     $pl->message ("Currently ignoring shouts from: ", cf::NDI_REPLY);
973     $pl->message ((join ", ", @ignored_shout), cf::NDI_REPLY);
974     $pl->message ("To stop ignoring one, use unignore.", cf::NDI_REPLY);
975     } else {
976     $pl->message ("Not ignoring anyone", cf::NDI_REPLY);
977     }
978 root 1.1
979 root 1.45 } elsif ($target && $type) {
980     $timeout ne "" or $timeout = 24;
981     my $absolute_timeout = time + $timeout * 3600;
982    
983     if (cf::player::exists $target) {
984     if ($type eq "tell") {
985     $pl->message ("Now ignoring private messages from $target for $timeout hours.", cf::NDI_REPLY);
986     $pl->{ext_ignore_tell}{$target} = $absolute_timeout;
987     } elsif ($type eq "shout") {
988     $pl->message ("Now ignoring shouts from $target for $timeout hours.", cf::NDI_REPLY);
989     $pl->{ext_ignore_shout}{$target} = $absolute_timeout;
990     } elsif ($type eq "all") {
991     $pl->message ("Now ignoring everything from $target for $timeout hours.", cf::NDI_REPLY);
992     $pl->{ext_ignore_tell}{$target} = $absolute_timeout;
993     $pl->{ext_ignore_shout}{$target} = $absolute_timeout;
994     } else {
995     $pl->message ("You need to specify tell, shout or all.", cf::NDI_REPLY);
996     }
997     } else {
998     $pl->message ("No such player: $target", cf::NDI_REPLY);
999     }
1000 root 1.1
1001     } else {
1002 root 1.45 $pl->message ("Usage: ignore <player> <tell|shout|all> <timeout>\n"
1003     . "will ignore a player for <timeout> hours.\n"
1004     . "Usage: ignore list\n"
1005     . "will show you a list of players currently ignored.", cf::NDI_REPLY);
1006 root 1.1 }
1007 root 1.45 };
1008 root 1.1 };
1009    
1010     cf::register_command unignore => sub {
1011 pippijn 1.9 my ($pl, $args) = @_;
1012 root 1.1 my ($target, $type) = split /\s+/, $args;
1013    
1014 root 1.45 cf::async {
1015     if ($args eq "") {
1016     if ($pl->{ext_ignore_tell}) {
1017     $pl->message ("Currently ignoring private messages from: ", cf::NDI_REPLY);
1018     $pl->message ((join ", ", sort keys %{ $pl->{ext_ignore_tell} }), cf::NDI_REPLY);
1019     $pl->message ("Currently ignoring shouts from: ", cf::NDI_REPLY);
1020     $pl->message ((join ", ", sort keys %{ $pl->{ext_ignore_shout} }), cf::NDI_REPLY);
1021     } else {
1022     $pl->message ("Not ignoring anyone", cf::NDI_REPLY);
1023     }
1024 root 1.1 } else {
1025 root 1.45 if (cf::player::exists $target) {
1026     if ($type eq "tell") {
1027     $pl->message ("Not ignoring private messages from $target anymore.", cf::NDI_REPLY);
1028     delete $pl->{ext_ignore_tell} {$target};
1029     } elsif ($type eq "shout") {
1030     $pl->message ("Not ignoring shouts from $target anymore.", cf::NDI_REPLY);
1031     delete $pl->{ext_ignore_shout}{$target};
1032     } elsif ($type eq "all") {
1033     $pl->message ("Not ignoring anything from $target anymore.", cf::NDI_REPLY);
1034     delete $pl->{ext_ignore_tell} {$target};
1035     delete $pl->{ext_ignore_shout}{$target};
1036     } else {
1037     $pl->message ("You need to specify tell, shout or all.", cf::NDI_REPLY);
1038     }
1039 root 1.1 } else {
1040 root 1.45 $pl->message ("No such player or ambiguous name: $target", cf::NDI_REPLY);
1041 root 1.1 }
1042     }
1043 root 1.45 };
1044 root 1.1 };
1045