2011-02-04 17:25:04 +00:00
|
|
|
/* (c) Rajh, Redix and Sushi. */
|
|
|
|
|
|
|
|
#ifndef GAME_CLIENT_COMPONENTS_GHOST_H
|
|
|
|
#define GAME_CLIENT_COMPONENTS_GHOST_H
|
|
|
|
|
|
|
|
#include <game/client/component.h>
|
2020-09-25 16:11:59 +00:00
|
|
|
#include <game/client/components/menus.h>
|
2022-06-10 21:54:42 +00:00
|
|
|
#include <game/generated/protocol.h>
|
2011-02-04 17:25:04 +00:00
|
|
|
|
2021-07-12 09:29:59 +00:00
|
|
|
#include <game/client/render.h>
|
|
|
|
|
|
|
|
struct CNetObj_Character;
|
|
|
|
|
2017-09-09 15:04:19 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
GHOSTDATA_TYPE_SKIN = 0,
|
|
|
|
GHOSTDATA_TYPE_CHARACTER_NO_TICK,
|
2017-09-12 15:01:32 +00:00
|
|
|
GHOSTDATA_TYPE_CHARACTER,
|
|
|
|
GHOSTDATA_TYPE_START_TICK
|
2017-09-09 15:04:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CGhostSkin
|
|
|
|
{
|
|
|
|
int m_Skin0;
|
|
|
|
int m_Skin1;
|
|
|
|
int m_Skin2;
|
|
|
|
int m_Skin3;
|
|
|
|
int m_Skin4;
|
|
|
|
int m_Skin5;
|
|
|
|
int m_UseCustomColor;
|
|
|
|
int m_ColorBody;
|
|
|
|
int m_ColorFeet;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CGhostCharacter_NoTick
|
|
|
|
{
|
|
|
|
int m_X;
|
|
|
|
int m_Y;
|
|
|
|
int m_VelX;
|
|
|
|
int m_VelY;
|
|
|
|
int m_Angle;
|
|
|
|
int m_Direction;
|
|
|
|
int m_Weapon;
|
|
|
|
int m_HookState;
|
|
|
|
int m_HookX;
|
|
|
|
int m_HookY;
|
|
|
|
int m_AttackTick;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CGhostCharacter : public CGhostCharacter_NoTick
|
|
|
|
{
|
|
|
|
int m_Tick;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CGhost : public CComponent
|
|
|
|
{
|
2011-02-04 17:25:04 +00:00
|
|
|
private:
|
2017-09-09 16:25:32 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
MAX_ACTIVE_GHOSTS = 8,
|
|
|
|
};
|
|
|
|
|
2017-09-16 15:45:09 +00:00
|
|
|
class CGhostPath
|
|
|
|
{
|
|
|
|
int m_ChunkSize;
|
|
|
|
int m_NumItems;
|
|
|
|
|
2022-06-11 19:38:18 +00:00
|
|
|
std::vector<CGhostCharacter *> m_vpChunks;
|
2017-09-16 15:45:09 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
CGhostPath() { Reset(); }
|
|
|
|
~CGhostPath() { Reset(); }
|
2017-09-28 14:42:47 +00:00
|
|
|
CGhostPath(const CGhostPath &Other) = delete;
|
2020-09-26 19:41:58 +00:00
|
|
|
CGhostPath &operator=(const CGhostPath &Other) = delete;
|
2017-09-28 14:42:47 +00:00
|
|
|
|
2020-11-05 10:34:20 +00:00
|
|
|
CGhostPath(CGhostPath &&Other) noexcept;
|
|
|
|
CGhostPath &operator=(CGhostPath &&Other) noexcept;
|
2017-09-16 15:45:09 +00:00
|
|
|
|
|
|
|
void Reset(int ChunkSize = 25 * 60); // one minute with default snap rate
|
|
|
|
void SetSize(int Items);
|
|
|
|
int Size() const { return m_NumItems; }
|
|
|
|
|
|
|
|
void Add(CGhostCharacter Char);
|
|
|
|
CGhostCharacter *Get(int Index);
|
|
|
|
};
|
|
|
|
|
2017-09-09 18:28:38 +00:00
|
|
|
class CGhostItem
|
2011-02-11 06:00:12 +00:00
|
|
|
{
|
2017-09-09 18:28:38 +00:00
|
|
|
public:
|
2017-09-09 15:04:19 +00:00
|
|
|
CTeeRenderInfo m_RenderInfo;
|
2017-09-10 22:22:35 +00:00
|
|
|
CGhostSkin m_Skin;
|
2017-09-16 15:45:09 +00:00
|
|
|
CGhostPath m_Path;
|
2017-09-12 15:01:32 +00:00
|
|
|
int m_StartTick;
|
2017-09-10 22:55:11 +00:00
|
|
|
char m_aPlayer[MAX_NAME_LENGTH];
|
2017-09-09 18:28:38 +00:00
|
|
|
int m_PlaybackPos;
|
|
|
|
|
|
|
|
CGhostItem() { Reset(); }
|
2017-09-09 15:04:19 +00:00
|
|
|
|
2017-09-16 15:45:09 +00:00
|
|
|
bool Empty() const { return m_Path.Size() == 0; }
|
2017-09-09 18:28:38 +00:00
|
|
|
void Reset()
|
|
|
|
{
|
2017-09-16 15:45:09 +00:00
|
|
|
m_Path.Reset();
|
2017-09-17 22:57:21 +00:00
|
|
|
m_StartTick = -1;
|
2017-10-06 20:01:33 +00:00
|
|
|
m_PlaybackPos = -1;
|
2017-09-09 18:28:38 +00:00
|
|
|
}
|
2011-02-11 06:00:12 +00:00
|
|
|
};
|
2015-07-09 00:08:14 +00:00
|
|
|
|
2017-09-28 17:13:20 +00:00
|
|
|
static const char *ms_pGhostDir;
|
|
|
|
|
2017-09-09 15:04:19 +00:00
|
|
|
class IGhostLoader *m_pGhostLoader;
|
|
|
|
class IGhostRecorder *m_pGhostRecorder;
|
|
|
|
|
2017-09-09 16:25:32 +00:00
|
|
|
CGhostItem m_aActiveGhosts[MAX_ACTIVE_GHOSTS];
|
2011-02-11 06:00:12 +00:00
|
|
|
CGhostItem m_CurGhost;
|
2011-02-04 17:25:04 +00:00
|
|
|
|
2017-09-28 17:13:20 +00:00
|
|
|
char m_aTmpFilename[128];
|
|
|
|
|
2017-10-06 20:01:33 +00:00
|
|
|
int m_NewRenderTick;
|
2011-02-04 17:25:04 +00:00
|
|
|
int m_StartRenderTick;
|
2017-09-09 18:28:38 +00:00
|
|
|
int m_LastDeathTick;
|
2017-10-28 12:23:24 +00:00
|
|
|
int m_LastRaceTick;
|
2011-02-04 17:25:04 +00:00
|
|
|
bool m_Recording;
|
|
|
|
bool m_Rendering;
|
|
|
|
|
2017-10-28 12:23:24 +00:00
|
|
|
bool m_RenderingStartedByServer;
|
|
|
|
|
2017-09-10 22:22:35 +00:00
|
|
|
static void GetGhostSkin(CGhostSkin *pSkin, const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet);
|
2022-06-10 21:54:42 +00:00
|
|
|
static void GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Character *pChar, const CNetObj_DDNetCharacter *pDDnetChar);
|
2017-09-09 22:57:32 +00:00
|
|
|
static void GetNetObjCharacter(CNetObj_Character *pChar, const CGhostCharacter *pGhostChar);
|
2015-07-09 00:08:14 +00:00
|
|
|
|
2017-09-28 17:13:20 +00:00
|
|
|
void GetPath(char *pBuf, int Size, const char *pPlayerName, int Time = -1) const;
|
|
|
|
|
2022-06-10 21:54:42 +00:00
|
|
|
void AddInfos(const CNetObj_Character *pChar, const CNetObj_DDNetCharacter *pDDnetChar);
|
2017-09-10 02:57:03 +00:00
|
|
|
int GetSlot() const;
|
2015-07-09 00:08:14 +00:00
|
|
|
|
2017-10-28 12:23:24 +00:00
|
|
|
void CheckStart();
|
|
|
|
void CheckStartLocal(bool Predicted);
|
|
|
|
void TryRenderStart(int Tick, bool ServerControl);
|
|
|
|
|
2017-09-12 15:01:32 +00:00
|
|
|
void StartRecord(int Tick);
|
2017-09-09 16:25:32 +00:00
|
|
|
void StopRecord(int Time = -1);
|
2017-09-12 15:01:32 +00:00
|
|
|
void StartRender(int Tick);
|
2011-02-04 17:25:04 +00:00
|
|
|
void StopRender();
|
2015-07-09 00:08:14 +00:00
|
|
|
|
2017-09-10 22:22:35 +00:00
|
|
|
void InitRenderInfos(CGhostItem *pGhost);
|
2011-02-04 17:25:04 +00:00
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
static void ConGPlay(IConsole::IResult *pResult, void *pUserData);
|
2011-02-04 17:25:04 +00:00
|
|
|
|
|
|
|
public:
|
2017-09-12 20:54:29 +00:00
|
|
|
bool m_AllowRestart;
|
2017-09-09 19:38:41 +00:00
|
|
|
|
2011-02-04 17:25:04 +00:00
|
|
|
CGhost();
|
2022-01-31 02:11:47 +00:00
|
|
|
virtual int Sizeof() const override { return sizeof(*this); }
|
2011-02-04 17:25:04 +00:00
|
|
|
|
2022-01-30 23:43:56 +00:00
|
|
|
virtual void OnRender() override;
|
|
|
|
virtual void OnConsoleInit() override;
|
|
|
|
virtual void OnReset() override;
|
|
|
|
virtual void OnMessage(int MsgType, void *pRawMsg) override;
|
|
|
|
virtual void OnMapLoad() override;
|
|
|
|
virtual void OnShutdown() override;
|
2015-07-09 00:08:14 +00:00
|
|
|
|
2017-10-28 12:23:24 +00:00
|
|
|
void OnNewSnapshot();
|
|
|
|
void OnNewPredictedSnapshot();
|
2017-10-06 20:01:33 +00:00
|
|
|
|
2017-10-28 12:23:24 +00:00
|
|
|
int FreeSlots() const;
|
2017-09-09 16:25:32 +00:00
|
|
|
int Load(const char *pFilename);
|
|
|
|
void Unload(int Slot);
|
2017-09-10 01:48:22 +00:00
|
|
|
void UnloadAll();
|
|
|
|
|
|
|
|
void SaveGhost(CMenus::CGhostItem *pItem);
|
|
|
|
|
2017-09-29 21:15:47 +00:00
|
|
|
const char *GetGhostDir() const { return ms_pGhostDir; }
|
|
|
|
|
2017-09-09 15:04:19 +00:00
|
|
|
class IGhostLoader *GhostLoader() const { return m_pGhostLoader; }
|
|
|
|
class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; }
|
2019-03-25 19:02:50 +00:00
|
|
|
|
|
|
|
int GetLastRaceTick();
|
2020-10-09 07:07:05 +00:00
|
|
|
|
|
|
|
void RefindSkin();
|
2011-02-04 17:25:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|