//-----------------------------------------------------------------------------
//
//  $Logfile:: /Quake 2 Engine/Sin/code/game/player.h                         $
// $Revision:: 119                                                            $
//   $Author:: Jimdose                                                        $
//     $Date:: 11/16/98 8:26p                                                 $
//
// Copyright (C) 1997 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/player.h                              $
//
// 119   11/16/98 8:26p Jimdose
// Added CheckWater
//
// 118   11/14/98 2:53a Aldie
// Added InitSkin for keeping the skin intact for savegames
//
// 117   11/13/98 2:35a Aldie
// Changed variable name
//
// 116   11/08/98 10:53p Jimdose
// some variables weren't being archived.  They were benign, but it helps
// ensure that we don't miss important variables
//
// 115   11/07/98 10:15p Markd
// Added forcemusic support
//
// 114   11/07/98 8:01p Markd
// Added in damage_since_pain, fixed some camera stuff
//
// 113   11/06/98 9:38p Aldie
// Moved waitforplayer stuff to think function
//
// 112   10/25/98 11:57p Jimdose
// exported EV_Player_Respawn
//
// 111   10/24/98 5:44p Markd
// Added killent, removent, killclass removeclass and added parameters to
// whatis
//
// 110   10/21/98 5:29p Aldie
// Added a setskin command
//
// 109   10/16/98 1:59a Jimdose
// Added EV_Player_EndLevel and EndLevel
// Made third person view work with savegames
//
// 108   10/14/98 1:36a Jimdose
// Got cross-level persitant data working
//
// 107   10/12/98 8:45p Jimdose
// Rewrote init function
// started adding persistant functions
//
// 106   10/11/98 8:58p Aldie
// Changed Restore to Human
//
// 105   10/11/98 7:41p Aldie
// Mutate and restore commands for Richard
//
// 104   10/10/98 9:59p Aldie
// Added trappedinquantum flag to archiver
//
// 103   10/10/98 5:58p Aldie
// More quantumdestab fixes
//
// 102   10/09/98 9:01p Aldie
// Moved GiveOxygen to player
//
// 101   10/07/98 11:54p Jimdose
// Added old_pmove to Player
// Added SetDeltaAngles
// Moved PlayerFrozen to game
//
// 100   10/02/98 7:20p Aldie
// Added flashcolor
//
// 99    9/30/98 5:39p Aldie
// Added showinfo command
//
// 98    9/29/98 5:06p Aldie
// Relocated gravity node functions
//
// 97    9/26/98 4:46p Aldie
// Added mutant mode
//
// 96    9/22/98 3:27p Markd
// Took out old variable
//
// 95    9/22/98 12:49p Markd
// Put in archive and unarchive functions
//
// 94    9/21/98 1:35a Aldie
// Moved some vars to sentient
//
// 93    9/19/98 4:47p Markd
// fixed music stuff and added actionincrement to weapons
//
// 92    9/18/98 10:57p Jimdose
// Added spawnactor and actorinfo
//
// 91    9/17/98 1:48p Markd
// Fixed swimmin animations
//
// 90    9/16/98 8:58p Aldie
// Added ability to do a hold down weapon charge
//
// 89    9/11/98 2:50p Aldie
// Added release firing functionality
//
// 88    9/10/98 8:53p Markd
// put in proper falling and landing animation thresholds.
//
// 87    9/09/98 5:06p Markd
// Added savefov and restorefov, also added fov change when teleporting
//
// 86    8/31/98 7:16p Markd
// Fixed player animation naming convention
//
// 85    8/31/98 5:45p Aldie
// Powerup timer stuff
//
// 84    8/30/98 7:29p Markd
// Put in auto-dead camera where after 10 seconds, player will follow the
// endnode1 path
//
// 83    8/29/98 9:53p Jimdose
// moved enums and #defines from g_local.h
//
// 82    8/29/98 5:27p Markd
// added specialfx, replaced misc with specialfx where appropriate
//
// 81    8/28/98 7:54p Markd
// Added TauntTime
//
// 80    8/27/98 4:50p Markd
// Added fallsurface
//
// 79    8/25/98 7:52p Markd
// Added crosshair to player again
//
// 78    8/25/98 4:11p Markd
// Added taunt support
//
// 77    8/17/98 8:59p Jimdose
// Added WhatIs
//
// 76    8/17/98 6:20p Markd
// Changed SetCamera to a Player method
//
// 75    8/17/98 3:07p Aldie
// Added the weaponuse command
//
// 74    8/12/98 6:04p Aldie
// Added a shield timer
//
// 73    8/07/98 6:01p Aldie
// Added frag credits for falling damage
//
// 72    7/31/98 8:10p Jimdose
// Script commands now include flags to indicate cheats and console commands
// Cheat function removed since events have cheat flags
//
// 71    7/31/98 4:20p Jimdose
// Added GiveHealthCheat
//
// 70    7/26/98 12:35p Jimdose
// Added GiveAllCheat
//
// 69    7/26/98 4:12a Aldie
// Updated getVehicle
//
// 68    7/25/98 5:21p Markd
// Added GotKill to player
//
// 67    7/24/98 7:37p Aldie
// Changed hud event
//
// 66    7/23/98 9:56p Aldie
// Added hud event
//
// 65    7/23/98 12:31p Markd
// Added onladder variable
//
// 64    7/22/98 10:20p Markd
// Added AnimPrefixForWeapon
//
// 63    7/21/98 9:07p Markd
// Added UpdateMusic
//
// 62    7/21/98 1:10p Aldie
// Added meansofdeath to obituaries
//
// 61    7/20/98 12:09p Markd
// Added vehicleanim support
//
// 60    7/17/98 4:04p Markd
// Added useWeapon
//
// 59    7/14/98 9:54p Markd
// Fixed camera stuff
//
// 58    7/13/98 5:02p Aldie
// Added dead player bodies with gibbing
//
// 57    7/11/98 8:58p Markd
// Added testthread command
//
// 56    7/10/98 11:18p Jimdose
// Removed third-person crosshair
//
// 55    7/08/98 3:12p Aldie
// First try at spectator mode
//
// 54    7/07/98 8:06p Aldie
// Spectator and dead stuff
//
// 53    7/02/98 2:34p Aldie
// Mission computer
//
// 52    6/24/98 1:39p Aldie
// Implementation of inventory system and picking stuff up
//
// 51    6/22/98 2:04p Jimdose
// Added vehicles back in
// Organized the control code a bit more.  May want to make physics into a
// class
//
// 50    6/19/98 6:39p Aldie
// More inventory stuff
//
// 49    6/18/98 9:26p Aldie
// Started inventory system
//
// 48    6/15/98 10:48p Jimdose
// Added AddPathNode
//
// 47    6/13/98 8:20p Jimdose
// removed optimize path stuff
//
// 46    6/10/98 2:10p Aldie
// Updated damage function.
//
// 45    6/03/98 4:39p Markd
// removed parameters from SetCameraEntity stuff
//
// 44    5/27/98 7:03a Markd
// added action_level
//
// 43    5/26/98 7:56p Jimdose
// added scripted cameras
//
// 42    5/26/98 4:46p Aldie
// Added take (object) from player
//
// 41    5/26/98 4:38a Jimdose
// Added tracking crosshair
//
// 40    5/25/98 6:47p Jimdose
// Made animateframe, prethink and posthink into functions built into the base
// entity class
//
// 39    5/24/98 8:46p Jimdose
// Made a lot of functions more str-friendly.
// Got rid of a lot of char * based strings
// Cleaned up get spawn arg functions and sound functions
// sound functions now use consistant syntax
//
// 38    5/13/98 4:49p Jimdose
// Now use SafePtrs for keeping track of nodes and cameras
//
// 37    5/05/98 2:41p Jimdose
// New interface for controlling the clients view
// moved a lot of variables from gclient_t to be internal to player
//
// 36    5/03/98 4:37p Jimdose
// Added camera
//
// 35    5/01/98 6:16p Jimdose
// Made Respawn an event so that Trigger_Hurt wouldn't rekill a player after
// respawn
//
// 34    4/27/98 5:27p Jimdose
// Working on ai
//
// 33    4/21/98 2:25p Aldie
// Added enterconsole and exitconsole events.
//
// 32    4/20/98 2:45p Jimdose
// working on ai
//
// 31    4/18/98 3:02p Jimdose
// Removed nodebeam
//
// 30    4/16/98 2:10p Jimdose
// Working on ai.
// Removed TESTPATH stuff
//
// 29    4/09/98 8:44p Jimdose
// Added view blend effects
// added drowing
//
// 28    4/07/98 3:49p Aldie
// Added zooming crosshair
//
// 27    4/06/98 7:10p Aldie
// Added zooming for SniperRifle
//
// 26    4/05/98 2:58a Jimdose
// added respawn_time
//
// 25    4/04/98 6:13p Jimdose
// Added events for syncing firing to animation
//
// 24    4/02/98 4:46p Jimdose
// Added Obituary, Pain, and ShowScores
//
// 23    3/31/98 1:44p Jimdose
// Removed footstep stuff
//
// 22    3/29/98 9:42p Jimdose
// Moved animation stuff to sentient
//
// 21    3/29/98 5:57p Jimdose
// Added SpawnEntity command
//
// 20    3/28/98 4:36p Jimdose
// Added kill event
//
// 19    3/27/98 9:59p Jimdose
// Changed CalcRoll to return a float
//
// 18    3/27/98 6:36p Jimdose
// Added third person view
//
// 17    3/26/98 8:16p Jimdose
// Added animation control functions
// Added respawn and init functions for deathmatch
//
// 16    3/23/98 1:33p Jimdose
// Revamped event and command system
//
// 15    3/18/98 7:21p Jimdose
// Added CalcGunOffset
//
// 14    3/03/98 6:03p Aldie
// First pass at footsteps.
//
// 13    3/02/98 8:49p Jimdose
// Changed CLASS_PROTOTYPE to only take the classname
//
// 12    2/21/98 1:22p Jimdose
// Removed A LOT of unused varables and code.
//
// 11    2/19/98 2:36p Jimdose
// Added weapons back in
//
// 10    2/17/98 8:35p Jimdose
// Removed useHeld
//
// 9     2/06/98 5:44p Jimdose
// replaced use of think and touch functions with events
// move client to Entity
//
// 8     2/03/98 10:59a Jimdose
// Updated to work with Quake 2 engine
// Moved initialization to constructor and removed Init function
// This will probably be rewritten to be simpler.  This first rewrite sucks.
//
// 6     12/05/97 4:08p Aldie
// Added event to player for giving weapons.
//
// 5     11/12/97 5:12p Jimdose
// Added event definitions
//
// 4     10/27/97 2:59p Jimdose
// Removed dependency on quakedef.h
//
// 3     10/08/97 6:03p Jimdose
// Began vehicle support.
//
// 2     9/26/97 6:47p Jimdose
// Added standard Ritual headers
//
// DESCRIPTION:
// Class definition of the player.
//

#ifndef __PLAYER_H__
#define __PLAYER_H__

#include "g_local.h"
#include "vector.h"
#include "entity.h"
#include "weapon.h"
#include "sentient.h"
#include "navigate.h"
#include "misc.h"
#include "bspline.h"
#include "camera.h"
#include "vehicle.h"
#include "specialfx.h"
#include "hoverbike.h" //###
#include "movecapture.h" //###

extern Event EV_Player_EndLevel;
extern Event EV_Player_PrevWeapon;
extern Event EV_Player_NextWeapon;
extern Event EV_Player_GiveCheat;
extern Event EV_Player_GodCheat;
extern Event EV_Player_NoTargetCheat;
extern Event EV_Player_NoClipCheat;
extern Event EV_Player_GameVersion;
extern Event EV_Player_Fov;
extern Event EV_Player_SaveFov;
extern Event EV_Player_RestoreFov;
extern Event EV_Player_ZoomOut;
extern Event EV_Player_ToggleZoomMode;
extern Event EV_Player_ClearFloatingInventory;
extern Event EV_Player_WhatIs;
extern Event EV_Player_DrawOverlay;
extern Event EV_Player_HideOverlay;
extern Event EV_Player_DrawStats;
extern Event EV_Player_HideStats;
extern Event EV_Player_SetFlashColor;
extern Event EV_Player_ClearFlashColor;
extern Event EV_Player_Respawn;
//###
extern Event EV_Player_WeaponSwitch;
extern Event EV_Player_WeaponOverride;
extern Event EV_Player_SetAngleJitter;
extern Event EV_Player_SetOffsetJitter;
//###

typedef enum
{
	ZOOMED_OUT,
	ZOOMED_IN
} zoom_mode_t;

typedef enum
{
	FIRST_PERSON,
	THIRD_PERSON,
	SPECTATOR,
	CAMERA_VIEW,
	MISSILE_VIEW //### added for guided missile
} viewmode_t;

// view pitching times
#define DAMAGE_TIME             0.5
#define FALL_TIME               0.3
#define  ENEMY_TIME           5.0

class EXPORT_FROM_DLL Player : public Sentient
{
protected:
	pmove_state_t old_pmove;            // for detecting out-of-pmove changes

	// bobbing
	float xyspeed;
	float bobtime;
	float bobmove;
	int bobcycle;                           // odd cycles are right foot going forward
	float bobfracsin;                           // sin(bobfrac*M_PI)

	Vector oldvelocity;

	// weapon kicks
	Vector kick_angles;
	Vector kick_origin;

	// damage kicks
	float v_dmg_roll;
	float v_dmg_pitch;
	float v_dmg_time;

	// for view drop on fall
	float fall_time;
	float fall_value;

	// blend //FIXME move to entity?
	float blend[ 4 ];                           // rgba full screen effect
	float fov;                                      // horizontal field of view
	float savedfov;                                 // saved horizontal field of view for teleports

	// view weapon orientation
	Vector v_gunoffset;
	Vector v_gunangles;

	friend class Camera;
	friend class Vehicle;
	//###
	friend class Hoverbike;
	friend class HoverWeap;
	friend class MoveCapture;
	//###

	// vehicle stuff
	VehiclePtr vehicle;
	str vehicleanim;

	HoverbikePtr hoverbike;            //###

	// aiming direction
	Vector v_angle;
	Vector v_kick;
	Vector oldviewangles;
	Vector v_offset;

	int buttons;
	int new_buttons;
	viewmode_t viewmode;
	viewmode_t defaultViewMode;
	zoom_mode_t zoom_mode;
	float respawn_time;

	qboolean firing;
	qboolean in_console;
	qboolean has_thought;

	// damage blend
	float damage_blood;
	float damage_alpha;
	Vector damage_blend;
	float bonus_alpha;

	float next_drown_time;
	float air_finished;

	int old_waterlevel;
	int drown_damage;

	Path                    *path;
	PathNodePtr goalNode;
	PathNodePtr nearestNode;
	PathNodePtr lastNode;
	Vector lastVisible;
	Vector lastGround;
	float searchTime;
	str con_name;

	EntityPtr thirdpersonCamera;
	EntityPtr watchCamera;
	EntityPtr movieCamera;
	EntityPtr spectatorCamera;
	EntityPtr CinematicCamera;
	EntityPtr crosshair;

	qboolean onladder;

	qboolean spectator;
	qboolean hidestats;
	qboolean drawoverlay;

	// music mood stuff
	float action_level;
	int music_current_mood;
	int music_fallback_mood;

	// falling damage stuff
	csurface_t          *fallsurface;

	// Pickup inventory stuff
	SentientPtr floating_owner;
	Container<int>        floating_inventory;

	float lastEnemyTime;

	int currentCameraTarget;
	qboolean gibbed;
	qboolean drawstats;

	float lastTauntTime;

	// variable to see if we checked the dead camera
	qboolean checked_dead_camera;

	qboolean falling;
	float flash_color[4];

	float last_damage_time;
	qboolean music_forced;

	float spectator_distance;

	//###
	// added for nuke view blend
	Vector nuke_blend;
	float nuke_alpha;

	// added for view jittering
	float jitter_angle;
	float jitter_angle_falloff;
	float jitter_angle_enttime;
	float jitter_offset;
	float jitter_offset_falloff;
	float jitter_offset_enttime;

	// movement capture thinggy
	MoveCapturePtr movecapturer;
	//###

public:

	CLASS_PROTOTYPE( Player );

	qboolean trappedInQuantum;

	Player();
	virtual ~Player();
	virtual void        Init( void );
	virtual void      RestorePersistantData( SpawnArgGroup &group );
	virtual void      WritePersistantData( SpawnArgGroup &group );

	virtual void        InitMusic( void );
	virtual void        InitEdict( void );
	virtual void        InitClient( void );
	virtual void        InitPath( void );
	virtual void        InitPhysics( void );
	virtual void        InitPowerups( void );
	virtual void        InitWorldEffects( void );
	virtual void        InitWeapons( void );
	virtual void        InitView( void );
	virtual void        InitModel( void );
	virtual void        InitState( void );
	virtual void        InitHealth( void );
	virtual void      InitInventory( void );
	virtual void      InitSkin( void );
	virtual void      ChooseSpawnPoint( void );

	virtual void        EndLevel( Event *ev );
	virtual void        Respawn( Event *ev );

	virtual void      SetDeltaAngles( void );

	virtual void        DoUse( void );
	virtual void        Obituary( Entity *attacker, Entity *inflictor, str location, int meansofdeath );
	virtual void        Killed( Event *ev );
	virtual void      Dead( Event *ev );
	virtual void        Pain( Event *ev );
	virtual void     Spectator( Event *ev );

	virtual void        CheckButtons( void );
	virtual void        TouchStuff( pmove_t *pm );
	void                    EnterVehicle( Event *ev );
	void                    ExitVehicle( Event *ev );

	virtual void        GetMoveInfo( pmove_t *pm );
	virtual void        SetMoveInfo( pmove_t *pm, usercmd_t *ucmd );
	virtual pmtype_t    GetMovePlayerMoveType( void );
	virtual void        ClientMove( usercmd_t *ucmd );
	void                    ClientThink( Event *ev );

	virtual void        EventUseItem( Event *ev );

	void                 GiveCheat( Event *ev );
	void                 GiveAllCheat( Event *ev );
	void               Take( Event *ev );
	void                 GodCheat( Event *ev );
	void                 NoTargetCheat( Event *ev );
	void                 NoclipCheat( Event *ev );
	void                 Kill( Event *ev );
	void               GibEvent( Event *ev );
	void                 SpawnEntity( Event *ev );
	void              SpawnActor( Event *ev );

	void                    EventPreviousWeapon( Event *ev );
	void                    EventNextWeapon( Event *ev );
	void                  EventPreviousItem( Event *ev );
	void                    EventNextItem( Event *ev );
	void                  EventUseInventoryItem( Event *ev );
	void                    GameVersion( Event *ev );
	void                    Fov( Event *ev );
	void                    SaveFov( Event *ev );
	void                    RestoreFov( Event *ev );
	void                    ToggleViewMode( Event *ev );
	void                    ToggleZoomMode( Event *ev );
	void                    ZoomOut( Event *ev );
	void              CrosshairLayout( Entity *ent );
	void              EnterConsole( Event *ev );
	void              ExitConsole( Event *ev );
	void              KickConsole( Event *ev );
	virtual void      WeaponUse( Event *ev );
	virtual float       CalcRoll( void );
	virtual void        CalcBob( void );
	virtual void        CalcViewOffset( void );
	virtual void        CalcGunOffset( void );
	virtual void      CheckWater( void );
	virtual void        WorldEffects( void );
	virtual void        AddBlend( float r, float g, float b, float a );
	virtual void        CalcBlend( void );
	virtual void        DamageFeedback( void );

	virtual void        ChooseAnim( void );

	virtual qboolean    CanMoveTo( Vector pos );
	virtual qboolean    ClearPathTo( Vector pos );

	virtual void        AddPathNode( Event *ev );
	virtual void        AddPathNodes( void );

	virtual void        UpdateStats( void );
	virtual void      UpdateMusic( void );

	virtual void        SetViewMode( viewmode_t mode, Entity * newCamera = NULL );
	virtual void        SetCameraValues( Vector position, Vector cameraoffset, Vector ang, Vector camerakick, Vector vel, float camerablend[ 4 ], float camerafov );

	virtual void        SetCameraEntity( Entity *cameraEnt );
	virtual void        FallingDamage( void );
	virtual void        FinishMove( void );
	virtual void        EndFrame( Event *ev );

	virtual void        ShowInfo( Event *ev );

	virtual void        ReadyToFire( Event *ev );
	virtual void        WaitingToFire( Event *ev );
	virtual void        DoneFiring( Event *ev );

	virtual void        TestThread( Event *ev );
	virtual Weapon    *useWeapon( const char *weaponname );

	virtual void      AddItemToFloatingInventory( Item *item );
	virtual void      SetFloatingOwner( Sentient *deceased_owner );
	virtual Sentient  *GetFloatingOwner( void );
	virtual void      SendFloatingInventory( void );
	virtual void      ClearFloatingInventory( Event *ev );
	virtual void      PickupFloatingInventory( void );
	virtual void      ChangeSpectator( void );
	virtual const char *AnimPrefixForWeapon( void );
	virtual void        GotKill( Event *ev );
	virtual VehiclePtr GetVehicle( void )
	{
		return vehicle;
	};
	virtual void      SetPowerupTimer( Event *ev );
	virtual void      UpdatePowerupTimer( Event *ev );

	virtual viewmode_t ViewMode( void );
	virtual Camera    *CurrentCamera( void );
	virtual void      SetCamera( Entity * ent );

	void                 WhatIs( Event *ev );
	void              ActorInfo( Event *ev );
	virtual void        Taunt( Event *ev );
	str       AnimPrefixForPlayer( void );

	virtual void        DrawOverlay( Event *ev );
	virtual void        HideOverlay( Event *ev );
	virtual void        HideStats( Event *ev );
	virtual void        DrawStats( Event *ev );
	virtual void      ChangeMusic( const char * current, const char * fallback, qboolean force );
	virtual void      GravityNodes( void );
	virtual void      Archive( Archiver &arc );
	virtual void      Unarchive( Archiver &arc );

	virtual void      SetFlashColor( Event *ev );
	virtual void      ClearFlashColor( Event *ev );
	void              Mutate( Event *ev );
	void              Human( Event *ev );
	void              SetSkin( Event *ev );
	void              GiveOxygen( float time );

	void                 KillEnt( Event *ev );
	void                 RemoveEnt( Event *ev );
	void                 KillClass( Event *ev );
	void                 RemoveClass( Event *ev );

//### 2015 added stuff
	// init 2015 stuff for player
	virtual void Init2015( void );

	// added so I can detect player's buttons from other entities
	virtual int Buttons( void )
	{
		return buttons;
	};

	// added for nuke view flash
	virtual void StartNukeFlash( Vector fblend, float falpha );

	// added for concussion gun
	virtual void ConcussionDamage( void );
	float concussion_timer;     // timer for cuncussioner removal

	// to get the hoverbike's entity
	virtual HoverbikePtr GetHoverbike( void )
	{
		return hoverbike;
	};

	// added for hoverbike weapon
//		virtual void FireWeapon(Event *ev);
//		virtual Weapon *giveWeapon(const char *weaponname);

	// spawn hoverbike on player
	virtual void SpawnPlayerBike( int forcespawn );

	// spawn hoverbike cheat
	virtual void GiveBikeCheat( Event *ev );

	// added stuff for view jitter
	virtual float JitterAngle( void )
	{
		return jitter_angle;
	};
	virtual void SetAngleJitter( float angle, float falloff, float time );
	virtual float JitterOffset( void )
	{
		return jitter_offset;
	};
	virtual void SetOffsetJitter( float offset, float falloff, float time );
	virtual void AngleJitterEvent( Event *ev );
	virtual void OffsetJitterEvent( Event *ev );

	// added for checkpoints
	float checkpoint_debounce;
	str cp_list;
	int last_cp_id;
	int last_goal_time;
	virtual qboolean CPTouched( int cp );
	virtual qboolean CPTouchedAll( void );
	virtual void CPListAdd( int cp );
	virtual void CPListClear( void );

	// command to set bike skin
	void SetBikeSkin( Event *ev );

	// set self to be informer
	void SetInformer( Event *ev );

	// set the player's movement capture entity
	virtual void SetMovementCapture( MoveCapture *capturer );

	// therm-optic goggles stuff
	qboolean nightvision;     // true if using goggles
	virtual void ToggleGoggles( Event *ev );

	// guided missile overlay
	void MissileOverlayOn( void );
	void MissileOverlayOff( void );

	// for togglable auto weapon switching
	virtual void WeaponSwitch( Event *ev );

	// for dissabling weapon select override
	virtual void WeaponOverride( Event *ev );

	// get player's xyspeed
	virtual float GetXYspeed( void )
	{
		return xyspeed;
	};

	// get the player's aiming direction
	Vector GetVAngle( void )
	{
		return v_angle;
	};

	// for switching back to a regular weapon from the informergun
	WeaponPtr lastWeapon;

	// MDF welcome message
	void WelcomeMessage( Event *ev );
//###
};

inline EXPORT_FROM_DLL void Player::Archive( Archiver &arc )
{
	Sentient::Archive( arc );

	arc.WriteRaw( &old_pmove, sizeof( old_pmove ) );

	// save bobbing variables
	arc.WriteFloat( xyspeed );
	arc.WriteFloat( bobtime );
	arc.WriteFloat( bobmove );
	arc.WriteInteger( bobcycle );
	arc.WriteFloat( bobfracsin );

	arc.WriteVector( oldvelocity );

	// save weapon kicks, damage kicks, view drop, and blend weapon kicks
	arc.WriteVector( kick_angles );
	arc.WriteVector( kick_origin );

	// damage kicks
	arc.WriteFloat( v_dmg_roll );
	arc.WriteFloat( v_dmg_pitch );
	arc.WriteFloat( v_dmg_time );

	// for view drop on fall
	arc.WriteFloat( fall_time );
	arc.WriteFloat( fall_value );

	// blend //FIXME move to entity?
	arc.WriteFloat( blend[ 0 ] );
	arc.WriteFloat( blend[ 1 ] );
	arc.WriteFloat( blend[ 2 ] );
	arc.WriteFloat( blend[ 3 ] );

	arc.WriteFloat( fov );
	arc.WriteFloat( savedfov );

	// save off v_gunangles, v_gunoffset for view weapon orientation
	arc.WriteVector( v_gunoffset );
	arc.WriteVector( v_gunangles );

	arc.WriteSafePointer( vehicle );
	arc.WriteString( vehicleanim );

	arc.WriteVector( v_angle );
	arc.WriteVector( v_kick );
	arc.WriteVector( oldviewangles );
	arc.WriteVector( v_offset );

	arc.WriteInteger( buttons );
	arc.WriteInteger( new_buttons );
	arc.WriteInteger( viewmode );
	arc.WriteInteger( defaultViewMode );
	arc.WriteInteger( zoom_mode );
	arc.WriteFloat( respawn_time );

	arc.WriteBoolean( firing );
	arc.WriteBoolean( in_console );
	arc.WriteBoolean( has_thought );

	arc.WriteFloat( damage_blood );
	arc.WriteFloat( damage_alpha );
	arc.WriteVector( damage_blend );
	arc.WriteFloat( bonus_alpha );

	arc.WriteFloat( next_drown_time );
	arc.WriteFloat( air_finished );

	arc.WriteInteger( old_waterlevel );
	arc.WriteInteger( drown_damage );

	arc.WriteObjectPointer( path );
	arc.WriteSafePointer( goalNode );
	arc.WriteSafePointer( nearestNode );
	arc.WriteSafePointer( lastNode );
	arc.WriteVector( lastVisible );
	arc.WriteVector( lastGround );
	arc.WriteFloat( searchTime );
	arc.WriteString( con_name );

	arc.WriteSafePointer( thirdpersonCamera );
	arc.WriteSafePointer( watchCamera );
	arc.WriteSafePointer( movieCamera );
	arc.WriteSafePointer( spectatorCamera );
	arc.WriteSafePointer( CinematicCamera );
	arc.WriteSafePointer( crosshair );

	arc.WriteBoolean( onladder );

	arc.WriteBoolean( spectator );
	arc.WriteBoolean( hidestats );
	arc.WriteBoolean( drawoverlay );

	arc.WriteFloat( action_level );
	arc.WriteInteger( music_current_mood );
	arc.WriteInteger( music_fallback_mood );

	// Can't archive this stuff
	// fallsurface
	// Pickup inventory stuff
	// SentientPtr       floating_owner;
	//Container<int>		floating_inventory;

	arc.WriteFloat( lastEnemyTime );

	arc.WriteInteger( currentCameraTarget );
	arc.WriteBoolean( gibbed );
	arc.WriteBoolean( drawstats );

	arc.WriteFloat( lastTauntTime );
	arc.WriteBoolean( checked_dead_camera );

	arc.WriteBoolean( falling );

	arc.WriteFloat( flash_color[ 0 ] );
	arc.WriteFloat( flash_color[ 1 ] );
	arc.WriteFloat( flash_color[ 2 ] );
	arc.WriteFloat( flash_color[ 3 ] );

	arc.WriteFloat( last_damage_time );
	arc.WriteBoolean( music_forced );

	arc.WriteBoolean( trappedInQuantum );

	//###
	arc.WriteSafePointer( hoverbike );

	arc.WriteVector( nuke_blend );
	arc.WriteFloat( nuke_alpha );

	arc.WriteFloat( jitter_angle );
	arc.WriteFloat( jitter_angle_falloff );
	arc.WriteFloat( jitter_angle_enttime );
	arc.WriteFloat( jitter_offset );
	arc.WriteFloat( jitter_offset_falloff );
	arc.WriteFloat( jitter_offset_enttime );

	arc.WriteSafePointer( movecapturer );

	arc.WriteFloat( concussion_timer );

	arc.WriteFloat( checkpoint_debounce );
	arc.WriteString( cp_list );
	arc.WriteInteger( last_cp_id );
	arc.WriteInteger( last_goal_time );
	arc.WriteBoolean( nightvision );

	arc.WriteSafePointer( lastWeapon );
	//###
}

inline EXPORT_FROM_DLL void Player::Unarchive( Archiver &arc )
{
	int temp;

	Sentient::Unarchive( arc );

	arc.ReadRaw( &old_pmove, sizeof( old_pmove ) );

	arc.ReadFloat( &xyspeed );
	arc.ReadFloat( &bobtime );
	arc.ReadFloat( &bobmove );
	arc.ReadInteger( &bobcycle );
	arc.ReadFloat( &bobfracsin );

	arc.ReadVector( &oldvelocity );

	// save weapon kicks, damage kicks, view drop, and blend weapon kicks
	arc.ReadVector( &kick_angles );
	arc.ReadVector( &kick_origin );

	// damage kicks
	arc.ReadFloat( &v_dmg_roll );
	arc.ReadFloat( &v_dmg_pitch );
	arc.ReadFloat( &v_dmg_time );

	// for view drop on fall
	arc.ReadFloat( &fall_time );
	arc.ReadFloat( &fall_value );

	// blend //FIXME move to entity?
	arc.ReadFloat( &blend[ 0 ] );
	arc.ReadFloat( &blend[ 1 ] );
	arc.ReadFloat( &blend[ 2 ] );
	arc.ReadFloat( &blend[ 3 ] );

	arc.ReadFloat( &fov );
	arc.ReadFloat( &savedfov );

	// save off v_gunangles, v_gunoffset for view weapon orientation
	arc.ReadVector( &v_gunoffset );
	arc.ReadVector( &v_gunangles );

	arc.ReadSafePointer( &vehicle );
	arc.ReadString( &vehicleanim );

	arc.ReadVector( &v_angle );
	arc.ReadVector( &v_kick );
	arc.ReadVector( &oldviewangles );
	arc.ReadVector( &v_offset );

	arc.ReadInteger( &buttons );
	arc.ReadInteger( &new_buttons );

	arc.ReadInteger( &temp );
	viewmode = ( viewmode_t )temp;

	arc.ReadInteger( &temp );
	defaultViewMode = ( viewmode_t )temp;

	arc.ReadInteger( &temp );
	zoom_mode = ( zoom_mode_t )temp;

	arc.ReadFloat( &respawn_time );

	arc.ReadBoolean( &firing );
	arc.ReadBoolean( &in_console );
	arc.ReadBoolean( &has_thought );

	arc.ReadFloat( &damage_blood );
	arc.ReadFloat( &damage_alpha );
	arc.ReadVector( &damage_blend );
	arc.ReadFloat( &bonus_alpha );

	arc.ReadFloat( &next_drown_time );
	arc.ReadFloat( &air_finished );

	arc.ReadInteger( &old_waterlevel );
	arc.ReadInteger( &drown_damage );

	arc.ReadObjectPointer( ( Class ** )&path );
	arc.ReadSafePointer( &goalNode );
	arc.ReadSafePointer( &nearestNode );
	arc.ReadSafePointer( &lastNode );
	arc.ReadVector( &lastVisible );
	arc.ReadVector( &lastGround );
	arc.ReadFloat( &searchTime );
	arc.ReadString( &con_name );

	arc.ReadSafePointer( &thirdpersonCamera );
	arc.ReadSafePointer( &watchCamera );
	arc.ReadSafePointer( &movieCamera );
	arc.ReadSafePointer( &spectatorCamera );
	arc.ReadSafePointer( &CinematicCamera );
	arc.ReadSafePointer( &crosshair );

	arc.ReadBoolean( &onladder );

	arc.ReadBoolean( &spectator );
	arc.ReadBoolean( &hidestats );
	arc.ReadBoolean( &drawoverlay );

	arc.ReadFloat( &action_level );
	arc.ReadInteger( &music_current_mood );
	arc.ReadInteger( &music_fallback_mood );

	// Can't archive this stuff
	fallsurface = NULL;
	floating_owner = NULL;
	floating_inventory.FreeObjectList();

	arc.ReadFloat( &lastEnemyTime );

	arc.ReadInteger( &currentCameraTarget );
	arc.ReadBoolean( &gibbed );
	arc.ReadBoolean( &drawstats );

	arc.ReadFloat( &lastTauntTime );
	arc.ReadBoolean( &checked_dead_camera );

	arc.ReadBoolean( &falling );

	arc.ReadFloat( &flash_color[ 0 ] );
	arc.ReadFloat( &flash_color[ 1 ] );
	arc.ReadFloat( &flash_color[ 2 ] );
	arc.ReadFloat( &flash_color[ 3 ] );

	arc.ReadFloat( &last_damage_time );
	arc.ReadBoolean( &music_forced );

	arc.ReadBoolean( &trappedInQuantum );

	//###
	arc.ReadSafePointer( &hoverbike );

	arc.ReadVector( &nuke_blend );
	arc.ReadFloat( &nuke_alpha );

	arc.ReadFloat( &jitter_angle );
	arc.ReadFloat( &jitter_angle_falloff );
	arc.ReadFloat( &jitter_angle_enttime );
	arc.ReadFloat( &jitter_offset );
	arc.ReadFloat( &jitter_offset_falloff );
	arc.ReadFloat( &jitter_offset_enttime );

	arc.ReadSafePointer( &movecapturer );

	arc.ReadFloat( &concussion_timer );

	arc.ReadFloat( &checkpoint_debounce );
	arc.ReadString( &cp_list );
	arc.ReadInteger( &last_cp_id );
	arc.ReadInteger( &last_goal_time );
	arc.ReadBoolean( &nightvision );

	arc.ReadSafePointer( &lastWeapon );
	//###
}

inline EXPORT_FROM_DLL str Player::AnimPrefixForPlayer( void )
{
	str prefix;

	if ( waterlevel > 2 || ( !groundentity && waterlevel ) )
	{
		prefix = str( "swim_" );
	}
	else if ( client && client->ps.pmove.pm_flags & PMF_DUCKED )
	{
		prefix = str( "crouch_" );
	}
	return prefix;
}

#endif /* player.h */
