aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2014_05_07_00_world_creature_template.sql2
-rw-r--r--sql/updates/world/2014_05_07_00_world_gossip_menu_option.sql1
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp84
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h3
-rw-r--r--src/server/game/Spells/Spell.cpp48
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp3
7 files changed, 60 insertions, 82 deletions
diff --git a/sql/updates/world/2014_05_07_00_world_creature_template.sql b/sql/updates/world/2014_05_07_00_world_creature_template.sql
new file mode 100644
index 00000000000..aa1a0511f18
--- /dev/null
+++ b/sql/updates/world/2014_05_07_00_world_creature_template.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature_template` SET `unit_flags`=`unit_flags`|256, `flags_extra`=0 WHERE `entry`=30413;
diff --git a/sql/updates/world/2014_05_07_00_world_gossip_menu_option.sql b/sql/updates/world/2014_05_07_00_world_gossip_menu_option.sql
new file mode 100644
index 00000000000..2939237dc7d
--- /dev/null
+++ b/sql/updates/world/2014_05_07_00_world_gossip_menu_option.sql
@@ -0,0 +1 @@
+DELETE FROM `gossip_menu_option` WHERE `menu_id`=8903 AND `id`=1;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index dd018911a14..5f91755d527 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_lootStateUnitGUID = 0;
m_spawnedByDefault = true;
m_usetimes = 0;
m_spellId = 0;
@@ -309,13 +310,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 +397,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;
}
@@ -423,7 +424,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;
@@ -435,13 +436,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<GameObject>(GetDBTableGUIDLow()) : 0;
if (poolid)
sPoolMgr->UpdatePool<GameObject>(poolid, GetDBTableGUIDLow());
@@ -466,47 +469,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<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> 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<Trinity::AnyPlayerInObjectRangeCheck> searcher(this, player, checker);
@@ -515,23 +506,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);
-
- // Template value or 4 seconds
- m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4));
+ SetLootState(GO_ACTIVATED, target);
- 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())
{
@@ -580,11 +556,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 (Unit* target = Unit::GetUnit(*this, m_lootStateUnitGUID))
+ {
+ // Some traps do not have a spell but should be triggered
+ if (goInfo->trap.spellId)
+ CastSpell(target, 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 = target->ToPlayer())
+ if (Battleground* bg = player->GetBattleground())
+ bg->HandleTriggerBuff(GetGUID());
+ }
break;
}
default:
@@ -2014,6 +2009,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
void GameObject::SetLootState(LootState state, Unit* unit)
{
m_lootState = state;
+ 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 7d4e6ed548f..640d5718186 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -124,7 +124,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
@@ -842,6 +842,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, 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;
+ 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.
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 74b33d9550b..93e42222048 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -573,6 +573,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;
@@ -2808,9 +2809,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);
@@ -4299,6 +4306,7 @@ void Spell::TakeCastItem()
m_CastItem = NULL;
m_castItemGUID = 0;
+ m_castItemEntry = 0;
}
}
@@ -4538,6 +4546,7 @@ void Spell::TakeReagents()
m_CastItem = NULL;
m_castItemGUID = 0;
+ m_castItemEntry = 0;
}
// if GetItemTarget is also spell reagent
@@ -6371,43 +6380,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 94e1ea44ce7..2b026b77160 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -456,6 +456,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 041757d152d..9c6b69ef7d7 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1934,6 +1934,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
m_CastItem = NULL;
m_castItemGUID = 0;
+ m_castItemEntry = 0;
player->StoreItem(dest, pNewItem, true);
return;
@@ -1953,6 +1954,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
m_CastItem = NULL;
m_castItemGUID = 0;
+ m_castItemEntry = 0;
player->BankItem(dest, pNewItem, true);
return;
@@ -1976,6 +1978,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
m_CastItem = NULL;
m_castItemGUID = 0;
+ m_castItemEntry = 0;
player->EquipItem(dest, pNewItem, true);
player->AutoUnequipOffhandIfNeed();