void Reset() override { if (!HasEscortState(STATE_ESCORT_ESCORTING)) m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); }
void UpdateAI(const uint32 uiDiff) { npc_escortAI::UpdateAI(uiDiff); DoMeleeAttackIfReady(); if (HasEscortState(STATE_ESCORT_ESCORTING)) m_uiChatTimer = 6000; }
void UpdateEscortAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { if (HasEscortState(STATE_ESCORT_PAUSED)) { if (m_uiGlobalTimer < uiDiff) { m_uiGlobalTimer = 5000; switch (m_uiPhase) { case PHASE_INTRO: { switch (m_uiPhaseCounter) { case 0: if (Creature* pReethe = GetCreature(NPC_REETHE)) DoScriptText(SAY_OGR_RET_SWEAR, pReethe); break; case 1: DoScriptText(SAY_OGR_REPLY_RET, m_creature); break; case 2: if (Creature* pReethe = GetCreature(NPC_REETHE)) DoScriptText(SAY_OGR_RET_TAKEN, pReethe); break; case 3: DoScriptText(SAY_OGR_TELL_FIRE, m_creature); if (Creature* pReethe = GetCreature(NPC_REETHE)) DoScriptText(SAY_OGR_RET_NOCLOSER, pReethe); break; case 4: if (Creature* pReethe = GetCreature(NPC_REETHE)) DoScriptText(SAY_OGR_RET_NOFIRE, pReethe); break; case 5: if (Creature* pReethe = GetCreature(NPC_REETHE)) DoScriptText(SAY_OGR_RET_HEAR, pReethe); m_creature->SummonCreature(NPC_CALDWELL, m_afSpawn[0], m_afSpawn[1], m_afSpawn[2], 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 300000); m_creature->SummonCreature(NPC_HALLAN, m_afSpawn[0], m_afSpawn[1], m_afSpawn[2], 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 300000); m_creature->SummonCreature(NPC_SKIRMISHER, m_afSpawn[0], m_afSpawn[1], m_afSpawn[2], 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 300000); m_creature->SummonCreature(NPC_SKIRMISHER, m_afSpawn[0], m_afSpawn[1], m_afSpawn[2], 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 300000); m_uiPhase = PHASE_GUESTS; break; } break; } case PHASE_GUESTS: { switch (m_uiPhaseCounter) { case 6: if (Creature* pCaldwell = GetCreature(NPC_CALDWELL)) DoScriptText(SAY_OGR_CAL_FOUND, pCaldwell); break; case 7: if (Creature* pCaldwell = GetCreature(NPC_CALDWELL)) DoScriptText(SAY_OGR_CAL_MERCY, pCaldwell); break; case 8: if (Creature* pHallan = GetCreature(NPC_HALLAN)) { DoScriptText(SAY_OGR_HALL_GLAD, pHallan); if (Creature* pReethe = GetCreature(NPC_REETHE)) pHallan->CastSpell(pReethe, SPELL_FAKE_SHOT, TRIGGERED_NONE); } break; case 9: if (Creature* pReethe = GetCreature(NPC_REETHE)) { DoScriptText(EMOTE_OGR_RET_ARROW, pReethe); DoScriptText(SAY_OGR_RET_ARROW, pReethe); } break; case 10: if (Creature* pCaldwell = GetCreature(NPC_CALDWELL)) DoScriptText(SAY_OGR_CAL_CLEANUP, pCaldwell); DoScriptText(SAY_OGR_NODIE, m_creature); break; case 11: DoStartAttackMe(); m_uiPhase = PHASE_FIGHT; break; } break; } case PHASE_COMPLETE: { switch (m_uiPhaseCounter) { case 12: if (Player* pPlayer = GetPlayerForEscort()) pPlayer->GroupEventHappens(QUEST_QUESTIONING, m_creature); DoScriptText(SAY_OGR_SURVIVE, m_creature); break; case 13: if (Creature* pReethe = GetCreature(NPC_REETHE)) DoScriptText(SAY_OGR_RET_LUCKY, pReethe); break; case 14: DoScriptText(SAY_OGR_THANKS, m_creature); SetRun(); SetEscortPaused(false); break; } break; } } if (m_uiPhase != PHASE_FIGHT) ++m_uiPhaseCounter; } else m_uiGlobalTimer -= uiDiff; } return; } DoMeleeAttackIfReady(); }
void SmartAI::JustDied(Unit* killer) { GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, killer); if (HasEscortState(SMART_ESCORT_ESCORTING)) EndPath(true); }
void JustEngagedWith(Unit* who) override { if (HasEscortState(STATE_ESCORT_ESCORTING)) Talk(SAY_ATTACKED, who); }
void EnterCombat(Unit* /*who*/) { if (HasEscortState(STATE_ESCORT_ESCORTING)) DoScriptText(SAY_ELF_AGGRO, me); }
/// @todo get rid of this many variables passed in function. void npc_escortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, ObjectGuid playerGUID /* = 0 */, Quest const* quest /* = NULL */, bool instantRespawn /* = false */, bool canLoopPath /* = false */, bool resetWaypoints /* = true */) { if (me->GetVictim()) { TC_LOG_ERROR("misc", "TSCR ERROR: EscortAI (script: %s, creature entry: %u) attempts to Start while in combat", me->GetScriptName().c_str(), me->GetEntry()); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { TC_LOG_ERROR("scripts", "EscortAI (script: %s, creature entry: %u) attempts to Start while already escorting", me->GetScriptName().c_str(), me->GetEntry()); return; } if (!ScriptWP && resetWaypoints) // sd2 never adds wp in script, but tc does { if (!WaypointList.empty()) WaypointList.clear(); FillPointMovementListForCreature(); } if (WaypointList.empty()) { TC_LOG_ERROR("scripts", "EscortAI (script: %s, creature entry: %u) starts with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", me->GetScriptName().c_str(), me->GetEntry(), quest ? quest->GetQuestId() : 0); return; } //set variables m_bIsActiveAttacker = isActiveAttacker; m_bIsRunning = run; m_uiPlayerGUID = playerGUID; m_pQuestForEscort = quest; m_bCanInstantRespawn = instantRespawn; m_bCanReturnToStart = canLoopPath; if (m_bCanReturnToStart && m_bCanInstantRespawn) TC_LOG_DEBUG("scripts", "EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn."); if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MoveIdle(); TC_LOG_DEBUG("scripts", "EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle."); } //disable npcflags me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC)) { HasImmuneToNPCFlags = true; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); } TC_LOG_DEBUG("scripts", "EscortAI started with " UI64FMTD " waypoints. ActiveAttacker = %d, Run = %d, %s", uint64(WaypointList.size()), m_bIsActiveAttacker, m_bIsRunning, m_uiPlayerGUID.ToString().c_str()); CurrentWP = WaypointList.begin(); //Set initial speed if (m_bIsRunning) me->SetWalk(false); else me->SetWalk(true); AddEscortState(STATE_ESCORT_ESCORTING); }
//TODO: get rid of this many variables passed in function. void npc_escortAI::Start(bool bIsActiveAttacker, bool bRun, uint64 uiPlayerGUID, const Quest* pQuest, bool bInstantRespawn, bool bCanLoopPath) { if (m_creature->getVictim()) { error_log("ISCR ERROR: EscortAI attempt to Start while in combat."); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { error_log("ISCR: EscortAI attempt to Start while already escorting."); return; } if (!ScriptWP) // sd2 never adds wp in script, but tc does { if (!WaypointList.empty()) WaypointList.clear(); FillPointMovementListForCreature(); } if (WaypointList.empty()) { if (pQuest != NULL) { error_db_log("TSCR: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", m_pQuestForEscort->GetQuestId()); return; } else return; } //set variables m_bIsActiveAttacker = bIsActiveAttacker; m_bIsRunning = bRun; m_uiPlayerGUID = uiPlayerGUID; m_pQuestForEscort = pQuest; m_bCanInstantRespawn = bInstantRespawn; m_bCanReturnToStart = bCanLoopPath; if (m_bCanReturnToStart && m_bCanInstantRespawn) debug_log("ISCR: EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn."); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MoveIdle(); debug_log("ISCR: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle."); } //disable npcflags m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); debug_log("ISCR: EscortAI started with %u waypoints. ActiveAttacker = %d, Run = %d, PlayerGUID = %u", WaypointList.size(), m_bIsActiveAttacker, m_bIsRunning, m_uiPlayerGUID); CurrentWP = WaypointList.begin(); //Set initial speed if (m_bIsRunning) m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); else m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); AddEscortState(STATE_ESCORT_ESCORTING); JustStartedEscort(); }
// TODO: get rid of this many variables passed in function. void npc_escortAI::Start(bool bRun, const Player* pPlayer, const Quest* pQuest, bool bInstantRespawn, bool bCanLoopPath) { if (m_creature->getVictim()) { script_error_log("EscortAI attempt to Start while in combat."); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { script_error_log("EscortAI attempt to Start while already escorting."); return; } if (!WaypointList.empty()) { WaypointList.clear(); } FillPointMovementListForCreature(); if (WaypointList.empty()) { error_db_log("SD2: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint)."); return; } // set variables m_bIsRunning = bRun; m_playerGuid = pPlayer ? pPlayer->GetObjectGuid() : ObjectGuid(); m_pQuestForEscort = pQuest; m_bCanInstantRespawn = bInstantRespawn; m_bCanReturnToStart = bCanLoopPath; if (m_bCanReturnToStart && m_bCanInstantRespawn) { debug_log("SD2: EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn."); } if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MoveIdle(); debug_log("SD2: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle."); } // disable npcflags m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); debug_log("SD2: EscortAI started with " SIZEFMTD " waypoints. Run = %d, PlayerGuid = %s", WaypointList.size(), m_bIsRunning, m_playerGuid.GetString().c_str()); CurrentWP = WaypointList.begin(); // Set initial speed m_creature->SetWalk(!m_bIsRunning); AddEscortState(STATE_ESCORT_ESCORTING); JustStartedEscort(); }
void Aggro(Unit*) { if (HasEscortState(STATE_ESCORT_ESCORTING)) me->Say(SAY_AGGRO1, LANG_UNIVERSAL, GetPlayerForEscort()->GetGUID()); else me->Say(SAY_AGGRO2, LANG_UNIVERSAL, 0); }
void UpdateAI(uint32 diff) override { _events.Update(diff); if (UpdateVictim()) { while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_FROST_SHOCK: DoCastVictim(SPELL_FROST_SHOCK); _events.DelayEvents(1 * IN_MILLISECONDS); _events.ScheduleEvent(EVENT_FROST_SHOCK, 10s, 15s); break; case EVENT_SEARING_TOTEM: DoCast(me, SPELL_SEARING_TOTEM); _events.DelayEvents(1 * IN_MILLISECONDS); _events.ScheduleEvent(EVENT_SEARING_TOTEM, urand(110, 130) * IN_MILLISECONDS); break; case EVENT_STRENGTH_OF_EARTH_TOTEM: DoCast(me, SPELL_STRENGTH_OF_EARTH_TOTEM); _events.DelayEvents(1 * IN_MILLISECONDS); _events.ScheduleEvent(EVENT_STRENGTH_OF_EARTH_TOTEM, urand(110, 130) * IN_MILLISECONDS); break; case EVENT_HEALING_SURGE: { Unit* target = nullptr; if (me->GetHealthPct() < 85) target = me; else if (Player* player = GetPlayerForEscort()) if (player->GetHealthPct() < 85) target = player; if (target) { DoCast(target, SPELL_HEALING_SURGE); _events.ScheduleEvent(EVENT_HEALING_SURGE, 10s); } else _events.ScheduleEvent(EVENT_HEALING_SURGE, 2s); break; } default: break; } } DoMeleeAttackIfReady(); } if (HasEscortState(STATE_ESCORT_NONE)) return; EscortAI::UpdateAI(diff); if (_phase) { if (_moveTimer <= diff) { switch (_phase) { case PHASE_WP_26: //debug skip path to point 26, buggy path calculation me->GetMotionMaster()->MovePoint(WP_DEBUG_2, -2021.77f, -10648.8f, 129.903f, false); _moveTimer = 2 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; case PHASE_CONTINUE: // continue escort SetEscortPaused(false); _moveTimer = 0 * IN_MILLISECONDS; _phase = PHASE_NONE; break; case PHASE_WP_22: //debug skip path to point 22, buggy path calculation me->GetMotionMaster()->MovePoint(WP_EXPLOSIVES_FIRST_PLANT, -1958.026f, -10660.465f, 111.547f, false); Talk(SAY_LEGOSO_3); _moveTimer = 2 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_KNEEL; break; case PHASE_PLANT_FIRST_KNEEL: // plant first explosives stage 1 kneel me->SetStandState(UNIT_STAND_STATE_KNEEL); _moveTimer = 10 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_STAND; break; case PHASE_PLANT_FIRST_STAND: // plant first explosives stage 1 stand me->SetStandState(UNIT_STAND_STATE_STAND); _moveTimer = 0.5* IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_WORK; break; case PHASE_PLANT_FIRST_WORK: // plant first explosives stage 2 work Talk(SAY_LEGOSO_4); _moveTimer = 17.5 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_FINISH; break; case PHASE_PLANT_FIRST_FINISH: // plant first explosives finish _explosivesGuids.clear(); for (uint8 i = 0; i != MAX_EXPLOSIVES; ++i) { if (GameObject* explosive = me->SummonGameObject(GO_DRAENEI_EXPLOSIVES_1, ExplosivesPos[0][i], QuaternionData(), 0)) _explosivesGuids.push_back(explosive->GetGUID()); } me->HandleEmoteCommand(EMOTE_ONESHOT_NONE); // reset anim state // force runoff movement so he will not screw up next waypoint me->GetMotionMaster()->MovePoint(WP_EXPLOSIVES_FIRST_RUNOFF, -1955.6f, -10669.8f, 110.65f, false); Talk(SAY_LEGOSO_5); _moveTimer = 1.5 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; case PHASE_PLANT_FIRST_TIMER_1: // first explosives detonate timer 1 Talk(SAY_LEGOSO_6); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_TIMER_2; break; case PHASE_PLANT_FIRST_TIMER_2: // first explosives detonate timer 2 Talk(SAY_LEGOSO_7); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_TIMER_3; break; case PHASE_PLANT_FIRST_TIMER_3: // first explosives detonate timer 3 Talk(SAY_LEGOSO_8); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_DETONATE; break; case PHASE_PLANT_FIRST_DETONATE: // first explosives detonate finish for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr) { if (GameObject* explosive = ObjectAccessor::GetGameObject(*me, *itr)) me->RemoveGameObject(explosive, true); } _explosivesGuids.clear(); me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); _moveTimer = 2 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_SPEECH; break; case PHASE_PLANT_FIRST_SPEECH: // after detonation 1 speech Talk(SAY_LEGOSO_9); _moveTimer = 4 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_ROTATE; break; case PHASE_PLANT_FIRST_ROTATE: // after detonation 1 rotate to next point me->SetFacingTo(2.272f); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_FIRST_POINT; break; case PHASE_PLANT_FIRST_POINT: // after detonation 1 send point anim and go on to next point me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); _moveTimer = 2 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; case PHASE_FEEL_SIRONAS_1: // legoso exclamation before sironas 1.1 Talk(SAY_LEGOSO_10); _moveTimer = 4 * IN_MILLISECONDS; _phase = PHASE_FEEL_SIRONAS_2; break; case PHASE_FEEL_SIRONAS_2: // legoso exclamation before sironas 1.2 Talk(SAY_LEGOSO_11); _moveTimer = 4 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; case PHASE_MEET_SIRONAS_ROAR: // legoso exclamation before sironas 2.1 Talk(SAY_LEGOSO_12); _moveTimer = 4 * IN_MILLISECONDS; _phase = PHASE_MEET_SIRONAS_TURN; break; case PHASE_MEET_SIRONAS_TURN: // legoso exclamation before sironas 2.2 if (Player* player = GetPlayerForEscort()) me->SetFacingToObject(player); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_MEET_SIRONAS_SPEECH; break; case PHASE_MEET_SIRONAS_SPEECH: // legoso exclamation before sironas 2.3 Talk(SAY_LEGOSO_13); _moveTimer = 7 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; case PHASE_PLANT_SECOND_KNEEL: // plant second explosives stage 1 kneel me->SetStandState(UNIT_STAND_STATE_KNEEL); _moveTimer = 11 * IN_MILLISECONDS; _phase = PHASE_PLANT_SECOND_SPEECH; break; case PHASE_PLANT_SECOND_SPEECH: // plant second explosives stage 2 kneel Talk(SAY_LEGOSO_14); _moveTimer = 13 * IN_MILLISECONDS; _phase = PHASE_PLANT_SECOND_STAND; break; case PHASE_PLANT_SECOND_STAND: // plant second explosives finish me->SetStandState(UNIT_STAND_STATE_STAND); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_SECOND_FINISH; break; case PHASE_PLANT_SECOND_FINISH: // plant second explosives finish - create explosives _explosivesGuids.clear(); for (uint8 i = 0; i != MAX_EXPLOSIVES; ++i) { if (GameObject* explosive = me->SummonGameObject(GO_DRAENEI_EXPLOSIVES_2, ExplosivesPos[1][i], QuaternionData(), 0)) _explosivesGuids.push_back(explosive->GetGUID()); } Talk(SAY_LEGOSO_15); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_SECOND_WAIT; break; case PHASE_PLANT_SECOND_WAIT: // plant second explosives finish - proceed to next point _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; case PHASE_PLANT_SECOND_TIMER_1: // second explosives detonate timer 1 Talk(SAY_LEGOSO_16); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_SECOND_TIMER_2; break; case PHASE_PLANT_SECOND_TIMER_2: // second explosives detonate timer 2 Talk(SAY_LEGOSO_17); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_SECOND_TIMER_3; break; case PHASE_PLANT_SECOND_TIMER_3: // second explosives detonate timer 3 Talk(SAY_LEGOSO_18); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_PLANT_SECOND_DETONATE; break; case PHASE_PLANT_SECOND_DETONATE: // second explosives detonate finish for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr) { if (GameObject* explosive = ObjectAccessor::GetGameObject(*me, *itr)) me->RemoveGameObject(explosive, true); } _explosivesGuids.clear(); if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS)) { sironas->SetImmuneToAll(false); me->SetFacingToObject(sironas); } _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_FIGHT_SIRONAS_STOP; break; case PHASE_FIGHT_SIRONAS_STOP: // sironas channel stop if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS)) sironas->AI()->DoAction(ACTION_SIRONAS_CHANNEL_STOP); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_FIGHT_SIRONAS_SPEECH_1; break; case PHASE_FIGHT_SIRONAS_SPEECH_1: // sironas exclamation before aggro if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS)) sironas->AI()->Talk(SAY_SIRONAS_1); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_FIGHT_SIRONAS_SPEECH_2; break; case PHASE_FIGHT_SIRONAS_SPEECH_2: // legoso exclamation before aggro if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS)) sironas->SetObjectScale(3.0f); Talk(SAY_LEGOSO_19); _moveTimer = 1 * IN_MILLISECONDS; _phase = PHASE_FIGHT_SIRONAS_START; break; case PHASE_FIGHT_SIRONAS_START: // legoso exclamation at aggro if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS)) { Unit* target = GetPlayerForEscort(); if (!target) target = me; AddThreat(sironas, 0.001f, target); sironas->Attack(target, true); sironas->GetMotionMaster()->MoveChase(target); } _moveTimer = 10 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; case PHASE_SIRONAS_SLAIN_SPEECH_1: // legoso exclamation after battle - stage 1.1 Talk(SAY_LEGOSO_20); _moveTimer = 2 * IN_MILLISECONDS; _phase = PHASE_SIRONAS_SLAIN_EMOTE_1; break; case PHASE_SIRONAS_SLAIN_EMOTE_1: // legoso exclamation after battle - stage 1.2 me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); _moveTimer = 2 * IN_MILLISECONDS; _phase = PHASE_SIRONAS_SLAIN_EMOTE_2; break; case PHASE_SIRONAS_SLAIN_EMOTE_2: // legoso exclamation after battle - stage 1.3 if (Player* player = GetPlayerForEscort()) player->GroupEventHappens(QUEST_ENDING_THEIR_WORLD, me); me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); _moveTimer = 5 * IN_MILLISECONDS; _phase = PHASE_SIRONAS_SLAIN_SPEECH_2; break; case PHASE_SIRONAS_SLAIN_SPEECH_2: // legoso exclamation after battle - stage 2 Talk(SAY_LEGOSO_21); _moveTimer = 30 * IN_MILLISECONDS; _phase = PHASE_CONTINUE; break; default: break; } } else if (!me->IsInCombat()) _moveTimer -= diff; } }
void UpdateEscortAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { if (!HasEscortState(STATE_ESCORT_ESCORTING)) return; if (HasEscortState(STATE_ESCORT_PAUSED)) { if (m_uiExplodeTimer < uiDiff) { if (m_bFirstBarrel) { switch(m_uiExplodePhase) { case 0: DoCastSpellIfCan(m_creature, SPELL_DETONATE_EXPLOSIVES_1); if (Player* pPlayer = GetPlayerForEscort()) DoScriptText(SAY_HELICE_EXPLODE_1, m_creature, pPlayer); m_uiExplodeTimer = 2500; ++m_uiExplodePhase; break; case 1: if (Player* pPlayer = GetPlayerForEscort()) DoScriptText(SAY_HELICE_MOVE_ON, m_creature, pPlayer); m_uiExplodeTimer = 2500; ++m_uiExplodePhase; break; case 2: SetEscortPaused(false); m_uiExplodePhase = 0; m_uiExplodeTimer = 5000; m_bFirstBarrel = false; break; } } else { switch(m_uiExplodePhase) { case 0: DoCastSpellIfCan(m_creature, SPELL_DETONATE_EXPLOSIVES_2); if (Player* pPlayer = GetPlayerForEscort()) DoScriptText(SAY_HELICE_EXPLODE_2, m_creature, pPlayer); m_uiExplodeTimer = 2500; ++m_uiExplodePhase; break; case 1: SetEscortPaused(false); m_uiExplodePhase = 0; m_uiExplodeTimer = 5000; m_bFirstBarrel = true; break; } } } else m_uiExplodeTimer -= uiDiff; } return; } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 uiDiff) { npc_escortAI::UpdateAI(uiDiff); if (HasEscortState(STATE_ESCORT_PAUSED)) { if (waveTimer <= uiDiff) { switch (wave) { case 0: Talk(SAY_BREAKOUT3); SummonAcolyte(3); waveTimer = 20000; break; case 1: Talk(SAY_BREAKOUT4); SummonAcolyte(3); waveTimer = 20000; break; case 2: Talk(SAY_BREAKOUT5); SummonAcolyte(4); waveTimer = 20000; break; case 3: Talk(SAY_BREAKOUT6); me->SummonCreature(NPC_HIGH_INQUISITOR_VALROTH, 1642.329f, -6045.818f, 127.583f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); waveTimer = 1000; break; case 4: { Creature* temp = Unit::GetCreature(*me, valrothGUID); if (!temp || !temp->isAlive()) { Talk(SAY_BREAKOUT8); waveTimer = 5000; } else { waveTimer = 2500; return; } break; } case 5: Talk(SAY_BREAKOUT9); me->RemoveAurasDueToSpell(SPELL_ANTI_MAGIC_ZONE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); waveTimer = 2500; break; case 6: Talk(SAY_BREAKOUT10); SetEscortPaused(false); break; } ++wave; } else waveTimer -= uiDiff; } }
void EnterCombat(Unit* pWho) { if (HasEscortState(STATE_ESCORT_ESCORTING)) DoScriptText(RAND(SAY_ATTACKED_1, SAY_ATTACKED_2), me, pWho); }
void JustDied(Unit* /*killer*/) override { if (HasEscortState(STATE_ESCORT_ESCORTING)) if (Player* player = GetPlayerForEscort()) player->FailQuest(QUEST_VORSHA); }
void EnterCombat(Unit* /*who*/) override { if (HasEscortState(STATE_ESCORT_ESCORTING)) Talk(SAY_ELF_AGGRO); }
void UpdateEscortAI(const uint32 uiDiff) { if (HasEscortState(STATE_ESCORT_PAUSED)) { if (m_uiRitualTimer < uiDiff) { switch(m_uiRitualPhase) { case 0: DoCastSpellIfCan(m_creature, SPELL_IDOL_SHUTDOWN); m_uiRitualTimer = 1000; break; case 1: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 39000; break; case 2: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 20000; break; case 3: DoScriptText(SAY_BELNISTRASZ_3_MIN, m_creature, m_creature); m_uiRitualTimer = 20000; break; case 4: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 40000; break; case 5: DoSummonSpawner(irand(1, 3)); DoScriptText(SAY_BELNISTRASZ_2_MIN, m_creature, m_creature); m_uiRitualTimer = 40000; break; case 6: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 20000; break; case 7: DoScriptText(SAY_BELNISTRASZ_1_MIN, m_creature, m_creature); m_uiRitualTimer = 40000; break; case 8: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 20000; break; case 9: DoScriptText(SAY_BELNISTRASZ_FINISH, m_creature, m_creature); m_uiRitualTimer = 3000; break; case 10: { if (Player* pPlayer = GetPlayerForEscort()) { pPlayer->GroupEventHappens(QUEST_EXTINGUISHING_THE_IDOL, m_creature); if (GameObject* pGo = GetClosestGameObjectWithEntry(m_creature, GO_BELNISTRASZ_BRAZIER, 10.0f)) { if (!pGo->isSpawned()) { pGo->SetRespawnTime(HOUR*IN_MILLISECONDS); pGo->Refresh(); } } } m_creature->RemoveAurasDueToSpell(SPELL_IDOL_SHUTDOWN); SetEscortPaused(false); break; } } ++m_uiRitualPhase; } else m_uiRitualTimer -= uiDiff; return; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiFireballTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_FIREBALL); m_uiFireballTimer = urand(2000,3000); } else m_uiFireballTimer -= uiDiff; if (m_uiFrostNovaTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_FROST_NOVA); m_uiFrostNovaTimer = urand(10000,15000); } else m_uiFrostNovaTimer -= uiDiff; DoMeleeAttackIfReady(); }
void JustEngagedWith(Unit* /*who*/) override { if (HasEscortState(STATE_ESCORT_ESCORTING)) Talk(SAY_ELF_AGGRO); }
void npc_escortAI::UpdateAI(uint32 diff) { //Waypoint Updating if (HasEscortState(STATE_ESCORT_ESCORTING) && !me->GetVictim() && m_uiWPWaitTimer && !HasEscortState(STATE_ESCORT_RETURNING)) { if (m_uiWPWaitTimer <= diff) { //End of the line if (CurrentWP == WaypointList.end()) { if (DespawnAtEnd) { TC_LOG_DEBUG("scripts", "EscortAI reached end of waypoints"); if (m_bCanReturnToStart) { float fRetX, fRetY, fRetZ; me->GetRespawnPosition(fRetX, fRetY, fRetZ); me->GetMotionMaster()->MovePoint(POINT_HOME, fRetX, fRetY, fRetZ); m_uiWPWaitTimer = 0; TC_LOG_DEBUG("scripts", "EscortAI are returning home to spawn location: %u, %f, %f, %f", POINT_HOME, fRetX, fRetY, fRetZ); return; } if (m_bCanInstantRespawn) { me->setDeathState(JUST_DIED); me->Respawn(); } else me->DespawnOrUnsummon(); return; } else { TC_LOG_DEBUG("scripts", "EscortAI reached end of waypoints with Despawn off"); return; } } if (!HasEscortState(STATE_ESCORT_PAUSED)) { me->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); TC_LOG_DEBUG("scripts", "EscortAI start waypoint %u (%f, %f, %f).", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); WaypointStart(CurrentWP->id); m_uiWPWaitTimer = 0; } } else m_uiWPWaitTimer -= diff; } //Check if player or any member of his group is within range if (HasEscortState(STATE_ESCORT_ESCORTING) && m_uiPlayerGUID && !me->GetVictim() && !HasEscortState(STATE_ESCORT_RETURNING)) { if (m_uiPlayerCheckTimer <= diff) { if (DespawnAtFar && !IsPlayerOrGroupInRange()) { TC_LOG_DEBUG("scripts", "EscortAI failed because player/group was to far away or not found"); if (m_bCanInstantRespawn) { me->setDeathState(JUST_DIED); me->Respawn(); } else me->DespawnOrUnsummon(); return; } m_uiPlayerCheckTimer = 1000; } else m_uiPlayerCheckTimer -= diff; } UpdateEscortAI(diff); }
void UpdateEscortAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { if (HasEscortState(STATE_ESCORT_PAUSED)) { if (m_uiEventTimer < uiDiff) { m_uiEventTimer = 7000; switch (m_uiEventCount) { case 0: DoScriptText(SAY_LE_ALMOST, m_creature); break; case 1: DoScriptText(SAY_LE_DRUM, m_creature); break; case 2: if (Creature* pResearcher = GetAvailableResearcher(0)) DoScriptText(SAY_LE_DRUM_REPLY, pResearcher); break; case 3: DoScriptText(SAY_LE_DISCOVERY, m_creature); break; case 4: if (Creature* pResearcher = GetAvailableResearcher(0)) DoScriptText(SAY_LE_DISCOVERY_REPLY, pResearcher); break; case 5: DoScriptText(SAY_LE_NO_LEAVE, m_creature); break; case 6: if (Creature* pResearcher = GetAvailableResearcher(1)) DoScriptText(SAY_LE_NO_LEAVE_REPLY1, pResearcher); break; case 7: if (Creature* pResearcher = GetAvailableResearcher(2)) DoScriptText(SAY_LE_NO_LEAVE_REPLY2, pResearcher); break; case 8: if (Creature* pResearcher = GetAvailableResearcher(3)) DoScriptText(SAY_LE_NO_LEAVE_REPLY3, pResearcher); break; case 9: if (Creature* pResearcher = GetAvailableResearcher(4)) DoScriptText(SAY_LE_NO_LEAVE_REPLY4, pResearcher); break; case 10: DoScriptText(SAY_LE_SHUT, m_creature); break; case 11: if (Creature* pResearcher = GetAvailableResearcher(0)) DoScriptText(SAY_LE_REPLY_HEAR, pResearcher); break; case 12: DoScriptText(SAY_LE_IN_YOUR_FACE, m_creature); m_creature->SummonCreature(NPC_BONE_SIFTER, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break; case 13: DoScriptText(EMOTE_LE_PICK_UP, m_creature); if (Player* pPlayer = GetPlayerForEscort()) { DoScriptText(SAY_LE_THANKS, m_creature, pPlayer); pPlayer->GroupEventHappens(QUEST_DIGGING_BONES, m_creature); } SetEscortPaused(false); break; } ++m_uiEventCount; } else m_uiEventTimer -= uiDiff; } return; } DoMeleeAttackIfReady(); }
void Reset() { if (!HasEscortState(STATE_ESCORT_ESCORTING)) m_bFriendSummoned = false; }
void UpdateAI(const uint32 uiDiff) { npc_escortAI::UpdateAI(uiDiff); if (HasEscortState(STATE_ESCORT_PAUSED)) { if(m_uiWave >= 0 && m_uiWave < 5) { if(!me->HasAuraEffect(SPELL_ANTI_MAGIC_ZONE,0)) DoCast(me,SPELL_ANTI_MAGIC_ZONE,true); } if (m_uiWave_Timer <= uiDiff) { switch (m_uiWave) { case 0: DoScriptText(SAY_BREAKOUT3, me); SummonAcolyte(3); m_uiWave_Timer = 20000; break; case 1: DoScriptText(SAY_BREAKOUT4, me); SummonAcolyte(3); m_uiWave_Timer = 20000; break; case 2: DoScriptText(SAY_BREAKOUT5, me); SummonAcolyte(4); m_uiWave_Timer = 20000; break; case 3: DoScriptText(SAY_BREAKOUT6, me); me->SummonCreature(NPC_HIGH_INQUISITOR_VALROTH, 1642.329f, -6045.818f, 127.583f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); m_uiWave_Timer = 1000; break; case 4: { Creature* temp = Unit::GetCreature(*me, m_uiValrothGUID); if (!temp || !temp->isAlive()) { DoScriptText(SAY_BREAKOUT8, me); m_uiWave_Timer = 5000; } else { m_uiWave_Timer = 2500; return; //return, we don't want m_uiWave to increment now } break; } case 5: DoScriptText(SAY_BREAKOUT9, me); me->RemoveAurasDueToSpell(SPELL_ANTI_MAGIC_ZONE); me->SetReactState(REACT_DEFENSIVE); // i do not know why the armor will also be removed m_uiWave_Timer = 2500; break; case 6: DoScriptText(SAY_BREAKOUT10, me); SetEscortPaused(false); break; } ++m_uiWave; } else m_uiWave_Timer -= uiDiff; } }
void SmartAI::Reset() { if (!HasEscortState(SMART_ESCORT_ESCORTING))//dont mess up escort movement after combat SetRun(true); GetScript()->OnReset(); }
void npc_escortAI::UpdateAI(const uint32 uiDiff) { //Waypoint Updating if (HasEscortState(STATE_ESCORT_ESCORTING) && !m_creature->getVictim() && m_uiWPWaitTimer && !HasEscortState(STATE_ESCORT_RETURNING)) { if (m_uiWPWaitTimer <= uiDiff) { //End of the line if (CurrentWP == WaypointList.end()) { debug_log("SD2: EscortAI reached end of waypoints"); if (m_bCanReturnToStart) { float fRetX, fRetY, fRetZ; m_creature->GetRespawnCoord(fRetX, fRetY, fRetZ); m_creature->GetMotionMaster()->MovePoint(POINT_HOME, fRetX, fRetY, fRetZ); m_uiWPWaitTimer = 0; debug_log("SD2: EscortAI are returning home to spawn location: %u, %f, %f, %f", POINT_HOME, fRetX, fRetY, fRetZ); return; } if (m_bCanInstantRespawn) { m_creature->setDeathState(JUST_DIED); m_creature->Respawn(); } else m_creature->ForcedDespawn(); return; } if (!HasEscortState(STATE_ESCORT_PAUSED)) { m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); debug_log("SD2: EscortAI start waypoint %u (%f, %f, %f).", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); WaypointStart(CurrentWP->id); m_uiWPWaitTimer = 0; } } else m_uiWPWaitTimer -= uiDiff; } //Check if player or any member of his group is within range if (HasEscortState(STATE_ESCORT_ESCORTING) && m_uiPlayerGUID && !m_creature->getVictim() && !HasEscortState(STATE_ESCORT_RETURNING)) { if (m_uiPlayerCheckTimer < uiDiff) { if (!IsPlayerOrGroupInRange()) { debug_log("SD2: EscortAI failed because player/group was to far away or not found"); if (m_bCanInstantRespawn) { m_creature->setDeathState(JUST_DIED); m_creature->Respawn(); } else m_creature->ForcedDespawn(); return; } m_uiPlayerCheckTimer = 1000; } else m_uiPlayerCheckTimer -= uiDiff; } UpdateEscortAI(uiDiff); }
void Reset() { if (!HasEscortState(STATE_ESCORT_ESCORTING)) me->SetStandState(UNIT_STAND_STATE_DEAD); }
void UpdateEscortAI(const uint32 uiDiff) { if (m_uiRandomTalkCooldown) { if (m_uiRandomTalkCooldown <= uiDiff) m_uiRandomTalkCooldown = 0; else m_uiRandomTalkCooldown -= uiDiff; } if (HasEscortState(STATE_ESCORT_PAUSED)) { Player* pPlayer = GetPlayerForEscort(); if (!pPlayer) return; if (m_uiTalkTimer <= uiDiff) { m_uiTalkTimer = 7500; switch (m_uiPointId) { case 5: //to lower city { switch (m_uiTalkCount) { case 1: DoScriptText(SAY_KHAD_SERV_1, me, pPlayer); break; case 2: DoScriptText(SAY_KHAD_SERV_2, me, pPlayer); break; case 3: DoScriptText(SAY_KHAD_SERV_3, me, pPlayer); break; case 4: DoScriptText(SAY_KHAD_SERV_4, me, pPlayer); SetEscortPaused(false); break; } break; } case 24: //in lower city { switch (m_uiTalkCount) { case 5: if (Creature* pShanir = me->FindNearestCreature(NPC_SHANIR, 10.0f)) DoScriptText(SAY_KHAD_INJURED, pShanir, pPlayer); DoScriptText(SAY_KHAD_SERV_5, me, pPlayer); break; case 6: DoScriptText(SAY_KHAD_SERV_6, me, pPlayer); break; case 7: DoScriptText(SAY_KHAD_SERV_7, me, pPlayer); SetEscortPaused(false); break; } break; } case 50: //outside { switch (m_uiTalkCount) { case 8: DoScriptText(SAY_KHAD_SERV_8, me, pPlayer); break; case 9: DoScriptText(SAY_KHAD_SERV_9, me, pPlayer); break; case 10: DoScriptText(SAY_KHAD_SERV_10, me, pPlayer); break; case 11: DoScriptText(SAY_KHAD_SERV_11, me, pPlayer); SetEscortPaused(false); break; } break; } case 63: //scryer { switch (m_uiTalkCount) { case 12: DoScriptText(SAY_KHAD_SERV_12, me, pPlayer); break; case 13: DoScriptText(SAY_KHAD_SERV_13, me, pPlayer); SetEscortPaused(false); break; } break; } case 74: //aldor { switch (m_uiTalkCount) { case 14: DoScriptText(SAY_KHAD_SERV_14, me, pPlayer); break; case 15: DoScriptText(SAY_KHAD_SERV_15, me, pPlayer); break; case 16: DoScriptText(SAY_KHAD_SERV_16, me, pPlayer); break; case 17: DoScriptText(SAY_KHAD_SERV_17, me, pPlayer); SetEscortPaused(false); break; } break; } case 75: //a'dal { switch (m_uiTalkCount) { case 18: DoScriptText(SAY_KHAD_SERV_18, me, pPlayer); break; case 19: DoScriptText(SAY_KHAD_SERV_19, me, pPlayer); break; case 20: DoScriptText(SAY_KHAD_SERV_20, me, pPlayer); break; case 21: DoScriptText(SAY_KHAD_SERV_21, me, pPlayer); pPlayer->AreaExploredOrEventHappens(QUEST_CITY_LIGHT); SetEscortPaused(false); break; } break; } } ++m_uiTalkCount; } else m_uiTalkTimer -= uiDiff; } return; }
void JustDied(Unit* /*killer*/) { Player* player = GetPlayerForEscort(); if (HasEscortState(STATE_ESCORT_ESCORTING) && player) player->FailQuest(QUEST_BITTER_DEPARTURE); }
void Aggro(Unit* /*pWho*/) override { if (HasEscortState(STATE_ESCORT_ESCORTING)) DoScriptText(SAY_ELF_AGGRO, m_creature); }
void SmartAI::UpdatePath(const uint32 diff) { if (!HasEscortState(SMART_ESCORT_ESCORTING)) return; if (mEscortInvokerCheckTimer < diff) { if (!IsEscortInvokerInRange()) { StopPath(mDespawnTime, mEscortQuestID, true); } mEscortInvokerCheckTimer = 1000; } else mEscortInvokerCheckTimer -= diff; // handle pause if (HasEscortState(SMART_ESCORT_PAUSED)) { if (mWPPauseTimer < diff) { if (!me->IsInCombat() && !HasEscortState(SMART_ESCORT_RETURNING) && (mWPReached || mLastWPIDReached == SMART_ESCORT_LAST_OOC_POINT || mForcedPaused)) { GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_RESUMED, NULL, mLastWP->id, GetScript()->GetPathId()); RemoveEscortState(SMART_ESCORT_PAUSED); if (mForcedPaused)// if paused between 2 wps resend movement { ResumePath(); mWPReached = false; mForcedPaused = false; } if (mLastWPIDReached == SMART_ESCORT_LAST_OOC_POINT) mWPReached = true; } mWPPauseTimer = 0; } else { mWPPauseTimer -= diff; } } if (HasEscortState(SMART_ESCORT_RETURNING)) { if (mWPReached)//reached OOC WP { RemoveEscortState(SMART_ESCORT_RETURNING); if (!HasEscortState(SMART_ESCORT_PAUSED)) ResumePath(); mWPReached = false; } } if ((!me->HasReactState(REACT_PASSIVE) && me->IsInCombat()) || HasEscortState(SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING)) return; // handle next wp if (mWPReached)//reached WP { mWPReached = false; if (mCurrentWPID == GetWPCount()) { EndPath(); } else if (WayPoint* wp = GetNextWayPoint()) { SetRun(mRun); me->GetMotionMaster()->MovePoint(wp->id, wp->x, wp->y, wp->z); } } }
//TODO: get rid of this many variables passed in function. void npc_escortAI::Start(bool bIsActiveAttacker, bool bRun, uint64 uiPlayerGUID, const Quest* pQuest, bool bInstantRespawn, bool bCanLoopPath) { if (me->getVictim()) { sLog->outError("TSCR ERROR: EscortAI (script: %s, creature entry: %u) attempts to Start while in combat", me->GetScriptName().c_str(), me->GetEntry()); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { sLog->outError("TSCR: EscortAI (script: %s, creature entry: %u) attempts to Start while already escorting", me->GetScriptName().c_str(), me->GetEntry()); return; } if (!ScriptWP) // sd2 never adds wp in script, but tc does { if (!WaypointList.empty()) WaypointList.clear(); FillPointMovementListForCreature(); } if (WaypointList.empty()) { sLog->outErrorDb("TSCR: EscortAI (script: %s, creature entry: %u) starts with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", me->GetScriptName().c_str(), me->GetEntry(), pQuest ? pQuest->GetQuestId() : 0); return; } //set variables m_bIsActiveAttacker = bIsActiveAttacker; m_bIsRunning = bRun; m_uiPlayerGUID = uiPlayerGUID; m_pQuestForEscort = pQuest; m_bCanInstantRespawn = bInstantRespawn; m_bCanReturnToStart = bCanLoopPath; if (m_bCanReturnToStart && m_bCanInstantRespawn) sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn."); if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MoveIdle(); sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle."); } //disable npcflags me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI started with " UI64FMTD " waypoints. ActiveAttacker = %d, Run = %d, PlayerGUID = " UI64FMTD "", uint64(WaypointList.size()), m_bIsActiveAttacker, m_bIsRunning, m_uiPlayerGUID); CurrentWP = WaypointList.begin(); //Set initial speed if (m_bIsRunning) me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); else me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); AddEscortState(STATE_ESCORT_ESCORTING); }