TrinityCore
Totem.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Totem.h"
19#include "Group.h"
20#include "Log.h"
21#include "Map.h"
22#include "Player.h"
23#include "SmartEnum.h"
24#include "SpellHistory.h"
25#include "SpellInfo.h"
26#include "SpellMgr.h"
27#include "TotemPackets.h"
28
29Totem::Totem(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner, false), m_type(TOTEM_PASSIVE), m_duration(0ms)
30{
32}
33
35{
36 if (!GetOwner()->IsAlive() || !IsAlive())
37 {
38 UnSummon(); // remove self
39 return;
40 }
41
42 if (m_duration <= Milliseconds(diff))
43 {
44 UnSummon(); // remove self
45 return;
46 }
47
48 m_duration -= Milliseconds(diff);
49
50 Creature::Update(diff);
51}
52
53void Totem::InitStats(WorldObject* summoner, Milliseconds duration)
54{
55 // client requires SMSG_TOTEM_CREATED to be sent before adding to world and before removing old totem
56 if (Player* owner = GetOwner()->ToPlayer())
57 {
58 int32 slot = m_Properties->Slot;
59 if (slot == SUMMON_SLOT_ANY_TOTEM)
60 slot = FindUsableTotemSlot(owner);
61
62 if (slot >= SUMMON_SLOT_TOTEM && slot < MAX_TOTEM_SLOT)
63 {
65 data.Totem = GetGUID();
66 data.Slot = slot - SUMMON_SLOT_TOTEM;
67 data.Duration = duration;
68 data.SpellID = m_unitData->CreatedBySpell;
69 owner->SendDirectMessage(data.Write());
70 }
71
72 // set display id depending on caster's race
73 if (uint32 totemDisplayId = sSpellMgr->GetModelForTotem(m_unitData->CreatedBySpell, owner->GetRace()))
74 SetDisplayId(totemDisplayId);
75 else
76 TC_LOG_DEBUG("misc", "Totem with entry {}, owned by player {}, does not have a specialized model for spell {} and race {}. Set to default.",
77 GetEntry(), owner->GetGUID().ToString(), *m_unitData->CreatedBySpell, EnumUtils::ToTitle(Races(owner->GetRace())));
78 }
79
80 Minion::InitStats(summoner, duration);
81
82 // Get spell cast by totem
83 if (SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(GetSpell(), GetMap()->GetDifficultyID()))
84 if (totemSpell->CalcCastTime()) // If spell has cast time -> its an active totem
86
87 m_duration = duration;
88}
89
90void Totem::InitSummon(WorldObject* /*summoner*/)
91{
92 if (m_type == TOTEM_PASSIVE && GetSpell())
93 CastSpell(this, GetSpell(), true);
94
95 // Some totems can have both instant effect and passive spell
96 if (GetSpell(1))
97 CastSpell(this, GetSpell(1), true);
98}
99
101{
102 if (msTime)
103 {
105 return;
106 }
107
108 CombatStop();
110
111 // clear owner's totem slot
112 for (uint8 i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
113 {
114 if (GetOwner()->m_SummonSlot[i] == GetGUID())
115 {
116 GetOwner()->m_SummonSlot[i].Clear();
117 break;
118 }
119 }
120
122
123 // remove aura all party members too
124 if (Player* owner = GetOwner()->ToPlayer())
125 {
126 owner->SendAutoRepeatCancel(this);
127
128 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(m_unitData->CreatedBySpell, GetMap()->GetDifficultyID()))
129 GetSpellHistory()->SendCooldownEvent(spell, 0, nullptr, false);
130
131 if (Group* group = owner->GetGroup())
132 {
133 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
134 {
135 Player* target = itr->GetSource();
136 if (target && target->IsInMap(owner) && group->SameSubGroup(owner, target))
138 }
139 }
140 }
141
143}
144
145bool Totem::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, WorldObject const* caster,
146 bool requireImmunityPurgesEffectAttribute /*= false*/) const
147{
148 // immune to all positive spells, except of stoneclaw totem absorb and sentry totem bind sight
149 // totems positive spells have unit_caster target
150 if (spellEffectInfo.Effect != SPELL_EFFECT_DUMMY &&
151 spellEffectInfo.Effect != SPELL_EFFECT_SCRIPT_EFFECT &&
152 spellInfo->IsPositive() && spellEffectInfo.TargetA.GetTarget() != TARGET_UNIT_CASTER &&
153 spellEffectInfo.TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
154 return true;
155
156 switch (spellEffectInfo.ApplyAuraName)
157 {
162 return true;
163 default:
164 break;
165 }
166
167 return Creature::IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute);
168}
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
Races
Definition: RaceMask.h:26
@ TARGET_UNIT_CASTER
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SUMMON_SLOT_ANY_TOTEM
@ SUMMON_SLOT_TOTEM
#define MAX_TOTEM_SLOT
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_TRANSFORM
@ SPELL_AURA_PERIODIC_LEECH
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:83
#define sSpellMgr
Definition: SpellMgr.h:849
@ TOTEM_ACTIVE
Definition: Totem.h:26
@ TOTEM_PASSIVE
Definition: Totem.h:25
@ UNIT_MASK_TOTEM
Definition: Unit.h:353
void Update(uint32 time) override
Definition: Creature.cpp:709
bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const override
Definition: Creature.cpp:2467
void SetDisplayId(uint32 displayId, bool setNative=false) override
Definition: Creature.cpp:3402
static char const * ToTitle(Enum value)
Definition: SmartEnum.h:123
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
GroupReference * next()
Definition: Group.h:197
Unit * GetOwner() const
void InitStats(WorldObject *summoner, Milliseconds duration) override
Player * ToPlayer()
Definition: Object.h:215
ObjectGuid const & GetGUID() const
Definition: Object.h:160
uint32 GetEntry() const
Definition: Object.h:161
AuraType ApplyAuraName
Definition: SpellInfo.h:219
SpellEffectName Effect
Definition: SpellInfo.h:218
SpellImplicitTargetInfo TargetA
Definition: SpellInfo.h:231
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool startCooldown=true)
SpellTargetCheckTypes GetCheckType() const
Definition: SpellInfo.cpp:95
Targets GetTarget() const
Definition: SpellInfo.cpp:132
bool IsPositive() const
Definition: SpellInfo.cpp:1709
std::ptrdiff_t FindUsableTotemSlot(Unit const *summoner) const
SummonPropertiesEntry const *const m_Properties
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:100
uint32 GetSpell(uint8 slot=0) const
Definition: Totem.h:39
void InitSummon(WorldObject *summoner) override
Definition: Totem.cpp:90
Milliseconds m_duration
Definition: Totem.h:57
void Update(uint32 diff) override
Definition: Totem.cpp:34
void InitStats(WorldObject *summoner, Milliseconds duration) override
Definition: Totem.cpp:53
TotemType m_type
Definition: Totem.h:56
bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const override
Definition: Totem.cpp:145
Totem(SummonPropertiesEntry const *properties, Unit *owner)
Definition: Totem.cpp:29
Definition: Unit.h:627
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition: Unit.cpp:5827
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1814
std::array< ObjectGuid, MAX_SUMMON_SLOT > m_SummonSlot
Definition: Unit.h:1460
bool IsAlive() const
Definition: Unit.h:1164
uint32 m_unitTypeMask
Definition: Unit.h:1913
SpellHistory * GetSpellHistory()
Definition: Unit.h:1457
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
Map * GetMap() const
Definition: Object.h:624
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
void AddObjectToRemoveList()
Definition: Object.cpp:1824
EventProcessor m_Events
Definition: Object.h:777
bool IsInMap(WorldObject const *obj) const
Definition: Object.cpp:1115
WorldPackets::Duration< Milliseconds, int32 > Duration
Definition: TotemPackets.h:49
WorldPacket const * Write() override