mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
13 cmangos commits implemented
commits: 432bd63 Commit Ported Core Implement TakePossessOf to generalize the code. 0b663eb Commit Ported Core Implement a possibility to summon manualy a temporary creature. b6a9ead Commit Imported Core Little rewrite of resurect code to prepare ability ro resurrect a player to a ghoul form. e98b42c Commit Imported Core Implement TemporarySummon Linked aura to owner. ab139ff Commit Imported Core Do not force the creature to attack summoner in all case 555f055 Commit Imported Core Avoid possibility to charm more than one new creature for an unit. fd78c4a Commit Imported Core Fix problem that occur when the charm unit field is updated after the possess bar. e9821e2 Commit Imported Core fix lightwell gameobject not appearing after spell is cast 17d0e93 Commit Imported Core Implement logic for Target 95 as TARGET_VEHICLE_DRIVER 42b3545 Commit Imported Core Now npc/gameobject interaction will remove unauthorized aura 1195398 Commit Imported Core Improve functionality for eventAI action 26 - ACTION_T_QUEST_EVENT_ALL 72b7a48 Commit Ported Core fix pet stay 245f068 Commit Imported Warlock [Charm] prevent charming multiple demons also remove pet temporarily when casting specific channels that summon other charmed creatures
This commit is contained in:
parent
18dd18780d
commit
df3ab5df8e
25 changed files with 508 additions and 313 deletions
|
|
@ -131,7 +131,7 @@ For all ACTION_T_RANDOM Actions, When a Particular Param is selected for the Eve
|
|||
23 ACTION_T_INC_PHASE Value Increments the phase by (Param1). May be negative to decrement, but should not be zero.
|
||||
24 ACTION_T_EVADE No Params Forces the creature to evade, wiping all threat and dropping combat.
|
||||
25 ACTION_T_FLEE_FOR_ASSIST No Params Causes the creature to flee for assistence (often at low health).
|
||||
26 ACTION_T_QUEST_EVENT_ALL QuestId Calls GroupEventHappens with (Param1). Only used if it's _expected_ event should call quest completion for all players in a current party.
|
||||
26 ACTION_T_QUEST_EVENT_ALL QuestId, UseThreatList Calls GroupEventHappens with (Param1). Only used if it's _expected_ event should call quest completion for all players in a current party. Can be used for the creature's threat list, for complex scripted events.
|
||||
27 ACTION_T_CASTCREATUREGO_ALL QuestId, SpellId Calls CastedCreatureOrGo for all players on the threat list with quest id specified in (Param1) and spell id in (Param2).
|
||||
28 ACTION_T_REMOVEAURASFROMSPELL Target, Spellid Removes all auras on a target (Param1) caused by a spell (Param2).
|
||||
29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator to a ranged type. (note: default melee type can still be set by using 0 as angle and 0 as distance).
|
||||
|
|
@ -701,10 +701,11 @@ NOTE: All Param Values Are 0 for this Action.
|
|||
26 = ACTION_T_QUEST_EVENT_ALL:
|
||||
------------------------------
|
||||
Parameter 1: QuestId - The quest ID to finish for everyone.
|
||||
Parameter 2: UseThreatList - Bool. If set to 1 (true), it will complete the QuestId for all the players in the threat list. If set to 0 (false), it will use the action invoker.
|
||||
|
||||
This action does the same thing as the ACTION_T_QUEST_EVENT does but it does it for all players in the creature's threat list.
|
||||
NOTE: If a player is not in the NPC's threat list for whatever reason, he/she won't get the quest completed.
|
||||
|
||||
|
||||
---------------------------------
|
||||
27 = ACTION_T_CASTCREATUREGO_ALL:
|
||||
---------------------------------
|
||||
|
|
|
|||
|
|
@ -2241,8 +2241,9 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const
|
|||
|
||||
CreatureDataAddon const* Creature::GetCreatureAddon() const
|
||||
{
|
||||
if (CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(GetGUIDLow()))
|
||||
return addon;
|
||||
if (!(GetObjectGuid().GetHigh() == HIGHGUID_PET)) // pets have guidlow that is conflicting with normal guidlows hence GetGUIDLow() gives wrong info
|
||||
if (CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(GetGUIDLow()))
|
||||
return addon;
|
||||
|
||||
// dependent from difficulty mode entry
|
||||
if (GetEntry() != GetCreatureInfo()->Entry)
|
||||
|
|
|
|||
|
|
@ -832,7 +832,14 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
m_creature->DoFleeToGetAssistance();
|
||||
break;
|
||||
case ACTION_T_QUEST_EVENT_ALL:
|
||||
if (pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER)
|
||||
if (action.quest_event_all.useThreatList)
|
||||
{
|
||||
ThreatList const& threatList = m_creature->GetThreatManager().getThreatList();
|
||||
for (ThreatList::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
|
||||
if (Player* temp = m_creature->GetMap()->GetPlayer((*i)->getUnitGuid()))
|
||||
temp->GroupEventHappens(action.quest_event_all.questId, m_creature);
|
||||
}
|
||||
else if (pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)pActionInvoker)->GroupEventHappens(action.quest_event_all.questId, m_creature);
|
||||
break;
|
||||
case ACTION_T_CAST_EVENT_ALL:
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ enum EventAI_ActionType
|
|||
ACTION_T_INC_PHASE = 23, // Value (may be negative to decrement phase, should not be 0)
|
||||
ACTION_T_EVADE = 24, // No Params
|
||||
ACTION_T_FLEE_FOR_ASSIST = 25, // No Params
|
||||
ACTION_T_QUEST_EVENT_ALL = 26, // QuestID
|
||||
ACTION_T_QUEST_EVENT_ALL = 26, // QuestID, UseThreatList (1 = true, 0 = false)
|
||||
ACTION_T_CAST_EVENT_ALL = 27, // CreatureId, SpellId
|
||||
ACTION_T_REMOVEAURASFROMSPELL = 28, // Target, Spellid
|
||||
ACTION_T_RANGED_MOVEMENT = 29, // Distance, Angle
|
||||
|
|
@ -297,6 +297,7 @@ struct CreatureEventAI_Action
|
|||
struct
|
||||
{
|
||||
uint32 questId;
|
||||
uint32 useThreatList; // bool: 1 = true; 0 = false
|
||||
} quest_event_all;
|
||||
// ACTION_T_CAST_EVENT_ALL = 27
|
||||
struct
|
||||
|
|
|
|||
|
|
@ -65,6 +65,12 @@ enum TempSummonType
|
|||
TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN = 9, // despawns after a specified time (OOC) OR when the creature dies
|
||||
};
|
||||
|
||||
enum TempSummonLinkedAura
|
||||
{
|
||||
TEMPSUMMON_LINKED_AURA_OWNER_CHECK = 0x00000001,
|
||||
TEMPSUMMON_LINKED_AURA_REMOVE_OWNER = 0x00000002
|
||||
};
|
||||
|
||||
enum PhaseMasks
|
||||
{
|
||||
PHASEMASK_NORMAL = 0x00000001,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ Pet::Pet(PetType type) :
|
|||
m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0),
|
||||
m_removed(false), m_petType(type), m_duration(0),
|
||||
m_bonusdamage(0), m_auraUpdateMask(0), m_loading(false),
|
||||
m_declinedname(NULL), m_petModeFlags(PET_MODE_DEFAULT)
|
||||
m_declinedname(nullptr), m_petModeFlags(PET_MODE_DEFAULT), m_retreating(false),
|
||||
m_stayPosSet(false), m_stayPosX(0), m_stayPosY(0), m_stayPosZ(0), m_stayPosO(0),
|
||||
m_opener(0), m_openerMinRange(0), m_openerMaxRange(0)
|
||||
{
|
||||
m_name = "Pet";
|
||||
m_regenTimer = 4000;
|
||||
|
|
|
|||
|
|
@ -254,6 +254,21 @@ class Pet : public Creature
|
|||
PetSpellMap m_spells;
|
||||
AutoSpellList m_autospells;
|
||||
|
||||
uint32 m_opener;
|
||||
uint32 m_openerMinRange;
|
||||
uint32 m_openerMaxRange;
|
||||
|
||||
uint32 GetSpellOpener() { return m_opener; }
|
||||
uint32 GetSpellOpenerMinRange() { return m_openerMinRange; }
|
||||
uint32 GetSpellOpenerMaxRange() { return m_openerMaxRange; }
|
||||
|
||||
void SetSpellOpener(uint32 spellId = 0, uint32 minRange = 0, uint32 maxRange = 0)
|
||||
{
|
||||
m_opener = spellId;
|
||||
m_openerMinRange = minRange;
|
||||
m_openerMaxRange = maxRange;
|
||||
}
|
||||
|
||||
void InitPetCreateSpells();
|
||||
|
||||
bool resetTalents(bool no_cost = false);
|
||||
|
|
|
|||
|
|
@ -2298,6 +2298,9 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 NpcFlagsmask)
|
|||
if (!guid || !IsInWorld() || IsTaxiFlying())
|
||||
return NULL;
|
||||
|
||||
// set player as interacting
|
||||
DoInteraction(guid);
|
||||
|
||||
// not in interactive state
|
||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
|
||||
return NULL;
|
||||
|
|
@ -2339,12 +2342,15 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 NpcFlagsmask)
|
|||
return unit;
|
||||
}
|
||||
|
||||
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type) const
|
||||
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type)
|
||||
{
|
||||
// some basic checks
|
||||
if (!guid || !IsInWorld() || IsTaxiFlying())
|
||||
return NULL;
|
||||
|
||||
// set player as interacting
|
||||
DoInteraction(guid);
|
||||
|
||||
// not in interactive state
|
||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
|
||||
return NULL;
|
||||
|
|
@ -21270,6 +21276,24 @@ void Player::SetClientControl(Unit* target, uint8 allowMove)
|
|||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::Uncharm()
|
||||
{
|
||||
if (Unit* charm = GetCharm())
|
||||
{
|
||||
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
|
||||
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
|
||||
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS_PET);
|
||||
if (charm == GetMover())
|
||||
{
|
||||
SetMover(nullptr);
|
||||
GetCamera().ResetView();
|
||||
RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
|
||||
SetCharm(nullptr);
|
||||
SetClientControl(this, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdateZoneDependentAuras()
|
||||
{
|
||||
// Some spells applied at enter into zone (with subzones), aura removed in UpdateAreaDependentAuras that called always at zone->area update
|
||||
|
|
@ -22699,6 +22723,15 @@ void Player::UnsummonPetTemporaryIfAny()
|
|||
pet->Unsummon(PET_SAVE_AS_CURRENT, this);
|
||||
}
|
||||
|
||||
void Player::UnsummonPetIfAny()
|
||||
{
|
||||
Pet* pet = GetPet();
|
||||
if (!pet)
|
||||
return;
|
||||
|
||||
pet->Unsummon(PET_SAVE_NOT_IN_SLOT, this);
|
||||
}
|
||||
|
||||
void Player::ResummonPetTemporaryUnSummonedIfAny()
|
||||
{
|
||||
if (!m_temporaryUnsummonedPetNumber)
|
||||
|
|
@ -24307,6 +24340,41 @@ float Player::GetCollisionHeight(bool mounted) const
|
|||
}
|
||||
}
|
||||
|
||||
// set data to accept next resurrect response and process it with required data
|
||||
void Player::setResurrectRequestData(Unit* caster, uint32 health, uint32 mana)
|
||||
{
|
||||
m_resurrectGuid = caster->GetObjectGuid();
|
||||
m_resurrectMap = caster->GetMapId();
|
||||
caster->GetPosition(m_resurrectX, m_resurrectY, m_resurrectZ);
|
||||
m_resurrectHealth = health;
|
||||
m_resurrectMana = mana;
|
||||
m_resurrectToGhoul = false;
|
||||
}
|
||||
|
||||
// we can use this to prepare data in case we have to resurrect player in ghoul form
|
||||
void Player::setResurrectRequestDataToGhoul(Unit* caster)
|
||||
{
|
||||
setResurrectRequestData(caster, 0, 0);
|
||||
m_resurrectToGhoul = true;
|
||||
}
|
||||
|
||||
// player is interacting so we have to remove non authorized aura
|
||||
void Player::DoInteraction(ObjectGuid const& interactObjGuid)
|
||||
{
|
||||
if (interactObjGuid.IsUnit())
|
||||
{
|
||||
// remove some aura like stealth aura
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
|
||||
}
|
||||
else if (interactObjGuid.IsGameObject())
|
||||
{
|
||||
// remove some aura like stealth aura
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_USE);
|
||||
}
|
||||
SendForcedObjectUpdate();
|
||||
}
|
||||
|
||||
|
||||
void Player::SendPetitionSignResult(ObjectGuid petitionGuid, Player* player, uint32 result)
|
||||
{
|
||||
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, 8 + 8 + 4);
|
||||
|
|
|
|||
|
|
@ -1128,7 +1128,7 @@ class Player : public Unit
|
|||
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time);
|
||||
|
||||
Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 NpcFlagsmask);
|
||||
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type = MAX_GAMEOBJECT_TYPE) const;
|
||||
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type = MAX_GAMEOBJECT_TYPE);
|
||||
|
||||
void ToggleAFK();
|
||||
void ToggleDND();
|
||||
|
|
@ -1214,7 +1214,13 @@ class Player : public Unit
|
|||
* \param: bool inRestPlace > if it was offline, is the player was in city/tavern/inn?
|
||||
* \returns: float
|
||||
**/
|
||||
float ComputeRest(time_t timePassed, bool offline = false, bool inRestPlace = false);
|
||||
float ComputeRest(time_t timePassed, bool offline = false, bool inRestPlace = false);
|
||||
|
||||
/**
|
||||
* \brief: player is interacting with something.
|
||||
* \param: ObjectGuid interactObj > object that interact with this player
|
||||
**/
|
||||
void DoInteraction(ObjectGuid const& interactObjGuid);
|
||||
|
||||
RestType GetRestType() const
|
||||
{
|
||||
|
|
@ -1817,6 +1823,8 @@ class Player : public Unit
|
|||
uint32 GetLastPotionId() { return m_lastPotionId; }
|
||||
void UpdatePotionCooldown(Spell* spell = NULL);
|
||||
|
||||
void setResurrectRequestData(Unit* caster, uint32 health, uint32 mana);
|
||||
void setResurrectRequestDataToGhoul(Unit* caster);
|
||||
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
|
||||
{
|
||||
m_resurrectGuid = guid;
|
||||
|
|
@ -2413,6 +2421,7 @@ class Player : public Unit
|
|||
void SetMover(Unit* target) { m_mover = target ? target : this; }
|
||||
Unit* GetMover() const { return m_mover; }
|
||||
bool IsSelfMover() const { return m_mover == this; }// normal case for player not controlling other unit
|
||||
void Uncharm() override;
|
||||
|
||||
ObjectGuid const& GetFarSightGuid() const { return GetGuidValue(PLAYER_FARSIGHT); }
|
||||
|
||||
|
|
@ -2472,6 +2481,7 @@ class Player : public Unit
|
|||
uint32 GetTemporaryUnsummonedPetNumber() const { return m_temporaryUnsummonedPetNumber; }
|
||||
void SetTemporaryUnsummonedPetNumber(uint32 petnumber) { m_temporaryUnsummonedPetNumber = petnumber; }
|
||||
void UnsummonPetTemporaryIfAny();
|
||||
void UnsummonPetIfAny();
|
||||
void ResummonPetTemporaryUnSummonedIfAny();
|
||||
bool IsPetNeedBeTemporaryUnsummoned() const { return !IsInWorld() || !IsAlive() || IsMounted() /*+in flight*/; }
|
||||
|
||||
|
|
@ -2745,6 +2755,7 @@ class Player : public Unit
|
|||
uint32 m_resurrectMap;
|
||||
float m_resurrectX, m_resurrectY, m_resurrectZ;
|
||||
uint32 m_resurrectHealth, m_resurrectMana;
|
||||
bool m_resurrectToGhoul;
|
||||
|
||||
WorldSession* m_session;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "CreatureAI.h"
|
||||
|
||||
TemporarySummon::TemporarySummon(ObjectGuid summoner) :
|
||||
Creature(CREATURE_SUBTYPE_TEMPORARY_SUMMON), m_type(TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN), m_timer(0), m_lifetime(0), m_summoner(summoner)
|
||||
Creature(CREATURE_SUBTYPE_TEMPORARY_SUMMON), m_type(TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN), m_timer(0), m_lifetime(0), m_summoner(summoner), m_linkedToOwnerAura(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -189,31 +189,93 @@ void TemporarySummon::Update(uint32 update_diff, uint32 diff)
|
|||
break;
|
||||
}
|
||||
|
||||
switch (m_deathState)
|
||||
{
|
||||
case ALIVE:
|
||||
if (m_linkedToOwnerAura & TEMPSUMMON_LINKED_AURA_OWNER_CHECK)
|
||||
{
|
||||
// we have to check if owner still have the required aura
|
||||
Unit* owner = GetCharmerOrOwner();
|
||||
uint32 const& spellId = GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
if (!owner || !spellId || !owner->HasAura(spellId))
|
||||
UnSummon();
|
||||
}
|
||||
break;
|
||||
|
||||
case DEAD:
|
||||
case CORPSE:
|
||||
if (m_linkedToOwnerAura & TEMPSUMMON_LINKED_AURA_REMOVE_OWNER)
|
||||
{
|
||||
RemoveAuraFromOwner();
|
||||
m_linkedToOwnerAura = 0; // we dont need to recheck
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Creature::Update(update_diff, diff);
|
||||
}
|
||||
|
||||
void TemporarySummon::Summon(TempSummonType type, uint32 lifetime)
|
||||
void TemporarySummon::SetSummonProperties(TempSummonType type, uint32 lifetime)
|
||||
{
|
||||
m_type = type;
|
||||
m_timer = lifetime;
|
||||
m_lifetime = lifetime;
|
||||
}
|
||||
|
||||
void TemporarySummon::Summon(TempSummonType type, uint32 lifetime)
|
||||
{
|
||||
SetSummonProperties(type, lifetime);
|
||||
|
||||
GetMap()->Add((Creature*)this);
|
||||
|
||||
AIM_Initialize();
|
||||
GetMap()->Add((Creature*)this);
|
||||
}
|
||||
|
||||
void TemporarySummon::UnSummon()
|
||||
{
|
||||
CombatStop();
|
||||
|
||||
if (m_linkedToOwnerAura & TEMPSUMMON_LINKED_AURA_REMOVE_OWNER)
|
||||
RemoveAuraFromOwner();
|
||||
|
||||
if (GetSummonerGuid().IsCreatureOrVehicle())
|
||||
{
|
||||
if (Creature* sum = GetMap()->GetCreature(GetSummonerGuid()))
|
||||
if (sum->AI())
|
||||
sum->AI()->SummonedCreatureDespawn(this);
|
||||
}
|
||||
else if (GetSummonerGuid().IsPlayer()) // if player that summoned this creature was MCing it, uncharm
|
||||
if (Player* player = GetMap()->GetPlayer(GetSummonerGuid()))
|
||||
if (player->GetMover() == this)
|
||||
player->Uncharm();
|
||||
|
||||
if (AI())
|
||||
AI()->SummonedCreatureDespawn(this);
|
||||
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
void TemporarySummon::RemoveAuraFromOwner()
|
||||
{
|
||||
// creature is dead and we have to remove the charmer aura if exist
|
||||
uint32 const& spellId = GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
if (spellId)
|
||||
{
|
||||
|
||||
if (Unit* charmer = GetCharmer())
|
||||
{
|
||||
charmer->RemoveAurasDueToSpell(spellId);
|
||||
charmer->ResetControlState(false);
|
||||
}
|
||||
else if (Unit* owner = GetOwner())
|
||||
{
|
||||
owner->RemoveAurasDueToSpell(spellId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TemporarySummon::SaveToDB()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,12 +35,15 @@ class TemporarySummon : public Creature
|
|||
virtual ~TemporarySummon() {};
|
||||
|
||||
void Update(uint32 update_diff, uint32 time) override;
|
||||
void SetSummonProperties(TempSummonType type, uint32 lifetime);
|
||||
void Summon(TempSummonType type, uint32 lifetime);
|
||||
void UnSummon();
|
||||
void MANGOS_DLL_SPEC UnSummon();
|
||||
void SaveToDB();
|
||||
ObjectGuid const& GetSummonerGuid() const { return m_summoner ; }
|
||||
Unit* GetSummoner() const { return ObjectAccessor::GetUnit(*this, m_summoner); }
|
||||
void SetLinkedToOwnerAura(uint32 flags) { m_linkedToOwnerAura |= flags; };
|
||||
private:
|
||||
void RemoveAuraFromOwner();
|
||||
void SaveToDB(uint32, uint8, uint32) override // overwrited of Creature::SaveToDB - don't must be called
|
||||
{
|
||||
MANGOS_ASSERT(false);
|
||||
|
|
@ -54,6 +57,7 @@ class TemporarySummon : public Creature
|
|||
uint32 m_timer;
|
||||
uint32 m_lifetime;
|
||||
ObjectGuid m_summoner;
|
||||
uint32 m_linkedToOwnerAura;
|
||||
};
|
||||
|
||||
class TemporarySummonWaypoint : public TemporarySummon
|
||||
|
|
|
|||
|
|
@ -12298,3 +12298,225 @@ void Unit::SendCollisionHeightUpdate(float height)
|
|||
}
|
||||
}
|
||||
|
||||
// This will create a new creature and set the current unit as the controller of that new creature
|
||||
Unit* Unit::TakePossessOf(SpellEntry const* spellEntry, SummonPropertiesEntry const* summonProp, SpellEffectEntry const* spellEffect, float x, float y, float z, float ang)
|
||||
{
|
||||
int32 const& creatureEntry = spellEffect->EffectMiscValue;
|
||||
CreatureInfo const* cinfo = ObjectMgr::GetCreatureTemplate(creatureEntry);
|
||||
if (!cinfo)
|
||||
{
|
||||
sLog.outErrorDb("WorldObject::SummonCreature: Creature (Entry: %u) not existed for summoner: %s. ", creatureEntry, GetGuidStr().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (GetCharm())
|
||||
{
|
||||
sLog.outError("Unit::TakePossessOf> There is already a charmed creature for %s its : %s. ", GetGuidStr().c_str(), GetCharm()->GetGuidStr().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TemporarySummon* pCreature = new TemporarySummon(GetObjectGuid());
|
||||
|
||||
CreatureCreatePos pos(GetMap(), x, y, z, ang, GetPhaseMask());
|
||||
|
||||
if (x == 0.0f && y == 0.0f && z == 0.0f)
|
||||
pos = CreatureCreatePos(this, GetOrientation(), CONTACT_DISTANCE, ang);
|
||||
|
||||
if (!pCreature->Create(GetMap()->GenerateLocalLowGuid(cinfo->GetHighGuid()), pos, cinfo))
|
||||
{
|
||||
delete pCreature;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Player* player = GetTypeId() == TYPEID_PLAYER ? static_cast<Player*>(this): nullptr;
|
||||
|
||||
pCreature->setFaction(getFaction()); // set same faction than player
|
||||
pCreature->SetRespawnCoord(pos); // set spawn coord
|
||||
pCreature->SetCharmerGuid(GetObjectGuid()); // save guid of the charmer
|
||||
pCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellEntry->Id); // set the spell id used to create this (may be used for removing corresponding aura
|
||||
pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); // set flag for client that mean this unit is controlled by a player
|
||||
pCreature->addUnitState(UNIT_STAT_CONTROLLED); // also set internal unit state flag
|
||||
pCreature->SelectLevel(getLevel()); // set level to same level than summoner TODO:: not sure its always the case...
|
||||
pCreature->SetLinkedToOwnerAura(TEMPSUMMON_LINKED_AURA_OWNER_CHECK | TEMPSUMMON_LINKED_AURA_REMOVE_OWNER); // set what to do if linked aura is removed or the creature is dead.
|
||||
pCreature->SetWalk(IsWalking(), true); // sync the walking state with the summoner
|
||||
|
||||
// important before adding to the map!
|
||||
SetCharmGuid(pCreature->GetObjectGuid()); // save guid of charmed creature
|
||||
|
||||
pCreature->SetSummonProperties(TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); // set 5s corpse decay
|
||||
GetMap()->Add(static_cast<Creature*>(pCreature)); // create the creature in the client
|
||||
|
||||
// Give the control to the player
|
||||
if (player)
|
||||
{
|
||||
player->GetCamera().SetView(pCreature); // modify camera view to the creature view
|
||||
player->SetClientControl(pCreature, 1); // transfer client control to the creature
|
||||
player->SetMover(pCreature); // set mover so now we know that creature is "moved" by this unit
|
||||
player->SendForcedObjectUpdate(); // we have to update client data here to avoid problem with the "release spirit" windows reappear.
|
||||
}
|
||||
|
||||
// initialize AI
|
||||
pCreature->AIM_Initialize();
|
||||
|
||||
if (player)
|
||||
{
|
||||
// Initialize pet bar
|
||||
if (CharmInfo* charmInfo = pCreature->InitCharmInfo(pCreature))
|
||||
charmInfo->InitPossessCreateSpells();
|
||||
player->PossessSpellInitialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
// fire just summoned hook
|
||||
if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
|
||||
((Creature*)this)->AI()->JustSummoned(pCreature);
|
||||
}
|
||||
|
||||
// Creature Linking, Initial load is handled like respawn
|
||||
if (pCreature->IsLinkingEventTrigger())
|
||||
GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_RESPAWN, pCreature);
|
||||
|
||||
// return the creature therewith the summoner has access to it
|
||||
return pCreature;
|
||||
}
|
||||
|
||||
bool Unit::TakePossessOf(Unit* possessed)
|
||||
{
|
||||
Player* player = nullptr;
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
player = static_cast<Player *>(this);
|
||||
|
||||
possessed->addUnitState(UNIT_STAT_CONTROLLED);
|
||||
possessed->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
possessed->SetCharmerGuid(GetObjectGuid());
|
||||
possessed->setFaction(getFaction());
|
||||
|
||||
SetCharm(possessed);
|
||||
|
||||
Creature* possessedCreature = nullptr;
|
||||
if (possessed->GetTypeId() == TYPEID_UNIT)
|
||||
possessedCreature = static_cast<Creature *>(possessed);
|
||||
|
||||
if (player)
|
||||
{
|
||||
player->GetCamera().SetView(possessed);
|
||||
player->SetClientControl(possessed, 1);
|
||||
player->SetMover(possessed);
|
||||
player->SendForcedObjectUpdate();
|
||||
|
||||
if (possessedCreature && possessedCreature->IsPet() && possessedCreature->GetObjectGuid() == GetPetGuid())
|
||||
{
|
||||
possessed->StopMoving();
|
||||
possessed->GetMotionMaster()->Clear(false);
|
||||
possessed->GetMotionMaster()->MoveIdle();
|
||||
return true;
|
||||
}
|
||||
else if (CharmInfo* charmInfo = possessed->InitCharmInfo(possessed))
|
||||
{
|
||||
charmInfo->InitPossessCreateSpells();
|
||||
charmInfo->SetReactState(REACT_PASSIVE);
|
||||
charmInfo->SetCommandState(COMMAND_STAY);
|
||||
}
|
||||
player->PossessSpellInitialize();
|
||||
}
|
||||
|
||||
possessed->CombatStop(true);
|
||||
possessed->DeleteThreatList();
|
||||
possessed->getHostileRefManager().deleteReferences();
|
||||
|
||||
if (possessedCreature)
|
||||
{
|
||||
possessedCreature->AIM_Initialize();
|
||||
}
|
||||
else if (possessed->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
static_cast<Player*>(possessed)->SetClientControl(possessed, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::ResetControlState(bool attackCharmer /*= true*/)
|
||||
{
|
||||
Player* player = nullptr;
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
player = static_cast<Player *>(this);
|
||||
|
||||
Unit* possessed = GetCharm();
|
||||
|
||||
if (!possessed)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
player->GetCamera().ResetView();
|
||||
player->SetClientControl(player, 1);
|
||||
player->SetMover(nullptr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Creature* possessedCreature = static_cast<Creature *>(possessed);
|
||||
|
||||
possessed->clearUnitState(UNIT_STAT_CONTROLLED);
|
||||
possessed->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
possessed->SetCharmerGuid(ObjectGuid());
|
||||
SetCharmGuid(ObjectGuid());
|
||||
|
||||
if (player)
|
||||
{
|
||||
player->SetClientControl(possessed, 0);
|
||||
player->SetMover(nullptr);
|
||||
player->GetCamera().ResetView();
|
||||
|
||||
if (possessedCreature->IsPet() && possessedCreature->GetObjectGuid() == GetPetGuid())
|
||||
{
|
||||
// out of range pet dismissed
|
||||
if (!possessedCreature->IsWithinDistInMap(this, possessedCreature->GetMap()->GetVisibilityDistance()))
|
||||
{
|
||||
player->RemovePet(PET_SAVE_REAGENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
possessedCreature->GetMotionMaster()->MoveFollow(this, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
player->RemovePetActionBar();
|
||||
}
|
||||
|
||||
possessed->CombatStop(true);
|
||||
possessed->DeleteThreatList();
|
||||
possessed->getHostileRefManager().deleteReferences();
|
||||
|
||||
if (possessed->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Player* possessedPlayer = static_cast<Player *>(possessed);
|
||||
possessedPlayer->setFactionForRace(possessedPlayer->getRace());
|
||||
possessedPlayer->SetClientControl(possessedPlayer, 1);
|
||||
}
|
||||
else if (possessedCreature)
|
||||
{
|
||||
if (possessedCreature->IsPet() && possessedCreature->GetObjectGuid() == GetPetGuid())
|
||||
{
|
||||
// out of range pet dismissed
|
||||
if (!possessedCreature->IsWithinDistInMap(this, possessedCreature->GetMap()->GetVisibilityDistance()))
|
||||
{
|
||||
player->RemovePet(PET_SAVE_REAGENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
possessedCreature->GetMotionMaster()->MoveFollow(this, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
}
|
||||
else if (attackCharmer)
|
||||
{
|
||||
CreatureInfo const* cinfo = possessedCreature->GetCreatureInfo();
|
||||
possessedCreature->setFaction(cinfo->FactionAlliance);
|
||||
possessedCreature->AIM_Initialize();
|
||||
possessedCreature->AttackedBy(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2826,7 +2826,7 @@ class Unit : public WorldObject
|
|||
* - \ref AuraType::SPELL_AURA_MOD_POSSESS
|
||||
* - \ref AuraType::SPELL_AURA_MOD_POSSESS_PET
|
||||
*/
|
||||
void Uncharm();
|
||||
virtual void Uncharm();
|
||||
/**
|
||||
* Does the same as \ref Unit::GetCharmerOrOwnerGuid but returns the \ref Unit for that instead
|
||||
* @return the \ref Unit that's charming this one or owning it, NULL if there is none
|
||||
|
|
@ -3530,6 +3530,15 @@ class Unit : public WorldObject
|
|||
void BuildMoveHoverPacket(WorldPacket* data, bool apply, uint32 value);
|
||||
void BuildMoveLevitatePacket(WorldPacket* data, bool apply, uint32 value);
|
||||
|
||||
// Take possession of an unit (pet, creature, ...)
|
||||
bool TakePossessOf(Unit* possessed);
|
||||
|
||||
// Take possession of a new spawned unit
|
||||
Unit* TakePossessOf(SpellEntry const* spellEntry, SummonPropertiesEntry const* summonProp, SpellEffectEntry const* spellEffect, float x, float y, float z, float ang);
|
||||
|
||||
// Reset control to player
|
||||
void ResetControlState(bool attackCharmer = true);
|
||||
|
||||
protected:
|
||||
explicit Unit();
|
||||
|
||||
|
|
|
|||
|
|
@ -1493,7 +1493,7 @@ enum Targets
|
|||
TARGET_91 = 91,
|
||||
TARGET_SUMMONER = 92,
|
||||
TARGET_CONTROLLED_VEHICLE = 94,
|
||||
TARGET_95 = 95,
|
||||
TARGET_VEHICLE_DRIVER = 95,
|
||||
TARGET_VEHICLE_PASSENGER_0 = 96,
|
||||
TARGET_VEHICLE_PASSENGER_1 = 97,
|
||||
TARGET_VEHICLE_PASSENGER_2 = 98,
|
||||
|
|
|
|||
|
|
@ -52,10 +52,6 @@ void WorldSession::HandleAuctionHelloOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
SendAuctionHello(unit);
|
||||
}
|
||||
|
||||
|
|
@ -295,10 +291,6 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
for (uint32 i = 0; i < itemCount; ++i)
|
||||
{
|
||||
ObjectGuid itemGuid = guids[i];
|
||||
|
|
@ -398,10 +390,6 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recv_data)
|
|||
// always return pointer
|
||||
AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry);
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
|
||||
Player* pl = GetPlayer();
|
||||
|
||||
|
|
@ -477,10 +465,6 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recv_data)
|
|||
// always return pointer
|
||||
AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry);
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
|
||||
Player* pl = GetPlayer();
|
||||
|
||||
|
|
@ -556,10 +540,6 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket& recv_data)
|
|||
// always return pointer
|
||||
AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry);
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4 + 4 + 4));
|
||||
Player* pl = GetPlayer();
|
||||
data << uint32(0); // add 0 as count
|
||||
|
|
@ -604,10 +584,6 @@ void WorldSession::HandleAuctionListOwnerItems(WorldPacket& recv_data)
|
|||
// always return pointer
|
||||
AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry);
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4 + 4 + 4));
|
||||
data << uint32(0); // amount place holder
|
||||
|
||||
|
|
@ -677,10 +653,6 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recv_data)
|
|||
AuctionSorter sorter(Sort, GetPlayer());
|
||||
std::sort(auctions.begin(), auctions.end(), sorter);
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
// DEBUG_LOG("Auctionhouse search %s list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u",
|
||||
// auctioneerGuid.GetString().c_str(), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);
|
||||
|
||||
|
|
|
|||
|
|
@ -959,10 +959,6 @@ void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId());
|
||||
if (!guild)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -351,10 +351,6 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
Item* pItem = _player->GetItemByGuid(itemGuid);
|
||||
if (pItem)
|
||||
{
|
||||
|
|
@ -457,10 +453,6 @@ void WorldSession::HandleBuybackItem(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
Item* pItem = _player->GetItemFromBuyBackSlot(slot);
|
||||
if (pItem)
|
||||
{
|
||||
|
|
@ -569,10 +561,6 @@ void WorldSession::SendListInventory(ObjectGuid vendorguid)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
// Stop the npc if moving
|
||||
pCreature->StopMoving();
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,6 @@ void WorldSession::HandleTabardVendorActivateOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
SendTabardVendorActivate(guid);
|
||||
}
|
||||
|
||||
|
|
@ -90,10 +86,6 @@ void WorldSession::HandleBankerActivateOpcode(WorldPacket& recv_data)
|
|||
if (!CheckBanker(guid))
|
||||
return;
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
SendShowBank(guid);
|
||||
}
|
||||
|
||||
|
|
@ -156,10 +148,6 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
// trainer list loaded at check;
|
||||
if (!unit->IsTrainerOf(_player, true))
|
||||
return;
|
||||
|
|
@ -259,10 +247,6 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recv_data)
|
|||
|
||||
uint32 trainState = 2;
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
if (!unit->IsTrainerOf(_player, true))
|
||||
trainState = 1;
|
||||
|
||||
|
|
@ -348,10 +332,6 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
pCreature->StopMoving();
|
||||
|
||||
if (pCreature->IsSpiritGuide())
|
||||
|
|
@ -381,10 +361,6 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recv_data)
|
|||
DEBUG_LOG("Gossip code: %s", code.c_str());
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
uint32 sender = _player->PlayerTalkClass->GossipOptionSender(gossipListId);
|
||||
uint32 action = _player->PlayerTalkClass->GossipOptionAction(gossipListId);
|
||||
|
||||
|
|
@ -431,10 +407,6 @@ void WorldSession::HandleSpiritHealerActivateOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
SendSpiritResurrect();
|
||||
}
|
||||
|
||||
|
|
@ -506,10 +478,6 @@ void WorldSession::HandleBinderActivateOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
SendBindPoint(unit);
|
||||
}
|
||||
|
||||
|
|
@ -544,10 +512,6 @@ void WorldSession::HandleListStabledPetsOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
SendStablePet(npcGUID);
|
||||
}
|
||||
|
||||
|
|
@ -656,10 +620,6 @@ void WorldSession::HandleStablePet(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
Pet* pet = _player->GetPet();
|
||||
|
||||
// can't place in stable dead pet
|
||||
|
|
@ -716,10 +676,6 @@ void WorldSession::HandleUnstablePet(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
uint32 creature_id = 0;
|
||||
|
||||
{
|
||||
|
|
@ -785,10 +741,6 @@ void WorldSession::HandleBuyStableSlot(WorldPacket& recv_data)
|
|||
SendStableResult(STABLE_ERR_STABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
}
|
||||
|
||||
void WorldSession::HandleStableRevivePet(WorldPacket &/* recv_data */)
|
||||
|
|
@ -810,10 +762,6 @@ void WorldSession::HandleStableSwapPet(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
Pet* pet = _player->GetPet();
|
||||
|
||||
if (!pet || pet->getPetType() != HUNTER_PET)
|
||||
|
|
@ -885,10 +833,6 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
// reputation discount
|
||||
float discountMod = _player->GetReputationPriceDiscount(unit);
|
||||
|
||||
|
|
|
|||
|
|
@ -150,9 +150,12 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data)
|
|||
break;
|
||||
}
|
||||
case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet)
|
||||
if (((Creature*)pet)->IsPet())
|
||||
{
|
||||
Creature* petC = (Creature*)pet;
|
||||
if (petC->IsPet())
|
||||
|
||||
{
|
||||
Pet* p = (Pet*)pet;
|
||||
Pet* p = (Pet*)petC;
|
||||
if (p->getPetType() == HUNTER_PET)
|
||||
p->Unsummon(PET_SAVE_AS_DELETED, _player);
|
||||
else
|
||||
|
|
@ -161,7 +164,16 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data)
|
|||
}
|
||||
else // charmed
|
||||
_player->Uncharm();
|
||||
|
||||
if (petC->IsTemporarySummon()) // special case when pet was temporary summon through DoSummonPossesed
|
||||
{
|
||||
petC->ForcedDespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
((Pet*)pet)->SetStayPosition();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,10 +88,6 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
if (!pCreature->IsTabardDesigner())
|
||||
{
|
||||
sLog.outError("WORLD: HandlePetitionBuyOpcode - unsupported npc type, npc: %s", guidNPC.GetString().c_str());
|
||||
|
|
@ -673,10 +669,6 @@ void WorldSession::SendPetitionShowList(ObjectGuid guid)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
// only guild petitions currently used
|
||||
if (!pCreature->IsTabardDesigner())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -100,10 +100,6 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
// Stop the npc if moving
|
||||
pCreature->StopMoving();
|
||||
|
||||
|
|
|
|||
|
|
@ -2257,6 +2257,11 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
if (m_caster->IsBoarded() && m_caster->GetTransportInfo()->IsOnVehicle())
|
||||
targetUnitMap.push_back((Unit*)m_caster->GetTransportInfo()->GetTransport());
|
||||
break;
|
||||
case TARGET_VEHICLE_DRIVER:
|
||||
if (m_caster->IsVehicle())
|
||||
if (Unit* vehicleDriver = m_caster->GetCharmer())
|
||||
targetUnitMap.push_back(vehicleDriver);
|
||||
break;
|
||||
case TARGET_VEHICLE_PASSENGER_0:
|
||||
case TARGET_VEHICLE_PASSENGER_1:
|
||||
case TARGET_VEHICLE_PASSENGER_2:
|
||||
|
|
@ -3704,8 +3709,10 @@ void Spell::_handle_immediate_phase()
|
|||
if(!spellEffect)
|
||||
continue;
|
||||
// persistent area auras target only the ground
|
||||
if(spellEffect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
|
||||
HandleEffects(NULL, NULL, NULL, SpellEffectIndex(j));
|
||||
if (spellEffect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA ||
|
||||
//summon a gameobject at the spell's destination xyz
|
||||
(spellEffect->Effect == SPELL_EFFECT_TRANS_DOOR && spellEffect->EffectImplicitTargetA == TARGET_AREAEFFECT_GO_AROUND_DEST))
|
||||
HandleEffects(nullptr, nullptr, nullptr, SpellEffectIndex(j));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6505,6 +6512,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
|
|||
target = m_targets.getUnitTarget();
|
||||
|
||||
bool need = false;
|
||||
bool script = false;
|
||||
for (int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i));
|
||||
|
|
@ -6523,9 +6531,16 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
|
|||
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
|
||||
break;
|
||||
}
|
||||
else if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES)
|
||||
{
|
||||
script = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (need)
|
||||
m_targets.setUnitTarget(target);
|
||||
else if (script == true)
|
||||
return CheckCast(true);
|
||||
|
||||
Unit* _target = m_targets.getUnitTarget();
|
||||
|
||||
|
|
|
|||
|
|
@ -4278,117 +4278,47 @@ void Aura::HandleAuraModScale(bool apply, bool /*Real*/)
|
|||
void Aura::HandleModPossess(bool apply, bool Real)
|
||||
{
|
||||
if (!Real)
|
||||
{ return; }
|
||||
return;
|
||||
|
||||
Unit* target = GetTarget();
|
||||
|
||||
// not possess yourself
|
||||
if (GetCasterGuid() == target->GetObjectGuid())
|
||||
{ return; }
|
||||
return;
|
||||
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
{ return; }
|
||||
|
||||
Player* p_caster = (Player*)caster;
|
||||
Camera& camera = p_caster->GetCamera();
|
||||
if (!caster || caster->GetTypeId() != TYPEID_PLAYER) // TODO:: well i know some bosses can take control of player???
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
{
|
||||
target->addUnitState(UNIT_STAT_CONTROLLED);
|
||||
|
||||
target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
target->SetCharmerGuid(p_caster->GetObjectGuid());
|
||||
target->setFaction(p_caster->getFaction());
|
||||
|
||||
// target should became visible at SetView call(if not visible before):
|
||||
// otherwise client\p_caster will ignore packets from the target(SetClientControl for example)
|
||||
camera.SetView(target);
|
||||
|
||||
p_caster->SetCharm(target);
|
||||
p_caster->SetClientControl(target, 1);
|
||||
p_caster->SetMover(target);
|
||||
|
||||
target->CombatStop(true);
|
||||
target->DeleteThreatList();
|
||||
target->getHostileRefManager().deleteReferences();
|
||||
|
||||
if (CharmInfo* charmInfo = target->InitCharmInfo(target))
|
||||
if (caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
charmInfo->InitPossessCreateSpells();
|
||||
charmInfo->SetReactState(REACT_PASSIVE);
|
||||
charmInfo->SetCommandState(COMMAND_STAY);
|
||||
//remove any existing charm just in case
|
||||
caster->Uncharm();
|
||||
|
||||
//pets should be removed when possesing a target if somehow check was bypassed
|
||||
((Player*)caster)->UnsummonPetIfAny();
|
||||
}
|
||||
|
||||
p_caster->PossessSpellInitialize();
|
||||
|
||||
if (target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
((Creature*)target)->AIM_Initialize();
|
||||
}
|
||||
else if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)target)->SetClientControl(target, 0);
|
||||
}
|
||||
caster->TakePossessOf(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_caster->SetCharm(NULL);
|
||||
|
||||
p_caster->SetClientControl(target, 0);
|
||||
p_caster->SetMover(NULL);
|
||||
|
||||
// there is a possibility that target became invisible for client\p_caster at ResetView call:
|
||||
// it must be called after movement control unapplying, not before! the reason is same as at aura applying
|
||||
camera.ResetView();
|
||||
|
||||
p_caster->RemovePetActionBar();
|
||||
|
||||
// on delete only do caster related effects
|
||||
if (m_removeMode == AURA_REMOVE_BY_DELETE)
|
||||
{ return; }
|
||||
|
||||
target->clearUnitState(UNIT_STAT_CONTROLLED);
|
||||
|
||||
target->CombatStop(true);
|
||||
target->DeleteThreatList();
|
||||
target->getHostileRefManager().deleteReferences();
|
||||
|
||||
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
target->SetCharmerGuid(ObjectGuid());
|
||||
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)target)->setFactionForRace(target->getRace());
|
||||
((Player*)target)->SetClientControl(target, 1);
|
||||
}
|
||||
else if (target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
CreatureInfo const* cinfo = ((Creature*)target)->GetCreatureInfo();
|
||||
target->setFaction(cinfo->FactionAlliance);
|
||||
}
|
||||
|
||||
if (target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
((Creature*)target)->AIM_Initialize();
|
||||
target->AttackedBy(caster);
|
||||
}
|
||||
}
|
||||
caster->ResetControlState();
|
||||
}
|
||||
|
||||
void Aura::HandleModPossessPet(bool apply, bool Real)
|
||||
{
|
||||
if (!Real)
|
||||
{ return; }
|
||||
return;
|
||||
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
{ return; }
|
||||
return;
|
||||
|
||||
Unit* target = GetTarget();
|
||||
if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->IsPet())
|
||||
{ return; }
|
||||
return;
|
||||
|
||||
Pet* pet = (Pet*)target;
|
||||
|
||||
|
|
@ -4397,52 +4327,23 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
|
|||
|
||||
if (apply)
|
||||
{
|
||||
pet->addUnitState(UNIT_STAT_CONTROLLED);
|
||||
if (caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
//remove any existing charm just in case
|
||||
caster->Uncharm();
|
||||
|
||||
// target should became visible at SetView call(if not visible before):
|
||||
// otherwise client\p_caster will ignore packets from the target(SetClientControl for example)
|
||||
camera.SetView(pet);
|
||||
|
||||
p_caster->SetCharm(pet);
|
||||
p_caster->SetClientControl(pet, 1);
|
||||
((Player*)caster)->SetMover(pet);
|
||||
|
||||
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
//pets should be removed when possesing a target if somehow check was bypassed
|
||||
((Player*)caster)->UnsummonPetIfAny();
|
||||
}
|
||||
|
||||
pet->StopMoving();
|
||||
pet->GetMotionMaster()->Clear(false);
|
||||
pet->GetMotionMaster()->MoveIdle();
|
||||
|
||||
caster->TakePossessOf(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_caster->SetCharm(NULL);
|
||||
p_caster->SetClientControl(pet, 0);
|
||||
p_caster->SetMover(NULL);
|
||||
|
||||
// there is a possibility that target became invisible for client\p_caster at ResetView call:
|
||||
// it must be called after movement control unapplying, not before! the reason is same as at aura applying
|
||||
camera.ResetView();
|
||||
|
||||
// on delete only do caster related effects
|
||||
if (m_removeMode == AURA_REMOVE_BY_DELETE)
|
||||
{ return; }
|
||||
|
||||
pet->clearUnitState(UNIT_STAT_CONTROLLED);
|
||||
|
||||
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
pet->AttackStop();
|
||||
|
||||
// out of range pet dismissed
|
||||
if (!pet->IsWithinDistInMap(p_caster, pet->GetMap()->GetVisibilityDistance()))
|
||||
{
|
||||
p_caster->RemovePet(PET_SAVE_REAGENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
}
|
||||
caster->ResetControlState();
|
||||
}
|
||||
|
||||
void Aura::HandleAuraModPetTalentsPoints(bool /*Apply*/, bool Real)
|
||||
|
|
@ -4472,6 +4373,15 @@ void Aura::HandleModCharm(bool apply, bool Real)
|
|||
|
||||
if (apply)
|
||||
{
|
||||
if (caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
//remove any existing charm just in case
|
||||
caster->Uncharm();
|
||||
|
||||
//pets should be removed when possesing a target if somehow check was bypassed
|
||||
((Player*)caster)->UnsummonPetIfAny();
|
||||
}
|
||||
|
||||
// is it really need after spell check checks?
|
||||
target->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM, GetHolder());
|
||||
target->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS, GetHolder());
|
||||
|
|
@ -4874,9 +4784,11 @@ void Aura::HandleInvisibility(bool apply, bool Real)
|
|||
|
||||
if (Real && target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// apply glow vision
|
||||
target->SetByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
|
||||
|
||||
if (((Player*)target)->GetMover() == nullptr) // check if the player doesnt have a mover, when player is hidden during MC of creature
|
||||
{
|
||||
// apply glow vision
|
||||
target->SetByteFlag(PLAYER_FIELD_BYTES2, 1, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
|
||||
}
|
||||
}
|
||||
|
||||
// apply only if not in GM invisibility and not stealth
|
||||
|
|
|
|||
|
|
@ -5556,9 +5556,7 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect)
|
|||
}
|
||||
case SUMMON_PROP_GROUP_CONTROLLABLE:
|
||||
{
|
||||
// TODO: Fix spell 46619
|
||||
if (m_spellInfo->Id != 46619)
|
||||
summonResult = DoSummonPossessed(summonPositions, summon_prop, effect, level);
|
||||
summonResult = DoSummonPossessed(summonPositions, summon_prop, effect, level);
|
||||
break;
|
||||
}
|
||||
case SUMMON_PROP_GROUP_VEHICLE:
|
||||
|
|
@ -5871,56 +5869,20 @@ bool Spell::DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEnt
|
|||
{
|
||||
MANGOS_ASSERT(!list.empty() && prop);
|
||||
|
||||
uint32 creatureEntry = effect->EffectMiscValue;
|
||||
CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creatureEntry);
|
||||
if (!cInfo)
|
||||
uint32 const& creatureEntry = effect->EffectMiscValue;
|
||||
|
||||
Unit* newUnit = m_caster->TakePossessOf(m_spellInfo, prop, effect, list[0].x, list[0].y, list[0].z, m_caster->GetOrientation());
|
||||
if (!newUnit)
|
||||
{
|
||||
sLog.outErrorDb("Spell::DoSummonPossessed: creature entry %u not found for spell %u.", creatureEntry, m_spellInfo->Id);
|
||||
sLog.outError("Spell::DoSummonPossessed: creature entry %d for spell %u could not be summoned.", creatureEntry, m_spellInfo->Id);
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature* spawnCreature = m_caster->SummonCreature(creatureEntry, list[0].x, list[0].y, list[0].z, m_caster->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
if (!spawnCreature)
|
||||
{
|
||||
sLog.outError("Spell::DoSummonPossessed: creature entry %u for spell %u could not be summoned.", creatureEntry, m_spellInfo->Id);
|
||||
return false;
|
||||
}
|
||||
|
||||
list[0].creature = spawnCreature;
|
||||
|
||||
// Changes to be sent
|
||||
spawnCreature->SetCharmerGuid(m_caster->GetObjectGuid());
|
||||
spawnCreature->SetCreatorGuid(m_caster->GetObjectGuid());
|
||||
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
spawnCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
spawnCreature->SetLevel(level);
|
||||
|
||||
spawnCreature->SetWalk(m_caster->IsWalking(), true);
|
||||
// TODO: Set Fly (ie glyph dependend)
|
||||
|
||||
// Internal changes
|
||||
spawnCreature->addUnitState(UNIT_STAT_CONTROLLED);
|
||||
|
||||
// Changes to owner
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Player* player = (Player*)m_caster;
|
||||
|
||||
player->GetCamera().SetView(spawnCreature);
|
||||
|
||||
player->SetCharm(spawnCreature);
|
||||
player->SetClientControl(spawnCreature, 1);
|
||||
player->SetMover(spawnCreature);
|
||||
|
||||
if (CharmInfo* charmInfo = spawnCreature->InitCharmInfo(spawnCreature))
|
||||
charmInfo->InitPossessCreateSpells();
|
||||
player->PossessSpellInitialize();
|
||||
}
|
||||
list[0].creature = static_cast<Creature*>(newUnit);
|
||||
|
||||
// Notify Summoner
|
||||
if (m_originalCaster && m_originalCaster != m_caster && m_originalCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_originalCaster)->AI())
|
||||
((Creature*)m_originalCaster)->AI()->JustSummoned(spawnCreature);
|
||||
((Creature*)m_originalCaster)->AI()->JustSummoned(list[0].creature);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -11368,6 +11330,11 @@ void Spell::EffectTransmitted(SpellEffectEntry const* effect)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case GAMEOBJECT_TYPE_SPELLCASTER:
|
||||
{
|
||||
m_caster->AddGameObject(pGameObj);
|
||||
break;
|
||||
}
|
||||
case GAMEOBJECT_TYPE_FISHINGHOLE:
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -85,10 +85,6 @@ void WorldSession::HandleTaxiQueryAvailableNodes(WorldPacket& recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
// unknown taxi node case
|
||||
if (SendLearnNewTaxiNode(unit))
|
||||
return;
|
||||
|
|
@ -119,10 +115,6 @@ void WorldSession::SendTaxiMenu(Creature* unit)
|
|||
|
||||
void WorldSession::SendDoFlight(uint32 mountDisplayId, uint32 path, uint32 pathNode)
|
||||
{
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
while (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
|
||||
GetPlayer()->GetMotionMaster()->MovementExpired(false);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue