Created
November 20, 2010 22:44
-
-
Save rsa/708243 to your computer and use it in GitHub Desktop.
Simplify PetActions for use with multiple controlled units. Original author Laise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/game/Pet.h b/src/game/Pet.h | |
index 620791d..9cdc2ad 100644 | |
--- a/src/game/Pet.h | |
+++ b/src/game/Pet.h | |
@@ -269,4 +269,30 @@ class Pet : public Creature | |
MANGOS_ASSERT(false); | |
} | |
}; | |
+ | |
+struct DoPetActionWithHelper | |
+{ | |
+ explicit DoPetActionWithHelper( Player* _owner, uint8 _flag, uint32 _spellid, ObjectGuid _petGuid, ObjectGuid _targetGuid) : | |
+ owner(_owner), flag(_flag), spellid(_spellid), petGuid(_petGuid), targetGuid(_targetGuid) | |
+ {} | |
+ void operator()(Unit* unit) const { unit->DoPetAction(owner, flag, spellid, petGuid, targetGuid); } | |
+ Player* owner; | |
+ uint8 flag; | |
+ uint32 spellid; | |
+ ObjectGuid petGuid; | |
+ ObjectGuid targetGuid; | |
+}; | |
+ | |
+struct DoPetCastWithHelper | |
+{ | |
+ explicit DoPetCastWithHelper( Player* _owner, uint8 _cast_count, SpellCastTargets* _targets, SpellEntry const* _spellInfo ) : | |
+ owner(_owner), cast_count(_cast_count), targets(_targets), spellInfo(_spellInfo) | |
+ {} | |
+ void operator()(Unit* unit) const { unit->DoPetCastSpell(owner,cast_count,targets,spellInfo ); } | |
+ Player* owner; | |
+ uint8 cast_count; | |
+ SpellCastTargets* targets; | |
+ SpellEntry const* spellInfo; | |
+}; | |
+ | |
#endif | |
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp | |
index f1ce925..2402087 100644 | |
--- a/src/game/PetHandler.cpp | |
+++ b/src/game/PetHandler.cpp | |
@@ -80,196 +80,8 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) | |
return; | |
} | |
- switch(flag) | |
- { | |
- case ACT_COMMAND: //0x07 | |
- switch(spellid) | |
- { | |
- case COMMAND_STAY: //flat=1792 //STAY | |
- pet->StopMoving(); | |
- pet->GetMotionMaster()->Clear(false); | |
- pet->GetMotionMaster()->MoveIdle(); | |
- charmInfo->SetCommandState( COMMAND_STAY ); | |
- break; | |
- case COMMAND_FOLLOW: //spellid=1792 //FOLLOW | |
- pet->AttackStop(); | |
- pet->GetMotionMaster()->MoveFollow(_player,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); | |
- charmInfo->SetCommandState( COMMAND_FOLLOW ); | |
- break; | |
- case COMMAND_ATTACK: //spellid=1792 //ATTACK | |
- { | |
- Unit *TargetUnit = _player->GetMap()->GetUnit(targetGuid); | |
- if(!TargetUnit) | |
- return; | |
- | |
- // not let attack friendly units. | |
- if(GetPlayer()->IsFriendlyTo(TargetUnit)) | |
- return; | |
- // Not let attack through obstructions | |
- if(!pet->IsWithinLOSInMap(TargetUnit)) | |
- return; | |
- | |
- // This is true if pet has no target or has target but targets differs. | |
- if(pet->getVictim() != TargetUnit) | |
- { | |
- if (pet->getVictim()) | |
- pet->AttackStop(); | |
- | |
- if (pet->hasUnitState(UNIT_STAT_CONTROLLED)) | |
- { | |
- pet->Attack(TargetUnit, true); | |
- pet->SendPetAIReaction(); | |
- } | |
- else | |
- { | |
- pet->GetMotionMaster()->Clear(); | |
- | |
- if (((Creature*)pet)->AI()) | |
- ((Creature*)pet)->AI()->AttackStart(TargetUnit); | |
- | |
- // 10% chance to play special pet attack talk, else growl | |
- if(((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10)) | |
- pet->SendPetTalk((uint32)PET_TALK_ATTACK); | |
- else | |
- { | |
- // 90% chance for pet and 100% chance for charmed creature | |
- pet->SendPetAIReaction(); | |
- } | |
- } | |
- } | |
- break; | |
- } | |
- case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) | |
- if(((Creature*)pet)->IsPet()) | |
- { | |
- Pet* p = (Pet*)pet; | |
- if(p->getPetType() == HUNTER_PET) | |
- p->Unsummon(PET_SAVE_AS_DELETED, _player); | |
- else | |
- //dismissing a summoned pet is like killing them (this prevents returning a soulshard...) | |
- p->SetDeathState(CORPSE); | |
- } | |
- else // charmed | |
- _player->Uncharm(); | |
- break; | |
- default: | |
- sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); | |
- } | |
- break; | |
- case ACT_REACTION: // 0x6 | |
- switch(spellid) | |
- { | |
- case REACT_PASSIVE: //passive | |
- case REACT_DEFENSIVE: //recovery | |
- case REACT_AGGRESSIVE: //activete | |
- charmInfo->SetReactState( ReactStates(spellid) ); | |
- break; | |
- } | |
- break; | |
- case ACT_DISABLED: // 0x81 spell (disabled), ignore | |
- case ACT_PASSIVE: // 0x01 | |
- case ACT_ENABLED: // 0xC1 spell | |
- { | |
- Unit* unit_target = NULL; | |
- if (!targetGuid.IsEmpty()) | |
- unit_target = _player->GetMap()->GetUnit(targetGuid); | |
- | |
- // do not cast unknown spells | |
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); | |
- if (!spellInfo) | |
- { | |
- sLog.outError("WORLD: unknown PET spell id %i", spellid); | |
- return; | |
- } | |
- | |
- if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) | |
- return; | |
- | |
- for(int i = 0; i < MAX_EFFECT_INDEX;++i) | |
- { | |
- if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) | |
- return; | |
- } | |
- | |
- // do not cast not learned spells | |
- if(!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) | |
- return; | |
- | |
- pet->clearUnitState(UNIT_STAT_MOVING); | |
- | |
- Spell *spell = new Spell(pet, spellInfo, false); | |
- | |
- SpellCastResult result = spell->CheckPetCast(unit_target); | |
- | |
- //auto turn to target unless possessed | |
- if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) | |
- { | |
- if(unit_target) | |
- { | |
- pet->SetInFront(unit_target); | |
- if (unit_target->GetTypeId() == TYPEID_PLAYER) | |
- pet->SendCreateUpdateToPlayer( (Player*)unit_target ); | |
- } | |
- else if(Unit *unit_target2 = spell->m_targets.getUnitTarget()) | |
- { | |
- pet->SetInFront(unit_target2); | |
- if (unit_target2->GetTypeId() == TYPEID_PLAYER) | |
- pet->SendCreateUpdateToPlayer( (Player*)unit_target2 ); | |
- } | |
- if (Unit* powner = pet->GetCharmerOrOwner()) | |
- if(powner->GetTypeId() == TYPEID_PLAYER) | |
- pet->SendCreateUpdateToPlayer((Player*)powner); | |
- result = SPELL_CAST_OK; | |
- } | |
- | |
- if(result == SPELL_CAST_OK) | |
- { | |
- ((Creature*)pet)->AddCreatureSpellCooldown(spellid); | |
- | |
- unit_target = spell->m_targets.getUnitTarget(); | |
- | |
- //10% chance to play special pet attack talk, else growl | |
- //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell | |
- if(((Creature*)pet)->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10)) | |
- pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); | |
- else | |
- { | |
- pet->SendPetAIReaction(); | |
- } | |
- | |
- if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) | |
- { | |
- // This is true if pet has no target or has target but targets differs. | |
- if (pet->getVictim() != unit_target) | |
- { | |
- if (pet->getVictim()) | |
- pet->AttackStop(); | |
- pet->GetMotionMaster()->Clear(); | |
- if (((Creature*)pet)->AI()) | |
- ((Creature*)pet)->AI()->AttackStart(unit_target); | |
- } | |
- } | |
- | |
- spell->prepare(&(spell->m_targets)); | |
- } | |
- else | |
- { | |
- if(pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) | |
- Spell::SendCastResult(GetPlayer(),spellInfo,0,result); | |
- else | |
- pet->SendPetCastFail(spellid, result); | |
- | |
- if (!((Creature*)pet)->HasSpellCooldown(spellid)) | |
- GetPlayer()->SendClearCooldown(spellid, pet); | |
- | |
- spell->finish(false); | |
- delete spell; | |
- } | |
- break; | |
- } | |
- default: | |
- sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); | |
- } | |
+ if (((Creature*)pet)->IsPet() || pet->isCharmed()) | |
+ GetPlayer()->CallForAllControlledUnits(DoPetActionWithHelper(GetPlayer(), flag, spellid, petGuid, targetGuid),CONTROLLED_PET|CONTROLLED_GUARDIANS|CONTROLLED_CHARM); | |
} | |
void WorldSession::HandlePetStopAttack(WorldPacket& recv_data) | |
@@ -636,7 +448,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) | |
DEBUG_LOG("WORLD: CMSG_PET_CAST_SPELL, %s, cast_count: %u, spellid %u, unk_flags %u", guid.GetString().c_str(), cast_count, spellid, unk_flags); | |
- Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid); | |
+ Creature* pet = GetPlayer()->GetMap()->GetAnyTypeCreature(guid); | |
if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid())) | |
{ | |
@@ -659,41 +471,15 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) | |
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) | |
return; | |
- SpellCastTargets targets; | |
- | |
- recvPacket >> targets.ReadForCaster(pet); | |
- | |
- pet->clearUnitState(UNIT_STAT_MOVING); | |
+ SpellCastTargets* targets = new SpellCastTargets; | |
- Spell *spell = new Spell(pet, spellInfo, false); | |
- spell->m_cast_count = cast_count; // probably pending spell cast | |
- spell->m_targets = targets; | |
- | |
- SpellCastResult result = spell->CheckPetCast(NULL); | |
- if (result == SPELL_CAST_OK) | |
- { | |
- pet->AddCreatureSpellCooldown(spellid); | |
- if (pet->IsPet()) | |
- { | |
- //10% chance to play special pet attack talk, else growl | |
- //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell | |
- if(((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) | |
- pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); | |
- else | |
- pet->SendPetAIReaction(); | |
- } | |
+ recvPacket >> targets->ReadForCaster(pet); | |
- spell->prepare(&(spell->m_targets)); | |
- } | |
- else | |
- { | |
- pet->SendPetCastFail(spellid, result); | |
- if (!pet->HasSpellCooldown(spellid)) | |
- GetPlayer()->SendClearCooldown(spellid, pet); | |
+ if (pet->IsPet() || pet->isCharmed()) | |
+ GetPlayer()->CallForAllControlledUnits(DoPetCastWithHelper(GetPlayer(), cast_count, targets, spellInfo ),CONTROLLED_PET|CONTROLLED_GUARDIANS|CONTROLLED_CHARM); | |
- spell->finish(false); | |
- delete spell; | |
- } | |
+ if (targets) | |
+ delete targets; | |
} | |
void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName) | |
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp | |
index 50f3f88..58200bc 100644 | |
--- a/src/game/Unit.cpp | |
+++ b/src/game/Unit.cpp | |
@@ -9554,6 +9554,245 @@ void CharmInfo::SetSpellAutocast( uint32 spell_id, bool state ) | |
} | |
} | |
+void Unit::DoPetAction( Player* owner, uint8 flag, uint32 spellid, ObjectGuid petGuid, ObjectGuid targetGuid) | |
+{ | |
+ if ((((Creature*)this)->IsPet() && !((Pet*)this)->IsInWorld()) || !GetCharmInfo()) | |
+ return; | |
+ | |
+ switch(flag) | |
+ { | |
+ case ACT_COMMAND: //0x07 | |
+ // Maybe exists some flag that disable it at client side | |
+ if (petGuid.IsVehicle()) | |
+ return; | |
+ | |
+ switch(spellid) | |
+ { | |
+ case COMMAND_STAY: //flat=1792 //STAY | |
+ StopMoving(); | |
+ GetMotionMaster()->Clear(false); | |
+ GetMotionMaster()->MoveIdle(); | |
+ GetCharmInfo()->SetCommandState( COMMAND_STAY ); | |
+ break; | |
+ case COMMAND_FOLLOW: //spellid=1792 //FOLLOW | |
+ AttackStop(); | |
+ GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); | |
+ GetCharmInfo()->SetCommandState( COMMAND_FOLLOW ); | |
+ break; | |
+ case COMMAND_ATTACK: //spellid=1792 //ATTACK | |
+ { | |
+ Unit *TargetUnit = owner->GetMap()->GetUnit(targetGuid); | |
+ if(!TargetUnit) | |
+ return; | |
+ | |
+ // not let attack friendly units. | |
+ if(owner->IsFriendlyTo(TargetUnit)) | |
+ return; | |
+ // Not let attack through obstructions | |
+ if(!IsWithinLOSInMap(TargetUnit)) | |
+ return; | |
+ | |
+ // This is true if pet has no target or has target but targets differs. | |
+ if(getVictim() != TargetUnit) | |
+ { | |
+ if (getVictim()) | |
+ AttackStop(); | |
+ | |
+ if (hasUnitState(UNIT_STAT_CONTROLLED)) | |
+ { | |
+ Attack(TargetUnit, true); | |
+ SendPetAIReaction(); | |
+ } | |
+ else | |
+ { | |
+ GetMotionMaster()->Clear(); | |
+ | |
+ if (((Creature*)this)->AI()) | |
+ ((Creature*)this)->AI()->AttackStart(TargetUnit); | |
+ | |
+ // 10% chance to play special pet attack talk, else growl | |
+ if(((Creature*)this)->IsPet() && ((Pet*)this)->getPetType() == SUMMON_PET && this != TargetUnit && roll_chance_i(10)) | |
+ SendPetTalk((uint32)PET_TALK_ATTACK); | |
+ else | |
+ { | |
+ // 90% chance for pet and 100% chance for charmed creature | |
+ SendPetAIReaction(); | |
+ } | |
+ } | |
+ | |
+ } | |
+ break; | |
+ } | |
+ case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) | |
+ if(((Creature*)this)->IsPet()) | |
+ { | |
+ Pet* p = (Pet*)this; | |
+ if(p->getPetType() == HUNTER_PET) | |
+ p->Unsummon(PET_SAVE_AS_DELETED, owner); | |
+ else | |
+ //dismissing a summoned pet is like killing them (this prevents returning a soulshard...) | |
+ p->SetDeathState(CORPSE); | |
+ } | |
+ else // charmed | |
+ owner->Uncharm(); | |
+ break; | |
+ default: | |
+ sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); | |
+ } | |
+ break; | |
+ case ACT_REACTION: // 0x6 | |
+ switch(spellid) | |
+ { | |
+ case REACT_PASSIVE: //passive | |
+ case REACT_DEFENSIVE: //recovery | |
+ case REACT_AGGRESSIVE: //activete | |
+ GetCharmInfo()->SetReactState( ReactStates(spellid) ); | |
+ break; | |
+ } | |
+ break; | |
+ case ACT_DISABLED: // 0x81 spell (disabled), ignore | |
+ case ACT_PASSIVE: // 0x01 | |
+ case ACT_ENABLED: // 0xC1 spell | |
+ { | |
+ Unit* unit_target = NULL; | |
+ | |
+ if (!targetGuid.IsEmpty()) | |
+ unit_target = owner->GetMap()->GetUnit(targetGuid); | |
+ | |
+ // do not cast unknown spells | |
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); | |
+ if(!spellInfo) | |
+ { | |
+ sLog.outError("WORLD: unknown PET spell id %i", spellid); | |
+ return; | |
+ } | |
+ | |
+ if (GetCharmInfo() && GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) | |
+ return; | |
+ | |
+ for(int i = 0; i < MAX_EFFECT_INDEX;++i) | |
+ { | |
+ if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) | |
+ return; | |
+ } | |
+ | |
+ // do not cast not learned spells | |
+ if(!HasSpell(spellid) || IsPassiveSpell(spellid)) | |
+ return; | |
+ | |
+ clearUnitState(UNIT_STAT_MOVING); | |
+ | |
+ Spell *spell = new Spell(this, spellInfo, false); | |
+ | |
+ SpellCastResult result = spell->CheckPetCast(unit_target); | |
+ | |
+ //auto turn to target unless possessed | |
+ if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !HasAuraType(SPELL_AURA_MOD_POSSESS)) | |
+ { | |
+ if(unit_target) | |
+ { | |
+ SetInFront(unit_target); | |
+ if (unit_target->GetTypeId() == TYPEID_PLAYER) | |
+ SendCreateUpdateToPlayer( (Player*)unit_target ); | |
+ } | |
+ else if(Unit *unit_target2 = spell->m_targets.getUnitTarget()) | |
+ { | |
+ SetInFront(unit_target2); | |
+ if (unit_target2->GetTypeId() == TYPEID_PLAYER) | |
+ SendCreateUpdateToPlayer( (Player*)unit_target2 ); | |
+ } | |
+ if (Unit* powner = GetCharmerOrOwner()) | |
+ if(powner->GetTypeId() == TYPEID_PLAYER) | |
+ SendCreateUpdateToPlayer((Player*)powner); | |
+ result = SPELL_CAST_OK; | |
+ } | |
+ | |
+ if(result == SPELL_CAST_OK) | |
+ { | |
+ ((Creature*)this)->AddCreatureSpellCooldown(spellid); | |
+ | |
+ unit_target = spell->m_targets.getUnitTarget(); | |
+ | |
+ //10% chance to play special pet attack talk, else growl | |
+ //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell | |
+ if(((Creature*)this)->IsPet() && (((Pet*)this)->getPetType() == SUMMON_PET) && (this != unit_target) && (urand(0, 100) < 10)) | |
+ SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); | |
+ else | |
+ SendPetAIReaction(); | |
+ | |
+ if( unit_target && !owner->IsFriendlyTo(unit_target) && !HasAuraType(SPELL_AURA_MOD_POSSESS)) | |
+ { | |
+ // This is true if pet has no target or has target but targets differs. | |
+ if (getVictim() != unit_target) | |
+ { | |
+ if (getVictim()) | |
+ AttackStop(); | |
+ GetMotionMaster()->Clear(); | |
+ if (((Creature*)this)->AI()) | |
+ ((Creature*)this)->AI()->AttackStart(unit_target); | |
+ } | |
+ } | |
+ | |
+ spell->prepare(&(spell->m_targets)); | |
+ } | |
+ else | |
+ { | |
+ if(HasAuraType(SPELL_AURA_MOD_POSSESS)) | |
+ Spell::SendCastResult(owner,spellInfo,0,result); | |
+ else | |
+ SendPetCastFail(spellid, result); | |
+ | |
+ if (!((Creature*)this)->HasSpellCooldown(spellid)) | |
+ owner->SendClearCooldown(spellid, this); | |
+ | |
+ spell->finish(false); | |
+ delete spell; | |
+ } | |
+ break; | |
+ } | |
+ default: | |
+ sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); | |
+ } | |
+ | |
+} | |
+ | |
+void Unit::DoPetCastSpell( Player *owner, uint8 cast_count, SpellCastTargets* targets, SpellEntry const* spellInfo ) | |
+{ | |
+ Creature* pet = dynamic_cast<Creature*>(this); | |
+ | |
+ clearUnitState(UNIT_STAT_MOVING); | |
+ | |
+ Spell *spell = new Spell(pet, spellInfo, false); | |
+ spell->m_cast_count = cast_count; // probably pending spell cast | |
+ spell->m_targets = *targets; | |
+ | |
+ SpellCastResult result = spell->CheckPetCast(NULL); | |
+ if (result == SPELL_CAST_OK) | |
+ { | |
+ pet->AddCreatureSpellCooldown(spellInfo->Id); | |
+ if (pet->IsPet()) | |
+ { | |
+ //10% chance to play special pet attack talk, else growl | |
+ //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell | |
+ if(((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) | |
+ pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); | |
+ else | |
+ pet->SendPetAIReaction(); | |
+ } | |
+ | |
+ spell->prepare(&(spell->m_targets)); | |
+ } | |
+ else | |
+ { | |
+ pet->SendPetCastFail(spellInfo->Id, result); | |
+ if (!pet->HasSpellCooldown(spellInfo->Id)) | |
+ owner->SendClearCooldown(spellInfo->Id, pet); | |
+ | |
+ spell->finish(false); | |
+ delete spell; | |
+ } | |
+} | |
+ | |
bool Unit::isFrozen() const | |
{ | |
return HasAuraState(AURA_STATE_FROZEN); | |
diff --git a/src/game/Unit.h b/src/game/Unit.h | |
index b8f5597..cde4a3d 100644 | |
--- a/src/game/Unit.h | |
+++ b/src/game/Unit.h | |
@@ -299,6 +299,7 @@ class Creature; | |
class Spell; | |
class DynamicObject; | |
class GameObject; | |
+class SpellCastTargets; | |
class Item; | |
class Pet; | |
class PetAura; | |
@@ -1925,6 +1926,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject | |
void SendPetTalk (uint32 pettalk); | |
void SendPetAIReaction(); | |
///----------End of Pet responses methods---------- | |
+ void DoPetAction (Player* owner, uint8 flag, uint32 spellid, ObjectGuid petGuid, ObjectGuid targetGuid); | |
+ void DoPetCastSpell (Player *owner, uint8 cast_count, SpellCastTargets* targets, SpellEntry const* spellInfo); | |
void propagateSpeedChange() { GetMotionMaster()->propagateSpeedChange(); } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment