aboutsummaryrefslogtreecommitdiff
path: root/src/game/PetHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/PetHandler.cpp')
-rw-r--r--src/game/PetHandler.cpp77
1 files changed, 47 insertions, 30 deletions
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index c162f22c64b..60a4bec0891 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -109,7 +109,6 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if(pet->GetTypeId() != TYPEID_PLAYER)
{
- pet->GetMotionMaster()->Clear();
if (((Creature*)pet)->AI())
((Creature*)pet)->AI()->AttackStart(TargetUnit);
@@ -139,8 +138,13 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
//dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
p->setDeathState(CORPSE);
}
- else // charmed
- _player->Uncharm();
+ else // charmed or possessed
+ {
+ if (_player->isPossessing())
+ _player->RemovePossess(true);
+ else
+ _player->Uncharm();
+ }
break;
default:
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.\n", flag, spellid);
@@ -194,7 +198,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
int16 result = spell->PetCanCast(unit_target);
//auto turn to target unless possessed
- if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
+ if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed())
{
pet->SetInFront(unit_target);
if( unit_target->GetTypeId() == TYPEID_PLAYER )
@@ -222,7 +226,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
pet->SendPetAIReaction(guid1);
}
- if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
+ if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed())
{
pet->clearUnitState(UNIT_STAT_FOLLOW);
if(pet->getVictim())
@@ -236,7 +240,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
}
else
{
- if(pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
+ if(pet->isPossessed())
{
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
data << uint32(spellid) << uint8(2) << uint8(result);
@@ -478,7 +482,10 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
}
else if(pet->GetGUID() == _player->GetCharmGUID())
{
- _player->Uncharm();
+ if (_player->isPossessing())
+ _player->RemovePossess(true);
+ else
+ _player->Uncharm();
}
}
}
@@ -601,21 +608,19 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
recvPacket >> guid >> spellid;
+ // This opcode is also sent from charmed and possessed units (players and creatures)
if(!_player->GetPet() && !_player->GetCharm())
return;
- if(ObjectAccessor::FindPlayer(guid))
- return;
-
- Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
+ Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
- if(!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
+ if(!caster || (caster != _player->GetPet() && caster != _player->GetCharm()))
{
sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
}
- if (pet->GetGlobalCooldown() > 0)
+ if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->GetGlobalCooldown() > 0)
return;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid);
@@ -626,41 +631,53 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
}
// do not cast not learned spells
- if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
+ if(!caster->HasSpell(spellid) || IsPassiveSpell(spellid))
return;
SpellCastTargets targets;
- if(!targets.read(&recvPacket,pet))
+ if(!targets.read(&recvPacket,caster))
return;
- pet->clearUnitState(UNIT_STAT_FOLLOW);
+ caster->clearUnitState(UNIT_STAT_FOLLOW);
- Spell *spell = new Spell(pet, spellInfo, false);
+ Spell *spell = new Spell(caster, spellInfo, false);
spell->m_targets = targets;
int16 result = spell->PetCanCast(NULL);
if(result == -1)
{
- pet->AddCreatureSpellCooldown(spellid);
- if(pet->isPet())
+ if(caster->GetTypeId() == TYPEID_UNIT)
{
- Pet* p = (Pet*)pet;
- p->CheckLearning(spellid);
- //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(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
- pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
- else
- pet->SendPetAIReaction(guid);
+ Creature* pet = (Creature*)caster;
+ pet->AddCreatureSpellCooldown(spellid);
+ if(pet->isPet())
+ {
+ Pet* p = (Pet*)pet;
+ p->CheckLearning(spellid);
+ // 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(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
+ pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
+ else
+ pet->SendPetAIReaction(guid);
+ }
}
spell->prepare(&(spell->m_targets));
}
else
{
- pet->SendPetCastFail(spellid, result);
- if(!pet->HasSpellCooldown(spellid))
- pet->SendPetClearCooldown(spellid);
+ caster->SendPetCastFail(spellid, result);
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(!((Player*)caster)->HasSpellCooldown(spellid))
+ caster->SendPetClearCooldown(spellid);
+ }
+ else
+ {
+ if(!((Creature*)caster)->HasSpellCooldown(spellid))
+ caster->SendPetClearCooldown(spellid);
+ }
spell->finish(false);
delete spell;