PDA

View Full Version : Npc Wont cast spells


Maceblade
06-21-2013, 08:38 AM
I have been having an Issue for awhile now and cant seem to figure it out.

My custom NPC's seem to be very picky on which spells they will and will not cast.

ie:
$npc->CastSpell(7983,0);

Will cast... however...
$npc->CastSpell(7984,0);
$npc->SpellFinished(7984,0);
$npc->CastSpell(7984,1);

Will not. Certain spells refuse to work. Ive even tried selfcast to get them to fire.
GolemSmash2 is another spell that will not work for me on NPC's. My GM toon can #cast it all damn day so i know the spell is in there and working. When I changed the target type to 1 it will interrupt its own spell. Ill post a section of my pl...

if ($timer eq "atimer")
{
$npc->CastSpell(7984,0);
quest::stoptimer("atimer");
quest::settimer("atimer2",10);
}

Dunge0nMastr
06-21-2013, 09:12 AM
ive had similar issues, my workaround with getting NPCs to cast spells in event situations (boss fights etc) was using this:


my $target = #see list below

if ($target) {
$npc->SpellFinished(spellid,$target);
}



just use that within, sub event hp, timers, etc.

for targets the list is pretty long of what you can do. but if for example you want top threat, $npc->GetHateTop(); etc. U can dig through the wiki for examples of these objects.

u can also have a single target spell hit everyone in raid regardless of positioning and stuff too (fun for % damage stuff :P).

using:

my @Hatelist = $npc->GetHateList();
foreach $i(@Hatelist) {
if ($i) {
my $hent = $i->GetEnt();
if ($hent) {
$npc->SpellFinished(spellid,$hent);
}
}
}


so can set up an array for all client entities within the zone, or on the mobs hatelist etc.

for beneficial stuff - buff bots etc. I found the best way to do it was simply use: quest::selfcast(spellid);

Figback65
06-22-2013, 04:21 PM
nice pointers dunge0nmaster!

Maceblade
06-26-2013, 04:18 PM
So would it appear like this Dungeon:

sub EVENT_TIMER
{
if ($timer eq "atimer")
{
my $target = #see list below

if ($target) {
$npc->SpellFinished(7983,$target);
}
quest::stoptimer("atimer");
quest::settimer("atimer2",10);
}

or would my $target = #see list below be at the very top? Sorry im trying to learn this, I have literally no back ground in this stuff at all lol

Dunge0nMastr
06-26-2013, 08:29 PM
yep for example:



if ($timer eq "AoE") {
my $target = $npc->GetHateTop(); #gets top of the hate list
if ($target) { #this is a check, that i was told to use, helps prevent crashes and the like.
$npc->SpellFinished(6556, $target); #casts a spell on the Top of the hate list. This case its an AoE blind, which would cause the AoE to hit everyone around the Top Target, likely the Main tank.
}
}


http://pastebin.com/QGrEfhNN pastbin link for easier reading

so if you were just declaring $target as Top Threat, for 1 event, then you could put it where i have it in the example.

if you were using it for multiple timer or Hp events you could this:

sub EVENT_HP {
my $target = $npc->GetHateRandom(); #gets random hate from the hatelist
if ($hpevent <= 50 && $hpevent >= 49) { #check to make sure that a nuke or something wont skip the event
quest::setnexthpevent(25); #this sets the $hpevent values. you would have to declare this earlier in your script, say when mob is aggroed for the 50% one to kick in, and yeah its by percentages.
if ($target) {
$npc->SpellFinished(6556, $target); #same spell as above for my sake :P
}
}
if ($hpevent <= 25 && $hpevent >= 24) { #we declared this when mob hit 50%
if ($target) { #since we are using same target, should work just fine, could redeclare the variable as a different target (random, top etc) but then we would include them within each $hpevent, as opposed to the top of the sub.
$npc->SpellFinished(6556, $target);
}
}
}

http://pastebin.com/FMUgvK51

Honestly my code tends to get a little long winded, heres a full example of a mob that uses both timers/Hp events and counters and such for spell casting: This one uses timers for the spell targeting, and it targets all clients within the zone (if someone from my server happens to see this heres a sneak peak of some stuff from Frostcrypts) My code is hardly clean as this was done a few months ago and needs to be cleaned up hard core before i make it live, but its in a working test state/debug state - i also tend to be hyper redundant in my scripting, i honeslty just like doing things that way cause im a bit OCD about things.


sub EVENT_SPAWN {
quest::modifynpcstat("min_hit",1595);
quest::modifynpcstat("max_hit",2000);
$counter = 0;
$counter1 = 0;
$counter2 = 0;
$counter3 = 0;
$counter4 = 0;
$counter5 = 0;
}

sub EVENT_COMBAT {
if ($combat_state == 1) {
quest::settimer("adds",75);
quest::shout("Aggro");
quest::setnexthpevent(50);
}
if ($combat_state == 0) {
quest::npcsize(15);
quest::stoptimer("adds");
quest::stoptimer("adds2");
quest::stoptimer("poison");
quest::stoptimer("disease");
quest::stoptimer("deathtouch");
quest::stoptimer("armorbreak");
quest::shout("De Aggro");
$counter = 0;
$counter1 = 0;
$counter2 = 0;
$counter3 = 0;
$counter4 = 0;
$counter5 = 0;
quest::depop(402145);
quest::depop(402146);
quest::depop(402147);
quest::depop(402148);
quest::depopall(402149);
}
}

sub EVENT_TIMER {
if ($timer eq "adds") {
quest::shout("Come my servants! Do away with these interlopers!");
quest::spawn2(402145,540947,0,-1,1499.1,-228.6,129.0);
quest::spawn2(402146,540948,0,-97.4,1400.0,-228.6,62.8);
quest::spawn2(402147,540945,0,-0.3,1273.1,-228.6,0.1);
quest::spawn2(402148,540946,0,94.8,1400.0,-228.6,192.3);
}
if ($timer eq "adds2") {
quest::shout("You will not win!");
quest::spawn2(402145,0,0,-1,1499.1,-228.6,129.0);
quest::spawn2(402146,0,0,-97.4,1400.0,-228.6,62.8);
quest::spawn2(402147,0,0,-0.3,1273.1,-228.6,0.1);
quest::spawn2(402148,0,0,94.8,1400.0,-228.6,192.3);
}
if ($timer eq "disease") {
my @ClientList = $entity_list->GetClientList();
foreach $i(@ClientList) {
if ($i) {
$npc->SpellFinished(5188, $i);
}
}
}
if ($timer eq "armorbreak") {
my @ClientList = $entity_list->GetClientList();
foreach $i(@ClientList) {
if ($i) {
$i->SpellFinished(5190, $i);
}
}
}
if ($timer eq "poison") {
my @ClientList = $entity_list->GetClientList();
foreach $i(@ClientList) {
if ($i) {
$npc->SpellFinished(5189, $i);
}
}
}

if ($timer eq "deathtouch") {
my @ClientList = $entity_list->GetClientList();
my $target = $ClientList[rand @ClientList];
if ($target) {
$npc->SpellFinished(7477,$target); #Cazic Touch 2
}
}
}

sub EVENT_HP {
if ($hpevent <= 50 && $hpevent >= 49) {
quest::shout("Come my Children!");
quest::spawn2(402145,0,0,-1,1499.1,-228.6,129.0);
quest::spawn2(402146,0,0,-97.4,1400.0,-228.6,62.8);
quest::spawn2(402147,0,0,-0.3,1273.1,-228.6,0.1);
quest::spawn2(402148,0,0,94.8,1400.0,-228.6,192.3);
quest::stoptimer("adds");
quest::settimer("adds2",45);
}
}

sub EVENT_SIGNAL {
my $npcname = $npc->GetCleanName();

if ($signal == 1) {
$minhit += 1595; #update with balanced minhit, bases, should scale +100 on each end
$maxhit += 2000; #update with balanced maxhit, bases, should scale +100 on each end
$counter += 1;
quest::ze(14,"$npcname Grows in Size");
$size = $counter;
quest::npcsize(15 + $size);
quest::modifynpcstat("min_hit",$minhit + 100); #balance
quest::modifynpcstat("max_hit",$maxhit + 200); #Balance5
$npc->SetHP($npc->GetHP() + 122500); #set for proper %s. 5% per mob will be #
}
if ($signal == 2) { #Southern Mobs
$counter2 += 1;
if ($counter2 == 2) {
quest::settimer("disease", 50);
}
}
if ($signal == 3) { #Northern Mobs
$counter3 += 1;
if ($counter3 == 2) {
quest::settimer("armorbreak", 40);
}
}
if ($signal == 4) { #Eastern Mobs
$counter4 += 1;
if ($counter4 == 2) {
quest::settimer("poison", 45);
}
}
if ($signal == 5) { #Western Mobs
$counter5 += 1;
if ($counter5 == 2) {
quest::settimer("deathtouch", 60); #Random Client DT
quest::shout("DT");
}
}
}

sub EVENT_SLAY { #Raises another Servant, this one is aggro and fights tho.
if ($npc && $entity_list) {
quest::shout("Rise! Serve your new master!");
my $entida = quest::spawn2(402149,0,0,$x,$y,$z,$h); #need to get NPCid for this shit.
if ($entida) {
$entida->CastToNPC()->AddToHateList($npc->GetHateTop(),1);
}
}
}

http://pastebin.com/BvJgWasv


Heres a much simpler example - which uses the targets in a # of different subs.

another dirty script but i wrote this a year ago now so :P.


#second priest of the nameless
#63147
#spawns in courtyard

sub EVENT_SPAWN {
quest::modifynpcstat("special_attacks","SERFTMCNIDf");
quest::shout("Behold! The power of The Nameless.");
$counter = 0;
}

sub EVENT_COMBAT {
if ($combat_state == 1) {
quest::shout("I will destroy you fools! How dare you challenge me!");
quest::settimer("race",10);
quest::settimer("leach",50);
quest::settime("ae",70);
quest::setnexthpevent(80);
}
if ($combat_state == 0) {
quest::stoptimer("race");
quest::stoptimer("leach");
quest::depopall(63149);
quest::depopall(63148);
quest::npcrace(1);
$npc->ChangeSize(5);
quest::shout("Foolish Mortals!");
$counter = 0;
quest::modifynpcstat("special_attacks","SERFTMCNIDf");
}
}

sub EVENT_TIMER {
if ($timer eq "leach") {
my $TTarget = $npc->GetHateTop();
quest::ze(4,"You feel your soul being ripped away...");
if ($TTarget) {
$npc->SpellFinished(4165,$TTarget);
}
}
if ($timer eq "race") {
quest::npcrace(452);
$npc->ChangeSize(75);
quest::stoptimer("race");
}
if ($timer eq "debuffirst") {
quest::stoptimer("debuffirst");
quest::settimer("debuff",70);
my @Hatelist = $npc->GetHateList();
foreach $i(@Hatelist) {
if ($i) {
my $hent = $i->GetEnt();
if ($hent) {
$npc->SpellFinished(3496,$hent);
}
}
}
}
if ($timer eq "ae") {
my @Hatelist = $npc->GetHateList();
foreach $i(@Hatelist) {
if ($i) {
my $hent = $i->GetEnt();
if ($hent) {
$npc->SpellFinished(3498,$hent);
}
}
}
}
if ($timer eq "debuff") {
my @Hatelist = $npc->GetHateList();
foreach $i(@Hatelist) {
if ($i) {
my $hent = $i->GetEnt();
if ($hent) {
$npc->SpellFinished(3496,$hent);
}
}
}
}
if ($timer eq "pull") {
my @Hatelist = $npc->GetHateList();
foreach $i(@Hatelist) {
if ($i) {
my $hent = $i->GetEnt();
if ($hent) {
$npc->SpellFinished(2080,$hent);
}
}
}
}
}

sub EVENT_HP {
if ($hpevent <= 80 && $hpevent >= 79) {
quest::shout("Feel my wraith!");
quest::settimer("debuffirst",3);
quest::setnexthpevent(60);
}
if ($hpevent <= 60 && $hpevent >= 59) {
quest::shout("Tremble before my power!");
quest::ze(14,"The Ground begins to shake, Crystals rise out of the ground");
quest::spawn2(63148,0,0,255.6, 832.7,6.8,165.3);
quest::spawn2(63148,0,0,160.0,750.2,6.9,40.6);
quest::spawn2(63148,0,0,239.2,681.5,6.9,6.0);
quest::modifynpcstat("special_attacks","ABSERFTMCNIDf");
quest::setnexthpevent(30);
}
if ($hpevent <= 30 && $hpevent >= 29) {
quest::ze(14,"You feel you skin rip away from you");
my @Hatelist = $npc->GetHateList();
foreach $i(@Hatelist) {
if ($i) {
my $hent = $i->GetEnt();
if ($hent) {
my $dmgamt = ($hent->GetHP() * .25);
$hent->Damage($npc,$dmgamt, 0, 1, 'FALSE', -1, 'FALSE');
$hent->Message(16, "The Priest's Eyes glow red. You have taken $dmgamt of Non-Melee damage.");
}
}
}
}
}

sub EVENT_SIGNAL {
if ($signal == 1) {
$counter += 1;
if ($counter == 3) {
quest::modifynpcstat("special_attacks","SERFTMCNIDf");
quest::ze(14,"The Priest of the Nameless roars with rage");
quest::depopall(63149);
$counter = 0;
}
}
}

sub EVENT_DEATH {
quest::stoptimer("pull");
quest::stoptimer("debuff");
quest::stoptimer("ae");
quest::shout2("I will have my revenge!");
quest::signalwith(63146,3,0);
}

sub EVENT_KILLED_MERIT {
my $globalname = "raidevent";

if (!defined $qglobals{$globalname}) {
quest::setglobal("$globalname",1,5,'H8');
}
}


http://pastebin.com/7hCm4ny8

im getting a bit long winded and this is prolly beyond answering your question and moving towards confusion (sorry just got home from work and burnt out lol). i can clarify anything, im not 100% sure on the reasoning for alot of the syntax i will admit, im not a programmer by trade only hobby, and alot of what i have done/scripted here has been taking bits and pieces from others work and asking them the why/what and how of their stuff so i can utilize it :P.

So feel free to do that with my stuff - best way to learn IMO :P

Dunge0nMastr
06-26-2013, 08:30 PM
sorry if i confused/confuddled :P lol i dont do a good job of proofing when im tired. id be happy to walk through some basics with people on what I know, hardly an expert but definately gotten better at this over the last year :P