/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : wwphys * * * * $Archive:: /Commando/Code/wwphys/Path.h $* * * * Author:: Patrick Smith * * * * $Modtime:: 9/06/01 11:01a $* * * * $Revision:: 27 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef __COMMANDO_PATH_H #define __COMMANDO_PATH_H #include "vector.h" #include "vector3.h" #include "hermitespline.h" #include "PathObject.h" #include "binheap.h" #include "refcount.h" ///////////////////////////////////////////////////////////////////////// // Forward declarations ///////////////////////////////////////////////////////////////////////// class WaypathClass; class WaypointClass; class PathSolveClass; class ChunkSaveClass; class ChunkLoadClass; ///////////////////////////////////////////////////////////////////////// // // PathClass // ///////////////////////////////////////////////////////////////////////// class PathClass : public RefCountClass { public: ///////////////////////////////////////////////////////////////////////// // Public data types ///////////////////////////////////////////////////////////////////////// typedef enum { STATE_TRAVERSING_PATH = 1, STATE_ACTION_REQUIRED, STATE_PATH_COMPLETE, FIRST_ERROR = 100, ERROR_DRIFTED_FROM_PATH, ERROR_GENERAL, ERROR_NOT_INITIALIZED, } STATE_DESC; typedef enum { LINEAR = 0, SPLINE } TRAVERSAL_TYPE; typedef enum { MOVE_X = 1, MOVE_Y = 2, MOVE_Z = 4, } MOVEMENT_DIRECTIONS; typedef enum { ACTION_NONE = 0, ACTION_JUMP, ACTION_LEAP, ACTION_LADDER, ACTION_MECHANISM } ACTION_ID; ///////////////////////////////////////////////////////////////////////// // Public constructors/destructors ///////////////////////////////////////////////////////////////////////// PathClass (void); ~PathClass (void); ///////////////////////////////////////////////////////////////////////// // Public methods ///////////////////////////////////////////////////////////////////////// // // Path evaluation // bool Evaluate_Next_Point (const Vector3 &curr_pos, Vector3 &new_pos); const Vector3 & Get_Start_Pos (void) const { return m_StartPos; } const Vector3 & Get_Dest_Pos (void) const { return m_DestPos; } const Vector3 & Get_Next_Pos (void) const { return m_ExpectedPos; } void Set_Movement_Radius (float radius) { m_MovementRadius = radius; } float Get_Movement_Radius (void) const { return m_MovementRadius; } float Get_Curve_Sharpness (Vector3 *position) const; float Get_Last_Eval_Time (void) const; float Get_Remaining_Path_Length (void); ACTION_ID Get_Action_Type (void); void Get_Action_Destination (Vector3 &dest); void Get_Action_Entrance (Vector3 &position); uint32 Get_Action_Mechanism (void); // // Velocity methods // float Get_Velocity (void) const { return m_Velocity; } void Set_Velocity (float velocity) { m_Velocity = velocity; } // // Traversal type methods // TRAVERSAL_TYPE Get_Traversal_Type (void) const; void Set_Traversal_Type (TRAVERSAL_TYPE type); // // Movement direction control // void Set_Movement_Directions (int directions) { m_MovementDirections = directions; } int Get_Movement_Directions (void) const { return m_MovementDirections; } // // Initialization methods // void Initialize (WaypathClass *waypath, int start_pt_id, int end_pt_id); void Initialize (PathSolveClass &path_solve); void Initialize (const Vector3 &start, const Vector3 &end); // // Initialization methods // STATE_DESC Get_State (void) const { return m_State; } // // Traversing object // void Set_Path_Object (PathObjectClass &path_object); void Get_Path_Object (PathObjectClass &path_object) const; // // Debug methods // void Display_Path (bool onoff = true); // // Save/load stuff // void Save (ChunkSaveClass &csave); void Load (ChunkLoadClass &cload); // // Debug support // static bool Are_Move_Vectors_Displayed (void) { return m_DisplayMoveVectors; } static void Display_Move_Vectors (bool onoff) { m_DisplayMoveVectors = onoff; } #ifdef WWDEBUG int Get_Path_Vector_Length(void) {return(m_PathActions.Length());}; int Get_Path_Vector_Count(void) {return(m_PathActions.Count());}; #endif //WWDEBUG protected: ///////////////////////////////////////////////////////////////////////// // Protected data types ///////////////////////////////////////////////////////////////////////// typedef struct _PATH_NODE { float time; float next_time; bool tighten_spline; ACTION_ID action_id; uint32 mechanism_id; Vector3 dest_pos; Vector3 pos; _PATH_NODE (void) : time (0), next_time (0), tighten_spline (false), action_id (ACTION_NONE), mechanism_id (0), dest_pos (0, 0, 0), pos (0, 0, 0) {} bool operator== (const _PATH_NODE &src) { return true; } bool operator!= (const _PATH_NODE &src) { return false; } } PATH_NODE; ///////////////////////////////////////////////////////////////////////// // Protected methods ///////////////////////////////////////////////////////////////////////// void Initialize_Spline (DynamicVectorClass &node_list); void Initialize_Vehicle_Spline (DynamicVectorClass &node_list); void Initialize_Human_Spline (DynamicVectorClass &node_list); void Clip_Spline_To_Pathfind_Data (DynamicVectorClass &node_list, PathSolveClass &path_solve); void Add_Waypath_Data (DynamicVectorClass &node_list, WaypathClass *waypath, int start_index, int end_index); void Add_Waypoint_Info_To_Node_List (DynamicVectorClass &node_list, WaypointClass *waypoint, WaypointClass *next_point); typedef DynamicVectorClass BOX_LIST; bool Is_Point_In_Boxes (const Vector3 &point, BOX_LIST &box_list); void Clip_Control_Point (const Vector3 &start_point, Vector3 *point, BOX_LIST §or_list, BOX_LIST &portal_list); // // Save/load methods // void Load_Variables (ChunkLoadClass &cload); private: ///////////////////////////////////////////////////////////////////////// // Private member data ///////////////////////////////////////////////////////////////////////// STATE_DESC m_State; TRAVERSAL_TYPE m_TraversalType; Vector3 m_StartPos; Vector3 m_DestPos; Vector3 m_ExpectedPos; float m_LookAheadDist; float m_LookAheadTime; float m_MovementRadius; float m_SplineTime; float m_Velocity; float m_TotalDist; DynamicVectorClass m_PathActions; int m_CurrentAction; int m_MovementDirections; Curve3DClass * m_Spline; PathObjectClass m_PathObject; float m_StartTime; float m_EndTime; bool m_IsLooping; static bool m_DisplayMoveVectors; }; ///////////////////////////////////////////////////////////////////////// // Inlines ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// // Get_Action_Type ///////////////////////////////////////////////////////////////////////// inline PathClass::ACTION_ID PathClass::Get_Action_Type (void) { ACTION_ID retval = ACTION_NONE; if (m_CurrentAction >= 0 && m_CurrentAction < m_PathActions.Count ()) { retval = m_PathActions[m_CurrentAction].action_id; } return retval; } ///////////////////////////////////////////////////////////////////////// // Get_Action_Destination ///////////////////////////////////////////////////////////////////////// inline void PathClass::Get_Action_Destination (Vector3 &dest) { if (m_CurrentAction >= 0 && m_CurrentAction < m_PathActions.Count ()) { dest = m_PathActions[m_CurrentAction].dest_pos; } return ; } ///////////////////////////////////////////////////////////////////////// // Get_Action_Entrance ///////////////////////////////////////////////////////////////////////// inline void PathClass::Get_Action_Entrance (Vector3 &position) { if (m_CurrentAction >= 0 && m_CurrentAction < m_PathActions.Count ()) { position = m_PathActions[m_CurrentAction].pos; } return ; } ///////////////////////////////////////////////////////////////////////// // Get_Action_Mechanism ///////////////////////////////////////////////////////////////////////// inline uint32 PathClass::Get_Action_Mechanism (void) { uint32 mechanism_id = 0; if (m_CurrentAction >= 0 && m_CurrentAction < m_PathActions.Count ()) { mechanism_id = m_PathActions[m_CurrentAction].mechanism_id; } return mechanism_id; } #endif //__COMMANDO_PATH_H