diff options
-rw-r--r-- | src/bindings/scripts/scripts/npc/npc_escortAI.cpp | 1 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp | 12 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp | 165 | ||||
-rw-r--r-- | src/game/GameObject.cpp | 8 | ||||
-rw-r--r-- | src/game/GridNotifiers.h | 17 | ||||
-rw-r--r-- | src/game/Group.cpp | 6 | ||||
-rw-r--r-- | src/game/Map.cpp | 2 | ||||
-rw-r--r-- | src/game/MapInstanced.cpp | 8 | ||||
-rw-r--r-- | src/game/MapInstanced.h | 1 | ||||
-rw-r--r-- | src/game/Spell.cpp | 2 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 12 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 3 | ||||
-rw-r--r-- | src/game/Unit.cpp | 10 |
13 files changed, 150 insertions, 97 deletions
diff --git a/src/bindings/scripts/scripts/npc/npc_escortAI.cpp b/src/bindings/scripts/scripts/npc/npc_escortAI.cpp index fefe9278322..c8584424414 100644 --- a/src/bindings/scripts/scripts/npc/npc_escortAI.cpp +++ b/src/bindings/scripts/scripts/npc/npc_escortAI.cpp @@ -299,4 +299,5 @@ void npc_escortAI::Start(bool bAttack, bool bDefend, bool bRun, uint64 pGUID) //Disable questgiver flag m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_ATTACKABLE_2); } diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp index 356baf01a60..b4064b437a4 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp @@ -108,7 +108,17 @@ void hyjalAI::Reset() else error_log(ERROR_INST_DATA); //Visibility - m_creature->SetVisibility(VISIBILITY_ON); + switch(m_creature->GetEntry()) + { + case 17772: if(pInstance->GetData(DATA_ANETHERONEVENT) == DONE) + m_creature->SetVisibility(VISIBILITY_OFF); + else m_creature->SetVisibility(VISIBILITY_ON); + break; + case 17852: if(pInstance->GetData(DATA_AZGALOREVENT) == DONE) + m_creature->SetVisibility(VISIBILITY_OFF); + else m_creature->SetVisibility(VISIBILITY_ON); + break; + } //If Jaina evades, reset the visibility of all other creatures in the grid. if(CreatureList.empty()) diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp index cab99d321f8..e2e1dd0a2b4 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp @@ -16,8 +16,9 @@ /* ScriptData SDName: Boss_Kalecgos -SD%Complete: 0 -SDComment: VERIFY SCRIPT +SD%Complete: 95 +SDComment: +SDCategory: Sunwell_Plateau EndScriptData */ #include "precompiled.h" @@ -68,7 +69,7 @@ EndScriptData */ #define SPELL_BANISH 44836 #define SPELL_TRANSFORM_KALEC 44670 -#define SPELL_ENRAGE 44807 +#define SPELL_ENRAGE 44806 #define SPELL_CORRUPTION_STRIKE 45029 #define SPELL_AGONY_CURSE 45032 @@ -119,8 +120,8 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI { if(pInstance) { - uint64 SathGUID = pInstance->GetData64(DATA_SATHROVARR); - uint64 DoorGUID = pInstance->GetData64(DATA_GO_FORCEFIELD); + SathGUID = pInstance->GetData64(DATA_SATHROVARR); + DoorGUID = pInstance->GetData64(DATA_GO_FORCEFIELD); } Unit *Sath = Unit::GetUnit(*m_creature,SathGUID); @@ -146,8 +147,7 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI TalkSequence = 0; isFriendly = false; isEnraged = false; - isBanished = false; - //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true); + isBanished = false; } void DamageTaken(Unit *done_by, uint32 &damage) @@ -191,8 +191,7 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI switch(TalkSequence) { case 1: - m_creature->setFaction(35); - DoCast(m_creature, SPELL_TRANSFORM_KALEC); + m_creature->setFaction(35); TalkTimer = 1000; break; case 2: @@ -251,6 +250,7 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI uint32 AgonyCurseTimer; uint32 ShadowBoltTimer; uint32 CheckTimer; + uint32 ResetThreat; uint64 KalecGUID; uint64 KalecgosGUID; @@ -274,11 +274,9 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI AgonyCurseTimer = 20000; CorruptionStrikeTimer = 13000; CheckTimer = 1000; + ResetThreat = 1000; isEnraged = false; - isBanished = false; - //m_creature->CastSpell(m_creature, AURA_SPECTRAL_INVISIBILITY, true); - //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true); - //m_creature->CastSpell(m_creature, AURA_DEMONIC_VISUAL, true); + isBanished = false; } void Aggro(Unit* who) @@ -341,9 +339,7 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI if(Player* i_pl = i->getSource()) if(i_pl->HasAura(AURA_SPECTRAL_REALM,0)) i_pl->RemoveAurasDueToSpell(AURA_SPECTRAL_REALM); - } - - void Enrage(); // demon and dragon should enrage at the same time + } void UpdateAI(const uint32 diff) { @@ -352,8 +348,14 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI if(CheckTimer < diff) { - if(!isEnraged && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10) - Enrage(); + if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !isEnraged) + { + Unit* Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID); + if (Kalecgos) + Kalecgos->CastSpell(Kalecgos, SPELL_ENRAGE, true); + DoCast(m_creature, SPELL_ENRAGE, true); + isEnraged = true; + } if(!isBanished && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1) { @@ -366,7 +368,7 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI } else { - m_creature->CastSpell(m_creature, SPELL_BANISH, true); + DoCast(m_creature, SPELL_BANISH); isBanished = true; } } @@ -379,6 +381,22 @@ struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI CheckTimer = 1000; }else CheckTimer -= diff; + if(ResetThreat < diff) + { + if ( ( m_creature->getVictim()->HasAura(AURA_SPECTRAL_EXHAUSTION,0)) && (m_creature->getVictim()->GetTypeId() == TYPEID_PLAYER) ) + { + for(std::list<HostilReference*>::iterator itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr) + { + if(((*itr)->getUnitGuid()) == (m_creature->getVictim()->GetGUID())) + { + (*itr)->removeReference(); + break; + } + } + } + ResetThreat = 1000; + }else ResetThreat -= diff; + if(ShadowBoltTimer < diff) { DoScriptText(SAY_SATH_SPELL1, m_creature); @@ -435,9 +453,6 @@ struct TRINITY_DLL_DECL boss_kalecAI : public ScriptedAI YellSequence = 0; isEnraged = false; - - //m_creature->CastSpell(m_creature, AURA_SPECTRAL_INVISIBILITY, true); - //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true); } void Aggro(Unit* who) {} @@ -452,11 +467,8 @@ struct TRINITY_DLL_DECL boss_kalecAI : public ScriptedAI void UpdateAI(const uint32 diff) { - if(!m_creature->getVictim()) // only victim is Sath - { - EnterEvadeMode(); - return; - } + if (!UpdateVictim()) + return; if(YellTimer < diff) { @@ -532,35 +544,38 @@ void boss_kalecgosAI::UpdateAI(const uint32 diff) return; if(CheckTimer < diff) - { - if(!isEnraged && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10) - { - if(Unit *Sath = Unit::GetUnit(*m_creature, SathGUID)) - ((boss_sathrovarrAI*)((Creature*)Sath)->AI())->Enrage(); - } - - if(!isBanished && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1) - { - if(Unit *Sath = Unit::GetUnit(*m_creature, SathGUID)) - { - if(((boss_sathrovarrAI*)((Creature*)Sath)->AI())->isBanished) - { - Sath->DealDamage(Sath, Sath->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - return; - } - else - { - m_creature->CastSpell(m_creature, SPELL_BANISH, true); - isBanished = true; - } - } - else - { - DoTextEmote("is unable to find Sath", NULL); - EnterEvadeMode(); - } - } - CheckTimer = 1000; //every 1 sec we check this + { + if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !isEnraged) + { + Unit* Sath = Unit::GetUnit(*m_creature, SathGUID); + if (Sath) + Sath->CastSpell(Sath, SPELL_ENRAGE, true); + DoCast(m_creature, SPELL_ENRAGE, true); + isEnraged = true; + } + + if(!isBanished && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1) + { + if(Unit *Sath = Unit::GetUnit(*m_creature, SathGUID)) + { + if(((boss_sathrovarrAI*)((Creature*)Sath)->AI())->isBanished) + { + Sath->DealDamage(Sath, Sath->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + return; + } + else + { + DoCast(m_creature, SPELL_BANISH); + isBanished = true; + } + } + else + { + error_log("TSCR: Didn't find Shathrowar. Kalecgos event reseted."); + EnterEvadeMode(); + } + } + CheckTimer = 1000; }else CheckTimer -= diff; if(ArcaneBuffetTimer < diff) @@ -583,42 +598,30 @@ void boss_kalecgosAI::UpdateAI(const uint32 diff) if(WildMagicTimer < diff) { - DoCast(m_creature, WildMagic[rand()%6]); + Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if(target && target->isAlive()) + DoCast(target, WildMagic[rand()%6]); WildMagicTimer = 20000; }else WildMagicTimer -= diff; if(SpectralBlastTimer < diff) { - m_creature->CastSpell(m_creature, SPELL_SPECTRAL_BLAST, true); - SpectralBlastTimer = 20000+(rand()%5000); + Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if( ( target != m_creature->getVictim() ) && target->isAlive() && !(target->HasAura(AURA_SPECTRAL_EXHAUSTION, 0)) ) + { + DoCast(target, SPELL_SPECTRAL_BLAST); + SpectralBlastTimer = 20000+(rand()%5000); + } + else + { + SpectralBlastTimer = 1000; + } }else SpectralBlastTimer -= diff; DoMeleeAttackIfReady(); } } -void boss_sathrovarrAI::Enrage() -{ - Unit *Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID); - Unit *Kalec = Unit::GetUnit(*m_creature, KalecGUID); - if(!Kalecgos) - { - error_log("SD2 ERROR: unable to find Kalecgos"); - return; - } - if(!Kalec) - { - error_log("SD2 ERROR: unable to find Kalec"); - return; - } - DoScriptText(SAY_SATH_ENRAGE, m_creature); - m_creature->CastSpell(m_creature, SPELL_ENRAGE, true); - Kalecgos->CastSpell(Kalecgos, SPELL_ENRAGE, true); - isEnraged = true; - ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->isEnraged = true; - ((boss_kalecAI*)((Creature*)Kalec)->AI())->isEnraged = true; -} - bool GOkalocegos_teleporter(Player *player, GameObject* _GO) { if(player->HasAura(AURA_SPECTRAL_EXHAUSTION, 0)) diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index f2bf5739334..64d604a04fc 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -326,18 +326,18 @@ void GameObject::Update(uint32 /*p_time*/) // search unfriendly creature if(owner && NeedDespawn) // hunter trap { - MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius); - MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(this,ok, u_check); + Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck u_check(this, owner, radius); + Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> checker(this, ok, u_check); CellLock<GridReadGuard> cell_lock(cell, p); - TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); + TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); // or unfriendly player/pet if(!ok) { - TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); + TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); } } diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 740ded8e17e..8df2cad8009 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -632,6 +632,23 @@ namespace Trinity float i_range; }; + class AnyUnfriendlyNoTotemUnitInObjectRangeCheck + { + public: + AnyUnfriendlyNoTotemUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} + bool operator()(Unit* u) + { + if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u) && !((Creature*)u)->isTotem()) + return true; + else + return false; + } + private: + WorldObject const* i_obj; + Unit const* i_funit; + float i_range; + }; + class CreatureWithDbGUIDCheck { public: diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 6134be7f9e4..9007da3bdaa 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -1411,8 +1411,10 @@ bool Group::InCombatToInstance(uint32 instanceId) for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) { Player *pPlayer = itr->getSource(); - if(pPlayer->getAttackers().size() && pPlayer->GetInstanceId() == instanceId) - return true; + if(pPlayer && pPlayer->getAttackers().size() && pPlayer->GetInstanceId() == instanceId && (pPlayer->GetMap()->IsRaid() || pPlayer->GetMap()->IsHeroic())) + for(std::set<Unit*>::const_iterator i = pPlayer->getAttackers().begin(); i!=pPlayer->getAttackers().end(); ++i) + if((*i) && (*i)->GetTypeId() == TYPEID_UNIT && ((Creature*)(*i))->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) + return true; } return false; } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 40df012410b..f0fdbd346df 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1781,7 +1781,7 @@ bool InstanceMap::CanEnter(Player *player) // cannot enter while players in the instance are in combat Group *pGroup = player->GetGroup(); - if(!player->isGameMaster() && pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->isAlive() && player->GetMapId() != GetId()) + if(!player->isGameMaster() && pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->GetMapId() != GetId()) { player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT); return false; diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index c61ed531c9a..37a4e1dcd6e 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -266,3 +266,11 @@ void MapInstanced::DestroyInstance(InstancedMaps::iterator &itr) delete itr->second; m_InstancedMaps.erase(itr++); } + +bool MapInstanced::CanEnter(Player *player) +{ + if(Map* map = GetInstance(player)) + return map->CanEnter(player); + + return false; +} diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h index 924f77b8d82..581c42aaad5 100644 --- a/src/game/MapInstanced.h +++ b/src/game/MapInstanced.h @@ -39,6 +39,7 @@ class TRINITY_DLL_DECL MapInstanced : public Map void RemoveAllObjectsInRemoveList(); bool RemoveBones(uint64 guid, float x, float y); void UnloadAll(bool pForce); + bool CanEnter(Player* player); Map* GetInstance(const WorldObject* obj); Map* FindMap(uint32 InstanceId) { return _FindMap(InstanceId); } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 0ede1f00e4d..d6d11ba80a7 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1121,7 +1121,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) m_diminishLevel = unit->GetDiminishing(m_diminishGroup); DiminishingReturnsType type = GetDiminishingReturnsGroupType(m_diminishGroup); // Increase Diminishing on unit, current informations for actually casts will use values above - if((type == DRTYPE_PLAYER && unit->GetTypeId() == TYPEID_PLAYER) || type == DRTYPE_ALL) + if((type == DRTYPE_PLAYER && (unit->GetTypeId() == TYPEID_PLAYER || ((Creature*)unit)->isPet() || ((Creature*)unit)->isPossessedByPlayer())) || type == DRTYPE_ALL) unit->IncrDiminishing(m_diminishGroup); } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e0a6dbe351d..d86cf091a5e 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -339,9 +339,17 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) switch(m_spellInfo->Id) // better way to check unknown { - case 35354://hand of death + case 35354: //Hand of Death { - if(unitTarget && unitTarget->HasAura(38528,0))//protection of elune + if(unitTarget && unitTarget->HasAura(38528,0)) //Protection of Elune + { + damage = 0; + } + break; + } + case 43648: //Electrical Storm + { + if(unitTarget && unitTarget->HasAura(44007, 0)) // Immune Aura { damage = 0; } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 37f627222fc..5ab5e828eec 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -484,6 +484,9 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex) case 23333: // BG spell case 23335: // BG spell case 34976: // BG spell + case 31579: // Arcane Empowerment Rank1 talent aura with one positive and one negative (check not needed in wotlk) + case 31582: // Arcane Empowerment Rank2 + case 31583: // Arcane Empowerment Rank3 return true; case 28441: // not positive dummy spell case 37675: // Chaos Blast diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6996df9ed97..0801ba454bb 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10158,13 +10158,13 @@ void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Un if(duration == -1 || group == DIMINISHING_NONE || caster->IsFriendlyTo(this) ) return; + // test pet/charm masters instead pets/charmeds + Unit const* targetOwner = GetCharmerOrOwner(); + Unit const* casterOwner = caster->GetCharmerOrOwner(); + // Duration of crowd control abilities on pvp target is limited by 10 sec. (2.2.0) if(duration > 10000 && IsDiminishingReturnsGroupDurationLimited(group)) { - // test pet/charm masters instead pets/charmeds - Unit const* targetOwner = GetCharmerOrOwner(); - Unit const* casterOwner = caster->GetCharmerOrOwner(); - Unit const* target = targetOwner ? targetOwner : this; Unit const* source = casterOwner ? casterOwner : caster; @@ -10175,7 +10175,7 @@ void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Un float mod = 1.0f; // Some diminishings applies to mobs too (for example, Stun) - if((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER && GetTypeId() == TYPEID_PLAYER) || GetDiminishingReturnsGroupType(group) == DRTYPE_ALL) + if((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER && (targetOwner ? targetOwner->GetTypeId():GetTypeId()) == TYPEID_PLAYER) || GetDiminishingReturnsGroupType(group) == DRTYPE_ALL) { DiminishingLevels diminish = Level; switch(diminish) |