Quote:
Originally Posted by sorvani
Testing Quest Scripts 101:
#1 open a command prompt and type: perl -c somescriptname.pl
#2 If errors, fix them, go back to #1. If no errors go to #3
#3 The script compiles fine but is not acting as expected. Add in quest::shout("some message"); at various points in the routines to output what is happening.
#4 based on the shouts, edit your script. do not forget to #reloadpl 1 in game.
# Go to #1
|
agreed.
and if you're going to write complex scripts on a regular basis, i'd recommend learning to write subroutines and classes which behave as the interfaces found embedded in the server do. the classes don't have to be completely mirrored. just give them the methods you need for testing. it may seem like a daunting task, but you'll learn a hell of a lot about perl and the server while putting it all together. eventually, you won't need to have access to a running server to develop your scripts.
example with timers and entity variables roughly emulated:
Code:
use 5.012;
# NOTE: the following two modules allow the emulation of quest timers
# and they are not part of the standard perl installation
use EV;
use AnyEvent;
# emulate EVENT_ITEM()
sub EVENT_ITEM
{
# NOTE: calls to plugin::check_handin() are done here in production quests
# but for now, assume correct items were turned in
if (1) {
# define global fuse array reference
our $fuse = [
('--' x 1).'x',
('--' x 5).'x',
('--' x 9).'x',
('--' x 13).'x'
];
# emulate $ent->SetEntityVariable(1, 3);
SetEntityVariable(1, 3);
# emulate $client->Message(0, "You carefully light the fuse.");
say "You carefully light the fuse.\n";
# print last element of fuse array
# emulate $client->Message(0, $fuse->[-1]);
say $fuse->[-1]."\n";
settimer('explode', 2);
}
# NOTE: the following should always be called outside all condition blocks
# and at the end of EVENT_ITEM
# plugin::return_items(\%itemcount);
}
# emulate EVENT_TIMER()
sub EVENT_TIMER
{
# NOTE: this just stores the first parameter passed to a local variable
# and is not needed in production quests
my $timer = shift;
# import global
our $fuse;
if ($timer eq 'explode') {
# emulate my $length = $ent->GetEntityVariable(1);
my $length = GetEntityVariable(1)-1;
# length is 0-3
if ($length ~~ [0..3]) {
# emulate $client->Message(0, $fuse->[$length]);
say $fuse->[$length]."\n";
# emulate $ent->SetEntityVariable(1, $length);
SetEntityVariable(1, $length);
}
# $length is -1
else {
# emulate $client->Message(0, "ka-BOOM!");
say "ka-BOOM!";
stoptimer($timer);
print "\n" if keys %$main::timer;
}
}
# stops 'random' timer at random iteration (1-20)
elsif ($timer =~ /^random_/) {
my $count = GetEntityVariable($timer."_count")+1;
say "iteration $count of EVENT_TIMER('$timer') triggered"
if $timer;
if ($count >= GetEntityVariable($timer."_limit")) {
stoptimer($timer);
}
else {
SetEntityVariable($timer."_count", $count);
}
print "\n" if keys %$main::timer;
}
else {
warn "I don't know what to do with $timer";
}
}
# emulate $mob->SetEntityVariable()
sub SetEntityVariable
{
my ($var, $val) = @_;
our $entvar;
if (not $entvar) {
our $entvar = {
$var => $val
};
}
else {
$entvar->{$var} = $val;
}
}
# emulate $mob->GetEntityVariable()
sub GetEntityVariable
{
my $var = shift;
our $entvar;
$entvar->{$var} // undef;
}
# emulate quest::settimer()
sub settimer
{
our $timer;
my ($name, $seconds) = @_;
stoptimer($name)
if defined $timer->{$name};
# fire off EVENT_TIMER($name) after $seconds and every $seconds
our $timer->{$name} = AE::timer($seconds, $seconds, sub {
EVENT_TIMER($name);
});
}
# emulate quest::stoptimer()
sub stoptimer
{
our $timer;
my $name = shift;
$timer->{$name}->stop;
delete $timer->{$name};
}
print "\n";
foreach (1..2) {
# set 'random' timer for random amount of time and iteration count
my $rsecf = rand(2)+1;
my $limit = int (rand 19)+1;
say "timer 'random_".$_."' set to a maximum of $limit iterations of $rsecf seconds each\n";
SetEntityVariable('random_'.$_.'_limit', $limit);
settimer('random_'.$_, $rsecf);
}
# emulate client giving item to npc
EVENT_ITEM();
# emulate $client->Message(0, You decide it's probably best to get as far away as possible.);
say "You decide it's probably best to get as far away as possible.\n";
# trigger timer loop
# not needed in production quests
EV::loop;
it also never hurts to find something to read:
http://modernperlbooks.com/books/modern_perl/