diff options
Diffstat (limited to 'src')
24 files changed, 1106 insertions, 141 deletions
diff --git a/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp b/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp index c988054cfa9..49935651cb6 100644 --- a/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp +++ b/src/bindings/scripts/scripts/zone/ashenvale_forest/ashenvale.cpp @@ -17,12 +17,13 @@ /* ScriptData SDName: Ashenvale SD%Complete: 70 -SDComment: Quest support: 6544 +SDComment: Quest support: 6544, 6482 SDCategory: Ashenvale Forest EndScriptData */ /* ContentData npc_torek +npc_ruul_snowhoof EndContentData */ #include "precompiled.h" @@ -174,7 +175,125 @@ CreatureAI* GetAI_npc_torek(Creature *_Creature) return (CreatureAI*)thisAI; } - + +/*#### +# npc_ruul_snowhoof +####*/ + +#define QUEST_FREEDOM_TO_RUUL 6482 +#define GO_CAGE 178147 + +struct TRINITY_DLL_DECL npc_ruul_snowhoofAI : public npc_escortAI +{ + npc_ruul_snowhoofAI(Creature *c) : npc_escortAI(c) {Reset();} + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + if (!player) + return; + + switch(i) + { + case 0: { + m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + GameObject* Cage = FindGameObject(GO_CAGE, 99); + if(Cage) + Cage->SetGoState(0); + break;} + case 13: + m_creature->SummonCreature(3922, 3449.218018, -587.825073, 174.978867, 4.714445, TEMPSUMMON_DEAD_DESPAWN, 60000); + m_creature->SummonCreature(3921, 3446.384521, -587.830872, 175.186279, 4.714445, TEMPSUMMON_DEAD_DESPAWN, 60000); + m_creature->SummonCreature(3926, 3444.218994, -587.835327, 175.380600, 4.714445, TEMPSUMMON_DEAD_DESPAWN, 60000); + break; + case 19: + m_creature->SummonCreature(3922, 3508.344482, -492.024261, 186.929031, 4.145029, TEMPSUMMON_DEAD_DESPAWN, 60000); + m_creature->SummonCreature(3921, 3506.265625, -490.531006, 186.740128, 4.239277, TEMPSUMMON_DEAD_DESPAWN, 60000); + m_creature->SummonCreature(3926, 3503.682373, -489.393799, 186.629684, 4.349232, TEMPSUMMON_DEAD_DESPAWN, 60000); + break; + + case 21:{ + if (player && player->GetTypeId() == TYPEID_PLAYER) + ((Player*)player)->GroupEventHappens(QUEST_FREEDOM_TO_RUUL,m_creature); + + break; } + } + } + + void Aggro(Unit* who) {} + + void Reset() + { + if (!IsBeingEscorted) + m_creature->setFaction(1602); + + GameObject* Cage = FindGameObject(GO_CAGE, 99); + if(Cage) + Cage->SetGoState(1); + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(m_creature); + } + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + if (player) + ((Player*)player)->FailQuest(QUEST_FREEDOM_TO_RUUL); + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } +}; + +bool QuestAccept_npc_ruul_snowhoof(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL) + { + creature->setFaction(1603); + ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID()); + } + return true; +} + +CreatureAI* GetAI_npc_ruul_snowhoofAI(Creature *_Creature) +{ + npc_ruul_snowhoofAI* ruul_snowhoofAI = new npc_ruul_snowhoofAI(_Creature); + + ruul_snowhoofAI->AddWaypoint(0, 3347.250089, -694.700989, 159.925995); + ruul_snowhoofAI->AddWaypoint(1, 3341.527039, -694.725891, 161.124542, 4000); + ruul_snowhoofAI->AddWaypoint(2, 3338.351074, -686.088138, 163.444000); + ruul_snowhoofAI->AddWaypoint(3, 3352.744873, -677.721741, 162.316269); + ruul_snowhoofAI->AddWaypoint(4, 3370.291016, -669.366943, 160.751358); + ruul_snowhoofAI->AddWaypoint(5, 3381.479492, -659.449097, 162.545303); + ruul_snowhoofAI->AddWaypoint(6, 3389.554199, -648.500000, 163.651825); + ruul_snowhoofAI->AddWaypoint(7, 3396.645020, -641.508911, 164.216019); + ruul_snowhoofAI->AddWaypoint(8, 3410.498535, -634.299622, 165.773453); + ruul_snowhoofAI->AddWaypoint(9, 3418.461426, -631.791992, 166.477615); + ruul_snowhoofAI->AddWaypoint(10, 3429.500000, -631.588745, 166.921265); + ruul_snowhoofAI->AddWaypoint(11,3434.950195, -629.245483, 168.333969); + ruul_snowhoofAI->AddWaypoint(12,3438.927979, -618.503235, 171.503143); + ruul_snowhoofAI->AddWaypoint(13,3444.217529, -609.293640, 173.077972, 1000); // Ambush 1 + ruul_snowhoofAI->AddWaypoint(14,3460.505127, -593.794189, 174.342255); + ruul_snowhoofAI->AddWaypoint(15,3480.283203, -578.210327, 176.652313); + ruul_snowhoofAI->AddWaypoint(16,3492.912842, -562.335449, 181.396301); + ruul_snowhoofAI->AddWaypoint(17,3495.230957, -550.977600, 184.652267); + ruul_snowhoofAI->AddWaypoint(18,3496.247070, -529.194214, 188.172028); + ruul_snowhoofAI->AddWaypoint(19,3497.619385, -510.411499, 188.345322, 1000); // Ambush 2 + ruul_snowhoofAI->AddWaypoint(20,3498.498047, -497.787506, 185.806274); + ruul_snowhoofAI->AddWaypoint(21,3484.218750, -489.717529, 182.389862, 4000); // End + + return (CreatureAI*)ruul_snowhoofAI; +} + void AddSC_ashenvale() { Script *newscript; @@ -184,4 +303,10 @@ void AddSC_ashenvale() newscript->GetAI = &GetAI_npc_torek; newscript->pQuestAccept = &QuestAccept_npc_torek; newscript->RegisterSelf(); -}
\ No newline at end of file + + newscript = new Script; + newscript->Name = "npc_ruul_snowhoof"; + newscript->GetAI = &GetAI_npc_ruul_snowhoofAI; + newscript->pQuestAccept = &QuestAccept_npc_ruul_snowhoof; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp index 665914deb43..cf35c4b9bc7 100644 --- a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp +++ b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: The_Barrens SD%Complete: 90 -SDComment: Quest support: 2458, 4921, 6981 +SDComment: Quest support: 2458, 4921, 6981, 1719, 863 SDCategory: Barrens EndScriptData */ @@ -25,9 +25,12 @@ EndScriptData */ npc_beaten_corpse npc_sputtervalve npc_taskmaster_fizzule remove hack when Trinity implement feature/detect spell kind to not aggro +npc_twiggy_flathead +npc_wizzlecrank_shredder EndContentData */ #include "precompiled.h" +#include "../../npc/npc_escortAI.h" /*###### ## npc_beaten_corpse @@ -361,6 +364,149 @@ CreatureAI* GetAI_npc_twiggy_flathead(Creature *_Creature) { return new npc_twiggy_flatheadAI (_Creature); } + +/*##### +## npc_wizzlecrank_shredder TODO: Pilot scripting +#####*/ + +#define SAY_PROGRESS_1 "Alright, alright I think I can figure out how to operate this thing..." +#define SAY_PROGRESS_2 "Arrrgh! This isn't right!" +#define SAY_PROGRESS_3 "Okay, I think I've got it, now. Follow me, $N!" + +#define SAY_MERCENARY_4 "There's the stolen shredder! Stop it or Lugwizzle will have our hides!" + +#define SAY_PROGRESS_5 "Looks like we're out of woods, eh? Wonder what this does..." +#define SAY_PROGRESS_6 "Come on, don't break down on me now!" +#define SAY_PROGRESS_7 "That was a close one! Well, let's get going, it's still a ways to Ratchet!" +#define SAY_PROGRESS_8 "Hmm... I don't think this blinking red light is a good thing..." + +#define SAY_PILOT_9 "Looks like you'll have to go ahead to Ratchet and tell Sputtervalve that I've wrecked the shredder." +#define SAY_PILOT_10 "I'll stay behind and guard the wreck. Hurry! Hopefully no one will notice the smoke..." + +#define QUEST_ESCAPE 863 +#define NPC_PILOT 3451 +#define MOB_MERCENARY 3282 + +struct TRINITY_DLL_DECL npc_wizzlecrank_shredderAI : public npc_escortAI +{ + npc_wizzlecrank_shredderAI(Creature* c) : npc_escortAI(c) {Reset();} + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + if(!player) + return; + + switch(i) + { + case 0: DoSay(SAY_PROGRESS_1, LANG_UNIVERSAL, NULL); + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); break; + case 1: DoSay(SAY_PROGRESS_2, LANG_UNIVERSAL, NULL); break; + case 10: DoSay(SAY_PROGRESS_3, LANG_UNIVERSAL, player); + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); break; + case 20:{ + Unit* Mercenary = FindCreature(MOB_MERCENARY, 99); + if(Mercenary) + { + ((Creature*)Mercenary)->Yell(SAY_MERCENARY_4, LANG_UNIVERSAL, NULL); + Mercenary->Attack(m_creature, true); + } + }break; + case 21: DoSay(SAY_PROGRESS_5, LANG_UNIVERSAL, NULL); + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); break; + case 28: DoSay(SAY_PROGRESS_6, LANG_UNIVERSAL, NULL); break; + case 29: DoSay(SAY_PROGRESS_7, LANG_UNIVERSAL, NULL); break; + case 30: DoSay(SAY_PROGRESS_8, LANG_UNIVERSAL, NULL); break; + case 31: m_creature->SummonCreature(NPC_PILOT, 1088.77, -2985.39, 91.84, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 300000); + m_creature->setDeathState(JUST_DIED); + if (player && player->GetTypeId() == TYPEID_PLAYER) + ((Player*)player)->GroupEventHappens(QUEST_ESCAPE, m_creature); + break; + case 32: {Unit* Pilot = FindCreature(NPC_PILOT, 30); + if(Pilot) + ((Creature*)Pilot)->Say(SAY_PILOT_9, LANG_UNIVERSAL, NULL);}break; + case 33:{ Unit* Pilot = FindCreature(NPC_PILOT, 30); + if(Pilot) + ((Creature*)Pilot)->Say(SAY_PILOT_10, LANG_UNIVERSAL, NULL);} break; + } + } + + void Reset() + { + m_creature->setDeathState(ALIVE); + } + + void Aggro(Unit* who){} + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + if (player) + ((Player*)player)->FailQuest(QUEST_ESCAPE); + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } +}; + +bool QuestAccept_npc_wizzlecrank_shredder(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == QUEST_ESCAPE) + { + ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID()); + creature->setFaction(35); + } + return true; +} + +CreatureAI* GetAI_npc_wizzlecrank_shredderAI(Creature *_Creature) +{ + npc_wizzlecrank_shredderAI* thisAI = new npc_wizzlecrank_shredderAI(_Creature); + + thisAI->AddWaypoint(0, 1109.15, -3104.11, 82.41, 6000);//say1 spw + thisAI->AddWaypoint(1, 1105.39, -3102.86, 82.74, 2000);//say2 crazy running + thisAI->AddWaypoint(2, 1104.97, -3108.52, 83.10, 1000); + thisAI->AddWaypoint(3, 1110.01, -3110.48, 82.81, 1000); + thisAI->AddWaypoint(4, 1111.72, -3103.03, 82.21, 1000); + thisAI->AddWaypoint(5, 1106.98, -3099.44, 82.18, 1000); + thisAI->AddWaypoint(6, 1103.74, -3103.29, 83.05, 1000); + thisAI->AddWaypoint(7, 1112.55, -3106.56, 82.31, 1000); + thisAI->AddWaypoint(8, 1108.12, -3111.04, 82.99, 1000); + thisAI->AddWaypoint(9, 1109.32, -3100.39, 82.08, 1000); + thisAI->AddWaypoint(10, 1109.32, -3100.39, 82.08, 6000);//end of crazy running + thisAI->AddWaypoint(11, 1098.92, -3095.14, 82.97); + thisAI->AddWaypoint(12, 1100.94, -3082.60, 82.83); + thisAI->AddWaypoint(13, 1101.12, -3068.83, 82.53); + thisAI->AddWaypoint(14, 1096.97, -3051,99, 82.50); + thisAI->AddWaypoint(15, 1094.06, -3036.79, 82.70); + thisAI->AddWaypoint(16, 1098.22, -3027.84, 83.79); + thisAI->AddWaypoint(17, 1109.51, -3015.92, 85.73); + thisAI->AddWaypoint(18, 1119.87, -3007.21, 87.08); + thisAI->AddWaypoint(19, 1130.23, -3002.49, 91.27, 5000);//twice + thisAI->AddWaypoint(20, 1130.23, -3002.49, 91.27, 3000);//mercenary + thisAI->AddWaypoint(21, 1130.23, -3002.49, 91.27, 4000);//say + thisAI->AddWaypoint(22, 1129.73, -2985.89, 92.46);//crazy running + thisAI->AddWaypoint(23, 1124.10, -2983.29, 92.81); + thisAI->AddWaypoint(24, 1111.74, -2992.38, 91.59); + thisAI->AddWaypoint(25, 1111.06, -2976.54, 91.81); + thisAI->AddWaypoint(26, 1099.91, -2991.17, 91.67); + thisAI->AddWaypoint(27, 1096.32, -2981.55, 91.73); + thisAI->AddWaypoint(28, 1091.28, -2985.82, 91.74, 4000);//6 + thisAI->AddWaypoint(29, 1091.28, -2985.82, 91.74, 3000);//7 + thisAI->AddWaypoint(30, 1091.28, -2985.82, 91.74, 7000);//8 + thisAI->AddWaypoint(31, 1091.28, -2985.82, 91.74, 3000);//justdied summon creature + thisAI->AddWaypoint(32, 1091.28, -2985.82, 91.74, 2000);//9 + thisAI->AddWaypoint(33, 1091.28, -2985.82, 91.74, 7000);//10 + + return (CreatureAI*)thisAI; +} + void AddSC_the_barrens() { Script *newscript; @@ -387,4 +533,10 @@ void AddSC_the_barrens() newscript->Name="npc_twiggy_flathead"; newscript->GetAI = &GetAI_npc_twiggy_flathead; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_wizzlecrank_shredder"; + newscript->GetAI = &GetAI_npc_wizzlecrank_shredderAI; + newscript->pQuestAccept = &QuestAccept_npc_wizzlecrank_shredder; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp index f26209d4340..ae035795193 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp @@ -363,9 +363,10 @@ static Animation DemonTransformation[]= /************************************** Illidan's AI ***************************************/ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI { - boss_illidan_stormrageAI(Creature* c) : ScriptedAI(c) + boss_illidan_stormrageAI(Creature* c) : ScriptedAI(c), Summons(m_creature) { pInstance = ((ScriptedInstance*)c->GetInstanceData()); + m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); Reset(); SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_SHADOWFIEND_PASSIVE); @@ -390,6 +391,8 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI uint64 FlameGUID[2]; uint64 GlaiveGUID[2]; + SummonList Summons; + void Reset(); void JustSummoned(Creature* summon); @@ -402,12 +405,13 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI if(summon->GetGUID() == FlameGUID[i]) FlameGUID[i] = 0; - if(!FlameGUID[0] && !FlameGUID[1]) + if(!FlameGUID[0] && !FlameGUID[1] && Phase != PHASE_NULL) { m_creature->InterruptNonMeleeSpells(true); EnterPhase(PHASE_FLIGHT_SEQUENCE); } } + Summons.Despawn(summon); } void MovementInform(uint32 MovementType, uint32 Data) @@ -899,7 +903,7 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI GlaiveGUID = 0; } - void Aggro(Unit *who) {} + void Aggro(Unit *who) {DoZoneInCombat();} void ChargeCheck() { @@ -1805,23 +1809,6 @@ void boss_illidan_stormrageAI::Reset() if(pInstance) pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, NOT_STARTED); - for(uint8 i = 0; i < 2; i++) - { - if(FlameGUID[i]) - { - if(GETUNIT(Flame, FlameGUID[i])) - Flame->setDeathState(JUST_DIED); - FlameGUID[i] = 0; - } - - if(GlaiveGUID[i]) - { - if(GETUNIT(Glaive, GlaiveGUID[i])) - Glaive->setDeathState(JUST_DIED); - GlaiveGUID[i] = 0; - } - } - if(AkamaGUID) { if(GETCRE(Akama, AkamaGUID)) @@ -1838,15 +1825,11 @@ void boss_illidan_stormrageAI::Reset() AkamaGUID = 0; } - if(MaievGUID) + MaievGUID = 0; + for(int i = 0; i < 2; ++i) { - GETUNIT(Maiev, MaievGUID); - if(Maiev && Maiev->isAlive()) - { - Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); - Maiev->setDeathState(JUST_DIED); - } - MaievGUID = 0; + FlameGUID[i] = 0; + GlaiveGUID[i] = 0; } Phase = PHASE_NULL; @@ -1865,17 +1848,23 @@ void boss_illidan_stormrageAI::Reset() m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT); - - m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); m_creature->setActive(false); + Summons.DespawnAll(); } void boss_illidan_stormrageAI::JustSummoned(Creature* summon) { + Summons.Summon(summon); switch(summon->GetEntry()) { case PARASITIC_SHADOWFIEND: { + if(Phase == PHASE_TALK_SEQUENCE) + { + summon->SetVisibility(VISIBILITY_OFF); + summon->setDeathState(JUST_DIED); + return; + } Unit *target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0, 999, true); if(!target || target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0) || target->HasAura(SPELL_PARASITIC_SHADOWFIEND2, 0)) @@ -1897,6 +1886,10 @@ void boss_illidan_stormrageAI::JustSummoned(Creature* summon) ((boss_maievAI*)summon->AI())->GetIllidanGUID(m_creature->GetGUID()); ((boss_maievAI*)summon->AI())->EnterPhase(PHASE_TALK_SEQUENCE); }break; + case FLAME_OF_AZZINOTH: + { + summon->AI()->AttackStart(summon->SelectNearestTarget(999)); + }break; default: break; } @@ -1948,6 +1941,7 @@ void boss_illidan_stormrageAI::HandleTalkSequence() }break; case 15: DoCast(m_creature, SPELL_DEATH); // Animate his kneeling + stun him + Summons.DespawnAll(); break; case 17: if(GETUNIT(Akama, AkamaGUID)) @@ -2037,10 +2031,8 @@ void boss_illidan_stormrageAI::SummonFlamesOfAzzinoth() { Flame->setFaction(m_creature->getFaction()); // Just in case the database has it as a different faction Flame->SetMeleeDamageSchool(SPELL_SCHOOL_FIRE); - Flame->AI()->AttackStart(m_creature->getVictim()); // Attack our target! FlameGUID[i] = Flame->GetGUID(); // Record GUID in order to check if they're dead later on to move to the next phase ((flame_of_azzinothAI*)Flame->AI())->SetGlaiveGUID(GlaiveGUID[i]); - DoZoneInCombat(Flame); Glaive->CastSpell(Flame, SPELL_AZZINOTH_CHANNEL, false); // Glaives do some random Beam type channel on it. } } diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp index 6c642ea41a3..ea7fc3cbd1e 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp @@ -193,6 +193,9 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI { if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true)) { + if(!target) + target = m_creature->getVictim(); + DoCast(target, SPELL_VOLCANIC_SUMMON); DoScriptText(EMOTE_GROUND_CRACK, m_creature); SummonVolcanoTimer = 10000; @@ -226,6 +229,55 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI } }; +struct TRINITY_DLL_DECL npc_volcanoAI : public ScriptedAI +{ + npc_volcanoAI(Creature *c) : ScriptedAI(c) + { + pInstance = ((ScriptedInstance*)c->GetInstanceData()); + Reset(); + } + + ScriptedInstance *pInstance; + + uint32 CheckTimer; + bool Eruption; + + void Reset() + { + CheckTimer = 1500; + Eruption = false; + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void Aggro(Unit *who) {} + + void MoveInLineOfSight(Unit *who) + { + return; // paralyze the npc + } + + void UpdateAI(const uint32 diff) + { + if(CheckTimer < diff) + { + uint64 SupremusGUID = pInstance->GetData64(DATA_SUPREMUS); + Creature* Supremus = ((Creature*)Unit::GetUnit((*m_creature), SupremusGUID)); + if(!Eruption && !((boss_supremusAI*)Supremus->AI())->Phase1) + { + Eruption = true; + DoCast(m_creature, SPELL_VOLCANIC_ERUPTION); + } + else if(Eruption && ((boss_supremusAI*)Supremus->AI())->Phase1) + { + m_creature->RemoveAura(SPELL_VOLCANIC_ERUPTION, 0); + } + CheckTimer = 1500; + }else CheckTimer -= diff; + } +}; + CreatureAI* GetAI_boss_supremus(Creature *_Creature) { return new boss_supremusAI (_Creature); @@ -236,6 +288,11 @@ CreatureAI* GetAI_molten_flame(Creature *_Creature) return new molten_flameAI (_Creature); } +CreatureAI* GetAI_npc_volcano(Creature *_Creature) +{ + return new npc_volcanoAI (_Creature); +} + void AddSC_boss_supremus() { Script *newscript; @@ -248,4 +305,9 @@ void AddSC_boss_supremus() newscript->Name="molten_flame"; newscript->GetAI = &GetAI_molten_flame; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_volcano"; + newscript->GetAI = &GetAI_npc_volcano; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp b/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp index dd4f0b37f66..978c1522f48 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp @@ -290,59 +290,59 @@ struct TRINITY_DLL_DECL mob_illidari_councilAI : public ScriptedAI if(!EventBegun) return; if(EndEventTimer) - { - if(EndEventTimer <= diff) { - if(DeathCount > 3) + if(EndEventTimer <= diff) { - if(pInstance) + if(DeathCount > 3) { - if(Creature* VoiceTrigger = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE)))) - VoiceTrigger->DealDamage(VoiceTrigger, VoiceTrigger->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - pInstance->SetData(DATA_ILLIDARICOUNCILEVENT, DONE); + if(pInstance) + { + if(Creature* VoiceTrigger = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE)))) + VoiceTrigger->DealDamage(VoiceTrigger, VoiceTrigger->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + pInstance->SetData(DATA_ILLIDARICOUNCILEVENT, DONE); + } + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + return; } - m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - return; - } - Creature* pMember = ((Creature*)Unit::GetUnit(*m_creature, Council[DeathCount])); - if(pMember && pMember->isAlive()) - pMember->DealDamage(pMember, pMember->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - ++DeathCount; - EndEventTimer = 1500; - }else EndEventTimer -= diff; - } + Creature* pMember = ((Creature*)Unit::GetUnit(*m_creature, Council[DeathCount])); + if(pMember && pMember->isAlive()) + pMember->DealDamage(pMember, pMember->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + ++DeathCount; + EndEventTimer = 1500; + }else EndEventTimer -= diff; + } if(CheckTimer) - { - if(CheckTimer <= diff) { - uint8 EvadeCheck = 0; - for(uint8 i = 0; i < 4; ++i) + if(CheckTimer <= diff) { - if(Council[i]) + uint8 EvadeCheck = 0; + for(uint8 i = 0; i < 4; ++i) { - if(Creature* Member = ((Creature*)Unit::GetUnit((*m_creature), Council[i]))) + if(Council[i]) { - // This is the evade/death check. - if(Member->isAlive() && !Member->SelectHostilTarget()) - ++EvadeCheck; //If all members evade, we reset so that players can properly reset the event - else if(!Member->isAlive()) // If even one member dies, kill the rest, set instance data, and kill self. + if(Creature* Member = ((Creature*)Unit::GetUnit((*m_creature), Council[i]))) { - EndEventTimer = 1000; - CheckTimer = 0; - return; + // This is the evade/death check. + if(Member->isAlive() && !Member->SelectHostilTarget()) + ++EvadeCheck; //If all members evade, we reset so that players can properly reset the event + else if(!Member->isAlive()) // If even one member dies, kill the rest, set instance data, and kill self. + { + EndEventTimer = 1000; + CheckTimer = 0; + return; + } } } } - } - if(EvadeCheck > 3) - Reset(); + if(EvadeCheck > 3) + Reset(); - CheckTimer = 2000; - }else CheckTimer -= diff; - } + CheckTimer = 2000; + }else CheckTimer -= diff; + } } }; @@ -385,6 +385,20 @@ struct TRINITY_DLL_DECL boss_illidari_councilAI : public ScriptedAI LoadGUIDs(); } + void EnterEvadeMode() + { + for(uint8 i = 0; i < 4; ++i) + { + if(Unit* pUnit = Unit::GetUnit(*m_creature, Council[i])) + if(pUnit != m_creature && pUnit->getVictim()) + { + AttackStart(pUnit->getVictim()); + return; + } + } + ScriptedAI::EnterEvadeMode(); + } + void DamageTaken(Unit* done_by, uint32 &damage) { if(done_by == m_creature) diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp index d4b2b7a7f09..b8864fe6506 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp @@ -211,16 +211,20 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI if(SpoutAnimTimer<diff) { DoCast(m_creature,SPELL_SPOUT_ANIM,true); - SpoutAnimTimer = 1000; - }else SpoutAnimTimer-=diff; - - std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); - for(std::list<HostilReference*>::iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) - { - Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); - if(target && target->GetTypeId() == TYPEID_PLAYER && m_creature->HasInArc((double)diff/20000*(double)M_PI*2,target) && m_creature->GetDistance(target) <= SPOUT_DIST && !target->IsInWater()) - DoCast(target,SPELL_SPOUT,true);//only knock back palyers in arc, in 100yards, not in water - } + SpoutAnimTimer = 1000; + }else SpoutAnimTimer-=diff; + + Map *map = m_creature->GetMap(); + if (map->IsDungeon() && pInstance->GetData(DATA_THELURKERBELOWEVENT) == IN_PROGRESS) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + Player *target = i->getSource(); + if(target->isAlive() && m_creature->HasInArc((double)diff/20000*(double)M_PI*2,target) && m_creature->GetDistance(target) <= SPOUT_DIST && !target->IsInWater()) + DoCast(target,SPELL_SPOUT,true);//only knock back palyers in arc, in 100yards, not in water + } + } } void StartRotate(Unit* victim) diff --git a/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp b/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp index ca9414a3077..903787adebe 100644 --- a/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp +++ b/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Isle_of_Queldanas SD%Complete: 100 -SDComment: Quest support: 11524, 11525, 11532, 11533, 11542, 11543 +SDComment: Quest support: 11524, 11525, 11532, 11533, 11542, 11543, 11541 SDCategory: Isle Of Quel'Danas EndScriptData */ @@ -25,6 +25,7 @@ EndScriptData */ npc_ayren_cloudbreaker npc_converted_sentry npc_unrestrained_dragonhawk +npc_greengill_slave EndContentData */ #include "precompiled.h" @@ -132,6 +133,63 @@ bool GossipSelect_npc_unrestrained_dragonhawk(Player *player, Creature *_Creatur return true; } +/*###### +## npc_greengill_slave +######*/ + +#define ENRAGE 45111 +#define ORB 45109 +#define QUESTG 11541 +#define DM 25060 + +struct TRINITY_DLL_DECL npc_greengill_slaveAI : public ScriptedAI +{ + npc_greengill_slaveAI(Creature* c) : ScriptedAI(c) {Reset();} + + uint64 PlayerGUID; + + void Aggro(Unit* who){} + + void Reset() + { + PlayerGUID = 0; + } + + void SpellHit(Unit* caster, const SpellEntry* spell) + { + if(!caster) + return; + + if(caster->GetTypeId() == TYPEID_PLAYER && spell->Id == ORB && !m_creature->HasAura(ENRAGE, 0)) + { + PlayerGUID = caster->GetGUID(); + if(PlayerGUID) + { + Unit* plr = Unit::GetUnit((*m_creature), PlayerGUID); + if(plr && ((Player*)plr)->GetQuestStatus(QUESTG) == QUEST_STATUS_INCOMPLETE) + ((Player*)plr)->KilledMonster(25086, m_creature->GetGUID()); + } + DoCast(m_creature, ENRAGE); + Unit* Myrmidon = FindCreature(DM, 70); + if(Myrmidon) + { + m_creature->AddThreat(Myrmidon, 100000.0f); + AttackStart(Myrmidon); + } + } + } + + void UpdateAI(const uint32 diff) + { + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_greengill_slaveAI(Creature* _Creature) +{ + return new npc_greengill_slaveAI(_Creature); +} + void AddSC_isle_of_queldanas() { Script *newscript; @@ -152,4 +210,9 @@ void AddSC_isle_of_queldanas() newscript->pGossipHello = &GossipHello_npc_unrestrained_dragonhawk; newscript->pGossipSelect = &GossipSelect_npc_unrestrained_dragonhawk; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_greengill_slave"; + newscript->GetAI = &GetAI_npc_greengill_slaveAI; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp index a00bbae283c..8255893763e 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp @@ -272,7 +272,8 @@ struct TRINITY_DLL_DECL boss_terestianAI : public ScriptedAI if(SummonKilrek && Kilrek) { Kilrek->Respawn(); - Kilrek->AI()->AttackStart(m_creature->getVictim()); + if(Kilrek->AI()) + Kilrek->AI()->AttackStart(m_creature->getVictim()); SummonKilrek = false; } diff --git a/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp b/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp index 44de5eab777..72125a8e2d9 100644 --- a/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp +++ b/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp @@ -17,12 +17,13 @@ /* ScriptData SDName: Mulgore SD%Complete: 100 -SDComment: Skorn Whitecloud: Just a story if not rewarded for quest +SDComment: Support for quest: 11129 SDCategory: Mulgore EndScriptData */ /* ContentData npc_skorn_whitecloud +npc_kyle_frenzied EndContentData */ #include "precompiled.h" @@ -52,13 +53,121 @@ bool GossipSelect_npc_skorn_whitecloud(Player *player, Creature *_Creature, uint return true; } +/*##### +# npc_kyle_frenzied +######*/ + +struct TRINITY_DLL_DECL npc_kyle_frenziedAI : public ScriptedAI +{ + npc_kyle_frenziedAI(Creature *c) : ScriptedAI(c) {Reset();} + + int STATE; + uint32 wait; + uint64 player; + + void Reset() + { + STATE = 0; + m_creature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); + m_creature->GetMotionMaster()->Initialize(); + } + void Aggro(Unit* who){} + + void SpellHit(Unit *caster, const SpellEntry* spell) + { // we can feed him without any quest + if(spell->Id == 42222 && caster->GetTypeId() == TYPEID_PLAYER && ((Player*)caster)->GetTeam() == HORDE) + { + STATE = 1; + player = caster->GetGUID(); + float x, y, z, z2; + caster->GetPosition(x, y, z); + x = x + 3.7*cos(caster->GetOrientation()); + y = y + 3.7*sin(caster->GetOrientation()); + z2 = m_creature->GetBaseMap()->GetHeight(x,y,z,false); + z = (z2 <= INVALID_HEIGHT) ? z : z2; + m_creature->SetDefaultMovementType(IDLE_MOTION_TYPE); //there is other way to stop waypoint movement? + m_creature->GetMotionMaster()->Initialize(); + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + m_creature->GetMotionMaster()->MovePoint(0,x, y, z); + } + } + + void MovementInform(uint32 type, uint32 id) + { + if(type == POINT_MOTION_TYPE) + { + switch(STATE) + { + case 1: + { + Unit *plr = Unit::GetUnit((*m_creature),player); + if(plr) + m_creature->SetOrientation(m_creature->GetAngle(plr)); + m_creature->HandleEmoteCommand(EMOTE_STATE_USESTANDING); //eat + WorldPacket data; + m_creature->BuildHeartBeatMsg(&data); + m_creature->SendMessageToSet(&data,true); + wait = 3000; + STATE = 2; + break; + } + case 4: + m_creature->setDeathState(JUST_DIED); + m_creature->Respawn(); + break; + } + } + } + + void UpdateAI(const uint32 diff) + { + if (!STATE || STATE == 4) + return; + if(wait < diff) + { + switch(STATE) + { + case 2: + STATE = 3; wait = 7000; + m_creature->UpdateEntry(23622,HORDE); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_DANCE); + break; + case 3: + STATE = 4; //go home + Unit *plr = Unit::GetUnit((*m_creature),player); + if(plr && ((Player*)plr)->GetQuestStatus(11129) == QUEST_STATUS_INCOMPLETE) + ((Player*)plr)->CompleteQuest(11129); + float x, y, z, z2, angle; + angle = m_creature->GetAngle(-2146, -430); + m_creature->GetPosition(x,y,z); + x = x + 40*cos(angle); + y = y + 40*sin(angle); + z2 = m_creature->GetBaseMap()->GetHeight(x,y,MAX_HEIGHT,false); + z = (z2 <= INVALID_HEIGHT) ? z : z2; + m_creature->GetMotionMaster()->MovePoint(0,x,y,z); + break; + } + }else wait -= diff; + } +}; + +CreatureAI* GetAI_npc_kyle_frenzied(Creature *_Creature) +{ + return new npc_kyle_frenziedAI (_Creature); +} + void AddSC_mulgore() { Script *newscript; newscript = new Script; newscript->Name="npc_skorn_whitecloud"; - newscript->pGossipHello = &GossipHello_npc_skorn_whitecloud; - newscript->pGossipSelect = &GossipSelect_npc_skorn_whitecloud; + newscript->pGossipHello = &GossipHello_npc_skorn_whitecloud; + newscript->pGossipSelect = &GossipSelect_npc_skorn_whitecloud; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_kyle_frenzied"; + newscript->GetAI = &GetAI_npc_kyle_frenzied; newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp index b7370dfd8eb..839c6ab1fe8 100644 --- a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp +++ b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Shattrath_City SD%Complete: 100 -SDComment: Quest support: 10004, 10009, 10211. Flask vendors, Teleport to Caverns of Time +SDComment: Quest support: 10004, 10009, 10211, 10231. Flask vendors, Teleport to Caverns of Time SDCategory: Shattrath City EndScriptData */ @@ -27,6 +27,9 @@ npc_salsalabim npc_shattrathflaskvendors npc_zephyr npc_kservant +npc_dirty_larry +npc_ishanah +npc_khadgar EndContentData */ #include "precompiled.h" @@ -406,6 +409,269 @@ CreatureAI* GetAI_npc_kservantAI(Creature *_Creature) return (CreatureAI*)kservantAI; } +/*###### +# npc_dirty_larry +######*/ + +#define GOSSIP_BOOK "Ezekiel said that you might have a certain book..." +#define SAY_1 "Time to teach you a lesson in manners, little boy!" +#define SAY_2 "Now I'm gonna give you to the count of '3' to get out of here before I sick the dogs on you." +#define SAY_3 "1..." +#define SAY_4 "2..." +#define SAY_5 "Time to meet your maker!" +#define SAY_GIVEUP "Alright, we give up! Don't hurt us!" + +#define QUEST_WBI 10231 +#define NPC_CREEPJACK 19726 +#define NPC_MALONE 19725 + +struct TRINITY_DLL_DECL npc_dirty_larryAI : public ScriptedAI +{ + npc_dirty_larryAI(Creature* c) : ScriptedAI(c) {Reset();} + + bool Event; + bool Attack; + bool Done; + + uint64 PlayerGUID; + + uint32 SayTimer; + uint32 Step; + + void Reset() + { + Event = false; + Attack = false; + Done = false; + + PlayerGUID = 0; + SayTimer = 0; + Step = 0; + + m_creature->setFaction(1194); + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20); + if(Creepjack) + { + ((Creature*)Creepjack)->AI()->EnterEvadeMode(); + Creepjack->setFaction(1194); + } + Unit* Malone = FindCreature(NPC_MALONE, 20); + if(Malone) + { + ((Creature*)Malone)->AI()->EnterEvadeMode(); + Malone->setFaction(1194); + } + } + + uint32 NextStep(uint32 Step) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + switch(Step) + { + case 0:{ m_creature->SetInFront(player); + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20); + if(Creepjack) + Creepjack->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Unit* Malone = FindCreature(NPC_MALONE, 20); + if(Malone) + Malone->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }return 2000; + case 1: DoSay(SAY_1, LANG_UNIVERSAL, player); return 3000; + case 2: DoSay(SAY_2, LANG_UNIVERSAL, player, true); return 5000; + case 3: DoSay(SAY_3, LANG_UNIVERSAL, player); return 2000; + case 4: DoSay(SAY_4, LANG_UNIVERSAL, player); return 2000; + case 5: DoSay(SAY_5, LANG_UNIVERSAL, player); return 2000; + case 6: Attack = true; return 2000; + default: return 0; + } + } + + void Aggro(Unit* who){} + + void UpdateAI(const uint32 diff) + { + if(SayTimer < diff) + { + if(Event) + SayTimer = NextStep(Step++); + }else SayTimer -= diff; + + if(Attack) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + m_creature->setFaction(14); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if(player) + { + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20); + if(Creepjack) + { + Creepjack->Attack(player, true); + Creepjack->setFaction(14); + Creepjack->GetMotionMaster()->MoveChase(player); + } + Unit* Malone = FindCreature(NPC_MALONE, 20); + if(Malone) + { + Malone->Attack(player, true); + Malone->setFaction(14); + Malone->GetMotionMaster()->MoveChase(player); + } + m_creature->SetInCombatWith(player); + DoStartMovement(player); + AttackStart(player); + } + Attack = false; + } + + if((m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1 && !Done) + { + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20); + if(Creepjack) + { + ((Creature*)Creepjack)->AI()->EnterEvadeMode(); + Creepjack->setFaction(1194); + } + Unit* Malone = FindCreature(NPC_MALONE, 20); + if(Malone) + { + ((Creature*)Malone)->AI()->EnterEvadeMode(); + Malone->setFaction(1194); + } + m_creature->setFaction(1194); + Done = true; + DoSay(SAY_GIVEUP, LANG_UNIVERSAL, NULL); + m_creature->DeleteThreatList(); + m_creature->CombatStop(); + m_creature->GetMotionMaster()->MoveTargetedHome(); + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + if(player) + ((Player*)player)->GroupEventHappens(QUEST_WBI, m_creature); + } + DoMeleeAttackIfReady(); + } +}; + +bool GossipHello_npc_dirty_larry(Player *player, Creature *creature) +{ + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if(player->GetQuestStatus(QUEST_WBI) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(0, GOSSIP_BOOK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(creature->GetNpcTextId(), creature->GetGUID()); + return true; +} + +bool GossipSelect_npc_dirty_larry(Player *player, Creature *creature, uint32 sender, uint32 action ) +{ + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + ((npc_dirty_larryAI*)creature->AI())->Event = true; + ((npc_dirty_larryAI*)creature->AI())->PlayerGUID = player->GetGUID(); + player->CLOSE_GOSSIP_MENU(); + } + + return true; +} + +CreatureAI* GetAI_npc_dirty_larryAI(Creature *_Creature) +{ + return new npc_dirty_larryAI (_Creature); +} + +/*###### +# npc_ishanah +######*/ + +#define ISANAH_GOSSIP_1 "Who are the Sha'tar?" +#define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?" + +bool GossipHello_npc_ishanah(Player *player, Creature *_Creature) +{ + if (_Creature->isQuestGiver()) + player->PrepareQuestMenu(_Creature->GetGUID()); + + player->ADD_GOSSIP_ITEM(0, ISANAH_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(0, ISANAH_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_ishanah(Player *player, Creature *_Creature, uint32 sender, uint32 action) +{ + if(action == GOSSIP_ACTION_INFO_DEF+1) + player->SEND_GOSSIP_MENU(9458, _Creature->GetGUID()); + else if(action == GOSSIP_ACTION_INFO_DEF+2) + player->SEND_GOSSIP_MENU(9459, _Creature->GetGUID()); + + return true; +} + +/*###### +# npc_khadgar +######*/ + +#define KHADGAR_GOSSIP_1 "I've heard your name spoken only in whispers, mage. Who are you?" +#define KHADGAR_GOSSIP_2 "Go on, please." +#define KHADGAR_GOSSIP_3 "I see." //6th too this +#define KHADGAR_GOSSIP_4 "What did you do then?" +#define KHADGAR_GOSSIP_5 "What happened next?" +#define KHADGAR_GOSSIP_7 "There was something else I wanted to ask you." + +bool GossipHello_npc_khadgar(Player *player, Creature *creature) +{ + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if(!player->hasQuest(10211)) + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_khadgar(Player *player, Creature *creature, uint32 sender, uint32 action) +{ + switch(action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(9876, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(9877, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(9878, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(9879, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(9880, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); + player->SEND_GOSSIP_MENU(9881, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+7: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); + break; + } + return true; +} + void AddSC_shattrath_city() { Script *newscript; @@ -434,8 +700,27 @@ void AddSC_shattrath_city() newscript->pGossipSelect = &GossipSelect_npc_zephyr; newscript->RegisterSelf(); - newscript = new Script; + newscript = new Script; newscript->Name="npc_kservant"; newscript->GetAI = &GetAI_npc_kservantAI; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_dirty_larry"; + newscript->GetAI = &GetAI_npc_dirty_larryAI; + newscript->pGossipHello = &GossipHello_npc_dirty_larry; + newscript->pGossipSelect = &GossipSelect_npc_dirty_larry; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_ishanah"; + newscript->pGossipHello = &GossipHello_npc_ishanah; + newscript->pGossipSelect = &GossipSelect_npc_ishanah; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_khadgar"; + newscript->pGossipHello = &GossipHello_npc_khadgar; + newscript->pGossipSelect = &GossipSelect_npc_khadgar; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp index 3eaaf773629..433cb691f2e 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp @@ -111,11 +111,12 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI m_creature->SetDisplayId(m_creature->GetNativeDisplayId()); m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); - m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); - m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); + //m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); + //m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->setActive(false); } void Aggro(Unit *who) @@ -125,6 +126,7 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); // after enterevademode will be set walk movement DoZoneInCombat(); + m_creature->setActive(true); } void JustDied(Unit *victim) @@ -136,13 +138,8 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI void JustSummoned(Creature *summon) { if(summon->GetEntry() == CREATURE_EMBER_OF_ALAR) - { if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) - { summon->AI()->AttackStart(target); - summon->SetInCombatWith(target); - } - } } void MoveInLineOfSight(Unit *who) {} @@ -405,7 +402,7 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI else { Unit *target = NULL; - if(Phase1 && (target = m_creature->SelectNearbyTarget()) && m_creature->IsHostileTo(target)) // core bug, 1620 faction bugged + if(Phase1 && (target = m_creature->SelectNearestTarget(5))) m_creature->AI()->AttackStart(target); else { diff --git a/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp b/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp index fdce0029e9d..6f3ca0149bb 100644 --- a/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp +++ b/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Zangarmarsh SD%Complete: 100 -SDComment: Quest support: 9785, 9803, 10009. Mark Of ... buffs. +SDComment: Quest support: 9785, 9803, 10009, 9752. Mark Of ... buffs. SDCategory: Zangarmarsh EndScriptData */ @@ -26,9 +26,11 @@ npcs_ashyen_and_keleth npc_cooshcoosh npc_elder_kuruti npc_mortog_steamhead +npc_kayra_longmane EndContentData */ #include "precompiled.h" +#include "../../npc/npc_escortAI.h" /*###### ## npcs_ashyen_and_keleth @@ -250,6 +252,126 @@ bool GossipSelect_npc_mortog_steamhead(Player *player, Creature *_Creature, uint } /*###### +## npc_kayra_longmane +######*/ + +#define SAY_PROGRESS_1 "Is the way clear? Let's get out while we can, $N." +#define SAY_PROGRESS_2 "Looks like we won't get away so easy. Get ready!" +#define SAY_PROGRESS_3 "Let's keep moving. We're not safe here!" +#define SAY_PROGRESS_4 "Look out, $N! Enemies ahead!" +#define SAY_PROGRESS_5 "We're almost to the refuge! Let's go." +#define SAY_PROGRESS_6 "I can see my fellow druids from here. Thank you, $N. I'm sure Ysiel will reward you for your actions!" + +#define QUEST_EFU 9752 +#define MOB_AMBUSH 18042 + +struct TRINITY_DLL_DECL npc_kayra_longmaneAI : public npc_escortAI +{ + npc_kayra_longmaneAI(Creature* c) : npc_escortAI(c) {Reset();} + + bool Completed; + + void Reset() + { + Completed = false; + } + + void Aggro(Unit* who){} + + void JustSummoned(Creature *summoned) + { + summoned->AI()->AttackStart(m_creature); + summoned->setFaction(14); + } + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + switch(i) + { + case 0: DoSay(SAY_PROGRESS_1, LANG_UNIVERSAL, player); break; + case 5: DoSay(SAY_PROGRESS_2, LANG_UNIVERSAL, player); + m_creature->SummonCreature(MOB_AMBUSH, -922.24, 5357.98, 17.93, 5.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + m_creature->SummonCreature(MOB_AMBUSH, -922.24, 5357.98, 17.93, 5.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + break; + case 6: DoSay(SAY_PROGRESS_3, LANG_UNIVERSAL, player); + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + break; + case 18: DoSay(SAY_PROGRESS_4, LANG_UNIVERSAL, player); + m_creature->SummonCreature(MOB_AMBUSH, -671.86, 5379.81, 22.12, 5.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + m_creature->SummonCreature(MOB_AMBUSH, -671.86, 5379.81, 22.12, 5.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + break; + case 19: m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + DoSay(SAY_PROGRESS_5, LANG_UNIVERSAL, player); break; + case 26: DoSay(SAY_PROGRESS_6, LANG_UNIVERSAL, player); + if(player) + ((Player*)player)->GroupEventHappens(QUEST_EFU, m_creature); + break; + } + } + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + if (player && !Completed) + ((Player*)player)->FailQuest(QUEST_EFU); + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } +}; + +bool QuestAccept_npc_kayra_longmane(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == QUEST_EFU) + { + ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID()); + creature->setFaction(775); + } + return true; +} + +CreatureAI* GetAI_npc_kayra_longmaneAI(Creature* _Creature) +{ + npc_kayra_longmaneAI* thisAI = new npc_kayra_longmaneAI(_Creature); + + thisAI->AddWaypoint(0, -931.88, 5283.56, 23.98);//SAY_PROGRESS_1 + thisAI->AddWaypoint(1, -930.52, 5287.57, 23.82); + thisAI->AddWaypoint(2, -924.98, 5297.94, 17.78); + thisAI->AddWaypoint(3, -928.83, 5316.07, 18.18); + thisAI->AddWaypoint(4, -930.07, 5323.10, 18.63); + thisAI->AddWaypoint(5, -926.58, 5331.24, 18.74, 6000);//SAY_PROGRESS_2 + thisAI->AddWaypoint(6, -926.58, 5331.24, 18.74, 3000);//SAY_PROGRESS_3 Run to the hills! + thisAI->AddWaypoint(7, -931.24, 5358.89, 18.14); + thisAI->AddWaypoint(8, -934.43, 5370.20, 22.41); + thisAI->AddWaypoint(9, -943.01, 5400.55, 22.74); + thisAI->AddWaypoint(10, -929.62, 5417.98, 23.07); + thisAI->AddWaypoint(11, -901.92, 5420.38, 24.19); + thisAI->AddWaypoint(12, -859.03, 5415.36, 23.64); + thisAI->AddWaypoint(13, -808.94, 5401.93, 23.11); + thisAI->AddWaypoint(14, -772.74, 5390.53, 22.97); + thisAI->AddWaypoint(15, -749.71, 5385.39, 22.75); + thisAI->AddWaypoint(16, -721.23, 5380.38, 22.47); + thisAI->AddWaypoint(17, -687.96, 5379.08, 22.16); + thisAI->AddWaypoint(18, -680.87, 5378.95, 21.99, 6000);//SAY_PROGRESS_4 Summon Ambush + thisAI->AddWaypoint(19, -680.87, 5378.95, 21.99, 6000);//SAY_PROGRESS_5 + thisAI->AddWaypoint(20, -636.14, 5385.25, 22.20); + thisAI->AddWaypoint(21, -602.94, 5411.36, 21.48); + thisAI->AddWaypoint(22, -566.86, 5421.87, 21.25); + thisAI->AddWaypoint(23, -547.27, 5427.87, 21.10); + thisAI->AddWaypoint(24, -520.59, 5444.83, 21.15); + thisAI->AddWaypoint(25, -488.45, 5447.83, 22.38); + thisAI->AddWaypoint(26, -449.65, 5463.78, 21.77, 11000);//SAY_PROGRESS_6 + + return (CreatureAI*)thisAI; +} +/*###### ## AddSC ######*/ @@ -280,4 +402,10 @@ void AddSC_zangarmarsh() newscript->pGossipHello = &GossipHello_npc_mortog_steamhead; newscript->pGossipSelect = &GossipSelect_npc_mortog_steamhead; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_kayra_longmane"; + newscript->GetAI = &GetAI_npc_kayra_longmaneAI; + newscript->pQuestAccept = &QuestAccept_npc_kayra_longmane; + newscript->RegisterSelf(); } diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index ee39245fc3b..ad8d01aeca0 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1638,6 +1638,7 @@ void Creature::setDeathState(DeathState s) { SetUInt64Value (UNIT_FIELD_TARGET,0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) SetUInt32Value(UNIT_NPC_FLAGS, 0); + setActive(false); if(!isPet() && GetCreatureInfo()->SkinLootId) if ( LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId) ) diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 713daf3a7e3..7881019a7ec 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -862,6 +862,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) missingItem = at->requiredItem2; uint32 missingKey = 0; + uint32 missingHeroicQuest = 0; if(GetPlayer()->GetDifficulty() == DIFFICULTY_HEROIC) { if(at->heroicKey) @@ -872,19 +873,24 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) } else if(at->heroicKey2 && !GetPlayer()->HasItemCount(at->heroicKey2, 1)) missingKey = at->heroicKey2; + + if(at->heroicQuest && !GetPlayer()->GetQuestRewardStatus(at->heroicQuest)) + missingHeroicQuest = at->heroicQuest; } uint32 missingQuest = 0; if(at->requiredQuest && !GetPlayer()->GetQuestRewardStatus(at->requiredQuest)) missingQuest = at->requiredQuest; - if(missingLevel || missingItem || missingKey || missingQuest) + if(missingLevel || missingItem || missingKey || missingQuest || missingHeroicQuest) { // TODO: all this is probably wrong if(missingItem) SendAreaTriggerMessage(GetTrinityString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1); else if(missingKey) GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC); + else if(missingHeroicQuest) + SendAreaTriggerMessage(at->heroicQuestFailedText.c_str()); else if(missingQuest) SendAreaTriggerMessage(at->requiredFailedText.c_str()); else if(missingLevel) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 6cd897a071d..226129c392d 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1649,7 +1649,7 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, UpdateGroundPositionZ(x,y,z); } -void WorldObject::GetClosePointAt(float &x, float &y, float &z, float dist, float angle) +void WorldObject::GetGroundPoint(float &x, float &y, float &z, float dist, float angle) { angle += GetOrientation(); x += dist * cos(angle); diff --git a/src/game/Object.h b/src/game/Object.h index 56c931cc3b8..815111eb91b 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -395,11 +395,11 @@ class TRINITY_DLL_SPEC WorldObject : public Object // angle calculated from current orientation GetNearPoint(NULL,x,y,z,size,distance2d,GetOrientation() + angle); } - void GetClosePointAt(float &x, float &y, float &z, float dist, float angle); - void GetClosePoint(float &x, float &y, float &z, float dist, float angle) + void GetGroundPoint(float &x, float &y, float &z, float dist, float angle); + void GetGroundPointAroundUnit(float &x, float &y, float &z, float dist, float angle) { GetPosition(x, y, z); - GetClosePointAt(x, y, z, dist, angle); + GetGroundPoint(x, y, z, dist, angle); } void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const { diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 8f8fc418118..9206fe0acd3 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -5179,9 +5179,9 @@ void ObjectMgr::LoadAreaTriggerTeleports() uint32 count = 0; - // 0 1 2 3 4 5 6 7 8 9 10 11 12 - QueryResult *result = WorldDatabase.Query("SELECT id, required_level, required_item, required_item2, heroic_key, heroic_key2, required_quest_done, required_failed_text, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport"); - if( !result ) + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + QueryResult *result = WorldDatabase.Query("SELECT id, required_level, required_item, required_item2, heroic_key, heroic_key2, heroic_required_quest_done, heroic_required_failed_quest_text, required_quest_done, required_failed_text, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport"); + if( !result ) { barGoLink bar( 1 ); @@ -5207,18 +5207,20 @@ void ObjectMgr::LoadAreaTriggerTeleports() AreaTrigger at; - at.requiredLevel = fields[1].GetUInt8(); - at.requiredItem = fields[2].GetUInt32(); - at.requiredItem2 = fields[3].GetUInt32(); - at.heroicKey = fields[4].GetUInt32(); - at.heroicKey2 = fields[5].GetUInt32(); - at.requiredQuest = fields[6].GetUInt32(); - at.requiredFailedText = fields[7].GetCppString(); - at.target_mapId = fields[8].GetUInt32(); - at.target_X = fields[9].GetFloat(); - at.target_Y = fields[10].GetFloat(); - at.target_Z = fields[11].GetFloat(); - at.target_Orientation = fields[12].GetFloat(); + at.requiredLevel = fields[1].GetUInt8(); + at.requiredItem = fields[2].GetUInt32(); + at.requiredItem2 = fields[3].GetUInt32(); + at.heroicKey = fields[4].GetUInt32(); + at.heroicKey2 = fields[5].GetUInt32(); + at.heroicQuest = fields[6].GetUInt32(); + at.heroicQuestFailedText = fields[7].GetCppString(); + at.requiredQuest = fields[8].GetUInt32(); + at.requiredFailedText = fields[9].GetCppString(); + at.target_mapId = fields[10].GetUInt32(); + at.target_X = fields[11].GetFloat(); + at.target_Y = fields[12].GetFloat(); + at.target_Z = fields[13].GetFloat(); + at.target_Orientation = fields[14].GetFloat(); AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); if(!atEntry) @@ -5266,6 +5268,15 @@ void ObjectMgr::LoadAreaTriggerTeleports() } } + if(at.heroicQuest) + { + if(!mQuestTemplates[at.heroicQuest]) + { + sLog.outErrorDb("Required Heroic Quest %u not exist for trigger %u, remove heroic quest done requirement.",at.heroicQuest,Trigger_ID); + at.heroicQuest = 0; + } + } + if(at.requiredQuest) { if(!mQuestTemplates[at.requiredQuest]) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index e4383cae605..74a63bfbe41 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -107,6 +107,8 @@ struct AreaTrigger uint32 requiredItem2; uint32 heroicKey; uint32 heroicKey2; + uint32 heroicQuest; + std::string heroicQuestFailedText; uint32 requiredQuest; std::string requiredFailedText; uint32 target_mapId; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index b234ed34829..1dd0c168329 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1857,7 +1857,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) default: angle = rand_norm()*2*M_PI; break; } - m_caster->GetClosePoint(x, y, z, dist, angle); + m_caster->GetGroundPointAroundUnit(x, y, z, dist, angle); m_targets.setDestination(x, y, z); // do not know if has ground visual }break; @@ -1903,7 +1903,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) default: angle = rand_norm()*2*M_PI; break; } - target->GetClosePoint(x, y, z, dist, angle); + target->GetGroundPointAroundUnit(x, y, z, dist, angle); m_targets.setDestination(x, y, z); // do not know if has ground visual }break; @@ -1940,7 +1940,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) x = m_targets.m_destX; y = m_targets.m_destY; z = m_targets.m_destZ; - m_caster->GetClosePointAt(x, y, z, dist, angle); + m_caster->GetGroundPoint(x, y, z, dist, angle); m_targets.setDestination(x, y, z); // do not know if has ground visual }break; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 0b59a82e966..9b3b35b7e99 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -690,11 +690,10 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) } } - if(m_originalCaster) - damage = m_originalCaster->SpellDamageBonus(unitTarget, m_spellInfo, damage, SPELL_DIRECT_DAMAGE); + if(m_originalCaster && damage > 0) + damage = m_originalCaster->SpellDamageBonus(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); - if(damage > 0) - m_damage += damage; + m_damage += damage; } } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 6585de79355..dd80acc2dc6 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1284,6 +1284,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool if(!spellInfo_1->SpellFamilyName) { if(!spellInfo_1->SpellIconID + || spellInfo_1->SpellIconID == 1 || spellInfo_1->SpellIconID != spellInfo_2->SpellIconID) return false; } diff --git a/src/game/TicketHandler.cpp b/src/game/TicketHandler.cpp index 1e1d97fd4ce..71375beb5da 100644 --- a/src/game/TicketHandler.cpp +++ b/src/game/TicketHandler.cpp @@ -36,6 +36,8 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data ) // always do a packet check CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4); + uint32 map; + float x, y, z; std::string ticketText = ""; std::string ticketText2 = ""; GM_Ticket *ticket = new GM_Ticket; @@ -43,7 +45,12 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data ) WorldPacket data(SMSG_GMTICKET_CREATE, 4); // recv Data - recv_data >> ticketText; + //TODO: Add map coordinates to tickets. + recv_data >> map; + recv_data >> x; + recv_data >> y; + recv_data >> z; + recv_data >> ticketText; // get additional data, rarely used recv_data >> ticketText2; @@ -180,4 +187,4 @@ void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ // Send Packet SendPacket(&data); -}
\ No newline at end of file +} diff --git a/src/game/TicketMgr.cpp b/src/game/TicketMgr.cpp index ffa8c522672..1e28c2a2ec1 100644 --- a/src/game/TicketMgr.cpp +++ b/src/game/TicketMgr.cpp @@ -108,11 +108,12 @@ void TicketMgr::DeleteGMTicketPermanently(uint64 ticketGuid) void TicketMgr::LoadGMTickets() { + InitTicketID(); // Delete all out of object holder GM_TicketList.clear(); QueryResult *result = CharacterDatabase.Query( "SELECT `guid`, `playerGuid`, `name`, `message`, `timestamp`, `closed`, `assignedto`, `comment` FROM `gm_tickets` WHERE `closed` = '0'" ); GM_Ticket *ticket; - + if(!result) return; @@ -168,18 +169,19 @@ void TicketMgr::RemoveGMTicketByPlayer(uint64 playerGuid, uint64 GMguid) void TicketMgr::SaveGMTicket(GM_Ticket* ticket) { + std::string msg = ticket->message; + CharacterDatabase.escape_string(msg); std::stringstream ss; - ss << "REPLACE INTO `gm_tickets` (`guid`, `playerGuid`, `name`, `message`, `timestamp`, `closed`, `assignedto`, `comment`) VALUES(\""; - ss << ticket->guid << "\", \""; - ss << ticket->playerGuid << "\", \""; - ss << ticket->name << "\", \""; - ss << ticket->message << "\", \"" ; - ss << ticket->timestamp << "\", \""; - ss << ticket->closed << "\", \""; - ss << ticket->assignedToGM << "\", \""; - ss << ticket->comment << "\");"; - - CharacterDatabase.BeginTransaction(); + ss << "REPLACE INTO `gm_tickets` (`guid`, `playerGuid`, `name`, `message`, `timestamp`, `closed`, `assignedto`, `comment`) VALUES('"; + ss << ticket->guid << "', '"; + ss << ticket->playerGuid << "', '"; + ss << ticket->name << "', '"; + ss << msg << "', '" ; + ss << ticket->timestamp << "', '"; + ss << ticket->closed << "', '"; + ss << ticket->assignedToGM << "', '"; + ss << ticket->comment << "');"; + CharacterDatabase.BeginTransaction(); CharacterDatabase.Execute(ss.str().c_str()); CharacterDatabase.CommitTransaction(); @@ -190,7 +192,7 @@ void TicketMgr::UpdateGMTicket(GM_Ticket *ticket) SaveGMTicket(ticket); } -uint64 TicketMgr::GenerateTicketID() +void TicketMgr::InitTicketID() { QueryResult *result = CharacterDatabase.Query("SELECT MAX(guid) FROM gm_tickets"); if(result) @@ -198,6 +200,9 @@ uint64 TicketMgr::GenerateTicketID() m_ticketid = result->Fetch()[0].GetUInt64() + 1; delete result; } +} +uint64 TicketMgr::GenerateTicketID() +{ return ++m_ticketid; -}
\ No newline at end of file +} diff --git a/src/game/TicketMgr.h b/src/game/TicketMgr.h index 33a9598e7cf..cf050303e39 100644 --- a/src/game/TicketMgr.h +++ b/src/game/TicketMgr.h @@ -61,6 +61,7 @@ class TicketMgr void SaveGMTicket(GM_Ticket* ticket); uint64 GenerateTicketID(); + void InitTicketID(); GM_Ticket* GetGMTicket(uint64 ticketGuid); GM_Ticket* GetGMTicketByPlayer(uint64 playerGuid); GM_Ticket* GetGMTicketByName(const char *name); |