diff --git a/Enderal - Forgotten Stories.ini b/Enderal - Forgotten Stories.ini index 3f429cb3..35139fd7 100644 --- a/Enderal - Forgotten Stories.ini +++ b/Enderal - Forgotten Stories.ini @@ -9,7 +9,7 @@ sResourceArchiveList=Skyrim - Misc.bsa, Skyrim - Shaders.bsa, Skyrim - Interface sResourceArchiveList2=Skyrim - Textures8.bsa, Skyrim - Patch.bsa, E - Meshes.bsa, E - Textures1.bsa, E - Textures2.bsa, E - Sounds.bsa, L - Voices.bsa, E - Misc.bsa, E - Update.bsa, L - Textures.bsa [SaveGame] -iAutoSaveCount=10 +iAutoSaveCount=5 [MapMenu] ; Paper map settings diff --git a/SKSE/Plugins/EnderalSE.dll b/SKSE/Plugins/EnderalSE.dll index 79881c56..2989e47a 100644 --- a/SKSE/Plugins/EnderalSE.dll +++ b/SKSE/Plugins/EnderalSE.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c5a759580e8541d086b08dddf8fd9f63749add3896d35dd9c6af843dc2c56c3 -size 717824 +oid sha256:c71b1d48c90e85a61283eba094d6349926d6506784e7dc788f481102726165a5 +size 726528 diff --git a/scripts/_00E_AutosaveIntervalAlias.pex b/scripts/_00E_AutosaveIntervalAlias.pex index eb3f3958..f4d5eb75 100644 Binary files a/scripts/_00E_AutosaveIntervalAlias.pex and b/scripts/_00E_AutosaveIntervalAlias.pex differ diff --git a/scripts/_00e_autosavesystem_functions.pex b/scripts/_00e_autosavesystem_functions.pex index c3a28c58..8f92b475 100644 Binary files a/scripts/_00e_autosavesystem_functions.pex and b/scripts/_00e_autosavesystem_functions.pex differ diff --git a/scripts/enderalfunctions.pex b/scripts/enderalfunctions.pex index e4f711af..3d2ab3be 100644 Binary files a/scripts/enderalfunctions.pex and b/scripts/enderalfunctions.pex differ diff --git a/source/Enderal DLL/CMakeLists.txt b/source/Enderal DLL/CMakeLists.txt index 68f0d094..493c5a47 100644 --- a/source/Enderal DLL/CMakeLists.txt +++ b/source/Enderal DLL/CMakeLists.txt @@ -6,7 +6,7 @@ message("Using toolchain file ${CMAKE_TOOLCHAIN_FILE}.") ######################################################################################################################## project( EnderalSE - VERSION 1.1.0 + VERSION 2.1.0 DESCRIPTION "Enderal SE DLL" LANGUAGES CXX) set(CMAKE_CXX_STANDARD 23) diff --git a/source/Enderal DLL/src/PapyrusFunctions.h b/source/Enderal DLL/src/PapyrusFunctions.h index 5ad18c67..b376eacb 100644 --- a/source/Enderal DLL/src/PapyrusFunctions.h +++ b/source/Enderal DLL/src/PapyrusFunctions.h @@ -62,6 +62,31 @@ namespace Papyrus::PapyrusFunctions return result; } + // Copied from Named Quicksaves by Ryan McKenzie (MIT) + RE::BSFixedString GetPlayerHash(RE::StaticFunctionTag*) + { + char buf[] = "DEADBEEF"; + auto saveData = RE::BSWin32SaveDataSystemUtility::GetSingleton(); + if (saveData->profileHash == static_cast(-1)) { + std::snprintf(buf, sizeof(buf), "%08o", 0); + } else { + std::snprintf(buf, sizeof(buf), "%08X", saveData->profileHash); + } + return buf; + } + + RE::BSFixedString StringToHex(RE::StaticFunctionTag*, RE::BSFixedString a_string) + { + std::string_view str(a_string); + + std::stringstream sstream; + for (auto ch : str) { + sstream << std::uppercase << std::hex << static_cast(ch); + } + + return sstream.str(); + } + inline void Bind(VM& a_vm) { BIND(CreatePotion); @@ -72,5 +97,9 @@ 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); } } diff --git a/source/Enderal DLL/vcpkg.json b/source/Enderal DLL/vcpkg.json index 99277de2..2d6a7dfe 100644 --- a/source/Enderal DLL/vcpkg.json +++ b/source/Enderal DLL/vcpkg.json @@ -1,10 +1,10 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json", "name": "enderal-se", - "version-string": "1.0.0", + "version-string": "2.1.0", "port-version": 0, "description": "Enderal SE Helper", - "homepage": "https://eddoursul.win/mods/enderal-se/", + "homepage": "https://mod.pub/enderal-se/38-enderal-se", "license": "LGPL-3.0", "features": { "plugin": { diff --git a/source/scripts/_00E_AutosaveIntervalAlias.psc b/source/scripts/_00E_AutosaveIntervalAlias.psc index 873bf6f3..2db37047 100644 --- a/source/scripts/_00E_AutosaveIntervalAlias.psc +++ b/source/scripts/_00E_AutosaveIntervalAlias.psc @@ -1,7 +1,9 @@ Scriptname _00E_AutosaveIntervalAlias extends ReferenceAlias Hidden -Event OnPlayerLoadGame() - +Event OnInit() (GetOwningQuest() as _00E_AutoSaveSystem_Functions).UpdateAutoSaveInterval() +EndEvent +Event OnPlayerLoadGame() + (GetOwningQuest() as _00E_AutoSaveSystem_Functions).UpdateAutoSaveInterval() EndEvent diff --git a/source/scripts/_00e_autosavesystem_functions.psc b/source/scripts/_00e_autosavesystem_functions.psc index 802c520d..309dd5ea 100644 --- a/source/scripts/_00e_autosavesystem_functions.psc +++ b/source/scripts/_00e_autosavesystem_functions.psc @@ -1,38 +1,47 @@ -Scriptname _00E_AutoSaveSystem_Functions extends Quest +Scriptname _00E_AutoSaveSystem_Functions extends Quest -Event OnInit() - - fUpdateTime = Utility.GetIniFloat("fAutosaveEveryXMins:SaveGame") - If fUpdateTime <= 0.0 ; just in case - fUpdateTime = 60 - EndIf - - RegisterForSingleUpdate(fUpdateTime*60) - -EndEvent +; 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() - If bAutosaveSystemStopped == false - If Utility.IsInMenuMode() == false && UI.IsTextInputEnabled() == false && UI.IsMenuOpen("Dialogue Menu") == false && PlayerREF.IsDead() == false && PlayerREF.IsInCombat() == false && Game.IsFightingControlsEnabled() == true - Game.RequestAutoSave() - RegisterForSingleUpdate(fUpdateTime*60) - Else - RegisterForSingleUpdate(5) - EndIf + If bAutosaveSystemStopped + return EndIf - + + Actor PlayerREF = Game.GetForm(0x14) as Actor + + If PlayerREF.IsInCombat() || ! Game.IsFightingControlsEnabled() || PlayerREF.IsDead() || Utility.IsInMenuMode() || UI.IsTextInputEnabled() || UI.IsMenuOpen("Dialogue Menu") + RegisterForSingleUpdate(5) + 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") + + iAutosaveIndex += 1 + if iAutosaveIndex >= Utility.GetIniInt("iAutoSaveCount:SaveGame") + iAutosaveIndex = 0 + endif + + RegisterForSingleUpdate(fUpdateTime*60) + EndEvent ; called from _00E_AutosaveIntervalAlias to update ini setting fAutosaveEveryXMins in case it was changed Function UpdateAutoSaveInterval() - fUpdateTime = Utility.GetIniFloat("fAutosaveEveryXMins:SaveGame") - If fUpdateTime <= 0.0 ; just in case - fUpdateTime = 60 - EndIf - - UnregisterForUpdate() + fUpdateTime = GetAutosaveEveryXMins() RegisterForSingleUpdate(fUpdateTime*60) EndFunction @@ -46,26 +55,28 @@ Function ResumeAutosaveSystemInXMinutes(float _fMinutes = 0.0) If _fMinutes == 0.0 _fMinutes = fUpdateTime - If _fMinutes == 0.0 ; just in case - _fMinutes = 60 + If _fMinutes <= 0.0 ; just in case + _fMinutes = 30 EndIf EndIf - UnregisterForUpdate() ; just in case again RegisterForSingleUpdate(_fMinutes*60) bAutosaveSystemStopped = false EndFunction -; not used yet btw / maybe will never be used -; called shortly before the end of every quest, parameter is always the quest name -Function RequestHardSave(string _sQuestName) +float function GetAutosaveEveryXMins() - Utility.Wait(0.1) ; in case we are in a menu (debug message boxes / dialogue etc) - Game.SaveGame(_sQuestName) + float fUpdateMinutes = Utility.GetIniFloat("fAutosaveEveryXMins:SaveGame") + + If fUpdateMinutes <= 0.0 ; just in case + fUpdateMinutes = 30 + EndIf -EndFunction + return fUpdateMinutes + +endfunction bool bAutosaveSystemStopped = false +int iAutosaveIndex = 0 float fUpdateTime -Actor Property PlayerREF Auto \ No newline at end of file diff --git a/source/scripts/enderalfunctions.psc b/source/scripts/enderalfunctions.psc index 3d6770ec..cf6e258c 100644 --- a/source/scripts/enderalfunctions.psc +++ b/source/scripts/enderalfunctions.psc @@ -10,6 +10,15 @@ 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() Global Native + +; 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) Global Native + bool function IsDLLLoaded() global int iVer = SKSE.GetPluginVersion("EnderalSE") return iVer > 0