mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
Improved ghost file management
This commit is contained in:
parent
d09e825065
commit
5b3e9e4bbf
|
@ -184,7 +184,7 @@ public:
|
|||
virtual bool RaceRecord_IsRecording() = 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_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader) = 0;
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
void CClient::GhostRecorder_Start()
|
||||
void CClient::GhostRecorder_Start(int Time)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ public:
|
|||
bool RaceRecord_IsRecording();
|
||||
|
||||
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_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader);
|
||||
|
||||
|
|
|
@ -233,15 +233,7 @@ void CGhost::StopRecord(int Time)
|
|||
|
||||
char aFilename[128] = { 0 };
|
||||
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);
|
||||
Storage()->RenameFile(aTmpFilename, aFilename, IStorage::TYPE_SAVE);
|
||||
}
|
||||
|
||||
// create ghost 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));
|
||||
Item.m_Time = Time;
|
||||
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
|
||||
if(pOwnGhost)
|
||||
*pOwnGhost = Item;
|
||||
else
|
||||
m_pClient->m_pMenus->m_lGhosts.add(Item);
|
||||
m_pClient->m_pMenus->m_lGhosts.sort_range();
|
||||
m_pClient->m_pMenus->UpdateOwnGhost(Item);
|
||||
}
|
||||
else if(RecordingToFile) // no new record
|
||||
Storage()->RemoveFile(aTmpFilename, IStorage::TYPE_SAVE);
|
||||
|
@ -364,6 +355,36 @@ void CGhost::Unload(int Slot)
|
|||
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)
|
||||
{
|
||||
((CGhost *)pUserData)->StartRender();
|
||||
|
@ -424,8 +445,7 @@ void CGhost::OnReset()
|
|||
void CGhost::OnMapLoad()
|
||||
{
|
||||
OnReset();
|
||||
for(int i = 0; i < MAX_ACTIVE_GHOSTS; i++)
|
||||
Unload(i);
|
||||
UnloadAll();
|
||||
m_pClient->m_pMenus->GhostlistPopulate();
|
||||
m_IsSolo = true;
|
||||
}
|
||||
|
|
|
@ -110,6 +110,10 @@ public:
|
|||
int Load(const char *pFilename);
|
||||
void Unload(int Slot);
|
||||
|
||||
void UnloadAll();
|
||||
|
||||
void SaveGhost(CMenus::CGhostItem *pItem);
|
||||
|
||||
class IGhostLoader *GhostLoader() const { return m_pGhostLoader; }
|
||||
class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; }
|
||||
};
|
||||
|
|
|
@ -351,6 +351,8 @@ public:
|
|||
|
||||
void GhostlistPopulate();
|
||||
CGhostItem *GetOwnGhost();
|
||||
void UpdateOwnGhost(CGhostItem Item);
|
||||
void DeleteGhostItem(int Index);
|
||||
|
||||
void setPopup(int Popup) { m_Popup = Popup; }
|
||||
|
||||
|
|
|
@ -885,6 +885,32 @@ CMenus::CGhostItem *CMenus::GetOwnGhost()
|
|||
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)
|
||||
{
|
||||
// render background
|
||||
|
@ -1045,11 +1071,11 @@ void CMenus::RenderGhost(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
|
||||
vec3 rgb = vec3(1.0f, 1.0f, 1.0f);
|
||||
if(pItem->m_Own)
|
||||
{
|
||||
vec3 rgb = HslToRgb(vec3(0.33f, 1.0f, 0.75f));
|
||||
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.0f);
|
||||
}
|
||||
rgb = HslToRgb(vec3(0.33f, 1.0f, 0.75f));
|
||||
|
||||
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, pItem->HasFile() ? 1.0f : 0.5f);
|
||||
|
||||
for(int c = 0; c < NumCols; c++)
|
||||
{
|
||||
|
@ -1108,22 +1134,46 @@ void CMenus::RenderGhost(CUIRect MainView)
|
|||
Status.Margin(5.0f, &Status);
|
||||
|
||||
CUIRect Button;
|
||||
Status.VSplitRight(120.0f, &Status, &Button);
|
||||
|
||||
static int s_GhostButton = 0;
|
||||
bool Delete = !pGhost->HasFile();
|
||||
const char *pText = pGhost->Active() ? (Delete ? Localize("Delete") : Localize("Deactivate")) : Localize("Activate");
|
||||
static int s_DeleteButton = 0;
|
||||
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(pGhost->Active())
|
||||
{
|
||||
m_pClient->m_pGhost->Unload(pGhost->m_Slot);
|
||||
pGhost->m_Slot = -1;
|
||||
if(Delete)
|
||||
m_lGhosts.remove_index(s_SelectedIndex);
|
||||
}
|
||||
else
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue