diff --git a/sql/migrations/20170707202843_world.sql b/sql/migrations/20170707202843_world.sql new file mode 100644 index 000000000..45e054be8 --- /dev/null +++ b/sql/migrations/20170707202843_world.sql @@ -0,0 +1,12 @@ +INSERT INTO `migrations` VALUES ('20170707202843'); + +INSERT INTO `script_texts` (`entry`, `type`, `content_default`, `comment`) + VALUES (-1900048, 0, 'Ah, here we are! Well let\'s get to work, shall we...?', 'J\'eevee Scholomance 1'), + (-1900049, 0, 'Oh, right! Over here now...', 'J\'eevee Scholomance 2'), + (-1900050, 0, 'And now... the final step!', 'J\'eevee Scholomance 3'), + (-1900051, 0, 'I\'m finished. The parchment is made. Now, return to Gorzeeki...', 'J\'eevee Scholomance 4'); + +UPDATE `quest_template` + SET `QuestFlags` = 6, `SpecialFlags` = 2, + `EndText` = 'Parchment Created', `ObjectiveText1` = '', + `ReqCreatureOrGOId1` = 0, `ReqCreatureOrGOCount1` = 0 WHERE `entry` = 7629; diff --git a/src/scripts/CMakeLists.txt b/src/scripts/CMakeLists.txt index 571a91a90..ce817105d 100644 --- a/src/scripts/CMakeLists.txt +++ b/src/scripts/CMakeLists.txt @@ -4,6 +4,7 @@ set(LIBRARY_NAME scripts) set (SCRIPTS_SRCS ScriptLoader.h custom/custom.h + custom/npc_j_eevee.h eastern_kingdoms/burning_steppes/blackrock_depths/blackrock_depths.h eastern_kingdoms/burning_steppes/blackrock_spire/blackrock_spire.h eastern_kingdoms/burning_steppes/blackwing_lair/blackwing_lair.h @@ -46,6 +47,7 @@ set (SCRIPTS_SRCS custom/npc_escort.cpp custom/npc_gobj_spawner.cpp custom/zero_creatures.cpp + custom/npc_j_eevee.cpp eastern_kingdoms/alterac_mountains/alterac_mountains.cpp eastern_kingdoms/arathi_highlands/arathi_highlands.cpp eastern_kingdoms/blasted_lands/blasted_lands.cpp diff --git a/src/scripts/ScriptLoader.cpp b/src/scripts/ScriptLoader.cpp index ae73e6246..69c13dc3f 100644 --- a/src/scripts/ScriptLoader.cpp +++ b/src/scripts/ScriptLoader.cpp @@ -270,6 +270,8 @@ void AddSC_thunder_bluff(); void AddSC_ungoro_crater(); void AddSC_winterspring(); +void AddSC_npc_j_eevee(); // J'Eevee, the Imp in a Jar + void AddScripts() { //Nostalrius @@ -535,4 +537,5 @@ void AddScripts() AddSC_ungoro_crater(); AddSC_winterspring(); + AddSC_npc_j_eevee(); } diff --git a/src/scripts/custom/npc_j_eevee.cpp b/src/scripts/custom/npc_j_eevee.cpp new file mode 100644 index 000000000..689e015df --- /dev/null +++ b/src/scripts/custom/npc_j_eevee.cpp @@ -0,0 +1,284 @@ +#include "scriptPCH.h" +#include "npc_j_eevee.h" + +struct EventLocations +{ + float m_fX, m_fY, m_fZ, m_fO; + int m_wait; +}; + +static EventLocations aJeeveeDreadsteedLocations[] = +{ + { -38.939999f, 812.849976f, -29.530002f, 4.890318f, 3500 }, //Jeevee spawn + { -27.768442f, 812.457703f, -29.535814f, 6.258483f, 4000 }, //Jeevee first point + { -45.293509f, 822.046747f, -29.535671f, 2.211563f, 3000 }, //Jeevee second point + { -44.074763f, 802.921135f, -29.535734f, 4.357706f, 3000 }, //Jeevee third point + { -38.939999f, 812.849976f, -29.530002f, 4.890318f, 4000 } //Jeevee last point +}; +enum +{ + SPELL_J_EEVEE_SUMMONS_OBJECT = 23140, + SPELL_J_EEVEE_TELEPORT = 7791, + + SHOUT_J_EEVEE_FREEDOM = -1780196, + SAY_J_EEVEE_DREADSTEED_1 = -1780197, + SAY_J_EEVEE_DREADSTEED_2 = -1780198, + SAY_J_EEVEE_DREADSTEED_3 = -1780199, + SAY_J_EEVEE_DREADSTEED_4 = -1780200, + + SAY_J_EEVEE_SCHOLOMANCE_1 = -1900048, + SAY_J_EEVEE_SCHOLOMANCE_2 = -1900049, + SAY_J_EEVEE_SCHOLOMANCE_3 = -1900050, + SAY_J_EEVEE_SCHOLOMANCE_4 = -1900051, + + QUEST_IMP_DELIVERY = 7629 +}; + + +npc_j_eevee_dreadsteedAI::npc_j_eevee_dreadsteedAI(Creature* pCreature) : ScriptedAI(pCreature) +{ + //m_pInstance = (instance_dire_maul*) pCreature->GetInstanceData(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); + m_creature->setFaction(35); //friendly to everyone + m_creature->SetWalk(true); + Reset(); +} + +void npc_j_eevee_dreadsteedAI::Reset() +{ + waitTimer = 3500; + currentPoint = 0; + waypointReached = true; +} + +void npc_j_eevee_dreadsteedAI::MovementInform(uint32 uiType, uint32 uiPointId) +{ + if (uiType != POINT_MOTION_TYPE) + return; + switch (uiPointId) + { + case 1: + case 2: + case 3: + m_creature->SetFacingTo(aJeeveeDreadsteedLocations[currentPoint].m_fO); + waypointReached = true; + m_creature->CastSpell(m_creature, SPELL_J_EEVEE_SUMMONS_OBJECT, false); + break; + case 4: + m_creature->SetFacingTo(aJeeveeDreadsteedLocations[currentPoint].m_fO); + waypointReached = true; + if (Player* player = m_creature->GetMap()->GetPlayer(guidPlayer)) + DoScriptText(SAY_J_EEVEE_DREADSTEED_4, m_creature, player); + + DoCastSpellIfCan(m_creature, SPELL_J_EEVEE_TELEPORT, CAST_TRIGGERED); + break; + + } +} +void npc_j_eevee_dreadsteedAI::UpdateAI(const uint32 uiDiff) +{ + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + { + if (waypointReached) + { + if (waitTimer < uiDiff) + { + if (currentPoint < 4) + { + switch (currentPoint) + { + case 0: + DoScriptText(SAY_J_EEVEE_DREADSTEED_1, m_creature); + break; + case 1: + DoScriptText(SAY_J_EEVEE_DREADSTEED_2, m_creature); + break; + case 2: + DoScriptText(SAY_J_EEVEE_DREADSTEED_3, m_creature); + break; + } + currentPoint++; + m_creature->GetMotionMaster()->MovePoint(currentPoint, aJeeveeDreadsteedLocations[currentPoint].m_fX, aJeeveeDreadsteedLocations[currentPoint].m_fY, aJeeveeDreadsteedLocations[currentPoint].m_fZ, true); + waitTimer = aJeeveeDreadsteedLocations[currentPoint].m_wait; + } + else + m_creature->DisappearAndDie(); + waypointReached = false; + } + else + waitTimer -= uiDiff; + } + return; + } + DoMeleeAttackIfReady(); +} +void npc_j_eevee_dreadsteedAI::SetPlayerGuid(uint64 playerGuid) +{ + guidPlayer = playerGuid; +} +void npc_j_eevee_dreadsteedAI::ShoutFreedom() +{ + DoScriptText(SHOUT_J_EEVEE_FREEDOM, m_creature); +} + +static EventLocations aJeeveeScholomanceLocations[] = +{ + { 38.706051f, 156.989319f, 83.545631f, 1.585528f, 2000 }, // 1. spawn, Text 1 + { 38.123325f, 159.745956f, 83.545631f, 1.587492f, 300 }, // 2. Move + { 36.478260f, 160.530975f, 83.545631f, 3.179874f, 4000 }, // 3. Move, EMOTE_ONESHOT_ATTACK once point reached + { 38.123325f, 159.745956f, 83.545631f, 5.250862f, 100 }, // 4. Move, text 2 at start of movement + { 41.213757f, 155.202774f, 83.545631f, 0.098650f, 50 }, // 5. Move + { 45.890804f, 155.115601f, 83.545631f, 0.018146f, 50 }, // 6. Move + { 46.639896f, 160.362015f, 83.545631f, 2.549089f, 50 }, // 7. Move + { 44.227440f, 160.631088f, 83.545631f, 2.549089f, 4000 }, // 8. Move, EMOTE_ONESHOT_ATTACK once point reached (attack twice?) + { 46.639896f, 160.362015f, 83.545631f, 5.250862f, 300 }, // 9. Move, run. text 3 at start of movement + { 46.425823f, 154.547577f, 83.645631f, 3.108989f, 50 }, // 10. Move + { 34.415833f, 154.561859f, 83.645631f, 3.140403f, 50 }, // 11. Move, run + { 28.838001f, 160.411469f, 83.645631f, 2.378568f, 100 }, // 12. Move, run + { 33.201927f, 160.234833f, 83.645624f, 6.242730f, 4000 }, // 13. Move WALK again, emote attack + { 33.201927f, 160.234833f, 83.645624f, 6.242730f, 2000 }, // 14. Finished, speak Text 4 +}; + +npc_j_eevee_scholomanceAI::npc_j_eevee_scholomanceAI(Creature* pCreature) : ScriptedAI(pCreature) +{ + m_creature->SetWalk(true); + + if (m_creature->IsTemporarySummon()) { + guidPlayer = ((TemporarySummon*)m_creature)->GetSummonerGuid(); + + if (Player *player = m_creature->GetMap()->GetPlayer(guidPlayer)) { + player->HandleEmote(EMOTE_ONESHOT_KNEEL); + m_creature->setFaction(player->getFaction()); // player faction, friendly to player but hostile to other mobs + } + } + + waitTimer = 4000; + // Repeat attack emotes at some positions + attackRepeatTimer = 1000; + currentPoint = 0; + waypointReached = true; + finished = false; + + Reset(); +} + +void npc_j_eevee_scholomanceAI::Reset() +{ + // do nothing, continue from where we left off +} + +void npc_j_eevee_scholomanceAI::MovementInform(uint32 uiType, uint32 uiPointId) +{ + if (uiType != POINT_MOTION_TYPE) + return; + + m_creature->SetFacingTo(aJeeveeScholomanceLocations[currentPoint].m_fO); + waypointReached = true; + switch (uiPointId) + { + case 2: + m_creature->HandleEmote(EMOTE_ONESHOT_ATTACKUNARMED); + attackRepeatTimer = 1000; + break; + case 7: + m_creature->HandleEmote(EMOTE_ONESHOT_ATTACKUNARMED); + attackRepeatTimer = 1000; + break; + case 12: + m_creature->HandleEmote(EMOTE_ONESHOT_ATTACKUNARMED); + attackRepeatTimer = 1000; + break; + case 13: + DoCastSpellIfCan(m_creature, SPELL_J_EEVEE_TELEPORT, CAST_TRIGGERED); + finished = true; + break; + } +} + +void npc_j_eevee_scholomanceAI::UpdateAI(const uint32 uiDiff) +{ + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + { + if (waypointReached || finished) + { + if (waitTimer < uiDiff) + { + if (currentPoint < 13) + { + switch (currentPoint) + { + case 0: + DoScriptText(SAY_J_EEVEE_SCHOLOMANCE_1, m_creature); + break; + case 3: + DoScriptText(SAY_J_EEVEE_SCHOLOMANCE_2, m_creature); + break; + case 8: + DoScriptText(SAY_J_EEVEE_SCHOLOMANCE_3, m_creature); + m_creature->SetWalk(false); + break; + case 11: + m_creature->SetWalk(true); + break; + case 12: + // final script text + DoScriptText(SAY_J_EEVEE_SCHOLOMANCE_4, m_creature); + + if (Player* player = m_creature->GetMap()->GetPlayer(guidPlayer)) + player->GroupEventHappens(QUEST_IMP_DELIVERY, m_creature); + + break; + } + + currentPoint++; + m_creature->GetMotionMaster()->MovePoint(currentPoint, aJeeveeScholomanceLocations[currentPoint].m_fX, aJeeveeScholomanceLocations[currentPoint].m_fY, aJeeveeScholomanceLocations[currentPoint].m_fZ, true); + waitTimer = aJeeveeScholomanceLocations[currentPoint].m_wait; + } + else + { + m_creature->DisappearAndDie(); + } + + waypointReached = false; + } + else + { + waitTimer -= uiDiff; + + if (currentPoint == 2 || currentPoint == 7 || currentPoint == 12) + { + if (attackRepeatTimer < uiDiff) + { + m_creature->HandleEmote(EMOTE_ONESHOT_ATTACKUNARMED); + + attackRepeatTimer = 1000; + } + else + attackRepeatTimer -= uiDiff; + } + } + } + return; + } + DoMeleeAttackIfReady(); +} + +CreatureAI* GetAI_npc_j_eevee(Creature* pCreature) +{ + if (pCreature->GetMapId() == 429) //Map 429 Zone 2557. HT. + return new npc_j_eevee_dreadsteedAI(pCreature); + else if (pCreature->GetMapId() == 289) // Map 289, Zone 2057. Scholomance + return new npc_j_eevee_scholomanceAI(pCreature); + + return NULL; +} + +void AddSC_npc_j_eevee() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_j_eevee"; + newscript->GetAI = &GetAI_npc_j_eevee; + newscript->RegisterSelf(); +} diff --git a/src/scripts/custom/npc_j_eevee.h b/src/scripts/custom/npc_j_eevee.h new file mode 100644 index 000000000..7463c2e57 --- /dev/null +++ b/src/scripts/custom/npc_j_eevee.h @@ -0,0 +1,37 @@ +#ifndef DEF_NPC_J_EEVEE_AI +#define DEF_NPC_J_EEVEE_AI +#include "scriptPCH.h" + +struct npc_j_eevee_dreadsteedAI : public ScriptedAI +{ + npc_j_eevee_dreadsteedAI(Creature* pCreature); + void Reset(); + uint64 guidPlayer; + uint32 waitTimer; + uint8 currentPoint; + bool waypointReached; + + void MovementInform(uint32 uiType, uint32 uiPointId); + void UpdateAI(const uint32 uiDiff); + + void SetPlayerGuid(uint64 playerGuid); + void ShoutFreedom(); +}; + +struct npc_j_eevee_scholomanceAI : public ScriptedAI +{ + npc_j_eevee_scholomanceAI(Creature* pCreature); + void Reset(); + + uint64 guidPlayer; + uint32 waitTimer; + uint32 attackRepeatTimer; + uint8 currentPoint; + bool waypointReached; + bool finished; + + void MovementInform(uint32 uiType, uint32 uiPointId); + void UpdateAI(const uint32 uiDiff); +}; + +#endif diff --git a/src/scripts/eastern_kingdoms/western_plaguelands/scholomance/scholomance.h b/src/scripts/eastern_kingdoms/western_plaguelands/scholomance/scholomance.h index a6a96c672..27601104c 100644 --- a/src/scripts/eastern_kingdoms/western_plaguelands/scholomance/scholomance.h +++ b/src/scripts/eastern_kingdoms/western_plaguelands/scholomance/scholomance.h @@ -20,7 +20,9 @@ enum NPC_KIRTONOS = 10506, NPC_GANDLING = 1853, NPC_VECTUS = 10432, - NPC_MARDUKE = 10433 + NPC_MARDUKE = 10433, + + NPC_J_EEVEE = 14500 }; enum diff --git a/src/scripts/kalimdor/feralas/dire_maul/dreadsteed_ritual.cpp b/src/scripts/kalimdor/feralas/dire_maul/dreadsteed_ritual.cpp index 3053db458..045a5c114 100644 --- a/src/scripts/kalimdor/feralas/dire_maul/dreadsteed_ritual.cpp +++ b/src/scripts/kalimdor/feralas/dire_maul/dreadsteed_ritual.cpp @@ -4,6 +4,7 @@ #include "scriptPCH.h" #include "dire_maul.h" +#include "../../../custom/npc_j_eevee.h" enum { @@ -51,119 +52,7 @@ struct EventLocations float m_fX, m_fY, m_fZ, m_fO; int m_wait; }; -static EventLocations aJeeveeLocations[] = -{ - { -38.939999f, 812.849976f, -29.530002f, 4.890318f, 3500}, //Jeevee spawn - { -27.768442f, 812.457703f, -29.535814f, 6.258483f, 4000}, //Jeevee first point - { -45.293509f, 822.046747f, -29.535671f, 2.211563f, 3000}, //Jeevee second point - { -44.074763f, 802.921135f, -29.535734f, 4.357706f, 3000}, //Jeevee third point - { -38.939999f, 812.849976f, -29.530002f, 4.890318f, 4000} //Jeevee last point -}; -enum -{ - SPELL_J_EEVEE_SUMMONS_OBJECT = 23140, - //SPELL_J_EEVEE_TELEPORT //??? - SHOUT_J_EEVEE_FREEDOM = -1780196, - SAY_J_EEVEE_1 = -1780197, - SAY_J_EEVEE_2 = -1780198, - SAY_J_EEVEE_3 = -1780199, - SAY_J_EEVEE_4 = -1780200 -}; -// J'eevee -struct npc_j_eeveeAI : public ScriptedAI -{ - npc_j_eeveeAI(Creature* pCreature) : ScriptedAI(pCreature) - { - //m_pInstance = (instance_dire_maul*) pCreature->GetInstanceData(); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); - m_creature->setFaction(35); //friendly to everyone - m_creature->SetWalk(true); - Reset(); - } - - - void Reset() - { - waitTimer = 3500; - currentPoint = 0; - waypointReached = true; - } - uint64 guidPlayer; - uint32 waitTimer; - uint8 currentPoint; - bool waypointReached; - void MovementInform(uint32 uiType, uint32 uiPointId) - { - if (uiType != POINT_MOTION_TYPE) - return; - switch (uiPointId) - { - case 1: - case 2: - case 3: - m_creature->SetFacingTo(aJeeveeLocations[currentPoint].m_fO); - waypointReached = true; - m_creature->CastSpell(m_creature, SPELL_J_EEVEE_SUMMONS_OBJECT, false); - break; - case 4: - m_creature->SetFacingTo(aJeeveeLocations[currentPoint].m_fO); - waypointReached = true; - if (Player* player = m_creature->GetMap()->GetPlayer(guidPlayer)) - DoScriptText(SAY_J_EEVEE_4, m_creature, player); - break; - - } - } - void UpdateAI(const uint32 uiDiff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - { - if (waypointReached) - { - if (waitTimer < uiDiff) - { - if (currentPoint < 4) - { - switch (currentPoint) - { - case 0: - DoScriptText(SAY_J_EEVEE_1, m_creature); - break; - case 1: - DoScriptText(SAY_J_EEVEE_2, m_creature); - break; - case 2: - DoScriptText(SAY_J_EEVEE_3, m_creature); - break; - } - currentPoint++; - m_creature->GetMotionMaster()->MovePoint(currentPoint, aJeeveeLocations[currentPoint].m_fX, aJeeveeLocations[currentPoint].m_fY, aJeeveeLocations[currentPoint].m_fZ, true); - waitTimer = aJeeveeLocations[currentPoint].m_wait; - } - else - m_creature->DisappearAndDie(); - waypointReached = false; - } - else - waitTimer -= uiDiff; - } - return; - } - DoMeleeAttackIfReady(); - } - void SetPlayerGuid(uint64 playerGuid) - { - guidPlayer = playerGuid; - } -}; - -CreatureAI* GetAI_npc_j_eevee(Creature* pCreature) -{ - if (pCreature->GetMapId() == 429) //Map 429 Zone 2557. HT. - return new npc_j_eeveeAI(pCreature); - return NULL; -} struct NodeInfo { uint64 highGuid; @@ -243,9 +132,11 @@ struct go_pedestal_of_immol_tharAI: public GameObjectAI eventPhase = 1; if (Creature* jeevee = me->SummonCreature(NPC_J_EEVEE, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 420000)) { - DoScriptText(SHOUT_J_EEVEE_FREEDOM, jeevee); - if (npc_j_eeveeAI* jeeveeAI = dynamic_cast(jeevee->AI())) + if (npc_j_eevee_dreadsteedAI* jeeveeAI = dynamic_cast(jeevee->AI())) + { + jeeveeAI->ShoutFreedom(); jeeveeAI->SetPlayerGuid(playerGuid); + } } return true; } @@ -1041,11 +932,6 @@ void AddSC_dreadsteed_ritual() newscript->pProcessEventId = &ProcessEventId_event_dreadsteed_ritual_second_part; newscript->RegisterSelf(); - newscript = new Script; - newscript->Name = "npc_j_eevee"; - newscript->GetAI = &GetAI_npc_j_eevee; - newscript->RegisterSelf(); - newscript = new Script; newscript->Name = "npc_ritual_trigger"; newscript->GetAI = &GetAI_npc_ritual_trigger;