diff options
author | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-03-04 19:09:57 +0100 |
---|---|---|
committer | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-03-04 19:09:57 +0100 |
commit | 7ce02e7900c9682a35f77dfa873fefc59b5014d2 (patch) | |
tree | 295103173d4a2501f39269ff3ae17ea246734712 /src | |
parent | c3767572416f7a22b66d1db8139500bafbe93f61 (diff) | |
parent | 226e0fdd1b08e315cb7f534b97a7d48e33bbf4fe (diff) |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts:
src/server/game/Entities/Creature/Creature.h
src/server/game/Entities/Player/Player.cpp
src/server/game/Entities/Player/Player.h
src/server/game/Entities/Unit/Unit.cpp
src/server/game/Entities/Unit/Unit.h
src/server/game/Globals/ObjectMgr.cpp
src/server/game/Handlers/CharacterHandler.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 48 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 49 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 263 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 265 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 421 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 388 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 266 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 216 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 84 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 18 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 97 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 10 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 251 | ||||
-rw-r--r-- | src/server/scripts/World/areatrigger_scripts.cpp | 6 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 7 | ||||
-rwxr-xr-x | src/server/shared/Database/Implementation/CharacterDatabase.h | 5 |
16 files changed, 1393 insertions, 1001 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 99d796bbb84..868102a19c0 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -862,6 +862,16 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, return true; } +void Creature::InitializeReactState() +{ + if (isTotem() || isTrigger() || GetCreatureType() == CREATURE_TYPE_CRITTER || isSpiritService()) + SetReactState(REACT_PASSIVE); + else + SetReactState(REACT_AGGRESSIVE); + /*else if (isCivilian()) + SetReactState(REACT_DEFENSIVE);*/; +} + bool Creature::isCanTrainingOf(Player* player, bool msg) const { if (!isTrainer()) @@ -1213,6 +1223,12 @@ float Creature::_GetHealthMod(int32 Rank) } } +void Creature::LowerPlayerDamageReq(uint32 unDamage) +{ + if (m_PlayerDamageReq) + m_PlayerDamageReq > unDamage ? m_PlayerDamageReq -= unDamage : m_PlayerDamageReq = 0; +} + float Creature::_GetDamageMod(int32 Rank) { switch (Rank) // define rates for each elite rank @@ -1731,6 +1747,23 @@ bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) return Unit::IsImmunedToSpellEffect(spellInfo, index); } +bool Creature::isElite() const +{ + if (isPet()) + return false; + + uint32 rank = GetCreatureTemplate()->rank; + return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE; +} + +bool Creature::isWorldBoss() const +{ + if (isPet()) + return false; + + return GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_BOSS; +} + SpellInfo const* Creature::reachWithSpellAttack(Unit* victim) { if (!victim) @@ -2255,6 +2288,13 @@ bool Creature::HasCategoryCooldown(uint32 spell_id) const return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILLISECONDS)) > time(NULL)); } +uint32 Creature::GetCreatureSpellCooldownDelay(uint32 spellId) const +{ + CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spellId); + time_t t = time(NULL); + return uint32(itr != m_CreatureSpellCooldowns.end() && itr->second > t ? itr->second - t : 0); +} + bool Creature::HasSpellCooldown(uint32 spell_id) const { CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id); @@ -2499,6 +2539,14 @@ void Creature::FarTeleportTo(Map* map, float X, float Y, float Z, float O) GetMap()->AddToMap(this); } +uint32 Creature::GetPetAutoSpellOnPos(uint8 pos) const +{ + if (pos >= MAX_SPELL_CHARM || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED) + return 0; + else + return m_charmInfo->GetCharmSpell(pos)->GetAction(); +} + void Creature::SetPosition(float x, float y, float z, float o) { // prevent crash when a bad coord is sent by the client diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 23a443e134f..e5ef3586406 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -473,15 +473,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature void SetReactState(ReactStates st) { m_reactState = st; } ReactStates GetReactState() { return m_reactState; } bool HasReactState(ReactStates state) const { return (m_reactState == state); } - void InitializeReactState() - { - if (isTotem() || isTrigger() || GetCreatureType() == CREATURE_TYPE_CRITTER || isSpiritService()) - SetReactState(REACT_PASSIVE); - else - SetReactState(REACT_AGGRESSIVE); - /*else if (isCivilian()) - SetReactState(REACT_DEFENSIVE);*/; - } + void InitializeReactState(); /// @todo Rename these properly bool isCanTrainingOf(Player* player, bool msg) const; @@ -490,22 +482,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature bool canCreatureAttack(Unit const* victim, bool force = true) const; bool IsImmunedToSpell(SpellInfo const* spellInfo); //override Unit::IsImmunedToSpell bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; //override Unit::IsImmunedToSpellEffect - bool isElite() const - { - if (isPet()) - return false; - - uint32 rank = GetCreatureTemplate()->rank; - return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE; - } - - bool isWorldBoss() const - { - if (isPet()) - return false; - - return GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_BOSS; - } + bool isElite() const; + bool isWorldBoss() const; bool IsDungeonBoss() const; @@ -530,12 +508,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature void AddCreatureSpellCooldown(uint32 spellid); bool HasSpellCooldown(uint32 spell_id) const; bool HasCategoryCooldown(uint32 spell_id) const; - uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const - { - CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spellId); - time_t t = time(NULL); - return uint32(itr != m_CreatureSpellCooldowns.end() && itr->second > t ? itr->second - t : 0); - } + uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const; virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs); bool HasSpell(uint32 spellID) const; @@ -665,13 +638,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature bool isRegeneratingHealth() { return m_regenHealth; } void setRegeneratingHealth(bool regenHealth) { m_regenHealth = regenHealth; } virtual uint8 GetPetAutoSpellSize() const { return MAX_SPELL_CHARM; } - virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const - { - if (pos >= MAX_SPELL_CHARM || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED) - return 0; - else - return m_charmInfo->GetCharmSpell(pos)->GetAction(); - } + virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const; void SetPosition(float x, float y, float z, float o); void SetPosition(const Position &pos) { SetPosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); } @@ -701,11 +668,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; } bool IsReputationGainDisabled() { return DisableReputationGain; } bool IsDamageEnoughForLootingAndReward() const { return m_PlayerDamageReq == 0; } - void LowerPlayerDamageReq(uint32 unDamage) - { - if (m_PlayerDamageReq) - m_PlayerDamageReq > unDamage ? m_PlayerDamageReq -= unDamage : m_PlayerDamageReq = 0; - } + void LowerPlayerDamageReq(uint32 unDamage); void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; } uint32 m_PlayerDamageReq; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 511ea6627df..f4c5e270a37 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -119,6 +119,7 @@ Object::~Object() } delete [] m_uint32Values; + m_uint32Values = 0; } void Object::_InitValues() @@ -308,6 +309,44 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const target->GetSession()->SendPacket(&data); } +int32 Object::GetInt32Value(uint16 index) const +{ + ASSERT(index < m_valuesCount || PrintIndexError(index, false)); + return m_int32Values[index]; +} + +uint32 Object::GetUInt32Value(uint16 index) const +{ + ASSERT(index < m_valuesCount || PrintIndexError(index, false)); + return m_uint32Values[index]; +} + +uint64 Object::GetUInt64Value(uint16 index) const +{ + ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, false)); + return *((uint64*)&(m_uint32Values[index])); +} + +float Object::GetFloatValue(uint16 index) const +{ + ASSERT(index < m_valuesCount || PrintIndexError(index, false)); + return m_floatValues[index]; +} + +uint8 Object::GetByteValue(uint16 index, uint8 offset) const +{ + ASSERT(index < m_valuesCount || PrintIndexError(index, false)); + ASSERT(offset < 4); + return *(((uint8*)&m_uint32Values[index])+offset); +} + +uint16 Object::GetUInt16Value(uint16 index, uint8 offset) const +{ + ASSERT(index < m_valuesCount || PrintIndexError(index, false)); + ASSERT(offset < 2); + return *(((uint16*)&m_uint32Values[index])+offset); +} + void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const { uint32 unkLoopCounter = 0; @@ -1226,6 +1265,13 @@ void Object::ApplyModSignedFloatValue(uint16 index, float val, bool apply) SetFloatValue(index, cur); } +void Object::ApplyPercentModFloatValue(uint16 index, float val, bool apply) +{ + float value = GetFloatValue(index); + ApplyPercentModFloatVar(value, val, apply); + SetFloatValue(index, value); +} + void Object::ApplyModPositiveFloatValue(uint16 index, float val, bool apply) { float cur = GetFloatValue(index); @@ -1275,6 +1321,27 @@ void Object::RemoveFlag(uint16 index, uint32 oldFlag) } } +void Object::ToggleFlag(uint16 index, uint32 flag) +{ + if (HasFlag(index, flag)) + RemoveFlag(index, flag); + else + SetFlag(index, flag); +} + +bool Object::HasFlag(uint16 index, uint32 flag) const +{ + if (index >= m_valuesCount && !PrintIndexError(index, false)) + return false; + + return (m_uint32Values[index] & flag) != 0; +} + +void Object::ApplyModFlag(uint16 index, uint32 flag, bool apply) +{ + if (apply) SetFlag(index, flag); else RemoveFlag(index, flag); +} + void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag) { ASSERT(index < m_valuesCount || PrintIndexError(index, true)); @@ -1321,6 +1388,54 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag) } } +void Object::ToggleByteFlag(uint16 index, uint8 offset, uint8 flag) +{ + if (HasByteFlag(index, offset, flag)) + RemoveByteFlag(index, offset, flag); + else + SetByteFlag(index, offset, flag); +} + +bool Object::HasByteFlag(uint16 index, uint8 offset, uint8 flag) const +{ + ASSERT(index < m_valuesCount || PrintIndexError(index, false)); + ASSERT(offset < 4); + return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0; +} + +void Object::SetFlag64(uint16 index, uint64 newFlag) +{ + uint64 oldval = GetUInt64Value(index); + uint64 newval = oldval | newFlag; + SetUInt64Value(index, newval); +} + +void Object::RemoveFlag64(uint16 index, uint64 oldFlag) +{ + uint64 oldval = GetUInt64Value(index); + uint64 newval = oldval & ~oldFlag; + SetUInt64Value(index, newval); +} + +void Object::ToggleFlag64(uint16 index, uint64 flag) +{ + if (HasFlag64(index, flag)) + RemoveFlag64(index, flag); + else + SetFlag64(index, flag); +} + +bool Object::HasFlag64(uint16 index, uint64 flag) const +{ + ASSERT(index < m_valuesCount || PrintIndexError(index, false)); + return (GetUInt64Value(index) & flag) != 0; +} + +void Object::ApplyModFlag64(uint16 index, uint64 flag, bool apply) +{ + if (apply) SetFlag64(index, flag); else RemoveFlag64(index, flag); +} + bool Object::PrintIndexError(uint32 index, bool set) const { sLog->outError(LOG_FILTER_GENERAL, "Attempt %s non-existed value field: %u (count: %u) for object typeid: %u type mask: %u", (set ? "set value to" : "get value from"), index, m_valuesCount, GetTypeId(), m_objectType); @@ -1479,6 +1594,16 @@ void WorldObject::_Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask) m_phaseMask = phaseMask; } +void WorldObject::RemoveFromWorld() +{ + if (!IsInWorld()) + return; + + DestroyForNearbyPlayers(); + + Object::RemoveFromWorld(); +} + uint32 WorldObject::GetZoneId() const { return GetBaseMap()->GetZoneId(m_positionX, m_positionY, m_positionZ); @@ -1548,6 +1673,80 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const return IsWithinLOS(ox, oy, oz); } +float WorldObject::GetDistance(const WorldObject* obj) const +{ + float d = GetExactDist(obj) - GetObjectSize() - obj->GetObjectSize(); + return d > 0.0f ? d : 0.0f; +} + +float WorldObject::GetDistance(const Position &pos) const +{ + float d = GetExactDist(&pos) - GetObjectSize(); + return d > 0.0f ? d : 0.0f; +} + +float WorldObject::GetDistance(float x, float y, float z) const +{ + float d = GetExactDist(x, y, z) - GetObjectSize(); + return d > 0.0f ? d : 0.0f; +} + +float WorldObject::GetDistance2d(const WorldObject* obj) const +{ + float d = GetExactDist2d(obj) - GetObjectSize() - obj->GetObjectSize(); + return d > 0.0f ? d : 0.0f; +} + +float WorldObject::GetDistance2d(float x, float y) const +{ + float d = GetExactDist2d(x, y) - GetObjectSize(); + return d > 0.0f ? d : 0.0f; +} + +bool WorldObject::IsSelfOrInSameMap(const WorldObject* obj) const +{ + if (this == obj) + return true; + return IsInMap(obj); +} + +bool WorldObject::IsInMap(const WorldObject* obj) const +{ + if (obj) + return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()); + return false; +} + +bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist) const +{ + return IsInDist(x, y, z, dist + GetObjectSize()); +} + +bool WorldObject::IsWithinDist3d(const Position* pos, float dist) const +{ + return IsInDist(pos, dist + GetObjectSize()); +} + +bool WorldObject::IsWithinDist2d(float x, float y, float dist) const +{ + return IsInDist2d(x, y, dist + GetObjectSize()); +} + +bool WorldObject::IsWithinDist2d(const Position* pos, float dist) const +{ + return IsInDist2d(pos, dist + GetObjectSize()); +} + +bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const +{ + return obj && _IsWithinDist(obj, dist2compare, is3D); +} + +bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const +{ + return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D); +} + bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const { /*float x, y, z; @@ -1779,6 +1978,13 @@ void WorldObject::GetRandomPoint(const Position &pos, float distance, float &ran UpdateGroundPositionZ(rand_x, rand_y, rand_z); // update to LOS height if available } +void WorldObject::GetRandomPoint(const Position &srcPos, float distance, Position &pos) const +{ + float x, y, z; + GetRandomPoint(srcPos, distance, x, y, z); + pos.Relocate(x, y, z, GetOrientation()); +} + void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const { float new_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true); @@ -1971,6 +2177,11 @@ bool WorldObject::canSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo return true; } +bool WorldObject::CanNeverSee(WorldObject const* obj) const +{ + return GetMap() != obj->GetMap() || !InSamePhase(obj); +} + bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const { const WorldObject* seer = this; @@ -2512,6 +2723,18 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, const Position &pos, TempS return NULL; } +TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang /*= 0*/, TempSummonType spwtype /*= TEMPSUMMON_MANUAL_DESPAWN*/, uint32 despwtime /*= 0*/) const +{ + if (!x && !y && !z) + { + GetClosePoint(x, y, z, GetObjectSize()); + ang = GetOrientation(); + } + Position pos; + pos.Relocate(x, y, z, ang); + return SummonCreature(id, pos, spwtype, despwtime, 0); +} + GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime) { if (!IsInWorld()) @@ -2843,6 +3066,41 @@ void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float &x, float */ } +void WorldObject::GetClosePoint(float &x, float &y, float &z, float size, float distance2d /*= 0*/, float angle /*= 0*/) const +{ + // angle calculated from current orientation + GetNearPoint(NULL, x, y, z, size, distance2d, GetOrientation() + angle); +} + +void WorldObject::GetNearPosition(Position &pos, float dist, float angle) +{ + GetPosition(&pos); + MovePosition(pos, dist, angle); +} + +void WorldObject::GetFirstCollisionPosition(Position &pos, float dist, float angle) +{ + GetPosition(&pos); + MovePositionToFirstCollision(pos, dist, angle); +} + +void WorldObject::GetRandomNearPosition(Position &pos, float radius) +{ + GetPosition(&pos); + MovePosition(pos, radius * (float)rand_norm(), (float)rand_norm() * static_cast<float>(2 * M_PI)); +} + +void WorldObject::GetContactPoint(const WorldObject* obj, float &x, float &y, float &z, float distance2d /*= CONTACT_DISTANCE*/) const +{ + // angle to face `obj` to `this` using distance includes size of `obj` + GetNearPoint(obj, x, y, z, obj->GetObjectSize(), distance2d, GetAngle(obj)); +} + +float WorldObject::GetObjectSize() const +{ + return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE; +} + void WorldObject::MovePosition(Position &pos, float dist, float angle) { angle += GetOrientation(); @@ -2964,6 +3222,11 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update) UpdateObjectVisibility(); } +bool WorldObject::InSamePhase(WorldObject const* obj) const +{ + return InSamePhase(obj->GetPhaseMask()); +} + void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/) { WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4+8); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 063cadcb610..622b60cd7af 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -205,43 +205,12 @@ class Object virtual void DestroyForPlayer(Player* target, bool onDeath = false) const; - int32 GetInt32Value(uint16 index) const - { - ASSERT(index < m_valuesCount || PrintIndexError(index, false)); - return m_int32Values[index]; - } - - uint32 GetUInt32Value(uint16 index) const - { - ASSERT(index < m_valuesCount || PrintIndexError(index, false)); - return m_uint32Values[index]; - } - - uint64 GetUInt64Value(uint16 index) const - { - ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, false)); - return *((uint64*)&(m_uint32Values[index])); - } - - float GetFloatValue(uint16 index) const - { - ASSERT(index < m_valuesCount || PrintIndexError(index, false)); - return m_floatValues[index]; - } - - uint8 GetByteValue(uint16 index, uint8 offset) const - { - ASSERT(index < m_valuesCount || PrintIndexError(index, false)); - ASSERT(offset < 4); - return *(((uint8*)&m_uint32Values[index])+offset); - } - - uint16 GetUInt16Value(uint16 index, uint8 offset) const - { - ASSERT(index < m_valuesCount || PrintIndexError(index, false)); - ASSERT(offset < 2); - return *(((uint16*)&m_uint32Values[index])+offset); - } + int32 GetInt32Value(uint16 index) const; + uint32 GetUInt32Value(uint16 index) const; + uint64 GetUInt64Value(uint16 index) const; + float GetFloatValue(uint16 index) const; + uint8 GetByteValue(uint16 index, uint8 offset) const; + uint16 GetUInt16Value(uint16 index, uint8 offset) const; void SetInt32Value(uint16 index, int32 value); void SetUInt32Value(uint16 index, uint32 value); @@ -262,88 +231,24 @@ class Object void ApplyModUInt64Value(uint16 index, int32 val, bool apply); void ApplyModPositiveFloatValue(uint16 index, float val, bool apply); void ApplyModSignedFloatValue(uint16 index, float val, bool apply); - - void ApplyPercentModFloatValue(uint16 index, float val, bool apply) - { - float value = GetFloatValue(index); - ApplyPercentModFloatVar(value, val, apply); - SetFloatValue(index, value); - } + void ApplyPercentModFloatValue(uint16 index, float val, bool apply); void SetFlag(uint16 index, uint32 newFlag); void RemoveFlag(uint16 index, uint32 oldFlag); - - void ToggleFlag(uint16 index, uint32 flag) - { - if (HasFlag(index, flag)) - RemoveFlag(index, flag); - else - SetFlag(index, flag); - } - - bool HasFlag(uint16 index, uint32 flag) const - { - if (index >= m_valuesCount && !PrintIndexError(index, false)) - return false; - - return (m_uint32Values[index] & flag) != 0; - } + void ToggleFlag(uint16 index, uint32 flag); + bool HasFlag(uint16 index, uint32 flag) const; + void ApplyModFlag(uint16 index, uint32 flag, bool apply); void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag); void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag); + void ToggleByteFlag(uint16 index, uint8 offset, uint8 flag); + bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const; - void ToggleFlag(uint16 index, uint8 offset, uint8 flag) - { - if (HasByteFlag(index, offset, flag)) - RemoveByteFlag(index, offset, flag); - else - SetByteFlag(index, offset, flag); - } - - bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const - { - ASSERT(index < m_valuesCount || PrintIndexError(index, false)); - ASSERT(offset < 4); - return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0; - } - - void ApplyModFlag(uint16 index, uint32 flag, bool apply) - { - if (apply) SetFlag(index, flag); else RemoveFlag(index, flag); - } - - void SetFlag64(uint16 index, uint64 newFlag) - { - uint64 oldval = GetUInt64Value(index); - uint64 newval = oldval | newFlag; - SetUInt64Value(index, newval); - } - - void RemoveFlag64(uint16 index, uint64 oldFlag) - { - uint64 oldval = GetUInt64Value(index); - uint64 newval = oldval & ~oldFlag; - SetUInt64Value(index, newval); - } - - void ToggleFlag64(uint16 index, uint64 flag) - { - if (HasFlag64(index, flag)) - RemoveFlag64(index, flag); - else - SetFlag64(index, flag); - } - - bool HasFlag64(uint16 index, uint64 flag) const - { - ASSERT(index < m_valuesCount || PrintIndexError(index, false)); - return (GetUInt64Value(index) & flag) != 0; - } - - void ApplyModFlag64(uint16 index, uint64 flag, bool apply) - { - if (apply) SetFlag64(index, flag); else RemoveFlag64(index, flag); - } + void SetFlag64(uint16 index, uint64 newFlag); + void RemoveFlag64(uint16 index, uint64 oldFlag); + void ToggleFlag64(uint16 index, uint64 flag); + bool HasFlag64(uint16 index, uint64 flag) const; + void ApplyModFlag64(uint16 index, uint64 flag, bool apply); void ClearUpdateMask(bool remove); @@ -660,68 +565,30 @@ class WorldObject : public Object, public WorldLocation virtual void Update (uint32 /*time_diff*/) { } void _Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask); - - virtual void RemoveFromWorld() - { - if (!IsInWorld()) - return; - - DestroyForNearbyPlayers(); - - Object::RemoveFromWorld(); - } + virtual void RemoveFromWorld(); void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const; void GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const; - void GetClosePoint(float &x, float &y, float &z, float size, float distance2d = 0, float angle = 0) const - { - // angle calculated from current orientation - GetNearPoint(NULL, x, y, z, size, distance2d, GetOrientation() + angle); - } + void GetClosePoint(float &x, float &y, float &z, float size, float distance2d = 0, float angle = 0) const; void MovePosition(Position &pos, float dist, float angle); - void GetNearPosition(Position &pos, float dist, float angle) - { - GetPosition(&pos); - MovePosition(pos, dist, angle); - } + void GetNearPosition(Position &pos, float dist, float angle); void MovePositionToFirstCollision(Position &pos, float dist, float angle); - void GetFirstCollisionPosition(Position &pos, float dist, float angle) - { - GetPosition(&pos); - MovePositionToFirstCollision(pos, dist, angle); - } - void GetRandomNearPosition(Position &pos, float radius) - { - GetPosition(&pos); - MovePosition(pos, radius * (float)rand_norm(), (float)rand_norm() * static_cast<float>(2 * M_PI)); - } + void GetFirstCollisionPosition(Position &pos, float dist, float angle); + void GetRandomNearPosition(Position &pos, float radius); + void GetContactPoint(const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const; - void GetContactPoint(const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const - { - // angle to face `obj` to `this` using distance includes size of `obj` - GetNearPoint(obj, x, y, z, obj->GetObjectSize(), distance2d, GetAngle(obj)); - } - - float GetObjectSize() const - { - return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE; - } + float GetObjectSize() const; void UpdateGroundPositionZ(float x, float y, float &z) const; void UpdateAllowedPositionZ(float x, float y, float &z) const; void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const; - void GetRandomPoint(const Position &srcPos, float distance, Position &pos) const - { - float x, y, z; - GetRandomPoint(srcPos, distance, x, y, z); - pos.Relocate(x, y, z, GetOrientation()); - } + void GetRandomPoint(const Position &srcPos, float distance, Position &pos) const; uint32 GetInstanceId() const { return m_InstanceId; } virtual void SetPhaseMask(uint32 newPhaseMask, bool update); uint32 GetPhaseMask() const { return m_phaseMask; } - bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); } + bool InSamePhase(WorldObject const* obj) const; bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); } uint32 GetZoneId() const; @@ -735,62 +602,22 @@ class WorldObject : public Object, public WorldLocation virtual std::string const& GetNameForLocaleIdx(LocaleConstant /*locale_idx*/) const { return m_name; } - float GetDistance(const WorldObject* obj) const - { - float d = GetExactDist(obj) - GetObjectSize() - obj->GetObjectSize(); - return d > 0.0f ? d : 0.0f; - } - float GetDistance(const Position &pos) const - { - float d = GetExactDist(&pos) - GetObjectSize(); - return d > 0.0f ? d : 0.0f; - } - float GetDistance(float x, float y, float z) const - { - float d = GetExactDist(x, y, z) - GetObjectSize(); - return d > 0.0f ? d : 0.0f; - } - float GetDistance2d(const WorldObject* obj) const - { - float d = GetExactDist2d(obj) - GetObjectSize() - obj->GetObjectSize(); - return d > 0.0f ? d : 0.0f; - } - float GetDistance2d(float x, float y) const - { - float d = GetExactDist2d(x, y) - GetObjectSize(); - return d > 0.0f ? d : 0.0f; - } + float GetDistance(const WorldObject* obj) const; + float GetDistance(const Position &pos) const; + float GetDistance(float x, float y, float z) const; + float GetDistance2d(const WorldObject* obj) const; + float GetDistance2d(float x, float y) const; float GetDistanceZ(const WorldObject* obj) const; - bool IsSelfOrInSameMap(const WorldObject* obj) const - { - if (this == obj) - return true; - return IsInMap(obj); - } - bool IsInMap(const WorldObject* obj) const - { - if (obj) - return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()); - return false; - } - bool IsWithinDist3d(float x, float y, float z, float dist) const - { return IsInDist(x, y, z, dist + GetObjectSize()); } - bool IsWithinDist3d(const Position* pos, float dist) const - { return IsInDist(pos, dist + GetObjectSize()); } - bool IsWithinDist2d(float x, float y, float dist) const - { return IsInDist2d(x, y, dist + GetObjectSize()); } - bool IsWithinDist2d(const Position* pos, float dist) const - { return IsInDist2d(pos, dist + GetObjectSize()); } + bool IsSelfOrInSameMap(const WorldObject* obj) const; + bool IsInMap(const WorldObject* obj) const; + bool IsWithinDist3d(float x, float y, float z, float dist) const; + bool IsWithinDist3d(const Position* pos, float dist) const; + bool IsWithinDist2d(float x, float y, float dist) const; + bool IsWithinDist2d(const Position* pos, float dist) const; // use only if you will sure about placing both object at same map - bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const - { - return obj && _IsWithinDist(obj, dist2compare, is3D); - } - bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const - { - return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D); - } + bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const; + bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const; bool IsWithinLOS(float x, float y, float z) const; bool IsWithinLOSInMap(const WorldObject* obj) const; bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; @@ -859,17 +686,7 @@ class WorldObject : public Object, public WorldLocation ZoneScript* GetZoneScript() const { return m_zoneScript; } TempSummon* SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, uint32 vehId = 0) const; - TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0) - { - if (!x && !y && !z) - { - GetClosePoint(x, y, z, GetObjectSize()); - ang = GetOrientation(); - } - Position pos; - pos.Relocate(x, y, z, ang); - return SummonCreature(id, pos, spwtype, despwtime, 0); - } + TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0) const; GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime); Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL); @@ -957,7 +774,7 @@ class WorldObject : public Object, public WorldLocation virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const; - bool CanNeverSee(WorldObject const* obj) const { return GetMap() != obj->GetMap() || !InSamePhase(obj); } + bool CanNeverSee(WorldObject const* obj) const; virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; } bool CanDetect(WorldObject const* obj, bool ignoreStealth) const; bool CanDetectInvisibilityOf(WorldObject const* obj) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b07c6183257..3b0d15839a4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1332,6 +1332,18 @@ void Player::UpdateMirrorTimers() m_MirrorTimerFlagsLast = ~m_MirrorTimerFlags; } +void Player::StopMirrorTimers() +{ + StopMirrorTimer(FATIGUE_TIMER); + StopMirrorTimer(BREATH_TIMER); + StopMirrorTimer(FIRE_TIMER); +} + +bool Player::IsMirrorTimerActive(MirrorTimerType type) +{ + return m_MirrorTimer[type] == getMaxTimer(type); +} + void Player::HandleDrowning(uint32 time_diff) { if (!m_MirrorTimerFlags) @@ -1863,6 +1875,15 @@ void Player::setDeathState(DeathState s) SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); } +void Player::InnEnter(time_t time, uint32 mapid, float x, float y, float z) +{ + inn_pos_mapid = mapid; + inn_pos_x = x; + inn_pos_y = y; + inn_pos_z = z; + time_inn_enter = time; +} + bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer) { // 0 1 2 3 4 5 6 7 @@ -2319,6 +2340,11 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return true; } +bool Player::TeleportTo(WorldLocation const &loc, uint32 options /*= 0*/) +{ + return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options); +} + bool Player::TeleportToBGEntryPoint() { if (m_bgData.joinPos.m_mapId == MAPID_INVALID) @@ -2936,6 +2962,11 @@ bool Player::IsInSameGroupWith(Player const* p) const GetGroup()->SameSubGroup(this, p)); } +bool Player::IsInSameRaidWith(Player const* p) const +{ + return p == this || (GetGroup() != NULL && GetGroup() == p->GetGroup()); +} + ///- If the player is invited, remove him. If the group if then only 1 person, disband the group. /// \todo Shouldn't we also check if there is no other invitees before disbanding the group? void Player::UninviteFromGroup() @@ -7611,7 +7642,7 @@ uint8 Player::GetRankFromDB(uint64 guid) return 0; } -void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value) +void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value) { SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value); if (type == ARENA_TEAM_PERSONAL_RATING && value > _maxPersonalArenaRate) @@ -7621,6 +7652,12 @@ void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 v } } +void Player::SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type) +{ + SetArenaTeamInfoField(slot, ARENA_TEAM_ID, ArenaTeamId); + SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type); +} + uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID); @@ -10263,6 +10300,14 @@ Item* Player::GetItemByPos(uint8 bag, uint8 slot) const return NULL; } +//Does additional check for disarmed weapons +Item* Player::GetUseableItemByPos(uint8 bag, uint8 slot) const +{ + if (!CanUseAttackType(GetAttackBySlot(slot))) + return NULL; + return GetItemByPos(bag, slot); +} + Bag* Player::GetBagByPos(uint8 bag) const { if ((bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END) @@ -10612,6 +10657,19 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item return EQUIP_ERR_OK; } +InventoryResult Player::CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count /*= NULL*/) const +{ + return CanStoreItem(bag, slot, dest, item, count, NULL, false, no_space_count); +} + +InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap /*= false*/) const +{ + if (!pItem) + return EQUIP_ERR_ITEM_NOT_FOUND; + uint32 count = pItem->GetCount(); + return CanStoreItem(bag, slot, dest, pItem->GetEntry(), count, pItem, swap, NULL); +} + InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVec &dest, ItemTemplate const* pProto, uint32& count, bool swap, Item* pSrcItem) const { Item* pItem2 = GetItemByPos(bag, slot); @@ -12207,6 +12265,11 @@ void Player::VisualizeItem(uint8 slot, Item* pItem) pItem->SetState(ITEM_CHANGED, this); } +Item* Player::BankItem(ItemPosCountVec const& dest, Item* pItem, bool update) +{ + return StoreItem(dest, pItem, update); +} + void Player::RemoveItem(uint8 bag, uint8 slot, bool update) { // note: removeitem does not actually change the item @@ -13315,6 +13378,18 @@ void Player::SendSellError(SellResult msg, Creature* creature, uint64 guid) GetSession()->SendPacket(&data); } +bool Player::IsUseEquipedWeapon(bool mainhand) const +{ + // disarm applied only to mainhand weapon + return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED)); +} + +bool Player::IsTwoHandUsed() const +{ + Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(); +} + void Player::TradeCancel(bool sendback) { if (m_trade) @@ -15926,6 +16001,70 @@ uint16 Player::FindQuestSlot(uint32 quest_id) const return MAX_QUEST_LOG_SIZE; } +uint32 Player::GetQuestSlotQuestId(uint16 slot) const +{ + return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET); +} + +uint32 Player::GetQuestSlotState(uint16 slot) const +{ + return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET); +} + +uint16 Player::GetQuestSlotCounter(uint16 slot, uint8 counter) const +{ + return (uint16)(GetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET) >> (counter * 16)); +} + +uint32 Player::GetQuestSlotTime(uint16 slot) const +{ + return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET); +} + +void Player::SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer /*= 0*/) +{ + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET, quest_id); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, 0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET, 0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET + 1, 0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET, timer); +} + +void Player::SetQuestSlotCounter(uint16 slot, uint8 counter, uint16 count) +{ + uint64 val = GetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET); + val &= ~((uint64)0xFFFF << (counter * 16)); + val |= ((uint64)count << (counter * 16)); + SetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET, val); +} + +void Player::SetQuestSlotState(uint16 slot, uint32 state) +{ + SetFlag(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, state); +} + +void Player::RemoveQuestSlotState(uint16 slot, uint32 state) +{ + RemoveFlag(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, state); +} + +void Player::SetQuestSlotTimer(uint16 slot, uint32 timer) +{ + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET, timer); +} + +void Player::SwapQuestSlot(uint16 slot1, uint16 slot2) +{ + for (int i = 0; i < MAX_QUEST_OFFSET; ++i) + { + uint32 temp1 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot1 + i); + uint32 temp2 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot2 + i); + + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot1 + i, temp2); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot2 + i, temp1); + } +} + void Player::AreaExploredOrEventHappens(uint32 questId) { if (questId) @@ -18602,6 +18741,12 @@ void Player::BindToInstance() GetSession()->SendCalendarRaidLockout(mapSave, true); } +void Player::SetPendingBind(uint32 instanceId, uint32 bindTimer) +{ + _pendingBindId = instanceId; + _pendingBindTimer = bindTimer; +} + void Player::SendRaidInfo() { uint32 counter = 0; @@ -18812,6 +18957,11 @@ bool Player::CheckInstanceCount(uint32 instanceId) const return _instanceResetTimes.find(instanceId) != _instanceResetTimes.end(); } +void Player::AddInstanceEnterTime(uint32 instanceId, time_t enterTime) +{ + if (_instanceResetTimes.find(instanceId) == _instanceResetTimes.end()) + _instanceResetTimes.insert(InstanceTimeMap::value_type(instanceId, enterTime + HOUR)); +} bool Player::_LoadHomeBind(PreparedQueryResult result) { @@ -19611,7 +19761,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) { if (saveItr->second) { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_QUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_QUESTSTATUS_REWARDED); stmt->setUInt32(0, GetGUIDLow()); stmt->setUInt32(1, saveItr->first); trans->Append(stmt); @@ -20160,6 +20310,13 @@ void Player::UpdateContestedPvP(uint32 diff) m_contestedPvPTimer -= diff; } +void Player::ResetContestedPvP() +{ + ClearUnitState(UNIT_STATE_ATTACK_PLAYER); + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP); + m_contestedPvPTimer = 0; +} + void Player::UpdatePvPFlag(time_t currTime) { if (!IsPvP()) @@ -20411,6 +20568,30 @@ void Player::Whisper(const std::string& text, uint32 language, uint64 receiver) ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName().c_str(), rPlayer->autoReplyMsg.c_str()); } +Item* Player::GetMItem(uint32 id) +{ + ItemMap::const_iterator itr = mMitems.find(id); + return itr != mMitems.end() ? itr->second : NULL; +} + +void Player::AddMItem(Item* it) +{ + ASSERT(it); + //ASSERT deleted, because items can be added before loading + mMitems[it->GetGUIDLow()] = it; +} + +bool Player::RemoveMItem(uint32 id) +{ + return mMitems.erase(id) ? true : false; +} + +void Player::SendOnCancelExpectedVehicleRideAura() +{ + WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); + GetSession()->SendPacket(&data); +} + void Player::PetSpellInitialize() { Pet* pet = GetPet(); @@ -21812,6 +21993,13 @@ void Player::UpdatePvPState(bool onlyFFA) } } +void Player::SetPvP(bool state) +{ + Unit::SetPvP(state); + for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) + (*itr)->SetPvP(state); +} + void Player::UpdatePvP(bool state, bool override) { if (!state || override) @@ -21826,6 +22014,19 @@ void Player::UpdatePvP(bool state, bool override) } } +bool Player::HasSpellCooldown(uint32 spell_id) const +{ + SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id); + return itr != m_spellCooldowns.end() && itr->second.end > time(NULL); +} + +uint32 Player::GetSpellCooldownDelay(uint32 spell_id) const +{ + SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id); + time_t t = time(NULL); + return uint32(itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0); +} + void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell, bool infinityCooldown) { // init cooldown values @@ -21966,6 +22167,16 @@ void Player::UpdatePotionCooldown(Spell* spell) m_lastPotionId = 0; } +void Player::SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura) +{ + ASSERT(!IsRessurectRequested()); + _resurrectionData = new ResurrectionData(); + _resurrectionData->GUID = caster->GetGUID(); + _resurrectionData->Location.WorldRelocate(*caster); + _resurrectionData->Health = health; + _resurrectionData->Mana = mana; + _resurrectionData->Aura = appliedAura; +} //slot to be excluded while counting bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) { @@ -22169,6 +22380,17 @@ void Player::SetBattlegroundEntryPoint() m_bgData.joinPos = WorldLocation(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, 0.0f); } +void Player::SetBGTeam(uint32 team) +{ + m_bgData.bgTeam = team; + SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? 1 : 0)); +} + +uint32 Player::GetBGTeam() const +{ + return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); +} + void Player::LeaveBattleground(bool teleportToEntryPoint) { if (Battleground* bg = GetBattleground()) @@ -22251,6 +22473,11 @@ WorldLocation Player::GetStartPosition() const return WorldLocation(mapId, info->positionX, info->positionY, info->positionZ, 0); } +bool Player::HaveAtClient(WorldObject const* u) const +{ + return u == this || m_clientGUIDs.find(u->GetGUID()) != m_clientGUIDs.end(); +} + bool Player::IsNeverVisible() const { if (Unit::IsNeverVisible()) @@ -22499,7 +22726,7 @@ bool Player::ModifyMoney(int64 amount, bool sendError /*= true*/) sScriptMgr->OnPlayerMoneyChanged(this, amount); if (amount < 0) - SetMoney (GetMoney() > uint64(-amount) ? GetMoney() + amount : 0); + SetMoney(GetMoney() > uint64(-amount) ? GetMoney() + amount : 0); else { if (GetMoney() < uint64(MAX_MONEY_AMOUNT - amount)) @@ -22515,6 +22742,25 @@ bool Player::ModifyMoney(int64 amount, bool sendError /*= true*/) return true; } +bool Player::HasEnoughMoney(int64 amount) const +{ + if (amount > 0) + return (GetMoney() >= (uint64) amount); + return true; +} + +void Player::SetMoney(uint64 value) +{ + SetUInt64Value(PLAYER_FIELD_COINAGE, value); + MoneyChanged(value); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED); +} + +bool Player::IsQuestRewarded(uint32 quest_id) const +{ + return m_RewardedQuests.find(quest_id) != m_RewardedQuests.end(); +} + Unit* Player::GetSelectedUnit() const { if (m_curSelection) @@ -23132,6 +23378,96 @@ Battleground* Player::GetBattleground() const return sBattlegroundMgr->GetBattleground(GetBattlegroundId(), m_bgData.bgTypeID); } +bool Player::InBattlegroundQueue() const +{ + for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_NONE) + return true; + return false; +} + +BattlegroundQueueTypeId Player::GetBattlegroundQueueTypeId(uint32 index) const +{ + return m_bgBattlegroundQueueID[index].bgQueueTypeId; +} + +uint32 Player::GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const +{ + for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) + return i; + return PLAYER_MAX_BATTLEGROUND_QUEUES; +} + +bool Player::IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const +{ + for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) + return m_bgBattlegroundQueueID[i].invitedToInstance != 0; + return false; +} + +bool Player::InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const +{ + return GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES; +} + +void Player::SetBattlegroundId(uint32 val, BattlegroundTypeId bgTypeId) +{ + m_bgData.bgInstanceID = val; + m_bgData.bgTypeID = bgTypeId; +} + +uint32 Player::AddBattlegroundQueueId(BattlegroundQueueTypeId val) +{ + for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + { + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE || m_bgBattlegroundQueueID[i].bgQueueTypeId == val) + { + m_bgBattlegroundQueueID[i].bgQueueTypeId = val; + m_bgBattlegroundQueueID[i].invitedToInstance = 0; + return i; + } + } + return PLAYER_MAX_BATTLEGROUND_QUEUES; +} + +bool Player::HasFreeBattlegroundQueueId() +{ + for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE) + return true; + return false; +} + +void Player::RemoveBattlegroundQueueId(BattlegroundQueueTypeId val) +{ + for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + { + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == val) + { + m_bgBattlegroundQueueID[i].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE; + m_bgBattlegroundQueueID[i].invitedToInstance = 0; + return; + } + } +} + +void Player::SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId) +{ + for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) + m_bgBattlegroundQueueID[i].invitedToInstance = instanceId; +} + +bool Player::IsInvitedForBattlegroundInstance(uint32 instanceId) const +{ + for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + if (m_bgBattlegroundQueueID[i].invitedToInstance == instanceId) + return true; + return false; +} + bool Player::InArena() const { Battleground* bg = GetBattleground(); @@ -23280,6 +23616,15 @@ void Player::UpdateForQuestWorldObjects() GetSession()->SendPacket(&packet); } +void Player::SetSummonPoint(uint32 mapid, float x, float y, float z) +{ + m_summon_expire = time(NULL) + MAX_PLAYER_SUMMON_DELAY; + m_summon_mapid = mapid; + m_summon_x = x; + m_summon_y = y; + m_summon_z = z; +} + void Player::SummonIfPossible(bool agree) { if (!agree) @@ -23678,10 +24023,6 @@ void Player::SetClientControl(Unit* target, uint8 allowMove) void Player::SetMover(Unit* target) { - m_mover->m_movedPlayer = NULL; - m_mover = target; - m_mover->m_movedPlayer = this; - ObjectGuid guid = target->GetGUID(); WorldPacket data(SMSG_MOVE_SET_ACTIVE_MOVER, 9); @@ -24201,6 +24542,12 @@ void Player::InitGlyphsForLevel() SetUInt32Value(PLAYER_GLYPHS_ENABLED, slotMask); } +void Player::SetGlyph(uint8 slot, uint32 glyph) +{ + _talentMgr->SpecInfo[GetActiveSpec()].Glyphs[slot] = glyph; + SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); +} + bool Player::isTotalImmune() { AuraEffectList const& immune = GetAuraEffectsByType(SPELL_AURA_SCHOOL_IMMUNITY); @@ -24330,6 +24677,22 @@ uint32 Player::GetRuneTypeBaseCooldown(RuneType runeType) const return cooldown; } +void Player::SetRuneCooldown(uint8 index, uint32 cooldown) +{ + m_runes->runes[index].Cooldown = cooldown; + m_runes->SetRuneState(index, (cooldown == 0) ? true : false); +} + +void Player::SetRuneConvertAura(uint8 index, AuraEffect const* aura) +{ + m_runes->runes[index].ConvertAura = aura; +} + +void Player::AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const* aura) +{ + SetRuneConvertAura(index, aura); ConvertRune(index, newType); +} + void Player::RemoveRunesByAuraEffect(AuraEffect const* aura) { for (uint8 i = 0; i < MAX_RUNES; ++i) @@ -24775,6 +25138,12 @@ InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8 return EQUIP_ERR_OK; } +void Player::SetFallInformation(uint32 time, float z) +{ + m_lastFallTime = time; + m_lastFallZ = z; +} + void Player::HandleFall(MovementInfo const& movementInfo) { // calculate total z distance of the fall @@ -25190,6 +25559,11 @@ void Player::ResummonPetTemporaryUnSummonedIfAny() m_temporaryUnsummonedPetNumber = 0; } +bool Player::IsPetNeedBeTemporaryUnsummoned() const +{ + return !IsInWorld() || !isAlive() || IsMounted() /*+in flight*/; +} + bool Player::canSeeSpellClickOn(Creature const* c) const { if (!c->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK)) @@ -26661,6 +27035,39 @@ void Player::SendMovementSetCollisionHeight(float height) SendDirectMessage(&data); } +float Player::GetCollisionHeight(bool mounted) const +{ + if (mounted) + { + CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID)); + if (!mountDisplayInfo) + return GetCollisionHeight(false); + + CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId); + if (!mountModelData) + return GetCollisionHeight(false); + + CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()); + ASSERT(displayInfo); + CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId); + ASSERT(modelData); + + float scaleMod = GetFloatValue(OBJECT_FIELD_SCALE_X); // 99% sure about this + + return scaleMod * mountModelData->MountHeight + modelData->CollisionHeight * 0.5f; + } + else + { + //! Dismounting case - use basic default model data + CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()); + ASSERT(displayInfo); + CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId); + ASSERT(modelData); + + return modelData->CollisionHeight; + } +} + Guild* Player::GetGuild() { uint32 guildId = GetGuildId(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 89a3a47b25d..5f13fd0d33a 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1221,20 +1221,10 @@ class Player : public Unit, public GridObject<Player> void RemoveFromWorld(); bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); - bool TeleportTo(WorldLocation const &loc, uint32 options = 0) - { - return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options); - } + bool TeleportTo(WorldLocation const &loc, uint32 options = 0); bool TeleportToBGEntryPoint(); - void SetSummonPoint(uint32 mapid, float x, float y, float z) - { - m_summon_expire = time(NULL) + MAX_PLAYER_SUMMON_DELAY; - m_summon_mapid = mapid; - m_summon_x = x; - m_summon_y = y; - m_summon_z = z; - } + void SetSummonPoint(uint32 mapid, float x, float y, float z); void SummonIfPossible(bool agree); bool Create(uint32 guidlow, CharacterCreateInfo* createInfo); @@ -1307,14 +1297,7 @@ class Player : public Unit, public GridObject<Player> void setDeathState(DeathState s); // overwrite Unit::setDeathState - void InnEnter (time_t time, uint32 mapid, float x, float y, float z) - { - inn_pos_mapid = mapid; - inn_pos_x = x; - inn_pos_y = y; - inn_pos_z = z; - time_inn_enter = time; - } + void InnEnter(time_t time, uint32 mapid, float x, float y, float z); float GetRestBonus() const { return m_rest_bonus; } void SetRestBonus(float rest_bonus_new); @@ -1361,13 +1344,8 @@ class Player : public Unit, public GridObject<Player> Item* GetItemByEntry(uint32 entry) const; Item* GetItemByPos(uint16 pos) const; Item* GetItemByPos(uint8 bag, uint8 slot) const; + Item* GetUseableItemByPos(uint8 bag, uint8 slot) const; Bag* GetBagByPos(uint8 slot) const; - inline Item* GetUseableItemByPos(uint8 bag, uint8 slot) const //Does additional check for disarmed weapons - { - if (!CanUseAttackType(GetAttackBySlot(slot))) - return NULL; - return GetItemByPos(bag, slot); - } Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const; Item* GetShield(bool useable = false) const; static uint8 GetAttackBySlot(uint8 slot); // MAX_ATTACK if not weapon slot @@ -1390,17 +1368,8 @@ class Player : public Unit, public GridObject<Player> bool HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const; InventoryResult CanTakeMoreSimilarItems(Item* pItem) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem); } InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return CanTakeMoreSimilarItems(entry, count, NULL); } - InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL) const - { - return CanStoreItem(bag, slot, dest, item, count, NULL, false, no_space_count); - } - InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const - { - if (!pItem) - return EQUIP_ERR_ITEM_NOT_FOUND; - uint32 count = pItem->GetCount(); - return CanStoreItem(bag, slot, dest, pItem->GetEntry(), count, pItem, swap, NULL); - } + InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL) const; + InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const; InventoryResult CanStoreItems(Item** pItem, int count) const; InventoryResult CanEquipNewItem(uint8 slot, uint16& dest, uint32 item, bool swap) const; InventoryResult CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading = true) const; @@ -1465,11 +1434,7 @@ class Player : public Unit, public GridObject<Player> void QuickEquipItem(uint16 pos, Item* pItem); void VisualizeItem(uint8 slot, Item* pItem); void SetVisibleItemSlot(uint8 slot, Item* pItem); - Item* BankItem(ItemPosCountVec const& dest, Item* pItem, bool update) - { - return StoreItem(dest, pItem, update); - } - Item* BankItem(uint16 pos, Item* pItem, bool update); + Item* BankItem(ItemPosCountVec const& dest, Item* pItem, bool update); void RemoveItem(uint8 bag, uint8 slot, bool update); void MoveItemFromInventory(uint8 bag, uint8 slot, bool update); // in trade, auction, guild bank, mail.... @@ -1493,16 +1458,8 @@ class Player : public Unit, public GridObject<Player> void AddArmorProficiency(uint32 newflag) { m_ArmorProficiency |= newflag; } uint32 GetWeaponProficiency() const { return m_WeaponProficiency; } uint32 GetArmorProficiency() const { return m_ArmorProficiency; } - bool IsUseEquipedWeapon(bool mainhand) const - { - // disarm applied only to mainhand weapon - return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED)); - } - bool IsTwoHandUsed() const - { - Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(); - } + bool IsUseEquipedWeapon(bool mainhand) const; + bool IsTwoHandUsed() const; void SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast = false); bool BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot); bool BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uint32 currency, uint32 count); @@ -1608,39 +1565,17 @@ class Player : public Unit, public GridObject<Player> void ResetSeasonalQuestStatus(uint16 event_id); uint16 FindQuestSlot(uint32 quest_id) const; - uint32 GetQuestSlotQuestId(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET); } - uint32 GetQuestSlotState(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET); } - uint16 GetQuestSlotCounter(uint16 slot, uint8 counter) const { return (uint16)(GetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET) >> (counter * 16)); } - uint32 GetQuestSlotTime(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET); } - void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer = 0) - { - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET, quest_id); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, 0); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET, 0); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET + 1, 0); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET, timer); - } - void SetQuestSlotCounter(uint16 slot, uint8 counter, uint16 count) - { - uint64 val = GetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET); - val &= ~((uint64)0xFFFF << (counter * 16)); - val |= ((uint64)count << (counter * 16)); - SetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET, val); - } - void SetQuestSlotState(uint16 slot, uint32 state) { SetFlag(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, state); } - void RemoveQuestSlotState(uint16 slot, uint32 state) { RemoveFlag(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, state); } - void SetQuestSlotTimer(uint16 slot, uint32 timer) { SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET, timer); } - void SwapQuestSlot(uint16 slot1, uint16 slot2) - { - for (int i = 0; i < MAX_QUEST_OFFSET; ++i) - { - uint32 temp1 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot1 + i); - uint32 temp2 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot2 + i); + uint32 GetQuestSlotQuestId(uint16 slot) const; + uint32 GetQuestSlotState(uint16 slot) const; + uint16 GetQuestSlotCounter(uint16 slot, uint8 counter) const; + uint32 GetQuestSlotTime(uint16 slot) const; + void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer = 0); + void SetQuestSlotCounter(uint16 slot, uint8 counter, uint16 count); + void SetQuestSlotState(uint16 slot, uint32 state); + void RemoveQuestSlotState(uint16 slot, uint32 state); + void SetQuestSlotTimer(uint16 slot, uint32 timer); + void SwapQuestSlot(uint16 slot1, uint16 slot2); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot1 + i, temp2); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot2 + i, temp1); - } - } uint16 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry); void AreaExploredOrEventHappens(uint32 questId); void GroupEventHappens(uint32 questId, WorldObject const* pEventObject); @@ -1740,31 +1675,17 @@ class Player : public Unit, public GridObject<Player> void setRegenTimerCount(uint32 time) {m_regenTimerCount = time;} void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;} - uint64 GetMoney() const { return GetUInt64Value(PLAYER_FIELD_COINAGE); } + uint64 GetMoney() const { return GetUInt32Value(PLAYER_FIELD_COINAGE); } bool ModifyMoney(int64 amount, bool sendError = true); - bool HasEnoughMoney(uint64 amount) const { return GetMoney() >= amount; } - bool HasEnoughMoney(int64 amount) const - { - if (amount > 0) - return (GetMoney() >= (uint64)amount); - return true; - } - - void SetMoney(uint64 value) - { - SetUInt64Value(PLAYER_FIELD_COINAGE, value); - MoneyChanged(value); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED); - } + bool HasEnoughMoney(uint64 amount) const { return (GetMoney() >= amount); } + bool HasEnoughMoney(int64 amount) const; + void SetMoney(uint64 value); RewardedQuestSet const& getRewardedQuests() const { return m_RewardedQuests; } QuestStatusMap& getQuestStatusMap() { return m_QuestStatus; } size_t GetRewardedQuestCount() const { return m_RewardedQuests.size(); } - bool IsQuestRewarded(uint32 quest_id) const - { - return m_RewardedQuests.find(quest_id) != m_RewardedQuests.end(); - } + bool IsQuestRewarded(uint32 quest_id) const; uint64 GetSelection() const { return m_curSelection; } Unit* GetSelectedUnit() const; @@ -1805,29 +1726,11 @@ class Player : public Unit, public GridObject<Player> ItemMap mMitems; //template defined in objectmgr.cpp - Item* GetMItem(uint32 id) - { - ItemMap::const_iterator itr = mMitems.find(id); - return itr != mMitems.end() ? itr->second : NULL; - } - - void AddMItem(Item* it) - { - ASSERT(it); - //ASSERT deleted, because items can be added before loading - mMitems[it->GetGUIDLow()] = it; - } + Item* GetMItem(uint32 id); + void AddMItem(Item* it); + bool RemoveMItem(uint32 id); - bool RemoveMItem(uint32 id) - { - return mMitems.erase(id) ? true : false; - } - - void SendOnCancelExpectedVehicleRideAura() - { - WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); - GetSession()->SendPacket(&data); - } + void SendOnCancelExpectedVehicleRideAura(); void PetSpellInitialize(); void CharmSpellInitialize(); void PossessSpellInitialize(); @@ -1891,12 +1794,9 @@ class Player : public Unit, public GridObject<Player> void InitGlyphsForLevel(); void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); } + uint32 GetGlyphSlot(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); } - void SetGlyph(uint8 slot, uint32 glyph) - { - _talentMgr->SpecInfo[GetActiveSpec()].Glyphs[slot] = glyph; - SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); - } + void SetGlyph(uint8 slot, uint32 glyph); uint32 GetGlyph(uint8 spec, uint8 slot) const { return _talentMgr->SpecInfo[spec].Glyphs[slot]; } PlayerTalentMap const* GetTalentMap(uint8 spec) const { return _talentMgr->SpecInfo[spec].Talents; } @@ -1923,17 +1823,8 @@ class Player : public Unit, public GridObject<Player> static uint32 const infinityCooldownDelay = MONTH; // used for set "infinity cooldowns" for spells and check static uint32 const infinityCooldownDelayCheck = MONTH/2; - bool HasSpellCooldown(uint32 spell_id) const - { - SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id); - return itr != m_spellCooldowns.end() && itr->second.end > time(NULL); - } - uint32 GetSpellCooldownDelay(uint32 spell_id) const - { - SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id); - time_t t = time(NULL); - return uint32(itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0); - } + bool HasSpellCooldown(uint32 spell_id) const; + uint32 GetSpellCooldownDelay(uint32 spell_id) const; void AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = NULL, bool infinityCooldown = false); void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = NULL, bool setCooldown = true); @@ -1953,17 +1844,7 @@ class Player : public Unit, public GridObject<Player> void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; } void UpdatePotionCooldown(Spell* spell = NULL); - void SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura) - { - ASSERT(!IsRessurectRequested()); - _resurrectionData = new ResurrectionData(); - _resurrectionData->GUID = caster->GetGUID(); - _resurrectionData->Location.WorldRelocate(*caster); - _resurrectionData->Health = health; - _resurrectionData->Mana = mana; - _resurrectionData->Aura = appliedAura; - } - + void SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura); void ClearResurrectRequestData() { delete _resurrectionData; @@ -1981,14 +1862,8 @@ class Player : public Unit, public GridObject<Player> bool IsRessurectRequested() const { return _resurrectionData != NULL; } void ResurectUsingRequestData(); - uint8 getCinematic() - { - return m_cinematic; - } - void setCinematic(uint8 cine) - { - m_cinematic = cine; - } + uint8 getCinematic() { return m_cinematic; } + void setCinematic(uint8 cine) { m_cinematic = cine; } ActionButton* addActionButton(uint8 button, uint32 action, uint8 type); void removeActionButton(uint8 button); @@ -1999,12 +1874,7 @@ class Player : public Unit, public GridObject<Player> PvPInfo pvpInfo; void UpdatePvPState(bool onlyFFA = false); - void SetPvP(bool state) - { - Unit::SetPvP(state); - for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) - (*itr)->SetPvP(state); - } + void SetPvP(bool state); void UpdatePvP(bool state, bool override=false); void UpdateZone(uint32 newZone, uint32 newArea); void UpdateArea(uint32 newArea); @@ -2016,12 +1886,7 @@ class Player : public Unit, public GridObject<Player> void UpdatePvPFlag(time_t currTime); void UpdateContestedPvP(uint32 currTime); void SetContestedPvPTimer(uint32 newTime) {m_contestedPvPTimer = newTime;} - void ResetContestedPvP() - { - ClearUnitState(UNIT_STATE_ATTACK_PLAYER); - RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP); - m_contestedPvPTimer = 0; - } + void ResetContestedPvP(); /** todo: -maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler.. **/ DuelInfo* duel; @@ -2032,7 +1897,7 @@ class Player : public Unit, public GridObject<Player> bool IsGroupVisibleFor(Player const* p) const; bool IsInSameGroupWith(Player const* p) const; - bool IsInSameRaidWith(Player const* p) const { return p == this || (GetGroup() != NULL && GetGroup() == p->GetGroup()); } + bool IsInSameRaidWith(Player const* p) const; void UninviteFromGroup(); static void RemoveFromGroup(Group* group, uint64 guid, RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT, uint64 kicker = 0, const char* reason = NULL); void RemoveFromGroup(RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT) { RemoveFromGroup(GetGroup(), GetGUID(), method); } @@ -2052,11 +1917,7 @@ class Player : public Unit, public GridObject<Player> static void RemovePetitionsAndSigns(uint64 guid, uint32 type); // Arena Team - void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type) - { - SetArenaTeamInfoField(slot, ARENA_TEAM_ID, ArenaTeamId); - SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type); - } + void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type); void SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value); static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot); static void LeaveAllArenaTeams(uint64 guid); @@ -2188,13 +2049,8 @@ class Player : public Unit, public GridObject<Player> uint32 DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank); void UpdateMirrorTimers(); - void StopMirrorTimers() - { - StopMirrorTimer(FATIGUE_TIMER); - StopMirrorTimer(BREATH_TIMER); - StopMirrorTimer(FIRE_TIMER); - } - bool IsMirrorTimerActive(MirrorTimerType type) { return m_MirrorTimer[type] == getMaxTimer(type); } + void StopMirrorTimers(); + bool IsMirrorTimerActive(MirrorTimerType type); bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone); @@ -2358,93 +2214,24 @@ class Player : public Unit, public GridObject<Player> m_bgData.bgQueuesJoinedTime.erase(m_bgData.bgQueuesJoinedTime.find(bgTypeId)->second); } - bool InBattlegroundQueue() const - { - for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - if (m_bgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_NONE) - return true; - return false; - } + bool InBattlegroundQueue() const; - BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const { return m_bgBattlegroundQueueID[index].bgQueueTypeId; } - uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const - { - for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) - return i; - return PLAYER_MAX_BATTLEGROUND_QUEUES; - } - bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const - { - for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) - return m_bgBattlegroundQueueID[i].invitedToInstance != 0; - return false; - } - bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const - { - return GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES; - } + BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const; + uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const; + bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const; + bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const; - void SetBattlegroundId(uint32 val, BattlegroundTypeId bgTypeId) - { - m_bgData.bgInstanceID = val; - m_bgData.bgTypeID = bgTypeId; - } - uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val) - { - for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - { - if (m_bgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE || m_bgBattlegroundQueueID[i].bgQueueTypeId == val) - { - m_bgBattlegroundQueueID[i].bgQueueTypeId = val; - m_bgBattlegroundQueueID[i].invitedToInstance = 0; - return i; - } - } - return PLAYER_MAX_BATTLEGROUND_QUEUES; - } - bool HasFreeBattlegroundQueueId() - { - for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - if (m_bgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE) - return true; - return false; - } - void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val) - { - for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - { - if (m_bgBattlegroundQueueID[i].bgQueueTypeId == val) - { - m_bgBattlegroundQueueID[i].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE; - m_bgBattlegroundQueueID[i].invitedToInstance = 0; - return; - } - } - } - void SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId) - { - for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - if (m_bgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId) - m_bgBattlegroundQueueID[i].invitedToInstance = instanceId; - } - bool IsInvitedForBattlegroundInstance(uint32 instanceId) const - { - for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - if (m_bgBattlegroundQueueID[i].invitedToInstance == instanceId) - return true; - return false; - } + void SetBattlegroundId(uint32 val, BattlegroundTypeId bgTypeId); + uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val); + bool HasFreeBattlegroundQueueId(); + void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val); + void SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId); + bool IsInvitedForBattlegroundInstance(uint32 instanceId) const; WorldLocation const& GetBattlegroundEntryPoint() const { return m_bgData.joinPos; } void SetBattlegroundEntryPoint(); - void SetBGTeam(uint32 team) - { - m_bgData.bgTeam = team; - SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? 1 : 0)); - } - uint32 GetBGTeam() const { return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); } + void SetBGTeam(uint32 team); + uint32 GetBGTeam() const; void LeaveBattleground(bool teleportToEntryPoint = true); bool CanJoinToBattleground(Battleground const* bg) const; @@ -2499,11 +2286,7 @@ class Player : public Unit, public GridObject<Player> void UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode); Unit* m_mover; WorldObject* m_seer; - void SetFallInformation(uint32 time, float z) - { - m_lastFallTime = time; - m_lastFallZ = z; - } + void SetFallInformation(uint32 time, float z); void HandleFall(MovementInfo const& movementInfo); bool IsKnowHowFlyIn(uint32 mapid, uint32 zone) const; @@ -2544,7 +2327,7 @@ class Player : public Unit, public GridObject<Player> typedef std::set<uint64> ClientGUIDs; ClientGUIDs m_clientGUIDs; - bool HaveAtClient(WorldObject const* u) const { return u == this || m_clientGUIDs.find(u->GetGUID()) != m_clientGUIDs.end(); } + bool HaveAtClient(WorldObject const* u) const; bool IsNeverVisible() const; @@ -2576,7 +2359,7 @@ class Player : public Unit, public GridObject<Player> void SetTemporaryUnsummonedPetNumber(uint32 petnumber) { m_temporaryUnsummonedPetNumber = petnumber; } void UnsummonPetTemporaryIfAny(); void ResummonPetTemporaryUnSummonedIfAny(); - bool IsPetNeedBeTemporaryUnsummoned() const { return !IsInWorld() || !isAlive() || IsMounted() /*+in flight*/; } + bool IsPetNeedBeTemporaryUnsummoned() const; void SendCinematicStart(uint32 CinematicSequenceId); void SendMovieStart(uint32 MovieId); @@ -2600,7 +2383,7 @@ class Player : public Unit, public GridObject<Player> void UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload = false); InstancePlayerBind* BindToInstance(InstanceSave* save, bool permanent, bool load = false); void BindToInstance(); - void SetPendingBind(uint32 instanceId, uint32 bindTimer) { _pendingBindId = instanceId; _pendingBindTimer = bindTimer; } + void SetPendingBind(uint32 instanceId, uint32 bindTimer); bool HasPendingBind() const { return _pendingBindId > 0; } void SendRaidInfo(); void SendSavedInstances(); @@ -2608,12 +2391,7 @@ class Player : public Unit, public GridObject<Player> bool Satisfy(AccessRequirement const* ar, uint32 target_map, bool report = false); bool CheckInstanceLoginValid(); bool CheckInstanceCount(uint32 instanceId) const; - - void AddInstanceEnterTime(uint32 instanceId, time_t enterTime) - { - if (_instanceResetTimes.find(instanceId) == _instanceResetTimes.end()) - _instanceResetTimes.insert(InstanceTimeMap::value_type(instanceId, enterTime + HOUR)); - } + void AddInstanceEnterTime(uint32 instanceId, time_t enterTime); // last used pet number (for BG's) uint32 GetLastPetNumber() const { return m_lastpetnumber; } @@ -2668,9 +2446,9 @@ class Player : public Unit, public GridObject<Player> void SetLastUsedRune(RuneType type) { m_runes->lastUsedRune = type; } void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; } void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; } - void SetRuneCooldown(uint8 index, uint32 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); } - void SetRuneConvertAura(uint8 index, AuraEffect const* aura) { m_runes->runes[index].ConvertAura = aura; } - void AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const* aura) { SetRuneConvertAura(index, aura); ConvertRune(index, newType); } + void SetRuneCooldown(uint8 index, uint32 cooldown); + void SetRuneConvertAura(uint8 index, AuraEffect const* aura); + void AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const* aura); void RemoveRunesByAuraEffect(AuraEffect const* aura); void RestoreBaseRune(uint8 index); void ConvertRune(uint8 index, RuneType newType); @@ -2720,38 +2498,7 @@ class Player : public Unit, public GridObject<Player> bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); } //! Return collision height sent to client - float GetCollisionHeight(bool mounted) - { - if (mounted) - { - CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID)); - if (!mountDisplayInfo) - return GetCollisionHeight(false); - - CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId); - if (!mountModelData) - return GetCollisionHeight(false); - - CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()); - ASSERT(displayInfo); - CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId); - ASSERT(modelData); - - float scaleMod = GetFloatValue(OBJECT_FIELD_SCALE_X); // 99% sure about this - - return scaleMod * mountModelData->MountHeight + modelData->CollisionHeight * 0.5f; - } - else - { - //! Dismounting case - use basic default model data - CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()); - ASSERT(displayInfo); - CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId); - ASSERT(modelData); - - return modelData->CollisionHeight; - } - } + float GetCollisionHeight(bool mounted) const; // Void Storage bool IsVoidStorageUnlocked() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); } @@ -2960,8 +2707,6 @@ class Player : public Unit, public GridObject<Player> int32 m_spellPenetrationItemMod; SpellModList m_spellMods[MAX_SPELLMOD]; - //uint32 m_pad; -// Spell* m_spellModTakingSpell; // Spell for which charges are dropped in spell::finish EnchantDurationList m_enchantDuration; ItemDurationList m_itemDuration; @@ -3071,12 +2816,7 @@ class Player : public Unit, public GridObject<Player> void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; } bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; } void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; } - - void ScheduleDelayedOperation(uint32 operation) - { - if (operation < DELAYED_END) - m_DelayedOperations |= operation; - } + void ScheduleDelayedOperation(uint32 operation) { if (operation < DELAYED_END) m_DelayedOperations |= operation; } MapReference m_mapRef; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 6421f6d07d3..f16aad73e42 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -451,6 +451,12 @@ void Unit::resetAttackTimer(WeaponAttackType type) m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); } +float Unit::GetMeleeReach() const +{ + float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; + return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; +} + bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const { if (!obj || !IsInMap(obj) || !InSamePhase(obj)) @@ -496,6 +502,26 @@ void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z, , 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)); } +AuraApplication * Unit::GetVisibleAura(uint8 slot) const +{ + VisibleAuraMap::const_iterator itr = m_visibleAuras.find(slot); + if (itr != m_visibleAuras.end()) + return itr->second; + return 0; +} + +void Unit::SetVisibleAura(uint8 slot, AuraApplication * aur) +{ + m_visibleAuras[slot]=aur; + UpdateAuraForGroup(slot); +} + +void Unit::RemoveVisibleAura(uint8 slot) +{ + m_visibleAuras.erase(slot); + UpdateAuraForGroup(slot); +} + void Unit::UpdateInterruptMask() { m_interruptMask = 0; @@ -2141,6 +2167,17 @@ int32 Unit::GetMechanicResistChance(const SpellInfo* spell) return resist_mech; } +bool Unit::CanUseAttackType(uint8 attacktype) const +{ + switch (attacktype) + { + case BASE_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + case OFF_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_OFFHAND); + case RANGED_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_RANGED); + } + return true; +} + // Melee based spells hit result calculations SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) { @@ -2441,6 +2478,11 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool Ca return SPELL_MISS_NONE; } +uint32 Unit::GetUnitMeleeSkill(Unit const* target) const +{ + return (target ? getLevelForTarget(target) : getLevel()) * 5; +} + float Unit::GetUnitDodgeChance() const { if (IsNonMeleeSpellCasted(false) || HasUnitState(UNIT_STATE_CONTROLLED)) @@ -3899,6 +3941,11 @@ AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 f return NULL; } +AuraEffect* Unit::GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const +{ + return GetAuraEffect(SPELL_AURA_DUMMY, name, iconId, effIndex); +} + AuraApplication * Unit::GetAuraApplication(uint32 spellId, uint64 casterGUID, uint64 itemCasterGUID, uint8 reqEffMask, AuraApplication * except) const { AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId); @@ -4421,6 +4468,45 @@ int32 Unit::GetMaxNegativeAuraModifierByAffectMask(AuraType auratype, SpellInfo return modifier; } +float Unit::GetResistanceBuffMods(SpellSchools school, bool positive) const +{ + return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school); +} + +void Unit::SetResistanceBuffMods(SpellSchools school, bool positive, float val) +{ + SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val); +} + +void Unit::ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) +{ + ApplyModSignedFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); +} + +void Unit::ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) +{ + ApplyPercentModFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); +} + +void Unit::InitStatBuffMods() +{ + for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) + SetFloatValue(UNIT_FIELD_POSSTAT0+i, 0); + for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) + SetFloatValue(UNIT_FIELD_NEGSTAT0+i, 0); +} + +void Unit::ApplyStatBuffMod(Stats stat, float val, bool apply) +{ + ApplyModSignedFloatValue((val > 0 ? UNIT_FIELD_POSSTAT0+stat : UNIT_FIELD_NEGSTAT0+stat), val, apply); +} + +void Unit::ApplyStatPercentBuffMod(Stats stat, float val, bool apply) +{ + ApplyPercentModFloatValue(UNIT_FIELD_POSSTAT0+stat, val, apply); + ApplyPercentModFloatValue(UNIT_FIELD_NEGSTAT0+stat, val, apply); +} + void Unit::_RegisterDynObject(DynamicObject* dynObj) { m_dynObj.push_back(dynObj); @@ -7883,6 +7969,27 @@ bool Unit::IsNeutralToAll() const return my_faction->IsNeutralToAll(); } +void Unit::_addAttacker(Unit* pAttacker) +{ + m_attackers.insert(pAttacker); +} + +void Unit::_removeAttacker(Unit* pAttacker) +{ + m_attackers.erase(pAttacker); +} + +Unit* Unit::getAttackerForHelper() const // If someone wants to help, who to give them +{ + if (getVictim() != NULL) + return getVictim(); + + if (!m_attackers.empty()) + return *(m_attackers.begin()); + + return NULL; +} + bool Unit::Attack(Unit* victim, bool meleeAttack) { if (!victim || victim == this) @@ -8273,6 +8380,19 @@ Unit* Unit::GetCharm() const return NULL; } +Unit* Unit::GetCharmerOrOwner() const +{ + return GetCharmerGUID() ? GetCharmer() : GetOwner(); +} + +Unit* Unit::GetCharmerOrOwnerOrSelf() const +{ + if (Unit* u = GetCharmerOrOwner()) + return u; + + return (Unit*)this; +} + void Unit::SetMinion(Minion *minion, bool apply) { sLog->outDebug(LOG_FILTER_UNITS, "SetMinion %u for %u, apply %u", minion->GetEntry(), GetEntry(), apply); @@ -8649,6 +8769,24 @@ void Unit::RemoveAllControlled() sLog->outFatal(LOG_FILTER_UNITS, "Unit %u is not able to release its charm " UI64FMTD, GetEntry(), GetCharmGUID()); } +bool Unit::isPossessedByPlayer() const +{ + return HasUnitState(UNIT_STATE_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); +} + +bool Unit::isPossessing(Unit* u) const +{ + return u->isPossessed() && GetCharmGUID() == u->GetGUID(); +} + +bool Unit::isPossessing() const +{ + if (Unit* u = GetCharm()) + return u->isPossessed(); + else + return false; +} + Unit* Unit::GetNextRandomRaidMemberOrPet(float radius) { Player* player = NULL; @@ -10342,6 +10480,15 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const return NULL; } +bool Unit::isServiceProvider() const +{ + return HasFlag(UNIT_NPC_FLAGS, + UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER | + UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER | + UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_SPIRITHEALER | + UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER); +} + void Unit::SetInCombatWith(Unit* enemy) { Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf(); @@ -10811,6 +10958,12 @@ int32 Unit::ModifyPowerPct(Powers power, float pct, bool apply) return ModifyPower(power, (int32)amount - GetMaxPower(power)); } +uint32 Unit::GetAttackTime(WeaponAttackType att) const +{ + float f_BaseAttackTime = GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att) / m_modAttackSpeedPct[att]; + return (uint32)f_BaseAttackTime; +} + bool Unit::IsAlwaysVisibleFor(WorldObject const* seer) const { if (WorldObject::IsAlwaysVisibleFor(seer)) @@ -10841,6 +10994,11 @@ bool Unit::IsAlwaysDetectableFor(WorldObject const* seer) const return false; } +bool Unit::IsVisible() const +{ + return (m_serverSideVisibility.GetValue(SERVERSIDE_VISIBILITY_GM) > SEC_PLAYER) ? false : true; +} + void Unit::SetVisible(bool x) { if (!x) @@ -12054,6 +12212,30 @@ uint32 Unit::GetCreatureType() const return ToCreature()->GetCreatureTemplate()->type; } +uint32 Unit::GetCreatureTypeMask() const +{ + uint32 creatureType = GetCreatureType(); + return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0; +} + +void Unit::SetShapeshiftForm(ShapeshiftForm form) +{ + SetByteValue(UNIT_FIELD_BYTES_2, 3, form); +} + +bool Unit::IsInFeralForm() const +{ + ShapeshiftForm form = GetShapeshiftForm(); + return form == FORM_CAT || form == FORM_BEAR; +} + +bool Unit::IsInDisallowedMountForm() const +{ + ShapeshiftForm form = GetShapeshiftForm(); + return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE && + form != FORM_SHADOW && form != FORM_STEALTH && form != FORM_UNDEAD; +} + /*####################################### ######## ######## ######## STAT SYSTEM ######## @@ -12252,6 +12434,12 @@ float Unit::GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange typ return m_weaponDamage[attType][type]; } +bool Unit::CanFreeMove() const +{ + return !HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | + UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED) && GetOwnerGUID() == 0; +} + void Unit::SetLevel(uint8 lvl) { SetUInt32Value(UNIT_FIELD_LEVEL, lvl); @@ -13379,6 +13567,18 @@ SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const return SPELL_SCHOOL_MASK_NORMAL; } +uint64 Unit::GetCharmerOrOwnerGUID() const +{ + return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); +} + +uint64 Unit::GetCharmerOrOwnerOrOwnGUID() const +{ + if (uint64 guid = GetCharmerOrOwnerGUID()) + return guid; + return GetGUID(); +} + Player* Unit::GetSpellModOwner() const { if (GetTypeId() == TYPEID_PLAYER) @@ -13819,6 +14019,17 @@ void Unit::UpdateAuraForGroup(uint8 slot) } } +void Unit::SetCantProc(bool apply) +{ + if (apply) + ++m_procDeep; + else + { + ASSERT(m_procDeep); + --m_procDeep; + } +} + float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffectType damagetype) const { // Damage over Time spells bonus calculation @@ -14463,6 +14674,15 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) } } +float Unit::GetPositionZMinusOffset() const +{ + float offset = 0.0f; + if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) + offset = GetFloatValue(UNIT_FIELD_HOVERHEIGHT); + + return GetPositionZ() - offset; +} + void Unit::SetControlled(bool apply, UnitState state) { if (apply) @@ -15061,6 +15281,11 @@ void Unit::RestoreFaction() } } +Unit* Unit::GetRedirectThreatTarget() +{ + return _redirectThreadInfo.GetTargetGUID() ? GetUnit(*this, _redirectThreadInfo.GetTargetGUID()) : NULL; +} + bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry) { VehicleEntry const* vehInfo = sVehicleStore.LookupEntry(id); @@ -15089,6 +15314,11 @@ void Unit::RemoveVehicleKit() RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); } +bool Unit::IsOnVehicle(const Unit* vehicle) const +{ + return m_vehicle && m_vehicle == vehicle->GetVehicleKit(); +} + Unit* Unit::GetVehicleBase() const { return m_vehicle ? m_vehicle->GetBase() : NULL; @@ -15195,6 +15425,22 @@ void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap) } } +bool Unit::IsContestedGuard() const +{ + if (FactionTemplateEntry const* entry = getFactionTemplateEntry()) + return entry->IsContestedGuardFaction(); + + return false; +} + +void Unit::SetPvP(bool state) +{ + if (state) + SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); + else + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); +} + Aura* Unit::AddAura(uint32 spellId, Unit* target) { if (!target) @@ -16865,6 +17111,11 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel return (relocated || turn); } +bool Unit::UpdatePosition(const Position &pos, bool teleport) +{ + return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); +} + //! Only server-side orientation update, does not broadcast to client void Unit::UpdateOrientation(float orientation) { @@ -17140,7 +17391,7 @@ bool CharmInfo::IsReturning() return _isReturning; } -void Unit::SetInFront(Unit const* target) +void Unit::SetInFront(WorldObject const* target) { if (!HasUnitState(UNIT_STATE_CANNOT_TURN)) SetOrientation(GetAngle(target)); @@ -17287,16 +17538,25 @@ bool Unit::IsSplineEnabled() const return movespline->Initialized(); } -void Unit::FocusTarget(Spell const* focusSpell, uint64 target) +void Unit::SetTarget(uint64 guid) +{ + if (!_focusSpell) + SetUInt64Value(UNIT_FIELD_TARGET, guid); +} + +void Unit::FocusTarget(Spell const* focusSpell, WorldObject const* target) { // already focused if (_focusSpell) return; _focusSpell = focusSpell; - SetUInt64Value(UNIT_FIELD_TARGET, target); + SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID()); if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) AddUnitState(UNIT_STATE_ROTATING); + + // Set serverside orientation if needed (needs to be after attribute check) + SetInFront(target); } void Unit::ReleaseFocus(Spell const* focusSpell) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index c2fd3494c79..c20fd6a3417 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -982,8 +982,8 @@ struct RedirectThreatInfo uint64 _targetGUID; uint32 _threatPct; - uint64 GetTargetGUID() { return _targetGUID; } - uint32 GetThreatPct() { return _threatPct; } + uint64 GetTargetGUID() const { return _targetGUID; } + uint32 GetThreatPct() const { return _threatPct; } void Set(uint64 guid, uint32 pct) { @@ -1286,31 +1286,16 @@ class Unit : public WorldObject bool CanDualWield() const { return m_canDualWield; } void SetCanDualWield(bool value) { m_canDualWield = value; } float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; } - float GetMeleeReach() const { float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; } + float GetMeleeReach() const; bool IsWithinCombatRange(const Unit* obj, float dist2compare) const; bool IsWithinMeleeRange(const Unit* obj, float dist = MELEE_RANGE) const; void GetRandomContactPoint(const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const; uint32 m_extraAttacks; bool m_canDualWield; - void _addAttacker(Unit* pAttacker) // must be called only from Unit::Attack(Unit*) - { - m_attackers.insert(pAttacker); - } - void _removeAttacker(Unit* pAttacker) // must be called only from Unit::AttackStop() - { - m_attackers.erase(pAttacker); - } - Unit* getAttackerForHelper() const // If someone wants to help, who to give them - { - if (getVictim() != NULL) - return getVictim(); - - if (!m_attackers.empty()) - return *(m_attackers.begin()); - - return NULL; - } + void _addAttacker(Unit* pAttacker); // must be called only from Unit::Attack(Unit*) + void _removeAttacker(Unit* pAttacker); // must be called only from Unit::AttackStop() + Unit* getAttackerForHelper() const; // If someone wants to help, who to give them bool Attack(Unit* victim, bool meleeAttack); void CastStop(uint32 except_spellid = 0); bool AttackStop(); @@ -1329,11 +1314,7 @@ class Unit : public WorldObject void AddUnitState(uint32 f) { m_state |= f; } bool HasUnitState(const uint32 f) const { return (m_state & f); } void ClearUnitState(uint32 f) { m_state &= ~f; } - bool CanFreeMove() const - { - return !HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | - UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED) && GetOwnerGUID() == 0; - } + bool CanFreeMove() const; uint32 HasUnitTypeMask(uint32 mask) const { return mask & m_unitTypeMask; } void AddUnitTypeMask(uint32 mask) { m_unitTypeMask |= mask; } @@ -1391,12 +1372,7 @@ class Unit : public WorldObject int32 ModifyPower(Powers power, int32 val); int32 ModifyPowerPct(Powers power, float pct, bool apply = true); - uint32 GetAttackTime(WeaponAttackType att) const - { - float f_BaseAttackTime = GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att) / m_modAttackSpeedPct[att]; - return (uint32)f_BaseAttackTime; - } - + uint32 GetAttackTime(WeaponAttackType att) const; void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(UNIT_FIELD_BASEATTACKTIME+att, val*m_modAttackSpeedPct[att]); } void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply); void ApplyCastTimePercentMod(float val, bool apply); @@ -1419,27 +1395,11 @@ class Unit : public WorldObject bool IsInPartyWith(Unit const* unit) const; bool IsInRaidWith(Unit const* unit) const; void GetPartyMembers(std::list<Unit*> &units); - bool IsContestedGuard() const - { - if (FactionTemplateEntry const* entry = getFactionTemplateEntry()) - return entry->IsContestedGuardFaction(); - - return false; - } + bool IsContestedGuard() const; bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); } - void SetPvP(bool state) - { - if (state) - SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - else - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - } + void SetPvP(bool state); uint32 GetCreatureType() const; - uint32 GetCreatureTypeMask() const - { - uint32 creatureType = GetCreatureType(); - return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0; - } + uint32 GetCreatureTypeMask() const; uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); } bool IsSitState() const; @@ -1499,20 +1459,12 @@ class Unit : public WorldObject float GetUnitMissChance(WeaponAttackType attType) const; float GetUnitCriticalChance(WeaponAttackType attackType, const Unit* victim) const; int32 GetMechanicResistChance(const SpellInfo* spell); - bool CanUseAttackType(uint8 attacktype) const - { - switch (attacktype) - { - case BASE_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); - case OFF_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_OFFHAND); - case RANGED_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_RANGED); - } - return true; - } + bool CanUseAttackType(uint8 attacktype) const; virtual uint32 GetBlockPercent() { return 30; } - uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } + uint32 GetUnitMeleeSkill(Unit const* target = NULL) const; + float GetWeaponProcChance() const; float GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellInfo* spellProto) const; @@ -1533,14 +1485,7 @@ class Unit : public WorldObject bool isTabardDesigner()const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TABARDDESIGNER); } bool isAuctioner() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER); } bool isArmorer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR); } - bool isServiceProvider() const - { - return HasFlag(UNIT_NPC_FLAGS, - UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER | - UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER | - UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_SPIRITHEALER | - UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER); - } + bool isServiceProvider() const; bool isSpiritService() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); } bool isInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); } @@ -1615,7 +1560,7 @@ class Unit : public WorldObject void SendTeleportPacket(Position& pos); virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport = false); // returns true if unit's position really changed - bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } + bool UpdatePosition(const Position &pos, bool teleport = false); void UpdateOrientation(float orientation); void UpdateHeight(float newZ); @@ -1646,7 +1591,7 @@ class Unit : public WorldObject virtual bool SetDisableGravity(bool disable, bool packetOnly = false); virtual bool SetHover(bool enable); - void SetInFront(Unit const* target); + void SetInFront(WorldObject const* target); void SetFacingTo(float ori); void SetFacingToObject(WorldObject* object); @@ -1680,13 +1625,8 @@ class Unit : public WorldObject uint64 GetCritterGUID() const { return GetUInt64Value(UNIT_FIELD_CRITTER); } bool IsControlledByPlayer() const { return m_ControlledByPlayer; } - uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); } - uint64 GetCharmerOrOwnerOrOwnGUID() const - { - if (uint64 guid = GetCharmerOrOwnerGUID()) - return guid; - return GetGUID(); - } + uint64 GetCharmerOrOwnerGUID() const; + uint64 GetCharmerOrOwnerOrOwnGUID() const; bool isCharmedOwnedByPlayerOrPlayer() const { return IS_PLAYER_GUID(GetCharmerOrOwnerOrOwnGUID()); } Player* GetSpellModOwner() const; @@ -1696,14 +1636,8 @@ class Unit : public WorldObject Minion *GetFirstMinion() const; Unit* GetCharmer() const; Unit* GetCharm() const; - Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); } - Unit* GetCharmerOrOwnerOrSelf() const - { - if (Unit* u = GetCharmerOrOwner()) - return u; - - return (Unit*)this; - } + Unit* GetCharmerOrOwner() const; + Unit* GetCharmerOrOwnerOrSelf() const; Player* GetCharmerOrOwnerPlayerOrPlayerItself() const; Player* GetAffectingPlayer() const; @@ -1722,15 +1656,9 @@ class Unit : public WorldObject bool isCharmed() const { return GetCharmerGUID() != 0; } bool isPossessed() const { return HasUnitState(UNIT_STATE_POSSESSED); } - bool isPossessedByPlayer() const { return HasUnitState(UNIT_STATE_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); } - bool isPossessing() const - { - if (Unit* u = GetCharm()) - return u->isPossessed(); - else - return false; - } - bool isPossessing(Unit* u) const { return u->isPossessed() && GetCharmGUID() == u->GetGUID(); } + bool isPossessedByPlayer() const; + bool isPossessing() const; + bool isPossessing(Unit* u) const; CharmInfo* GetCharmInfo() { return m_charmInfo; } CharmInfo* InitCharmInfo(); @@ -1813,7 +1741,7 @@ class Unit : public WorldObject AuraEffect* GetAuraEffectOfRankedSpell(uint32 spellId, uint8 effIndex, uint64 casterGUID = 0) const; AuraEffect* GetAuraEffect(AuraType type, SpellFamilyNames name, uint32 iconId, uint8 effIndex) const; // spell mustn't have familyflags AuraEffect* GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID =0); - inline AuraEffect* GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const { return GetAuraEffect(SPELL_AURA_DUMMY, name, iconId, effIndex);} + AuraEffect* GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const; AuraApplication * GetAuraApplication(uint32 spellId, uint64 casterGUID = 0, uint64 itemCasterGUID = 0, uint8 reqEffMask = 0, AuraApplication * except = NULL) const; Aura* GetAura(uint32 spellId, uint64 casterGUID = 0, uint64 itemCasterGUID = 0, uint8 reqEffMask = 0) const; @@ -1859,21 +1787,13 @@ class Unit : public WorldObject int32 GetMaxPositiveAuraModifierByAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const; int32 GetMaxNegativeAuraModifierByAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const; - float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school); } - void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val); } - void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) { ApplyModSignedFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } - void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) { ApplyPercentModFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } - void InitStatBuffMods() - { - for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_POSSTAT0+i, 0); - for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_NEGSTAT0+i, 0); - } - void ApplyStatBuffMod(Stats stat, float val, bool apply) { ApplyModSignedFloatValue((val > 0 ? UNIT_FIELD_POSSTAT0+stat : UNIT_FIELD_NEGSTAT0+stat), val, apply); } - void ApplyStatPercentBuffMod(Stats stat, float val, bool apply) - { - ApplyPercentModFloatValue(UNIT_FIELD_POSSTAT0+stat, val, apply); - ApplyPercentModFloatValue(UNIT_FIELD_NEGSTAT0+stat, val, apply); - } + float GetResistanceBuffMods(SpellSchools school, bool positive) const; + void SetResistanceBuffMods(SpellSchools school, bool positive, float val); + void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply); + void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply); + void InitStatBuffMods(); + void ApplyStatBuffMod(Stats stat, float val, bool apply); + void ApplyStatPercentBuffMod(Stats stat, float val, bool apply); void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; } void SetCreateHealth(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_HEALTH, val); } uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); } @@ -1909,23 +1829,11 @@ class Unit : public WorldObject uint64 m_ObjectSlot[MAX_GAMEOBJECT_SLOT]; ShapeshiftForm GetShapeshiftForm() const { return ShapeshiftForm(GetByteValue(UNIT_FIELD_BYTES_2, 3)); } - void SetShapeshiftForm(ShapeshiftForm form) - { - SetByteValue(UNIT_FIELD_BYTES_2, 3, form); - } + void SetShapeshiftForm(ShapeshiftForm form); - inline bool IsInFeralForm() const - { - ShapeshiftForm form = GetShapeshiftForm(); - return form == FORM_CAT || form == FORM_BEAR; - } + bool IsInFeralForm() const; - inline bool IsInDisallowedMountForm() const - { - ShapeshiftForm form = GetShapeshiftForm(); - return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE && - form != FORM_SHADOW && form != FORM_STEALTH && form != FORM_UNDEAD; - } + bool IsInDisallowedMountForm() const; float m_modMeleeHitChance; float m_modRangedHitChance; @@ -1965,7 +1873,7 @@ class Unit : public WorldObject bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const; // Visibility system - bool IsVisible() const { return (m_serverSideVisibility.GetValue(SERVERSIDE_VISIBILITY_GM) > SEC_PLAYER) ? false : true; } + bool IsVisible() const; void SetVisible(bool x); // common function for visibility checks for player/creatures with detection code @@ -1988,23 +1896,17 @@ class Unit : public WorldObject HostileRefManager& getHostileRefManager() { return m_HostileRefManager; } VisibleAuraMap const* GetVisibleAuras() { return &m_visibleAuras; } - AuraApplication * GetVisibleAura(uint8 slot) - { - VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); - if (itr != m_visibleAuras.end()) - return itr->second; - return 0; - } - void SetVisibleAura(uint8 slot, AuraApplication * aur){ m_visibleAuras[slot]=aur; UpdateAuraForGroup(slot);} - void RemoveVisibleAura(uint8 slot){ m_visibleAuras.erase(slot); UpdateAuraForGroup(slot);} + AuraApplication * GetVisibleAura(uint8 slot) const; + void SetVisibleAura(uint8 slot, AuraApplication * aur); + void RemoveVisibleAura(uint8 slot); uint32 GetInterruptMask() const { return m_interruptMask; } void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } void UpdateInterruptMask(); - uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } + uint32 GetDisplayId() const { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } void SetDisplayId(uint32 modelId); - uint32 GetNativeDisplayId() { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } + uint32 GetNativeDisplayId() const { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } void RestoreDisplayId(); void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); } void setTransForm(uint32 spellid) { m_transform = spellid;} @@ -2111,14 +2013,7 @@ class Unit : public WorldObject void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; } bool IsSplineEnabled() const; - float GetPositionZMinusOffset() const - { - float offset = 0.0f; - if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - offset = GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - - return GetPositionZ() - offset; - } + float GetPositionZMinusOffset() const; void SetControlled(bool apply, UnitState state); @@ -2144,17 +2039,8 @@ class Unit : public WorldObject void UpdateAuraForGroup(uint8 slot); // proc trigger system - bool CanProc(){return !m_procDeep;} - void SetCantProc(bool apply) - { - if (apply) - ++m_procDeep; - else - { - ASSERT(m_procDeep); - --m_procDeep; - } - } + bool CanProc() const {return !m_procDeep;} + void SetCantProc(bool apply); // pet auras typedef std::set<PetAura const*> PetAuraSet; @@ -2169,8 +2055,8 @@ class Unit : public WorldObject void SetRedirectThreat(uint64 guid, uint32 pct) { _redirectThreadInfo.Set(guid, pct); } void ResetRedirectThreat() { SetRedirectThreat(0, 0); } void ModifyRedirectThreat(int32 amount) { _redirectThreadInfo.ModifyThreatPct(amount); } - uint32 GetRedirectThreatPercent() { return _redirectThreadInfo.GetThreatPct(); } - Unit* GetRedirectThreatTarget() { return _redirectThreadInfo.GetTargetGUID() ? GetUnit(*this, _redirectThreadInfo.GetTargetGUID()) : NULL; } + uint32 GetRedirectThreatPercent() const { return _redirectThreadInfo.GetThreatPct(); } + Unit* GetRedirectThreatTarget(); friend class VehicleJoinEvent; bool IsAIEnabled, NeedChangeAI; @@ -2178,7 +2064,7 @@ class Unit : public WorldObject void RemoveVehicleKit(); Vehicle* GetVehicleKit()const { return m_vehicleKit; } Vehicle* GetVehicle() const { return m_vehicle; } - bool IsOnVehicle(const Unit* vehicle) const { return m_vehicle && m_vehicle == vehicle->GetVehicleKit(); } + bool IsOnVehicle(const Unit* vehicle) const; Unit* GetVehicleBase() const; Creature* GetVehicleCreatureBase() const; float GetTransOffsetX() const { return m_movementInfo.t_pos.GetPositionX(); } @@ -2229,14 +2115,10 @@ class Unit : public WorldObject TempSummon* ToTempSummon() { if (isSummon()) return reinterpret_cast<TempSummon*>(this); else return NULL; } TempSummon const* ToTempSummon() const { if (isSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; } - void SetTarget(uint64 guid) - { - if (!_focusSpell) - SetUInt64Value(UNIT_FIELD_TARGET, guid); - } + void SetTarget(uint64 guid); // Handling caster facing during spellcast - void FocusTarget(Spell const* focusSpell, uint64 target); + void FocusTarget(Spell const* focusSpell, WorldObject const* target); void ReleaseFocus(Spell const* focusSpell); // Movement info diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 9a28de30104..f3762b0aa9d 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7672,13 +7672,13 @@ uint32 ObjectMgr::GetAreaTriggerScriptId(uint32 trigger_id) return 0; } -SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds(uint32 spell_id) +SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds(uint32 spellId) { - return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id)); + return SpellScriptsBounds(_spellScriptsStore.equal_range(spellId)); } // this allows calculating base reputations to offline players, just by race and class -int32 ObjectMgr::GetBaseReputationOff(FactionEntry const* factionEntry, uint8 race, uint8 playerClass) +int32 ObjectMgr::GetBaseReputationOf(FactionEntry const* factionEntry, uint8 race, uint8 playerClass) { if (!factionEntry) return 0; @@ -8595,11 +8595,11 @@ void ObjectMgr::LoadFactionChangeAchievements() uint32 horde = fields[1].GetUInt32(); if (!sAchievementMgr->GetAchievement(alliance)) - sLog->outError(LOG_FILTER_SQL, "Achievement %u referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance); + sLog->outError(LOG_FILTER_SQL, "Achievement %u (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance); else if (!sAchievementMgr->GetAchievement(horde)) - sLog->outError(LOG_FILTER_SQL, "Achievement %u referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde); + sLog->outError(LOG_FILTER_SQL, "Achievement %u (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde); else - FactionChange_Achievements[alliance] = horde; + FactionChangeAchievements[alliance] = horde; ++count; } @@ -8630,11 +8630,11 @@ void ObjectMgr::LoadFactionChangeItems() uint32 horde = fields[1].GetUInt32(); if (!GetItemTemplate(alliance)) - sLog->outError(LOG_FILTER_SQL, "Item %u referenced in `player_factionchange_items` does not exist, pair skipped!", alliance); + sLog->outError(LOG_FILTER_SQL, "Item %u (alliance_id) referenced in `player_factionchange_items` does not exist, pair skipped!", alliance); else if (!GetItemTemplate(horde)) - sLog->outError(LOG_FILTER_SQL, "Item %u referenced in `player_factionchange_items` does not exist, pair skipped!", horde); + sLog->outError(LOG_FILTER_SQL, "Item %u (horde_id) referenced in `player_factionchange_items` does not exist, pair skipped!", horde); else - FactionChange_Items[alliance] = horde; + FactionChangeItems[alliance] = horde; ++count; } @@ -8643,15 +8643,15 @@ void ObjectMgr::LoadFactionChangeItems() sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change item pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadFactionChangeSpells() +void ObjectMgr::LoadFactionChangeQuests() { uint32 oldMSTime = getMSTime(); - QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells"); + QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_quests"); if (!result) { - sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty."); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty."); return; } @@ -8664,18 +8664,18 @@ void ObjectMgr::LoadFactionChangeSpells() uint32 alliance = fields[0].GetUInt32(); uint32 horde = fields[1].GetUInt32(); - if (!sSpellMgr->GetSpellInfo(alliance)) - sLog->outError(LOG_FILTER_SQL, "Spell %u referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance); - else if (!sSpellMgr->GetSpellInfo(horde)) - sLog->outError(LOG_FILTER_SQL, "Spell %u referenced in `player_factionchange_spells` does not exist, pair skipped!", horde); + if (!sObjectMgr->GetQuestTemplate(alliance)) + sLog->outError(LOG_FILTER_SQL, "Quest %u (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance); + else if (!sObjectMgr->GetQuestTemplate(horde)) + sLog->outError(LOG_FILTER_SQL, "Quest %u (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde); else - FactionChange_Spells[alliance] = horde; + FactionChangeQuests[alliance] = horde; ++count; } while (result->NextRow()); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change spell pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change quest pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadFactionChangeReputations() @@ -8700,11 +8700,11 @@ void ObjectMgr::LoadFactionChangeReputations() uint32 horde = fields[1].GetUInt32(); if (!sFactionStore.LookupEntry(alliance)) - sLog->outError(LOG_FILTER_SQL, "Reputation %u referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance); + sLog->outError(LOG_FILTER_SQL, "Reputation %u (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance); else if (!sFactionStore.LookupEntry(horde)) - sLog->outError(LOG_FILTER_SQL, "Reputation %u referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde); + sLog->outError(LOG_FILTER_SQL, "Reputation %u (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde); else - FactionChange_Reputation[alliance] = horde; + FactionChangeReputation[alliance] = horde; ++count; } @@ -8738,6 +8738,7 @@ void ObjectMgr::LoadHotfixData() info.Type = fields[1].GetUInt32(); info.Timestamp = fields[2].GetUInt64(); _hotfixData.push_back(info); + ++count; } while (result->NextRow()); @@ -8745,6 +8746,41 @@ void ObjectMgr::LoadHotfixData() sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadFactionChangeSpells() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells"); + + if (!result) + { + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty."); + return; + } + + uint32 count = 0; + + do + { + Field* fields = result->Fetch(); + + uint32 alliance = fields[0].GetUInt32(); + uint32 horde = fields[1].GetUInt32(); + + if (!sSpellMgr->GetSpellInfo(alliance)) + sLog->outError(LOG_FILTER_SQL, "Spell %u (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance); + else if (!sSpellMgr->GetSpellInfo(horde)) + sLog->outError(LOG_FILTER_SQL, "Spell %u (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde); + else + FactionChangeSpells[alliance] = horde; + + ++count; + } + while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change spell pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadFactionChangeTitles() { uint32 oldMSTime = getMSTime(); @@ -8767,11 +8803,11 @@ void ObjectMgr::LoadFactionChangeTitles() uint32 horde = fields[1].GetUInt32(); if (!sCharTitlesStore.LookupEntry(alliance)) - sLog->outError(LOG_FILTER_SQL, "Title %u referenced in `player_factionchange_title` does not exist, pair skipped!", alliance); + sLog->outError(LOG_FILTER_SQL, "Title %u (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance); else if (!sCharTitlesStore.LookupEntry(horde)) - sLog->outError(LOG_FILTER_SQL, "Title %u referenced in `player_factionchange_title` does not exist, pair skipped!", horde); + sLog->outError(LOG_FILTER_SQL, "Title %u (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde); else - FactionChange_Titles[alliance] = horde; + FactionChangeTitles[alliance] = horde; ++count; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index d1413ac9fa1..50d9baf292a 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -775,7 +775,7 @@ class ObjectMgr AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const; uint32 GetAreaTriggerScriptId(uint32 trigger_id); - SpellScriptsBounds GetSpellScriptsBounds(uint32 spell_id); + SpellScriptsBounds GetSpellScriptsBounds(uint32 spellId); RepRewardRate const* GetRepRewardRate(uint32 factionId) const { @@ -794,7 +794,7 @@ class ObjectMgr return NULL; } - int32 GetBaseReputationOff(FactionEntry const* factionEntry, uint8 race, uint8 playerClass); + int32 GetBaseReputationOf(FactionEntry const* factionEntry, uint8 race, uint8 playerClass); RepSpilloverTemplate const* GetRepSpilloverTemplate(uint32 factionId) const { @@ -1212,16 +1212,18 @@ class ObjectMgr value = data[loc_idx]; } - CharacterConversionMap FactionChange_Achievements; - CharacterConversionMap FactionChange_Items; - CharacterConversionMap FactionChange_Spells; - CharacterConversionMap FactionChange_Reputation; - CharacterConversionMap FactionChange_Titles; + CharacterConversionMap FactionChangeAchievements; + CharacterConversionMap FactionChangeItems; + CharacterConversionMap FactionChangeQuests; + CharacterConversionMap FactionChangeReputation; + CharacterConversionMap FactionChangeSpells; + CharacterConversionMap FactionChangeTitles; void LoadFactionChangeAchievements(); void LoadFactionChangeItems(); - void LoadFactionChangeSpells(); + void LoadFactionChangeQuests(); void LoadFactionChangeReputations(); + void LoadFactionChangeSpells(); void LoadFactionChangeTitles(); void LoadHotfixData(); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index a647a9098e0..71c16d6029e 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1990,44 +1990,6 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) trans->Append(stmt); } - // Delete all current quests - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS); - stmt->setUInt32(0, GUID_LOPART(guid)); - trans->Append(stmt); - - // Delete record of the faction old completed quests - { - std::ostringstream quests; - ObjectMgr::QuestMap const& questTemplate = sObjectMgr->GetQuestTemplates(); - for (ObjectMgr::QuestMap::const_iterator iter = questTemplate.begin(); iter != questTemplate.end(); ++iter) - { - Quest* questInfo = iter->second; - uint32 requiredRaces = questInfo->GetRequiredRaces(); - if (team == TEAM_ALLIANCE) - { - if (requiredRaces & RACEMASK_ALLIANCE) - { - quests << uint32(questInfo->GetQuestId()); - quests << ','; - } - } - else // if (team == TEAM_HORDE) - { - if (requiredRaces & RACEMASK_HORDE) - { - quests << uint32(questInfo->GetQuestId()); - quests << ','; - } - } - } - - std::string questsStr = quests.str(); - questsStr = questsStr.substr(0, questsStr.length() - 1); - - if (!questsStr.empty()) - trans->PAppend("DELETE FROM `character_queststatus_rewarded` WHERE guid='%u' AND quest IN (%s)", lowGuid, questsStr.c_str()); - } - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) { // Reset guild @@ -2085,7 +2047,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) trans->Append(stmt); // Achievement conversion - for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Achievements.begin(); it != sObjectMgr->FactionChange_Achievements.end(); ++it) + for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeAchievements.begin(); it != sObjectMgr->FactionChangeAchievements.end(); ++it) { uint32 achiev_alliance = it->first; uint32 achiev_horde = it->second; @@ -2103,7 +2065,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } // Item conversion - for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Items.begin(); it != sObjectMgr->FactionChange_Items.end(); ++it) + for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeItems.begin(); it != sObjectMgr->FactionChangeItems.end(); ++it) { uint32 item_alliance = it->first; uint32 item_horde = it->second; @@ -2115,8 +2077,53 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) trans->Append(stmt); } + // Delete all current quests + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS); + stmt->setUInt32(0, GUID_LOPART(guid)); + trans->Append(stmt); + + // Quest conversion + for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeQuests.begin(); it != sObjectMgr->FactionChangeQuests.end(); ++it) + { + uint32 quest_alliance = it->first; + uint32 quest_horde = it->second; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST); + stmt->setUInt32(0, lowGuid); + stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE); + stmt->setUInt32(0, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde)); + stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_horde : quest_alliance)); + stmt->setUInt32(2, lowGuid); + trans->Append(stmt); + } + + // Mark all rewarded quests as "active" (will count for completed quests achievements) + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE); + stmt->setUInt32(0, lowGuid); + trans->Append(stmt); + + // Disable all old-faction specific quests + { + ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates(); + for (ObjectMgr::QuestMap::const_iterator iter = questTemplates.begin(); iter != questTemplates.end(); ++iter) + { + Quest const* quest = iter->second; + uint32 newRaceMask = (team == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE; + if (!(quest->GetRequiredRaces() & newRaceMask)) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST); + stmt->setUInt32(0, lowGuid); + stmt->setUInt32(1, quest->GetQuestId()); + trans->Append(stmt); + } + } + } + // Spell conversion - for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Spells.begin(); it != sObjectMgr->FactionChange_Spells.end(); ++it) + for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeSpells.begin(); it != sObjectMgr->FactionChangeSpells.end(); ++it) { uint32 spell_alliance = it->first; uint32 spell_horde = it->second; @@ -2134,7 +2141,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } // Reputation conversion - for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Reputation.begin(); it != sObjectMgr->FactionChange_Reputation.end(); ++it) + for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeReputation.begin(); it != sObjectMgr->FactionChangeReputation.end(); ++it) { uint32 reputation_alliance = it->first; uint32 reputation_horde = it->second; @@ -2160,10 +2167,10 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation); // old base reputation - int32 oldBaseRep = sObjectMgr->GetBaseReputationOff(factionEntry, oldRace, playerClass); + int32 oldBaseRep = sObjectMgr->GetBaseReputationOf(factionEntry, oldRace, playerClass); // new base reputation - int32 newBaseRep = sObjectMgr->GetBaseReputationOff(sFactionStore.LookupEntry(newReputation), race, playerClass); + int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), race, playerClass); // final reputation shouldnt change int32 FinalRep = oldDBRep + oldBaseRep; @@ -2195,7 +2202,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) for (uint32 index = 0; index < ktcount; ++index) knownTitles[index] = atol(tokens[index]); - for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Titles.begin(); it != sObjectMgr->FactionChange_Titles.end(); ++it) + for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it) { uint32 title_alliance = it->first; uint32 title_horde = it->second; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index be0d7628774..3c3c36b86dc 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3071,8 +3071,8 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered // set target for proper facing if ((m_casttime || m_spellInfo->IsChanneled()) && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)) - if (m_caster->GetGUID() != m_targets.GetObjectTargetGUID() && m_caster->GetTypeId() == TYPEID_UNIT) - m_caster->FocusTarget(this, m_targets.GetObjectTargetGUID()); + if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget()) + m_caster->FocusTarget(this, m_targets.GetObjectTarget()); if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD)) TriggerGlobalCooldown(); @@ -3164,10 +3164,12 @@ void Spell::cast(bool skipCheck) if (playerPet->isAlive() && playerPet->isControlled() && (m_targets.GetTargetMask() & TARGET_FLAG_UNIT)) playerPet->AI()->OwnerAttacked(m_targets.GetObjectTarget()->ToUnit()); } + SetExecutedCurrently(true); - if (m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.GetUnitTarget() && m_targets.GetUnitTarget() != m_caster) - m_caster->SetInFront(m_targets.GetUnitTarget()); + if (!(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)) + if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget()) + m_caster->SetInFront(m_targets.GetObjectTarget()); // Should this be done for original caster? if (m_caster->GetTypeId() == TYPEID_PLAYER) diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 75c56a9d947..44dff329433 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -324,8 +324,10 @@ enum MiscData // Target guids DATA_LAST_OVERLOAD_GUID = 13, // used to store last Arcane Overload guid DATA_FIRST_SURGE_TARGET_GUID = 14, - DATA_SECOND_SURGE_TARGET_GUID = 15, - DATA_THIRD_SURGE_TARGET_GUID = 16 + //DATA_SECOND_SURGE_TARGET_GUID = 15, + //DATA_THIRD_SURGE_TARGET_GUID = 16 + + NUM_MAX_SURGE_TARGETS = 3, }; // Used to check if summons guids come from vehicles @@ -357,9 +359,7 @@ public: _summonDeaths = 0; _preparingPulsesChecker = 0; _arcaneOverloadGUID = NULL; - _firstSelectedSurgeTargetGUID = NULL; - _secondSelectedSurgeTargetGUID = NULL; - _thirdSelectedSurgeTargetGUID = NULL; + memset(_surgeTargetGUID, 0, sizeof(_surgeTargetGUID)); _killSpamFilter = false; _canAttack = false; @@ -421,17 +421,10 @@ public: } } - uint64 GetGUID(int32 data) const + uint64 GetGUID(int32 type) const { - switch (data) - { - case DATA_FIRST_SURGE_TARGET_GUID: - return _firstSelectedSurgeTargetGUID; - case DATA_SECOND_SURGE_TARGET_GUID: - return _secondSelectedSurgeTargetGUID; - case DATA_THIRD_SURGE_TARGET_GUID: - return _thirdSelectedSurgeTargetGUID; - } + if (type >= DATA_FIRST_SURGE_TARGET_GUID && type < DATA_FIRST_SURGE_TARGET_GUID + NUM_MAX_SURGE_TARGETS) + return _surgeTargetGUID[type - DATA_FIRST_SURGE_TARGET_GUID]; return 0; } @@ -444,13 +437,9 @@ public: _arcaneOverloadGUID = guid; break; case DATA_FIRST_SURGE_TARGET_GUID: - _firstSelectedSurgeTargetGUID = guid; - break; - case DATA_SECOND_SURGE_TARGET_GUID: - _secondSelectedSurgeTargetGUID = guid; - break; - case DATA_THIRD_SURGE_TARGET_GUID: - _thirdSelectedSurgeTargetGUID = guid; + case DATA_FIRST_SURGE_TARGET_GUID + 1: + case DATA_FIRST_SURGE_TARGET_GUID + 2: + _surgeTargetGUID[type - DATA_FIRST_SURGE_TARGET_GUID] = guid; break; } } @@ -954,22 +943,24 @@ public: case EVENT_SURGE_OF_POWER_P_THREE: if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) { - _tempSurgeTarget = NULL; - _drakeVehicle = NULL; - _playerSurgeTarget = NULL; - if ((_tempSurgeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, SPELL_RIDE_RED_DRAGON_BUDDY))) - if ((_drakeVehicle = _tempSurgeTarget->GetVehicleKit())) - if ((_playerSurgeTarget = _drakeVehicle->GetPassenger(0)->ToPlayer())) + if (Unit* tempSurgeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, SPELL_RIDE_RED_DRAGON_BUDDY)) + { + if (Vehicle* drakeVehicle = tempSurgeTarget->GetVehicleKit()) + { + if (Unit* passenger = drakeVehicle->GetPassenger(0)) { - Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, _playerSurgeTarget->GetGUID()); - DoCast(_tempSurgeTarget, SPELL_SURGE_OF_POWER_PHASE_3_10); + if (passenger->GetTypeId() == TYPEID_PLAYER) + { + Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, passenger->GetGUID()); + DoCast(tempSurgeTarget, SPELL_SURGE_OF_POWER_PHASE_3_10); + } } + } + } } else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) { - _firstSelectedSurgeTargetGUID = NULL; - _secondSelectedSurgeTargetGUID = NULL; - _thirdSelectedSurgeTargetGUID = NULL; + memset(_surgeTargetGUID, 0, sizeof(_surgeTargetGUID)); DoCastAOE(SPELL_SURGE_OF_POWER_WARNING_SELECTOR_25); } @@ -1053,13 +1044,7 @@ public: uint8 _summonDeaths; // Keeps count of arcane trash. uint8 _preparingPulsesChecker; // In retail they use 2 preparing pulses with 7 sec CD, after they pass 2 seconds. uint64 _arcaneOverloadGUID; // Last Arcane Overload summoned to know to which should visual be cast to (the purple ball, not bubble). - uint64 _firstSelectedSurgeTargetGUID; // All these three are used to keep current tagets to which warning should be sent - uint64 _secondSelectedSurgeTargetGUID; // during Surge of Power 25 man, also they act as sent targets because of that mechanic. - uint64 _thirdSelectedSurgeTargetGUID; - - Unit* _tempSurgeTarget; // These three are used for 10 man Surge of Power targeting. - Vehicle* _drakeVehicle; - Player* _playerSurgeTarget; + uint64 _surgeTargetGUID[3]; // All these three are used to keep current tagets to which warning should be sent bool _killSpamFilter; // Prevent text spamming on killed player by helping implement a CD. bool _canAttack; // Used to control attacking (Move Chase not being applied after Stop Attack, only few times should act like this). @@ -1542,8 +1527,11 @@ public: void IsSummonedBy(Unit* summoner) { - if ((_malygos = summoner->ToCreature())) + if (Creature* creature = summoner->ToCreature()) + { + _malygos = creature; _malygos->AI()->SetGUID(me->GetGUID(), DATA_LAST_OVERLOAD_GUID); + } } void UpdateAI (uint32 /*diff*/) @@ -1598,8 +1586,11 @@ public: void IsSummonedBy(Unit* summoner) { _summoner = NULL; - if ((_summoner = summoner->ToPlayer())) + if (Player* player = summoner->ToPlayer()) + { + _summoner = player; _events.ScheduleEvent(EVENT_CAST_RIDE_SPELL, 2*IN_MILLISECONDS); + } } void UpdateAI(uint32 diff) @@ -1618,7 +1609,7 @@ public: } } - void PassengerBoarded(Unit* unit, int8 /*seat*/, bool apply) + void PassengerBoarded(Unit* /*unit*/, int8 /*seat*/, bool apply) { if (!apply) { @@ -1762,22 +1753,19 @@ class spell_malygos_random_portal : public SpellScriptLoader } }; -class isPlayerOnVehicleChecker +class IsCreatureVehicleCheck { public: - isPlayerOnVehicleChecker(Unit* source) : _source(source) { } + IsCreatureVehicleCheck() { } - bool operator()(WorldObject* unit) + bool operator()(WorldObject* obj) { - if (Unit* target = ObjectAccessor::GetUnit(*_source, unit->GetGUID())) - if (target->IsOnVehicle(target->GetVehicleBase())) + if (Unit* unit = obj->ToUnit()) + if (unit->GetTypeId() == TYPEID_UNIT && unit->GetVehicleKit()) return true; return false; } - - private: - Unit* _source; }; class spell_malygos_arcane_storm : public SpellScriptLoader @@ -1804,20 +1792,31 @@ class spell_malygos_arcane_storm : public SpellScriptLoader void FilterTargets(std::list<WorldObject*>& targets) { + if (targets.empty()) + return; + Creature* malygos = GetCaster()->ToCreature(); if (GetSpellInfo()->Id == SPELL_ARCANE_STORM_P_III) - targets.remove_if(isPlayerOnVehicleChecker(malygos)); - - if (!targets.empty()) + { + IsCreatureVehicleCheck check; + Trinity::Containers::RandomResizeList(targets, check, (malygos->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 10)); + } + else Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 10)); + } - for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) - malygos->CastSpell((*itr)->ToUnit(), SPELL_ARCANE_STORM_EXTRA_VISUAL, true); + void HandleVisual() + { + if (!GetHitUnit()) + return; + + GetCaster()->CastSpell(GetHitUnit(), SPELL_ARCANE_STORM_EXTRA_VISUAL, true); } void Register() { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_arcane_storm_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + AfterHit += SpellHitFn(spell_malygos_arcane_storm_SpellScript::HandleVisual); } }; @@ -2013,48 +2012,19 @@ class spell_nexus_lord_align_disk_aggro : public SpellScriptLoader class IsPlayerOnHoverDisk { public: - IsPlayerOnHoverDisk(Unit* source, bool isOnHoverDisk) : _source(source), _isOnHoverDisk(isOnHoverDisk) { } + IsPlayerOnHoverDisk(bool isOnHoverDisk) : _isOnHoverDisk(isOnHoverDisk) { } - bool operator()(WorldObject* unit) + bool operator()(WorldObject* obj) { - if (_isOnHoverDisk) - { - if (Unit* passenger = ObjectAccessor::GetUnit(*_source, unit->GetGUID())) - if (passenger->GetVehicleBase() && passenger->GetVehicleBase()->GetEntry() == NPC_HOVER_DISK_MELEE) - return true; - } - else if (!_isOnHoverDisk) - { - if (Unit* passenger = ObjectAccessor::GetUnit(*_source, unit->GetGUID())) - if (!passenger->GetVehicleBase()) - return true; - } + if (Unit* passenger = obj->ToUnit()) + if (passenger->GetVehicleBase() && passenger->GetVehicleBase()->GetEntry() == NPC_HOVER_DISK_MELEE) + return _isOnHoverDisk; - return false; - } - - private: - Unit* _source; - - bool _isOnHoverDisk; -}; - -class CheckUnitAura -{ - public: - CheckUnitAura(Unit* source) : _source(source) { } - - bool operator()(WorldObject* unit) - { - if (Unit* target = ObjectAccessor::GetUnit(*_source, unit->GetGUID())) - if (target->HasAura(SPELL_ARCANE_BARRAGE_DAMAGE)) - return true; - - return false; + return !_isOnHoverDisk; } private: - Unit* _source; + bool _isOnHoverDisk; }; class spell_scion_of_eternity_arcane_barrage : public SpellScriptLoader @@ -2076,20 +2046,21 @@ class spell_scion_of_eternity_arcane_barrage : public SpellScriptLoader if (targets.empty()) return; - Creature* caster = GetCaster()->ToCreature(); - for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) - _playersWithoutDisk.push_back((*itr)); + // Remove players not on Hover Disk from second list + std::list<WorldObject*> playersWithoutDisk; + IsPlayerOnHoverDisk check(false); + for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) + if (check(*itr)) + playersWithoutDisk.push_back(*itr); - // Remove players not on Hover Disk from second list, // if it's empty than we can have player on Hover disk as target. - _playersWithoutDisk.remove_if(IsPlayerOnHoverDisk(caster, false)); - // Else if there are players on the ground we remove all from vehicles. - if (_playersWithoutDisk.empty()) - targets.remove_if(IsPlayerOnHoverDisk(caster, true)); + if (!playersWithoutDisk.empty()) + targets = playersWithoutDisk; + // Finally here we remove all targets that have been damaged by Arcane Barrage // and have 2 seconds long aura still lasting. Used to give healers some time. if (!targets.empty()) - targets.remove_if(CheckUnitAura(caster)); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_ARCANE_BARRAGE_DAMAGE)); } void TriggerDamageSpellFromPlayer() @@ -2105,8 +2076,6 @@ class spell_scion_of_eternity_arcane_barrage : public SpellScriptLoader OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_scion_of_eternity_arcane_barrage_SpellScript::FilterMeleeHoverDiskPassangers, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnHit += SpellHitFn(spell_scion_of_eternity_arcane_barrage_SpellScript::TriggerDamageSpellFromPlayer); } - - std::list<WorldObject*> _playersWithoutDisk; }; SpellScript* GetSpellScript() const @@ -2332,41 +2301,32 @@ class spell_malygos_surge_of_power_warning_selector_25 : public SpellScriptLoade void SendThreeTargets(std::list<WorldObject*>& targets) { + // This spell hits only vehicles (SMSG_SPELL_GO target) Creature* caster = GetCaster()->ToCreature(); - targets.remove_if(isPlayerOnVehicleChecker(caster)); + targets.remove_if(IsCreatureVehicleCheck()); if (targets.empty()) return; - for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) - _filteredSelectedTargets.push_back((*itr)); - - if (_filteredSelectedTargets.empty()) - return; + // But in fact it selects 3 targets (SMSG_SPELL_GO target are not filtered) + std::list<WorldObject*> selectedTargets = targets; - uint8 guidDataSlot = 14; // SetGuid in Malygos AI is reserved for 14th, 15th and 16th Id for the three targets - Trinity::Containers::RandomResizeList(_filteredSelectedTargets, 3); - for (std::list<WorldObject*>::const_iterator itr = _filteredSelectedTargets.begin(); itr != _filteredSelectedTargets.end(); ++itr) + uint8 guidDataSlot = DATA_FIRST_SURGE_TARGET_GUID; // SetGuid in Malygos AI is reserved for 14th, 15th and 16th Id for the three targets + Trinity::Containers::RandomResizeList(selectedTargets, 3); + for (std::list<WorldObject*>::const_iterator itr = selectedTargets.begin(); itr != selectedTargets.end(); ++itr) { - caster->AI()->SetGUID((*itr)->GetGUID(), guidDataSlot++); - if (IS_VEHICLE_GUID((*itr)->GetGUID())) - { - if (Vehicle* tempVehicle = (*itr)->ToCreature()->GetVehicleKit()) - if (tempVehicle->GetPassenger(0)) - if (Player* tempPlayer = tempVehicle->GetPassenger(0)->ToPlayer()) - caster->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, tempPlayer->GetGUID()); - } - else if (IS_PLAYER_GUID((*itr)->GetGUID())) - { - caster->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, (*itr)->GetGUID()); - } + Creature* target = (*itr)->ToCreature(); + caster->AI()->SetGUID(target->GetGUID(), guidDataSlot++); + + if (Vehicle* vehicle = target->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (passenger->GetTypeId() == TYPEID_PLAYER) + caster->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, passenger->GetGUID()); } } void ExecuteMainSpell() { - // We shouldn't cast stuff from target selector hooks - Creature* caster = GetCaster()->ToCreature(); - caster->AI()->DoCastAOE(SPELL_SURGE_OF_POWER_PHASE_3_25); + GetCaster()->ToCreature()->AI()->DoCastAOE(SPELL_SURGE_OF_POWER_PHASE_3_25); } void Register() @@ -2374,8 +2334,6 @@ class spell_malygos_surge_of_power_warning_selector_25 : public SpellScriptLoade OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_surge_of_power_warning_selector_25_SpellScript::SendThreeTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); AfterHit += SpellHitFn(spell_malygos_surge_of_power_warning_selector_25_SpellScript::ExecuteMainSpell); } - - std::list<WorldObject*> _filteredSelectedTargets; }; SpellScript* GetSpellScript() const @@ -2401,25 +2359,25 @@ class spell_malygos_surge_of_power_25 : public SpellScriptLoader void FilterTargets(std::list<WorldObject*>& targets) { Creature* caster = GetCaster()->ToCreature(); - if (!targets.empty()) - targets.clear(); - for (int guidSlot = 14; guidSlot <= 16; guidSlot++) + for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();) { - uint64 guidTypeChecker = caster->AI()->GetGUID(guidSlot); - if (IS_EMPTY_GUID(guidTypeChecker)) - continue; + bool found = false; + WorldObject* target = *itr; - if (IS_VEHICLE_GUID(guidTypeChecker)) - { - WorldObject* tempTarget = caster->GetMap()->GetCreature(guidTypeChecker); - targets.push_back(tempTarget); - } - else if (IS_PLAYER_GUID(guidTypeChecker)) + for (uint32 guidSlot = DATA_FIRST_SURGE_TARGET_GUID; guidSlot < DATA_FIRST_SURGE_TARGET_GUID + NUM_MAX_SURGE_TARGETS; ++guidSlot) { - WorldObject* tempTarget = ObjectAccessor::GetPlayer(*caster, guidTypeChecker); - targets.push_back(tempTarget); + if (target->GetGUID() == caster->AI()->GetGUID(guidSlot)) + { + found = true; + break; + } } + + if (!found) + targets.erase(itr++); + else + ++itr; } } @@ -2513,12 +2471,12 @@ class spell_alexstrasza_gift_beam_visual : public SpellScriptLoader if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { _alexstraszaGift->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - if ((_heartMagic = target->GetMap()->GetGameObject(instance->GetData64(DATA_HEART_OF_MAGIC_GUID)))) + if (GameObject* heartMagic = target->GetMap()->GetGameObject(instance->GetData64(DATA_HEART_OF_MAGIC_GUID))) { - _heartMagic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + heartMagic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); // TO DO: This is hack, core doesn't have support for these flags, // remove line below if it ever gets supported otherwise object won't be accessible. - _heartMagic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + heartMagic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); } } } @@ -2530,7 +2488,6 @@ class spell_alexstrasza_gift_beam_visual : public SpellScriptLoader } GameObject* _alexstraszaGift; - GameObject* _heartMagic; }; AuraScript* GetAuraScript() const diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp index 65ebb46c5dd..c8436dfa1f0 100644 --- a/src/server/scripts/World/areatrigger_scripts.cpp +++ b/src/server/scripts/World/areatrigger_scripts.cpp @@ -465,7 +465,8 @@ public: if (stormforgedEradictor) return false; - if ((stormforgedMonitor = player->SummonCreature(NPC_STORMFORGED_MONITOR, stormforgedMonitorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))) + stormforgedMonitor = player->SummonCreature(NPC_STORMFORGED_MONITOR, stormforgedMonitorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + if (stormforgedMonitor) { stormforgedMonitorGUID = stormforgedMonitor->GetGUID(); stormforgedMonitor->SetWalk(false); @@ -474,7 +475,8 @@ public: stormforgedMonitor->GetMotionMaster()->MovePath(NPC_STORMFORGED_MONITOR * 100, false); } - if ((stormforgedEradictor = player->SummonCreature(NPC_STORMFORGED_ERADICTOR, stormforgedEradictorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))) + stormforgedEradictor = player->SummonCreature(NPC_STORMFORGED_ERADICTOR, stormforgedEradictorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + if (stormforgedEradictor) { stormforgedEradictorGUID = stormforgedEradictor->GetGUID(); stormforgedEradictor->GetMotionMaster()->MovePath(NPC_STORMFORGED_ERADICTOR * 100, false); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 111ab111b02..0838007a53c 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -114,7 +114,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_BANNED, "SELECT guid FROM character_banned WHERE guid = ? AND active = 1", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ? AND active = 1", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC); // End LoginQueryHolder content @@ -529,8 +529,11 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_MAIL, "UPDATE mail SET has_items = ?, expire_time = ?, deliver_time = ?, money = ?, cod = ?, checked = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_REP_CHAR_QUESTSTATUS, "REPLACE INTO character_queststatus (guid, quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, itemcount1, itemcount2, itemcount3, itemcount4, playercount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, "DELETE FROM character_queststatus WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_QUESTSTATUS, "INSERT IGNORE INTO character_queststatus_rewarded (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHAR_QUESTSTATUS_REWARDED, "INSERT IGNORE INTO character_queststatus_rewarded (guid, quest, active) VALUES (?, ?, 1)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, "DELETE FROM character_queststatus_rewarded WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, "UPDATE character_queststatus_rewarded SET quest = ? WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, "UPDATE character_queststatus_rewarded SET active = 1 WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, "UPDATE character_queststatus_rewarded SET active = 0 WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SKILL_BY_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_UDP_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 67f794a9c01..27be26636c7 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -467,8 +467,11 @@ enum CharacterDatabaseStatements CHAR_UPD_MAIL, CHAR_REP_CHAR_QUESTSTATUS, CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, - CHAR_INS_CHAR_QUESTSTATUS, + CHAR_INS_CHAR_QUESTSTATUS_REWARDED, CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, + CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, + CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, + CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, CHAR_DEL_CHAR_SKILL_BY_SKILL, CHAR_INS_CHAR_SKILLS, CHAR_UDP_CHAR_SKILLS, |