Jump to content

Playerbot (archive)


Recommended Posts

Looking into warlock AI I found that PlayerBot has no ability to cast pet spells. AI expects pet spells to be found in master's spell list and casted by master as well. Maybe it was ok before, but doesn't work now. I created a patch which adds:

1) 'pet spells' command, similar to 'spells';

2) 'petcast' / 'pc' command, similar to 'cast'/'c'

Patch itself: http://pastebin.org/378580

Please test it and leave your comments.

Hi,

Thanks very much for your contribution, I'll start testing it now. I have been testing the 'soul_link' patch and it works fine. If it's O.K with you I'll included it in the next repo update. It will be done shortly, with code compatible with client 3.3.5a - MaNGOS[10136]+

Game play is certainly quieter now. I didn't realise that the warlock was continuely casting 'soul link', :rolleyes:

Have you got a GitHub account? If not they are easy to setup and free. I can then add you as a contributor to both repos and you can push your own work, when your ready.

Let me know, and thanks again

Link to comment
Share on other sites

  • Replies 1.8k
  • Created
  • Last Reply

Top Posters In This Topic

Hi kyle1,

I am presently testing your patch with MaNGOS[10136] SD2[1736].

I'm having an issue with 'pet spells'

/w botname pet spells 

&

/p pet spells

Bot Test Group

Warlock Pet Imp Companion Red Dragon Hatchling Mount Felsteed

Hunter Pet Raptor Mount Timber Wolf

Rogue Mount Black Skeletal Horse

Shaman None

Paladin None

The command 'pet spells' works fine for the Warlock and the Hunter, but when used with the Rogue causes the server to crash everytime. Both the Warlock and the Hunter have multiple creatures listed under the pet tab, whereas the Rogue only has the mount. As far as I know, none of the mounts should have spells, so it's even more of a puzzle why the crash occurs.

The crash is sudden with no server warnings. I'll try to gather more info if I can.

EDIT: I have found the problem. Although you include an event trap to cater for bots without pets, the program flow still continues. As soon as the pointer 'pet' is first used, the server will crash. Include a 'return' in the trap condition, as below.

else if (text == "pet spells")

{

sLog.outDebug( "[PlayerbotAI]: pet spells %s", m_bot->GetName());

Pet *pet = m_bot->GetPet();

if (!pet) {

SendWhisper("I have no pet.", fromPlayer);

return;

}

I notice that you use a similar trap for the command 'pet cast'. A 'return' should be included in this too

Hope this helps.

Link to comment
Share on other sites

Hi kyle1,

I've now been using the 'petcast' only for a short time, but It is difficult see it's effects.

As I understand it, spells are used by pets automatically. The player is able to selectively activate or deactivate these spells. If 'petcast' was to allow the botmaster to activate/deacitvate these spell, that would be good. I assume this is what 'petcast' does, but there is no way of telling whether a spell has been activated or deactivated. A suggestion would be to display the links to (activated/deactivated) spells in different colours. Something like this;

/w pascal pet spells

[Pascal] whispers: Here's my pet's non-attack spells:

[Dash]

[Pascal] whispers: and here's my pet's attack spells:

[Claw][Cower][Growl][savage Rend]

Speak with you soon

Link to comment
Share on other sites

You are right, blueboy, pet spells are not so simple as player ones. Besides autocast flag, some spells can be triggered on/off, like paladin auras, Blood Pact for example. AI will need extra commands to set autocast flag and purge aura spells for pets.

Update: Here is a quick fix for your suggestion, red means autocast is off, green - on.

    else if (text == "pet spells")
   {
       Pet *pet = m_bot->GetPet();
       if (!pet) {
           SendWhisper("I have no pet.", fromPlayer);
           return;
       }

       int loc = GetMaster()->GetSession()->GetSessionDbcLocale();

       std::ostringstream posOut;
       std::ostringstream negOut;

       const std::string ignoreList = ",";
       std::string alreadySeenList = ",";

       for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) {
           const uint32 spellId = itr->first;

           if (itr->second.state == PETSPELL_REMOVED || itr->second.active == ACT_PASSIVE || IsPassiveSpell(spellId))
               continue;

           const SpellEntry* const pSpellInfo = sSpellStore.LookupEntry(spellId);
           if (!pSpellInfo)
               continue;

           std::string comp = ",";
           comp.append(pSpellInfo->SpellName[loc]);
           comp.append(",");

           if (!(ignoreList.find(comp) == std::string::npos && alreadySeenList.find(comp) == std::string::npos))
               continue;

           alreadySeenList += pSpellInfo->SpellName[loc];
           alreadySeenList += ",";

           std::string color;
           switch (itr->second.active)
           {
               case ACT_DISABLED:
                   color = "cffff0000";
                   break;
               case ACT_ENABLED:
                   color = "cff00ff00";
                   break;
               default:
                   color = "cffffffff";
           }

           if (IsPositiveSpell(spellId))
               posOut << " |" << color << "|Hspell:" << spellId << "|h["
                      << pSpellInfo->SpellName[loc] << "]|h|r";
           else
               negOut << " |" << color << "|Hspell:" << spellId << "|h["
                      << pSpellInfo->SpellName[loc] << "]|h|r";
       }

       ChatHandler ch(&fromPlayer);
       SendWhisper("Here's my pet's non-attack spells:", fromPlayer);
       ch.SendSysMessage(posOut.str().c_str());
       SendWhisper("and here's my pet's attack spells:", fromPlayer);
       ch.SendSysMessage(negOut.str().c_str());
   }

Link to comment
Share on other sites

Hi kyle1,

I hope you don't mind I've been trying a few ideas out that may help with your 'petcast' command. It might be nice to utilize string links (e.g [Growl]) from the 'pet spell' command.

In post #1175 I issued a patch to enhance the bot 'cast' command, although I didn't get much feedback. This included a function 'extractSpellId' to extract spellIds, encoded in the string links obtained from the 'spells' command.

I have adapted this, and included a patch for you to try out. (This was created for use with the portal repo, you will have to edit the file paths to work with blueboy)

diff --git a/src/game/playerbot/PlayerbotAI.h b/src/game/playerbot/PlayerbotAI.h
index ef4383f..4d4a2a1 100644
--- a/src/game/playerbot/PlayerbotAI.h
+++ b/src/game/playerbot/PlayerbotAI.h
@@ -127,6 +127,9 @@ class MANGOS_DLL_SPEC PlayerbotAI
        // extracts item ids from links
        void extractItemIds(const std::string& text, std::list<uint32>& itemIds) const;

+        // extract spellid from links
+        bool extractSpellId(const std::string& text, uint32 &spellId) const;
+
        // extracts currency from a string as #g#s#c and returns the total in copper
        uint32 extractMoney(const std::string& text) const;

diff --git a/src/game/playerbot/PlayerbotAI.cpp b/src/game/playerbot/PlayerbotAI.cpp
index 9e42771..54e5d04 100644
--- a/src/game/playerbot/PlayerbotAI.cpp
+++ b/src/game/playerbot/PlayerbotAI.cpp
@@ -2377,6 +2377,34 @@ void PlayerbotAI::extractItemIds(const std::string& text, std::list<uint32>& ite
    }
}

+bool PlayerbotAI::extractSpellId(const std::string& text, uint32 &spellId) const
+{
+
+     //   Link format
+     //   |cffffffff|Hspell:" << spellId << ":" << "|h[" << pSpellInfo->SpellName[loc] << "]|h|r";
+     //   cast |cff71d5ff|Hspell:686|h[shadow Bolt]|h|r";
+     //   012345678901234567890123456
+     //        base = 16 >|  +7 >|
+
+    uint8 pos = 0;
+
+        int i = text.find("Hspell:", pos);
+        if (i == -1)
+            return false;
+
+        // DEBUG_LOG("extractSpellId first pos %u i %u",pos,i);
+        pos = i + 7; // start of window in text 16 + 7 = 23
+        int endPos = text.find('|', pos);
+        if (endPos == -1)
+            return false;
+
+        // DEBUG_LOG("extractSpellId second endpos : %u pos : %u",endPos,pos);
+        std::string idC = text.substr(pos, endPos - pos); // 26 - 23
+        spellId = atol(idC.c_str());
+        pos = endPos; // end
+        return true;
+}
+
bool PlayerbotAI::extractGOinfo(const std::string& text, uint32 &guid, uint32 &entry, int &mapid, float &x, float &y, float &z) const
{

@@ -2872,6 +2900,41 @@ void PlayerbotAI::HandleCommand(const std::string& text, Player& fromPlayer)
        }
    }

+    //handle pet cast command
+    else if (text.size() > 3 && text.substr(0, 3) == "pc " || text.size() > 8 && text.substr(0, 8) == "petcast ")
+    {
+        Pet *pet = m_bot->GetPet();
+        if (!pet) {
+            SendWhisper("I have no pet.", fromPlayer);
+            return;
+        }
+        else {
+            std::string spellStr = text.substr(text.find(" ") + 1);
+            uint32 spellId = (uint32) atol(spellStr.c_str());
+
+            // try and get spell ID by name
+            if (spellId == 0)
+                spellId = getPetSpellId(spellStr.c_str());
+
+            // try link if text NOT (spellid OR spellname)
+            if (spellId == 0)
+                extractSpellId(text, spellId);
+
+            if (spellId != 0 && pet->HasSpell(spellId))
+            {
+
+                PetSpellMap::iterator itr = pet->m_spells.find(spellId);
+                if (itr != pet->m_spells.end())
+                {
+                    if(itr->second.active == ACT_ENABLED)
+                        pet->ToggleAutocast(spellId, false);
+                    else
+                        pet->ToggleAutocast(spellId, true);
+                }
+            }
+        }
+    }
+
    // use items
    else if (text.size() > 2 && text.substr(0, 2) == "u " || text.size() > 4 && text.substr(0, 4) == "use ")
    {
@@ -3170,6 +3233,70 @@ void PlayerbotAI::HandleCommand(const std::string& text, Player& fromPlayer)
        ch.SendSysMessage(negOut.str().c_str());
    }

+
+    else if (text == "pet spells")
+    {
+
+        Pet *pet = m_bot->GetPet();
+        if (!pet) {
+            SendWhisper("I have no pet.", fromPlayer);
+            return;
+        }
+
+        int loc = GetMaster()->GetSession()->GetSessionDbcLocale();
+
+        std::ostringstream posOut;
+        std::ostringstream negOut;
+
+        const std::string ignoreList = ",";
+        std::string alreadySeenList = ",";
+
+        for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) {
+            const uint32 spellId = itr->first;
+
+            if (itr->second.state == PETSPELL_REMOVED || IsPassiveSpell(spellId))
+                continue;
+
+            const SpellEntry* const pSpellInfo = sSpellStore.LookupEntry(spellId);
+            if (!pSpellInfo)
+                continue;
+
+            std::string comp = ",";
+            comp.append(pSpellInfo->SpellName[loc]);
+            comp.append(",");
+
+            if (!(ignoreList.find(comp) == std::string::npos && alreadySeenList.find(comp) == std::string::npos))
+                continue;
+
+            alreadySeenList += pSpellInfo->SpellName[loc];
+            alreadySeenList += ",";
+
+            if (IsPositiveSpell(spellId))
+            {
+              if(itr->second.active == ACT_ENABLED) // link green
+                  posOut << " |CFF086142|Hspell:" << spellId << "|h["
+                       << pSpellInfo->SpellName[loc] << "]|h|r";
+              else // link red
+                  posOut << " |CFFFF0000|Hspell:" << spellId << "|h["
+                       << pSpellInfo->SpellName[loc] << "]|h|r";
+            }else{
+              if(itr->second.active == ACT_ENABLED) // link green
+                  negOut << " |CFF086142|Hspell:" << spellId << "|h["
+                      << pSpellInfo->SpellName[loc] << "]|h|r";
+              else // link red
+                  negOut << " |CFFFF0000|Hspell:" << spellId << "|h["
+                      << pSpellInfo->SpellName[loc] << "]|h|r";
+            }
+        }
+
+        ChatHandler ch(&fromPlayer);
+        SendWhisper("Here's my pet's non-attack spells:", fromPlayer);
+        ch.SendSysMessage(posOut.str().c_str());
+        SendWhisper("and here's my pet's attack spells:", fromPlayer);
+        ch.SendSysMessage(negOut.str().c_str());
+    }
+
+
    // survey project: 18:30 29/04/10 rev.3 filter out event triggered objects & now updates list
    else if (text == "survey")
    {

Essentially, you first use the 'pet spells' command

You will get a list of string links, activated ones in green and deactivated ones in red. By default each pet will have some spells that are always loaded active (e.g Demon imp - [Firebolt][blood Pact]). Although you can then deactivate them if you wish.

Autocast spells

To toggle (activate or deactivate) spell(s)

/p petcast <Shift Click> [Firebolt]

/w botname petcast <Shift Click> [Firebolt]

Hope this helps

Link to comment
Share on other sites

there is a bug!

Invite the player to the party, player will logouf of the game!

Hi,

Thanks for the info, but can you give me some details.

What version of MaNGOS are you running with playerbot and which mods/patches are you using?

Please get back to me

Link to comment
Share on other sites

Hi, blueboy.

I like the idea of extraction of spellid from links cos people are lazy to type usually. But toggling autocast on cast command is not very good. Try to toggle Consume Shadows of warlock's voidwalker, and it will burn all its mana in vain. I suggest to introduce a new command ( (t)oggle for example ) to explicitly toggle autocast for pet spells, and keep petcast command for casting when its needed.

Link to comment
Share on other sites

Hi,

Thanks for the info, but can you give me some details.

What version of MaNGOS are you running with playerbot and which mods/patches are you using?

Please get back to me

Mangos core 10149

UBD

BattleGround Patch

VeHicle e Dungoen_Finde Patch from zergtmn

All patch works well, including PlayerBot.

logout happens every time it is to invite for group another player!

Link to comment
Share on other sites

Hi kyle1

That sounds good, I'll update the repos shortly to include your 'soul link' patch and my 'cast' patch. So the extractSpellId function will be available in the code for you to use. I have a few more patches, but I won't push them yet.

Cheers

Link to comment
Share on other sites

Hi kaxias,

So let me get this straight, when you invite another player (not a bot) to join the player group, your logged out. Is the exit graceful, or are you booted?

Although the patches may well appear to work well, they can often conflict, causing weird side effects. I will check playerbot with MaNGOS[10149] and see whether I get a problem. Then I suggest you add each of the patches one by one until the error occurs again. That way we can track the root cause. I'll also look at the changelogs, to see if there are any logout issues.

Cheers

Link to comment
Share on other sites

Hi kaxias,

So let me get this straight, when you invite another player (not a bot) to join the player group, your logged out.

Although the patches may well appear to work well, they can often conflict, causing weird side effects. I will check playerbot with MaNGOS[10149] and see whether I get a problem. Then I suggest you add each of the patches one by one until the error occurs again. That way we can track the root cause. I'll also look at the changelogs, to see if there are any logout issues.

Cheers

Hi BlueBoy

i try to invite playerbot for injoin the grupo for do instance!

Link to comment
Share on other sites

BlueBoy

Look at this diff, correct white spaces, and includes VB2010 and VB2005!

Special look Here!

        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid);

-        sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
-        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",
-            GetAccountId());
        DEBUG_LOG( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );

http://www.mediafire.com/?0gldjtmtaj2

Link to comment
Share on other sites

BlueBoy

Look at this diff, correct white spaces, and includes VB2010 and VB2005!

Special look Here!

        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid);

-        sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
-        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",
-            GetAccountId());
        DEBUG_LOG( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );

http://www.mediafire.com/?0gldjtmtaj2

Hi kaxias,

Thanks for the info. I found the code snippet you cited in WorldSession.cpp. Here is the patch for that section of code

@@ -439,6 +489,13 @@ void WorldSession::LogoutPlayer(bool Save)

        ///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline
        //No SQL injection as AccountId is uint32
+        //CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",
+        //    GetAccountId());
+
+        // Playerbot mod: commented out above and do this one instead
+        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid);
+
+        sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",
            GetAccountId());
        DEBUG_LOG( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );

I see what you mean. The comments actually tell you to comment out the line

CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",

GetAccountId());

But it remains uncommented just below the Playerbot mod. I must tell you that I have tested playerbot out and I can't get it to misbehave, as it does for you. You could try commenting out the above line and see if it solves your issue.

Are all the other mods up-to-date. I have checked zergtmn's github repos

Dungeon Finder was last merged with MaNGOS[10054] I see you had issues with this mod and he told you that he had only just ported in from Trinitycore.

and

Vehicle_dev was last merged with MaNGOS[10130]

As you are no doubt aware core has just switched to 3.3.5a MaNGOS[10136] and the other mods might not be fully compatible. It might even be a database issue, is UDB compatible with 3.3.5a. Try building a server first with just MaNGOS and playerbot. See whether you still get the logout issue. If it checks out, then add your other mods one by one until the issue occurs.

I have check playerbot with the latest MaNGOS[10154] & SD2[1737] and it works fine, with no group invite logout issue.

Hope this helps

Link to comment
Share on other sites

Hi Guys,

Since posting both botguy patches, I have not received any bad feedback. I have tested the patches myself and they work well, so I have now decided to include the code in the repos. I will be updating the repos shortly.

Recap

#

# PlayerbotAI.BotguyQuests

# List of Quest ids, any of which, once completed will enable botguy menu on NPCs

# List must be enclosed in double quotes ("") and multiple Quest Ids separated by a comma(,)

# Example: "805,54,2160"

# Default: "" no quest restriction, memu always displayed by NPCs

#

# PlayerbotAI.BotguyCost

# Cost (Copper coins) levied on summoning a bot

# If player has the cost, botguy menu will be displayed by NPCs

# Default: 0 - no cost, menu always displayed by NPCs#

###################################################################################################################

PlayerbotAI.DisableBots = 0

PlayerbotAI.DebugWhisper = 0

PlayerbotAI.FollowDistanceMin = 0.5

PlayerbotAI.FollowDistanceMax = 1.0

PlayerbotAI.MaxNumBots = 9

PlayerbotAI.RestrictBotLevel = 80

PlayerbotAI.BotguyQuests = "805,54,2160"

PlayerbotAI.BotguyCost = 5

PlayerbotAI.BotguyQuests (To disable, choose a very high level quest)

A list of pre-requisite quest ids, separated by commas and included in quotes. If the player has completed any one of the quests listed, then the botguy menu will be displayed. The composition of the list is your choice, the quests can be made as hard or as easy as you want. I have given "805,54,2160" as an example. You may feel it's a good idea to encourage players to complete the trial quests first. Below is a suggested list of level 5 quests.

QuestId       Description Quest,Location,Race
805           Report to Sen jin Village, Durotar, Orcs & Trolls
383           Vital Intelligence, Deathknell Tirisfal Glades, Undead
2160          Supplies to Tannock, Coldridge Valley Dun Morogh, Dwarves & Gnomes
54            Report to Goldshire, Northshire Elwynn Forest, Human
8350          Completing the Delivery,Sunstrider Isle Eversong Wood, Blood Elves
9313          Travel to Azure Watch, Ammen Vale Azuremyst Isle, Draenei
1656          A Task Unfinished, Red Cloud Mesa Mulgore, Tauren
2159          Dolanaar Delivery, Shadowglen Teldrassil, Night Elves

PlayerbotAI.BotguyCost (To disable, choose a very high cost)

This is self explanatory. A tax is levied on the ability to summon bot. If the player does not have enough money, the botguy menu will not be available. (Thanks to ckegg for his help with this).

Hope this helps

Link to comment
Share on other sites

it is not easy to maintain a list of quest id inside a conf files, perhaps a table should be easyer, what do you think ?

Hi,

What is difficult in creating this list. The list of quests is only a suggestion. If you want the botguy menu to always show, leave the quotes empty, else

PlayerbotAI.BotguyQuests = "805,383,2160,54,8350,9313,1656,2159"

That's it. Your players must then complete at least one of the listed quests, for the botguy menu to show.

no maintenance is required?

EDIT: If it would help I'll include the full list above in the conf description as an example. A table suggests that the list of quests were pre-defined, and that would not be practical. I wanted it to be flexible, so you the server administator would have better control over the use of botguy menus by your players.

Cheers

Link to comment
Share on other sites

Hi Guys,

More changes with the core. I suggest you do not update passed MaNGOS[10155] yet. Changes have broken playerbot & SD2. It's a real mine field at present, so stay put. I think I have resolved the issue with playebot, but until SD2 is working again I can't test it

AuraMap has changed to SpellAuraHolderMap

and GetAuras() is now GetSpellAuraHolderMap()

These changes effect PlayerbotAI.cpp in function HasAura().

The compile then continued until it reached

../../../../src/bindings/ScriptDev2/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp: In member function void boss_archimondeAI::UnleashSoulCharge():                                                                                                                                                         
../../../../src/bindings/ScriptDev2/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp:400: error: class Creature has no member named RemoveSingleAuraFromStack                                                                                                                                               
make[6]: *** [boss_archimonde.lo] Error 1                                                                                                                    
make[6]: Leaving directory `/home/mangos/compile/mangos/objdir/src/bindings/ScriptDev2'                                                                      
make[5]: *** [all-recursive] Error 1                                                                                                                         
make[5]: Leaving directory `/home/mangos/compile/mangos/objdir/src/bindings/ScriptDev2'                                                                      
make[4]: *** [all] Error 2                                                                                                                                   

Hope this helps

Link to comment
Share on other sites

Hi Guys,

More changes with the core. I suggest you do not update passed MaNGOS[10155] yet. Changes have broken playerbot & SD2. It's a real mine field at present, so stay put. I think I have resolved the issue with playebot, but until SD2 is working again I can't test it

AuraMap has changed to SpellAuraHolderMap

and GetAuras() is now GetSpellAuraHolderMap()

These changes effect PlayerbotAI.cpp in function HasAura().

The compile then continued until it reached

../../../../src/bindings/ScriptDev2/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp: In member function void boss_archimondeAI::UnleashSoulCharge():                                                                                                                                                         
../../../../src/bindings/ScriptDev2/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp:400: error: class Creature has no member named RemoveSingleAuraFromStack                                                                                                                                               
make[6]: *** [boss_archimonde.lo] Error 1                                                                                                                    
make[6]: Leaving directory `/home/mangos/compile/mangos/objdir/src/bindings/ScriptDev2'                                                                      
make[5]: *** [all-recursive] Error 1                                                                                                                         
make[5]: Leaving directory `/home/mangos/compile/mangos/objdir/src/bindings/ScriptDev2'                                                                      
make[4]: *** [all] Error 2                                                                                                                                   

Hope this helps

changed from

void RemoveSingleAuraFromStack(uint32 spellId, SpellEffectIndex effindex, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);

to

void RemoveSingleAuraHolderFromStack(uint32 spellId, uint64 casterGUID = 0, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);

so probably change

       if (m_creature->HasAura(chargeSpell, EFFECT_INDEX_0))
       {
           m_creature->RemoveSingleAuraFromStack(chargeSpell, EFFECT_INDEX_0);
           DoCastSpellIfCan(m_creature->getVictim(), unleashSpell);
           HasCast = true;
           --SoulChargeCount;
       }

to

       if (m_creature->HasAura(chargeSpell, EFFECT_INDEX_0))
       {
           m_creature->RemoveSingleAuraHolderFromStack(chargeSpell, m_creature);
           DoCastSpellIfCan(m_creature->getVictim(), unleashSpell);
           HasCast = true;
           --SoulChargeCount;
       }

note: it's 01:00 (AM) so i was just going to bed when seeing this, it may not be correct xD

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use