Improved ghost file management

This commit is contained in:
Redix 2017-09-10 03:48:22 +02:00
parent d09e825065
commit 5b3e9e4bbf
7 changed files with 111 additions and 35 deletions

View file

@ -184,7 +184,7 @@ public:
virtual bool RaceRecord_IsRecording() = 0; virtual bool RaceRecord_IsRecording() = 0;
virtual void Ghost_GetPath(char *pBuf, int Size, int Time = -1) = 0; virtual void Ghost_GetPath(char *pBuf, int Size, int Time = -1) = 0;
virtual void GhostRecorder_Start() = 0; virtual void GhostRecorder_Start(int Time = -1) = 0;
virtual bool GhostLoader_Load(const char *pFilename) = 0; virtual bool GhostLoader_Load(const char *pFilename) = 0;
virtual bool GhostLoader_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader) = 0; virtual bool GhostLoader_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader) = 0;

View file

@ -3661,10 +3661,10 @@ void CClient::Ghost_GetPath(char *pBuf, int Size, int Time)
str_format(pBuf, Size, "ghosts/%s_%s_%d.%03d_%08x.gho", m_aCurrentMap, aPlayerName, Time / 1000, Time % 1000, m_pMap->Crc()); str_format(pBuf, Size, "ghosts/%s_%s_%d.%03d_%08x.gho", m_aCurrentMap, aPlayerName, Time / 1000, Time % 1000, m_pMap->Crc());
} }
void CClient::GhostRecorder_Start() void CClient::GhostRecorder_Start(int Time)
{ {
char aFilename[128]; char aFilename[128];
Ghost_GetPath(aFilename, sizeof(aFilename)); Ghost_GetPath(aFilename, sizeof(aFilename), Time);
m_GhostRecorder.Start(Storage(), m_pConsole, aFilename, m_aCurrentMap, m_pMap->Crc(), g_Config.m_PlayerName); m_GhostRecorder.Start(Storage(), m_pConsole, aFilename, m_aCurrentMap, m_pMap->Crc(), g_Config.m_PlayerName);
} }

View file

@ -392,7 +392,7 @@ public:
bool RaceRecord_IsRecording(); bool RaceRecord_IsRecording();
void Ghost_GetPath(char *pBuf, int Size, int Time = -1); void Ghost_GetPath(char *pBuf, int Size, int Time = -1);
void GhostRecorder_Start(); void GhostRecorder_Start(int Time = -1);
bool GhostLoader_Load(const char *pFilename); bool GhostLoader_Load(const char *pFilename);
bool GhostLoader_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader); bool GhostLoader_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader);

View file

@ -233,15 +233,7 @@ void CGhost::StopRecord(int Time)
char aFilename[128] = { 0 }; char aFilename[128] = { 0 };
if(RecordingToFile) if(RecordingToFile)
{
// remove old ghost
if(pOwnGhost && pOwnGhost->HasFile())
Storage()->RemoveFile(pOwnGhost->m_aFilename, IStorage::TYPE_SAVE);
// save new ghost
Client()->Ghost_GetPath(aFilename, sizeof(aFilename), Time); Client()->Ghost_GetPath(aFilename, sizeof(aFilename), Time);
Storage()->RenameFile(aTmpFilename, aFilename, IStorage::TYPE_SAVE);
}
// create ghost item // create ghost item
CMenus::CGhostItem Item; CMenus::CGhostItem Item;
@ -249,14 +241,13 @@ void CGhost::StopRecord(int Time)
str_copy(Item.m_aPlayer, g_Config.m_PlayerName, sizeof(Item.m_aPlayer)); str_copy(Item.m_aPlayer, g_Config.m_PlayerName, sizeof(Item.m_aPlayer));
Item.m_Time = Time; Item.m_Time = Time;
Item.m_Slot = Slot; Item.m_Slot = Slot;
Item.m_Own = true;
// save new ghost file
if(Item.HasFile())
Storage()->RenameFile(aTmpFilename, aFilename, IStorage::TYPE_SAVE);
// add item to menu list // add item to menu list
if(pOwnGhost) m_pClient->m_pMenus->UpdateOwnGhost(Item);
*pOwnGhost = Item;
else
m_pClient->m_pMenus->m_lGhosts.add(Item);
m_pClient->m_pMenus->m_lGhosts.sort_range();
} }
else if(RecordingToFile) // no new record else if(RecordingToFile) // no new record
Storage()->RemoveFile(aTmpFilename, IStorage::TYPE_SAVE); Storage()->RemoveFile(aTmpFilename, IStorage::TYPE_SAVE);
@ -364,6 +355,36 @@ void CGhost::Unload(int Slot)
m_aActiveGhosts[Slot].Reset(); m_aActiveGhosts[Slot].Reset();
} }
void CGhost::UnloadAll()
{
for(int i = 0; i < MAX_ACTIVE_GHOSTS; i++)
Unload(i);
}
void CGhost::SaveGhost(CMenus::CGhostItem *pItem)
{
int Slot = pItem->m_Slot;
if(Slot < 0 || pItem->HasFile() || m_aActiveGhosts[Slot].Empty() || GhostRecorder()->IsRecording())
return;
int NumTicks = m_aActiveGhosts[Slot].m_lPath.size();
Client()->GhostRecorder_Start(pItem->m_Time);
const CGameClient::CClientData *pClientData = &m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID];
CGhostSkin Skin;
StrToInts(&Skin.m_Skin0, 6, pClientData->m_aSkinName);
Skin.m_UseCustomColor = pClientData->m_UseCustomColor;
Skin.m_ColorBody = pClientData->m_ColorBody;
Skin.m_ColorFeet = pClientData->m_ColorFeet;
GhostRecorder()->WriteData(GHOSTDATA_TYPE_SKIN, (const char*)&Skin, sizeof(Skin));
for(int i = 0; i < NumTicks; i++)
GhostRecorder()->WriteData(GHOSTDATA_TYPE_CHARACTER, (const char*)&m_aActiveGhosts[Slot].m_lPath[i], sizeof(CGhostCharacter));
GhostRecorder()->Stop(NumTicks, pItem->m_Time);
Client()->Ghost_GetPath(pItem->m_aFilename, sizeof(pItem->m_aFilename), pItem->m_Time);
}
void CGhost::ConGPlay(IConsole::IResult *pResult, void *pUserData) void CGhost::ConGPlay(IConsole::IResult *pResult, void *pUserData)
{ {
((CGhost *)pUserData)->StartRender(); ((CGhost *)pUserData)->StartRender();
@ -424,8 +445,7 @@ void CGhost::OnReset()
void CGhost::OnMapLoad() void CGhost::OnMapLoad()
{ {
OnReset(); OnReset();
for(int i = 0; i < MAX_ACTIVE_GHOSTS; i++) UnloadAll();
Unload(i);
m_pClient->m_pMenus->GhostlistPopulate(); m_pClient->m_pMenus->GhostlistPopulate();
m_IsSolo = true; m_IsSolo = true;
} }

View file

@ -110,6 +110,10 @@ public:
int Load(const char *pFilename); int Load(const char *pFilename);
void Unload(int Slot); void Unload(int Slot);
void UnloadAll();
void SaveGhost(CMenus::CGhostItem *pItem);
class IGhostLoader *GhostLoader() const { return m_pGhostLoader; } class IGhostLoader *GhostLoader() const { return m_pGhostLoader; }
class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; } class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; }
}; };

View file

@ -351,6 +351,8 @@ public:
void GhostlistPopulate(); void GhostlistPopulate();
CGhostItem *GetOwnGhost(); CGhostItem *GetOwnGhost();
void UpdateOwnGhost(CGhostItem Item);
void DeleteGhostItem(int Index);
void setPopup(int Popup) { m_Popup = Popup; } void setPopup(int Popup) { m_Popup = Popup; }

View file

@ -885,6 +885,32 @@ CMenus::CGhostItem *CMenus::GetOwnGhost()
return 0; return 0;
} }
void CMenus::UpdateOwnGhost(CGhostItem Item)
{
int Own = -1;
for(int i = 0; i < m_lGhosts.size(); i++)
if(m_lGhosts[i].m_Own)
Own = i;
if(Own != -1)
{
m_lGhosts[Own].m_Slot = -1;
m_lGhosts[Own].m_Own = false;
if(Item.HasFile() || !m_lGhosts[Own].HasFile())
DeleteGhostItem(Own);
}
Item.m_Own = true;
m_lGhosts.add(Item);
}
void CMenus::DeleteGhostItem(int Index)
{
if(m_lGhosts[Index].HasFile())
Storage()->RemoveFile(m_lGhosts[Index].m_aFilename, IStorage::TYPE_SAVE);
m_lGhosts.remove_index(Index);
}
void CMenus::RenderGhost(CUIRect MainView) void CMenus::RenderGhost(CUIRect MainView)
{ {
// render background // render background
@ -1045,11 +1071,11 @@ void CMenus::RenderGhost(CUIRect MainView)
} }
} }
vec3 rgb = vec3(1.0f, 1.0f, 1.0f);
if(pItem->m_Own) if(pItem->m_Own)
{ rgb = HslToRgb(vec3(0.33f, 1.0f, 0.75f));
vec3 rgb = HslToRgb(vec3(0.33f, 1.0f, 0.75f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.0f); TextRender()->TextColor(rgb.r, rgb.g, rgb.b, pItem->HasFile() ? 1.0f : 0.5f);
}
for(int c = 0; c < NumCols; c++) for(int c = 0; c < NumCols; c++)
{ {
@ -1108,22 +1134,46 @@ void CMenus::RenderGhost(CUIRect MainView)
Status.Margin(5.0f, &Status); Status.Margin(5.0f, &Status);
CUIRect Button; CUIRect Button;
Status.VSplitRight(120.0f, &Status, &Button);
static int s_GhostButton = 0; static int s_GhostButton = 0;
bool Delete = !pGhost->HasFile(); static int s_DeleteButton = 0;
const char *pText = pGhost->Active() ? (Delete ? Localize("Delete") : Localize("Deactivate")) : Localize("Activate"); static int s_SaveButton = 0;
if(pGhost->HasFile())
{
Status.VSplitRight(120.0f, &Status, &Button);
const char *pText = pGhost->Active() ? Localize("Deactivate") : Localize("Activate");
if(DoButton_Menu(&s_GhostButton, pText, 0, &Button) || (NewSelected != -1 && Input()->MouseDoubleClick())) if(DoButton_Menu(&s_GhostButton, pText, 0, &Button) || (NewSelected != -1 && Input()->MouseDoubleClick()))
{ {
if(pGhost->Active()) if(pGhost->Active())
{ {
m_pClient->m_pGhost->Unload(pGhost->m_Slot); m_pClient->m_pGhost->Unload(pGhost->m_Slot);
pGhost->m_Slot = -1; pGhost->m_Slot = -1;
if(Delete)
m_lGhosts.remove_index(s_SelectedIndex);
} }
else else
pGhost->m_Slot = m_pClient->m_pGhost->Load(pGhost->m_aFilename); pGhost->m_Slot = m_pClient->m_pGhost->Load(pGhost->m_aFilename);
} }
Status.VSplitRight(5.0f, &Status, 0);
}
Status.VSplitRight(120.0f, &Status, &Button);
if(DoButton_Menu(&s_DeleteButton, Localize("Delete"), 0, &Button))
{
if(pGhost->Active())
m_pClient->m_pGhost->Unload(pGhost->m_Slot);
DeleteGhostItem(s_SelectedIndex);
}
Status.VSplitRight(5.0f, &Status, 0);
bool Recording = m_pClient->m_pGhost->GhostRecorder()->IsRecording();
if(!pGhost->HasFile() && !Recording && pGhost->Active())
{
Status.VSplitRight(120.0f, &Status, &Button);
if(DoButton_Menu(&s_SaveButton, Localize("Save"), 0, &Button))
m_pClient->m_pGhost->SaveGhost(pGhost);
}
} }