Scripts/Icecrown Citadel: Only one Mutated Abomination can exist during Professor Putricide encounter

Scripts/Spells: Added blizzlike error messages for certain spells
Scripts/Items: Removed obsolete scripts
This commit is contained in:
Shauren
2011-03-04 23:53:11 +01:00
parent 22cd262e6c
commit 36f848a4c2
13 changed files with 260 additions and 130 deletions
+2 -2
View File
@@ -111,7 +111,6 @@ UPDATE `creature_template` SET `ScriptName`='npc_innkeeper' WHERE `entry` IN
/* ITEM */
UPDATE `item_template` SET `ScriptName`='item_draenei_fishing_net' WHERE `entry`=23654;
UPDATE `item_template` SET `ScriptName`='item_flying_machine' WHERE `entry` IN (34060,34061);
UPDATE `item_template` SET `ScriptName`='item_gor_dreks_ointment' WHERE `entry`=30175;
UPDATE `item_template` SET `ScriptName`='item_nether_wraith_beacon' WHERE `entry`=31742;
UPDATE `item_template` SET `ScriptName`='item_tainted_core' WHERE `entry`=31088;
@@ -119,7 +118,6 @@ UPDATE `item_template` SET `ScriptName`='item_only_for_flight' WHERE `entry` IN
UPDATE `item_template` SET `ScriptName`='item_incendiary_explosives' WHERE (`entry`=35704);
UPDATE `item_template` SET `ScriptName`='item_mysterious_egg' WHERE `entry` IN(39878);
UPDATE `item_template` SET `ScriptName`='item_disgusting_jar' WHERE `entry` IN(44717);
UPDATE `item_template` SET `ScriptName`='item_harvesters_gift' WHERE `entry`=39253;
UPDATE `item_template` SET `ScriptName`='item_petrov_cluster_bombs' WHERE `entry`=33098;
UPDATE `item_template` SET `ScriptName`='item_Trident_of_Nazjan' WHERE `entry`=35850;
UPDATE `item_template` SET `ScriptName`='item_captured_frog' WHERE `entry`=53510;
@@ -2108,6 +2106,7 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
( 67533, 'spell_item_red_rider_air_rifle'),
( 26678, 'spell_item_create_heart_candy'),
( 64323, 'spell_item_book_of_glyph_mastery'),
( 52481, 'spell_item_gift_of_the_harvester'),
-- warrior
( 12975, 'spell_warr_last_stand'),
( 59725, 'spell_warr_improved_spell_reflection'),
@@ -2152,6 +2151,7 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(-49145, 'spell_dk_spell_deflection'),
(-52284, 'spell_dk_will_of_the_necropolis'),
( 48743, 'spell_dk_death_pact'),
( 52751, 'spell_dk_death_gate'),
-- shaman
(-51474, 'spell_sha_astral_shift'),
( 39610, 'spell_sha_mana_tide_totem'),
@@ -0,0 +1,2 @@
UPDATE `item_template` SET `ScriptName`='' WHERE `ScriptName`='item_harvesters_gift';
UPDATE `item_template` SET `ScriptName`='' WHERE `ScriptName`='item_flying_machine';
@@ -0,0 +1,5 @@
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_item_gift_of_the_harvester';
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dk_death_gate';
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(52481, 'spell_item_gift_of_the_harvester'),
(52751, 'spell_dk_death_gate');
@@ -81,6 +81,33 @@ void SummonList::DespawnAll()
}
}
void SummonList::RemoveNotExisting()
{
for (iterator i = begin(); i != end();)
{
if (Unit::GetCreature(*me, *i))
++i;
else
erase(i++);
}
}
bool SummonList::HasEntry(uint32 entry)
{
for (iterator i = begin(); i != end();)
{
Creature* summon = Unit::GetCreature(*me, *i);
if (!summon)
erase(i++);
else if (summon->GetEntry() == entry)
return true;
else
++i;
}
return false;
}
ScriptedAI::ScriptedAI(Creature* pCreature) : CreatureAI(pCreature),
me(pCreature),
IsFleeing(false),
@@ -36,6 +36,8 @@ class SummonList : public std::list<uint64>
void DespawnAll();
void DoAction(uint32 entry, uint32 info);
void DoZoneInCombat(uint32 entry = 0);
void RemoveNotExisting();
bool HasEntry(uint32 entry);
private:
Creature *me;
};
@@ -1045,7 +1045,7 @@ enum SpellCustomErrors
SPELL_CUSTOM_ERROR_MUST_BE_DEATH_KNIGHT = 33, // Only Death Knights may enter Ebon Hold.
SPELL_CUSTOM_ERROR_MUST_BE_IN_FERAL_FORM = 34, // Must be in Cat Form, Bear Form, or Dire Bear Form
SPELL_CUSTOM_ERROR_MUST_BE_NEAR_HELPLESS_VILLAGER = 35, // You must be within range of a Helpless Wintergarde Villager.
SPELL_CUSTOM_ERROR_MUST_TARGET_ELEMENTAL_MECHANICAL = 36, // You cannot target an elemental or mechanical corpse.
SPELL_CUSTOM_ERROR_CANT_TARGET_ELEMENTAL_MECHANICAL = 36, // You cannot target an elemental or mechanical corpse.
SPELL_CUSTOM_ERROR_MUST_HAVE_USED_DALARAN_CRYSTAL = 37, // This teleport crystal cannot be used until the teleport crystal in Dalaran has been used at least once.
SPELL_CUSTOM_ERROR_YOU_ALREADY_HOLD_SOMETHING = 38, // You are already holding something in your hand. You must throw the creature in your hand before picking up another.
SPELL_CUSTOM_ERROR_YOU_DONT_HOLD_ANYTHING = 39, // You don't have anything to throw! Find a Vargul and use Gymer Grab to pick one up!
-9
View File
@@ -4826,15 +4826,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
if (unitTarget && m_originalCaster)
m_originalCaster->CastSpell(unitTarget, urand(0, 1) ? damage : 52505, true);
return;
// Death Gate
case 52751:
{
if (!unitTarget || unitTarget->getClass() != CLASS_DEATH_KNIGHT)
return;
// triggered spell is stored in m_spellInfo->EffectBasePoints[0]
unitTarget->CastSpell(unitTarget, damage, false);
break;
}
case 53110: // Devour Humanoid
if (unitTarget)
unitTarget->CastSpell(m_caster, damage, true);
@@ -432,19 +432,22 @@ class spell_blood_queen_vampiric_bite : public SpellScriptLoader
return true;
}
SpellCastResult CheckTarget()
{
if (IsVampire(GetTargetUnit()))
{
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TARGET_VAMPIRES);
return SPELL_FAILED_CUSTOM_ERROR;
}
return SPELL_CAST_OK;
}
void OnCast()
{
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
return;
if (IsVampire(GetHitUnit()))
{
PreventHitDamage();
PreventHitDefaultEffect(EFFECT_1);
Spell::SendCastResult(GetCaster()->ToPlayer(), GetSpellInfo(), 0, SPELL_FAILED_BAD_TARGETS);
return;
}
SpellEntry const* spell = sSpellStore.LookupEntry(SPELL_FRENZIED_BLOODTHIRST);
spell = sSpellMgr->GetSpellForDifficultyFromSpell(spell, GetCaster());
GetCaster()->RemoveAura(spell->Id, 0, 0, AURA_REMOVE_BY_ENEMY_SPELL);
@@ -473,6 +476,7 @@ class spell_blood_queen_vampiric_bite : public SpellScriptLoader
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_blood_queen_vampiric_bite_SpellScript::CheckTarget);
BeforeHit += SpellHitFn(spell_blood_queen_vampiric_bite_SpellScript::OnCast);
}
};
@@ -20,6 +20,7 @@
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "Group.h"
#include "icecrown_citadel.h"
enum ScriptTexts
@@ -152,7 +153,13 @@ static const Position tablePos = {4356.190f, 3262.90f, 389.4820f, 1.483
static const uint32 oozeFloodSpells[4] = {69782, 69796, 69798, 69801};
#define DATA_EXPERIMENT_STAGE 0
enum PutricideData
{
DATA_EXPERIMENT_STAGE = 1,
DATA_PHASE = 2,
DATA_ABOMINATION = 3,
};
#define EXPERIMENT_STATE_OOZE false
#define EXPERIMENT_STATE_GAS true
@@ -205,8 +212,6 @@ class boss_professor_putricide : public CreatureScript
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_PUTRICIDE_TABLE)))
table->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
}
void EnterCombat(Unit* who)
@@ -235,8 +240,6 @@ class boss_professor_putricide : public CreatureScript
DoZoneInCombat(me);
instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, IN_PROGRESS);
if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_PUTRICIDE_TABLE)))
table->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
}
void JustReachedHome()
@@ -501,8 +504,6 @@ class boss_professor_putricide : public CreatureScript
events.CancelEvent(EVENT_UNSTABLE_EXPERIMENT);
summons.DespawnEntry(NPC_MUTATED_ABOMINATION_10);
summons.DespawnEntry(NPC_MUTATED_ABOMINATION_25);
if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_PUTRICIDE_TABLE)))
table->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
break;
default:
break;
@@ -515,12 +516,22 @@ class boss_professor_putricide : public CreatureScript
uint32 GetData(uint32 type)
{
if (type == DATA_EXPERIMENT_STAGE)
switch (type)
{
// ALSO MODIFIES!
uint32 ret = uint32(experimentState);
experimentState ^= true;
return ret;
case DATA_EXPERIMENT_STAGE:
{
// ALSO MODIFIES!
uint32 ret = uint32(experimentState);
experimentState ^= true;
return ret;
}
case DATA_PHASE:
return phase;
case DATA_ABOMINATION:
summons.RemoveNotExisting();
return summons.HasEntry(NPC_MUTATED_ABOMINATION_10) || summons.HasEntry(NPC_MUTATED_ABOMINATION_25);
default:
break;
}
return 0;
@@ -1027,28 +1038,33 @@ class spell_putricide_unbound_plague : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_unbound_plague_SpellScript);
bool Validate(SpellEntry const* /*spell*/)
{
if (!sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE))
return false;
if (!sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE_SEARCHER))
return false;
return true;
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (!GetHitUnit())
return;
SpellEntry const* plague = sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE);
SpellEntry const* searcher = sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE_SEARCHER);
Creature* professor = NULL;
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
{
professor = Unit::GetCreature(*GetCaster(), instance->GetData64(DATA_PROFESSOR_PUTRICIDE));
if (professor)
{
plague = sSpellMgr->GetSpellForDifficultyFromSpell(plague, professor);
searcher = sSpellMgr->GetSpellForDifficultyFromSpell(searcher, professor);
}
}
InstanceScript* instance = GetCaster()->GetInstanceScript();
if (!instance)
return;
SpellEntry const* plague = sSpellMgr->GetSpellForDifficultyFromSpell(sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE), GetCaster());
SpellEntry const* searcher = sSpellMgr->GetSpellForDifficultyFromSpell(sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE_SEARCHER), GetCaster());
if (!GetHitUnit()->HasAura(plague->Id))
{
if (professor)
if (Creature* professor = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
{
if (Aura* oldPlague = GetCaster()->GetAura(plague->Id, professor->GetGUID()))
{
if (Aura* newPlague = professor->AddAura(plague->Id, GetHitUnit()))
{
newPlague->SetMaxDuration(oldPlague->GetDuration());
@@ -1059,6 +1075,8 @@ class spell_putricide_unbound_plague : public SpellScriptLoader
GetCaster()->CastSpell(GetCaster(), SPELL_UNBOUND_PLAGUE_PROTECTION, true);
professor->CastSpell(GetHitUnit(), SPELL_UNBOUND_PLAGUE_SEARCHER, true);
}
}
}
}
}
@@ -1170,6 +1188,54 @@ class spell_putricide_mutation_init : public SpellScriptLoader
public:
spell_putricide_mutation_init() : SpellScriptLoader("spell_putricide_mutation_init") { }
class spell_putricide_mutation_init_SpellScript : public SpellScript
{
PrepareSpellScript(spell_putricide_mutation_init_SpellScript);
SpellCastResult CheckRequirement()
{
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_TARGET_NOT_PLAYER;
InstanceScript* instance = GetCaster()->GetInstanceScript();
if (!instance)
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
Creature* professor = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_PROFESSOR_PUTRICIDE));
if (!professor || !professor->isInCombat())
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
if (professor->AI()->GetData(DATA_PHASE) == PHASE_COMBAT_3 || !professor->isAlive())
{
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_ALL_POTIONS_USED);
return SPELL_FAILED_CUSTOM_ERROR;
}
// find another player with initialization aura
bool abominationExists = false;
Group* group = GetCaster()->ToPlayer()->GetGroup();
for (GroupReference* plrRef = group->GetFirstMember(); plrRef && !abominationExists; plrRef = plrRef->next())
if (Player* player = plrRef->getSource())
if (player->HasAura(GetSpellInfo()->Id))
abominationExists = true;
// or an existing abomination
abominationExists |= bool(professor->AI()->GetData(DATA_ABOMINATION));
if (abominationExists)
{
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS);
return SPELL_FAILED_CUSTOM_ERROR;
}
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_putricide_mutation_init_SpellScript::CheckRequirement);
}
};
class spell_putricide_mutation_init_AuraScript : public AuraScript
{
PrepareAuraScript(spell_putricide_mutation_init_AuraScript);
@@ -1189,6 +1255,11 @@ class spell_putricide_mutation_init : public SpellScriptLoader
}
};
SpellScript* GetSpellScript() const
{
return new spell_putricide_mutation_init_SpellScript();
}
AuraScript* GetAuraScript() const
{
return new spell_putricide_mutation_init_AuraScript();
+42
View File
@@ -233,6 +233,47 @@ class spell_dk_corpse_explosion : public SpellScriptLoader
}
};
class spell_dk_death_gate : public SpellScriptLoader
{
public:
spell_dk_death_gate() : SpellScriptLoader("spell_dk_death_gate") {}
class spell_dk_death_gate_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dk_death_gate_SpellScript);
SpellCastResult CheckClass()
{
if (GetCaster()->getClass() != CLASS_DEATH_KNIGHT)
{
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_BE_DEATH_KNIGHT);
return SPELL_FAILED_CUSTOM_ERROR;
}
return SPELL_CAST_OK;
}
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (!GetHitUnit())
return;
GetHitUnit()->CastSpell(GetHitUnit(), GetEffectValue(), false);
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_dk_death_gate_SpellScript::CheckClass);
OnEffect += SpellEffectFn(spell_dk_death_gate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_dk_death_gate_SpellScript();
}
};
class spell_dk_death_pact : public SpellScriptLoader
{
public:
@@ -474,6 +515,7 @@ void AddSC_deathknight_spell_scripts()
new spell_dk_anti_magic_shell_self();
new spell_dk_anti_magic_zone();
new spell_dk_corpse_explosion();
new spell_dk_death_gate();
new spell_dk_death_pact();
new spell_dk_runic_power_feed();
new spell_dk_scourge_strike();
+41
View File
@@ -882,6 +882,46 @@ class spell_item_book_of_glyph_mastery : public SpellScriptLoader
}
};
enum GiftOfTheHarvester
{
NPC_GHOUL = 28845,
MAX_GHOULS = 5,
};
class spell_item_gift_of_the_harvester : public SpellScriptLoader
{
public:
spell_item_gift_of_the_harvester() : SpellScriptLoader("spell_item_gift_of_the_harvester") {}
class spell_item_gift_of_the_harvester_SpellScript : public SpellScript
{
PrepareSpellScript(spell_item_gift_of_the_harvester_SpellScript);
SpellCastResult CheckRequirement()
{
std::list<Creature*> ghouls;
GetCaster()->GetAllMinionsByEntry(ghouls, NPC_GHOUL);
if (ghouls.size() >= MAX_GHOULS)
{
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_TOO_MANY_GHOULS);
return SPELL_FAILED_CUSTOM_ERROR;
}
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_item_gift_of_the_harvester_SpellScript::CheckRequirement);
}
};
SpellScript* GetSpellScript() const
{
return new spell_item_gift_of_the_harvester_SpellScript();
}
};
void AddSC_item_spell_scripts()
{
// 23074 Arcanite Dragonling
@@ -908,4 +948,5 @@ void AddSC_item_spell_scripts()
new spell_item_create_heart_candy();
new spell_item_book_of_glyph_mastery();
new spell_item_gift_of_the_harvester();
}
+19 -10
View File
@@ -102,24 +102,33 @@ public:
return true;
}
SpellCastResult CheckFireTotem()
{
// fire totem
if (!GetCaster()->m_SummonSlot[1])
{
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_FIRE_TOTEM);
return SPELL_FAILED_CUSTOM_ERROR;
}
return SPELL_CAST_OK;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
Unit* caster = GetCaster();
uint8 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id);
if (uint32 spellId = sSpellMgr->GetSpellWithRank(SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1, rank))
{
uint8 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id);
uint32 spellId = sSpellMgr->GetSpellWithRank(SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1, rank);
// fire slot
if (spellId && caster->m_SummonSlot[1])
{
Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[1]);
if (totem && totem->isTotem())
totem->CastSpell(totem, spellId, true);
}
Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[1]);
if (totem && totem->isTotem())
totem->CastSpell(totem, spellId, true);
}
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_sha_fire_nova_SpellScript::CheckFireTotem);
OnEffect += SpellEffectFn(spell_sha_fire_nova_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
+11 -75
View File
@@ -140,32 +140,6 @@ public:
}
};
/*#####
# item_flying_machine
#####*/
class item_flying_machine : public ItemScript
{
public:
item_flying_machine() : ItemScript("item_flying_machine") { }
bool OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/)
{
uint32 itemId = pItem->GetEntry();
if (itemId == 34060)
if (pPlayer->GetBaseSkillValue(SKILL_RIDING) >= 225)
return false;
if (itemId == 34061)
if (pPlayer->GetBaseSkillValue(SKILL_RIDING) == 300)
return false;
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: Player attempt to use item %u, but did not meet riding requirement",itemId);
pPlayer->SendEquipError(EQUIP_ERR_CANT_EQUIP_SKILL,pItem,NULL);
return true;
}
};
/*#####
# item_gor_dreks_ointment
#####*/
@@ -246,42 +220,6 @@ public:
}
};
/*#####
# item_harvesters_gift
#####*/
#define GHOULS 28845
class item_harvesters_gift : public ItemScript
{
public:
item_harvesters_gift() : ItemScript("item_harvesters_gift") { }
bool OnUse(Player* pPlayer, Item* /*pItem*/, SpellCastTargets const& /*targets*/)
{
std::list<Creature*> MinionList;
pPlayer->GetAllMinionsByEntry(MinionList,GHOULS);
if (pPlayer->GetQuestStatus(12698) == QUEST_STATUS_INCOMPLETE)
{
if (!MinionList.empty())
{
if (MinionList.size() < 5)
return false;
else
{
// This should be sent to the player as red text.
// TODO: Text should be moved to DB
pPlayer->Say("You have created enough ghouls. Return to Gothik the Harvester at Death's Breach.", LANG_UNIVERSAL);
return true;
}
}
else
return false;
}
return true;
}
};
/*#####
# item_pile_fake_furs
#####*/
@@ -512,18 +450,16 @@ public:
void AddSC_item_scripts()
{
new item_only_for_flight;
new item_draenei_fishing_net;
new item_nether_wraith_beacon;
new item_flying_machine;
new item_gor_dreks_ointment;
new item_incendiary_explosives;
new item_mysterious_egg;
new item_disgusting_jar;
new item_harvesters_gift;
new item_pile_fake_furs;
new item_petrov_cluster_bombs;
new item_dehta_trap_smasher;
new item_trident_of_nazjan;
new item_only_for_flight();
new item_draenei_fishing_net();
new item_nether_wraith_beacon();
new item_gor_dreks_ointment();
new item_incendiary_explosives();
new item_mysterious_egg();
new item_disgusting_jar();
new item_pile_fake_furs();
new item_petrov_cluster_bombs();
new item_dehta_trap_smasher();
new item_trident_of_nazjan();
new item_captured_frog();
}