View Full Version : Buff Bots: $npc->CastSpell vs. quest:selfcast ??
Huppy
12-02-2010, 03:18 PM
Just wondering if there is a fix for this in quest scripts?
I currently have some buff bots setup using the $npc->CastSpell (spellid)
to cast a single buff on a toon. But this command won't cast any group buffs.
(HoV,Kei, FoE, etc.)
With my GM toon, I can use the #castspell (spellid) and freely cast any
group based buff on any toon, but it won't work on a quest script.
The quest:selfcast will work fine, but the buff timers are level dependant,
so I was trying to set up the bots for full length buffs.
This likely has nothing to do with the problem so i apologize in advance for potentially side tracking your thread, but when the quest:selfcast is used does it ignore the spells duration all together and use one pre set somewhere else?
Example being, you create a spell that adds X amount of HP for... say 2 hours, it would ignore the two hour duration art dor the spell and create its own? If that is the case, where ous the data being pulled from to create its own timer?
Huppy
12-02-2010, 04:35 PM
When a script uses the quest::selfcast , on a level 1 toon, the duration
is only 3 minutes, no matter what the buff is.
But if the script uses $npc->CastSpell then the buff is on full timer.
For example casting Temp would give a level 1 toon 1 hr & 40 min buff
using the $npc->CastSpell
But casting the same Temp buff on a level 1 toon using the quest::selfcast
would give you a 3 minute buff. Its just the way it works.
But the $npc->CastSpell appears not to be any good for GROUP buffs, such
as KEI, etc. You have to use the quest::selfcast for those ones.
This is what I'm looking for is a fix or work around for it.
joligario
12-02-2010, 05:41 PM
That's because it is dependent on the level of the character activating the quest script.
From http://www.eqemulator.net/wiki/wikka.php?wakka=QuestTutorial
"Forces client to cast spell on themself". So the level ?? NPC is not casting the spell, it is the level 1 PC that is casting the spell.
Huppy
12-02-2010, 05:43 PM
Yes, I know that already ....
joligario
12-02-2010, 05:46 PM
Good.... Then I guess you are set?
Huppy
12-02-2010, 05:49 PM
My question hasnt been answered yet :)
Congdar
12-02-2010, 05:57 PM
is your buff bot level 65... or 1?
Huppy
12-02-2010, 08:11 PM
The buff bots are level 75
Caryatis
12-02-2010, 08:33 PM
My question hasnt been answered yet
lol, god forbid your question isnt answered in less than a day.
Huppy
12-02-2010, 09:09 PM
That wasn't a cry of impatience Caryatis, it was a response /shrug
What if you were to make a copy of whatever group buffs you want the buff bot to use, and change the level of the spell to 1. Obviously it wouldn't be available to players as a memorable spell, purely one for buff bot use.
In theory, would look like a lvl 1 char is casting a level 1 group buff on himself (pet and other party members as well). That is if I'm understanding this all correctly.
Caryatis
12-03-2010, 01:32 AM
The level of the spell or buff bot doesnt matter in this case since its forcing the client to cast the spell. Therefore if a level 1 character receives a group buff through the selfcast routine, it treats it as a level 1 character casting the spell, which using the buff formula equates to a short duration buff. I would say use $client->CastSpell but I think that would result in the same effect as using selfcast.
Alternatively you could copy the buff and change the duration formula to use a set duration although Im too lazy to look up which formula that would be besides 50(which is perm and probably not desirable).
lerxst2112
12-03-2010, 02:10 AM
11 & 12 both result in the actual spell duration being used. As an example, if a level 1 toon casts Acumen it would last the full duration as it uses formula 11.
trevius
12-03-2010, 03:50 AM
If you want to cast a spell on the entire group, it would be easiest to just get the group and cycle through each member having the NPC cast the spell on them. Though, if you only want group spells to land on the full group (and not single target), it would probably take a bit more work. I am not aware of any current commands to check if a spell is a group spell or not, but it would probably be really easy to add one to the source if needed.
Here is an example script (not tested) that includes a subroutine for casting a spell on the whole group. You could even add the sub into your plugins folder and make it into a plugin instead if you wanted so it can be accessed from any script (using plugin::CastOnGroup(SpellID, MaxDist)).
sub EVENT_SAY {
if ($text =~ /Hail/i)
{
#plugin::CastOnGroup(11, 100, $client); # Can use like this is saved as a plugin instead
CastOnGroup(11);
quest::say("Casting buff on your group");
}
}
#Usage: plugin::CastOnGroup(SpellID, MaxDist=0, Client=$client);
# This script will cast the spell on the client's group from an NPC (such as a buff bot).
# SpellID - This is just the spell ID to be cast.
# MaxDist - This is an optional field for setting the Max Distance for the spell to land on group members.
# The Default 0 setting for MaxDist disables the check for distance so it will be cast on all group members in zone.
# Client - This is an optional field to set a specific client to cast buffs on their group (Default is the client interacting with the NPC)
sub CastOnGroup {
my $npc = plugin::val('$npc');
my $client = plugin::val('$client');
my $SpellID = $_[0];
my $MaxDist = $_[1];
my $Caster = $_[2];
# If the caster field was not set, use the client interacting with the NPC as the caster
if (!$Caster)
{
$Caster = $client;
}
my $ClientGroup = $client->GetGroup();
# If the client is grouped
if ($ClientGroup)
{
# Cycle through all 6 possible group members
my $GCount = 0;
while ($GCount < 6)
{
$GroupMember = $Group->GetMember($GCount);
# If this group member exists
if ($GroupMember)
{
my $OutOfRange = 0;
# If MaxDist was set, make sure the client is within the desired range
if ($MaxDist)
{
my $ClientX = $GroupMember->GetX();
my $ClientY = $GroupMember->GetY();
my $ClientZ = $GroupMember->GetZ();
my $ClientDist = $npc->CalculateDistance($ClientX, $ClientY, $ClientZ);
# Check if the Square Root of the Distance from NPC to Client is less than MaxDist
# CalculateDistance returns squared distance
if (sqrt($ClientDist) > $MaxDist)
{
$OutOfRange = 1;
}
}
# If they aren't out of range or range was not specified
if (!$OutOfRange)
{
my $MemberID = $GroupMember->GetID();
# Cast the spell on this member
$npc->CastSpell($SpellID, $MemberID);
my $PetID = $GroupMember->GetPetID();
# Check if this member has a pet and if so, cast it on the pet as well
if ($PetID)
{
$npc->CastSpell($SpellID, $PetID);
}
}
}
$GCount++;
}
}
else
{
# Client is not grouped, so just cast on them
my $CasterID = $Caster->GetID();
$npc->CastSpell($SpellID, $CasterID);
my $PetID = $Caster->GetPetID();
# Check if the client has a pet and if so, cast it on the pet as well
if ($PetID)
{
$npc->CastSpell($SpellID, $PetID);
}
}
}
Again, this is untested and I just wrote it from scratch. If it works, it would probably be a good one to add to plugins if there isn't already a better way to do this.
Akkadius
12-03-2010, 11:05 AM
If you want to cast a spell on the entire group, it would be easiest to just get the group and cycle through each member having the NPC cast the spell on them. Though, if you only want group spells to land on the full group (and not single target), it would probably take a bit more work. I am not aware of any current commands to check if a spell is a group spell or not, but it would probably be really easy to add one to the source if needed.
Here is an example script (not tested) that includes a subroutine for casting a spell on the whole group. You could even add the sub into your plugins folder and make it into a plugin instead if you wanted so it can be accessed from any script (using plugin::CastOnGroup(SpellID, MaxDist)).
sub EVENT_SAY {
if ($text =~ /Hail/i)
{
#plugin::CastOnGroup(11, 100, $client); # Can use like this is saved as a plugin instead
CastOnGroup(11);
quest::say("Casting buff on your group");
}
}
#Usage: plugin::CastOnGroup(SpellID, MaxDist=0, Client=$client);
# This script will cast the spell on the client's group from an NPC (such as a buff bot).
# SpellID - This is just the spell ID to be cast.
# MaxDist - This is an optional field for setting the Max Distance for the spell to land on group members.
# The Default 0 setting for MaxDist disables the check for distance so it will be cast on all group members in zone.
# Client - This is an optional field to set a specific client to cast buffs on their group (Default is the client interacting with the NPC)
sub CastOnGroup {
my $npc = plugin::val('$npc');
my $client = plugin::val('$client');
my $SpellID = $_[0];
my $MaxDist = $_[1];
my $Caster = $_[2];
# If the caster field was not set, use the client interacting with the NPC as the caster
if (!$Caster)
{
$Caster = $client;
}
my $ClientGroup = $client->GetGroup();
# If the client is grouped
if ($ClientGroup)
{
# Cycle through all 6 possible group members
my $GCount = 0;
while ($GCount < 6)
{
$GroupMember = $Group->GetMember($GCount);
# If this group member exists
if ($GroupMember)
{
my $OutOfRange = 0;
# If MaxDist was set, make sure the client is within the desired range
if ($MaxDist)
{
my $ClientX = $GroupMember->GetX();
my $ClientY = $GroupMember->GetY();
my $ClientZ = $GroupMember->GetZ();
my $ClientDist = $npc->CalculateDistance($ClientX, $ClientY, $ClientZ);
# Check if the Square Root of the Distance from NPC to Client is less than MaxDist
# CalculateDistance returns squared distance
if (sqrt($ClientDist) > $MaxDist)
{
$OutOfRange = 1;
}
}
# If they aren't out of range or range was not specified
if (!$OutOfRange)
{
my $MemberID = $GroupMember->GetID();
# Cast the spell on this member
$npc->CastSpell($SpellID, $MemberID);
my $PetID = $GroupMember->GetPetID();
# Check if this member has a pet and if so, cast it on the pet as well
if ($PetID)
{
$npc->CastSpell($SpellID, $PetID);
}
}
}
$GCount++;
}
}
else
{
# Client is not grouped, so just cast on them
my $CasterID = $Caster->GetID();
$npc->CastSpell($SpellID, $CasterID);
my $PetID = $Caster->GetPetID();
# Check if the client has a pet and if so, cast it on the pet as well
if ($PetID)
{
$npc->CastSpell($SpellID, $PetID);
}
}
}
Again, this is untested and I just wrote it from scratch. If it works, it would probably be a good one to add to plugins if there isn't already a better way to do this.
Plugin added to repo, merged into group_utils.pl
Huppy
12-03-2010, 02:23 PM
If you want to cast a spell on the entire group, it would be easiest to just get the group and cycle through each member having the NPC cast the spell on them. Though, if you only want group spells to land on the full group (and not single target), it would probably take a bit more work. I am not aware of any current commands to check if a spell is a group spell or not, but it would probably be really easy to add one to the source if needed.
Here is an example script (not tested) that includes a subroutine for casting a spell on the whole group. You could even add the sub into your plugins folder and make it into a plugin instead if you wanted so it can be accessed from any script (using plugin::CastOnGroup(SpellID, MaxDist))..
Thanx Trevius. Your right, it would be easiest to just get the group members
to cycle through, getting the buff from the NPC, which I really could live with
that. My whole problem started when using the $npc->CastSpell in a script.
It works fine if the spellid is a single buff (such as Spirit of Eagle). But if I
change the spellid to a group buff (such as Flight of Eagles), the NPC will go
through the anim of casting, but does not actually cast the spell.
The selfcast::(spellid) will work fine with any group buff like KEI, but not the
$npc->CastSpell
This is one of the scripts I am currently using;
sub EVENT_SAY {
if ($text =~/hail/i) {
quest::say("Incoming Clarity for $name");
my $GetPlayerID = $client->GetID();
$npc->CastSpell(1693, $GetPlayerID );
}
}
This script works perfect for any single target spell (SoW, Temp, etc)
But if I change the spellid from 1693 to 2570 (Koadic's Endless Intellect),
The NPC will not cast that spell or any other group spellid.
My goal, to start out with was having an NPC cast the KEI buff using the
$npc->CastSpell only because it casts a full timer buff duration, no matter
what level the character is.
This is when I found out, that command would not cast any group buff.
trevius
12-04-2010, 05:09 AM
I am not having any issues casting group spells from an NPC using this:
sub EVENT_SAY {
if ($text =~/hail/i) {
my $Group = $client->GetGroup();
if($Group) {
$Group->CastGroupSpell($npc, 1693);
}
else {
my $GetPlayerID = $client->GetID();
$npc->CastSpell(1693, $GetPlayerID );
}
quest::say("Incoming Clarity for $name");
}
}
And, Akkadius, keep in mind that that code was untested. I tested it a bit and there was an issue or 2 with it. This updated one seems to work well enough though:
#Usage: plugin::CastOnGroup(SpellID, MaxDist=0, Client=$client);
# This script will cast the spell on the client's group from an NPC (such as a buff bot).
# SpellID - This is just the spell ID to be cast.
# MaxDist - This is an optional field for setting the Max Distance for the spell to land on group members.
# The Default 0 setting for MaxDist disables the check for distance so it will be cast on all group members in zone.
# Client - This is an optional field to set a specific client to cast buffs on their group (Default is the client interacting with the NPC)
sub CastOnGroup {
my $npc = plugin::val('$npc');
my $client = plugin::val('$client');
my $entity_list = plugin::val('$entity_list');
my $SpellID = $_[0];
my $MaxDist = $_[1];
my $Caster = $_[2];
#plugin::Debug("If the caster field was not set, use the client interacting with the NPC as the caster");
if (!$Caster)
{
$Caster = $client;
}
my $ClientGroup = $client->GetGroup();
#plugin::Debug("If the client is grouped");
if ($ClientGroup)
{
#plugin::Debug("Cycle through all 6 possible group members");
my $GCount = 0;
while ($GCount < 6)
{
$GroupMember = $ClientGroup->GetMember($GCount);
#plugin::Debug("If this group member exists");
if ($GroupMember)
{
my $OutOfRange = 0;
#plugin::Debug("If MaxDist was set, make sure the client is within the desired range");
if ($MaxDist)
{
my $ClientX = $GroupMember->GetX();
my $ClientY = $GroupMember->GetY();
my $ClientZ = $GroupMember->GetZ();
my $ClientDist = $npc->CalculateDistance($ClientX, $ClientY, $ClientZ);
#plugin::Debug("Check if the Square Root of the Distance from NPC to Client is less than MaxDist");
# CalculateDistance returns squared distance
if (sqrt($ClientDist) > $MaxDist)
{
$OutOfRange = 1;
}
}
#plugin::Debug("If they aren't out of range or range was not specified");
if (!$OutOfRange)
{
my $MemberID = $GroupMember->GetID();
#plugin::Debug("Cast the spell on this member");
#$npc->CastSpell($SpellID, $MemberID);
$npc->SpellFinished($SpellID, $GroupMember, 0);
my $PetID = $GroupMember->GetPetID();
#plugin::Debug("Check if this member has a pet and if so, cast it on the pet as well");
if ($PetID)
{
#$npc->CastSpell($SpellID, $PetID);
$npc->SpellFinished($SpellID, $entity_list->GetMobByID($PetID), 0);
}
}
}
$GCount++;
}
}
else
{
#plugin::Debug("Client is not grouped, so just cast on them");
my $CasterID = $Caster->GetID();
#$npc->CastSpell($SpellID, $CasterID);
$npc->SpellFinished($SpellID, $Caster, 0);
my $PetID = $Caster->GetPetID();
#plugin::Debug("Check if the client has a pet and if so, cast it on the pet as well");
if ($PetID)
{
#$npc->CastSpell($SpellID, $PetID);
$npc->SpellFinished($SpellID, $entity_list->GetMobByID($PetID), 0);
}
}
}
Huppy
12-04-2010, 06:57 AM
[QUOTE=trevius;194793]I am not having any issues casting group spells from an NPC using this:
sub EVENT_SAY {
if ($text =~/hail/i) {
my $Group = $client->GetGroup();
if($Group) {
$Group->CastGroupSpell($npc, 1693)
}
else {
my $GetPlayerID = $client->GetID();
$npc->CastSpell(1693, $GetPlayerID );
}
quest::say("Incoming Clarity for $name");
}
}
THANK YOU VERY MUCH, That works perfect :)
Akkadius
12-04-2010, 02:00 PM
I am not having any issues casting group spells from an NPC using this:
sub EVENT_SAY {
if ($text =~/hail/i) {
my $Group = $client->GetGroup();
if($Group) {
$Group->CastGroupSpell($npc, 1693)
}
else {
my $GetPlayerID = $client->GetID();
$npc->CastSpell(1693, $GetPlayerID );
}
quest::say("Incoming Clarity for $name");
}
}
And, Akkadius, keep in mind that that code was untested. I tested it a bit and there was an issue or 2 with it. This updated one seems to work well enough though:
#Usage: plugin::CastOnGroup(SpellID, MaxDist=0, Client=$client);
# This script will cast the spell on the client's group from an NPC (such as a buff bot).
# SpellID - This is just the spell ID to be cast.
# MaxDist - This is an optional field for setting the Max Distance for the spell to land on group members.
# The Default 0 setting for MaxDist disables the check for distance so it will be cast on all group members in zone.
# Client - This is an optional field to set a specific client to cast buffs on their group (Default is the client interacting with the NPC)
sub CastOnGroup {
my $npc = plugin::val('$npc');
my $client = plugin::val('$client');
my $entity_list = plugin::val('$entity_list');
my $SpellID = $_[0];
my $MaxDist = $_[1];
my $Caster = $_[2];
#plugin::Debug("If the caster field was not set, use the client interacting with the NPC as the caster");
if (!$Caster)
{
$Caster = $client;
}
my $ClientGroup = $client->GetGroup();
#plugin::Debug("If the client is grouped");
if ($ClientGroup)
{
#plugin::Debug("Cycle through all 6 possible group members");
my $GCount = 0;
while ($GCount < 6)
{
$GroupMember = $ClientGroup->GetMember($GCount);
#plugin::Debug("If this group member exists");
if ($GroupMember)
{
my $OutOfRange = 0;
#plugin::Debug("If MaxDist was set, make sure the client is within the desired range");
if ($MaxDist)
{
my $ClientX = $GroupMember->GetX();
my $ClientY = $GroupMember->GetY();
my $ClientZ = $GroupMember->GetZ();
my $ClientDist = $npc->CalculateDistance($ClientX, $ClientY, $ClientZ);
#plugin::Debug("Check if the Square Root of the Distance from NPC to Client is less than MaxDist");
# CalculateDistance returns squared distance
if (sqrt($ClientDist) > $MaxDist)
{
$OutOfRange = 1;
}
}
#plugin::Debug("If they aren't out of range or range was not specified");
if (!$OutOfRange)
{
my $MemberID = $GroupMember->GetID();
#plugin::Debug("Cast the spell on this member");
#$npc->CastSpell($SpellID, $MemberID);
$npc->SpellFinished($SpellID, $GroupMember, 0);
my $PetID = $GroupMember->GetPetID();
#plugin::Debug("Check if this member has a pet and if so, cast it on the pet as well");
if ($PetID)
{
#$npc->CastSpell($SpellID, $PetID);
$npc->SpellFinished($SpellID, $entity_list->GetMobByID($PetID), 0);
}
}
}
$GCount++;
}
}
else
{
#plugin::Debug("Client is not grouped, so just cast on them");
my $CasterID = $Caster->GetID();
#$npc->CastSpell($SpellID, $CasterID);
$npc->SpellFinished($SpellID, $Caster, 0);
my $PetID = $Caster->GetPetID();
#plugin::Debug("Check if the client has a pet and if so, cast it on the pet as well");
if ($PetID)
{
#$npc->CastSpell($SpellID, $PetID);
$npc->SpellFinished($SpellID, $entity_list->GetMobByID($PetID), 0);
}
}
}
I figured since your history of posting plugins it would be fine. Not a big deal, updated the plugin. Good job
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.