
#ifndef _GUSER_H
#define _GUSER_H

#pragma warning (disable : 4200 4244)

#include <stdarg.h>
#include <math.h>

#include "dk_shared.h"

// define GAME_INCLUDE so that game.h does not define the
// short, server-visible gclient_t and edict_t structures,
// because we define the full size ones in this file
#define	GAME_INCLUDE
#include "physics.h"

typedef float vec_t;
typedef float vec3_t[3];

#define qv_len(v) (sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]))

#define qv_dist(v1, v2)                           \
(                                                 \
    sqrt( ((v2[0] - v1[0]) * (v2[0] - v1[0])) +   \
	      ((v2[1] - v1[1]) * (v2[1] - v1[1])) +   \
		  ((v2[2] - v1[2]) * (v2[2] - v1[2])) )   \
)

#define xy_dist(v1, v2)                           \
(                                                 \
    sqrt( ((v2[0] - v1[0]) * (v2[0] - v1[0])) +   \
	      ((v2[1] - v1[1]) * (v2[1] - v1[1])) )	  \
)

#define	TRUE	1
#define	FALSE	0

// edict->movetype values
typedef enum
{
	MOVETYPE_NONE,			// never moves
	MOVETYPE_NOCLIP,		// origin and angles change with no interaction
	MOVETYPE_PUSH,			// no clip to world, push on box contact
	MOVETYPE_STOP,			// no clip to world, stops on box contact

	MOVETYPE_WALK,			// gravity
	MOVETYPE_STEP,			// gravity, special edge handling
	MOVETYPE_FLY,
	MOVETYPE_TOSS,			// gravity
	MOVETYPE_FLYMISSILE,	// extra size to monsters
	MOVETYPE_BOUNCE,
	MOVETYPE_FLOAT,
	MOVETYPE_BOUNCEMISSILE,
} movetype_t;										// if not in water, then acts like movetype_toss

// edict->deadflag values

#define	DEAD_NO					0
#define	DEAD_DYING				1
#define	DEAD_DEAD				2

#define	DAMAGE_NO				0
#define	DAMAGE_YES				1
#define	DAMAGE_AIM				2

//	edict->flags
//	Q2FIXME:	remove useless flags
#define	FL_FORCEANGLES			0x00000001	//	force the client to look a certain direction
#define	FL_FIXANGLES			0x00000002	//	force the client angles to change on next frame,
											//	cleared each time a frame is run for the client
#define	FL_FAKEENTITY			0x00000004	// not a real server entity - malloced up as a temporary goal
#define	FL_CLIENT				0x00000008
#define	FL_INWATER				0x00000010
#define	FL_MONSTER				0x00000020
#define	FL_SWIM   				0x00000040
#define	FL_NOTARGET				0x00000080
#define	FL_ITEM					0x00000100
#define	FL_ONGROUND				0x00000200
#define	FL_PARTIALGROUND		0x00000400	// not all corners are valid
#define	FL_WATERJUMP			0x00000800	// player jumping out of water
#define	FL_JUMPRELEASED			0x00001000	// for jump debouncing
#define	FL_BOT					0x00002000
#define FL_EXPLOSIVE			0x00004000
#define	FL_ATTACKHOLD    		0x00008000
#define	FL_HCHILD				0x00010000	// a hierarchial child entity
#define	FL_HPARENT	 			0x00020000	// a hierarchial parent entity
#define	FL_BODY					0x00040000
#define	FL_INWARP				0x00080000
#define	FL_CAMERAMODE			0x00100000
#define	FL_DEBUG				0x00200000
#define	FL_IGNOREUSETARGET		0x00400000
#define	FL_NORESPAWN			0x00800000	// item will not respawn if set
#define	FL_POSSESSED			0x01000000
#define FL_PUSHABLE				0x02000000	// can be pushed by a MOVETYPE_WALK
#define	FL_LEDGEDROP			0x04000000	// monster/bot can fall off of ledges
#define	FL_TEAMSLAVE			0x08000000
#define  FL_LOOPAMBIENT       0x10000000  // constantly play weapon ambient

//	hierarchical types
#define	HR_SURFACE				1	//	attaches child to a specific surface
#define	HR_RELATIVE				2	//	attaches child based on initial position of child relative to parent
#define	HR_BMODEL				3	//	not implemented from DK Quake 1 source yet -- might not be necessary...
#define	HR_SURFACE_OLD			4	//	attaches child to a specific set of surfaces (same as HR_SURFACE but
									//	less efficient -- should be phased out eventually)

//	flags for children in a hierarchical list
#define	HRF_NOROLL			0x00000001	//	sticking object's roll not tied to parent 
#define	HRF_NOPITCH			0x00000002	//	sticking object's pitch not tied to parent
#define	HRF_NOYAW			0x00000004	//	sticking object's yaw not tied to parent
#define	HRF_NOMOVE			0x00000008	//	sticking objects movement not tied to parent
#define	HRF_NOREMOVE 		0x00000020	//	don't remove this this sticky if parent is removed
#define	HRF_FLIPFORWARD		0x00000080	//	flip normal of forward surface
#define	HRF_FLIPRIGHT		0x00000100	//	flip normal of right surface
#define	HRF_OFFSET			0x00000200	//	offest model by child->offset field

// Item flags

#define	IT_PLASTEEL			0x00000001
#define	IT_CHROMATIC		0x00000002
#define	IT_SILVER			0x00000004
#define	IT_GOLD				0x00000008
#define	IT_CHAINMAIL		0x00000010
#define	IT_BLACK_ADAMANT	0x00000020
#define	IT_KEVLAR			0x00000040
#define	IT_EBONITE			0x00000080
#define	IT_WRAITHORB		0x00000100
#define IT_MEGASHIELD		0x00000200
#define IT_GOLDENSOUL		0x00000400
#define IT_ANTIDOTE			0x00000800
#define IT_POWERBOOST		0x00001000
#define	IT_ATTACKBOOST		0x00002000
#define	IT_SPEEDBOOST		0x00004000
#define	IT_ACROBOOST		0x00008000
#define	IT_VITABOOST		0x00010000
#define	IT_JET_BOOTS		0x00020000
#define	IT_OXYLUNG			0x00040000
#define	IT_ICE_BOOTS		0x00080000
#define	IT_ENVIROSUIT		0x00100000
#define	IT_POISON    		0x00200000

#define	SPAWNFLAG_NOT_EASY			256
#define	SPAWNFLAG_NOT_MEDIUM		512
#define	SPAWNFLAG_NOT_HARD			1024
#define	SPAWNFLAG_NOT_DEATHMATCH	2048

// sound channels
// channel 0 never willingly overrides
// other channels (1-7) allways override a playing sound on that channel

#define	CHAN_AUTO		0
#define	CHAN_WEAPON		1
#define	CHAN_VOICE		2
#define	CHAN_ITEM		3
#define	CHAN_BODY		4

// modifier flags
#define	CHAN_NO_PHS_ADD	8	// send to all clients, not just ones in PHS (ATTN 0 will also do this)
#define	CHAN_RELIABLE	16	// send by reliable message, not datagram
#define	CHAN_OVERRIDE	CHAN_NO_PHS_ADD + CHAN_WEAPON	//	mother fucking shit fucking asshole shit fuck damn fuckers ARGH!!!!

#define	ATTN_NONE		 0
#define	ATTN_NORM		 1
#define	ATTN_IDLE		 2
#define	ATTN_STATIC		 3

// set when an item is picked up, cleared once its expire message is shown
#define	EXP_WRAITHORB	0x00000001   
#define	EXP_MEGASHIELD	0x00000002 
#define	EXP_ENVIROSUIT	0x00000004
#define EXP_POWERBOOST	0x00000008
#define EXP_SPEEDBOOST	0x00000010
#define EXP_ATTACKBOOST	0x00000020
#define EXP_ACROBOOST	0x00000040
#define EXP_VITABOOST	0x00000080
#define EXP_OXYLUNG		0x00000100
#define EXP_JETBOOTS	0x00000200
#define	EXP_POISON		0x00000400

// door/plat/button states
#define STATE_TOP     0         // door is at top
#define STATE_BOTTOM  1         // door is at bottom
#define STATE_DOWN    2         // door is going down
#define STATE_UP      3         // door is going up

// base attribute levels used to calculate attribute modifications based on boost levels
#define	ATTR_JUMPSPEED		190.0
#define	ATTR_RUNSPEED		320.0
#define	ATTR_ATTACKMULT		1.0
#define	ATTR_HEALTH			100.0
#define	ATTR_POWERMULT		1.0

//	camera flags for SetCameraState
#define	CAMFL_LOCK_X		0x00000001
#define	CAMFL_LOCK_Y		0x00000002
#define	CAMFL_LOCK_Z		0x00000004

typedef struct
{
	char  *key;
	char  *value;
} userEpair_t;


// frames
typedef struct
{
	int    frameIndex;    // frame number
	int    frameNext;     // next frame to goto
	char  *frameName;
} userFrame_t;

typedef struct
{
	int   frameIndex;
	int   frameNext;
	int   frameTrans;
} followFrame_t;






///////////////////////////////////////////////////////////////////////////
/// Frame Info
///////////////////////////////////////////////////////////////////////////

// model info

// userFrameInfo flags
#define MI_MODELALIAS  0x00000001
#define MI_MODELLW     0x00000002


typedef struct
{
	char           modelName[50];
	unsigned long  flags;
	int            numframes;
	int            numsurfs;
} userModelInfo_t;





// frame info
typedef struct
{
	char          frameName[50];
	unsigned long flags;

	// unsigned char bboxmin[3];
	// unsigned char bboxmax[3];
} userFrameInfo_t;

////////////////////////////////////////////////////////////////////////
//	used for trace function
////////////////////////////////////////////////////////////////////////

typedef struct
{
	int			allsolid;	        // if true, plane is not valid
	int			startsolid;        // if true, the initial point was in a solid area
	int			inopen;
	int			inwater;
	float		fraction;		    // time completed, 1.0 = didn't hit anything
	vec3_t		endpos;			// final position
	vec3_t		planeNormal;
	
	struct	edict_s		*ent;         // entity the surface is on
} userTrace_t;


///////////////////////////////////////////////////////////////////////////////
//	Stuff from Quake 2's g_local.h
///////////////////////////////////////////////////////////////////////////////


//
// this structure is cleared as each map is entered
// it is read/written to the level.sav file for savegames
//
typedef struct
{
	int			framenum;
	float		time;

	char		level_name[MAX_QPATH];	// the descriptive name (Outer Base, etc)
	char		mapname[MAX_QPATH];		// the server name (base1, etc)
	char		nextmap[MAX_QPATH];		// go here when fraglimit is hit

	// intermission state
	float		intermissiontime;		// time the intermission was started
	char		*changemap;
	int			exitintermission;
	vec3_t		intermission_origin;
	vec3_t		intermission_angle;

	int			players;		// FIXME: count when needed, don't store

	edict_t		*sight_client;	// changed once each frame for coop games

	edict_t		*sight_entity;
	int			sight_entity_framenum;
	edict_t		*sound_entity;
	int			sound_entity_framenum;
	edict_t		*sound2_entity;
	int			sound2_entity_framenum;

	int			pic_health;

	int			total_secrets;
	int			found_secrets;

	int			total_goals;
	int			found_goals;

	int			total_monsters;
	int			killed_monsters;

	edict_t		*current_entity;	// entity running from G_RunFrame
	edict_t		*body_que;			// looped chain of dead bodies
} level_locals_t;


// spawn_temp_t is only used to hold entity field values that
// can be set from the editor, but aren't actualy present
// in edict_t during gameplay
typedef struct
{
	// world vars
	char		*sky;
	float		skyrotate;
	vec3_t		skyaxis;
	char		*nextmap;

	int			lip;
	int			distance;
	int			height;
	char		*noise;
	float		pausetime;
	char		*item;
	char		*gravity;

	float		minyaw;
	float		maxyaw;
	float		minpitch;
	float		maxpitch;
} spawn_temp_t;

// client data that stays across multiple level loads
typedef struct
{
	char		userinfo[MAX_INFO_STRING];
	char		netname[16];
	char		sounddir[MAX_QPATH];		// player/male, etc
	int			hand;

	// values saved and restored from edicts when changing levels
	int			health;
	int			max_health;

	int			selected_item;
	int			inventory[MAX_ITEMS];

	// ammo capacities
	int			max_bullets;
	int			max_shells;
	int			max_rockets;
	int			max_grenades;
	int			max_cells;
	int			max_slugs;
} client_persistant_t;

// client data that staus across deathmatch respawns
typedef struct
{
	int			enterframe;			// level.framenum the client entered the game
	int			score;				// frags, etc
	vec3_t		cmd_angles;			// angles sent over in the last command
} client_respawn_t;

// this structure is cleared on each PutClientInServer(),
// except for 'client->pers'
typedef struct gclient_s
{
	// known to server
	player_state_t	ps;				// communicated by server to clients
	int				ping;

	// private to game
	client_persistant_t	pers;
	client_respawn_t	resp;
	pmove_state_t		old_pmove;	// for detecting out-of-pmove changes

	qboolean	showscores;			// set layout stat
	qboolean	showinventory;		// set layout stat
	qboolean	showhelpicon;

	int			ammo_index;

	int			buttons;
	int			oldbuttons;
	int			latched_buttons;

	qboolean	weapon_thunk;

	// sum up damage over an entire frame, so
	// shotgun blasts give a single big kick
	int			damage_armor;		// damage absorbed by armor
	int			damage_parmor;		// damage absorbed by power armor
	int			damage_blood;		// damage taken out of health
	int			damage_knockback;	// impact damage
	vec3_t		damage_from;		// origin for vector calculation

	float		killer_yaw;			// when dead, look at killer

//	weaponstate_t	weaponstate;
	vec3_t		kick_angles;	// weapon kicks
	vec3_t		kick_origin;
	float		v_dmg_roll, v_dmg_pitch, v_dmg_time;	// damage kicks
	float		fall_time, fall_value;		// for view drop on fall
	float		damage_alpha;
	float		bonus_alpha;
	vec3_t		damage_blend;
	vec3_t		v_angle;			// aiming direction
	float		bobtime;			// so off-ground doesn't change it
	vec3_t		oldviewangles;
	vec3_t		oldvelocity;

	float		next_drown_time;
	int			old_waterlevel;
	int			breather_sound;

	int			machinegun_shots;	// for weapon raising

	// animation vars
	int			anim_end;
	int			anim_priority;
	qboolean	anim_duck;
	qboolean	anim_run;

	// powerup timers
	float		quad_framenum;
	float		invincible_framenum;
	float		breather_framenum;
	float		enviro_framenum;

	qboolean	grenade_blew_up;
	float		grenade_time;
	int			silencer_shots;
	int			weapon_sound;

	float		pickup_msg_time;

	float		respawn_time;		// can respawn when time > this
} gclient_t;

//
// this structure is left intact through an entire game
// it should be initialized at dll load time, and read/written to
// the server.ssv file for savegames
//
typedef struct
{
	char		helpmessage1[512];
	char		helpmessage2[512];
	qboolean	helpchanged;

	gclient_t	*clients;		// [maxclients]

	// can't store spawnpoint in level, because
	// it would get overwritten by the savegame restore
	char		spawnpoint[512];	// needed for coop respawns

	// store latched cvars here that we want to get at often
	int			maxclients;
	int			maxentities;

	// cross level triggers
	int			serverflags;

	// items
	int			num_items;
} game_locals_t;

///////////////////////////////////////////////////////////////////////////////
//	function typedefs
///////////////////////////////////////////////////////////////////////////////

typedef void	(*think_t)	(struct edict_s *self);
typedef void	(*touch_t)	(struct edict_s *self, struct edict_s *other, cplane_t *plane, csurface_t *surf);
typedef	void	(*use_t)	(struct edict_s *self, struct edict_s *other, struct edict_s *activator);
typedef	void	(*pain_t)	(struct edict_s *self, struct edict_s *other, float kick, int damage);
typedef	void	(*die_t)	(struct edict_s *self, struct edict_s *inflictor, struct edict_s *attacker, int damage, vec3_t point);
typedef	void	(*blocked_t)(struct edict_s *self, struct edict_s *other);

///////////////////////////////////////////////////////////////////////////////
// this file is shared between katana and the dlls so be
// careful changing it
//
// if you change the fields of this structure then the
// dlls need to be recompiled
//
// will be reduced!!!!!!
///////////////////////////////////////////////////////////////////////////////

typedef struct edict_s
{
	// QUAKE2 REQUIRED FILEDS
	entity_state_t	s;
	struct gclient_s	*client;	// NULL if not a player
									// the server expects the first part
									// of gclient_s to be a player_state_t
									// but the rest of it is opaque

	qboolean	inuse;
	int			linkcount;

	// FIXME: move these fields to a server private sv_entity_t
	link_t		area;				// linked to a division node or leaf
	
	int			num_clusters;		// if -1, use headnode instead
	int			clusternums[MAX_ENT_CLUSTERS];
	int			headnode;			// unused if num_clusters != -1
	int			areanum, areanum2;

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

	int			svflags;
//	vec3_t		mins, maxs;
	vec3_t		absmin, absmax, size;
	solid_t		solid;
	int			clipmask;
	struct edict_s *owner;

	// END OF QUAKE2 REQUIRED FIELDS


	float		freetime;			// sv.time when the object was freed

	// this is an epair list of values that we
	// got out of the bsp file
	// These need to be parsed in the spawn functions.
	// NULL in key terminates this
	userEpair_t  *epair;

	// class this entity belongs to
	char    *className;

	// index into sv.models (model we are using)
	// needed here?  Shouldn't set model set this
	// for us?
	int     modelIndex;         

	// 
	struct edict_s  *enemy;
	struct edict_s  *goalentity;

	// the entity under this one
	// used in pushmove code
	edict_t  *groundEntity;
	int		  groundEntity_linkcount;

	// used by engine for clipping - objects never clip against owner
	// struct userEntity_s  *owner;

	struct edict_s  *view_entity;
	struct edict_s  *input_entity;

	// user's inventory
	// this pointer must be saved between levels
	void			*inventory;
	
	// these are flags that the editor can set and when
	// the entity gets spawned the dll code can do something
	// This field is not used by the engine/
    unsigned long  spawnflags;

	// delay for nelno
	float delay;

	// kill target
	char *killtarget;

	// name of the model file we are using
	char *modelName;

	int    movetype;

	// local time for a bmodel entity.  This time does not change if a bmodel is blocked so that
	// time dependent bmodel moves will not finish before the movement is completed
	float	ltime;


	vec3_t	velocity;
	vec3_t	avelocity;

	//	Q2FIXME:	Is this the same as ent->s.frame now?
	int frameIndex;    // frame in model file

	float	skin;
	
	//	effects gone, use self->s.effects
	//	unsigned long effects;

    // functions
	void (*prethink)	(struct edict_s *ent);
	void (*postthink)	(struct edict_s *ent);

#ifdef	VERYOLD
	void (*touch)		(struct edict_s *touched, struct edict_s *touchee);
	void (*think)       (struct edict_s *ent);
	void (*blocked)		(struct edict_s *self, struct edict_s *other);
	void (*use)			(struct edict_s *ent);
	void (*pain)		(struct edict_s *self);
	void (*die)			(struct edict_s *self);
#endif

	touch_t		touch;
	think_t		think;
	blocked_t	blocked;
	use_t		use;
	pain_t		pain;
	die_t		die;

	float	nextthink;
	// int	    groundentity;

   float       exppoints;              // experience points
   float       explevel;               // experience level
	float			armor_val;
	float			armor_abs;

	float	health;
	float	frags;

	// weapons
   // Q2FIXME: with weapons being an entity now, are these needed anymore?
   // --weapon entity ptr is in client->ps.weapon (model/frame info are same as other ents)
	float	weapon;
	char 	*weaponmodel;
	float	weaponframe;
 
	// items has been replaced by inventory structure
	// float	items;

	float	takedamage;
	float	deadflag;
	vec3_t	view_ofs;

	float	button0;
	float	button1;
	float	button2;

	float	fixangle;
	float	idealpitch;
	char    *netname;     // if this entity is a user then name of user
	// int	    enemy;
	unsigned long    flags;
	float	colormap;
	float	team;

	// float	max_health;

	float	teleport_time;

	int		waterlevel;
	int		watertype;

	int	    aiment;
	char 	*target;
	char 	*targetname;

	vec3_t	movedir;

	char 	*message;
	float	sounds;

	//translucency %
	// 0 = opaque
	// 1 = 20% translucent
	// 2 = 40% translucent
	// 3 = 60% translucent 
	// 4 = 80% translucent
	int		translucent;		

	// user's local gravity
	float gravity;

	// user hook
	// This should only be used by spawn function!!!!
	void *userHook;

	// invHandle_t *curWeapon;        // current weapon
	// invHandle_t *curItem;          // ??

	struct userInventory_s *curWeapon;
	struct userInventory_s *curItem;

	// hierarchial model list
	struct	edict_s	*hchild;

	float	max_speed;	// entity's maximum running speed

	float	elasticity;	// how much this entity will bounce
	float	mass;		// 1.0 = player mass, mass * velocity = momentum
						// standard physics stuff, except units are players

	vec3_t	gravity_dir;	// can be used to make individual entities "attracted" to something
							// not implemented in sv_phys yet

	void	*stickyHook;

	vec3_t	rotation_org;	//	origin for special-case rotations (player torso)
							//	should always be an offset from self->origin

	vec3_t	angle_delta;	//	angular offsets for hierarchical models

	vec3_t	ideal_ang;		//	replaces ideal_yaw, idealpitch and adds ideal_roll as ideal_ang [2]
	vec3_t	ang_speed;		//	replaces yaw_speed and adds pitch speed and roll speed

	void	*ptr1;			//	this is actually used as a temporary hook for warping objects
	
	void	*t1;
	void	*t2;

	///////////////////////////////////////////////////////////////////////////
	//	added for Q2
	///////////////////////////////////////////////////////////////////////////

	int		viewheight;
	int		light_level;

	//	for linked moving entities...
	edict_t		*teamchain;
	edict_t		*teammaster;

	void		*child_list;
} userEntity_t;

// typedef struct edict_s userEntity_t;


////////////////////////////////////////////////////////////////////////
//	server state
////////////////////////////////////////////////////////////////////////

typedef struct serverState_s {
    float	frametime;			// time
	float	coop;				// coop mode
	float	deathmatch;			// deathmatch mode
	float	time;				// diff between frametime?
	char	*mapName;			// current mapname
	int		foglevel;			// duh... fog level
	int     cdtrack;
	vec3_t	gravity_dir;		// direction of gravity pull
	char	*basedir;			// base directory that Daikatana is running in
	int		maxclients;			//	maximum number of clients allowed in the game
	float	skill;				//	how hard the game is, 1 - 100, set by cvar... only changes at level start

	// global colors
	// get updated at beginning of level
	int	global_black;
	int	global_blue;
	int	global_green;
	int	global_cyan;
	int	global_red;
	int	global_purple;
	int	global_brown;
	int	global_ltgray;
	int	global_dkgray;
	int	global_ltblue;
	int	global_ltgrn;
	int	global_ltcyan;
	int	global_ltred;
	int	global_ltpurple;
	int	global_yellow;
	int	global_white;

	// for nelno and noel
	userEntity_t *attacker; 
	userEntity_t *inflictor;
	userEntity_t *activator;
	userEntity_t *targeter;			//	FIXME: still necessary?

	float		damage_inflicted;	//	how much damage was done during last call to Sub_Damage
	vec3_t		damage_vector;		//	what direction the attack came from in last call to Sub_Damage
	unsigned long	damage_flags;	//	what type of damage was done in last call to Sub_Damage

	// interface functions
	void  (*Con_Printf)(char *fmt, ...);	// prints only to the server console
	void  (*Con_Dprintf)(char *fmt, ...);	// prints only to the sever console if developer != 0
	void  (*Precache_Model)(char *modName);
	void  (*Precache_Sound)(char *soundName);
	void  (*AddCommand)(char *cmd_name, void *function);
	void  (*LightStyle)(int style, char *val);
	void  (*SetOrigin)(userEntity_t *ent, float x, float y, float z);
	void  (*SetOrigin2)(userEntity_t *ent, vec3_t pos);
	void  (*SetModel)(userEntity_t *ent, char *m);
	void  (*TraceLine)(vec3_t start, vec3_t end, int nomonsters, userEntity_t *passent, userTrace_t *trace);
	int   (*PointContents)(vec3_t point);
	void  (*RemoveEntity)(userEntity_t *ent);

	void  (*SetSize)(userEntity_t *e,
		           float minx, float miny, float minz,
				   float maxx, float maxy, float maxz);

	userEntity_t *(*FirstEntity)(void);
	userEntity_t *(*NextEntity)(userEntity_t *start);
	userEntity_t *(*SpawnEntity)(void);

    void *(*Hunk_Alloc)(int size);

    void (*bprint)(char *fmt, ...);
    void (*sprint)(userEntity_t *ent, char *fmt, ...);
    void (*particle)(vec3_t org, vec3_t dir, int color, int count);
    void (*centerprint)(userEntity_t *ent, float msg_time, char *fmt, ...);
    void (*sound)(userEntity_t *ent, int channel, char *sample, int volume, float attenuation);
	
	//	Q2FIXME:	looks like these no longer need ent passed each time
	//				instead call multicast or unicast first to prefix the message...
	//				can just integrate this into each function
#ifdef	QUAKE1_NETWORK_CODE
	void (*WriteFloat)(userEntity_t *ent, int dest, float c);  /// Nelno added
    void (*WriteByte)(userEntity_t *ent, int dest, int c);
    void (*WriteChar)(userEntity_t *ent, int dest, int c);
    void (*WriteShort)(userEntity_t *ent, int dest, int c);
    void (*WriteLong)(userEntity_t *ent, int dest, int c);
    void (*WriteAngle)(userEntity_t *ent, int dest, float angle);
    void (*WriteCoord)(userEntity_t *ent, int dest, float coord);
    void (*WriteString)(userEntity_t *ent, int dest, char *str);
    void (*WriteEntity)(userEntity_t *destEnt, int dest, userEntity_t *ent);
#endif

    void (*ServerCmd)(char *cmd);
	void (*ClientCmd)(userEntity_t *ent, char *cmd);

	float (*GetCvar)(char *varName);
	void  (*SetCvar)(char *varName, char *value);

	// debug
	void (*printxy)(int x, int y, char *fmt, ...);
    void (*clearxy)(void);

	// inventory create/delete methods
	invHandle_t	*(*InventoryNew)(void);
    void         (*InventoryFree)(void *ptr);

	// inventory search methods
    struct userInventory_s *(*InventoryFindItem)(invHandle_t *ptr, char *name); 
	struct userInventory_s *(*InventoryFirstItem)(invHandle_t *ptr);
    struct userInventory_s *(*InventoryNextItem)(invHandle_t *ptr);

	// inventory add/delete methods
	int		(*InventoryAddItem)(invHandle_t *ptr, struct userInventory_s *item);
    void	(*InventoryDeleteItem)(invHandle_t *ptr, struct userInventory_s *item);

	// inventory items must be precached so client can get resources early on
	void	(*InventoryPrecache)(char *className, char *iconName, char *modelName);

	// model info
	int		(*ModelInfo)(int modelIndex, userModelInfo_t *modelInfo);
	
	//	Q2FIXME:	remove FrameInfo when DLLs are all clear of it
	int		(*FrameInfo)(int modelIndex, int frameIndex, userFrameInfo_t *frameInfo);
	void	(*GetFrameName)(int modelindex, int frameindex, char *name);
	void	(*ForceModelLoad) (int modelindex, char *name);

	void	(*AmbientSound)(vec3_t pos, char *samp, int vol, int attenuation, float fade);
	void	(*MakeStatic)(userEntity_t *ent);

	//	Q2FIXME:	remove this crap
	void	(*DrawSpriteOverlay)(char *fileName, int x, int y);

	// functions to get to the parameter list of a function
	// only call these when a registered function has been called
	char *(*GetArgv)(int arg);
	int   (*GetArgc)(void);

	// error function
	void (*Error)(char *error, ...);

    void  (*SetFunction) (char *funcName, void *func, char *funcDesc);
    void *(*GetFunction) (char *funcName);
    void  (*ListFunction)(char *funcName);

	//	returns the transformed and translated location of a vertex in self's model
    int (*VertInfo)(userEntity_t *self, int surfaceIndex, int vertIndex, vec3_t vert);
	
	//	returns the index of surface surfName
	int	(*SurfIndex) (int modelIndex, char *surfName);
	int	(*TriVerts) (edict_t *ent, int surfIndex, int vertIndex, vec3_t v1, vec3_t v2, vec3_t v3);

	void (*SetClientViewEntity)(userEntity_t *client, userEntity_t *viewEntity);
	void (*SetClientInputEntity)(userEntity_t *client, userEntity_t *inputEntity);

	///////////////////////////////////////////////////////////////////////////
	//	hierarchical model system
	///////////////////////////////////////////////////////////////////////////

	void	(*hr_InitSurface) (userEntity_t *parent, edict_t *child, char *f_surf, int f_vIndex, unsigned long flags);
	void	(*hr_InitSurface_Old) (userEntity_t *parent, edict_t *child, char *f_surf, int f_vIndex, char *r_surf, int r_vIndex, unsigned long int flags);
	void	(*hr_InitRelative) (userEntity_t *parent, userEntity_t *child, unsigned long int flags);
	void	(*hr_InitBmodel) (userEntity_t *parent, userEntity_t *child, unsigned long int flags);
	
	//	removes a child from a parent's list of children
	//	does not free the child entity unless free_child is true
	void	(*hr_RemoveChild) (userEntity_t *parent, userEntity_t *child, int free_child);
	//	removes all children from a parent's list of children
	//	does not free the child entities unless free_children is true
	void	(*hr_RemoveChildren) (userEntity_t *parent, int free_children);	
	
	void	(*hr_SetFlags) (userEntity_t *parent, userEntity_t *child, unsigned long int flags);
	unsigned long	(*hr_GetFlags) (userEntity_t *parent, userEntity_t *child);

	///////////////////////////////////////////////////////////////////////////
	//	New stuff for Quake 2
	//	FIXME:	reorder this stuff at some point when I have time
	//	FIXME:	at some point these should be cleaned out because there are
	//			a lot of duplicate functions, but for the initial merge and
	//			E3 deadline it's just A LOT easier if they stay
	///////////////////////////////////////////////////////////////////////////

	//	collision detection
	trace_t		(*trace_q2) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask);
	qboolean	(*inPVS) (vec3_t p1, vec3_t p2);
	qboolean	(*inPHS) (vec3_t p1, vec3_t p2);
	void		(*SetAreaPortalState) (int portalnum, qboolean open);
	qboolean	(*AreasConnected) (int area1, int area2);

	//	an entity will never be sent to a client or used for collision
	//	if it is not passed to linkentity.  If the size, position, or
	//	solidity changes, it must be relinked.
	void	(*LinkEntity) (edict_t *ent);
	void	(*UnlinkEntity) (edict_t *ent);		// call before removing an interactive edict
	int		(*BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list,	int maxcount, int areatype);
	void	(*Pmove) (pmove_t *pmove);		// player movement code common with client prediction

#ifndef	QUAKE1_NETWORK_CODE
	void	(*MultiCast) (vec3_t origin, multicast_t to);
	void	(*UniCast) (edict_t *ent, qboolean reliable);
	void	(*WriteChar) (int c);
	void	(*WriteByte) (int c);
	void	(*WriteShort) (int c);
	void	(*WriteLong) (int c);
	void	(*WriteFloat) (float f);
	void	(*WriteString) (char *s);
	void	(*WritePosition) (vec3_t pos);	// some fractional bits
	void	(*WriteDir) (vec3_t pos);		// single byte encoded, very coarse
	void	(*WriteAngle) (float f);
#endif

	void	(*DebugGraph) (float value, int color);

	cvar_t	*(*ForceCvar) (char *var_name, char *value);	// cvar_forceset in game_import_t

	void	(*PositionedSound) (vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);

	// config strings hold all the index strings, the lightstyles,
	// and misc data like the sky definition and cdtrack.
	// All of the current configstrings are sent to clients when
	// they connect, and changes are sent to all connected clients.
	void	(*ConfigString) (int num, char *string);

	// new names can only be added during spawning
	// existing names can be looked up at any time
	int		(*ModelIndex) (char *name);
	int		(*SoundIndex) (char *name);
	int		(*ImageIndex) (char *name);

	void	(*bprintf) (int printlevel, char *fmt, ...);
	void	(*dprintf) (char *fmt, ...);
	void	(*cprintf) (edict_t *ent, int printlevel, char *fmt, ...);
	void	(*centerprintf) (edict_t *ent, char *fmt, ...);

	// managed memory allocation
	void	*(*TagMalloc) (int size, int tag);
	void	(*TagFree) (void *block);
	void	(*FreeTags) (int tag);

	int		(*Sys_Milliseconds) (void);

	void	(*SetCameraState) (userEntity_t *ent, int state, int flags);
	
	//	Set's fix_angles in physics, p_client.c.  This forces the clients view angles
	//	only if FL_FIXANGLES is set, or if the camera state is set to true (enabled)
	void	(*SetClientAngles) (userEntity_t *ent, vec3_t angles);

	int		(*PushMove) (userEntity_t *ent, vec3_t move, vec3_t amove);

	//	PAK File IO routines
	int		(*FS_FileLength)	(FILE *F);
	void	(*FS_Close)			(FILE *F);
	int		(*FS_Open)			(char *filename, FILE **file);
	void	(*FS_Read)			(void *buffer, int len, FILE *f);
	int		(*FS_LoadFile)		(char *path, void **buffer);
	void	(*FS_FreeFile)		(void *buffer);
	int		(*FS_Seek)			(FILE *f, long offset, int origin);
	long	(*FS_Tell)			(FILE *f);
	int		(*FS_Getc)			(FILE *f);
	
	///////////////////////////////////////////////////////////////////////////////
	//	pointers to structures in physics.dll, set up in dk_ServerState.c
	///////////////////////////////////////////////////////////////////////////////

	game_locals_t	*game;
	level_locals_t	*level;
	game_import_t	*gi;
	game_export_t	*globals;
	userEntity_t	*g_edicts;
	void			*common_exports;
} serverState_t;


#ifdef	ASSES_R_US
typedef void (*weaponUse_t) (struct userInventory_s *ptr, userEntity_t *user);
typedef void *(*weaponCommand_t) (struct userInventory_s *ptr, char *commandStr, void *data);

typedef struct userInventory_s
{
	char    *name;
	weaponUse_t	use;
	weaponCommand_t	command;
	void   *precache;
	void   *dummy2;
	void   *dummy3;
	void   *dummy4;
} userInventory_t;
#endif

////////////////////////////////////////////////////////////////////////////////
// icons for inventory items
////////////////////////////////////////////////////////////////////////////////


// icons for inventory items
typedef struct userIcon_s
{
	int  width, height;
	char data [];
} userIcon_t;


#endif