ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/chat.ext
Revision: 1.5
Committed: Wed Feb 28 19:23:21 2007 UTC (17 years, 2 months ago) by pippijn
Branch: MAIN
Changes since 1.4: +193 -208 lines
Log Message:
forgot ,

File Contents

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