Skip to content

Commit

Permalink
Implement Prof. Putricide trap event - ICC
Browse files Browse the repository at this point in the history
(based on cmangos/mangos-wotlk@48b408d)

Signed-off-by: Xfurry <xfurry@cmangos.net>
  • Loading branch information
xfurry committed May 21, 2016
1 parent 9e9e0f2 commit f2eeceb
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 11 deletions.
4 changes: 3 additions & 1 deletion sql/scriptdev2/scriptdev2.sql
Expand Up @@ -794,17 +794,19 @@ UPDATE creature_template SET ScriptName='mob_little_ooze' WHERE entry=36897;
UPDATE creature_template SET ScriptName='mob_big_ooze' WHERE entry=36899;
UPDATE creature_template SET ScriptName='boss_valithria_dreamwalker' WHERE entry=36789;
UPDATE creature_template SET ScriptName='boss_professor_putricide' WHERE entry=36678;
UPDATE creature_template SET ScriptName='npc_putricides_trap' WHERE entry=38879;
UPDATE creature_template SET ScriptName='boss_the_lich_king_icc' WHERE entry=36597;
UPDATE gameobject_template SET ScriptName='go_icc_teleporter' WHERE entry IN (202235,202242,202243,202244,202245,202246);
DELETE FROM scripted_event_id WHERE id IN (23426,23438);
INSERT INTO scripted_event_id VALUES
(23426,'event_gameobject_citadel_valve'),
(23438,'event_gameobject_citadel_valve');
DELETE FROM scripted_areatrigger WHERE entry IN (5604,5611,5612,5709,5718,5732);
DELETE FROM scripted_areatrigger WHERE entry IN (5604,5611,5612,5647,5709,5718,5732);
INSERT INTO scripted_areatrigger VALUES
(5604,'at_icecrown_citadel'),
(5611,'at_lights_hammer'),
(5612,'at_lights_hammer'),
(5647,'at_putricides_trap'),
(5709,'at_icecrown_citadel'),
(5718,'at_frozen_throne_tele'),
(5732,'at_icecrown_citadel');
Expand Down
Expand Up @@ -16,8 +16,8 @@

/* ScriptData
SDName: icecrown_citadel
SD%Complete: 20%
SDComment: Teleporters script.
SD%Complete: 50%
SDComment: Teleporters, Light's Hammer ATs, Putricide's trap.
SDCategory: Icecrown Citadel
EndScriptData */

Expand Down Expand Up @@ -228,6 +228,181 @@ bool AreaTrigger_at_lights_hammer(Player* pPlayer, AreaTriggerEntry const* pAt)
return false;
}

enum
{
SPELL_GIANT_INSECT_SWARM = 70475,

NPC_FLESH_EATING_INSECT = 37782,

// NOTE: these numbers are quesswork
MAX_INSECT_PER_ROUND = 8,
TOTAL_INSECTS_PER_EVENT = 100,
};

/*#####
## at_putricides_trap
#####*/

bool AreaTrigger_at_putricides_trap(Player* pPlayer, AreaTriggerEntry const* pAt)
{
if (pPlayer->isGameMaster() || pPlayer->isDead())
return false;

if (pAt->id != AT_PUTRICIDES_TRAP)
return false;

instance_icecrown_citadel* pInstance = (instance_icecrown_citadel*)pPlayer->GetInstanceData();
if (!pInstance)
return false;

if (pInstance->GetData(TYPE_PLAGUE_WING_ENTRANCE) == DONE || pInstance->GetData(TYPE_PLAGUE_WING_ENTRANCE) == IN_PROGRESS)
return false;

// cast spell and start event
if (Creature* pTrap = pInstance->GetSingleCreatureFromStorage(NPC_PUTRICIDES_TRAP))
{
pTrap->CastSpell(pTrap, SPELL_GIANT_INSECT_SWARM, false);
pInstance->SetData(TYPE_PLAGUE_WING_ENTRANCE, IN_PROGRESS);
}

return false;
}

/*######
## npc_putricides_trap
######*/

struct npc_putricides_trapAI : public ScriptedAI
{
npc_putricides_trapAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (instance_icecrown_citadel*)pCreature->GetInstanceData();
Reset();
}

instance_icecrown_citadel* m_pInstance;

uint8 m_uiInsectCounter;
uint32 m_uiEventTimer;
uint32 m_uiSummonTimer;

void Reset() override
{
m_uiInsectCounter = 0;
m_uiSummonTimer = 1000;
m_uiEventTimer = 5 * MINUTE * IN_MILLISECONDS;
}

void MoveInLineOfSight(Unit* /*pWho*/) override { }
void AttackStart(Unit* /*pWho*/) override { }

void JustSummoned(Creature* pSummoned) override
{
if (pSummoned->GetEntry() == NPC_FLESH_EATING_INSECT)
{
float fX, fY, fZ;
pSummoned->GetPosition(fX, fY, fZ);
pSummoned->UpdateAllowedPositionZ(fX, fY, fZ);
pSummoned->SetWalk(false);
pSummoned->SetLevitate(true);
pSummoned->GetMotionMaster()->MovePoint(1, fX, fY, fZ);
}
}

void SummonedMovementInform(Creature* pSummoned, uint32 uiMotionType, uint32 uiPointId) override
{
if (uiMotionType != POINT_MOTION_TYPE || !uiPointId)
return;

pSummoned->SetLevitate(false);
}

void SummonedCreatureJustDied(Creature* pSummoned) override
{
if (!m_pInstance)
return;

if (m_pInstance->GetData(TYPE_PLAGUE_WING_ENTRANCE) != IN_PROGRESS)
return;

if (pSummoned->GetEntry() == NPC_FLESH_EATING_INSECT)
{
++m_uiInsectCounter;
if (m_uiInsectCounter >= TOTAL_INSECTS_PER_EVENT)
{
m_uiSummonTimer = 0;
m_uiEventTimer = 0;

m_pInstance->SetData(TYPE_PLAGUE_WING_ENTRANCE, DONE);
m_creature->ForcedDespawn();
}
}
}

void UpdateAI(const uint32 uiDiff) override
{
if (!m_pInstance)
return;

if (m_pInstance->GetData(TYPE_PLAGUE_WING_ENTRANCE) != IN_PROGRESS)
return;

// random summon creatures
if (m_uiSummonTimer)
{
if (m_uiSummonTimer <= uiDiff)
{
float fX, fY, fZ;
uint8 uiMaxInsects = urand(MAX_INSECT_PER_ROUND * 0.5, MAX_INSECT_PER_ROUND);
for (uint8 i = 0; i < uiMaxInsects; ++i)
{
m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 15.0f, fX, fY, fZ);
m_creature->SummonCreature(NPC_FLESH_EATING_INSECT, fX, fY, fZ + 20.0f, 0, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 5 * MINUTE * IN_MILLISECONDS);
}
m_uiSummonTimer = urand(2000, 5000);
}
else
m_uiSummonTimer -= uiDiff;
}

// event can last max 5 min
if (m_uiEventTimer)
{
if (m_uiEventTimer <= uiDiff)
{
bool bEventFailed = true;

// check withing all players in map if any are still alive and in LoS
Map::PlayerList const& pAllPlayers = m_pInstance->instance->GetPlayers();

if (!pAllPlayers.isEmpty())
{
for (Map::PlayerList::const_iterator itr = pAllPlayers.begin(); itr != pAllPlayers.end(); ++itr)
{
if (Player* pPlayer = itr->getSource())
{
if (pPlayer->isAlive() && pPlayer->IsWithinLOSInMap(m_creature))
bEventFailed = false;
}
}
}

// set event as done if there are still players around
m_pInstance->SetData(TYPE_PLAGUE_WING_ENTRANCE, bEventFailed ? FAIL : DONE);
m_uiSummonTimer = 0;
m_uiEventTimer = 0;
}
else
m_uiEventTimer -= uiDiff;
}
}
};

CreatureAI* GetAI_npc_putricides_trap(Creature* pCreature)
{
return new npc_putricides_trapAI(pCreature);
};

void AddSC_icecrown_citadel()
{
Script* pNewScript;
Expand All @@ -247,4 +422,14 @@ void AddSC_icecrown_citadel()
pNewScript->Name = "at_lights_hammer";
pNewScript->pAreaTrigger = &AreaTrigger_at_lights_hammer;
pNewScript->RegisterSelf();

pNewScript = new Script;
pNewScript->Name = "at_putricides_trap";
pNewScript->pAreaTrigger = &AreaTrigger_at_putricides_trap;
pNewScript->RegisterSelf();

pNewScript = new Script;
pNewScript->Name = "npc_putricides_trap";
pNewScript->GetAI = &GetAI_npc_putricides_trap;
pNewScript->RegisterSelf();
}
Expand Up @@ -7,7 +7,7 @@

enum
{
MAX_ENCOUNTER = 14,
MAX_ENCOUNTER = 15,

TYPE_MARROWGAR = 0,
TYPE_LADY_DEATHWHISPER = 1,
Expand All @@ -23,6 +23,7 @@ enum
TYPE_LICH_KING = 11,
TYPE_BLOOD_WING_ENTRANCE = 12,
TYPE_FROST_WING_ENTRANCE = 13,
TYPE_PLAGUE_WING_ENTRANCE = 14,

// NPC entries
NPC_LORD_MARROWGAR = 36612,
Expand All @@ -48,6 +49,7 @@ enum
NPC_SKYBREAKER_MARINE = 37830,
NPC_ALLIANCE_MARINE = 37830,
NPC_BLOOD_ORB_CONTROL = 38008,
NPC_PUTRICIDES_TRAP = 38879, // Handles trap event before Putricide
NPC_LANATHEL_INTRO = 38004,
NPC_VALITHRIA_QUEST = 38589,
NPC_VALITHRIA_COMBAT_TRIGGER = 38752,
Expand Down Expand Up @@ -171,6 +173,7 @@ enum
AT_SINDRAGOSA_PLATFORM = 5604,
AT_LIGHTS_HAMMER_INTRO_1 = 5611,
AT_LIGHTS_HAMMER_INTRO_2 = 5612,
AT_PUTRICIDES_TRAP = 5647,
AT_DEATHWHISPER_INTRO = 5709,
AT_FROZEN_THRONE_TELE = 5718,
AT_MARROWGAR_INTRO = 5732,
Expand Down
Expand Up @@ -160,6 +160,7 @@ void instance_icecrown_citadel::OnCreatureCreate(Creature* pCreature)
case NPC_SPINESTALKER:
case NPC_VALITHRIA_COMBAT_TRIGGER:
case NPC_BLOOD_ORB_CONTROL:
case NPC_PUTRICIDES_TRAP:
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
break;
case NPC_DEATHWHISPER_SPAWN_STALKER:
Expand Down Expand Up @@ -202,7 +203,10 @@ void instance_icecrown_citadel::OnObjectCreate(GameObject* pGo)
// ToDo: set in motion when TYPE_LADY_DEATHWHISPER == DONE
break;
case GO_SAURFANG_DOOR:
break;
case GO_SCIENTIST_DOOR:
if (m_auiEncounter[TYPE_PLAGUE_WING_ENTRANCE] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_CRIMSON_HALL_DOOR:
if (m_auiEncounter[TYPE_BLOOD_WING_ENTRANCE] == DONE)
Expand Down Expand Up @@ -508,11 +512,6 @@ void instance_icecrown_citadel::SetData(uint32 uiType, uint32 uiData)
DoUseDoorOrButton(GO_SAURFANG_DOOR);
DoRespawnGameObject(GO_SAURFANG_CACHE, 60 * MINUTE);
DoToggleGameObjectFlags(GO_SAURFANG_CACHE, GO_FLAG_NO_INTERACT, false);

// Note: these doors may not be correct. In theory the doors should be already opened
DoUseDoorOrButton(GO_SCIENTIST_DOOR);
DoUseDoorOrButton(GO_CRIMSON_HALL_DOOR);
DoUseDoorOrButton(GO_GREEN_DRAGON_ENTRANCE);
}
else if (uiData == IN_PROGRESS)
SetSpecialAchievementCriteria(TYPE_ACHIEV_MADE_A_MESS, true);
Expand Down Expand Up @@ -648,6 +647,26 @@ void instance_icecrown_citadel::SetData(uint32 uiType, uint32 uiData)
if (uiData == DONE)
DoUseDoorOrButton(GO_GREEN_DRAGON_ENTRANCE);
break;
case TYPE_PLAGUE_WING_ENTRANCE:
m_auiEncounter[uiType] = uiData;
// combat door
DoUseDoorOrButton(GO_SCIENTIST_DOOR_COLLISION);
if (uiData == DONE)
DoUseDoorOrButton(GO_SCIENTIST_DOOR);
// combat doors with custom anim
else if (uiData == IN_PROGRESS)
{
DoUseDoorOrButton(GO_SCIENTIST_DOOR_GREEN);
DoUseDoorOrButton(GO_SCIENTIST_DOOR_ORANGE);
}
if (uiData == FAIL || uiData == DONE)
{
if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_SCIENTIST_DOOR_GREEN))
pDoor->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_SCIENTIST_DOOR_ORANGE))
pDoor->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
break;
default:
script_error_log("Instance Icecrown Citadel: ERROR SetData = %u for type %u does not exist/not implemented.", uiType, uiData);
return;
Expand All @@ -663,7 +682,7 @@ void instance_icecrown_citadel::SetData(uint32 uiType, uint32 uiData)
<< m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
<< m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8] << " "
<< m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11] << " "
<< m_auiEncounter[12] << " " << m_auiEncounter[13];
<< m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiEncounter[14];

m_strInstData = saveStream.str();

Expand Down Expand Up @@ -719,7 +738,7 @@ void instance_icecrown_citadel::Load(const char* strIn)
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
>> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7]
>> m_auiEncounter[8] >> m_auiEncounter[9] >> m_auiEncounter[10] >> m_auiEncounter[11]
>> m_auiEncounter[12] >> m_auiEncounter[13];
>> m_auiEncounter[12] >> m_auiEncounter[13] >> m_auiEncounter[14];

for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
{
Expand Down

0 comments on commit f2eeceb

Please sign in to comment.