diff --git a/src/server/scripts/EasternKingdoms/Gilneas/gilneas_chapter_1.cpp b/src/server/scripts/EasternKingdoms/Gilneas/gilneas_chapter_1.cpp index 804d60d1c6d..b1e9fd25fc6 100644 --- a/src/server/scripts/EasternKingdoms/Gilneas/gilneas_chapter_1.cpp +++ b/src/server/scripts/EasternKingdoms/Gilneas/gilneas_chapter_1.cpp @@ -54,87 +54,76 @@ enum FrightenedCitizen EVENT_DESPAWN = 4 }; -class npc_frightened_citizen : public CreatureScript +struct npc_frightened_citizen : public PassiveAI { - public: - npc_frightened_citizen() : CreatureScript("npc_frightened_citizen") { } + npc_frightened_citizen(Creature* creature) : PassiveAI(creature) { } - struct npc_frightened_citizenAI : public PassiveAI - { - npc_frightened_citizenAI(Creature* creature) : PassiveAI(creature) { } + void IsSummonedBy(Unit* /*summoner*/) override + { + if (Creature* stalkerNear = me->FindNearestCreature(NPC_EVACUATION_STALKER_FIRST, 20.0f)) + me->GetMotionMaster()->MovePoint(POINT_STALKER_FIRST, stalkerNear->GetPosition(), true); + } - void IsSummonedBy(Unit* /*summoner*/) override + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; + + switch (id) { - if (Creature* stalkerNear = me->FindNearestCreature(NPC_EVACUATION_STALKER_FIRST, 20.0f)) - me->GetMotionMaster()->MovePoint(POINT_STALKER_FIRST, stalkerNear->GetPosition(), true); + case POINT_STALKER_FIRST: + _events.ScheduleEvent(EVENT_TALK_FRIGHTENED, 1s); + break; + case POINT_STALKER_NEAR: + _events.ScheduleEvent(EVENT_MOVE_TO_FAR_STALKER, 1ms); + break; + case POINT_STALKER_FAR: + _events.ScheduleEvent(EVENT_DESPAWN, 1ms); + break; + default: + break; } + } - void MovementInform(uint32 type, uint32 id) override + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) { - if (type != POINT_MOTION_TYPE) - return; - - switch (id) + switch (eventId) { - case POINT_STALKER_FIRST: - _events.ScheduleEvent(EVENT_TALK_FRIGHTENED, Seconds(1)); + case EVENT_TALK_FRIGHTENED: + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + { + if (Player* player = summoner->ToPlayer()) + { + player->KilledMonsterCredit(CREDIT_35830); + Talk(SAY_FRIGHTENED_CITIZEN_RESCUE, summoner); + } + } + _events.ScheduleEvent(EVENT_MOVE_TO_NEAR_STALKER, 2s); break; - case POINT_STALKER_NEAR: - _events.ScheduleEvent(EVENT_MOVE_TO_FAR_STALKER, Milliseconds(1)); + case EVENT_MOVE_TO_NEAR_STALKER: + if (Creature* stalker = me->FindNearestCreature(NPC_EVACUATION_STALKER_FAR, 50.0f)) + me->GetMotionMaster()->MovePoint(POINT_STALKER_FAR, stalker->GetPosition(), true); + else if (Creature* stalker = me->FindNearestCreature(NPC_EVACUATION_STALKER_NEAR, 100.0f)) + me->GetMotionMaster()->MovePoint(POINT_STALKER_NEAR, stalker->GetPosition(), true); break; - case POINT_STALKER_FAR: - _events.ScheduleEvent(EVENT_DESPAWN, Milliseconds(1)); + case EVENT_MOVE_TO_FAR_STALKER: + if (Creature* stalker = me->FindNearestCreature(NPC_EVACUATION_STALKER_FAR, 500.0f)) + me->GetMotionMaster()->MovePoint(POINT_STALKER_FAR, stalker->GetPosition(), true); + break; + case EVENT_DESPAWN: + me->DespawnOrUnsummon(); break; default: break; } } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_TALK_FRIGHTENED: - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - { - if (Player* player = summoner->ToPlayer()) - { - player->KilledMonsterCredit(CREDIT_35830); - Talk(SAY_FRIGHTENED_CITIZEN_RESCUE, summoner); - } - } - _events.ScheduleEvent(EVENT_MOVE_TO_NEAR_STALKER, Seconds(2)); - break; - case EVENT_MOVE_TO_NEAR_STALKER: - if (Creature* stalker = me->FindNearestCreature(NPC_EVACUATION_STALKER_FAR, 50.0f)) - me->GetMotionMaster()->MovePoint(POINT_STALKER_FAR, stalker->GetPosition(), true); - else if (Creature* stalker = me->FindNearestCreature(NPC_EVACUATION_STALKER_NEAR, 100.0f)) - me->GetMotionMaster()->MovePoint(POINT_STALKER_NEAR, stalker->GetPosition(), true); - break; - case EVENT_MOVE_TO_FAR_STALKER: - if (Creature* stalker = me->FindNearestCreature(NPC_EVACUATION_STALKER_FAR, 500.0f)) - me->GetMotionMaster()->MovePoint(POINT_STALKER_FAR, stalker->GetPosition(), true); - break; - case EVENT_DESPAWN: - me->DespawnOrUnsummon(); - break; - default: - break; - } - } - } - private: - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_frightened_citizenAI(creature); - } + } +private: + EventMap _events; }; /*###### @@ -171,170 +160,148 @@ enum WorgenRunt NPC_WORGEN_RUNT_SPELL = 35188, }; -Position const runtSpellSummonJumpPos = { -1671.915f, 1446.734f, 52.28712f }; +static Position const RuntSpellSummonJumpPos = { -1671.915f, 1446.734f, 52.28712f }; -class npc_worgen_runt : public CreatureScript +struct npc_worgen_runt : public ScriptedAI { - public: - npc_worgen_runt() : CreatureScript("npc_worgen_runt") { } + npc_worgen_runt(Creature* creature) : ScriptedAI(creature), _worgenID(0), _wayPointCounter(0), _jumped(false) { } - struct npc_worgen_runtAI : public ScriptedAI + void JustEngagedWith(Unit* /*who*/) override + { + _events.SetPhase(PHASE_COMBAT); + } + + void IsSummonedBy(Unit* summoner) override + { + me->setActive(true); // we are in a phased and cut off map so we're fine to use that here + _events.SetPhase(PHASE_ROOF); + _events.ScheduleEvent(EVENT_FORCE_DESPAWN, 70s, 0, PHASE_ROOF); + _playerGuid = summoner->GetGUID(); + if (me->GetEntry() == NPC_WORGEN_RUNT_SPELL) + me->GetMotionMaster()->MoveJump(RuntSpellSummonJumpPos, 16.0f, 4.371286f); + } + + void DoAction(int32 action) override + { + _worgenID = action; + switch (_worgenID) // ugly as fuck but needed for individual controls { - npc_worgen_runtAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - _worgenID = 0; - _wayPointCounter = 0; - _jumped = false; - _playerGuid = ObjectGuid::Empty; - } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.SetPhase(PHASE_COMBAT); - } - - void IsSummonedBy(Unit* summoner) override - { - me->setActive(true); // we are in a phased and cut off map so we're fine to use that here - _events.SetPhase(PHASE_ROOF); - _events.ScheduleEvent(EVENT_FORCE_DESPAWN, Seconds(70), 0, PHASE_ROOF); - _playerGuid = summoner->GetGUID(); - if (me->GetEntry() == NPC_WORGEN_RUNT_SPELL) - me->GetMotionMaster()->MoveJump(runtSpellSummonJumpPos, 16.0f, 4.371286f); - } - - void DoAction(int32 action) override - { - _worgenID = action; - switch (_worgenID) // ugly as fuck but needed for individual controls - { - // House roof cases - case WORGEN_ID_ROOF_1: - _wayPointCounter = runtHousePathSize1; - me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize1, worgenRuntHousePath1, runtHousePathSize1); - break; - case WORGEN_ID_ROOF_2: - _wayPointCounter = runtHousePathSize2; - me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize2, worgenRuntHousePath2, runtHousePathSize2); - break; - case WORGEN_ID_ROOF_3: - _wayPointCounter = runtHousePathSize3; - me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize3, worgenRuntHousePath3, runtHousePathSize3); - break; - case WORGEN_ID_ROOF_4: - _wayPointCounter = runtHousePathSize4; - me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize4, worgenRuntHousePath4, runtHousePathSize4); - break; - case WORGEN_ID_ROOF_5: - _wayPointCounter = runtHousePathSize5; - me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize5, worgenRuntHousePath5, runtHousePathSize5); - break; - case WORGEN_ID_ROOF_6: - _wayPointCounter = runtHousePathSize6; - me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize6, worgenRuntHousePath6, runtHousePathSize6); - break; - case WORGEN_ID_ROOF_7: - _wayPointCounter = runtHousePathSize7; - me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize7, worgenRuntHousePath7, runtHousePathSize7); - break; - // Cathedral cases - case WORGEN_ID_CATHEDRAL_1: - _wayPointCounter = runtCathedralPathSize1; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize1, worgenRuntCathedralPath1, runtCathedralPathSize1); - break; - case WORGEN_ID_CATHEDRAL_2: - _wayPointCounter = runtCathedralPathSize2; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize2, worgenRuntCathedralPath1, runtCathedralPathSize2); - break; - case WORGEN_ID_CATHEDRAL_3: - _wayPointCounter = runtCathedralPathSize3; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize3, worgenRuntCathedralPath1, runtCathedralPathSize3); - break; - case WORGEN_ID_CATHEDRAL_4: - _wayPointCounter = runtCathedralPathSize4; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize4, worgenRuntCathedralPath1, runtCathedralPathSize4); - break; - case WORGEN_ID_CATHEDRAL_5: - _wayPointCounter = runtCathedralPathSize5; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize5, worgenRuntCathedralPath1, runtCathedralPathSize5); - break; - case WORGEN_ID_CATHEDRAL_6: - _wayPointCounter = runtCathedralPathSize6; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize6, worgenRuntCathedralPath1, runtCathedralPathSize6); - break; - case WORGEN_ID_CATHEDRAL_7: - _wayPointCounter = runtCathedralPathSize7; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize7, worgenRuntCathedralPath1, runtCathedralPathSize7); - break; - case WORGEN_ID_CATHEDRAL_8: - _wayPointCounter = runtCathedralPathSize8; - me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize8, worgenRuntCathedralPath1, runtCathedralPathSize8); - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(Seconds(5)); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type == EFFECT_MOTION_TYPE && pointId == _wayPointCounter && !_jumped) - { - _jumped = true; - _events.ScheduleEvent(EVENT_JUMP_TO_PRISON, Milliseconds(1)); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !_events.IsInPhase(PHASE_ROOF)) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch(eventId) - { - case EVENT_FORCE_DESPAWN: - me->DespawnOrUnsummon(); - break; - case EVENT_JUMP_TO_PRISON: - me->GetMotionMaster()->MoveJump(worgenRuntJumpPos[_worgenID], 16.0f, _worgenID < WORGEN_ID_CATHEDRAL_1 ? 19.2911f : frand(3.945607f, 4.852813f)); - me->SetHomePosition(worgenRuntJumpPos[_worgenID]); - _events.ScheduleEvent(EVENT_AGGRO_PLAYER, Seconds(2)); - break; - case EVENT_AGGRO_PLAYER: - if (Unit* player = ObjectAccessor::GetPlayer(*me, _playerGuid)) - if (me->IsAIEnabled() && me->IsInDist(player->GetPosition(), 100.0f)) - me->AI()->AttackStart(player); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - private: - uint32 _worgenID; - uint32 _wayPointCounter; - bool _jumped; - ObjectGuid _playerGuid; - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_worgen_runtAI(creature); + // House roof cases + case WORGEN_ID_ROOF_1: + _wayPointCounter = runtHousePathSize1; + me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize1, worgenRuntHousePath1, runtHousePathSize1); + break; + case WORGEN_ID_ROOF_2: + _wayPointCounter = runtHousePathSize2; + me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize2, worgenRuntHousePath2, runtHousePathSize2); + break; + case WORGEN_ID_ROOF_3: + _wayPointCounter = runtHousePathSize3; + me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize3, worgenRuntHousePath3, runtHousePathSize3); + break; + case WORGEN_ID_ROOF_4: + _wayPointCounter = runtHousePathSize4; + me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize4, worgenRuntHousePath4, runtHousePathSize4); + break; + case WORGEN_ID_ROOF_5: + _wayPointCounter = runtHousePathSize5; + me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize5, worgenRuntHousePath5, runtHousePathSize5); + break; + case WORGEN_ID_ROOF_6: + _wayPointCounter = runtHousePathSize6; + me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize6, worgenRuntHousePath6, runtHousePathSize6); + break; + case WORGEN_ID_ROOF_7: + _wayPointCounter = runtHousePathSize7; + me->GetMotionMaster()->MoveSmoothPath(runtHousePathSize7, worgenRuntHousePath7, runtHousePathSize7); + break; + // Cathedral cases + case WORGEN_ID_CATHEDRAL_1: + _wayPointCounter = runtCathedralPathSize1; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize1, worgenRuntCathedralPath1, runtCathedralPathSize1); + break; + case WORGEN_ID_CATHEDRAL_2: + _wayPointCounter = runtCathedralPathSize2; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize2, worgenRuntCathedralPath1, runtCathedralPathSize2); + break; + case WORGEN_ID_CATHEDRAL_3: + _wayPointCounter = runtCathedralPathSize3; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize3, worgenRuntCathedralPath1, runtCathedralPathSize3); + break; + case WORGEN_ID_CATHEDRAL_4: + _wayPointCounter = runtCathedralPathSize4; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize4, worgenRuntCathedralPath1, runtCathedralPathSize4); + break; + case WORGEN_ID_CATHEDRAL_5: + _wayPointCounter = runtCathedralPathSize5; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize5, worgenRuntCathedralPath1, runtCathedralPathSize5); + break; + case WORGEN_ID_CATHEDRAL_6: + _wayPointCounter = runtCathedralPathSize6; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize6, worgenRuntCathedralPath1, runtCathedralPathSize6); + break; + case WORGEN_ID_CATHEDRAL_7: + _wayPointCounter = runtCathedralPathSize7; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize7, worgenRuntCathedralPath1, runtCathedralPathSize7); + break; + case WORGEN_ID_CATHEDRAL_8: + _wayPointCounter = runtCathedralPathSize8; + me->GetMotionMaster()->MoveSmoothPath(runtCathedralPathSize8, worgenRuntCathedralPath1, runtCathedralPathSize8); + break; } + } + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(5s); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type == EFFECT_MOTION_TYPE && pointId == _wayPointCounter && !_jumped) + { + _jumped = true; + _events.ScheduleEvent(EVENT_JUMP_TO_PRISON, 1ms); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_ROOF)) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FORCE_DESPAWN: + me->DespawnOrUnsummon(); + break; + case EVENT_JUMP_TO_PRISON: + me->GetMotionMaster()->MoveJump(worgenRuntJumpPos[_worgenID], 16.0f, _worgenID < WORGEN_ID_CATHEDRAL_1 ? 19.2911f : frand(3.945607f, 4.852813f)); + me->SetHomePosition(worgenRuntJumpPos[_worgenID]); + _events.ScheduleEvent(EVENT_AGGRO_PLAYER, 2s); + break; + case EVENT_AGGRO_PLAYER: + if (Unit* player = ObjectAccessor::GetPlayer(*me, _playerGuid)) + if (me->IsInDist(player->GetPosition(), 100.0f)) + AttackStart(player); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } +private: + uint32 _worgenID; + uint32 _wayPointCounter; + bool _jumped; + ObjectGuid _playerGuid; + EventMap _events; }; /*###### @@ -357,78 +324,67 @@ enum TheRebelLordsArsena EVENT_SHOOT_JOSIAH }; -Position const josiahJumpPos = { -1796.63f, 1427.73f, 12.4624f }; +static Position const JosiahJumpPos = { -1796.63f, 1427.73f, 12.4624f }; -class npc_josiah_avery : public CreatureScript +struct npc_josiah_avery : public PassiveAI { - public: - npc_josiah_avery() : CreatureScript("npc_josiah_avery") { } + npc_josiah_avery(Creature* creature) : PassiveAI(creature) { } - struct npc_josiah_averyAI : public PassiveAI + void IsSummonedBy(Unit* summoner) override + { + PhasingHandler::AddPhase(me, PHASE_ID_SUMMON, true); + PhasingHandler::AddPhase(me, PHASE_ID_WOUND, true); + _playerGuid = summoner->GetGUID(); + _events.ScheduleEvent(EVENT_COSMETIC_ATTACK, 500ms); + } + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(5s); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) { - npc_josiah_averyAI(Creature* creature) : PassiveAI(creature) { } - - void IsSummonedBy(Unit* summoner) override + switch (eventId) { - PhasingHandler::AddPhase(me, PHASE_ID_SUMMON, true); - PhasingHandler::AddPhase(me, PHASE_ID_WOUND, true); - _playerGuid = summoner->GetGUID(); - _events.ScheduleEvent(EVENT_COSMETIC_ATTACK, Milliseconds(500)); - } - - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(Seconds(5)); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch(eventId) + case EVENT_COSMETIC_ATTACK: + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid)) { - case EVENT_COSMETIC_ATTACK: - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid)) - { - DoCast(player, SPELL_COSMETIC_ATTACK); - if (Creature* lorna = me->FindNearestCreature(NPC_LORNA_CROWLEY, 30.0f, true)) - if (Creature* labTrigger = lorna->FindNearestCreature(NPC_GENERIC_TRIGGER_LAB, 5.0f, true)) - labTrigger->CastSpell(player, SPELL_PULL_TO); + DoCast(player, SPELL_COSMETIC_ATTACK); + if (Creature* lorna = me->FindNearestCreature(NPC_LORNA_CROWLEY, 30.0f, true)) + if (Creature* labTrigger = lorna->FindNearestCreature(NPC_GENERIC_TRIGGER_LAB, 5.0f, true)) + labTrigger->CastSpell(player, SPELL_PULL_TO); - _events.ScheduleEvent(EVENT_JUMP_TO_PLAYER, Seconds(1)); - } - break; - case EVENT_JUMP_TO_PLAYER: - me->GetMotionMaster()->MoveJump(josiahJumpPos, 10.0f, 14.18636f); - _events.ScheduleEvent(EVENT_SHOOT_JOSIAH, Milliseconds(500)); - break; - case EVENT_SHOOT_JOSIAH: - if (Creature* lorna = me->FindNearestCreature(NPC_LORNA_CROWLEY, 30.0f, true)) - lorna->CastSpell(me, SPELL_SHOOT_INSTAKILL, true); - break; - default: - break; + _events.ScheduleEvent(EVENT_JUMP_TO_PLAYER, 1s); } - } + break; + case EVENT_JUMP_TO_PLAYER: + me->GetMotionMaster()->MoveJump(JosiahJumpPos, 10.0f, 14.18636f); + _events.ScheduleEvent(EVENT_SHOOT_JOSIAH, 500ms); + break; + case EVENT_SHOOT_JOSIAH: + if (Creature* lorna = me->FindNearestCreature(NPC_LORNA_CROWLEY, 30.0f, true)) + lorna->CastSpell(me, SPELL_SHOOT_INSTAKILL, true); + break; + default: + break; } - private: - ObjectGuid _playerGuid; - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_josiah_averyAI(creature); } + } +private: + ObjectGuid _playerGuid; + EventMap _events; }; /*###### ## Quest 14293 - Save Krennan Aranas ######*/ -Position const greymanesHorseJumpPos = { -1676.16f, 1346.19f, 15.1349f }; +static Position const GreymanesHorseJumpPos = { -1676.16f, 1346.19f, 15.1349f }; enum GreymanesHorse { @@ -449,118 +405,99 @@ enum GreymanesHorse NPC_TRAPPED_KRENNAN = 35753, }; -class npc_greymanes_horse : public CreatureScript +struct npc_greymanes_horse : public VehicleAI { - public: - npc_greymanes_horse() : CreatureScript("npc_greymanes_horse") { } + npc_greymanes_horse(Creature* creature) : VehicleAI(creature), _currentPath(PATH_KRENNAN_TREE) { } - struct npc_greymanes_horseAI : public VehicleAI + void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override + { + if (apply && passenger->GetTypeId() == TYPEID_PLAYER) { - npc_greymanes_horseAI(Creature* creature) : VehicleAI(creature) - { - Initialize(); - } - - void Initialize() - { - _currentPath = PATH_KRENNAN_TREE; - } - - void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override - { - if (apply && passenger->GetTypeId() == TYPEID_PLAYER) - { - me->SetControlled(true, UNIT_STATE_ROOT); - _events.ScheduleEvent(EVENT_START_PATH_1, Seconds(1)); - } - else if (apply && passenger->GetEntry() == NPC_RESCUED_KRENNAN) - _events.ScheduleEvent(EVENT_START_PATH_2, Seconds(1)); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type == EFFECT_MOTION_TYPE && pointId == pathSize1 && _currentPath == PATH_KRENNAN_TREE) - _events.ScheduleEvent(EVENT_JUMP_TO_KRENNAN, Milliseconds(1)); - else if (type == EFFECT_MOTION_TYPE && pointId == pathSize2 && _currentPath == PATH_KRENNAN_BACK) - _events.ScheduleEvent(EVENT_DISMOUNT_PLAYER, Milliseconds(1)); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_START_PATH_1: - me->SetControlled(false, UNIT_STATE_ROOT); - _currentPath = PATH_KRENNAN_TREE; - me->GetMotionMaster()->MoveSmoothPath(pathSize1, greymanesHorsePath1, pathSize1); - break; - case EVENT_JUMP_TO_KRENNAN: - me->GetMotionMaster()->MoveJump(greymanesHorseJumpPos, 16.0f, 14.00968f); - _events.ScheduleEvent(EVENT_ANNOUNCE_RESCUE, Seconds(2)); - break; - case EVENT_ANNOUNCE_RESCUE: - me->SetControlled(true, UNIT_STATE_ROOT); - if (Unit* passenger = me->GetVehicleKit()->GetPassenger(0)) - { - Talk(SAY_ANNOUNCE_RESCUE, passenger); - if (Creature* krennan = me->FindNearestCreature(NPC_TRAPPED_KRENNAN, 30.0f, true)) - krennan->AI()->Talk(SAY_TRAPPED, passenger); - } - break; - case EVENT_START_PATH_2: - me->SetControlled(true, UNIT_STATE_ROOT); - _currentPath = PATH_KRENNAN_BACK; - me->GetMotionMaster()->MoveSmoothPath(pathSize2, greymanesHorsePath2, pathSize2); - break; - case EVENT_DISMOUNT_PLAYER: - if (Unit* passenger = me->GetVehicleKit()->GetPassenger(1)) - { - if (Unit* player = me->GetVehicleKit()->GetPassenger(0)) - { - if (Creature* krennan = passenger->ToCreature()) - { - std::vector storedAttackers; - - for (Unit* attacker : me->getAttackers()) - storedAttackers.push_back(attacker); - - for (Unit* attacker : storedAttackers) - { - if (Creature* creature = attacker->ToCreature()) - if (creature->IsAIEnabled()) - creature->AI()->EnterEvadeMode(); - } - - player->ExitVehicle(); - krennan->AddUnitState(UNIT_STATE_ROOT); - krennan->ExitVehicle(); - krennan->AI()->Talk(SAY_RESCUED, me); - krennan->DespawnOrUnsummon(Seconds(7)); - } - } - } - break; - default: - break; - } - } - } - private: - EventMap _events; - uint32 _currentPath; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_greymanes_horseAI(creature); + me->SetControlled(true, UNIT_STATE_ROOT); + _events.ScheduleEvent(EVENT_START_PATH_1, 1s); } + else if (apply && passenger->GetEntry() == NPC_RESCUED_KRENNAN) + _events.ScheduleEvent(EVENT_START_PATH_2, 1s); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type == EFFECT_MOTION_TYPE && pointId == pathSize1 && _currentPath == PATH_KRENNAN_TREE) + _events.ScheduleEvent(EVENT_JUMP_TO_KRENNAN, 1ms); + else if (type == EFFECT_MOTION_TYPE && pointId == pathSize2 && _currentPath == PATH_KRENNAN_BACK) + _events.ScheduleEvent(EVENT_DISMOUNT_PLAYER, 1ms); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_START_PATH_1: + me->SetControlled(false, UNIT_STATE_ROOT); + _currentPath = PATH_KRENNAN_TREE; + me->GetMotionMaster()->MoveSmoothPath(pathSize1, greymanesHorsePath1, pathSize1); + break; + case EVENT_JUMP_TO_KRENNAN: + me->GetMotionMaster()->MoveJump(GreymanesHorseJumpPos, 16.0f, 14.00968f); + _events.ScheduleEvent(EVENT_ANNOUNCE_RESCUE, 2s); + break; + case EVENT_ANNOUNCE_RESCUE: + me->SetControlled(true, UNIT_STATE_ROOT); + if (Unit* passenger = me->GetVehicleKit()->GetPassenger(0)) + { + Talk(SAY_ANNOUNCE_RESCUE, passenger); + if (Creature* krennan = me->FindNearestCreature(NPC_TRAPPED_KRENNAN, 30.0f, true)) + krennan->AI()->Talk(SAY_TRAPPED, passenger); + } + break; + case EVENT_START_PATH_2: + me->SetControlled(true, UNIT_STATE_ROOT); + _currentPath = PATH_KRENNAN_BACK; + me->GetMotionMaster()->MoveSmoothPath(pathSize2, greymanesHorsePath2, pathSize2); + break; + case EVENT_DISMOUNT_PLAYER: + if (Unit* passenger = me->GetVehicleKit()->GetPassenger(1)) + { + if (Unit* player = me->GetVehicleKit()->GetPassenger(0)) + { + if (Creature* krennan = passenger->ToCreature()) + { + std::vector storedAttackers; + + for (Unit* attacker : me->getAttackers()) + storedAttackers.push_back(attacker); + + for (Unit* attacker : storedAttackers) + { + if (Creature* creature = attacker->ToCreature()) + if (creature->IsAIEnabled()) + creature->AI()->EnterEvadeMode(); + } + + player->ExitVehicle(); + krennan->AddUnitState(UNIT_STATE_ROOT); + krennan->ExitVehicle(); + krennan->AI()->Talk(SAY_RESCUED, me); + krennan->DespawnOrUnsummon(7s); + } + } + } + break; + default: + break; + } + } + } +private: + EventMap _events; + uint32 _currentPath; }; /*###### @@ -583,112 +520,89 @@ enum CrowleysHorse NPC_CROWLEYS_HORSE_2 = 44428, }; -Position const crowleysHorseJumpPos = { -1714.762f, 1673.16f, 20.49182f }; -Position const crowleysHorseJumpPos2 = { -1566.71f, 1708.04f, 20.4849f }; +static Position const CrowleysHorseJumpPos = { -1714.762f, 1673.16f, 20.49182f }; +static Position const CrowleysHorseJumpPos2 = { -1566.71f, 1708.04f, 20.4849f }; -class npc_crowleys_horse : public CreatureScript +struct npc_crowleys_horse : public VehicleAI { - public: - npc_crowleys_horse() : CreatureScript("npc_crowleys_horse") { } + npc_crowleys_horse(Creature* creature) : VehicleAI(creature), _currentPath(0) { } - struct npc_crowleys_horseAI : public VehicleAI + void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override + { + if (apply && passenger->GetTypeId() == TYPEID_PLAYER && me->GetEntry() != NPC_CROWLEYS_HORSE_2) { - npc_crowleys_horseAI(Creature* creature) : VehicleAI(creature) - { - Initialize(); - } - - void Initialize() - { - _currentPath = 0; - } - - void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override - { - if (apply && passenger->GetTypeId() == TYPEID_PLAYER && me->GetEntry() != NPC_CROWLEYS_HORSE_2) - { - me->SetControlled(true, UNIT_STATE_ROOT); - _events.ScheduleEvent(EVENT_JUMP_OVER_BARRICADES_1, Seconds(2)); - } - else if (apply && passenger->GetTypeId() == TYPEID_PLAYER) - { - me->SetControlled(true, UNIT_STATE_ROOT); - _events.ScheduleEvent(EVENT_MOVE_OFF_PATH, Seconds(2)); - } - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type == WAYPOINT_MOTION_TYPE && pointId == 14 && _currentPath == PATH_ID_CROWLEYS_HORSE_1) - _events.ScheduleEvent(EVENT_JUMP_OVER_BARRICADES_2, Seconds(1)); - else if (type == WAYPOINT_MOTION_TYPE && pointId == 15 && _currentPath == PATH_ID_CROWLEYS_HORSE_2) - _events.ScheduleEvent(EVENT_DISMOUNT_PLAYER, Milliseconds(1)); - else if (type == WAYPOINT_MOTION_TYPE && pointId == 16 && _currentPath == PATH_ID_CROWLEYS_HORSE_3) - _events.ScheduleEvent(EVENT_DISMOUNT_PLAYER, Milliseconds(1)); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_JUMP_OVER_BARRICADES_1: - me->SetControlled(false, UNIT_STATE_ROOT); - me->GetMotionMaster()->MoveJump(crowleysHorseJumpPos, 16.0f, 18.56182f); - _events.ScheduleEvent(EVENT_MOVE_PATH_MAIN_1, Seconds(2)); - break; - case EVENT_MOVE_PATH_MAIN_1: - me->GetMotionMaster()->MovePath(PATH_ID_CROWLEYS_HORSE_1, false); - _currentPath = PATH_ID_CROWLEYS_HORSE_1; - break; - case EVENT_JUMP_OVER_BARRICADES_2: - me->GetMotionMaster()->MoveJump(crowleysHorseJumpPos2, 16.0f, 18.56182f); - _events.ScheduleEvent(EVENT_MOVE_PATH_MAIN_2, Seconds(2)); - break; - case EVENT_MOVE_PATH_MAIN_2: - _currentPath = PATH_ID_CROWLEYS_HORSE_2; - me->GetMotionMaster()->MovePath(PATH_ID_CROWLEYS_HORSE_2, false); - break; - case EVENT_DISMOUNT_PLAYER: - { - std::vector storedAttackers; - - for (Unit* attacker : me->getAttackers()) - storedAttackers.push_back(attacker); - - for (Unit* attacker : storedAttackers) - { - if (Creature* creature = attacker->ToCreature()) - if (creature->IsAIEnabled()) - creature->AI()->EnterEvadeMode(); - } - - me->RemoveAurasDueToSpell(VEHICLE_SPELL_RIDE_HARDCODED); - me->DespawnOrUnsummon(Seconds(5)); - break; - } - case EVENT_MOVE_OFF_PATH: - me->SetControlled(false, UNIT_STATE_ROOT); - _currentPath = PATH_ID_CROWLEYS_HORSE_3; - me->GetMotionMaster()->MovePath(PATH_ID_CROWLEYS_HORSE_3, false); - break; - default: - break; - } - } - } - private: - EventMap _events; - uint32 _currentPath; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_crowleys_horseAI(creature); + me->SetControlled(true, UNIT_STATE_ROOT); + _events.ScheduleEvent(EVENT_JUMP_OVER_BARRICADES_1, 2s); } + else if (apply && passenger->GetTypeId() == TYPEID_PLAYER) + { + me->SetControlled(true, UNIT_STATE_ROOT); + _events.ScheduleEvent(EVENT_MOVE_OFF_PATH, 2s); + } + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type == WAYPOINT_MOTION_TYPE && pointId == 14 && _currentPath == PATH_ID_CROWLEYS_HORSE_1) + _events.ScheduleEvent(EVENT_JUMP_OVER_BARRICADES_2, 1s); + else if (type == WAYPOINT_MOTION_TYPE && pointId == 15 && _currentPath == PATH_ID_CROWLEYS_HORSE_2) + _events.ScheduleEvent(EVENT_DISMOUNT_PLAYER, 1ms); + else if (type == WAYPOINT_MOTION_TYPE && pointId == 16 && _currentPath == PATH_ID_CROWLEYS_HORSE_3) + _events.ScheduleEvent(EVENT_DISMOUNT_PLAYER, 1ms); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_JUMP_OVER_BARRICADES_1: + me->SetControlled(false, UNIT_STATE_ROOT); + me->GetMotionMaster()->MoveJump(CrowleysHorseJumpPos, 16.0f, 18.56182f); + _events.ScheduleEvent(EVENT_MOVE_PATH_MAIN_1, 2s); + break; + case EVENT_MOVE_PATH_MAIN_1: + me->GetMotionMaster()->MovePath(PATH_ID_CROWLEYS_HORSE_1, false); + _currentPath = PATH_ID_CROWLEYS_HORSE_1; + break; + case EVENT_JUMP_OVER_BARRICADES_2: + me->GetMotionMaster()->MoveJump(CrowleysHorseJumpPos2, 16.0f, 18.56182f); + _events.ScheduleEvent(EVENT_MOVE_PATH_MAIN_2, 2s); + break; + case EVENT_MOVE_PATH_MAIN_2: + _currentPath = PATH_ID_CROWLEYS_HORSE_2; + me->GetMotionMaster()->MovePath(PATH_ID_CROWLEYS_HORSE_2, false); + break; + case EVENT_DISMOUNT_PLAYER: + { + std::set attackersCopy = me->getAttackers(); + for (Unit* attacker : attackersCopy) + { + if (Creature* creature = attacker->ToCreature()) + if (creature->IsAIEnabled()) + creature->AI()->EnterEvadeMode(); + } + + me->RemoveAurasDueToSpell(VEHICLE_SPELL_RIDE_HARDCODED); + me->DespawnOrUnsummon(5s); + break; + } + case EVENT_MOVE_OFF_PATH: + me->SetControlled(false, UNIT_STATE_ROOT); + _currentPath = PATH_ID_CROWLEYS_HORSE_3; + me->GetMotionMaster()->MovePath(PATH_ID_CROWLEYS_HORSE_3, false); + break; + default: + break; + } + } + } +private: + EventMap _events; + uint32 _currentPath; }; enum GileanCrow @@ -754,10 +668,10 @@ private: void AddSC_gilneas_chapter_1() { - new npc_frightened_citizen(); - new npc_worgen_runt(); - new npc_josiah_avery(); - new npc_greymanes_horse(); - new npc_crowleys_horse(); + RegisterCreatureAI(npc_frightened_citizen); + RegisterCreatureAI(npc_worgen_runt); + RegisterCreatureAI(npc_josiah_avery); + RegisterCreatureAI(npc_greymanes_horse); + RegisterCreatureAI(npc_crowleys_horse); RegisterCreatureAI(npc_gilnean_crow); }