Core/Creature: implement initial SummonInfo API for handling summons in the future
This commit is contained in:
1 parent
0f41e34aa1
commit
5848eedb24
10 files changed
+427
-1
No files matched your search
@@ -18,9 +18,91 @@
|
||||
#ifndef TRINITY_ADVSTD_H
|
||||
#define TRINITY_ADVSTD_H
|
||||
|
||||
#include <version>
|
||||
|
||||
#ifdef __cpp_lib_bit_cast
|
||||
#include <bit>
|
||||
#else
|
||||
#include <cstring> // for memcpy
|
||||
#endif
|
||||
#include <compare>
|
||||
|
||||
// this namespace holds implementations of upcoming stdlib features that our c++ version doesn't have yet
|
||||
namespace advstd
|
||||
{
|
||||
// libc++ is missing these two
|
||||
[[nodiscard]] constexpr bool is_eq(std::partial_ordering cmp) noexcept { return cmp == 0; }
|
||||
[[nodiscard]] constexpr bool is_neq(std::partial_ordering cmp) noexcept { return cmp != 0; }
|
||||
|
||||
#ifdef __cpp_lib_bit_cast
|
||||
using std::bit_cast;
|
||||
#else
|
||||
// libstdc++ v10 is missing this
|
||||
template <typename To, typename From,
|
||||
std::enable_if_t<std::conjunction_v<
|
||||
std::bool_constant<sizeof(To) == sizeof(From)>,
|
||||
std::is_trivially_copyable<To>,
|
||||
std::is_trivially_copyable<From>>, int> = 0>
|
||||
[[nodiscard]] constexpr To bit_cast(From const& from) noexcept
|
||||
{
|
||||
To to;
|
||||
std::memcpy(&to, &from, sizeof(To));
|
||||
return to;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// std::forward_like
|
||||
#ifdef __cpp_lib_forward_like
|
||||
#include <utility>
|
||||
namespace advstd
|
||||
{
|
||||
using std::forward_like;
|
||||
}
|
||||
#else
|
||||
namespace advstd
|
||||
{
|
||||
template <class T, class U>
|
||||
[[nodiscard]] constexpr decltype(auto) forward_like(U&& value) noexcept
|
||||
{
|
||||
using ValueU = std::remove_reference_t<U>;
|
||||
using ValueConstU = std::conditional_t<std::is_const_v<std::remove_reference_t<T>>, ValueU const, ValueU>;
|
||||
return static_cast<std::conditional_t<std::is_rvalue_reference_v<T&&>, ValueConstU&&, ValueConstU&>>(value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// std::ranges::contains
|
||||
#include <algorithm>
|
||||
#ifndef __cpp_lib_ranges_contains
|
||||
#include <functional> // for std::ranges::equal_to, std::identity
|
||||
#include <iterator> // for std::input_iterator, std::sentinel_for, std::projected
|
||||
#endif
|
||||
|
||||
namespace advstd::ranges
|
||||
{
|
||||
#ifndef __cpp_lib_ranges_contains
|
||||
struct Contains
|
||||
{
|
||||
template<std::input_iterator I, std::sentinel_for<I> S, class T, class Proj = std::identity>
|
||||
requires std::indirect_binary_predicate<std::ranges::equal_to, std::projected<I, Proj>, T const*>
|
||||
[[nodiscard]] inline constexpr bool operator()(I first, S last, T const& value, Proj proj = {}) const
|
||||
{
|
||||
return std::ranges::find(std::move(first), last, value, proj) != last;
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R, class T, class Proj = std::identity>
|
||||
requires std::indirect_binary_predicate<std::ranges::equal_to, std::projected<std::ranges::iterator_t<R>, Proj>, T const*>
|
||||
[[nodiscard]] inline constexpr bool operator()(R&& r, T const& value, Proj proj = {}) const
|
||||
{
|
||||
auto first = std::ranges::begin(r);
|
||||
auto last = std::ranges::end(r);
|
||||
return std::ranges::find(std::move(first), last, value, proj) != last;
|
||||
}
|
||||
} inline constexpr contains;
|
||||
#else
|
||||
using std::ranges::contains;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SummonInfo.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Transport.h"
|
||||
#include "Util.h"
|
||||
@@ -316,6 +317,11 @@ void Creature::AddToWorld()
|
||||
if (IsVehicle())
|
||||
GetVehicleKit()->Install();
|
||||
|
||||
// If the creature has been summoned, register it for the summoner
|
||||
if (IsSummon())
|
||||
if (Unit* summoner = GetSummonInfo()->GetUnitSummoner())
|
||||
summoner->RegisterSummon(GetSummonInfo());
|
||||
|
||||
if (GetZoneScript())
|
||||
GetZoneScript()->OnCreatureCreate(this);
|
||||
}
|
||||
@@ -325,6 +331,11 @@ void Creature::RemoveFromWorld()
|
||||
{
|
||||
if (IsInWorld())
|
||||
{
|
||||
// If the creature about to despawn, unregister it for the summoner
|
||||
if (IsSummon())
|
||||
if (Unit* summoner = GetSummonInfo()->GetUnitSummoner())
|
||||
summoner->UnregisterSummon(GetSummonInfo());
|
||||
|
||||
if (GetZoneScript())
|
||||
GetZoneScript()->OnCreatureRemove(this);
|
||||
|
||||
@@ -2761,6 +2772,22 @@ void Creature::InitializeMovementSpeeds()
|
||||
SetSpeed(MOVE_WALK, _creatureMovementInfo.WalkSpeed);
|
||||
}
|
||||
|
||||
void Creature::InitializeSummonInfo(SummonInfoArgs const& args)
|
||||
{
|
||||
ASSERT(_summonInfo == nullptr, "SummonInfo has already been initialized and must not be allocated again!");
|
||||
_summonInfo = std::make_unique<SummonInfo>(this, args);
|
||||
}
|
||||
|
||||
SummonInfo* Creature::GetSummonInfo() const
|
||||
{
|
||||
return _summonInfo.get();
|
||||
}
|
||||
|
||||
bool Creature::IsSummon() const
|
||||
{
|
||||
return _summonInfo != nullptr;
|
||||
}
|
||||
|
||||
void Creature::AllLootRemovedFromCorpse()
|
||||
{
|
||||
if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
|
||||
|
||||
@@ -34,8 +34,11 @@ class Group;
|
||||
class Quest;
|
||||
class Player;
|
||||
class SpellInfo;
|
||||
class SummonInfo;
|
||||
class WorldSession;
|
||||
|
||||
struct SummonInfoArgs;
|
||||
|
||||
enum MovementGeneratorType : uint8;
|
||||
|
||||
struct VendorItemCount
|
||||
@@ -420,6 +423,13 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
void ResetNoNpcDamageBelowPctHealthValue() { _noNpcDamageBelowPctHealth = 0.f; }
|
||||
float GetNoNpcDamageBelowPctHealthValue() const { return _noNpcDamageBelowPctHealth; }
|
||||
|
||||
// Initializes the summon API for this creature which marks it as summon and will be treated accordingly
|
||||
void InitializeSummonInfo(SummonInfoArgs const& args);
|
||||
// Returns a pointer to the SummonInfo API, nullptr if the creature is not a summon
|
||||
SummonInfo* GetSummonInfo() const;
|
||||
|
||||
bool IsSummon() const override;
|
||||
|
||||
protected:
|
||||
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data = nullptr, uint32 vehId = 0);
|
||||
bool InitEntry(uint32 entry, CreatureData const* data = nullptr);
|
||||
@@ -510,6 +520,9 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
|
||||
Optional<uint32> _defaultMountDisplayIdOverride;
|
||||
float _noNpcDamageBelowPctHealth;
|
||||
|
||||
// The Summon API which controls the behavior of summons
|
||||
std::unique_ptr<SummonInfo> _summonInfo;
|
||||
};
|
||||
|
||||
class TC_GAME_API AssistDelayEvent : public BasicEvent
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* 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 "SummonInfo.h"
|
||||
|
||||
#include "Creature.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "SummonInfoArgs.h"
|
||||
|
||||
SummonInfo::SummonInfo(Creature* summonedCreature, SummonInfoArgs const& args) :
|
||||
_summonedCreature(ASSERT_NOTNULL(summonedCreature)), _summonerGUID(args.SummonerGUID), _remainingDuration(args.Duration),
|
||||
_maxHealth(args.MaxHealth), _summonSpellId(args.SummonSpellId),_despawnOnSummonerLogout(false),
|
||||
_despawnOnSummonerDeath(false), _despawnWhenExpired(false)
|
||||
{
|
||||
if (args.SummonPropertiesId.has_value())
|
||||
InitializeSummonProperties(*args.SummonPropertiesId);
|
||||
}
|
||||
|
||||
void SummonInfo::InitializeSummonProperties(uint32 summonPropertiesId)
|
||||
{
|
||||
SummonPropertiesEntry const* summonProperties = sSummonPropertiesStore.LookupEntry(summonPropertiesId);
|
||||
if (!summonProperties)
|
||||
{
|
||||
TC_LOG_ERROR("entities.unit", "Creature %s has been summoned with a non-existing SummonProperties.dbc entry (RecId: %u).", _summonedCreature->GetGUID().ToString().c_str(), summonPropertiesId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (summonProperties->Faction)
|
||||
_factionId = summonProperties->Faction;
|
||||
|
||||
_despawnOnSummonerLogout = summonProperties->GetFlags().HasFlag(SummonPropertiesFlags::DespawnOnSummonerLogout);
|
||||
_despawnOnSummonerDeath = summonProperties->GetFlags().HasFlag(SummonPropertiesFlags::DespawnOnSummonerDeath);
|
||||
_despawnWhenExpired = summonProperties->GetFlags().HasFlag(SummonPropertiesFlags::DespawnWhenExpired);
|
||||
|
||||
//if (_despawnOnSummonerDeath && summonProperties->GetFlags().HasFlag(SummonPropertiesFlags::DontDespawnOnSummonerDeath))
|
||||
// _despawnOnSummonerDeath = false;
|
||||
}
|
||||
|
||||
Creature* SummonInfo::GetSummonedCreature() const
|
||||
{
|
||||
return _summonedCreature;
|
||||
}
|
||||
|
||||
Unit* SummonInfo::GetUnitSummoner() const
|
||||
{
|
||||
if (!_summonerGUID.has_value())
|
||||
return nullptr;
|
||||
|
||||
return ObjectAccessor::GetUnit(*_summonedCreature, *_summonerGUID);
|
||||
}
|
||||
|
||||
GameObject* SummonInfo::GetGameObjectSummoner() const
|
||||
{
|
||||
if (!_summonerGUID.has_value())
|
||||
return nullptr;
|
||||
|
||||
return ObjectAccessor::GetGameObject(*_summonedCreature, *_summonerGUID);
|
||||
}
|
||||
|
||||
Optional<Milliseconds> SummonInfo::GetRemainingDuration() const
|
||||
{
|
||||
return _remainingDuration;
|
||||
}
|
||||
|
||||
Optional<uint64> SummonInfo::GetMaxHealth() const
|
||||
{
|
||||
return _maxHealth;
|
||||
}
|
||||
|
||||
Optional<uint32> SummonInfo::GetSummonSpellId() const
|
||||
{
|
||||
return _summonSpellId;
|
||||
}
|
||||
|
||||
Optional<uint32> SummonInfo::GetFactionId() const
|
||||
{
|
||||
return _factionId;
|
||||
}
|
||||
|
||||
bool SummonInfo::DespawnsOnSummonerLogout() const
|
||||
{
|
||||
return _despawnOnSummonerLogout;
|
||||
}
|
||||
|
||||
void SummonInfo::SetDespawnOnSummonerLogout(bool set)
|
||||
{
|
||||
_despawnOnSummonerLogout = set;
|
||||
}
|
||||
|
||||
bool SummonInfo::DespawnsOnSummonerDeath() const
|
||||
{
|
||||
return _despawnOnSummonerDeath;
|
||||
}
|
||||
|
||||
void SummonInfo::SetDespawnOnSummonerDeath(bool set)
|
||||
{
|
||||
_despawnOnSummonerDeath = set;
|
||||
}
|
||||
|
||||
bool SummonInfo::DespawnsWhenExpired() const
|
||||
{
|
||||
return _despawnWhenExpired;
|
||||
}
|
||||
|
||||
void SummonInfo::SetDespawnWhenExpired(bool set)
|
||||
{
|
||||
_despawnWhenExpired = set;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* 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 _SummonInfo_h__
|
||||
#define _SummonInfo_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include "Duration.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "Optional.h"
|
||||
|
||||
class Creature;
|
||||
class GameObject;
|
||||
class Unit;
|
||||
|
||||
struct SummonInfoArgs;
|
||||
|
||||
class TC_GAME_API SummonInfo
|
||||
{
|
||||
public:
|
||||
SummonInfo(SummonInfo const& right) = delete;
|
||||
SummonInfo(SummonInfo&& right) = delete;
|
||||
SummonInfo& operator=(SummonInfo const& right) = delete;
|
||||
SummonInfo& operator=(SummonInfo&& right) = delete;
|
||||
|
||||
explicit SummonInfo(Creature* summonedCreature, SummonInfoArgs const& args);
|
||||
|
||||
// Initializes additional settings based on the provided SummonProperties ID.
|
||||
void InitializeSummonProperties(uint32 summonPropertiesId);
|
||||
// Returns the creature that is tied to this SummonInfo instance.
|
||||
Creature* GetSummonedCreature() const;
|
||||
// Returns the Unit summoner, or nullptr if no summoner has been provided or if the summoner is not a Unit.
|
||||
Unit* GetUnitSummoner() const;
|
||||
// Returns the GameObject summoner, or nullptr if no summoner has been provided or if the summoner is not a GameObject.
|
||||
GameObject* GetGameObjectSummoner() const;
|
||||
|
||||
// Returns the remaining time until the summon expires. Nullopt when no duration was set which implies that the summon is permanent.
|
||||
Optional<Milliseconds> GetRemainingDuration() const;
|
||||
// Returns the health amount that will override the default max health calculation. Nullopt when no amount is provided.
|
||||
Optional<uint64> GetMaxHealth() const;
|
||||
// Returns the ID of the spell that has been used to summon the creature. Nullopt when the creature has not been summoned by a spell (scripted summons/ other APIs).
|
||||
Optional<uint32> GetSummonSpellId() const;
|
||||
// Returns the FactionTemplate ID of the summon that is overriding the default ID of the creature. Nullopt when the faction has not been overriden.
|
||||
Optional<uint32> GetFactionId() const;
|
||||
|
||||
// Returns true when the summon will despawn when the summoner logs out. This also includes despawning and teleporting between map instances.
|
||||
bool DespawnsOnSummonerLogout() const;
|
||||
// Marks the summon to despawn when the summoner logs out. This also includes despawning and teleporting between map instaces.
|
||||
void SetDespawnOnSummonerLogout(bool set);
|
||||
// Returns true when the summon will despawn when its summoner has died.
|
||||
bool DespawnsOnSummonerDeath() const;
|
||||
// Marks the summon to despawn when the summoner has died.
|
||||
void SetDespawnOnSummonerDeath(bool set);
|
||||
// Returns true when the summon will despawn after its duration has expired. If not set, the summon will just die.
|
||||
bool DespawnsWhenExpired() const;
|
||||
// Marks the summon to despawn after its duration has expired. If disabled, the summon will just die.
|
||||
void SetDespawnWhenExpired(bool set);
|
||||
|
||||
private:
|
||||
Creature* _summonedCreature;
|
||||
Optional<ObjectGuid> _summonerGUID;
|
||||
Optional<Milliseconds> _remainingDuration; // NYI
|
||||
Optional<uint64> _maxHealth; // NYI
|
||||
Optional<uint32> _summonSpellId; // NYI
|
||||
Optional<uint32> _factionId; // NYI
|
||||
bool _despawnOnSummonerLogout; // NYI
|
||||
bool _despawnOnSummonerDeath; // NYI
|
||||
bool _despawnWhenExpired; // NYI
|
||||
};
|
||||
|
||||
#endif // _SummonInfo_h__
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* 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 _SummonInfoArgs_h__
|
||||
#define _SummonInfoArgs_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include "Duration.h"
|
||||
#include "Optional.h"
|
||||
#include "ObjectGuid.h"
|
||||
|
||||
// Controls the behavior of a summoned creature and must be set with extreme care. If you want a blank summon that just exists as a permanent spawn, leave all fields untouched.
|
||||
struct SummonInfoArgs
|
||||
{
|
||||
Optional<ObjectGuid> SummonerGUID;
|
||||
Optional<uint64> MaxHealth;
|
||||
Optional<Milliseconds> Duration;
|
||||
Optional<uint32> SummonPropertiesId;
|
||||
Optional<uint32> SummonSpellId;
|
||||
};
|
||||
|
||||
#endif // _SummonInfoArgs_h__
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "SpellDefines.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "SummonInfoArgs.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Totem.h"
|
||||
#include "Transport.h"
|
||||
@@ -2086,6 +2087,22 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonCreatur
|
||||
if (summonArgs.Summoner)
|
||||
PhasingHandler::InheritPhaseShift(summon, summonArgs.Summoner);
|
||||
|
||||
// Store special settings which have been extracted from spell effects/scripts
|
||||
SummonInfoArgs args;
|
||||
if (summonArgs.Summoner)
|
||||
args.SummonerGUID = summonArgs.Summoner->GetGUID();
|
||||
if (summonArgs.SummonProperties)
|
||||
args.SummonPropertiesId = summonArgs.SummonProperties->ID;
|
||||
if (summonArgs.SummonDuration)
|
||||
args.Duration = Milliseconds(summonArgs.SummonDuration);
|
||||
if (summonArgs.SummonSpellId)
|
||||
args.SummonSpellId = summonArgs.SummonSpellId;
|
||||
if (summonArgs.SummonHealth)
|
||||
args.MaxHealth = summonArgs.SummonHealth;
|
||||
|
||||
// Initialize the SummonInfo API which marks the creature as Summon
|
||||
summon->InitializeSummonInfo(args);
|
||||
|
||||
TransportBase* transport = summonArgs.Summoner ? summonArgs.Summoner->GetTransport() : nullptr;
|
||||
if (transport)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "SpellHistory.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SummonInfo.h"
|
||||
#include "SummonInfoArgs.h"
|
||||
#include "Unit.h"
|
||||
#include "Util.h"
|
||||
#include "Group.h"
|
||||
@@ -43,6 +45,8 @@ Pet::Pet(Player* owner, PetType type) :
|
||||
{
|
||||
ASSERT(GetOwner());
|
||||
|
||||
InitializeSummonInfo({ .SummonerGUID = GetOwner()->GetGUID()});
|
||||
|
||||
m_unitTypeMask |= UNIT_MASK_PET;
|
||||
if (type == HUNTER_PET)
|
||||
m_unitTypeMask |= UNIT_MASK_HUNTER_PET;
|
||||
@@ -69,6 +73,11 @@ void Pet::AddToWorld()
|
||||
///- Register the pet for guid lookup
|
||||
GetMap()->GetObjectsStore().Insert<Pet>(GetGUID(), this);
|
||||
Unit::AddToWorld();
|
||||
|
||||
// SummonInfo should always be initialized for pets. Make sure that we will not go any further if this is no longer the case.
|
||||
if (Unit* summoner = ASSERT_NOTNULL(GetSummonInfo())->GetUnitSummoner())
|
||||
summoner->RegisterSummon(GetSummonInfo());
|
||||
|
||||
AIM_Initialize();
|
||||
}
|
||||
|
||||
@@ -89,6 +98,10 @@ void Pet::RemoveFromWorld()
|
||||
///- Remove the pet from the accessor
|
||||
if (IsInWorld())
|
||||
{
|
||||
// SummonInfo should always be initialized for pets. Make sure that we will not go any further if this is no longer the case.
|
||||
if (Unit* summoner = ASSERT_NOTNULL(GetSummonInfo())->GetUnitSummoner())
|
||||
summoner->UnregisterSummon(GetSummonInfo());
|
||||
|
||||
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
||||
Unit::RemoveFromWorld();
|
||||
GetMap()->GetObjectsStore().Remove<Pet>(GetGUID());
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SpellPackets.h"
|
||||
#include "SummonInfo.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Totem.h"
|
||||
#include "Transport.h"
|
||||
@@ -8818,6 +8819,23 @@ uint32 Unit::GetCreatureTypeMask() const
|
||||
return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0;
|
||||
}
|
||||
|
||||
void Unit::RegisterSummon(SummonInfo* summon)
|
||||
{
|
||||
if (!summon)
|
||||
return;
|
||||
|
||||
if (!advstd::ranges::contains(_activeSummons, summon))
|
||||
_activeSummons.push_back(summon);
|
||||
}
|
||||
|
||||
void Unit::UnregisterSummon(SummonInfo* summon)
|
||||
{
|
||||
if (!summon)
|
||||
return;
|
||||
|
||||
std::erase(_activeSummons, summon);
|
||||
}
|
||||
|
||||
void Unit::SetShapeshiftForm(ShapeshiftForm form)
|
||||
{
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_SHAPESHIFT_FORM, form);
|
||||
@@ -9607,6 +9625,9 @@ void Unit::RemoveFromWorld()
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all active summon references. If we are about to switch map instances, we want to make sure that we leave all summons behind so we won't do threadunsafe operations
|
||||
_activeSummons.clear();
|
||||
|
||||
WorldObject::RemoveFromWorld();
|
||||
m_duringRemoveFromWorld = false;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ class Spell;
|
||||
class SpellCastTargets;
|
||||
class SpellHistory;
|
||||
class SpellInfo;
|
||||
class SummonInfo;
|
||||
class Totem;
|
||||
class Transport;
|
||||
class TransportBase;
|
||||
@@ -756,7 +757,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
|
||||
uint32 HasUnitTypeMask(uint32 mask) const { return mask & m_unitTypeMask; }
|
||||
void AddUnitTypeMask(uint32 mask) { m_unitTypeMask |= mask; }
|
||||
bool IsSummon() const { return (m_unitTypeMask & UNIT_MASK_SUMMON) != 0; }
|
||||
virtual bool IsSummon() const { return false; }
|
||||
bool IsMinion() const { return (m_unitTypeMask & UNIT_MASK_MINION) != 0; }
|
||||
bool IsGuardian() const { return (m_unitTypeMask & UNIT_MASK_GUARDIAN) != 0; }
|
||||
bool IsPet() const { return (m_unitTypeMask & UNIT_MASK_PET) != 0; }
|
||||
@@ -1323,6 +1324,11 @@ class TC_GAME_API Unit : public WorldObject
|
||||
std::array<ObjectGuid, MAX_SUMMON_SLOT> m_SummonSlot;
|
||||
std::array<ObjectGuid, MAX_GAMEOBJECT_SLOT> m_ObjectSlot;
|
||||
|
||||
// Registers the SummonInfo API of a summoned creature to allow safely accessing it
|
||||
void RegisterSummon(SummonInfo* summon);
|
||||
// Unregisters the SummonInfo API of a summoned creature so it can no longer be accessed
|
||||
void UnregisterSummon(SummonInfo* summon);
|
||||
|
||||
ShapeshiftForm GetShapeshiftForm() const { return ShapeshiftForm(GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_SHAPESHIFT_FORM)); }
|
||||
void SetShapeshiftForm(ShapeshiftForm form);
|
||||
|
||||
@@ -1819,6 +1825,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
std::unordered_map<MovementChangeType, PlayerMovementPendingChange> m_pendingMovementChanges;
|
||||
|
||||
/* Player Movement fields END*/
|
||||
|
||||
std::vector<SummonInfo*> _activeSummons;
|
||||
};
|
||||
|
||||
namespace Trinity
|
||||
|
||||
Reference in new issue
Block a user