diff options
author | megamage <none@none> | 2008-11-06 10:27:58 -0600 |
---|---|---|
committer | megamage <none@none> | 2008-11-06 10:27:58 -0600 |
commit | 43910434c5eb2240dc4b4585ccbb5f95fa399d53 (patch) | |
tree | 3dd9f0bc0c9bdc5d6d3ab84585d9c2dea50cd2ef /src | |
parent | 5746d0e98d8a5c4af96102835d501c47ed370def (diff) |
[svn] Rewrite canSeeOrDetect function.
Minor change on trigger creatures.
Remove some unused hacks in scripts.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp | 546 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp | 65 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp | 315 | ||||
-rw-r--r-- | src/game/Creature.cpp | 47 | ||||
-rw-r--r-- | src/game/Creature.h | 3 | ||||
-rw-r--r-- | src/game/Object.cpp | 2 | ||||
-rw-r--r-- | src/game/OutdoorPvPObjectiveAI.cpp | 6 | ||||
-rw-r--r-- | src/game/Player.cpp | 108 | ||||
-rw-r--r-- | src/game/Player.h | 5 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 13 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 7 | ||||
-rw-r--r-- | src/game/Unit.cpp | 306 | ||||
-rw-r--r-- | src/game/Unit.h | 8 | ||||
-rw-r--r-- | src/trinityrealm/AuthCodes.h | 4 | ||||
-rw-r--r-- | src/trinityrealm/AuthSocket.h | 7 | ||||
-rw-r--r-- | src/trinityrealm/Main.cpp | 5 | ||||
-rw-r--r-- | src/trinityrealm/RealmList.cpp | 4 |
17 files changed, 590 insertions, 861 deletions
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp index 06cb81ac03c..8eb93721d02 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp @@ -1,18 +1,18 @@ /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ /* ScriptData SDName: boss_illidan_stormrage @@ -382,8 +382,6 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI uint64 FlameGUID[2]; uint64 GlaiveGUID[2]; - std::list<uint64> ParasiteTargets; // for safety, do not use Unit* - void Reset(); void JustSummoned(Creature* summon) @@ -433,6 +431,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI void Aggro(Unit *who) { + m_creature->setActive(true); DoZoneInCombat(); } @@ -503,19 +502,6 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI } } - void AddParasiteTarget(uint64 targetGUID) - { - for(std::list<uint64>::iterator tIter = ParasiteTargets.begin(); tIter != ParasiteTargets.end(); tIter++) - { - if(*tIter == targetGUID) - return; - } - ParasiteTargets.push_back(targetGUID); - - if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV) - Timer[EVENT_PARASITE_CHECK] += 1000; - } - void DeleteFromThreatList(uint64 TargetGUID) { for(std::list<HostilReference*>::iterator itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr) @@ -562,19 +548,14 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI { case 1://lift off m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - //m_creature->GetMotionMaster()->Clear(false); m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT); - //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ()); m_creature->StopMoving(); DoYell(SAY_TAKEOFF, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_TAKEOFF); Timer[EVENT_FLIGHT_SEQUENCE] = 3000; break; case 2://move to center - //m_creature->GetMotionMaster()->Clear(false); - //m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); m_creature->GetMotionMaster()->MovePoint(0, CENTER_X + 5, CENTER_Y, CENTER_Z); //+5, for SPELL_THROW_GLAIVE bug - //m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); Timer[EVENT_FLIGHT_SEQUENCE] = 0; break; case 3://throw one glaive @@ -614,15 +595,11 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI Timer[EVENT_FLIGHT_SEQUENCE] = 3000; break; case 6://fly to hover point - //m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); m_creature->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z); - //m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); Timer[EVENT_FLIGHT_SEQUENCE] = 0; break; case 7://return to center - //m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z); - //m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); Timer[EVENT_FLIGHT_SEQUENCE] = 0; break; case 8://glaive return @@ -641,9 +618,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI Timer[EVENT_FLIGHT_SEQUENCE] = 2000; break; case 9://land - //m_creature->GetMotionMaster()->Clear(false); m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT); - //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ()); m_creature->StopMoving(); m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); for(uint8 i = 0; i < 2; i++) @@ -663,7 +638,6 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI case 10://attack DoResetThreat(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); - //m_creature->GetMotionMaster()->Clear(); m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); EnterPhase(PHASE_NORMAL_2); break; @@ -723,11 +697,12 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI void UpdateAI(const uint32 diff) { - if((!m_creature->SelectHostilTarget() || !m_creature->getVictim()) && Phase < PHASE_TALK_SEQUENCE) + if((!m_creature->SelectHostilTarget() && !m_creature->getVictim()) && Phase < PHASE_TALK_SEQUENCE) return; Event = EVENT_NULL; for(uint32 i = 1; i <= MaxTimer[Phase]; i++) + { if(Timer[i]) if(Timer[i] <= diff) { @@ -735,224 +710,188 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI Event = (EventIllidan)i; } else Timer[i] -= diff; + } - switch(Phase) - { - case PHASE_NORMAL: - if(HPPCT(m_creature) < 65) - EnterPhase(PHASE_FLIGHT_SEQUENCE); - break; - - case PHASE_NORMAL_2: - if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30) - EnterPhase(PHASE_TALK_SEQUENCE); - break; - - case PHASE_NORMAL_MAIEV: - if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 1) - EnterPhase(PHASE_TALK_SEQUENCE); - break; - - case PHASE_TALK_SEQUENCE: - if(Event == EVENT_TALK_SEQUENCE) - HandleTalkSequence(); - break; - - case PHASE_FLIGHT_SEQUENCE: - if(Event == EVENT_FLIGHT_SEQUENCE) - HandleFlightSequence(); - break; - - case PHASE_TRANSFORM_SEQUENCE: - if(Event == EVENT_TRANSFORM_SEQUENCE) - HandleTransformSequence(); - break; - } + switch(Phase) + { + case PHASE_NORMAL: + if(HPPCT(m_creature) < 65) + EnterPhase(PHASE_FLIGHT_SEQUENCE); + break; + + case PHASE_NORMAL_2: + if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30) + EnterPhase(PHASE_TALK_SEQUENCE); + break; + + case PHASE_NORMAL_MAIEV: + if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 1) + EnterPhase(PHASE_TALK_SEQUENCE); + break; + + case PHASE_TALK_SEQUENCE: + if(Event == EVENT_TALK_SEQUENCE) + HandleTalkSequence(); + break; - if(m_creature->IsNonMeleeSpellCasted(false)) - return; + case PHASE_FLIGHT_SEQUENCE: + if(Event == EVENT_FLIGHT_SEQUENCE) + HandleFlightSequence(); + break; - if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV && !m_creature->HasAura(SPELL_CAGED, 0)) + case PHASE_TRANSFORM_SEQUENCE: + if(Event == EVENT_TRANSFORM_SEQUENCE) + HandleTransformSequence(); + break; + } + + if(m_creature->IsNonMeleeSpellCasted(false)) + return; + + if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV && !m_creature->HasAura(SPELL_CAGED, 0)) + { + switch(Event) + { + //PHASE_NORMAL + case EVENT_BERSERK: + DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_ENRAGE); + DoCast(m_creature, SPELL_BERSERK, true); + Timer[EVENT_BERSERK] = 5000;//The buff actually lasts forever. + break; + + case EVENT_TAUNT: { - switch(Event) - { - //PHASE_NORMAL - case EVENT_BERSERK: - DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(m_creature, SOUND_ENRAGE); - DoCast(m_creature, SPELL_BERSERK, true); - Timer[EVENT_BERSERK] = 5000;//The buff actually lasts forever. - break; - - case EVENT_TAUNT: - { - uint32 random = rand()%4; - char* yell = RandomTaunts[random].text; - uint32 soundid = RandomTaunts[random].sound; - if(yell) - DoYell(yell, LANG_UNIVERSAL, NULL); - if(soundid) - DoPlaySoundToSet(m_creature, soundid); - } - Timer[EVENT_TAUNT] = 32000; - break; - - case EVENT_SHEAR: - DoCast(m_creature->getVictim(), SPELL_SHEAR); - Timer[EVENT_SHEAR] = 25000 + (rand()%16 * 1000); - break; - - case EVENT_FLAME_CRASH: - DoCast(m_creature->getVictim(), SPELL_FLAME_CRASH); - Timer[EVENT_FLAME_CRASH] = 35000; - break; - - case EVENT_PARASITIC_SHADOWFIEND: - { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1); - if(!target) target = m_creature->getVictim(); - if(target->GetTypeId() == TYPEID_PLAYER && !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) - { - target->CastSpell(target, SPELL_PARASITIC_SHADOWFIEND, true); // do not miss - ParasiteTargets.push_back(target->GetGUID()); - Timer[EVENT_PARASITE_CHECK] += 1000; // do not check immediately - } - Timer[EVENT_PARASITIC_SHADOWFIEND] = 40000; - } - break; - - case EVENT_PARASITE_CHECK: - for(std::list<uint64>::iterator tIter = ParasiteTargets.begin(); tIter != ParasiteTargets.end();) - { - Unit* target = Unit::GetUnit((*m_creature), *tIter); - if(!target || !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) - { - if(target && target->isAlive()) - target->CastSpell(target, SPELL_SUMMON_PARASITICS, true); - std::list<uint64>::iterator tIter2 = tIter; - ++tIter; - ParasiteTargets.erase(tIter2); - } - else - ++tIter; - } - if(ParasiteTargets.empty()) - Timer[EVENT_PARASITE_CHECK] = 0; - else - Timer[EVENT_PARASITE_CHECK] = 1000; - break; - - case EVENT_DRAW_SOUL: - DoCast(m_creature->getVictim(), SPELL_DRAW_SOUL); - Timer[EVENT_DRAW_SOUL] = 55000; - break; - - //PHASE_NORMAL_2 - case EVENT_AGONIZING_FLAMES: - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0), SPELL_AGONIZING_FLAMES); - Timer[EVENT_AGONIZING_FLAMES] = 0; - break; - - case EVENT_TRANSFORM_NORMAL: - EnterPhase(PHASE_TRANSFORM_SEQUENCE); - break; - - //PHASE_NORMAL_MAIEV - case EVENT_ENRAGE: - DoCast(m_creature, SPELL_ENRAGE); - Timer[EVENT_ENRAGE] = 0; - break; - - default: - break; - } - DoMeleeAttackIfReady(); + uint32 random = rand()%4; + char* yell = RandomTaunts[random].text; + uint32 soundid = RandomTaunts[random].sound; + if(yell) + DoYell(yell, LANG_UNIVERSAL, NULL); + if(soundid) + DoPlaySoundToSet(m_creature, soundid); } + Timer[EVENT_TAUNT] = 32000; + break; + + case EVENT_SHEAR: + DoCast(m_creature->getVictim(), SPELL_SHEAR); + Timer[EVENT_SHEAR] = 25000 + (rand()%16 * 1000); + break; - if(Phase == PHASE_FLIGHT) + case EVENT_FLAME_CRASH: + DoCast(m_creature->getVictim(), SPELL_FLAME_CRASH); + Timer[EVENT_FLAME_CRASH] = 35000; + break; + + case EVENT_PARASITIC_SHADOWFIEND: { - switch(Event) - { - case EVENT_FIREBALL: - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL); - Timer[EVENT_FIREBALL] = 3000; - break; - - case EVENT_DARK_BARRAGE: - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE); - Timer[EVENT_DARK_BARRAGE] = 0; - break; - - case EVENT_EYE_BLAST: - CastEyeBlast(); - Timer[EVENT_EYE_BLAST] = 0; - break; - - case EVENT_MOVE_POINT: - Phase = PHASE_FLIGHT_SEQUENCE; - Timer[EVENT_FLIGHT_SEQUENCE] = 0;//do not start Event when changing hover point - for (uint8 i = 0; i <= rand()%3; i++) - { - HoverPoint++; - if(HoverPoint > 3) - HoverPoint = 0; - } - m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); - m_creature->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z); - m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); - break; - - default: - break; - } - } + Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 200, true); + if(!target) target = m_creature->getVictim(); + if(target) + m_creature->CastSpell(target, SPELL_PARASITIC_SHADOWFIEND, true); + }break; + + case EVENT_PARASITE_CHECK: + Timer[EVENT_PARASITE_CHECK] = 0; + break; + + case EVENT_DRAW_SOUL: + DoCast(m_creature->getVictim(), SPELL_DRAW_SOUL); + Timer[EVENT_DRAW_SOUL] = 55000; + break; + + //PHASE_NORMAL_2 + case EVENT_AGONIZING_FLAMES: + DoCast(SelectUnit(SELECT_TARGET_RANDOM,0), SPELL_AGONIZING_FLAMES); + Timer[EVENT_AGONIZING_FLAMES] = 0; + break; + + case EVENT_TRANSFORM_NORMAL: + EnterPhase(PHASE_TRANSFORM_SEQUENCE); + break; + + //PHASE_NORMAL_MAIEV + case EVENT_ENRAGE: + DoCast(m_creature, SPELL_ENRAGE); + Timer[EVENT_ENRAGE] = 0; + break; + + default: + break; + } + DoMeleeAttackIfReady(); + } + + if(Phase == PHASE_FLIGHT) + { + switch(Event) + { + case EVENT_FIREBALL: + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL); + Timer[EVENT_FIREBALL] = 3000; + break; - if(Phase == PHASE_DEMON) + case EVENT_DARK_BARRAGE: + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE); + Timer[EVENT_DARK_BARRAGE] = 0; + break; + + case EVENT_EYE_BLAST: + CastEyeBlast(); + Timer[EVENT_EYE_BLAST] = 0; + break; + + case EVENT_MOVE_POINT: + Phase = PHASE_FLIGHT_SEQUENCE; + Timer[EVENT_FLIGHT_SEQUENCE] = 0;//do not start Event when changing hover point + for (uint8 i = 0; i <= rand()%3; i++) { - switch(Event) - { - case EVENT_SHADOW_BLAST: - m_creature->GetMotionMaster()->Clear(false); - if(!m_creature->IsWithinDistInMap(m_creature->getVictim(), 50)||!m_creature->IsWithinLOSInMap(m_creature->getVictim())) - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), 30); - else - m_creature->GetMotionMaster()->MoveIdle(); - DoCast(m_creature->getVictim(), SPELL_SHADOW_BLAST); - Timer[EVENT_SHADOW_BLAST] = 4000; - break; - case EVENT_SHADOWDEMON: - DoCast(m_creature, SPELL_SUMMON_SHADOWDEMON); - Timer[EVENT_SHADOWDEMON] = 0; - Timer[EVENT_FLAME_BURST] += 10000; - break; - case EVENT_FLAME_BURST: - DoCast(m_creature, SPELL_FLAME_BURST); - Timer[EVENT_FLAME_BURST] = 15000; - break; - case EVENT_TRANSFORM_DEMON: - EnterPhase(PHASE_TRANSFORM_SEQUENCE); - break; - default: - break; - } + HoverPoint++; + if(HoverPoint > 3) + HoverPoint = 0; } - } -}; + m_creature->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z); + break; -/********************************** End of Illidan AI ******************************************/ + default: + break; + } + } -//This is used to sort the players by distance in preparation for being charged by the flames. -struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> -{ - const Unit* MainTarget; - TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {}; - // functor for operator ">" - bool operator()(const Unit* _Left, const Unit* _Right) const - { - return (MainTarget->GetDistance(_Left) > MainTarget->GetDistance(_Right)); + if(Phase == PHASE_DEMON) + { + switch(Event) + { + case EVENT_SHADOW_BLAST: + m_creature->GetMotionMaster()->Clear(false); + if(!m_creature->IsWithinDistInMap(m_creature->getVictim(), 50)||!m_creature->IsWithinLOSInMap(m_creature->getVictim())) + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), 30); + else + m_creature->GetMotionMaster()->MoveIdle(); + DoCast(m_creature->getVictim(), SPELL_SHADOW_BLAST); + Timer[EVENT_SHADOW_BLAST] = 4000; + break; + case EVENT_SHADOWDEMON: + DoCast(m_creature, SPELL_SUMMON_SHADOWDEMON); + Timer[EVENT_SHADOWDEMON] = 0; + Timer[EVENT_FLAME_BURST] += 10000; + break; + case EVENT_FLAME_BURST: + DoCast(m_creature, SPELL_FLAME_BURST); + Timer[EVENT_FLAME_BURST] = 15000; + break; + case EVENT_TRANSFORM_DEMON: + EnterPhase(PHASE_TRANSFORM_SEQUENCE); + break; + default: + break; + } + } } }; +/********************************** End of Illidan AI ******************************************/ + struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI { flame_of_azzinothAI(Creature *c) : ScriptedAI(c) {Reset();} @@ -972,29 +911,7 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI void ChargeCheck() { - // Get the Threat List - std::list<HostilReference *> m_threatlist = m_creature->getThreatManager().getThreatList(); - - if(!m_threatlist.size()) return; // He doesn't have anyone in his threatlist, useless to continue - - std::list<Unit *> targets; - std::list<HostilReference *>::iterator itr = m_threatlist.begin(); - for( ; itr!= m_threatlist.end(); ++itr) //store the threat list in a different container - { - Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); - if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER && target->GetPositionZ()>350) //only on alive players - targets.push_back(target); - } - - if (!targets.size()) - return; - - //Sort the list of players - targets.sort(TargetDistanceOrder(m_creature)); - //Resize so we only get the furthest target - targets.resize(1); - - Unit* target = (*targets.begin()); + Unit* target = SelectUnit(SELECT_TARGET_FARTHEST, 0, 200, false); if(target && (!m_creature->IsWithinDistInMap(target, FLAME_CHARGE_DISTANCE))) { m_creature->AttackStop(); @@ -1128,6 +1045,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has strange values.. m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + m_creature->setActive(false); } // Do not call reset in Akama's evade mode, as this will stop him from summoning minions after he kills the first bit @@ -1184,6 +1102,8 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI void BeginChannel() { + m_creature->setActive(true); + float x, y, z; if(GETGO(Gate, GateGUID)) Gate->GetPosition(x, y, z); @@ -1527,7 +1447,6 @@ struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI } m_creature->InterruptNonMeleeSpells(false); m_creature->GetMotionMaster()->Clear(false); - //m_creature->GetMotionMaster()->MoveIdle(); m_creature->AttackStop(); m_creature->SetUInt64Value(UNIT_FIELD_TARGET, IllidanGUID); MaxTimer = 0; @@ -1557,7 +1476,6 @@ struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI m_creature->AttackStop(); m_creature->InterruptNonMeleeSpells(false); m_creature->GetMotionMaster()->Clear(false); - //m_creature->GetMotionMaster()->MoveIdle(); m_creature->Relocate(x, y, z); m_creature->SendMonsterMove(x, y, z, 0, 0, 0); DoCast(m_creature, SPELL_TELEPORT_VISUAL, true); @@ -1839,9 +1757,7 @@ struct TRINITY_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI { if(!m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) { - m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_PARASITIC_SHADOWFIEND, true); //do not stack - if(GETCRE(Illidan, IllidanGUID)) - ((boss_illidan_stormrageAI*)Illidan->AI())->AddParasiteTarget(m_creature->getVictim()->GetGUID()); + m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_PARASITIC_SHADOWFIEND, true, 0, 0, IllidanGUID); //do not stack } m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); @@ -1936,67 +1852,6 @@ struct TRINITY_DLL_DECL demonfireAI : public ScriptedAI } }; -struct TRINITY_DLL_DECL blazeAI : public ScriptedAI -{ - blazeAI(Creature *c) : ScriptedAI(c) {Reset();} - - uint32 BlazeTimer; - uint32 DespawnTimer; - - void Reset() - { - BlazeTimer = 3000; - DespawnTimer = 60000; // Spell duration = 1 min - //((TemporarySummon*)m_creature)->Summon(TEMPSUMMON_TIMED_DESPAWN, 0, false); - } - - void Aggro(Unit *who) {} - void AttackStart(Unit* who) { } - void MoveInLineOfSight(Unit *who){ } - - void UpdateAI(const uint32 diff) - { - if(BlazeTimer) - if(BlazeTimer <= diff) - { - DoCast(m_creature, SPELL_BLAZE_EFFECT);//duration 60s - BlazeTimer = 0; - }else BlazeTimer -= diff; - - if(DespawnTimer < diff) - { - m_creature->SetVisibility(VISIBILITY_OFF); - m_creature->setDeathState(JUST_DIED); - }else DespawnTimer -= diff; - } -}; - -struct TRINITY_DLL_DECL flamecrashAI : public ScriptedAI -{ - flamecrashAI(Creature *c) : ScriptedAI(c) {Reset();} - - uint32 DespawnTimer; - - void Reset() - { - DoCast(m_creature, SPELL_FLAME_CRASH_EFFECT);//duration inf - DespawnTimer = 120000; // summon spell duration - } - - void Aggro(Unit *who) {} - void AttackStart(Unit *who) { } - void MoveInLineOfSight(Unit *who){ } - - void UpdateAI(const uint32 diff) - { - if(DespawnTimer < diff) - { - m_creature->SetVisibility(VISIBILITY_OFF); - m_creature->setDeathState(JUST_DIED); - }else DespawnTimer -= diff; - } -}; - struct TRINITY_DLL_DECL blade_of_azzinothAI : public ScriptedAI { blade_of_azzinothAI(Creature* c) : ScriptedAI(c) {} @@ -2070,8 +1925,6 @@ void boss_illidan_stormrageAI::Reset() FlightCount = 0; TransformCount = 0; - ParasiteTargets.clear(); - m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 21135); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -2080,6 +1933,7 @@ void boss_illidan_stormrageAI::Reset() m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT); m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); + m_creature->setActive(false); } void boss_illidan_stormrageAI::HandleTalkSequence() @@ -2377,21 +2231,11 @@ CreatureAI* GetAI_shadow_demon(Creature *_Creature) return new shadow_demonAI (_Creature); } -CreatureAI* GetAI_flamecrash(Creature *_Creature) -{ - return new flamecrashAI (_Creature); -} - CreatureAI* GetAI_demonfire(Creature *_Creature) { return new demonfireAI (_Creature); } -CreatureAI* GetAI_blaze(Creature *_Creature) -{ - return new blazeAI (_Creature); -} - CreatureAI* GetAI_blade_of_azzinoth(Creature *_Creature) { return new blade_of_azzinothAI (_Creature); @@ -2449,21 +2293,11 @@ void AddSC_boss_illidan() m_scripts[nrscripts++] = newscript; newscript = new Script; - newscript->Name="mob_flame_crash"; - newscript->GetAI = GetAI_flamecrash; - m_scripts[nrscripts++] = newscript; - - newscript = new Script; newscript->Name="mob_demon_fire"; newscript->GetAI = GetAI_demonfire; m_scripts[nrscripts++] = newscript; newscript = new Script; - newscript->Name="mob_blaze"; - newscript->GetAI = GetAI_blaze; - m_scripts[nrscripts++] = newscript; - - newscript = new Script; newscript->Name = "mob_parasitic_shadowfiend"; newscript->GetAI = GetAI_parasitic_shadowfiend; m_scripts[nrscripts++] = newscript; diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp index 50a0a4de3ac..81beb63166a 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp @@ -634,45 +634,6 @@ struct TRINITY_DLL_DECL boss_essence_of_angerAI : public ScriptedAI } } - void SelectSpiteTarget(uint32 num, float max_range = 999) - { - if(!num) return; - - CellPair p(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - std::list<Unit *> tempUnitMap; - - { - Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range); - Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check); - - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); - - CellLock<GridReadGuard> cell_lock(cell, p); - cell_lock->Visit(cell_lock, world_unit_searcher, *(m_creature->GetMap())); - cell_lock->Visit(cell_lock, grid_unit_searcher, *(m_creature->GetMap())); - } - - std::list<Unit*>::iterator itr; - while(tempUnitMap.size() && SpiteTargetGUID.size() < num) - { - itr = tempUnitMap.begin(); - advance(itr, rand()%tempUnitMap.size()); - SpiteTargetGUID.push_back((*itr)->GetGUID()); - tempUnitMap.erase(itr); - } - - for(itr = tempUnitMap.begin(); itr != tempUnitMap.end(); ++itr) - (*itr)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->CastSpell(m_creature, SPELL_SPITE_TARGET, true); // must true - for(itr = tempUnitMap.begin(); itr != tempUnitMap.end(); ++itr) - (*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - void UpdateAI(const uint32 diff) { //Return since we have no target @@ -700,7 +661,7 @@ struct TRINITY_DLL_DECL boss_essence_of_angerAI : public ScriptedAI if(SoulScreamTimer < diff) { DoCast(m_creature->getVictim(), SPELL_SOUL_SCREAM); - SoulScreamTimer = 10000; + SoulScreamTimer = 9000 + rand()%2000; if(!(rand()%3)) { DoYell(ANGER_SAY_SCREAM,LANG_UNIVERSAL,NULL); @@ -710,26 +671,10 @@ struct TRINITY_DLL_DECL boss_essence_of_angerAI : public ScriptedAI if(SpiteTimer < diff) { - if(!SpiteTargetGUID.empty()) - { - for (std::list<uint64>::iterator itr = SpiteTargetGUID.begin(); itr != SpiteTargetGUID.end(); ++itr) - { - if(Unit* target = Unit::GetUnit(*m_creature, *itr)) - { - target->RemoveAurasDueToSpell(SPELL_SPITE_TARGET); - m_creature->CastSpell(target, SPELL_SPITE_DAMAGE, true); - } - } - SpiteTargetGUID.clear(); - SpiteTimer = 24000; - } - else - { - SelectSpiteTarget(3); - SpiteTimer = 6000; - DoYell(ANGER_SAY_SPEC,LANG_UNIVERSAL,NULL); - DoPlaySoundToSet(m_creature, ANGER_SOUND_SPEC); - } + DoCast(m_creature, SPELL_SPITE_TARGET); + SpiteTimer = 30000; + DoYell(ANGER_SAY_SPEC,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature, ANGER_SOUND_SPEC); }else SpiteTimer -= diff; DoMeleeAttackIfReady(); diff --git a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp index a4bac36295d..cfeb700282b 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp @@ -1,18 +1,18 @@ /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ /* ScriptData SDName: Instance_Black_Temple @@ -55,22 +55,21 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance uint64 BloodElfCouncilVoice; uint64 IllidanStormrage; - uint16 BossKilled; + uint16 BossKilled; uint64 NajentusGate; uint64 MainTempleDoors; - uint64 ShadeOfAkamaDoor; - uint64 CommonDoor;//Teron - uint64 TeronDoor; - uint64 GuurtogDoor; - uint64 MotherDoor; - uint64 TempleDoor;//Befor mother - uint64 CouncilDoor; - uint64 SimpleDoor;//council + uint64 ShadeOfAkamaDoor; + uint64 CommonDoor;//Teron + uint64 TeronDoor; + uint64 GuurtogDoor; + uint64 MotherDoor; + uint64 TempleDoor;//Befor mother + uint64 CouncilDoor; + uint64 SimpleDoor;//council uint64 IllidanGate; uint64 IllidanDoor[2]; - uint32 Encounters[ENCOUNTERS]; void Initialize() @@ -88,18 +87,18 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance BloodElfCouncilVoice = 0; IllidanStormrage = 0; - BossKilled = 0; + BossKilled = 0; NajentusGate = 0; MainTempleDoors = 0; - ShadeOfAkamaDoor= 0; - CommonDoor = 0;//teron - TeronDoor = 0; - GuurtogDoor = 0; - MotherDoor = 0; - TempleDoor = 0; - SimpleDoor = 0;//Bycouncil - CouncilDoor = 0; + ShadeOfAkamaDoor= 0; + CommonDoor = 0;//teron + TeronDoor = 0; + GuurtogDoor = 0; + MotherDoor = 0; + TempleDoor = 0; + SimpleDoor = 0;//Bycouncil + CouncilDoor = 0; IllidanGate = 0; IllidanDoor[0] = 0; IllidanDoor[1] = 0; @@ -118,38 +117,32 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance void OpenDoor(uint64 DoorGUID, bool open) { - if(((InstanceMap*)instance)->GetPlayers().size()) - if(Player* first = ((InstanceMap*)instance)->GetPlayers().front()) - if(GameObject *Door = GameObject::GetGameObject(*first, DoorGUID)) - Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); + if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) + Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); } - void CloseDoor(uint64 DoorGUID, bool close) - { - if(((InstanceMap*)instance)->GetPlayers().size()) - if(Player* first = ((InstanceMap*)instance)->GetPlayers().front()) - if(GameObject *Door = GameObject::GetGameObject(*first, DoorGUID)) - Door->SetUInt32Value(GAMEOBJECT_STATE, close ? 1 : 0); - } - - + void CloseDoor(uint64 DoorGUID, bool close) + { + if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) + Door->SetUInt32Value(GAMEOBJECT_STATE, close ? 1 : 0); + } void OnCreatureCreate(Creature *creature, uint32 creature_entry) { switch(creature_entry) { - case 22887: Najentus = creature->GetGUID(); break; - case 23089: Akama = creature->GetGUID(); break; - case 22990: Akama_Shade = creature->GetGUID(); break; - case 22841: ShadeOfAkama = creature->GetGUID(); break; - case 22898: Supremus = creature->GetGUID(); break; - case 22917: IllidanStormrage = creature->GetGUID(); break; - case 22949: GathiosTheShatterer = creature->GetGUID(); break; - case 22950: HighNethermancerZerevor = creature->GetGUID(); break; - case 22951: LadyMalande = creature->GetGUID(); break; - case 22952: VerasDarkshadow = creature->GetGUID(); break; - case 23426: IllidariCouncil = creature->GetGUID(); break; - case 23499: BloodElfCouncilVoice = creature->GetGUID(); break; + case 22887: Najentus = creature->GetGUID(); break; + case 23089: Akama = creature->GetGUID(); break; + case 22990: Akama_Shade = creature->GetGUID(); break; + case 22841: ShadeOfAkama = creature->GetGUID(); break; + case 22898: Supremus = creature->GetGUID(); break; + case 22917: IllidanStormrage = creature->GetGUID(); break; + case 22949: GathiosTheShatterer = creature->GetGUID(); break; + case 22950: HighNethermancerZerevor = creature->GetGUID(); break; + case 22951: LadyMalande = creature->GetGUID(); break; + case 22952: VerasDarkshadow = creature->GetGUID(); break; + case 23426: IllidariCouncil = creature->GetGUID(); break; + case 23499: BloodElfCouncilVoice = creature->GetGUID(); break; } } @@ -157,38 +150,38 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance { switch(go->GetEntry()) { - case 185483: // Gate past Naj'entus (at the entrance to Supermoose's courtyards) - NajentusGate = go->GetGUID();break; - case 185882: // Main Temple Doors - right past Supermoose (Supremus) - MainTempleDoors = go->GetGUID();break; - case 185478: - ShadeOfAkamaDoor = go->GetGUID();break; - case 185480: - CommonDoor = go->GetGUID();break; - case 186153: - TeronDoor = go->GetGUID();break; - case 185892: - GuurtogDoor = go->GetGUID();break; - case 185479: - TempleDoor = go->GetGUID();break; - case 185482: - MotherDoor = go->GetGUID();break; - case 185481: - CouncilDoor = go->GetGUID();break; - case 186152://used by council - SimpleDoor = go->GetGUID();break; - case 185905: // Gate leading to Temple Summit - IllidanGate = go->GetGUID(); - go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); - break; - case 186261: // Right door at Temple Summit - IllidanDoor[0] = go->GetGUID(); - go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); - break; - case 186262: // Left door at Temple Summit - IllidanDoor[1] = go->GetGUID(); - go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); - break; + case 185483: // Gate past Naj'entus (at the entrance to Supermoose's courtyards) + NajentusGate = go->GetGUID();break; + case 185882: // Main Temple Doors - right past Supermoose (Supremus) + MainTempleDoors = go->GetGUID();break; + case 185478: + ShadeOfAkamaDoor = go->GetGUID();break; + case 185480: + CommonDoor = go->GetGUID();break; + case 186153: + TeronDoor = go->GetGUID();break; + case 185892: + GuurtogDoor = go->GetGUID();break; + case 185479: + TempleDoor = go->GetGUID();break; + case 185482: + MotherDoor = go->GetGUID();break; + case 185481: + CouncilDoor = go->GetGUID();break; + case 186152://used by council + SimpleDoor = go->GetGUID();break; + case 185905: // Gate leading to Temple Summit + IllidanGate = go->GetGUID(); + go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); + break; + case 186261: // Right door at Temple Summit + IllidanDoor[0] = go->GetGUID(); + go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); + break; + case 186262: // Left door at Temple Summit + IllidanDoor[1] = go->GetGUID(); + go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); + break; } } @@ -196,23 +189,23 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance { switch(identifier) { - case DATA_HIGHWARLORDNAJENTUS: return Najentus; - case DATA_AKAMA: return Akama; - case DATA_AKAMA_SHADE: return Akama_Shade; - case DATA_SHADEOFAKAMA: return ShadeOfAkama; - case DATA_SUPREMUS: return Supremus; - case DATA_ILLIDANSTORMRAGE: return IllidanStormrage; - case DATA_GATHIOSTHESHATTERER: return GathiosTheShatterer; - case DATA_HIGHNETHERMANCERZEREVOR: return HighNethermancerZerevor; - case DATA_LADYMALANDE: return LadyMalande; - case DATA_VERASDARKSHADOW: return VerasDarkshadow; - case DATA_ILLIDARICOUNCIL: return IllidariCouncil; - case DATA_GAMEOBJECT_NAJENTUS_GATE: return NajentusGate; - case DATA_GAMEOBJECT_ILLIDAN_GATE: return IllidanGate; - case DATA_GAMEOBJECT_ILLIDAN_DOOR_R: return IllidanDoor[0]; - case DATA_GAMEOBJECT_ILLIDAN_DOOR_L: return IllidanDoor[1]; - case DATA_GAMEOBJECT_SUPREMUS_DOORS: return MainTempleDoors; - case DATA_BLOOD_ELF_COUNCIL_VOICE: return BloodElfCouncilVoice; + case DATA_HIGHWARLORDNAJENTUS: return Najentus; + case DATA_AKAMA: return Akama; + case DATA_AKAMA_SHADE: return Akama_Shade; + case DATA_SHADEOFAKAMA: return ShadeOfAkama; + case DATA_SUPREMUS: return Supremus; + case DATA_ILLIDANSTORMRAGE: return IllidanStormrage; + case DATA_GATHIOSTHESHATTERER: return GathiosTheShatterer; + case DATA_HIGHNETHERMANCERZEREVOR: return HighNethermancerZerevor; + case DATA_LADYMALANDE: return LadyMalande; + case DATA_VERASDARKSHADOW: return VerasDarkshadow; + case DATA_ILLIDARICOUNCIL: return IllidariCouncil; + case DATA_GAMEOBJECT_NAJENTUS_GATE: return NajentusGate; + case DATA_GAMEOBJECT_ILLIDAN_GATE: return IllidanGate; + case DATA_GAMEOBJECT_ILLIDAN_DOOR_R: return IllidanDoor[0]; + case DATA_GAMEOBJECT_ILLIDAN_DOOR_L: return IllidanDoor[1]; + case DATA_GAMEOBJECT_SUPREMUS_DOORS: return MainTempleDoors; + case DATA_BLOOD_ELF_COUNCIL_VOICE: return BloodElfCouncilVoice; } return 0; @@ -222,69 +215,69 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance { switch(type) { - case DATA_HIGHWARLORDNAJENTUSEVENT: Encounters[0] = data; break; - case DATA_SUPREMUSEVENT: Encounters[1] = data; break; - case DATA_SHADEOFAKAMAEVENT: Encounters[2] = data; break; - case DATA_TERONGOREFIENDEVENT: Encounters[3] = data; break; - case DATA_GURTOGGBLOODBOILEVENT: Encounters[4] = data; break; - case DATA_RELIQUARYOFSOULSEVENT: Encounters[5] = data; break; - case DATA_MOTHERSHAHRAZEVENT: Encounters[6] = data; break; - case DATA_ILLIDARICOUNCILEVENT: Encounters[7] = data; break; - case DATA_ILLIDANSTORMRAGEEVENT: Encounters[8] = data; break; + case DATA_HIGHWARLORDNAJENTUSEVENT: Encounters[0] = data; break; + case DATA_SUPREMUSEVENT: Encounters[1] = data; break; + case DATA_SHADEOFAKAMAEVENT: Encounters[2] = data; break; + case DATA_TERONGOREFIENDEVENT: Encounters[3] = data; break; + case DATA_GURTOGGBLOODBOILEVENT: Encounters[4] = data; break; + case DATA_RELIQUARYOFSOULSEVENT: Encounters[5] = data; break; + case DATA_MOTHERSHAHRAZEVENT: Encounters[6] = data; break; + case DATA_ILLIDARICOUNCILEVENT: Encounters[7] = data; break; + case DATA_ILLIDANSTORMRAGEEVENT: Encounters[8] = data; break; } if(data == DONE) - { + { SaveToDB(); - BossKilled++; - } - CheckInstanceStatus(); + BossKilled++; + } + CheckInstanceStatus(); } - void CheckInstanceStatus() - { - if(BossKilled >= 6) - OpenDoor(TempleDoor, true); - if(Encounters[0] == DONE) - OpenDoor(NajentusGate, true); - if(Encounters[2] == IN_PROGRESS) - CloseDoor(ShadeOfAkamaDoor, true); - else OpenDoor(ShadeOfAkamaDoor, true); - if(Encounters[3] == IN_PROGRESS) - { - CloseDoor(TeronDoor, true); - CloseDoor(CommonDoor, true); - }else{ - OpenDoor(TeronDoor, true); - OpenDoor(CommonDoor, true); - } - if(Encounters[4] == DONE) - OpenDoor(GuurtogDoor, true); - if(Encounters[6] == DONE) - OpenDoor(MotherDoor, true); - if(Encounters[7] == IN_PROGRESS) - { - CloseDoor(CouncilDoor, true); - CloseDoor(SimpleDoor, true); - }else{ - OpenDoor(CouncilDoor, true); - OpenDoor(SimpleDoor, true); - } - } + void CheckInstanceStatus() + { + if(BossKilled >= 6) + OpenDoor(TempleDoor, true); + if(Encounters[0] == DONE) + OpenDoor(NajentusGate, true); + if(Encounters[2] == IN_PROGRESS) + CloseDoor(ShadeOfAkamaDoor, true); + else OpenDoor(ShadeOfAkamaDoor, true); + if(Encounters[3] == IN_PROGRESS) + { + CloseDoor(TeronDoor, true); + CloseDoor(CommonDoor, true); + }else{ + OpenDoor(TeronDoor, true); + OpenDoor(CommonDoor, true); + } + if(Encounters[4] == DONE) + OpenDoor(GuurtogDoor, true); + if(Encounters[6] == DONE) + OpenDoor(MotherDoor, true); + if(Encounters[7] == IN_PROGRESS) + { + CloseDoor(CouncilDoor, true); + CloseDoor(SimpleDoor, true); + }else{ + OpenDoor(CouncilDoor, true); + OpenDoor(SimpleDoor, true); + } + } uint32 GetData(uint32 type) { switch(type) { - case DATA_HIGHWARLORDNAJENTUSEVENT: return Encounters[0]; - case DATA_SUPREMUSEVENT: return Encounters[1]; - case DATA_SHADEOFAKAMAEVENT: return Encounters[2]; - case DATA_TERONGOREFIENDEVENT: return Encounters[3]; - case DATA_GURTOGGBLOODBOILEVENT: return Encounters[4]; - case DATA_RELIQUARYOFSOULSEVENT: return Encounters[5]; - case DATA_MOTHERSHAHRAZEVENT: return Encounters[6]; - case DATA_ILLIDARICOUNCILEVENT: return Encounters[7]; - case DATA_ILLIDANSTORMRAGEEVENT: return Encounters[8]; + case DATA_HIGHWARLORDNAJENTUSEVENT: return Encounters[0]; + case DATA_SUPREMUSEVENT: return Encounters[1]; + case DATA_SHADEOFAKAMAEVENT: return Encounters[2]; + case DATA_TERONGOREFIENDEVENT: return Encounters[3]; + case DATA_GURTOGGBLOODBOILEVENT: return Encounters[4]; + case DATA_RELIQUARYOFSOULSEVENT: return Encounters[5]; + case DATA_MOTHERSHAHRAZEVENT: return Encounters[6]; + case DATA_ILLIDARICOUNCILEVENT: return Encounters[7]; + case DATA_ILLIDANSTORMRAGEEVENT: return Encounters[8]; } return 0; @@ -319,8 +312,8 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance OUT_LOAD_INST_DATA(in); std::istringstream stream(in); stream >> Encounters[0] >> Encounters[1] >> Encounters[2] >> Encounters[3] - >> Encounters[4] >> Encounters[5] >> Encounters[6] >> Encounters[7] - >> Encounters[8]; + >> Encounters[4] >> Encounters[5] >> Encounters[6] >> Encounters[7] + >> Encounters[8]; for(uint8 i = 0; i < ENCOUNTERS; ++i) if(Encounters[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. Encounters[i] = NOT_STARTED; diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index b15010ec67d..0bb7c024c1a 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -319,6 +319,10 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) m_spells[2] = GetCreatureInfo()->spell3; m_spells[3] = GetCreatureInfo()->spell4; + // HACK: trigger creature is always not selectable + if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + return true; } @@ -1487,6 +1491,47 @@ void Creature::DeleteFromDB() WorldDatabase.CommitTransaction(); } +bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const +{ + // not in world + if(!IsInWorld() || !u->IsInWorld()) + return false; + + // all dead creatures/players not visible for any creatures + if(!u->isAlive() || !isAlive()) + return false; + + // Always can see self + if (u == this) + return true; + + // always seen by owner + if(GetGUID() == u->GetCharmerOrOwnerGUID()) + return true; + + if(u->GetVisibility() == VISIBILITY_OFF) //GM + return false; + + // invisible aura + if((m_invisibilityMask || u->m_invisibilityMask) && !canDetectInvisibilityOf(u)) + return false; + + // unit got in stealth in this moment and must ignore old detected state + //if (m_Visibility == VISIBILITY_GROUP_NO_DETECT) + // return false; + + // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible + if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH) + { + //do not know what is the use of this detect + if(!detect || !canDetectStealthOf(u, GetDistance(u))) + return false; + } + + // Now check is target visible with LoS + return u->IsWithinLOS(GetPositionX(),GetPositionY(),GetPositionZ()); +} + float Creature::GetAttackDistance(Unit const* pl) const { float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO); @@ -1698,7 +1743,7 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim) return NULL; } -bool Creature::IsVisibleInGridForPlayer(Player* pl) const +bool Creature::IsVisibleInGridForPlayer(Player const* pl) const { // gamemaster in GM mode see all, including ghosts if(pl->isGameMaster()) diff --git a/src/game/Creature.h b/src/game/Creature.h index 679b17f416f..e65c72465f2 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -547,6 +547,7 @@ class TRINITY_DLL_SPEC Creature : public Unit CreatureSpellCooldowns m_CreatureCategoryCooldowns; uint32 m_GlobalCooldown; + bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; float GetAttackDistance(Unit const* pl) const; void CallAssistence(); @@ -560,7 +561,7 @@ class TRINITY_DLL_SPEC Creature : public Unit Cell const& GetCurrentCell() const { return m_currentCell; } void SetCurrentCell(Cell const& cell) { m_currentCell = cell; } - bool IsVisibleInGridForPlayer(Player* pl) const; + bool IsVisibleInGridForPlayer(Player const* pl) const; void RemoveCorpse(); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 4fbd030217a..568e9a90a31 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1486,7 +1486,7 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa { if(GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) pCreature->setFaction(((Unit*)this)->getFaction()); - pCreature->CastSpell(pCreature, pCreature->m_spells[0], true, 0, 0, GetGUID()); + pCreature->CastSpell(pCreature, pCreature->m_spells[0], false, 0, 0, GetGUID()); } //return the creature therewith the summoner has access to it diff --git a/src/game/OutdoorPvPObjectiveAI.cpp b/src/game/OutdoorPvPObjectiveAI.cpp index fc762f77e7a..62c4cb96191 100644 --- a/src/game/OutdoorPvPObjectiveAI.cpp +++ b/src/game/OutdoorPvPObjectiveAI.cpp @@ -50,13 +50,13 @@ bool OutdoorPvPObjectiveAI::IsVisible(Unit *pl) const void OutdoorPvPObjectiveAI::AttackStart(Unit *) { - EnterEvadeMode(); + //EnterEvadeMode(); } void OutdoorPvPObjectiveAI::EnterEvadeMode() { - i_creature.DeleteThreatList(); - i_creature.CombatStop(); +// i_creature.DeleteThreatList(); +// i_creature.CombatStop(); } void OutdoorPvPObjectiveAI::UpdateAI(const uint32 diff) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 7723cb23a3b..e02ac468244 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2000,8 +2000,8 @@ void Player::SetGMVisible(bool on) // Reapply stealth/invisibility if active or show if not any if(HasAuraType(SPELL_AURA_MOD_STEALTH)) SetVisibility(VISIBILITY_GROUP_STEALTH); - else if(HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) - SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + //else if(HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) + // SetVisibility(VISIBILITY_GROUP_INVISIBILITY); else SetVisibility(VISIBILITY_ON); } @@ -16395,7 +16395,6 @@ void Player::HandleStealthedUnitsDetection() if ((*i)->isVisibleForOrDetect(this,true)) { - (*i)->SendUpdateToPlayer(this); m_clientGUIDs.insert((*i)->GetGUID()); @@ -17188,7 +17187,108 @@ void Player::ReportedAfkBy(Player* reporter) } } -bool Player::IsVisibleInGridForPlayer( Player* pl ) const +bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const +{ + // Always can see self + if (u == this) + return true; + + // player visible for other player if not logout and at same transport + // including case when player is out of world + bool at_same_transport = + GetTransport() && u->GetTypeId() == TYPEID_PLAYER + && !GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() + && !GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() + && GetTransport() == ((Player*)u)->GetTransport(); + + // not in world + if(!at_same_transport && (!IsInWorld() || !u->IsInWorld())) + return false; + + // forbidden to seen (at GM respawn command) + if(u->GetVisibility() == VISIBILITY_RESPAWN) + return false; + + // always seen by owner + if(GetGUID() == u->GetCharmerOrOwnerGUID()) + return true; + + // Grid dead/alive checks + // non visible at grid for any stealth state + if(!u->IsVisibleInGridForPlayer(this)) + return false; + + // If the player is currently possessing, update visibility from the possessed unit's location + const Unit* target = isPossessing() ? GetCharm() : this; + + // different visible distance checks + if(isInFlight()) // what see player in flight + { + if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } + else if(!u->isAlive()) // distance for show body + { + if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } + else if(u->GetTypeId()==TYPEID_PLAYER) // distance for show player + { + // Players far than max visible distance for player or not in our map are not visible too + if (!at_same_transport && !target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else if(u->GetCharmerOrOwnerGUID()) // distance for show pet/charmed + { + // Pet/charmed far than max visible distance for player or not in our map are not visible too + if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else // distance for show creature + { + // Units far than max visible distance for creature or not in our map are not visible too + if (!target->IsWithinDistInMap(u, target->isActive() + ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) + : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))) + return false; + } + + // GMs see any players, not higher GMs and all units + if(isGameMaster()) + { + if(u->GetTypeId() == TYPEID_PLAYER) + return ((Player *)u)->GetSession()->GetSecurity() <= GetSession()->GetSecurity(); + else + return true; + } + + if(u->GetVisibility() == VISIBILITY_OFF) + return false; + + // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting) + if((m_invisibilityMask || u->m_invisibilityMask) && !canDetectInvisibilityOf(u)) + if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u)))) + return false; + + // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible + if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH) + { + // if player is dead then he can't detect anyone in anycases + //do not know what is the use of this detect + // stealth and detected and visible for some seconds + if(!isAlive()) + detect = false; + if(m_DetectInvTimer < 300 || !HaveAtClient(u)) + if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u)))) + if(!detect || !canDetectStealthOf(u, GetDistance(u))) + return false; + } + + // Now check is target visible with LoS + return u->IsWithinLOS(GetPositionX(),GetPositionY(),GetPositionZ()); +} + +bool Player::IsVisibleInGridForPlayer( Player const * pl ) const { // gamemaster in GM mode see all, including ghosts if(pl->isGameMaster() && GetSession()->GetSecurity() <= pl->GetSession()->GetSecurity()) diff --git a/src/game/Player.h b/src/game/Player.h index f8865040a9e..2e8de5e5823 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1992,9 +1992,10 @@ class TRINITY_DLL_SPEC Player : public Unit typedef std::set<uint64> ClientGUIDs; ClientGUIDs m_clientGUIDs; - bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); } + bool HaveAtClient(WorldObject const* u) const { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); } - bool IsVisibleInGridForPlayer(Player* pl) const; + bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; + bool IsVisibleInGridForPlayer(Player const* pl) const; bool IsVisibleGloballyFor(Player* pl) const; void UpdateVisibilityOf(WorldObject* target); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index d0a70858b71..1d7df27a76f 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3230,7 +3230,8 @@ void Aura::HandleModStealth(bool apply, bool Real) // apply only if not in GM invisibility (and overwrite invisibility state) if(m_target->GetVisibility()!=VISIBILITY_OFF) { - m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); + //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); + m_target->SetVisibility(VISIBILITY_OFF); m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); } @@ -3258,8 +3259,9 @@ void Aura::HandleModStealth(bool apply, bool Real) // restore invisibility if any if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) { - m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); - m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); + //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + m_target->SetVisibility(VISIBILITY_ON); } else { @@ -3314,8 +3316,9 @@ void Aura::HandleInvisibility(bool apply, bool Real) if(m_target->GetVisibility()==VISIBILITY_ON) { // Aura not added yet but visibility code expect temporary add aura - m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); - m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); + //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + m_target->SetVisibility(VISIBILITY_ON); } } else diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e8060d282e6..eeafd0d024e 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3576,6 +3576,13 @@ void Spell::EffectSummonGuardian(uint32 i) return; } + // trigger + if(m_spellInfo->Id == 40276) + { + EffectSummonWild(i); + return; + } + // set timer for unsummon int32 duration = GetSpellDuration(m_spellInfo); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 0c94c095c3e..00cd8694b35 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8506,9 +8506,6 @@ bool Unit::isTargetableForAttack() const if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) return false; - if(GetTypeId()==TYPEID_UNIT && (((Creature *)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)) - return false; - return isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; } @@ -8580,240 +8577,79 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList) { if(!u) return false; + return u->canSeeOrDetect(this, detect, inVisibleList); +} - // Always can see self - if (u==this) - return true; - - // player visible for other player if not logout and at same transport - // including case when player is out of world - bool at_same_transport = - GetTypeId() == TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER && - !((Player*)this)->GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() && - !((Player*)this)->GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() && - ((Player*)this)->GetTransport() && ((Player*)this)->GetTransport() == ((Player*)u)->GetTransport(); - - // not in world - if(!at_same_transport && (!IsInWorld() || !u->IsInWorld())) - return false; - - // forbidden to seen (at GM respawn command) - if(m_Visibility==VISIBILITY_RESPAWN) - return false; +bool Unit::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const +{ + return true; +} - // always seen by owner - if(GetCharmerOrOwnerGUID()==u->GetGUID()) +bool Unit::canDetectInvisibilityOf(Unit const* u) const +{ + if(m_invisibilityMask & u->m_invisibilityMask) // same group return true; + AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark + for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) + if((*iter)->GetCasterGUID()==u->GetGUID()) + return true; - // Grid dead/alive checks - if( u->GetTypeId()==TYPEID_PLAYER) - { - // non visible at grid for any stealth state - if(!IsVisibleInGridForPlayer((Player *)u)) - return false; - - // if player is dead then he can't detect anyone in anycases - if(!u->isAlive()) - detect = false; - } - else - { - // all dead creatures/players not visible for any creatures - if(!u->isAlive() || !isAlive()) - return false; - } - - // If the player is currently possessing, update visibility from the possessed unit's location - const Unit* target = u->GetTypeId() == TYPEID_PLAYER && u->isPossessing() ? u->GetCharm() : u; - - // different visible distance checks - if(u->isInFlight()) // what see player in flight - { - // use object grey distance for all (only see objects any way) - if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) - return false; - } - else if(!isAlive()) // distance for show body - { - if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) - return false; - } - else if(GetTypeId()==TYPEID_PLAYER) // distance for show player + if(uint32 mask = (m_detectInvisibilityMask & u->m_invisibilityMask)) { - if(u->GetTypeId()==TYPEID_PLAYER) - { - // Players far than max visible distance for player or not in our map are not visible too - if (!at_same_transport && !IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) - return false; - } - else + for(uint32 i = 0; i < 10; ++i) { - // Units far than max visible distance for creature or not in our map are not visible too - // Active unit should always be visibile - if (!IsWithinDistInMap(target, target->isActive() - ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) - : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))) - return false; - } - } - else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed - { - // Pet/charmed far than max visible distance for player or not in our map are not visible too - if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) - return false; - } - else // distance for show creature - { - // Units far than max visible distance for creature or not in our map are not visible too - if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) - return false; - } - - // Visible units, always are visible for all units, except for units under invisibility - if (m_Visibility == VISIBILITY_ON && u->m_invisibilityMask==0) - return true; - - // GMs see any players, not higher GMs and all units - if (u->GetTypeId() == TYPEID_PLAYER && ((Player *)u)->isGameMaster()) - { - if(GetTypeId() == TYPEID_PLAYER) - return ((Player *)this)->GetSession()->GetSecurity() <= ((Player *)u)->GetSession()->GetSecurity(); - else - return true; - } - - // non faction visibility non-breakable for non-GMs - if (m_Visibility == VISIBILITY_OFF) - return false; - - // raw invisibility - bool invisible = (m_invisibilityMask != 0 || u->m_invisibilityMask !=0); + if(((1 << i) & mask)==0) + continue; - // detectable invisibility case - if( invisible && ( - // Invisible units, always are visible for units under same invisibility type - (m_invisibilityMask & u->m_invisibilityMask)!=0 || - // Invisible units, always are visible for unit that can detect this invisibility (have appropriate level for detect) - u->canDetectInvisibilityOf(this) || - // Units that can detect invisibility always are visible for units that can be detected - canDetectInvisibilityOf(u) )) - { - invisible = false; - } + // find invisibility level + uint32 invLevel = 0; + Unit::AuraList const& iAuras = u->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY); + for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr) + if(((*itr)->GetModifier()->m_miscvalue)==i && invLevel < (*itr)->GetModifier()->m_amount) + invLevel = (*itr)->GetModifier()->m_amount; - // special cases for always overwrite invisibility/stealth - if(invisible || m_Visibility == VISIBILITY_GROUP_STEALTH) - { - // non-hostile case - if (!u->IsHostileTo(this)) - { - // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting) - if(GetTypeId()==TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER) + // find invisibility detect level + uint32 detectLevel = 0; + if(i==6 && GetTypeId()==TYPEID_PLAYER) // special drunk detection case { - if(((Player*)this)->IsGroupVisibleFor(((Player*)u))) - return true; - - // else apply same rules as for hostile case (detecting check for stealth) + detectLevel = ((Player*)this)->GetDrunkValue(); + } + else + { + Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION); + for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr) + if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount) + detectLevel = (*itr)->GetModifier()->m_amount; } - } - // hostile case - else - { - // Hunter mark functionality - AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED); - for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) - if((*iter)->GetCasterGUID()==u->GetGUID()) - return true; - // else apply detecting check for stealth + if(invLevel <= detectLevel) + return true; } - - // none other cases for detect invisibility, so invisible - if(invisible) - return false; - - // else apply stealth detecting check } - // unit got in stealth in this moment and must ignore old detected state - if (m_Visibility == VISIBILITY_GROUP_NO_DETECT) - return false; - - // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible - if (m_Visibility != VISIBILITY_GROUP_STEALTH) - return true; - - // NOW ONLY STEALTH CASE - - // stealth and detected and visible for some seconds - if (u->GetTypeId() == TYPEID_PLAYER && ((Player*)u)->m_DetectInvTimer > 300 && ((Player*)u)->HaveAtClient(this)) - return true; + return false; +} - //if in non-detect mode then invisible for unit - if (!detect) +bool Unit::canDetectStealthOf(Unit const* target, float distance) const +{ + if(hasUnitState(UNIT_STAT_STUNNED)) return false; - - // Special cases - - // If is attacked then stealth is lost, some creature can use stealth too - if( !getAttackers().empty() ) - return true; - - // If there is collision rogue is seen regardless of level difference - // TODO: check sizes in DB - float distance = GetDistance(u); - if (distance < 0.24f) + if(distance < 0.24f) //collision return true; - - //If a mob or player is stunned he will not be able to detect stealth - if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this)) + if(!HasInArc(M_PI, target)) //behind return false; + if(HasAuraType(SPELL_AURA_DETECT_STEALTH)) + return true; - // Creature can detect target only in aggro radius - if(u->GetTypeId() != TYPEID_PLAYER) - { - //Always invisible from back and out of aggro range - bool isInFront = u->isInFront(this,((Creature const*)u)->GetAttackDistance(this)); - if(!isInFront) - return false; - } - else - { - //Always invisible from back - bool isInFront = u->isInFront(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature()); - if(!isInFront) - return false; - } - - // if doesn't have stealth detection (Shadow Sight), then check how stealthy the unit is, otherwise just check los - if(!u->HasAuraType(SPELL_AURA_DETECT_STEALTH)) - { - //Calculation if target is in front - - //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5) - float visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f); - - //Visible distance is modified by - //-Level Diff (every level diff = 1.0f in visible distance) - visibleDistance += int32(u->getLevelForTarget(this)) - int32(this->getLevelForTarget(u)); - - //This allows to check talent tree and will add addition stealth dependent on used points) - int32 stealthMod = GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL); - if(stealthMod < 0) - stealthMod = 0; - - //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia) - //based on wowwiki every 5 mod we have 1 more level diff in calculation - visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f; - - if(distance > visibleDistance) - return false; - } + //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5) + float visibleDistance = 10.5f - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH) / 100.0f; + //Visible distance is modified by -Level Diff (every level diff = 1.0f in visible distance) + visibleDistance += int32(getLevelForTarget(target)) - int32(target->getLevelForTarget(this)); + //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia) + //based on wowwiki every 5 mod we have 1 more level diff in calculation + visibleDistance += (float)(GetTotalAuraModifier(SPELL_AURA_MOD_DETECT) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL)) / 5.0f; - // Now check is target visible with LoS - float ox,oy,oz; - u->GetPosition(ox,oy,oz); - return IsWithinLOS(ox,oy,oz); + return distance < visibleDistance; } void Unit::SetVisibility(UnitVisibility x) @@ -8831,42 +8667,6 @@ void Unit::SetVisibility(UnitVisibility x) } } -bool Unit::canDetectInvisibilityOf(Unit const* u) const -{ - if(uint32 mask = (m_detectInvisibilityMask & u->m_invisibilityMask)) - { - for(uint32 i = 0; i < 10; ++i) - { - if(((1 << i) & mask)==0) - continue; - - // find invisibility level - uint32 invLevel = 0; - Unit::AuraList const& iAuras = u->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY); - for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr) - if(((*itr)->GetModifier()->m_miscvalue)==i && invLevel < (*itr)->GetModifier()->m_amount) - invLevel = (*itr)->GetModifier()->m_amount; - - // find invisibility detect level - uint32 detectLevel = 0; - Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION); - for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr) - if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount) - detectLevel = (*itr)->GetModifier()->m_amount; - - if(i==6 && GetTypeId()==TYPEID_PLAYER) // special drunk detection case - { - detectLevel = ((Player*)this)->GetDrunkValue(); - } - - if(invLevel <= detectLevel) - return true; - } - } - - return false; -} - void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) { int32 main_speed_mod = 0; diff --git a/src/game/Unit.h b/src/game/Unit.h index 2482648180e..c113587a5ff 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -437,8 +437,8 @@ enum UnitVisibility VISIBILITY_OFF = 0, // absolute, not detectable, GM-like, can see all other VISIBILITY_ON = 1, VISIBILITY_GROUP_STEALTH = 2, // detect chance, seen and can see group members - VISIBILITY_GROUP_INVISIBILITY = 3, // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead) - VISIBILITY_GROUP_NO_DETECT = 4, // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break + //VISIBILITY_GROUP_INVISIBILITY = 3, // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead) + //VISIBILITY_GROUP_NO_DETECT = 4, // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break VISIBILITY_RESPAWN = 5 // special totally not detectable visibility for force delete object at respawn command }; @@ -1135,13 +1135,15 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SetVisibility(UnitVisibility x); // common function for visibility checks for player/creatures with detection code + virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false) const; bool canDetectInvisibilityOf(Unit const* u) const; + bool canDetectStealthOf(Unit const* u, float distance) const; // virtual functions for all world objects types bool isVisibleForInState(Player const* u, bool inVisibleList) const; // function for low level grid visibility checks in player/creature cases - virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0; + virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0; bool waterbreath; AuraList & GetSingleCastAuras() { return m_scAuras; } diff --git a/src/trinityrealm/AuthCodes.h b/src/trinityrealm/AuthCodes.h index 140857e6ffe..768f51efb59 100644 --- a/src/trinityrealm/AuthCodes.h +++ b/src/trinityrealm/AuthCodes.h @@ -10,12 +10,12 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** \file diff --git a/src/trinityrealm/AuthSocket.h b/src/trinityrealm/AuthSocket.h index e955a6ba5f4..17f41ad945b 100644 --- a/src/trinityrealm/AuthSocket.h +++ b/src/trinityrealm/AuthSocket.h @@ -10,12 +10,12 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /// \addtogroup realmd @@ -75,8 +75,7 @@ class AuthSocket: public TcpSocket std::string _login; std::string _safelogin; - - + // Since GetLocaleByName() is _NOT_ bijective, we have to store the locale as a string. Otherwise we can't differ // between enUS and enGB, which is important for the patch system std::string _localizationName; diff --git a/src/trinityrealm/Main.cpp b/src/trinityrealm/Main.cpp index 1cd0d11a888..0e2f68f76c6 100644 --- a/src/trinityrealm/Main.cpp +++ b/src/trinityrealm/Main.cpp @@ -10,12 +10,12 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /// \addtogroup realmd Realm Daemon @@ -340,7 +340,6 @@ void UnhookSignals() #ifdef _WIN32 signal(SIGBREAK, 0); #endif - } /// @} diff --git a/src/trinityrealm/RealmList.cpp b/src/trinityrealm/RealmList.cpp index 35343e70095..e393ead1ac4 100644 --- a/src/trinityrealm/RealmList.cpp +++ b/src/trinityrealm/RealmList.cpp @@ -10,12 +10,12 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** \file |