/***
*
*	Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*	
*	This product contains software technology licensed from Id 
*	Software, Inc. ("Id Technology").  Id Technology (c) 1996 Id Software, Inc. 
*	All Rights Reserved.
*
*   Use, distribution, and modification of this source code and/or resulting
*   object code is restricted to non-commercial enhancements to products from
*   Valve LLC.  All other use, distribution, or modification is prohibited
*   without written permission from Valve LLC.
*
****/
#pragma once
#if !defined(EIFACE_H)
#define EIFACE_H

#if HLDEMO_BUILD
#define INTERFACE_VERSION       	001
#else  // !HLDEMO_BUILD, i.e., regular version of HL
#define INTERFACE_VERSION		140
#endif // !HLDEMO_BUILD

#include <stdio.h>
#include "custom.h"
#include "cvardef.h"
//
// Defines entity interface between engine and DLLs.
// This header file included by engine files and DLL files.
//
// Before including this header, DLLs must:
//		include progdefs.h
// This is conveniently done for them in extdll.h
//

typedef enum
{
	at_notice,
	at_console,	// same as at_notice, but forces a ConPrintf, not a message box
	at_aiconsole,	// same as at_console, but only shown if developer level is 2!
	at_warning,
	at_error,
	at_logged		// Server print to console ( only in multiplayer games ).
} ALERT_TYPE;

// 4-22-98  JOHN: added for use in pfnClientPrintf
typedef enum
{
	print_console,
	print_center,
	print_chat
} PRINT_TYPE;

// For integrity checking of content on clients
typedef enum
{
	force_exactfile,			// File on client must exactly match server's file
	force_model_samebounds,		// For model files only, the geometry must fit in the same bbox
	force_model_specifybounds,		// For model files only, the geometry must fit in the specified bbox
	force_model_specifybounds_if_avail	// For Steam model files only, the geometry must fit in the specified bbox (if the file is available)
} FORCE_TYPE;

// Returned by TraceLine
typedef struct
{
	int	fAllSolid;		// if true, plane is not valid
	int	fStartSolid;		// if true, the initial point was in a solid area
	int	fInOpen;
	int	fInWater;
	float	flFraction;		// time completed, 1.0 = didn't hit anything
	vec3_t	vecEndPos;		// final position
	float	flPlaneDist;
	vec3_t	vecPlaneNormal;		// surface normal at impact
	edict_t	*pHit;			// entity the surface is on
	int	iHitgroup;		// 0 == generic, non zero is specific body part
} TraceResult;

// CD audio status
typedef struct 
{
	int	fPlaying;// is sound playing right now?
	int	fWasPlaying;// if not, CD is paused if WasPlaying is true.
	int	fInitialized;
	int	fEnabled;
	int	fPlayLooping;
	float	cdvolume;
	int	fCDRom;
	int	fPlayTrack;
} CDStatus;
		
typedef unsigned int	CRC32_t;

// Engine hands this to DLLs for functionality callbacks
typedef struct enginefuncs_s
{
	int	(*pfnPrecacheModel)( const char *s );
	int	(*pfnPrecacheSound)( const char *s );
	void	(*pfnSetModel)( edict_t *e, const char *m );
	int	(*pfnModelIndex)( const char *m );
	int	(*pfnModelFrames)( int modelIndex );
	void	(*pfnSetSize)( edict_t *e, const float *rgflMin, const float *rgflMax );
	void	(*pfnChangeLevel)( const char *s1, const char *s2 );
	void	(*pfnGetSpawnParms)( edict_t *ent );
	void	(*pfnSaveSpawnParms)( edict_t *ent );
	float	(*pfnVecToYaw)( const float *rgflVector );
	void	(*pfnVecToAngles)( const float *rgflVectorIn, float *rgflVectorOut );
	void	(*pfnMoveToOrigin)( edict_t *ent, const float *pflGoal, float dist, int iMoveType );
	void	(*pfnChangeYaw)( edict_t* ent );
	void	(*pfnChangePitch)( edict_t* ent );
	edict_t*	(*pfnFindEntityByString)( edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue );
	int	(*pfnGetEntityIllum)( edict_t* pEnt );
	edict_t*	(*pfnFindEntityInSphere)( edict_t *pEdictStartSearchAfter, const float *org, float rad );
	edict_t*	(*pfnFindClientInPVS)( edict_t *pEdict );
	edict_t*	(*pfnEntitiesInPVS)( edict_t *pplayer );
	void	(*pfnMakeVectors)( const float *rgflVector );
	void	(*pfnAngleVectors)( const float *rgflVector, float *forward, float *right, float *up );
	edict_t*	(*pfnCreateEntity)( void );
	void	(*pfnRemoveEntity)( edict_t* e );
	edict_t*	(*pfnCreateNamedEntity)( int className );
	void	(*pfnMakeStatic)( edict_t *ent );
	int	(*pfnEntIsOnFloor)( edict_t *e );
	int	(*pfnDropToFloor)( edict_t* e );
	int	(*pfnWalkMove)( edict_t *ent, float yaw, float dist, int iMode );
	void	(*pfnSetOrigin)( edict_t *e, const float *rgflOrigin );
	void	(*pfnEmitSound)( edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch );
	void	(*pfnEmitAmbientSound)( edict_t *entity, const float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch );
	void	(*pfnTraceLine)( const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr );
	void	(*pfnTraceToss)( edict_t* pent, edict_t* pentToIgnore, TraceResult *ptr );
	int	(*pfnTraceMonsterHull)( edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr );
	void	(*pfnTraceHull)( const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr );
	void	(*pfnTraceModel)( const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr );
	const char *(*pfnTraceTexture)( edict_t *pTextureEntity, const float *v1, const float *v2 );
	void	(*pfnTraceSphere)( const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr );
	void	(*pfnGetAimVector)( edict_t *ent, float speed, float *rgflReturn );
	void	(*pfnServerCommand)( const char *str );
	void	(*pfnServerExecute)( void );
	void	(*pfnClientCommand)( edict_t* pEdict, const char *szFmt, ... );
	void	(*pfnParticleEffect)( const float *org, const float *dir, float color, float count );
	void	(*pfnLightStyle)( int style, const char *val );
	int	(*pfnDecalIndex)( const char *name );
	int	(*pfnPointContents)( const float *rgflVector );
	void	(*pfnMessageBegin)( int msg_dest, int msg_type, const float *pOrigin, edict_t *ed );
	void	(*pfnMessageEnd)( void );
	void	(*pfnWriteByte)( int iValue );
	void	(*pfnWriteChar)( int iValue );
	void	(*pfnWriteShort)( int iValue );
	void	(*pfnWriteLong)( int iValue );
	void	(*pfnWriteAngle)( float flValue );
	void	(*pfnWriteCoord)( float flValue );
	void	(*pfnWriteString)( const char *sz );
	void	(*pfnWriteEntity)( int iValue );
	void	(*pfnCVarRegister)( cvar_t *pCvar );
	float	(*pfnCVarGetFloat)( const char *szVarName );
	const char* (*pfnCVarGetString)( const char *szVarName );
	void	(*pfnCVarSetFloat)( const char *szVarName, float flValue );
	void	(*pfnCVarSetString)( const char *szVarName, const char *szValue );
	void	(*pfnAlertMessage)( ALERT_TYPE atype, const char *szFmt, ... );
	void	(*pfnEngineFprintf)( FILE *pfile, const char *szFmt, ... );
	void*	(*pfnPvAllocEntPrivateData)( edict_t *pEdict, int cb );
	void*	(*pfnPvEntPrivateData)( edict_t *pEdict );
	void	(*pfnFreeEntPrivateData)( edict_t *pEdict );
	const char *(*pfnSzFromIndex)( int iString );
	int	(*pfnAllocString)( const char *szValue );
	struct entvars_s *(*pfnGetVarsOfEnt)( edict_t *pEdict );
	edict_t*	(*pfnPEntityOfEntOffset)( int iEntOffset );
	int	(*pfnEntOffsetOfPEntity)( const edict_t *pEdict );
	int	(*pfnIndexOfEdict)( const edict_t *pEdict );
	edict_t*	(*pfnPEntityOfEntIndex)( int iEntIndex );
	edict_t*	(*pfnFindEntityByVars)( struct entvars_s* pvars );
	void*	(*pfnGetModelPtr)( edict_t* pEdict );
	int	(*pfnRegUserMsg)( const char *pszName, int iSize );
	void	(*pfnAnimationAutomove)( const edict_t* pEdict, float flTime );
	void	(*pfnGetBonePosition)( const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles );
	void* (*pfnFunctionFromName)( const char *pName );
	const char *(*pfnNameForFunction)( void *function );
	void	(*pfnClientPrintf)( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients
	void	(*pfnServerPrint)( const char *szMsg );
	const char *(*pfnCmd_Args)( void );		// these 3 added 
	const char *(*pfnCmd_Argv)( int argc );		// so game DLL can easily 
	int	(*pfnCmd_Argc)( void );		// access client 'cmd' strings
	void	(*pfnGetAttachment)( const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles );
	void	(*pfnCRC32_Init)( CRC32_t *pulCRC );
	void	(*pfnCRC32_ProcessBuffer)( CRC32_t *pulCRC, void *p, int len );
	void	(*pfnCRC32_ProcessByte)( CRC32_t *pulCRC, unsigned char ch );
	CRC32_t	(*pfnCRC32_Final)( CRC32_t pulCRC );
	int	(*pfnRandomLong)( int lLow, int lHigh );
	float	(*pfnRandomFloat)( float flLow, float flHigh );
	void	(*pfnSetView)( const edict_t *pClient, const edict_t *pViewent );
	float	(*pfnTime)( void );
	void	(*pfnCrosshairAngle)( const edict_t *pClient, float pitch, float yaw );
	byte*	(*pfnLoadFileForMe)( const char *filename, int *pLength );
	void	(*pfnFreeFile)( void *buffer );
	void	(*pfnEndSection)( const char *pszSectionName ); // trigger_endsection
	int	(*pfnCompareFileTime)( char *filename1, char *filename2, int *iCompare );
	void	(*pfnGetGameDir)( char *szGetGameDir );
	void	(*pfnCvar_RegisterVariable)( cvar_t *variable );
	void	(*pfnFadeClientVolume)( const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds );
	void	(*pfnSetClientMaxspeed)( const edict_t *pEdict, float fNewMaxspeed );
	edict_t	*(*pfnCreateFakeClient)( const char *netname ); // returns NULL if fake client can't be created
	void	(*pfnRunPlayerMove)( edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec );
	int	(*pfnNumberOfEntities)( void );
	char*	(*pfnGetInfoKeyBuffer)( edict_t *e );			// passing in NULL gets the serverinfo
	char*	(*pfnInfoKeyValue)( char *infobuffer, const char *key );
	void	(*pfnSetKeyValue)( char *infobuffer, const char *key, const char *value );
	void	(*pfnSetClientKeyValue)( int clientIndex, char *infobuffer, const char *key, const char *value );
	int	(*pfnIsMapValid)( const char *filename );
	void	(*pfnStaticDecal)( const float *origin, int decalIndex, int entityIndex, int modelIndex );
	int	(*pfnPrecacheGeneric)( const char *s );
	int	(*pfnGetPlayerUserId)( edict_t *e ); // returns the server assigned userid for this player.  useful for logging frags, etc.  returns -1 if the edict couldn't be found in the list of clients
	void	(*pfnBuildSoundMsg)( edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed );
	int	(*pfnIsDedicatedServer)( void );			// is this a dedicated server?
	cvar_t	*(*pfnCVarGetPointer)( const char *szVarName );
	unsigned int (*pfnGetPlayerWONId)( edict_t *e ); // returns the server assigned WONid for this player.  useful for logging frags, etc.  returns -1 if the edict couldn't be found in the list of clients

	// YWB 8/1/99 TFF Physics additions
	void	(*pfnInfo_RemoveKey)( char *s, const char *key );
	const char *(*pfnGetPhysicsKeyValue)( const edict_t *pClient, const char *key );
	void	(*pfnSetPhysicsKeyValue)( const edict_t *pClient, const char *key, const char *value );
	const char *(*pfnGetPhysicsInfoString)( const edict_t *pClient );
	unsigned short (*pfnPrecacheEvent)( int type, const char*psz );
	void	(*pfnPlaybackEvent)( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, const float *origin, const float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );

	unsigned char *(*pfnSetFatPVS)( const float *org );
	unsigned char *(*pfnSetFatPAS)( const float *org );

	int	(*pfnCheckVisibility )( const edict_t *entity, unsigned char *pset );

	void	(*pfnDeltaSetField)	( struct delta_s *pFields, const char *fieldname );
	void	(*pfnDeltaUnsetField)( struct delta_s *pFields, const char *fieldname );
	void	(*pfnDeltaAddEncoder)( const char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) );
	int	(*pfnGetCurrentPlayer)( void );
	int	(*pfnCanSkipPlayer)( const edict_t *player );
	int	(*pfnDeltaFindField)( struct delta_s *pFields, const char *fieldname );
	void	(*pfnDeltaSetFieldByIndex)( struct delta_s *pFields, int fieldNumber );
	void	(*pfnDeltaUnsetFieldByIndex)( struct delta_s *pFields, int fieldNumber );
	void	(*pfnSetGroupMask)( int mask, int op );
	int	(*pfnCreateInstancedBaseline)( int classname, struct entity_state_s *baseline );
	void	(*pfnCvar_DirectSet)( struct cvar_s *var, const char *value );

	// Forces the client and server to be running with the same version of the specified file
	//  ( e.g., a player model ).
	// Calling this has no effect in single player
	void	(*pfnForceUnmodified)( FORCE_TYPE type, const float *mins, const float *maxs, const char *filename );

	void	(*pfnGetPlayerStats)( const edict_t *pClient, int *ping, int *packet_loss );

	void	(*pfnAddServerCommand)( const char *cmd_name, void (*function) (void) );

	// For voice communications, set which clients hear eachother.
	// NOTE: these functions take player entity indices (starting at 1).
	qboolean	(*pfnVoice_GetClientListening)(int iReceiver, int iSender);
	qboolean	(*pfnVoice_SetClientListening)(int iReceiver, int iSender, qboolean bListen);

	const char *(*pfnGetPlayerAuthId)		( edict_t *e );

	void	*(*pfnSequenceGet)( const char *fileName, const char *entryName );
	void	*(*pfnSequencePickSentence)( const char *groupName, int pickMethod, int *picked );
	int	(*pfnGetFileSize)( const char *filename );
	unsigned int (*pfnGetApproxWavePlayLen)( const char *filepath );
	int	(*pfnIsCareerMatch)( void );
	int	(*pfnGetLocalizedStringLength)( const char *label );
	void	(*pfnRegisterTutorMessageShown)( int mid );
	int	(*pfnGetTimesTutorMessageShown)( int mid );
	void	(*pfnProcessTutorMessageDecayBuffer)( int *buffer, int bufferLength );
	void	(*pfnConstructTutorMessageDecayBuffer)( int *buffer, int bufferLength );
	void	(*pfnResetTutorMessageDecayData)( void );
	void	(*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName );
	void	(*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID );
	int	(*CheckParm)( char *parm, char **ppnext );
} enginefuncs_t;
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT.  INTERFACE VERSION IS FROZEN AT 138
	
// Passed to pfnKeyValue
typedef struct KeyValueData_s
{
	const char	*szClassName;	// in: entity classname
	const char	*szKeyName;	// in: name of key
	const char	*szValue;		// in: value of key
	int	fHandled;		// out: DLL sets to true if key-value pair was understood
} KeyValueData;


typedef struct
{
	char	mapName[32];
	char	landmarkName[32];
	edict_t	*pentLandmark;
	vec3_t	vecLandmarkOrigin;
} LEVELLIST;

typedef struct 
{
	int	id;		// Ordinal ID of this entity (used for entity <--> pointer conversions)
	edict_t	*pent;		// Pointer to the in-game entity

	int	location;		// Offset from the base data of this entity
	int	size;		// Byte size of this entity's data
	int	flags;		// This could be a short -- bit mask of transitions that this entity is in the PVS of
	string_t	classname;	// entity class name

} ENTITYTABLE;

#define MAX_LEVEL_CONNECTIONS		16		// These are encoded in the lower 16bits of ENTITYTABLE->flags

#define FENTTABLE_PLAYER		0x80000000
#define FENTTABLE_REMOVED		0x40000000
#define FENTTABLE_MOVEABLE		0x20000000
#define FENTTABLE_GLOBAL		0x10000000

typedef struct saverestore_s
{
	char		*pBaseData;		// Start of all entity save data
	char		*pCurrentData;		// Current buffer pointer for sequential access
	int		size;			// Current data size
	int		bufferSize;		// Total space for data
	int		tokenSize;		// Size of the linear list of tokens
	int		tokenCount;		// Number of elements in the pTokens table
	char		**pTokens;		// Hash table of entity strings (sparse)
	int		currentIndex;		// Holds a global entity table ID
	int		tableCount;		// Number of elements in the entity table
	int		connectionCount;		// Number of elements in the levelList[]
	ENTITYTABLE	*pTable;			// Array of ENTITYTABLE elements (1 for each entity)
	LEVELLIST		levelList[MAX_LEVEL_CONNECTIONS];	// List of connections from this level

	// smooth transition
	int		fUseLandmark;
	char		szLandmarkName[20];		// landmark we'll spawn near in next level
	vec3_t		vecLandmarkOffset;		// for landmark transitions
	float		time;
	char		szCurrentMapName[32];	// To check global entities
} SAVERESTOREDATA;

typedef enum _fieldtypes
{
	FIELD_FLOAT = 0,		// Any floating point value
	FIELD_STRING,		// A string ID (return from ALLOC_STRING)
	FIELD_ENTITY,		// An entity offset (EOFFSET)
	FIELD_CLASSPTR,		// CBaseEntity *
	FIELD_EHANDLE,		// Entity handle
	FIELD_EVARS,		// EVARS *
	FIELD_EDICT,		// edict_t *, or edict_t *  (same thing)
	FIELD_VECTOR,		// Any vector
	FIELD_POSITION_VECTOR,	// A world coordinate (these are fixed up across level transitions automagically)
	FIELD_POINTER,		// Arbitrary data pointer... to be removed, use an array of FIELD_CHARACTER
	FIELD_INTEGER,		// Any integer or enum
	FIELD_FUNCTION,		// A class function pointer (Think, Use, etc)
	FIELD_BOOLEAN,		// boolean, implemented as an int, I may use this as a hint for compression
	FIELD_SHORT,		// 2 byte integer
	FIELD_CHARACTER,		// a byte
	FIELD_TIME,		// a floating point time (these are fixed up automatically too!)
	FIELD_MODELNAME,		// Engine string that is a model name (needs precache)
	FIELD_SOUNDNAME,		// Engine string that is a sound name (needs precache)

	FIELD_TYPECOUNT		// MUST BE LAST
} FIELDTYPE;

#if !defined(offsetof) && !__GNUC__
#define offsetof(s,m)	(size_t)&(((s *)0)->m)
#endif

#define _FIELD(type,name,fieldtype,count,flags)		{ fieldtype, #name, offsetof(type, name), count, flags }
#define DEFINE_FIELD(type,name,fieldtype)		_FIELD(type, name, fieldtype, 1, 0)
#define DEFINE_ARRAY(type,name,fieldtype,count)		_FIELD(type, name, fieldtype, count, 0)
#define DEFINE_ENTITY_FIELD(name,fieldtype)		_FIELD(entvars_t, name, fieldtype, 1, 0 )
#define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype)	_FIELD(entvars_t, name, fieldtype, 1, FTYPEDESC_GLOBAL )
#define DEFINE_GLOBAL_FIELD(type,name,fieldtype)		_FIELD(type, name, fieldtype, 1, FTYPEDESC_GLOBAL )

#define FTYPEDESC_GLOBAL		0x0001		// This field is masked for global entity save/restore
#define FTYPEDESC_SAVE		0x0002		// This field is saved to disk
#define FTYPEDESC_KEY		0x0004		// This field can be requested and written to by string name at load time
#define FTYPEDESC_FUNCTIONTABLE	0x0008		// This is a table entry for a member function pointer

typedef struct 
{
	FIELDTYPE		fieldType;
	const char		*fieldName;
	int		fieldOffset;
	short		fieldSize;
	short		flags;
} TYPEDESCRIPTION;

#if !defined(ARRAYSIZE)
#define ARRAYSIZE(p)	(sizeof(p)/sizeof(p[0]))
#endif

typedef struct 
{
	// Initialize/shutdown the game (one-time call after loading of game .dll )
	void	(*pfnGameInit)( void );				
	int	(*pfnSpawn)( edict_t *pent );
	void	(*pfnThink)( edict_t *pent );
	void	(*pfnUse)( edict_t *pentUsed, edict_t *pentOther );
	void	(*pfnTouch)( edict_t *pentTouched, edict_t *pentOther );
	void	(*pfnBlocked)( edict_t *pentBlocked, edict_t *pentOther );
	void	(*pfnKeyValue)( edict_t *pentKeyvalue, KeyValueData *pkvd );
	void	(*pfnSave)( edict_t *pent, SAVERESTOREDATA *pSaveData );
	int 	(*pfnRestore)( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity );
	void	(*pfnSetAbsBox)( edict_t *pent );

	void	(*pfnSaveWriteFields)( SAVERESTOREDATA*, const char*, void*, TYPEDESCRIPTION*, int );
	void	(*pfnSaveReadFields)( SAVERESTOREDATA*, const char*, void*, TYPEDESCRIPTION*, int );
	void	(*pfnSaveGlobalState)( SAVERESTOREDATA * );
	void	(*pfnRestoreGlobalState)( SAVERESTOREDATA * );
	void	(*pfnResetGlobalState)( void );

	qboolean	(*pfnClientConnect)( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] );
	
	void	(*pfnClientDisconnect)( edict_t *pEntity );
	void	(*pfnClientKill)( edict_t *pEntity );
	void	(*pfnClientPutInServer)( edict_t *pEntity );
	void	(*pfnClientCommand)( edict_t *pEntity );
	void	(*pfnClientUserInfoChanged)( edict_t *pEntity, char *infobuffer );
	void	(*pfnServerActivate)( edict_t *pEdictList, int edictCount, int clientMax );
	void	(*pfnServerDeactivate)( void );
	void	(*pfnPlayerPreThink)( edict_t *pEntity );
	void	(*pfnPlayerPostThink)( edict_t *pEntity );

	void	(*pfnStartFrame)( void );
	void	(*pfnParmsNewLevel)( void );
	void	(*pfnParmsChangeLevel)( void );

	 // Returns string describing current .dll.  E.g., TeamFotrress 2, Half-Life
	const char     *(*pfnGetGameDescription)( void );     

	// Notify dll about a player customization.
	void	(*pfnPlayerCustomization)( edict_t *pEntity, customization_t *pCustom );

	// Spectator funcs
	void	(*pfnSpectatorConnect)( edict_t *pEntity );
	void	(*pfnSpectatorDisconnect)( edict_t *pEntity );
	void	(*pfnSpectatorThink)( edict_t *pEntity );

	// Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint.
	void	(*pfnSys_Error)( const char *error_string );

	void	(*pfnPM_Move)( struct playermove_s *ppmove, qboolean server );
	void	(*pfnPM_Init)( struct playermove_s *ppmove );
	char	(*pfnPM_FindTextureType)( const char *name );
	void	(*pfnSetupVisibility)( struct edict_s *pViewEntity, struct edict_s *pClient, unsigned char **pvs, unsigned char **pas );
	void	(*pfnUpdateClientData) ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd );
	int	(*pfnAddToFullPack)( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet );
	void	(*pfnCreateBaseline)( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs );
	void	(*pfnRegisterEncoders)( void );
	int	(*pfnGetWeaponData)( struct edict_s *player, struct weapon_data_s *info );

	void	(*pfnCmdStart)( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed );
	void	(*pfnCmdEnd)( const edict_t *player );

	// Return 1 if the packet is valid.  Set response_buffer_size if you want to send a response packet.  Incoming, it holds the max
	//  size of the response_buffer, so you must zero it out if you choose not to respond.
	int	(*pfnConnectionlessPacket )( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );

	// Enumerates player hulls.  Returns 0 if the hull number doesn't exist, 1 otherwise
	int	(*pfnGetHullBounds)	( int hullnumber, float *mins, float *maxs );

	// Create baselines for certain "unplaced" items.
	void	(*pfnCreateInstancedBaselines) ( void );

	// One of the pfnForceUnmodified files failed the consistency check for the specified player
	// Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters )
	int	(*pfnInconsistentFile)( const struct edict_s *player, const char *filename, char *disconnect_message );

	// The game .dll should return 1 if lag compensation should be allowed ( could also just set
	//  the sv_unlag cvar.
	// Most games right now should return 0, until client-side weapon prediction code is written
	//  and tested for them.
	int	(*pfnAllowLagCompensation)( void );
} DLL_FUNCTIONS;

extern DLL_FUNCTIONS		gEntityInterface;

// Current version.
#define NEW_DLL_FUNCTIONS_VERSION	1

typedef struct
{
	// Called right before the object's memory is freed. 
	// Calls its destructor.
	void	(*pfnOnFreeEntPrivateData)( edict_t *pEnt );
	void	(*pfnGameShutdown)(void);
	int	(*pfnShouldCollide)( edict_t *pentTouched, edict_t *pentOther );
	void	(*pfnCvarValue)( const edict_t *pEnt, const char *value ); 
	void	(*pfnCvarValue2)( const edict_t *pEnt, int requestID, const char *cvarName, const char *value );
} NEW_DLL_FUNCTIONS;
typedef int	(*NEW_DLL_FUNCTIONS_FN)( NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );

// Pointers will be null if the game DLL doesn't support this API.
extern NEW_DLL_FUNCTIONS		gNewDLLFunctions;

typedef int	(*APIFUNCTION)( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion );
typedef int	(*APIFUNCTION2)( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );

#endif//EIFACE_H
