diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 21 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectAccessor.cpp | 109 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectAccessor.h | 73 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 33 | ||||
| -rw-r--r-- | src/server/game/Reputation/ReputationMgr.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Server/Protocol/Handlers/PetHandler.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 17 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/borean_tundra.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/World/go_scripts.cpp | 2 |
13 files changed, 121 insertions, 158 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 22edaa2273d..3361f4c40f7 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -85,12 +85,7 @@ void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/) // Possible crash at access to deleted GO in Unit::m_gameobj if (uint64 owner_guid = GetOwnerGUID()) { - Unit* owner = NULL; - // Object may be deleted while player is not in world, skip this check for now. - /*if (IS_PLAYER_GUID(owner_guid)) - owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL); - else*/ - owner = ObjectAccessor::GetUnit(*this,owner_guid); + Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid); if (owner) owner->RemoveGameObject(this,false); @@ -133,9 +128,9 @@ void GameObject::RemoveFromWorld() // Possible crash at access to deleted GO in Unit::m_gameobj if (uint64 owner_guid = GetOwnerGUID()) { - if (Unit * owner = GetOwner(false)) + if (Unit * owner = GetOwner()) owner->RemoveGameObject(this,false); - else if (!IS_PLAYER_GUID(owner_guid)) + else sLog.outError("Delete GameObject (GUID: %u Entry: %u) that have references in not found creature %u GO list. Crash possible later.",GetGUIDLow(),GetGOInfo()->id,GUID_LOPART(owner_guid)); } WorldObject::RemoveFromWorld(); @@ -490,7 +485,7 @@ void GameObject::Update(uint32 diff) if (GetOwnerGUID()) { - if (Unit* owner = GetOwner(false)) + if (Unit* owner = GetOwner()) { owner->RemoveGameObject(this, false); SetRespawnTime(0); @@ -553,7 +548,7 @@ void GameObject::Delete() { SetLootState(GO_NOT_READY); if (GetOwnerGUID()) - if (Unit * owner = GetOwner(false)) + if (Unit * owner = GetOwner()) owner->RemoveGameObject(this, false); assert (!GetOwnerGUID()); @@ -776,11 +771,9 @@ bool GameObject::IsDynTransport() const } -Unit* GameObject::GetOwner(bool inWorld) const +Unit* GameObject::GetOwner() const { - if (inWorld) - return ObjectAccessor::GetUnit(*this, GetOwnerGUID()); - return ObjectAccessor::GetUnitInOrOutOfWorld(*this, GetOwnerGUID()); + return ObjectAccessor::GetUnit(*this, GetOwnerGUID()); } void GameObject::SaveRespawnTime() diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 2c1765ea14e..ccb2a42399d 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -640,7 +640,7 @@ class GameObject : public WorldObject, public GridObject<GameObject> SetUInt64Value(OBJECT_FIELD_CREATED_BY, owner); } uint64 GetOwnerGUID() const { return GetUInt64Value(OBJECT_FIELD_CREATED_BY); } - Unit* GetOwner(bool inWorld = true) const; + Unit* GetOwner() const; void SetSpellId(uint32 id) { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 094a3d55acc..ba27524e899 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -18526,7 +18526,7 @@ Pet* Player::GetPet() const if (!IS_PET_GUID(pet_guid)) return NULL; - Pet* pet = ObjectAccessor::GetPet(pet_guid); + Pet* pet = ObjectAccessor::GetPet(*this, pet_guid); if (!pet) return NULL; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 29dad933686..950d8b5e975 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -9400,13 +9400,11 @@ bool Unit::HasAuraState(AuraState flag, SpellEntry const *spellProto, Unit const return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); } -Unit *Unit::GetOwner(bool inWorld) const +Unit *Unit::GetOwner() const { if (uint64 ownerid = GetOwnerGUID()) { - if (inWorld) - return ObjectAccessor::GetUnit(*this, ownerid); - return ObjectAccessor::GetUnitInOrOutOfWorld(*this, ownerid); + return ObjectAccessor::GetUnit(*this, ownerid); } return NULL; } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 5ef7918f11d..0822ae1cb7b 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1492,7 +1492,7 @@ class Unit : public WorldObject Player* GetSpellModOwner() const; - Unit* GetOwner(bool inWorld = true) const; + Unit* GetOwner() const; Guardian *GetGuardianPet() const; Minion *GetFirstMinion() const; Unit* GetCharmer() const; diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index b82944d8327..8e2e476693e 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -54,43 +54,16 @@ ObjectAccessor::~ObjectAccessor() } } -Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, uint64 guid) -{ - if (IS_PLAYER_GUID(guid)) - return NULL; - - if (IS_PET_GUID(guid)) - return GetPet(guid); - - return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL; -} - -Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, uint64 guid) -{ - Corpse* ret = GetObjectInWorld(guid, (Corpse*)NULL); - - if (!ret) - return NULL; - - if (ret->GetMapId() != u.GetMapId()) - return NULL; - - if (ret->GetInstanceId() != u.GetInstanceId()) - return NULL; - - return ret; -} - WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid) { switch (GUID_HIPART(guid)) { - case HIGHGUID_PLAYER: return FindPlayer(guid); - case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid); + case HIGHGUID_PLAYER: return GetPlayer(p, guid); + case HIGHGUID_GAMEOBJECT: return GetGameObject(p, guid); case HIGHGUID_VEHICLE: - case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid); - case HIGHGUID_PET: return GetPet(guid); - case HIGHGUID_DYNAMICOBJECT: return p.GetMap()->GetDynamicObject(guid); + case HIGHGUID_UNIT: return GetCreature(p, guid); + case HIGHGUID_PET: return GetPet(p, guid); + case HIGHGUID_DYNAMICOBJECT: return GetDynamicObject(p, guid); case HIGHGUID_TRANSPORT: return NULL; case HIGHGUID_CORPSE: return GetCorpse(p,guid); case HIGHGUID_MO_TRANSPORT: return NULL; @@ -108,24 +81,24 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, u break; case HIGHGUID_PLAYER: if (typemask & TYPEMASK_PLAYER) - return FindPlayer(guid); + return GetPlayer(p, guid); break; case HIGHGUID_GAMEOBJECT: if (typemask & TYPEMASK_GAMEOBJECT) - return p.GetMap()->GetGameObject(guid); + return GetGameObject(p, guid); break; case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: if (typemask & TYPEMASK_UNIT) - return p.GetMap()->GetCreature(guid); + return GetCreature(p, guid); break; case HIGHGUID_PET: if (typemask & TYPEMASK_UNIT) - return GetPet(guid); + return GetPet(p, guid); break; case HIGHGUID_DYNAMICOBJECT: if (typemask & TYPEMASK_DYNAMICOBJECT) - return p.GetMap()->GetDynamicObject(guid); + return GetDynamicObject(p, guid); break; case HIGHGUID_TRANSPORT: case HIGHGUID_CORPSE: @@ -136,13 +109,60 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, u return NULL; } -Player* ObjectAccessor::FindPlayer(uint64 guid) +Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, uint64 guid) { - Player* plr = GetObjectInWorld(guid, (Player*)NULL); - if (!plr || !plr->IsInWorld()) - return NULL; + return GetObjectInMap(guid, u.GetMap(), (Corpse*)NULL); +} - return plr; +GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, uint64 guid) +{ + return GetObjectInMap(guid, u.GetMap(), (GameObject*)NULL); +} + +DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, uint64 guid) +{ + return GetObjectInMap(guid, u.GetMap(), (DynamicObject*)NULL); +} + +Unit* ObjectAccessor::GetUnit(WorldObject const& u, uint64 guid) +{ + return GetObjectInMap(guid, u.GetMap(), (Unit*)NULL); +} + +Creature* ObjectAccessor::GetCreature(WorldObject const& u, uint64 guid) +{ + return GetObjectInMap(guid, u.GetMap(), (Creature*)NULL); +} + +Pet* ObjectAccessor::GetPet(WorldObject const& u, uint64 guid) +{ + return GetObjectInMap(guid, u.GetMap(), (Pet*)NULL); +} + +Player* ObjectAccessor::GetPlayer(WorldObject const& u, uint64 guid) +{ + return GetObjectInMap(guid, u.GetMap(), (Player*)NULL); +} + +Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, uint64 guid) +{ + if (IS_PET_GUID(guid)) + return GetPet(u, guid); + + if (IS_CRE_OR_VEH_GUID(guid)) + return GetCreature(u, guid); + + return NULL; +} + +Pet* ObjectAccessor::FindPet(uint64 guid) +{ + return GetObjectInWorld(guid, (Pet*)NULL); +} + +Player* ObjectAccessor::FindPlayer(uint64 guid) +{ + return GetObjectInWorld(guid, (Player*)NULL); } Player* ObjectAccessor::FindPlayerByName(const char* name) @@ -164,11 +184,6 @@ void ObjectAccessor::SaveAllPlayers() itr->second->SaveToDB(); } -Pet* ObjectAccessor::GetPet(uint64 guid) -{ - return GetObjectInWorld(guid, (Pet*)NULL); -} - Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) { ACE_GUARD_RETURN(LockType, guard, i_corpseGuard, NULL); diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index fc128d6a4e0..b010254ae13 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -40,6 +40,7 @@ class Unit; class GameObject; class DynamicObject; class WorldObject; +class Vehicle; class Map; template <class T> @@ -95,47 +96,42 @@ class ObjectAccessor typedef UNORDERED_MAP<uint64, Corpse*> Player2CorpsesMapType; typedef UNORDERED_MAP<Player*, UpdateData>::value_type UpdateDataValueType; - template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/) + // TODO: override these template functions for each holder type and add assertions + + // returns object if is in world + template<class T> static T* GetObjectInWorld(uint64 guid, T* /*typeSpecifier*/) { return HashMapHolder<T>::Find(guid); } - static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/) + // Player may be not in world while in ObjectAccessor + static Player* GetObjectInWorld(uint64 guid, Player* /*typeSpecifier*/) { - if (!guid) - return NULL; + Player * player = HashMapHolder<Player>::Find(guid); + if (player && player->IsInWorld()) + return player; + return NULL; + } + static Unit* GetObjectInWorld(uint64 guid, Unit* /*typeSpecifier*/) + { if (IS_PLAYER_GUID(guid)) - { - Unit* u = (Unit*)HashMapHolder<Player>::Find(guid); - if (!u || !u->IsInWorld()) - return NULL; - - return u; - } + return (Unit*)GetObjectInWorld(guid, (Player*)NULL); if (IS_PET_GUID(guid)) - return (Unit*)HashMapHolder<Pet>::Find(guid); + return (Unit*)GetObjectInWorld(guid, (Pet*)NULL); - return (Unit*)HashMapHolder<Creature>::Find(guid); + return (Unit*)GetObjectInWorld(guid, (Creature*)NULL); } - static Unit* GetUnitInOrOutOfWorld(uint64 guid, Unit* /*fake*/) + // returns object if is in map + template<class T> static T* GetObjectInMap(uint64 guid, Map * map, T* /*typeSpecifier*/) { - if (!guid) - return NULL; - - if (IS_PLAYER_GUID(guid)) - { - Unit* u = (Unit*)HashMapHolder<Player>::Find(guid); - if (!u) - return NULL; - - return u; - } - - // Other object types than player are unloaded while out of world - return GetObjectInWorld(guid, (Unit*)NULL); + assert(map); + if (T * obj = GetObjectInWorld(guid, (T*)NULL)) + if (obj->GetMap() == map) + return obj; + return NULL; } template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/) @@ -167,18 +163,23 @@ class ObjectAccessor return NULL; } + // these functions return objects only if in map of specified object static WorldObject* GetWorldObject(WorldObject const&, uint64); static Object* GetObjectByTypeMask(WorldObject const&, uint64, uint32 typemask); - static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, uint64); - static Unit* GetUnit(WorldObject const&, uint64 guid) { return GetObjectInWorld(guid, (Unit*)NULL); } - static Unit* GetUnitInOrOutOfWorld(WorldObject const&, uint64 guid) { return GetUnitInOrOutOfWorld(guid, (Unit*)NULL); } - static Pet* GetPet(Unit const&, uint64 guid) { return GetPet(guid); } - static Player* GetPlayer(Unit const&, uint64 guid) { return FindPlayer(guid); } static Corpse* GetCorpse(WorldObject const& u, uint64 guid); - static Pet* GetPet(uint64 guid); - static Player* FindPlayer(uint64); + static GameObject* GetGameObject(WorldObject const& u, uint64 guid); + static DynamicObject* GetDynamicObject(WorldObject const& u, uint64 guid); + static Unit* GetUnit(WorldObject const&, uint64 guid); + static Creature* GetCreature(WorldObject const& u, uint64 guid); + static Pet* GetPet(WorldObject const&, uint64 guid); + static Player* GetPlayer(WorldObject const&, uint64 guid); + static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, uint64); - Player* FindPlayerByName(const char* name) ; + // these functions return objects if found in whole world + // ACCESS LIKE THAT IS NOT THREAD SAFE + static Pet * FindPet(uint64); + static Player* FindPlayer(uint64); + Player* FindPlayerByName(const char* name); // when using this, you must use the hashmapholder's lock HashMapHolder<Player>::MapType& GetPlayers() diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index dbad99f79f0..2d86e17819c 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3942,46 +3942,19 @@ void Map::ScriptsProcess() Creature* Map::GetCreature(uint64 guid) { - Creature * ret = NULL; - if (IS_CRE_OR_VEH_GUID(guid)) - ret = ObjectAccessor::GetObjectInWorld(guid, (Creature*)NULL); - - if (!ret) - return NULL; - - if (ret->GetMapId() != GetId()) - return NULL; - - if (ret->GetInstanceId() != GetInstanceId()) - return NULL; - - return ret; + return ObjectAccessor::GetObjectInMap(guid, this, (Creature*)NULL); } GameObject* Map::GetGameObject(uint64 guid) { - GameObject * ret = ObjectAccessor::GetObjectInWorld(guid, (GameObject*)NULL); - if (!ret) - return NULL; - if (ret->GetMapId() != GetId()) - return NULL; - if (ret->GetInstanceId() != GetInstanceId()) - return NULL; - return ret; + return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)NULL); } DynamicObject* Map::GetDynamicObject(uint64 guid) { - DynamicObject * ret = ObjectAccessor::GetObjectInWorld(guid, (DynamicObject*)NULL); - if (!ret) - return NULL; - if (ret->GetMapId() != GetId()) - return NULL; - if (ret->GetInstanceId() != GetInstanceId()) - return NULL; - return ret; + return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)NULL); } void Map::UpdateIteratorBack(Player *player) diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 3bf189af88f..54e6d96939d 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -273,12 +273,12 @@ bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standi else { // update for the actual faction first - bool res = SetOneFactionReputation(factionEntry, standing, incremental); + bool res = SetOneFactionReputation(factionEntry, standing, incremental); if (res) { // then some spillover calculation here if it exist - if (const RepSpilloverTemplate *repTemplate = objmgr.GetRepSpilloverTemplate(factionEntry->ID)) + if (RepSpilloverTemplate const * repTemplate = objmgr.GetRepSpilloverTemplate(factionEntry->ID)) { for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i) { @@ -287,7 +287,7 @@ bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standi if (m_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i])) { // bonuses are already given, so just modify standing by rate - int32 spilloverRep = standing * repTemplate->faction_rate[i]; + int32 spilloverRep = standing * repTemplate->faction_rate[i]; SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental); } } @@ -295,7 +295,7 @@ bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standi } // now we can send it - FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); + FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); if (itr != m_factions.end()) SendState(&itr->second); } diff --git a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp index 5beff7e597d..bc7428ddf13 100644 --- a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp @@ -557,7 +557,7 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data) recv_data >> name; recv_data >> isdeclined; - Pet* pet = ObjectAccessor::GetPet(petguid); + Pet* pet = ObjectAccessor::FindPet(petguid); // check it! if (!pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET || !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) || diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index ca396674412..9582286ab23 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1046,23 +1046,6 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex) void Spell::DoAllEffectOnTarget(TargetInfo *target) { - // invalid pointer, log debug info to trac the reason - if (target && target < ((TargetInfo*)1024)) - { - sLog.outString("Spell::DoAllEffectOnTarget CRASH! - debug info:"); - sLog.outString("Caster:"); - m_caster->OutDebugInfo(); - if (m_targets.getUnitTarget()) - { - sLog.outString("Unit target:"); - m_targets.getUnitTarget()->OutDebugInfo(); - } - sLog.outString("SpellId: %d", m_spellInfo->Id); - sLog.outString("SpellTargetMap:"); - for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - sLog.outStringInLine("guid:%u, effmask:%u, ", ihit->targetGUID, ihit->effectMask); - ASSERT(false); - } if (!target || target->processed) return; diff --git a/src/server/scripts/Northrend/borean_tundra.cpp b/src/server/scripts/Northrend/borean_tundra.cpp index b2b975f54ab..bd6f390165a 100644 --- a/src/server/scripts/Northrend/borean_tundra.cpp +++ b/src/server/scripts/Northrend/borean_tundra.cpp @@ -2017,7 +2017,7 @@ struct npc_seaforium_depth_chargeAI : public ScriptedAI { if (Creature* cCredit = me->FindNearestCreature(25402 + i, 10.0f))//25402-25405 credit markers { - if (Unit* uOwner = me->GetOwner(true)) + if (Unit* uOwner = me->GetOwner()) { Player* pOwner = uOwner->ToPlayer(); if (pOwner && pOwner->GetQuestStatus(QUEST_BURY_THOSE_COCKROACHES) == QUEST_STATUS_INCOMPLETE) diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index ca7a136c2fb..266b616c7d4 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -753,7 +753,7 @@ bool GOHello_go_inconspicuous_landmark(Player *pPlayer, GameObject* /*pGO*/) bool GOHello_go_soulwell(Player *pPlayer, GameObject* pGO) { - Unit *caster = pGO->GetOwner(false); + Unit *caster = pGO->GetOwner(); if (!caster || caster->GetTypeId() != TYPEID_PLAYER) return true; |
