--- deliantra/server/ext/NPC_Dialogue.pm 2006/12/15 19:29:18 1.1 +++ deliantra/server/ext/NPC_Dialogue.pm 2008/12/18 02:49:22 1.12 @@ -6,18 +6,14 @@ NPC dialogue support module. +=over 4 + =cut package NPC_Dialogue; use strict; -sub has_dialogue($) { - my ($ob) = @_; - - $ob->msg =~ /^\@match /; -} - sub parse_message($) { map [split /\n/, $_, 2], grep length, @@ -28,6 +24,8 @@ sub new { my ($class, %arg) = @_; + $arg{ob} = $arg{pl}->ob; + my $self = bless { %arg, }, $class; @@ -105,6 +103,36 @@ The environment is that standard "map scripting environment", which is limited in the type of constructs allowed (no loops, for example). +Here is a example: + +=over 4 + +=item B + + @match hi + @cond grep $_->name =~ /royalty/, $who->inv + You got royalties there! Wanna have! + +You may want to change the C method there to something like C, +C<slaying> or any other method that is allowed to be called on a +C<cf::object> here. + +=item B<matching for an item name and removing the matched item> + + @match found earhorn + @cond grep $_->slaying =~ /Gramp's walking stick/, $who->inv + @eval my @g = grep { $_->slaying =~ /Gramp's walking stick/ } $who->inv; $g[0]->decrease; + Thanks for the earhorn! + +This example is a bit more complex. The C<@eval> statement will search +the players inventory for the same term as the C<@cond> and then +decreases the number of objects used there. + +(See also the map: C<scorn/houses/cornerbrook.map> for an example how this is +used in the real world :-) + +=back + =item @eval perl Like C<@cond>, but proceed regardless of the outcome. @@ -166,10 +194,31 @@ @ifflag kings_quest Hi, I was told you want to do the kings quest? -=item @trigger connected-id +=item @trigger connected-id [state] + +Trigger all objects with the given connected-id. + +When the state argument is omitted the trigger is stateful and retains an +internal state per connected-id. There is a limitation to the use of this: The +state won't be changed when the connection is triggered by other triggers. So +be careful when triggering the connection from other objects. + +When a state argument is given it should be either 0 or 1. 1 will 'push' the connection +and 0 will 'release' the connection. This is useful for example when you want to +let a npc control a door. + +Trigger all objects with the given connected-id by 'releasing' the connection. + +=item @playersound face-name + +Plays the given sound face (either an alias or sound file path) so that +only the player talking to the npc can hear it. -Trigger all objects with the given connected-id. The trigger is stateful -and retains state per connected-id. +=item @npcsound face-name + +Plays the given sound face (either an alias or sound file path) as if +the npc had made that sound, i.e. it will be located at the npc and all +players near enough can hear it. =item @addtopic topic @@ -188,7 +237,7 @@ topic: for my $match (@{ $self->{match} }) { for (split /\|/, $match->[0]) { - if ($_ eq "*" || $lcmsg eq lc) { + if ($_ eq "*" || $lcmsg =~ /\b\Q$_\E\b/i) { my $reply = $match->[1]; my @kw; @@ -221,6 +270,12 @@ } elsif ($cmd eq "comment") { # nop + } elsif ($cmd eq "playersound") { + $self->{ob}->contr->play_sound (cf::sound::find $args); + + } elsif ($cmd eq "npcsound") { + $self->{npc}->play_sound (cf::sound::find $args); + } elsif ($cmd eq "cond") { cf::safe_eval $args, %vars or next topic; @@ -253,8 +308,15 @@ or next topic; } elsif ($cmd eq "trigger") { - my $rvalue = \$self->{npc}{dialog_trigger}{$args*1}; - $self->{npc}->map->trigger ($args, $$rvalue = !$$rvalue); + my ($con, $state) = split /\s+/, $args, 2; + $con = $con * 1; + + if (defined $state) { + $self->{npc}->map->trigger ($args, $state); + } else { + my $rvalue = \$self->{npc}{dialog_trigger}{$con}; + $self->{npc}->map->trigger ($con, $$rvalue = !$$rvalue); + } } elsif ($cmd eq "addtopic") { push @kw, split /\|/, $args; @@ -272,10 +334,6 @@ delete $self->{npc}{$self->{ob}->name}{dialog_state} unless %$state; delete $self->{ob}{dialog_flag} unless %$flag; - # combine lines into paragraphs - $reply =~ s/(?<=\S)\n(?=\w)/ /g; - $reply =~ s/\n\n/\n/g; - # ignores flags and npc from replies $reply = join "\n", (map $_->[1], @replies), $reply; @@ -289,6 +347,8 @@ } } + $self->{npc}->use_trigger if $self->{npc}->type == cf::MAGIC_EAR; + return wantarray ? ($reply, @kw) : $reply; } }