diff options
Diffstat (limited to 'src')
10 files changed, 155 insertions, 105 deletions
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 851c5f4c243..df58c705c17 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 @@ -366,9 +366,9 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI { switch(rand()%2) { - case 0: DoScriptText(SUFF_SAY_SLAY1, m_creature); break; - case 1: DoScriptText(SUFF_SAY_SLAY2, m_creature); break; - case 2: DoScriptText(SUFF_SAY_SLAY3, m_creature); break; + case 0: DoScriptText(SUFF_SAY_SLAY1, m_creature); break; + case 1: DoScriptText(SUFF_SAY_SLAY2, m_creature); break; + case 2: DoScriptText(SUFF_SAY_SLAY3, m_creature); break; } } @@ -391,25 +391,30 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI targets.resize(1); // Only need closest target. Unit* target = targets.front(); // Get the first target. target->CastSpell(m_creature, SPELL_FIXATE_TAUNT, true); + DoResetThreat(); + m_creature->AddThreat(target,1000000); } void UpdateAI(const uint32 diff) { + if(InCombat) + { + //Supposed to be cast on nearest target + if(FixateTimer < diff) + { + CastFixate(); + FixateTimer = 5000; + if(!(rand()%16)) + { + DoScriptText(SUFF_SAY_AGGRO, m_creature); + } + }else FixateTimer -= diff; + } + //Return since we have no target if (!UpdateVictim()) return; - //Supposed to be cast on nearest target - if(FixateTimer < diff) - { - CastFixate(); - FixateTimer = 5000; - if(!(rand()%16)) - { - DoScriptText(SUFF_SAY_AGGRO, m_creature); - } - }else FixateTimer -= diff; - if(EnrageTimer < diff) { DoCast(m_creature, SPELL_ENRAGE); @@ -419,7 +424,7 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI if(SoulDrainTimer < diff) { - DoCast(m_creature->getVictim(), SPELL_SOUL_DRAIN); + DoCast(SelectUnit(SELECT_TARGET_RANDOM,0), SPELL_SOUL_DRAIN); SoulDrainTimer = 60000; }else SoulDrainTimer -= diff; diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp index 0e4cc9129db..00358be80f3 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp @@ -145,7 +145,7 @@ struct TRINITY_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI if(CheckTimer < diff) { - Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID); + Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID); if(Shade && Shade->isAlive() && m_creature->isAlive()) { if(m_creature->GetDistance2d(Shade) < 20) @@ -165,10 +165,13 @@ struct TRINITY_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI { - boss_shade_of_akamaAI(Creature* c) : ScriptedAI(c) + boss_shade_of_akamaAI(Creature* c) : ScriptedAI(c), summons(m_creature) { pInstance = ((ScriptedInstance*)c->GetInstanceData()); AkamaGUID = pInstance ? pInstance->GetData64(DATA_AKAMA_SHADE) : 0; + m_creature->setActive(true);//if view distance is too low + m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); + m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); } ScriptedInstance* pInstance; @@ -189,30 +192,28 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI bool HasKilledAkama; bool reseting; bool GridSearcherSucceeded; + bool HasKilledAkamaAndReseting; + SummonList summons; void Reset() { reseting = true; + HasKilledAkamaAndReseting = false; GridSearcherSucceeded = false; - if(!Sorcerers.empty()) + Sorcerers.clear(); + summons.DespawnAll();//despawn all adds + + if(Creature* Akama = Unit::GetCreature(*m_creature, AkamaGUID)) { - for(std::list<uint64>::iterator itr = Sorcerers.begin(); itr != Sorcerers.end(); ++itr) + Akama->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);//turn gossip on so players can restart the event + if(Akama->isDead()) { - if(Creature* Sorcerer = (Unit::GetCreature(*m_creature, *itr))) - if(Sorcerer->isAlive()) - { - Sorcerer->SetVisibility(VISIBILITY_OFF); - Sorcerer->Kill(Sorcerer); - } + Akama->Respawn();//respawn akama if dead + Akama->AI()->EnterEvadeMode(); } - Sorcerers.clear(); } - - if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID)) - Akama->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - SorcererCount = 0; DeathCount = 0; @@ -236,42 +237,42 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI reseting = false; } + void JustSummoned(Creature *summon) {summons.Summon(summon);} + void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} - void MoveInLineOfSight(Unit *who) - { - if(!GridSearcherSucceeded) - { - FindChannelers(); - - if (!Channelers.empty()) + void MoveInLineOfSight(Unit *who) + { + if(!GridSearcherSucceeded) { - for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr) - { - Creature* Channeler = NULL; - Channeler = (Unit::GetCreature(*m_creature, *itr)); + FindChannelers(); - if (Channeler) + if (!Channelers.empty()) + { + for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr) { - if (Channeler->isDead()) + Creature* Channeler = (Unit::GetCreature(*m_creature, *itr)); + if (Channeler) { - Channeler->RemoveCorpse(); - Channeler->Respawn(); - Channeler->InterruptNonMeleeSpells(true); - Channeler->RemoveAurasDueToSpell(SPELL_SHADE_SOUL_CHANNEL); - } + if (Channeler->isDead()) + { + Channeler->RemoveCorpse(); + Channeler->Respawn(); + Channeler->InterruptNonMeleeSpells(true); + Channeler->RemoveAurasDueToSpell(SPELL_SHADE_SOUL_CHANNEL); + } - if (Channeler->isAlive()) - { - Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL, true); - Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL_2, true); - Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - GridSearcherSucceeded = true; + if (Channeler->isAlive()) + { + Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL, true); + Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL_2, true); + Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + GridSearcherSucceeded = true; + } } } - } - }else error_log("SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly"); - } - } + }else error_log("SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly"); + } + } void Aggro(Unit* who) { } @@ -387,7 +388,10 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI { // Akama is set in the threatlist so when we reset, we make sure that he is not included in our check if(m_creature->getThreatManager().getThreatList().size() < 2) + { EnterEvadeMode(); + return; + } if(DefenderTimer < diff) { @@ -399,7 +403,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI bool move = true; if(AkamaGUID) { - if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID)) + if(Creature* Akama = Unit::GetCreature(*m_creature, AkamaGUID)) { float x, y, z; Akama->GetPosition(x,y,z); @@ -424,7 +428,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI { if(AkamaGUID) { - Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID); + Creature* Akama = Unit::GetCreature((*m_creature), AkamaGUID); if(Akama && Akama->isAlive()) { IsBanished = false; @@ -449,31 +453,30 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI { if(AkamaGUID) { - Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID); + Creature* Akama = Unit::GetCreature((*m_creature), AkamaGUID); if(Akama && Akama->isAlive()) { //10 % less health every few seconds. m_creature->DealDamage(Akama, Akama->GetMaxHealth()/10, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); ReduceHealthTimer = 12000; } - else - { - HasKilledAkama = true; // Akama is dead or missing, we stop fighting and disappear - m_creature->SetVisibility(VISIBILITY_OFF); - m_creature->SetHealth(m_creature->GetMaxHealth()); - m_creature->RemoveAllAuras(); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } } }else ReduceHealthTimer -= diff; if(HasKilledAkama) { - if(ResetTimer < diff) - { - InCombat = false; - EnterEvadeMode(); // Reset a little while after killing Akama + if(!HasKilledAkamaAndReseting)//do not let players kill Shade if Akama is dead and Shade is waiting for ResetTimer!! event would bug + { + HasKilledAkamaAndReseting = true; + m_creature->RemoveAllAuras(); + m_creature->DeleteThreatList(); + m_creature->CombatStop(); + //m_creature->SetHealth(m_creature->GetMaxHealth()); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->GetMotionMaster()->MoveTargetedHome(); } + if(ResetTimer < diff) + EnterEvadeMode();// Reset a little while after killing Akama, evade and respawn Akama else ResetTimer -= diff; } @@ -505,7 +508,17 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI ShadeHasDied = false; StartCombat = false; pInstance = ((ScriptedInstance*)c->GetInstanceData()); - ShadeGUID = pInstance ? pInstance->GetData64(DATA_SHADEOFAKAMA) : 0; + ShadeGUID = pInstance ? pInstance->GetData64(DATA_SHADEOFAKAMA) : NOT_STARTED; + m_creature->setActive(true); + EventBegun = false; + CastSoulRetrieveTimer = 0; + SoulRetrieveTimer = 0; + SummonBrokenTimer = 0; + EndingTalkCount = 0; + WayPointId = 0; + BrokenSummonIndex = 0; + BrokenList.clear(); + HasYelledOnce = false; } ScriptedInstance* pInstance; @@ -534,20 +547,12 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI DestructivePoisonTimer = 15000; LightningBoltTimer = 10000; CheckTimer = 2000; - CastSoulRetrieveTimer = 0; - SoulRetrieveTimer = 0; - SummonBrokenTimer = 0; - EndingTalkCount = 0; - WayPointId = 0; - BrokenSummonIndex = 0; - - BrokenList.clear(); - - EventBegun = false; - HasYelledOnce = false; - - m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has very very strange values - m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + + if(!EventBegun) + { + m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has very very strange values + m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } } void Aggro(Unit* who) {} @@ -589,7 +594,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI case 0: ++WayPointId; break; case 1: - if(Unit* Shade = Unit::GetUnit(*m_creature, ShadeGUID)) + if(Creature* Shade = Unit::GetCreature(*m_creature, ShadeGUID)) { m_creature->SetUInt64Value(UNIT_FIELD_TARGET, ShadeGUID); DoCast(Shade, SPELL_AKAMA_SOUL_RETRIEVE); @@ -603,6 +608,20 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI void JustDied(Unit* killer) { DoScriptText(SAY_DEATH, m_creature); + EventBegun = false; + ShadeHasDied = false; + StartCombat = false; + CastSoulRetrieveTimer = 0; + SoulRetrieveTimer = 0; + SummonBrokenTimer = 0; + EndingTalkCount = 0; + WayPointId = 0; + BrokenSummonIndex = 0; + BrokenList.clear(); + HasYelledOnce = false; + Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID); + if(Shade && Shade->isAlive()) + ((boss_shade_of_akamaAI*)Shade->AI())->HasKilledAkama = true; } void UpdateAI(const uint32 diff) @@ -650,7 +669,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI { if(ShadeGUID) { - Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID); + Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID); if(Shade && !Shade->isAlive()) { ShadeHasDied = true; @@ -658,6 +677,11 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI m_creature->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE); m_creature->GetMotionMaster()->MovePoint(WayPointId, AkamaWP[0].x, AkamaWP[0].y, AkamaWP[0].z); } + if(Shade && Shade->isAlive()) + { + if(Shade->getThreatManager().getThreatList().size() < 2) + Shade->AI()->EnterEvadeMode(); + } } CheckTimer = 5000; }else CheckTimer -= diff; @@ -710,7 +734,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI { bool Yelled = false; for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) - if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr)) + if(Creature* pUnit = Unit::GetCreature(*m_creature, *itr)) { if(!Yelled) { @@ -727,7 +751,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI if(!BrokenList.empty()) { for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) - if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr)) + if(Creature* pUnit = Unit::GetCreature(*m_creature, *itr)) // This is the incorrect spell, but can't seem to find the right one. pUnit->CastSpell(pUnit, 39656, true); } @@ -738,7 +762,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI if(!BrokenList.empty()) { for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) - if(Unit* pUnit = Unit::GetUnit((*m_creature), *itr)) + if(Creature* pUnit = Unit::GetCreature((*m_creature), *itr)) pUnit->MonsterYell(SAY_BROKEN_FREE_02, LANG_UNIVERSAL, 0); } SoulRetrieveTimer = 0; @@ -751,7 +775,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI if(DestructivePoisonTimer < diff) { - Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID); + Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID); if (Shade && Shade->isAlive()) DoCast(Shade, SPELL_DESTRUCTIVE_POISON); DestructivePoisonTimer = 15000; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp index 32b944861ff..c5f7b402df6 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp @@ -60,6 +60,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI void Reset() { + damageTaken = 0; SwarmTimer = 45000; SleepTimer = 60000; AuraTimer = 5000; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp index b89a614389e..af842479ed1 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp @@ -239,6 +239,7 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI pInstance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED); DoomfireSpiritGUID = 0; + damageTaken = 0; WorldTreeGUID = 0; DrainNordrassilTimer = 0; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp index ef4db888797..fac53fbda02 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp @@ -51,6 +51,7 @@ struct TRINITY_DLL_DECL boss_azgalorAI : public hyjal_trashAI void Reset() { + damageTaken = 0; RainTimer = 20000; DoomTimer = 50000; HowlTimer = 30000; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp index 9e8b4393fed..33c6ec44cf9 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp @@ -48,6 +48,7 @@ struct TRINITY_DLL_DECL boss_kazrogalAI : public hyjal_trashAI void Reset() { + damageTaken = 0; CleaveTimer = 5000; WarStompTimer = 15000; MarkTimer = 45000; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp index c77e4aef20d..ddf5e0ad715 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp @@ -48,6 +48,7 @@ struct TRINITY_DLL_DECL boss_rage_winterchillAI : public hyjal_trashAI void Reset() { + damageTaken = 0; FrostArmorTimer = 37000; DecayTimer = 45000; NovaTimer = 15000; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp index f099f1be6da..ac15c8cc30e 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp @@ -158,7 +158,7 @@ hyjal_trashAI::hyjal_trashAI(Creature *c) : npc_escortAI(c) void hyjal_trashAI::DamageTaken(Unit *done_by, uint32 &damage) { - if(done_by->GetTypeId() == TYPEID_PLAYER) + if(done_by->GetTypeId() == TYPEID_PLAYER || (done_by->GetTypeId() == TYPEID_UNIT && ((Creature*)done_by)->isPet())) { damageTaken += damage; if(pInstance) @@ -431,6 +431,7 @@ void hyjal_trashAI::UpdateAI(const uint32 diff) AddWaypoint(i, HordeWPs[i][0]+irand(-10,10), HordeWPs[i][1]+irand(-10,10), HordeWPs[i][2]); switch(OverrunType) { + case 0: default: AddWaypoint( 5, HordeOverrunWP[0][0]+irand(-10,10), HordeOverrunWP[0][1]+irand(-10,10), HordeOverrunWP[0][2]); AddWaypoint( 6, HordeOverrunWP[1][0]+irand(-10,10), HordeOverrunWP[1][1]+irand(-10,10), HordeOverrunWP[1][2]); @@ -465,7 +466,7 @@ void hyjal_trashAI::JustDied(Unit *victim) if(IsEvent && !m_creature->isWorldBoss()) pInstance->SetData(DATA_TRASH, 0);//signal trash is dead - if((pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE && !m_creature->isWorldBoss()) || (damageTaken < m_creature->GetMaxHealth()/2 && m_creature->isWorldBoss())) + if((pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE && !m_creature->isWorldBoss()) || (damageTaken < m_creature->GetMaxHealth()/4 && m_creature->isWorldBoss())) m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);//no loot if(IsOverrun) diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index d3e8397baaa..368edce0a53 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -311,10 +311,13 @@ ObjectGridStoper::Visit(CreatureMapType &m) // stop any fights at grid de-activation and remove dynobjects created at cast by creatures for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) { - iter->getSource()->CombatStop(); - iter->getSource()->DeleteThreatList(); iter->getSource()->RemoveAllDynObjects(); - iter->getSource()->AI()->EnterEvadeMode(); + if(iter->getSource()->isInCombat()) + { + iter->getSource()->CombatStop(); + iter->getSource()->DeleteThreatList(); + iter->getSource()->AI()->EnterEvadeMode(); + } } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index b9f8edf2b66..237a8180d19 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17987,7 +17987,7 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool return false; } - if(u->GetVisibility() == VISIBILITY_OFF || u->m_invisibilityMask ) + if(u->GetVisibility() == VISIBILITY_OFF) { // GMs see any players, not higher GMs and all units if(isGameMaster()) @@ -18000,13 +18000,25 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool 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_mover->m_invisibilityMask || u->m_invisibilityMask) && !m_mover->canDetectInvisibilityOf(u)) - if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u)))) - return false; + // GM's can see everyone with invisibilitymask with less or equal security level + if(m_mover->m_invisibilityMask || u->m_invisibilityMask) + { + if(isGameMaster()) + { + if(u->GetTypeId() == TYPEID_PLAYER) + return ((Player*)u)->GetSession()->GetSecurity() <= GetSession()->GetSecurity(); + else + return true; + } + + // 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_mover->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(u->GetVisibility() == VISIBILITY_GROUP_STEALTH && !isGameMaster()) { // if player is dead then he can't detect anyone in any cases //do not know what is the use of this detect |