aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp546
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp65
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp315
-rw-r--r--src/game/Creature.cpp47
-rw-r--r--src/game/Creature.h3
-rw-r--r--src/game/Object.cpp2
-rw-r--r--src/game/OutdoorPvPObjectiveAI.cpp6
-rw-r--r--src/game/Player.cpp108
-rw-r--r--src/game/Player.h5
-rw-r--r--src/game/SpellAuras.cpp13
-rw-r--r--src/game/SpellEffects.cpp7
-rw-r--r--src/game/Unit.cpp306
-rw-r--r--src/game/Unit.h8
-rw-r--r--src/trinityrealm/AuthCodes.h4
-rw-r--r--src/trinityrealm/AuthSocket.h7
-rw-r--r--src/trinityrealm/Main.cpp5
-rw-r--r--src/trinityrealm/RealmList.cpp4
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