Moved getting autosave name to DLL

This commit is contained in:
Eddoursul 2024-01-24 18:12:06 +01:00
parent 494ec674c1
commit 33ab86a112
6 changed files with 59 additions and 44 deletions

Binary file not shown.

View File

@ -63,28 +63,41 @@ namespace Papyrus::PapyrusFunctions
return result;
}
// Copied from Named Quicksaves by Ryan McKenzie (MIT)
RE::BSFixedString GetPlayerHash(RE::StaticFunctionTag*)
RE::BSFixedString GetAutosaveName(RE::StaticFunctionTag*, std::int32_t a_index)
{
char buf[] = "DEADBEEF";
auto saveData = RE::BSWin32SaveDataSystemUtility::GetSingleton();
if (saveData->profileHash == static_cast<std::uint32_t>(-1)) {
std::snprintf(buf, sizeof(buf), "%08o", 0);
} else {
std::snprintf(buf, sizeof(buf), "%08X", saveData->profileHash);
}
return buf;
}
/*
Save Name Structure (from NQS NamedQuicksaves by Ryan McKenzie)
RE::BSFixedString StringToHex(RE::StaticFunctionTag*, RE::BSFixedString a_string)
{
std::string_view str(a_string);
Save3_0C2D58E2_0_507269736F6E6572_Tamriel_000002_20180503063315_4_1.ess
Save3: Type and index of save
0C2D58E2: Unique hash used to identify your save profile. Regenerated on closing racemenu.
0: Flag for modded game.
507269736F6E6572: Character name in hex.
Tamriel: coc code.
000002: Days, hours, minutes played.
20180503063315: Year, month, day, hour, minute, second in GMT + 0.
4: Player level.
1: Unknown flag.
*/
std::stringstream sstream;
for (auto ch : str) {
sstream << std::uppercase << std::hex << static_cast<int>(ch);
sstream << "Autosave0";
sstream << a_index;
sstream << "_";
sstream << GetPlayerHash().c_str();
sstream << "_0_";
sstream << StringToHex(RE::PlayerCharacter::GetSingleton()->GetName()).c_str();
sstream << "_";
RE::TESObjectCELL* parentCell = RE::PlayerCharacter::GetSingleton()->parentCell;
if (parentCell->IsInteriorCell()) {
sstream << parentCell->GetFormEditorID();
} else {
sstream << RE::PlayerCharacter::GetSingleton()->GetWorldspace()->GetFormEditorID();
}
sstream << "_000000_00000000000000_1_1";
return sstream.str();
}
@ -165,10 +178,8 @@ namespace Papyrus::PapyrusFunctions
logger::info("{}", "Registered GetCurrentContainer"sv);
BIND(GetPlayerFollowers);
logger::info("{}", "Registered GetPlayerFollowers"sv);
BIND(GetPlayerHash);
logger::info("{}", "Registered GetPlayerHash"sv);
BIND(StringToHex);
logger::info("{}", "Registered StringToHex"sv);
BIND(GetAutosaveName);
logger::info("{}", "Registered GetAutosaveName"sv);
BIND(DisableDialogueQuitting);
logger::info("{}", "Registered DisableDialogueQuitting"sv);
BIND(EnableDialogueQuitting);

View File

@ -225,3 +225,28 @@ inline std::uint32_t GetItemCount(RE::TESObjectREFR* a_container, RE::TESForm* a
return iResult > 0 ? iResult : 0;
}
// Copied from Named Quicksaves by Ryan McKenzie (MIT)
inline RE::BSFixedString GetPlayerHash()
{
char buf[] = "DEADBEEF";
auto saveData = RE::BSWin32SaveDataSystemUtility::GetSingleton();
if (saveData->profileHash == static_cast<std::uint32_t>(-1)) {
std::snprintf(buf, sizeof(buf), "%08o", 0);
} else {
std::snprintf(buf, sizeof(buf), "%08X", saveData->profileHash);
}
return buf;
}
inline RE::BSFixedString StringToHex(RE::BSFixedString a_string)
{
std::string_view str(a_string);
std::stringstream sstream;
for (auto ch : str) {
sstream << std::uppercase << std::hex << static_cast<int>(ch);
}
return sstream.str();
}

View File

@ -1,23 +1,10 @@
Scriptname _00E_AutoSaveSystem_Functions extends Quest
; Save Name Structure (from NQS NamedQuicksaves by Ryan McKenzie)
; Save3_0C2D58E2_0_507269736F6E6572_Tamriel_000002_20180503063315_4_1.ess
; Save3: Type and index of save
; 0C2D58E2: Unique hash used to identify your save profile. Regenerated on closing racemenu.
; 0: Flag for modded game.
; 507269736F6E6572: Character name in hex.
; Tamriel: coc code.
; 000002: Days, hours, minutes played.
; 20180503063315: Year, month, day, hour, minute, second in GMT + 0.
; 4: Player level.
; 1: Unknown flag.
Event OnUpdate()
Actor PlayerREF = Game.GetForm(0x14) as Actor
if PlayerREF.IsDead()
if PlayerREF.IsDead() || ! PlayerREF.GetParentCell()
return
endif
@ -26,8 +13,7 @@ Event OnUpdate()
return
endif
; Eddoursul: Index prefixed with 0 ensures the engine does not rotate these saves out
Game.SaveGame("Autosave0" + iAutosaveIndex + "_" + EnderalFunctions.GetPlayerHash() + "_0_" + EnderalFunctions.StringToHex(PlayerREF.GetActorBase().GetName()) + "_EnderalSE_000000_00000000000000_1_1")
Game.SaveGame(EnderalFunctions.GetAutosaveName(iAutosaveIndex))
iAutosaveIndex += 1
if iAutosaveIndex >= Utility.GetIniInt("iAutoSaveCount:SaveGame")

View File

@ -10,14 +10,7 @@ int function GetNewGameCount() native global
Actor[] function GetPlayerFollowers() native global
; Gets the player hash used to uniquely identify the player's save profile.
; RETURN - Returns the player hash as an 8-digit string.
String Function GetPlayerHash() native global
; Converts the given string to it's hexadecimal equivalent. Preserves case.
; a_string - The string to convert to hexadecimal.
; RETURN - Returns the hexadecimal equivalent of the passed string.
String Function StringToHex(String a_string) native global
String Function GetAutosaveName(int index) native global
float function ComputeNeededExp(int CurrentLevel, float Slope, float Mult, float fExpAcc = 1.0, float fExpAcc_Level20 = 1.2, float fExpAcc_Level30 = 1.5, float fExpAcc_Level40 = 2.0) native global