ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/chat.ext
Revision: 1.20
Committed: Thu Jun 28 08:34:42 2007 UTC (16 years, 11 months ago) by elmex
Branch: MAIN
Changes since 1.19: +14 -4 lines
Log Message:
made multiline chats possible

File Contents

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