aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/7083_world_creature_template.sql5
-rw-r--r--src/bindings/scripts/scripts/northrend/naxxramas/boss_gothik.cpp336
-rw-r--r--src/game/ThreatManager.cpp14
-rw-r--r--src/game/ThreatManager.h22
4 files changed, 275 insertions, 102 deletions
diff --git a/sql/updates/7083_world_creature_template.sql b/sql/updates/7083_world_creature_template.sql
new file mode 100644
index 00000000000..b8d69da2a09
--- /dev/null
+++ b/sql/updates/7083_world_creature_template.sql
@@ -0,0 +1,5 @@
+-- Usually creature_template changes MUST GO to TDB
+-- creature_template spell1-spell8 are in the exceptions
+UPDATE `creature_template` SET `spell8` = 27892 WHERE `entry` IN (16124, 29987);
+UPDATE `creature_template` SET `spell8` = 27928 WHERE `entry` IN (16125, 29985);
+UPDATE `creature_template` SET `spell8` = 27935 WHERE `entry` IN (16126, 29986);
diff --git a/src/bindings/scripts/scripts/northrend/naxxramas/boss_gothik.cpp b/src/bindings/scripts/scripts/northrend/naxxramas/boss_gothik.cpp
index 4cde7236b55..24d535f7782 100644
--- a/src/bindings/scripts/scripts/northrend/naxxramas/boss_gothik.cpp
+++ b/src/bindings/scripts/scripts/northrend/naxxramas/boss_gothik.cpp
@@ -16,6 +16,7 @@
#include "precompiled.h"
#include "naxxramas.h"
+#include "spellId.h"
enum Yells
{
@@ -27,15 +28,15 @@ enum Yells
//Gothik
enum Spells
{
- SPELL_HARVEST_SOUL = 28679,
- SPELL_SHADOW_BOLT = 29317,
- H_SPELL_SHADOW_BOLT = 56405,
- SPELL_INFORM_LIVE_TRAINEE = 27892,
- SPELL_INFORM_LIVE_KNIGHT = 27928,
- SPELL_INFORM_LIVE_RIDER = 27935,
- SPELL_INFORM_DEAD_TRAINEE = 27915,
- SPELL_INFORM_DEAD_KNIGHT = 27931,
- SPELL_INFORM_DEAD_RIDER = 27937
+ SPELL_HARVEST_SOUL = SPELL_HARVEST_SOUL_28679,
+ SPELL_SHADOW_BOLT = SPELL_SHADOW_BOLT_29317,
+ H_SPELL_SHADOW_BOLT = SPELL_SHADOW_BOLT_56405,
+ SPELL_INFORM_LIVE_TRAINEE = SPELL_TO_ANCHOR_1_27892,
+ SPELL_INFORM_LIVE_KNIGHT = SPELL_TO_ANCHOR_1_27928,
+ SPELL_INFORM_LIVE_RIDER = SPELL_TO_ANCHOR_1_27935,
+ SPELL_INFORM_DEAD_TRAINEE = SPELL_ANCHOR_TO_SKULLS_27915,
+ SPELL_INFORM_DEAD_KNIGHT = SPELL_ANCHOR_TO_SKULLS_27931,
+ SPELL_INFORM_DEAD_RIDER = SPELL_ANCHOR_TO_SKULLS_27937
};
enum Creatures
{
@@ -47,64 +48,45 @@ enum Creatures
MOB_DEAD_RIDER = 16150,
MOB_DEAD_HORSE = 16149
};
-struct Waves { uint32 entry, number, time; };
+
+struct Waves { uint32 entry, time; };
+// wave setups are the same in heroic and normal difficulty, only count of mobs is different,
+// but this is handled in DoGothikSummon function
const Waves waves[] =
{
- {MOB_LIVE_TRAINEE, 2, 20000},
- {MOB_LIVE_TRAINEE, 2, 20000},
- {MOB_LIVE_TRAINEE, 2, 10000},
- {MOB_LIVE_KNIGHT, 1, 10000},
- {MOB_LIVE_TRAINEE, 2, 15000},
- {MOB_LIVE_KNIGHT, 1, 5000},
- {MOB_LIVE_TRAINEE, 2, 20000},
- {MOB_LIVE_TRAINEE, 2, 0},
- {MOB_LIVE_KNIGHT, 1, 10000},
- {MOB_LIVE_RIDER, 1, 10000},
- {MOB_LIVE_TRAINEE, 2, 5000},
- {MOB_LIVE_KNIGHT, 1, 15000},
- {MOB_LIVE_TRAINEE, 2, 0},
- {MOB_LIVE_RIDER, 1, 10000},
- {MOB_LIVE_KNIGHT, 2, 10000},
- {MOB_LIVE_TRAINEE, 2, 10000},
- {MOB_LIVE_RIDER, 1, 5000},
- {MOB_LIVE_KNIGHT, 1, 5000},
- {MOB_LIVE_TRAINEE, 2, 20000},
- {MOB_LIVE_TRAINEE, 2, 0},
- {MOB_LIVE_KNIGHT, 1, 0},
- {MOB_LIVE_RIDER, 1, 15000},
- {MOB_LIVE_TRAINEE, 2, 29000},
- {0, 0, 0},
-};
-const Waves wavesHeroic[] =
-{
- {MOB_LIVE_TRAINEE, 3, 20000},
- {MOB_LIVE_TRAINEE, 3, 20000},
- {MOB_LIVE_TRAINEE, 3, 10000},
- {MOB_LIVE_KNIGHT, 2, 10000},
- {MOB_LIVE_TRAINEE, 3, 15000},
- {MOB_LIVE_KNIGHT, 2, 5000},
- {MOB_LIVE_TRAINEE, 3, 20000},
- {MOB_LIVE_TRAINEE, 3, 0},
- {MOB_LIVE_KNIGHT, 2, 10000},
- {MOB_LIVE_TRAINEE, 3, 10000},
- {MOB_LIVE_RIDER, 1, 5000},
- {MOB_LIVE_TRAINEE, 3, 15000},
- {MOB_LIVE_RIDER, 1, 10000},
- {MOB_LIVE_KNIGHT, 2, 10000},
- {MOB_LIVE_RIDER, 1, 10000},
- {MOB_LIVE_RIDER, 1, 0},
- {MOB_LIVE_TRAINEE, 3, 5000},
- {MOB_LIVE_KNIGHT, 1, 0},
- {MOB_LIVE_TRAINEE, 3, 5000},
- {MOB_LIVE_RIDER, 1, 0},
- {MOB_LIVE_TRAINEE, 3, 20000},
- {MOB_LIVE_KNIGHT, 2, 0},
- {MOB_LIVE_RIDER, 1, 0},
- {MOB_LIVE_TRAINEE, 3, 29000},
- {0, 0, 0},
+ {MOB_LIVE_TRAINEE, 20000},
+ {MOB_LIVE_TRAINEE, 20000},
+ {MOB_LIVE_TRAINEE, 10000},
+ {MOB_LIVE_KNIGHT, 10000},
+ {MOB_LIVE_TRAINEE, 15000},
+ {MOB_LIVE_KNIGHT, 5000},
+ {MOB_LIVE_TRAINEE, 20000},
+ {MOB_LIVE_TRAINEE, 0},
+ {MOB_LIVE_KNIGHT, 10000},
+ {MOB_LIVE_RIDER, 10000},
+ {MOB_LIVE_TRAINEE, 5000},
+ {MOB_LIVE_KNIGHT, 15000},
+ {MOB_LIVE_RIDER, 0},
+ {MOB_LIVE_TRAINEE, 10000},
+ {MOB_LIVE_KNIGHT, 10000},
+ {MOB_LIVE_TRAINEE, 10000},
+ {MOB_LIVE_RIDER, 5000},
+ {MOB_LIVE_KNIGHT, 5000},
+ {MOB_LIVE_TRAINEE, 20000},
+ {MOB_LIVE_RIDER, 0},
+ {MOB_LIVE_KNIGHT, 0},
+ {MOB_LIVE_TRAINEE, 20000},
+ {MOB_LIVE_TRAINEE, 25000},
+ {0, 0},
};
#define POS_Y_GATE -3360.78f
+#define POS_Y_WEST -3285.0f
+#define POS_Y_EAST -3434.0f
+#define POS_X_NORTH 2750.49f
+#define POS_X_SOUTH 2633.84f
+
+#define IN_LIVE_SIDE(who) (who->GetPositionY() < POS_Y_GATE)
enum Events
{
@@ -112,18 +94,22 @@ enum Events
EVENT_SUMMON,
EVENT_HARVEST,
EVENT_BOLT,
+ EVENT_TELEPORT
};
enum Pos
{
- POS_LIVE = 3,
+ POS_LIVE = 6,
POS_DEAD = 5
};
const Position PosSummonLive[POS_LIVE] =
{
- {2669.7, -3430.9, 268.56, 1.6},
- {2692.0, -3430.9, 268.56, 1.6},
- {2714.1, -3430.9, 268.56, 1.6},
+ {2669.7, -3428.76, 268.56, 1.6},
+ {2692.1, -3428.76, 268.56, 1.6},
+ {2714.4, -3428.76, 268.56, 1.6},
+ {2669.7, -3431.67, 268.56, 1.6},
+ {2692.1, -3431.67, 268.56, 1.6},
+ {2714.4, -3431.67, 268.56, 1.6},
};
const Position PosSummonDead[POS_DEAD] =
@@ -135,9 +121,19 @@ const Position PosSummonDead[POS_DEAD] =
{2664.8, -3340.7, 268.23, 3.7},
};
-const float PosGround[4] = {2691.2, -3362.7, 267.68, 1.7};
+const float PosGroundLiveSide[4] = {2691.2, -3387.0, 267.68, 1.52};
+const float PosGroundDeadSide[4] = {2693.5, -3334.6, 267.68, 4.67};
const float PosPlatform[4] = {2640.5, -3360.6, 285.26, 0};
+// Predicate function to check that the r efzr unit is NOT on the same side as the source.
+struct NotOnSameSide : public std::unary_function<Unit *, bool> {
+ bool m_inLiveSide;
+ NotOnSameSide(Unit *pSource) : m_inLiveSide(IN_LIVE_SIDE(pSource)) {}
+ bool operator() (const Unit *pTarget) {
+ return (m_inLiveSide != IN_LIVE_SIDE(pTarget));
+ }
+};
+
struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
{
boss_gothikAI(Creature *c) : BossAI(c, BOSS_GOTHIK) {}
@@ -145,16 +141,22 @@ struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
uint32 waveCount;
typedef std::vector<Creature*> TriggerVct;
TriggerVct liveTrigger, deadTrigger;
+ bool mergedSides;
+ bool phaseTwo;
+ bool thirtyPercentReached;
void Reset()
{
liveTrigger.clear();
deadTrigger.clear();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
me->SetReactState(REACT_PASSIVE);
if (instance)
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
_Reset();
+ mergedSides = false;
+ phaseTwo = false;
+ thirtyPercentReached = false;
}
void EnterCombat(Unit *who)
@@ -174,7 +176,7 @@ struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
}
_EnterCombat();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
waveCount = 0;
events.ScheduleEvent(EVENT_SUMMON, 30000);
DoTeleportTo(PosPlatform);
@@ -187,25 +189,21 @@ struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
{
if (summon->GetEntry() == WORLD_TRIGGER)
summon->setActive(true);
- else
+ else if (!mergedSides)
{
summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0);
summon->AI()->EnterEvadeMode();
}
+ else
+ {
+ summon->AI()->DoAction(0);
+ summon->AI()->DoZoneInCombat();
+ }
summons.Summon(summon);
}
void SummonedCreatureDespawn(Creature *summon)
{
- if (summon->GetEntry() == WORLD_TRIGGER)
- {
- //for (TriggerVct::iterator itr = liveTrigger.begin(); itr != liveTrigger.end(); ++itr)
- // if(*itr == summon)
- error_log("boss_gothikAI: trigger is despawned!");
- EnterEvadeMode();
- return;
- }
-
summons.Despawn(summon);
}
@@ -221,6 +219,85 @@ struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
deadTrigger.clear();
_JustDied();
DoScriptText(SAY_DEATH, me);
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
+ }
+
+ void DoGothikSummon(uint32 entry)
+ {
+ if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ {
+ switch(entry)
+ {
+ case MOB_LIVE_TRAINEE:
+ DoSummon(MOB_LIVE_TRAINEE, liveTrigger[0], 1);
+ DoSummon(MOB_LIVE_TRAINEE, liveTrigger[1], 1);
+ DoSummon(MOB_LIVE_TRAINEE, liveTrigger[2], 1);
+ break;
+ case MOB_LIVE_KNIGHT:
+ DoSummon(MOB_LIVE_KNIGHT, liveTrigger[3], 1);
+ DoSummon(MOB_LIVE_KNIGHT, liveTrigger[5], 1);
+ break;
+ case MOB_LIVE_RIDER:
+ DoSummon(MOB_LIVE_RIDER, liveTrigger[4], 1);
+ break;
+ }
+ }
+ else
+ {
+ switch(entry)
+ {
+ case MOB_LIVE_TRAINEE:
+ DoSummon(MOB_LIVE_TRAINEE, liveTrigger[0], 1);
+ DoSummon(MOB_LIVE_TRAINEE, liveTrigger[1], 1);
+ break;
+ case MOB_LIVE_KNIGHT:
+ DoSummon(MOB_LIVE_KNIGHT, liveTrigger[5], 1);
+ break;
+ case MOB_LIVE_RIDER:
+ DoSummon(MOB_LIVE_RIDER, liveTrigger[4], 1);
+ break;
+ }
+ }
+ }
+
+ bool CheckGroupSplitted()
+ {
+ bool checklife = false;
+ bool checkdead = false;
+
+ Map* pMap = me->GetMap();
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+ if (!PlayerList.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource() && i->getSource()->isAlive() &&
+ i->getSource()->GetPositionX() <= POS_X_NORTH &&
+ i->getSource()->GetPositionX() >= POS_X_SOUTH &&
+ i->getSource()->GetPositionY() <= POS_Y_GATE &&
+ i->getSource()->GetPositionY() >= POS_Y_EAST)
+ {
+ checklife = true;
+ }
+ else if (i->getSource() && i->getSource()->isAlive() &&
+ i->getSource()->GetPositionX() <= POS_X_NORTH &&
+ i->getSource()->GetPositionX() >= POS_X_SOUTH &&
+ i->getSource()->GetPositionY() >= POS_Y_GATE &&
+ i->getSource()->GetPositionY() <= POS_Y_WEST)
+ {
+ checkdead = true;
+ }
+
+ if (checklife && checkdead)
+ return true;
+ }
+ }
+ }
+
+ return false;
}
void SpellHit(Unit *caster, const SpellEntry *spell)
@@ -246,10 +323,16 @@ struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
switch(spell->Id)
{
- case SPELL_INFORM_DEAD_TRAINEE: DoSummon(MOB_DEAD_TRAINEE, pTarget, 0); break;
- case SPELL_INFORM_DEAD_KNIGHT: DoSummon(MOB_DEAD_KNIGHT, pTarget, 0); break;
- case SPELL_INFORM_DEAD_RIDER: DoSummon(MOB_DEAD_RIDER, pTarget, 1.0f);
- DoSummon(MOB_DEAD_HORSE, pTarget, 1.0f); break;
+ case SPELL_INFORM_DEAD_TRAINEE:
+ DoSummon(MOB_DEAD_TRAINEE, pTarget, 0);
+ break;
+ case SPELL_INFORM_DEAD_KNIGHT:
+ DoSummon(MOB_DEAD_KNIGHT, pTarget, 0);
+ break;
+ case SPELL_INFORM_DEAD_RIDER:
+ DoSummon(MOB_DEAD_RIDER, pTarget, 1.0f);
+ DoSummon(MOB_DEAD_HORSE, pTarget, 1.0f);
+ break;
}
}
@@ -260,6 +343,13 @@ struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
events.Update(diff);
+ if (!thirtyPercentReached && HealthBelowPct(30) && phaseTwo)
+ {
+ thirtyPercentReached = true;
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
+ }
+
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
@@ -270,33 +360,69 @@ struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
case EVENT_SUMMON:
if (waves[waveCount].entry)
{
- for (uint32 i = 0; i < waves[waveCount].number; ++i)
- DoSummon(waves[waveCount].entry, liveTrigger[rand()%POS_LIVE], 1.0f);
- events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time);
+ DoGothikSummon(waves[waveCount].entry);
+
+ // if group is not splitted, open gate and merge both sides at ~ 2 minutes (wave 11)
+ if (waveCount == 11)
+ {
+ if (!CheckGroupSplitted())
+ {
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
+ summons.DoAction(0, 0);
+ summons.DoZoneInCombat();
+ mergedSides = true;
+ }
+ }
+
++waveCount;
+ events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time);
}
else
{
+ phaseTwo = true;
DoScriptText(SAY_TELEPORT, me);
- DoTeleportTo(PosGround);
+ DoTeleportTo(PosGroundLiveSide);
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
- if (instance)
- instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
summons.DoAction(0, 0);
summons.DoZoneInCombat();
events.ScheduleEvent(EVENT_BOLT, 1000);
- events.ScheduleEvent(EVENT_HARVEST, 15000);
+ events.ScheduleEvent(EVENT_HARVEST, urand(3000,15000));
+ events.ScheduleEvent(EVENT_TELEPORT, 20000);
}
break;
case EVENT_BOLT:
DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT));
events.ScheduleEvent(EVENT_BOLT, 1000);
- return;
+ break;
case EVENT_HARVEST:
- DoCast(me->getVictim(), SPELL_HARVEST_SOUL);
- events.ScheduleEvent(EVENT_HARVEST, 15000);
- return;
+ DoCast(me->getVictim(), SPELL_HARVEST_SOUL, true);
+ events.ScheduleEvent(EVENT_HARVEST, urand(20000,25000));
+ break;
+ case EVENT_TELEPORT:
+ if (!thirtyPercentReached)
+ {
+ m_creature->AttackStop();
+ if (IN_LIVE_SIDE(m_creature))
+ {
+ DoTeleportTo(PosGroundDeadSide);
+ }
+ else
+ {
+ DoTeleportTo(PosGroundLiveSide);
+ }
+
+ m_creature->getThreatManager().resetAggro(NotOnSameSide(m_creature));
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0))
+ {
+ m_creature->getThreatManager().addThreat(pTarget, 100.0f);
+ AttackStart(pTarget);
+ }
+
+ events.ScheduleEvent(EVENT_TELEPORT, 20000);
+ }
+ break;
}
}
@@ -308,13 +434,16 @@ struct TRINITY_DLL_DECL mob_gothik_minionAI : public CombatAI
{
mob_gothik_minionAI(Creature *c) : CombatAI(c)
{
- liveSide = me->GetPositionY() < POS_Y_GATE;
+ liveSide = IN_LIVE_SIDE(me);
}
bool liveSide;
bool gateClose;
-#define SIDE_CHECK(who) (liveSide == (who->GetPositionY() < POS_Y_GATE))
+ bool isOnSameSide(const Unit *pWho)
+ {
+ return (liveSide == IN_LIVE_SIDE(pWho));
+ }
void DoAction(const int32 param)
{
@@ -323,7 +452,7 @@ struct TRINITY_DLL_DECL mob_gothik_minionAI : public CombatAI
void DamageTaken(Unit *attacker, uint32 &damage)
{
- if (gateClose && !SIDE_CHECK(attacker))
+ if (gateClose && !isOnSameSide(attacker))
damage = 0;
}
@@ -351,12 +480,15 @@ struct TRINITY_DLL_DECL mob_gothik_minionAI : public CombatAI
if (pMap->IsDungeon())
{
Map::PlayerList const &PlayerList = pMap->GetPlayers();
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (!PlayerList.isEmpty())
{
- if (i->getSource()->isAlive() && SIDE_CHECK(i->getSource()))
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
- AttackStart(i->getSource());
- return;
+ if (i->getSource() && i->getSource()->isAlive() && isOnSameSide(i->getSource()))
+ {
+ AttackStart(i->getSource());
+ return;
+ }
}
}
}
@@ -367,7 +499,7 @@ struct TRINITY_DLL_DECL mob_gothik_minionAI : public CombatAI
void UpdateAI(const uint32 diff)
{
- if (gateClose && (!SIDE_CHECK(me) || me->getVictim() && !SIDE_CHECK(me->getVictim())))
+ if (gateClose && (!isOnSameSide(me) || me->getVictim() && !isOnSameSide(me->getVictim())))
{
EnterEvadeMode();
return;
diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp
index cf688cf163a..ad22ba6b5c1 100644
--- a/src/game/ThreatManager.cpp
+++ b/src/game/ThreatManager.cpp
@@ -537,3 +537,17 @@ bool ThreatManager::isNeedUpdateToClient(uint32 time)
return false;
}
+// Reset all aggro without modifying the threadlist.
+void ThreatManager::resetAllAggro()
+{
+ std::list<HostilReference*> &threatlist = getThreatList();
+ if (threatlist.empty())
+ return;
+
+ for (std::list<HostilReference*>::iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
+ {
+ (*itr)->setThreat(0);
+ }
+
+ setDirty(true);
+}
diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h
index 1c0e2708a5e..3dd444a065d 100644
--- a/src/game/ThreatManager.h
+++ b/src/game/ThreatManager.h
@@ -215,6 +215,28 @@ class TRINITY_DLL_SPEC ThreatManager
void setDirty(bool bDirty) { iThreatContainer.setDirty(bDirty); }
+ // Reset all aggro without modifying the threadlist.
+ void resetAllAggro();
+
+ // Reset all aggro of unit in threadlist satisfying the predicate.
+ template<class PREDICATE> void resetAggro(PREDICATE predicate)
+ {
+ std::list<HostilReference*> &threatlist = getThreatList();
+ if (threatlist.empty())
+ return;
+
+ for (std::list<HostilReference*>::iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
+ {
+ HostilReference* ref = (*itr);
+
+ if (predicate(ref->getTarget()))
+ {
+ ref->setThreat(0);
+ setDirty(true);
+ }
+ }
+ }
+
// methods to access the lists from the outside to do some dirty manipulation (scriping and such)
// I hope they are used as little as possible.
std::list<HostilReference*>& getThreatList() { return iThreatContainer.getThreatList(); }