/*
Copyright (C) 2002-2003 Victor Luchits

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
#include "gs_qrespath.h"
#include "gs_pmodels.h"

#define	GAMENAME	"Warsow" // This name is used for master server queries and the "gamename" cvar

//===============================================================
//		WARSOW player AAboxes sizes

extern vec3_t	playerbox_stand_mins;
extern vec3_t	playerbox_stand_maxs;
extern int	playerbox_stand_viewheight;

extern vec3_t	playerbox_crouch_mins;
extern vec3_t	playerbox_crouch_maxs;
extern int	playerbox_crouch_viewheight;

extern vec3_t	playerbox_gib_mins;
extern vec3_t	playerbox_gib_maxs;
extern int	playerbox_gib_viewheight;

// item box
extern vec3_t	item_box_mins;
extern vec3_t	item_box_maxs;

//==================================================================

/*
==============================================================

PLAYER MOVEMENT CODE

Common between server and client so prediction matches

==============================================================
*/

#define STEPSIZE 18

// pmove_state_t is the information necessary for client side movement
// prediction
typedef enum 
{
	// can accelerate and turn
	PM_NORMAL,
	PM_SPECTATOR,
	// no acceleration or turning
	PM_DEAD,
	PM_GIB,		// different bounding box
	PM_FREEZE,
	PM_CHASECAM // same as freeze, but so client knows it's in chasecam
} pmtype_t;

// pmove->pm_flags
#define	PMF_DUCKED			1
#define	PMF_JUMP_HELD		2
#define	PMF_ON_GROUND		4
#define	PMF_TIME_WATERJUMP	8	// pm_time is waterjump
#define	PMF_TIME_LAND		16	// pm_time is time before rejump
#define	PMF_TIME_TELEPORT	32	// pm_time is non-moving time
#define PMF_NO_PREDICTION	64	// temporarily disables prediction (used for grappling hook)

// Kurim : new warsow flags
#define PMF_DASHING			128	// Dashing flag
#define PMF_SPECIAL_HELD	256	// Special flag
#define PMF_WALLJUMPING		512 // WJ starting flag
#define PMF_DOUBLEJUMPED	1024 // DJ stat flag

//#ifdef WJDOUBLECLICKED
//#define PMF_WALLJUMPARMED	0x00000800	// 2048
//#endif

void Pmove (pmove_t *pmove);

//===============================================================

//==================
//SPLITMODELS
//==================
//jal [start]

#define PMODEL_MAX_ANIMS	64

// The parts must be listed in draw order
enum {
	LOWER = 0,	
	UPPER,
	HEAD,

	PMODEL_PARTS
};

//jalVWState
enum {
	WEAPON,
	EXPANSION,
	BARREL,
	FLASH,
	HAND,

	WEAPMODEL_PARTS
};
//jal [end]

// gender stuff
enum
{
	GENDER_MALE,
	GENDER_FEMALE,
	GENDER_NEUTRAL
};

//===============================================================

/* gs_items - shared items definitions */

//==================
//	ITEM TAGS
//==================

typedef enum
{
	WEAP_NONE = 0,
	WEAP_GUNBLADE,
	WEAP_SHOCKWAVE,
	WEAP_RIOTGUN,
	WEAP_GRENADELAUNCHER,
	WEAP_ROCKETLAUNCHER,
	WEAP_PLASMAGUN,
	WEAP_LASERGUN,
	WEAP_ELECTROBOLT,

	WEAP_TOTAL
} weapon_tag_t;

typedef enum
{
	AMMO_NONE = 0,
	AMMO_CELLS = WEAP_TOTAL,
	AMMO_WAVES,
	AMMO_SHELLS,
	AMMO_GRENADES,
	AMMO_ROCKETS,
	AMMO_PLASMA,
	AMMO_LASERS,
	AMMO_BOLTS,

	AMMO_WEAK_GUNBLADE, //this is the blade
	AMMO_WEAK_WAVES,
	AMMO_WEAK_SHELLS,
	AMMO_WEAK_GRENADES,
	AMMO_WEAK_ROCKETS,
	AMMO_WEAK_PLASMA,
	AMMO_WEAK_LASERS,
	AMMO_WEAK_BOLTS,

	AMMO_TOTAL

} ammo_tag_t;

typedef enum
{
	ARMOR_NONE = 0,
	ARMOR_GA = AMMO_TOTAL,
	ARMOR_YA,
	ARMOR_RA,
	ARMOR_SHARD,

	ARMOR_TOTAL

} armor_tag_t;

typedef enum
{
	HEALTH_NONE = 0,
	HEALTH_SMALL = ARMOR_TOTAL,
	HEALTH_MEDIUM,
	HEALTH_LARGE,
	HEALTH_MEGA,

	HEALTH_TOTAL

} health_tag_t;

typedef enum
{
	POWERUP_NONE = 0,
	POWERUP_QUAD = HEALTH_TOTAL,

	POWERUP_TOTAL

} powerup_tag_t;

typedef enum
{
	AMMO_PACK = POWERUP_TOTAL,
	FLAG_RED,
	FLAG_BLUE,
	FLAG_GREEN,
	FLAG_YELLOW,

	ITEMS_TOTAL
} otheritems_tag_t;

#define GS_MAX_ITEM_TAGS ITEMS_TOTAL

#define MAX_ITEM_MODELS 2

// gitem_t->flags
#define	ITFLAG_PICKABLE			1
#define	ITFLAG_USABLE			2
#define ITFLAG_DROPABLE			4
#define ITFLAG_STAY_COOP		8

// gitem_t->type
// define as bitflags values so they can be masked
typedef enum {
	IT_WEAPON = 1
,	IT_AMMO = 2
,	IT_ARMOR = 4
,	IT_POWERUP = 8
,	IT_FLAG = 16
,	IT_HEALTH = 64
}itemtype_t;

typedef struct gitem_s
{
	//header
	char		*classname;		// spawning name
	int			tag;
	itemtype_t	type;
	int			flags;			// actions the item does in the game
	
	//media
	char		*world_model[MAX_ITEM_MODELS];
	char		*icon;
	char		*pickup_sound;
	int			effects;
	int			renderfx;

	
	char		*pickup_name;	// for printing on pickup
	char		*short_name;	// for printing on messages
	char		*color;			// for printing on messages
	
	int			quantity;		// for ammo how much, for weapons how much is used per shot
	// special
	int			ammo_tag;		// uses this ammo, for weapons
	int			weakammo_tag;

	void		*info;			// miscelanea info goes pointed in here

	char		*q3classname;

	// space separeted string of stuff to precache that's not mentioned above
	char		*precache_models;
	char		*precache_sounds;
	char		*precache_images;
} gitem_t;

extern gitem_t	itemdefs[];

gitem_t	*GS_FindItemByTag( int tag );
gitem_t	*GS_FindItemByClassname( char *classname );
gitem_t	*GS_FindItemByName( char *name );

//===============================================================

//===================
//	GAMETYPES
//===================

enum {
	MATCH_STATE_NONE,
	MATCH_STATE_WARMUP,
	MATCH_STATE_COUNTDOWN,
	MATCH_STATE_PLAYTIME,
	MATCH_STATE_POSTMATCH,
	MATCH_STATE_WAITEXIT
};

enum {
	GAMETYPE_DM,
	GAMETYPE_DUEL,
	GAMETYPE_TDM,
	GAMETYPE_CTF,
	GAMETYPE_RACE,
	GAMETYPE_MIDAIR,

	GAMETYPE_TOTAL
};

enum {
	TEAM_SPECTATOR,
	TEAM_PLAYERS,
	TEAM_RED,
	TEAM_BLUE,
	TEAM_GREEN,
	TEAM_YELLOW,

	GS_MAX_TEAMS
};

// gs_gametypes.c
int GS_Gametype_FindByName( char *name );
int GS_Gametype_FindByShortName( char *name );
char *GS_Gametype_StatusBar( int gametype );
char *GS_Gametype_Name( int gametype );
char *GS_Gametype_ShortName( int gametype );
qboolean GS_Gametype_IsTeamBased( int gametype );
int GS_Gametype_SpawnableItemMask( int gametype );
int GS_Gametype_RespawnableItemMask( int gametype );
int GS_Gametype_DropableItemMask( int gametype );
int	GS_GameType_MaxWallJumps( int gametype );

// teams
void GS_TeamColor( int team, vec4_t color ) ;
char *GS_TeamName( int team );
char *GS_TeamSkinName( int team );
int GS_Teams_TeamFromName( char *teamname );

//===============================================================

//gs_misc.c
void GS_Obituary ( void *victim, int gender, void *attacker, int mod, char *message, char *message2 );

//===============================================================

#define DEFAULT_BULLET_HSPREAD	300
#define DEFAULT_BULLET_VSPREAD	500

//===============================================================

#ifdef __linux__
static const char	*gs_stat_names[] __attribute__ ((unused)) = {
#else
static const char	*gs_stat_names[] = {
#endif
	"STAT_GAMETYPE"
	,"STAT_HEALTH"
	,"STAT_AMMO"
	,"STAT_AMMO_ITEM"
	,"STAT_WEAK_AMMO"
	,"STAT_ARMOR"
	,"STAT_ARMOR_ITEM"
	,"STAT_SELECTED_ITEM"
	,"STAT_PICKUP_ITEM"
	,"STAT_WEAPON_ITEM"
	,"STAT_POWERUP_ITEM"
	
	,"STAT_LAYOUTS"
	,"STAT_FRAGS"
	,"STAT_TEAM"
	,"STAT_CHASING"

	,"STAT_POINTED_PLAYER"
	,"STAT_POINTED_TEAMPLAYER"

	,"STAT_RACE_TIME"
	,"STAT_RACE_PLAYERBESTTIME"
	,"STAT_RACE_MATCHBESTTIME"

	,"STAT_TEAM_RED_SCORE"
	,"STAT_TEAM_BLUE_SCORE"
	,"STAT_TEAM_GREEN_SCORE"
	,"STAT_TEAM_YELLOW_SCORE"

	,"STAT_CTF_RED_FLAG"
	,"STAT_CTF_BLUE_FLAG"

	,NULL
};

enum {
	STAT_GAMETYPE = 0
	,STAT_HEALTH
	,STAT_AMMO
	,STAT_AMMO_ITEM
	,STAT_WEAK_AMMO
	,STAT_ARMOR
	,STAT_ARMOR_ITEM
	,STAT_SELECTED_ITEM	
	,STAT_PICKUP_ITEM
	,STAT_WEAPON_ITEM
	,STAT_POWERUP_ITEM

	,STAT_LAYOUTS	
	,STAT_FRAGS	
	,STAT_TEAM	
	,STAT_CHASING

	,STAT_POINTED_PLAYER
	,STAT_POINTED_TEAMPLAYER
	
	,STAT_RACE_TIME	
	,STAT_RACE_PLAYERBESTTIME
	,STAT_RACE_MATCHBESTTIME

	,STAT_TEAM_RED_SCORE
	,STAT_TEAM_BLUE_SCORE
	,STAT_TEAM_GREEN_SCORE
	,STAT_TEAM_YELLOW_SCORE

	,STAT_CTF_RED_FLAG
	,STAT_CTF_BLUE_FLAG

	,MAX_STATS = PS_MAX_STATS	//32
};

// STAT_LAYOUTS flag bits meanings
#define	STAT_LAYOUT_GENERIC				0x00000001
#define	STAT_LAYOUT_INVENTORY			0x00000002
#define	STAT_LAYOUT_SCOREBOARD			0x00000004
#define	STAT_LAYOUT_TEAMTAB				0x00000008
#define	STAT_LAYOUT_CHALLENGER			0x00000010 // player is in challengers queue (used for ingame menu)
#define	STAT_LAYOUT_READY				0x00000020 // player is ready (used for ingame menu)

#define STAT_NOTSET						-9999 // used for stats that don't have meaningful value atm.

#define FLAG_STATUS_SAFE				0
#define FLAG_STATUS_STOLEN				1
#define FLAG_STATUS_DROPPED				2

//===============================================================

// dmflags->integer flags
#define	DF_NO_HEALTH		0x00000001	// 1
#define	DF_NO_ITEMS			0x00000002	// 2
#define	DF_WEAPONS_STAY		0x00000004	// 4
//#define	DF_UNUSED		0x00000008	// 8
#define	DF_INSTANT_ITEMS	0x00000010	// 16
//#define	DF_SAME_LEVEL		0x00000020	// 32
//#define DF_UNUSED2		0x00000040	// 64
//#define DF_UNUSED3		0x00000080	// 128
//	#define DF_UNUSED4		0x00000100	// 256
//#define	DF_SPAWN_FARTHEST	0x00000200	// 512
//#define DF_FORCE_RESPAWN	0x00000400	// 1024
#define DF_NO_ARMOR			0x00000800	// 2048
//#define DF_UNUSED5		0x00001000	// 4096
#define DF_INFINITE_AMMO	0x00002000	// 8192
#define DF_QUAD_DROP		0x00004000	// 16384
//#define DF_UNUSED6		0x00008000	// 32768

//===============================================================

// silencer bit
#define MZ_SILENCED				128

//-----------------------------------------------

// wsw : pb : MOD cleanup

// means of death
#define MOD_UNKNOWN			0

typedef enum {

	//MOD_UNKNOWN,

	// Weapon damage :
	MOD_GUNBLADE_W = 36,
	MOD_GUNBLADE_S,
	MOD_RIOTGUN_W,
	MOD_RIOTGUN_S,
	MOD_GRENADE_W,
	MOD_GRENADE_S,
	MOD_ROCKET_W,
	MOD_ROCKET_S,
	MOD_PLASMA_W,
	MOD_PLASMA_S,
	MOD_ELECTROBOLT_W,
	MOD_ELECTROBOLT_S,
	MOD_LASERGUN_W,
	MOD_LASERGUN_S,
	MOD_GRENADE_SPLASH_W,
	MOD_GRENADE_SPLASH_S,
	MOD_ROCKET_SPLASH_W,
	MOD_ROCKET_SPLASH_S,
	MOD_PLASMA_SPLASH_W,
	MOD_PLASMA_SPLASH_S,
	
	// World damage
	MOD_WATER,
	MOD_SLIME,
	MOD_LAVA,
	MOD_CRUSH, // moving item blocked by player
	MOD_TELEFRAG,
	MOD_FALLING,
	MOD_SUICIDE,
	MOD_EXPLOSIVE,

	 // probably not used
	MOD_BARREL,
	MOD_BOMB,
	MOD_EXIT, // except this one : player leaves
	MOD_SPLASH,
	MOD_TARGET_LASER,
	MOD_TRIGGER_HURT,
	MOD_HIT,
	MOD_TARGET_BLASTER,
	//MOD_LASER_TRAP,
	MOD_GRAPPLE,

} mod_damage_t;

//===============================================================

//
// events, event parms
//
#ifdef THIS_IS_DISABLED
enum
{
	FOOTSTEP_NORMAL,
	FOOTSTEP_BOOT,
	FOOTSTEP_FLESH,
	FOOTSTEP_MECH,
	FOOTSTEP_ENERGY,
	FOOTSTEP_METAL,
	FOOTSTEP_SPLASH,

	FOOTSTEP_TOTAL
};
#endif
enum
{
	PAIN_25,
	PAIN_50,
	PAIN_75,
	PAIN_100,

	PAIN_TOTAL
};

enum
{
	FALL_SHORT,
	FALL_MEDIUM,
	FALL_FAR,

	FALL_TOTAL
};

//fire modes as event parm
enum
{
	FIRE_MODE_WEAK,
	FIRE_MODE_STRONG,

	FIRE_MODES_COUNT
};

// vsay tokens list
#ifdef VSAYS
enum
{
	VSAY_GENERIC,
	VSAY_NEEDHEALTH,
	VSAY_NEEDWEAPON,
	VSAY_NEEDARMOR,
	VSAY_AFFIRMATIVE,
	VSAY_NEGATIVE,
	VSAY_YES,
	VSAY_NO,
	VSAY_ONDEFENSE,
	VSAY_ONOFFENSE,
	VSAY_OOPS,
	VSAY_SORRY,
	VSAY_THANKS,
	VSAY_NOPROBLEM,
	VSAY_YEEHAA,
	VSAY_GOODGAME,
	VSAY_DEFEND,
	VSAY_ATTACK,
	VSAY_NEEDBACKUP,
	VSAY_BOOO,
	VSAY_NEEDDEFENSE,
	VSAY_NEEDOFFENSE,
	VSAY_NEEDHELP,
	VSAY_ROGER,
	VSAY_ARMORFREE,
	VSAY_AREASECURED,
	VSAY_SHUTUP,
	VSAY_BOOMSTICK,
	VSAY_GOTOPOWERUP,
	VSAY_GOTOQUAD,
	VSAY_OK,

	VSAY_TOTAL = 128
};
#endif // VSAYS

// entity_state_t->event values
typedef enum
{
	EV_NONE,
	EV_ITEM_RESPAWN,
	EV_FALL,
	EV_PAIN,
	EV_DIE,
	EV_GIB,
	EV_JUMP,
	EV_JUMP_PAD,
	EV_MUZZLEFLASH,

	EV_PLAYER_TELEPORT_IN,
	EV_PLAYER_TELEPORT_OUT,

	EV_TELEPORT,

	EV_GESTURE,	//splitmodels events
	EV_DROP,
	EV_WEAPONUP,
	EV_SPOG,	//debrisbounce

	EV_BLOOD2,
	EV_BLOOD_SAVED,

	//wsw weapon events
	EV_FIRE_BLADE,	// unused
	EV_BLADE_IMPACT,
	EV_GUNBLADEBLAST_IMPACT,
	EV_FIRE_BULLET,
	EV_FIRE_RIOTGUN,
	EV_GRENADE_BOUNCE,
	EV_GRENADE_EXPLOSION,
	EV_ROCKET_EXPLOSION,
	EV_PLASMA_EXPLOSION,
	EV_ELECTROTRAIL,
	EV_BOLT_EXPLOSION,
	//EV_ELECTROSHELL,

	// nine spots reserved for new weapons sfx, so
	// the events below don't change their numbers easily
	EV_FREE1,
	EV_FREE2,
	EV_FREE3,
	EV_FREE4,
	EV_FREE5,
	EV_FREE6,
	EV_FREE7,
	EV_FREE8,
	EV_FREE9,
	
	// unused

	EV_EXPLOSION1,
	EV_EXPLOSION2,

	EV_BLOOD,
	EV_BLASTER,
	EV_SPARKS,
	EV_BULLET_SPARKS,
	
	EV_SEXEDSOUND,		//used
	
	// vsay tokens

	EV_VSAY,				

	EV_LASER_SPARKS,

	EV_FIRE_SHOTGUN,
	EV_LIGHTNING,
	EV_FREE12,
	EV_GREEN_LASER,
	
	MAX_EVENTS = 128
} entity_event_t;

typedef enum
{
	PSEV_NONE = 0,
	PSEV_HIT,
	PSEV_PICKUP,
	PSEV_DAMAGE_BLEND,
	PSEV_INDEXEDSOUND,
	PSEV_NOAMMO,
	PSEV_ANNOUNCER,
	PSEV_ANNOUNCER_QUEUED,

	PSEV_MAX_EVENTS = 0xFF
} playerstate_event_t;
//===============================================================

// entity_state_t->type values
enum
{
	ET_GENERIC,
	ET_PLAYER,
	ET_BEAM,
	ET_PORTALSURFACE,
	ET_EVENT,
	ET_PUSH_TRIGGER,

	ET_GIB,				// leave a trail
	ET_BLASTER,			// redlight + trail
	ET_ELECTRO_WEAK,
	ET_ROCKET,			// redlight + trail
	ET_GRENADE,
	ET_PLASMA,
	ET_SHOCKWAVE,

	ET_ITEM,			// for simple items
	ET_LASERBEAM,		// for continuous beams
	ET_CURVELASERBEAM,	// for curved beams
	ET_FLAG_BASE,

	MAX_ENTITY_TYPES = 128
};

