openmohaa/code/fgame/gravpath.h
2024-09-27 20:19:11 +02:00

203 lines
5 KiB
C++

/*
===========================================================================
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<GravPathNode> GravPathNodePtr;
class GravPath : public Listener
{
private:
Container<GravPathNodePtr> 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<GravPath *> 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;