⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gravpath.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//
//  $Logfile:: /Quake 2 Engine/Sin/code/game/gravpath.cpp                     $
// $Revision:: 18                                                             $
//   $Author:: Markd                                                          $
//     $Date:: 10/24/98 12:42a                                                $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/gravpath.cpp                          $
// 
// 18    10/24/98 12:42a Markd
// changed origins to worldorigins where appropriate
// 
// 17    10/21/98 2:24a Jimdose
// Made GravPath not add to the gravPathManager while loading savegames
// 
// 16    10/09/98 5:22p Aldie
// Changed commands to activate and deactivate
// 
// 15    10/07/98 11:52p Jimdose
// Added destructor for GravPathManager
// 
// 14    9/30/98 4:34p Aldie
// Free gravpath when level changes
// 
// 13    9/30/98 1:17p Markd
// Fixed gravpath null pointer checks
// 
// 12    9/29/98 5:33p Aldie
// Added force gravity to the path
// 
// 11    8/29/98 9:43p Jimdose
// Added call info to G_Trace
// 
// 10    8/27/98 2:55p Aldie
// Added a headnode spawnflag
// 
// 9     8/27/98 2:33p Aldie
// Added functionality so gravpaths work out of water
// 
// 8     8/26/98 8:46p Aldie
// Added activate and deactivate commands
// 
// 7     5/26/98 4:45p Aldie
// Fixed an error printf
// 
// 6     5/25/98 2:28p Aldie
// Fixed issues with not loading game dll
// 
// 5     5/23/98 10:21p Aldie
// Removed drawing of gravpath.
// 
// 4     5/23/98 5:15p Aldie
// Removed traces checking for obstacles when finding the closest grav point.
// 
// 3     5/22/98 12:24p Aldie
// Updated defaults
// 
// 2     5/22/98 12:19p Aldie
// First version of gravity path
//
// DESCRIPTION:
// Gravity path - Used for underwater currents and wells.

#include "g_local.h"
#include "entity.h"
#include "gravpath.h"
#include "container.h"
#include "navigate.h"
#include "misc.h"
#include "player.h"

GravPathManager gravPathManager;

CLASS_DECLARATION(Class, GravPathManager, NULL);

ResponseDef GravPathManager::Responses[] = 
   {
      { NULL,NULL }
   };

GravPathManager::~GravPathManager()
   {
   Reset();
   }

void GravPathManager::Reset( void )
   {
   while( pathList.NumObjects() > 0 )
		{
		delete ( GravPath * )pathList.ObjectAt( 1 );
      }

   pathList.FreeObjectList();
   }

void GravPathManager::AddPath(GravPath *p)
	{
   int num;
	num = pathList.AddObject( p );
   pathList.Resize( pathList.NumObjects() );
	}

void GravPathManager::RemovePath(GravPath *p)
	{
	pathList.RemoveObject( p );
   pathList.Resize( pathList.NumObjects() );
	}

Vector GravPathManager::CalculateGravityPull(Entity &ent, Vector pos, qboolean *force)
   {
   int            i,num;
   GravPath       *p;
   GravPathNode   *node;
   Vector         point;
   Vector         newpoint;
   Vector         dir;
   float          bestdist = 99999;
   float          dist;
   float          speed;
   float          radius;
   Vector         velocity;
   int            bestpath = 0;
   int            entity_contents, grav_contents;

 	num = pathList.NumObjects();

   entity_contents = gi.pointcontents( ent.worldorigin.vec3() );

   for( i = 1; i <= num; i++ )
		{
		p = ( GravPath * )pathList.ObjectAt( i );

      if ( !p )
         continue;
      
      // Check to see if path is active
      node = p->GetNode( 1 );
      if ( !node || !node->active )
         continue;

      // Check to see if the contents are the same
      grav_contents = gi.pointcontents( node->worldorigin.vec3() );

      // If grav node is in water, make sure ent is too.
      if ( ( grav_contents & CONTENTS_WATER ) && !( entity_contents & CONTENTS_WATER ) )
         continue;

      // Test to see if we are in this path's bounding box
      if ( (pos.x < p->maxs.x) && (pos.y < p->maxs.y) && (pos.z < p->maxs.z) && 
           (pos.x > p->mins.x) && (pos.y > p->mins.y) && (pos.z > p->mins.z) )
         {
         point = p->ClosestPointOnPath(pos, ent, &dist, &speed, &radius);      

         // If the closest distance on the path is greater than the radius, then 
         // do not consider this path.

         if (dist > radius)
            {
            continue;
            }
         else if (dist < bestdist)
            {
            bestpath = i;
            bestdist  = dist;
            }
         }
      }
   
   if (!bestpath)
      {
      return vec_zero;
      }

   p = ( GravPath * )pathList.ObjectAt( bestpath );
   if ( !p )
      return velocity;
   *force    = p->force;
   dist     = p->DistanceAlongPath(pos, &speed);
   newpoint = p->PointAtDistance( dist + speed);
   dir      = newpoint-pos;
   dir.normalize();
   velocity = dir * speed;
   return velocity;
   }

/*****************************************************************************/
/*SINED info_grav_pathnode (0 0 .5) (-16 -16 0) (16 16 32) HEADNODE FORCE
 "radius" Radius of the effect of the pull (Default is 256)
 "speed"  Speed of the pull (Use negative for a repulsion) (Default is 100)

  Set HEADNODE to signify the head of the path.
  Set FORCE if you want un-fightable gravity ( i.e. can't go backwards )
/*****************************************************************************/

CLASS_DECLARATION( Entity, GravPathNode, "info_grav_pathnode" );

Event EV_GravPath_Create( "gravpath_create" );
Event EV_GravPath_Activate( "activate" );
Event EV_GravPath_Deactivate( "deactivate" );

ResponseDef GravPathNode::Responses[] =
	{
      { &EV_GravPath_Create,           ( Response )GravPathNode::CreatePath },
      { &EV_GravPath_Activate,         ( Response )GravPathNode::Activate },
      { &EV_GravPath_Deactivate,       ( Response )GravPathNode::Deactivate },
      { NULL, NULL }
   };

GravPathNode::GravPathNode()
	{
	setMoveType( MOVETYPE_NONE );
	setSolidType( SOLID_NOT );
   hideModel();

   speed    = G_GetFloatArg( "speed",100.0f );
   radius   = G_GetFloatArg( "radius",256.0f );
   headnode = spawnflags & 1;
   active   = true;

   // This is the head of a new path, post an event to create the path
   if ( headnode )
      {
      PostEvent( EV_GravPath_Create, 0 );
      }
	}

float GravPathNode::Speed( void )
   {
   if ( active )
      return speed;
   else
      return 0;
   };

void GravPathNode::Activate(Event *ev)
   {
   GravPathNode   *node;
   int            num;
   const char     *target;
   
   active = true;
   node = this;
   // Go through the entire path and activate it
   target = node->Target();
   while (target[0])
      {
      if (num = G_FindTarget(0, target))
         {
         node = (GravPathNode *)G_GetEntity( num );
         assert( node );
         node->active = true;
         }
      else
         {
         gi.error("GravPathNode::CreatePath: target %s not found\n",target);
         }
      target = node->Target();
      }
   }

void GravPathNode::Deactivate(Event *ev)
   {
   GravPathNode   *node;
   int            num;
   const char     *target;
   
   active = false;
   node = this;
   // Go through the entire path and activate it
   target = node->Target();
   while (target[0])
      {
      if (num = G_FindTarget(0, target))
         {
         node = (GravPathNode *)G_GetEntity( num );
         assert( node );
         node->active = false;
         }
      else
         {
         gi.error("GravPathNode::CreatePath: target %s not found\n",target);
         }
      target = node->Target();
      }
   }

void GravPathNode::CreatePath(Event *ev)
   {
   const char     *target;
   GravPath       *path = new GravPath;
   GravPathNode   *node;
   int            num;

   ClearBounds(path->mins.vec3(),path->maxs.vec3());

   // This node is the head of a path, create a new path in the path manager.
   // and add it in, then add all of it's children in the path.
   node = this;
   path->AddNode(node);
   path->force = spawnflags & 2;

   // Make the path from the targetlist.
   target = node->Target();
   while (target[0])
      {
      if (num = G_FindTarget(0, target))
         {
         node = (GravPathNode *)G_GetEntity( num );
         assert( node );
         path->AddNode(node);
         }
      else
         {
         gi.error("GravPathNode::CreatePath: target %s not found\n",target);
         }
      target = node->Target();
      }

   // Set the origin.
   path->origin = path->mins + path->maxs;
   path->origin *= 0.5f;
   }

CLASS_DECLARATION( Listener, GravPath, NULL );

Event EV_DrawGravPath( "drawpath" );

ResponseDef GravPath::Responses[] =
	{
      { &EV_DrawGravPath, (Response)GravPath::DrawPath },
		{ NULL, NULL }
	};

GravPath::GravPath()
	{
	// Event *event;

   pathlength  = 0;
	from        = NULL;
	to          = NULL;
	nextnode    = 1;

   if ( !LoadingSavegame )
      {
      gravPathManager.AddPath(this);
      }

   // event = new Event(EV_DrawGravPath);
   // event->AddFloat(1);
   // event->AddFloat(0);
   // event->AddFloat(0);
   // PostEvent(event,0.1f);
	}

GravPath::~GravPath()
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -