Loxo
02-14-2013, 08:32 AM
XS(XS_Mob_DoKnockback); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_DoKnockback)
{
dXSARGS;
if (items != 4)
Perl_croak(aTHX_ "Usage: Mob::DoKnockback(THIS, caster, pushback, pushup)");
{
Mob * THIS;
Mob * caster;
uint32 pushback = (uint16)SvUV(ST(2));
uint32 pushup = (uint16)SvUV(ST(2));
if (sv_derived_from(ST(0), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(Mob *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type Mob");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
if (sv_derived_from(ST(1), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(1)));
caster = INT2PTR(Mob *,tmp);
}
else
Perl_croak(aTHX_ "caster is not of type Mob");
if(caster == NULL)
Perl_croak(aTHX_ "caster is NULL, avoiding crash.");
THIS->DoKnockback(caster, pushback, pushup);
}
XSRETURN_EMPTY;
}
I'm having trouble finding what will work as a variable for "caster." I have tried numerous variations on $mobid, $charid, $userid, just plain $mob/$npc/$client; but they all end up giving me an undefined report:
[02.14. - 06:09:54] Script error: qst1002524::EVENT_TIMER - Perl runtime error: Can't call method "DoKnockback" on an undefined value at quests/wood/northwind.pl line 45 (or 56).
This is the script I'm trying to use the object in, currently unsuccessfully using $character = $ent to try to specify, though I have tried various other mob/npc/client global variables as I'm not sure from the perl_mob.cpp who "caster" is supposed to be exactly:
sub EVENT_SPAWN
{
my $randomgail = (int(rand(1800)) + int(rand(1200)));
my $randomgust = (int(rand(1200)) + int(rand(600)));
my $randombreeze = (int(rand(600)) + int(rand(300)));
quest::settimer("gail",31);
quest::settimer("gust",53);
quest::settimer("breeze",71);
}
sub EVENT_TIMER
{
my $delaywind = (int(rand(10)) + 1);
if ($timer eq "breeze")
{
quest::settimer("windone",$delaywind);
quest::ze(10, "The tree tops begin to rustle...");
}
elsif ($timer eq "gust")
{
quest::settimer("windtwo",$delaywind);
quest::ze(10, "The tree tops begin to rustle...");
}
elsif ($timer eq "gail")
{
quest::settimer("windthree",$delaywind);
quest::ze(10, "The tree tops begin to rustle...");
}
elsif ($timer eq "windone")
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$npc->CastSpell(697, $userid);
quest::ze(10, "A gentle breeze passes through.");
quest::stoptimer("windone");
}
}
elsif ($timer eq "windtwo")
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$character = $ent;
$mob->DoKnockback($character, 15, 0);
quest::ze(10, "A gust from the North sweeps through.");
quest::stoptimer("windtwo");
}
}
elsif ($timer eq "windthree")
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$character = $ent;
$mob->DoKnockback($character, 1, 0);
quest::stoptimer("windthree");
quest::settimerMS("constwind", 500);
quest::ze(10, "The wind howls...");
}
}
elsif ($timer eq "constwind")
{
my $randomstopwind = int(rand(10));
if ($randomstopwind < 9)
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$character = $ent;
$mob->DoKnockback($character, 1, 0);
}
}
else
{
quest::stoptimer("constwind");
quest::ze(10, "The wind dies down");
}
}
else
{
}
}
I've had success in other scripts defining a $variable = ($client) outside of the EVENT_TIMER so I could specify which client I wanted inside the timer, but with the $entity_list I don't think that will work, as I want these small knockbacks to hit each player in the zone.
XS(XS_Mob_DoKnockback)
{
dXSARGS;
if (items != 4)
Perl_croak(aTHX_ "Usage: Mob::DoKnockback(THIS, caster, pushback, pushup)");
{
Mob * THIS;
Mob * caster;
uint32 pushback = (uint16)SvUV(ST(2));
uint32 pushup = (uint16)SvUV(ST(2));
if (sv_derived_from(ST(0), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(Mob *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type Mob");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
if (sv_derived_from(ST(1), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(1)));
caster = INT2PTR(Mob *,tmp);
}
else
Perl_croak(aTHX_ "caster is not of type Mob");
if(caster == NULL)
Perl_croak(aTHX_ "caster is NULL, avoiding crash.");
THIS->DoKnockback(caster, pushback, pushup);
}
XSRETURN_EMPTY;
}
I'm having trouble finding what will work as a variable for "caster." I have tried numerous variations on $mobid, $charid, $userid, just plain $mob/$npc/$client; but they all end up giving me an undefined report:
[02.14. - 06:09:54] Script error: qst1002524::EVENT_TIMER - Perl runtime error: Can't call method "DoKnockback" on an undefined value at quests/wood/northwind.pl line 45 (or 56).
This is the script I'm trying to use the object in, currently unsuccessfully using $character = $ent to try to specify, though I have tried various other mob/npc/client global variables as I'm not sure from the perl_mob.cpp who "caster" is supposed to be exactly:
sub EVENT_SPAWN
{
my $randomgail = (int(rand(1800)) + int(rand(1200)));
my $randomgust = (int(rand(1200)) + int(rand(600)));
my $randombreeze = (int(rand(600)) + int(rand(300)));
quest::settimer("gail",31);
quest::settimer("gust",53);
quest::settimer("breeze",71);
}
sub EVENT_TIMER
{
my $delaywind = (int(rand(10)) + 1);
if ($timer eq "breeze")
{
quest::settimer("windone",$delaywind);
quest::ze(10, "The tree tops begin to rustle...");
}
elsif ($timer eq "gust")
{
quest::settimer("windtwo",$delaywind);
quest::ze(10, "The tree tops begin to rustle...");
}
elsif ($timer eq "gail")
{
quest::settimer("windthree",$delaywind);
quest::ze(10, "The tree tops begin to rustle...");
}
elsif ($timer eq "windone")
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$npc->CastSpell(697, $userid);
quest::ze(10, "A gentle breeze passes through.");
quest::stoptimer("windone");
}
}
elsif ($timer eq "windtwo")
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$character = $ent;
$mob->DoKnockback($character, 15, 0);
quest::ze(10, "A gust from the North sweeps through.");
quest::stoptimer("windtwo");
}
}
elsif ($timer eq "windthree")
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$character = $ent;
$mob->DoKnockback($character, 1, 0);
quest::stoptimer("windthree");
quest::settimerMS("constwind", 500);
quest::ze(10, "The wind howls...");
}
}
elsif ($timer eq "constwind")
{
my $randomstopwind = int(rand(10));
if ($randomstopwind < 9)
{
my @clientlist = $entity_list->GetClientList();
foreach $ent (@clientlist)
{
$character = $ent;
$mob->DoKnockback($character, 1, 0);
}
}
else
{
quest::stoptimer("constwind");
quest::ze(10, "The wind dies down");
}
}
else
{
}
}
I've had success in other scripts defining a $variable = ($client) outside of the EVENT_TIMER so I could specify which client I wanted inside the timer, but with the $entity_list I don't think that will work, as I want these small knockbacks to hit each player in the zone.