Core/Objects: Added ToWorldObject and ToItem

This commit is contained in:
Shauren
2024-03-14 11:37:32 +01:00
parent 9402c66e84
commit 6f6af6a1a1
7 changed files with 50 additions and 39 deletions

View File

@@ -86,8 +86,8 @@ Object::~Object()
if (IsInWorld())
{
TC_LOG_FATAL("misc", "Object::~Object {} deleted but still in world!!", GetGUID().ToString());
if (isType(TYPEMASK_ITEM))
TC_LOG_FATAL("misc", "Item slot {}", ((Item*)this)->GetSlot());
if (Item* item = ToItem())
TC_LOG_FATAL("misc", "Item slot {}", item->GetSlot());
ABORT();
}
@@ -1361,7 +1361,11 @@ void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
{
float new_z = GetMapHeight(x, y, z);
if (new_z > INVALID_HEIGHT)
z = new_z + (isType(TYPEMASK_UNIT) ? static_cast<Unit const*>(this)->GetHoverOffset() : 0.0f);
{
z = new_z;
if (Unit const* unit = ToUnit())
z += unit->GetHoverOffset();
}
}
void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z, float* groundZ) const
@@ -3635,7 +3639,7 @@ void WorldObject::DestroyForNearbyPlayers()
if (!player->HaveAtClient(this))
continue;
if (isType(TYPEMASK_UNIT) && ToUnit()->GetCharmerGUID() == player->GetGUID()) /// @todo this is for puppet
if (Unit const* unit = ToUnit(); unit && unit->GetCharmerGUID() == player->GetGUID()) /// @todo this is for puppet
continue;
DestroyForPlayer(player);

View File

@@ -45,6 +45,7 @@ class CreatureAI;
class DynamicObject;
class GameObject;
class InstanceScript;
class Item;
class Map;
class Object;
class Player;
@@ -196,6 +197,18 @@ class TC_GAME_API Object
virtual void BuildUpdate(UpdateDataMapType&) { }
void BuildFieldsUpdate(Player*, UpdateDataMapType &) const;
inline bool IsWorldObject() const { return isType(TYPEMASK_WORLDOBJECT); }
static WorldObject* ToWorldObject(Object* o) { return o ? o->ToWorldObject() : nullptr; }
static WorldObject const* ToWorldObject(Object const* o) { return o ? o->ToWorldObject() : nullptr; }
WorldObject* ToWorldObject() { if (IsUnit()) return reinterpret_cast<WorldObject*>(this); else return nullptr; }
WorldObject const* ToWorldObject() const { if (IsUnit()) return reinterpret_cast<WorldObject const*>(this); else return nullptr; }
inline bool IsItem() const { return isType(TYPEMASK_ITEM); }
static Item* ToItem(Object* o) { return o ? o->ToItem() : nullptr; }
static Item const* ToItem(Object const* o) { return o ? o->ToItem() : nullptr; }
Item* ToItem() { if (IsItem()) return reinterpret_cast<Item*>(this); else return nullptr; }
Item const* ToItem() const { if (IsItem()) return reinterpret_cast<Item const*>(this); else return nullptr; }
inline bool IsPlayer() const { return GetTypeId() == TYPEID_PLAYER; }
static Player* ToPlayer(Object* o) { return o ? o->ToPlayer() : nullptr; }
static Player const* ToPlayer(Object const* o) { return o ? o->ToPlayer() : nullptr; }

View File

@@ -27,8 +27,8 @@
#include <set>
#include <string>
#include <type_traits>
#include <vector>
#include <unordered_set>
#include <vector>
enum TypeID
{
@@ -66,7 +66,9 @@ enum TypeMask
TYPEMASK_AREATRIGGER = 0x0800,
TYPEMASK_SCENEOBJECT = 0x1000,
TYPEMASK_CONVERSATION = 0x2000,
TYPEMASK_SEER = TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT
TYPEMASK_SEER = TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT,
TYPEMASK_WORLDOBJECT = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_DYNAMICOBJECT | TYPEMASK_CORPSE | TYPEMASK_AREATRIGGER | TYPEMASK_SCENEOBJECT | TYPEMASK_CONVERSATION
};
enum class HighGuid

View File

@@ -14988,9 +14988,8 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetSrcSpell(), GetMap()->GetDifficultyID());
Unit* caster = this;
if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ACCEPT) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER) && !spellInfo->HasTargetType(TARGET_DEST_CASTER_SUMMON))
if (Unit* unit = questGiver->ToUnit())
caster = unit;
if (questGiver && questGiver->IsUnit() && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ACCEPT) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER) && !spellInfo->HasTargetType(TARGET_DEST_CASTER_SUMMON))
caster = questGiver->ToUnit();
caster->CastSpell(this, spellInfo->Id, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetCastDifficulty(spellInfo->Difficulty));
}
@@ -15356,9 +15355,8 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
{
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(quest->GetRewSpell(), GetMap()->GetDifficultyID());
Unit* caster = this;
if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
if (Unit* unit = questGiver->ToUnit())
caster = unit;
if (questGiver && questGiver->IsUnit() && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
caster = questGiver->ToUnit();
caster->CastSpell(this, spellInfo->Id, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetCastDifficulty(spellInfo->Difficulty));
}
@@ -15372,9 +15370,8 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(displaySpell.SpellId, GetMap()->GetDifficultyID());
Unit* caster = this;
if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
if (Unit* unit = questGiver->ToUnit())
caster = unit;
if (questGiver && questGiver->IsUnit() && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
caster = questGiver->ToUnit();
caster->CastSpell(this, spellInfo->Id, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetCastDifficulty(spellInfo->Difficulty));
}
@@ -15407,7 +15404,7 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
//lets remove flag for delayed teleports
SetCanDelayTeleport(false);
if (questGiver && questGiver->isType(TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT))
if (questGiver && questGiver->IsWorldObject())
{
//For AutoSubmition was added plr case there as it almost same exclute AI script cases.
// Send next quest
@@ -23948,8 +23945,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
// target aura duration for caster show only if target exist at caster client
// send data at target visibility change (adding to client)
if (target->isType(TYPEMASK_UNIT))
SendInitialVisiblePackets(static_cast<Unit*>(target));
SendInitialVisiblePackets(target);
}
}
}
@@ -26132,14 +26128,11 @@ bool ItemPosCount::isContainedIn(std::vector<ItemPosCount> const& vec) const
void Player::StopCastingBindSight() const
{
if (WorldObject* target = GetViewpoint())
if (Unit* target = Object::ToUnit(GetViewpoint()))
{
if (target->isType(TYPEMASK_UNIT))
{
static_cast<Unit*>(target)->RemoveAurasByType(SPELL_AURA_BIND_SIGHT, GetGUID());
static_cast<Unit*>(target)->RemoveAurasByType(SPELL_AURA_MOD_POSSESS, GetGUID());
static_cast<Unit*>(target)->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET, GetGUID());
}
target->RemoveAurasByType(SPELL_AURA_BIND_SIGHT, GetGUID());
target->RemoveAurasByType(SPELL_AURA_MOD_POSSESS, GetGUID());
target->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET, GetGUID());
}
}
@@ -26161,8 +26154,8 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
// farsight dynobj or puppet may be very far away
UpdateVisibilityOf(target);
if (target->isType(TYPEMASK_UNIT) && target != GetVehicleBase())
static_cast<Unit*>(target)->AddPlayerToVision(this);
if (Unit* targetUnit = target->ToUnit(); targetUnit && targetUnit != GetVehicleBase())
targetUnit->AddPlayerToVision(this);
SetSeer(target);
}
else
@@ -26177,8 +26170,8 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::FarsightObject), ObjectGuid::Empty);
if (target->isType(TYPEMASK_UNIT) && target != GetVehicleBase())
static_cast<Unit*>(target)->RemovePlayerFromVision(this);
if (Unit* targetUnit = target->ToUnit(); targetUnit && targetUnit != GetVehicleBase())
targetUnit->RemovePlayerFromVision(this);
//must immediately set seer back otherwise may crash
SetSeer(this);

View File

@@ -41,7 +41,7 @@ void Map::ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo>> const
// prepare static data
ObjectGuid sourceGUID = source ? source->GetGUID() : ObjectGuid::Empty; //some script commands doesn't have source
ObjectGuid targetGUID = target ? target->GetGUID() : ObjectGuid::Empty;
ObjectGuid ownerGUID = (source && source->isType(TYPEMASK_ITEM)) ? ((Item*)source)->GetOwnerGUID() : ObjectGuid::Empty;
ObjectGuid ownerGUID = [&] { if (Item* item = Object::ToItem(source)) return item->GetOwnerGUID(); return ObjectGuid::Empty; }();
///- Schedule script execution for all scripts in the script map
ScriptMap const* s2 = &(s->second);
@@ -76,7 +76,7 @@ void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* sou
// prepare static data
ObjectGuid sourceGUID = source ? source->GetGUID() : ObjectGuid::Empty;
ObjectGuid targetGUID = target ? target->GetGUID() : ObjectGuid::Empty;
ObjectGuid ownerGUID = (source && source->isType(TYPEMASK_ITEM)) ? ((Item*)source)->GetOwnerGUID() : ObjectGuid::Empty;
ObjectGuid ownerGUID = [&] { if (Item* item = Object::ToItem(source)) return item->GetOwnerGUID(); return ObjectGuid::Empty; }();
ScriptAction sa;
sa.sourceGUID = sourceGUID;
@@ -191,7 +191,7 @@ inline Unit* Map::_GetScriptUnit(Object* obj, bool isSource, ScriptInfo const* s
Unit* unit = nullptr;
if (!obj)
TC_LOG_ERROR("scripts", "{} {} object is NULL.", scriptInfo->GetDebugInfo(), isSource ? "source" : "target");
else if (!obj->isType(TYPEMASK_UNIT))
else if (!obj->IsUnit())
TC_LOG_ERROR("scripts", "{} {} object is not unit {}, skipping.",
scriptInfo->GetDebugInfo(), isSource ? "source" : "target", obj->GetGUID().ToString());
else
@@ -267,7 +267,7 @@ inline void Map::_ScriptProcessDoor(Object* source, Object* target, ScriptInfo c
TC_LOG_ERROR("scripts", "{} door guid is not specified.", scriptInfo->GetDebugInfo());
else if (!source)
TC_LOG_ERROR("scripts", "{} source object is NULL.", scriptInfo->GetDebugInfo());
else if (!source->isType(TYPEMASK_UNIT))
else if (!source->IsUnit())
TC_LOG_ERROR("scripts", "{} source object is not unit {}, skipping.", scriptInfo->GetDebugInfo(),
source->GetGUID().ToString());
else
@@ -288,9 +288,8 @@ inline void Map::_ScriptProcessDoor(Object* source, Object* target, ScriptInfo c
{
pDoor->UseDoorOrButton(nTimeToToggle);
if (target && target->isType(TYPEMASK_GAMEOBJECT))
if (GameObject* goTarget = Object::ToGameObject(target))
{
GameObject* goTarget = target->ToGameObject();
if (goTarget && goTarget->GetGoType() == GAMEOBJECT_TYPE_BUTTON)
goTarget->UseDoorOrButton(nTimeToToggle);
}

View File

@@ -404,10 +404,10 @@ Aura* Aura::Create(AuraCreateInfo& createInfo)
createInfo.CasterGUID = createInfo.Caster->GetGUID();
// check if aura can be owned by owner
if (createInfo._owner->isType(TYPEMASK_UNIT))
if (!createInfo._owner->IsInWorld() || createInfo._owner->ToUnit()->IsDuringRemoveFromWorld())
if (Unit* ownerUnit = createInfo._owner->ToUnit())
if (!ownerUnit->IsInWorld() || ownerUnit->IsDuringRemoveFromWorld())
// owner not in world so don't allow to own not self cast single target auras
if (createInfo.CasterGUID != createInfo._owner->GetGUID() && createInfo._spellInfo->IsSingleTarget())
if (createInfo.CasterGUID != ownerUnit->GetGUID() && createInfo._spellInfo->IsSingleTarget())
return nullptr;
Aura* aura = nullptr;

View File

@@ -952,7 +952,7 @@ public:
void IsSummonedBy(WorldObject* summoner) override
{
if (summoner->isType(TYPEMASK_PLAYER))
if (summoner->IsPlayer())
playerGuid = summoner->GetGUID();
}