From d0e66932668bcae08e8d5f960a0175b4d16c7371 Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 12:35:41 +0200 Subject: Core/GameObject: Format comments and apply rename of previous commit. --- src/server/game/Entities/GameObject/GameObject.cpp | 10 ++++++---- src/server/game/Entities/GameObject/GameObject.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 98cfb722e50..1c86db771a5 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -422,7 +422,7 @@ void GameObject::Update(uint32 diff) } case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: - //we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) + // We need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) if (GetGoState() != GO_STATE_READY) ResetDoorOrButton(); break; @@ -434,13 +434,15 @@ void GameObject::Update(uint32 diff) break; } - if (!m_spawnedByDefault) // despawn timer + // Despawn timer + if (!m_spawnedByDefault) { - // can be despawned or destroyed + // Can be despawned or destroyed SetLootState(GO_JUST_DEACTIVATED); return; } - // respawn timer + + // Respawn timer uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool(GetDBTableGUIDLow()) : 0; if (poolid) sPoolMgr->UpdatePool(poolid, GetDBTableGUIDLow()); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 95d8933a1fa..6e36639b84f 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -123,7 +123,7 @@ struct GameObjectTemplate { uint32 lockId; //0 -> Lock.dbc uint32 level; //1 - uint32 diameter; //2 radius for trap activation + uint32 diameter; //2 diameter for trap activation uint32 spellId; //3 uint32 type; //4 0 trap with no despawn after cast. 1 trap despawns after cast. 2 bomb casts on spawn. uint32 cooldown; //5 time in secs -- cgit v1.2.3 From c6bf7e0b1d615a22c2145c6f4a757a10a9eca92c Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 18:39:53 +0200 Subject: Core/GameObject: Store unit in GameObject::SetLootState - required for trap activation. --- src/server/game/Entities/GameObject/GameObject.cpp | 1 + src/server/game/Entities/GameObject/GameObject.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 1c86db771a5..f4f2a26240c 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2015,6 +2015,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* void GameObject::SetLootState(LootState state, Unit* unit) { m_lootState = state; + m_lootStateUnit = unit; AI()->OnStateChanged(state, unit); sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); if (m_model) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 6e36639b84f..7b73f9a2318 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -841,6 +841,7 @@ class GameObject : public WorldObject, public GridObject, public Map time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer LootState m_lootState; + Unit* m_lootStateUnit; bool m_spawnedByDefault; time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). // For traps this: spell casting cooldown, for doors/buttons: reset time. -- cgit v1.2.3 From 3ac4e3033cb0f8b33554dcfbd29a2cf5d94a19bf Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 18:59:56 +0200 Subject: Core/GameObject: Add missing initialization of m_lootStateUnit --- src/server/game/Entities/GameObject/GameObject.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index f4f2a26240c..f9ff0d09b9f 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -47,6 +47,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_respawnTime = 0; m_respawnDelayTime = 300; m_lootState = GO_NOT_READY; + m_lootStateUnit = NULL; m_spawnedByDefault = true; m_usetimes = 0; m_spellId = 0; -- cgit v1.2.3 From 2878b0d1051ed01f9ff024828ed409f0db25cdc7 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 5 May 2014 20:05:33 +0200 Subject: Core/Misc: Fix enchants broken in 3aca9e64b34baee781f402c3f33ad7ee7991c232 Compare cast item entry instead of checking cast item spells to fix the exploit mentioned in 3aca9e64b34baee781f402c3f33ad7ee7991c232 without breaking any functionality. --- src/server/game/Spells/Spell.cpp | 48 ++++++++------------------------- src/server/game/Spells/Spell.h | 1 + src/server/game/Spells/SpellEffects.cpp | 3 +++ 3 files changed, 15 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 2dc501d896f..7c6f2552b44 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -571,6 +571,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; unitTarget = NULL; itemTarget = NULL; @@ -2806,9 +2807,15 @@ bool Spell::UpdateChanneledTargetList() void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura) { if (m_CastItem) + { m_castItemGUID = m_CastItem->GetGUID(); + m_castItemEntry = m_CastItem->GetEntry(); + } else + { m_castItemGUID = 0; + m_castItemEntry = 0; + } InitExplicitTargets(*targets); @@ -4264,6 +4271,7 @@ void Spell::TakeCastItem() m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; } } @@ -4509,6 +4517,7 @@ void Spell::TakeReagents() m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; } // if GetItemTarget is also spell reagent @@ -6336,43 +6345,8 @@ bool Spell::UpdatePointers() if (!m_CastItem) return false; - // check if the retrieved item can even cast the spell - ItemTemplate const* proto = m_CastItem->GetTemplate(); - bool spellFound = false; - for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - { - if (uint32(proto->Spells[i].SpellId) == GetSpellInfo()->Id) - { - spellFound = true; - break; - } - } - - // check enchantment if the spell wasn't found in item proto - if (!spellFound) - { - for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) - { - uint32 enchant_id = m_CastItem->GetEnchantmentId(EnchantmentSlot(e_slot)); - SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!pEnchant) - continue; - - for (uint8 s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s) - { - if (pEnchant->spellid[s] == GetSpellInfo()->Id) - { - spellFound = true; - break; - } - } - - if (spellFound) - break; - } - } - - if (!spellFound) + // check if the item is really the same, in case it has been wrapped for example + if (m_castItemEntry != m_CastItem->GetEntry()) return false; } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 9c6353da486..341867ff787 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -451,6 +451,7 @@ class Spell SpellInfo const* const m_spellInfo; Item* m_CastItem; uint64 m_castItemGUID; + uint32 m_castItemEntry; uint8 m_cast_count; uint32 m_glyphIndex; uint32 m_preCastSpell; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 31e0006d9f3..65530b4b282 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2097,6 +2097,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; player->StoreItem(dest, pNewItem, true); return; @@ -2116,6 +2117,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; player->BankItem(dest, pNewItem, true); return; @@ -2139,6 +2141,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; player->EquipItem(dest, pNewItem, true); player->AutoUnequipOffhandIfNeed(); -- cgit v1.2.3 From b48879ab7947b3910fb18d842cf05fcba8b5a5a2 Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 22:28:45 +0200 Subject: Core/GameObject: Finish moving activation code of traps to GO_ACTIVATED Fixing #6388 should be easier now... --- src/server/game/Entities/GameObject/GameObject.cpp | 72 ++++++++++------------ 1 file changed, 32 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index f9ff0d09b9f..4f3f4c73f3b 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -309,13 +309,13 @@ void GameObject::Update(uint32 diff) GameObjectTemplate const* goInfo = GetGOInfo(); // Bombs if (goInfo->trap.type == 2) - m_cooldownTime = time(NULL) + 10; // Hardcoded tooltip value + // Hardcoded tooltip value + m_cooldownTime = time(NULL) + 10; else if (Unit* owner = GetOwner()) - { if (owner->IsInCombat()) m_cooldownTime = time(NULL) + goInfo->trap.startDelay; - } - m_lootState = GO_READY; + + SetLootState(GO_READY); break; } case GAMEOBJECT_TYPE_TRANSPORT: @@ -396,7 +396,7 @@ void GameObject::Update(uint32 diff) if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day) SetRespawnTime(DAY); else - m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime)+urand(5, MINUTE); // else copy time from master and add a little + m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + urand(5, MINUTE); // else copy time from master and add a little SaveRespawnTime(); // also save to DB immediately return; } @@ -468,47 +468,35 @@ void GameObject::Update(uint32 diff) } // Type 0 despawns after being triggered, type 1 does not. - - bool isBattlegroundTrap; - /// @todo This is activation radius. Casting radius must be selected from spell data. - /// @todo Move activated state code to GO_ACTIVATED, in this place just check for activation and set state. float radius; if (!goInfo->trap.diameter) { - // Cast in other case (at some triggering/linked go/etc explicit call) - if (goInfo->trap.cooldown != 3 || m_respawnTime > 0) + // Battleground traps: data2 == 0 && data5 == 3 + if (goInfo->trap.cooldown != 3) break; - // Battleground gameobjects have data2 == 0 && data5 == 3 - isBattlegroundTrap = true; radius = 3.f; } else - { - isBattlegroundTrap = false; radius = goInfo->trap.diameter / 2.f; - } - Unit* owner = GetOwner(); // Pointer to appropriate target if found any Unit* target = NULL; /// @todo this hack with search required until GO casting not implemented - // Hunter trap: Search units which are unfriendly to the trap's owner - if (owner) + if (Unit* owner = GetOwner()) { + // Hunter trap: Search units which are unfriendly to the trap's owner Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius); Trinity::UnitSearcher searcher(this, target, checker); VisitNearbyGridObject(radius, searcher); if (!target) VisitNearbyWorldObject(radius, searcher); } - // Environmental trap: Any target else { - // Environmental damage spells already have around enemies targeting but this does not help in case of not existing GO casting support - // Affect only players + // Environmental trap: Any player Player* player = NULL; Trinity::AnyPlayerInObjectRangeCheck checker(this, radius); Trinity::PlayerSearcher searcher(this, player, checker); @@ -517,23 +505,8 @@ void GameObject::Update(uint32 diff) } if (target) - { - // Some traps do not have a spell but should be triggered - if (goInfo->trap.spellId) - CastSpell(target, goInfo->trap.spellId); + SetLootState(GO_ACTIVATED, target); - // Template value or 4 seconds - m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); - - if (goInfo->trap.type == 1) - SetLootState(GO_JUST_DEACTIVATED); - - // Battleground gameobjects case - if (isBattlegroundTrap) - if (Player* player = target->ToPlayer()) - if (Battleground* bg = player->GetBattleground()) - bg->HandleTriggerBuff(GetGUID()); - } } else if (uint32 max_charges = goInfo->GetCharges()) { @@ -582,11 +555,30 @@ void GameObject::Update(uint32 diff) case GAMEOBJECT_TYPE_TRAP: { GameObjectTemplate const* goInfo = GetGOInfo(); - if (goInfo->trap.spellId) + if (goInfo->trap.type == 2 && goInfo->trap.spellId) + { /// @todo NULL target won't work for target type 1 CastSpell(NULL, goInfo->trap.spellId); + SetLootState(GO_JUST_DEACTIVATED); + } + else if (m_lootStateUnit) + { + // Some traps do not have a spell but should be triggered + if (goInfo->trap.spellId) + CastSpell(m_lootStateUnit, goInfo->trap.spellId); - SetLootState(GO_JUST_DEACTIVATED); + // Template value or 4 seconds + m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); + + if (goInfo->trap.type == 1) + SetLootState(GO_JUST_DEACTIVATED); + + // Battleground gameobjects have data2 == 0 && data5 == 3 + if (!goInfo->trap.diameter && goInfo->trap.cooldown == 3) + if (Player* player = m_lootStateUnit->ToPlayer()) + if (Battleground* bg = player->GetBattleground()) + bg->HandleTriggerBuff(GetGUID()); + } break; } default: -- cgit v1.2.3 From 41d9364b164aca67d66134a565890d2f8d49fbd0 Mon Sep 17 00:00:00 2001 From: Gacko Date: Tue, 6 May 2014 18:46:08 +0200 Subject: Core/GameObject: Fix crash added in c6bf7e0b1d615a22c2145c6f4a757a10a9eca92c Thanks @jackpoz --- src/server/game/Entities/GameObject/GameObject.cpp | 11 ++++++----- src/server/game/Entities/GameObject/GameObject.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 4f3f4c73f3b..ea27d7add1f 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -47,7 +47,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_respawnTime = 0; m_respawnDelayTime = 300; m_lootState = GO_NOT_READY; - m_lootStateUnit = NULL; + m_lootStateUnitGUID = 0; m_spawnedByDefault = true; m_usetimes = 0; m_spellId = 0; @@ -561,11 +561,12 @@ void GameObject::Update(uint32 diff) CastSpell(NULL, goInfo->trap.spellId); SetLootState(GO_JUST_DEACTIVATED); } - else if (m_lootStateUnit) + else if (m_lootStateUnitGUID) + if (Unit* target = Unit::GetUnit(*this, m_lootStateUnitGUID)) { // Some traps do not have a spell but should be triggered if (goInfo->trap.spellId) - CastSpell(m_lootStateUnit, goInfo->trap.spellId); + CastSpell(target, goInfo->trap.spellId); // Template value or 4 seconds m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); @@ -575,7 +576,7 @@ void GameObject::Update(uint32 diff) // Battleground gameobjects have data2 == 0 && data5 == 3 if (!goInfo->trap.diameter && goInfo->trap.cooldown == 3) - if (Player* player = m_lootStateUnit->ToPlayer()) + if (Player* player = target->ToPlayer()) if (Battleground* bg = player->GetBattleground()) bg->HandleTriggerBuff(GetGUID()); } @@ -2008,7 +2009,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* void GameObject::SetLootState(LootState state, Unit* unit) { m_lootState = state; - m_lootStateUnit = unit; + m_lootStateUnitGUID = unit ? unit->GetGUID() : 0; AI()->OnStateChanged(state, unit); sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); if (m_model) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 7b73f9a2318..a99c5db93aa 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -841,7 +841,7 @@ class GameObject : public WorldObject, public GridObject, public Map time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer LootState m_lootState; - Unit* m_lootStateUnit; + uint64 m_lootStateUnitGUID; // GUID of the unit passed with SetLootState(LootState, Unit*) bool m_spawnedByDefault; time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). // For traps this: spell casting cooldown, for doors/buttons: reset time. -- cgit v1.2.3 From 111bbb3620093f7db9bb94c37fcbc97c0a45c4c3 Mon Sep 17 00:00:00 2001 From: Gacko Date: Tue, 6 May 2014 19:06:59 +0200 Subject: Remove unnecessary check in previous fix --- src/server/game/Entities/GameObject/GameObject.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index ea27d7add1f..8051c757bf2 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -561,8 +561,7 @@ void GameObject::Update(uint32 diff) CastSpell(NULL, goInfo->trap.spellId); SetLootState(GO_JUST_DEACTIVATED); } - else if (m_lootStateUnitGUID) - if (Unit* target = Unit::GetUnit(*this, m_lootStateUnitGUID)) + else if (Unit* target = Unit::GetUnit(*this, m_lootStateUnitGUID)) { // Some traps do not have a spell but should be triggered if (goInfo->trap.spellId) -- cgit v1.2.3