//-----------------------------------------------------------------------------
//
//  $Logfile:: /Quake 2 Engine/Sin/code/game/behavior.h                       $
// $Revision:: 55                                                             $
//   $Author:: Jimdose                                                        $
//     $Date:: 10/27/98 8:02p                                                 $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/behavior.h                           $
// 
// 55    10/27/98 8:02p Jimdose
// added PlayAnimSeekEnemy
// 
// 54    10/27/98 12:42a Jimdose
// added animprefix to AimAndShoot
// 
// 53    10/25/98 11:52p Jimdose
// added EXPORT_TEMPLATE
// 
// 52    10/25/98 4:59a Jimdose
// Added lastSearchNode and lastSearchPos to chase
// archived howclose in GetCloseToEnemy
// 
// 51    10/22/98 11:44p Jimdose
// Added GetCloseToEnemy
// 
// 50    10/20/98 11:30p Markd
// Added aim_time to aimandshoot
// 
// 49    10/20/98 2:38a Markd
// Added goal variable to Jump
// 
// 48    10/17/98 4:41p Markd
// Added curioustime to Investigate behavior
// 
// 47    10/16/98 7:20p Markd
// Added maxshots and numshots to AimAndMelee
// 
// 46    10/14/98 9:02p Markd
// Made the Jump behavior more robust, and added landing
// 
// 45    10/14/98 5:22p Markd
// Moved jump definition
// 
// 44    10/13/98 7:38p Markd
// Created behaviors for Wander, FLy, FlyCloseAttack and WanderCloseAttack
// 
// 43    10/10/98 6:08p Markd
// Added FleeAndRemove, FindFlee, fixed max_ainode bug
// 
// 42    10/10/98 1:25a Jimdose
// Removed unneccesary definition stack template
// 
// 41    10/05/98 3:04p Markd
// Added enemy_health variable to AimAndShoot
// 
// 40    10/04/98 3:01p Markd
// fixed swimming behavior
// 
// 39    10/03/98 7:27p Markd
// working on swimming character and redid some weapon aiming stuff
// 
// 38    10/01/98 8:01p Markd
// Added AimAndMelee
// 
// 37    9/29/98 5:58p Markd
// put in archive and unarchive
// 
// 36    9/22/98 1:55a Jimdose
// Completed ShowInfo for all behaviors
// Added StrafeTo
// 
// 35    9/18/98 10:56p Jimdose
// Separated steering behaviors into their own file
// 
// 34    9/14/98 5:27p Jimdose
// Added SetPathRate to Chase so that actors can choose how often they search
// for a new path
// 
// 33    8/31/98 7:48p Jimdose
// Simplified FollowPath
// 
// 32    8/26/98 11:13p Jimdose
// Added StrafeAttack
// 
// 31    8/19/98 8:47p Jimdose
// Added Jump behavior
// 
// 30    8/14/98 6:25p Jimdose
// Got rid of decelleration for steering
// Added GoalEnt to GotoPathNode
// 
// 29    8/08/98 8:24p Markd
// added pickupandthrow
// 
// 28    8/07/98 6:02p Jimdose
// Rewrote AimAndShoot
// 
// 27    8/06/98 6:57p Jimdose
// Removed FireFromCover (now done in script)
// Added SetArgs to AimAndShoot
// 
// 26    8/03/98 7:58p Aldie
// Added a first attempt at wander behavior
// 
// 25    7/26/98 11:44a Jimdose
// Added FindClosestSightNode
// 
// 24    7/22/98 10:51p Jimdose
// Added repel behavior
// 
// 23    7/08/98 9:00p Jimdose
// Made OpenDoor script callable
// 
// 22    7/06/98 1:06p Jimdose
// working on ai
// 
// 21    6/30/98 6:03p Jimdose
// Chase and GotoPathNode now can use vectors for goals
// Investigate no longer needs currentEnemy to be set
// 
// 20    6/24/98 4:26p Jimdose
// Fixed bugs in TurnTo
// 
// 19    6/17/98 1:18a Jimdose
// Removed TargetEnemies.  Moved it back into actor
// 
// 18    6/15/98 10:47p Jimdose
// Added Hide and CoverFire
// 
// 17    6/13/98 8:21p Jimdose
// Added FindCover
// 
// 16    6/11/98 12:44a Jimdose
// behaviors now get info from the script at startup
// 
// 15    6/10/98 10:25p Jimdose
// added priority based state system
// 
// 14    6/09/98 4:24p Jimdose
// worked on ai
// 
// 13    6/04/98 10:48p Jimdose
// Fixed a bunch of things that got broken just in time for E3.  Paths and
// scripting actually work now.
// 
// 12    6/03/98 5:44p Jimdose
// Fixed spelling of behavior. :)
// 
// 11    5/27/98 7:12a Jimdose
// ai ai ai
// 
// 10    5/27/98 6:39a Jimdose
// working on ai
// 
// 9     5/27/98 5:11a Jimdose
// working on ai
// 
// 8     5/25/98 5:31p Jimdose
// Pathnodes are no longer a subclass of Entity.  This was done to save on
// edicts
// 
// 7     5/25/98 1:06a Jimdose
// Added chatter
// 
// 6     5/24/98 1:02a Jimdose
// Added Investigate
// 
// 5     5/23/98 6:29p Jimdose
// Added Aim
// 
// 4     5/22/98 9:39p Jimdose
// Worked on ai
// 
// 3     5/20/98 6:38p Jimdose
// working on ai
// 
// 2     5/18/98 8:15p Jimdose
// Created file
// 
// DESCRIPTION:
// Standard class for creating AI behaviors
//

#ifndef __BEHAVIOR_H__
#define __BEHAVIOR_H__

#include "g_local.h"
#include "entity.h"
#include "path.h"
#include "steering.h"

extern Event EV_Behavior_Args;
extern Event EV_Behavior_AnimDone;

class Actor;

class Behavior : public Listener
	{
	protected:
		PathNodePtr				movegoal;

	public:
      CLASS_PROTOTYPE( Behavior );

									Behavior();

      virtual void         ShowInfo( Actor &self );
		virtual void			Begin( Actor &self );
		virtual qboolean		Evaluate( Actor &self );
		virtual void			End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Behavior::Archive
	(
	Archiver &arc
	)
   {
   Listener::Archive( arc );

   arc.WriteSafePointer( movegoal );
   }

inline void Behavior::Unarchive
	(
	Archiver &arc
	)
   {
   Listener::Unarchive( arc );

   arc.ReadSafePointer( &movegoal );
   }

#ifdef EXPORT_TEMPLATE
template class SafePtr<Behavior>;
#endif
typedef SafePtr<Behavior> BehaviorPtr;

class Idle : public Behavior
	{
	private:
		float						nexttwitch;
		str						anim;

	public:
      CLASS_PROTOTYPE( Idle );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Idle::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteFloat( nexttwitch );
   arc.WriteString( anim );
   }

inline void Idle::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadFloat( &nexttwitch );
   arc.ReadString( &anim );
   }

class Aim : public Behavior
	{
	private:
		Seek						seek;
		EntityPtr				target;

	public:
      CLASS_PROTOTYPE( Aim );

		void						SetTarget( Entity *ent );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Aim::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteSafePointer( target );
   }

inline void Aim::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadSafePointer( &target );
   }

class FireOnSight : public Behavior
	{
	private:
		Chase						chase;
		Aim						aim;
		int						mode;
		str						anim;

	public:
      CLASS_PROTOTYPE( FireOnSight );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void FireOnSight::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &chase );
   arc.WriteObject( &aim );
   arc.WriteInteger( mode );
   arc.WriteString( anim );
   }

inline void FireOnSight::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &chase );
   arc.ReadObject( &aim );
   arc.ReadInteger( &mode );
   arc.ReadString( &anim );
   }

class TurnTo : public Behavior
	{
	private:
		Seek						seek;
		EntityPtr				ent;
		Vector					dir;
		float						yaw;
		int						mode;

	public:
      CLASS_PROTOTYPE( TurnTo );

									TurnTo();
		void						SetDirection( float yaw );
		void						SetTarget( Entity *ent );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void TurnTo::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteSafePointer( ent );
   arc.WriteVector( dir );
   arc.WriteFloat( yaw );
   arc.WriteInteger( mode );
   }

inline void TurnTo::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadSafePointer( &ent );
   arc.ReadVector( &dir );
   arc.ReadFloat( &yaw );
   arc.ReadInteger( &mode );
   }

class Jump : public Behavior
	{
	private:
		float						endtime;
		float						speed;
		str						anim;
      int                  state;
		qboolean					animdone;
      Vector               goal;

	public:
      CLASS_PROTOTYPE( Jump );

									Jump();
		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
		void						AnimDone( Event *ev );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Jump::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteFloat( endtime );
   arc.WriteFloat( speed );
   arc.WriteString( anim );
   arc.WriteInteger( state );
   arc.WriteBoolean( animdone );
   arc.WriteVector( goal );
   }

inline void Jump::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadFloat( &endtime );
   arc.ReadFloat( &speed );
   arc.ReadString( &anim );
   arc.ReadInteger( &state );
   arc.ReadBoolean( &animdone );
   arc.ReadVector( &goal );
   }


class GotoPathNode : public Behavior
	{
	private:
		TurnTo					turnto;
		Chase						chase;
		int						state;
		qboolean					usevec;
		float						time;
		str						anim;
		EntityPtr				goalent;
		Vector					goal;

	public:
      CLASS_PROTOTYPE( GotoPathNode );

									GotoPathNode();
		void						SetArgs( Event *ev );
		void						SetGoal( PathNode *node );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void GotoPathNode::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &turnto );
   arc.WriteObject( &chase );
   arc.WriteInteger( state );
   arc.WriteBoolean( usevec );
   arc.WriteFloat( time );
   arc.WriteString( anim );
   arc.WriteSafePointer( goalent );
   arc.WriteVector( goal );
   }

inline void GotoPathNode::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &turnto );
   arc.ReadObject( &chase );
   arc.ReadInteger( &state );
   arc.ReadBoolean( &usevec );
   arc.ReadFloat( &time );
   arc.ReadString( &anim );
   arc.ReadSafePointer( &goalent );
   arc.ReadVector( &goal );
   }

class Investigate : public Behavior
	{
	private:
		Chase						chase;
		str						anim;
		Vector					goal;
      float                curioustime;

		qboolean					Done( Actor &self );

	public:
      CLASS_PROTOTYPE( Investigate );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Investigate::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &chase );
   arc.WriteString( anim );
   arc.WriteVector( goal );
   arc.WriteFloat( curioustime );
   }

inline void Investigate::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &chase );
   arc.ReadString( &anim );
   arc.ReadVector( &goal );
   arc.ReadFloat( &curioustime );
   }

class Flee : public Behavior
	{
	private:
		FollowPath				follow;
		PathPtr					path;
		ObstacleAvoidance		avoid;
		float						avoidtime;
		str						anim;

	public:
      CLASS_PROTOTYPE( Flee );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Flee::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &follow );
   arc.WriteSafePointer( path );
   arc.WriteObject( &avoid );
   arc.WriteFloat( avoidtime );
   arc.WriteString( anim );
   }

inline void Flee::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &follow );
   arc.ReadSafePointer( &path );
   arc.ReadObject( &avoid );
   arc.ReadFloat( &avoidtime );
   arc.ReadString( &anim );
   }

class OpenDoor : public Behavior
	{
	private:
		float						time;
		float						endtime;
		qboolean					usedir;
		Vector					dir;

	public:
      CLASS_PROTOTYPE( OpenDoor );

									OpenDoor();
		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void OpenDoor::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteFloat( time );
   arc.WriteFloat( endtime );
   arc.WriteBoolean( usedir );
   arc.WriteVector( dir );
   }

inline void OpenDoor::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadFloat( &time );
   arc.ReadFloat( &endtime );
   arc.ReadBoolean( &usedir );
   arc.ReadVector( &dir );
   }

class PlayAnim : public Behavior
	{
	private:
		str						anim;
		
	public:
      CLASS_PROTOTYPE( PlayAnim );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void PlayAnim::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteString( anim );
   }

inline void PlayAnim::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadString( &anim );
   }

class FindCover : public Behavior
	{
	private:
		str						anim;
		Chase						chase;
		int						state;
		float						nextsearch;
		
	public:
      CLASS_PROTOTYPE( FindCover );

		void						SetArgs( Event *ev );
		PathNode					*FindCoverNode( Actor &self );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void FindCover::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteString( anim );
   arc.WriteObject( &chase );
   arc.WriteInteger( state );
   arc.WriteFloat( nextsearch );
   }

inline void FindCover::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadString( &anim );
   arc.ReadObject( &chase );
   arc.ReadInteger( &state );
   arc.ReadFloat( &nextsearch );
   }

class FindFlee : public Behavior
	{
	private:
		str						anim;
		Chase						chase;
		int						state;
		float						nextsearch;
		
	public:
      CLASS_PROTOTYPE( FindFlee );

		void						SetArgs( Event *ev );
		PathNode					*FindFleeNode( Actor &self );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void FindFlee::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteString( anim );
   arc.WriteObject( &chase );
   arc.WriteInteger( state );
   arc.WriteFloat( nextsearch );
   }

inline void FindFlee::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadString( &anim );
   arc.ReadObject( &chase );
   arc.ReadInteger( &state );
   arc.ReadFloat( &nextsearch );
   }

class FindEnemy : public Behavior
	{
	private:
		str						anim;
		Chase						chase;
		int						state;
		float						nextsearch;
      PathNodePtr          lastSearchNode;
      Vector               lastSearchPos;
		
	public:
      CLASS_PROTOTYPE( FindEnemy );

		PathNode					*FindClosestSightNode( Actor &self );
		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void FindEnemy::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteString( anim );
   arc.WriteObject( &chase );
   arc.WriteInteger( state );
   arc.WriteFloat( nextsearch );
   arc.WriteSafePointer( lastSearchNode );
   arc.WriteVector( lastSearchPos );
   }

inline void FindEnemy::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadString( &anim );
   arc.ReadObject( &chase );
   arc.ReadInteger( &state );
   arc.ReadFloat( &nextsearch );
   arc.ReadSafePointer( &lastSearchNode );
   arc.ReadVector( &lastSearchPos );
   }

class Hide : public Behavior
	{
	private:
		FindCover				hide;
		str						anim;
		int						state;
		float						checktime;
		
	public:
      CLASS_PROTOTYPE( Hide );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Hide::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &hide );
   arc.WriteString( anim );
   arc.WriteInteger( state );
   arc.WriteFloat( checktime );
   }

inline void Hide::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &hide );
   arc.ReadString( &anim );
   arc.ReadInteger( &state );
   arc.ReadFloat( &checktime );
   }


class FleeAndRemove : public Behavior
	{
	private:
		FindFlee				   flee;
		str						anim;
		int						state;
		float						checktime;
		
	public:
      CLASS_PROTOTYPE( FleeAndRemove );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void FleeAndRemove::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &flee );
   arc.WriteString( anim );
   arc.WriteInteger( state );
   arc.WriteFloat( checktime );
   }

inline void FleeAndRemove::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &flee );
   arc.ReadString( &anim );
   arc.ReadInteger( &state );
   arc.ReadFloat( &checktime );
   }


class AimAndShoot : public Behavior
	{
	private:
		Aim						aim;
		int						mode;
		int						maxshots;
		int						numshots;
		qboolean					animdone;
      float                enemy_health;
      float                aim_time;
      str                  animprefix;
      str                  readyfireanim;
      str                  aimanim;
      str                  fireanim;

	public:
      CLASS_PROTOTYPE( AimAndShoot );

									AimAndShoot();
		void						SetMaxShots( int num );
		void						SetArgs( Event *ev );
		void						AnimDone( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void AimAndShoot::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &aim );
   arc.WriteInteger( mode );
   arc.WriteInteger( maxshots );
   arc.WriteInteger( numshots );
   arc.WriteBoolean( animdone );
   arc.WriteFloat( enemy_health );
   arc.WriteFloat( aim_time );
   arc.WriteString( animprefix );
   arc.WriteString( readyfireanim );
   arc.WriteString( aimanim );
   arc.WriteString( fireanim );
   }

inline void AimAndShoot::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &aim );
   arc.ReadInteger( &mode );
   arc.ReadInteger( &maxshots );
   arc.ReadInteger( &numshots );
   arc.ReadBoolean( &animdone );
   arc.ReadFloat( &enemy_health );
   arc.ReadFloat( &aim_time );
   arc.ReadString( &animprefix );
   arc.ReadString( &readyfireanim );
   arc.ReadString( &aimanim );
   arc.ReadString( &fireanim );
   }

class AimAndMelee : public Behavior
	{
	private:
		Aim						aim;
		int						mode;
		int						maxshots;
		int						numshots;
		qboolean					animdone;

	public:
      CLASS_PROTOTYPE( AimAndMelee );

									AimAndMelee();
		void						SetArgs( Event *ev );
		void						AnimDone( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void AimAndMelee::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &aim );
   arc.WriteInteger( mode );
   arc.WriteInteger( maxshots );
   arc.WriteInteger( numshots );
   arc.WriteBoolean( animdone );
   }

inline void AimAndMelee::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &aim );
   arc.ReadInteger( &mode );
   arc.ReadInteger( &maxshots );
   arc.ReadInteger( &numshots );
   arc.ReadBoolean( &animdone );
   }


class Melee : public Behavior
	{
	private:
		int						mode;
		qboolean					animdone;

	public:
      CLASS_PROTOTYPE( Melee );

									Melee();
		void						SetArgs( Event *ev );
		void						AnimDone( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Melee::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteInteger( mode );
   arc.WriteBoolean( animdone );
   }

inline void Melee::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadInteger( &mode );
   arc.ReadBoolean( &animdone );
   }

class Repel : public Behavior
	{
	private:
		str						anim;
		float						dist;
		float						len;
		float						speed;
		Vector					goal;
		Vector					start;
		Vector					dir;
		
	public:
      CLASS_PROTOTYPE( Repel );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Repel::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteString( anim );
   arc.WriteFloat( dist );
   arc.WriteFloat( len );
   arc.WriteFloat( speed );
   arc.WriteVector( goal );
   arc.WriteVector( start );
   arc.WriteVector( dir );
   }

inline void Repel::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadString( &anim );
   arc.ReadFloat( &dist );
   arc.ReadFloat( &len );
   arc.ReadFloat( &speed );
   arc.ReadVector( &goal );
   arc.ReadVector( &start );
   arc.ReadVector( &dir );
   }


class PickupAndThrow : public Behavior
	{
	private:
		Aim						aim;
		int						mode;
		qboolean					animdone;
      EntityPtr            pickup_target;


	public:
      CLASS_PROTOTYPE( PickupAndThrow );

									PickupAndThrow();
		void						SetArgs( Event *ev );
		void						AnimDone( Event *ev );
		void						Pickup( Event *ev );
		void						Throw( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void PickupAndThrow::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &aim );
   arc.WriteInteger( mode );
   arc.WriteBoolean( animdone );
   arc.WriteSafePointer( pickup_target );
   }

inline void PickupAndThrow::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &aim );
   arc.ReadInteger( &mode );
   arc.ReadBoolean( &animdone );
   arc.ReadSafePointer( &pickup_target );
   }

class StrafeAttack : public Behavior
	{
	private:
		int						state;
		TurnTo					turn;

	public:
      CLASS_PROTOTYPE( StrafeAttack );

      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void StrafeAttack::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteInteger( state );
   arc.WriteObject( &turn );
   }

inline void StrafeAttack::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadInteger( &state );
   arc.ReadObject( &turn );
   }

class StrafeTo : public Behavior
	{
	private:
      Vector               goal;
      Seek                 seek;
      int                  fail;

	public:
      CLASS_PROTOTYPE( StrafeTo );

      void                 ShowInfo( Actor &self );
      void						SetArgs( Event *ev );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void StrafeTo::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteVector( goal );
   arc.WriteObject( &seek );
   arc.WriteInteger( fail );
   }

inline void StrafeTo::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadVector( &goal );
   arc.ReadObject( &seek );
   arc.ReadInteger( &fail );
   }

class Swim : public Behavior
	{
	private:
      Seek                 seek;
		ObstacleAvoidance2   avoid;
		str						anim;
      float                avoidtime;
      Vector               avoidvec;

	public:
      CLASS_PROTOTYPE( Swim );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Swim::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteObject( &avoid );
   arc.WriteString( anim );
   arc.WriteFloat( avoidtime );
   arc.WriteVector( avoidvec );
   }

inline void Swim::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadObject( &avoid );
   arc.ReadString( &anim );
   arc.ReadFloat( &avoidtime );
   arc.ReadVector( &avoidvec );
   }

class SwimCloseAttack : public Behavior
	{
	private:
      Seek                 seek;
		ObstacleAvoidance2   avoid;
      qboolean             avoiding;
		str						anim;
      float                avoidtime;
      Vector               avoidvec;

	public:
      CLASS_PROTOTYPE( SwimCloseAttack );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void SwimCloseAttack::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteObject( &avoid );
   arc.WriteBoolean( avoiding );
   arc.WriteString( anim );
   arc.WriteFloat( avoidtime );
   arc.WriteVector( avoidvec );
   }

inline void SwimCloseAttack::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadObject( &avoid );
   arc.ReadBoolean( &avoiding );
   arc.ReadString( &anim );
   arc.ReadFloat( &avoidtime );
   arc.ReadVector( &avoidvec );
   }

class Fly : public Behavior
	{
	private:
      Seek                 seek;
		ObstacleAvoidance2   avoid;
		str						anim;
      float                avoidtime;
      Vector               avoidvec;

	public:
      CLASS_PROTOTYPE( Fly );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Fly::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteObject( &avoid );
   arc.WriteString( anim );
   arc.WriteFloat( avoidtime );
   arc.WriteVector( avoidvec );
   }

inline void Fly::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadObject( &avoid );
   arc.ReadString( &anim );
   arc.ReadFloat( &avoidtime );
   arc.ReadVector( &avoidvec );
   }

class FlyCloseAttack : public Behavior
	{
	private:
      Seek                 seek;
		ObstacleAvoidance2   avoid;
      qboolean             avoiding;
		str						anim;
      float                avoidtime;
      Vector               avoidvec;

	public:
      CLASS_PROTOTYPE( FlyCloseAttack );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void FlyCloseAttack::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteObject( &avoid );
   arc.WriteBoolean( avoiding );
   arc.WriteString( anim );
   arc.WriteFloat( avoidtime );
   arc.WriteVector( avoidvec );
   }

inline void FlyCloseAttack::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadObject( &avoid );
   arc.ReadBoolean( &avoiding );
   arc.ReadString( &anim );
   arc.ReadFloat( &avoidtime );
   arc.ReadVector( &avoidvec );
   }

class Wander : public Behavior
	{
	private:
      Seek                 seek;
		ObstacleAvoidance2   avoid;
		str						anim;
      float                avoidtime;
      Vector               avoidvec;

	public:
      CLASS_PROTOTYPE( Wander );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void Wander::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteObject( &avoid );
   arc.WriteString( anim );
   arc.WriteFloat( avoidtime );
   arc.WriteVector( avoidvec );
   }

inline void Wander::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadObject( &avoid );
   arc.ReadString( &anim );
   arc.ReadFloat( &avoidtime );
   arc.ReadVector( &avoidvec );
   }


class WanderCloseAttack : public Behavior
	{
	private:
      Seek                 seek;
		ObstacleAvoidance2   avoid;
      qboolean             avoiding;
		str						anim;
      float                avoidtime;
      Vector               avoidvec;

	public:
      CLASS_PROTOTYPE( WanderCloseAttack );

		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void WanderCloseAttack::Archive
	(
	Archiver &arc
	)
   {
   Behavior::Archive( arc );

   arc.WriteObject( &seek );
   arc.WriteObject( &avoid );
   arc.WriteBoolean( avoiding );
   arc.WriteString( anim );
   arc.WriteFloat( avoidtime );
   arc.WriteVector( avoidvec );
   }

inline void WanderCloseAttack::Unarchive
	(
	Archiver &arc
	)
   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &seek );
   arc.ReadObject( &avoid );
   arc.ReadBoolean( &avoiding );
   arc.ReadString( &anim );
   arc.ReadFloat( &avoidtime );
   arc.ReadVector( &avoidvec );
   }

class GetCloseToEnemy : public Behavior
	{
	private:
      float                howclose;
		str						anim;
		Chase						chase;
		int						state;
		float						nextsearch;
		
	public:
      CLASS_PROTOTYPE( GetCloseToEnemy );
                        
                           GetCloseToEnemy();
		void						SetArgs( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void GetCloseToEnemy::Archive
	(
	Archiver &arc
	)

   {
   Behavior::Archive( arc );

   arc.WriteFloat( howclose );
   arc.WriteString( anim );
   arc.WriteObject( &chase );
   arc.WriteInteger( state );
   arc.WriteFloat( nextsearch );
   }

inline void GetCloseToEnemy::Unarchive
	(
	Archiver &arc
	)

   {
   Behavior::Unarchive( arc );

   arc.ReadFloat( &howclose );
   arc.ReadString( &anim );
   arc.ReadObject( &chase );
   arc.ReadInteger( &state );
   arc.ReadFloat( &nextsearch );
   }

class PlayAnimSeekEnemy : public Behavior
	{
	private:
		Aim						aim;
		int						mode;
		qboolean					animdone;
      str                  anim;
		str						oldanim;

	public:
      CLASS_PROTOTYPE( PlayAnimSeekEnemy );

		void						SetArgs( Event *ev );
		void						AnimDone( Event *ev );
      void                 ShowInfo( Actor &self );
		void						Begin( Actor &self );
		qboolean					Evaluate( Actor &self );
		void						End( Actor &self );
	   virtual void         Archive( Archiver &arc );
      virtual void         Unarchive( Archiver &arc );
	};

inline void PlayAnimSeekEnemy::Archive
	(
	Archiver &arc
	)

   {
   Behavior::Archive( arc );

   arc.WriteObject( &aim );
   arc.WriteInteger( mode );
   arc.WriteBoolean( animdone );
   arc.WriteString( anim );
   arc.WriteString( oldanim );
   }

inline void PlayAnimSeekEnemy::Unarchive
	(
	Archiver &arc
	)

   {
   Behavior::Unarchive( arc );

   arc.ReadObject( &aim );
   arc.ReadInteger( &mode );
   arc.ReadBoolean( &animdone );
   arc.ReadString( &anim );
   arc.ReadString( &oldanim );
   }

#endif /* behavior.h */
