Core/Creatures: moved the initialization of CreatorGUIDs to new summon handling
This commit is contained in:
1 parent
ce55b5ad24
commit
2f9ced6ddc
8 files changed
+72
-42
No files matched your search
@@ -53,6 +53,7 @@
|
|||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
#include "SummonInfo.h"
|
#include "SummonInfo.h"
|
||||||
#include "TemporarySummon.h"
|
#include "TemporarySummon.h"
|
||||||
|
#include "TotemPackets.h"
|
||||||
#include "Transport.h"
|
#include "Transport.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
@@ -317,11 +318,15 @@ void Creature::AddToWorld()
|
|||||||
if (IsVehicle())
|
if (IsVehicle())
|
||||||
GetVehicleKit()->Install();
|
GetVehicleKit()->Install();
|
||||||
|
|
||||||
// If the creature has been summoned, register it for the summoner
|
|
||||||
if (SummonInfo* summonInfo = GetSummonInfo())
|
if (SummonInfo* summonInfo = GetSummonInfo())
|
||||||
|
{
|
||||||
|
// If the creature has been summoned, register it for the summoner
|
||||||
if (Unit* summoner = summonInfo->GetUnitSummoner())
|
if (Unit* summoner = summonInfo->GetUnitSummoner())
|
||||||
summoner->RegisterSummon(summonInfo);
|
summoner->RegisterSummon(summonInfo);
|
||||||
|
|
||||||
|
HandlePostSummonActions();
|
||||||
|
}
|
||||||
|
|
||||||
if (GetZoneScript())
|
if (GetZoneScript())
|
||||||
GetZoneScript()->OnCreatureCreate(this);
|
GetZoneScript()->OnCreatureCreate(this);
|
||||||
}
|
}
|
||||||
@@ -2808,6 +2813,45 @@ bool Creature::IsSummon() const
|
|||||||
return _summonInfo != nullptr;
|
return _summonInfo != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Creature::HandlePostSummonActions()
|
||||||
|
{
|
||||||
|
SummonInfo* summonInfo = ASSERT_NOTNULL(GetSummonInfo());
|
||||||
|
|
||||||
|
if (Unit* summoner = summonInfo->GetUnitSummoner())
|
||||||
|
{
|
||||||
|
SummonPropertiesSlot slot = summonInfo->GetSummonSlot();
|
||||||
|
|
||||||
|
// Controlled summons always set their creator guid, which is being used to display summoner names in their title
|
||||||
|
if (summonInfo->IsControlledBySummoner())
|
||||||
|
SetCreatorGUID(summoner->GetGUID());
|
||||||
|
|
||||||
|
// Totem slot summons always send the TotemCreated packet. Some non-Shaman classes use this
|
||||||
|
// to display summon icons that can be canceled (Consecration, DK ghouls, Wild Mushrooms)
|
||||||
|
switch (slot)
|
||||||
|
{
|
||||||
|
case SummonPropertiesSlot::Totem1:
|
||||||
|
case SummonPropertiesSlot::Totem2:
|
||||||
|
case SummonPropertiesSlot::Totem3:
|
||||||
|
case SummonPropertiesSlot::Totem4:
|
||||||
|
{
|
||||||
|
if (Player* playerSummoner = Object::ToPlayer(summoner))
|
||||||
|
{
|
||||||
|
WorldPackets::Totem::TotemCreated totemCreated;
|
||||||
|
totemCreated.Totem = GetGUID();
|
||||||
|
totemCreated.SpellID = GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||||
|
totemCreated.Duration = summonInfo->GetRemainingDuration().value_or(0ms).count();
|
||||||
|
totemCreated.Slot = AsUnderlyingType(summonInfo->GetSummonSlot()) - 1;
|
||||||
|
|
||||||
|
playerSummoner->SendDirectMessage(totemCreated.Write());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Creature::AllLootRemovedFromCorpse()
|
void Creature::AllLootRemovedFromCorpse()
|
||||||
{
|
{
|
||||||
if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
|
if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
|
||||||
|
|||||||
@@ -430,6 +430,9 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
|||||||
|
|
||||||
bool IsSummon() const override;
|
bool IsSummon() const override;
|
||||||
|
|
||||||
|
// Handles all summon relation actions, such as setting guid values, casting passives and initializing the control status
|
||||||
|
void HandlePostSummonActions();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data = nullptr, uint32 vehId = 0);
|
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data = nullptr, uint32 vehId = 0);
|
||||||
bool InitEntry(uint32 entry, CreatureData const* data = nullptr);
|
bool InitEntry(uint32 entry, CreatureData const* data = nullptr);
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ void SummonInfo::SetUseSummonerFaction(bool set)
|
|||||||
else
|
else
|
||||||
_flags.RemoveFlag(SummonPropertiesFlags::UseSummonerFaction);
|
_flags.RemoveFlag(SummonPropertiesFlags::UseSummonerFaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SummonInfo::IsControlledBySummoner() const
|
bool SummonInfo::IsControlledBySummoner() const
|
||||||
{
|
{
|
||||||
return _control > SummonPropertiesControl::None;
|
return _control > SummonPropertiesControl::None;
|
||||||
|
|||||||
@@ -189,9 +189,6 @@ void TempSummon::InitStats(uint32 duration)
|
|||||||
|
|
||||||
if (m_Properties->Control != SUMMON_CATEGORY_WILD)
|
if (m_Properties->Control != SUMMON_CATEGORY_WILD)
|
||||||
{
|
{
|
||||||
// Creator guid is always set for allied summons
|
|
||||||
SetCreatorGUID(owner->GetGUID());
|
|
||||||
|
|
||||||
// Summons inherit their player summoner's guild data
|
// Summons inherit their player summoner's guild data
|
||||||
if (owner && (owner->IsPlayer() || owner->IsTotem()))
|
if (owner && (owner->IsPlayer() || owner->IsTotem()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,7 +82,6 @@
|
|||||||
#include "SummonInfo.h"
|
#include "SummonInfo.h"
|
||||||
#include "TemporarySummon.h"
|
#include "TemporarySummon.h"
|
||||||
#include "Totem.h"
|
#include "Totem.h"
|
||||||
#include "TotemPackets.h"
|
|
||||||
#include "Transport.h"
|
#include "Transport.h"
|
||||||
#include "UnitAI.h"
|
#include "UnitAI.h"
|
||||||
#include "UpdateFieldFlags.h"
|
#include "UpdateFieldFlags.h"
|
||||||
@@ -5727,6 +5726,16 @@ void Unit::SetOwnerGUID(ObjectGuid owner)
|
|||||||
RemoveFieldNotifyFlag(UF_FLAG_OWNER);
|
RemoveFieldNotifyFlag(UF_FLAG_OWNER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unit* Unit::GetCreator() const
|
||||||
|
{
|
||||||
|
return ObjectAccessor::GetUnit(*this, GetCreatorGUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
Creature* Unit::GetCritter() const
|
||||||
|
{
|
||||||
|
return ObjectAccessor::GetCreature(*this, GetCritterGUID());
|
||||||
|
}
|
||||||
|
|
||||||
Player* Unit::GetControllingPlayer() const
|
Player* Unit::GetControllingPlayer() const
|
||||||
{
|
{
|
||||||
if (ObjectGuid guid = GetCharmerOrOwnerGUID())
|
if (ObjectGuid guid = GetCharmerOrOwnerGUID())
|
||||||
@@ -8840,44 +8849,13 @@ void Unit::RegisterSummon(SummonInfo* summon)
|
|||||||
return;
|
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);
|
uint8 targetSlot = AsUnderlyingType(slot);
|
||||||
|
|
||||||
// Another is occupying the slot. Unsummon that summon first
|
// Another summon is occupying the slot. Unsummon that one first
|
||||||
if (SummonInfo* activeSummon = _slottedSummons[targetSlot])
|
if (SummonInfo* activeSummon = _slottedSummons[targetSlot])
|
||||||
activeSummon->GetSummonedCreature()->DespawnOrUnsummon();
|
activeSummon->GetSummonedCreature()->DespawnOrUnsummon();
|
||||||
|
|
||||||
_slottedSummons[targetSlot] = summon;
|
_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)
|
void Unit::UnregisterSummon(SummonInfo* summon)
|
||||||
|
|||||||
@@ -1078,14 +1078,21 @@ class TC_GAME_API Unit : public WorldObject
|
|||||||
|
|
||||||
ObjectGuid GetOwnerGUID() const override { return GetGuidValue(UNIT_FIELD_SUMMONEDBY); }
|
ObjectGuid GetOwnerGUID() const override { return GetGuidValue(UNIT_FIELD_SUMMONEDBY); }
|
||||||
void SetOwnerGUID(ObjectGuid owner);
|
void SetOwnerGUID(ObjectGuid owner);
|
||||||
|
|
||||||
ObjectGuid GetCreatorGUID() const { return GetGuidValue(UNIT_FIELD_CREATEDBY); }
|
ObjectGuid GetCreatorGUID() const { return GetGuidValue(UNIT_FIELD_CREATEDBY); }
|
||||||
void SetCreatorGUID(ObjectGuid creator) { SetGuidValue(UNIT_FIELD_CREATEDBY, creator); }
|
void SetCreatorGUID(ObjectGuid creator) { SetGuidValue(UNIT_FIELD_CREATEDBY, creator); }
|
||||||
|
Unit* GetCreator() const;
|
||||||
|
|
||||||
ObjectGuid GetMinionGUID() const { return GetGuidValue(UNIT_FIELD_SUMMON); }
|
ObjectGuid GetMinionGUID() const { return GetGuidValue(UNIT_FIELD_SUMMON); }
|
||||||
void SetMinionGUID(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_SUMMON, guid); }
|
void SetMinionGUID(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_SUMMON, guid); }
|
||||||
void SetPetGUID(ObjectGuid guid) { m_SummonSlot[SUMMON_SLOT_PET] = guid; }
|
|
||||||
ObjectGuid GetPetGUID() const { return m_SummonSlot[SUMMON_SLOT_PET]; }
|
ObjectGuid GetPetGUID() const { return m_SummonSlot[SUMMON_SLOT_PET]; }
|
||||||
void SetCritterGUID(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_CRITTER, guid); }
|
void SetPetGUID(ObjectGuid guid) { m_SummonSlot[SUMMON_SLOT_PET] = guid; }
|
||||||
|
|
||||||
ObjectGuid GetCritterGUID() const { return GetGuidValue(UNIT_FIELD_CRITTER); }
|
ObjectGuid GetCritterGUID() const { return GetGuidValue(UNIT_FIELD_CRITTER); }
|
||||||
|
void SetCritterGUID(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_CRITTER, guid); }
|
||||||
|
Creature* GetCritter() const;
|
||||||
|
|
||||||
ObjectGuid GetOwnerOrCreatorGUID() const { return GetOwnerGUID() ? GetOwnerGUID() : GetCreatorGUID(); }
|
ObjectGuid GetOwnerOrCreatorGUID() const { return GetOwnerGUID() ? GetOwnerGUID() : GetCreatorGUID(); }
|
||||||
|
|
||||||
ObjectGuid GetCharmerGUID() const { return GetGuidValue(UNIT_FIELD_CHARMEDBY); }
|
ObjectGuid GetCharmerGUID() const { return GetGuidValue(UNIT_FIELD_CHARMEDBY); }
|
||||||
@@ -1324,7 +1331,7 @@ class TC_GAME_API Unit : public WorldObject
|
|||||||
std::array<ObjectGuid, MAX_SUMMON_SLOT> m_SummonSlot;
|
std::array<ObjectGuid, MAX_SUMMON_SLOT> m_SummonSlot;
|
||||||
std::array<ObjectGuid, MAX_GAMEOBJECT_SLOT> m_ObjectSlot;
|
std::array<ObjectGuid, MAX_GAMEOBJECT_SLOT> m_ObjectSlot;
|
||||||
|
|
||||||
// Registers the SummonInfo API of a summoned creature to allow safely accessing it
|
// Registers the SummonInfo API of a summoned creature to allow to safely access it
|
||||||
void RegisterSummon(SummonInfo* summon);
|
void RegisterSummon(SummonInfo* summon);
|
||||||
// Unregisters the SummonInfo API of a summoned creature so it can no longer be accessed
|
// Unregisters the SummonInfo API of a summoned creature so it can no longer be accessed
|
||||||
void UnregisterSummon(SummonInfo* summon);
|
void UnregisterSummon(SummonInfo* summon);
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public:
|
|||||||
creatureTarget->DespawnOrUnsummon();
|
creatureTarget->DespawnOrUnsummon();
|
||||||
creatureTarget->SetHealth(0); // just for nice GM-mode view
|
creatureTarget->SetHealth(0); // just for nice GM-mode view
|
||||||
|
|
||||||
pet->SetGuidValue(UNIT_FIELD_CREATEDBY, player->GetGUID());
|
pet->SetCreatorGUID(player->GetGUID());
|
||||||
pet->SetFaction(player->GetFaction());
|
pet->SetFaction(player->GetFaction());
|
||||||
|
|
||||||
if (!pet->InitStatsForLevel(creatureTarget->getLevel()))
|
if (!pet->InitStatsForLevel(creatureTarget->getLevel()))
|
||||||
|
|||||||
@@ -2476,7 +2476,7 @@ public:
|
|||||||
if (Creature* injuredStormwindInfantry = caster->FindNearestCreature(NPC_INJURED_STORMWIND_INFANTRY, 5.0f, true))
|
if (Creature* injuredStormwindInfantry = caster->FindNearestCreature(NPC_INJURED_STORMWIND_INFANTRY, 5.0f, true))
|
||||||
{
|
{
|
||||||
injuredStormwindInfantry->SetCreatorGUID(caster->GetGUID());
|
injuredStormwindInfantry->SetCreatorGUID(caster->GetGUID());
|
||||||
injuredStormwindInfantry->CastSpell(injuredStormwindInfantry, SPELL_RENEWED_LIFE, true);
|
injuredStormwindInfantry->CastSpell(injuredStormwindInfantry, SPELL_RENEWED_LIFE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user