diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 13 | ||||
| -rwxr-xr-x | src/server/game/Spells/SpellMgr.cpp | 13 | ||||
| -rwxr-xr-x | src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp | 205 |
3 files changed, 139 insertions, 92 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 0e7ffcecd0b..d5d83b3a7df 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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())) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 3308332ce04..b6edca815ea 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -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) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 4b60b306048..ef6e78f13d2 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -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); - void CalcDamage(SpellEffIndex /*effIndex*/) + bool Load() { - if (GetCaster()->GetTypeId() != TYPEID_UNIT) - return; + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + void CalcDamage(SpellEffIndex /*effIndex*/) + { 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(); |
