Files
FC1/CryGame/XClient.h
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

463 lines
17 KiB
C++

//////////////////////////////////////////////////////////////////////
//
// Game Source Code
//
// File: XClient.h
// Description: XClient class.
//
// History:
// - August 3, 2001: Created by Alberto Demichelis
//
//////////////////////////////////////////////////////////////////////
#ifndef GAME_XCLIENT_H
#define GAME_XCLIENT_H
#if _MSC_VER > 1000
# pragma once
#endif
#include <vector>
#include <string>
#include <map>
#include <IInput.h>
#include "ScriptObjectClient.h"
#include "XClientSnapshot.h"
#include "XEntityProcessingCmd.h"
#include "XNetworkStats.h" // CXNetworkStats
#include "ScriptObjectVector.h" // CXNetworkStats
struct SCameraParams;
struct IScriptSystem;
struct SXGameContext;
struct SSoundInfo
{
int nEntityId; //!<
Vec3 Pos; //!<
float fRadius; //!<
float fThread; //!<
float fDistance2; //!< squared distance from player at the time of occurance
float fTimeout; //!< Time until this soundinfo is removed from list
};
/////////////////////////////////////////////////////////////////////////////////////////////
typedef std::vector<EntityId> EntityIdList;
typedef EntityIdList::iterator EntityIdListItor;
typedef std::vector<IEntity*> EntityList;
typedef EntityList::iterator EntityListItor;
typedef std::vector<SSoundInfo> TSoundList;
typedef TSoundList::iterator TSoundListIt;
/////////////////////////////////////////////////////////////////////////////////////////////
// CXClient class.
class CXClient :
public IClientSink,
public IActionMapSink,
public IEntitySystemSink
{
public:
//! constructor
CXClient();
private: // to make sure the client is only released in one place
//! destructor
virtual ~CXClient();
public:
//!
bool Init(CXGame *pGame,bool bLocal=false);
//!
void Reset();
//!
void DrawNetStats();
// interface IClientSink -------------------------------------------------
virtual void OnXConnect();
virtual void OnXClientDisconnect(const char *szCause);
virtual void OnXContextSetup(CStream &stmContex);
virtual void OnXData(CStream &stm);
virtual void OnXServerTimeout();
virtual void OnXServerRessurect();
virtual unsigned int GetTimeoutCompensation();
virtual void MarkForDestruct();
virtual bool DestructIfMarked();
// interface IEntitySystemSink -------------------------------------------
void OnSpawnContainer( CEntityDesc &ed,IEntity *pEntity );
void OnSpawn(IEntity *ent,CEntityDesc & ed);
void OnRemove(IEntity *ent);
void OnBind(EntityId id,EntityId child,unsigned char param){}
void OnUnbind(EntityId id,EntityId child,unsigned char param){}
IClient* GetNetworkClient() const { return m_pIClient; };
// -----------------------------------------------------------------------
// console variables
bool CreateConsoleVariables();
TSoundList& GetSoundEventList() { return m_lstSounds; }
// Connection management functions
//! \param szAddr
//! \param inbDoLateSwitch
//! \param inbCDAuthorization true=request CDKeyAuthorization - needed for joining WAN Servers, false=Send fake CDKeyAuthorization
void XConnect( const char *szAddr, const bool inbDoLateSwitch=false, const bool inbCDAuthorization=false );
//!
void DemoConnect();
//!
void XDisconnect(const char *szCause);
//!
void Update();
//!
void UpdateClientNetwork();
#ifdef PS2
unsigned int GetCurrentTime()
{
return (unsigned int)(m_pTimer->GetCurrTime()*1000.f);
}
#else
inline unsigned int GetCurrentTime()
{
return (unsigned int)(m_pTimer->GetCurrTime()*1000.f);
}
#endif
void SoundEvent(EntityId idSrc,Vec3 &pos,float fRadius,float fThreat);
// Overload of the IClient interface
void SendReliable(CStream &stm);
void SendUnreliable(CStream &stm);
//! \return size in bits of the whole packet
size_t SendReliableMsg(XCLIENTMSG msg, CStream &stm);
//! \return size in bits of the whole packet
size_t SendUnreliableMsg(XCLIENTMSG msg, CStream &stm, const bool bWithSize=false );
//!
bool IsReady();
//!
void SendTextMessage(TextMessage &tm);
//!
void SendCommand(const char *sCmd);
//!
void SendScriptHashResponse( const unsigned int dwHash );
//!
void SetBitsPerSecond( const unsigned int dwBitsPerSecond );
//!
void SetUpdateRate( const unsigned int dwUpdatesPerSec );
//!
void AddHudMessage(const char *sMessage,float lifetime,bool bHighPriority=false);
//!
void AddHudSubtitle(const char *sMessage, float lifetime);
//!
void ResetSubtitles(void);
//!
void OnMapChanged();
//!
void OnMapChangedReally();
//!
void SetEntityCamera( const SCameraParams &CameraParams );
// player management functions
//!
EntityId GetPlayerId() const;
//!
void SetPlayerID( EntityId wPlayerID );
//!
int GetPing()
{
return m_pIClient->GetPing();
}
bool IsConnected() { return m_bConnected; };
//!
void LazyChannelAcknowledge();
//!
bool GetLazyChannelState();
// Triggers function
void TriggerMoveLeft(float fValue,XActivationEvent ae);
void TriggerMoveRight(float fValue,XActivationEvent ae);
void TriggerMoveForward(float fValue,XActivationEvent ae);
void TriggerMoveBackward(float fValue,XActivationEvent ae);
void TriggerJump(float fValue,XActivationEvent ae);
void TriggerMoveMode(float fValue,XActivationEvent ae);
void TriggerMoveMode2(float fValue,XActivationEvent ae);
void TriggerLeanLeft(float fValue,XActivationEvent ae);
void TriggerLeanRight(float fValue,XActivationEvent ae);
void TriggerHoldBreath(float fValue,XActivationEvent ae);
void TriggerFireMode(float fValue,XActivationEvent ae);
void TriggerFire0(float fValue,XActivationEvent ae);
void TriggerFireCancel(float fValue,XActivationEvent ae);
void TriggerFireGrenade(float fValue,XActivationEvent ae);
void TriggerVehicleBoost(float fValue,XActivationEvent ae);
void TriggerReload(float fValue,XActivationEvent ae);
void TriggerUse(float fValue,XActivationEvent ae);
void TriggerTurnLR(float fValue,XActivationEvent ae);
void TriggerTurnUD(float fValue,XActivationEvent ae);
void TriggerWalk(float fValue,XActivationEvent ae);
void TriggerRunSprint(float fValue,XActivationEvent ae);
void TriggerFlashlight(float fValue,XActivationEvent ae);
void TriggerChangeView(float fValue,XActivationEvent ae);
//weapons.
void TriggerNextWeapon(float fValue,XActivationEvent ae);
void TriggerPrevWeapon(float fValue,XActivationEvent ae);
void TriggerWeapon0(float fValue,XActivationEvent ae);
void TriggerWeapon1(float fValue,XActivationEvent ae);
void TriggerWeapon2(float fValue,XActivationEvent ae);
void TriggerWeapon3(float fValue,XActivationEvent ae);
void TriggerWeapon4(float fValue,XActivationEvent ae);
void TriggerWeapon5(float fValue,XActivationEvent ae);
void TriggerWeapon6(float fValue,XActivationEvent ae);
void TriggerWeapon7(float fValue,XActivationEvent ae);
void TriggerWeapon8(float fValue,XActivationEvent ae);
void TriggerWeapon9(float fValue,XActivationEvent ae);
void TriggerWeapon10(float fValue,XActivationEvent ae);
void TriggerWeapon11(float fValue,XActivationEvent ae);
void TriggerWeapon12(float fValue,XActivationEvent ae);
void TriggerWeapon13(float fValue,XActivationEvent ae);
void TriggerWeapon14(float fValue,XActivationEvent ae);
void TriggerDropWeapon(float fValue,XActivationEvent ae);
void CycleGrenade(float fValue,XActivationEvent ae);
//client side
void TriggerItem0(float fValue,XActivationEvent ae);
void TriggerItem1(float fValue,XActivationEvent ae);
void TriggerItem2(float fValue,XActivationEvent ae);
void TriggerItem3(float fValue,XActivationEvent ae);
void TriggerZoomToggle(float fValue,XActivationEvent ae);
void TriggerZoomIn(float fValue,XActivationEvent ae);
void TriggerZoomOut(float fValue,XActivationEvent ae);
void TriggerConcentration(float fValue,XActivationEvent ae);
void TriggerQuickLoad(float fValue,XActivationEvent ae);
void TriggerQuickSave(float fValue,XActivationEvent ae);
void TriggerMessageMode(float fValue,XActivationEvent ae);
void TriggerMessageMode2(float fValue,XActivationEvent ae);
void TriggerScreenshot(float fValue, XActivationEvent ae);
void TriggerMoveModeToggle(float fValue, XActivationEvent ae);
void TriggerAimToggle(float fValue, XActivationEvent ae);
BEGIN_INPUTACTIONMAP()
REGISTER_INPUTACTIONMAP(ACTION_MOVE_LEFT, TriggerMoveLeft)
REGISTER_INPUTACTIONMAP(ACTION_MOVE_RIGHT, TriggerMoveRight)
REGISTER_INPUTACTIONMAP(ACTION_MOVE_FORWARD, TriggerMoveForward)
REGISTER_INPUTACTIONMAP(ACTION_MOVE_BACKWARD, TriggerMoveBackward)
REGISTER_INPUTACTIONMAP(ACTION_JUMP, TriggerJump)
REGISTER_INPUTACTIONMAP(ACTION_WALK, TriggerWalk)
REGISTER_INPUTACTIONMAP(ACTION_RUNSPRINT, TriggerRunSprint)
REGISTER_INPUTACTIONMAP(ACTION_MOVEMODE, TriggerMoveMode)
REGISTER_INPUTACTIONMAP(ACTION_MOVEMODE2, TriggerMoveMode2)
REGISTER_INPUTACTIONMAP(ACTION_LEANLEFT, TriggerLeanLeft)
REGISTER_INPUTACTIONMAP(ACTION_LEANRIGHT, TriggerLeanRight)
REGISTER_INPUTACTIONMAP(ACTION_HOLDBREATH, TriggerHoldBreath)
REGISTER_INPUTACTIONMAP(ACTION_FIREMODE, TriggerFireMode)
REGISTER_INPUTACTIONMAP(ACTION_FIRE0, TriggerFire0)
REGISTER_INPUTACTIONMAP(ACTION_FIRECANCEL, TriggerFireCancel)
REGISTER_INPUTACTIONMAP(ACTION_FIRE_GRENADE, TriggerFireGrenade)
REGISTER_INPUTACTIONMAP(ACTION_VEHICLE_BOOST, TriggerVehicleBoost)
REGISTER_INPUTACTIONMAP(ACTION_RELOAD, TriggerReload)
REGISTER_INPUTACTIONMAP(ACTION_USE, TriggerUse)
REGISTER_INPUTACTIONMAP(ACTION_TURNLR, TriggerTurnLR)
REGISTER_INPUTACTIONMAP(ACTION_TURNUD, TriggerTurnUD)
// REGISTER_INPUTACTIONMAP(ACTION_SAVEPOS, TriggerSavePos)
// REGISTER_INPUTACTIONMAP(ACTION_LOADPOS, TriggerLoadPos)
REGISTER_INPUTACTIONMAP(ACTION_FLASHLIGHT, TriggerFlashlight)
REGISTER_INPUTACTIONMAP(ACTION_CHANGE_VIEW, TriggerChangeView)
//weapons.
REGISTER_INPUTACTIONMAP(ACTION_NEXT_WEAPON, TriggerNextWeapon)
REGISTER_INPUTACTIONMAP(ACTION_PREV_WEAPON, TriggerPrevWeapon)
REGISTER_INPUTACTIONMAP(ACTION_WEAPON_0, TriggerWeapon0)
REGISTER_INPUTACTIONMAP(ACTION_WEAPON_1, TriggerWeapon1)
REGISTER_INPUTACTIONMAP(ACTION_WEAPON_2, TriggerWeapon2)
REGISTER_INPUTACTIONMAP(ACTION_WEAPON_3, TriggerWeapon3)
REGISTER_INPUTACTIONMAP(ACTION_WEAPON_4, TriggerWeapon4)
REGISTER_INPUTACTIONMAP(ACTION_CYCLE_GRENADE, CycleGrenade)
REGISTER_INPUTACTIONMAP(ACTION_DROPWEAPON, TriggerDropWeapon)
//client side only(for script)
REGISTER_INPUTACTIONMAP(ACTION_ITEM_0, TriggerItem0)
REGISTER_INPUTACTIONMAP(ACTION_ITEM_1, TriggerItem1)
REGISTER_INPUTACTIONMAP(ACTION_ZOOM_TOGGLE, TriggerZoomToggle)
REGISTER_INPUTACTIONMAP(ACTION_ZOOM_IN, TriggerZoomIn)
REGISTER_INPUTACTIONMAP(ACTION_ZOOM_OUT, TriggerZoomOut)
REGISTER_INPUTACTIONMAP(ACTION_CONCENTRATION, TriggerConcentration);
//REGISTER_INPUTACTIONMAP(ACTION_QUICKLOAD,TriggerQuickLoad);
//REGISTER_INPUTACTIONMAP(ACTION_QUICKSAVE,TriggerQuickSave);
REGISTER_INPUTACTIONMAP(ACTION_MESSAGEMODE, TriggerMessageMode)
REGISTER_INPUTACTIONMAP(ACTION_MESSAGEMODE2, TriggerMessageMode2)
REGISTER_INPUTACTIONMAP(ACTION_TAKESCREENSHOT, TriggerScreenshot)
REGISTER_INPUTACTIONMAP(ACTION_MOVEMODE_TOGGLE, TriggerMoveModeToggle)
REGISTER_INPUTACTIONMAP(ACTION_AIM_TOGGLE, TriggerAimToggle)
END_INPUTACTIONMAP()
private: // -------------------------------------------------------------
void UpdateISystem();
void LoadPlayerDesc();
//packet parsers
bool ParseIncomingStream(CStream &stm);
bool OnServerMsgSetPlayer(CStream &stm);
bool OnServerMsgText(CStream &stm);
bool OnServerMsgSetTeam(CStream &stm);
bool OnServerMsgAddTeam(CStream &stm);
bool OnServerMsgRemoveTeam(CStream &stm);
bool OnServerMsgAddEntity(CStream &stm);
bool OnServerMsgRemoveEntity(CStream &stm);
bool OnServerMsgUpdateEntity(CStream &stm);
bool OnServerMsgTimeStamp(CStream &stm);
bool OnServerMsgStuff(CStream &stm);
bool OnServerMsgClientString(CStream &stm);
bool OnServerMsgSetEntityName(CStream &stm);
bool OnServerMsgScoreBoard(CStream &stm);
bool OnServerMsgSetTeamScore(CStream &stm);
bool OnServerMsgSetTeamFlags(CStream &stm);
bool OnServerMsgSetPlayerScore(CStream &stm);
bool OnServerMsgGameState(CStream &stm);
bool OnServerMsgSetEntityState(CStream &stm);
bool OnServerMsgBindEntity(CStream &stm);
// bool OnServerMsgObituary(CStream &stm);
bool OnServerMsgCmd(CStream &stm);
bool OnServerMsgSyncVar(CStream &stm);
bool OnServerMsgEventSchedule(CStream &stm);
bool OnServerMsgRequestScriptHash(CStream &stm);
bool OnServerMsgSyncAIState(CStream &stm);
/*
void OnCommandSay(IEntity *pSender, CStream &stm, _SmartScriptObject &pTable);
void OnCommandGo(IEntity *pSender, CStream &stm, _SmartScriptObject &pTable);
void OnCommandAttack(IEntity *pSender, CStream &stm, _SmartScriptObject &pTable);
void OnCommandDefend(IEntity *pSender, CStream &stm, _SmartScriptObject &pTable);
void OnCommandCover(IEntity *pSender, CStream &stm, _SmartScriptObject &pTable);
void OnCommandBarrageFire(IEntity *pSender, CStream &stm, _SmartScriptObject &pTable);
*/
void LoadingError(const char *szError);
private: // -------------------------------------------------------------
EntityId m_wPlayerID; //!<
int m_iPhysicalWorldTime; //!<
bool m_bIgnoreSnapshot; //!<
bool bDoSwitch; //!<
public: // -------------------------------------------------------------
float m_fFrontSound; //!<
float m_fBackSound; //!<
float m_fLeftSound; //!<
float m_fRightSound; //!<
TSoundList m_lstSounds; //!< occured sounds to be used for the radar
bool m_bDisplayHud; //!<
IClient * m_pIClient; //!<
CStream * m_pSavedConsoleVars; //!< saved console variable state (to restore the VF_REQUIRE_NET_SYNC marked vars), 0 when not used
bool m_bLocalHost; //!< this client is the local host ?
class CXGame * m_pGame; //!< The game
bool m_bLinkListenerToCamera; //!<
struct IXSystem * m_pISystem; //!< The system interface
IScriptSystem * m_pScriptSystem; //!<
IEntitySystem * m_pEntitySystem; //!<
ILog * m_pLog; //!<
bool m_bLazyChannelState; //!< used for sending ordered reliable data over the unreliable connection (slow but never stalls, used for scoreboard)
// Player
CXEntityProcessingCmd m_PlayerProcessingCmd;
CXEntityProcessingCmd m_PrevPlayerProcessingCmd;
// The current game context
SXGameContext m_GameContext;
// Action map
struct IActionMapManager* m_pIActionMapManager;
//used to discard old unreliable packets
float m_fLastRemoteAsyncCurrTime;
float m_fLastScoreBoardTime;
float m_fLastClientStringTime;
SCameraParams * m_CameraParams; //!<
// gamestate stuff
char m_nGameState; //!< one of the above. hardcoded in Lua
short m_nGameLastTime; //!< in seconds
float m_fGameLastTimeReceived; //!<
unsigned int m_nDiscardedPackets; //!<
CXClientSnapshot m_Snapshot; //!< Snapshot
bool m_bSelfDestruct; //!< usually false, to make sure the client is only released in one place
// Client console variables
ICVar* cl_sound_event_timeout;
ICVar* cl_sound_event_radius;
ICVar* cl_runroll;
ICVar* cl_runpitch;
ICVar* cl_runheight;
ICVar* cl_runheightspeed;
ICVar* cl_playerclassid;
/*
ICVar* cl_explShakeDCoef;
ICVar* cl_explShakeAmplH;
ICVar* cl_explShakeAmplV;
ICVar* cl_explShakeFreq;
ICVar* cl_explShakeTime;
*/
float cl_explShakeDCoef;
float cl_explShakeAmplH;
float cl_explShakeAmplV;
float cl_explShakeFreq;
float cl_explShakeTime;
ICVar* cl_sound_detection_max_distance;
ICVar* cl_sound_detection_min_distance;
ICVar* cl_netstats;
ICVar* cl_cmdrate;
bool m_bMapConnecting; //!<
EntityIdList m_lstGarbageEntities; //!<
EntityList m_lstUpdatedEntities; //!<
ITimer * m_pTimer; //!<
bool m_bRecordingDemo; //!< used for demo recording (use network stream)
bool m_bPlaybackDemo; //!< used for demo recording (use network stream)
CScriptObjectClient * m_pScriptObjectClient; //!<
IScriptObject * m_pClientStuff; //!< connection to the associated scriptobject
private: // --------------------------------------------------------------------------------
string m_sClientString; //!< XSERVERMSG_CLIENTSTRING
CXNetworkStats m_NetStats; //!< for network statistics (count and size per packet type)
CStream m_stmVehicle; //!<
bool m_bConnected; //!< is the client fully connected to the game ? (connection established, map loaded, setup complete, ...)
CScriptObjectVector m_sopMsgNormal; //!<
CScriptObjectVector m_sopMsgPos; //!<
//!
static const char *GetMsgName( XSERVERMSG inValue );
//! is called by Update()
void UpdateSound( const float fFrameTime );
//!
void SendInputToServer( const bool bTimeToSend );
//! restore VF_REQUIRE_NET_SYNC marked console vars
void RestoreServerSyncedVars();
};
#endif // GAME_XCLIENT_H