void SmartAI::EndPath(bool fail) { GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, NULL, mLastWP->id, GetScript()->GetPathId()); RemoveEscortState(SMART_ESCORT_ESCORTING | SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING); mWayPoints = NULL; mCurrentWPID = 0; mWPPauseTimer = 0; mLastWP = NULL; if (mCanRepeatPath) StartPath(mRun, GetScript()->GetPathId(), mCanRepeatPath); else GetScript()->SetPathId(0); ObjectList* targets = GetScript()->GetTargetList(SMART_ESCORT_TARGETS); if (targets && mEscortQuestID) { if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin()))) { Player* plr = (*targets->begin())->ToPlayer(); if(!fail && plr->IsAtGroupRewardDistance(me) && !plr->GetCorpse()) plr->GroupEventHappens(mEscortQuestID, me); if(fail && plr->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) plr->FailQuest(mEscortQuestID); if (Group *pGroup = plr->GetGroup()) { for (GroupReference *gr = pGroup->GetFirstMember(); gr != NULL; gr = gr->next()) { Player *pGroupGuy = gr->getSource(); if(!fail && pGroupGuy->IsAtGroupRewardDistance(me) && !pGroupGuy->GetCorpse()) pGroupGuy->AreaExploredOrEventHappens(mEscortQuestID); if(fail && pGroupGuy->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) pGroupGuy->FailQuest(mEscortQuestID); } } }else { for (ObjectList::iterator iter = targets->begin(); iter != targets->end(); iter++) { if (GetScript()->IsPlayer((*iter))) { Player* plr = (*iter)->ToPlayer(); if(!fail && plr->IsAtGroupRewardDistance(me) && !plr->GetCorpse()) plr->AreaExploredOrEventHappens(mEscortQuestID); if(fail && plr->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) plr->FailQuest(mEscortQuestID); } } } } if (mDespawnState == 1) StartDespawn(); }
void npc_escortAI::SetEscortPaused(bool bPaused) { if (!HasEscortState(STATE_ESCORT_ESCORTING)) return; if (bPaused) AddEscortState(STATE_ESCORT_PAUSED); else RemoveEscortState(STATE_ESCORT_PAUSED); }
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) { if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING)) { return; } // Combat start position reached, continue waypoint movement if (uiPointId == POINT_LAST_POINT) { debug_log("SD2: EscortAI has returned to original position before combat"); m_creature->SetWalk(!m_bIsRunning); RemoveEscortState(STATE_ESCORT_RETURNING); } else if (uiPointId == POINT_HOME) { debug_log("SD2: EscortAI has returned to original home location and will continue from beginning of waypoint list."); CurrentWP = WaypointList.begin(); m_uiWPWaitTimer = 0; } else { // Make sure that we are still on the right waypoint if (CurrentWP->uiId != uiPointId) { script_error_log("EscortAI for Npc %u reached waypoint out of order %u, expected %u.", m_creature->GetEntry(), uiPointId, CurrentWP->uiId); return; } debug_log("SD2: EscortAI waypoint %u reached.", CurrentWP->uiId); // In case we were moving while in combat, we should evade back to this position m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); // Call WP function WaypointReached(CurrentWP->uiId); m_uiWPWaitTimer = CurrentWP->uiWaitTime; ++CurrentWP; } if (!m_uiWPWaitTimer) { // Continue WP Movement if Can if (HasEscortState(STATE_ESCORT_ESCORTING) && !HasEscortState(STATE_ESCORT_PAUSED | STATE_ESCORT_RETURNING) && !m_creature->getVictim()) { MoveToNextWaypoint(); } else { m_uiWPWaitTimer = 1; } } }
void SmartAI::ResumePath() { GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_RESUMED, NULL, mCurrentWPID, GetScript()->GetPathId()); RemoveEscortState(SMART_ESCORT_PAUSED); mForcedPaused = false; mWPReached = false; mWPPauseTimer = 0; SetRun(mRun); if (WaypointMovementGenerator<Creature>* move = dynamic_cast<WaypointMovementGenerator<Creature>*>(me->GetMotionMaster()->top())) move->GetTrackerTimer().Reset(1); }
void SmartAI::UpdatePath(const uint32 diff) { if (!HasEscortState(SMART_ESCORT_ESCORTING)) return; if (mEscortInvokerCheckTimer < diff) { if (!IsEscortInvokerInRange()) { StopPath(0, mEscortQuestID, true); // allow to properly hook out of range despawn action, which in most cases should perform the same operation as dying GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, me); me->DespawnOrUnsummon(1); return; } mEscortInvokerCheckTimer = 1000; } else mEscortInvokerCheckTimer -= diff; // handle pause if (HasEscortState(SMART_ESCORT_PAUSED)) { if (mWPPauseTimer <= diff) { if (!me->IsInCombat() && !HasEscortState(SMART_ESCORT_RETURNING) && (mWPReached || mForcedPaused)) { ResumePath(); } } else mWPPauseTimer -= diff; } else if (m_Ended) // end path { m_Ended = false; StopPath(); return; } if (HasEscortState(SMART_ESCORT_RETURNING)) { if (mOOCReached)//reached OOC WP { mOOCReached = false; RemoveEscortState(SMART_ESCORT_RETURNING); if (!HasEscortState(SMART_ESCORT_PAUSED)) ResumePath(); } } }
void npc_escortAI::MovementInform(uint32 moveType, uint32 pointId) { if(moveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING)) return; //Combat start position reached, continue waypoint movement if(pointId == POINT_LAST_POINT) { sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI has returned to original position before combat"); if(m_bIsRunning && me->HasUnitMovementFlag(MOVEMENTFLAG_WALKING)) me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); else if(!m_bIsRunning && !me->HasUnitMovementFlag(MOVEMENTFLAG_WALKING)) me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); RemoveEscortState(STATE_ESCORT_RETURNING); if(!m_uiWPWaitTimer) m_uiWPWaitTimer = 1; } else if(pointId == POINT_HOME) { sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list."); CurrentWP = WaypointList.begin(); m_uiWPWaitTimer = 1; } else { if(WaypointList.empty() || CurrentWP == WaypointList.end()) { sLog->outError("TSCR ERROR: EscortAI has no current WP set up for point %u of creature entry %u", pointId, me->GetEntry()); return; } //Make sure that we are still on the right waypoint if(CurrentWP->id != pointId) { sLog->outError("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u, creature entry %u", pointId, CurrentWP->id, me->GetEntry()); return; } sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI Waypoint %u reached", CurrentWP->id); //Call WP function WaypointReached(CurrentWP->id); m_uiWPWaitTimer = CurrentWP->WaitTimeMs + 1; ++CurrentWP; } }
void SmartAI::ResumePath() { GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_RESUMED, nullptr, _currentWaypointNode, GetScript()->GetPathId()); RemoveEscortState(SMART_ESCORT_PAUSED); _waypointPauseForced = false; _waypointReached = false; _waypointPauseTimer = 0; SetRun(mRun); me->ResumeMovement(); }
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) { if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING)) return; //Combat start position reached, continue waypoint movement if (uiPointId == POINT_LAST_POINT) { debug_log("SD0: EscortAI has returned to original position before combat"); if (m_bIsRunning && m_creature->HasSplineFlag(SPLINEFLAG_WALKMODE)) m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); else if (!m_bIsRunning && !m_creature->HasSplineFlag(SPLINEFLAG_WALKMODE)) m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE); RemoveEscortState(STATE_ESCORT_RETURNING); if (!m_uiWPWaitTimer) m_uiWPWaitTimer = 1; } else if (uiPointId == POINT_HOME) { debug_log("SD0: EscortAI has returned to original home location and will continue from beginning of waypoint list."); CurrentWP = WaypointList.begin(); m_uiWPWaitTimer = 1; } else { //Make sure that we are still on the right waypoint if (CurrentWP->uiId != uiPointId) { error_log("SD0: EscortAI for Npc %u reached waypoint out of order %u, expected %u.", m_creature->GetEntry(), uiPointId, CurrentWP->uiId); return; } debug_log("SD0: EscortAI waypoint %u reached.", CurrentWP->uiId); // In case we were moving while in combat, we should evade back to this position m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); //Call WP function WaypointReached(CurrentWP->uiId); m_uiWPWaitTimer = CurrentWP->uiWaitTime + 1; ++CurrentWP; } }
void npc_escortAI::SetEscortPaused(bool bPaused) { if (!HasEscortState(STATE_ESCORT_ESCORTING)) return; if (bPaused) { AddEscortState(STATE_ESCORT_PAUSED); m_creature->addUnitState(UNIT_STAT_WAYPOINT_PAUSED); } else { RemoveEscortState(STATE_ESCORT_PAUSED); m_creature->clearUnitState(UNIT_STAT_WAYPOINT_PAUSED); } }
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) { if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING) || me->isInCombat()) return; //Combat start position reached, continue waypoint movement if (uiPointId == POINT_LAST_POINT) { debug_log("TSCR: EscortAI has returned to original position before combat"); if (IsRunning && me->IsWalking()) me->SetWalk(false); else if (!IsRunning && !me->IsWalking()) me->SetWalk(true); me->GetUnitStateMgr().InitDefaults(false); RemoveEscortState(STATE_ESCORT_INCOMBAT); if (!WPWaitTimer) WPWaitTimer = 1; } else if (uiPointId == POINT_HOME) { debug_log("TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list."); CurrentWP = WaypointList.begin(); WPWaitTimer = 1; } else { //Make sure that we are still on the right waypoint if (CurrentWP->id != uiPointId) { error_log("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u", uiPointId, CurrentWP->id); return; } debug_log("TSCR: EscortAI Waypoint %u reached", CurrentWP->id); //Call WP function WaypointReached(CurrentWP->id); WPWaitTimer = CurrentWP->WaitTimeMs + 1; ++CurrentWP; } }
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) { if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING)) return; //Combat start position reached, continue waypoint movement if (uiPointId == POINT_LAST_POINT) { debug_log("TSCR: EscortAI has returned to original position before combat"); if (m_bIsRunning && m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE)) m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); else if (!m_bIsRunning && !m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE)) m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); RemoveEscortState(STATE_ESCORT_RETURNING); if (!m_uiWPWaitTimer) m_uiWPWaitTimer = 1; } else if (uiPointId == POINT_HOME) { debug_log("TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list."); CurrentWP = WaypointList.begin(); m_uiWPWaitTimer = 1; } else { //Make sure that we are still on the right waypoint if (CurrentWP->id != uiPointId) { error_log("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u", uiPointId, CurrentWP->id); return; } debug_log("TSCR: EscortAI Waypoint %u reached", CurrentWP->id); //Call WP function WaypointReached(CurrentWP->id); m_uiWPWaitTimer = CurrentWP->WaitTimeMs + 1; ++CurrentWP; } }
void SmoothEscortAI::EnterEvadeMode() { if (HasEscortState(ESCORT_STATE_COMBAT)) { Reset(); RemoveEscortState(ESCORT_STATE_COMBAT); me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(true); me->SetLootRecipient(NULL); me->LoadCreaturesAddon(); me->StopMoving(); if (HasEscortState(ESCORT_STATE_ESCORTING)) StartMove(); else me->GetMotionMaster()->MoveTargetedHome(); } }
void npc_escortAI::MovementInform(uint32 moveType, uint32 pointId) { if (moveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING)) return; //Combat start position reached, continue waypoint movement if (pointId == POINT_LAST_POINT) { TC_LOG_DEBUG("scripts", "EscortAI has returned to original position before combat"); me->SetWalk(!m_bIsRunning); RemoveEscortState(STATE_ESCORT_RETURNING); if (!m_uiWPWaitTimer) m_uiWPWaitTimer = 1; } else if (pointId == POINT_HOME) { TC_LOG_DEBUG("scripts", "EscortAI has returned to original home location and will continue from beginning of waypoint list."); CurrentWP = WaypointList.begin(); m_uiWPWaitTimer = 1; } else { //Make sure that we are still on the right waypoint if (CurrentWP->id != pointId) { TC_LOG_ERROR("misc", "TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u, creature entry %u", pointId, CurrentWP->id, me->GetEntry()); return; } TC_LOG_DEBUG("scripts", "EscortAI Waypoint %u reached", CurrentWP->id); //Call WP function WaypointReached(CurrentWP->id); m_uiWPWaitTimer = CurrentWP->WaitTimeMs + 1; ++CurrentWP; } }
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->isInCombat() || HasEscortState(SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING)) return; // handle next wp if (mWPReached)//reached WP { mWPReached = false; if (mCurrentWPID == GetWPCount()) { EndPath(); } else { WayPoint* wp = GetNextWayPoint(); if (wp) { SetRun(mRun); me->GetMotionMaster()->MovePoint(wp->id, wp->x, wp->y, wp->z); } } } }
void CreatureStartAttackDoor() { RemoveEscortState(STATE_ESCORT_ESCORTING | STATE_ESCORT_RETURNING | STATE_ESCORT_PAUSED); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); me->CastSpell((Unit*)NULL, SPELL_DESTROY_DOOR_SEAL, true); }
void SmartAI::EndPath(bool fail) { RemoveEscortState(SMART_ESCORT_ESCORTING | SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING); _path.nodes.clear(); _waypointPauseTimer = 0; if (_escortNPCFlags) { me->SetFlag(UNIT_NPC_FLAGS, _escortNPCFlags); _escortNPCFlags = 0; } ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS, *me); if (targets && mEscortQuestID) { if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin()))) { Player* player = targets->front()->ToPlayer(); if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse()) player->GroupEventHappens(mEscortQuestID, me); if (fail) player->FailQuest(mEscortQuestID); if (Group* group = player->GetGroup()) { for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next()) { Player* groupGuy = groupRef->GetSource(); if (!groupGuy->IsInMap(player)) continue; if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->HasCorpse()) groupGuy->AreaExploredOrEventHappens(mEscortQuestID); else if (fail) groupGuy->FailQuest(mEscortQuestID); } } } else { for (WorldObject* target : *targets) { if (GetScript()->IsPlayer(target)) { Player* player = target->ToPlayer(); if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse()) player->AreaExploredOrEventHappens(mEscortQuestID); else if (fail) player->FailQuest(mEscortQuestID); } } } } // End Path events should be only processed if it was SUCCESSFUL stop or stop called by SMART_ACTION_WAYPOINT_STOP if (fail) return; GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, _currentWaypointNode, GetScript()->GetPathId()); if (_repeatWaypointPath) { if (IsAIControlled()) StartPath(mRun, GetScript()->GetPathId(), _repeatWaypointPath); } else GetScript()->SetPathId(0); if (mDespawnState == 1) StartDespawn(); }
void npc_escortAI::UpdateAI(const uint32 uiDiff) { //Waypoint Updating if (HasEscortState(STATE_ESCORT_ESCORTING) && !me->isInCombat() && WPWaitTimer && !HasEscortState(STATE_ESCORT_INCOMBAT)) { if (WPWaitTimer <= uiDiff) { //End of the line if (CurrentWP == WaypointList.end()) { if (DespawnAtEnd) { if (CanReturnToStart) { float fRetX, fRetY, fRetZ; me->GetRespawnCoord(fRetX, fRetY, fRetZ); me->GetMotionMaster()->MovePoint(POINT_HOME, fRetX, fRetY, fRetZ, UNIT_ACTION_CHASE); WPWaitTimer = 0; debug_log("TSCR: EscortAI are returning home to spawn location: %u, %f, %f, %f", POINT_HOME, fRetX, fRetY, fRetZ); return; } if (CanInstantRespawn) { me->setDeathState(JUST_DIED); me->Respawn(); } else me->ForcedDespawn(); return; } else { if (ClearWaypoints) { WaypointList.clear(); RemoveEscortState(STATE_ESCORT_ESCORTING); ScriptWP = false; } debug_log("TSCR: 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); debug_log("TSCR: EscortAI start waypoint %u (%f, %f, %f).", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); WaypointStart(CurrentWP->id); WPWaitTimer = 0; } } else WPWaitTimer -= uiDiff; } //Check if player or any member of his group is within range if (HasEscortState(STATE_ESCORT_ESCORTING) && PlayerGUID && !me->isInCombat() && !HasEscortState(STATE_ESCORT_INCOMBAT)) { if (PlayerCheckTimer < uiDiff) { if (DespawnAtFar && !IsPlayerOrGroupInRange()) { debug_log("TSCR: EscortAI failed because player/group was to far away or not found"); if (CanInstantRespawn) { me->setDeathState(JUST_DIED); me->Respawn(); } else me->ForcedDespawn(); return; } PlayerCheckTimer = 1000; } else PlayerCheckTimer -= uiDiff; } UpdateEscortAI(uiDiff); }
void SmartAI::EndPath(bool fail) { RemoveEscortState(SMART_ESCORT_ESCORTING | SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING); mWayPoints = NULL; mLastWP = NULL; mWPPauseTimer = 0; if (mEscortNPCFlags) { me->SetUInt32Value(UNIT_NPC_FLAGS, mEscortNPCFlags); mEscortNPCFlags = 0; } ObjectList* targets = GetScript()->GetTargetList(SMART_ESCORT_TARGETS); if (targets && mEscortQuestID) { if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin()))) { Player* player = (*targets->begin())->ToPlayer(); if (Group* group = player->GetGroup()) { for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) { Player* groupGuy = groupRef->GetSource(); if (!groupGuy || !player->IsInMap(groupGuy)) continue; if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->GetCorpse()) groupGuy->AreaExploredOrEventHappens(mEscortQuestID); else if (fail && groupGuy->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) groupGuy->FailQuest(mEscortQuestID); } } else { if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse()) player->GroupEventHappens(mEscortQuestID, me); else if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) player->FailQuest(mEscortQuestID); } } else { for (ObjectList::iterator iter = targets->begin(); iter != targets->end(); ++iter) { if (GetScript()->IsPlayer((*iter))) { Player* player = (*iter)->ToPlayer(); if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse()) player->AreaExploredOrEventHappens(mEscortQuestID); else if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) player->FailQuest(mEscortQuestID); } } } } // Xinef: if the escort failed - DO NOT PROCESS ANYTHING, ITS RETARDED // Xinef: End Path events should be only processed if it was SUCCESSFUL stop or stop called by SMART_ACTION_WAYPOINT_STOP if (fail) { mCurrentWPID = 0; return; } GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, NULL, mCurrentWPID, GetScript()->GetPathId()); mCurrentWPID = 0; if (mCanRepeatPath) StartPath(mRun, GetScript()->GetPathId(), mCanRepeatPath); else GetScript()->SetPathId(0); if (mDespawnState == 1) StartDespawn(); }
void SmartAI::UpdatePath(const uint32 diff) { if (!HasEscortState(SMART_ESCORT_ESCORTING)) return; if (mEscortInvokerCheckTimer < diff) { // Xinef: Escort failed - no players in range // Xinef: Despawn immediately if (!IsEscortInvokerInRange()) { StopPath(0, mEscortQuestID, true); // Xinef: allow to properly hook out of range despawn action, which in most cases should perform the same operation as dying GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, me); me->DespawnOrUnsummon(1); return; } mEscortInvokerCheckTimer = 1000; } else mEscortInvokerCheckTimer -= diff; // handle pause if (HasEscortState(SMART_ESCORT_PAUSED)) { if (mWPPauseTimer < diff) { if (!me->IsInCombat() && !HasEscortState(SMART_ESCORT_RETURNING) && (mWPReached || mForcedPaused)) { GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_RESUMED, NULL, mCurrentWPID, GetScript()->GetPathId()); RemoveEscortState(SMART_ESCORT_PAUSED); if (mForcedPaused)// if paused between 2 wps resend movement { mWPReached = false; mForcedPaused = false; ResumePath(); } mWPPauseTimer = 0; } } else mWPPauseTimer -= diff; } if (HasEscortState(SMART_ESCORT_RETURNING)) { if (mOOCReached)//reached OOC WP { mOOCReached = false; RemoveEscortState(SMART_ESCORT_RETURNING); if (!HasEscortState(SMART_ESCORT_PAUSED)) ResumePath(); } } if ((me->GetVictim() && me->IsInCombat()) || HasEscortState(SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING)) return; // handle next wp if (!me->HasUnitState(UNIT_STATE_NOT_MOVE) && me->movespline->Finalized())//reached WP { if (!mWPReached) { ResumePath(); return; } mWPReached = false; if (mCurrentWPID == GetWPCount()) EndPath(); else if (GetNextWayPoint()) { SetRun(mRun); // xinef: if we have reached waypoint, and there is no working spline movement it means our splitted array has ended, make new one if (me->movespline->Finalized()) ResumePath(); } } }
void SmoothEscortAI::UpdateAI(uint32 diff) { if (HasEscortState(ESCORT_STATE_COMBAT) && !me->IsInCombat()) EnterEvadeMode(); if (HasEscortState(ESCORT_STATE_PAUSED) || HasEscortState(ESCORT_STATE_NONE) || HasEscortState(ESCORT_STATE_COMBAT)) return; if (me->HasUnitState(UNIT_STATE_ROOT) || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_DISTRACTED)) return; nextMoveTime.Update(diff); if (nextMoveTime.GetExpiry() <= timeDiff) { if (waypointList.empty()) { RemoveEscortState(ESCORT_STATE_ESCORTING); AddEscortState(ESCORT_STATE_NONE); return; } if (HasEscortState(ESCORT_STATE_WAITING)) { RemoveEscortState(ESCORT_STATE_WAITING); StartMove(); return; } WaypointReached(currentWP->id); if (currentWP->waitTimeMs) { nextMoveTime.Reset(currentWP->waitTimeMs); AddEscortState(ESCORT_STATE_WAITING); return; } if (currentWPId == waypointList.size() - 1) { if (!repeat) { me->SetHomePosition(currentWP->x, currentWP->y, currentWP->z, me->GetOrientation()); me->ClearUnitState(UNIT_STATE_ROAMING_MOVE); me->GetMotionMaster()->Initialize(); waypointList.clear(); FinishEscort(); RemoveEscortState(ESCORT_STATE_ESCORTING); AddEscortState(ESCORT_STATE_NONE); if (despawnAtEnd) me->DespawnOrUnsummon(); return; } currentWP = waypointList.begin(); currentWPId = 0; } else { ++currentWP; ++currentWPId; } StartMove(); } }
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(); } if (m_despawnAtEnd) m_creature->ForcedDespawn(); else RemoveEscortState(STATE_ESCORT_ESCORTING); 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); }