/* =========================================================================== Copyright (C) 2024 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code 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 2 of the License, or (at your option) any later version. OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // gravpath.h: Gravity path - Used for underwater currents and wells. #pragma once #include "g_local.h" #include "class.h" #include "container.h" class GravPathNode : public Entity { private: float speed; float radius; qboolean headnode; float max_speed; public: qboolean active; CLASS_PROTOTYPE(GravPathNode); GravPathNode(); void SetSpeed( Event *ev ); void SetMaxSpeed( Event *ev ); void SetRadius( Event *ev ); void CreatePath( Event *ev ); void Activate( Event *ev ); void Deactivate( Event *ev ); float Speed( void ); float MaxSpeed( void ); float Radius( void ) { return radius; }; void Archive( Archiver &arc ) override; }; inline void GravPathNode::Archive ( Archiver &arc ) { Entity::Archive( arc ); arc.ArchiveFloat( &speed ); arc.ArchiveFloat( &radius ); arc.ArchiveBoolean( &headnode ); arc.ArchiveBoolean( &active ); arc.ArchiveFloat( &max_speed ); } typedef SafePtr GravPathNodePtr; class GravPath : public Listener { private: Container pathlist; float pathlength; GravPathNodePtr from; GravPathNodePtr to; int nextnode; public: CLASS_PROTOTYPE( GravPath ); GravPath(); ~GravPath(); void Clear(void); void Reset(void); void AddNode(GravPathNode *node); GravPathNode *GetNode(int num); GravPathNode *NextNode(void); Vector ClosestPointOnPath(Vector pos, Entity &ent,float *bestdist,float *speed,float *radius); float DistanceAlongPath(Vector pos, float *speed); Vector PointAtDistance( Vector pos, float dist, qboolean is_player, float *max_distance ); void DrawPath(float r, float g, float b); int NumNodes(void); float Length(void); GravPathNode *Start(void); GravPathNode *End(void); void Archive( Archiver &arc ) override; Vector mins; Vector maxs; Vector origin; qboolean force; }; inline void GravPath::Archive ( Archiver &arc ) { GravPathNodePtr *tempPtr; int i, num; Listener::Archive( arc ); if ( arc.Loading() ) { Reset(); } else { num = pathlist.NumObjects(); } arc.ArchiveInteger( &num ); if ( arc.Loading() ) { pathlist.Resize( num ); } for ( i = 1; i <= num; i++ ) { tempPtr = pathlist.AddressOfObjectAt( i ); arc.ArchiveSafePointer( tempPtr ); } arc.ArchiveFloat( &pathlength ); arc.ArchiveSafePointer( &from ); arc.ArchiveSafePointer( &to ); arc.ArchiveInteger( &nextnode ); arc.ArchiveVector( &mins ); arc.ArchiveVector( &maxs ); arc.ArchiveVector( &origin ); arc.ArchiveBoolean( &force ); } class GravPathManager : public Class { private: Container pathList; public: CLASS_PROTOTYPE( GravPathManager ); ~GravPathManager(); void Reset( void ); void AddPath(GravPath *p); void RemovePath(GravPath *p); Vector CalculateGravityPull(Entity &ent, Vector position, qboolean *force, float *max_speed); void DrawGravPaths( void ); void Archive( Archiver &arc ) override; }; inline void GravPathManager::Archive ( Archiver &arc ) { GravPath * ptr; int i, num; Class::Archive( arc ); if ( arc.Saving() ) { num = pathList.NumObjects(); } else { Reset(); } arc.ArchiveInteger( &num ); for ( i = 1; i <= num; i++ ) { if ( arc.Saving() ) { ptr = pathList.ObjectAt( i ); } else { ptr = new GravPath; } arc.ArchiveObject( ptr ); if ( arc.Loading() ) { pathList.AddObject( ptr ); } } } extern GravPathManager gravPathManager;