ddnet/src/game/client/gameclient.h

461 lines
12 KiB
C
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2010-05-29 07:25:38 +00:00
#ifndef GAME_CLIENT_GAMECLIENT_H
#define GAME_CLIENT_GAMECLIENT_H
#include <base/vmath.h>
#include <engine/client.h>
#include <engine/console.h>
#include <game/layers.h>
#include <game/localization.h>
2010-05-29 07:25:38 +00:00
#include <game/gamecore.h>
#include "render.h"
#include <game/teamscore.h>
2014-07-07 13:43:34 +00:00
#define MIN3(x,y,z) ((y) <= (z) ? \
((x) <= (y) ? (x) : (y)) \
: \
((x) <= (z) ? (x) : (z)))
#define MAX3(x,y,z) ((y) >= (z) ? \
((x) >= (y) ? (x) : (y)) \
: \
((x) >= (z) ? (x) : (z)))
class CGameClient;
class CWeaponData
{
public:
int m_Tick;
vec2 m_Pos;
vec2 m_Direction;
vec2 StartPos() { return m_Pos + m_Direction * 28.0f * 0.75f; }
};
class CLocalProjectile
{
public:
2015-07-09 00:08:14 +00:00
int m_Active;
CGameClient *m_pGameClient;
2015-07-09 00:08:14 +00:00
CWorldCore *m_pWorld;
CCollision *m_pCollision;
vec2 m_Direction;
vec2 m_Pos;
int m_StartTick;
int m_Type;
int m_Owner;
int m_Weapon;
bool m_Explosive;
int m_Bouncing;
bool m_Freeze;
2015-07-09 00:08:14 +00:00
bool m_ExtraInfo;
2015-07-09 00:08:14 +00:00
vec2 GetPos(float Time);
void CreateExplosion(vec2 Pos, int LocalClientID);
void Tick(int CurrentTick, int GameTickSpeed, int LocalClientID);
void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, const CNetObj_Projectile *pProj);
void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, vec2 Vel, vec2 Pos, int StartTick, int Type, int Owner, int Weapon, bool Explosive, int Bouncing, bool Freeze, bool ExtraInfo);
bool GameLayerClipped(vec2 CheckPos);
2015-07-09 00:08:14 +00:00
void Deactivate() { m_Active = 0; }
};
2010-05-29 07:25:38 +00:00
class CGameClient : public IGameClient
{
class CStack
{
public:
enum
{
MAX_COMPONENTS = 64,
};
2010-05-29 07:25:38 +00:00
CStack();
void Add(class CComponent *pComponent);
2010-05-29 07:25:38 +00:00
class CComponent *m_paComponents[MAX_COMPONENTS];
int m_Num;
};
2010-05-29 07:25:38 +00:00
CStack m_All;
CStack m_Input;
CNetObjHandler m_NetObjHandler;
2011-02-27 16:56:03 +00:00
class IEngine *m_pEngine;
2010-05-29 07:25:38 +00:00
class IInput *m_pInput;
class IGraphics *m_pGraphics;
class ITextRender *m_pTextRender;
class IClient *m_pClient;
class ISound *m_pSound;
class IConsole *m_pConsole;
class IStorage *m_pStorage;
class IDemoPlayer *m_pDemoPlayer;
class IServerBrowser *m_pServerBrowser;
class IEditor *m_pEditor;
2011-03-23 12:06:35 +00:00
class IFriends *m_pFriends;
2015-07-22 20:16:49 +00:00
class IFriends *m_pFoes;
class IUpdater *m_pUpdater;
2010-05-29 07:25:38 +00:00
CLayers m_Layers;
class CCollision m_Collision;
CUI m_UI;
2010-05-29 07:25:38 +00:00
void ProcessEvents();
void UpdatePositions();
2010-05-29 07:25:38 +00:00
int m_PredictedTick;
2014-05-23 21:59:26 +00:00
int m_LastNewPredictedTick[2];
2010-05-29 07:25:38 +00:00
int m_LastRoundStartTick;
int m_LastFlagCarrierRed;
int m_LastFlagCarrierBlue;
int m_CheckInfo[2];
2011-01-06 03:46:10 +00:00
static void ConTeam(IConsole::IResult *pResult, void *pUserData);
static void ConKill(IConsole::IResult *pResult, void *pUserData);
2019-04-10 06:58:08 +00:00
static void ConColorFromRgb(IConsole::IResult *pResult, void *pUserData);
2019-04-10 20:43:57 +00:00
static void ConColorToRgb(IConsole::IResult *pResult, void *pUserData);
2010-05-29 07:25:38 +00:00
static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
2014-04-28 13:19:57 +00:00
static void ConchainSpecialDummyInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainSpecialDummy(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
2010-05-29 07:25:38 +00:00
public:
IKernel *Kernel() { return IInterface::Kernel(); }
2011-02-27 16:56:03 +00:00
IEngine *Engine() const { return m_pEngine; }
2010-05-29 07:25:38 +00:00
class IGraphics *Graphics() const { return m_pGraphics; }
class IClient *Client() const { return m_pClient; }
class CUI *UI() { return &m_UI; }
class ISound *Sound() const { return m_pSound; }
class IInput *Input() const { return m_pInput; }
class IStorage *Storage() const { return m_pStorage; }
class IConsole *Console() { return m_pConsole; }
class ITextRender *TextRender() const { return m_pTextRender; }
class IDemoPlayer *DemoPlayer() const { return m_pDemoPlayer; }
class IDemoRecorder *DemoRecorder(int Recorder) const { return Client()->DemoRecorder(Recorder); }
2010-05-29 07:25:38 +00:00
class IServerBrowser *ServerBrowser() const { return m_pServerBrowser; }
class CRenderTools *RenderTools() { return &m_RenderTools; }
class CLayers *Layers() { return &m_Layers; };
class CCollision *Collision() { return &m_Collision; };
class IEditor *Editor() { return m_pEditor; }
2011-03-23 12:06:35 +00:00
class IFriends *Friends() { return m_pFriends; }
2015-07-22 20:16:49 +00:00
class IFriends *Foes() { return m_pFoes; }
class IUpdater *Updater() { return m_pUpdater; }
int NetobjNumCorrections() { return m_NetObjHandler.NumObjCorrections(); }
const char *NetobjCorrectedOn() { return m_NetObjHandler.CorrectedObjOn(); }
2010-05-29 07:25:38 +00:00
bool m_SuppressEvents;
bool m_NewTick;
bool m_NewPredictedTick;
int m_FlagDropTick[2];
2010-05-29 07:25:38 +00:00
// TODO: move this
CTuningParams m_Tuning[2];
2010-05-29 07:25:38 +00:00
enum
{
SERVERMODE_PURE=0,
SERVERMODE_MOD,
SERVERMODE_PUREMOD,
};
int m_ServerMode;
2019-01-11 14:08:40 +00:00
int m_AllowTimeScore[2];
2018-11-24 13:56:03 +00:00
int m_DemoSpecID;
2010-05-29 07:25:38 +00:00
vec2 m_LocalCharacterPos;
// predicted players
CCharacterCore m_PredictedPrevChar;
CCharacterCore m_PredictedChar;
// snap pointers
struct CSnapState
{
const CNetObj_Character *m_pLocalCharacter;
const CNetObj_Character *m_pLocalPrevCharacter;
const CNetObj_PlayerInfo *m_pLocalInfo;
const CNetObj_SpectatorInfo *m_pSpectatorInfo;
const CNetObj_SpectatorInfo *m_pPrevSpectatorInfo;
2010-05-29 07:25:38 +00:00
const CNetObj_Flag *m_paFlags[2];
2011-03-04 16:08:10 +00:00
const CNetObj_GameInfo *m_pGameInfoObj;
const CNetObj_GameData *m_pGameDataObj;
int m_GameDataSnapID;
2010-05-29 07:25:38 +00:00
const CNetObj_PlayerInfo *m_paPlayerInfos[MAX_CLIENTS];
const CNetObj_PlayerInfo *m_paInfoByScore[MAX_CLIENTS];
2014-02-08 21:24:57 +00:00
const CNetObj_PlayerInfo *m_paInfoByName[MAX_CLIENTS];
2014-09-23 07:52:18 +00:00
//const CNetObj_PlayerInfo *m_paInfoByTeam[MAX_CLIENTS];
2014-01-22 00:39:18 +00:00
const CNetObj_PlayerInfo *m_paInfoByDDTeam[MAX_CLIENTS];
int m_LocalClientID;
2010-05-29 07:25:38 +00:00
int m_NumPlayers;
int m_aTeamSize[2];
// spectate data
struct CSpectateInfo
{
bool m_Active;
int m_SpectatorID;
bool m_UsePosition;
vec2 m_Position;
} m_SpecInfo;
2010-05-29 07:25:38 +00:00
//
struct CCharacterInfo
{
bool m_Active;
2010-05-29 07:25:38 +00:00
// snapshots
CNetObj_Character m_Prev;
CNetObj_Character m_Cur;
2010-05-29 07:25:38 +00:00
// interpolated position
vec2 m_Position;
};
2010-05-29 07:25:38 +00:00
CCharacterInfo m_aCharacters[MAX_CLIENTS];
};
CSnapState m_Snap;
2010-05-29 07:25:38 +00:00
// client data
struct CClientData
{
int m_UseCustomColor;
int m_ColorBody;
int m_ColorFeet;
char m_aName[MAX_NAME_LENGTH];
char m_aClan[MAX_CLAN_LENGTH];
int m_Country;
2010-05-29 07:25:38 +00:00
char m_aSkinName[64];
int m_SkinID;
2010-05-29 07:25:38 +00:00
int m_SkinColor;
int m_Team;
int m_Emoticon;
int m_EmoticonStart;
bool m_Solo;
2010-05-29 07:25:38 +00:00
CCharacterCore m_Predicted;
2013-10-09 14:02:23 +00:00
CCharacterCore m_PrevPredicted;
2010-05-29 07:25:38 +00:00
CTeeRenderInfo m_SkinInfo; // this is what the server reports
CTeeRenderInfo m_RenderInfo; // this is what we use
2010-05-29 07:25:38 +00:00
float m_Angle;
bool m_Active;
bool m_ChatIgnore;
2011-03-23 12:06:35 +00:00
bool m_Friend;
2015-07-22 20:16:49 +00:00
bool m_Foe;
int m_AuthLevel;
2010-05-29 07:25:38 +00:00
void UpdateRenderInfo();
void Reset();
// DDRace
int m_Score;
2010-05-29 07:25:38 +00:00
};
2010-05-29 07:25:38 +00:00
CClientData m_aClients[MAX_CLIENTS];
2015-05-19 22:51:02 +00:00
class CClientStats
{
int m_IngameTicks;
int m_JoinTick;
bool m_Active;
public:
CClientStats();
2015-05-19 22:51:02 +00:00
int m_aFragsWith[NUM_WEAPONS];
int m_aDeathsFrom[NUM_WEAPONS];
int m_Frags;
int m_Deaths;
int m_Suicides;
int m_BestSpree;
int m_CurrentSpree;
2015-05-19 22:51:02 +00:00
int m_FlagGrabs;
int m_FlagCaptures;
2015-05-19 22:51:02 +00:00
void Reset();
bool IsActive() const { return m_Active; }
void JoinGame(int Tick) { m_Active = true; m_JoinTick = Tick; };
void JoinSpec(int Tick) { m_Active = false; m_IngameTicks += Tick - m_JoinTick; };
int GetIngameTicks(int Tick) const { return m_IngameTicks + Tick - m_JoinTick; };
float GetFPM(int Tick, int TickSpeed) const { return (float)(m_Frags * TickSpeed * 60) / GetIngameTicks(Tick); };
2015-05-19 22:51:02 +00:00
};
2015-05-21 12:34:20 +00:00
CClientStats m_aStats[MAX_CLIENTS];
2015-05-19 22:51:02 +00:00
2010-05-29 07:25:38 +00:00
CRenderTools m_RenderTools;
2010-05-29 07:25:38 +00:00
void OnReset();
// hooks
virtual void OnConnected();
virtual void OnRender();
virtual void OnUpdate();
2014-04-28 14:47:44 +00:00
virtual void OnDummyDisconnect();
virtual void OnRelease();
2010-05-29 07:25:38 +00:00
virtual void OnInit();
virtual void OnConsoleInit();
virtual void OnStateChange(int NewState, int OldState);
2014-05-03 00:30:05 +00:00
virtual void OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy = 0);
2010-05-29 07:25:38 +00:00
virtual void OnNewSnapshot();
virtual void OnPredict();
virtual void OnActivateEditor();
virtual void OnDummySwap();
virtual int OnSnapInput(int *pData, bool Dummy, bool Force);
2010-05-29 07:25:38 +00:00
virtual void OnShutdown();
virtual void OnEnterGame();
virtual void OnRconType(bool UsernameReq);
2010-05-29 07:25:38 +00:00
virtual void OnRconLine(const char *pLine);
2019-01-11 14:08:40 +00:00
virtual void OnTimeScore(int AllowTimeScore, bool Dummy);
virtual void OnGameOver();
virtual void OnStartGame();
virtual void OnFlagGrab(int TeamID);
void OnWindowResize();
static void OnWindowResizeCB(void *pUser);
2010-05-29 07:25:38 +00:00
virtual const char *GetItemName(int Type);
virtual const char *Version();
virtual const char *NetVersion();
2010-05-29 07:25:38 +00:00
// actions
// TODO: move these
void SendSwitchTeam(int Team);
void SendInfo(bool Start);
2014-04-28 13:19:57 +00:00
virtual void SendDummyInfo(bool Start);
void SendKill(int ClientID);
2010-05-29 07:25:38 +00:00
// pointers to all systems
class CGameConsole *m_pGameConsole;
class CBinds *m_pBinds;
class CParticles *m_pParticles;
class CMenus *m_pMenus;
class CSkins *m_pSkins;
class CCountryFlags *m_pCountryFlags;
2010-05-29 07:25:38 +00:00
class CFlow *m_pFlow;
class CChat *m_pChat;
class CDamageInd *m_pDamageind;
class CCamera *m_pCamera;
class CControls *m_pControls;
class CEffects *m_pEffects;
class CSounds *m_pSounds;
class CMotd *m_pMotd;
class CMapImages *m_pMapimages;
class CVoting *m_pVoting;
class CScoreboard *m_pScoreboard;
2015-05-21 09:41:59 +00:00
class CStatboard *m_pStatboard;
2011-04-03 08:11:23 +00:00
class CItems *m_pItems;
class CMapLayers *m_pMapLayersBackGround;
class CMapLayers *m_pMapLayersForeGround;
2015-08-25 00:11:04 +00:00
class CBackground *m_pBackGround;
2014-10-10 17:10:57 +00:00
class CMapSounds *m_pMapSounds;
class CPlayers *m_pPlayers;
2014-10-10 17:10:57 +00:00
// DDRace
int m_LocalIDs[2];
CNetObj_PlayerInput m_DummyInput;
CNetObj_PlayerInput m_HammerInput;
int m_DummyFire;
class CRaceDemo *m_pRaceDemo;
class CGhost *m_pGhost;
2014-01-21 23:08:30 +00:00
class CTeamsCore m_Teams;
2014-01-30 03:10:52 +00:00
int IntersectCharacter(vec2 Pos0, vec2 Pos1, vec2& NewPos, int ownID);
int IntersectCharacter(vec2 OldPos, vec2 NewPos, float Radius, vec2* NewPos2, int ownID, CWorldCore *World);
CWeaponData m_aWeaponData[150];
CWeaponData *GetWeaponData(int Tick) { return &m_aWeaponData[((Tick%150)+150)%150]; }
CWeaponData *FindWeaponData(int TargetTick);
2013-08-23 23:50:35 +00:00
virtual int GetLastRaceTick();
2015-01-11 16:36:38 +00:00
void FindWeaker(bool IsWeaker[2][MAX_CLIENTS]);
bool AntiPingPlayers() { return g_Config.m_ClAntiPing && g_Config.m_ClAntiPingPlayers && !m_Snap.m_SpecInfo.m_Active && Client()->State() != IClient::STATE_DEMOPLAYBACK && (m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_Tuning[g_Config.m_ClDummy].m_PlayerHooking); }
2016-04-23 23:57:01 +00:00
bool AntiPingGrenade() { return g_Config.m_ClAntiPing && g_Config.m_ClAntiPingGrenade && !m_Snap.m_SpecInfo.m_Active && Client()->State() != IClient::STATE_DEMOPLAYBACK; }
bool AntiPingWeapons() { return g_Config.m_ClAntiPing && g_Config.m_ClAntiPingWeapons && !m_Snap.m_SpecInfo.m_Active && Client()->State() != IClient::STATE_DEMOPLAYBACK; }
private:
2014-04-27 11:44:04 +00:00
bool m_DDRaceMsgSent[2];
int m_ShowOthers[2];
2010-05-29 07:25:38 +00:00
};
2011-01-04 10:58:25 +00:00
inline float HueToRgb(float v1, float v2, float h)
{
if(h < 0.0f) h += 1;
if(h > 1.0f) h -= 1;
if((6.0f * h) < 1.0f) return v1 + (v2 - v1) * 6.0f * h;
if((2.0f * h) < 1.0f) return v2;
if((3.0f * h) < 2.0f) return v1 + (v2 - v1) * ((2.0f/3.0f) - h) * 6.0f;
return v1;
2011-01-04 10:58:25 +00:00
}
inline vec3 HslToRgb(vec3 HSL)
{
if(HSL.s == 0.0f)
return vec3(HSL.l, HSL.l, HSL.l);
else
{
float v2 = HSL.l < 0.5f ? HSL.l * (1.0f + HSL.s) : (HSL.l+HSL.s) - (HSL.s*HSL.l);
float v1 = 2.0f * HSL.l - v2;
return vec3(HueToRgb(v1, v2, HSL.h + (1.0f/3.0f)), HueToRgb(v1, v2, HSL.h), HueToRgb(v1, v2, HSL.h - (1.0f/3.0f)));
}
}
2014-07-07 13:43:34 +00:00
inline vec3 RgbToHsl(vec3 RGB)
{
vec3 HSL;
2017-03-21 10:24:44 +00:00
float MaxColor = MAX3(RGB.r, RGB.g, RGB.b);
float MinColor = MIN3(RGB.r, RGB.g, RGB.b);
if (MinColor == MaxColor)
2014-07-07 13:43:34 +00:00
return vec3(0.0f, 0.0f, RGB.g * 255.0f);
else
{
2017-03-21 10:24:44 +00:00
HSL.l = (MinColor + MaxColor) / 2;
2014-07-07 13:43:34 +00:00
if (HSL.l < 0.5)
2017-03-21 10:24:44 +00:00
HSL.s = (MaxColor - MinColor) / (MaxColor + MinColor);
2015-07-09 00:08:14 +00:00
else
2017-03-21 10:24:44 +00:00
HSL.s = (MaxColor - MinColor) / (2.0 - MaxColor - MinColor);
2014-07-07 13:43:34 +00:00
2017-03-21 10:24:44 +00:00
if (RGB.r == MaxColor)
HSL.h = (RGB.g - RGB.b) / (MaxColor - MinColor);
else if (RGB.g == MaxColor)
HSL.h = 2.0 + (RGB.b - RGB.r) / (MaxColor - MinColor);
2015-07-09 00:08:14 +00:00
else
2017-03-21 10:24:44 +00:00
HSL.h = 4.0 + (RGB.r - RGB.g) / (MaxColor - MinColor);
2014-07-07 13:43:34 +00:00
HSL.h /= 6; //to bring it to a number between 0 and 1
if (HSL.h < 0) HSL.h++;
}
HSL.h = int(HSL.h * 255.0);
HSL.s = int(HSL.s * 255.0);
HSL.l = int(HSL.l * 255.0);
return HSL;
}
2017-03-06 13:04:09 +00:00
vec3 CalculateNameColor(vec3 TextColorHSL);
2011-01-04 10:58:25 +00:00
2010-05-29 07:25:38 +00:00
#endif