Core/Creatures: moved replacement of old summons and sending of SMSG_TOTEM_CREATED to new SummonInfo API and
This commit is contained in:
1 parent
ec1ab2a5e7
commit
ce55b5ad24
7 files changed
+82
-27
No files matched your search
@@ -318,9 +318,9 @@ void Creature::AddToWorld()
|
||||
GetVehicleKit()->Install();
|
||||
|
||||
// If the creature has been summoned, register it for the summoner
|
||||
if (IsSummon())
|
||||
if (Unit* summoner = GetSummonInfo()->GetUnitSummoner())
|
||||
summoner->RegisterSummon(GetSummonInfo());
|
||||
if (SummonInfo* summonInfo = GetSummonInfo())
|
||||
if (Unit* summoner = summonInfo->GetUnitSummoner())
|
||||
summoner->RegisterSummon(summonInfo);
|
||||
|
||||
if (GetZoneScript())
|
||||
GetZoneScript()->OnCreatureCreate(this);
|
||||
@@ -332,9 +332,9 @@ 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 (SummonInfo* summonInfo = GetSummonInfo())
|
||||
if (Unit* summoner = summonInfo->GetUnitSummoner())
|
||||
summoner->UnregisterSummon(summonInfo);
|
||||
|
||||
if (GetZoneScript())
|
||||
GetZoneScript()->OnCreatureRemove(this);
|
||||
|
||||
@@ -158,3 +158,8 @@ bool SummonInfo::IsControlledBySummoner() const
|
||||
{
|
||||
return _control > SummonPropertiesControl::None;
|
||||
}
|
||||
|
||||
SummonPropertiesSlot SummonInfo::GetSummonSlot() const
|
||||
{
|
||||
return _summonSlot;
|
||||
}
|
||||
@@ -77,6 +77,8 @@ public:
|
||||
void SetUseSummonerFaction(bool set);
|
||||
// Returns true when the summon is either a Guardian, Pet, Vehicle or Possessed summon
|
||||
bool IsControlledBySummoner() const;
|
||||
// Returns the summon slot that the summon is going to be stored in
|
||||
SummonPropertiesSlot GetSummonSlot() const;
|
||||
|
||||
private:
|
||||
Creature* _summonedCreature;
|
||||
|
||||
@@ -184,12 +184,6 @@ void TempSummon::InitStats(uint32 duration)
|
||||
int32 slot = m_Properties->Slot;
|
||||
if (slot > 0)
|
||||
{
|
||||
if (owner->m_SummonSlot[slot] && owner->m_SummonSlot[slot] != GetGUID())
|
||||
{
|
||||
Creature* oldSummon = GetMap()->GetCreature(owner->m_SummonSlot[slot]);
|
||||
if (oldSummon && oldSummon->IsSummon())
|
||||
oldSummon->ToTempSummon()->UnSummon();
|
||||
}
|
||||
owner->m_SummonSlot[slot] = GetGUID();
|
||||
}
|
||||
|
||||
|
||||
@@ -53,17 +53,8 @@ void Totem::Update(uint32 time)
|
||||
void Totem::InitStats(uint32 duration)
|
||||
{
|
||||
// client requires SMSG_TOTEM_CREATED to be sent before adding to world and before removing old totem
|
||||
if (GetOwner()->GetTypeId() == TYPEID_PLAYER
|
||||
&& m_Properties->Slot >= SUMMON_SLOT_TOTEM_FIRE
|
||||
&& m_Properties->Slot < MAX_TOTEM_SLOT)
|
||||
if (GetOwner()->GetTypeId() == TYPEID_PLAYER && m_Properties->Slot >= SUMMON_SLOT_TOTEM_FIRE && m_Properties->Slot < MAX_TOTEM_SLOT)
|
||||
{
|
||||
WorldPacket data(SMSG_TOTEM_CREATED, 1 + 8 + 4 + 4);
|
||||
data << uint8(m_Properties->Slot - 1);
|
||||
data << uint64(GetGUID());
|
||||
data << uint32(duration);
|
||||
data << uint32(GetUInt32Value(UNIT_CREATED_BY_SPELL));
|
||||
GetOwner()->ToPlayer()->SendDirectMessage(&data);
|
||||
|
||||
// set display id depending on caster's race
|
||||
SetDisplayId(GetOwner()->GetModelForTotem(PlayerTotemType(m_Properties->ID)));
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "SummonInfo.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Totem.h"
|
||||
#include "TotemPackets.h"
|
||||
#include "Transport.h"
|
||||
#include "UnitAI.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
@@ -379,6 +380,8 @@ Unit::Unit(bool isWorldObject) :
|
||||
|
||||
_oldFactionId = 0;
|
||||
_isWalkingBeforeCharm = false;
|
||||
|
||||
_slottedSummons.resize(AsUnderlyingType(SummonPropertiesSlot::Max), nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -8824,8 +8827,57 @@ void Unit::RegisterSummon(SummonInfo* summon)
|
||||
if (!summon)
|
||||
return;
|
||||
|
||||
if (!advstd::ranges::contains(_activeSummons, summon))
|
||||
_activeSummons.push_back(summon);
|
||||
SummonPropertiesSlot slot = summon->GetSummonSlot();
|
||||
|
||||
// Wild Summons usually don't need any tracking but some do have certain SummonPropertiesFlags which
|
||||
// causes them to interact with the summoner in some way (e.g. despawning when the summoner died)
|
||||
if (slot == SummonPropertiesSlot::None)
|
||||
{
|
||||
if (advstd::ranges::contains(_wildSummons, summon))
|
||||
return;
|
||||
|
||||
_wildSummons.push_back(summon);
|
||||
return;
|
||||
}
|
||||
|
||||
// Select any available totem slot if empty, otherwise they just replace the oldest summon of the same entry
|
||||
if (slot == SummonPropertiesSlot::AnyAvailableTotem)
|
||||
{
|
||||
// @Todo
|
||||
slot = SummonPropertiesSlot::Totem1;
|
||||
}
|
||||
|
||||
uint8 targetSlot = AsUnderlyingType(slot);
|
||||
|
||||
// Another is occupying the slot. Unsummon that summon first
|
||||
if (SummonInfo* activeSummon = _slottedSummons[targetSlot])
|
||||
activeSummon->GetSummonedCreature()->DespawnOrUnsummon();
|
||||
|
||||
_slottedSummons[targetSlot] = summon;
|
||||
|
||||
switch (slot)
|
||||
{
|
||||
case SummonPropertiesSlot::Totem1:
|
||||
case SummonPropertiesSlot::Totem2:
|
||||
case SummonPropertiesSlot::Totem3:
|
||||
case SummonPropertiesSlot::Totem4:
|
||||
{
|
||||
Creature const* summonedCreature = summon->GetSummonedCreature();
|
||||
if (Player* playerSummoner = Object::ToPlayer(summon->GetUnitSummoner()))
|
||||
{
|
||||
WorldPackets::Totem::TotemCreated totemCreated;
|
||||
totemCreated.Totem = summonedCreature->GetGUID();
|
||||
totemCreated.SpellID = summonedCreature->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
totemCreated.Duration = summon->GetRemainingDuration().value_or(0ms).count();
|
||||
totemCreated.Slot = AsUnderlyingType(summon->GetSummonSlot()) - 1;
|
||||
|
||||
playerSummoner->SendDirectMessage(totemCreated.Write());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::UnregisterSummon(SummonInfo* summon)
|
||||
@@ -8833,7 +8885,15 @@ void Unit::UnregisterSummon(SummonInfo* summon)
|
||||
if (!summon)
|
||||
return;
|
||||
|
||||
std::erase(_activeSummons, summon);
|
||||
SummonPropertiesSlot slot = summon->GetSummonSlot();
|
||||
if (slot == SummonPropertiesSlot::None)
|
||||
{
|
||||
std::erase(_wildSummons, summon);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 targetSlot = AsUnderlyingType(slot);
|
||||
_slottedSummons[targetSlot] = nullptr;
|
||||
}
|
||||
|
||||
void Unit::SetShapeshiftForm(ShapeshiftForm form)
|
||||
@@ -9626,7 +9686,8 @@ 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();
|
||||
_wildSummons.clear();
|
||||
_slottedSummons.clear();
|
||||
|
||||
WorldObject::RemoveFromWorld();
|
||||
m_duringRemoveFromWorld = false;
|
||||
|
||||
@@ -1826,7 +1826,9 @@ class TC_GAME_API Unit : public WorldObject
|
||||
|
||||
/* Player Movement fields END*/
|
||||
|
||||
std::vector<SummonInfo*> _activeSummons;
|
||||
// SummonInfo slot handling
|
||||
std::vector<SummonInfo*> _wildSummons;
|
||||
std::vector<SummonInfo*> _slottedSummons;
|
||||
};
|
||||
|
||||
namespace Trinity
|
||||
|
||||
Reference in new issue
Block a user