void npc_escortAI::MovementInform(uint32 type, uint32 id) { if (type != POINT_MOTION_TYPE || !IsBeingEscorted) return; //Original position reached, continue waypoint movement if (id == WP_LAST_POINT) { debug_log("RSCR: EscortAI has returned to original position before combat"); ReconnectWP = true; Returning = false; if(!WaitTimer) WaitTimer = 1; } else { //Make sure that we are still on the right waypoint if (CurrentWP->id != id) { debug_log("RSCR ERROR: EscortAI reached waypoint out of order %d, expected %d", id, CurrentWP->id); return; } debug_log("RSCR: EscortAI Waypoint %d reached", CurrentWP->id); //Call WP function WaypointReached(CurrentWP->id); WaitTimer = 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("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 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; } }
//----------------------------------------------------------------------------- // Purpose: Check to see if we should teleport to the current path corner //----------------------------------------------------------------------------- void CNPC_VehicleDriver::CheckForTeleport( void ) { if ( !GetGoalEnt() ) return; CPathTrack *pTrack = dynamic_cast<CPathTrack *>( GetGoalEnt() ); if ( !pTrack ) return; // Does it have the teleport flag set? if ( pTrack->HasSpawnFlags( SF_PATH_TELEPORT ) ) { AddEffects( EF_NOINTERP ); // Teleport the vehicle to the pathcorner Vector vecMins, vecMaxs; vecMins = m_hVehicleEntity->CollisionProp()->OBBMins(); vecMaxs = m_hVehicleEntity->CollisionProp()->OBBMaxs(); Vector vecTarget = pTrack->GetAbsOrigin() - (vecMins + vecMaxs) * 0.5; vecTarget.z += ((vecMaxs.z - vecMins.z) * 0.5) + 8; // Safety buffer // Orient it to face the next point QAngle vecAngles = pTrack->GetAbsAngles(); Vector vecToTarget = vec3_origin; if ( pTrack->GetNext() ) { vecToTarget = (pTrack->GetNext()->GetAbsOrigin() - pTrack->GetAbsOrigin()); VectorNormalize( vecToTarget ); // Vehicles are rotated 90 degrees VectorAngles( vecToTarget, vecAngles ); vecAngles[YAW] -= 90; } m_hVehicleEntity->Teleport( &vecTarget, &vecAngles, &vec3_origin ); // Teleport the driver SetAbsOrigin( m_hVehicleEntity->WorldSpaceCenter() ); SetAbsAngles( m_hVehicleEntity->GetAbsAngles() ); m_vecPrevPoint = pTrack->GetAbsOrigin(); // Move to the next waypoint, we've reached this one if ( GetNavigator()->GetPath() ) { WaypointReached(); } // Clear our waypoints, because the next waypoint is certainly invalid now. ClearWaypoints(); } }
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::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 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 npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) { if (!IsSD2EscortMovement(uiMoveType) || !HasEscortState(STATE_ESCORT_ESCORTING)) return; //uint32 pathId = uiMoveType & 0xFF; if (uiMoveType < EXTERNAL_WAYPOINT_MOVE_START) WaypointReached(uiPointId); else if (uiMoveType < EXTERNAL_WAYPOINT_FINISHED_LAST) WaypointStart(uiPointId); else // Last WP Reached { if (m_bCanInstantRespawn) { m_creature->SetDeathState(JUST_DIED); m_creature->Respawn(); } else m_creature->ForcedDespawn(); } }
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(); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CNPC_VehicleDriver::OverridePathMove( float flInterval ) { // Setup our initial path data if we've just started running a path if ( !m_pCurrentWaypoint ) { m_vecPrevPoint = GetAbsOrigin(); m_vecPrevPrevPoint = GetAbsOrigin(); m_vecDesiredPosition = GetNavigator()->GetCurWaypointPos(); CalculatePostPoints(); // Init our two waypoints m_Waypoints[0] = new CVehicleWaypoint( m_vecPrevPrevPoint, m_vecPrevPoint, m_vecDesiredPosition, m_vecPostPoint ); m_Waypoints[1] = new CVehicleWaypoint( m_vecPrevPoint, m_vecDesiredPosition, m_vecPostPoint, m_vecPostPostPoint ); m_pCurrentWaypoint = m_Waypoints[0]; m_pNextWaypoint = m_Waypoints[1]; m_flDistanceAlongSpline = 0.2; } // Have we reached our target? See if we've passed the current waypoint's plane. Vector vecAbsMins, vecAbsMaxs; CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs ); if ( BoxOnPlaneSide( vecAbsMins, vecAbsMaxs, &m_pCurrentWaypoint->planeWaypoint ) == 3 ) { if ( WaypointReached() ) return true; } // Did we bypass it and reach the next one already? if ( m_pNextWaypoint && BoxOnPlaneSide( vecAbsMins, vecAbsMaxs, &m_pNextWaypoint->planeWaypoint ) == 3 ) { if ( WaypointReached() ) return true; } // We may have just teleported, so check to make sure we have a waypoint if ( !m_pCurrentWaypoint || !m_pNextWaypoint ) return false; // Figure out which spline we're trucking along CVehicleWaypoint *pCurrentSplineBeingTraversed = m_pCurrentWaypoint; if ( m_flDistanceAlongSpline > 1 ) { pCurrentSplineBeingTraversed = m_pNextWaypoint; } // Get our current speed, and check it against the length of the spline to know how far to advance our marker AngularImpulse angVel; Vector vecVelocity; IPhysicsObject *pVehiclePhysics = m_hVehicleEntity->VPhysicsGetObject(); if( !pVehiclePhysics ) { // I think my vehicle has been destroyed. return false; } pVehiclePhysics->GetVelocity( &vecVelocity, &angVel ); float flSpeed = vecVelocity.Length(); float flIncTime = gpGlobals->curtime - GetLastThink(); float flIncrement = flIncTime * (flSpeed / pCurrentSplineBeingTraversed->GetLength()); // Now advance our point along the spline m_flDistanceAlongSpline = clamp( m_flDistanceAlongSpline + flIncrement, 0, 2); if ( m_flDistanceAlongSpline > 1 ) { // We crossed the spline boundary pCurrentSplineBeingTraversed = m_pNextWaypoint; } Vector vSplinePoint = pCurrentSplineBeingTraversed->GetPointAt( m_flDistanceAlongSpline > 1 ? m_flDistanceAlongSpline-1 : m_flDistanceAlongSpline ); Vector vSplineTangent = pCurrentSplineBeingTraversed->GetTangentAt( m_flDistanceAlongSpline > 1 ? m_flDistanceAlongSpline-1 : m_flDistanceAlongSpline ); // Now that we've got the target spline point & tangent, use it to decide what our desired velocity is. // If we're close to the tangent, just use the tangent. Otherwise, Lerp towards it. Vector vecToDesired = (vSplinePoint - GetAbsOrigin()); float flDistToDesired = VectorNormalize( vecToDesired ); float flTangentLength = VectorNormalize( vSplineTangent ); if ( flDistToDesired > (flTangentLength * 0.75) ) { m_vecDesiredVelocity = vecToDesired * flTangentLength; } else { VectorLerp( vSplineTangent, vecToDesired * flTangentLength, (flDistToDesired / (flTangentLength * 0.5)), m_vecDesiredVelocity ); } // Decrease speed according to the turn we're trying to make Vector vecRight; m_hVehicleEntity->GetVectors( NULL, &vecRight, NULL ); Vector vecNormVel = m_vecDesiredVelocity; VectorNormalize( vecNormVel ); float flDotRight = DotProduct( vecRight, vecNormVel ); flSpeed = (1.0 - fabs(flDotRight)); // Don't go slower than we've been told to go if ( flSpeed < m_flDriversMinSpeed ) { flSpeed = m_flDriversMinSpeed; } m_vecDesiredVelocity = vecNormVel * (flSpeed * m_flMaxSpeed); // Bunch o'debug if ( g_debug_vehicledriver.GetInt() & DRIVER_DEBUG_PATH ) { NDebugOverlay::Box( m_vecPrevPrevPoint, -Vector(15,15,15), Vector(15,15,15), 192,0,0, true, 0.1); NDebugOverlay::Box( m_vecPrevPoint, -Vector(20,20,20), Vector(20,20,20), 255,0,0, true, 0.1); NDebugOverlay::Box( m_vecPostPoint, -Vector(20,20,20), Vector(20,20,20), 0,192,0, true, 0.1); NDebugOverlay::Box( m_vecPostPostPoint, -Vector(20,20,20), Vector(20,20,20), 0,128,0, true, 0.1); NDebugOverlay::Box( vSplinePoint, -Vector(10,10,10), Vector(10,10,10), 0,0,255, true, 0.1); NDebugOverlay::Line( vSplinePoint, vSplinePoint + (vSplineTangent * 40), 0,0,255, true, 0.1); //NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[0], pCurrentSplineBeingTraversed->splinePoints[1], 30, 255,255,255,0, false, 0.1f ); //NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[1], pCurrentSplineBeingTraversed->splinePoints[2], 20, 255,255,255,0, false, 0.1f ); //NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[2], pCurrentSplineBeingTraversed->splinePoints[3], 10, 255,255,255,0, false, 0.1f ); // Draw the plane we're checking against for waypoint passing Vector vecPlaneRight; CrossProduct( m_pCurrentWaypoint->planeWaypoint.normal, Vector(0,0,1), vecPlaneRight ); Vector vecPlane = m_pCurrentWaypoint->splinePoints[2]; NDebugOverlay::Line( vecPlane + (vecPlaneRight * -100), vecPlane + (vecPlaneRight * 100), 255,0,0, true, 0.1); // Draw the next plane too CrossProduct( m_pNextWaypoint->planeWaypoint.normal, Vector(0,0,1), vecPlaneRight ); vecPlane = m_pNextWaypoint->splinePoints[2]; NDebugOverlay::Line( vecPlane + (vecPlaneRight * -100), vecPlane + (vecPlaneRight * 100), 192,0,0, true, 0.1); } if ( g_debug_vehicledriver.GetInt() & DRIVER_DEBUG_PATH_SPLINE ) { for ( int i = 0; i < 10; i++ ) { Vector vecTarget = m_pCurrentWaypoint->GetPointAt( 0.1 * i ); Vector vecTangent = m_pCurrentWaypoint->GetTangentAt( 0.1 * i ); VectorNormalize(vecTangent); NDebugOverlay::Box( vecTarget, -Vector(10,10,10), Vector(10,10,10), 255,0,0, true, 0.1 ); NDebugOverlay::Line( vecTarget, vecTarget + (vecTangent * 10), 255,255,0, true, 0.1); } } return true; }