Scripts/Icecrown Citadel: Fixed Professor Putricide ooze adds behavior (cannot taunt/aggro anymore), also removed targeting dbc hack and scripted the spell properly

This commit is contained in:
Shauren
2011-04-06 21:21:45 +02:00
parent 06acfddb86
commit 24240430ad
7 changed files with 167 additions and 92 deletions
+7 -6
View File
@@ -8517,6 +8517,11 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
target = pVictim;
break;
}
// Professor Putricide - Ooze Spell Tank Protection
case 71770:
if (pVictim)
pVictim->CastSpell(pVictim, trigger_spell_id, true); // EffectImplicitTarget is self
return true;
default:
break;
}
@@ -8544,7 +8549,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
// Custom basepoints/target for exist spell
// dummy basepoints or other customs
switch(trigger_spell_id)
switch (trigger_spell_id)
{
// Auras which should proc on area aura source (caster in this case):
// Turn the Tables
@@ -8723,10 +8728,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
return false;
break;
}
// Deathbringer Saurfang - Blood Link
case 72202:
target = FindNearestCreature(37813, 75.0f); // NPC_DEATHBRINGER_SAURFANG = 37813
break;
// Shadow's Fate (Shadowmourne questline)
case 71169:
{
@@ -8766,7 +8767,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
// try detect target manually if not set
if (target == NULL)
target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && IsPositiveSpell(trigger_spell_id) ? this : pVictim;
target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && IsPositiveSpell(trigger_spell_id) ? this : pVictim;
// default case
if ((!target && !sSpellMgr->IsSrcTargetSpell(triggerEntry)) || (target && target != this && !target->isAlive()))
-13
View File
@@ -4033,19 +4033,6 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->Effect[1] = 0;
count++;
break;
case 70447: // Volatile Ooze Adhesive (Professor Putricide)
case 72836: // Volatile Ooze Adhesive (Professor Putricide)
case 72837: // Volatile Ooze Adhesive (Professor Putricide)
case 72838: // Volatile Ooze Adhesive (Professor Putricide)
case 70672: // Gaseous Bloat (Professor Putricide)
case 72455: // Gaseous Bloat (Professor Putricide)
case 72832: // Gaseous Bloat (Professor Putricide)
case 72833: // Gaseous Bloat (Professor Putricide)
spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY;
spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_TARGET_ENEMY;
spellInfo->EffectImplicitTargetB[2] = TARGET_UNIT_TARGET_ENEMY;
count++;
break;
case 70911: // Unbound Plague (Professor Putricide)
case 72854: // Unbound Plague (Professor Putricide)
case 72855: // Unbound Plague (Professor Putricide)
@@ -163,20 +163,6 @@ enum PutricideData
#define EXPERIMENT_STATE_OOZE false
#define EXPERIMENT_STATE_GAS true
class StartMovementEvent : public BasicEvent
{
public:
StartMovementEvent(Creature& owner) : BasicEvent(), m_owner(owner) { }
bool Execute(uint64 /*eventTime*/, uint32 /*diff*/)
{
m_owner.GetMotionMaster()->MoveChase(m_owner.getVictim());
return true;
}
private:
Creature& m_owner;
};
class boss_professor_putricide : public CreatureScript
{
public:
@@ -198,7 +184,7 @@ class boss_professor_putricide : public CreatureScript
events.Reset();
summons.DespawnAll();
_SetPhase(PHASE_COMBAT_1);
SetPhase(PHASE_COMBAT_1);
experimentState = EXPERIMENT_STATE_OOZE;
me->SetReactState(REACT_DEFENSIVE);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
@@ -229,7 +215,7 @@ class boss_professor_putricide : public CreatureScript
if (IsHeroic())
events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 20000);
_SetPhase(PHASE_COMBAT_1);
SetPhase(PHASE_COMBAT_1);
Talk(SAY_AGGRO);
DoCast(me, SPELL_OOZE_TANK_PROTECTION, true);
DoZoneInCombat(me);
@@ -268,30 +254,17 @@ class boss_professor_putricide : public CreatureScript
break;
case NPC_GAS_CLOUD:
// no possible aura seen in sniff adding the aurastate
summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN22-1));
summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN22 - 1));
summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_GASEOUS_BLOAT_PROTECTION))
{
summon->AI()->AttackStart(target);
summon->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_MAX_TARGETS, 1, target, false);
summon->ClearUnitState(UNIT_STAT_CASTING);
summon->GetMotionMaster()->MoveIdle();
summon->m_Events.AddEvent(new StartMovementEvent(*summon), summon->m_Events.CalculateTime(3500));
}
summon->CastSpell(summon, SPELL_GASEOUS_BLOAT, false);
summon->SetReactState(REACT_PASSIVE);
return;
case NPC_VOLATILE_OOZE:
// no possible aura seen in sniff adding the aurastate
summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN19-1));
summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN19 - 1));
summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_VOLATILE_OOZE_PROTECTION))
{
summon->AI()->AttackStart(target);
summon->CastCustomSpell(SPELL_VOLATILE_OOZE_ADHESIVE, SPELLVALUE_MAX_TARGETS, 1, target, false);
summon->ClearUnitState(UNIT_STAT_CASTING);
summon->GetMotionMaster()->MoveIdle();
summon->m_Events.AddEvent(new StartMovementEvent(*summon), summon->m_Events.CalculateTime(3500));
me->SetReactState(REACT_PASSIVE);
}
summon->CastSpell(summon, SPELL_VOLATILE_OOZE_ADHESIVE, false);
summon->SetReactState(REACT_PASSIVE);
return;
case NPC_CHOKING_GAS_BOMB:
summon->CastSpell(summon, SPELL_CHOKING_GAS_BOMB_PERIODIC, true);
@@ -303,6 +276,7 @@ class boss_professor_putricide : public CreatureScript
default:
break;
}
if (me->isInCombat())
DoZoneInCombat(summon);
}
@@ -381,12 +355,12 @@ class boss_professor_putricide : public CreatureScript
}
}
void DoAction(const int32 action)
void DoAction(int32 const action)
{
switch (action)
{
case ACTION_FESTERGUT_COMBAT:
_SetPhase(PHASE_FESTERGUT);
SetPhase(PHASE_FESTERGUT);
me->SetSpeed(MOVE_RUN, baseSpeed*2.0f, true);
me->GetMotionMaster()->MovePoint(POINT_FESTERGUT, festergutWatchPos);
me->SetReactState(REACT_PASSIVE);
@@ -403,7 +377,7 @@ class boss_professor_putricide : public CreatureScript
break;
case ACTION_ROTFACE_COMBAT:
{
_SetPhase(PHASE_ROTFACE);
SetPhase(PHASE_ROTFACE);
me->SetSpeed(MOVE_RUN, baseSpeed*2.0f, true);
me->GetMotionMaster()->MovePoint(POINT_ROTFACE, rotfaceWatchPos);
me->SetReactState(REACT_PASSIVE);
@@ -489,12 +463,12 @@ class boss_professor_putricide : public CreatureScript
switch (phase)
{
case PHASE_COMBAT_1:
_SetPhase(PHASE_COMBAT_2);
SetPhase(PHASE_COMBAT_2);
events.ScheduleEvent(EVENT_MALLEABLE_GOO, urand(21000, 26000));
events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, urand(35000, 40000));
break;
case PHASE_COMBAT_2:
_SetPhase(PHASE_COMBAT_3);
SetPhase(PHASE_COMBAT_3);
events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 25000);
events.CancelEvent(EVENT_UNSTABLE_EXPERIMENT);
summons.DespawnEntry(NPC_MUTATED_ABOMINATION_10);
@@ -532,7 +506,7 @@ class boss_professor_putricide : public CreatureScript
return 0;
}
void UpdateAI(const uint32 diff)
void UpdateAI(uint32 const diff)
{
if ((!UpdateVictim() && !(events.GetPhaseMask() & PHASE_MASK_NOT_SELF)) || !CheckInRoom())
return;
@@ -667,7 +641,7 @@ class boss_professor_putricide : public CreatureScript
}
private:
void _SetPhase(Phases newPhase)
void SetPhase(Phases newPhase)
{
phase = newPhase;
events.SetPhase(newPhase);
@@ -675,7 +649,7 @@ class boss_professor_putricide : public CreatureScript
uint64 oozeFloodDummy[4];
Phases phase; // external of EventMap because event phase gets reset on evade
const float baseSpeed;
float const baseSpeed;
uint8 oozeFloodStage;
bool experimentState;
};
@@ -700,22 +674,13 @@ class npc_volatile_ooze : public CreatureScript
void SpellHitTarget(Unit* /*target*/, SpellEntry const* spell)
{
SpellEntry const* explode = sSpellStore.LookupEntry(SPELL_OOZE_ERUPTION);
explode = sSpellMgr->GetSpellForDifficultyFromSpell(explode, me);
if (explode->Id == spell->Id)
{
newTargetSelectTimer = 5000;
DoStartNoMovement(me);
}
if (!newTargetSelectTimer && sSpellMgr->GetSpellDifficultyId(spell->Id) == sSpellMgr->GetSpellDifficultyId(SPELL_OOZE_ERUPTION))
newTargetSelectTimer = 1000;
}
void UpdateAI(const uint32 diff)
void UpdateAI(uint32 const diff)
{
// simplified update, we do not want to select new target
if (!me->isInCombat())
return;
if (!me->getVictim())
if (!UpdateVictim())
return;
if (!newTargetSelectTimer)
@@ -724,13 +689,7 @@ class npc_volatile_ooze : public CreatureScript
if (newTargetSelectTimer <= diff)
{
newTargetSelectTimer = 0;
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_VOLATILE_OOZE_PROTECTION))
{
AttackStart(target);
me->CastCustomSpell(SPELL_VOLATILE_OOZE_ADHESIVE, SPELLVALUE_MAX_TARGETS, 1, target, false);
}
else
me->DespawnOrUnsummon();
me->CastSpell(me, SPELL_VOLATILE_OOZE_ADHESIVE, false);
}
else
newTargetSelectTimer -= diff;
@@ -774,7 +733,11 @@ class spell_putricide_gaseous_bloat : public SpellScriptLoader
void HandleExtraEffect(AuraEffect const* /*aurEff*/)
{
GetTarget()->RemoveAuraFromStack(GetSpellProto()->Id, GetCasterGUID());
Unit* target = GetTarget();
Unit* caster = GetCaster();
target->RemoveAuraFromStack(GetSpellProto()->Id, GetCasterGUID());
if (!target->HasAura(GetId()) && caster && caster->GetTypeId() == TYPEID_UNIT)
caster->ToCreature()->DespawnOrUnsummon();
}
void Register()
@@ -794,6 +757,94 @@ class spell_putricide_gaseous_bloat : public SpellScriptLoader
}
};
class BeamProtectionPred
{
public:
explicit BeamProtectionPred(uint32 excludeAura) : _excludeAura(excludeAura) { }
bool operator()(Unit* unit)
{
return unit->HasAura(_excludeAura);
}
private:
uint32 _excludeAura;
};
class spell_putricide_ooze_channel : public SpellScriptLoader
{
public:
spell_putricide_ooze_channel() : SpellScriptLoader("spell_putricide_ooze_channel") { }
class spell_putricide_ooze_channel_SpellScript : public SpellScript
{
PrepareSpellScript(spell_putricide_ooze_channel_SpellScript);
bool Validate(SpellEntry const* spell)
{
if (!spell->excludeTargetAuraSpell)
return false;
if (!sSpellStore.LookupEntry(spell->excludeTargetAuraSpell))
return false;
return true;
}
// set up initial variables and check if caster is creature
// this will let use safely use ToCreature() casts in entire script
bool Load()
{
_target = NULL;
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void SelectTarget(std::list<Unit*>& targetList)
{
targetList.remove_if(BeamProtectionPred(GetSpellInfo()->excludeTargetAuraSpell));
if (targetList.empty())
{
FinishCast(SPELL_FAILED_NO_VALID_TARGETS);
GetCaster()->ToCreature()->DespawnOrUnsummon(1); // despawn next update
return;
}
std::list<Unit*>::iterator itr = targetList.begin();
std::advance(itr, urand(0, targetList.size() - 1));
Unit* target = *itr;
targetList.clear();
targetList.push_back(target);
_target = target;
}
void SetTarget(std::list<Unit*>& targetList)
{
targetList.clear();
if (_target)
targetList.push_back(_target);
}
void StartAttack()
{
GetCaster()->ClearUnitState(UNIT_STAT_CASTING);
GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC);
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_AREA_ENEMY_SRC);
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_AREA_ENEMY_SRC);
AfterHit += SpellHitFn(spell_putricide_ooze_channel_SpellScript::StartAttack);
}
Unit* _target;
};
SpellScript* GetSpellScript() const
{
return new spell_putricide_ooze_channel_SpellScript();
}
};
class spell_putricide_expunged_gas : public SpellScriptLoader
{
public:
@@ -803,11 +854,13 @@ class spell_putricide_expunged_gas : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_expunged_gas_SpellScript);
bool Load()
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void CalcDamage(SpellEffIndex /*effIndex*/)
{
if (GetCaster()->GetTypeId() != TYPEID_UNIT)
return;
InstanceScript* instance = GetCaster()->GetInstanceScript();
if (!instance)
return;
@@ -817,23 +870,28 @@ class spell_putricide_expunged_gas : public SpellScriptLoader
return;
int32 dmg = 0;
ScriptedAI* professorAI = CAST_AI(ScriptedAI, professor->AI());
if (Aura* gasBloat = GetTargetUnit()->GetAura(professorAI->SPELL_GASEOUS_BLOAT_HELPER))
SpellEntry const* bloat = sSpellStore.LookupEntry(SPELL_GASEOUS_BLOAT);
bloat = sSpellMgr->GetSpellForDifficultyFromSpell(bloat, GetCaster());
if (Aura* gasBloat = GetTargetUnit()->GetAura(bloat->Id))
{
uint32 stack = gasBloat->GetStackAmount();
const int32 mod = professorAI->Is25ManRaid() ? 1500 : 1250;
int32 const mod = (GetCaster()->GetMap()->GetSpawnMode() & 1) ? 1500 : 1250;
for (uint8 i = 1; i < stack; ++i)
dmg += mod * stack;
}
else
GetCaster()->ToCreature()->DespawnOrUnsummon();
SetHitDamage(dmg);
}
void DespawnAfterCast()
{
GetCaster()->ToCreature()->DespawnOrUnsummon(100);
}
void Register()
{
OnEffect += SpellEffectFn(spell_putricide_expunged_gas_SpellScript::CalcDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
AfterHit += SpellHitFn(spell_putricide_expunged_gas_SpellScript::DespawnAfterCast);
}
};
@@ -974,7 +1032,7 @@ class spell_putricide_ooze_eruption_searcher : public SpellScriptLoader
if (GetHitUnit()->HasAura(adhesive->Id))
{
GetCaster()->CastSpell(GetHitUnit(), SPELL_OOZE_ERUPTION, true);
GetHitUnit()->RemoveAurasDueToSpell(adhesive->Id, GetCaster()->GetGUID());
GetHitUnit()->RemoveAurasDueToSpell(adhesive->Id, GetCaster()->GetGUID(), 0, AURA_REMOVE_BY_ENEMY_SPELL);
}
}
@@ -1448,6 +1506,7 @@ void AddSC_boss_professor_putricide()
new boss_professor_putricide();
new npc_volatile_ooze();
new spell_putricide_gaseous_bloat();
new spell_putricide_ooze_channel();
new spell_putricide_expunged_gas();
new spell_putricide_slime_puddle();
new spell_putricide_unstable_experiment();