void SmartAI::StartPath(bool run, uint32 path, bool repeat, Unit* /*invoker*/) { if (me->isInCombat())// no wp movement in combat { sLog->outError("SmartAI::StartPath: Creature entry %u wanted to start waypoint movement while in combat, ignoring.", me->GetEntry()); return; } if (HasEscortState(SMART_ESCORT_ESCORTING)) StopPath(); if (path) if (!LoadPath(path)) return; if (!mWayPoints || mWayPoints->empty()) return; AddEscortState(SMART_ESCORT_ESCORTING); mCanRepeatPath = repeat; SetRun(run); WayPoint* wp = GetNextWayPoint(); if (wp) { me->GetPosition(&mLastOOCPos); me->GetMotionMaster()->MovePoint(wp->id, wp->x, wp->y, wp->z); GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_START, NULL, wp->id, GetScript()->GetPathId()); } }
void npc_escortAI::EnterEvadeMode() { m_creature->RemoveAllAurasOnEvade(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); m_creature->SetLootRecipient(NULL); if (HasEscortState(STATE_ESCORT_ESCORTING)) { // We have left our path if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) { debug_log("SD2: EscortAI has left combat and is now returning to CombatStartPosition."); AddEscortState(STATE_ESCORT_RETURNING); float fPosX, fPosY, fPosZ; m_creature->GetCombatStartPosition(fPosX, fPosY, fPosZ); m_creature->GetMotionMaster()->MovePoint(POINT_LAST_POINT, fPosX, fPosY, fPosZ); } } else m_creature->GetMotionMaster()->MoveTargetedHome(); Reset(); }
void SmartAI::EnterEvadeMode(EvadeReason /*why*/) { if (!me->IsAlive() || me->IsInEvadeMode()) return; me->RemoveAurasOnEvade(); me->AddUnitState(UNIT_STATE_EVADE); _EnterEvadeMode(); GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db SetRun(mRun); if (HasEscortState(SMART_ESCORT_ESCORTING)) { AddEscortState(SMART_ESCORT_RETURNING); ReturnToLastOOCPos(); } else if (mFollowGuid) { if (Unit* target = ObjectAccessor::GetUnit(*me, mFollowGuid)) me->GetMotionMaster()->MoveFollow(target, mFollowDist, mFollowAngle); // evade is not cleared in MoveFollow, so we can't keep it me->ClearUnitState(UNIT_STATE_EVADE); } else me->GetMotionMaster()->MoveTargetedHome(); if (!HasEscortState(SMART_ESCORT_ESCORTING))//dont mess up escort movement after combat SetRun(mRun); }
void SmartAI::EnterEvadeMode() { if (!me->isAlive()) return; me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(true); me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); me->ResetPlayerDamageReq(); GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db SetRun(mRun); if (HasEscortState(SMART_ESCORT_ESCORTING)) { AddEscortState(SMART_ESCORT_RETURNING); ReturnToLastOOCPos(); } else if (mFollowGuid) { if (Unit* target = me->GetUnit(*me, mFollowGuid)) me->GetMotionMaster()->MoveFollow(target, mFollowDist, mFollowAngle); } else { me->GetMotionMaster()->MoveTargetedHome(); } Reset(); }
void SmartAI::PausePath(uint32 delay, bool forced) { if (!HasEscortState(SMART_ESCORT_ESCORTING)) return; if (HasEscortState(SMART_ESCORT_PAUSED)) { sLog->outError("SmartAI::StartPath: Creature entry %u wanted to pause waypoint movement while already paused, ignoring.", me->GetEntry()); return; } AddEscortState(SMART_ESCORT_PAUSED); mWPPauseTimer = delay; if (forced && !mWPReached) { mForcedPaused = forced; SetRun(mRun); if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_ACTIVE) == ESCORT_MOTION_TYPE) me->GetMotionMaster()->MovementExpired(); me->StopMoving(); me->GetMotionMaster()->MoveIdle();//force stop } GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_PAUSED, NULL, mCurrentWPID, GetScript()->GetPathId()); }
void SmartAI::EnterEvadeMode() { if (!me->IsAlive() || me->IsInEvadeMode()) return; me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_CLONE_CASTER); me->AddUnitState(UNIT_STATE_EVADE); me->DeleteThreatList(); me->CombatStop(true); me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); me->ResetPlayerDamageReq(); me->SetLastDamagedTime(0); GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db SetRun(mRun); if (HasEscortState(SMART_ESCORT_ESCORTING)) { AddEscortState(SMART_ESCORT_RETURNING); ReturnToLastOOCPos(); } else if (mFollowGuid) { if (Unit* target = me->GetUnit(*me, mFollowGuid)) me->GetMotionMaster()->MoveFollow(target, mFollowDist, mFollowAngle); } else me->GetMotionMaster()->MoveTargetedHome(); if (!HasEscortState(SMART_ESCORT_ESCORTING))//dont mess up escort movement after combat SetRun(mRun); }
//TODO: get rid of this many variables passed in function. void npc_escortAI::Start(bool bRun, uint64 uiPlayerGUID, const Quest* pQuest, bool bInstantRespawn, bool bCanLoopPath) { if (m_creature->getVictim()) { error_log("SD2: EscortAI attempt to Start while in combat."); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { error_log("SD2: 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_uiPlayerGUID = uiPlayerGUID; 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 = " UI64FMTD, WaypointList.size(), m_bIsRunning, m_uiPlayerGUID); CurrentWP = WaypointList.begin(); //Set initial speed if (m_bIsRunning) m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE); AddEscortState(STATE_ESCORT_ESCORTING); JustStartedEscort(); }
void npc_escortAI::SetEscortPaused(bool bPaused) { if (!HasEscortState(STATE_ESCORT_ESCORTING)) return; if (bPaused) AddEscortState(STATE_ESCORT_PAUSED); else RemoveEscortState(STATE_ESCORT_PAUSED); }
void SmartAI::EnterEvadeMode() { // xinef: fixes strange jumps when charming SmartAI npc if (!me->IsAlive() || me->IsInEvadeMode()) return; if (IS_PLAYER_GUID(me->GetCharmerGUID()) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) { me->AttackStop(); return; } me->RemoveEvadeAuras(); me->AddUnitState(UNIT_STATE_EVADE); me->DeleteThreatList(); me->CombatStop(true); me->LoadCreaturesAddon(true); me->SetLootRecipient(NULL); me->ResetPlayerDamageReq(); me->SetLastDamagedTime(0); GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db SetRun(mRun); if (HasEscortState(SMART_ESCORT_ESCORTING)) { AddEscortState(SMART_ESCORT_RETURNING); ReturnToLastOOCPos(); } else if (mFollowGuid) { if (Unit* target = ObjectAccessor::GetUnit(*me, mFollowGuid)) me->GetMotionMaster()->MoveFollow(target, mFollowDist, mFollowAngle); me->ClearUnitState(UNIT_STATE_EVADE); // xinef: do not forget to reset scripts as we wont call reached home GetScript()->OnReset(); } else { me->GetMotionMaster()->MoveTargetedHome(); // xinef: do not forget to reset scripts as we wont call reached home if (!me->HasUnitState(UNIT_STATE_EVADE)) GetScript()->OnReset(); } }
// 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 (!pSystemMgr.GetPathInfo(m_creature->GetEntry(), 1)) { script_error_log("EscortAI attempt to start escorting for %s, but has no waypoints loaded", m_creature->GetGuidStr().c_str()); 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."); // disable npcflags m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); AddEscortState(STATE_ESCORT_ESCORTING); // Set initial speed m_creature->SetWalk(!m_bIsRunning); m_creature->StopMoving(); // Start moving along the path with 2500ms delay m_creature->GetMotionMaster()->Clear(false, true); m_creature->GetMotionMaster()->MoveWaypoint(1, 3, 2500); JustStartedEscort(); }
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::EnterEvadeMode() { me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(true); me->SetLootRecipient(NULL); if (HasEscortState(STATE_ESCORT_ESCORTING)) { AddEscortState(STATE_ESCORT_RETURNING); ReturnToLastPoint(); sLog->outDebug( LOG_FILTER_TSCR, "TSCR: EscortAI (script: %s, creature entry: %u) has left combat and is now returning to last point"); } else { me->GetMotionMaster()->MoveTargetedHome(); Reset(); } }
void npc_escortAI::AttackStart(Unit* pWho) { if (!pWho) return; if (me->Attack(pWho, true)) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE && !HasEscortState(STATE_ESCORT_INCOMBAT)) AddEscortState(STATE_ESCORT_INCOMBAT); if (IsCombatMovement()) { me->StopMoving(); me->GetMotionMaster()->MoveChase(pWho); } } }
void SmartAI::EnterEvadeMode(EvadeReason /*why*/) { if (mEvadeDisabled) { GetScript()->ProcessEventsFor(SMART_EVENT_EVADE); return; } if (!IsAIControlled()) { me->AttackStop(); return; } if (!_EnterEvadeMode()) return; me->AddUnitState(UNIT_STATE_EVADE); GetScript()->ProcessEventsFor(SMART_EVENT_EVADE); // must be after _EnterEvadeMode (spells, auras, ...) SetRun(mRun); if (Unit* owner = me->GetCharmerOrOwner()) { me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); me->ClearUnitState(UNIT_STATE_EVADE); } else if (HasEscortState(SMART_ESCORT_ESCORTING)) { AddEscortState(SMART_ESCORT_RETURNING); ReturnToLastOOCPos(); } else if (Unit* target = mFollowGuid ? ObjectAccessor::GetUnit(*me, mFollowGuid) : nullptr) { me->GetMotionMaster()->MoveFollow(target, mFollowDist, mFollowAngle); // evade is not cleared in MoveFollow, so we can't keep it me->ClearUnitState(UNIT_STATE_EVADE); } else me->GetMotionMaster()->MoveTargetedHome(); if (!me->HasUnitState(UNIT_STATE_EVADE)) GetScript()->OnReset(); }
void npc_escortAI::EnterEvadeMode() { m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); m_creature->SetLootRecipient(NULL); if (HasEscortState(STATE_ESCORT_ESCORTING)) { AddEscortState(STATE_ESCORT_RETURNING); ReturnToLastPoint(); debug_log("TSCR: EscortAI has left combat and is now returning to last point"); } else { m_creature->GetMotionMaster()->MoveTargetedHome(); Reset(); } }
void SmoothEscortAI::AttackStart(Unit* who) { if (!who) return; if (me->Attack(who, true)) { if (!HasEscortState(ESCORT_STATE_COMBAT)) { AddEscortState(ESCORT_STATE_COMBAT); me->StopMoving(); Position pos; me->GetPosition(&pos); me->SetHomePosition(pos); } if (IsCombatMovementAllowed()) me->GetMotionMaster()->MoveChase(who); } }
void SmartAI::PausePath(uint32 delay, bool forced) { if (!HasEscortState(SMART_ESCORT_ESCORTING)) return; if (HasEscortState(SMART_ESCORT_PAUSED)) { sLog->outError("SmartAI::StartPath: Creature entry %u wanted to pause waypoint movement while already paused, ignoring.", me->GetEntry()); return; } mForcedPaused = forced; me->GetPosition(&mLastOOCPos); AddEscortState(SMART_ESCORT_PAUSED); mWPPauseTimer = delay; if (forced) { SetRun(mRun); me->StopMoving();//force stop me->GetMotionMaster()->MoveIdle();//force stop } GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_PAUSED, NULL, mLastWP->id, GetScript()->GetPathId()); }
void npc_escortAI::EnterEvadeMode(EvadeReason /*why*/) { me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(true); me->SetLootRecipient(NULL); if (HasEscortState(STATE_ESCORT_ESCORTING)) { AddEscortState(STATE_ESCORT_RETURNING); ReturnToLastPoint(); TC_LOG_DEBUG("scripts", "EscortAI has left combat and is now returning to last point"); } else { me->GetMotionMaster()->MoveTargetedHome(); if (HasImmuneToNPCFlags) me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); Reset(); } }
void SmartAI::PausePath(uint32 delay, bool forced) { if (!HasEscortState(SMART_ESCORT_ESCORTING)) return; if (HasEscortState(SMART_ESCORT_PAUSED)) { TC_LOG_ERROR("misc", "SmartAI::PausePath: Creature entry %u wanted to pause waypoint (current waypoint: %u) movement while already paused, ignoring.", me->GetEntry(), mCurrentWPID); return; } AddEscortState(SMART_ESCORT_PAUSED); mWPPauseTimer = delay; if (forced && !mWPReached) { mForcedPaused = forced; SetRun(mRun); me->StopMoving(); } GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_PAUSED, nullptr, mCurrentWPID, GetScript()->GetPathId()); }
void EnterEvadeMode() { if (!HasEscortState(STATE_ESCORT_ESCORTING)) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); me->SetHomePosition(1845.577759f+rand_norm()*5-2.5f, 800.681152f+rand_norm()*5-2.5f, 44.104248f, M_PI); } me->DeleteThreatList(); me->CombatStop(true); if (HasEscortState(STATE_ESCORT_ESCORTING)) { AddEscortState(STATE_ESCORT_RETURNING); ReturnToLastPoint(); } else { me->GetMotionMaster()->MoveTargetedHome(); Reset(); } me->ClearUnitState(UNIT_STATE_EVADE); }
void SmartAI::StartPath(bool run, uint32 path, bool repeat, Unit* invoker) { if (me->IsInCombat())// no wp movement in combat { sLog->outError("SmartAI::StartPath: Creature entry %u wanted to start waypoint movement while in combat, ignoring.", me->GetEntry()); return; } if (HasEscortState(SMART_ESCORT_ESCORTING)) StopPath(); if (path) { if (!LoadPath(path)) return; } if (!mWayPoints || mWayPoints->empty()) return; if (WayPoint* wp = GetNextWayPoint()) { AddEscortState(SMART_ESCORT_ESCORTING); mCanRepeatPath = repeat; SetRun(run); if (invoker && invoker->GetTypeId() == TYPEID_PLAYER) { mEscortNPCFlags = me->GetUInt32Value(UNIT_NPC_FLAGS); me->SetUInt32Value(UNIT_NPC_FLAGS, 0); } Movement::PointsArray pathPoints; GenerateWayPointArray(&pathPoints); me->GetMotionMaster()->MoveSplinePath(&pathPoints); GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_START, NULL, wp->id, GetScript()->GetPathId()); } }
void SmartAI::EnterEvadeMode() { if (!me->isAlive() || me->IsInEvadeMode()) return; RemoveAuras(); me->AddUnitState(UNIT_STATE_EVADE); me->DeleteThreatList(); me->CombatStop(true); me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); me->ResetPlayerDamageReq(); GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db SetRun(mRun); if (HasEscortState(SMART_ESCORT_ESCORTING)) { AddEscortState(SMART_ESCORT_RETURNING); ReturnToLastOOCPos(); } else if (mFollowGuid) { if (Unit* target = me->GetUnit(*me, mFollowGuid)) me->GetMotionMaster()->MoveFollow(target, mFollowDist, mFollowAngle); } else { mCanCombatMove = true; me->GetMotionMaster()->MoveTargetedHome(); } //sLog->OutSpecialLog("SmartAI::EnterEvadeMode Entry %u" , me->GetEntry()); if (!HasEscortState(SMART_ESCORT_ESCORTING)) // Don't mess up escort movement after combat. SetRun(mRun); }
//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("TSCR ERROR: EscortAI attempt to Start while in combat."); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { error_log("TSCR: 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()) { error_db_log("TSCR: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", 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) debug_log("TSCR: 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("TSCR: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle."); } //disable npcflags m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); debug_log("TSCR: 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); }
//TODO: get rid of this many variables passed in function. void npc_escortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, uint64 playerGUID /* = 0 */, Quest const* quest /* = NULL */, bool instantRespawn /* = false */, bool canLoopPath /* = false */, bool resetWaypoints /* = true */) { 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 && resetWaypoints) // 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(), quest ? quest->GetQuestId() : 0); CurrentWP = WaypointList.end(); 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) 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); }
/// @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("scripts.escortai", "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", "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->SetUInt64Value(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); }
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(); } }