--- deliantra/maps/perl/chat.ext 2006/05/07 19:51:50 1.13 +++ deliantra/maps/perl/chat.ext 2006/07/30 19:56:57 1.27 @@ -1,11 +1,10 @@ #! perl -# implement a replacement for the built-in chat/shout/tell/reply commands +# implement a replacement for the built-in say/chat/shout/tell/reply commands # adds ignore/unignore functionality -sub valid_user($) { - -f sprintf "%s/%s/%s/%s.pl", cf::localdir, cf::playerdir, ($_[0]) x 2; -} +use NPC_Dialogue; +use POSIX (); # for strftime only sub clean_timeouts($) { my ($player) = @_; @@ -14,10 +13,10 @@ for my $hash (@$player{qw(ext_ignore_shout ext_ignore_tell)}) { while (my ($k, $v) = each %$hash) { if ($v < $NOW) { - $player->message ("Your ignore on $k has expired.", cf::NDI_GREEN); + $player->message ("Your ignore on $k has expired.", cf::NDI_GREEN | cf::NDI_UNIQUE); delete $hash->{$k}; - } elsif (!valid_user $k) { - $player->message ("Your ignore on $k is no longer valid (no such user).", cf::NDI_GREEN); + } elsif (!cf::player::exists $k) { + $player->message ("Your ignore on $k is no longer valid (no such user).", cf::NDI_GREEN | cf::NDI_UNIQUE); delete $hash->{$k}; } } @@ -30,15 +29,94 @@ clean_timeouts $pl->ob; } +cf::register_command listen => 0, sub { + my ($who, $msg) = @_; + my $player = cf::player::find $who->name; + + if ($msg ne "") { + my $prev_listen = $player->listening; + $player->listening ($msg); + if ($prev_listen == $player->listening) { + $who->message ("Your verbose level stayed $prev_listen.", cf::NDI_UNIQUE); + } else { + $who->message ("Your verbose level is now " . $player->listening . ". (previously: $prev_listen)", cf::NDI_UNIQUE); + } + } else { + $who->message ("Your verbose level is " . $player->listening . ".", cf::NDI_UNIQUE); + } +}; + +cf::register_command say => 0, sub { + my ($who, $msg) = @_; + + utf8::decode $msg; + + if ($msg) { + my $name = $who->name; + + utf8::encode $msg; # ->message not yet utf8-ified + $_->ob->message ("$name says: $msg", cf::NDI_GREY | cf::NDI_UNIQUE) + for grep $who->on_same_map_as ($_->ob), cf::player::list; + utf8::decode $msg; + + # npcs, magic_ears etc. + # first find all objects and their inventories within a 5x5 square + # that have something resembling dialogue + my ($map, $x, $y) = ($who->map, $who->x - 2, $who->y - 2); + + for my $npc ( + grep NPC_Dialogue::has_dialogue $_, + map +($_, $_->inv), + grep $_, + map $map->at ($x + $_ % 5, $y + (int $_ / 5)), + 0..24 + ) { + # if some listener teleported us somewhere else, stop right here + last unless $map->path == $who->map->path; + + my $dialog = new NPC_Dialogue ob => $who, npc => $npc; + my ($reply, @kw) = $dialog->tell ($msg); + + if (defined $reply) { + if ($npc->type == cf::MAGIC_EAR) { + if (length $reply) { + $_->ob->message ($reply, cf::NDI_BROWN | cf::NDI_UNIQUE) + for grep $who->on_same_map_as ($_->ob), cf::player::list; + } + $npc->use_trigger; + } else { + if (length $reply) { + $_->ob->message ($npc->name . " says: $reply", cf::NDI_BROWN | cf::NDI_UNIQUE) + for grep $who->on_same_map_as ($_->ob), cf::player::list; + } + } + } + + if (@kw) { + $_->ob->message ("[further topics: " . (join ", ", @kw) . "]", cf::NDI_BROWN | cf::NDI_UNIQUE) + for grep $who->on_same_map_as ($_->ob), cf::player::list; + } + } + + } else { + $who->message ("What do you want to say?", cf::NDI_UNIQUE); + } +}; + cf::register_command chat => 0, sub { my ($who, $msg) = @_; + utf8::decode $msg; + if ($msg) { my $name = $who->name; my $NOW = time; + utf8::encode $msg; # ->message not yet utf8-ified + cf::LOG cf::llevDebug, sprintf "QBERT [%s] %s\n", $name, $msg; + $_->ob->message ("$name chats: $msg", cf::NDI_BLUE) - for grep { $_->ob->{ext_ignore_shout}{$name} and $_->listening >= 10 } < $NOW, cf::player::list; + for grep { $_->ob->{ext_ignore_shout}{$name} < $NOW && $_->listening >= 10 } cf::player::list; } else { $who->message ("Chat what?", cf::NDI_UNIQUE); @@ -48,12 +126,17 @@ cf::register_command shout => 0, sub { my ($who, $msg) = @_; + utf8::decode $msg; + if ($msg) { my $NOW = time; my $name = $who->name; + cf::LOG cf::llevDebug, sprintf "QBERT {%s} %s\n", $name, $msg; + + utf8::encode $msg; # ->message not yet utf8-ified $_->ob->message ("$name shouts: $msg", cf::NDI_RED) - for grep { $_->ob->{ext_ignore_shout}{$name} < $NOW and $_->listening >= 2 }, cf::player::list; + for grep { $_->ob->{ext_ignore_shout}{$name} < $NOW && $_->listening >= 2 } cf::player::list; } else { $who->message ("Shout what?", cf::NDI_UNIQUE); @@ -65,6 +148,8 @@ my ($who, $args) = @_; my ($target, $msg) = split /\s+/, $args, 2; + utf8::decode $msg; + my $name = $who->name; if (my $other = cf::player::find $target) { @@ -75,6 +160,9 @@ } elsif ($other->ob->{ext_ignore_tell}{$name} >= time) { $who->message ("$target ignores what you say. Give up on it.", cf::NDI_UNIQUE); } else { + utf8::encode $msg; # ->message not yet utf8-ified + cf::LOG cf::llevDebug, sprintf "TELL [%s>%s] %s\n", $name, $target, $msg; + $who->message ("You tell $target: $msg"); $other->ob->message ("$name tells you: $msg"); $other->ob->{ext_last_tell} = $name; @@ -92,6 +180,8 @@ my ($who, $args) = @_; my $name = $who->name; + utf8::decode $args; + if (my $other = cf::player::find $who->{ext_last_tell}) { if ($args) { @@ -99,6 +189,9 @@ or delete $other->ob->{ext_ignore_tell}{$name}; if ($other->ob->{ext_ignore_tell}{$name} < time) { + utf8::encode $msg; # ->message not yet utf8-ified + cf::LOG cf::llevDebug, sprintf "TELL [%s>%s] %s\n", $name, $other->ob->name, $args; + $who->message ("You tell " . $other->ob->name . ": $args"); $other->ob->message ("$name tells you: $args"); $who->{ext_last_tell} = $other->ob->name; @@ -137,7 +230,7 @@ $timeout ne "" or $timeout = 24; my $absolute_timeout = time + $timeout * 3600; - if (valid_user $target) { + if (cf::player::exists $target) { if ($type eq "tell") { $who->message ("Now ignoring private messages from $target for $timeout hours.", cf::NDI_UNIQUE); $who->{ext_ignore_tell}{$target} = $absolute_timeout; @@ -156,7 +249,7 @@ } } else { - $who->message ("Usage: ignore \n" + $who->message ("Usage: ignore \n" . "will ignore a player for hours.\n" . "Usage: ignore list\n" . "will show you a list of players currently ignored.", cf::NDI_UNIQUE); @@ -177,8 +270,7 @@ $who->message ("Not ignoring anyone", cf::NDI_UNIQUE); } } else { - - if (valid_user $target) { + if (cf::player::exists $target) { if ($type eq "tell") { $who->message ("Not ignoring private messages from $target anymore.", cf::NDI_UNIQUE); delete $who->{ext_ignore_tell} {$target}; @@ -195,7 +287,29 @@ } else { $who->message ("No such player or ambiguous name: $target", cf::NDI_UNIQUE); } + } +}; +cf::register_command seen => 0, sub { + my ($who, $args) = @_; + + if (my ($login) = $args =~ /(\S+)/) { + if ($login eq $who->name) { + $who->message ("Very funny, $login. Ha. Ha.", cf::NDI_UNIQUE); + } elsif (cf::player::find $login) { + $who->message ("$login is right here on this server!", cf::NDI_UNIQUE); + } elsif (cf::player::exists $login + and stat sprintf "%s/%s/%s/%s.pl", cf::localdir, cf::playerdir, ($login) x 2) { + my $time = (stat _)[9]; + + $who->message ("$login was last seen here " + . (POSIX::strftime "%Y-%m-%d %H:%M:%S +0000", gmtime $time) + . " which was " . (int +(time - $time) / 3600) . " hours ago.", cf::NDI_UNIQUE); + } else { + $who->message ("No player named $login is known to me.", cf::NDI_UNIQUE); + } + } else { + $who->message ("Usage: seen ", cf::NDI_UNIQUE); } };