Added saving checkpoints to disk for mappers (mostly for Lily). !savecps !loadcps

This commit is contained in:
shavitush 2020-07-10 19:44:16 +03:00
parent d9f49b7b2f
commit 8f1da48e82
3 changed files with 196 additions and 1 deletions

View File

@ -44,6 +44,9 @@
#define HUD_NOSOUNDS (1 << 11) // disables sounds on personal best, world record etc #define HUD_NOSOUNDS (1 << 11) // disables sounds on personal best, world record etc
#define HUD_NOPRACALERT (1 << 12) // hides practice mode chat alert #define HUD_NOPRACALERT (1 << 12) // hides practice mode chat alert
// replay
#define CELLS_PER_FRAME 8 // origin[3], angles[2], buttons, flags, movetype
// status // status
enum TimerStatus enum TimerStatus
{ {

View File

@ -116,6 +116,10 @@ StringMap gSM_Checkpoints = null;
ArrayList gA_Targetnames = null; ArrayList gA_Targetnames = null;
ArrayList gA_Classnames = null; ArrayList gA_Classnames = null;
// checkpoint files
char gS_CPData[PLATFORM_MAX_PATH];
char gS_MapPath[PLATFORM_MAX_PATH];
// save states // save states
bool gB_SaveStatesSegmented[MAXPLAYERS+1]; bool gB_SaveStatesSegmented[MAXPLAYERS+1];
float gF_SaveStateData[MAXPLAYERS+1][3][3]; float gF_SaveStateData[MAXPLAYERS+1][3][3];
@ -251,6 +255,8 @@ public void OnPluginStart()
RegConsoleCmd("sm_checkpoints", Command_Checkpoints, "Opens the checkpoints menu. Alias for sm_cpmenu."); RegConsoleCmd("sm_checkpoints", Command_Checkpoints, "Opens the checkpoints menu. Alias for sm_cpmenu.");
RegConsoleCmd("sm_save", Command_Save, "Saves checkpoint."); RegConsoleCmd("sm_save", Command_Save, "Saves checkpoint.");
RegConsoleCmd("sm_tele", Command_Tele, "Teleports to checkpoint. Usage: sm_tele [number]"); RegConsoleCmd("sm_tele", Command_Tele, "Teleports to checkpoint. Usage: sm_tele [number]");
RegConsoleCmd("sm_savecps", Command_SaveCPs, "Saves all your checkpoints data on disk");
RegConsoleCmd("sm_loadcps", Command_LoadCPs, "Loads your checkpoint data from disk");
gH_CheckpointsCookie = RegClientCookie("shavit_checkpoints", "Checkpoints settings", CookieAccess_Protected); gH_CheckpointsCookie = RegClientCookie("shavit_checkpoints", "Checkpoints settings", CookieAccess_Protected);
gSM_Checkpoints = new StringMap(); gSM_Checkpoints = new StringMap();
gA_Targetnames = new ArrayList(ByteCountToCells(64)); gA_Targetnames = new ArrayList(ByteCountToCells(64));
@ -395,6 +401,13 @@ public void OnPluginStart()
gB_Rankings = LibraryExists("shavit-rankings"); gB_Rankings = LibraryExists("shavit-rankings");
gB_Replay = LibraryExists("shavit-replay"); gB_Replay = LibraryExists("shavit-replay");
gB_Zones = LibraryExists("shavit-zones"); gB_Zones = LibraryExists("shavit-zones");
BuildPath(Path_SM, gS_CPData, PLATFORM_MAX_PATH, "data/checkpoints");
if(!DirExists(gS_CPData))
{
CreateDirectory(gS_CPData, 511);
}
} }
public void OnClientCookiesCached(int client) public void OnClientCookiesCached(int client)
@ -547,6 +560,8 @@ public void OnMapStart()
{ {
CreateTimer(gCV_AdvertisementInterval.FloatValue, Timer_Advertisement, 0, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); CreateTimer(gCV_AdvertisementInterval.FloatValue, Timer_Advertisement, 0, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
} }
FormatEx(gS_MapPath, PLATFORM_MAX_PATH, "%s/%s.cp", gS_CPData, gS_CurrentMap);
} }
public void OnMapEnd() public void OnMapEnd()
@ -1738,6 +1753,184 @@ public Action Command_Save(int client, int args)
return Plugin_Handled; return Plugin_Handled;
} }
void WriteArrayToFile(File pFile, any[] aVec, int nSize)
{
for(int i = 0; i < nSize; i++)
{
pFile.WriteInt32(view_as<int>(aVec[i]));
}
}
void WriteCheckpointToFile(File pFile, int client, int nCheckpoint)
{
cp_cache_t aCache;
GetCheckpoint(client, nCheckpoint, aCache);
WriteArrayToFile(pFile, aCache.fPosition, 3);
WriteArrayToFile(pFile, aCache.fAngles, 3);
WriteArrayToFile(pFile, aCache.fVelocity, 3);
WriteArrayToFile(pFile, aCache.fBaseVelocity, 3);
pFile.WriteInt32(view_as<int>(aCache.iMoveType));
pFile.WriteInt32(view_as<int>(aCache.fGravity));
pFile.WriteInt32(view_as<int>(aCache.fSpeed));
pFile.WriteInt32(view_as<int>(aCache.fStamina));
pFile.WriteInt8(view_as<int>(aCache.bDucked));
pFile.WriteInt8(view_as<int>(aCache.bDucking));
pFile.WriteInt32(view_as<int>(aCache.fDucktime));
pFile.WriteInt32(view_as<int>(aCache.fDuckSpeed));
pFile.WriteInt32(view_as<int>(aCache.iFlags));
pFile.WriteInt8(view_as<int>(aCache.aSnapshot.bTimerEnabled));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.fCurrentTime));
pFile.WriteInt8(view_as<int>(aCache.aSnapshot.bClientPaused));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iJumps));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.bsStyle));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iStrafes));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iTotalMeasures));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iGoodGains));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.fServerTime));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iSHSWCombination));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iTimerTrack));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iMeasuredJumps));
pFile.WriteInt32(view_as<int>(aCache.aSnapshot.iPerfectJumps));
pFile.WriteInt8(view_as<int>(aCache.bSegmented));
pFile.WriteInt8(view_as<int>(aCache.bPractice));
pFile.WriteInt32(view_as<int>(aCache.iGroundEntity));
int nLength = aCache.aFrames != null ? aCache.aFrames.Length : 0;
pFile.WriteInt32(nLength);
any aData[CELLS_PER_FRAME];
for(int i = 0; i < nLength; i++)
{
aCache.aFrames.GetArray(i, aData, CELLS_PER_FRAME);
pFile.Write(aData, CELLS_PER_FRAME, 4);
}
}
public Action Command_SaveCPs(int client, int args)
{
if(client == 0)
{
return Plugin_Handled;
}
if(FileExists(gS_MapPath))
{
DeleteFile(gS_MapPath);
}
File fFile = OpenFile(gS_MapPath, "wb");
fFile.WriteInt32(gA_CheckpointsCache[client].iCheckpoints);
for(int i = 1; i <= gA_CheckpointsCache[client].iCheckpoints; i++)
{
WriteCheckpointToFile(fFile, client, i);
}
delete fFile;
ReplyToCommand(client, "Saved CPs to %s", gS_MapPath);
return Plugin_Handled;
}
void ReadArrayFromFile(File pFile, any[] aVec, int nSize)
{
for(int i = 0; i < nSize; i++)
{
pFile.ReadInt32(aVec[i]);
}
}
void ReadCheckpointFromFile(File pFile, int client, int nCheckpoint)
{
cp_cache_t aCache;
ReadArrayFromFile(pFile, aCache.fPosition, 3);
ReadArrayFromFile(pFile, aCache.fAngles, 3);
ReadArrayFromFile(pFile, aCache.fVelocity, 3);
ReadArrayFromFile(pFile, aCache.fBaseVelocity, 3);
pFile.ReadInt32(view_as<int>(aCache.iMoveType));
pFile.ReadInt32(view_as<int>(aCache.fGravity));
pFile.ReadInt32(view_as<int>(aCache.fSpeed));
pFile.ReadInt32(view_as<int>(aCache.fStamina));
pFile.ReadInt8(aCache.bDucked);
pFile.ReadInt8(aCache.bDucking);
pFile.ReadInt32(view_as<int>(aCache.fDucktime));
pFile.ReadInt32(view_as<int>(aCache.fDuckSpeed));
pFile.ReadInt32(aCache.iFlags);
pFile.ReadInt8(aCache.aSnapshot.bTimerEnabled);
pFile.ReadInt32(view_as<int>(aCache.aSnapshot.fCurrentTime));
pFile.ReadInt8(aCache.aSnapshot.bClientPaused);
pFile.ReadInt32(aCache.aSnapshot.iJumps);
pFile.ReadInt32(aCache.aSnapshot.bsStyle);
pFile.ReadInt32(aCache.aSnapshot.iStrafes);
pFile.ReadInt32(aCache.aSnapshot.iTotalMeasures);
pFile.ReadInt32(aCache.aSnapshot.iGoodGains);
pFile.ReadInt32(view_as<int>(aCache.aSnapshot.fServerTime));
pFile.ReadInt32(aCache.aSnapshot.iSHSWCombination);
pFile.ReadInt32(aCache.aSnapshot.iTimerTrack);
pFile.ReadInt32(aCache.aSnapshot.iMeasuredJumps);
pFile.ReadInt32(aCache.aSnapshot.iPerfectJumps);
pFile.ReadInt8(aCache.bSegmented);
pFile.ReadInt8(aCache.bPractice);
pFile.ReadInt32(aCache.iGroundEntity);
aCache.iTargetname = -1;
aCache.iClassname = -1;
aCache.iSerial = GetClientSerial(client);
aCache.aFrames = null;
int nLength;
pFile.ReadInt32(nLength);
if(nLength > 0)
{
aCache.aFrames = new ArrayList(CELLS_PER_FRAME, nLength);
any aData[CELLS_PER_FRAME];
for(int i = 0; i < nLength; i++)
{
pFile.Read(aData, CELLS_PER_FRAME, 4);
aCache.aFrames.SetArray(i, aData, CELLS_PER_FRAME);
}
}
SetCheckpoint(client, nCheckpoint, aCache);
}
public Action Command_LoadCPs(int client, int args)
{
if(client == 0)
{
return Plugin_Handled;
}
if(!FileExists(gS_MapPath))
{
ReplyToCommand(client, "No CP data saved. Use !savecps");
return Plugin_Handled;
}
ResetCheckpoints(client);
File fFile = OpenFile(gS_MapPath, "rb");
fFile.ReadInt32(gA_CheckpointsCache[client].iCheckpoints);
gA_CheckpointsCache[client].iCurrentCheckpoint = gA_CheckpointsCache[client].iCheckpoints;
for(int i = 0; i < gA_CheckpointsCache[client].iCheckpoints; i++)
{
ReadCheckpointFromFile(fFile, client, i + 1);
}
delete fFile;
ReplyToCommand(client, "Loaded CP data uwu");
return OpenCheckpointsMenu(client);
}
public Action Command_Tele(int client, int args) public Action Command_Tele(int client, int args)
{ {
if(client == 0) if(client == 0)

View File

@ -34,7 +34,6 @@
#define REPLAY_FORMAT_V2 "{SHAVITREPLAYFORMAT}{V2}" #define REPLAY_FORMAT_V2 "{SHAVITREPLAYFORMAT}{V2}"
#define REPLAY_FORMAT_FINAL "{SHAVITREPLAYFORMAT}{FINAL}" #define REPLAY_FORMAT_FINAL "{SHAVITREPLAYFORMAT}{FINAL}"
#define REPLAY_FORMAT_SUBVERSION 0x04 #define REPLAY_FORMAT_SUBVERSION 0x04
#define CELLS_PER_FRAME 8 // origin[3], angles[2], buttons, flags, movetype
#define FRAMES_PER_WRITE 100 // amounts of frames to write per read/write call #define FRAMES_PER_WRITE 100 // amounts of frames to write per read/write call
// #define DEBUG // #define DEBUG