// Emacs style mode select	 -*- C++ -*- 
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// DESCRIPTION:
//
//
//-----------------------------------------------------------------------------


#ifndef __D_PLAYER_H__
#define __D_PLAYER_H__

// Finally, for odd reasons, the player input
// is buffered within the player data struct,
// as commands per game tick.
#include "d_ticcmd.h"

// The player data structure depends on a number
// of other structs: items (internal inventory),
// animation states (closely tied to the sprites
// used to represent them, unfortunately).
#include "d_items.h"
#include "p_pspr.h"

// In addition, the player is just a special
// case of the generic moving object/actor.
#include "actor.h"

#include "d_netinf.h"

//Added by MC:
#include "b_bot.h"

#include "t_info.h"

class skullb_s;	// [BC]
class teaminfo_s;	// [BC]

//
// Player states.
//
typedef enum
{
	// Playing or camping.
	PST_LIVE,
	// Dead on the ground, view follows killer.
	PST_DEAD,
	// Ready to restart/respawn???
	PST_REBORN,
	// [BC] Entered the game
	PST_ENTER,
	// [BC] Entered the level, but don't clear stats (intermission)
	PST_ENTER2
} playerstate_t;

//
// Player internal flags, for cheats and debug.
//
typedef enum
{
	// No clipping, walk through barriers.
	CF_NOCLIP			= 1,
	// No damage, no health loss.
	CF_GODMODE			= 2,
	// Not really a cheat, just a debug aid.
	CF_NOMOMENTUM		= 4,
	// [RH] Monsters don't target
	CF_NOTARGET			= 8,
	// [RH] Flying player
	CF_FLY				= 16,
	// [RH] Put camera behind player
	CF_CHASECAM			= 32,
	// [RH] Don't let the player move
	CF_FROZEN			= 64,
	// [RH] Stick camera in player's head if he moves
	CF_REVERTPLEASE		= 128,
	// [BC] Player can move in freeze mode
	CF_FREEZE			= 256,
	// [BC] Quad damage
	CF_HISSY			= 512
} cheat_t;


//
// Extended player object info: player_t
//
class player_s
{
public:
	void Serialize (FArchive &arc);
	void FixPointers (const DObject *obj);

	AActor		*mo;
	BYTE		playerstate;
	struct ticcmd_t	cmd;

	userinfo_t	userinfo;				// [RH] who is this?
	
	float		fov;					// field of vision
	fixed_t		viewz;					// focal origin above r.z
	fixed_t		viewheight;				// base height above floor for viewz
	fixed_t		deltaviewheight;		// squat speed.
	fixed_t		bob;					// bounded/scaled total momentum

	// killough 10/98: used for realistic bobbing (i.e. not simply overall speed)
	// mo->momx and mo->momy represent true momenta experienced by player.
	// This only represents the thrust that the player applies himself.
	// This avoids anomolies with such things as Boom ice and conveyors.
	fixed_t		momx, momy;				// killough 10/98

	int			health;					// only used between levels, mo->health
										// is used during levels
	int			maxlowhealth;			// [BC] Player's max low health
	int			maxhighhealth;			// [BC] Player's max high health

	int			armorpoints;
	int			armortype;				// armor type is 0-3
	int			maxarmor;				// [BC] Player's max armor
	runetype_t	rune;					// [BC] Rune player has
	runetype_t	lastrune;				// [BC] Avoid picking up the same rune superfast
	BOOL		slot1;					// [BC] If team leader, put next rune picked
										// up under rune slot 1

	int			powers[NUMPOWERS];		// invinc and invis are tic counters
	bool		cards[NUMCARDS];
	int			medals[NUMMEDALS];		// [BC] Player's medal count
	BOOL		backpack;
	byte		railhits;				// [BC] Consecutive railgun hits
	byte		consechits;				// [BC] 10 in a row gets an accuracy!
	byte		unanskills;				// [BC] 10 unanswered kills gets a domination!
	byte		railshots;				// [BC] Reload after 4th shot

	int			pending;				// [BC] Waiting to see if we hit something
	int			medalTics;				// [BC]
	char		*medalString;			// [BC]

	int			hits;					// [BC] Used for accuracy
	int			totalshots;				// [BC] Ditto
	
//	int			frags[MAXPLAYERS];		// kills of other players	[BC] Screw that!
	int			fragcount;				// [RH] Cumulative frags for this player
	int			lastkilltime;			// [BC] Level time when a player killed someone last
	int			lastexcellenttime;		// [BC] Level time when a player got an "Excellent!"

	int			pointcount;				// [BC] Teamgame pointcount
	int			score;					// [BC] For that new type of deathmatch

	int			deaths;					// [BC] Deaths. If you died, no perfect for you!

	weapontype_t	readyweapon;
	weapontype_t	pendingweapon;		// wp_nochange if not changing
	int			weaponowned[NUMWEAPONS];// needs to be int for status bar
	int			ammo[NUMAMMO];
	int			maxammo[NUMAMMO];

	int			attackdown, usedown;	// true if button down last tic
	int			tauntdown;				// [BC] Same here
	int			cheats;					// bit flags
	short		refire;					// refired shots are less accurate
	short		inconsistant;
	int			killcount, itemcount, secretcount;		// for intermission
	int			damagecount, bonuscount;// for screen flashing
	AActor		*attacker;				// who did damage (NULL for floors)
	int			extralight;				// so gun flashes light up areas
	int			xviewshift;				// [RH] view shift (for earthquakes)
	pspdef_t	psprites[NUMPSPRITES];	// view sprites (gun, etc)
	int			jumpTics;				// delay the next jump for a moment
	int			runeTics;				// [BC] How many tics left until they can
										// pick up another rune (used to avoid
										// instantly picking up the rune they just
										// dropped)

	int			invulTics;				// [BC] Temporary invulnerability when respawned
	int			nameTics;				// [BC] For onscreen name display
	player_s	*namePlyr;				// [BC] Player we just saw

	int			respawn_time;			// [RH] delay respawning until this tic
	fixed_t		oldvelocity[3];			// [RH] Used for falling damage
	AActor		*camera;				// [RH] Whose eyes this player sees through

	int			air_finished;			// [RH] Time when you start drowning

	AActor		*grab;					// [BC] Points to AActor player is grabbing
	AActor		*icon;					// [BC] Points to any floating icons above the player

	team_t		team;					// [BC] Team player is on
	bool		scored;					// [BC] Player has just scored a point (used for
										// evil grinning)
	bool		chatting;				// [BC] Player is chatting... don't shoot him, llama!

    byte        ping;                   // [csDoom] guess what :)	
	int         last_received;

	fixed_t     real_origin[3];			// coordinates and velocity which
	fixed_t     real_velocity[3];		// a client got from the server
	int         tic;					// and that was on tic "tic"

	// [BC] All bot info now stored in skullb_s
	skullb_s	*skullb;				// [BC] Player is a skull bot
	bool		isbot;					// [BC] Player is bot (for multiplayer games)
};

typedef player_s player_t;

// Bookkeeping on players - state.
extern player_s		players[MAXPLAYERS];

inline FArchive &operator<< (FArchive &arc, player_s *p)
{
	if (p)
		return arc << (BYTE)(p - players);
	else
		return arc << (BYTE)0xff;
}

inline FArchive &operator>> (FArchive &arc, player_s *&p)
{
	BYTE ofs;
	arc >> ofs;
	if (ofs == 0xff)
		p = NULL;
	else
		p = players + ofs;
	return arc;
}

//
// INTERMISSION
// Structure passed e.g. to WI_Start(wb)
//
typedef struct wbplayerstruct_s
{
	BOOL		in;			// whether the player is in game
	
	// Player stats, kills, collected items etc.
	int			skills;
	int			sitems;
	int			ssecret;
	int			stime;
//	int			frags[MAXPLAYERS];	[BC] Screw that!
	int			fragcount;	// [RH] Cumulative frags for this player
	int			deaths;		// [BC] Times player has died
	int			score;		// current score on entry, modified on return

} wbplayerstruct_t;

typedef struct wbstartstruct_s
{
	int			epsd;	// episode # (0-2)

	char		current[8];	// [RH] Name of map just finished
	char		next[8];	// next level, [RH] actual map name

	char		lname0[8];
	char		lname1[8];
	
	int			maxkills;
	int			maxitems;
	int			maxsecret;
	int			maxfrags;

	// the par time
	int			partime;
	
	// index of this player in game
	int			pnum;	

	wbplayerstruct_s	plyr[MAXPLAYERS];
} wbstartstruct_t;


#endif // __D_PLAYER_H__
