aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp30
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h17
-rw-r--r--src/server/game/AI/CreatureAI.h6
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp195
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.h52
-rw-r--r--src/server/game/CMakeLists.txt1
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp39
-rw-r--r--src/server/game/Entities/Player/Player.h5
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp32
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp14
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp12
13 files changed, 304 insertions, 102 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index a3a5e7f7663..3aadf6e59a0 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -259,36 +259,6 @@ void UnitAI::FillAISpellInfo()
}
}
-//Enable PlayerAI when charmed
-void PlayerAI::OnCharmed(bool apply)
-{
- me->IsAIEnabled = apply;
-}
-
-void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
-{
- Creature* charmer = me->GetCharmer()->ToCreature();
-
- //kill self if charm aura has infinite duration
- if (charmer->IsInEvadeMode())
- {
- Unit::AuraEffectList const& auras = me->GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
- for (Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if ((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
- {
- charmer->Kill(me);
- return;
- }
- }
-
- if (!charmer->IsInCombat())
- me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, me->GetFollowAngle());
-
- Unit* target = me->GetVictim();
- if (!target || !charmer->IsValidAttackTarget(target))
- AttackStart(charmer->SelectNearestTargetInAttackDistance());
-}
-
SpellTargetSelector::SpellTargetSelector(Unit* caster, uint32 spellId) :
_caster(caster), _spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(sSpellMgr->GetSpellInfo(spellId), caster))
{
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 5dc5946b226..766e747d998 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -268,21 +268,4 @@ class UnitAI
UnitAI& operator=(UnitAI const& right) = delete;
};
-class PlayerAI : public UnitAI
-{
- protected:
- Player* const me;
- public:
- explicit PlayerAI(Player* player) : UnitAI((Unit*)player), me(player) { }
-
- void OnCharmed(bool apply) override;
-};
-
-class SimpleCharmedAI : public PlayerAI
-{
- public:
- void UpdateAI(uint32 diff) override;
- SimpleCharmedAI(Player* player): PlayerAI(player) { }
-};
-
#endif
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index 239fda577a7..e009e2ed0b6 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -28,6 +28,7 @@ class WorldObject;
class Unit;
class Creature;
class Player;
+class PlayerAI;
class SpellInfo;
#define TIME_INTERVAL_LOOK 5000
@@ -186,6 +187,11 @@ class CreatureAI : public UnitAI
virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; }
+ // Called when a player is charmed by the creature
+ // If a PlayerAI* is returned, that AI is placed on the player instead of the default charm AI
+ // Object destruction is handled by Unit::RemoveCharmedBy
+ virtual PlayerAI* GetAIForCharmedPlayer(Player* /*who*/) { return nullptr; }
+
// intended for encounter design/debugging. do not use for other purposes. expensive.
int32 VisualizeBoundary(uint32 duration, Unit* owner=nullptr, bool fill=false) const;
virtual bool CheckInRoom();
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
new file mode 100644
index 00000000000..65e60be8eee
--- /dev/null
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -0,0 +1,195 @@
+/*
+* Copyright (C) 2016-2016 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "PlayerAI.h"
+#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
+
+enum Spells
+{
+ /* Generic */
+ SPELL_AUTO_SHOT = 75,
+ SPELL_SHOOT = 3018,
+ SPELL_THROW = 2764,
+ SPELL_SHOOT_WAND = 5019,
+
+ /* Priest */
+ SPELL_SHADOWFORM = 15473,
+
+ /* Shaman */
+ SPELL_STORMSTRIKE = 17364,
+
+ /* Druid */
+ SPELL_MOONKIN_FORM = 24858
+};
+PlayerAI::PlayerAI(Player* player) : UnitAI(static_cast<Unit*>(player)), me(player), _isRangedAttacker(false)
+{
+ switch (me->getClass())
+ {
+ case CLASS_WARRIOR:
+ _isRangedAttacker = false;
+ break;
+ case CLASS_PALADIN:
+ _isRangedAttacker = false;
+ break;
+ case CLASS_HUNTER:
+ {
+ // check if we have a ranged weapon equipped
+ Item const* rangedSlot = me->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ if (ItemTemplate const* rangedTemplate = rangedSlot ? rangedSlot->GetTemplate() : nullptr)
+ if ((1 << rangedTemplate->SubClass) & ITEM_SUBCLASS_MASK_WEAPON_RANGED)
+ {
+ _isRangedAttacker = true;
+ break;
+ }
+ _isRangedAttacker = false;
+ break;
+ }
+ case CLASS_ROGUE:
+ _isRangedAttacker = false;
+ break;
+ case CLASS_PRIEST:
+ _isRangedAttacker = me->HasSpell(SPELL_SHADOWFORM);
+ break;
+ case CLASS_DEATH_KNIGHT:
+ _isRangedAttacker = false;
+ break;
+ case CLASS_SHAMAN:
+ _isRangedAttacker = !me->HasSpell(SPELL_STORMSTRIKE);
+ break;
+ case CLASS_MAGE:
+ _isRangedAttacker = true;
+ break;
+ case CLASS_WARLOCK:
+ _isRangedAttacker = true;
+ break;
+ case CLASS_DRUID:
+ _isRangedAttacker = me->HasAura(SPELL_MOONKIN_FORM);
+ break;
+ default:
+ TC_LOG_WARN("entities.unit", "Possessed player %s (possessed by %s) does not have any recognized class (class = %u).", me->GetGUID().ToString().c_str(), me->GetCharmerGUID().ToString().c_str(), me->getClass());
+ break;
+ }
+}
+
+void PlayerAI::DoRangedAttackIfReady()
+{
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ if (!me->isAttackReady(RANGED_ATTACK))
+ return;
+
+ Unit* victim = me->GetVictim();
+ if (!victim)
+ return;
+
+ uint32 rangedAttackSpell = 0;
+
+ Item const* rangedItem = me->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ if (ItemTemplate const* rangedTemplate = rangedItem ? rangedItem->GetTemplate() : nullptr)
+ {
+ switch (rangedTemplate->SubClass)
+ {
+ case ITEM_SUBCLASS_WEAPON_BOW:
+ case ITEM_SUBCLASS_WEAPON_GUN:
+ case ITEM_SUBCLASS_WEAPON_CROSSBOW:
+ rangedAttackSpell = SPELL_SHOOT;
+ break;
+ case ITEM_SUBCLASS_WEAPON_THROWN:
+ rangedAttackSpell = SPELL_THROW;
+ break;
+ case ITEM_SUBCLASS_WEAPON_WAND:
+ rangedAttackSpell = SPELL_SHOOT_WAND;
+ break;
+ }
+ }
+
+ std::cout << "Selected " << rangedAttackSpell << std::endl;
+
+ if (!rangedAttackSpell)
+ return;
+
+ me->CastSpell(victim, rangedAttackSpell, TRIGGERED_CAST_DIRECTLY);
+ me->resetAttackTimer(RANGED_ATTACK);
+}
+
+void PlayerAI::DoAutoAttackIfReady()
+{
+ if (IsRangedAttacker())
+ DoRangedAttackIfReady();
+ else
+ DoMeleeAttackIfReady();
+}
+
+void SimpleCharmedPlayerAI::UpdateAI(const uint32 /*diff*/)
+{
+ Creature* charmer = me->GetCharmer()->ToCreature();
+
+ //kill self if charm aura has infinite duration
+ if (charmer->IsInEvadeMode())
+ {
+ Player::AuraEffectList const& auras = me->GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
+ for (Player::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ if ((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
+ {
+ me->Kill(me);
+ return;
+ }
+ }
+
+ if (charmer->IsInCombat())
+ {
+ Unit* target = me->GetVictim();
+ if (!target || !charmer->IsValidAttackTarget(target))
+ {
+ target = charmer->SelectNearestTarget();
+ if (!target)
+ return;
+
+ if (IsRangedAttacker())
+ AttackStartCaster(target, 28.0f);
+ else
+ AttackStart(target);
+ }
+ }
+ else
+ {
+ me->AttackStop();
+ me->CastStop();
+ me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ }
+
+ DoAutoAttackIfReady();
+}
+
+void SimpleCharmedPlayerAI::OnCharmed(bool apply)
+{
+ if (apply)
+ {
+ me->CastStop();
+ me->AttackStop();
+ }
+ else
+ {
+ me->CastStop();
+ me->AttackStop();
+ // @todo only voluntary movement (don't cancel stuff like death grip or charge mid-animation)
+ me->GetMotionMaster()->Clear();
+ me->StopMoving();
+ }
+}
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.h b/src/server/game/AI/PlayerAI/PlayerAI.h
new file mode 100644
index 00000000000..39b04a70d67
--- /dev/null
+++ b/src/server/game/AI/PlayerAI/PlayerAI.h
@@ -0,0 +1,52 @@
+/*
+* Copyright (C) 2016-2016 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef TRINITY_PLAYERAI_H
+#define TRINITY_PLAYERAI_H
+
+#include "UnitAI.h"
+#include "Player.h"
+#include "Creature.h"
+
+class PlayerAI : public UnitAI
+{
+ public:
+ explicit PlayerAI(Player* player);
+
+ void OnCharmed(bool /*apply*/) override { } // charm AI application for players is handled by Unit::SetCharmedBy / Unit::RemoveCharmedBy
+
+ protected:
+ Player* const me;
+ void SetIsRangedAttacker(bool state) { _isRangedAttacker = state; }
+ bool IsRangedAttacker() const { return _isRangedAttacker; }
+
+ void DoRangedAttackIfReady();
+ void DoAutoAttackIfReady();
+
+ private:
+ bool _isRangedAttacker;
+};
+
+class SimpleCharmedPlayerAI : public PlayerAI
+{
+ public:
+ SimpleCharmedPlayerAI(Player* player) : PlayerAI(player) { }
+ void UpdateAI(uint32 diff) override;
+ void OnCharmed(bool apply) override;
+};
+
+#endif
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index aae5b4874d8..4d41fbc32eb 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -108,6 +108,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Addons
${CMAKE_CURRENT_SOURCE_DIR}/AI
${CMAKE_CURRENT_SOURCE_DIR}/AI/CoreAI
+ ${CMAKE_CURRENT_SOURCE_DIR}/AI/PlayerAI
${CMAKE_CURRENT_SOURCE_DIR}/AI/ScriptedAI
${CMAKE_CURRENT_SOURCE_DIR}/AI/SmartScripts
${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouse
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 49bd854ef2f..0803345f4f0 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -479,7 +479,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
bool AIM_Initialize(CreatureAI* ai = NULL);
void Motion_Initialize();
- CreatureAI* AI() const { return (CreatureAI*)i_AI; }
+ CreatureAI* AI() const { return reinterpret_cast<CreatureAI*>(i_AI); }
bool SetWalk(bool enable) override;
bool SetDisableGravity(bool disable, bool packetOnly = false) override;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a60bfb4a444..cbf29980057 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1237,12 +1237,7 @@ void Player::Update(uint32 p_time)
UpdateAfkReport(now);
- if (IsCharmed())
- if (Unit* charmer = GetCharmer())
- if (charmer->GetTypeId() == TYPEID_UNIT && charmer->IsAlive())
- UpdateCharmedAI();
-
- if (GetAI() && IsAIEnabled)
+ if (IsAIEnabled && GetAI())
GetAI()->UpdateAI(p_time);
// Update items that have just a limited lifetime
@@ -24129,38 +24124,6 @@ bool Player::isTotalImmunity()
return false;
}
-void Player::UpdateCharmedAI()
-{
- //This should only called in Player::Update
- Creature* charmer = GetCharmer()->ToCreature();
-
- //kill self if charm aura has infinite duration
- if (charmer->IsInEvadeMode())
- {
- AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
- for (AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if ((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
- {
- charmer->DealDamage(this, GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- return;
- }
- }
-
- if (!charmer->IsInCombat())
- GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
-
- Unit* target = GetVictim();
- if (!target || !charmer->IsValidAttackTarget(target))
- {
- target = charmer->SelectNearestTarget();
- if (!target)
- return;
-
- GetMotionMaster()->MoveChase(target);
- Attack(target, true);
- }
-}
-
uint32 Player::GetRuneBaseCooldown(uint8 index)
{
uint8 rune = GetBaseRune(index);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 2388cf9d0c7..0d6d21c6b28 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -54,6 +54,7 @@ class PlayerMenu;
class PlayerSocial;
class SpellCastTargets;
class UpdateMask;
+class PlayerAI;
struct CharacterCustomizeInfo;
@@ -1022,6 +1023,8 @@ class Player : public Unit, public GridObject<Player>
explicit Player(WorldSession* session);
~Player();
+ PlayerAI* AI() const { return reinterpret_cast<PlayerAI*>(i_AI); }
+
void CleanupsBeforeDelete(bool finalCleanup = true) override;
void AddToWorld() override;
@@ -2533,8 +2536,6 @@ class Player : public Unit, public GridObject<Player>
MapReference m_mapRef;
- void UpdateCharmedAI();
-
uint32 m_lastFallTime;
float m_lastFallZ;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 80c5febdcc9..a2a3151666e 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -45,6 +45,7 @@
#include "PetAI.h"
#include "Pet.h"
#include "Player.h"
+#include "PlayerAI.h"
#include "QuestDef.h"
#include "ReputationMgr.h"
#include "SpellAuraEffects.h"
@@ -15902,11 +15903,21 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
ToCreature()->AI()->OnCharmed(true);
GetMotionMaster()->MoveIdle();
}
- else
+ else if (Player* player = ToPlayer())
{
- Player* player = ToPlayer();
if (player->isAFK())
player->ToggleAFK();
+
+ if (Creature* creatureCharmer = charmer->ToCreature()) // we are charmed by a creature
+ {
+ IsAIEnabled = true;
+ i_disabledAI = i_AI;
+ // set our AI to the charmer's custom charm AI if applicable
+ if (PlayerAI* charmAI = creatureCharmer->AI()->GetAIForCharmedPlayer(player))
+ i_AI = charmAI;
+ else // otherwise use the default charmed player AI
+ i_AI = new SimpleCharmedPlayerAI(player);
+ }
player->SetClientControl(this, false);
}
@@ -16064,7 +16075,24 @@ void Unit::RemoveCharmedBy(Unit* charmer)
}
if (Player* player = ToPlayer())
+ {
+ if (charmer->GetTypeId() == TYPEID_UNIT) // charmed by a creature, this means we had PlayerAI
+ {
+ if (i_AI)
+ {
+ // allow charmed player AI to clean up
+ i_AI->OnCharmed(false);
+ // then delete it
+ delete i_AI;
+ // and restore our previous playerAI (if we had one)
+ if ((i_AI = i_disabledAI))
+ i_disabledAI = nullptr;
+ else
+ IsAIEnabled = false;
+ }
+ }
player->SetClientControl(this, true);
+ }
// a guardian should always have charminfo
if (playerCharmer && this != charmer->GetFirstControlled())
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index 32e7421465a..545902dca66 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -73,6 +73,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Addons
${CMAKE_SOURCE_DIR}/src/server/game/AI
${CMAKE_SOURCE_DIR}/src/server/game/AI/CoreAI
+ ${CMAKE_SOURCE_DIR}/src/server/game/AI/PlayerAI
${CMAKE_SOURCE_DIR}/src/server/game/AI/ScriptedAI
${CMAKE_SOURCE_DIR}/src/server/game/AI/SmartScripts
${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouse
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
index 96bd0aaa35e..dd3ed10f96f 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
@@ -22,6 +22,7 @@
#include "pit_of_saron.h"
#include "Vehicle.h"
#include "Player.h"
+#include "PlayerAI.h"
enum Yells
{
@@ -438,9 +439,10 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
if (GetTarget()->GetTypeId() != TYPEID_PLAYER)
return;
- oldAI = GetTarget()->GetAI();
- oldAIState = GetTarget()->IsAIEnabled;
- GetTarget()->SetAI(new player_overlord_brandAI(GetTarget()->ToPlayer(), GetCasterGUID()));
+ Player* pTarget = GetTarget()->ToPlayer();
+ oldAI = pTarget->AI();
+ oldAIState = pTarget->IsAIEnabled;
+ GetTarget()->SetAI(static_cast<UnitAI*>(new player_overlord_brandAI(pTarget, GetCasterGUID())));
GetTarget()->IsAIEnabled = true;
}
@@ -450,8 +452,8 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
return;
GetTarget()->IsAIEnabled = oldAIState;
- UnitAI* thisAI = GetTarget()->GetAI();
- GetTarget()->SetAI(oldAI);
+ PlayerAI* thisAI = GetTarget()->ToPlayer()->AI();
+ GetTarget()->SetAI(static_cast<UnitAI*>(oldAI));
delete thisAI;
}
@@ -461,7 +463,7 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
AfterEffectRemove += AuraEffectRemoveFn(spell_tyrannus_overlord_brand_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
- UnitAI* oldAI;
+ PlayerAI* oldAI;
bool oldAIState;
};
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 3cea620559a..f1ad785c13d 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -22,7 +22,7 @@
*/
#include "Player.h"
-#include "UnitAI.h"
+#include "PlayerAI.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
@@ -1909,9 +1909,9 @@ public:
if (!player || player->GetGhoulResurrectGhoulGUID().IsEmpty())
return;
- oldAI = player->GetAI();
+ oldAI = player->AI();
oldAIState = player->IsAIEnabled;
- player->SetAI(new player_ghoulAI(player, player->GetGhoulResurrectGhoulGUID()));
+ player->SetAI(static_cast<UnitAI*>(new player_ghoulAI(player, player->GetGhoulResurrectGhoulGUID())));
player->IsAIEnabled = true;
}
@@ -1922,8 +1922,8 @@ public:
return;
player->IsAIEnabled = oldAIState;
- UnitAI* thisAI = player->GetAI();
- player->SetAI(oldAI);
+ PlayerAI* thisAI = player->AI();
+ player->SetAI(static_cast<UnitAI*>(oldAI));
delete thisAI;
// Dismiss ghoul if necessary
@@ -1943,7 +1943,7 @@ public:
AfterEffectRemove += AuraEffectRemoveFn(spell_dk_raise_ally_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
- UnitAI* oldAI;
+ PlayerAI* oldAI;
bool oldAIState;
};