//-----------------------------------------------------------------------------
//
//  $Logfile:: /game/player.h                                                 $
// $Revision:: 2                                                              $
//   $Author:: Burgermac                                                      $
//     $Date:: 12/27/00 6:56 PM                                               $
//
// 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.
//
// 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 "movecapture.h" //###
#include "grapple.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;
extern Event EV_Player_CTF_SpawnRune;
//###
extern Event EV_Player_CTF_SoundEvent;

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 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 MoveCapture;
	//###

	// vehicle stuff
	VehiclePtr vehicle;
	str vehicleanim;

	// 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;

	qboolean grapple_pull;
	Vector grapple_org;
	float grapple_speed;
	float grapple_time;

	// 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;

	// CTF
	HookPtr hook;
	BeamPtr beam;

	//###
	// 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              GetPlayerView( Vector* pos, Vector* angle );

	void                 WhatIs( Event* ev );
	void              ActorInfo( Event* ev );
	virtual void        Taunt( Event* ev );
	const char* 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

	// 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 );

	// misc stuff for hoverbike
	Entity* WatchCamera( void )
	{
		return watchCamera;
	};

	int IsHoldingAttack( void )
	{
		return ( buttons & BUTTON_ATTACK );
	};

	// redefinitions of sentient virtual functions for the hoverbike
	int IsFiringMissile( void )
	{
		return viewmode == MISSILE_VIEW;
	};
	int BikeIsTurboing( void )
	{
		return ( buttons & BUTTON_USE );
	};
	void SetBikeAnim( str bikeanim )
	{
		vehicleanim = bikeanim;
	};
	float WishedBikeYaw( void )
	{
		return v_angle[YAW];
	};
	float BikeAimPitch( void )
	{
		return v_angle[PITCH] * 1.05;
	}; // need to scale
	   // the player's view pitch up to compensate for the
	   // weapons firing from so far forward.

	void CTF_SpawnRuneSelect( Event* ev );
	void CTF_SetSpawnRune( Event* ev );
	void CTF_GiveRune( int runenum );
//###
	// CTF
	void SetGrapplePull( Vector dir, float speed );
	void ClearGrapplePull( void );
	void                    InitCTF( void );
	void                   CTF_JoinTeamHardcorps( Event* ev );
	void                   CTF_JoinTeamSintek( Event* ev );
	void                    CTF_JoinTeam( int desired_team );
	void              CTF_Team( Event* ev );
	void              CTF_ExtendGrapple( void );
	void              CTF_ReleaseGrapple( void );
	void              CTF_DeadDropFlag( void );
	void              CTF_UpdateHookBeam( Event* ev );
	Vector            CTF_GetGrapplePosition( void );
	void              CTF_AssignTeam( void );
	void              CTF_OpenJoinMenu( void );
	void              CTF_UpdateNumberOfPlayers( void );
	void                    CTF_DeadDropTech( void );
	void                    CTF_DropTech( Event* ev );
	void                    CTF_SoundEvent( Event* ev );
	void              SetViewAngles( Vector ang );
	void              DropWeaponEvent( Event* ev );
	void              CTF_DropFlag( Event* ev );
	void CTF_DrawHud( void );
	void CTF_HideHud( void );
};


#endif /* player.h */
