aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/1437_TC1_world_scripts.sql14
-rw-r--r--sql/world_scripts_full.sql14
-rw-r--r--src/game/CombatHandler.cpp10
-rw-r--r--src/game/PetHandler.cpp10
-rw-r--r--src/game/Spell.cpp33
-rw-r--r--src/game/Spell.h2
-rw-r--r--src/game/SpellHandler.cpp6
-rw-r--r--src/game/Unit.cpp54
-rw-r--r--src/game/Unit.h4
9 files changed, 85 insertions, 62 deletions
diff --git a/sql/updates/1437_TC1_world_scripts.sql b/sql/updates/1437_TC1_world_scripts.sql
new file mode 100644
index 00000000000..7d53254cc5b
--- /dev/null
+++ b/sql/updates/1437_TC1_world_scripts.sql
@@ -0,0 +1,14 @@
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184418 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184419 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184420 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184421 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184422 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184423 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184424 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184425 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184426 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184427 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184428 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184429 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184430 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184431 LIMIT 1; \ No newline at end of file
diff --git a/sql/world_scripts_full.sql b/sql/world_scripts_full.sql
index a4f4182bb08..b4e381d2a44 100644
--- a/sql/world_scripts_full.sql
+++ b/sql/world_scripts_full.sql
@@ -25,6 +25,20 @@ UPDATE `gameobject_template` SET `ScriptName`='go_crystal_prison' WHERE `entry`=
UPDATE `gameobject_template` SET `ScriptName`='go_legion_obelisk' WHERE `entry` IN (185193,185195,185196,185197,185198);
UPDATE `gameobject_template` SET `ScriptName`='go_jump_a_tron' WHERE `entry`=183146;
UPDATE `gameobject_template` SET `ScriptName`='go_ethereum_prison' WHERE `entry`=184421;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184418 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184419 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184420 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184421 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184422 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184423 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184424 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184425 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184426 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184427 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184428 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184429 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184430 LIMIT 1;
+UPDATE `gameobject_template` SET `ScriptName` = 'go_ethereum_prison' WHERE `entry` = 184431 LIMIT 1;
UPDATE `gameobject_template` SET `ScriptName`='go_sacred_fire_of_life' WHERE `entry`=175944;
UPDATE `gameobject_template` SET `ScriptName`='go_skull_pile' WHERE `entry`=185913;
UPDATE `gameobject_template` SET `ScriptName`='go_tele_to_dalaran_crystal' WHERE entry=191230;
diff --git a/src/game/CombatHandler.cpp b/src/game/CombatHandler.cpp
index 878d8e35648..f732f128fd0 100644
--- a/src/game/CombatHandler.cpp
+++ b/src/game/CombatHandler.cpp
@@ -49,7 +49,7 @@ void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data )
return;
}
- if(_player->IsFriendlyTo(pEnemy) || pEnemy->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
+ if(!_player->canAttack(pEnemy))
{
sLog.outError( "WORLD: Enemy %s %u is friendly",(IS_PLAYER_GUID(guid) ? "player" : "creature"),GUID_LOPART(guid));
@@ -58,14 +58,6 @@ void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data )
return;
}
- if(!pEnemy->isAlive())
- {
- // client can generate swing to known dead target if autoswitch between autoshot and autohit is enabled in client options
- // stop attack state at client
- SendAttackStop(pEnemy);
- return;
- }
-
_player->Attack(pEnemy,true);
}
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 79cb16e0637..6576a2a7622 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -116,20 +116,20 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
//TODO: Send proper error message to client
return;
}
+
// only place where pet can be player
- pet->clearUnitState(UNIT_STAT_FOLLOW);
- const uint64& selguid = _player->GetSelection();
- Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, selguid);
+ Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
if(!TargetUnit)
return;
- // not let attack friendly units.
- if(GetPlayer()->IsFriendlyTo(TargetUnit))
+ if(!pet->canAttack(TargetUnit))
return;
+
// Not let attack through obstructions
//if(!pet->IsWithinLOSInMap(TargetUnit))
// return;
+ pet->clearUnitState(UNIT_STAT_FOLLOW);
// This is true if pet has no target or has target but targets differs.
if(pet->getVictim() != TargetUnit)
{
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 5990c70a2e9..5ffb17d05ac 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -925,7 +925,16 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
spellHitTarget = m_caster;
}
- DoSpellHitOnUnit(spellHitTarget, mask);
+ if(spellHitTarget)
+ {
+ SpellMissInfo missInfo = DoSpellHitOnUnit(spellHitTarget, mask);
+ if(missInfo != SPELL_MISS_NONE)
+ {
+ m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo);
+ m_damage = 0;
+ spellHitTarget = NULL;
+ }
+ }
// Do not take combo points on dodge
if (m_needComboPoints && m_targets.getUnitTargetGUID() == target->targetGUID)
@@ -1034,19 +1043,17 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
}
}
-void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
+SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
{
if(!unit || !effectMask)
- return;
+ return SPELL_MISS_EVADE;
// Recheck immune (only for delayed spells)
if( m_spellInfo->speed &&
(unit->IsImmunedToDamage(m_spellInfo) ||
unit->IsImmunedToSpell(m_spellInfo)))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
- m_damage = 0;
- return;
+ return SPELL_MISS_IMMUNE;
}
if (unit->GetTypeId() == TYPEID_PLAYER)
@@ -1067,9 +1074,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) &&
unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
if( !m_caster->IsFriendlyTo(unit) )
@@ -1077,9 +1082,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// for delayed spells ignore not visible explicit target
if(m_spellInfo->speed > 0.0f && unit==m_targets.getUnitTarget() && !unit->isVisibleForOrDetect(m_caster,false))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL);
@@ -1092,9 +1095,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// TODO: this cause soul transfer bugged
if(m_spellInfo->speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !IsPositiveSpell(m_spellInfo->Id))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
// assisting case, healing and resurrection
@@ -1165,6 +1166,8 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if (unit->AddAura(Aur))
m_spellAura = Aur;
}
+
+ return SPELL_MISS_NONE;
}
void Spell::DoTriggersOnSpellHit(Unit *unit)
diff --git a/src/game/Spell.h b/src/game/Spell.h
index d7bbc119572..64aa7f24eb0 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -588,7 +588,7 @@ class Spell
void AddGOTarget(uint64 goGUID, uint32 effIndex);
void AddItemTarget(Item* target, uint32 effIndex);
void DoAllEffectOnTarget(TargetInfo *target);
- void DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
+ SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
void DoTriggersOnSpellHit(Unit *unit);
void DoAllEffectOnTarget(GOTargetInfo *target);
void DoAllEffectOnTarget(ItemTargetInfo *target);
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index b98d693c416..5cd5da67118 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -347,12 +347,8 @@ void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
recvPacket >> counter;
recvPacket >> spellId;
- //FIXME: hack, ignore unexpected client cancel Deadly Throw cast
- if(spellId==26679)
- return;
-
if(_player->IsNonMeleeSpellCasted(false))
- _player->InterruptNonMeleeSpells(false,spellId);
+ _player->InterruptNonMeleeSpells(false,spellId,false);
}
void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index f2f824481ad..b1a39c30cce 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -3394,12 +3394,14 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
pSpell->SetReferencedFromCurrent(true);
}
-void Unit::InterruptSpell(uint32 spellType, bool withDelayed)
+void Unit::InterruptSpell(uint32 spellType, bool withDelayed, bool withInstant)
{
assert(spellType < CURRENT_MAX_SPELL);
Spell *spell = m_currentSpells[spellType];
- if(spell && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) )
+ if(spell
+ && (withDelayed || spell->getState() != SPELL_STATE_DELAYED)
+ && (withInstant || spell->GetCastTime() > 0))
{
// for example, do not let self-stun aura interrupt itself
if(!spell->IsInterruptable())
@@ -3443,19 +3445,19 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip
return(false);
}
-void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id)
+void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id, bool withInstant)
{
// generic spells are interrupted if they are not finished or delayed
if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id))
- InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed);
+ InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed,withInstant);
// autorepeat spells are interrupted if they are not finished or delayed
if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id))
- InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed);
+ InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed,withInstant);
// channeled spells are interrupted if they are not finished, even if they are delayed
if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id))
- InterruptSpell(CURRENT_CHANNELED_SPELL,true);
+ InterruptSpell(CURRENT_CHANNELED_SPELL,true,true);
}
Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
@@ -3484,10 +3486,9 @@ bool Unit::isInBack(Unit const* target, float distance, float arc) const
bool Unit::isInLine(Unit const* target, float distance) const
{
if(!HasInArc(M_PI, target) || !IsWithinDistInMap(target, distance)) return false;
- float width = (GetObjectSize() / 2 + target->GetObjectSize()) / 2;
- float angle = GetAngle(target);
- angle -= GetOrientation();
- return abs(sin(angle)) * distance < width;
+ float width = GetObjectSize() + target->GetObjectSize() * 0.5f;
+ float angle = GetAngle(target) - GetOrientation();
+ return abs(sin(angle)) * GetExactDistance2d(target->GetPositionX(), target->GetPositionY()) < width;
}
bool Unit::isInAccessiblePlaceFor(Creature const* c) const
@@ -9336,10 +9337,13 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask)
bool Unit::IsImmunedToDamage(SpellEntry const* spellInfo)
{
+ if(spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ return false;
+
uint32 shoolMask = GetSpellSchoolMask(spellInfo);
- if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity
- !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) // can remove immune (by dispell or immune it)
- && (spellInfo->Id != 42292))
+ if(!(spellInfo->AttributesEx &
+ (SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE | SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
+ && spellInfo->Id != 42292)
{
//If m_immuneToSchool type contain this school type, IMMUNE damage.
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
@@ -9362,14 +9366,23 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
if (!spellInfo)
return false;
+ // Single spell immunity.
+ SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
+ for(SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
+ if(itr->type == spellInfo->Id)
+ return true;
+
+ if(spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ return false;
+
SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
if(itr->type == spellInfo->Dispel)
return true;
- if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity
- !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) // can remove immune (by dispell or immune it)
- && (spellInfo->Id != 42292))
+ if(!(spellInfo->AttributesEx &
+ (SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE | SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
+ && spellInfo->Id != 42292)
{
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
@@ -9390,15 +9403,6 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
}
}
- SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
- for(SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
- {
- if(itr->type == spellInfo->Id)
- {
- return true;
- }
- }
-
return false;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 539d8859684..8e008e1357e 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1337,7 +1337,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetCurrentCastedSpell(Spell * pSpell);
virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { }
- void InterruptSpell(uint32 spellType, bool withDelayed = true);
+ void InterruptSpell(uint32 spellType, bool withDelayed = true, bool withInstant = true);
// set withDelayed to true to account delayed spells as casted
// delayed+channeled spells are always accounted as casted
@@ -1346,7 +1346,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
// set withDelayed to true to interrupt delayed spells too
// delayed+channeled spells are always interrupted
- void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0);
+ void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0, bool withInstant = true);
Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;