Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Unit.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Battlefield.h"
7#include "BattlefieldMgr.h"
8#include "Battleground.h"
9#include "CellImpl.h"
10#include "CombatPackets.h"
11#include "Common.h"
12#include "ConditionMgr.h"
13#include "Creature.h"
14#include "CreatureAI.h"
15#include "CreatureAIImpl.h"
16#include "CreatureGroups.h"
17#include "Formulas.h"
18#include "GridNotifiersImpl.h"
19#include "Group.h"
20#include "InstanceSaveMgr.h"
21#include "InstanceScript.h"
22#include "Log.h"
23#include "Map.h"
24#include "MapManager.h"
25#include "MovementStructures.h"
26#include "MoveSpline.h"
27#include "ObjectAccessor.h"
28#include "ObjectMgr.h"
29#include "Opcodes.h"
30#include "OutdoorPvP.h"
31#include "PassiveAI.h"
32#include "Pet.h"
33#include "PetAI.h"
34#include "PetTransportSupport.h"
35#include "Player.h"
36#include "QuestDef.h"
37#include "ReputationMgr.h"
38#include "Spell.h"
39#include "SpellAuraEffects.h"
40#include "SpellAuras.h"
41#include "SpellInfo.h"
42#include "SpellMgr.h"
43#include "TemporarySummon.h"
44#include "Totem.h"
45#include "Transport.h"
46#include "Unit.h"
47#include "UpdateFieldFlags.h"
48#include "Util.h"
49#include "Vehicle.h"
50#include "World.h"
51#include "WorldPacket.h"
52#include "WorldSession.h"
53
54#include <math.h>
55
57{
58 2.5f, // MOVE_WALK
59 7.0f, // MOVE_RUN
60 4.5f, // MOVE_RUN_BACK
61 4.722222f, // MOVE_SWIM
62 2.5f, // MOVE_SWIM_BACK
63 3.141594f, // MOVE_TURN_RATE
64 7.0f, // MOVE_FLIGHT
65 4.5f, // MOVE_FLIGHT_BACK
66 3.14f // MOVE_PITCH_RATE
67};
68
70{
71 2.5f, // MOVE_WALK
72 7.0f, // MOVE_RUN
73 4.5f, // MOVE_RUN_BACK
74 4.722222f, // MOVE_SWIM
75 2.5f, // MOVE_SWIM_BACK
76 3.141594f, // MOVE_TURN_RATE
77 7.0f, // MOVE_FLIGHT
78 4.5f, // MOVE_FLIGHT_BACK
79 3.14f // MOVE_PITCH_RATE
80};
81
82DamageInfo::DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType)
83 : m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask),
85{
86 m_absorb = 0;
87 m_resist = 0;
88 m_block = 0;
89}
91 : m_attacker(dmgInfo.attacker), m_victim(dmgInfo.target), m_damage(dmgInfo.damage), m_spellInfo(NULL), m_schoolMask(SpellSchoolMask(dmgInfo.damageSchoolMask)),
92 m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType)
93{
94 m_absorb = 0;
95 m_resist = 0;
96 m_block = 0;
97}
98
100{
101 amount = std::min(amount, int32(GetDamage()));
102 m_damage += amount;
103}
104
106{
107 amount = std::min(amount, GetDamage());
108 m_absorb += amount;
109 m_damage -= amount;
110}
111
113{
114 amount = std::min(amount, GetDamage());
115 m_resist += amount;
116 m_damage -= amount;
117}
118
120{
121 amount = std::min(amount, GetDamage());
122 m_block += amount;
123 m_damage -= amount;
124}
125
126ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget,
127 uint32 typeMask, uint32 spellTypeMask,
128 uint32 spellPhaseMask, uint32 hitMask,
129 Spell* spell, DamageInfo* damageInfo,
130 HealInfo* healInfo) :
131 _actor(actor), _actionTarget(actionTarget), _procTarget(procTarget),
132 _typeMask(typeMask), _spellTypeMask(spellTypeMask),
133 _spellPhaseMask(spellPhaseMask), _hitMask(hitMask), _spell(spell),
134 _damageInfo(damageInfo), _healInfo(healInfo)
135{ }
136
137// we can disable this warning for this since it only
138// causes undefined behavior when passed to the base class constructor
139#ifdef _MSC_VER
140#pragma warning(disable:4355)
141#endif
142Unit::Unit(bool isWorldObject) :
143 WorldObject(isWorldObject), m_movedPlayer(NULL), m_lastSanctuaryTime(0),
144 IsAIEnabled(false), NeedChangeAI(false), LastCharmerGUID(0),
145 m_ControlledByPlayer(false), movespline(std::make_unique<Movement::MoveSpline>()),
146 i_AI(NULL), i_disabledAI(NULL), m_AutoRepeatFirstCast(false), m_procDeep(0),
150{
151#ifdef _MSC_VER
152#pragma warning(default:4355)
153#endif
156
158
165
166 m_extraAttacks = 0;
167 m_canDualWield = false;
168
170
171 m_state = 0;
173
174 for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
175 m_currentSpells[i] = NULL;
176
177 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
178 m_SummonSlot[i] = 0;
179
180 for (uint8 i = 0; i < MAX_GAMEOBJECT_SLOT; ++i)
181 m_ObjectSlot[i] = 0;
182
185
186 m_interruptMask = 0;
187 m_transform = 0;
188 m_canModifyStats = false;
189
190 for (uint8 i = 0; i < MAX_SPELL_IMMUNITY; ++i)
191 m_spellImmune[i].clear();
192
193 for (uint8 i = 0; i < UNIT_MOD_END; ++i)
194 {
199 }
200 // implement 50% base damage from offhand
202
204 for (uint8 i = 0; i < maxAttackType; ++i)
205 {
208 }
209
210 for (uint8 i = 0; i < MAX_STATS; ++i)
211 m_createStats[i] = 0.0f;
212
213 m_attacking = NULL;
214 m_modMeleeHitChance = 0.0f;
216 m_modSpellHitChance = 0.0f;
218
219 m_CombatTimer = 0;
220
221 for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
222 m_threatModifier[i] = 1.0f;
223
224 m_isSorted = true;
225
226 for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i)
227 m_speed_rate[i] = 1.0f;
228
229 m_charmInfo = NULL;
230
232
233 // remove aurastates allowing special moves
234 for (uint8 i = 0; i < MAX_REACTIVE; ++i)
235 m_reactiveTimer[i] = 0;
236
237 m_cleanupDone = false;
239
241
242 _lastLiquid = NULL;
243 _isWalkingBeforeCharm = false;
244}
245
247// Methods of class GlobalCooldownMgr
249{
250 GlobalCooldownList::const_iterator itr = m_GlobalCooldowns.find(spellInfo->StartRecoveryCategory);
251 return itr != m_GlobalCooldowns.end() && itr->second.duration && getMSTimeDiff(itr->second.cast_time, getMSTime()) < itr->second.duration;
252}
253
258
260{
261 m_GlobalCooldowns[spellInfo->StartRecoveryCategory].duration = 0;
262}
263
265// Methods of class Unit
267{
268 // set current spells as deletable
269 for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
270 if (m_currentSpells[i])
271 {
272 m_currentSpells[i]->SetReferencedFromCurrent(false);
273 m_currentSpells[i] = NULL;
274 }
275
277
278 delete m_charmInfo;
279 movespline.reset();
280
283 ASSERT(m_attackers.empty());
284 ASSERT(m_sharedVision.empty());
285 ASSERT(m_Controlled.empty());
286 ASSERT(m_appliedAuras.empty());
287 ASSERT(m_ownedAuras.empty());
288 ASSERT(m_removedAuras.empty());
289 ASSERT(m_gameObj.empty());
290 ASSERT(m_dynObj.empty());
291}
292
294{
295 // WARNING! Order of execution here is important, do not change.
296 // Spells must be processed with event system BEFORE they go to _UpdateSpells.
297 // Or else we may have some SPELL_STATE_FINISHED spells stalled in pointers, that is bad.
298 m_Events.Update(p_time);
299
300 if (!IsInWorld())
301 return;
302
303 _UpdateSpells(p_time);
304
305 // If this is set during update SetCantProc(false) call is missing somewhere in the code
306 // Having this would prevent spells from being proced, so let's crash
308
309 if (CanHaveThreatList() && getThreatManager().isNeedUpdateToClient(p_time))
311
312 // update combat timer only for players and pets (only pets with PetAI)
314 {
315 // Check UNIT_STATE_MELEE_ATTACKING or UNIT_STATE_CHASE (without UNIT_STATE_FOLLOW in this case) so pets can reach far away
316 // targets without stopping half way there and running off.
317 // These flags are reset after target dies or another command is given.
318 if (m_HostileRefManager.isEmpty())
319 {
320 // m_CombatTimer set at aura start and it will be freeze until aura removing
321 if (m_CombatTimer <= p_time)
323 else
324 m_CombatTimer -= p_time;
325 }
326 }
327
328 // not implemented before 3.0.2
330 setAttackTimer(WeaponAttackType::BASE_ATTACK, (p_time >= base_att ? 0 : base_att - p_time));
332 setAttackTimer(WeaponAttackType::RANGED_ATTACK, (p_time >= ranged_att ? 0 : ranged_att - p_time));
334 setAttackTimer(WeaponAttackType::OFF_ATTACK, (p_time >= off_att ? 0 : off_att - p_time));
335
336 // update abilities available only for fraction of time
337 UpdateReactives(p_time);
338
339 if (IsAlive())
340 {
344 }
345
346 UpdateSplineMovement(p_time);
347 i_motionMaster.UpdateMotion(p_time);
348}
349
351{
354 else
355 return m_canDualWield;
356}
357
358void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath, bool forceDestination)
359{
360 Movement::MoveSplineInit init(this);
361 init.MoveTo(x, y, z, generatePath, forceDestination);
362 init.SetVelocity(speed);
363 init.Launch();
364}
365
367{
368 if (movespline->Finalized())
369 return;
370
371 movespline->updateState(t_diff);
372 bool arrived = movespline->Finalized();
373
374 if (arrived)
376
377 m_movesplineTimer.Update(t_diff);
378 if (m_movesplineTimer.Passed() || arrived)
380}
381
383{
384 uint32 const positionUpdateDelay = 400;
385
386 m_movesplineTimer.Reset(positionUpdateDelay);
387 Movement::Location loc = movespline->ComputePosition();
388 bool const hasTransport = GetTransGUID() != 0;
389 if (hasTransport)
390 {
391 Position& pos = m_movementInfo.transport.pos;
392 pos.m_positionX = loc.x;
393 pos.m_positionY = loc.y;
394 pos.m_positionZ = loc.z;
396
397 if (TransportBase* transport = GetDirectTransport())
398 transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
399 }
400
403
404 // Ground spline paths can interpolate below terrain on hills; snap server position to vmap.
406 {
407 Creature const* creature = ToCreature();
408 CreatureTemplate const* cInfo = creature->GetCreatureTemplate();
409 if (cInfo && !(cInfo->InhabitType & INHABIT_AIR) && !creature->CanFly()
411 {
412 float ground = GetMap()->GetHeight(GetPhaseMask(), loc.x, loc.y, loc.z + 5.0f, true);
413 float floor = GetMap()->GetHeight(GetPhaseMask(), loc.x, loc.y, loc.z, true);
414 if (ground > INVALID_HEIGHT || floor > INVALID_HEIGHT)
415 {
416 float const terrainZ = (ground > INVALID_HEIGHT && floor > INVALID_HEIGHT)
417 ? (fabs(ground - loc.z) <= fabs(floor - loc.z) ? ground : floor)
418 : (floor > INVALID_HEIGHT ? floor : ground);
419 if (loc.z < terrainZ)
420 loc.z = terrainZ;
421 else
422 UpdateAllowedPositionZ(loc.x, loc.y, loc.z);
423 }
424 }
425 }
426
427 UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
428}
429
431{
432 m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD);
433 movespline->_Interrupt();
434}
435
440
442{
444 return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH;
445}
446
447bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const
448{
449 if (!obj || !IsInMap(obj) || !InSamePhase(obj))
450 return false;
451
452 float dx = GetPositionX() - obj->GetPositionX();
453 float dy = GetPositionY() - obj->GetPositionY();
454 float dz = GetPositionZ() - obj->GetPositionZ();
455 float distsq = dx * dx + dy * dy + dz * dz;
456
457 float sizefactor = GetCombatReach() + obj->GetCombatReach();
458 float maxdist = dist2compare + sizefactor;
459
460 return distsq < maxdist * maxdist;
461}
462
463bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const
464{
465 if (!obj || !IsInMap(obj) || !InSamePhase(obj))
466 return false;
467
468 float dx = GetPositionX() - obj->GetPositionX();
469 float dy = GetPositionY() - obj->GetPositionY();
470 float dz = GetPositionZ() - obj->GetPositionZ();
471 float distsq = dx * dx + dy * dy + dz * dz;
472
473 float sizefactor = GetMeleeReach() + obj->GetMeleeReach();
474 float maxdist = dist + sizefactor;
475
476 return distsq < maxdist * maxdist;
477}
478
479void Unit::GetRandomContactPoint(const Unit* obj, float& x, float& y, float& z, float distance2dMin, float distance2dMax) const
480{
481 float combat_reach = GetCombatReach();
482 if (combat_reach < 0.1f) // sometimes bugged for players
483 combat_reach = DEFAULT_COMBAT_REACH;
484
485 uint32 attacker_number = getAttackers().size();
486 if (attacker_number > 0)
487 --attacker_number;
488 GetNearPoint(obj, x, y, z, obj->GetCombatReach(), distance2dMin + (distance2dMax - distance2dMin) * (float)rand_norm(),
489 GetAngle(obj) + (attacker_number ? (static_cast<float>(M_PI / 2) - static_cast<float>(M_PI) * (float)rand_norm()) * float(attacker_number) / combat_reach * 0.3f : 0));
490}
491
493{
494 VisibleAuraMap::const_iterator itr = m_visibleAuras.find(slot);
495 if (itr != m_visibleAuras.end())
496 return itr->second;
497 return 0;
498}
499
501{
502 m_visibleAuras[slot] = aur;
503 UpdateAuraForGroup(slot);
504}
505
507{
508 m_visibleAuras.erase(slot);
509 UpdateAuraForGroup(slot);
510}
511
513{
514 m_interruptMask = 0;
515 for (AuraApplicationList::const_iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
516 m_interruptMask |= (*i)->GetBase()->GetSpellInfo()->AuraInterruptFlags;
517
519 if (spell->getState() == SPELL_STATE_CASTING)
520 m_interruptMask |= spell->m_spellInfo->ChannelInterruptFlags;
521}
522
523bool Unit::HasVisionObscured(Unit const* target) const
524{
525 if (!target)
526 return false;
527
530
531 if (!casterStateAuras.empty())
532 {
533 for (Unit::AuraEffectList::const_iterator i = casterStateAuras.begin(); i != casterStateAuras.end(); ++i)
534 {
535 // caster is friendly to Aura caster => No restrictions
536 if ((*i)->GetCaster() && IsFriendlyTo((*i)->GetCaster()))
537 continue;
538
539 bool failCast = true;
540 for (Unit::AuraEffectList::iterator j = targetStateAuras.begin(); j != targetStateAuras.end();)
541 {
542 if (((*i)->GetId() == (*j)->GetId()) && ((*i)->GetCasterGUID() == (*i)->GetCasterGUID()))
543 {
544 failCast = false;
545 j = targetStateAuras.erase(j);
546 break;
547 }
548 else
549 ++j;
550 }
551
552 if (failCast) // caster has some aura that target not
553 return true;
554 }
555 }
556
557 if (!targetStateAuras.empty()) // target has some aura that caster not
558 {
559 for (Unit::AuraEffectList::const_iterator i = targetStateAuras.begin(); i != targetStateAuras.end(); ++i)
560 if (!(*i)->GetCaster() || !IsFriendlyTo((*i)->GetCaster()))
561 return true;
562 }
563
564 return false;
565}
566
567bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const
568{
569 if (!HasAuraType(auraType))
570 return false;
571 AuraEffectList const& auras = GetAuraEffectsByType(auraType);
572 for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
573 if (SpellInfo const* iterSpellProto = (*itr)->GetSpellInfo())
574 if (iterSpellProto->SpellFamilyName == familyName && iterSpellProto->SpellFamilyFlags[0] & familyFlags)
575 return true;
576 return false;
577}
578
580{
581 AuraEffectList const& auras = GetAuraEffectsByType(type);
582 for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
583 if ((!excludeAura || excludeAura != (*itr)->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction
584 ((*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE))
585 return true;
586 return false;
587}
588
589bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) const
590{
591 uint32 excludeAura = 0;
592 if (Spell* currentChanneledSpell = excludeCasterChannel ? excludeCasterChannel->GetCurrentSpell(CURRENT_CHANNELED_SPELL) : NULL)
593 excludeAura = currentChanneledSpell->GetSpellInfo()->Id; //Avoid self interrupt of channeled Crowd Control spells like Seduction
594
601}
602
604{
605 WorldPacket data(SMSG_ATTACK_START, 8 + 8);
606
607 ObjectGuid attackerGuid = victim->GetGUID();
608 ObjectGuid victimGuid = GetGUID();
609
610 data.WriteBit(victimGuid[7]);
611 data.WriteBit(attackerGuid[7]);
612 data.WriteBit(attackerGuid[3]);
613 data.WriteBit(victimGuid[3]);
614 data.WriteBit(victimGuid[5]);
615 data.WriteBit(attackerGuid[4]);
616 data.WriteBit(attackerGuid[1]);
617 data.WriteBit(victimGuid[4]);
618 data.WriteBit(attackerGuid[0]);
619 data.WriteBit(victimGuid[6]);
620 data.WriteBit(attackerGuid[5]);
621 data.WriteBit(victimGuid[2]);
622 data.WriteBit(attackerGuid[6]);
623 data.WriteBit(victimGuid[1]);
624 data.WriteBit(attackerGuid[2]);
625 data.WriteBit(victimGuid[0]);
626
627 data.WriteByteSeq(attackerGuid[5]);
628 data.WriteByteSeq(attackerGuid[0]);
629 data.WriteByteSeq(victimGuid[5]);
630 data.WriteByteSeq(attackerGuid[4]);
631 data.WriteByteSeq(attackerGuid[6]);
632 data.WriteByteSeq(victimGuid[6]);
633 data.WriteByteSeq(victimGuid[1]);
634 data.WriteByteSeq(victimGuid[0]);
635 data.WriteByteSeq(attackerGuid[7]);
636 data.WriteByteSeq(victimGuid[4]);
637 data.WriteByteSeq(attackerGuid[2]);
638 data.WriteByteSeq(victimGuid[3]);
639 data.WriteByteSeq(victimGuid[7]);
640 data.WriteByteSeq(victimGuid[2]);
641 data.WriteByteSeq(attackerGuid[3]);
642 data.WriteByteSeq(attackerGuid[1]);
643
644 SendMessageToSet(&data, true);
645}
646
648{
649 WorldPacket data(SMSG_ATTACKSTOP, 8 + 8);
650
651 ObjectGuid attackerGuid = GetGUID();
652 ObjectGuid victimGuid = victim ? victim->GetGUID() : 0;
653
654 data.WriteBit(victimGuid[5]);
655 data.WriteBit(victimGuid[6]);
656 data.WriteBit(attackerGuid[3]);
657 data.WriteBit(attackerGuid[6]);
658 data.WriteBit(attackerGuid[7]);
659 data.WriteBit(attackerGuid[2]);
660 data.WriteBit(attackerGuid[5]);
661 data.WriteBit(victimGuid[4]);
663 victim != NULL, victim && victim->isDead());
664 data.WriteBit(victimIsDead);
665 data.WriteBit(victimGuid[3]);
666 data.WriteBit(victimGuid[0]);
667 data.WriteBit(victimGuid[2]);
668 data.WriteBit(victimGuid[7]);
669 data.WriteBit(attackerGuid[4]);
670 data.WriteBit(attackerGuid[1]);
671 data.WriteBit(attackerGuid[0]);
672 data.WriteBit(victimGuid[1]);
673
674 data.FlushBits();
675
676 data.WriteByteSeq(victimGuid[0]);
677 data.WriteByteSeq(victimGuid[3]);
678 data.WriteByteSeq(victimGuid[5]);
679 data.WriteByteSeq(victimGuid[2]);
680 data.WriteByteSeq(attackerGuid[0]);
681 data.WriteByteSeq(attackerGuid[6]);
682 data.WriteByteSeq(attackerGuid[3]);
683 data.WriteByteSeq(victimGuid[4]);
684 data.WriteByteSeq(attackerGuid[1]);
685 data.WriteByteSeq(attackerGuid[4]);
686 data.WriteByteSeq(victimGuid[6]);
687 data.WriteByteSeq(attackerGuid[5]);
688 data.WriteByteSeq(attackerGuid[7]);
689 data.WriteByteSeq(attackerGuid[2]);
690 data.WriteByteSeq(victimGuid[1]);
691 data.WriteByteSeq(victimGuid[7]);
692
693 SendMessageToSet(&data, true);
694}
695
696bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType /*attackType*/)
697{
698 // These spells can't be blocked
699 if (spellProto && spellProto->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK)
700 return false;
701
702 if (victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION) || victim->HasInArc(M_PI, this))
703 {
704 // Check creatures flags_extra for disable block
705 if (victim->GetTypeId() == TypeID::TYPEID_UNIT &&
707 return false;
708
709 if (roll_chance_f(victim->GetUnitBlockChance()))
710 return true;
711 }
712 return false;
713}
714
716{
718 return true;
719 return false;
720}
721
723{
724 if (!spellInfo)
725 return 0;
726
727 int32 resistMech = 0;
728 for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
729 {
730 if (!spellInfo->Effects[eff].IsEffect())
731 break;
732
733 int32 effectMech = spellInfo->GetEffectMechanic(eff);
734 if (effectMech)
735 {
737 if (resistMech < temp)
738 resistMech = temp;
739 }
740 }
741 return resistMech;
742}
743
745{
746 switch (attacktype)
747 {
754 default:
755 return true;
756 }
757}
758
759// Melee based spells hit result calculations
761{
762 // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore
763 // resist and deflect chances
765 return SPELL_MISS_NONE;
766
768
769 // Check damage class instead of attack type to correctly handle judgements
770 // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class
771 if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
773
774 uint32 roll = std::rand() % 10000;
775
776 uint32 missChance = uint32(MeleeSpellMissChance(victim, attType, spellInfo->Id) * 100.0f);
777
778 // Roll miss
779 uint32 tmp = missChance;
780 if (roll < tmp)
781 return SPELL_MISS_MISS;
782
783 // Chance resist mechanic (select max value from every mechanic spell effect)
784 int32 resist_mech = 0;
785 // Get effects mechanic and chance
786 for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
787 {
788 int32 effect_mech = spellInfo->GetEffectMechanic(eff);
789 if (effect_mech)
790 {
792 if (resist_mech < temp * 100)
793 resist_mech = temp * 100;
794 }
795 }
796 // Roll chance
797 tmp += resist_mech;
798 if (roll < tmp)
799 return SPELL_MISS_RESIST;
800
801 bool canDodge = true;
802 bool canParry = true;
803 bool canBlock = spellInfo->AttributesEx3 & SPELL_ATTR3_BLOCKABLE_SPELL;
804
805 // Same spells cannot be parry/dodge
807 return SPELL_MISS_NONE;
808
809 // Chance resist mechanic
810 int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100;
811 tmp += resist_chance;
812 if (roll < tmp)
813 return SPELL_MISS_RESIST;
814
815 // Ranged attacks can only miss, resist and deflect
816 if (attType == WeaponAttackType::RANGED_ATTACK)
817 {
818 canParry = false;
819 canDodge = false;
820
821 // only if in front
822 if (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
823 {
824 int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100;
825 tmp += deflect_chance;
826 if (roll < tmp)
827 return SPELL_MISS_DEFLECT;
828 }
829 return SPELL_MISS_NONE;
830 }
831
832 // Check for attack from behind
833 if (!victim->HasInArc(M_PI, this))
834 {
836 {
837 // Can`t dodge from behind in PvP (but its possible in PvE)
838 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
839 canDodge = false;
840 // Can`t parry or block
841 canParry = false;
842 canBlock = false;
843 }
844 else // Only deterrence as of 3.3.5
845 {
847 canParry = false;
848 }
849 }
850 // Check creatures flags_extra for disable parry
851 if (victim->GetTypeId() == TypeID::TYPEID_UNIT)
852 {
853 uint32 flagEx = victim->ToCreature()->GetCreatureTemplate()->flags_extra;
854 if (flagEx & CREATURE_FLAG_EXTRA_NO_PARRY)
855 canParry = false;
856 // Check creatures flags_extra for disable block
857 if (flagEx & CREATURE_FLAG_EXTRA_NO_BLOCK)
858 canBlock = false;
859 }
860 // Ignore combat result aura
862 for (AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
863 {
864 if (!(*i)->IsAffectingSpell(spellInfo))
865 continue;
866 switch (MeleeHitOutcome((*i)->GetMiscValue()))
867 {
869 canDodge = false;
870 break;
872 canBlock = false;
873 break;
875 canParry = false;
876 break;
877 default:
878 SF_LOG_DEBUG("entities.unit", "Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT has unhandled state %d", (*i)->GetId(), (*i)->GetMiscValue());
879 break;
880 }
881 }
882
883 if (canDodge)
884 {
885 // Roll dodge
886 int32 dodgeChance = int32(victim->GetUnitDodgeChance() * 100.0f);
887 // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
889 dodgeChance = int32(float(dodgeChance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
890 // Reduce dodge chance by attacker expertise rating
892 dodgeChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
893 else
895 if (dodgeChance < 0)
896 dodgeChance = 0;
897
898 if (roll < (tmp += dodgeChance))
899 return SPELL_MISS_DODGE;
900 }
901
902 if (canParry)
903 {
904 // Roll parry
905 int32 parryChance = int32(victim->GetUnitParryChance() * 100.0f);
906 // Reduce parry chance by attacker expertise rating
908 parryChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
909 else
911 if (parryChance < 0)
912 parryChance = 0;
913
914 tmp += parryChance;
915 if (roll < tmp)
916 return SPELL_MISS_PARRY;
917 }
918
919 if (canBlock)
920 {
921 int32 blockChance = int32(victim->GetUnitBlockChance() * 100.0f);
922 if (blockChance < 0)
923 blockChance = 0;
924 tmp += blockChance;
925
926 if (roll < tmp)
927 return SPELL_MISS_BLOCK;
928 }
929
930 return SPELL_MISS_NONE;
931}
932
935{
936 // Can`t miss on dead target (on skinning for example)
937 if ((!victim->IsAlive() && victim->GetTypeId() != TypeID::TYPEID_PLAYER) || spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT)
938 return SPELL_MISS_NONE;
939
940 SpellSchoolMask schoolMask = spellInfo->GetSchoolMask();
941 // PvP - PvE spell misschances per leveldif > 2
942 int32 lchance = victim->GetTypeId() == TypeID::TYPEID_PLAYER ? 7 : 11;
943 int32 thisLevel = getLevelForTarget(victim);
944 if (GetTypeId() == TypeID::TYPEID_UNIT && ToCreature()->IsTrigger())
945 thisLevel = std::max<int32>(thisLevel, spellInfo->SpellLevel);
946 int32 leveldif = int32(victim->getLevelForTarget(this)) - thisLevel;
947
948 // Base hit chance from attacker and victim levels
949 int32 modHitChance;
950 if (leveldif < 3)
951 modHitChance = 96 - leveldif;
952 else
953 modHitChance = 94 - (leveldif - 2) * lchance;
954
955 // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
956 if (Player* modOwner = GetSpellModOwner())
957 modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance);
958
959 // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects
961 {
962 // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
964 }
965
966 int32 HitChance = modHitChance * 100;
967 // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings
968 HitChance += int32(m_modSpellHitChance * 100.0f);
969
970 RoundToInterval(HitChance, 100, 10000);
971
972 int32 tmp = 10000 - HitChance;
973
974 int32 rand = std::rand() % 10000;
975
976 if (rand < tmp)
977 return SPELL_MISS_MISS;
978
979 // Chance resist mechanic (select max value from every mechanic spell effect)
980 int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100;
981 tmp += resist_chance;
982
983 // Roll chance
984 if (rand < tmp)
985 return SPELL_MISS_RESIST;
986
987 // cast by caster in front of victim
988 if (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
989 {
990 int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100;
991 tmp += deflect_chance;
992 if (rand < tmp)
993 return SPELL_MISS_DEFLECT;
994 }
995
996 return SPELL_MISS_NONE;
997}
998
999// Calculate spell hit result can be:
1000// Every spell can: Evade/Immune/Reflect/Sucesful hit
1001// For melee based spells:
1002// Miss
1003// Dodge
1004// Parry
1005// For spells
1006// Resist
1007SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spellInfo, bool CanReflect)
1008{
1009 // Check for immune
1010 if (victim->IsImmunedToSpell(spellInfo))
1011 return SPELL_MISS_IMMUNE;
1012
1013 // All positive spells can`t miss
1015 if (spellInfo->IsPositive() && !IsHostileTo(victim)) // prevent from affecting enemy by "positive" spell
1016 return SPELL_MISS_NONE;
1017
1018 // Check for immune
1019 if (victim->IsImmunedToDamage(spellInfo))
1020 return SPELL_MISS_IMMUNE;
1021
1022 if (this == victim)
1023 return SPELL_MISS_NONE;
1024
1025 // Return evade for units in evade mode
1026 if (victim->GetTypeId() == TypeID::TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
1027 return SPELL_MISS_EVADE;
1028
1029 // Try victim reflect spell
1030 if (CanReflect)
1031 {
1032 int32 reflectchance = victim->GetTotalAuraModifier(SPELL_AURA_REFLECT_SPELLS);
1033 Unit::AuraEffectList const& mReflectSpellsSchool = victim->GetAuraEffectsByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
1034 for (Unit::AuraEffectList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
1035 if ((*i)->GetMiscValue() & spellInfo->GetSchoolMask())
1036 reflectchance += (*i)->GetAmount();
1037 if (reflectchance > 0 && roll_chance_i(reflectchance))
1038 {
1039 // Start triggers for remove charges if need (trigger only for victim, and mark as active spell)
1041 return SPELL_MISS_REFLECT;
1042 }
1043 }
1044
1045 switch (spellInfo->DmgClass)
1046 {
1049 return MeleeSpellHitResult(victim, spellInfo);
1051 return SPELL_MISS_NONE;
1053 return MagicSpellHitResult(victim, spellInfo);
1054 }
1055 return SPELL_MISS_NONE;
1056}
1057
1059{
1060 return (target ? getLevelForTarget(target) : getLevel()) * 5;
1061}
1062
1064{
1066 return 0.0f;
1067
1070 else
1071 {
1072 if (ToCreature()->IsTotem())
1073 return 0.0f;
1074 else
1075 {
1076 float dodge = 5.0f;
1078 return dodge > 0.0f ? dodge : 0.0f;
1079 }
1080 }
1081}
1082
1084{
1086 return 0.0f;
1087
1088 float chance = 0.0f;
1089
1090 if (Player const* player = ToPlayer())
1091 {
1092 if (player->CanParry())
1093 {
1094 Item* tmpitem = player->GetWeaponForAttack(WeaponAttackType::BASE_ATTACK, true);
1095 if (!tmpitem)
1096 tmpitem = player->GetWeaponForAttack(WeaponAttackType::OFF_ATTACK, true);
1097
1098 if (tmpitem)
1100 }
1101 }
1102 else if (GetTypeId() == TypeID::TYPEID_UNIT)
1103 {
1105 {
1106 chance = 5.0f;
1108 }
1109 }
1110
1111 return chance > 0.0f ? chance : 0.0f;
1112}
1113
1115{
1116 float miss_chance = 5.00f;
1117
1118 if (attType == WeaponAttackType::RANGED_ATTACK)
1120 else
1122
1123 return miss_chance;
1124}
1125
1127{
1129 return 0.0f;
1130
1131 if (Player const* player = ToPlayer())
1132 {
1133 if (player->CanBlock())
1134 {
1135 Item* tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
1136 if (tmpitem && !tmpitem->IsBroken())
1138 }
1139 // is player but has no block ability or no not broken shield equipped
1140 return 0.0f;
1141 }
1142 else
1143 {
1144 if (ToCreature()->IsTotem())
1145 return 0.0f;
1146 else
1147 {
1148 float block = 5.0f;
1150 return block > 0.0f ? block : 0.0f;
1151 }
1152 }
1153}
1154
1155float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit* victim) const
1156{
1157 float crit;
1158
1160 {
1161 switch (attackType)
1162 {
1165 break;
1168 break;
1171 break;
1172 // Just for good manner
1173 default:
1174 crit = 0.0f;
1175 break;
1176 }
1177 }
1178 else
1179 {
1180 crit = 5.0f;
1183 }
1184
1185 // flat aura mods
1187
1189
1190 if (crit < 0.0f)
1191 crit = 0.0f;
1192 return crit;
1193}
1194
1196{
1199
1200 // remove finished spells from current pointers
1201 for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i)
1202 {
1203 if (m_currentSpells[i] && m_currentSpells[i]->getState() == SPELL_STATE_FINISHED)
1204 {
1205 m_currentSpells[i]->SetReferencedFromCurrent(false);
1206 m_currentSpells[i] = NULL; // remove pointer
1207 }
1208 }
1209
1210 // m_auraUpdateIterator can be updated in indirect called code at aura remove to skip next planned to update but removed auras
1212 {
1213 Aura* i_aura = m_auraUpdateIterator->second;
1214 ++m_auraUpdateIterator; // need shift to next for allow update if need into aura update
1215 i_aura->UpdateOwner(time, this);
1216 }
1217
1218 // remove expired auras - do that after updates(used in scripts?)
1219 for (AuraMap::iterator i = m_ownedAuras.begin(); i != m_ownedAuras.end();)
1220 {
1221 if (i->second->IsExpired())
1223 else
1224 ++i;
1225 }
1226
1227 for (VisibleAuraMap::iterator itr = m_visibleAuras.begin(); itr != m_visibleAuras.end(); ++itr)
1228 if (itr->second->IsNeedClientUpdate())
1229 itr->second->ClientUpdate();
1230
1232
1233 if (!m_gameObj.empty())
1234 {
1235 GameObjectList::iterator itr;
1236 for (itr = m_gameObj.begin(); itr != m_gameObj.end();)
1237 {
1238 if (!(*itr)->isSpawned())
1239 {
1240 (*itr)->SetOwnerGUID(0);
1241 (*itr)->SetRespawnTime(0);
1242 (*itr)->Delete();
1243 m_gameObj.erase(itr++);
1244 }
1245 else
1246 ++itr;
1247 }
1248 }
1249}
1250
1252{
1253 // check "realtime" interrupts
1254 // don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
1255 if (((GetTypeId() == TypeID::TYPEID_PLAYER && ToPlayer()->isMoving()) || IsNonMeleeSpellCasted(false, false, true, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == 75)) &&
1257 {
1258 // cancel wand shoot
1259 if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)
1261 m_AutoRepeatFirstCast = true;
1262 return;
1263 }
1264
1265 // apply delay (Auto Shot (spellID 75) not affected)
1268 m_AutoRepeatFirstCast = false;
1269
1270 // castroutine
1272 {
1273 // Check if able to cast
1275 {
1277 return;
1278 }
1279
1280 // we want to shoot
1281 Spell* spell = new Spell(this, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo, TRIGGERED_FULL_MASK);
1282 spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets));
1283
1284 // all went good, reset attack
1286 }
1287}
1288
1290{
1291 ASSERT(pSpell); // NULL may be never passed here, use InterruptSpell or InterruptNonMeleeSpells
1292
1293 CurrentSpellTypes CSpellType = pSpell->GetCurrentContainer();
1294
1295 if (pSpell == m_currentSpells[CSpellType]) // avoid breaking self
1296 return;
1297
1298 // break same type spell if it is not delayed
1299 InterruptSpell(CSpellType, false);
1300
1301 // special breakage effects:
1302 switch (CSpellType)
1303 {
1305 {
1306 // generic spells always break channeled not delayed spells
1308
1309 // autorepeat breaking
1311 {
1312 // break autorepeat if not Auto Shot
1313 if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetSpellInfo()->Id != 75)
1315 m_AutoRepeatFirstCast = true;
1316 }
1317 if (pSpell->GetCastTime() > 0)
1319
1320 break;
1321 }
1323 {
1324 // channel spells always break generic non-delayed and any channeled spells
1327
1328 // it also does break autorepeat if not Auto Shot
1330 m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetSpellInfo()->Id != 75)
1333
1334 break;
1335 }
1337 {
1338 // only Auto Shoot does not break anything
1339 if (pSpell->GetSpellInfo()->Id != 75)
1340 {
1341 // generic autorepeats break generic non-delayed and channeled non-delayed spells
1344 }
1345 // special action: set first cast flag
1346 m_AutoRepeatFirstCast = true;
1347
1348 break;
1349 }
1350 default:
1351 break; // other spell types don't break anything now
1352 }
1353
1354 // current spell (if it is still here) may be safely deleted now
1355 if (m_currentSpells[CSpellType])
1356 m_currentSpells[CSpellType]->SetReferencedFromCurrent(false);
1357
1358 // set new current spell
1359 m_currentSpells[CSpellType] = pSpell;
1360 pSpell->SetReferencedFromCurrent(true);
1361
1362 pSpell->m_selfContainer = &(m_currentSpells[pSpell->GetCurrentContainer()]);
1363}
1364
1365void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool withInstant)
1366{
1367 //SF_LOG_DEBUG("entities.unit", "Interrupt spell for unit %u.", GetEntry());
1368 Spell* spell = m_currentSpells[spellType];
1369 if (spell
1370 && (withDelayed || spell->getState() != SPELL_STATE_DELAYED)
1371 && (withInstant || spell->GetCastTime() > 0))
1372 {
1373 // for example, do not let self-stun aura interrupt itself
1374 if (!spell->IsInterruptable())
1375 return;
1376
1377 // send autorepeat cancel message for autorepeat spells
1378 if (spellType == CURRENT_AUTOREPEAT_SPELL)
1381
1382 if (spell->getState() != SPELL_STATE_FINISHED)
1383 spell->cancel();
1384
1385 m_currentSpells[spellType] = NULL;
1386 spell->SetReferencedFromCurrent(false);
1387 }
1388}
1389
1390void Unit::FinishSpell(CurrentSpellTypes spellType, bool ok /*= true*/)
1391{
1392 Spell* spell = m_currentSpells[spellType];
1393 if (!spell)
1394 return;
1395
1396 if (spellType == CURRENT_CHANNELED_SPELL)
1397 spell->SendChannelUpdate(0);
1398
1399 spell->finish(ok);
1400}
1401
1402bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skipAutorepeat, bool isAutoshoot, bool skipInstant) const
1403{
1404 // We don't do loop here to explicitly show that melee spell is excluded.
1405 // Maybe later some special spells will be excluded too.
1406
1407 // if skipInstant then instant spells shouldn't count as being casted
1408 if (skipInstant && m_currentSpells[CURRENT_GENERIC_SPELL] && !m_currentSpells[CURRENT_GENERIC_SPELL]->GetCastTime())
1409 return false;
1410
1411 // generic spells are casted when they are not finished and not delayed
1414 (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED))
1415 {
1416 if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))
1417 return true;
1418 }
1419 // channeled spells may be delayed, but they are still considered casted
1420 else if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
1422 {
1423 if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))
1424 return true;
1425 }
1426 // autorepeat spells may be finished or delayed, but they are still considered casted
1427 else if (!skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
1428 return true;
1429
1430 return false;
1431}
1432
1433void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id, bool withInstant)
1434{
1435 // generic spells are interrupted if they are not finished or delayed
1436 if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id == spell_id))
1437 InterruptSpell(CURRENT_GENERIC_SPELL, withDelayed, withInstant);
1438
1439 // autorepeat spells are interrupted if they are not finished or delayed
1440 if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == spell_id))
1441 InterruptSpell(CURRENT_AUTOREPEAT_SPELL, withDelayed, withInstant);
1442
1443 // channeled spells are interrupted if they are not finished, even if they are delayed
1444 if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id == spell_id))
1446}
1447
1449{
1450 for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
1451 if (m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id == spell_id)
1452 return m_currentSpells[i];
1453 return NULL;
1454}
1455
1457{
1458 if (Spell const* spell = FindCurrentSpellBySpellId(spell_id))
1459 return spell->GetCastTime();
1460 return 0;
1461}
1462
1463bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
1464{
1465 return IsWithinDistInMap(target, distance) && HasInArc(arc, target);
1466}
1467
1468bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
1469{
1470 return IsWithinDistInMap(target, distance) && !HasInArc(2 * M_PI - arc, target);
1471}
1472
1474{
1475 if (IsInWater())
1476 return c->CanSwim();
1477 else
1478 return c->CanWalk() || c->CanFly();
1479}
1480
1482{
1484}
1485
1487{
1489}
1490
1491void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z)
1492{
1493 if (!IsPet() && !IsVehicle())
1494 return;
1495
1496 LiquidData liquid_status;
1497 ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
1498 if (!res)
1499 {
1500 if (_lastLiquid && _lastLiquid->SpellId)
1502
1504 _lastLiquid = NULL;
1505 return;
1506 }
1507
1508 if (uint32 liqEntry = liquid_status.entry)
1509 {
1510 LiquidTypeEntry const* liquid = sLiquidTypeStore.LookupEntry(liqEntry);
1511 if (_lastLiquid && _lastLiquid->SpellId && _lastLiquid->Id != liqEntry)
1513
1514 if (liquid && liquid->SpellId)
1515 {
1517 {
1518 if (!HasAura(liquid->SpellId))
1519 CastSpell(this, liquid->SpellId, true);
1520 }
1521 else
1523 }
1524
1526 _lastLiquid = liquid;
1527 }
1528 else if (_lastLiquid && _lastLiquid->SpellId)
1529 {
1532 _lastLiquid = NULL;
1533 }
1534}
1535
1540
1542{
1543 int32 modifier = 0;
1544
1545 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1546 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1547 {
1548 if ((*i)->IsAffectingSpell(affectedSpell) && (*i)->GetAmount() > modifier)
1549 modifier = (*i)->GetAmount();
1550 }
1551
1552 return modifier;
1553}
1554
1556{
1557 int32 modifier = 0;
1558
1559 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1560 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1561 {
1562 if ((*i)->IsAffectingSpell(affectedSpell) && (*i)->GetAmount() < modifier)
1563 modifier = (*i)->GetAmount();
1564 }
1565
1566 return modifier;
1567}
1568
1573
1578
1579void Unit::ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply)
1580{
1582}
1583
1584void Unit::ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply)
1585{
1587}
1588
1590{
1591 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
1593 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
1595}
1596
1597void Unit::ApplyStatBuffMod(Stats stat, float val, bool apply)
1598{
1600}
1601
1602void Unit::ApplyStatPercentBuffMod(Stats stat, float val, bool apply)
1603{
1606}
1607
1609{
1610 m_dynObj.push_back(dynObj);
1611}
1612
1614{
1615 m_dynObj.remove(dynObj);
1616}
1617
1619{
1620 if (m_dynObj.empty())
1621 return NULL;
1622 for (DynObjectList::const_iterator i = m_dynObj.begin(); i != m_dynObj.end(); ++i)
1623 {
1624 DynamicObject* dynObj = *i;
1625 if (dynObj->GetSpellId() == spellId)
1626 return dynObj;
1627 }
1628 return NULL;
1629}
1630
1632{
1633 if (m_dynObj.empty())
1634 return;
1635 for (DynObjectList::iterator i = m_dynObj.begin(); i != m_dynObj.end();)
1636 {
1637 DynamicObject* dynObj = *i;
1638 if (dynObj->GetSpellId() == spellId)
1639 {
1640 dynObj->Remove();
1641 i = m_dynObj.begin();
1642 }
1643 else
1644 ++i;
1645 }
1646}
1647
1649{
1650 while (!m_dynObj.empty())
1651 m_dynObj.front()->Remove();
1652}
1653
1655{
1656 for (GameObjectList::const_iterator i = m_gameObj.begin(); i != m_gameObj.end(); ++i)
1657 if ((*i)->GetSpellId() == spellId)
1658 return *i;
1659
1660 return NULL;
1661}
1662
1664{
1665 if (!gameObj)
1666 return;
1667
1668 m_gameObj.push_back(gameObj);
1669}
1670
1672{
1673 if (!gameObj || !(gameObj->GetOwnerGUID() == 0))
1674 return;
1675
1676 m_gameObj.push_back(gameObj);
1677 gameObj->SetOwnerGUID(GetGUID());
1678
1679 if (GetTypeId() == TypeID::TYPEID_PLAYER && gameObj->GetSpellId())
1680 {
1681 SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(gameObj->GetSpellId());
1682 // Need disable spell use for owner
1683 if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
1684 // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
1685 ToPlayer()->AddSpellAndCategoryCooldowns(createBySpell, 0, NULL, true);
1686 }
1687}
1688
1689void Unit::RemoveGameObject(GameObject* gameObj, bool del)
1690{
1691 if (!gameObj || gameObj->GetOwnerGUID() != GetGUID())
1692 return;
1693
1694 gameObj->SetOwnerGUID(0);
1695
1696 for (uint8 i = 0; i < MAX_GAMEOBJECT_SLOT; ++i)
1697 {
1698 if (m_ObjectSlot[i] == gameObj->GetGUID())
1699 {
1700 m_ObjectSlot[i] = 0;
1701 break;
1702 }
1703 }
1704
1705 // GO created by some spell
1706 if (uint32 spellid = gameObj->GetSpellId())
1707 {
1708 RemoveAurasDueToSpell(spellid);
1709
1711 {
1712 SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(spellid);
1713 // Need activate spell use for owner
1714 if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
1715 // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
1716 ToPlayer()->SendCooldownEvent(createBySpell);
1717 }
1718 }
1719
1720 m_gameObj.remove(gameObj);
1721
1722 if (del)
1723 {
1724 gameObj->SetRespawnTime(0);
1725 gameObj->Delete();
1726 }
1727}
1728
1729void Unit::RemoveGameObject(uint32 spellid, bool del)
1730{
1731 if (m_gameObj.empty())
1732 return;
1733 GameObjectList::iterator i, next;
1734 for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next)
1735 {
1736 next = i;
1737 if (spellid == 0 || (*i)->GetSpellId() == spellid)
1738 {
1739 (*i)->SetOwnerGUID(0);
1740 if (del)
1741 {
1742 (*i)->SetRespawnTime(0);
1743 (*i)->Delete();
1744 }
1745
1746 next = m_gameObj.erase(i);
1747 }
1748 else
1749 ++next;
1750 }
1751}
1752
1754{
1755 // remove references to unit
1756 while (!m_gameObj.empty())
1757 {
1758 GameObjectList::iterator i = m_gameObj.begin();
1759 (*i)->SetOwnerGUID(0);
1760 (*i)->SetRespawnTime(0);
1761 (*i)->Delete();
1762 m_gameObj.erase(i);
1763 }
1764}
1765
1767{
1768 ObjectGuid attackerGuid = log->attacker->GetGUID();
1769 ObjectGuid targetGuid = log->target->GetGUID();
1770 int32 overkill = log->damage - log->target->GetHealth();
1771
1772 WorldPacket data(SMSG_SPELL_NON_MELEE_DAMAGE_LOG, (16 + 4 + 4 + 4 + 1 + 4 + 4 + 1 + 1 + 4 + 4 + 1)); // we guess size
1773 data.WriteBit(targetGuid[2]);
1774 data.WriteBit(attackerGuid[7]);
1775 data.WriteBit(attackerGuid[6]);
1776 data.WriteBit(attackerGuid[1]);
1777 data.WriteBit(attackerGuid[5]);
1778 data.WriteBit(0); // Unk
1779 data.WriteBit(attackerGuid[0]);
1780 data.WriteBit(targetGuid[0]);
1781 data.WriteBit(targetGuid[7]);
1782 data.WriteBit(attackerGuid[3]);
1783 data.WriteBit(targetGuid[6]);
1784 data.WriteBit(0); // Unk
1785 data.WriteBit(0); // HasPowerData
1786 data.WriteBit(targetGuid[1]);
1787 data.WriteBit(0); // No floats
1788 data.WriteBit(targetGuid[5]);
1789 data.WriteBit(attackerGuid[2]);
1790 data.WriteBit(attackerGuid[4]);
1791 data.WriteBit(targetGuid[3]);
1792 data.WriteBit(targetGuid[4]);
1793
1794 data.FlushBits();
1795
1796 data << uint32(log->blocked);
1797 data.WriteByteSeq(attackerGuid[1]);
1798 data << uint32(overkill > 0 ? overkill : 0);
1799 data.WriteByteSeq(targetGuid[3]);
1800 data.WriteByteSeq(attackerGuid[0]);
1801 data.WriteByteSeq(targetGuid[6]);
1802 data.WriteByteSeq(targetGuid[4]);
1803 data.WriteByteSeq(attackerGuid[7]);
1804 data << uint32(log->resist);
1805 data << uint32(log->absorb);
1806 data.WriteByteSeq(attackerGuid[5]);
1807 data.WriteByteSeq(targetGuid[5]);
1808 data.WriteByteSeq(attackerGuid[3]);
1809 data.WriteByteSeq(attackerGuid[2]);
1810 data.WriteByteSeq(targetGuid[2]);
1811 data.WriteByteSeq(attackerGuid[6]);
1812 data.WriteByteSeq(targetGuid[0]);
1813 data.WriteByteSeq(attackerGuid[4]);
1814 data << uint32(log->damage);
1815 data << uint8(log->schoolMask);
1816 data.WriteByteSeq(targetGuid[7]);
1817 data << uint32(log->HitInfo);
1818 data.WriteByteSeq(targetGuid[1]);
1819 data << uint32(log->SpellID);
1820
1821 SendMessageToSet(&data, true);
1822}
1823
1824void Unit::SendSpellNonMeleeDamageLog(Unit* target, uint32 SpellID, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit)
1825{
1826 SpellNonMeleeDamage log(this, target, SpellID, damageSchoolMask);
1827 log.damage = Damage - AbsorbedDamage - Resist - Blocked;
1828 log.absorb = AbsorbedDamage;
1829 log.resist = Resist;
1830 log.physicalLog = PhysicalDamage;
1831 log.blocked = Blocked;
1833 if (CriticalHit)
1836}
1837
1839{
1840 AuraEffect const* aura = pInfo->auraEff;
1841 ObjectGuid CasterGUID = aura->GetCasterGUID();
1842 ObjectGuid TargetGUID = GetGUID();
1843
1845
1846 data.WriteGuidMask(TargetGUID, 7);
1847 data.WriteGuidMask(CasterGUID, 0, 7);
1848 data.WriteGuidMask(TargetGUID, 1);
1849 data.WriteBits(1, 21); // PeriodicAuraLogEffect
1850 data.WriteGuidMask(TargetGUID, 0);
1851
1852 //PeriodicAuraLogEffect
1853 {
1854 data.WriteBit(!pInfo->overDamage); // 8
1855 data.WriteBit(!pInfo->absorb); // 16
1856 data.WriteBit(pInfo->critical); // 24
1857 data.WriteBit(!pInfo->resist); // 20
1858 data.WriteBit(!pInfo->power); // 12
1859 }
1860
1861 data.WriteGuidMask(TargetGUID, 5, 3);
1862 data.WriteGuidMask(CasterGUID, 1);
1863 data.WriteGuidMask(TargetGUID, 2);
1864 data.WriteGuidMask(CasterGUID, 6, 3, 4);
1865 data.WriteBit(0); // SpellCastLogData
1866 data.WriteGuidMask(CasterGUID, 2);
1867 data.WriteGuidMask(TargetGUID, 6);
1868 data.WriteGuidMask(CasterGUID, 5);
1869 //SpellCastLogData
1870 {
1871 //data.WriteBits(0, 21); // SpellLogPowerData
1872 }
1873 data.WriteGuidMask(TargetGUID, 4);
1874 data.FlushBits();
1875
1876 //PeriodicAuraLogEffect
1877 {
1878 //if8
1879 if (pInfo->overDamage)
1880 data << pInfo->overDamage;
1881
1882 data << uint32(pInfo->damage); // 4
1883 data << uint32(aura->GetAuraType()); // 0
1884
1885 //if20
1886 if (pInfo->resist)
1887 data << uint32(pInfo->resist);
1888
1889 //if16
1890 if (pInfo->absorb)
1891 data << uint32(pInfo->absorb);
1892 //if12
1893 if (pInfo->power)
1894 data << uint32(pInfo->power);
1895 }
1896
1897 data.WriteGuidBytes(CasterGUID, 5, 3);
1898 data.WriteGuidBytes(TargetGUID, 4);
1899 data << int32(aura->GetId()); // auraId
1900 data.WriteGuidBytes(TargetGUID, 6);
1901 data.WriteGuidBytes(CasterGUID, 7, 1);
1902
1903 // SpellCastLogData
1904 {
1905 //SpellLogPowerData
1906 {
1907 //data << uint32(0); //40.4
1908 //data << uint32(0); //40.0
1909 }
1910
1911 //data << uint32(0); //28
1912 //data << uint32(0); //24
1913 //data << uint32(0); //32
1914 }
1915
1916 data.WriteGuidBytes(TargetGUID, 5);
1917 data.WriteGuidBytes(CasterGUID, 0);
1918 data.WriteGuidBytes(TargetGUID, 1, 7);
1919 data.WriteGuidBytes(CasterGUID, 4);
1920 data.WriteGuidBytes(TargetGUID, 3);
1921 data.WriteGuidBytes(CasterGUID, 2);
1922 data.WriteGuidBytes(TargetGUID, 0, 2);
1923 data.WriteGuidBytes(CasterGUID, 6);
1924 SendMessageToSet(&data, true);
1925}
1926
1927void Unit::SendSpellMiss(Unit* target, uint32 spellID, SpellMissInfo missInfo)
1928{
1929 WorldPacket data(SMSG_SPELLLOGMISS, (8 + 4 + 1 + (8 + 1 + (1 + (2 * 4)))));
1930 data.WriteGuidMask(GetGUID(), 5, 1, 4, 0, 7, 3, 2, 6);
1931 data.WriteBits(1, 23);
1932 data.WriteGuidMask(target->GetGUID(), 0, 1, 6, 2, 5, 3, 4, 7);
1933 data.WriteBit(false); // debuginfo
1934
1935 data.FlushBits();
1936 data << missInfo;
1937 data.WriteGuidBytes(target->GetGUID(), 7, 5, 0, 6, 3, 2);
1938 // debuginfo { float, float }
1939 data.WriteGuidBytes(target->GetGUID(), 1, 4);
1940 data.WriteGuidBytes(GetGUID(), 6, 4, 2, 0, 1);
1941 data << uint32(spellID);
1942 data.WriteGuidBytes(GetGUID(), 3, 7, 5);
1943 SendMessageToSet(&data, true);
1944}
1945
1947{
1948 WorldPacket data(SMSG_PROCRESIST, 8 + 8 + 4 + 1);
1949 data << uint64(GetGUID());
1950 data << uint64(target->GetGUID());
1951 data << uint32(spellId);
1952 data << uint8(0); // bool - log format: 0-default, 1-debug
1953 SendMessageToSet(&data, true);
1954}
1955
1957{
1958 ObjectGuid guid = GetGUID();
1959 ObjectGuid targetGuid = target->GetGUID();
1960 WorldPacket data(SMSG_SPELLORDAMAGE_IMMUNE, 8 + 8 + 4 + 1);
1961 data.WriteGuidMask(guid, 5, 0);
1962 data.WriteGuidMask(targetGuid, 6);
1963 data.WriteBit(0); // bool - log format: 0-default, 1-debug
1964 data.WriteGuidMask(guid, 7);
1965 data.WriteGuidMask(targetGuid, 5, 2);
1966 data.WriteGuidMask(guid, 2, 1, 3);
1967 data.WriteGuidMask(targetGuid, 4);
1968 data.WriteGuidMask(guid, 4);
1969 data.WriteGuidMask(targetGuid, 7);
1970 data.WriteGuidMask(guid, 6);
1971 data.WriteGuidMask(targetGuid, 3, 1, 0);
1972 data.FlushBits();
1973 data.WriteGuidBytes(targetGuid, 4, 3);
1974 data.WriteGuidBytes(guid, 2);
1975 data.WriteGuidBytes(targetGuid, 6, 5);
1976 data.WriteGuidBytes(guid, 3);
1977 data.WriteGuidBytes(targetGuid, 7, 2, 0);
1978 data.WriteGuidBytes(guid, 7, 5, 0, 1, 4);
1979 data << uint32(spellId);
1980 data.WriteGuidBytes(targetGuid, 1);
1981 data.WriteGuidBytes(guid, 6);
1982 SendMessageToSet(&data, true);
1983}
1984
1986{
1987 SF_LOG_DEBUG("entities.unit", "WORLD: Sending SMSG_ATTACKER_STATE_UPDATE");
1988 uint32 count = 1;
1989
1990 ByteBuffer buff;
1991 buff << uint32(damageInfo->HitInfo);
1992 buff.append(damageInfo->attacker->GetPackGUID());
1993 buff.append(damageInfo->target->GetPackGUID());
1994
1995
1996 buff << uint32(damageInfo->damage); // Full damage
1997
1998 int32 overkill = damageInfo->damage - damageInfo->target->GetHealth();
1999 buff << uint32(overkill < 0 ? 0 : overkill); // Overkill
2000 buff << uint8(count); // Sub damage count
2001
2002 for (uint32 i = 0; i < count; ++i)
2003 {
2004 buff << uint32(damageInfo->damageSchoolMask); // School of sub damage
2005 buff << float(damageInfo->damage); // sub damage
2006 buff << uint32(damageInfo->damage); // Sub Damage
2007 }
2008
2010 {
2011 for (uint32 i = 0; i < count; ++i)
2012 buff << uint32(damageInfo->absorb); // Absorb
2013 }
2014
2016 {
2017 for (uint32 i = 0; i < count; ++i)
2018 buff << uint32(damageInfo->resist); // Resist
2019 }
2020
2021 buff << uint8(damageInfo->TargetState);
2022 buff << uint32(0); // Unknown attackerstate
2023 buff << uint32(0); // Melee spellid
2024
2025 if (damageInfo->HitInfo & HITINFO_BLOCK)
2026 buff << uint32(damageInfo->blocked_amount);
2027
2028 if (damageInfo->HitInfo & HITINFO_RAGE_GAIN)
2029 buff << uint32(0);
2030
2032 if (damageInfo->HitInfo & HITINFO_UNK1)
2033 {
2034 buff << uint32(0);
2035 buff << float(0);
2036 buff << float(0);
2037 buff << float(0);
2038 buff << float(0);
2039 buff << float(0);
2040 buff << float(0);
2041 buff << float(0);
2042 buff << float(0);
2043
2044 for (uint8 i = 0; i < 2; ++i)
2045 {
2046 buff << float(0);
2047 buff << float(0);
2048 }
2049 buff << uint32(0);
2050 }
2051
2052 if (damageInfo->HitInfo & (HITINFO_BLOCK | HITINFO_UNK12))
2053 buff << float(0);
2054
2055
2056 WorldPacket data(SMSG_ATTACKER_STATE_UPDATE, buff.size() + 1 + 4);
2057 data.WriteBit(0); // hasSpellCastLogData
2058 data.FlushBits();
2059 data << uint32(buff.size());
2060 data.append(buff);
2061 SendMessageToSet(&data, true);
2062}
2063
2064void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType*/, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
2065{
2066 CalcDamageInfo dmgInfo;
2067 dmgInfo.HitInfo = HitInfo;
2068 dmgInfo.attacker = this;
2069 dmgInfo.target = target;
2070 dmgInfo.damage = Damage - AbsorbDamage - Resist - BlockedAmount;
2071 dmgInfo.damageSchoolMask = damageSchoolMask;
2072 dmgInfo.absorb = AbsorbDamage;
2073 dmgInfo.resist = Resist;
2074 dmgInfo.TargetState = TargetState;
2075 dmgInfo.blocked_amount = BlockedAmount;
2076 SendAttackStateUpdate(&dmgInfo);
2077}
2078
2079void Unit::setPowerType(Powers new_powertype)
2080{
2081 SetFieldPowerType(new_powertype);
2082
2084 {
2085 if (ToPlayer()->GetGroup())
2087 }
2088 else if (Pet* pet = ToCreature()->ToPet())
2089 {
2090 if (pet->isControlled())
2091 {
2092 Unit* owner = GetOwner();
2093 if (owner && (owner->GetTypeId() == TypeID::TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
2095 }
2096 }
2097
2098 switch (new_powertype)
2099 {
2100 default:
2101 case POWER_MANA:
2102 break;
2103 case POWER_RAGE:
2105 SetPower(POWER_RAGE, 0);
2106 break;
2107 case POWER_FOCUS:
2110 break;
2111 case POWER_ENERGY:
2113 break;
2114 }
2115}
2116
2118{
2119 FactionTemplateEntry const* entry = sFactionTemplateStore.LookupEntry(getFaction());
2120 if (!entry)
2121 {
2122 static uint64 guid = 0; // prevent repeating spam same faction problem
2123
2124 if (GetGUID() != guid)
2125 {
2126 if (Player const* player = ToPlayer())
2127 SF_LOG_ERROR("entities.unit", "Player %s has invalid faction (faction template id) #%u", player->GetName().c_str(), getFaction());
2128 else if (Creature const* creature = ToCreature())
2129 SF_LOG_ERROR("entities.unit", "Creature (template id: %u) has invalid faction (faction template id) #%u", creature->GetCreatureTemplate()->Entry, getFaction());
2130 else
2131 SF_LOG_ERROR("entities.unit", "Unit (name=%s, type=%u) has invalid faction (faction template id) #%u", GetName().c_str(), uint32(GetTypeId()), getFaction());
2132
2133 guid = GetGUID();
2134 }
2135 }
2136 return entry;
2137}
2138
2139// function based on function Unit::UnitReaction from 13850 client
2141{
2142 // always friendly to self
2143 if (this == target)
2144 return REP_FRIENDLY;
2145
2146 if (!target)
2147 return REP_FRIENDLY;
2148
2149 // always friendly to charmer or owner
2151 return REP_FRIENDLY;
2152
2153 Player const* selfPlayerOwner = GetAffectingPlayer();
2154 Player const* targetPlayerOwner = target->GetAffectingPlayer();
2155
2156 // check forced reputation to support SPELL_AURA_FORCE_REACTION
2157 if (selfPlayerOwner)
2158 {
2159 if (FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry())
2160 if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry))
2161 return *repRank;
2162 }
2163 else if (targetPlayerOwner)
2164 {
2165 if (FactionTemplateEntry const* selfFactionTemplateEntry = GetFactionTemplateEntry())
2166 if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(selfFactionTemplateEntry))
2167 return *repRank;
2168 }
2169
2171 {
2173 {
2174 Player const* selfPlayerOwner = GetAffectingPlayer();
2175 Player const* targetPlayerOwner = target->GetAffectingPlayer();
2176
2177 if (selfPlayerOwner && targetPlayerOwner)
2178 {
2179 // always friendly to other unit controlled by player, or to the player himself
2180 if (selfPlayerOwner == targetPlayerOwner)
2181 return REP_FRIENDLY;
2182
2183 // duel - always hostile to opponent
2184 if (selfPlayerOwner->duel && selfPlayerOwner->duel->opponent == targetPlayerOwner && selfPlayerOwner->duel->startTime != 0)
2185 return REP_HOSTILE;
2186
2187 // same group - checks dependant only on our faction - skip FFA_PVP for example
2188 if (selfPlayerOwner->IsInRaidWith(targetPlayerOwner))
2189 return REP_FRIENDLY; // return true to allow config option AllowTwoSide.Interaction.Group to work
2190 // however client seems to allow mixed group parties, because in 13850 client it works like:
2191 // return GetFactionReactionTo(GetFactionTemplateEntry(), target);
2192 }
2193
2194 // check FFA_PVP
2197 return REP_HOSTILE;
2198
2199 if (selfPlayerOwner)
2200 {
2201 if (FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry())
2202 {
2203 if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry))
2204 return *repRank;
2206 {
2207 if (FactionEntry const* targetFactionEntry = sFactionStore.LookupEntry(targetFactionTemplateEntry->faction))
2208 {
2209 if (targetFactionEntry->CanHaveReputation())
2210 {
2211 // check contested flags
2212 if (targetFactionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD
2214 return REP_HOSTILE;
2215
2216 // if faction has reputation, hostile state depends only from AtWar state
2217 if (selfPlayerOwner->GetReputationMgr().IsAtWar(targetFactionEntry))
2218 return REP_HOSTILE;
2219 return REP_FRIENDLY;
2220 }
2221 }
2222 }
2223 }
2224 }
2225 }
2226 }
2227 // do checks dependant only on our faction
2229}
2230
2231ReputationRank Unit::GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, Unit const* target)
2232{
2233 // always neutral when no template entry found
2234 if (!factionTemplateEntry)
2235 return REP_NEUTRAL;
2236
2237 FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry();
2238 if (!targetFactionTemplateEntry)
2239 return REP_NEUTRAL;
2240
2241 if (Player const* targetPlayerOwner = target->GetAffectingPlayer())
2242 {
2243 // check contested flags
2244 if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD
2245 && targetPlayerOwner->HasFlag(PLAYER_FIELD_PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP))
2246 return REP_HOSTILE;
2247 if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(factionTemplateEntry))
2248 return *repRank;
2250 {
2251 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction))
2252 {
2253 if (factionEntry->CanHaveReputation())
2254 {
2255 // CvP case - check reputation, don't allow state higher than neutral when at war
2256 ReputationRank repRank = targetPlayerOwner->GetReputationMgr().GetRank(factionEntry);
2257 if (targetPlayerOwner->GetReputationMgr().IsAtWar(factionEntry))
2258 repRank = std::min(REP_NEUTRAL, repRank);
2259 return repRank;
2260 }
2261 }
2262 }
2263 }
2264
2265 // common faction based check
2266 if (factionTemplateEntry->IsHostileTo(*targetFactionTemplateEntry))
2267 return REP_HOSTILE;
2268 if (factionTemplateEntry->IsFriendlyTo(*targetFactionTemplateEntry))
2269 return REP_FRIENDLY;
2270 if (targetFactionTemplateEntry->IsFriendlyTo(*factionTemplateEntry))
2271 return REP_FRIENDLY;
2272 if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_HOSTILE_BY_DEFAULT)
2273 return REP_HOSTILE;
2274 // neutral by default
2275 return REP_NEUTRAL;
2276}
2277
2278bool Unit::IsHostileTo(Unit const* unit) const
2279{
2280 return GetReactionTo(unit) <= REP_HOSTILE;
2281}
2282
2283bool Unit::IsFriendlyTo(Unit const* unit) const
2284{
2285 return GetReactionTo(unit) >= REP_FRIENDLY;
2286}
2287
2289{
2290 FactionTemplateEntry const* my_faction = GetFactionTemplateEntry();
2291 if (!my_faction || !my_faction->faction)
2292 return false;
2293
2294 FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction);
2295 if (raw_faction && raw_faction->reputationListID >= 0)
2296 return false;
2297
2298 return my_faction->IsHostileToPlayers();
2299}
2300
2302{
2303 FactionTemplateEntry const* my_faction = GetFactionTemplateEntry();
2304 if (!my_faction || !my_faction->faction)
2305 return true;
2306
2307 FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction);
2308 if (raw_faction && raw_faction->reputationListID >= 0)
2309 return false;
2310
2311 return my_faction->IsNeutralToAll();
2312}
2313
2315{
2316 if (GetOwnerGUID() == owner)
2317 return;
2318
2320 if (!owner)
2321 return;
2322
2323 // Update owner dependent fields
2324 Player* player = ObjectAccessor::GetPlayer(*this, owner);
2325 if (!player || !player->HaveAtClient(this)) // if player cannot see this unit yet, he will receive needed data with create object
2326 return;
2327
2329
2330 UpdateData udata(GetMapId());
2331 WorldPacket packet;
2332 BuildValuesUpdateBlockForPlayer(&udata, player);
2333 udata.BuildPacket(&packet);
2334 player->SendDirectMessage(&packet);
2335
2337}
2338
2340{
2341 if (uint64 ownerid = GetOwnerGUID())
2342 {
2343 return ObjectAccessor::GetUnit(*this, ownerid);
2344 }
2345 return NULL;
2346}
2347
2349{
2350 if (uint64 charmerid = GetCharmerGUID())
2351 return ObjectAccessor::GetUnit(*this, charmerid);
2352 return NULL;
2353}
2354
2356{
2358 if (IS_PLAYER_GUID(guid))
2359 return ObjectAccessor::GetPlayer(*this, guid);
2360
2361 return const_cast<Unit*>(this)->ToPlayer();
2362}
2363
2365{
2366 if (!GetCharmerOrOwnerGUID())
2367 return const_cast<Unit*>(this)->ToPlayer();
2368
2369 if (Unit* owner = GetCharmerOrOwner())
2371
2372 return NULL;
2373}
2374
2376{
2377 if (uint64 pet_guid = GetMinionGUID())
2378 {
2379 if (Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, pet_guid))
2380 if (pet->HasUnitTypeMask(UNIT_MASK_MINION))
2381 return (Minion*)pet;
2382
2383 SF_LOG_ERROR("entities.unit", "Unit::GetFirstMinion: Minion %u not exist.", GUID_LOPART(pet_guid));
2384 const_cast<Unit*>(this)->SetMinionGUID(0);
2385 }
2386
2387 return NULL;
2388}
2389
2391{
2392 if (uint64 pet_guid = GetPetGUID())
2393 {
2394 if (Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, pet_guid))
2395 if (pet->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
2396 return (Guardian*)pet;
2397
2398 SF_LOG_FATAL("entities.unit", "Unit::GetGuardianPet: Guardian " UI64FMTD " not exist.", pet_guid);
2399 const_cast<Unit*>(this)->SetPetGUID(0);
2400 }
2401
2402 return NULL;
2403}
2404
2406{
2407 if (uint64 charm_guid = GetCharmGUID())
2408 {
2409 if (Unit* pet = ObjectAccessor::GetUnit(*this, charm_guid))
2410 return pet;
2411
2412 SF_LOG_ERROR("entities.unit", "Unit::GetCharm: Charmed creature %u not exist.", GUID_LOPART(charm_guid));
2413 const_cast<Unit*>(this)->SetUInt64Value(UNIT_FIELD_CHARM, 0);
2414 }
2415
2416 return NULL;
2417}
2418
2420{
2421 return GetCharmerGUID() ? GetCharmer() : GetOwner();
2422}
2423
2425{
2426 if (Unit* u = GetCharmerOrOwner())
2427 return u;
2428
2429 return (Unit*)this;
2430}
2431
2432void Unit::SetMinion(Minion* minion, bool apply)
2433{
2434 SF_LOG_DEBUG("entities.unit", "SetMinion %u for %u, apply %u", minion->GetEntry(), GetEntry(), apply);
2435
2436 if (apply)
2437 {
2438 if (minion->GetOwnerGUID())
2439 {
2440 SF_LOG_FATAL("entities.unit", "SetMinion: Minion %u is not the minion of owner %u", minion->GetEntry(), GetEntry());
2441 return;
2442 }
2443
2444 minion->SetOwnerGUID(GetGUID());
2445
2446 m_Controlled.insert(minion);
2447
2449 {
2450 minion->m_ControlledByPlayer = true;
2452 }
2453
2454 // Can only have one pet. If a new one is summoned, dismiss the old one.
2455 if (minion->IsGuardianPet())
2456 {
2457 if (Guardian* oldPet = GetGuardianPet())
2458 {
2459 if (oldPet != minion && (oldPet->IsPet() || minion->IsPet() || oldPet->GetEntry() != minion->GetEntry()))
2460 {
2461 // remove existing minion pet
2462 if (oldPet->IsPet())
2463 ((Pet*)oldPet)->Remove(PET_SAVE_AS_CURRENT);
2464 else
2465 oldPet->UnSummon();
2466 SetPetGUID(minion->GetGUID());
2467 SetMinionGUID(0);
2468 }
2469 }
2470 else
2471 {
2472 SetPetGUID(minion->GetGUID());
2473 SetMinionGUID(0);
2474 }
2475 }
2476
2478 {
2480 }
2481
2482 if (minion->m_Properties && minion->m_Properties->Type == SUMMON_TYPE_MINIPET)
2483 {
2484 SetCritterGUID(minion->GetGUID());
2485 }
2486
2487 // PvP, FFAPvP
2489
2490 // FIXME: hack, speed must be set only at follow
2491 if (GetTypeId() == TypeID::TYPEID_PLAYER && minion->IsPet())
2492 for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i)
2493 minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
2494
2495 // Ghoul pets have energy instead of mana (is anywhere better place for this code?)
2496 if (minion->IsPetGhoul())
2497 minion->setPowerType(POWER_ENERGY);
2498
2500 {
2501 // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
2502 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_FIELD_CREATED_BY_SPELL));
2503
2504 if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
2505 ToPlayer()->AddSpellAndCategoryCooldowns(spellInfo, 0, NULL, true);
2506 }
2507 }
2508 else
2509 {
2510 if (minion->GetOwnerGUID() != GetGUID())
2511 {
2512 SF_LOG_FATAL("entities.unit", "SetMinion: Minion %u is not the minion of owner %u", minion->GetEntry(), GetEntry());
2513 return;
2514 }
2515
2516 m_Controlled.erase(minion);
2517
2518 if (minion->m_Properties && minion->m_Properties->Type == SUMMON_TYPE_MINIPET)
2519 {
2520 if (GetCritterGUID() == minion->GetGUID())
2521 SetCritterGUID(0);
2522 }
2523
2524 if (minion->IsGuardianPet())
2525 {
2526 if (GetPetGUID() == minion->GetGUID())
2527 SetPetGUID(0);
2528 }
2529 else if (minion->IsTotem())
2530 {
2531 // All summoned by totem minions must disappear when it is removed.
2532 if (SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(minion->ToTotem()->GetSpell()))
2533 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
2534 {
2535 if (spInfo->Effects[i].Effect != SPELL_EFFECT_SUMMON)
2536 continue;
2537
2538 RemoveAllMinionsByEntry(spInfo->Effects[i].MiscValue);
2539 }
2540 }
2541
2543 {
2544 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_FIELD_CREATED_BY_SPELL));
2545 // Remove infinity cooldown
2546 if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
2547 ToPlayer()->SendCooldownEvent(spellInfo);
2548 }
2549
2550 //if (minion->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
2551 {
2553 {
2554 // Check if there is another minion
2555 for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
2556 {
2557 // do not use this check, creature do not have charm guid
2558 //if (GetCharmGUID() == (*itr)->GetGUID())
2559 if (GetGUID() == (*itr)->GetCharmerGUID())
2560 continue;
2561
2562 //ASSERT((*itr)->GetOwnerGUID() == GetGUID());
2563 if ((*itr)->GetOwnerGUID() != GetGUID())
2564 {
2565 OutDebugInfo();
2566 (*itr)->OutDebugInfo();
2567 ASSERT(false);
2568 }
2569 ASSERT((*itr)->GetTypeId() == TypeID::TYPEID_UNIT);
2570
2571 if (!(*itr)->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
2572 continue;
2573
2574 if (AddUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID()))
2575 {
2576 // show another pet bar if there is no charm bar
2578 {
2579 if ((*itr)->IsPet())
2581 else
2583 }
2584 }
2585 break;
2586 }
2587 }
2588 }
2589 }
2590}
2591
2592void Unit::GetAllMinionsByEntry(std::list<Creature*>& Minions, uint32 entry)
2593{
2594 for (Unit::ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end();)
2595 {
2596 Unit* unit = *itr;
2597 ++itr;
2598 if (unit->GetEntry() == entry && unit->GetTypeId() == TypeID::TYPEID_UNIT
2599 && unit->ToCreature()->IsSummon()) // minion, actually
2600 Minions.push_back(unit->ToCreature());
2601 }
2602}
2603
2605{
2606 for (Unit::ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end();)
2607 {
2608 Unit* unit = *itr;
2609 ++itr;
2610 if (unit->GetEntry() == entry && unit->GetTypeId() == TypeID::TYPEID_UNIT
2611 && unit->ToCreature()->IsSummon()) // minion, actually
2612 unit->ToTempSummon()->UnSummon();
2613 // i think this is safe because i have never heard that a despawned minion will trigger a same minion
2614 }
2615}
2616
2617void Unit::SetCharm(Unit* charm, bool apply)
2618{
2619 if (apply)
2620 {
2622 {
2623 if (!AddUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID()))
2624 SF_LOG_FATAL("entities.unit", "Player %s is trying to charm unit %u, but it already has a charmed unit " UI64FMTD "", GetName().c_str(), charm->GetEntry(), GetCharmGUID());
2625
2626 charm->m_ControlledByPlayer = true;
2629 }
2630 else
2631 charm->m_ControlledByPlayer = false;
2632
2633 // PvP, FFAPvP
2635
2637 SF_LOG_FATAL("entities.unit", "Unit %u is being charmed, but it already has a charmer " UI64FMTD "", charm->GetEntry(), charm->GetCharmerGUID());
2638
2641 charm->SetWalk(false);
2642
2643 m_Controlled.insert(charm);
2644 }
2645 else
2646 {
2648 {
2650 SF_LOG_FATAL("entities.unit", "Player %s is trying to uncharm unit %u, but it has another charmed unit " UI64FMTD "", GetName().c_str(), charm->GetEntry(), GetCharmGUID());
2651 }
2652
2654 SF_LOG_FATAL("entities.unit", "Unit %u is being uncharmed, but it has another charmer " UI64FMTD "", charm->GetEntry(), charm->GetCharmerGUID());
2655
2656 if (charm->GetTypeId() == TypeID::TYPEID_PLAYER)
2657 {
2658 charm->m_ControlledByPlayer = true;
2660 charm->ToPlayer()->UpdatePvPState();
2661 }
2662 else if (Player* player = charm->GetCharmerOrOwnerPlayerOrPlayerItself())
2663 {
2664 charm->m_ControlledByPlayer = true;
2666 charm->SetByteValue(UNIT_FIELD_SHAPESHIFT_FORM, 1, player->GetByteValue(UNIT_FIELD_SHAPESHIFT_FORM, 1));
2667 }
2668 else
2669 {
2670 charm->m_ControlledByPlayer = false;
2673 }
2674
2675 if (charm->IsWalking() != _isWalkingBeforeCharm)
2677
2678 if (charm->GetTypeId() == TypeID::TYPEID_PLAYER
2680 || charm->GetOwnerGUID() != GetGUID())
2681 {
2682 m_Controlled.erase(charm);
2683 }
2684 }
2685}
2686
2687int32 Unit::DealHeal(Unit* victim, uint32 addhealth)
2688{
2689 int32 gain = 0;
2690
2691 if (victim->IsAIEnabled)
2692 victim->GetAI()->HealReceived(this, addhealth);
2693
2694 if (IsAIEnabled)
2695 GetAI()->HealDone(victim, addhealth);
2696
2697 if (addhealth)
2698 gain = victim->ModifyHealth(int32(addhealth));
2699
2700 // Hook for OnHeal Event
2701 sScriptMgr->OnHeal(this, victim, (uint32&)gain);
2702
2703 Unit* unit = this;
2704
2706 unit = GetOwner();
2707
2708 if (Player* player = unit->ToPlayer())
2709 {
2710 if (Battleground* bg = player->GetBattleground())
2711 bg->UpdatePlayerScore(player, SCORE_HEALING_DONE, gain);
2712
2713 // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria)
2714 if (gain)
2715 player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, 0, victim);
2716
2717 player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth);
2718 }
2719
2720 if (Player* player = victim->ToPlayer())
2721 {
2722 player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain);
2723 player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth);
2724 }
2725
2726 return gain;
2727}
2728
2730{
2731 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
2733 return victim;
2734
2736 for (Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
2737 {
2738 if (Unit* magnet = (*itr)->GetBase()->GetCaster())
2739 if (spellInfo->CheckExplicitTarget(this, magnet) == SpellCastResult::SPELL_CAST_OK
2740 && spellInfo->CheckTarget(this, magnet, false) == SpellCastResult::SPELL_CAST_OK
2741 && _IsValidAttackTarget(magnet, spellInfo))
2742 {
2744 (*itr)->GetBase()->DropCharge(AURA_REMOVE_BY_EXPIRE);
2745 return magnet;
2746 }
2747 }
2748 return victim;
2749}
2750
2752{
2754 for (AuraEffectList::const_iterator i = hitTriggerAuras.begin(); i != hitTriggerAuras.end(); ++i)
2755 {
2756 if (Unit* magnet = (*i)->GetBase()->GetCaster())
2757 if (_IsValidAttackTarget(magnet, spellInfo) && magnet->IsWithinLOSInMap(this)
2758 && (!spellInfo || (spellInfo->CheckExplicitTarget(this, magnet) == SpellCastResult::SPELL_CAST_OK
2759 && spellInfo->CheckTarget(this, magnet, false) == SpellCastResult::SPELL_CAST_OK)))
2760 if (roll_chance_i((*i)->GetAmount()))
2761 {
2762 (*i)->GetBase()->DropCharge(AURA_REMOVE_BY_EXPIRE);
2763 return magnet;
2764 }
2765 }
2766 return victim;
2767}
2768
2770{
2771 // Sequence: charmed, pet, other guardians
2772 Unit* unit = GetCharm();
2773 if (!unit)
2774 if (uint64 guid = GetPetGUID())
2775 unit = ObjectAccessor::GetUnit(*this, guid);
2776 if (!unit)
2777 if (uint64 guid = GetMinionGUID())
2778 unit = ObjectAccessor::GetUnit(*this, guid);
2779
2780 return unit;
2781}
2782
2784{
2785 // possessed pet and vehicle
2788
2789 while (!m_Controlled.empty())
2790 {
2791 Unit* target = *m_Controlled.begin();
2792 m_Controlled.erase(m_Controlled.begin());
2793 if (target->GetCharmerGUID() == GetGUID())
2794 target->RemoveCharmAuras();
2795 else if (target->GetOwnerGUID() == GetGUID() && target->IsSummon())
2796 target->ToTempSummon()->UnSummon();
2797 else
2798 SF_LOG_ERROR("entities.unit", "Unit %u is trying to release unit %u which is neither charmed nor owned by it", GetEntry(), target->GetEntry());
2799 }
2800 if (GetPetGUID())
2801 SF_LOG_FATAL("entities.unit", "Unit %u is not able to release its pet " UI64FMTD, GetEntry(), GetPetGUID());
2802 if (GetMinionGUID())
2803 SF_LOG_FATAL("entities.unit", "Unit %u is not able to release its minion " UI64FMTD, GetEntry(), GetMinionGUID());
2804 if (GetCharmGUID())
2805 SF_LOG_FATAL("entities.unit", "Unit %u is not able to release its charm " UI64FMTD, GetEntry(), GetCharmGUID());
2806}
2807
2812
2814{
2815 return u->isPossessed() && GetCharmGUID() == u->GetGUID();
2816}
2817
2819{
2820 if (Unit* u = GetCharm())
2821 return u->isPossessed();
2822 else
2823 return false;
2824}
2825
2827{
2828 Player* player = NULL;
2830 player = ToPlayer();
2831 // Should we enable this also for charmed units?
2832 else if (GetTypeId() == TypeID::TYPEID_UNIT && ToCreature()->IsPet())
2833 player = GetOwner()->ToPlayer();
2834
2835 if (!player)
2836 return NULL;
2837 Group* group = player->GetGroup();
2838 // When there is no group check pet presence
2839 if (!group)
2840 {
2841 // We are pet now, return owner
2842 if (player != this)
2843 return IsWithinDistInMap(player, radius) ? player : NULL;
2844 Unit* pet = GetGuardianPet();
2845 // No pet, no group, nothing to return
2846 if (!pet)
2847 return NULL;
2848 // We are owner now, return pet
2849 return IsWithinDistInMap(pet, radius) ? pet : NULL;
2850 }
2851
2852 std::vector<Unit*> nearMembers;
2853 // reserve place for players and pets because resizing vector every unit push is unefficient (vector is reallocated then)
2854 nearMembers.reserve(group->GetMembersCount() * 2);
2855
2856 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
2857 if (Player* Target = itr->GetSource())
2858 {
2859 // IsHostileTo check duel and controlled by enemy
2860 if (Target != this && Target->IsAlive() && IsWithinDistInMap(Target, radius) && !IsHostileTo(Target))
2861 nearMembers.push_back(Target);
2862
2863 // Push player's pet to vector
2864 if (Unit* pet = Target->GetGuardianPet())
2865 if (pet != this && pet->IsAlive() && IsWithinDistInMap(pet, radius) && !IsHostileTo(pet))
2866 nearMembers.push_back(pet);
2867 }
2868
2869 if (nearMembers.empty())
2870 return NULL;
2871
2872 uint32 randTarget = std::rand() % nearMembers.size();
2873 return nearMembers[randTarget];
2874}
2875
2876// only called in Player::SetSeer
2877// so move it to Player?
2879{
2880 if (m_sharedVision.empty())
2881 {
2882 setActive(true);
2883 SetWorldObject(true);
2884 }
2885 m_sharedVision.push_back(player);
2886}
2887
2888// only called in Player::SetSeer
2890{
2891 m_sharedVision.remove(player);
2892 if (m_sharedVision.empty())
2893 {
2894 setActive(false);
2895 SetWorldObject(false);
2896 }
2897}
2898
2903
2911
2913{
2914 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
2915 {
2916 if (!m_SummonSlot[i])
2917 continue;
2918
2919 if (Creature* OldTotem = GetMap()->GetCreature(m_SummonSlot[i]))
2920 if (OldTotem->IsSummon())
2921 OldTotem->ToTempSummon()->UnSummon();
2922 }
2923}
2924
2925void Unit::SendHealSpellLog(ObjectGuid CasterGUID, ObjectGuid TargetGUID, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical)
2926{
2927 WorldPacket data(SMSG_SPELL_HEAL_LOG, 8 + 8 + 4 + 4 + 4 + 4 + 1 + 1 + 1 /*+ SpellCastLogData.size()*/);
2928 data << uint32(SpellID); // SpellID
2929 data << uint32(Absorb); // Absorb
2930 data << uint32(Damage); // Health
2931 data << uint32(OverHeal); // OverHeal
2932 data.WriteGuidMask(TargetGUID, 0);
2933 data.WriteGuidMask(CasterGUID, 2, 6);
2934 data.WriteGuidMask(TargetGUID, 2);
2935 data.WriteBit(critical); // Crit
2936 data.WriteGuidMask(CasterGUID, 3, 0, 5);
2937 data.WriteGuidMask(TargetGUID, 3);
2938 data.WriteBit(0); // SpellCastLogData
2939 data.WriteGuidMask(TargetGUID, 7, 5);
2940 data.WriteGuidMask(CasterGUID, 7);
2941 data.WriteGuidMask(TargetGUID, 4);
2942 //if (SpellCastLogData ) Write 21Bits
2943 data.WriteBit(0); // CritRollMade
2944 data.WriteBit(0); // CritRollNeeded
2945 data.WriteGuidMask(CasterGUID, 4, 1);
2946 data.WriteGuidMask(TargetGUID, 1, 6);
2947 data.FlushBits();
2948 //if (SpellCastLogData )
2949 data.WriteGuidBytes(CasterGUID, 2);
2950 data.WriteGuidBytes(TargetGUID, 6);
2951 data.WriteGuidBytes(CasterGUID, 5, 3);
2952 data.WriteGuidBytes(TargetGUID, 7);
2953 //if (88) Float CritRollNeeded
2954 data.WriteGuidBytes(CasterGUID, 7, 6, 1);
2955 data.WriteGuidBytes(TargetGUID, 2, 4, 3, 0, 5);
2956 data.WriteGuidBytes(CasterGUID, 0);
2957 //if (72) Float CritRollMade
2958 data.WriteGuidBytes(TargetGUID, 1);
2959 data.WriteGuidBytes(CasterGUID, 4);
2960 SendMessageToSet(&data, true);
2961}
2962
2963int32 Unit::HealBySpell(Unit* victim, SpellInfo const* spellInfo, uint32 addHealth, bool critical)
2964{
2965 uint32 absorb = 0;
2966 // calculate heal absorb and reduce healing
2967 CalcHealAbsorb(victim, spellInfo, addHealth, absorb);
2968
2969 int32 gain = DealHeal(victim, addHealth);
2970 SendHealSpellLog(GetObjectGUID(), victim->GetObjectGUID(), spellInfo->Id, addHealth, uint32(addHealth - gain), absorb, critical);
2971 return gain;
2972}
2973
2974void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellId, int32 damage, Powers powerType)
2975{
2976 //bool hasPower = false;
2977 ObjectGuid victimGuid = victim->GetGUID();
2978 ObjectGuid casterGuid = GetGUID();
2979
2980 WorldPacket data(SMSG_SPELL_ENERGIZE_LOG, (8 + 8 + 4 + 4 + 4 + 1));
2981
2982 data.WriteBit(victimGuid[7]);
2983 data.WriteBit(victimGuid[3]);
2984 data.WriteBit(casterGuid[1]);
2985 data.WriteBit(victimGuid[4]);
2986 data.WriteBit(victimGuid[2]);
2987 data.WriteBit(casterGuid[3]);
2988 data.WriteBit(victimGuid[5]);
2989
2990 data.WriteBit(0); // hasPower
2991
2992 data.WriteBit(casterGuid[7]);
2993 data.WriteBit(casterGuid[0]);
2994 data.WriteBit(casterGuid[2]);
2995
2996 //if (hasPower)
2997 // data.WriteBits(count, 21);
2998
2999 data.WriteBit(casterGuid[4]);
3000 data.WriteBit(casterGuid[6]);
3001 data.WriteBit(victimGuid[6]);
3002 data.WriteBit(victimGuid[1]);
3003 data.WriteBit(victimGuid[0]);
3004 data.WriteBit(casterGuid[5]);
3005
3006 data.FlushBits();
3007
3008 data.WriteByteSeq(victimGuid[0]);
3009 data.WriteByteSeq(casterGuid[5]);
3010 data.WriteByteSeq(victimGuid[6]);
3011
3012 /*if (hasPower)
3013 {
3014 data << UInt32();
3015
3016 for (var i = 0; i < count; ++i)
3017 {
3018 data << Int32();
3019 data << Int32();
3020 }
3021 data << Int32();
3022 data << Int32();
3023 }*/
3024 data.WriteByteSeq(casterGuid[6]);
3025 data.WriteByteSeq(victimGuid[2]);
3026 data.WriteByteSeq(casterGuid[0]);
3027 data.WriteByteSeq(victimGuid[1]);
3028 data << int32(damage);
3029 data.WriteByteSeq(victimGuid[4]);
3030 data.WriteByteSeq(casterGuid[1]);
3031 data.WriteByteSeq(casterGuid[7]);
3032 data.WriteByteSeq(victimGuid[5]);
3033 data.WriteByteSeq(casterGuid[2]);
3034 data.WriteByteSeq(casterGuid[3]);
3035 data.WriteByteSeq(victimGuid[7]);
3036 data.WriteByteSeq(casterGuid[4]);
3037 data.WriteByteSeq(victimGuid[3]);
3038 data << uint32(spellId);
3039
3040 data << uint32(powerType);
3041
3042 SendMessageToSet(&data, true);
3043}
3044
3045void Unit::EnergizeBySpell(Unit* victim, uint32 spellId, int32 damage, Powers powerType)
3046{
3047 SendEnergizeSpellLog(victim, spellId, damage, powerType);
3048 // needs to be called after sending spell log
3049 victim->ModifyPower(powerType, damage);
3050
3051 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
3052 victim->getHostileRefManager().threatAssist(this, float(damage) * 0.5f, spellInfo);
3053}
3054
3056{
3058 {
3060 if (overrideSP > 0.0f)
3062 }
3063
3064 int32 DoneAdvertisedBenefit = 0;
3065
3067 for (AuraEffectList::const_iterator i = mDamageDone.begin(); i != mDamageDone.end(); ++i)
3068 if (((*i)->GetMiscValue() & schoolMask) != 0 &&
3069 (*i)->GetSpellInfo()->EquippedItemClass == -1 &&
3070 // -1 == any item class (not wand then)
3071 (*i)->GetSpellInfo()->EquippedItemInventoryTypeMask == 0)
3072 // 0 == any inventory type (not wand then)
3073 DoneAdvertisedBenefit += (*i)->GetAmount();
3074
3076 {
3077 // Base value
3078 DoneAdvertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus();
3079
3080 // Check if we are ever using mana - PaperDollFrame.lua
3082 DoneAdvertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect
3083
3084 // Damage bonus from stats
3086 for (AuraEffectList::const_iterator i = mDamageDoneOfStatPercent.begin(); i != mDamageDoneOfStatPercent.end(); ++i)
3087 {
3088 if ((*i)->GetMiscValue() & schoolMask)
3089 {
3090 // stat used stored in miscValueB for this aura
3091 Stats usedStat = Stats((*i)->GetMiscValueB());
3092 DoneAdvertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount()));
3093 }
3094 }
3095 }
3096 return DoneAdvertisedBenefit;
3097}
3098
3100{
3101 int32 TakenAdvertisedBenefit = 0;
3102
3104 for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
3105 if (((*i)->GetMiscValue() & schoolMask) != 0)
3106 TakenAdvertisedBenefit += (*i)->GetAmount();
3107
3108 return TakenAdvertisedBenefit;
3109}
3110
3111bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const
3112{
3115 if (IS_CREATURE_GUID(GetGUID()) && !(IsTotem() && IS_PLAYER_GUID(GetOwnerGUID())) && GetEntry() != 15438)
3116 return false;
3117
3118 // not critting spell
3119 if ((spellProto->AttributesEx2 & SPELL_ATTR2_CANT_CRIT))
3120 return false;
3121
3122 float crit_chance = 0.0f;
3123 switch (spellProto->DmgClass)
3124 {
3126 {
3127 // We need more spells to find a general way (if there is any)
3128 switch (spellProto->Id)
3129 {
3130 case 379: // Earth Shield
3131 case 33778: // Lifebloom Final Bloom
3132 case 64844: // Divine Hymn
3133 case 71607: // Item - Bauble of True Blood 10m
3134 case 71646: // Item - Bauble of True Blood 25m
3135 break;
3136 default:
3137 return false;
3138 }
3139 break;
3140 }
3142 {
3143 if (schoolMask & SPELL_SCHOOL_MASK_NORMAL)
3144 crit_chance = 0.0f;
3145 // For other schools
3146 else if (GetTypeId() == TypeID::TYPEID_PLAYER)
3148 else
3149 crit_chance = (float)m_baseSpellCritChance;
3150
3151 // taken
3152 if (victim)
3153 {
3154 if (!spellProto->IsPositive())
3155 {
3156 // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
3158 // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
3160 }
3161 // scripted (increase crit chance ... against ... target by x%
3163 for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
3164 {
3165 if (!((*i)->IsAffectingSpell(spellProto)))
3166 continue;
3167
3168 switch ((*i)->GetMiscValue())
3169 {
3170 // Shatter // 5.4.8
3171 case 911:
3172 if (victim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
3173 ApplyPct(crit_chance, (*i)->GetAmount() * 25);
3174 break;
3175 default:
3176 break;
3177 }
3178 }
3179 // Custom crit by class
3180 switch (spellProto->SpellFamilyName)
3181 {
3182 case SPELLFAMILY_MAGE:
3183 {
3184 // Glyph of Fire Blast
3185 if (spellProto->SpellFamilyFlags[0] == 0x2 && spellProto->SpellIconID == 12)
3186 if (victim->HasAuraWithMechanic((1 << MECHANIC_STUN) | (1 << MECHANIC_KNOCKOUT)))
3187 if (AuraEffect const* aurEff = GetAuraEffect(56369, EFFECT_0))
3188 crit_chance += aurEff->GetAmount();
3189 break;
3190 }
3191 case SPELLFAMILY_DRUID:
3192 {
3193 // Improved Faerie Fire
3195 if (AuraEffect const* aurEff = GetDummyAuraEffect(SPELLFAMILY_DRUID, 109, 0))
3196 crit_chance += aurEff->GetAmount();
3197
3198 // cumulative effect - don't break
3199
3200 // Starfire
3201 if (spellProto->SpellFamilyFlags[0] & 0x4 && spellProto->SpellIconID == 1485)
3202 {
3203 // Improved Insect Swarm
3204 if (AuraEffect const* aurEff = GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
3205 if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00000002, 0, 0))
3206 crit_chance += aurEff->GetAmount();
3207 }
3208 break;
3209 }
3210 case SPELLFAMILY_ROGUE:
3211 {
3212 // Shiv-applied poisons can't crit
3213 if (FindCurrentSpellBySpellId(5938))
3214 crit_chance = 0.0f;
3215 break;
3216 }
3218 {
3219 // Flash of light
3220 if (spellProto->SpellFamilyFlags[0] & 0x40000000)
3221 {
3222 // Sacred Shield
3223 if (AuraEffect const* aura = victim->GetAuraEffect(58597, 1, GetGUID()))
3224 crit_chance += aura->GetAmount();
3225 break;
3226 }
3227 // Exorcism
3228 else if (spellProto->GetCategory() == 19)
3229 {
3231 return true;
3232 break;
3233 }
3234 break;
3235 }
3236 case SPELLFAMILY_SHAMAN:
3237 {
3238 // Lava Burst
3239 if (spellProto->SpellFamilyFlags[1] & 0x00001000)
3240 {
3241 if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0, 0, GetGUID()))
3243 return true;
3244 break;
3245 }
3246 break;
3247 }
3248 }
3249 }
3250 break;
3251 }
3253 {
3254 if (victim)
3255 {
3256 // Custom crit by class
3257 switch (spellProto->SpellFamilyName)
3258 {
3260 {
3261 // bloodthirst double crit chance
3262 if (spellProto->SpellFamilyFlags[1] & 0x00000400
3263 && spellProto->SpellIconID == 38)
3264 {
3265 crit_chance += (GetUnitCriticalChance(attackType, victim) * 2.0f);
3266 break;
3267 }
3268 break;
3269 }
3270 case SPELLFAMILY_DRUID:
3271 {
3272 // Rend and Tear - bonus crit chance for Ferocious Bite on bleeding targets
3273 if (spellProto->SpellFamilyFlags[0] & 0x00800000
3274 && spellProto->SpellIconID == 1680
3276 {
3277 if (AuraEffect const* rendAndTear = GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 1))
3278 crit_chance += rendAndTear->GetAmount();
3279 }
3280 break;
3281 }
3282 }
3283 crit_chance += GetUnitCriticalChance(attackType, victim);
3284 }
3285 break;
3286 }
3287 // Calculate critical strike chance for both Ranged and Melee spells
3289 {
3290 if (victim)
3291 crit_chance += GetUnitCriticalChance(attackType, victim);
3292 break;
3293 }
3294 default:
3295 return false;
3296 }
3297 // percent done
3298 // only players use intelligence for critical chance computations
3299 if (Player* modOwner = GetSpellModOwner())
3300 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance);
3301
3302 if (victim)
3303 {
3305 for (AuraEffectList::const_iterator i = critAuras.begin(); i != critAuras.end(); ++i)
3306 if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectingSpell(spellProto))
3307 crit_chance += (*i)->GetAmount();
3308 }
3309
3310 crit_chance = crit_chance > 0.0f ? crit_chance : 0.0f;
3311 if (roll_chance_f(crit_chance))
3312 return true;
3313 return false;
3314}
3315
3316uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* /*victim*/)
3317{
3318 // Calculate critical bonus
3319 int32 crit_bonus = damage;
3320 float crit_mod = 0.0f;
3321
3322 switch (spellProto->DmgClass)
3323 {
3324 case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100%
3327 crit_bonus += damage;
3328 break;
3329 default:
3330 crit_bonus += damage / 2; // for spells is 50%
3331 break;
3332 }
3333
3334 crit_mod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellProto->GetSchoolMask()) - 1.0f) * 100;
3335
3336 if (crit_bonus != 0)
3337 AddPct(crit_bonus, crit_mod);
3338
3339 crit_bonus -= damage;
3340
3341 if (damage > uint32(crit_bonus))
3342 {
3343 // adds additional damage to critBonus (from talents)
3344 if (Player* modOwner = GetSpellModOwner())
3345 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
3346 }
3347
3348 crit_bonus += damage;
3349
3350 return crit_bonus;
3351}
3352
3353uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* /*spellProto*/, uint32 damage, Unit* /*victim*/)
3354{
3355 // Calculate critical bonus
3356 int32 crit_bonus = damage;
3357
3358 damage += crit_bonus;
3359
3361
3362 return damage;
3363}
3364
3366{
3368 {
3370 if (overrideSP > 0.0f)
3372 }
3373
3374 int32 advertisedBenefit = 0;
3375
3377 for (AuraEffectList::const_iterator i = mHealingDone.begin(); i != mHealingDone.end(); ++i)
3378 if (!(*i)->GetMiscValue() || ((*i)->GetMiscValue() & schoolMask) != 0)
3379 advertisedBenefit += (*i)->GetAmount();
3380
3381 // Healing bonus of spirit, intellect and strength
3383 {
3384 // Base value
3385 advertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus();
3386
3387 // Check if we are ever using mana - PaperDollFrame.lua
3389 advertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect
3390
3391 // Healing bonus from stats
3393 for (AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i)
3394 {
3395 // stat used dependent from misc value (stat index)
3396 Stats usedStat = Stats((*i)->GetSpellInfo()->Effects[(*i)->GetEffIndex()].MiscValue);
3397 advertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount()));
3398 }
3399 }
3400 return advertisedBenefit;
3401}
3402
3404{
3405 int32 advertisedBenefit = 0;
3406
3408 for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
3409 if (((*i)->GetMiscValue() & schoolMask) != 0)
3410 advertisedBenefit += (*i)->GetAmount();
3411
3412 return advertisedBenefit;
3413}
3414
3416{
3417 // If m_immuneToSchool type contain this school type, IMMUNE damage.
3418 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
3419 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
3420 if (itr->type & shoolMask)
3421 return true;
3422
3423 // If m_immuneToDamage type contain magic, IMMUNE damage.
3424 SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
3425 for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
3426 if (itr->type & shoolMask)
3427 return true;
3428
3429 return false;
3430}
3431
3432bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo) const
3433{
3435 return false;
3436
3437 uint32 shoolMask = spellInfo->GetSchoolMask();
3438 if (spellInfo->Id != 42292 && spellInfo->Id != 59752)
3439 {
3440 // If m_immuneToSchool type contain this school type, IMMUNE damage.
3441 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
3442 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
3443 if (itr->type & shoolMask && !spellInfo->CanPierceImmuneAura(sSpellMgr->GetSpellInfo(itr->spellId)))
3444 return true;
3445 }
3446
3447 // If m_immuneToDamage type contain magic, IMMUNE damage.
3448 SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
3449 for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
3450 if (itr->type & shoolMask)
3451 return true;
3452
3453 return false;
3454}
3455
3456bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) const
3457{
3458 if (!spellInfo)
3459 return false;
3460
3461 // Single spell immunity.
3462 SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
3463 for (SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
3464 if (itr->type == spellInfo->Id)
3465 return true;
3466
3468 return false;
3469
3470 if (spellInfo->Dispel)
3471 {
3472 SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
3473 for (SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
3474 if (itr->type == spellInfo->Dispel)
3475 return true;
3476 }
3477
3478 // Spells that don't have effectMechanics.
3479 if (spellInfo->Mechanic)
3480 {
3481 SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
3482 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
3483 if (itr->type == spellInfo->Mechanic)
3484 return true;
3485 }
3486
3487 bool immuneToAllEffects = true;
3488 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3489 {
3490 // State/effect immunities applied by aura expect full spell immunity
3491 // Ignore effects with mechanic, they are supposed to be checked separately
3492 if (!spellInfo->Effects[i].IsEffect())
3493 continue;
3494 if (!IsImmunedToSpellEffect(spellInfo, i))
3495 {
3496 immuneToAllEffects = false;
3497 break;
3498 }
3499 }
3500
3501 if (immuneToAllEffects) //Return immune only if the target is immune to all spell effects.
3502 return true;
3503
3504 if (spellInfo->Id != 42292 && spellInfo->Id != 59752)
3505 {
3506 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
3507 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
3508 {
3509 SpellInfo const* immuneSpellInfo = sSpellMgr->GetSpellInfo(itr->spellId);
3510 if ((itr->type & spellInfo->GetSchoolMask())
3511 && !(immuneSpellInfo && immuneSpellInfo->IsPositive() && spellInfo->IsPositive())
3512 && !spellInfo->CanPierceImmuneAura(immuneSpellInfo))
3513 return true;
3514 }
3515 }
3516
3517 return false;
3518}
3519
3520bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
3521{
3522 if (!spellInfo || !spellInfo->Effects[index].IsEffect())
3523 return false;
3524
3525 // If m_immuneToEffect type contain this effect type, IMMUNE effect.
3526 uint32 effect = spellInfo->Effects[index].Effect;
3527 SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
3528 for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
3529 if (itr->type == effect)
3530 return true;
3531
3532 if (uint32 mechanic = spellInfo->Effects[index].Mechanic)
3533 {
3534 SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
3535 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
3536 if (itr->type == mechanic)
3537 return true;
3538 }
3539
3540 if (uint32 aura = spellInfo->Effects[index].ApplyAuraName)
3541 {
3543 for (SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
3544 if (itr->type == aura)
3545 if (!(spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT))
3546 return true;
3547
3548 // Check for immune to application of harmful magical effects
3550 for (AuraEffectList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
3551 if (spellInfo->Dispel == DISPEL_MAGIC && // Magic debuff
3552 ((*iter)->GetMiscValue() & spellInfo->GetSchoolMask()) && // Check school
3553 !spellInfo->IsPositiveEffect(index)) // Harmful
3554 return true;
3555 }
3556
3557 return false;
3558}
3559
3561{
3562 uint32 mask = 0;
3563 SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
3564 for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
3565 mask |= itr->type;
3566
3567 return mask;
3568}
3569
3571{
3572 uint32 mask = 0;
3573 SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
3574 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
3575 mask |= (1 << itr->type);
3576
3577 return mask;
3578}
3579
3580void Unit::ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
3581{
3582 if (apply)
3583 {
3584 for (SpellImmuneList::iterator itr = m_spellImmune[op].begin(), next; itr != m_spellImmune[op].end(); itr = next)
3585 {
3586 next = itr; ++next;
3587 if (itr->type == type)
3588 {
3589 m_spellImmune[op].erase(itr);
3590 next = m_spellImmune[op].begin();
3591 }
3592 }
3593 SpellImmune Immune;
3594 Immune.spellId = spellId;
3595 Immune.type = type;
3596 m_spellImmune[op].push_back(Immune);
3597 }
3598 else
3599 {
3600 for (SpellImmuneList::iterator itr = m_spellImmune[op].begin(); itr != m_spellImmune[op].end(); ++itr)
3601 {
3602 if (itr->spellId == spellId && itr->type == type)
3603 {
3604 m_spellImmune[op].erase(itr);
3605 break;
3606 }
3607 }
3608 }
3609}
3610
3611void Unit::ApplySpellDispelImmunity(const SpellInfo* spellProto, DispelType type, bool apply)
3612{
3613 ApplySpellImmune(spellProto->Id, IMMUNITY_DISPEL, type, apply);
3614
3615 if (apply && spellProto->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
3616 {
3617 // Create dispel mask by dispel type
3618 uint32 dispelMask = SpellInfo::GetDispelMask(type);
3619 // Dispel all existing auras vs current dispel type
3621 for (AuraApplicationMap::iterator itr = auras.begin(); itr != auras.end();)
3622 {
3623 SpellInfo const* spell = itr->second->GetBase()->GetSpellInfo();
3624 if (spell->GetDispelMask() & dispelMask)
3625 {
3626 // Dispel aura
3627 RemoveAura(itr);
3628 }
3629 else
3630 ++itr;
3631 }
3632 }
3633}
3634
3635void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
3636{
3637 if (mount)
3639
3641
3642 if (Player* player = ToPlayer())
3643 {
3644 // mount as a vehicle
3645 if (VehicleId)
3646 {
3647 if (CreateVehicleKit(VehicleId, creatureEntry))
3648 {
3649 player->SendOnCancelExpectedVehicleRideAura();
3650
3651 // mounts can also have accessories
3653 }
3654 }
3655
3656 // unsummon pet
3657 Pet* pet = player->GetPet();
3658 if (pet)
3659 {
3661 bool hasFlyingMountSpeedAura = false;
3663 if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(GetAuraEffectsByType(SPELL_AURA_MOUNTED).front()->GetAmount()))
3664 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(mountCapability->SpeedModSpell))
3665 hasFlyingMountSpeedAura = spellInfo->HasAura(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED);
3666
3667 if (Skyfire::PetTransport::ShouldTemporarilyUnsummonMountedPet(bg && !bg->isArena(), hasFlyingMountSpeedAura))
3668 player->UnsummonPetTemporaryIfAny();
3669 else if (!player->GetTransport())
3670 {
3672 pet->AI()->EnterEvadeMode();
3673 }
3675 player->GetTransport() != NULL, pet->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED)))
3677 }
3678
3679 player->SendMovementSetCollisionHeight(player->GetCollisionHeight(true));
3680 }
3681
3683}
3684
3686{
3687 if (!IsMounted())
3688 return;
3689
3692
3693 if (Player* thisPlayer = ToPlayer())
3694 thisPlayer->SendMovementSetCollisionHeight(thisPlayer->GetCollisionHeight(false));
3695
3696 ObjectGuid guid = GetGUID();
3697 WorldPacket data(SMSG_DISMOUNT, 8);
3698
3699 data.WriteGuidMask(guid, 6, 3, 0, 7, 1, 2, 5, 4);
3700 data.WriteGuidBytes(guid, 3, 6, 7, 5, 1, 4, 2, 0);
3701
3702 SendMessageToSet(&data, true);
3703
3704 // dismount as a vehicle
3706 {
3707 // Remove vehicle from player
3709 }
3710
3712
3713 // only resummon old pet if the player is already added to a map
3714 // this prevents adding a pet to a not created map which would otherwise cause a crash
3715 // (it could probably happen when logging in after a previous crash)
3716 if (Player* player = ToPlayer())
3717 {
3718 if (Pet* pPet = player->GetPet())
3719 {
3720 if (pPet->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && !pPet->HasUnitState(UNIT_STATE_STUNNED))
3721 pPet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
3722 }
3723 else
3724 player->ResummonPetTemporaryUnSummonedIfAny();
3725 }
3726}
3727
3729{
3730 if (!mountType)
3731 return NULL;
3732
3733 MountTypeEntry const* mountTypeEntry = sMountTypeStore.LookupEntry(mountType);
3734 if (!mountTypeEntry)
3735 return NULL;
3736
3737 uint32 zoneId, areaId;
3738 GetZoneAndAreaId(zoneId, areaId);
3739 uint32 ridingSkill = 5000;
3741 ridingSkill = ToPlayer()->GetSkillValue(SKILL_RIDING);
3742
3743 for (uint32 i = MAX_MOUNT_CAPABILITIES; i > 0; --i)
3744 {
3745 MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(mountTypeEntry->MountCapability[i - 1]);
3746 if (!mountCapability)
3747 continue;
3748
3749 if (ridingSkill < mountCapability->RequiredRidingSkill)
3750 continue;
3751
3753 {
3754 if (!(mountCapability->Flags & MOUNT_FLAG_CAN_PITCH))
3755 continue;
3756 }
3758 {
3759 if (!(mountCapability->Flags & MOUNT_FLAG_CAN_SWIM))
3760 continue;
3761 }
3762 else if (!(mountCapability->Flags & 0x1)) // unknown flags, checked in 4.2.2 14545 client
3763 {
3764 if (!(mountCapability->Flags & 0x2))
3765 continue;
3766 }
3767
3768 if (mountCapability->RequiredMap != -1 && int32(GetMapId()) != mountCapability->RequiredMap)
3769 continue;
3770
3771 if (mountCapability->RequiredArea && (mountCapability->RequiredArea != zoneId && mountCapability->RequiredArea != areaId))
3772 continue;
3773
3774 if (mountCapability->RequiredAura && !HasAura(mountCapability->RequiredAura))
3775 continue;
3776
3777 if (mountCapability->RequiredSpell && (GetTypeId() != TypeID::TYPEID_PLAYER || !ToPlayer()->HasSpell(mountCapability->RequiredSpell)))
3778 continue;
3779
3780 return mountCapability;
3781 }
3782
3783 return NULL;
3784}
3785
3794
3795bool Unit::isTargetableForAttack(bool checkFakeDeath) const
3796{
3797 if (!IsAlive())
3798 return false;
3799
3802 return false;
3803
3804 if (GetTypeId() == TypeID::TYPEID_PLAYER && ToPlayer()->IsGameMaster())
3805 return false;
3806
3807 return !HasUnitState(UNIT_STATE_UNATTACKABLE) && (!checkFakeDeath || !HasUnitState(UNIT_STATE_DIED));
3808}
3809
3810bool Unit::IsValidAttackTarget(Unit const* target) const
3811{
3812 return _IsValidAttackTarget(target, NULL);
3813}
3814
3815// function based on function Unit::CanAttack from 13850 client
3816bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj) const
3817{
3818 ASSERT(target);
3819
3820 // can't attack self
3821 if (this == target)
3822 return false;
3823
3824 // can't attack unattackable units or GMs
3826 || (target->GetTypeId() == TypeID::TYPEID_PLAYER && target->ToPlayer()->IsGameMaster()))
3827 return false;
3828
3829 // can't attack own vehicle or passenger
3830 if (m_vehicle)
3831 if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target))
3832 return false;
3833
3834 // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit.
3835 if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea())))
3836 return false;
3837
3838 // can't attack dead
3839 if ((!bySpell || !bySpell->IsAllowingDeadTarget()) && !target->IsAlive())
3840 return false;
3841
3842 // can't attack untargetable
3843 if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_UNTARGETABLE))
3845 return false;
3846
3847 if (Player const* playerAttacker = ToPlayer())
3848 {
3849 if (playerAttacker->HasFlag(PLAYER_FIELD_PLAYER_FLAGS, PLAYER_FLAGS_UBER))
3850 return false;
3851 }
3852
3853 // check flags
3857 return false;
3858
3859 if ((!bySpell || !(bySpell->AttributesEx8 & SPELL_ATTR8_ATTACK_IGNORE_IMMUNE_TO_PC_FLAG))
3861 // check if this is a world trigger cast - GOs are using world triggers to cast their spells, so we need to ignore their immunity flag here, this is a temp workaround, needs removal when go cast is implemented properly
3862 && GetEntry() != WORLD_TRIGGER)
3863 return false;
3864
3865 // CvC case - can attack each other only when one of them is hostile
3867 return GetReactionTo(target) <= REP_HOSTILE || target->GetReactionTo(this) <= REP_HOSTILE;
3868
3869 // PvP, PvC, CvP case
3870 // can't attack friendly targets
3871 if (GetReactionTo(target) > REP_NEUTRAL
3872 || target->GetReactionTo(this) > REP_NEUTRAL)
3873 return false;
3874
3875 // Not all neutral creatures can be attacked
3876 if (GetReactionTo(target) == REP_NEUTRAL &&
3877 target->GetReactionTo(this) == REP_NEUTRAL)
3878 {
3879 if (!(target->GetTypeId() == TypeID::TYPEID_PLAYER && GetTypeId() == TypeID::TYPEID_PLAYER) &&
3881 {
3882 Player const* player = target->GetTypeId() == TypeID::TYPEID_PLAYER ? target->ToPlayer() : ToPlayer();
3883 Unit const* creature = target->GetTypeId() == TypeID::TYPEID_UNIT ? target : this;
3884
3885 if (FactionTemplateEntry const* factionTemplate = creature->GetFactionTemplateEntry())
3886 {
3887 if (!(player->GetReputationMgr().GetForcedRankIfAny(factionTemplate)))
3888 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplate->faction))
3889 if (FactionState const* repState = player->GetReputationMgr().GetState(factionEntry))
3890 if (!(repState->Flags & FACTION_FLAG_AT_WAR))
3891 return false;
3892 }
3893 }
3894 }
3895
3896 Creature const* creatureAttacker = ToCreature();
3897 if (creatureAttacker && creatureAttacker->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER)
3898 return false;
3899
3900 Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? GetAffectingPlayer() : NULL;
3901 Player const* playerAffectingTarget = target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? target->GetAffectingPlayer() : NULL;
3902
3903 // check duel - before sanctuary checks
3904 if (playerAffectingAttacker && playerAffectingTarget)
3905 if (playerAffectingAttacker->duel && playerAffectingAttacker->duel->opponent == playerAffectingTarget && playerAffectingAttacker->duel->startTime != 0)
3906 return true;
3907
3908 // PvP case - can't attack when attacker or target are in sanctuary
3909 // however, 13850 client doesn't allow to attack when one of the unit's has sanctuary flag and is pvp
3912 return false;
3913
3914 // additional checks - only PvP case
3915 if (playerAffectingAttacker && playerAffectingTarget)
3916 {
3918 return true;
3919
3922 return true;
3923
3926 }
3927 return true;
3928}
3929
3930bool Unit::IsValidAssistTarget(Unit const* target) const
3931{
3932 return _IsValidAssistTarget(target, NULL);
3933}
3934
3935// function based on function Unit::CanAssist from 13850 client
3936bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) const
3937{
3938 ASSERT(target);
3939
3940 // can assist to self
3941 if (this == target)
3942 return true;
3943
3944 // can't assist unattackable units or GMs
3946 || (target->GetTypeId() == TypeID::TYPEID_PLAYER && target->ToPlayer()->IsGameMaster()))
3947 return false;
3948
3949 // can't assist own vehicle or passenger
3950 if (m_vehicle)
3951 if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target))
3952 return false;
3953
3954 // can't assist invisible
3955 if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))
3956 return false;
3957
3958 // can't assist dead
3959 if ((!bySpell || !bySpell->IsAllowingDeadTarget()) && !target->IsAlive())
3960 return false;
3961
3962 // can't assist untargetable
3963 if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_UNTARGETABLE))
3965 return false;
3966
3967 if (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG))
3968 {
3970 {
3972 return false;
3973 }
3974 else
3975 {
3977 return false;
3978 }
3979 }
3980
3981 // can't assist non-friendly targets
3982 if (GetReactionTo(target) <= REP_NEUTRAL
3983 && target->GetReactionTo(this) <= REP_NEUTRAL
3984 && (!ToCreature() || !(ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER)))
3985 return false;
3986
3987 // PvP case
3989 {
3990 Player const* targetPlayerOwner = target->GetAffectingPlayer();
3992 {
3993 Player const* selfPlayerOwner = GetAffectingPlayer();
3994 if (selfPlayerOwner && targetPlayerOwner)
3995 {
3996 // can't assist player which is dueling someone
3997 if (selfPlayerOwner != targetPlayerOwner
3998 && targetPlayerOwner->duel)
3999 return false;
4000 }
4001 // can't assist player in ffa_pvp zone from outside
4004 return false;
4005 // can't assist player out of sanctuary from sanctuary if has pvp enabled
4008 return false;
4009 }
4010 }
4011 // PvC case - player can assist creature only if has specific type flags
4012 // !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) &&
4014 && (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG))
4016 {
4017 if (Creature const* creatureTarget = target->ToCreature())
4018 return creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER || creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_AID_PLAYERS;
4019 }
4020 return true;
4021}
4022
4024{
4025 int32 gain = 0;
4026
4027 if (dVal == 0)
4028 return 0;
4029
4030 int32 curHealth = (int32)GetHealth();
4031
4032 int32 val = dVal + curHealth;
4033 if (val <= 0)
4034 {
4035 SetHealth(0);
4036 return -curHealth;
4037 }
4038
4039 int32 maxHealth = (int32)GetMaxHealth();
4040
4041 if (val < maxHealth)
4042 {
4043 SetHealth(val);
4044 gain = val - curHealth;
4045 }
4046 else if (curHealth != maxHealth)
4047 {
4048 SetHealth(maxHealth);
4049 gain = maxHealth - curHealth;
4050 }
4051
4052 return gain;
4053}
4054
4056{
4057 int32 gain = 0;
4058
4059 if (dVal == 0)
4060 return 0;
4061
4062 int32 curHealth = (int32)GetHealth();
4063
4064 int32 val = dVal + curHealth;
4065 if (val <= 0)
4066 {
4067 return -curHealth;
4068 }
4069
4070 int32 maxHealth = (int32)GetMaxHealth();
4071
4072 if (val < maxHealth)
4073 gain = dVal;
4074 else if (curHealth != maxHealth)
4075 gain = maxHealth - curHealth;
4076
4077 return gain;
4078}
4079
4080// returns negative amount on power reduction
4082{
4083 int32 gain = 0;
4084
4085 if (dVal == 0)
4086 return 0;
4087
4088 int32 curPower = GetPower(power);
4089
4090 int32 val = dVal + curPower;
4091 if (val <= GetMinPower(power))
4092 {
4093 SetPower(power, GetMinPower(power));
4094 return -curPower;
4095 }
4096
4097 int32 maxPower = GetMaxPower(power);
4098
4099 if (val < maxPower)
4100 {
4101 SetPower(power, val);
4102 gain = val - curPower;
4103 }
4104 else if (curPower != maxPower)
4105 {
4106 SetPower(power, maxPower);
4107 gain = maxPower - curPower;
4108 }
4109
4110 return gain;
4111}
4112
4113// returns negative amount on power reduction
4114int32 Unit::ModifyPowerPct(Powers power, float pct, bool apply)
4115{
4116 float amount = (float)GetMaxPower(power);
4117 ApplyPercentModFloatVar(amount, pct, apply);
4118
4119 return ModifyPower(power, (int32)amount - GetMaxPower(power));
4120}
4121
4123{
4124 float f_BaseAttackTime = GetFloatValue(UNIT_FIELD_ATTACK_ROUND_BASE_TIME + uint8(att)) / m_modAttackSpeedPct[uint8(att)];
4125 return (uint32)f_BaseAttackTime;
4126}
4127
4129{
4131 return true;
4132
4133 // Always seen by owner
4134 if (uint64 guid = GetCharmerOrOwnerGUID())
4135 if (seer->GetGUID() == guid)
4136 return true;
4137
4138 if (Player const* seerPlayer = seer->ToPlayer())
4139 if (Unit* owner = GetOwner())
4140 if (Player* ownerPlayer = owner->ToPlayer())
4141 if (ownerPlayer->IsGroupVisibleFor(seerPlayer))
4142 return true;
4143
4144 return false;
4145}
4146
4148{
4150 return true;
4151
4153 return true;
4154
4155 return false;
4156}
4157
4159{
4161}
4162
4172
4173void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
4174{
4175 int32 main_speed_mod = 0;
4176 float stack_bonus = 1.0f;
4177 float non_stack_bonus = 1.0f;
4178
4179 switch (mtype)
4180 {
4181 // Only apply debuffs
4182 case MOVE_FLIGHT_BACK:
4183 case MOVE_RUN_BACK:
4184 case MOVE_SWIM_BACK:
4185 break;
4186 case MOVE_WALK:
4187 return;
4188 case MOVE_RUN:
4189 {
4190 if (IsMounted()) // Use on mount auras
4191 {
4195 }
4196 else
4197 {
4201 }
4202 break;
4203 }
4204 case MOVE_SWIM:
4205 {
4207 break;
4208 }
4209 case MOVE_FLIGHT:
4210 {
4211 if (GetTypeId() == TypeID::TYPEID_UNIT && IsControlledByPlayer()) // not sure if good for pet
4212 {
4215
4216 // for some spells this mod is applied on vehicle owner
4217 int32 owner_speed_mod = 0;
4218
4219 if (Unit* owner = GetCharmer())
4220 owner_speed_mod = owner->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED);
4221
4222 main_speed_mod = std::max(main_speed_mod, owner_speed_mod);
4223 }
4224 else if (IsMounted())
4225 {
4228 }
4229 else // Use not mount (shapeshift for example) auras (should stack)
4231
4233
4234 // Update speed for vehicle if available
4237 break;
4238 }
4239 default:
4240 SF_LOG_ERROR("entities.unit", "Unit::UpdateSpeed: Unsupported move type (%d)", mtype);
4241 return;
4242 }
4243
4244 // now we ready for speed calculation
4245 float speed = std::max(non_stack_bonus, stack_bonus);
4246 if (main_speed_mod)
4247 AddPct(speed, main_speed_mod);
4248
4249 switch (mtype)
4250 {
4251 case MOVE_RUN:
4252 case MOVE_SWIM:
4253 case MOVE_FLIGHT:
4254 {
4255 // Set creature speed rate
4257 {
4258 Unit* pOwner = GetCharmerOrOwner();
4259 if ((IsPet() || IsGuardian()) && !IsInCombat() && pOwner) // Must check for owner or crash on "Tame Beast"
4260 {
4261 // For every yard over 5, increase speed by 0.01
4262 // to help prevent pet from lagging behind and despawning
4263 float dist = GetDistance(pOwner);
4264 float base_rate = 1.00f; // base speed is 100% of owner speed
4265
4266 if (dist < 5)
4267 dist = 5;
4268
4269 float mult = base_rate + ((dist - 5) * 0.01f);
4270
4271 speed *= pOwner->GetSpeedRate(mtype) * mult; // pets derive speed from owner when not in combat
4272 }
4273 else
4274 speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
4275 }
4276
4277 // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
4280 {
4281 // Use speed from aura
4282 float max_speed = normalization / (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]);
4283 if (speed > max_speed)
4284 speed = max_speed;
4285 }
4286 break;
4287 }
4288 default:
4289 break;
4290 }
4291
4292 // for creature case, we check explicit if mob searched for assistance
4294 {
4295 if (ToCreature()->HasSearchedAssistance())
4296 speed *= 0.66f; // best guessed value, so this will be 33% reduction. Based off initial speed, mob can then "run", "walk fast" or "walk".
4297 }
4298
4299 // Apply strongest slow aura mod to speed
4301 if (slow)
4302 AddPct(speed, slow);
4303
4304 if (float minSpeedMod = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MINIMUM_SPEED))
4305 {
4306 float min_speed = minSpeedMod / 100.0f;
4307 if (speed < min_speed)
4308 speed = min_speed;
4309 }
4310 SetSpeed(mtype, speed, forced);
4311}
4312
4314{
4315 return m_speed_rate[mtype] * (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]);
4316}
4317
4318void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
4319{
4320 if (rate < 0)
4321 rate = 0.0f;
4322
4323 // Update speed only on change
4324 if (m_speed_rate[mtype] == rate)
4325 return;
4326
4327 m_speed_rate[mtype] = rate;
4328
4330
4331 static Opcodes const moveTypeToOpcode[MAX_MOVE_TYPE][3] =
4332 {
4342 };
4343
4345 {
4346 // register forced speed changes for WorldSession::HandleForceSpeedChangeAck
4347 // and do it only for real sent packets and use run for run/mounted as client expected
4348 ++ToPlayer()->m_forced_speed_changes[mtype];
4349
4350 if (!IsInCombat())
4351 if (Pet* pet = ToPlayer()->GetPet())
4352 pet->SetSpeed(mtype, m_speed_rate[mtype], forced);
4353 }
4354
4355 if (IsInWorld())
4356 {
4357 static MovementStatusElements const speedVal = MSEExtraFloat;
4358 Movement::ExtraMovementStatusElement extra(&speedVal);
4359 extra.Data.floatData = GetSpeed(mtype);
4360
4361 Movement::PacketSender(this, moveTypeToOpcode[mtype][0], moveTypeToOpcode[mtype][1], moveTypeToOpcode[mtype][2], &extra).Send();
4362 }
4363}
4364
4366{
4368 {
4369 CombatStop();
4372 ClearComboPointHolders(); // any combo points pointed to unit lost at it death
4373
4374 if (IsNonMeleeSpellCasted(false))
4376
4377 ExitVehicle(); // Exit vehicle before calling RemoveAllControlled
4378 // vehicles use special type of charm that is not removed by the next function
4379 // triggering an assert
4383 }
4384
4385 if (s == DeathState::JUST_DIED)
4386 {
4389 // remove aurastates allowing special moves
4392 if (IsInWorld())
4393 {
4394 // Only clear MotionMaster for entities that exists in world
4395 // Avoids crashes in the following conditions :
4396 // * Using 'call pet' on dead pets
4397 // * Using 'call stabled pet'
4398 // * Logging in with dead pets
4399 GetMotionMaster()->Clear(false);
4401 }
4402 StopMoving();
4403 DisableSpline();
4404 // without this when removing IncreaseMaxHealth aura player may stuck with 1 hp
4405 // do not why since in IncreaseMaxHealth currenthealth is checked
4406 SetHealth(0);
4407 SetPower(getPowerType(), 0);
4408
4409 // players in instance don't have ZoneScript, but they have InstanceScript
4410 if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : GetInstanceScript())
4411 zoneScript->OnUnitDeath(this);
4412 }
4413 else if (s == DeathState::JUST_RESPAWNED)
4414 RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground)
4415
4416 m_deathState = s;
4417}
4418
4419/*########################################
4420######## ########
4421######## AGGRO SYSTEM ########
4422######## ########
4423########################################*/
4425{
4426 // only creatures can have threat list
4428 return false;
4429
4430 // only alive units can have threat list
4431 if (!IsAlive() || isDying())
4432 return false;
4433
4434 // totems can not have threat list
4435 if (ToCreature()->IsTotem())
4436 return false;
4437
4438 // vehicles can not have threat list
4439 //if (ToCreature()->IsVehicle())
4440 // return false;
4441
4442 // summons can not have a threat list, unless they are controlled by a creature
4444 return false;
4445
4446 return true;
4447}
4448
4449//======================================================================
4450
4451float Unit::ApplyTotalThreatModifier(float fThreat, SpellSchoolMask schoolMask)
4452{
4453 if (!HasAuraType(SPELL_AURA_MOD_THREAT) || fThreat < 0)
4454 return fThreat;
4455
4456 SpellSchools school = GetFirstSchoolInMask(schoolMask);
4457
4458 return fThreat * m_threatModifier[school];
4459}
4460
4461//======================================================================
4462
4463void Unit::AddThreat(Unit* victim, float fThreat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
4464{
4465 // Only mobs can manage threat lists
4466 if (CanHaveThreatList())
4467 m_ThreatManager.addThreat(victim, fThreat, schoolMask, threatSpell);
4468}
4469
4470//======================================================================
4471
4473{
4474 if (CanHaveThreatList() && !m_ThreatManager.isThreatListEmpty())
4476 m_ThreatManager.clearReferences();
4477}
4478
4479//======================================================================
4480
4482{
4484
4485 if (!taunter || (taunter->GetTypeId() == TypeID::TYPEID_PLAYER && taunter->ToPlayer()->IsGameMaster()))
4486 return;
4487
4488 if (!CanHaveThreatList())
4489 return;
4490
4491 Creature* creature = ToCreature();
4492
4493 if (creature->HasReactState(REACT_PASSIVE))
4494 return;
4495
4496 Unit* target = GetVictim();
4497 if (target && target == taunter)
4498 return;
4499
4500 SetInFront(taunter);
4501 if (creature->IsAIEnabled)
4502 creature->AI()->AttackStart(taunter);
4503
4504 //m_ThreatManager.tauntApply(taunter);
4505}
4506
4507//======================================================================
4508
4510{
4512
4513 if (!taunter || (taunter->GetTypeId() == TypeID::TYPEID_PLAYER && taunter->ToPlayer()->IsGameMaster()))
4514 return;
4515
4516 if (!CanHaveThreatList())
4517 return;
4518
4519 Creature* creature = ToCreature();
4520
4521 if (creature->HasReactState(REACT_PASSIVE))
4522 return;
4523
4524 Unit* target = GetVictim();
4525 if (!target || target != taunter)
4526 return;
4527
4528 if (m_ThreatManager.isThreatListEmpty())
4529 {
4530 if (creature->IsAIEnabled)
4531 creature->AI()->EnterEvadeMode();
4532 return;
4533 }
4534
4535 target = creature->SelectVictim(); // might have more taunt auras remaining
4536
4537 if (target && target != taunter)
4538 {
4539 SetInFront(target);
4540 if (creature->IsAIEnabled)
4541 creature->AI()->AttackStart(target);
4542 }
4543}
4544
4545//======================================================================
4546
4548{
4549 // function provides main threat functionality
4550 // next-victim-selection algorithm and evade mode are called
4551 // threat list sorting etc.
4552
4553 Unit* target = NULL;
4554 // First checking if we have some taunt on us
4556 if (!tauntAuras.empty())
4557 {
4558 Unit* caster = tauntAuras.back()->GetCaster();
4559
4560 // The last taunt aura caster is alive an we are happy to attack him
4561 if (caster && caster->IsAlive())
4562 return GetVictim();
4563 else if (tauntAuras.size() > 1)
4564 {
4565 // We do not have last taunt aura caster but we have more taunt auras,
4566 // so find first available target
4567
4568 // Auras are pushed_back, last caster will be on the end
4569 AuraEffectList::const_iterator aura = --tauntAuras.end();
4570 do
4571 {
4572 --aura;
4573 caster = (*aura)->GetCaster();
4574 if (caster && CanSeeOrDetect(caster, true) && IsValidAttackTarget(caster) && caster->isInAccessiblePlaceFor(ToCreature()))
4575 {
4576 target = caster;
4577 break;
4578 }
4579 } while (aura != tauntAuras.begin());
4580 }
4581 else
4582 target = GetVictim();
4583 }
4584
4585 if (CanHaveThreatList())
4586 {
4587 if (!target && !m_ThreatManager.isThreatListEmpty())
4588 // No taunt aura or taunt aura caster is dead standard target selection
4589 target = m_ThreatManager.getHostilTarget();
4590 }
4591 else if (!HasReactState(REACT_PASSIVE))
4592 {
4593 // We have player pet probably
4594 target = getAttackerForHelper();
4595 if (!target && IsSummon())
4596 {
4597 if (Unit* owner = ToTempSummon()->GetOwner())
4598 {
4599 if (owner->IsInCombat())
4600 target = owner->getAttackerForHelper();
4601 if (!target)
4602 {
4603 for (ControlList::const_iterator itr = owner->m_Controlled.begin(); itr != owner->m_Controlled.end(); ++itr)
4604 {
4605 if ((*itr)->IsInCombat())
4606 {
4607 target = (*itr)->getAttackerForHelper();
4608 if (target)
4609 break;
4610 }
4611 }
4612 }
4613 }
4614 }
4615 }
4616 else
4617 return NULL;
4618
4619 if (target && _IsTargetAcceptable(target) && CanCreatureAttack(target))
4620 {
4621 SetInFront(target);
4622 return target;
4623 }
4624
4625 // Case where mob is being kited.
4626 // Mob may not be in range to attack or may have dropped target. In any case,
4627 // don't evade if damage received within the last 10 seconds
4628 // Does not apply to world bosses to prevent kiting to cities
4629 if (!isWorldBoss() && !GetInstanceId())
4630 if (time(NULL) - GetLastDamagedTime() <= MAX_AGGRO_RESET_TIME)
4631 return target;
4632
4633 // last case when creature must not go to evade mode:
4634 // it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list
4635 // for example at owner command to pet attack some far away creature
4636 // Note: creature does not have targeted movement generator but has attacker in this case
4637 for (AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
4638 {
4639 if ((*itr) && !CanCreatureAttack(*itr) && (*itr)->GetTypeId() != TypeID::TYPEID_PLAYER
4640 && !(*itr)->ToCreature()->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
4641 return NULL;
4642 }
4643
4645 if (GetVehicle())
4646 return NULL;
4647
4648 // search nearby enemy before enter evade mode
4650 {
4652
4653 if (target && _IsTargetAcceptable(target) && CanCreatureAttack(target))
4654 return target;
4655 }
4656
4658 if (!iAuras.empty())
4659 {
4660 for (Unit::AuraEffectList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
4661 {
4662 if ((*itr)->GetBase()->IsPermanent())
4663 {
4664 AI()->EnterEvadeMode();
4665 break;
4666 }
4667 }
4668 return NULL;
4669 }
4670
4671 // enter in evade mode in other case
4672 AI()->EnterEvadeMode();
4673
4674 return NULL;
4675}
4676
4677//======================================================================
4678//======================================================================
4679//======================================================================
4680
4681float Unit::ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index, float value) const
4682{
4683 if (Player* modOwner = GetSpellModOwner())
4684 {
4685 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_ALL_EFFECTS, value);
4686 switch (effect_index)
4687 {
4688 case 0:
4689 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT1, value);
4690 break;
4691 case 1:
4692 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT2, value);
4693 break;
4694 case 2:
4695 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT3, value);
4696 break;
4697 case 3:
4698 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT4, value);
4699 break;
4700 case 4:
4701 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT5, value);
4702 break;
4703 }
4704 }
4705 return value;
4706}
4707
4708// function uses real base points (typically value - 1)
4709int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints) const
4710{
4711 return spellProto->Effects[effect_index].CalcValue(this, basePoints, target);
4712}
4713
4715{
4716 uint8 comboPoints = m_movedPlayer ? m_movedPlayer->GetComboPoints() : 0;
4717
4718 int32 minduration = spellProto->GetDuration();
4719 int32 maxduration = spellProto->GetMaxDuration();
4720
4721 int32 duration;
4722
4723 if (comboPoints && minduration != -1 && minduration != maxduration)
4724 {
4725 if (minduration)
4726 duration = minduration + (minduration * comboPoints);
4727 else
4728 duration = minduration + int32((maxduration - minduration) * comboPoints / 5);
4729 }
4730 else
4731 duration = minduration;
4732
4733 return duration;
4734}
4735
4736int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, int32 duration, bool positive, uint32 effectMask)
4737{
4738 // don't mod permanent auras duration
4739 if (duration < 0)
4740 return duration;
4741
4742 // cut duration only of negative effects
4743 if (!positive)
4744 {
4745 int32 mechanic = spellProto->GetSpellMechanicMaskByEffectMask(effectMask);
4746
4747 int32 durationMod;
4748 int32 durationMod_always = 0;
4749 int32 durationMod_not_stack = 0;
4750
4751 for (uint8 i = 1; i <= MECHANIC_ENRAGED; ++i)
4752 {
4753 if (!(mechanic & 1 << i))
4754 continue;
4755 // Find total mod value (negative bonus)
4756 int32 new_durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, i);
4757 // Find max mod (negative bonus)
4759 // Check if mods applied before were weaker
4760 if (new_durationMod_always < durationMod_always)
4761 durationMod_always = new_durationMod_always;
4762 if (new_durationMod_not_stack < durationMod_not_stack)
4763 durationMod_not_stack = new_durationMod_not_stack;
4764 }
4765
4766 // Select strongest negative mod
4767 if (durationMod_always > durationMod_not_stack)
4768 durationMod = durationMod_not_stack;
4769 else
4770 durationMod = durationMod_always;
4771
4772 if (durationMod != 0)
4773 AddPct(duration, durationMod);
4774
4775 // there are only negative mods currently
4776 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL, spellProto->Dispel);
4777
4778 durationMod = 0;
4779 if (durationMod_always)
4780 durationMod += durationMod_always;
4781
4782 if (durationMod != 0)
4783 AddPct(duration, durationMod);
4784 }
4785 else
4786 {
4787 // else positive mods here, there are no currently
4788 // when there will be, change GetTotalAuraModifierByMiscValue to GetTotalPositiveAuraModifierByMiscValue
4789
4790 // Mixology - duration boost
4791 if (target->GetTypeId() == TypeID::TYPEID_PLAYER)
4792 {
4793 if (spellProto->SpellFamilyName == SPELLFAMILY_POTION && (
4794 sSpellMgr->IsSpellMemberOfSpellGroup(spellProto->Id, SPELL_GROUP_ELIXIR_BATTLE) ||
4795 sSpellMgr->IsSpellMemberOfSpellGroup(spellProto->Id, SPELL_GROUP_ELIXIR_GUARDIAN)))
4796 {
4797 if (target->HasAura(53042) && target->HasSpell(spellProto->Effects[0].TriggerSpell))
4798 duration *= 2;
4799 }
4800 }
4801 }
4802
4803 // Glyphs which increase duration of selfcasted buffs
4804 if (target == this)
4805 {
4806 switch (spellProto->SpellFamilyName)
4807 {
4808 case SPELLFAMILY_DRUID:
4809 if (spellProto->SpellFamilyFlags[0] & 0x100)
4810 {
4811 // Glyph of Thorns
4812 if (AuraEffect* aurEff = GetAuraEffect(57862, 0))
4813 duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS;
4814 }
4815 break;
4816 }
4817 }
4818 return std::max(duration, 0);
4819}
4820
4821void Unit::ModSpellCastTime(SpellInfo const* spellProto, int32& castTime, Spell* spell)
4822{
4823 if (!spellProto || castTime < 0)
4824 return;
4825 // called from caster
4826 if (Player* modOwner = GetSpellModOwner())
4827 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime, spell);
4828
4830 castTime = int32(float(castTime) * GetFloatValue(UNIT_FIELD_MOD_CASTING_SPEED));
4831 else if (spellProto->Attributes & SPELL_ATTR0_REQ_AMMO && !(spellProto->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG))
4832 castTime = int32(float(castTime) * m_modAttackSpeedPct[uint8(WeaponAttackType::RANGED_ATTACK)]);
4833 else if (spellProto->SpellVisual[0] == 3881 && HasAura(67556)) // cooking with Chef Hat.
4834 castTime = 500;
4835}
4836
4838{
4839 for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
4840 {
4841 if (i->DRGroup != group)
4842 continue;
4843
4844 if (!i->hitCount)
4845 return DIMINISHING_LEVEL_1;
4846
4847 if (!i->hitTime)
4848 return DIMINISHING_LEVEL_1;
4849
4850 // If last spell was casted more than 15 seconds ago - reset the count.
4851 if (i->stack == 0 && getMSTimeDiff(i->hitTime, getMSTime()) > 15000)
4852 {
4853 i->hitCount = DIMINISHING_LEVEL_1;
4854 return DIMINISHING_LEVEL_1;
4855 }
4856 // or else increase the count.
4857 else
4858 return DiminishingLevels(i->hitCount);
4859 }
4860 return DIMINISHING_LEVEL_1;
4861}
4862
4864{
4865 // Checking for existing in the table
4866 for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
4867 {
4868 if (i->DRGroup != group)
4869 continue;
4870 if (int32(i->hitCount) < GetDiminishingReturnsMaxLevel(group))
4871 i->hitCount += 1;
4872 return;
4873 }
4875}
4876
4877float Unit::GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const
4878{
4879 if (!spellInfo->RangeEntry)
4880 return 0;
4881 if (spellInfo->RangeEntry->maxRangeFriend == spellInfo->RangeEntry->maxRangeHostile)
4882 return spellInfo->GetMaxRange();
4883 return spellInfo->GetMaxRange(!IsHostileTo(target));
4884}
4885
4886float Unit::GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const
4887{
4888 if (!spellInfo->RangeEntry)
4889 return 0;
4890 if (spellInfo->RangeEntry->minRangeFriend == spellInfo->RangeEntry->minRangeHostile)
4891 return spellInfo->GetMinRange();
4892 return spellInfo->GetMinRange(!IsHostileTo(target));
4893}
4894
4896{
4897 return ObjectAccessor::GetUnit(object, guid);
4898}
4899
4901{
4902 return ObjectAccessor::GetPlayer(object, guid);
4903}
4904
4906{
4907 return object.GetMap()->GetCreature(guid);
4908}
4909
4911{
4913 {
4915 SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form);
4916 if (ssEntry && ssEntry->creatureType > 0)
4917 return ssEntry->creatureType;
4918 else
4920 }
4921 else
4922 return ToCreature()->GetCreatureTemplate()->type;
4923}
4924
4926{
4927 uint32 creatureType = GetCreatureType();
4928 return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0;
4929}
4930
4935
4937{
4939 return form == FORM_CAT || form == FORM_BEAR;
4940}
4941
4943{
4945 return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE &&
4946 form != FORM_SHADOW && form != FORM_STEALTH && form != FORM_UNDEAD && form != FORM_WISE_SERPENT && form != FORM_STURDY_OX && form != FORM_FIERCE_TIGER && form != FORM_MOONKIN;
4947}
4948
4949/*#######################################
4950######## ########
4951######## STAT SYSTEM ########
4952######## ########
4953#######################################*/
4954
4955bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply)
4956{
4957 if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END)
4958 {
4959 SF_LOG_ERROR("entities.unit", "ERROR in HandleStatModifier(): non-existing UnitMods or wrong UnitModifierType!");
4960 return false;
4961 }
4962
4963 switch (modifierType)
4964 {
4965 case BASE_VALUE:
4966 case TOTAL_VALUE:
4967 m_auraModifiersGroup[unitMod][modifierType] += apply ? amount : -amount;
4968 break;
4969 case BASE_PCT:
4970 case TOTAL_PCT:
4971 ApplyPercentModFloatVar(m_auraModifiersGroup[unitMod][modifierType], amount, apply);
4972 break;
4973 default:
4974 break;
4975 }
4976
4977 if (!CanModifyStats())
4978 return false;
4979
4980 switch (unitMod)
4981 {
4987
4988 case UNIT_MOD_ARMOR: UpdateArmor(); break;
4989 case UNIT_MOD_HEALTH: UpdateMaxHealth(); break;
4990
4991 case UNIT_MOD_MANA:
4992 case UNIT_MOD_RAGE:
4993 case UNIT_MOD_FOCUS:
4994 case UNIT_MOD_ENERGY:
4995 case UNIT_MOD_RUNE:
4998 case UNIT_MOD_ECLIPSE:
5000 case UNIT_MOD_CHI:
5005
5012
5015
5019
5020 default:
5021 break;
5022 }
5023
5024 return true;
5025}
5026
5027float Unit::GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
5028{
5029 if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END)
5030 {
5031 SF_LOG_ERROR("entities.unit", "attempt to access non-existing modifier value from UnitMods!");
5032 return 0.0f;
5033 }
5034
5035 if (modifierType == TOTAL_PCT && m_auraModifiersGroup[unitMod][modifierType] <= 0.0f)
5036 return 0.0f;
5037
5038 return m_auraModifiersGroup[unitMod][modifierType];
5039}
5040
5042{
5043 UnitMods unitMod = UnitMods(UNIT_MOD_STAT_START + UnitMods(stat));
5044
5045 if (m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f)
5046 return 0.0f;
5047
5048 // value = ((base_value * base_pct) + total_value) * total_pct
5049 float value = m_auraModifiersGroup[unitMod][BASE_VALUE] + GetCreateStat(stat);
5050 value *= m_auraModifiersGroup[unitMod][BASE_PCT];
5051 value += m_auraModifiersGroup[unitMod][TOTAL_VALUE];
5052 value *= m_auraModifiersGroup[unitMod][TOTAL_PCT];
5053
5054 return value;
5055}
5056
5058{
5060
5061 switch (unitMod)
5062 {
5063 case UNIT_MOD_RESISTANCE_HOLY: school = SPELL_SCHOOL_HOLY; break;
5064 case UNIT_MOD_RESISTANCE_FIRE: school = SPELL_SCHOOL_FIRE; break;
5065 case UNIT_MOD_RESISTANCE_NATURE: school = SPELL_SCHOOL_NATURE; break;
5066 case UNIT_MOD_RESISTANCE_FROST: school = SPELL_SCHOOL_FROST; break;
5067 case UNIT_MOD_RESISTANCE_SHADOW: school = SPELL_SCHOOL_SHADOW; break;
5068 case UNIT_MOD_RESISTANCE_ARCANE: school = SPELL_SCHOOL_ARCANE; break;
5069
5070 default:
5071 break;
5072 }
5073
5074 return school;
5075}
5076
5078{
5079 Stats stat = STAT_STRENGTH;
5080
5081 switch (unitMod)
5082 {
5083 case UNIT_MOD_STAT_STRENGTH: stat = STAT_STRENGTH; break;
5084 case UNIT_MOD_STAT_AGILITY: stat = STAT_AGILITY; break;
5085 case UNIT_MOD_STAT_STAMINA: stat = STAT_STAMINA; break;
5086 case UNIT_MOD_STAT_INTELLECT: stat = STAT_INTELLECT; break;
5087 case UNIT_MOD_STAT_SPIRIT: stat = STAT_SPIRIT; break;
5088
5089 default:
5090 break;
5091 }
5092
5093 return stat;
5094}
5095
5097{
5098 switch (unitMod)
5099 {
5100 case UNIT_MOD_RAGE: return POWER_RAGE;
5101 case UNIT_MOD_FOCUS: return POWER_FOCUS;
5102 case UNIT_MOD_ENERGY: return POWER_ENERGY;
5103 case UNIT_MOD_RUNE: return POWER_RUNES;
5106 case UNIT_MOD_ECLIPSE: return POWER_ECLIPSE;
5108 case UNIT_MOD_CHI: return POWER_CHI;
5113 default:
5114 case UNIT_MOD_MANA: return POWER_MANA;
5115 }
5116}
5117
5119{
5120 if (attType == WeaponAttackType::RANGED_ATTACK)
5121 {
5123 if (ap < 0)
5124 return 0.0f;
5126 }
5127 else
5128 {
5130 if (ap < 0)
5131 return 0.0f;
5133 }
5134}
5135
5137{
5139 return 0.0f;
5140
5141 return m_weaponDamage[uint8(attType)][uint8(type)];
5142}
5143
5149
5151{
5153
5154 // group update
5155 if (GetTypeId() == TypeID::TYPEID_PLAYER && ToPlayer()->GetGroup())
5157
5159 sWorld->UpdateCharacterNameDataLevel(ToPlayer()->GetGUIDLow(), lvl);
5160}
5161
5163{
5165 val = 0;
5167 val = 1;
5168 else
5169 {
5170 uint32 maxHealth = GetMaxHealth();
5171 if (maxHealth < val)
5172 val = maxHealth;
5173 }
5174
5176
5177 if (IsInWorld())
5178 {
5179 ObjectGuid guid = GetGUID();
5180
5181 WorldPacket data(SMSG_HEALTH_UPDATE, 8 + 4);
5182 data.WriteGuidMask(guid, 4, 3, 0, 2, 7, 5, 1, 6);
5183 data.WriteGuidBytes(guid, 3, 1, 2, 4, 6);
5184 data << int32(val);
5185 data.WriteGuidBytes(guid, 7, 5, 0);
5187 }
5188
5189 // group update
5190 if (Player* player = ToPlayer())
5191 {
5192 if (player->GetGroup())
5193 player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_HP);
5194 }
5195 else if (Pet* pet = ToCreature()->ToPet())
5196 {
5197 if (pet->isControlled())
5198 {
5199 Unit* owner = GetOwner();
5200 if (owner && (owner->GetTypeId() == TypeID::TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
5202 }
5203 }
5204}
5205
5207{
5208 if (!val)
5209 val = 1;
5210
5212 val = 0;
5213
5214 uint32 health = GetHealth();
5216
5217 // group update
5219 {
5220 if (ToPlayer()->GetGroup())
5222 }
5223 else if (Pet* pet = ToCreature()->ToPet())
5224 {
5225 if (pet->isControlled())
5226 {
5227 Unit* owner = GetOwner();
5228 if (owner && (owner->GetTypeId() == TypeID::TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
5230 }
5231 }
5232
5233 if (val < health)
5234 SetHealth(val);
5235}
5236
5238{
5239 uint32 powerIndex = GetPowerIndex(power);
5240 if (powerIndex == MAX_POWERS)
5241 return 0;
5242
5243 return GetUInt32Value(UNIT_FIELD_POWER + powerIndex);
5244}
5245
5247{
5248 uint32 powerIndex = GetPowerIndex(power);
5249 if (powerIndex == MAX_POWERS)
5250 return 0;
5251
5252 return GetInt32Value(UNIT_FIELD_MAX_POWER + powerIndex);
5253}
5254
5256{
5257 uint32 powerIndex = GetPowerIndex(power);
5258 if (powerIndex == MAX_POWERS)
5259 return;
5260
5261 int32 maxPower = int32(GetMaxPower(power));
5262 if (maxPower < val)
5263 val = maxPower;
5264
5265 SetInt32Value(UNIT_FIELD_POWER + powerIndex, val);
5266
5267 if (IsInWorld())
5268 {
5269 ObjectGuid guid = GetGUID();
5270
5271 WorldPacket data(SMSG_POWER_UPDATE, 8 + 4 + 1 + 4);
5272 data.WriteBit(guid[4]);
5273 data.WriteBit(guid[6]);
5274 data.WriteBit(guid[7]);
5275 data.WriteBit(guid[5]);
5276 data.WriteBit(guid[2]);
5277 data.WriteBit(guid[3]);
5278 data.WriteBit(guid[0]);
5279 data.WriteBit(guid[1]);
5280 data.WriteBits(1, 21); // 1 update
5281
5282 data.FlushBits();
5283
5284 data.WriteByteSeq(guid[7]);
5285 data.WriteByteSeq(guid[0]);
5286 data.WriteByteSeq(guid[5]);
5287 data.WriteByteSeq(guid[3]);
5288 data.WriteByteSeq(guid[1]);
5289 data.WriteByteSeq(guid[2]);
5290 data.WriteByteSeq(guid[4]);
5291
5292 data << uint8(powerIndex);
5293 data << int32(val);
5294
5295 data.WriteByteSeq(guid[6]);
5296
5298 }
5299
5300 // group update
5301 if (Player* player = ToPlayer())
5302 {
5303 if (player->GetGroup())
5304 player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER);
5305 }
5306 else if (Pet* pet = ToCreature()->ToPet())
5307 {
5308 if (pet->isControlled())
5309 {
5310 Unit* owner = GetOwner();
5311 if (owner && (owner->GetTypeId() == TypeID::TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
5313 }
5314 }
5315}
5316
5318{
5319 uint32 powerIndex = GetPowerIndex(power);
5320 if (powerIndex == MAX_POWERS)
5321 return;
5322
5323 int32 cur_power = GetPower(power);
5324 SetInt32Value(UNIT_FIELD_MAX_POWER + powerIndex, val);
5325
5326 // group update
5328 {
5329 if (ToPlayer()->GetGroup())
5331 }
5332 else if (Pet* pet = ToCreature()->ToPet())
5333 {
5334 if (pet->isControlled())
5335 {
5336 Unit* owner = GetOwner();
5337 if (owner && (owner->GetTypeId() == TypeID::TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
5339 }
5340 }
5341
5342 if (val < cur_power)
5343 SetPower(power, val);
5344}
5345
5347{
5352 uint32 classId = getClass();
5353 //if (ToPet() && ToPet()->getPetType() == HUNTER_PET)
5354 // classId = CLASS_HUNTER;
5355
5356 return GetPowerIndexByClass(powerType, classId);
5357}
5358
5360{
5361 switch (power)
5362 {
5363 case POWER_MANA:
5364 return GetCreateMana();
5365 case POWER_RAGE:
5366 return 1000;
5367 case POWER_FOCUS:
5369 return 100;
5370 return (GetTypeId() == TypeID::TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != PetType::HUNTER_PET ? 0 : 100);
5371 case POWER_ENERGY:
5372 return 100;
5373 case POWER_RUNIC_POWER:
5374 return 1000;
5375 case POWER_RUNES:
5376 return 0;
5377 case POWER_SOUL_SHARDS:
5378 return 400;
5379 case POWER_ECLIPSE:
5380 return 100;
5381 case POWER_HOLY_POWER:
5382 case POWER_SHADOW_ORBS:
5383 return 3;
5384 case POWER_HEALTH:
5385 return 0;
5386 case POWER_CHI:
5388 return 4;
5389 case POWER_DEMONIC_FURY:
5390 return 1000;
5392 return 40;
5393 default:
5394 break;
5395 }
5396
5397 return 0;
5398}
5399
5401{
5402 if (!IsInWorld())
5403 {
5405 }
5407}
5408
5410{
5411 // cleanup
5412 ASSERT(GetGUID());
5413
5414 if (IsInWorld())
5415 {
5417 if (IsVehicle())
5418 RemoveVehicleKit(true);
5419
5423
5426
5427 ExitVehicle(); // Remove applied auras with SPELL_AURA_CONTROL_VEHICLE
5430
5432
5433 if (GetCharmerGUID())
5434 {
5435 SF_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry());
5436 ASSERT(false);
5437 }
5438
5439 if (Unit* owner = GetOwner())
5440 {
5441 if (owner->m_Controlled.find(this) != owner->m_Controlled.end())
5442 {
5443 SF_LOG_FATAL("entities.unit", "Unit %u is in controlled list of %u when removed from world", GetEntry(), owner->GetEntry());
5444 ASSERT(false);
5445 }
5446 }
5447
5450 }
5451}
5452
5454{
5455 // This needs to be before RemoveFromWorld to make GetCaster() return a valid pointer on aura removal
5457
5458 if (IsInWorld())
5460
5461 ASSERT(GetGUID());
5462
5463 // A unit may be in removelist and not in world, but it is still in grid
5464 // and may have some references during delete
5467
5468 if (finalCleanup)
5469 m_cleanupDone = true;
5470
5471 m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
5472 CombatStop();
5476 GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
5477}
5478
5479void Unit::CleanupsBeforeDelete(bool finalCleanup)
5480{
5481 CleanupBeforeRemoveFromMap(finalCleanup);
5482
5483 if (GetTransport())
5484 {
5486 SetTransport(NULL);
5487 m_movementInfo.transport.Reset();
5488 }
5489}
5490
5492{
5494 return;
5495
5496 if (i_disabledAI) // disabled AI must be primary AI
5497 {
5498 if (!IsCharmed())
5499 {
5500 delete i_AI;
5502 i_disabledAI = NULL;
5503 }
5504 }
5505 else
5506 {
5507 if (IsCharmed())
5508 {
5510 if (isPossessed() || IsVehicle())
5511 i_AI = new PossessedAI(ToCreature());
5512 else
5513 i_AI = new PetAI(ToCreature());
5514 }
5515 }
5516}
5517
5519{
5520 if (!m_charmInfo)
5521 m_charmInfo = new CharmInfo(this);
5522
5523 return m_charmInfo;
5524}
5525
5527{
5528 if (!m_charmInfo)
5529 return;
5530
5531 m_charmInfo->RestoreState();
5532 delete m_charmInfo;
5533 m_charmInfo = NULL;
5534}
5535
5538 _isCommandAttack(false), _isCommandFollow(false), _isAtStay(false), _isFollowing(false), _isReturning(false),
5539 _stayX(0.0f), _stayY(0.0f), _stayZ(0.0f)
5540{
5541 for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i)
5542 _charmspells[i].SetActionAndType(0, ACT_DISABLED);
5543
5544 if (_unit->GetTypeId() == TypeID::TYPEID_UNIT)
5545 {
5546 _oldReactState = _unit->ToCreature()->GetReactState();
5547 _unit->ToCreature()->SetReactState(REACT_PASSIVE);
5548 }
5549}
5550
5553
5555{
5556 if (_unit->GetTypeId() == TypeID::TYPEID_UNIT)
5557 if (Creature* creature = _unit->ToCreature())
5558 creature->SetReactState(_oldReactState);
5559}
5560
5562{
5563 // the first 3 SpellOrActions are attack, follow and stay
5565 {
5566 if (i < 2)
5568 else
5570 }
5571
5572 // middle 4 SpellOrActions are spells/special attacks/abilities
5575
5576 // last 3 SpellOrActions are reactions
5578 {
5579 if (i != 1)
5581 else
5583 }
5584}
5585
5587{
5588 if (withAttack)
5590 else
5592 for (uint32 x = ACTION_BAR_INDEX_START + 1; x < ACTION_BAR_INDEX_END; ++x)
5594}
5595
5597{
5598 if (_unit->GetTypeId() == TypeID::TYPEID_UNIT)
5599 {
5600 switch (_unit->GetEntry())
5601 {
5602 case 28511: // Eye of Acherus
5603 break;
5604 default:
5606 break;
5607 }
5608
5609 for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
5610 {
5611 uint32 spellId = _unit->ToCreature()->m_spells[i];
5612 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
5613 if (spellInfo && !(spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD))
5614 {
5615 if (spellInfo->IsPassive())
5616 _unit->CastSpell(_unit, spellInfo, true);
5617 else
5619 }
5620 }
5621 }
5622 else
5624}
5625
5627{
5628 if (_unit->GetTypeId() == TypeID::TYPEID_PLAYER) // charmed players don't have spells
5629 {
5631 return;
5632 }
5633
5635
5636 for (uint32 x = 0; x < MAX_SPELL_CHARM; ++x)
5637 {
5638 uint32 spellId = _unit->ToCreature()->m_spells[x];
5639 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
5640
5641 if (!spellInfo || spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD)
5642 {
5643 _charmspells[x].SetActionAndType(spellId, ACT_DISABLED);
5644 continue;
5645 }
5646
5647 if (spellInfo->IsPassive())
5648 {
5649 _unit->CastSpell(_unit, spellInfo, true);
5650 _charmspells[x].SetActionAndType(spellId, ACT_PASSIVE);
5651 }
5652 else
5653 {
5654 _charmspells[x].SetActionAndType(spellId, ACT_DISABLED);
5655
5656 ActiveStates newstate = ACT_PASSIVE;
5657
5658 if (!spellInfo->IsAutocastable())
5659 newstate = ACT_PASSIVE;
5660 else
5661 {
5662 if (spellInfo->NeedsExplicitUnitTarget())
5663 {
5664 newstate = ACT_ENABLED;
5665 ToggleCreatureAutocast(spellInfo, true);
5666 }
5667 else
5668 newstate = ACT_DISABLED;
5669 }
5670
5671 AddSpellToActionBar(spellInfo, newstate);
5672 }
5673 }
5674}
5675
5676bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate, uint8 preferredSlot)
5677{
5678 uint32 spell_id = spellInfo->Id;
5679 uint32 first_id = spellInfo->GetFirstRankSpell()->Id;
5680
5681 ASSERT(preferredSlot < MAX_UNIT_ACTION_BAR_INDEX);
5682 // new spell rank can be already listed
5683 for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
5684 {
5685 if (uint32 action = PetActionBar[i].GetAction())
5686 {
5687 if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id)
5688 {
5689 PetActionBar[i].SetAction(spell_id);
5690 return true;
5691 }
5692 }
5693 }
5694
5695 // or use empty slot in other case
5696 for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
5697 {
5698 uint8 j = (preferredSlot + i) % MAX_UNIT_ACTION_BAR_INDEX;
5699 if (!PetActionBar[j].GetAction() && PetActionBar[j].IsActionBarForSpell())
5700 {
5701 SetActionBar(j, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate);
5702 return true;
5703 }
5704 }
5705 return false;
5706}
5707
5709{
5710 uint32 first_id = sSpellMgr->GetFirstSpellInChain(spell_id);
5711
5712 for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
5713 {
5714 if (uint32 action = PetActionBar[i].GetAction())
5715 {
5716 if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id)
5717 {
5719 return true;
5720 }
5721 }
5722 }
5723
5724 return false;
5725}
5726
5727void CharmInfo::ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply)
5728{
5729 if (spellInfo->IsPassive())
5730 return;
5731
5732 for (uint32 x = 0; x < MAX_SPELL_CHARM; ++x)
5733 if (spellInfo->Id == _charmspells[x].GetAction())
5734 _charmspells[x].SetType(apply ? ACT_ENABLED : ACT_DISABLED);
5735}
5736
5737void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
5738{
5739 _petnumber = petnumber;
5740 if (statwindow)
5741 _unit->SetUInt32Value(UNIT_FIELD_PET_NUMBER, _petnumber);
5742 else
5743 _unit->SetUInt32Value(UNIT_FIELD_PET_NUMBER, 0);
5744}
5745
5746void CharmInfo::LoadPetActionBar(const std::string& data)
5747{
5749
5750 Tokenizer tokens(data, ' ');
5751
5752 if (tokens.size() != (ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_START) * 2)
5753 return; // non critical, will reset to default
5754
5756 Tokenizer::const_iterator iter = tokens.begin();
5757 for (; index < ACTION_BAR_INDEX_END; ++iter, ++index)
5758 {
5759 // use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
5760 ActiveStates type = ActiveStates(atol(*iter));
5761 ++iter;
5762 uint32 action = uint32(atol(*iter));
5763
5764 PetActionBar[index].SetActionAndType(action, type);
5765
5766 // check correctness
5767 if (PetActionBar[index].IsActionBarForSpell())
5768 {
5769 SpellInfo const* spelInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction());
5770 if (!spelInfo)
5771 SetActionBar(index, 0, ACT_PASSIVE);
5772 else if (!spelInfo->IsAutocastable())
5773 SetActionBar(index, PetActionBar[index].GetAction(), ACT_PASSIVE);
5774 }
5775 }
5776}
5777
5779{
5780 for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
5781 *data << uint32(PetActionBar[i].packedData);
5782}
5783
5784void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool AutocastEnabled)
5785{
5786 for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
5787 {
5788 if (spellInfo->Id == PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
5789 {
5790 PetActionBar[i].SetType(AutocastEnabled ? ACT_ENABLED : ACT_DISABLED);
5791 break;
5792 }
5793 }
5794}
5795
5796bool Unit::isFrozen() const
5797{
5799}
5800
5805
5810
5812{
5813 if (uint64 guid = GetCharmerOrOwnerGUID())
5814 return guid;
5815 return GetGUID();
5816}
5817
5819{
5820 if (Player* player = const_cast<Unit*>(this)->ToPlayer())
5821 return player;
5822
5823 if (ToCreature()->IsPet() || ToCreature()->IsTotem())
5824 {
5825 if (Unit* owner = GetOwner())
5826 if (Player* player = owner->ToPlayer())
5827 return player;
5828 }
5829 return NULL;
5830}
5831
5834{
5835 Unit* owner = GetOwner();
5836 if (!owner || owner->GetTypeId() != TypeID::TYPEID_PLAYER)
5837 return;
5838
5840 data << uint8(msg);
5841 owner->ToPlayer()->GetSession()->SendPacket(&data);
5842}
5843
5844void Unit::SendPetTalk(uint32 pettalk) const
5845{
5846 Unit* owner = GetOwner();
5847 if (!owner || owner->GetTypeId() != TypeID::TYPEID_PLAYER)
5848 return;
5849
5851 data.WriteGuidMask(GetObjectGUID(), 2, 7, 6, 0, 5, 1, 3, 4);
5852 data.WriteGuidBytes(GetObjectGUID(), 7, 4, 6, 1);
5853 data << uint32(pettalk);
5854 data.WriteGuidBytes(GetObjectGUID(), 2, 3, 5, 0);
5855 owner->ToPlayer()->GetSession()->SendPacket(&data);
5856}
5857
5859{
5860 Unit* owner = GetOwner();
5861 if (!owner || owner->GetTypeId() != TypeID::TYPEID_PLAYER)
5862 return;
5863
5864 WorldPacket data(SMSG_AI_REACTION, 8 + 4);
5865
5866 data.WriteGuidMask(UnitGUID, 5, 7, 0, 4, 6, 2, 3, 1);
5867
5868 data.WriteGuidBytes(UnitGUID, 4, 6, 5);
5869 data << uint32(AI_REACTION_HOSTILE);
5870 data.WriteGuidBytes(UnitGUID, 7, 1, 2, 0, 3);
5871
5872 owner->ToPlayer()->GetSession()->SendPacket(&data);
5873}
5874
5876
5878{
5880
5881 // not need send any packets if not in world or not moving
5882 if (!IsInWorld() || movespline->Finalized())
5883 return;
5884
5885 Movement::MoveSplineInit init(this);
5886 init.Stop();
5887}
5888
5895
5897{
5898 uint8 s = getStandState();
5900}
5901
5903{
5905
5906 if (IsStandState())
5908
5910 {
5912 data << (uint8)state;
5913 ToPlayer()->GetSession()->SendPacket(&data);
5914 }
5915}
5916
5918{
5920 return;
5921
5922 if (GetByteValue(UNIT_FIELD_ANIM_TIER, 3) == uint8(tier))
5923 return;
5924
5926}
5927
5929{
5930 uint32 transformId = getTransForm();
5931 if (!transformId)
5932 return false;
5933
5934 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(transformId);
5935 if (!spellInfo)
5936 return false;
5937
5938 return spellInfo->GetSpellSpecific() == SPELL_SPECIFIC_MAGE_POLYMORPH;
5939}
5940
5942{
5944}
5945
5947{
5948 AuraEffect* handledAura = NULL;
5949 // try to receive model from transform auras
5951 if (!transforms.empty())
5952 {
5953 // iterate over already applied transform auras - from newest to oldest
5954 for (Unit::AuraEffectList::const_reverse_iterator i = transforms.rbegin(); i != transforms.rend(); ++i)
5955 {
5956 if (AuraApplication const* aurApp = (*i)->GetBase()->GetApplicationOfTarget(GetGUID()))
5957 {
5958 if (!handledAura)
5959 handledAura = (*i);
5960 // prefer negative auras
5961 if (!aurApp->IsPositive())
5962 {
5963 handledAura = (*i);
5964 break;
5965 }
5966 }
5967 }
5968 }
5969 // transform aura was found
5970 if (handledAura)
5971 handledAura->HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
5972 // we've found shapeshift
5973 else if (uint32 modelId = GetModelForForm(GetShapeshiftForm()))
5974 SetDisplayId(modelId);
5975 // no auras found - set modelid to default
5976 else
5978}
5979
5981{
5982 while (!m_ComboPointHolders.empty())
5983 {
5984 uint32 lowguid = *m_ComboPointHolders.begin();
5985
5987 if (player && player->GetComboTarget() == GetGUID()) // recheck for safe
5988 player->ClearComboPoints(); // remove also guid from m_ComboPointHolders;
5989 else
5990 m_ComboPointHolders.erase(lowguid); // or remove manually
5991 }
5992}
5993
6006
6008{
6009 for (uint8 i = 0; i < MAX_REACTIVE; ++i)
6010 {
6011 ReactiveType reactive = ReactiveType(i);
6012
6013 if (!m_reactiveTimer[reactive])
6014 continue;
6015
6016 if (m_reactiveTimer[reactive] <= p_time)
6017 {
6018 m_reactiveTimer[reactive] = 0;
6019
6020 switch (reactive)
6021 {
6022 case REACTIVE_DEFENSE:
6025 break;
6029 break;
6030 case REACTIVE_OVERPOWER:
6033 break;
6034 }
6035 }
6036 else
6037 {
6038 m_reactiveTimer[reactive] -= p_time;
6039 }
6040 }
6041}
6042
6043Unit* Unit::SelectNearbyTarget(Unit* exclude, float dist) const
6044{
6045 std::list<Unit*> targets;
6046 Skyfire::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, dist);
6048 VisitNearbyObject(dist, searcher);
6049
6050 // remove current target
6051 if (GetVictim())
6052 targets.remove(GetVictim());
6053
6054 if (exclude)
6055 targets.remove(exclude);
6056
6057 // remove not LoS targets
6058 for (std::list<Unit*>::iterator tIter = targets.begin(); tIter != targets.end();)
6059 {
6060 if (!IsWithinLOSInMap(*tIter) || (*tIter)->IsTotem() || (*tIter)->IsSpiritService() || (*tIter)->GetCreatureType() == CREATURE_TYPE_CRITTER)
6061 targets.erase(tIter++);
6062 else
6063 ++tIter;
6064 }
6065
6066 // no appropriate targets
6067 if (targets.empty())
6068 return NULL;
6069
6070 // select random
6072}
6073
6075{
6076 float remainingTimePct = (float)m_attackTimer[uint8(att)] / (GetAttackTime(att) * m_modAttackSpeedPct[uint8(att)]);
6077 if (val > 0)
6078 {
6081
6083 {
6086 else if (att == WeaponAttackType::RANGED_ATTACK)
6088 }
6089 }
6090 else
6091 {
6094
6096 {
6099 else if (att == WeaponAttackType::RANGED_ATTACK)
6101 }
6102 }
6103 m_attackTimer[uint8(att)] = uint32(GetAttackTime(att) * m_modAttackSpeedPct[uint8(att)] * remainingTimePct);
6104}
6105
6106void Unit::ApplyCastTimePercentMod(float val, bool apply)
6107{
6108 if (val > 0)
6109 {
6112 }
6113 else
6114 {
6117 }
6118}
6119
6120uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const
6121{
6122 // Not apply this to creature casted spells with casttime == 0
6123 if (CastingTime == 0 && GetTypeId() == TypeID::TYPEID_UNIT && !ToCreature()->IsPet())
6124 return 3500;
6125
6126 if (CastingTime > 7000) CastingTime = 7000;
6127 if (CastingTime < 1500) CastingTime = 1500;
6128
6129 if (damagetype == DOT && !spellProto->IsChanneled())
6130 CastingTime = 3500;
6131
6132 int32 overTime = 0;
6133 uint8 effects = 0;
6134 bool DirectDamage = false;
6135 bool AreaEffect = false;
6136
6137 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; i++)
6138 {
6139 switch (spellProto->Effects[i].Effect)
6140 {
6146 case SPELL_EFFECT_HEAL:
6147 DirectDamage = true;
6148 break;
6150 {
6151 switch (spellProto->Effects[i].ApplyAuraName)
6152 {
6156 if (spellProto->GetDuration())
6157 overTime = spellProto->GetDuration();
6158 break;
6159 default:
6160 // -5% per additional effect
6161 ++effects;
6162 break;
6163 }
6164 }
6165 default:
6166 break;
6167 }
6168
6169 if (spellProto->Effects[i].IsTargetingArea())
6170 AreaEffect = true;
6171 }
6172
6173 // Combined Spells with Both Over Time and Direct Damage
6174 if (overTime > 0 && CastingTime > 0 && DirectDamage)
6175 {
6176 // mainly for DoTs which are 3500 here otherwise
6177 uint32 OriginalCastTime = spellProto->CalcCastTime(getLevel());
6178 if (OriginalCastTime > 7000) OriginalCastTime = 7000;
6179 if (OriginalCastTime < 1500) OriginalCastTime = 1500;
6180 // Portion to Over Time
6181 float PtOT = (overTime / 15000.0f) / ((overTime / 15000.0f) + (OriginalCastTime / 3500.0f));
6182
6183 if (damagetype == DOT)
6184 CastingTime = uint32(CastingTime * PtOT);
6185 else if (PtOT < 1.0f)
6186 CastingTime = uint32(CastingTime * (1 - PtOT));
6187 else
6188 CastingTime = 0;
6189 }
6190
6191 // Area Effect Spells receive only half of bonus
6192 if (AreaEffect)
6193 CastingTime /= 2;
6194
6195 // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
6196 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6197 {
6198 if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH ||
6200 {
6201 CastingTime /= 2;
6202 break;
6203 }
6204 }
6205
6206 // -5% of total per any additional effect
6207 for (uint8 i = 0; i < effects; ++i)
6208 CastingTime *= 0.95f;
6209
6210 return CastingTime;
6211}
6212
6213float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffectType damagetype) const
6214{
6215 // Damage over Time spells bonus calculation
6216 float DotFactor = 1.0f;
6217 if (damagetype == DOT)
6218 {
6219 int32 DotDuration = spellInfo->GetDuration();
6220 if (!spellInfo->IsChanneled() && DotDuration > 0)
6221 DotFactor = DotDuration / 15000.0f;
6222
6223 if (uint32 DotTicks = spellInfo->GetMaxTicks())
6224 DotFactor /= DotTicks;
6225 }
6226
6227 int32 CastingTime = spellInfo->IsChanneled() ? spellInfo->GetDuration() : spellInfo->CalcCastTime(getLevel());
6228 // Distribute Damage over multiple effects, reduce by AoE
6229 CastingTime = GetCastingTimeForBonus(spellInfo, damagetype, CastingTime);
6230
6231 // As wowwiki says: C = (Cast Time / 3.5)
6232 return (CastingTime / 3500.0f) * DotFactor;
6233}
6234
6235void Unit::AddPetAura(PetAura const* petSpell)
6236{
6238 return;
6239
6240 m_petAuras.insert(petSpell);
6241 if (Pet* pet = ToPlayer()->GetPet())
6242 pet->CastPetAura(petSpell);
6243}
6244
6245void Unit::RemovePetAura(PetAura const* petSpell)
6246{
6248 return;
6249
6250 m_petAuras.erase(petSpell);
6251 if (Pet* pet = ToPlayer()->GetPet())
6252 pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry()));
6253}
6254
6255Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget, uint32 spell_id)
6256{
6258 return NULL;
6259
6260 Pet* pet = new Pet(ToPlayer(), PetType::HUNTER_PET);
6261
6262 if (!pet->CreateBaseAtCreature(creatureTarget))
6263 {
6264 delete pet;
6265 return NULL;
6266 }
6267
6268 uint8 level = creatureTarget->getLevel() + 5 < getLevel() ? (getLevel() - 5) : creatureTarget->getLevel();
6269
6270 InitTamedPet(pet, level, spell_id);
6271
6272 return pet;
6273}
6274
6276{
6278 return NULL;
6279
6280 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creatureEntry);
6281 if (!creatureInfo)
6282 return NULL;
6283
6284 Pet* pet = new Pet(ToPlayer(), PetType::HUNTER_PET);
6285
6286 if (!pet->CreateBaseAtCreatureInfo(creatureInfo, this) || !InitTamedPet(pet, getLevel(), spell_id))
6287 {
6288 delete pet;
6289 return NULL;
6290 }
6291
6292 return pet;
6293}
6294
6295bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) const
6296{
6297 pet->SetCreatorGUID(GetGUID());
6298 pet->setFaction(getFaction());
6300
6303
6304 if (!pet->InitStatsForLevel(level))
6305 {
6306 SF_LOG_ERROR("entities.unit", "Pet::InitStatsForLevel() failed for creature (Entry: %u)!", pet->GetEntry());
6307 return false;
6308 }
6309
6310 for (auto phase : GetPhases())
6311 pet->SetPhased(phase, false, true);
6312
6313 pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
6314 // this enables pet details window (Shift+P)
6315 pet->InitPetCreateSpells();
6316 //pet->InitLevelupSpellsForLevel();
6317 pet->SetFullHealth();
6318 return true;
6319}
6320
6322{
6324 data << uint32(percent);
6325 receiver->GetSession()->SendPacket(&data);
6326}
6327
6329{
6330 ObjectGuid Guid;
6332
6333 data.WriteGuidMask(Guid, 3, 1, 7, 6, 0, 4, 5, 2);
6334
6335 data.WriteGuidBytes(Guid, 3, 6, 1, 4);
6336 data << uint16(id);
6337 data.WriteGuidBytes(Guid, 2, 7, 5, 0);
6338
6339 SendMessageToSet(&data, true);
6340}
6341
6342void Unit::Kill(Unit* victim, bool durabilityLoss)
6343{
6344 // Prevent killing unit twice (and giving reward from kill twice)
6345 if (!victim->GetHealth())
6346 return;
6347
6348 // find player: owner of controlled `this` or `this` itself maybe
6350 Creature* creature = victim->ToCreature();
6351
6352 bool isRewardAllowed = true;
6353 if (creature)
6354 {
6355 isRewardAllowed = creature->IsDamageEnoughForLootingAndReward();
6356 if (!isRewardAllowed)
6357 creature->SetLootRecipient(NULL);
6358 }
6359
6360 if (isRewardAllowed && creature && creature->GetLootRecipient())
6361 player = creature->GetLootRecipient();
6362
6363 // Reward player, his pets, and group/raid members
6364 // call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop)
6365 if (isRewardAllowed && player && player != victim)
6366 {
6367 ObjectGuid playerGuid = player->GetGUID();
6368 ObjectGuid victimGuid = victim->GetGUID();
6369 WorldPacket data(SMSG_PARTYKILLLOG); // send event PARTY_KILL
6370
6371 data.WriteBit(victimGuid[7]);
6372 data.WriteBit(victimGuid[2]);
6373 data.WriteBit(playerGuid[1]);
6374 data.WriteBit(victimGuid[4]);
6375 data.WriteBit(playerGuid[2]);
6376 data.WriteBit(playerGuid[5]);
6377 data.WriteBit(victimGuid[3]);
6378 data.WriteBit(victimGuid[1]);
6379 data.WriteBit(victimGuid[0]);
6380 data.WriteBit(playerGuid[3]);
6381 data.WriteBit(playerGuid[0]);
6382 data.WriteBit(playerGuid[4]);
6383 data.WriteBit(victimGuid[6]);
6384 data.WriteBit(playerGuid[7]);
6385 data.WriteBit(victimGuid[5]);
6386 data.WriteBit(playerGuid[6]);
6387
6388 data.WriteByteSeq(victimGuid[0]);
6389 data.WriteByteSeq(victimGuid[5]);
6390 data.WriteByteSeq(playerGuid[0]);
6391 data.WriteByteSeq(playerGuid[2]);
6392 data.WriteByteSeq(victimGuid[7]);
6393 data.WriteByteSeq(victimGuid[6]);
6394 data.WriteByteSeq(victimGuid[1]);
6395 data.WriteByteSeq(victimGuid[4]);
6396 data.WriteByteSeq(playerGuid[4]);
6397 data.WriteByteSeq(playerGuid[1]);
6398 data.WriteByteSeq(victimGuid[2]);
6399 data.WriteByteSeq(playerGuid[6]);
6400 data.WriteByteSeq(playerGuid[3]);
6401 data.WriteByteSeq(playerGuid[5]);
6402 data.WriteByteSeq(playerGuid[7]);
6403 data.WriteByteSeq(victimGuid[3]);
6404
6405 Player* looter = player;
6406
6407 if (Group* group = player->GetGroup())
6408 {
6409 group->BroadcastPacket(&data, group->GetMemberGroup(player->GetGUID()));
6410
6411 if (creature)
6412 {
6413 group->UpdateLooterGuid(creature, true);
6414 if (group->GetLooterGuid())
6415 {
6416 looter = ObjectAccessor::FindPlayer(group->GetLooterGuid());
6417 if (looter)
6418 {
6419 creature->SetLootRecipient(looter); // update creature loot recipient to the allowed looter.
6420 group->SendLooter(creature, looter);
6421 }
6422 else
6423 group->SendLooter(creature, NULL);
6424 }
6425 else
6426 group->SendLooter(creature, NULL);
6427
6428 group->UpdateLooterGuid(creature);
6429 }
6430 }
6431 else
6432 {
6433 player->SendDirectMessage(&data);
6434
6435 if (creature)
6436 {
6437 ObjectGuid creatureGuid = creature->GetGUID();
6439
6440 data2.WriteGuidMask(creatureGuid, 5);
6441 data2.WriteBit(0);
6442 data2.WriteGuidMask(creatureGuid, 1);
6443 data2.WriteBit(0);
6444 data2.WriteGuidMask(creatureGuid, 4, 3, 2, 7, 0, 6);
6445
6446 data2.WriteGuidBytes(creatureGuid, 5, 1, 6, 2, 3, 0, 7, 4);
6447
6448 player->SendMessageToSet(&data2, true);
6449 }
6450 }
6451
6452 if (creature)
6453 {
6454 Loot* loot = &creature->loot;
6455 if (creature->lootForPickPocketed)
6456 creature->lootForPickPocketed = false;
6457
6458 loot->clear();
6459 if (uint32 lootid = creature->GetCreatureTemplate()->lootid)
6460 loot->FillLoot(lootid, LootTemplates_Creature, looter, false, false, creature->GetLootMode());
6461
6463 }
6464
6465 player->RewardPlayerAndGroupAtKill(victim, false);
6466 }
6467
6468 // Do KILL and KILLED procs. KILL proc is called only for the unit who landed the killing blow (and its owner - for pets and totems) regardless of who tapped the victim
6469 if (IsPet() || IsTotem())
6470 if (Unit* owner = GetOwner())
6472
6473 if (victim->GetCreatureType() != CREATURE_TYPE_CRITTER)
6475
6476 // Proc auras on death - must be before aura/combat remove
6478
6479 // update get killing blow achievements, must be done before setDeathState to be able to require auras on target
6480 // and before Spirit of Redemption as it also removes auras
6481 if (player)
6483
6484 // if talent known but not triggered (check priest class for speedup check)
6485 bool spiritOfRedemption = false;
6486 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER && victim->getClass() == CLASS_PRIEST)
6487 {
6488 AuraEffectList const& dummyAuras = victim->GetAuraEffectsByType(SPELL_AURA_DUMMY);
6489 for (AuraEffectList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
6490 {
6491 if ((*itr)->GetSpellInfo()->SpellIconID == 1654)
6492 {
6493 AuraEffect const* aurEff = *itr;
6494 // save value before aura remove
6495 uint32 ressSpellId = victim->GetUInt32Value(PLAYER_FIELD_SELF_RES_SPELL);
6496 if (!ressSpellId)
6497 ressSpellId = victim->ToPlayer()->GetResurrectionSpellId();
6498 // Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers)
6499 victim->RemoveAllAurasOnDeath();
6500 // restore for use at real death
6501 victim->SetUInt32Value(PLAYER_FIELD_SELF_RES_SPELL, ressSpellId);
6502
6503 // FORM_SPIRITOFREDEMPTION and related auras
6504 victim->CastSpell(victim, 27827, true, NULL, aurEff);
6505 spiritOfRedemption = true;
6506 break;
6507 }
6508 }
6509 }
6510
6511 if (!spiritOfRedemption)
6512 {
6513 SF_LOG_DEBUG("entities.unit", "SET JUST_DIED");
6515 }
6516
6517 // Inform pets (if any) when player kills target)
6518 // MUST come after victim->setDeathState(JUST_DIED); or pet next target
6519 // selection will get stuck on same target and break pet react state
6520 if (player)
6521 {
6522 Pet* pet = player->GetPet();
6523 if (pet && pet->IsAlive() && pet->isControlled())
6524 pet->AI()->KilledUnit(victim);
6525 }
6526
6527 // 10% durability loss on death
6528 // clean InHateListOf
6529 if (Player* plrVictim = victim->ToPlayer())
6530 {
6531 // remember victim PvP death for corpse type and corpse reclaim delay
6532 // at original death (not at SpiritOfRedemtionTalent timeout)
6533 plrVictim->SetPvPDeath(player != NULL);
6534
6535 // only if not player and not controlled by player pet. And not at BG
6536 if ((durabilityLoss && !player && !victim->ToPlayer()->InBattleground()) || (player && sWorld->GetBoolConfig(WorldBoolConfigs::CONFIG_DURABILITY_LOSS_IN_PVP)))
6537 {
6538 double baseLoss = sWorld->getRate(Rates::RATE_DURABILITY_LOSS_ON_DEATH);
6539 uint32 loss = uint32(baseLoss - (baseLoss * plrVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_DURABILITY_LOSS)));
6540 SF_LOG_DEBUG("entities.unit", "We are dead, losing %u percent durability", loss);
6541 // Durability loss is calculated more accurately again for each item in Player::DurabilityLoss
6542 plrVictim->DurabilityLossAll(baseLoss, false);
6543 // durability lost message
6544 SendDurabilityLoss(plrVictim, loss);
6545 }
6546 // Call KilledUnit for creatures
6548 ToCreature()->AI()->KilledUnit(victim);
6549
6550 // last damage from non duel opponent or opponent controlled creature
6551 if (plrVictim->duel)
6552 {
6553 plrVictim->duel->opponent->CombatStopWithPets(true);
6554 plrVictim->CombatStopWithPets(true);
6555 plrVictim->DuelComplete(DuelCompleteType::DUEL_INTERRUPTED);
6556 }
6557 }
6558 else // creature died
6559 {
6560 SF_LOG_DEBUG("entities.unit", "DealDamageNotPlayer");
6561
6562 if (creature && !creature->IsPet())
6563 {
6564 creature->DeleteThreatList();
6565 CreatureTemplate const* cInfo = creature->GetCreatureTemplate();
6566 if (cInfo && (cInfo->lootid || cInfo->maxgold > 0))
6568 }
6569
6570 // Call KilledUnit for creatures, this needs to be called after the lootable flag is set
6572 ToCreature()->AI()->KilledUnit(victim);
6573
6574 // Call creature just died function
6575 if (creature && creature->IsAIEnabled)
6576 creature->AI()->JustDied(this);
6577
6578 if (TempSummon* summon = creature->ToTempSummon())
6579 if (Unit* summoner = summon->GetSummoner())
6580 if (summoner->ToCreature() && summoner->IsAIEnabled)
6581 summoner->ToCreature()->AI()->SummonedCreatureDies(creature, this);
6582
6583 // Dungeon specific stuff, only applies to players killing creatures
6584 if (creature && creature->GetInstanceId())
6585 {
6586 Map* instanceMap = creature->GetMap();
6589
6590 if (instanceMap->IsInstance() && creditedPlayer)
6591 {
6592 if (instanceMap->IsRaidOrHeroicDungeon())
6593 {
6595 ((InstanceMap*)instanceMap)->PermBindAllPlayers(creditedPlayer);
6596 }
6597 else
6598 {
6599 // the reset time is set but not added to the scheduler
6600 // until the players leave the instance
6601 time_t resettime = creature->GetRespawnTimeEx() + time_t(2 * HOUR);
6602 if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(creature->GetInstanceId()))
6603 if (save->GetResetTime() < resettime) save->SetResetTime(resettime);
6604 }
6605 }
6606 }
6607 }
6608
6609 // outdoor pvp things, do these after setting the death state, else the player activity notify won't work... doh...
6610 // handle player kill only if not suicide (spirit of redemption for example)
6611 if (player && this != victim)
6612 {
6613 if (OutdoorPvP* pvp = player->GetOutdoorPvP())
6614 pvp->HandleKill(player, victim);
6615
6616 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId()))
6617 bf->HandleKill(player, victim);
6618 }
6619
6620 //if (victim->GetTypeId() == TYPEID_PLAYER)
6621 // if (OutdoorPvP* pvp = victim->ToPlayer()->GetOutdoorPvP())
6622 // pvp->HandlePlayerActivityChangedpVictim->ToPlayer();
6623
6624 // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill)
6625 if (player && player->InBattleground())
6626 {
6627 if (Battleground* bg = player->GetBattleground())
6628 {
6629 if (Player* playerVictim = victim->ToPlayer())
6630 bg->HandleKillPlayer(playerVictim, player);
6631 else
6632 bg->HandleKillUnit(victim->ToCreature(), player);
6633 }
6634 }
6635
6636 // achievement stuff
6637 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
6638 {
6641 else if (GetTypeId() == TypeID::TYPEID_PLAYER && victim != this)
6643 }
6644
6645 // Hook for OnPVPKill Event
6646 if (Player* killerPlr = ToPlayer())
6647 {
6648 if (Player* killedPlr = victim->ToPlayer())
6649 sScriptMgr->OnPVPKill(killerPlr, killedPlr);
6650 else if (Creature* killedCre = victim->ToCreature())
6651 sScriptMgr->OnCreatureKill(killerPlr, killedCre);
6652 }
6653 else if (Creature* killerCre = ToCreature())
6654 {
6655 if (Player* killed = victim->ToPlayer())
6656 sScriptMgr->OnPlayerKilledByCreature(killerCre, killed);
6657 }
6658}
6659
6661{
6662 float offset = 0.0f;
6665
6666 return GetPositionZ() - offset;
6667}
6668
6669void Unit::SetControlled(bool apply, UnitState state)
6670{
6671 if (apply)
6672 {
6673 if (HasUnitState(state))
6674 return;
6675
6676 AddUnitState(state);
6677 switch (state)
6678 {
6679 case UNIT_STATE_STUNNED:
6680 SetStunned(true);
6681 CastStop();
6682 break;
6683 case UNIT_STATE_ROOT:
6685 SetRooted(true);
6686 break;
6689 {
6692 // SendAutoRepeatCancel ?
6693 SetConfused(true);
6694 CastStop();
6695 }
6696 break;
6697 case UNIT_STATE_FLEEING:
6699 {
6702 // SendAutoRepeatCancel ?
6703 SetFeared(true);
6704 CastStop();
6705 }
6706 break;
6707 default:
6708 break;
6709 }
6710 }
6711 else
6712 {
6713 switch (state)
6714 {
6715 case UNIT_STATE_STUNNED:
6717 return;
6718
6719 SetStunned(false);
6720 break;
6721 case UNIT_STATE_ROOT:
6723 return;
6724
6726 SetRooted(false);
6727 break;
6730 return;
6731
6732 SetConfused(false);
6733 break;
6734 case UNIT_STATE_FLEEING:
6736 return;
6737
6738 SetFeared(false);
6739 break;
6740 default:
6741 return;
6742 }
6743
6744 ClearUnitState(state);
6745
6747 SetStunned(true);
6748 else
6749 {
6751 SetRooted(true);
6752
6754 SetConfused(true);
6756 SetFeared(true);
6757 }
6758 }
6759}
6760
6761void Unit::SetStunned(bool apply)
6762{
6763 if (apply)
6764 {
6765 SetTarget(0);
6767
6768 // Creature specific
6771 else
6773
6774 SetRooted(true);
6775
6776 CastStop();
6777 }
6778 else
6779 {
6780 if (IsAlive() && GetVictim())
6782
6783 // don't remove UNIT_FLAG_STUNNED for pet when owner is mounted (disabled pet's interface)
6784 Unit* owner = GetOwner();
6785 if (!owner || (owner->GetTypeId() == TypeID::TYPEID_PLAYER
6786 && (!owner->ToPlayer()->IsMounted() || owner->ToPlayer()->GetTransport())))
6788
6789 if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect
6790 SetRooted(false);
6791 }
6792}
6793
6794void Unit::SetRooted(bool apply, bool packetOnly /*= false*/)
6795{
6796 if (!packetOnly)
6797 {
6798 if (apply)
6799 {
6800 // MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a)
6801 // this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
6802 // setting MOVEMENTFLAG_ROOT
6805 }
6806 else
6808 }
6809
6810 if (apply)
6812 else
6814}
6815
6816void Unit::SetFeared(bool apply)
6817{
6818 if (apply)
6819 {
6820 SetTarget(0);
6821
6822 Unit* caster = NULL;
6824 if (!fearAuras.empty())
6825 {
6826 caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID());
6827 if (!caster)
6828 caster = getAttackerForHelper();
6829 GetMotionMaster()->MoveFleeing(caster, fearAuras.empty() ? sWorld->getIntConfig(WorldIntConfigs::CONFIG_CREATURE_FAMILY_FLEE_DELAY) : 0); // caster == NULL processed in MoveFleeing
6830 }
6831
6833 if (!fearAuras2.empty())
6834 {
6835 caster = ObjectAccessor::GetUnit(*this, fearAuras2.front()->GetCasterGUID());
6836 if (!caster)
6837 caster = getAttackerForHelper();
6838 GetMotionMaster()->MoveFleeing(caster, fearAuras2.empty() ? sWorld->getIntConfig(WorldIntConfigs::CONFIG_CREATURE_FAMILY_FLEE_DELAY) : 0); // caster == NULL processed in MoveFleeing
6839 }
6840 }
6841 else
6842 {
6843 if (IsAlive())
6844 {
6845 if (GetMotionMaster()->GetCurrentMovementGeneratorType() == FLEEING_MOTION_TYPE)
6847 if (GetVictim())
6849 }
6850 }
6851
6853 ToPlayer()->SetClientControl(this, !apply);
6854}
6855
6856void Unit::SetConfused(bool apply)
6857{
6858 if (apply)
6859 {
6860 SetTarget(0);
6862 }
6863 else
6864 {
6865 if (IsAlive())
6866 {
6867 if (GetMotionMaster()->GetCurrentMovementGeneratorType() == CONFUSED_MOTION_TYPE)
6869 if (GetVictim())
6871 }
6872 }
6873
6875 ToPlayer()->SetClientControl(this, !apply);
6876}
6877
6878bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* aurApp)
6879{
6880 if (!charmer)
6881 return false;
6882
6883 // dismount players when charmed
6886
6887 if (charmer->GetTypeId() == TypeID::TYPEID_PLAYER)
6889
6890 ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TypeID::TYPEID_PLAYER);
6891 ASSERT((type == CHARM_TYPE_VEHICLE) == IsVehicle());
6892
6893 SF_LOG_DEBUG("entities.unit", "SetCharmedBy: charmer %u (GUID %u), charmed %u (GUID %u), type %u.", charmer->GetEntry(), charmer->GetGUIDLow(), GetEntry(), GetGUIDLow(), uint32(type));
6894
6895 if (this == charmer)
6896 {
6897 SF_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Unit %u (GUID %u) is trying to charm itself!", GetEntry(), GetGUIDLow());
6898 return false;
6899 }
6900
6901 //if (HasUnitState(UNIT_STATE_UNATTACKABLE))
6902 // return false;
6903
6905 {
6906 SF_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Player on transport is trying to charm %u (GUID %u)", GetEntry(), GetGUIDLow());
6907 return false;
6908 }
6909
6910 // Already charmed
6911 if (GetCharmerGUID())
6912 {
6913 SF_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: %u (GUID %u) has already been charmed but %u (GUID %u) is trying to charm it!", GetEntry(), GetGUIDLow(), charmer->GetEntry(), charmer->GetGUIDLow());
6914 return false;
6915 }
6916
6917 CastStop();
6918 CombatStop();
6920
6921 // Charmer stop charming
6922 if (charmer->GetTypeId() == TypeID::TYPEID_PLAYER)
6923 {
6924 charmer->ToPlayer()->StopCastingCharm();
6925 charmer->ToPlayer()->StopCastingBindSight();
6926 }
6927
6928 // Charmed stop charming
6930 {
6933 }
6934
6935 // StopCastingCharm may remove a possessed pet?
6936 if (!IsInWorld())
6937 {
6938 SF_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: %u (GUID %u) is not in world but %u (GUID %u) is trying to charm it!", GetEntry(), GetGUIDLow(), charmer->GetEntry(), charmer->GetGUIDLow());
6939 return false;
6940 }
6941
6942 // charm is set by aura, and aura effect remove handler was called during apply handler execution
6943 // prevent undefined behaviour
6944 if (aurApp && aurApp->GetRemoveMode())
6945 return false;
6946
6947 // Set charmed
6948 Map* map = GetMap();
6949 if (!IsVehicle() || (IsVehicle() && map && !map->IsBattleground()))
6950 setFaction(charmer->getFaction());
6951
6952 charmer->SetCharm(this, true);
6953
6955 {
6956 ToCreature()->AI()->OnCharmed(true);
6958 }
6959 else
6960 {
6961 Player* player = ToPlayer();
6962 if (player->isAFK())
6963 player->ToggleAFK();
6964 player->SetClientControl(this, 0);
6965 }
6966
6967 // charm is set by aura, and aura effect remove handler was called during apply handler execution
6968 // prevent undefined behaviour
6969 if (aurApp && aurApp->GetRemoveMode())
6970 return false;
6971
6972 // Pets already have a properly initialized CharmInfo, don't overwrite it.
6973 if (type != CHARM_TYPE_VEHICLE && !GetCharmInfo())
6974 {
6975 InitCharmInfo();
6976 if (type == CHARM_TYPE_POSSESS)
6978 else
6980 }
6981
6982 if (charmer->GetTypeId() == TypeID::TYPEID_PLAYER)
6983 {
6984 switch (type)
6985 {
6986 case CHARM_TYPE_VEHICLE:
6988 charmer->ToPlayer()->SetClientControl(this, 1);
6989 charmer->ToPlayer()->SetMover(this);
6990 charmer->ToPlayer()->SetViewpoint(this, true);
6991 charmer->ToPlayer()->VehicleSpellInitialize();
6992 break;
6993 case CHARM_TYPE_POSSESS:
6997 charmer->ToPlayer()->SetClientControl(this, 1);
6998 charmer->ToPlayer()->SetMover(this);
6999 charmer->ToPlayer()->SetViewpoint(this, true);
7000 charmer->ToPlayer()->PossessSpellInitialize();
7001 break;
7002 case CHARM_TYPE_CHARM:
7003 if (GetTypeId() == TypeID::TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
7004 {
7006 if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
7007 {
7008 // to prevent client crash
7010
7011 // just to enable stat window
7012 if (GetCharmInfo())
7013 GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
7014
7015 // if charmed two demons the same session, the 2nd gets the 1st one's name
7016 SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped
7017 }
7018 }
7019 charmer->ToPlayer()->CharmSpellInitialize();
7020 break;
7021 default:
7022 case CHARM_TYPE_CONVERT:
7023 break;
7024 }
7025 }
7026 return true;
7027}
7028
7030{
7031 if (!IsCharmed())
7032 return;
7033
7034 if (!charmer)
7035 charmer = GetCharmer();
7036 if (charmer != GetCharmer()) // one aura overrides another?
7037 {
7038 // SF_LOG_FATAL("entities.unit", "Unit::RemoveCharmedBy: this: " UI64FMTD " true charmer: " UI64FMTD " false charmer: " UI64FMTD,
7039 // GetGUID(), GetCharmerGUID(), charmer->GetGUID());
7040 // ASSERT(false);
7041 return;
7042 }
7043
7044 CharmType type;
7046 type = CHARM_TYPE_POSSESS;
7047 else if (charmer && charmer->IsOnVehicle(this))
7048 type = CHARM_TYPE_VEHICLE;
7049 else
7050 type = CHARM_TYPE_CHARM;
7051
7052 CastStop();
7053 CombatStop();
7056 Map* map = GetMap();
7057 if (!IsVehicle() || (IsVehicle() && map && !map->IsBattleground()))
7060
7061 if (type == CHARM_TYPE_POSSESS)
7062 {
7065 }
7066
7067 if (Creature* creature = ToCreature())
7068 {
7069 // Creature will restore its old AI on next update
7070 if (creature->AI())
7071 creature->AI()->OnCharmed(false);
7072
7073 // Vehicle should not attack its passenger after he exists the seat
7074 if (type != CHARM_TYPE_VEHICLE)
7075 LastCharmerGUID = charmer->GetGUID();
7076 }
7077 else
7078 ToPlayer()->SetClientControl(this, 1);
7079
7080 // If charmer still exists
7081 if (!charmer)
7082 return;
7083
7084 ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TypeID::TYPEID_PLAYER);
7086
7087 charmer->SetCharm(this, false);
7088
7089 if (charmer->GetTypeId() == TypeID::TYPEID_PLAYER)
7090 {
7091 switch (type)
7092 {
7093 case CHARM_TYPE_VEHICLE:
7094 charmer->ToPlayer()->SetClientControl(charmer, 1);
7095 charmer->ToPlayer()->SetViewpoint(this, false);
7096 charmer->ToPlayer()->SetClientControl(this, 0);
7098 ToPlayer()->SetMover(this);
7099 break;
7100 case CHARM_TYPE_POSSESS:
7101 charmer->ToPlayer()->SetClientControl(charmer, 1);
7102 charmer->ToPlayer()->SetViewpoint(this, false);
7103 charmer->ToPlayer()->SetClientControl(this, 0);
7106 ToPlayer()->SetMover(this);
7107 break;
7108 case CHARM_TYPE_CHARM:
7109 if (GetTypeId() == TypeID::TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
7110 {
7112 if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
7113 {
7114 SetClass(uint8(cinfo->unit_class));
7115 if (GetCharmInfo())
7116 GetCharmInfo()->SetPetNumber(0, true);
7117 else
7118 SF_LOG_ERROR("entities.unit", "Aura::HandleModCharm: target=" UI64FMTD " with typeid=%d has a charm aura but no charm info!", GetGUID(), uint8(GetTypeId()));
7119 }
7120 }
7121 break;
7122 default:
7123 case CHARM_TYPE_CONVERT:
7124 break;
7125 }
7126 }
7127
7128 // a guardian should always have charminfo
7129 if (charmer->GetTypeId() == TypeID::TYPEID_PLAYER && this != charmer->GetFirstControlled())
7130 charmer->ToPlayer()->SendRemoveControlBar();
7133}
7134
7136{
7139 else
7140 {
7142 {
7143 if (Unit* owner = GetOwner())
7144 {
7145 setFaction(owner->getFaction());
7146 return;
7147 }
7148 }
7149
7150 if (CreatureTemplate const* cinfo = ToCreature()->GetCreatureTemplate()) // normal creature
7151 {
7153 setFaction((faction && faction->friendlyMask & 0x004) ? cinfo->faction_H : cinfo->faction_A);
7154 }
7155 }
7156}
7157
7159{
7160 return _redirectThreadInfo.GetTargetGUID() ? ObjectAccessor::GetUnit(*this, _redirectThreadInfo.GetTargetGUID()) : NULL;
7161}
7162
7163bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry, bool loading /*= false*/)
7164{
7165 VehicleEntry const* vehInfo = sVehicleStore.LookupEntry(id);
7166 if (!vehInfo)
7167 return false;
7168
7169 m_vehicleKit = new Vehicle(this, vehInfo, creatureEntry);
7172
7173 if (!loading)
7175
7176 return true;
7177}
7178
7179void Unit::RemoveVehicleKit(bool remove /*= false*/)
7180{
7181 if (!m_vehicleKit)
7182 return;
7183
7184 if (!remove)
7186
7187 m_vehicleKit->Uninstall();
7188 delete m_vehicleKit;
7189
7190 m_vehicleKit = NULL;
7191
7196}
7197
7198bool Unit::IsOnVehicle(const Unit* vehicle) const
7199{
7200 return m_vehicle && m_vehicle == vehicle->GetVehicleKit();
7201}
7202
7204{
7205 return m_vehicle ? m_vehicle->GetBase() : NULL;
7206}
7207
7209{
7210 if (Unit* veh = GetVehicleBase())
7211 if (Creature* c = veh->ToCreature())
7212 return c;
7213
7214 return NULL;
7215}
7216
7218{
7219 if (GetVehicle())
7220 return GetVehicleBase()->GetGUID();
7221 if (GetTransport())
7222 return GetTransport()->GetGUID();
7223
7224 return 0;
7225}
7226
7228{
7229 if (Vehicle* veh = GetVehicle())
7230 return veh;
7231 return GetTransport();
7232}
7233
7234bool Unit::IsInPartyWith(Unit const* unit) const
7235{
7236 if (this == unit)
7237 return true;
7238
7239 const Unit* u1 = GetCharmerOrOwnerOrSelf();
7240 const Unit* u2 = unit->GetCharmerOrOwnerOrSelf();
7241 if (u1 == u2)
7242 return true;
7243
7245 return u1->ToPlayer()->IsInSameGroupWith(u2->ToPlayer());
7248 return true;
7249 else
7250 return false;
7251}
7252
7253bool Unit::IsInRaidWith(Unit const* unit) const
7254{
7255 if (this == unit)
7256 return true;
7257
7258 const Unit* u1 = GetCharmerOrOwnerOrSelf();
7259 const Unit* u2 = unit->GetCharmerOrOwnerOrSelf();
7260 if (u1 == u2)
7261 return true;
7262
7264 return u1->ToPlayer()->IsInSameRaidWith(u2->ToPlayer());
7267 return true;
7268 else
7269 return false;
7270}
7271
7272void Unit::GetPartyMembers(std::list<Unit*>& TagUnitMap)
7273{
7274 Unit* owner = GetCharmerOrOwnerOrSelf();
7275 Group* group = NULL;
7276 if (owner->GetTypeId() == TypeID::TYPEID_PLAYER)
7277 group = owner->ToPlayer()->GetGroup();
7278
7279 if (group)
7280 {
7281 uint8 subgroup = owner->ToPlayer()->GetSubGroup();
7282
7283 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
7284 {
7285 Player* Target = itr->GetSource();
7286
7287 // IsHostileTo check duel and controlled by enemy
7288 if (Target && Target->GetSubGroup() == subgroup && !IsHostileTo(Target))
7289 {
7290 if (Target->IsAlive() && IsInMap(Target))
7291 TagUnitMap.push_back(Target);
7292
7293 if (Guardian* pet = Target->GetGuardianPet())
7294 if (pet->IsAlive() && IsInMap(Target))
7295 TagUnitMap.push_back(pet);
7296 }
7297 }
7298 }
7299 else
7300 {
7301 if (owner->IsAlive() && (owner == this || IsInMap(owner)))
7302 TagUnitMap.push_back(owner);
7303 if (Guardian* pet = owner->GetGuardianPet())
7304 if (pet->IsAlive() && (pet == this || IsInMap(pet)))
7305 TagUnitMap.push_back(pet);
7306 }
7307}
7308
7310{
7311 if (FactionTemplateEntry const* entry = GetFactionTemplateEntry())
7312 return entry->IsContestedGuardFaction();
7313
7314 return false;
7315}
7316
7324
7325void Unit::SendPlaySpellVisual(uint32 SpellVisualId, float x, float y, float z, float orientation, uint8 SpeedTime, uint16 MissReason, uint16 ReflectStatus)
7326{
7327 ObjectGuid SourceGuid = GetGUID();
7328 ObjectGuid TargetGuid;
7329
7330 WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 4 + 4 + 4 + 8);
7331
7332 data.WriteBit(SourceGuid[4]);
7333 data.WriteBit(TargetGuid[6]);
7334 data.WriteBit(TargetGuid[4]);
7335 data.WriteBit(TargetGuid[7]);
7336 data.WriteBit(SourceGuid[6]);
7337 data.WriteBit(TargetGuid[2]);
7338 data.WriteBit(TargetGuid[0]);
7339 data.WriteBit(SourceGuid[2]);
7340 data.WriteBit(SpeedTime);
7341 data.WriteBit(SourceGuid[7]);
7342 data.WriteBit(TargetGuid[3]);
7343 data.WriteBit(TargetGuid[1]);
7344 data.WriteBit(SourceGuid[0]);
7345 data.WriteBit(SourceGuid[1]);
7346 data.WriteBit(TargetGuid[5]);
7347 data.WriteBit(SourceGuid[5]);
7348 data.WriteBit(SourceGuid[3]);
7349
7350 data << float(z);
7351 data.WriteByteSeq(SourceGuid[2]);
7352 data.WriteByteSeq(SourceGuid[6]);
7353 data.WriteByteSeq(SourceGuid[5]);
7354 data.WriteByteSeq(TargetGuid[2]);
7355 data.WriteByteSeq(SourceGuid[1]);
7356 data << float(x);
7357 data.WriteByteSeq(SourceGuid[3]);
7358 data << uint16(ReflectStatus);
7359 data.WriteByteSeq(TargetGuid[4]);
7360 data.WriteByteSeq(TargetGuid[7]);
7361 data << float(orientation);
7362 data << float(y);
7363 data.WriteByteSeq(SourceGuid[4]);
7364 data.WriteByteSeq(TargetGuid[5]);
7365 data << uint32(SpellVisualId);
7366 data.WriteByteSeq(TargetGuid[1]);
7367 data.WriteByteSeq(SourceGuid[7]);
7368 data << uint16(MissReason);
7369 data.WriteByteSeq(TargetGuid[0]);
7370 data.WriteByteSeq(TargetGuid[6]);
7371 data.WriteByteSeq(SourceGuid[0]);
7372 data.WriteByteSeq(TargetGuid[3]);
7373
7374 SendMessageToSet(&data, true);
7375}
7376
7377void Unit::SendPlaySpellVisualKit(uint32 SpellVisualId, uint32 Duration, int32 Type)
7378{
7379 ObjectGuid UnitGuid = GetGUID();
7380
7381 WorldPacket data(SMSG_PLAY_SPELL_VISUAL_KIT, 4 + 4 + 4 + 8);
7382
7383 data.WriteGuidMask(UnitGuid, 4, 2, 6, 5, 1, 3, 0, 7);
7384
7385 data.WriteGuidBytes(UnitGuid, 5, 7);
7386 data << uint32(Type);
7387 data.WriteGuidBytes(UnitGuid, 1, 0, 6);
7388 data << uint32(Duration);
7389 data.WriteGuidBytes(UnitGuid, 4, 2, 3);
7390 data << uint32(SpellVisualId);
7391
7392 SendMessageToSet(&data, true);
7393}
7394
7395void Unit::ApplyResilience(Unit const* victim, int32* damage, bool isCrit) const
7396{
7397 // player mounted on multi-passenger mount is also classified as vehicle
7398 if (IsVehicle() || (victim->IsVehicle() && victim->GetTypeId() != TypeID::TYPEID_PLAYER))
7399 return;
7400
7401 // Don't consider resilience if not in PvP - player or pet
7403 return;
7404
7405 Unit const* target = NULL;
7406 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
7407 target = victim;
7408 else if (victim->GetTypeId() == TypeID::TYPEID_UNIT && victim->GetOwner() && victim->GetOwner()->GetTypeId() == TypeID::TYPEID_PLAYER)
7409 target = victim->GetOwner();
7410
7411 if (!target)
7412 return;
7413
7414 if (isCrit)
7415 *damage -= target->GetCritDamageReduction(*damage);
7416 *damage -= target->GetDamageReduction(*damage);
7417}
7418
7419// Melee based spells can be miss, parry or dodge on this step
7420// Crit or block - determined on damage calculation phase! (and can be both in some time)
7421float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, uint32 spellId) const
7422{
7423 //calculate miss chance
7424 float missChance = victim->GetUnitMissChance(attType);
7425
7426 if (!spellId && haveOffhandWeapon())
7427 missChance += 19;
7428
7429 // Calculate hit chance
7430 float hitChance = 100.0f;
7431
7432 // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
7433 if (spellId)
7434 {
7435 if (Player* modOwner = GetSpellModOwner())
7436 modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, hitChance);
7437 }
7438
7439 missChance += hitChance - 100.0f;
7440
7441 if (attType == WeaponAttackType::RANGED_ATTACK)
7442 missChance -= m_modRangedHitChance;
7443 else
7444 missChance -= m_modMeleeHitChance;
7445
7446 // Limit miss chance from 0 to 60%
7447 if (missChance < 0.0f)
7448 return 0.0f;
7449 if (missChance > 60.0f)
7450 return 60.0f;
7451 return missChance;
7452}
7453
7454void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
7455{
7456 if (newPhaseMask == GetPhaseMask())
7457 return;
7458
7459 if (IsInWorld())
7460 {
7461 RemoveNotOwnSingleTargetAuras(newPhaseMask); // we can lost access to caster or target
7462
7463 // modify hostile references for new phasemask, some special cases deal with hostile references themselves
7464 if (GetTypeId() == TypeID::TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))
7465 {
7467 HostileReference* ref = refManager.getFirst();
7468
7469 while (ref)
7470 {
7471 if (Unit* unit = ref->GetSource()->GetOwner())
7472 if (Creature* creature = unit->ToCreature())
7473 refManager.setOnlineOfflineState(creature, creature->InSamePhase(newPhaseMask));
7474
7475 ref = ref->next();
7476 }
7477
7478 // modify threat lists for new phasemask
7480 {
7481 std::list<HostileReference*> threatList = getThreatManager().getThreatList();
7482 std::list<HostileReference*> offlineThreatList = getThreatManager().getOfflineThreatList();
7483
7484 // merge expects sorted lists
7485 threatList.sort();
7486 offlineThreatList.sort();
7487 threatList.merge(offlineThreatList);
7488
7489 for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
7490 if (Unit* unit = (*itr)->getTarget())
7491 unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->InSamePhase(newPhaseMask));
7492 }
7493 }
7494 }
7495
7496 WorldObject::SetPhaseMask(newPhaseMask, update);
7497
7498 if (!IsInWorld())
7499 return;
7500
7501 for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
7502 if ((*itr)->GetTypeId() == TypeID::TYPEID_UNIT)
7503 (*itr)->SetPhaseMask(newPhaseMask, true);
7504
7505 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
7506 if (m_SummonSlot[i])
7507 if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i]))
7508 summon->SetPhaseMask(newPhaseMask, true);
7509}
7510
7511void Unit::ClearPhases(bool update)
7512{
7514}
7515
7516bool Unit::SetPhased(uint32 id, bool update, bool apply)
7517{
7518 bool res = WorldObject::SetPhased(id, update, apply);
7519
7520 if (!IsInWorld())
7521 return res;
7522
7523 if (GetTypeId() == TypeID::TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))
7524 {
7526 HostileReference* ref = refManager.getFirst();
7527
7528 while (ref)
7529 {
7530 if (Unit* unit = ref->GetSource()->GetOwner())
7531 if (Creature* creature = unit->ToCreature())
7532 refManager.setOnlineOfflineState(creature, creature->IsPhased(this));
7533
7534 ref = ref->next();
7535 }
7536
7537 // modify threat lists for new phasemask
7539 {
7540 std::list<HostileReference*> threatList = getThreatManager().getThreatList();
7541 std::list<HostileReference*> offlineThreatList = getThreatManager().getOfflineThreatList();
7542
7543 // merge expects sorted lists
7544 threatList.sort();
7545 offlineThreatList.sort();
7546 threatList.merge(offlineThreatList);
7547
7548 for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
7549 if (Unit* unit = (*itr)->getTarget())
7550 unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->IsPhased(this));
7551 }
7552 }
7553
7554 for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
7555 if ((*itr)->GetTypeId() == TypeID::TYPEID_UNIT)
7556 (*itr)->SetPhased(id, true, apply);
7557
7558 for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
7559 if (m_SummonSlot[i])
7560 if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i]))
7561 summon->SetPhased(id, true, apply);
7562
7564 return res;
7565}
7566
7568{
7569 if (!forced)
7571 else
7572 {
7574 // call MoveInLineOfSight for nearby creatures
7575 Skyfire::AIRelocationNotifier notifier(*this);
7577 }
7578}
7579
7580void Unit::SendMoveKnockBack(Player* player, float speedXY, float speedZ, float vcos, float vsin)
7581{
7582 ObjectGuid guid = GetGUID();
7583 WorldPacket data(SMSG_MOVE_KNOCK_BACK, (1 + 8 + 4 + 4 + 4 + 4 + 4));
7584
7585 data << float(speedXY);
7586 data << float(vsin);
7587 data << float(speedZ);
7588 data << uint32(0);
7589 data << float(vcos);
7590
7591 data.WriteGuidMask(guid, 2, 0, 7, 1, 4, 6, 5, 3);
7592 data.WriteGuidBytes(guid, 6, 0, 7, 5, 4, 3, 1, 2);
7593
7594 player->GetSession()->SendPacket(&data);
7595}
7596
7597void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
7598{
7599 Player* player = ToPlayer();
7600 if (!player)
7601 {
7602 if (Unit* charmer = GetCharmer())
7603 {
7604 player = charmer->ToPlayer();
7605 if (player && player->m_mover != this)
7606 player = NULL;
7607 }
7608 }
7609
7610 if (!player)
7611 GetMotionMaster()->MoveKnockbackFrom(x, y, speedXY, speedZ);
7612 else
7613 {
7614 float vcos, vsin;
7615 GetSinCos(x, y, vsin, vcos);
7616 SendMoveKnockBack(player, speedXY, -speedZ, vcos, vsin);
7617 }
7618}
7619
7621{
7622 if (Player const* player = ToPlayer())
7623 return player->GetRatingBonusValue(cr);
7624 // Player's pet get resilience from owner
7625 else if (IsPet() && GetOwner())
7626 if (Player* owner = GetOwner()->ToPlayer())
7627 return owner->GetRatingBonusValue(cr);
7628
7629 return 0.0f;
7630}
7631
7632uint32 Unit::GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const
7633{
7634 float percent = std::min(GetCombatRatingReduction(cr) * rate, cap);
7635 return CalculatePct(damage, percent);
7636}
7637
7639{
7641 {
7642 switch (form)
7643 {
7644 case FORM_CAT:
7645 // Based on Hair color
7646 if (getRace() == RACE_NIGHTELF)
7647 {
7649 switch (hairColor)
7650 {
7651 case 7: // Violet
7652 case 8:
7653 return 29405;
7654 case 3: // Light Blue
7655 return 29406;
7656 case 0: // Green
7657 case 1: // Light Green
7658 case 2: // Dark Green
7659 return 29407;
7660 case 4: // White
7661 return 29408;
7662 default: // original - Dark Blue
7663 return 892;
7664 }
7665 }
7666 else if (getRace() == RACE_TROLL)
7667 {
7669 switch (hairColor)
7670 {
7671 case 0: // Red
7672 case 1:
7673 return 33668;
7674 case 2: // Yellow
7675 case 3:
7676 return 33667;
7677 case 4: // Blue
7678 case 5:
7679 case 6:
7680 return 33666;
7681 case 7: // Purple
7682 case 10:
7683 return 33665;
7684 default: // original - white
7685 return 33669;
7686 }
7687 }
7688 else if (getRace() == RACE_WORGEN)
7689 {
7690 // Based on Skin color
7692 // Male
7693 if (getGender() == GENDER_MALE)
7694 {
7695 switch (skinColor)
7696 {
7697 case 1: // Brown
7698 return 33662;
7699 case 2: // Black
7700 case 7:
7701 return 33661;
7702 case 4: // yellow
7703 return 33664;
7704 case 3: // White
7705 case 5:
7706 return 33663;
7707 default: // original - Gray
7708 return 33660;
7709 }
7710 }
7711 // Female
7712 else
7713 {
7714 switch (skinColor)
7715 {
7716 case 5: // Brown
7717 case 6:
7718 return 33662;
7719 case 7: // Black
7720 case 8:
7721 return 33661;
7722 case 3: // yellow
7723 case 4:
7724 return 33664;
7725 case 2: // White
7726 return 33663;
7727 default: // original - Gray
7728 return 33660;
7729 }
7730 }
7731 }
7732 // Based on Skin color
7733 else if (getRace() == RACE_TAUREN)
7734 {
7736 // Male
7737 if (getGender() == GENDER_MALE)
7738 {
7739 switch (skinColor)
7740 {
7741 case 12: // White
7742 case 13:
7743 case 14:
7744 case 18: // Completly White
7745 return 29409;
7746 case 9: // Light Brown
7747 case 10:
7748 case 11:
7749 return 29410;
7750 case 6: // Brown
7751 case 7:
7752 case 8:
7753 return 29411;
7754 case 0: // Dark
7755 case 1:
7756 case 2:
7757 case 3: // Dark Grey
7758 case 4:
7759 case 5:
7760 return 29412;
7761 default: // original - Grey
7762 return 8571;
7763 }
7764 }
7765 // Female
7766 else
7767 {
7768 switch (skinColor)
7769 {
7770 case 10: // White
7771 return 29409;
7772 case 6: // Light Brown
7773 case 7:
7774 return 29410;
7775 case 4: // Brown
7776 case 5:
7777 return 29411;
7778 case 0: // Dark
7779 case 1:
7780 case 2:
7781 case 3:
7782 return 29412;
7783 default: // original - Grey
7784 return 8571;
7785 }
7786 }
7787 }
7788 else if (Player::TeamForRace(getRace()) == ALLIANCE)
7789 return 892;
7790 else
7791 return 8571;
7792 case FORM_BEAR:
7793 // Based on Hair color
7794 if (getRace() == RACE_NIGHTELF)
7795 {
7797 switch (hairColor)
7798 {
7799 case 0: // Green
7800 case 1: // Light Green
7801 case 2: // Dark Green
7802 return 29413; // 29415?
7803 case 6: // Dark Blue
7804 return 29414;
7805 case 4: // White
7806 return 29416;
7807 case 3: // Light Blue
7808 return 29417;
7809 default: // original - Violet
7810 return 2281;
7811 }
7812 }
7813 else if (getRace() == RACE_TROLL)
7814 {
7816 switch (hairColor)
7817 {
7818 case 0: // Red
7819 case 1:
7820 return 33657;
7821 case 2: // Yellow
7822 case 3:
7823 return 33659;
7824 case 7: // Purple
7825 case 10:
7826 return 33656;
7827 case 8: // White
7828 case 9:
7829 case 11:
7830 case 12:
7831 return 33658;
7832 default: // original - Blue
7833 return 33655;
7834 }
7835 }
7836 else if (getRace() == RACE_WORGEN)
7837 {
7838 // Based on Skin color
7840 // Male
7841 if (getGender() == GENDER_MALE)
7842 {
7843 switch (skinColor)
7844 {
7845 case 1: // Brown
7846 return 33652;
7847 case 2: // Black
7848 case 7:
7849 return 33651;
7850 case 4: // Yellow
7851 return 33653;
7852 case 3: // White
7853 case 5:
7854 return 33654;
7855 default: // original - Gray
7856 return 33650;
7857 }
7858 }
7859 // Female
7860 else
7861 {
7862 switch (skinColor)
7863 {
7864 case 5: // Brown
7865 case 6:
7866 return 33652;
7867 case 7: // Black
7868 case 8:
7869 return 33651;
7870 case 3: // yellow
7871 case 4:
7872 return 33654;
7873 case 2: // White
7874 return 33653;
7875 default: // original - Gray
7876 return 33650;
7877 }
7878 }
7879 }
7880 // Based on Skin color
7881 else if (getRace() == RACE_TAUREN)
7882 {
7884 // Male
7885 if (getGender() == GENDER_MALE)
7886 {
7887 switch (skinColor)
7888 {
7889 case 0: // Dark (Black)
7890 case 1:
7891 case 2:
7892 return 29418;
7893 case 3: // White
7894 case 4:
7895 case 5:
7896 case 12:
7897 case 13:
7898 case 14:
7899 return 29419;
7900 case 9: // Light Brown/Grey
7901 case 10:
7902 case 11:
7903 case 15:
7904 case 16:
7905 case 17:
7906 return 29420;
7907 case 18: // Completly White
7908 return 29421;
7909 default: // original - Brown
7910 return 2289;
7911 }
7912 }
7913 // Female
7914 else
7915 {
7916 switch (skinColor)
7917 {
7918 case 0: // Dark (Black)
7919 case 1:
7920 return 29418;
7921 case 2: // White
7922 case 3:
7923 return 29419;
7924 case 6: // Light Brown/Grey
7925 case 7:
7926 case 8:
7927 case 9:
7928 return 29420;
7929 case 10: // Completly White
7930 return 29421;
7931 default: // original - Brown
7932 return 2289;
7933 }
7934 }
7935 }
7936 else if (Player::TeamForRace(getRace()) == ALLIANCE)
7937 return 2281;
7938 else
7939 return 2289;
7940 case FORM_FLIGHT:
7942 return 20857;
7943 return 20872;
7944 case FORM_FLIGHT_EPIC:
7946 return (getRace() == RACE_WORGEN ? 37729 : 21243);
7947 if (getRace() == RACE_TROLL)
7948 return 37730;
7949 return 21244;
7950 case FORM_MOONKIN:
7952 return 37173;
7953 return 37174;
7954 case FORM_TRAVEL:
7956 return 40816;
7957 return 45339;
7958 case FORM_GHOSTWOLF:
7959 if (HasAura(58135))
7960 return 27312;
7961 default:
7962 break;
7963 }
7964 }
7965
7966 uint32 modelid = 0;
7967 SpellShapeshiftFormEntry const* formEntry = sSpellShapeshiftFormStore.LookupEntry(form);
7968 if (formEntry && formEntry->modelID_A)
7969 {
7970 // Take the alliance modelid as default
7972 return formEntry->modelID_A;
7973 else
7974 {
7976 modelid = formEntry->modelID_A;
7977 else
7978 modelid = formEntry->modelID_H;
7979
7980 // If the player is horde but there are no values for the horde modelid - take the alliance modelid
7981 if (!modelid && Player::TeamForRace(getRace()) == HORDE)
7982 modelid = formEntry->modelID_A;
7983 }
7984 }
7985
7986 return modelid;
7987}
7988
7990{
7991 if (totemType == 3211)
7992 totemType = SUMMON_TYPE_TOTEM_FIRE;
7993
7994 if (totemType == 3403)
7995 totemType = SUMMON_TYPE_TOTEM_FIRE;
7996
7997 if (totemType == 3402)
7998 totemType = SUMMON_TYPE_TOTEM_WATER;
7999
8000 if (totemType == 3406)
8001 totemType = SUMMON_TYPE_TOTEM_AIR;
8002
8003 if (totemType == 3407)
8004 totemType = SUMMON_TYPE_TOTEM_AIR;
8005
8006 if (totemType == 3405)
8007 totemType = SUMMON_TYPE_TOTEM_AIR;
8008
8009 if (totemType == 3399)
8010 totemType = SUMMON_TYPE_TOTEM_AIR;
8011
8012 if (totemType == 3400)
8013 totemType = SUMMON_TYPE_TOTEM_EARTH;
8014
8015 if (totemType == SUMMON_TYPE_LIGHTSPRING)
8016 return 27769;
8017
8018 // jade serpent statue
8019 if (totemType == SUMMON_TYPE_STATUE_JADE)
8020 return 42449;
8021
8022 // black ox statue
8023 if (totemType == SUMMON_TYPE_STATUE_OX)
8024 return 41853;
8025
8026 switch (getRace())
8027 {
8028 case RACE_ORC:
8029 {
8030 switch (totemType)
8031 {
8032 case SUMMON_TYPE_TOTEM_FIRE: // fire
8033 return 30758;
8034 case SUMMON_TYPE_TOTEM_EARTH: // earth
8035 return 30757;
8036 case SUMMON_TYPE_TOTEM_WATER: // water
8037 return 30759;
8038 case SUMMON_TYPE_TOTEM_AIR: // air
8039 return 30756;
8040 }
8041 break;
8042 }
8043 case RACE_DWARF:
8044 {
8045 switch (totemType)
8046 {
8047 case SUMMON_TYPE_TOTEM_FIRE: // fire
8048 return 30754;
8049 case SUMMON_TYPE_TOTEM_EARTH: // earth
8050 return 30753;
8051 case SUMMON_TYPE_TOTEM_WATER: // water
8052 return 30755;
8053 case SUMMON_TYPE_TOTEM_AIR: // air
8054 return 30736;
8055 }
8056 break;
8057 }
8058 case RACE_TROLL:
8059 {
8060 switch (totemType)
8061 {
8062 case SUMMON_TYPE_TOTEM_FIRE: // fire
8063 return 30762;
8064 case SUMMON_TYPE_TOTEM_EARTH: // earth
8065 return 30761;
8066 case SUMMON_TYPE_TOTEM_WATER: // water
8067 return 30763;
8068 case SUMMON_TYPE_TOTEM_AIR: // air
8069 return 30760;
8070 }
8071 break;
8072 }
8073 case RACE_TAUREN:
8074 {
8075 switch (totemType)
8076 {
8077 case SUMMON_TYPE_TOTEM_FIRE: // fire
8078 return 4589;
8079 case SUMMON_TYPE_TOTEM_EARTH: // earth
8080 return 4588;
8081 case SUMMON_TYPE_TOTEM_WATER: // water
8082 return 4587;
8083 case SUMMON_TYPE_TOTEM_AIR: // air
8084 return 4590;
8085 }
8086 break;
8087 }
8088 case RACE_DRAENEI:
8089 {
8090 switch (totemType)
8091 {
8092 case SUMMON_TYPE_TOTEM_FIRE: // fire
8093 return 19074;
8094 case SUMMON_TYPE_TOTEM_EARTH: // earth
8095 return 19073;
8096 case SUMMON_TYPE_TOTEM_WATER: // water
8097 return 19075;
8098 case SUMMON_TYPE_TOTEM_AIR: // air
8099 return 19071;
8100 }
8101 break;
8102 }
8103 case RACE_GOBLIN:
8104 {
8105 switch (totemType)
8106 {
8107 case SUMMON_TYPE_TOTEM_FIRE: // fire
8108 return 30783;
8109 case SUMMON_TYPE_TOTEM_EARTH: // earth
8110 return 30782;
8111 case SUMMON_TYPE_TOTEM_WATER: // water
8112 return 30784;
8113 case SUMMON_TYPE_TOTEM_AIR: // air
8114 return 30781;
8115 }
8116 break;
8117 }
8121 {
8122 switch (totemType)
8123 {
8124 case SUMMON_TYPE_TOTEM_FIRE: // fire
8125 return 41670;
8126 case SUMMON_TYPE_TOTEM_EARTH: // earth
8127 return 41669;
8128 case SUMMON_TYPE_TOTEM_WATER: // water
8129 return 41671;
8130 case SUMMON_TYPE_TOTEM_AIR: // air
8131 return 41668;
8132 }
8133 break;
8134 }
8135 }
8136 return 0;
8137}
8138
8139void Unit::JumpTo(float speedXY, float speedZ, bool forward)
8140{
8141 float angle = forward ? 0 : M_PI;
8143 GetMotionMaster()->MoveJumpTo(angle, speedXY, speedZ);
8144 else
8145 {
8146 float vcos = std::cos(angle + GetOrientation());
8147 float vsin = std::sin(angle + GetOrientation());
8148 SendMoveKnockBack(ToPlayer(), speedXY, -speedZ, vcos, vsin);
8149 }
8150}
8151
8152void Unit::JumpTo(WorldObject* obj, float speedZ)
8153{
8154 float x, y, z;
8155 obj->GetContactPoint(this, x, y, z);
8156 float speedXY = GetExactDist2d(x, y) * 10.0f / speedZ;
8157 GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
8158}
8159
8160bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
8161{
8162 bool result = false;
8163 uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry();
8164 SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry);
8165 for (SpellClickInfoContainer::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
8166 {
8168 if (!itr->second.IsFitToRequirements(clicker, this))
8169 continue;
8170
8172 ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(spellClickEntry, itr->second.spellId);
8173 ConditionSourceInfo info = ConditionSourceInfo(clicker, this);
8174 if (!sConditionMgr->IsObjectMeetToConditions(info, conds))
8175 continue;
8176
8177 Unit* caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this;
8178 Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this;
8179 uint64 origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? GetOwnerGUID() : clicker->GetGUID();
8180
8181 SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->second.spellId);
8182 // if (!spellEntry) should be checked at npc_spellclick load
8183
8184 if (seatId > -1)
8185 {
8186 uint8 i = 0;
8187 bool valid = false;
8188 while (i < MAX_SPELL_EFFECTS && !valid)
8189 {
8190 if (spellEntry->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
8191 {
8192 valid = true;
8193 break;
8194 }
8195 ++i;
8196 }
8197
8198 if (!valid)
8199 {
8200 SF_LOG_ERROR("sql.sql", "Spell %u specified in npc_spellclick_spells is not a valid vehicle enter aura!", itr->second.spellId);
8201 continue;
8202 }
8203
8204 if (IsInMap(caster))
8205 caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0 + i), seatId + 1, target, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
8206 else // This can happen during Player::_LoadAuras
8207 {
8209 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
8210 bp0[j] = spellEntry->Effects[j].BasePoints;
8211
8212 bp0[i] = seatId;
8213 Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, NULL, origCasterGUID);
8214 }
8215 }
8216 else
8217 {
8218 if (IsInMap(caster))
8219 caster->CastSpell(target, spellEntry, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
8220 else
8221 Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID);
8222 }
8223
8224 result = true;
8225 }
8226
8227 Creature* creature = ToCreature();
8228 if (creature && creature->IsAIEnabled)
8229 creature->AI()->OnSpellClick(clicker, result);
8230
8231 return result;
8232}
8233
8238
8239void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp)
8240{
8241 // Must be called only from aura handler
8242 ASSERT(aurApp);
8243
8244 if (!IsAlive() || GetVehicleKit() == vehicle || vehicle->GetBase()->IsOnVehicle(this))
8245 return;
8246
8247 if (m_vehicle)
8248 {
8249 if (m_vehicle != vehicle)
8250 {
8251 SF_LOG_DEBUG("entities.vehicle", "EnterVehicle: %u exit %u and enter %u.", GetEntry(), m_vehicle->GetBase()->GetEntry(), vehicle->GetBase()->GetEntry());
8252 ExitVehicle();
8253 }
8254 else if (seatId >= 0 && seatId == GetTransSeat())
8255 return;
8256 }
8257
8258 if (aurApp->GetRemoveMode())
8259 return;
8260
8261 if (Player* player = ToPlayer())
8262 {
8263 if (vehicle->GetBase()->GetTypeId() == TypeID::TYPEID_PLAYER && player->IsInCombat())
8264 {
8265 vehicle->GetBase()->RemoveAura(const_cast<AuraApplication*>(aurApp));
8266 return;
8267 }
8268 }
8269
8270 ASSERT(!m_vehicle);
8271 (void)vehicle->AddPassenger(this, seatId);
8272}
8273
8274void Unit::ChangeSeat(int8 seatId, bool next)
8275{
8276 if (!m_vehicle)
8277 return;
8278
8279 // Don't change if current and new seat are identical
8280 if (seatId == GetTransSeat())
8281 return;
8282
8283 SeatMap::const_iterator seat = (seatId < 0 ? m_vehicle->GetNextEmptySeat(GetTransSeat(), next) : m_vehicle->Seats.find(seatId));
8284 // The second part of the check will only return true if seatId >= 0. @Vehicle::GetNextEmptySeat makes sure of that.
8285 if (seat == m_vehicle->Seats.end() || !seat->second.IsEmpty())
8286 return;
8287
8288 AuraEffect* rideVehicleEffect = NULL;
8289 AuraEffectList const& vehicleAuras = m_vehicle->GetBase()->GetAuraEffectsByType(SPELL_AURA_CONTROL_VEHICLE);
8290 for (AuraEffectList::const_iterator itr = vehicleAuras.begin(); itr != vehicleAuras.end(); ++itr)
8291 {
8292 if ((*itr)->GetCasterGUID() != GetGUID())
8293 continue;
8294
8295 // Make sure there is only one ride vehicle aura on target cast by the unit changing seat
8296 ASSERT(!rideVehicleEffect);
8297 rideVehicleEffect = *itr;
8298 }
8299
8300 // Unit riding a vehicle must always have control vehicle aura on target
8301 ASSERT(rideVehicleEffect);
8302
8303 rideVehicleEffect->ChangeAmount(seat->first + 1);
8304}
8305
8306void Unit::ExitVehicle(Position const* /*exitPosition*/)
8307{
8309 if (!m_vehicle)
8310 return;
8311
8316 /*_ExitVehicle(exitPosition);*/
8323}
8324
8325void Unit::_ExitVehicle(Position const* exitPosition)
8326{
8330 if (!m_vehicle)
8331 return;
8332
8333 // This should be done before dismiss, because there may be some aura removal
8334 Vehicle* vehicle = m_vehicle->RemovePassenger(this);
8335
8336 Player* player = ToPlayer();
8337
8338 // If the player is on mounted duel and exits the mount, he should immediatly lose the duel
8339 if (player && player->duel && player->duel->isMounted)
8341
8342 SetDisableGravity(false); // SMSG_MOVE_GRAVITY_ENABLE
8343 SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
8344
8345 Position pos;
8346 if (!exitPosition) // Exit position not specified
8347 vehicle->GetBase()->GetPosition(&pos); // This should use passenger's current position, leaving it as it is now
8348 // because we calculate positions incorrect (sometimes under map)
8349 else
8350 pos = *exitPosition;
8351
8353
8354 if (player)
8355 player->SetFallInformation(0, GetPositionZ());
8356
8357 float height = pos.GetPositionZ();
8358
8359 Movement::MoveSplineInit init(this);
8360
8361 // Creatures without inhabit type air should begin falling after exiting the vehicle
8362 if (GetTypeId() == TypeID::TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
8363 init.SetFall();
8364
8365 init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
8366 init.SetFacing(GetOrientation());
8367 init.SetTransportExit();
8368 init.Launch();
8369
8370 if (player)
8372
8373 if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION) && vehicle->GetBase()->GetTypeId() == TypeID::TYPEID_UNIT)
8374 if (((Minion*)vehicle->GetBase())->GetOwner() == this)
8375 vehicle->GetBase()->ToCreature()->DespawnOrUnsummon(1);
8376
8378 {
8379 // Vehicle just died, we die too
8380 if (vehicle->GetBase()->getDeathState() == DeathState::JUST_DIED)
8382 // If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
8383 else
8384 ToTempSummon()->UnSummon(2000); // Approximation
8385 }
8386}
8387
8389{
8390 return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR) || movespline->isFalling();
8391}
8392
8393void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool casting /*= false*/)
8394{
8395 DisableSpline();
8398 else
8399 {
8400 Position pos = { x, y, z, orientation };
8401 SendTeleportPacket(pos);
8402 UpdatePosition(x, y, z, orientation, true);
8404 }
8405}
8406
8408{
8409 MovementInfo const& mi = m_movementInfo;
8410
8411 bool hasMountDisplayId = GetUInt32Value(UNIT_FIELD_MOUNT_DISPLAY_ID) != 0;
8412 bool hasMovementFlags = GetUnitMovementFlags() != 0;
8413 bool hasMovementFlags2 = GetExtraUnitMovementFlags() != 0;
8414 bool hasTimestamp = mi.time;
8415 bool hasOrientation = !G3D::fuzzyEq(GetOrientation(), 0.0f);
8416 bool hasTransportData = GetTransGUID() != 0;
8417 bool hasSpline = movespline ? IsSplineEnabled() : false;
8418
8419 bool hasTransportTime2 = hasTransportData && m_movementInfo.transport.time2 != 0;
8420 bool hasTransportTime3 = false;
8421 bool hasTransportVehicleId = hasTransportData && m_movementInfo.transport.time3 != 0;
8423 bool hasFallDirection = HasUnitMovementFlag(MOVEMENTFLAG_FALLING);
8424 bool hasFallData = hasFallDirection || m_movementInfo.jump.fallTime != 0;
8425 bool hasSplineElevation = HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
8426
8428 if (!sequence)
8429 {
8430 SF_LOG_ERROR("network", "Unit::WriteMovementInfo: No movement sequence found for opcode %s", GetOpcodeNameForLogging(data.GetOpcode(), true).c_str());
8431 return;
8432 }
8433
8434 ObjectGuid guid = GetGUID();
8435 ObjectGuid tguid = hasTransportData ? GetTransGUID() : 0;
8436
8437 for (; *sequence != MSEEnd; ++sequence)
8438 {
8439 MovementStatusElements const& element = *sequence;
8440
8441 switch (element)
8442 {
8443 case MSEHasGuidByte0:
8444 case MSEHasGuidByte1:
8445 case MSEHasGuidByte2:
8446 case MSEHasGuidByte3:
8447 case MSEHasGuidByte4:
8448 case MSEHasGuidByte5:
8449 case MSEHasGuidByte6:
8450 case MSEHasGuidByte7:
8451 data.WriteBit(guid[element - MSEHasGuidByte0]);
8452 break;
8461 if (hasTransportData)
8462 data.WriteBit(tguid[element - MSEHasTransportGuidByte0]);
8463 break;
8464 case MSEGuidByte0:
8465 case MSEGuidByte1:
8466 case MSEGuidByte2:
8467 case MSEGuidByte3:
8468 case MSEGuidByte4:
8469 case MSEGuidByte5:
8470 case MSEGuidByte6:
8471 case MSEGuidByte7:
8472 data.WriteByteSeq(guid[element - MSEGuidByte0]);
8473 break;
8482 if (hasTransportData)
8483 data.WriteByteSeq(tguid[element - MSETransportGuidByte0]);
8484 break;
8485 case MSEHasCounter:
8487 break;
8489 data.WriteBit(!hasMovementFlags);
8490 break;
8492 data.WriteBit(!hasMovementFlags2);
8493 break;
8495 data.WriteBit(!hasMountDisplayId);
8496 break;
8497 case MSEHasTimestamp:
8498 data.WriteBit(!hasTimestamp);
8499 break;
8500 case MSEHasOrientation:
8501 data.WriteBit(!hasOrientation);
8502 break;
8504 data.WriteBit(hasTransportData);
8505 break;
8507 if (hasTransportData)
8508 data.WriteBit(hasTransportTime2);
8509 break;
8511 if (hasTransportData)
8512 data.WriteBit(hasTransportTime3);
8513 break;
8514 case MSEHasPitch:
8515 data.WriteBit(!hasPitch);
8516 break;
8517 case MSEHasFallData:
8518 data.WriteBit(hasFallData);
8519 break;
8521 if (hasFallData)
8522 data.WriteBit(hasFallDirection);
8523 break;
8525 data.WriteBit(!hasSplineElevation);
8526 break;
8527 case MSEHasSpline:
8528 data.WriteBit(hasSpline);
8529 break;
8530 case MSEMountDisplayIdWithCheck: // Fallback here
8531 if (!hasMountDisplayId)
8532 break;
8535 break;
8536 case MSEMovementFlags:
8537 if (hasMovementFlags)
8538 data.WriteBits(GetUnitMovementFlags(), 30);
8539 break;
8540 case MSEMovementFlags2:
8541 if (hasMovementFlags2)
8543 break;
8544 case MSETimestamp:
8545 if (hasTimestamp)
8546 data << mi.time;
8547 break;
8548 case MSEPositionX:
8549 data << GetPositionX();
8550 break;
8551 case MSEPositionY:
8552 data << GetPositionY();
8553 break;
8554 case MSEPositionZ:
8555 data << GetPositionZ();
8556 break;
8557 case MSEOrientation:
8558 if (hasOrientation)
8559 data << GetOrientation();
8560 break;
8562 data << GetOrientation();
8563 break;
8565 if (hasTransportData)
8566 data << GetTransOffsetX();
8567 break;
8569 if (hasTransportData)
8570 data << GetTransOffsetY();
8571 break;
8573 if (hasTransportData)
8574 data << GetTransOffsetZ();
8575 break;
8577 if (hasTransportData)
8578 data << GetTransOffsetO();
8579 break;
8580 case MSETransportSeat:
8581 if (hasTransportData)
8582 data << GetTransSeat();
8583 break;
8584 case MSETransportTime:
8585 if (hasTransportData)
8586 data << GetTransTime();
8587 break;
8588 case MSETransportTime2:
8589 if (hasTransportData && hasTransportTime2)
8590 data << mi.transport.time2;
8591 break;
8592 case MSETransportTime3:
8593 if (hasTransportData && hasTransportTime3)
8594 data << mi.transport.time3;
8595 break;
8596 case MSEPitch:
8597 if (hasPitch)
8598 data << mi.pitch;
8599 break;
8600 case MSEFallTime:
8601 if (hasFallData)
8602 data << mi.jump.fallTime;
8603 break;
8605 if (hasFallData)
8606 data << mi.jump.zspeed;
8607 break;
8608 case MSEFallCosAngle:
8609 if (hasFallData && hasFallDirection)
8610 data << mi.jump.cosAngle;
8611 break;
8612 case MSEFallSinAngle:
8613 if (hasFallData && hasFallDirection)
8614 data << mi.jump.sinAngle;
8615 break;
8617 if (hasFallData && hasFallDirection)
8618 data << mi.jump.xyspeed;
8619 break;
8620 case MSESplineElevation:
8621 if (hasSplineElevation)
8622 data << mi.splineElevation;
8623 break;
8624 case MSEForcesCount:
8625 data.WriteBits(0, 22);
8626 break;
8627 case MSECounter:
8629 data << m_movementCounter;
8631 break;
8632 case MSECount:
8633 data << m_movementCounter++;
8634 break;
8635 case MSEZeroBit:
8636 data.WriteBit(0);
8637 break;
8638 case MSEOneBit:
8639 data.WriteBit(1);
8640 break;
8641 case MSEExtraElement:
8642 extras->WriteNextElement(data);
8643 break;
8644 case MSEUintCount:
8645 data << uint32(0);
8646 break;
8648 data.WriteBit(hasTransportVehicleId);
8649 break;
8651 if (hasTransportVehicleId)
8652 data << mi.transport.time3; // this should be renamed
8653 break;
8654 case MSEForces:
8655 /*
8656 for (uint8 i = 0; i < forcesCount; ++i)
8657 data << uint32(0);
8658 */
8659 break;
8660 case MSEFlushBits:
8661 data.FlushBits();
8662 break;
8663 default:
8664 ASSERT(Movement::PrintInvalidSequenceElement(element, __FUNCTION__));
8665 break;
8666 }
8667 }
8668}
8669
8671{
8672 // SMSG_MOVE_UPDATE_TELEPORT is sent to nearby players to signal the teleport
8673 // SMSG_MOVE_TELEPORT is sent to self in order to trigger CMSG_MOVE_TELEPORT_ACK and update the position server side
8674
8675 // This oldPos actually contains the destination position if the Unit is a Player.
8677
8679 Relocate(&pos); // Relocate the unit to its new position in order to build the packets correctly.
8680
8682 WriteMovementInfo(data);
8683
8685 {
8686 WorldPacket data2(SMSG_MOVE_TELEPORT, 1 + 8 + 1 + 8 + 1 + 4 + 4 + 4 + 4);
8687 WriteMovementInfo(data2);
8688 ToPlayer()->SendDirectMessage(&data2); // Send the SMSG_MOVE_TELEPORT packet to self.
8689 }
8690
8691 // Relocate the player/creature to its old position, so we can broadcast to nearby players correctly
8693 Relocate(&pos);
8694 else
8695 Relocate(&oldPos);
8696
8697 // Broadcast the packet to everyone except self.
8698 SendMessageToSet(&data, false);
8699}
8700
8701bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport)
8702{
8703 // prevent crash when a bad coord is sent by the client
8704 if (!Skyfire::IsValidMapCoord(x, y, z, orientation))
8705 {
8706 SF_LOG_DEBUG("entities.unit", "Unit::UpdatePosition(%f, %f, %f) .. bad coordinates!", x, y, z);
8707 return false;
8708 }
8709
8710 bool turn = (GetOrientation() != orientation);
8711 bool relocated = (teleport || GetPositionX() != x || GetPositionY() != y || GetPositionZ() != z);
8712
8713 if (turn)
8715
8716 if (relocated)
8717 {
8719
8720 // move and update visible state if need
8722 GetMap()->PlayerRelocation(ToPlayer(), x, y, z, orientation);
8723 else
8724 GetMap()->CreatureRelocation(ToCreature(), x, y, z, orientation);
8725 }
8726 else if (turn)
8727 UpdateOrientation(orientation);
8728
8729 // code block for underwater state update
8730 UpdateUnderwaterState(GetMap(), x, y, z);
8731
8732 return (relocated || turn);
8733}
8734
8735bool Unit::UpdatePosition(const Position& pos, bool teleport)
8736{
8737 return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport);
8738}
8739
8741void Unit::UpdateOrientation(float orientation)
8742{
8743 SetOrientation(orientation);
8744 if (IsVehicle())
8746}
8747
8749void Unit::UpdateHeight(float newZ)
8750{
8752 if (IsVehicle())
8754}
8755
8757{
8758 if (!getThreatManager().isThreatListEmpty())
8759 {
8760 uint32 count = getThreatManager().getThreatList().size();
8761
8762 SF_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_UPDATE Message");
8763
8764 ObjectGuid UnitGUID = GetGUID();
8766
8767 data.WriteGuidMask(UnitGUID, 5, 6, 1, 3, 7, 0, 4);
8768 data.WriteBits(count, 21);
8769
8771 for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
8772 {
8773 ObjectGuid UnitThreatGUID = (*itr)->getUnitGuid();
8774 data.WriteGuidMask(UnitThreatGUID, 2, 3, 6, 5, 1, 4, 0, 7);
8775 }
8776
8777 data.WriteGuidMask(UnitGUID, 2);
8778 data.FlushBits();
8779
8780 for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
8781 {
8782 ObjectGuid UnitThreatGUID = (*itr)->getUnitGuid();
8783 data.WriteGuidBytes(UnitThreatGUID, 6, 7, 0, 1, 2, 5, 3, 4);
8784 data << uint32((*itr)->getThreat() * 100);
8785 }
8786
8787 data.WriteGuidBytes(UnitGUID, 1, 4, 2, 3, 5, 6, 0, 7);
8788 SendMessageToSet(&data, false);
8789 }
8790}
8791
8793{
8794 if (!getThreatManager().isThreatListEmpty())
8795 {
8796 uint32 count = getThreatManager().getThreatList().size();
8797
8798 SF_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message");
8799 ObjectGuid Guid = GetGUID();
8800 ObjectGuid UnitGuid = pHostileReference->getUnitGuid();
8801 WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8);
8802
8803 data.WriteBit(Guid[3]);
8804 data.WriteBit(Guid[0]);
8805 data.WriteBit(UnitGuid[3]);
8806 data.WriteBit(UnitGuid[6]);
8807 data.WriteBit(UnitGuid[1]);
8808 data.WriteBit(Guid[5]);
8809 data.WriteBit(Guid[1]);
8810 data.WriteBit(Guid[6]);
8811 data.WriteBit(UnitGuid[2]);
8812 data.WriteBit(UnitGuid[5]);
8813 data.WriteBit(Guid[7]);
8814 data.WriteBit(Guid[4]);
8815 data.WriteBit(UnitGuid[4]);
8816 data << uint32(count);
8817
8819 for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
8820 {
8821 ObjectGuid UnitGuid = (*itr)->getUnitGuid();
8822 data.WriteBit(UnitGuid[6]);
8823 data.WriteBit(UnitGuid[1]);
8824 data.WriteBit(UnitGuid[0]);
8825 data.WriteBit(UnitGuid[2]);
8826 data.WriteBit(UnitGuid[7]);
8827 data.WriteBit(UnitGuid[4]);
8828 data.WriteBit(UnitGuid[3]);
8829 data.WriteBit(UnitGuid[5]);
8830 }
8831
8832 data.WriteBit(UnitGuid[7]);
8833 data.WriteBit(UnitGuid[0]);
8834 data.WriteBit(Guid[2]);
8835
8836 data.WriteByteSeq(UnitGuid[4]);
8837
8838 for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
8839 {
8840 ObjectGuid UnitGuid = (*itr)->getUnitGuid();
8841
8842 data.WriteByteSeq(UnitGuid[6]);
8843
8844 data << uint32((*itr)->getThreat());
8845
8846 data.WriteByteSeq(UnitGuid[4]);
8847 data.WriteByteSeq(UnitGuid[0]);
8848 data.WriteByteSeq(UnitGuid[3]);
8849 data.WriteByteSeq(UnitGuid[5]);
8850 data.WriteByteSeq(UnitGuid[2]);
8851 data.WriteByteSeq(UnitGuid[1]);
8852 data.WriteByteSeq(UnitGuid[7]);
8853 }
8854
8855 data.WriteByteSeq(Guid[3]);
8856 data.WriteByteSeq(UnitGuid[5]);
8857 data.WriteByteSeq(Guid[2]);
8858 data.WriteByteSeq(UnitGuid[1]);
8859 data.WriteByteSeq(UnitGuid[0]);
8860 data.WriteByteSeq(UnitGuid[2]);
8861 data.WriteByteSeq(Guid[6]);
8862 data.WriteByteSeq(Guid[1]);
8863 data.WriteByteSeq(UnitGuid[7]);
8864 data.WriteByteSeq(Guid[0]);
8865 data.WriteByteSeq(Guid[4]);
8866 data.WriteByteSeq(Guid[7]);
8867 data.WriteByteSeq(UnitGuid[3]);
8868 data.WriteByteSeq(UnitGuid[6]);
8869 data.WriteByteSeq(Guid[5]);
8870
8871 SendMessageToSet(&data, false);
8872 }
8873}
8874
8876{
8878 data.WriteGuidMask(UnitGUID, 6, 7, 4, 5, 2, 1, 0, 3);
8879 data.WriteGuidBytes(UnitGUID, 7, 0, 4, 3, 2, 1, 6, 5);
8880 SendMessageToSet(&data, false);
8881}
8882
8884{
8885 SF_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_REMOVE Message");
8886 ObjectGuid victimGUID = GetGUID();
8887 ObjectGuid hostileGUID = pHostileReference->getUnitGuid();
8888
8889 WorldPacket data(SMSG_THREAT_REMOVE, 1 + 1 + 8 + 8);
8890
8891 data.WriteGuidMask(victimGUID, 0, 1, 5);
8892 data.WriteGuidMask(hostileGUID, 4, 0);
8893 data.WriteGuidMask(victimGUID, 4, 6);
8894 data.WriteGuidMask(hostileGUID, 7, 6, 3);
8895 data.WriteGuidMask(victimGUID, 2);
8896 data.WriteGuidMask(hostileGUID, 1);
8897 data.WriteGuidMask(victimGUID, 3, 7);
8898 data.WriteGuidMask(hostileGUID, 5, 2);
8899
8900 data.WriteGuidBytes(hostileGUID, 3, 0, 2);
8901 data.WriteGuidBytes(victimGUID, 5, 4, 7, 3, 0);
8902 data.WriteGuidBytes(hostileGUID, 4);
8903 data.WriteGuidBytes(victimGUID, 1);
8904 data.WriteGuidBytes(hostileGUID, 1);
8905 data.WriteGuidBytes(victimGUID, 6);
8906 data.WriteGuidBytes(hostileGUID, 7, 6);
8907 data.WriteGuidBytes(victimGUID, 2);
8908 data.WriteGuidBytes(hostileGUID, 5);
8909
8910 SendMessageToSet(&data, false);
8911}
8912
8913// baseRage means damage taken when attacker = false
8914void Unit::RewardRage(uint32 baseRage, bool attacker)
8915{
8916 float addRage;
8917
8918 if (attacker)
8919 {
8920 addRage = baseRage;
8921 // talent who gave more rage on attack
8923 }
8924 else
8925 {
8926 // Calculate rage from health and damage taken
8928 addRage = floor(0.5f + (25.7f * baseRage / GetMaxHealth()));
8929 // Berserker Rage effect
8930 if (HasAura(18499))
8931 addRage *= 2.0f;
8932 }
8933
8934 addRage *= sWorld->getRate(Rates::RATE_POWER_RAGE_INCOME);
8935
8936 ModifyPower(POWER_RAGE, uint32(addRage * 10));
8937}
8938
8940{
8941 if (Unit* victim = GetVictim())
8942 {
8943 if (victim->GetFactionTemplateEntry()->faction == faction_id)
8944 {
8945 AttackStop();
8946 if (IsNonMeleeSpellCasted(false))
8948
8949 // melee and ranged forced attack cancel
8952 }
8953 }
8954
8955 AttackerSet const& attackers = getAttackers();
8956 for (AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
8957 {
8958 if ((*itr)->GetFactionTemplateEntry()->faction == faction_id)
8959 {
8960 (*itr)->AttackStop();
8961 itr = attackers.begin();
8962 }
8963 else
8964 ++itr;
8965 }
8966
8968
8969 for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
8970 (*itr)->StopAttackFaction(faction_id);
8971}
8972
8973void Unit::GetAttackableUnitListInRange(std::list<Unit*>& list, float fMaxSearchRange) const
8974{
8976 Cell cell(p);
8977 cell.SetNoCreate();
8978
8979 Skyfire::AnyUnitInObjectRangeCheck u_check(this, fMaxSearchRange);
8981
8984
8985 cell.Visit(p, world_unit_searcher, *GetMap(), *this, fMaxSearchRange);
8986 cell.Visit(p, grid_unit_searcher, *GetMap(), *this, fMaxSearchRange);
8987}
8988
8990{
8991 SF_LOG_ERROR("entities.unit", "Unit::OutDebugInfo");
8992 SF_LOG_INFO("entities.unit", "GUID " UI64FMTD ", entry %u, type %u, name %s", GetGUID(), GetEntry(), (uint32)GetTypeId(), GetName().c_str());
8993 SF_LOG_INFO("entities.unit", "OwnerGUID " UI64FMTD ", MinionGUID " UI64FMTD ", CharmerGUID " UI64FMTD ", CharmedGUID " UI64FMTD, GetOwnerGUID(), GetMinionGUID(), GetCharmerGUID(), GetCharmGUID());
8994 SF_LOG_INFO("entities.unit", "In world %u, unit type mask %u", (uint32)(IsInWorld() ? 1 : 0), m_unitTypeMask);
8995 if (IsInWorld())
8996 SF_LOG_INFO("entities.unit", "Mapid %u", GetMapId());
8997
8998 std::ostringstream o;
8999 o << "Summon Slot: ";
9000 for (uint32 i = 0; i < MAX_SUMMON_SLOT; ++i)
9001 o << m_SummonSlot[i] << ", ";
9002
9003 SF_LOG_INFO("entities.unit", "%s", o.str().c_str());
9004 o.str("");
9005
9006 o << "Controlled List: ";
9007 for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
9008 o << (*itr)->GetGUID() << ", ";
9009 SF_LOG_INFO("entities.unit", "%s", o.str().c_str());
9010 o.str("");
9011
9012 o << "Aura List: ";
9013 for (AuraApplicationMap::const_iterator itr = m_appliedAuras.begin(); itr != m_appliedAuras.end(); ++itr)
9014 o << itr->first << ", ";
9015 SF_LOG_INFO("entities.unit", "%s", o.str().c_str());
9016 o.str("");
9017
9018 if (IsVehicle())
9019 {
9020 o << "Passenger List: ";
9021 for (SeatMap::iterator itr = GetVehicleKit()->Seats.begin(); itr != GetVehicleKit()->Seats.end(); ++itr)
9022 if (Unit* passenger = ObjectAccessor::GetUnit(*GetVehicleBase(), itr->second.Passenger.Guid))
9023 o << passenger->GetGUID() << ", ";
9024 SF_LOG_INFO("entities.unit", "%s", o.str().c_str());
9025 }
9026
9027 if (GetVehicle())
9028 SF_LOG_INFO("entities.unit", "On vehicle %u.", GetVehicleBase()->GetEntry());
9029}
9030
9031uint32 Unit::GetRemainingPeriodicAmount(uint64 caster, uint32 spellId, AuraType auraType, uint8 effectIndex) const
9032{
9033 uint32 amount = 0;
9034 AuraEffectList const& periodicAuras = GetAuraEffectsByType(auraType);
9035 for (AuraEffectList::const_iterator i = periodicAuras.begin(); i != periodicAuras.end(); ++i)
9036 {
9037 if ((*i)->GetCasterGUID() != caster || (*i)->GetId() != spellId || (*i)->GetEffIndex() != effectIndex || !(*i)->GetTotalTicks())
9038 continue;
9039 amount += uint32(((*i)->GetAmount() * std::max<int32>((*i)->GetTotalTicks() - int32((*i)->GetTickNumber()), 0)) / (*i)->GetTotalTicks());
9040 break;
9041 }
9042
9043 return amount;
9044}
9045
9047{
9049 ObjectGuid UnitGUID = GetGUID();
9050
9051 data.WriteGuidMask(UnitGUID, 2, 3, 7, 5, 4, 6, 0, 1);
9052 data.WriteGuidBytes(UnitGUID, 2, 1, 3, 0, 7, 4, 6, 5);
9053 SendMessageToSet(&data, false);
9054}
9055
9057{
9058 int32 resist = -1;
9059 for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
9060 if (mask & (1 << i) && (resist < 0 || resist > int32(GetResistance(SpellSchools(i)))))
9061 resist = int32(GetResistance(SpellSchools(i)));
9062
9063 // resist value will never be negative here
9064 return uint32(resist);
9065}
9066
9068{
9069 _isCommandAttack = val;
9070}
9071
9073{
9074 _isCommandFollow = val;
9075}
9076
9078{
9080 G3D::Vector3 const stayPos = _unit->movespline->FinalDestination();
9081 _stayX = stayPos.x;
9082 _stayY = stayPos.y;
9083 _stayZ = stayPos.z;
9084}
9085
9086void CharmInfo::GetStayPosition(float& x, float& y, float& z) const
9087{
9088 x = _stayX;
9089 y = _stayY;
9090 z = _stayZ;
9091}
9092
9094{
9095 _isAtStay = val;
9096}
9097
9099{
9100 _isFollowing = val;
9101}
9102
9104{
9105 _isReturning = val;
9106}
9107
9109{
9111 SetOrientation(GetAngle(target));
9112}
9113
9114void Unit::SetFacingTo(float ori)
9115{
9116 Movement::MoveSplineInit init(this);
9118 if (GetTransport())
9119 init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
9120 init.SetFacing(ori);
9121 init.Launch();
9122}
9123
9125{
9126 // never face when already moving
9127 if (!IsStopped())
9128 return;
9129
9131 Movement::MoveSplineInit init(this);
9133 init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming
9134 init.Launch();
9135}
9136
9137bool Unit::SetWalk(bool enable)
9138{
9139 if (enable == IsWalking())
9140 return false;
9141
9142 if (enable)
9144 else
9146
9148 if (enable)
9150 else
9152
9153 return true;
9154}
9155
9156bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
9157{
9158 if (!packetOnly)
9159 {
9160 if (disable == IsLevitating())
9161 return false;
9162
9163 if (disable)
9164 {
9167 SetFall(false);
9168 }
9169 else
9170 {
9173 SetFall(true);
9174 }
9175 }
9176
9177 if (disable)
9179 else
9181
9182 return true;
9183}
9184
9185bool Unit::SetFall(bool enable)
9186{
9188 return false;
9189
9190 if (enable)
9191 {
9193 m_movementInfo.SetFallTime(0);
9194 }
9195 else
9197
9198 return true;
9199}
9200
9201bool Unit::SetSwim(bool enable)
9202{
9204 return false;
9205
9206 if (enable)
9208 else
9210
9211 if (enable)
9213 else
9215
9216 return true;
9217}
9218
9219bool Unit::SetCanFly(bool enable)
9220{
9222 return false;
9223
9224 if (enable)
9225 {
9228 SetFall(false);
9229 }
9230 else
9231 {
9233 if (!IsLevitating())
9234 SetFall(true);
9235 }
9236
9237 if (enable)
9239 else
9241
9242 return true;
9243}
9244
9245bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
9246{
9247 if (!packetOnly)
9248 {
9250 return false;
9251
9252 if (enable)
9254 else
9256 }
9257
9258 if (enable)
9260 else
9262
9263 return true;
9264}
9265
9266bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
9267{
9268 if (!packetOnly)
9269 {
9271 return false;
9272
9273 if (enable)
9275 else
9277 }
9278
9279 if (enable)
9281 else
9283
9284 return true;
9285}
9286
9287bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
9288{
9289 if (!packetOnly)
9290 {
9292 return false;
9293
9294 if (enable)
9295 {
9298 if (float hh = GetFloatValue(UNIT_FIELD_HOVER_HEIGHT))
9299 UpdateHeight(GetPositionZ() + hh);
9300 }
9301 else
9302 {
9304 if (float hh = GetFloatValue(UNIT_FIELD_HOVER_HEIGHT))
9305 {
9306 float newZ = GetPositionZ() - hh;
9308 UpdateHeight(newZ);
9309 }
9310 }
9311 }
9312
9313 if (enable)
9315 else
9317
9318 return true;
9319}
9320/*
9321void Unit::SendSetPlayHoverAnim(bool PlayHoverAnim)
9322{
9323 ObjectGuid UnitGUID = GetGUID();
9324 WorldPacket data(SMSG_SET_PLAY_HOVER_ANIM, 10);
9325 data.WriteBit(UnitGUID [3]);
9326 data.WriteBit(UnitGUID [6]);
9327 data.WriteBit(UnitGUID [1]);
9328 data.WriteBit(UnitGUID [4]);
9329 data.WriteBit(UnitGUID [5]);
9330 data.WriteBit(UnitGUID [0]);
9331 data.WriteBit(PlayHoverAnim);
9332 data.WriteBit(UnitGUID [2]);
9333 data.WriteBit(UnitGUID [7]);
9334
9335 data.WriteByteSeq(UnitGUID [5]);
9336 data.WriteByteSeq(UnitGUID [1]);
9337 data.WriteByteSeq(UnitGUID [6]);
9338 data.WriteByteSeq(UnitGUID [2]);
9339 data.WriteByteSeq(UnitGUID [3]);
9340 data.WriteByteSeq(UnitGUID [0]);
9341 data.WriteByteSeq(UnitGUID [4]);
9342 data.WriteByteSeq(UnitGUID [7]);
9343
9344 SendMessageToSet(&data, true);
9345}
9346
9347void Unit::SendMovementSetSplineAnim(Movement::AnimType anim)
9348{
9349 WorldPacket data(SMSG_SPLINE_MOVE_SET_ANIM, 8 + 4);
9350 data.append(GetPackGUID());
9351 data << uint32(anim);
9352 SendMessageToSet(&data, false);
9353}
9354*/
9356{
9357 return movespline->Initialized() && !movespline->Finalized();
9358}
9359
9360
9361void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
9362{
9363 if (!target)
9364 return;
9365
9366 ByteBuffer fieldBuffer;
9367 UpdateMask updateMask;
9368
9369 uint32 valCount = m_valuesCount;
9370
9373
9374 if (target == this)
9375 visibleFlag |= UF_FLAG_PRIVATE;
9376 //else if (GetTypeId() == TYPEID_PLAYER)
9377 // valCount = PLAYER_END_NOT_SELF;
9378
9379 updateMask.SetCount(valCount);
9380
9382 if (GetOwnerGUID() == target->GetGUID())
9383 visibleFlag |= UF_FLAG_OWNER;
9384
9387 visibleFlag |= UF_FLAG_SPECIAL_INFO;
9388
9389 if (plr && plr->IsInSameRaidWith(target))
9390 visibleFlag |= UF_FLAG_PARTY_MEMBER;
9391
9392 Creature const* creature = ToCreature();
9393 for (uint16 index = 0; index < valCount; ++index)
9394 {
9395 if ((m_fieldNotifyFlags & flags[index] ||
9396 ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) ||
9397 ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
9399 {
9400 updateMask.SetBit(index);
9401
9402 if (index == UNIT_FIELD_NPC_FLAGS)
9403 {
9405
9406 if (creature)
9407 if (!target->CanSeeSpellClickOn(creature))
9408 appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
9409
9410 fieldBuffer << uint32(appendValue);
9411 }
9412 else if (index == UNIT_FIELD_AURA_STATE)
9413 {
9414 // Check per caster aura states to not enable using a spell in client if specified aura is not by target
9415 fieldBuffer << BuildAuraStateUpdateForTarget(target);
9416 }
9417 // FIXME: Some values at server stored in float format but must be sent to client in uint32 format
9419 {
9420 // convert from float to uint32 and send
9421 fieldBuffer << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]);
9422 }
9423 // there are some float values which may be negative or can't get negative due to other checks
9424 else if ((index >= UNIT_FIELD_STAT_NEG_BUFF && index <= UNIT_FIELD_STAT_NEG_BUFF + 4) ||
9427 (index >= UNIT_FIELD_STAT_POS_BUFF && index <= UNIT_FIELD_STAT_POS_BUFF + 4))
9428 {
9429 fieldBuffer << uint32(m_floatValues[index]);
9430 }
9431 // Gamemasters should be always able to select units - remove not selectable flag
9432 else if (index == UNIT_FIELD_FLAGS)
9433 {
9434 uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS];
9435 if (target->IsGameMaster())
9436 appendValue &= ~UNIT_FLAG_NOT_SELECTABLE;
9437
9438 fieldBuffer << uint32(appendValue);
9439 }
9440 // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
9441 else if (index == UNIT_FIELD_DISPLAY_ID)
9442 {
9444 if (creature)
9445 {
9446 CreatureTemplate const* cinfo = creature->GetCreatureTemplate();
9447
9448 // this also applies for transform auras
9449 if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm()))
9450 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
9451 if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
9452 if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
9453 {
9454 cinfo = transformInfo;
9455 break;
9456 }
9457
9459 {
9460 if (target->IsGameMaster())
9461 {
9462 if (cinfo->Modelid1)
9463 displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms
9464 else
9465 displayId = 17519; // world visible trigger's model
9466 }
9467 else
9468 {
9469 if (cinfo->Modelid2)
9470 displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players
9471 else
9472 displayId = 11686; // world invisible trigger's model
9473 }
9474 }
9475 }
9476
9477 fieldBuffer << uint32(displayId);
9478 }
9479 // hide lootable animation for unallowed players
9480 else if (index == OBJECT_FIELD_DYNAMIC_FLAGS)
9481 {
9483
9484 if (creature)
9485 {
9486 if (creature->hasLootRecipient())
9487 {
9488 dynamicFlags |= UNIT_DYNFLAG_TAPPED;
9489 if (creature->isTappedBy(target))
9490 dynamicFlags |= UNIT_DYNFLAG_TAPPED_BY_PLAYER;
9491 }
9492
9493 if (!target->isAllowedToLoot(creature))
9494 dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
9495 }
9496
9497 // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras
9498 if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT)
9500 dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT;
9501
9502 fieldBuffer << dynamicFlags;
9503 }
9504 // FG: pretend that OTHER players in own group are friendly ("blue")
9505 else if (index == UNIT_FIELD_SHAPESHIFT_FORM || index == UNIT_FIELD_FACTION_TEMPLATE)
9506 {
9507 if (IsControlledByPlayer() && target != this && sWorld->GetBoolConfig(WorldBoolConfigs::CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target))
9508 {
9510 FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry();
9511 if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
9512 {
9513 if (index == UNIT_FIELD_SHAPESHIFT_FORM)
9514 // Allow targetting opposite faction in party when enabled in config
9515 fieldBuffer << (m_uint32Values[UNIT_FIELD_SHAPESHIFT_FORM] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !!
9516 else
9517 // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
9518 fieldBuffer << uint32(target->getFaction());
9519 }
9520 else
9521 fieldBuffer << m_uint32Values[index];
9522 }
9523 else
9524 fieldBuffer << m_uint32Values[index];
9525 }
9526 else
9527 {
9528 // send in current format (float as float, uint32 as uint32)
9529 fieldBuffer << m_uint32Values[index];
9530 }
9531 }
9532 }
9533
9534 *data << uint8(updateMask.GetBlockCount());
9535 updateMask.AppendToPacket(data);
9536 data->append(fieldBuffer);
9537 BuildDynamicValuesUpdate(updateType, data, target);
9538}
9539
9541{
9542 if (Player* player = ToPlayer())
9543 {
9544 ObjectGuid moverGuid = GetGUID();
9545 uint32 index = m_movementCounter++;
9547 data.WriteGuidMask(moverGuid, 0, 6, 1, 3, 7, 4, 5, 2);
9548
9549 data.WriteGuidBytes(moverGuid, 6, 7, 0, 3);
9550 data << uint32(vehicleId);
9551 data << uint32(index);
9552 data.WriteGuidBytes(moverGuid, 1, 5, 2, 4);
9553
9554 player->SendDirectMessage(&data);
9555 }
9556
9557 ObjectGuid vehicleGuid = GetGUID();
9559 data.WriteGuidMask(vehicleGuid, 5, 7, 2, 1, 4, 0, 3, 6);
9560 data.WriteGuidBytes(vehicleGuid, 5, 7, 4, 6, 2, 1, 3, 0);
9561 data << uint32(vehicleId);
9562
9563 SendMessageToSet(&data, true);
9564}
9565
9566void Unit::SendMissileCancel(uint32 spellId, bool cancel)
9567{
9568 ObjectGuid guid = GetGUID();
9570 data.WriteGuidMask(guid, 6, 1, 4, 7, 0, 2, 5);
9571 data.WriteBit(cancel);
9572 data.WriteGuidMask(guid, 3);
9573 data.WriteGuidBytes(guid, 4, 1);
9574 data << spellId;
9575 data.WriteGuidBytes(guid, 2, 3, 7, 5, 0, 6);
9576 SendMessageToSet(&data, true);
9577}
#define sBattlefieldMgr
@ SCORE_HEALING_DONE
@ IN_MILLISECONDS
Definition Common.h:125
@ MINUTE
Definition Common.h:119
@ HOUR
Definition Common.h:120
@ SEC_GAMEMASTER
Definition Common.h:132
#define M_PI
Definition Common.h:192
#define sConditionMgr
std::list< Condition * > ConditionList
@ CREATURE_FLAG_EXTRA_NO_BLOCK
Definition Creature.h:33
@ CREATURE_FLAG_EXTRA_TRIGGER
Definition Creature.h:36
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
Definition Creature.h:29
@ CREATURE_FLAG_EXTRA_NO_PARRY
Definition Creature.h:31
@ INHABIT_AIR
Definition Creature.h:298
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED
Definition DBCEnums.h:261
@ ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE
Definition DBCEnums.h:220
@ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED
Definition DBCEnums.h:260
@ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER
Definition DBCEnums.h:189
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED
Definition DBCEnums.h:259
@ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE
Definition DBCEnums.h:188
@ ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS
Definition DBCEnums.h:221
@ MOUNT_FLAG_CAN_PITCH
Definition DBCEnums.h:438
@ MOUNT_FLAG_CAN_SWIM
Definition DBCEnums.h:439
@ FACTION_TEMPLATE_FLAG_HOSTILE_BY_DEFAULT
Definition DBCEnums.h:379
@ FACTION_TEMPLATE_FLAG_CONTESTED_GUARD
Definition DBCEnums.h:378
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormfmt)
DBCStorage< VehicleEntry > sVehicleStore(VehicleEntryfmt)
DBCStorage< MountCapabilityEntry > sMountCapabilityStore(MountCapabilityfmt)
uint32 GetPowerIndexByClass(uint32 powerType, uint32 classId)
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
DBCStorage< MountTypeEntry > sMountTypeStore(MountTypefmt)
DBCStorage< LiquidTypeEntry > sLiquidTypeStore(LiquidTypefmt)
#define MAX_EFFECT_MASK
#define MAX_SPELL_EFFECTS
#define MAX_MOUNT_CAPABILITIES
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
std::uint64_t uint64
Definition Define.h:76
std::uint16_t uint16
Definition Define.h:78
#define ASSERT
Definition Errors.h:29
TypeMapContainer< AllWorldObjectTypes > WorldTypeMapContainer
Definition GridDefines.h:72
TypeMapContainer< AllGridObjectTypes > GridTypeMapContainer
Definition GridDefines.h:71
CoordPair< TOTAL_NUMBER_OF_CELLS_PER_MAP > CellCoord
@ GROUP_UPDATE_FLAG_CUR_HP
Definition Group.h:77
@ GROUP_UPDATE_FLAG_PET_CUR_HP
Definition Group.h:91
@ GROUP_UPDATE_FLAG_POWER_TYPE
Definition Group.h:79
@ GROUP_UPDATE_FLAG_PET_CUR_POWER
Definition Group.h:95
@ GROUP_UPDATE_FLAG_PET_MAX_POWER
Definition Group.h:96
@ GROUP_UPDATE_FLAG_MAX_HP
Definition Group.h:78
@ GROUP_UPDATE_FLAG_PET_POWER_TYPE
Definition Group.h:93
@ GROUP_UPDATE_FLAG_MAX_POWER
Definition Group.h:82
@ GROUP_UPDATE_FLAG_LEVEL
Definition Group.h:83
@ GROUP_UPDATE_FLAG_PET_MAX_HP
Definition Group.h:92
@ GROUP_UPDATE_FLAG_CUR_POWER
Definition Group.h:81
#define sInstanceSaveMgr
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_FATAL(filterType__,...)
Definition Log.h:146
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true)
ZLiquidStatus
Definition Map.h:114
@ LIQUID_MAP_UNDER_WATER
Definition Map.h:119
@ LIQUID_MAP_IN_WATER
Definition Map.h:118
#define MAP_ALL_LIQUIDS
Definition Map.h:128
#define INVALID_HEIGHT
Definition Map.h:142
@ FLEEING_MOTION_TYPE
@ CONFUSED_MOTION_TYPE
MovementStatusElements const * GetMovementStatusElementsSequence(Opcodes opcode)
MovementStatusElements
@ MSEFallHorizontalSpeed
@ MSETransportGuidByte6
@ MSEHasGuidByte6
@ MSEZeroBit
@ MSEHasTransportData
@ MSEFlushBits
@ MSEHasCounter
@ MSEFallVerticalSpeed
@ MSEMountDisplayIdWithCheck
@ MSEForcesCount
@ MSESplineElevation
@ MSEHasMovementFlags
@ MSEFallTime
@ MSEHasTransportVehicleId
@ MSEGuidByte6
@ MSEHasTransportGuidByte5
@ MSEHasGuidByte4
@ MSEHasGuidByte5
@ MSEHasOrientation
@ MSETransportGuidByte0
@ MSEOrientation
@ MSETransportGuidByte2
@ MSETransportVehicleId
@ MSETransportGuidByte1
@ MSECounter
@ MSETransportGuidByte7
@ MSEPositionX
@ MSEMountDisplayIdWithoutCheck
@ MSEFallSinAngle
@ MSEHasPitch
@ MSEMovementFlags2
@ MSEHasGuidByte3
@ MSEHasTimestamp
@ MSEHasFallData
@ MSEFallCosAngle
@ MSEHasMovementFlags2
@ MSETransportPositionX
@ MSEHasSpline
@ MSEHasTransportTime2
@ MSEHasTransportGuidByte3
@ MSEGuidByte1
@ MSEHasFallDirection
@ MSETransportTime3
@ MSETransportGuidByte3
@ MSEHasTransportGuidByte6
@ MSEHasGuidByte0
@ MSEHasTransportTime3
@ MSEHasTransportGuidByte2
@ MSEGuidByte2
@ MSEGuidByte0
@ MSEHasTransportGuidByte1
@ MSEHasSplineElevation
@ MSETransportTime
@ MSETransportTime2
@ MSEPositionZ
@ MSEPitch
@ MSEUintCount
@ MSEExtraElement
@ MSEHasTransportGuidByte7
@ MSETransportSeat
@ MSEPositionY
@ MSEHasGuidByte7
@ MSEExtraFloat
@ MSEMovementFlags
@ MSEHasMountDisplayId
@ MSEOrientationWithoutCheck
@ MSEHasGuidByte2
@ MSECount
@ MSEGuidByte3
@ MSETransportGuidByte5
@ MSEOneBit
@ MSETransportOrientation
@ MSETransportPositionY
@ MSETransportGuidByte4
@ MSEGuidByte5
@ MSEHasTransportGuidByte4
@ MSETransportPositionZ
@ MSEHasTransportGuidByte0
@ MSEForces
@ MSEGuidByte7
@ MSETimestamp
@ MSEGuidByte4
@ MSEHasGuidByte1
#define ATTACK_DISTANCE
Definition Object.h:22
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
#define MIN_MELEE_REACH
Definition Object.h:31
#define DEFAULT_COMBAT_REACH
Definition Object.h:30
@ TYPEMASK_UNIT
Definition Object.h:40
@ NOTIFY_VISIBILITY_CHANGED
Definition Object.h:88
uint32 GUID_LOPART(uint64 x)
bool IS_CREATURE_GUID(uint64 guid)
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
bool IS_PLAYER_GUID(uint64 guid)
#define sObjectMgr
Definition ObjectMgr.h:1617
std::pair< SpellClickInfoContainer::const_iterator, SpellClickInfoContainer::const_iterator > SpellClickInfoMapBounds
Definition ObjectMgr.h:402
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:22
@ HUNTER_PET
Definition PetDefines.h:12
@ TELE_TO_SPELL
Definition Player.h:833
@ TELE_TO_NOT_LEAVE_COMBAT
Definition Player.h:831
@ TELE_TO_NOT_UNSUMMON_PET
Definition Player.h:832
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition Player.h:830
@ PLAYER_FLAGS_CONTESTED_PVP
Definition Player.h:545
@ PLAYER_FLAGS_UBER
Definition Player.h:556
@ EQUIPMENT_SLOT_OFFHAND
Definition Player.h:705
#define INVENTORY_SLOT_BAG_0
Definition Player.h:684
@ FACTION_FLAG_AT_WAR
#define sScriptMgr
Definition ScriptMgr.h:764
@ SERVERSIDE_VISIBILITY_GM
@ SERVERSIDE_VISIBILITY_GHOST
@ EFFECT_0
#define MAX_STATS
@ SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK
@ SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY
@ SPELL_ATTR0_CASTABLE_WHILE_DEAD
@ SPELL_ATTR0_TRADESPELL
@ SPELL_ATTR0_ABILITY
@ SPELL_ATTR0_REQ_AMMO
Powers
@ MAX_POWERS
@ POWER_SHADOW_ORBS
@ POWER_ECLIPSE
@ POWER_RAGE
@ POWER_DEMONIC_FURY
@ POWER_ARCANE_CHARGES
@ POWER_HEALTH
@ POWER_BURNING_EMBERS
@ POWER_RUNIC_POWER
@ POWER_ENERGY
@ POWER_CHI
@ POWER_SOUL_SHARDS
@ POWER_RUNES
@ POWER_MANA
@ POWER_HOLY_POWER
@ POWER_FOCUS
DiminishingGroup
SpellSchools
@ SPELL_SCHOOL_SHADOW
@ SPELL_SCHOOL_NORMAL
@ SPELL_SCHOOL_NATURE
@ SPELL_SCHOOL_FROST
@ SPELL_SCHOOL_ARCANE
@ SPELL_SCHOOL_FIRE
@ SPELL_SCHOOL_HOLY
@ SPELL_EFFECT_POWER_BURN
@ SPELL_EFFECT_HEALTH_LEECH
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_POWER_DRAIN
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ SPELL_EFFECT_APPLY_AURA
@ SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY
@ SPELL_ATTR1_CANT_BE_REDIRECTED
@ GENDER_MALE
@ NPC_CLICK_CAST_TARGET_CLICKER
@ NPC_CLICK_CAST_ORIG_CASTER_OWNER
@ NPC_CLICK_CAST_CASTER_CLICKER
@ SPELL_ATTR2_AUTOREPEAT_FLAG
@ SPELL_ATTR2_CANT_CRIT
@ SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS
@ CREATURE_TYPE_HUMANOID
@ CREATURE_TYPE_CRITTER
@ CREATURE_TYPE_DEMON
SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask)
uint32 const CREATURE_TYPEMASK_DEMON_OR_UNDEAD
@ UNIT_DYNFLAG_SPECIALINFO
@ UNIT_DYNFLAG_TAPPED_BY_PLAYER
@ UNIT_DYNFLAG_TAPPED
@ UNIT_DYNFLAG_LOOTABLE
@ UNIT_DYNFLAG_TRACK_UNIT
@ SPELL_DAMAGE_CLASS_RANGED
@ SPELL_DAMAGE_CLASS_MAGIC
@ SPELL_DAMAGE_CLASS_NONE
@ SPELL_DAMAGE_CLASS_MELEE
@ AI_REACTION_HOSTILE
@ SPELL_ATTR6_CAN_TARGET_INVISIBLE
@ SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG
@ SPELL_ATTR6_CAN_TARGET_UNTARGETABLE
@ SUMMON_TYPE_MINIPET
@ CLASS_HUNTER
@ CLASS_PRIEST
@ CLASS_WARRIOR
@ CLASS_WARLOCK
@ CLASS_MAGE
#define PER_CASTER_AURA_STATE_MASK
@ SPELL_ATTR3_BLOCKABLE_SPELL
@ SPELL_ATTR3_IGNORE_HIT_RESULT
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_ID
@ IMMUNITY_DAMAGE
@ IMMUNITY_MECHANIC
@ IMMUNITY_SCHOOL
@ IMMUNITY_DISPEL
@ SPELLFAMILY_MAGE
@ SPELLFAMILY_WARRIOR
@ SPELLFAMILY_PALADIN
@ SPELLFAMILY_POTION
@ SPELLFAMILY_ROGUE
@ SPELLFAMILY_SHAMAN
@ SPELLFAMILY_DRUID
@ ALLIANCE
@ HORDE
ReputationRank
@ REP_FRIENDLY
@ REP_NEUTRAL
@ REP_HOSTILE
DiminishingLevels
@ DIMINISHING_LEVEL_1
@ DIMINISHING_LEVEL_2
@ GHOST_VISIBILITY_ALIVE
@ SPELL_HIT_TYPE_UNK1
@ SPELL_HIT_TYPE_CRIT
@ SPELL_HIT_TYPE_UNK3
@ SPELL_HIT_TYPE_UNK6
@ RACE_TROLL
@ RACE_PANDAREN_NEUTRAL
@ RACE_ORC
@ RACE_DRAENEI
@ RACE_NIGHTELF
@ RACE_DWARF
@ RACE_GOBLIN
@ RACE_WORGEN
@ RACE_PANDAREN_ALLIANCE
@ RACE_PANDAREN_HORDE
@ RACE_TAUREN
SpellMissInfo
@ SPELL_MISS_PARRY
@ SPELL_MISS_IMMUNE
@ SPELL_MISS_DODGE
@ SPELL_MISS_NONE
@ SPELL_MISS_RESIST
@ SPELL_MISS_MISS
@ SPELL_MISS_EVADE
@ SPELL_MISS_REFLECT
@ SPELL_MISS_BLOCK
@ SPELL_MISS_DEFLECT
@ AURA_STATE_DEFENSE
@ AURA_STATE_FROZEN
@ AURA_STATE_BLEEDING
@ AURA_STATE_FAERIE_FIRE
@ AURA_STATE_HEALTHLESS_35_PERCENT
@ AURA_STATE_HEALTH_ABOVE_75_PERCENT
@ AURA_STATE_HEALTHLESS_20_PERCENT
@ AURA_STATE_HUNTER_PARRY
Stats
@ STAT_SPIRIT
@ STAT_INTELLECT
@ STAT_AGILITY
@ STAT_STRENGTH
@ STAT_STAMINA
@ MECHANIC_ENRAGED
@ MECHANIC_KNOCKOUT
@ MECHANIC_STUN
#define MAX_SPELL_SCHOOL
DispelType
@ DISPEL_MAGIC
@ SPELL_ATTR8_ATTACK_IGNORE_IMMUNE_TO_PC_FLAG
#define MAX_SPELL_IMMUNITY
@ CREATURE_TYPEFLAGS_PARTY_MEMBER
@ CREATURE_TYPEFLAGS_AID_PLAYERS
@ SKILL_RIDING
SpellSchoolMask
@ SPELL_SCHOOL_MASK_NORMAL
@ SPELL_STATE_DELAYED
Definition Spell.h:269
@ SPELL_STATE_FINISHED
Definition Spell.h:267
@ SPELL_STATE_CASTING
Definition Spell.h:266
@ SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE
@ SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
@ SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
@ SPELL_AURA_MOD_PARRY_PERCENT
@ SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT
@ SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK
@ SPELL_AURA_MOD_THREAT
@ SPELL_AURA_MOD_POSSESS_PET
@ SPELL_AURA_MOD_INCREASE_SPEED
@ SPELL_AURA_MOD_EXPERTISE
@ SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
@ SPELL_AURA_CAST_WHILE_WALKING
@ SPELL_AURA_ADD_CASTER_HIT_TRIGGER
@ SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
@ SPELL_AURA_REFLECT_SPELLS
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_IGNORE_HIT_DIRECTION
@ SPELL_AURA_IGNORE_COMBAT_RESULT
@ SPELL_AURA_EMPATHY
@ SPELL_AURA_MOD_SPEED_NOT_STACK
@ SPELL_AURA_MOD_STALKED
@ SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED
@ SPELL_AURA_MOD_INVISIBILITY
@ SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_MOD_ENEMY_DODGE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_DODGE_PERCENT
@ SPELL_AURA_MOD_INCREASE_SWIM_SPEED
@ SPELL_AURA_DEFLECT_SPELLS
@ SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
@ SPELL_AURA_MOD_HEALING_DONE
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
@ SPELL_AURA_MOD_CHARM
@ SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT
@ SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
@ SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT
@ SPELL_AURA_MOD_FEAR_2
@ SPELL_AURA_MOD_ROOT
@ SPELL_AURA_MECHANIC_DURATION_MOD
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE
@ SPELL_AURA_MOD_DAMAGE_TAKEN
@ SPELL_AURA_MOD_TAUNT
@ SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
@ SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
@ SPELL_AURA_MOD_CRIT_PCT
@ SPELL_AURA_MOD_MINIMUM_SPEED
@ SPELL_AURA_MOD_BLOCK_CRIT_CHANCE
@ SPELL_AURA_AOE_CHARM
@ SPELL_AURA_MOD_SPEED_ALWAYS
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_TRANSFORM
@ SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
@ SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
@ SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
@ SPELL_AURA_SPELL_MAGNET
@ SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL
@ SPELL_AURA_MOD_DURABILITY_LOSS
@ SPELL_AURA_PERIODIC_LEECH
@ SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE
@ SPELL_AURA_MOD_HEALING
@ SPELL_AURA_MOD_DAMAGE_DONE
@ SPELL_AURA_MOD_CONFUSE
@ SPELL_AURA_MOD_POSSESS
@ SPELL_AURA_REFLECT_SPELLS_SCHOOL
@ SPELL_AURA_MOD_MECHANIC_RESISTANCE
@ SPELL_AURA_INTERFERE_TARGETTING
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
@ SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
@ SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
@ SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
@ SPELL_AURA_MOD_BLOCK_PERCENT
@ SPELL_AURA_MOD_STUN
@ SPELL_AURA_BIND_SIGHT
@ AURA_EFFECT_HANDLE_SEND_FOR_CLIENT
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:79
@ SPELL_SPECIFIC_MAGE_POLYMORPH
Definition SpellInfo.h:46
DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group)
Definition SpellMgr.cpp:224
@ SPELL_GROUP_ELIXIR_BATTLE
Definition SpellMgr.h:316
@ SPELL_GROUP_ELIXIR_GUARDIAN
Definition SpellMgr.h:317
#define sSpellMgr
Definition SpellMgr.h:744
@ PROC_EX_NONE
Definition SpellMgr.h:184
@ PROC_EX_REFLECT
Definition SpellMgr.h:196
@ PROC_FLAG_KILLED
Definition SpellMgr.h:98
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:123
@ PROC_FLAG_DEATH
Definition SpellMgr.h:134
@ PROC_FLAG_KILL
Definition SpellMgr.h:99
@ PROC_FLAG_NONE
Definition SpellMgr.h:96
uint32 getMSTime()
Definition Timer.h:12
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition Timer.h:17
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:56
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:69
@ UNIT_NPC_FLAG_TABARDDESIGNER
Definition Unit.h:706
@ UNIT_NPC_FLAG_BANKER
Definition Unit.h:704
@ UNIT_NPC_FLAG_AUCTIONEER
Definition Unit.h:708
@ UNIT_NPC_FLAG_VENDOR
Definition Unit.h:694
@ UNIT_NPC_FLAG_BATTLEMASTER
Definition Unit.h:707
@ UNIT_NPC_FLAG_INNKEEPER
Definition Unit.h:703
@ UNIT_NPC_FLAG_SPELLCLICK
Definition Unit.h:711
@ UNIT_NPC_FLAG_PLAYER_VEHICLE
Definition Unit.h:712
@ UNIT_NPC_FLAG_FLIGHTMASTER
Definition Unit.h:700
@ UNIT_NPC_FLAG_TRAINER
Definition Unit.h:691
@ UNIT_NPC_FLAG_PETITIONER
Definition Unit.h:705
@ UNIT_NPC_FLAG_SPIRITGUIDE
Definition Unit.h:702
@ UNIT_NPC_FLAG_SPIRITHEALER
Definition Unit.h:701
#define MAX_SPELL_CHARM
Definition Unit.h:273
@ AURA_INTERRUPT_FLAG_TAKE_DAMAGE
Definition Unit.h:42
@ AURA_INTERRUPT_FLAG_MOVE
Definition Unit.h:44
@ AURA_INTERRUPT_FLAG_TURNING
Definition Unit.h:45
@ AURA_INTERRUPT_FLAG_NOT_ABOVEWATER
Definition Unit.h:48
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition Unit.h:59
@ AURA_INTERRUPT_FLAG_NOT_UNDERWATER
Definition Unit.h:49
@ AURA_INTERRUPT_FLAG_MOUNT
Definition Unit.h:58
@ AURA_INTERRUPT_FLAG_NOT_MOUNTED
Definition Unit.h:47
MovementFlags
Definition Unit.h:721
@ MOVEMENTFLAG_FORWARD
Definition Unit.h:723
@ MOVEMENTFLAG_WATERWALKING
Definition Unit.h:749
@ MOVEMENTFLAG_MASK_MOVING
Definition Unit.h:755
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition Unit.h:732
@ MOVEMENTFLAG_FLYING
Definition Unit.h:747
@ MOVEMENTFLAG_FALLING_SLOW
Definition Unit.h:750
@ MOVEMENTFLAG_CAN_FLY
Definition Unit.h:746
@ MOVEMENTFLAG_ROOT
Definition Unit.h:733
@ MOVEMENTFLAG_FALLING
Definition Unit.h:734
@ MOVEMENTFLAG_MASK_MOVING_FLY
Definition Unit.h:763
@ MOVEMENTFLAG_FALLING_FAR
Definition Unit.h:735
@ MOVEMENTFLAG_SWIMMING
Definition Unit.h:743
@ MOVEMENTFLAG_HOVER
Definition Unit.h:751
@ MOVEMENTFLAG_SPLINE_ELEVATION
Definition Unit.h:748
@ MOVEMENTFLAG_WALKING
Definition Unit.h:731
@ UNIT_MASK_NONE
Definition Unit.h:804
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition Unit.h:813
@ UNIT_MASK_ACCESSORY
Definition Unit.h:814
@ UNIT_MASK_VEHICLE
Definition Unit.h:810
@ UNIT_MASK_GUARDIAN
Definition Unit.h:807
@ UNIT_MASK_MINION
Definition Unit.h:806
#define WORLD_TRIGGER
Definition Unit.h:20
#define MAX_UNIT_ACTION_BAR_INDEX
Definition Unit.h:1233
WeaponAttackType
Definition Unit.h:572
VictimState
Definition Unit.h:289
@ VICTIMSTATE_DODGE
Definition Unit.h:292
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:56
@ SPELLMOD_EFFECT2
Definition Unit.h:85
@ SPELLMOD_CRIT_DAMAGE_BONUS
Definition Unit.h:88
@ SPELLMOD_EFFECT5
Definition Unit.h:106
@ SPELLMOD_ALL_EFFECTS
Definition Unit.h:81
@ SPELLMOD_CRITICAL_CHANCE
Definition Unit.h:80
@ SPELLMOD_EFFECT3
Definition Unit.h:96
@ SPELLMOD_EFFECT4
Definition Unit.h:105
@ SPELLMOD_EFFECT1
Definition Unit.h:76
@ SPELLMOD_CASTING_TIME
Definition Unit.h:83
@ SPELLMOD_RESIST_MISS_CHANCE
Definition Unit.h:89
WeaponDamageRange
Definition Unit.h:392
SpellValueMod
Definition Unit.h:113
@ SPELLVALUE_BASE_POINT0
Definition Unit.h:114
UnitMods
Definition Unit.h:439
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:473
@ UNIT_MOD_RUNE
Definition Unit.h:451
@ UNIT_MOD_STAT_INTELLECT
Definition Unit.h:443
@ UNIT_MOD_STAT_SPIRIT
Definition Unit.h:444
@ UNIT_MOD_ARMOR
Definition Unit.h:463
@ UNIT_MOD_RESISTANCE_SHADOW
Definition Unit.h:468
@ UNIT_MOD_RESISTANCE_FROST
Definition Unit.h:467
@ UNIT_MOD_END
Definition Unit.h:475
@ UNIT_MOD_ATTACK_POWER
Definition Unit.h:470
@ UNIT_MOD_RESISTANCE_HOLY
Definition Unit.h:464
@ UNIT_MOD_SOUL_SHARDS
Definition Unit.h:453
@ UNIT_MOD_RESISTANCE_ARCANE
Definition Unit.h:469
@ UNIT_MOD_ARCANE_CHARGES
Definition Unit.h:462
@ UNIT_MOD_ECLIPSE
Definition Unit.h:454
@ UNIT_MOD_ENERGY
Definition Unit.h:449
@ UNIT_MOD_HEALTH
Definition Unit.h:445
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:474
@ UNIT_MOD_HOLY_POWER
Definition Unit.h:455
@ UNIT_MOD_BURNING_EMBERS
Definition Unit.h:460
@ UNIT_MOD_CHI
Definition Unit.h:458
@ UNIT_MOD_RESISTANCE_FIRE
Definition Unit.h:465
@ UNIT_MOD_STAT_STRENGTH
Definition Unit.h:440
@ UNIT_MOD_RESISTANCE_NATURE
Definition Unit.h:466
@ UNIT_MOD_DEMONIC_FURY
Definition Unit.h:461
@ UNIT_MOD_STAT_AGILITY
Definition Unit.h:441
@ UNIT_MOD_FOCUS
Definition Unit.h:448
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:472
@ UNIT_MOD_SHADOW_ORBS
Definition Unit.h:459
@ UNIT_MOD_MANA
Definition Unit.h:446
@ UNIT_MOD_STAT_START
Definition Unit.h:477
@ UNIT_MOD_RAGE
Definition Unit.h:447
@ UNIT_MOD_STAT_STAMINA
Definition Unit.h:442
@ UNIT_MOD_RUNIC_POWER
Definition Unit.h:452
@ UNIT_MOD_ATTACK_POWER_RANGED
Definition Unit.h:471
HitInfo
Definition Unit.h:302
@ HITINFO_PARTIAL_ABSORB
Definition Unit.h:310
@ HITINFO_FULL_RESIST
Definition Unit.h:311
@ HITINFO_BLOCK
Definition Unit.h:317
@ HITINFO_UNK12
Definition Unit.h:316
@ HITINFO_RAGE_GAIN
Definition Unit.h:327
@ HITINFO_FULL_ABSORB
Definition Unit.h:309
@ HITINFO_UNK1
Definition Unit.h:304
@ HITINFO_PARTIAL_RESIST
Definition Unit.h:312
@ ACTION_BAR_INDEX_PET_SPELL_START
Definition Unit.h:1228
@ ACTION_BAR_INDEX_PET_SPELL_END
Definition Unit.h:1229
@ ACTION_BAR_INDEX_END
Definition Unit.h:1230
@ ACTION_BAR_INDEX_START
Definition Unit.h:1227
DeathState
Definition Unit.h:502
@ ALIVE
Definition Unit.h:503
@ JUST_DIED
Definition Unit.h:504
@ JUST_RESPAWNED
Definition Unit.h:507
#define MAX_MOVE_TYPE
Definition Unit.h:566
@ COMMAND_ATTACK
Definition Unit.h:1166
@ COMMAND_MOVE_TO
Definition Unit.h:1168
@ COMMAND_FOLLOW
Definition Unit.h:1165
@ UNIT_STAND_STATE_SLEEP
Definition Unit.h:165
@ UNIT_STAND_STATE_SIT_HIGH_CHAIR
Definition Unit.h:168
@ UNIT_STAND_STATE_SIT_MEDIUM_CHAIR
Definition Unit.h:167
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition Unit.h:166
@ UNIT_STAND_STATE_KNEEL
Definition Unit.h:170
@ UNIT_STAND_STATE_SIT_CHAIR
Definition Unit.h:164
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ UNIT_STAND_STATE_SIT
Definition Unit.h:163
#define MAX_SUMMON_SLOT
Definition Unit.h:1344
#define MAX_AGGRO_RESET_TIME
Definition Unit.h:278
@ AURA_REMOVE_BY_EXPIRE
Definition Unit.h:410
@ TRIGGERED_FULL_MASK
Will ignore most target checks (mostly DBC target checks).
Definition Unit.h:435
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition Unit.h:429
@ TRIGGERED_NONE
Definition Unit.h:416
#define CREATURE_MAX_SPELLS
Definition Unit.h:272
UnitModifierType
Definition Unit.h:383
@ MODIFIER_TYPE_END
Definition Unit.h:388
@ BASE_VALUE
Definition Unit.h:384
@ TOTAL_VALUE
Definition Unit.h:386
@ TOTAL_PCT
Definition Unit.h:387
@ BASE_PCT
Definition Unit.h:385
#define CURRENT_MAX_SPELL
Definition Unit.h:1115
CombatRating
Definition Unit.h:580
ShapeshiftForm
Definition Unit.h:206
@ FORM_FIERCE_TIGER
Definition Unit.h:231
@ FORM_UNDEAD
Definition Unit.h:232
@ FORM_TRAVEL
Definition Unit.h:210
@ FORM_SHADOW
Definition Unit.h:235
@ FORM_BERSERKERSTANCE
Definition Unit.h:226
@ FORM_DEFENSIVESTANCE
Definition Unit.h:225
@ FORM_FLIGHT_EPIC
Definition Unit.h:234
@ FORM_MOONKIN
Definition Unit.h:238
@ FORM_NONE
Definition Unit.h:207
@ FORM_CAT
Definition Unit.h:208
@ FORM_FLIGHT
Definition Unit.h:236
@ FORM_GHOSTWOLF
Definition Unit.h:223
@ FORM_STEALTH
Definition Unit.h:237
@ FORM_BATTLESTANCE
Definition Unit.h:224
@ FORM_STURDY_OX
Definition Unit.h:230
@ FORM_WISE_SERPENT
Definition Unit.h:227
@ FORM_BEAR
Definition Unit.h:212
#define BASE_MAXDAMAGE
Definition Unit.h:156
CharmType
Definition Unit.h:1216
@ CHARM_TYPE_CHARM
Definition Unit.h:1217
@ CHARM_TYPE_POSSESS
Definition Unit.h:1218
@ CHARM_TYPE_CONVERT
Definition Unit.h:1220
@ CHARM_TYPE_VEHICLE
Definition Unit.h:1219
CurrentSpellTypes
Definition Unit.h:1107
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
@ CURRENT_GENERIC_SPELL
Definition Unit.h:1109
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:1111
MeleeHitOutcome
Definition Unit.h:828
@ MELEE_HIT_PARRY
Definition Unit.h:829
@ MELEE_HIT_DODGE
Definition Unit.h:829
@ MELEE_HIT_BLOCK
Definition Unit.h:829
ReactiveType
Definition Unit.h:1332
@ REACTIVE_OVERPOWER
Definition Unit.h:1335
@ REACTIVE_DEFENSE
Definition Unit.h:1333
@ REACTIVE_HUNTER_PARRY
Definition Unit.h:1334
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition Unit.h:788
@ MOVEMENTFLAG2_FULL_SPEED_PITCHING
Definition Unit.h:787
ActiveStates
Definition Unit.h:1144
@ ACT_REACTION
Definition Unit.h:1150
@ ACT_DECIDE
Definition Unit.h:1151
@ ACT_COMMAND
Definition Unit.h:1149
@ ACT_ENABLED
Definition Unit.h:1148
@ ACT_PASSIVE
Definition Unit.h:1145
@ ACT_DISABLED
Definition Unit.h:1147
#define MAX_REACTIVE
Definition Unit.h:1338
#define MAX_GAMEOBJECT_SLOT
Definition Unit.h:1346
@ UNIT_BYTE2_FLAG_UNK1
Definition Unit.h:256
@ UNIT_BYTE2_FLAG_PVP
Definition Unit.h:255
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition Unit.h:257
@ UNIT_BYTE2_FLAG_SANCTUARY
Definition Unit.h:258
UnitState
Definition Unit.h:511
@ UNIT_STATE_DISTRACTED
Definition Unit.h:524
@ UNIT_STATE_DIED
Definition Unit.h:512
@ UNIT_STATE_POSSESSED
Definition Unit.h:528
@ UNIT_STATE_UNATTACKABLE
Definition Unit.h:540
@ UNIT_STATE_CONFUSED
Definition Unit.h:523
@ UNIT_STATE_ROOT
Definition Unit.h:522
@ UNIT_STATE_CONTROLLED
Definition Unit.h:543
@ UNIT_STATE_FLEEING
Definition Unit.h:519
@ UNIT_STATE_CANNOT_TURN
Definition Unit.h:547
@ UNIT_STATE_MOVING
Definition Unit.h:542
@ UNIT_STATE_MOVE
Definition Unit.h:531
@ UNIT_STATE_MELEE_ATTACKING
Definition Unit.h:513
@ UNIT_STATE_IN_FLIGHT
Definition Unit.h:520
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ UNIT_STATE_STUNNED
Definition Unit.h:515
AnimTier
Definition Unit.h:196
@ SUMMON_TYPE_LIGHTSPRING
Definition Unit.h:1355
@ SUMMON_TYPE_TOTEM_EARTH
Definition Unit.h:1351
@ SUMMON_TYPE_TOTEM_WATER
Definition Unit.h:1352
@ SUMMON_TYPE_STATUE_JADE
Definition Unit.h:1356
@ SUMMON_TYPE_TOTEM_FIRE
Definition Unit.h:1350
@ SUMMON_TYPE_STATUE_OX
Definition Unit.h:1357
@ SUMMON_TYPE_TOTEM_AIR
Definition Unit.h:1353
#define BASE_MINDAMAGE
Definition Unit.h:155
UnitMoveType
Definition Unit.h:554
@ MOVE_FLIGHT
Definition Unit.h:561
@ MOVE_SWIM
Definition Unit.h:558
@ MOVE_FLIGHT_BACK
Definition Unit.h:562
@ MOVE_SWIM_BACK
Definition Unit.h:559
@ MOVE_RUN
Definition Unit.h:556
@ MOVE_RUN_BACK
Definition Unit.h:557
@ MOVE_WALK
Definition Unit.h:555
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ REACT_ASSIST
Definition Unit.h:1159
std::list< SpellImmune > SpellImmuneList
Definition Unit.h:380
@ UNIT_FLAG_TAXI_FLIGHT
Definition Unit.h:645
@ UNIT_FLAG_STUNNED
Definition Unit.h:643
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_IMMUNE_TO_NPC
Definition Unit.h:634
@ UNIT_FLAG_DISABLE_POWERS
Definition Unit.h:654
@ UNIT_FLAG_DISARMED
Definition Unit.h:646
@ UNIT_FLAG_PVP_ATTACKABLE
Definition Unit.h:628
@ UNIT_FLAG_DISABLE_MOVE
Definition Unit.h:627
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ UNIT_FLAG_NOT_ATTACKABLE_1
Definition Unit.h:632
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition Unit.h:649
@ UNIT_FLAG_SKINNABLE
Definition Unit.h:651
@ UNIT_FLAG_UNK_16
Definition Unit.h:641
@ UNIT_FLAG_MOUNT
Definition Unit.h:652
@ UNIT_FLAG2_IGNORE_REPUTATION
Definition Unit.h:665
@ UNIT_FLAG2_DISARM_OFFHAND
Definition Unit.h:670
@ UNIT_FLAG2_DISARM_RANGED
Definition Unit.h:672
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:69
DamageEffectType
Definition Unit.h:613
@ DIRECT_DAMAGE
Definition Unit.h:614
@ DOT
Definition Unit.h:616
@ UPDATETYPE_VALUES
Definition UpdateData.h:16
@ UPDATEFLAG_LIVING
Definition UpdateData.h:30
@ UPDATEFLAG_VEHICLE
Definition UpdateData.h:32
uint32 UnitUpdateFieldFlags[PLAYER_END]
@ UF_FLAG_VIEWER_DEPENDENT
@ UF_FLAG_SPECIAL_INFO
@ UF_FLAG_PUBLIC
@ UF_FLAG_OWNER
@ UF_FLAG_PRIVATE
@ UF_FLAG_PARTY_MEMBER
EUnitFields
@ UNIT_FIELD_ATTACK_ROUND_BASE_TIME
@ UNIT_FIELD_MOD_CASTING_SPEED
@ UNIT_FIELD_FLAGS2
@ UNIT_FIELD_STAT_POS_BUFF
@ UNIT_FIELD_HEALTH
@ UNIT_FIELD_SHAPESHIFT_FORM
@ UNIT_FIELD_MAX_HEALTH
@ UNIT_FIELD_MOUNT_DISPLAY_ID
@ UNIT_FIELD_LEVEL
@ UNIT_FIELD_MOD_SPELL_HASTE
@ UNIT_FIELD_RANGED_ATTACK_POWER
@ UNIT_FIELD_RESISTANCE_BUFF_MODS_NEGATIVE
@ UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER
@ UNIT_FIELD_SUMMON
@ UNIT_FIELD_POWER
@ UNIT_FIELD_RESISTANCE_BUFF_MODS_POSITIVE
@ UNIT_FIELD_ATTACK_POWER_MULTIPLIER
@ UNIT_FIELD_ATTACK_POWER
@ UNIT_FIELD_CHARMED_BY
@ UNIT_FIELD_MOD_HASTE
@ UNIT_FIELD_PET_NUMBER
@ UNIT_FIELD_CHARM
@ UNIT_FIELD_PET_NAME_TIMESTAMP
@ UNIT_FIELD_MAX_POWER
@ UNIT_FIELD_FACTION_TEMPLATE
@ UNIT_FIELD_DISPLAY_ID
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_ANIM_TIER
@ UNIT_FIELD_AURA_STATE
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_SUMMONED_BY
@ UNIT_FIELD_COMBAT_REACH
@ UNIT_FIELD_RANGED_ATTACK_ROUND_BASE_TIME
@ UNIT_FIELD_MOD_RANGED_HASTE
@ UNIT_FIELD_HOVER_HEIGHT
@ UNIT_FIELD_STAT_NEG_BUFF
@ UNIT_FIELD_CREATED_BY_SPELL
@ OBJECT_FIELD_DYNAMIC_FLAGS
@ PLAYER_FIELD_OFFHAND_CRIT_PERCENTAGE
@ PLAYER_FIELD_DODGE_PERCENTAGE
@ PLAYER_FIELD_RANGED_CRIT_PERCENTAGE
@ PLAYER_FIELD_PARRY_PERCENTAGE
@ PLAYER_FIELD_HAIR_COLOR_ID
@ PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_APPERCENT
@ PLAYER_FIELD_CRIT_PERCENTAGE
@ PLAYER_FIELD_SPELL_CRIT_PERCENTAGE
@ PLAYER_FIELD_SELF_RES_SPELL
@ PLAYER_FIELD_BLOCK_PERCENTAGE
@ PLAYER_FIELD_PLAYER_FLAGS
double rand_norm(void)
Definition Util.cpp:50
bool roll_chance_f(float chance)
Definition Util.h:83
bool roll_chance_i(int chance)
Definition Util.h:89
T AddPct(T &base, U pct)
Definition Util.h:109
T RoundToInterval(T &num, T floor, T ceil)
Definition Util.h:121
T ApplyPct(T &base, U pct)
Definition Util.h:115
void ApplyPercentModFloatVar(float &var, float val, bool apply)
Definition Util.h:94
T CalculatePct(T base, U pct)
Definition Util.h:103
@ VEHICLE_SPELL_RIDE_HARDCODED
Aura * GetBase() const
Definition SpellAuras.h:55
AuraRemoveMode GetRemoveMode() const
Definition SpellAuras.h:66
void ChangeAmount(int32 newAmount, bool mark=true, bool onStackOrReapply=false)
AuraType GetAuraType() const
uint32 GetId() const
void HandleEffect(AuraApplication *aurApp, uint8 mode, bool apply)
uint64 GetCasterGUID() const
const AuraApplication * GetApplicationOfTarget(uint64 guid) const
Definition SpellAuras.h:176
void UpdateOwner(uint32 diff, WorldObject *owner)
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint32 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=NULL, Item *castItem=NULL, uint64 casterGUID=0, bool *refresh=NULL)
bool isArena() const
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void append(T value)
Definition ByteBuffer.h:147
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
size_t size() const
Definition ByteBuffer.h:609
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
virtual void OnSpellClick(Unit *, bool &)
Definition CreatureAI.h:165
virtual void JustDied(Unit *)
Definition CreatureAI.h:92
virtual void KilledUnit(Unit *)
Definition CreatureAI.h:95
void OnCharmed(bool apply)
virtual void EnterEvadeMode()
Loot loot
Definition Creature.h:544
bool isWorldBoss() const
uint16 GetLootMode() const
Definition Creature.h:555
bool lootForPickPocketed
Definition Creature.h:545
bool CanWalk() const
Definition Creature.h:456
bool HasReactState(ReactStates state) const
Definition Creature.h:462
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
bool CanFly() const OVERRIDE
Definition Creature.h:458
bool hasLootRecipient() const
Definition Creature.h:549
void SetLootRecipient(Unit *unit)
Definition Creature.cpp:893
bool CanSwim() const
Definition Creature.h:457
float m_CombatDistance
Definition Creature.h:660
Player * GetLootRecipient() const
Definition Creature.cpp:879
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:524
bool CanCreatureAttack(Unit const *victim, bool force=true) const
bool IsDamageEnoughForLootingAndReward() const
Definition Creature.h:650
bool isTappedBy(Player const *player) const
Definition Creature.cpp:922
Unit * SelectVictim()
Definition Unit.cpp:4547
bool _IsTargetAcceptable(const Unit *target) const
Unit * SelectNearestTargetInAttackDistance(float dist=0) const
time_t GetRespawnTimeEx() const
bool IsInEvadeMode() const
Definition Creature.h:478
CreatureAI * AI() const
Definition Creature.h:483
void ResistDamage(uint32 amount)
Definition Unit.cpp:112
void AbsorbDamage(uint32 amount)
Definition Unit.cpp:105
uint32 m_resist
Definition Unit.h:888
Unit *const m_attacker
Definition Unit.h:880
void ModifyDamage(int32 amount)
Definition Unit.cpp:99
WeaponAttackType m_attackType
Definition Unit.h:886
SpellInfo const *const m_spellInfo
Definition Unit.h:883
uint32 m_block
Definition Unit.h:889
void BlockDamage(uint32 amount)
Definition Unit.cpp:119
uint32 m_absorb
Definition Unit.h:887
uint32 m_damage
Definition Unit.h:882
DamageInfo(Unit *_attacker, Unit *_victim, uint32 _damage, SpellInfo const *_spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType)
Definition Unit.cpp:82
SpellSchoolMask const m_schoolMask
Definition Unit.h:884
uint32 GetDamage() const
Definition Unit.h:923
DamageEffectType const m_damageType
Definition Unit.h:885
Unit *const m_victim
Definition Unit.h:881
uint32 GetSpellId() const
uint32 GetSpellId() const
Definition GameObject.h:687
void SetOwnerGUID(uint64 owner)
Definition GameObject.h:665
uint64 GetOwnerGUID() const
Definition GameObject.h:679
void Delete()
void SetRespawnTime(int32 respawn)
Definition GameObject.h:699
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition Unit.cpp:248
GlobalCooldownList m_GlobalCooldowns
Definition Unit.h:1140
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition Unit.cpp:254
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition Unit.cpp:259
Definition Group.h:147
uint32 GetMembersCount() const
Definition Group.h:227
GroupReference * GetFirstMember()
Definition Group.h:225
GroupReference * next()
bool InitStatsForLevel(uint8 level)
Definition Pet.cpp:828
HostileReference * getFirst()
void deleteReferencesForFaction(uint32 faction)
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=NULL)
void setOnlineOfflineState(bool isOnline)
HostileReference * next()
uint64 getUnitGuid() const
Definition Item.h:202
bool IsBroken() const
Definition Item.h:247
Definition Map.h:238
void CreatureRelocation(Creature *creature, float x, float y, float z, float ang, bool respawnRelocationOnFail=true)
Definition Map.cpp:909
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1959
bool IsBattleground() const
Definition Map.h:376
bool IsUnderWater(float x, float y, float z) const
Definition Map.cpp:2263
bool IsInWater(float x, float y, float z, LiquidData *data=0) const
Definition Map.cpp:2256
Creature * GetCreature(uint64 guid)
Definition Map.cpp:3179
bool IsRaidOrHeroicDungeon() const
Definition Map.h:373
void PlayerRelocation(Player *, float x, float y, float z, float orientation)
Definition Map.cpp:877
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data=0) const
Definition Map.cpp:2110
bool IsInstance() const
Definition Map.h:368
bool IsGuardianPet() const
bool IsPetGhoul() const
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=EVENT_JUMP)
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
void MovementExpired(bool reset=true)
void MoveJumpTo(float angle, float speedXY, float speedZ)
void Clear(bool reset=true)
void MoveFleeing(Unit *enemy, uint32 time=0)
struct Movement::ExtraMovementStatusElement::@223034106340337246130275244156275117357303062005 Data
void SetVelocity(float velocity)
void SetFacing(float angle)
void MoveTo(const Vector3 &destination, bool generatePath=true, bool forceDestination=false)
static Creature * GetCreatureOrPetOrVehicle(WorldObject const &, uint64)
static Player * GetPlayer(WorldObject const &, uint64 guid)
static Unit * GetUnit(WorldObject const &, uint64 guid)
static Player * FindPlayer(uint64)
void ApplyModSignedFloatValue(uint16 index, float val, bool apply)
Definition Object.cpp:1238
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:343
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition Object.cpp:1158
uint16 m_objectType
Definition Object.h:242
ObjectGuid GetObjectGUID() const
Definition Object.h:123
int32 GetInt32Value(uint16 index) const
Definition Object.cpp:319
void SetInt32Value(uint16 index, int32 value)
Definition Object.cpp:1021
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
uint32 GetGUIDLow() const
Definition Object.h:120
void RemoveFieldNotifyFlag(uint16 flag)
Definition Object.h:199
UpdateMask _changesMask
Definition Object.h:254
TypeID GetTypeId() const
Definition Object.h:131
uint32 * m_uint32Values
Definition Object.h:250
bool RemoveUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1119
uint16 m_valuesCount
Definition Object.h:256
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
float GetFloatValue(uint16 index) const
Definition Object.cpp:337
void BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer *data, Player *target) const
Definition Object.cpp:832
uint16 m_fieldNotifyFlags
Definition Object.h:258
const ByteBuffer & GetPackGUID() const
Definition Object.h:124
uint32 GetEntry() const
Definition Object.h:125
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition Object.cpp:270
Creature * ToCreature()
Definition Object.h:207
void SetFloatValue(uint16 index, float value)
Definition Object.cpp:1141
virtual void AddToWorld()
Definition Object.cpp:148
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:1345
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
float * m_floatValues
Definition Object.h:251
void SetFieldNotifyFlag(uint16 flag)
Definition Object.h:198
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
uint16 m_updateFlag
Definition Object.h:245
TypeID m_objectTypeId
Definition Object.h:244
void ApplyPercentModFloatValue(uint16 index, float val, bool apply)
Definition Object.cpp:1245
void SetUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1079
bool AddUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1097
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:1322
Definition PetAI.h:16
uint32 GetAura(uint32 petEntry) const
Definition SpellMgr.h:443
Definition Pet.h:28
bool CreateBaseAtCreatureInfo(CreatureTemplate const *cinfo, Unit *owner)
Definition Pet.cpp:788
bool CreateBaseAtCreature(Creature *creature)
Definition Pet.cpp:755
bool isControlled() const
Definition Pet.cpp:2135
void InitPetCreateSpells()
Definition Pet.cpp:1668
void setFactionForRace(uint8 race)
Definition Player.cpp:7090
void SendAttackSwingCancelAttack()
Definition Player.cpp:15465
bool IsInSameRaidWith(Player const *p) const
Definition Player.cpp:3030
void SendRemoveControlBar()
Definition Player.cpp:16204
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2993
void DuelComplete(DuelCompleteType type)
Definition Player.cpp:8277
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:6563
void SendAutoRepeatCancel(Unit *target)
Definition Player.cpp:15471
uint8 m_forced_speed_changes[MAX_MOVE_TYPE]
Definition Player.h:2874
void SendDirectMessage(WorldPacket *data)
Definition Player.cpp:6904
void CharmSpellInitialize()
Definition Player.cpp:16142
void ClearComboPoints()
Definition Player.cpp:18488
bool HaveAtClient(WorldObject const *u) const
Definition Player.cpp:18066
void UpdatePvPState(bool onlyFFA=false)
Definition Player.cpp:17441
Unit * m_mover
Definition Player.h:2807
bool InBattleground() const
Definition Player.h:2692
void PetSpellInitialize()
Definition Player.cpp:15884
uint32 GetBaseSpellPowerBonus() const
Returns base spellpower bonus from spellpower stat on items, without spellpower from intellect stat.
Definition Player.h:2364
void SetFallInformation(uint32 time, float z)
Definition Player.cpp:20943
Pet * GetPet() const
Definition Player.cpp:15640
uint32 GetResurrectionSpellId()
Definition Player.cpp:19654
WorldSession * GetSession() const
Definition Player.h:2417
OutdoorPvP * GetOutdoorPvP() const
Definition Player.cpp:19552
void SetViewpoint(WorldObject *target, bool apply)
Definition Player.cpp:20275
static uint32 TeamForRace(uint8 race)
Definition Player.cpp:7072
void RewardPlayerAndGroupAtKill(Unit *victim, bool isBattleGround)
Definition Player.cpp:19757
void StopCastingCharm()
Definition Player.cpp:15768
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=NULL, bool infinityCooldown=false)
Definition Player.cpp:17511
Battleground * GetBattleground() const
Definition Player.cpp:19212
void SetClientControl(Unit *target, uint8 allowMove)
Definition Player.cpp:19853
Group * GetGroup()
Definition Player.h:2972
bool IsGameMaster() const
Definition Player.h:1369
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, Unit *unit=NULL)
Definition Player.cpp:21033
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:2090
void ToggleAFK()
Definition Player.cpp:2060
void PossessSpellInitialize()
Definition Player.cpp:15991
void StopCastingBindSight()
Definition Player.cpp:20262
void SendMessageToSet(WorldPacket *data, bool self) override
Definition Player.h:2443
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=NULL, bool setCooldown=true)
Definition Player.cpp:17720
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
uint8 GetSubGroup() const
Definition Player.h:2985
bool isAFK() const
Definition Player.h:1333
void VehicleSpellInitialize()
Definition Player.cpp:16039
bool isAllowedToLoot(const Creature *creature)
Definition Player.cpp:12883
void ResummonPetTemporaryUnSummonedIfAny()
Definition Player.cpp:21128
uint64 GetComboTarget() const
Definition Player.h:1983
bool CanSeeSpellClickOn(Creature const *creature) const
Definition Player.cpp:21165
void SetMover(Unit *target)
Definition Player.cpp:19869
DuelInfo * duel
Definition Player.h:2253
bool IsInSameGroupWith(Player const *p) const
Definition Player.cpp:3023
ReputationMgr & GetReputationMgr()
Definition Player.h:2555
DamageInfo * _damageInfo
Definition Unit.h:997
HealInfo * _healInfo
Definition Unit.h:998
ProcEventInfo(Unit *actor, Unit *actionTarget, Unit *procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell *spell, DamageInfo *damageInfo, HealInfo *healInfo)
Definition Unit.cpp:126
Unit *const _actionTarget
Definition Unit.h:990
uint32 _hitMask
Definition Unit.h:995
uint32 _spellTypeMask
Definition Unit.h:993
Unit *const _actor
Definition Unit.h:989
Spell * _spell
Definition Unit.h:996
uint32 _typeMask
Definition Unit.h:992
uint32 _spellPhaseMask
Definition Unit.h:994
Unit *const _procTarget
Definition Unit.h:991
FROM * GetSource() const
Definition Reference.h:83
FactionState const * GetState(FactionEntry const *factionEntry) const
bool IsAtWar(uint32 faction_id) const
ReputationRank const * GetForcedRankIfAny(FactionTemplateEntry const *factionTemplateEntry) const
Mechanics Mechanic
Definition SpellInfo.h:101
uint32 TriggerSpell
Definition SpellInfo.h:108
bool IsEffect() const
Definition SpellInfo.cpp:59
bool IsTargetingArea() const
Definition SpellInfo.cpp:79
uint32 ApplyAuraName
Definition SpellInfo.h:90
int32 CalcValue(Unit const *caster=NULL, int32 const *basePoints=NULL, Unit const *target=NULL) const
Definition Spell.h:289
SpellInfo const * GetSpellInfo() const
Definition Spell.h:565
bool IsInterruptable() const
Definition Spell.h:553
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5023
void prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=NULL)
Definition Spell.cpp:2939
int32 GetCastTime() const
Definition Spell.h:542
uint32 getState() const
Definition Spell.h:494
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7251
void cancel()
Definition Spell.cpp:3210
Spell ** m_selfContainer
Definition Spell.h:589
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:552
void finish(bool ok=true)
Definition Spell.cpp:3762
SpellEffectInfo Effects[MAX_SPELL_EFFECTS]
Definition SpellInfo.h:255
uint32 SpellLevel
Definition SpellInfo.h:206
uint32 GetMaxTicks() const
uint32 SpellVisual[2]
Definition SpellInfo.h:219
SpellInfo const * GetFirstRankSpell() const
bool IsAutocastable() const
uint32 GetCategory() const
uint32 AttributesCu
Definition SpellInfo.h:178
uint32 AttributesEx8
Definition SpellInfo.h:172
bool IsCooldownStartedOnEvent() const
bool IsPassive() const
uint32 CalcCastTime(uint8 level=0, Spell *spell=NULL) const
uint32 Mechanic
Definition SpellInfo.h:163
uint32 Id
Definition SpellInfo.h:160
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:209
uint32 GetDispelMask() const
SpellSpecificType GetSpellSpecific() const
uint32 Dispel
Definition SpellInfo.h:162
float GetMinRange(bool positive=false) const
int32 GetMaxDuration() const
bool CanPierceImmuneAura(SpellInfo const *aura) const
uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const
flag128 SpellFamilyFlags
Definition SpellInfo.h:227
float GetMaxRange(bool positive=false, Unit *caster=NULL, Spell *spell=NULL) const
bool IsAllowingDeadTarget() const
uint32 AttributesEx3
Definition SpellInfo.h:167
Mechanics GetEffectMechanic(uint8 effIndex) const
SpellSchoolMask GetSchoolMask() const
bool IsChanneled() const
uint32 Attributes
Definition SpellInfo.h:164
uint32 AttributesEx
Definition SpellInfo.h:165
int32 GetDuration() const
uint32 AttributesEx6
Definition SpellInfo.h:170
uint32 SpellIconID
Definition SpellInfo.h:220
bool NeedsExplicitUnitTarget() const
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
bool IsAffectingArea() const
bool IsPositive() const
uint32 AttributesEx2
Definition SpellInfo.h:166
uint32 DmgClass
Definition SpellInfo.h:228
uint32 StartRecoveryCategory
Definition SpellInfo.h:196
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=NULL) const
uint32 SpellFamilyName
Definition SpellInfo.h:226
bool IsPositiveEffect(uint8 effIndex) const
virtual void UnSummon(uint32 msTime=0)
const SummonPropertiesEntry *const m_Properties
std::list< HostileReference * > StorageType
ThreatContainer::StorageType const & getThreatList() const
ThreatContainer::StorageType const & getOfflineThreatList() const
Unit * GetOwner() const
size_type size() const
Definition Util.h:46
StorageType::const_iterator const_iterator
Definition Util.h:35
const_iterator begin() const
Definition Util.h:43
uint32 GetSpell(uint8 slot=0) const
Definition Totem.h:27
void RemovePassenger(WorldObject *passenger)
virtual void HealReceived(Unit *, uint32 &)
Definition UnitAI.h:219
virtual void HealDone(Unit *, uint32 &)
Definition UnitAI.h:222
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:16
Definition Unit.h:1367
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition Unit.cpp:8234
int32 ModifyHealth(int32 val)
Definition Unit.cpp:4023
void ApplyResilience(Unit const *victim, int32 *damage, bool isCrit) const
Definition Unit.cpp:7395
uint32 m_reactiveTimer[MAX_REACTIVE]
Definition Unit.h:2927
void ClearUnitState(uint32 f)
Definition Unit.h:1489
void OutDebugInfo() const
Definition Unit.cpp:8989
bool IsStopped() const
Definition Unit.h:2614
void _EnterVehicle(Vehicle *vehicle, int8 seatId, AuraApplication const *aurApp=NULL)
Definition Unit.cpp:8239
bool IsVehicle() const
Definition Unit.h:1523
uint64 LastCharmerGUID
Definition Unit.h:2736
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:2432
void CastStop(uint32 except_spellid=0)
bool _IsValidAssistTarget(Unit const *target, SpellInfo const *bySpell) const
Definition Unit.cpp:3936
bool IsCharmed() const
Definition Unit.h:2136
bool m_duringRemoveFromWorld
Definition Unit.h:2984
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Vehicle * GetVehicle() const
Definition Unit.h:2743
void SetVisible(bool x)
Definition Unit.cpp:4163
bool HealthAbovePct(int32 pct) const
Definition Unit.h:1621
void DeleteCharmInfo()
Definition Unit.cpp:5526
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:1689
bool isTargetableForAttack(bool checkFakeDeath=true) const
Definition Unit.cpp:3795
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:2243
uint32 GetSchoolImmunityMask() const
Definition Unit.cpp:3560
Spell * m_currentSpells[CURRENT_MAX_SPELL]
Definition Unit.h:2895
uint8 getGender() const
Definition Unit.h:1551
uint32 m_lastSanctuaryTime
Definition Unit.h:2446
uint32 GetMechanicImmunityMask() const
Definition Unit.cpp:3570
virtual void UpdateDamagePhysical(WeaponAttackType attType)=0
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:4837
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=NULL, Unit const *Caster=NULL) const
void setFaction(uint32 faction)
Definition Unit.h:1699
Unit * GetCharm() const
Definition Unit.cpp:2405
void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply)
Definition Unit.cpp:1584
void GetRandomContactPoint(const Unit *target, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const
Definition Unit.cpp:479
AuraList m_removedAuras
Definition Unit.h:2901
uint32 SpellCriticalDamageBonus(SpellInfo const *spellProto, uint32 damage, Unit *victim)
Definition Unit.cpp:3316
void SetResistanceBuffMods(SpellSchools school, bool positive, float val)
Definition Unit.cpp:1574
uint32 GetUnitMovementFlags() const
Definition Unit.h:2632
LiquidTypeEntry const * _lastLiquid
Definition Unit.h:2936
bool HasAuraTypeWithCaster(AuraType auratype, uint64 caster) const
void RemovePetAura(PetAura const *petSpell)
Definition Unit.cpp:6245
AuraApplication * GetVisibleAura(uint8 slot) const
Definition Unit.cpp:492
void _UpdateAutoRepeatSpell()
Definition Unit.cpp:1251
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=NULL) const
Definition Unit.cpp:4709
void SendMoveKnockBack(Player *player, float speedXY, float speedZ, float vcos, float vsin)
Definition Unit.cpp:7580
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:4863
Unit * SelectNearbyTarget(Unit *exclude=NULL, float dist=NOMINAL_MELEE_RANGE) const
Definition Unit.cpp:6043
uint32 m_transform
Definition Unit.h:2893
void SetFacingTo(float ori)
Definition Unit.cpp:9114
void Kill(Unit *victim, bool durabilityLoss=true)
Definition Unit.cpp:6342
void RemoveAllControlled()
Definition Unit.cpp:2783
Unit * GetOwner() const
Definition Unit.cpp:2339
Pet * ToPet()
Definition Unit.h:2803
Player * m_movedPlayer
Definition Unit.h:2156
bool CanHaveThreatList() const
Definition Unit.cpp:4424
uint64 GetCharmGUID() const
Definition Unit.h:2079
float GetTotalStatValue(Stats stat) const
Definition Unit.cpp:5041
void CombatStop(bool includingCast=false)
void TrackGameObject(GameObject *gameObj)
Definition Unit.cpp:1663
void ClearPhases(bool update=false)
Definition Unit.cpp:7511
void PlayOneShotAnimKit(uint32 id)
Definition Unit.cpp:6328
virtual void SetTarget(uint64)=0
void SendMeleeAttackStop(Unit *victim=NULL)
Definition Unit.cpp:647
ReputationRank GetReactionTo(Unit const *target) const
Definition Unit.cpp:2140
uint32 m_CombatTimer
Definition Unit.h:2970
bool IsContestedGuard() const
Definition Unit.cpp:7309
bool IsValidAttackTarget(Unit const *target) const
Definition Unit.cpp:3810
bool isSpellBlocked(Unit *victim, SpellInfo const *spellProto, WeaponAttackType attackType=WeaponAttackType::BASE_ATTACK)
Definition Unit.cpp:696
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:4313
bool SetFall(bool enable)
Definition Unit.cpp:9185
void _UnregisterDynObject(DynamicObject *dynObj)
Definition Unit.cpp:1613
bool m_canModifyStats
Definition Unit.h:2913
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
void UpdateObjectVisibility(bool forced=true) override
Definition Unit.cpp:7567
uint32 getFaction() const
Definition Unit.h:1695
void SetFullHealth()
Definition Unit.h:1644
uint32 GetRemainingPeriodicAmount(uint64 caster, uint32 spellId, AuraType auraType, uint8 effectIndex=0) const
Definition Unit.cpp:9031
bool HasVisionObscured(Unit const *target) const
Definition Unit.cpp:523
Diminishing m_Diminishing
Definition Unit.h:2973
void SendClearThreatListOpcode(ObjectGuid UnitGUID)
Definition Unit.cpp:8875
void UpdateHeight(float newZ)
Only server-side height update, does not broadcast to client.
Definition Unit.cpp:8749
bool isBlockCritical()
Definition Unit.cpp:715
bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:1402
ComboPointHolderSet m_ComboPointHolders
Definition Unit.h:2979
void SetConfused(bool apply)
Definition Unit.cpp:6856
void _UpdateSpells(uint32 time)
Definition Unit.cpp:1195
Unit * GetCharmerOrOwnerOrSelf() const
Definition Unit.cpp:2424
void SetAnimTier(AnimTier tier)
Definition Unit.cpp:5917
void AddToWorld() override
Definition Unit.cpp:5400
bool SetPhased(uint32 id, bool update, bool apply) OVERRIDE
Definition Unit.cpp:7516
void RestoreFaction()
Definition Unit.cpp:7135
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:2117
bool NeedChangeAI
Definition Unit.h:2735
SpellMissInfo MeleeSpellHitResult(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:760
void SetControlled(bool apply, UnitState state)
Definition Unit.cpp:6669
SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const
Definition Unit.cpp:5057
SpellMissInfo MagicSpellHitResult(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:934
void SetStunned(bool apply)
Definition Unit.cpp:6761
uint32 GetModelForForm(ShapeshiftForm form) const
Definition Unit.cpp:7638
Stats GetStatByAuraGroup(UnitMods unitMod) const
Definition Unit.cpp:5077
uint32 m_regenTimer
Definition Unit.h:2928
uint32 m_state
Definition Unit.h:2969
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]
Definition Unit.h:2911
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
uint32 GetResistance(SpellSchools school) const
Definition Unit.h:1590
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0)
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:6235
float m_modAttackSpeedPct[3]
Definition Unit.h:2393
void SetPower(Powers power, int32 val)
Definition Unit.cpp:5255
void SendPetActionFeedback(uint8 msg) const
-------—Pet responses methods--------------—
Definition Unit.cpp:5833
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Player * GetSpellModOwner() const
Definition Unit.cpp:5818
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition Unit.cpp:1448
Vehicle * m_vehicle
Definition Unit.h:2932
Totem * ToTotem()
Definition Unit.h:2812
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:1927
Creature * GetVehicleCreatureBase() const
Definition Unit.cpp:7208
void RemoveVehicleKit(bool remove=false)
Definition Unit.cpp:7179
uint32 m_overrideAutoattackRange
Definition Unit.h:2897
void RemoveAllGameObjects()
Definition Unit.cpp:1753
uint64 GetCharmerOrOwnerGUID() const
Definition Unit.cpp:5806
bool isPossessedByPlayer() const
Definition Unit.cpp:2808
void SendClearTarget()
Definition Unit.cpp:9046
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:1376
void ApplyStatBuffMod(Stats stat, float val, bool apply)
Definition Unit.cpp:1597
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:4886
void _RegisterDynObject(DynamicObject *dynObj)
Definition Unit.cpp:1608
bool isInFrontInMap(Unit const *target, float distance, float arc=M_PI) const
Definition Unit.cpp:1463
bool IsPolymorphed() const
Definition Unit.cpp:5928
bool isFrozen() const
Definition Unit.cpp:5796
float GetUnitDodgeChance() const
Definition Unit.cpp:1063
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:2377
void SetPvP(bool state)
Definition Unit.cpp:7317
float ApplyTotalThreatModifier(float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:4451
void WriteMovementInfo(WorldPacket &data, Movement::ExtraMovementStatusElement *extras=NULL)
Definition Unit.cpp:8407
void RemoveNotOwnSingleTargetAuras(uint32 newPhase=0, bool phaseid=false)
float CalculateDefaultCoefficient(SpellInfo const *spellInfo, DamageEffectType damagetype) const
Definition Unit.cpp:6213
float GetCombatRatingReduction(CombatRating cr) const
Definition Unit.cpp:7620
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=NULL)
Definition Unit.cpp:4463
bool isSpellCrit(Unit *victim, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType=WeaponAttackType::BASE_ATTACK) const
Definition Unit.cpp:3111
virtual void UpdateAttackPowerAndDamage(bool ranged=false)=0
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:2355
void SetCreatorGUID(uint64 creator)
Definition Unit.h:2059
uint32 SpellCriticalHealingBonus(SpellInfo const *spellProto, uint32 damage, Unit *victim)
Definition Unit.cpp:3353
Unit * GetCharmer() const
Definition Unit.cpp:2348
void GetAttackableUnitListInRange(std::list< Unit * > &list, float fMaxSearchRange) const
Definition Unit.cpp:8973
float GetPositionZMinusOffset() const
Definition Unit.cpp:6660
Unit * getAttackerForHelper() const
void SendMeleeAttackStart(Unit *victim)
Definition Unit.cpp:603
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:6255
bool IsHostileToPlayers() const
Definition Unit.cpp:2288
UnitAI * i_AI
Definition Unit.h:2867
bool IsInDisallowedMountForm() const
Definition Unit.cpp:4942
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition Unit.cpp:1956
float m_weaponDamage[uint8(WeaponAttackType::MAX_ATTACK)][2]
Definition Unit.h:2912
void SendAttackStateUpdate(CalcDamageInfo *damageInfo)
Definition Unit.cpp:1985
CharmInfo * m_charmInfo
Definition Unit.h:2918
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:1433
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:1618
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:4714
virtual bool CanFly() const =0
Unit * GetVehicleBase() const
Definition Unit.cpp:7203
bool haveOffhandWeapon() const
Definition Unit.cpp:350
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
uint64 GetPetGUID() const
Definition Unit.h:2087
bool IsPet() const
Definition Unit.h:1511
void RemoveVisibleAura(uint8 slot)
Definition Unit.cpp:506
void Dismount()
Definition Unit.cpp:3685
void SetCharm(Unit *target, bool apply)
Definition Unit.cpp:2617
void SendTeleportPacket(Position &pos)
Definition Unit.cpp:8670
void SendHealSpellLog(ObjectGuid CasterGUID, ObjectGuid TargetGUID, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical=false)
Definition Unit.cpp:2925
uint8 getLevelForTarget(WorldObject const *) const override
Definition Unit.h:1532
bool SetCharmedBy(Unit *charmer, CharmType type, AuraApplication const *aurApp=NULL)
Definition Unit.cpp:6878
uint64 m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2374
void UpdateInterruptMask()
Definition Unit.cpp:512
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Unit.cpp:5479
uint32 GetMaxHealth() const
Definition Unit.h:1604
void TauntApply(Unit *victim)
Definition Unit.cpp:4481
uint64 m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition Unit.h:2375
virtual void UpdateResistances(uint32 school)=0
void SetFacingToObject(WorldObject *object)
Definition Unit.cpp:9124
void UpdateSplineMovement(uint32 t_diff)
Definition Unit.cpp:366
bool IsLevitating() const
Definition Unit.h:2003
uint32 GetDamageReduction(uint32 damage) const
Definition Unit.h:1792
bool CanFreeMove() const
Definition Unit.cpp:5144
uint8 getClass() const
Definition Unit.h:1543
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:4736
float m_createStats[MAX_STATS]
Definition Unit.h:2878
bool HasAuraWithMechanic(uint32 mechanicMask) const
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:4681
bool IsSplineEnabled() const
Definition Unit.cpp:9355
int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
void UpdateReactives(uint32 p_time)
Definition Unit.cpp:6007
bool IsAlive() const
Definition Unit.h:2032
float m_modRangedHitChance
Definition Unit.h:2388
bool IsOnVehicle(const Unit *vehicle) const
Definition Unit.cpp:7198
void ApplyStatPercentBuffMod(Stats stat, float val, bool apply)
Definition Unit.cpp:1602
DeathState m_deathState
Definition Unit.h:2883
void SetClass(uint8 newClass)
Definition Unit.h:1564
void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply)
Definition Unit.cpp:6074
void NearTeleportTo(float x, float y, float z, float orientation, bool casting=false)
Definition Unit.cpp:8393
int32 GetMaxPower(Powers power) const
Definition Unit.cpp:5246
uint32 m_unitTypeMask
Definition Unit.h:2935
void StopMoving()
-------—End of Pet responses methods-------—
Definition Unit.cpp:5877
uint32 GetUnitMeleeSkill(Unit const *target=NULL) const
Definition Unit.cpp:1058
void AddPlayerToVision(Player *player)
Definition Unit.cpp:2878
uint64 GetMinionGUID() const
Definition Unit.h:2063
GameObject * GetGameObject(uint32 spellId) const
Definition Unit.cpp:1654
bool IsWithinCombatRange(const Unit *obj, float dist2compare) const
Definition Unit.cpp:447
virtual ~Unit()
Definition Unit.cpp:266
uint32 m_removedAurasCount
Definition Unit.h:2903
void RemoveAllAurasOnDeath()
uint32 m_movementCounter
Incrementing counter used in movement packets.
Definition Unit.h:2966
void SetHealth(uint32 val)
Definition Unit.cpp:5162
bool IsStandState() const
Definition Unit.cpp:5896
TempSummon * ToTempSummon()
Definition Unit.h:2821
CharmInfo * GetCharmInfo()
Definition Unit.h:2148
ControlList m_Controlled
Definition Unit.h:2132
void DisableSpline()
Definition Unit.cpp:430
int32 GetMechanicResistChance(SpellInfo const *spellInfo) const
Definition Unit.cpp:722
AuraMap::iterator m_auraUpdateIterator
Definition Unit.h:2902
bool m_AutoRepeatFirstCast
Definition Unit.h:2874
void TauntFadeOut(Unit *taunter)
Definition Unit.cpp:4509
void _DeleteRemovedAuras()
int32 ModifyPower(Powers power, int32 val)
Definition Unit.cpp:4081
Unit * GetNextRandomRaidMemberOrPet(float radius)
Definition Unit.cpp:2826
Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const
Definition Unit.cpp:5096
int32 HealBySpell(Unit *victim, SpellInfo const *spellInfo, uint32 addHealth, bool critical=false)
Definition Unit.cpp:2963
bool IsNeutralToAll() const
Definition Unit.cpp:2301
uint32 m_extraAttacks
Definition Unit.h:1453
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
uint64 GetCharmerGUID() const
Definition Unit.h:2071
virtual bool HasSpell(uint32) const
Definition Unit.h:1910
float GetUnitMissChance(WeaponAttackType attType) const
Definition Unit.cpp:1114
void AddUnitState(uint32 f)
Definition Unit.h:1481
uint32 GetCritDamageReduction(uint32 damage) const
Definition Unit.h:1788
void ClearComboPointHolders()
Definition Unit.cpp:5980
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition Unit.cpp:3635
void SendSpellDamageResist(Unit *target, uint32 spellId)
Definition Unit.cpp:1946
bool isInAccessiblePlaceFor(Creature const *c) const
Definition Unit.cpp:1473
int32 GetMinPower(Powers power) const
Definition Unit.h:1662
int32 DealHeal(Unit *victim, uint32 addhealth)
Definition Unit.cpp:2687
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=NULL) const
Definition Unit.cpp:3816
uint32 getAttackTimer(WeaponAttackType type) const
Definition Unit.h:1428
uint32 BuildAuraStateUpdateForTarget(Unit *target) const
Unit * GetRedirectThreatTarget()
Definition Unit.cpp:7158
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:4877
void _ExitVehicle(Position const *exitPosition=NULL)
Definition Unit.cpp:8325
ThreatManager m_ThreatManager
Definition Unit.h:2930
bool m_ControlledByPlayer
Definition Unit.h:2758
void SetFeared(bool apply)
Definition Unit.cpp:6816
Unit * GetCharmerOrOwner() const
Definition Unit.cpp:2419
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=NULL)
Definition Unit.cpp:2751
MotionMaster i_motionMaster
Definition Unit.h:2925
int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.cpp:744
void propagateSpeedChange()
-------—End of Pet responses methods-------—
Definition Unit.h:2683
bool SetHover(bool enable, bool packetOnly=false)
Definition Unit.cpp:9287
uint32 GetCreatureType() const
Definition Unit.cpp:4910
void SetOwnerGUID(uint64 owner)
Definition Unit.cpp:2314
float GetMeleeReach() const
Definition Unit.cpp:441
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:1671
bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply)
Definition Unit.cpp:4955
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:1289
void SendSetVehicleRecId(uint32 vehicleId)
Definition Unit.cpp:9540
bool SetSwim(bool enable)
Definition Unit.cpp:9201
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo) const
Definition Unit.cpp:3456
bool isAttackReady(WeaponAttackType type=WeaponAttackType::BASE_ATTACK) const
Definition Unit.h:1432
float GetCombatReach() const
Definition Unit.h:1445
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Definition Unit.cpp:8701
DynObjectList m_dynObj
Definition Unit.h:2888
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:4055
void EnergizeBySpell(Unit *victim, uint32 SpellID, int32 Damage, Powers powertype)
Definition Unit.cpp:3045
AuraApplicationList m_interruptableAuras
Definition Unit.h:2907
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2445
void ModifyAuraState(AuraStateType flag, bool apply)
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const
Definition Unit.cpp:567
bool isInBackInMap(Unit const *target, float distance, float arc=M_PI) const
Definition Unit.cpp:1468
void SetCritterGUID(uint64 guid)
Definition Unit.h:2091
bool isPossessing() const
Definition Unit.cpp:2818
uint32 GetNativeDisplayId() const
Definition Unit.h:2495
uint64 GetTransGUID() const override
Definition Unit.cpp:7217
virtual void UpdateArmor()=0
bool HealthBelowPct(int32 pct) const
Definition Unit.h:1613
void UpdateCharmAI()
Definition Unit.cpp:5491
void ClearAllReactives()
Definition Unit.cpp:5994
EventProcessor m_Events
Definition Unit.h:2396
void SetRooted(bool apply, bool packetOnly=false)
Definition Unit.cpp:6794
void AddUnitMovementFlag(uint32 f)
Definition Unit.h:2620
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition Unit.cpp:5027
float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const
Definition Unit.cpp:5136
void UpdateAuraForGroup(uint8 slot)
int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const
Definition Unit.cpp:3099
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition Unit.cpp:8139
bool SetCanFly(bool enable)
Definition Unit.cpp:9219
HostileRefManager m_HostileRefManager
Definition Unit.h:2975
void CalcHealAbsorb(Unit *victim, SpellInfo const *spellInfo, uint32 &healAmount, uint32 &absorb)
bool isPossessed() const
Definition Unit.h:2140
void SendRemoveFromThreatListOpcode(HostileReference *pHostileReference)
Definition Unit.cpp:8883
int32 m_baseSpellCritChance
Definition Unit.h:2390
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:2628
virtual void UpdateMaxPower(Powers power)=0
AttackerSet m_attackers
Definition Unit.h:2880
bool IsSummon() const
Definition Unit.h:1503
void SendPetTalk(uint32 pettalk) const
Definition Unit.cpp:5844
virtual bool IsInWater() const
Definition Unit.cpp:1481
uint32 GetHealth() const
Definition Unit.h:1600
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle).
Definition Unit.cpp:7227
void RewardRage(uint32 baseRage, bool attacker)
Definition Unit.cpp:8914
uint32 GetModelForTotem(uint32 totemType) const
Definition Unit.cpp:7989
void RemoveDynObject(uint32 spellId)
Definition Unit.cpp:1631
void DeleteThreatList()
Definition Unit.cpp:4472
Unit * m_attacking
Definition Unit.h:2881
AttackerSet const & getAttackers() const
Definition Unit.h:1463
uint32 GetPowerIndex(uint32 powerType) const
Definition Unit.cpp:5346
bool SetFeatherFall(bool enable, bool packetOnly=false)
Definition Unit.cpp:9266
float GetTotalAuraMultiplier(AuraType auratype) const
bool IsVisible() const
Definition Unit.cpp:4158
bool HasAuraType(AuraType auraType) const
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
bool isMoving() const
Definition Unit.h:2771
bool SetWalk(bool enable)
Definition Unit.cpp:9137
int32 GetMaxPositiveAuraModifier(AuraType auratype) const
void SetVisibleAura(uint8 slot, AuraApplication *aur)
Definition Unit.cpp:500
void setAttackTimer(WeaponAttackType type, uint32 time)
Definition Unit.h:1423
virtual bool UpdateStats(Stats stat)=0
void RemoveAllDynObjects()
Definition Unit.cpp:1648
float m_modMeleeHitChance
Definition Unit.h:2387
void SetPhaseMask(uint32 newPhaseMask, bool update) override
Definition Unit.cpp:7454
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.cpp:4122
time_t GetLastDamagedTime() const
Definition Unit.h:2840
uint16 GetExtraUnitMovementFlags() const
Definition Unit.h:2653
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:2729
void StopAttackFaction(uint32 faction_id)
Definition Unit.cpp:8939
uint32 GetCastingTimeForBonus(SpellInfo const *spellProto, DamageEffectType damagetype, uint32 CastingTime) const
Definition Unit.cpp:6120
bool IsWithinMeleeRange(const Unit *obj, float dist=MELEE_RANGE) const
Definition Unit.cpp:463
void RemoveAreaAurasDueToLeaveWorld()
bool CanModifyStats() const
Definition Unit.h:2410
uint16 HasExtraUnitMovementFlag(uint16 f) const
Definition Unit.h:2649
void RemoveCharmedBy(Unit *charmer)
Definition Unit.cpp:7029
bool IsMounted() const
Definition Unit.h:1742
HostileRefManager & getHostileRefManager()
Definition Unit.h:2466
int32 ModifyPowerPct(Powers power, float pct, bool apply=true)
Definition Unit.cpp:4114
void RemoveAurasByType(AuraType auraType, uint64 casterGUID=0, Aura *except=NULL, bool negative=true, bool positive=true)
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 casterGUID=0) const
float GetSpeedRate(UnitMoveType mtype) const
Definition Unit.h:2581
virtual void SetDisplayId(uint32 modelId)
Definition Unit.cpp:5941
std::set< Unit * > AttackerSet
Definition Unit.h:1369
void SendMissileCancel(uint32 spellId, bool cancel=true)
Definition Unit.cpp:9566
time_t _lastDamagedTime
Definition Unit.h:2988
void CleanupBeforeRemoveFromMap(bool finalCleanup)
Definition Unit.cpp:5453
uint8 getStandState() const
Definition Unit.h:1724
bool IsGuardian() const
Definition Unit.h:1507
Unit * GetVictim() const
Definition Unit.h:1468
int32 GetPower(Powers power) const
Definition Unit.cpp:5237
RedirectThreatInfo _redirectThreadInfo
Definition Unit.h:2981
Vehicle * m_vehicleKit
Definition Unit.h:2933
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:3365
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:1766
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:8741
virtual bool IsUnderWater() const
Definition Unit.cpp:1486
float GetUnitBlockChance() const
Definition Unit.cpp:1126
void RemovePlayerFromVision(Player *player)
Definition Unit.cpp:2889
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:3415
float GetCreateStat(Stats stat) const
Definition Unit.h:2343
void UpdateSplinePosition()
Definition Unit.cpp:382
DeathState getDeathState() const
Definition Unit.h:2044
Unit * GetFirstControlled() const
Definition Unit.cpp:2769
void SetSpeed(UnitMoveType mtype, float rate, bool forced=false)
Definition Unit.cpp:4318
bool IsAIEnabled
Definition Unit.h:2735
void ApplyCastTimePercentMod(float val, bool apply)
Definition Unit.cpp:6106
bool CreateVehicleKit(uint32 id, uint32 creatureEntry, bool loading=false)
Definition Unit.cpp:7163
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition Unit.cpp:3520
bool HasUnitState(const uint32 f) const
Definition Unit.h:1485
Player * GetAffectingPlayer() const
Definition Unit.cpp:2364
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
Definition Unit.cpp:3580
TimeTrackerSmall m_movesplineTimer
Definition Unit.h:2971
void FinishSpell(CurrentSpellTypes spellType, bool ok=true)
Definition Unit.cpp:1390
void resetAttackTimer(WeaponAttackType type=WeaponAttackType::BASE_ATTACK)
Definition Unit.cpp:436
bool m_isSorted
Definition Unit.h:2892
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:7253
void UnsummonAllTotems()
Definition Unit.cpp:2912
void CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
GameObjectList m_gameObj
Definition Unit.h:2891
AuraMap m_ownedAuras
Definition Unit.h:2899
Unit(bool isWorldObject)
Definition Unit.cpp:142
bool IsInFeralForm() const
Definition Unit.cpp:4936
int32 GetCreatePowers(Powers power) const
Definition Unit.cpp:5359
std::unique_ptr< Movement::MoveSpline > movespline
Definition Unit.h:2837
static ReputationRank GetFactionReactionTo(FactionTemplateEntry const *factionTemplateEntry, Unit const *target)
Definition Unit.cpp:2231
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:2283
void RemoveUnitMovementFlag(uint32 f)
Definition Unit.h:2624
void RemoveBindSightAuras()
Definition Unit.cpp:2899
ThreatManager & getThreatManager()
Definition Unit.h:2455
int32 GetMaxNegativeAuraModifier(AuraType auratype) const
AuraApplicationMap m_appliedAuras
Definition Unit.h:2900
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
CharmInfo * InitCharmInfo()
Definition Unit.cpp:5518
void RemoveFromWorld() override
Definition Unit.cpp:5409
void SendPlaySpellVisual(uint32 SpellVisualId, float x, float y, float z, float orientation, uint8 SpeedTime, uint16 MissReason, uint16 ReflectStatus)
Definition Unit.cpp:7325
uint32 m_attackTimer[uint8(WeaponAttackType::MAX_ATTACK)]
Definition Unit.h:2876
UnitAI * GetAI()
Definition Unit.h:1393
bool InitTamedPet(Pet *pet, uint8 level, uint32 spell_id) const
Definition Unit.cpp:6295
virtual void UpdateMaxHealth()=0
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:1495
void SendPeriodicAuraLog(SpellPeriodicAuraLogInfo *pInfo)
Definition Unit.cpp:1838
void ClearInCombat()
float GetResistanceBuffMods(SpellSchools school, bool positive) const
Definition Unit.cpp:1569
bool isDying() const
Definition Unit.h:2036
SpellInfo const * m_overrideAutoattackSpellInfo
Definition Unit.h:2896
float GetStat(Stats stat) const
Definition Unit.h:1573
void SendEnergizeSpellLog(Unit *victim, uint32 spellID, int32 damage, Powers powertype)
Definition Unit.cpp:2974
void UpdateSpeed(UnitMoveType mtype, bool forced)
Definition Unit.cpp:4173
void SendDurabilityLoss(Player *receiver, uint32 percent)
Definition Unit.cpp:6321
uint64 GetOwnerGUID() const
Definition Unit.h:2050
void RemoveAllAuras()
bool IsControlledByPlayer() const
Definition Unit.h:2100
void RestoreDisplayId()
Definition Unit.cpp:5946
float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const
bool m_canDualWield
Definition Unit.h:1454
int32 GetMaxNegativeAuraModifierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:1555
virtual SpellSchoolMask GetMeleeDamageSchoolMask() const
Definition Unit.cpp:5801
Minion * GetFirstMinion() const
Definition Unit.cpp:2375
bool HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition Unit.cpp:8160
bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura=0) const
Definition Unit.cpp:579
bool IsAlwaysVisibleFor(WorldObject const *seer) const override
Definition Unit.cpp:4128
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
uint32 getTransForm() const
Definition Unit.h:2508
void SetMaxPower(Powers power, int32 val)
Definition Unit.cpp:5317
float GetUnitParryChance() const
Definition Unit.cpp:1083
PetAuraSet m_petAuras
Definition Unit.h:2708
bool SetDisableGravity(bool disable, bool packetOnly=false)
Definition Unit.cpp:9156
Powers getPowerType() const
Definition Unit.h:1651
virtual void setDeathState(DeathState s)
Definition Unit.cpp:4365
void SetMaxHealth(uint32 val)
Definition Unit.cpp:5206
void GetPartyMembers(std::list< Unit * > &units)
Definition Unit.cpp:7272
uint32 m_interruptMask
Definition Unit.h:2909
uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const
Definition Unit.cpp:7632
int32 GetTotalAuraModifier(AuraType auratype) const
void SendChangeCurrentVictimOpcode(HostileReference *pHostileReference)
Definition Unit.cpp:8792
uint32 GetCreatureTypeMask() const
Definition Unit.cpp:4925
bool HasBreakableByDamageCrowdControlAura(Unit *excludeCasterChannel=NULL) const
Definition Unit.cpp:589
uint8 getLevel() const
Definition Unit.h:1528
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:2204
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:1383
void InitStatBuffMods()
Definition Unit.cpp:1589
int32 m_procDeep
Definition Unit.h:2885
void SetMinionGUID(uint64 guid)
Definition Unit.h:2067
void ClearDiminishings()
Definition Unit.h:1412
VisibleAuraMap m_visibleAuras
Definition Unit.h:2914
void SetLevel(uint8 lvl)
Definition Unit.cpp:5150
uint32 GetCreateMana() const
Definition Unit.h:2329
bool IsServiceProvider() const
Definition Unit.cpp:3786
MountCapabilityEntry const * GetMountCapability(uint32 mountType) const
Definition Unit.cpp:3728
bool IsTotem() const
Definition Unit.h:1519
void ChangeSeat(int8 seatId, bool next=true)
Definition Unit.cpp:8274
void SetInFront(WorldObject const *target)
Definition Unit.cpp:9108
void ApplySpellDispelImmunity(const SpellInfo *spellProto, DispelType type, bool apply)
Definition Unit.cpp:3611
int32 GetMaxPositiveAuraModifierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:1541
static Player * GetPlayer(WorldObject &object, uint64 guid)
Definition Unit.cpp:4900
float m_speed_rate[MAX_MOVE_TYPE]
Definition Unit.h:2916
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const
Definition Unit.cpp:3403
void setPowerType(Powers power)
Definition Unit.cpp:2079
void SetFieldPowerType(uint32 powerType)
Definition Unit.h:1655
float MeleeSpellMissChance(Unit const *victim, WeaponAttackType attType, uint32 spellId) const
Definition Unit.cpp:7421
bool IsAlwaysDetectableFor(WorldObject const *seer) const override
Definition Unit.cpp:4147
bool IsValidAssistTarget(Unit const *target) const
Definition Unit.cpp:3930
Vehicle * GetVehicleKit() const
Definition Unit.h:2739
void SendPlaySpellVisualKit(uint32 SpellVisualId, uint32 Duration, int32 Type)
Definition Unit.cpp:7377
float m_modSpellHitChance
Definition Unit.h:2389
Guardian * GetGuardianPet() const
Definition Unit.cpp:2390
uint64 GetCritterGUID() const
Definition Unit.h:2095
void SendThreatListUpdate()
Definition Unit.cpp:8756
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:2278
void ExitVehicle(Position const *exitPosition=NULL)
Definition Unit.cpp:8306
UnitAI * i_disabledAI
Definition Unit.h:2867
void SetStandState(uint8 state)
Definition Unit.cpp:5902
void DeMorph()
Definition Unit.cpp:1536
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:2604
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:3055
virtual void UpdateUnderwaterState(Map *m, float x, float y, float z)
Definition Unit.cpp:1491
bool IsFalling() const
Definition Unit.cpp:8388
bool AttackStop()
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition Unit.cpp:7597
int32 GetCurrentSpellCastTime(uint32 spell_id) const
Definition Unit.cpp:1456
uint64 GetCharmerOrOwnerOrOwnGUID() const
Definition Unit.cpp:5811
void SetShapeshiftForm(ShapeshiftForm form)
Definition Unit.cpp:4931
void GetAllMinionsByEntry(std::list< Creature * > &Minions, uint32 entry)
Definition Unit.cpp:2592
bool IsInPartyWith(Unit const *unit) const
Definition Unit.cpp:7234
void Update(uint32 time) OVERRIDE
Definition Unit.cpp:293
bool m_cleanupDone
Definition Unit.h:2983
void ProcDamageAndSpell(Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=WeaponAttackType::BASE_ATTACK, SpellInfo const *procSpell=NULL, SpellInfo const *procAura=NULL)
Definition UnitProc.cpp:53
SharedVisionList m_sharedVision
Definition Unit.h:2919
void SendPetAIReaction(ObjectGuid UnitGUID) const
Definition Unit.cpp:5858
void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply)
Definition Unit.cpp:1579
bool _isWalkingBeforeCharm
Definition Unit.h:2986
void RemoveCharmAuras()
Definition Unit.cpp:2904
bool IsInCombat() const
Definition Unit.h:1896
bool IsWalking() const
Definition Unit.h:2007
void ModSpellCastTime(SpellInfo const *spellProto, int32 &castTime, Spell *spell=NULL)
Definition Unit.cpp:4821
bool IsSitState() const
Definition Unit.cpp:5889
void SetPetGUID(uint64 guid)
Definition Unit.h:2083
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
Definition Unit.cpp:1365
float GetTotalAttackPowerValue(WeaponAttackType attType) const
Definition Unit.cpp:5118
float m_threatModifier[MAX_SPELL_SCHOOL]
Definition Unit.h:2392
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, Player *target) const override
Definition Unit.cpp:9361
bool SetWaterWalking(bool enable, bool packetOnly=false)
Definition Unit.cpp:9245
void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath=false, bool forceDestination=false)
Definition Unit.cpp:358
uint8 getRace() const
Definition Unit.h:1535
float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *victim) const
Definition Unit.cpp:1155
bool isDead() const
Definition Unit.h:2040
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:2363
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spellInfo, bool canReflect=false)
Definition Unit.cpp:1007
bool BuildPacket(WorldPacket *packet)
uint32 GetBlockCount() const
Definition UpdateMask.h:51
void SetCount(uint32 valuesCount)
Definition UpdateMask.h:54
void SetBit(uint32 index)
Definition UpdateMask.h:34
void AppendToPacket(ByteBuffer *data)
Definition UpdateMask.h:38
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:38
bool AddPassenger(Unit *passenger, int8 seatId=-1)
Attempts to add a passenger to the vehicle on 'seatId'.
Definition Vehicle.cpp:415
uint32 GetCreatureEntry() const
Definition Vehicle.h:40
void RelocatePassengers()
Relocate passengers. Must be called after m_base::Relocate.
Definition Vehicle.cpp:536
void InstallAllAccessories(bool evading)
Definition Vehicle.cpp:109
uint32 GetMapId() const
Definition Object.h:546
int8 GetTransSeat() const
Definition Object.h:803
bool IsPhased(WorldObject const *obj) const
Definition Object.cpp:3393
virtual void SetPhaseMask(uint32 newPhaseMask, bool update)
Definition Object.cpp:3219
uint32 GetPhaseMask() const
Definition Object.h:643
Map * GetMap() const
Definition Object.h:740
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
virtual void RemoveFromWorld()
Definition Object.cpp:1587
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1735
bool IsWithinLOSInMap(WorldObject const *obj) const
Definition Object.cpp:1656
virtual bool IsAlwaysDetectableFor(WorldObject const *) const
Definition Object.h:833
std::set< uint32 > const & GetPhases() const
Definition Object.h:647
void SetWorldObject(bool apply)
Definition Object.cpp:1523
void SetTransport(Transport *t)
Definition Object.h:805
void RebuildTerrainSwaps()
Definition Object.cpp:3227
virtual bool SetPhased(uint32 id, bool update, bool apply)
Definition Object.cpp:3353
float GetTransOffsetX() const
Definition Object.h:798
ZoneScript * GetZoneScript() const
Definition Object.h:748
uint32 GetInstanceId() const
Definition Object.h:638
void setActive(bool isActiveObject)
Definition Object.cpp:1542
float GetTransOffsetY() const
Definition Object.h:799
std::string const & GetName() const
Definition Object.h:664
float GetTransOffsetZ() const
Definition Object.h:800
virtual bool IsAlwaysVisibleFor(WorldObject const *) const
Definition Object.h:830
void VisitNearbyObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:782
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const
Definition Object.cpp:2945
bool InSamePhase(WorldObject const *obj) const
Definition Object.cpp:3412
WorldObject(bool isWorldObject)
Definition Object.cpp:1514
void GetContactPoint(WorldObject const *obj, float &x, float &y, float &z, float distance2d=CONTACT_DISTANCE) const
Definition Object.cpp:3094
uint32 GetTransTime() const
Definition Object.h:802
Transport * GetTransport() const
Definition Object.h:797
void UpdateAllowedPositionZ(float x, float y, float &z) const
Definition Object.cpp:1985
void ClearPhases(bool update=false)
Definition Object.cpp:3383
void AddToNotify(uint16 f)
Definition Object.h:769
Map const * GetBaseMap() const
Definition Object.cpp:2544
float GetVisibilityRange() const
Definition Object.cpp:2070
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1666
float GetTransOffsetO() const
Definition Object.h:801
uint32 GetZoneId() const
Definition Object.cpp:1597
MovementInfo m_movementInfo
Definition Object.h:807
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition Object.cpp:2485
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition Object.h:732
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:1607
bool CanSeeOrDetect(WorldObject const *obj, bool ignoreStealth=false, bool distanceCheck=false) const
Definition Object.cpp:2105
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:1703
virtual void UpdateObjectVisibility(bool forced=true)
Definition Object.cpp:3480
Opcodes GetOpcode() const
Definition WorldPacket.h:38
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
std::string GetOpcodeNameForLogging(Opcodes id, bool isServerOpcode, uint16 opcodeNumber=0)
Lookup opcode name for human understandable logging.
Definition Opcodes.h:1157
Opcodes
List of Opcodes.
Definition Opcodes.h:21
@ SMSG_MOVE_SET_FLIGHT_SPEED
Definition Opcodes.h:802
@ SMSG_MOVE_SET_FLIGHT_BACK_SPEED
Definition Opcodes.h:801
@ SMSG_MOVE_LAND_WALK
Definition Opcodes.h:792
@ SMSG_SPLINE_MOVE_STOP_SWIM
Definition Opcodes.h:1012
@ SMSG_PARTYKILLLOG
Definition Opcodes.h:843
@ SMSG_MOVE_UPDATE_PITCH_RATE
Definition Opcodes.h:823
@ SMSG_MOVE_ROOT
Definition Opcodes.h:795
@ SMSG_SET_VEHICLE_REC_ID
Definition Opcodes.h:965
@ SMSG_MOVE_FEATHER_FALL
Definition Opcodes.h:788
@ SMSG_MOVE_SET_HOVER
Definition Opcodes.h:803
@ SMSG_PLAY_SPELL_VISUAL
Definition Opcodes.h:884
@ SMSG_MOVE_SET_VEHICLE_REC_ID
Definition Opcodes.h:810
@ SMSG_MOVE_UNROOT
Definition Opcodes.h:813
@ SMSG_MOVE_SET_RUN_BACK_SPEED
Definition Opcodes.h:805
@ SMSG_SPLINE_MOVE_START_SWIM
Definition Opcodes.h:1011
@ SMSG_SPELLLOGMISS
Definition Opcodes.h:974
@ SMSG_SPLINE_MOVE_SET_RUN_MODE
Definition Opcodes.h:1003
@ SMSG_PET_ACTION_FEEDBACK
Definition Opcodes.h:852
@ SMSG_MOVE_WATER_WALK
Definition Opcodes.h:832
@ SMSG_SPLINE_MOVE_GRAVITY_DISABLE
Definition Opcodes.h:991
@ SMSG_SPLINE_MOVE_SET_RUN_SPEED
Definition Opcodes.h:1004
@ SMSG_SPELLORDAMAGE_IMMUNE
Definition Opcodes.h:975
@ SMSG_MOVE_UPDATE_TELEPORT
Definition Opcodes.h:829
@ SMSG_MISSILE_CANCEL
Definition Opcodes.h:783
@ SMSG_MOVE_KNOCK_BACK
Definition Opcodes.h:791
@ SMSG_SPLINE_MOVE_SET_PITCH_RATE
Definition Opcodes.h:1001
@ SMSG_PLAY_SPELL_VISUAL_KIT
Definition Opcodes.h:885
@ SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED
Definition Opcodes.h:996
@ SMSG_PROCRESIST
Definition Opcodes.h:889
@ SMSG_SPELL_NON_MELEE_DAMAGE_LOG
Definition Opcodes.h:987
@ SMSG_BREAK_TARGET
Definition Opcodes.h:569
@ SMSG_SPLINE_MOVE_SET_NORMAL_FALL
Definition Opcodes.h:1000
@ SMSG_MOVE_UPDATE_FLIGHT_SPEED
Definition Opcodes.h:821
@ SMSG_MOVE_SET_PITCH_RATE
Definition Opcodes.h:804
@ SMSG_SPELL_PERIODIC_AURA_LOG
Definition Opcodes.h:988
@ SMSG_MOVE_GRAVITY_DISABLE
Definition Opcodes.h:789
@ SMSG_ATTACKER_STATE_UPDATE
Definition Opcodes.h:519
@ SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED
Definition Opcodes.h:820
@ SMSG_LOOT_LIST
Definition Opcodes.h:768
@ SMSG_MOVE_UPDATE_WALK_SPEED
Definition Opcodes.h:831
@ SMSG_SPLINE_MOVE_SET_LAND_WALK
Definition Opcodes.h:999
@ SMSG_MOVE_GRAVITY_ENABLE
Definition Opcodes.h:790
@ SMSG_MOVE_UPDATE_SWIM_SPEED
Definition Opcodes.h:828
@ SMSG_SPELL_ENERGIZE_LOG
Definition Opcodes.h:981
@ SMSG_THREAT_UPDATE
Definition Opcodes.h:1028
@ SMSG_SPLINE_MOVE_SET_WALK_SPEED
Definition Opcodes.h:1009
@ SMSG_HIGHEST_THREAT_UPDATE
Definition Opcodes.h:717
@ SMSG_THREAT_CLEAR
Definition Opcodes.h:1026
@ SMSG_MOVE_NORMAL_FALL
Definition Opcodes.h:793
@ SMSG_PET_ACTION_SOUND
Definition Opcodes.h:853
@ SMSG_MOVE_UPDATE_TURN_RATE
Definition Opcodes.h:830
@ SMSG_SPLINE_MOVE_SET_HOVER
Definition Opcodes.h:998
@ SMSG_SPLINE_MOVE_SET_FLYING
Definition Opcodes.h:997
@ SMSG_MOVE_SET_TURN_RATE
Definition Opcodes.h:809
@ SMSG_SPLINE_MOVE_UNSET_HOVER
Definition Opcodes.h:1015
@ SMSG_SPLINE_MOVE_SET_TURN_RATE
Definition Opcodes.h:1007
@ SMSG_MOVE_SET_SWIM_SPEED
Definition Opcodes.h:808
@ SMSG_THREAT_REMOVE
Definition Opcodes.h:1027
@ SMSG_HEALTH_UPDATE
Definition Opcodes.h:716
@ SMSG_MOVE_UPDATE_RUN_SPEED
Definition Opcodes.h:826
@ SMSG_MOVE_SET_WALK_SPEED
Definition Opcodes.h:811
@ SMSG_SPLINE_MOVE_UNROOT
Definition Opcodes.h:1013
@ SMSG_ATTACKSTOP
Definition Opcodes.h:520
@ SMSG_MOVE_UNSET_HOVER
Definition Opcodes.h:817
@ SMSG_DISMOUNT
Definition Opcodes.h:637
@ SMSG_DURABILITY_DAMAGE_DEATH
Definition Opcodes.h:646
@ SMSG_MOVE_SET_CAN_FLY
Definition Opcodes.h:797
@ SMSG_ATTACK_START
Definition Opcodes.h:522
@ SMSG_SPLINE_MOVE_SET_WATER_WALK
Definition Opcodes.h:1010
@ SMSG_SPELL_HEAL_LOG
Definition Opcodes.h:986
@ SMSG_SPLINE_MOVE_SET_SWIM_SPEED
Definition Opcodes.h:1006
@ SMSG_SPLINE_MOVE_ROOT
Definition Opcodes.h:993
@ SMSG_MOVE_UPDATE_SWIM_BACK_SPEED
Definition Opcodes.h:827
@ SMSG_SPLINE_MOVE_SET_WALK_MODE
Definition Opcodes.h:1008
@ SMSG_SPLINE_MOVE_GRAVITY_ENABLE
Definition Opcodes.h:992
@ SMSG_SPLINE_MOVE_UNSET_FLYING
Definition Opcodes.h:1014
@ SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED
Definition Opcodes.h:1002
@ SMSG_AI_REACTION
Definition Opcodes.h:512
@ SMSG_MOVE_UNSET_CAN_FLY
Definition Opcodes.h:814
@ SMSG_MOVE_UPDATE_RUN_BACK_SPEED
Definition Opcodes.h:825
@ SMSG_MOVE_SET_SWIM_BACK_SPEED
Definition Opcodes.h:807
@ SMSG_STANDSTATE_UPDATE
Definition Opcodes.h:1017
@ SMSG_MOVE_SET_RUN_SPEED
Definition Opcodes.h:806
@ NULL_OPCODE
Definition Opcodes.h:22
@ SMSG_SPLINE_MOVE_SET_FEATHER_FALL
Definition Opcodes.h:994
@ SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED
Definition Opcodes.h:1005
@ SMSG_PLAY_ONE_SHOT_ANIM_KIT
Definition Opcodes.h:881
@ SMSG_POWER_UPDATE
Definition Opcodes.h:887
@ SMSG_MOVE_TELEPORT
Definition Opcodes.h:812
@ SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED
Definition Opcodes.h:995
#define sWorld
Definition World.h:910
@ CONFIG_CREATURE_FAMILY_FLEE_DELAY
Definition World.h:271
@ CONFIG_DURABILITY_LOSS_IN_PVP
Definition World.h:90
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition World.h:98
@ RATE_DURABILITY_LOSS_ON_DEATH
Definition World.h:434
@ RATE_POWER_RAGE_INCOME
Definition World.h:378
bool PrintInvalidSequenceElement(MovementStatusElements element, char const *function)
bool GetAttackStopVictimDeadBit(bool hasVictim, bool victimIsDead)
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
bool ShouldTemporarilyUnsummonMountedPet(bool inBattleground, bool hasFlyingMountSpeedAura)
bool ShouldApplySplineGroundClamp(bool hasTransport, bool isCreature, bool isFalling)
bool ShouldClearMountedPetStunForTransport(bool ownerMounted, bool ownerHasTransport, bool petStunned)
bool IsValidMapCoord(float c)
CellCoord ComputeCellCoord(float x, float y)
uint32 damageSchoolMask
Definition Unit.h:1011
uint32 blocked_amount
Definition Unit.h:1015
VictimState TargetState
Definition Unit.h:1017
uint32 absorb
Definition Unit.h:1013
uint32 resist
Definition Unit.h:1014
uint32 damage
Definition Unit.h:1012
uint32 HitInfo
Definition Unit.h:1016
Unit * attacker
Definition Unit.h:1009
Unit * target
Definition Unit.h:1010
Definition Cell.h:37
void SetNoCreate()
Definition Cell.h:66
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition CellImpl.h:109
void RestoreState()
Definition Unit.cpp:5554
void SaveStayPosition()
Definition Unit.cpp:9077
CharmInfo(Unit *unit)
Definition Unit.cpp:5536
float _stayY
Definition Unit.h:1322
void SetIsCommandFollow(bool val)
Definition Unit.cpp:9072
void BuildActionBar(WorldPacket *data) const
Definition Unit.cpp:5778
void LoadPetActionBar(const std::string &data)
Definition Unit.cpp:5746
void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
Definition Unit.h:1271
bool _isAtStay
Definition Unit.h:1318
bool AddSpellToActionBar(SpellInfo const *spellInfo, ActiveStates newstate=ACT_DECIDE, uint8 preferredSlot=0)
Definition Unit.cpp:5676
void InitPossessCreateSpells()
Definition Unit.cpp:5596
void SetIsAtStay(bool val)
Definition Unit.cpp:9093
float _stayX
Definition Unit.h:1321
void SetPetNumber(uint32 petnumber, bool statwindow)
Definition Unit.cpp:5737
float _stayZ
Definition Unit.h:1323
void SetIsFollowing(bool val)
Definition Unit.cpp:9098
void InitPetActionBar()
Definition Unit.cpp:5561
bool _isCommandFollow
Definition Unit.h:1317
UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX]
Definition Unit.h:1307
~CharmInfo()
Definition Unit.cpp:5551
void SetIsReturning(bool val)
Definition Unit.cpp:9103
void InitCharmCreateSpells()
Definition Unit.cpp:5626
bool RemoveSpellFromActionBar(uint32 spell_id)
Definition Unit.cpp:5708
CommandStates _CommandState
Definition Unit.h:1309
void GetStayPosition(float &x, float &y, float &z) const
Definition Unit.cpp:9086
void SetSpellAutocast(SpellInfo const *spellInfo, bool state)
Definition Unit.cpp:5784
bool _isFollowing
Definition Unit.h:1319
bool _isCommandAttack
Definition Unit.h:1316
ReactStates _oldReactState
Definition Unit.h:1314
void ToggleCreatureAutocast(SpellInfo const *spellInfo, bool apply)
Definition Unit.cpp:5727
void InitEmptyActionBar(bool withAttack=true)
Definition Unit.cpp:5586
void SetIsCommandAttack(bool val)
Definition Unit.cpp:9067
bool _isReturning
Definition Unit.h:1320
Unit * _unit
Definition Unit.h:1306
bool _barInit
Definition Unit.h:1311
uint32 _petnumber
Definition Unit.h:1310
CharmSpellInfo _charmspells[4]
Definition Unit.h:1308
uint32 Modelid1
Definition Creature.h:67
uint32 Modelid2
Definition Creature.h:68
uint32 InhabitType
Definition Creature.h:118
uint32 flags_extra
Definition Creature.h:129
uint32 type_flags
Definition Creature.h:105
uint32 unit_class
Definition Creature.h:93
bool isMounted
Definition Player.h:463
Player * opponent
Definition Player.h:459
time_t startTime
Definition Player.h:461
int32 reputationListID
bool IsHostileTo(FactionTemplateEntry const &entry) const
uint32 faction
bool IsHostileToPlayers() const
uint32 friendlyMask
bool IsNeutralToAll() const
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
uint32 factionFlags
uint32 entry
Definition Map.h:136
uint32 SpellId
void clear()
Definition LootMgr.h:308
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT)
Definition LootMgr.cpp:418
void generateMoneyLoot(uint32 minAmount, uint32 maxAmount)
Definition LootMgr.cpp:673
uint32 RequiredSpell
int32 RequiredMap
uint32 RequiredArea
uint32 RequiredAura
uint32 Flags
uint32 MountCapability[MAX_MOUNT_CAPABILITIES]
uint32 time
Definition Object.h:453
struct MovementInfo::JumpInfo jump
struct MovementInfo::TransportInfo transport
float splineElevation
Definition Object.h:494
float pitch
Definition Object.h:477
float GetAngle(Position const *pos) const
Definition Object.cpp:1860
float m_positionZ
Definition Object.h:289
float GetExactDist2d(const float x, const float y) const
Definition Object.h:366
float m_positionX
Definition Object.h:287
float GetPositionZ() const
Definition Object.h:330
float m_positionY
Definition Object.h:288
float GetOrientation() const
Definition Object.h:331
bool HasInArc(float arcangle, Position const *pos, float border=2.0f) const
Definition Object.cpp:1898
void GetSinCos(float x, float y, float &vsin, float &vcos) const
Definition Object.cpp:1879
void SetOrientation(float orientation)
Definition Object.h:323
float GetPositionX() const
Definition Object.h:328
void GetPosition(float &x, float &y) const
Definition Object.h:333
float GetPositionY() const
Definition Object.h:329
void Relocate(float x, float y)
Definition Object.h:302
uint32 spellId
Definition Unit.h:377
uint32 type
Definition Unit.h:376
uint32 schoolMask
Definition Unit.h:1040
AuraEffect const * auraEff
Definition Unit.h:1057
float maxRangeFriend
float minRangeFriend
float minRangeHostile
float maxRangeHostile
uint32 modelID_H
int32 creatureType
uint32 modelID_A
uint32 Type