Skip to content

Commit

Permalink
ghosts support added (not fully tested)
Browse files Browse the repository at this point in the history
  • Loading branch information
JSaurusRex committed Dec 6, 2023
1 parent de52f7e commit daa311c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
39 changes: 36 additions & 3 deletions src/game/client/components/ghost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ void CGhost::AddInfos(const CNetObj_Character *pChar, const CNetObj_DDNetCharact
GhostRecorder()->Start(m_aTmpFilename, Client()->GetCurrentMap(), Client()->GetCurrentMapSha256(), m_CurGhost.m_aPlayer);

GhostRecorder()->WriteData(GHOSTDATA_TYPE_START_TICK, &m_CurGhost.m_StartTick, sizeof(int));
GhostRecorder()->WriteData(GHOSTDATA_TYPE_TICKRATE, &m_CurGhost.m_Tickrate, sizeof(int));
GhostRecorder()->WriteData(GHOSTDATA_TYPE_SKIN, &m_CurGhost.m_Skin, sizeof(CGhostSkin));
for(int i = 0; i < NumTicks; i++)
GhostRecorder()->WriteData(GHOSTDATA_TYPE_CHARACTER, m_CurGhost.m_Path.Get(i), sizeof(CGhostCharacter));
Expand Down Expand Up @@ -321,8 +322,11 @@ void CGhost::OnRender()
{
if(Ghost.Empty())
continue;

float speedDiff = Client()->GameTickSpeed() / (float)Ghost.m_Tickrate;

int GhostTick = Ghost.m_StartTick + PlaybackTick;
int GhostTick = Ghost.m_StartTick + floor(PlaybackTick / speedDiff);
int GhostTickUnscaled = Ghost.m_StartTick*speedDiff + PlaybackTick;
while(Ghost.m_PlaybackPos >= 0 && Ghost.m_Path.Get(Ghost.m_PlaybackPos)->m_Tick < GhostTick)
{
if(Ghost.m_PlaybackPos < Ghost.m_Path.Size() - 1)
Expand All @@ -346,9 +350,9 @@ void CGhost::OnRender()
int TickDiff = Player.m_Tick - Prev.m_Tick;
float IntraTick = 0.f;
if(TickDiff > 0)
IntraTick = (GhostTick - Prev.m_Tick - 1 + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / TickDiff;
IntraTick = (GhostTickUnscaled - Prev.m_Tick*speedDiff - speedDiff + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (TickDiff*speedDiff);

Player.m_AttackTick += Client()->GameTick(g_Config.m_ClDummy) - GhostTick;
Player.m_AttackTick += Client()->GameTick(g_Config.m_ClDummy) - GhostTickUnscaled;

CTeeRenderInfo *pRenderInfo = &Ghost.m_RenderInfo;
CTeeRenderInfo GhostNinjaRenderInfo;
Expand Down Expand Up @@ -377,6 +381,25 @@ void CGhost::OnRender()
}
}

//convert positions
if(Ghost.m_Tickrate <= SERVER_TICK_SPEED && Client()->GameTickSpeed() > SERVER_TICK_SPEED)
{
Prev.m_X *= 4;
Prev.m_Y *= 4;

Player.m_X *= 4;
Player.m_Y *= 4;
}

if(Ghost.m_Tickrate > SERVER_TICK_SPEED && Client()->GameTickSpeed() <= SERVER_TICK_SPEED)
{
Prev.m_X /= 4;
Prev.m_Y /= 4;

Player.m_X /= 4;
Player.m_Y /= 4;
}

m_pClient->m_Players.RenderHook(&Prev, &Player, pRenderInfo, -2, IntraTick);
m_pClient->m_Players.RenderHookCollLine(&Prev, &Player, -2, IntraTick);
m_pClient->m_Players.RenderPlayer(&Prev, &Player, pRenderInfo, -2, IntraTick);
Expand Down Expand Up @@ -414,6 +437,7 @@ void CGhost::StartRecord(int Tick)
m_Recording = true;
m_CurGhost.Reset();
m_CurGhost.m_StartTick = Tick;
m_CurGhost.m_Tickrate = Client()->GameTickSpeed();

const CGameClient::CClientData *pData = &m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID];
str_copy(m_CurGhost.m_aPlayer, Client()->PlayerName());
Expand Down Expand Up @@ -538,6 +562,11 @@ int CGhost::Load(const char *pFilename)
if(!GhostLoader()->ReadData(Type, &pGhost->m_StartTick, sizeof(int)))
Error = true;
}
else if(Type == GHOSTDATA_TYPE_TICKRATE)
{
if(!GhostLoader()->ReadData(Type, &pGhost->m_Tickrate, sizeof(int)))
Error = true;
}
}

GhostLoader()->Close();
Expand All @@ -562,6 +591,9 @@ int CGhost::Load(const char *pFilename)
if(pGhost->m_StartTick == -1)
pGhost->m_StartTick = pGhost->m_Path.Get(0)->m_Tick;

if(pGhost->m_Tickrate <= 0)
pGhost->m_Tickrate = SERVER_TICK_SPEED;

if(!FoundSkin)
GetGhostSkin(&pGhost->m_Skin, "default", 0, 0, 0);
InitRenderInfos(pGhost);
Expand Down Expand Up @@ -593,6 +625,7 @@ void CGhost::SaveGhost(CMenus::CGhostItem *pItem)
GhostRecorder()->Start(pItem->m_aFilename, Client()->GetCurrentMap(), Client()->GetCurrentMapSha256(), pItem->m_aPlayer);

GhostRecorder()->WriteData(GHOSTDATA_TYPE_START_TICK, &pGhost->m_StartTick, sizeof(int));
GhostRecorder()->WriteData(GHOSTDATA_TYPE_TICKRATE, &pGhost->m_Tickrate, sizeof(int));
GhostRecorder()->WriteData(GHOSTDATA_TYPE_SKIN, &pGhost->m_Skin, sizeof(CGhostSkin));
for(int i = 0; i < NumTicks; i++)
GhostRecorder()->WriteData(GHOSTDATA_TYPE_CHARACTER, pGhost->m_Path.Get(i), sizeof(CGhostCharacter));
Expand Down
4 changes: 3 additions & 1 deletion src/game/client/components/ghost.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ enum
GHOSTDATA_TYPE_SKIN = 0,
GHOSTDATA_TYPE_CHARACTER_NO_TICK,
GHOSTDATA_TYPE_CHARACTER,
GHOSTDATA_TYPE_START_TICK
GHOSTDATA_TYPE_START_TICK,
GHOSTDATA_TYPE_TICKRATE
};

struct CGhostSkin
Expand Down Expand Up @@ -91,6 +92,7 @@ class CGhost : public CComponent
CGhostSkin m_Skin;
CGhostPath m_Path;
int m_StartTick;
int m_Tickrate;
char m_aPlayer[MAX_NAME_LENGTH];
int m_PlaybackPos;

Expand Down

0 comments on commit daa311c

Please sign in to comment.