diff options
| -rw-r--r-- | sql/updates/1437_TC1_world_scripts.sql | 14 | ||||
| -rw-r--r-- | sql/world_scripts_full.sql | 14 | ||||
| -rw-r--r-- | src/game/CombatHandler.cpp | 10 | ||||
| -rw-r--r-- | src/game/PetHandler.cpp | 10 | ||||
| -rw-r--r-- | src/game/Spell.cpp | 33 | ||||
| -rw-r--r-- | src/game/Spell.h | 2 | ||||
| -rw-r--r-- | src/game/SpellHandler.cpp | 6 | ||||
| -rw-r--r-- | src/game/Unit.cpp | 54 | ||||
| -rw-r--r-- | src/game/Unit.h | 4 |
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; |
