Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
56 kB
1
Indexable
Never
Scriptname SSSOConfigMenu extends nl_mcm_module  
;===============  PROPERTIES  ==========================================;
Actor Property PlayerREF Auto
SSSOConfigMenuHelp property helppage auto
SSSOConfigMenuProfile property profilepage auto
Formlist property SSSO_DoomStoneList auto
Formlist property SSSO_ShrineLIST auto

;===============  UTILITIES   ==========================================;
import StringUtil
Import Utility
;===============  VARIABLES   ==========================================;
bool _use_standalone_mcm
string[] ASCIITable1
string[] ASCIITable2
string[] HexTable1
string[] HexTable2

String UniqueHash = "notset"
bool RegenIDSuccess = false

string playername
string PlayerNamefromHex = "none"
Int SaveIndex  = 1

bool ModEnable = false
bool DisableAutoSave = false
Bool Saveprotection = true
bool MSGSafeSave = true
bool SleepToSave = false
bool StoneToSave = false
bool ShrineToSave = false
int Savedelay = 300
int PreviousSavedelay


Bool RotatingSave = false
bool BypassCheck = false
Int RotatingSaveNb  = 10
bool IncludeManualSave = false

bool HardcoreMode = false
bool TrueHeroMode = false
bool allowedtoload = true
bool previousloadstatus = true
int quitdelay = 15
int savekey = 1

bool reset = false
bool keypressed = false
Bool activity = false
bool loading = false
bool Saveperformed = false

float lastsavetimestamp
bool automaticsave = false
bool manualsave = false
bool testsave = false
bool Immersivesave = false

bool debugcheck = false
;===============    EVENTS    ==========================================;
event OnInit()

    CheckRequirement()

    if Game.GetModByName("SMF.esp") == 255 && Game.GetModByName("SMF.esl") == 255
        _use_standalone_mcm = True
        RegisterModule("Core")
        helppage.RegisterModule("Help",101)
        profilepage.RegisterModule("Profile",102)
    else
        RegisterModule("Save System - Core", 1011, "_SMF_ConfigMenuInstance")
        helppage.RegisterModule("Save System - Help", 1012, "_SMF_ConfigMenuInstance" )
        profilepage.RegisterModule("Save System - Profile",1013, "_SMF_ConfigMenuInstance" )
    endif
endevent

event OnGameReload()
    loading = true
    keypressed = false

    CheckRequirement()   

    if Game.GetModByName("SMF.esp") == 255 && Game.GetModByName("SMF.esl") == 255
        if !_use_standalone_mcm
            UnregisterAllModules()
            _use_standalone_mcm = True
            RegisterModule("Core")
            helppage.RegisterModule("Help",101)
            profilepage.RegisterModule("Profile",102)
        endif
    else
        if _use_standalone_mcm
            UnregisterAllModules()
            _use_standalone_mcm = False
            RegisterModule("Save System - Core", 1011, "_SMF_ConfigMenuInstance")
            helppage.RegisterModule("Save - System - Help", 1012, "_SMF_ConfigMenuInstance" )
            profilepage.RegisterModule("Save - System - Profile",1013, "_SMF_ConfigMenuInstance" )
        endif
    endif
    Playername = PlayerREF.GetBaseObject().GetName()
    if RotatingSave && UniqueHash == "notset" || RotatingSave && !RegenIDSuccess && !BypassCheck
        RegenID()
    EndIf
    grantload()
endevent

event OnPageInit()
    if _use_standalone_mcm
        SetModName("Save System Overhaul 2")
        SetLandingPage("Core")
    endif

    ;Initialize array
    ASCIITable1 = new string[109]
    ASCIITable2 = new string[108]
    HexTable1 = new string[109]
    HexTable2 = new string[108]
    ;create conversion table
    HexConvTable()
    ModStart()
    SetPersistentMCMPreset("persistence/settings")
endevent

event OnConfigOpen()
    PreviousSavedelay = Savedelay
    UnregisterForAllKeys()
endevent

event OnPageDraw()
    Playername = PlayerREF.GetBaseObject().GetName()
    ;left side
    SetCursorFillMode(TOP_TO_BOTTOM)
    AddHeaderOption(FONT_PRIMARY("Main Options"))
    AddToggleOptionST("ModEnableState", "Enable Mod", ModEnable)
    AddToggleOptionST("SaveprotectionState", "Enable Save Protection", Saveprotection)
    AddToggleOptionST("DisableAutoSaveState", "Disable Auto Save", DisableAutoSave)
    AddToggleOptionST("MSGSafeSaveState", "Enable Safe Save Notification", MSGSafeSave)
    AddSliderOptionST("SaveDelayState", "Time Between Saves (In Seconds): ", (savedelay))
    AddHeaderOption(FONT_PRIMARY("Immersive Save Options"))
    AddToggleOptionST("SleepToSaveState", "Sleep to Save", SleepToSave)
    AddToggleOptionST("StoneToSaveState", "Use Standing Stone to Save", StoneToSave)
    AddToggleOptionST("ShrineToSaveState", "Use God Shrine to Save", ShrineToSave)
    AddKeyMapOptionST("savekeyState", "Manual Save Shortcut", savekey)
    ; Right side
    SetCursorPosition(1)
    AddHeaderOption(FONT_PRIMARY("Hardcore Mode"))
    AddToggleOptionST("HardcoreModeState", "I'm Not a Milk Drinker", HardcoreMode)
    if HardcoreMode
        AddToggleOptionST("TrueHeroModeState", "Let Me Be a True Hero", TrueHeroMode)
        AddToggleOptionST("ImmersiveSaveState", "Immersive save are always allowed to load", ImmersiveSave)
    else
        AddToggleOptionST("TrueHeroModeState", "Let Me Be a True Hero", TrueHeroMode, OPTION_FLAG_DISABLED)
        AddToggleOptionST("ImmersiveSaveState", "Immersive save are always allowed to load", ImmersiveSave, OPTION_FLAG_DISABLED)
    endif
    AddSliderOptionST("QuitDelayState", "Delay (in seconds) Before Exit: ", (Quitdelay))
    AddHeaderOption(FONT_PRIMARY("Rotating Saves"))
    AddToggleOptionST("RotatingSaveState", "Enable Save Rotation", RotatingSave)
    AddToggleOptionST("IncludeManualSaveState", "Include Manual Save in Rotation", IncludeManualSave)
    AddSliderOptionST("RotatingSaveNbState", "Number of savegames to be preserved: ", (RotatingSaveNb))
    AddToggleOptionST("BypassCheckState", "Bypass Name/ID Check: ", (BypassCheck))
    AddHeaderOption(FONT_PRIMARY("Information "))
    if manualsave
        AddParagraph("Manual save performed " + (((Game.GetRealHoursPassed() - lastsavetimestamp) * 60) as int) + " minutes ago")
        AddParagraph("Will be allowed to load: " + previousloadstatus)
    elseif automaticsave
        AddParagraph("Automatic save performed " + (((Game.GetRealHoursPassed() - lastsavetimestamp) * 60) as int) + " minutes ago")
        AddParagraph("Will be allowed to load: " + previousloadstatus)
    elseif testsave
        AddParagraph("test save performed " + (((Game.GetRealHoursPassed() - lastsavetimestamp) * 60) as int) + " minutes ago")
        AddParagraph("Will be allowed to load: " + previousloadstatus)
    endif

    If GetIniBool("bSaveOnPause") || GetIniBool("bSaveOnTravel") || GetIniBool("bSaveOnWait") || GetIniBool("bSaveOnRest")
        AddParagraph(FONT_DANGER("Warning!"))
		AddParagraph(("Game save system enabled! Check your INI"))
	EndIf
    AddParagraph(FONT_INFO("Character Name :\n" + playername))

    if PlayerNamefromHex != "none" && PlayerNamefromHex != playername && !bypasscheck
        AddParagraph("Encoded Character Name read from file:\n" + PlayerNamefromHex,FONT_INFO())
        AddParagraph("Names mismatch, check your id or enable check bypass at your own risk",FONT_DANGER())
    elseif PlayerNamefromHex == playername
        AddParagraph("Encoded character name successfully checked",FONT_INFO())
    elseif bypasscheck
        AddParagraph("Encoded character name check disabled",FONT_DANGER())
    endif

    AddHeaderOption(FONT_PRIMARY("Maintenance"))
    AddTextOptionST("ReGeneratePlayerIDState", "", FONT_WARNING("Regenerate Player ID"))
    AddTextOptionST("GenerateTestSaveState", "", FONT_WARNING("Generate testing save"))
    AddToggleOptionST("DebugCheckState", "Enable Debug Notification", DebugCheck)
endevent


event OnVersionUpdate(int a_version)
    if CurrentVersion < 111 && a_version >= 111
        SleepToSave = false
    endif
    if CurrentVersion < 113 && a_version >= 113
        Saveperformed = false
    endif
    if CurrentVersion < 114 && a_version >= 114
        StoneToSave = false
        ShrineToSave = false
    endif
    if CurrentVersion < 115 && a_version >= 115
        DisableAutoSave = false
        ImmersiveSave = false
    endif
    Debug.Notification("Save System Overhaul 2 updating MCM Version " + Substring((a_version * 0.01) as string, 0, 4))
endevent

event OnConfigClose()
    If PlayerUpdatedOptions
        if modenable
            if PreviousSavedelay != Savedelay
                UnregisterForUpdate()
                RegisterForSingleUpdate(savedelay)
            endif
            UnregisterForAllKeys()
            if savekey != 1
                RegisterForKey(savekey)
            endif
            if HardcoreMode
                allowedtoload = false
            else
                allowedtoload = true
            endif
            if SleepToSave 
                RegisterForSleep()
            else
                UnRegisterForSleep()
            endif
            if StoneToSave || ShrineToSave
                RegisterForControl("Activate")
            elseif !ShrineToSave && !StoneToSave
                UnregisterForAllControls()
            endif
        else
            UnregisterForUpdate()
            UnregisterForAllKeys()
            UnregisterForAllControls()
        endif
    endif
endevent

;mod event

Event OnKeyUp(Int KeyCode, Float HoldTime)
        if !keypressed
            if MSGSafeSave
                Debug.Notification("Save Request...")
            endif
            keypressed = true
            UnregisterForUpdate()
            GenerateSave(false)
        endif
endEvent

Event OnControlUp(string control, float HoldTime)
	If control == "Activate" && HoldTime >= 3.0
        If StoneToSave
            If Game.FindClosestReferenceOfAnyTypeInListFromRef(SSSO_DoomStoneList, PlayerRef, 350.0)
                if Immersivesave
                    keypressed = true
                endIf
		        GenerateSave(true)
            EndIf
        EndIf
        If ShrineToSave
            If Game.FindClosestReferenceOfAnyTypeInListFromRef(SSSO_ShrineLIST, PlayerRef, 350.0)
                if Immersivesave
                    keypressed = true
                endIf
		        GenerateSave(true)
            EndIf
        EndIf
	EndIf
EndEvent

Event OnSleepStop(bool abInterrupted)
	if !abInterrupted
        UnregisterForUpdate()
        GenerateSave(true)
	endIf
endEvent

event onupdate()
    If ModEnable && !Saveperformed && !DisableAutoSave
        GenerateSave(true)
    else
        Saveperformed = false
        if HardcoreMode
            allowedtoload = false
        endif
        RegisterForSingleUpdate(savedelay - 10)
    endif
EndEvent

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
	activity = true
EndEvent
;===============    STATES    ==========================================;
;main mode option
State ModEnableState
    event OnHighlightST(string state_id)
        SetInfoText("Enable / Disable save management")
    endevent

    event OnSelectST(string state_id)
        ModEnable = !ModEnable
        SetToggleOptionValueST(ModEnable, false, "ModEnableState")
    endevent
EndState

State SaveprotectionState
    event OnHighlightST(string state_id)
        SetInfoText("Enable / Disable safe check before saving")
    endevent

    event OnSelectST(string state_id)
        Saveprotection = !Saveprotection
        SetToggleOptionValueST(Saveprotection, false, "SaveprotectionState")
    endevent
EndState

State DisableAutoSaveState
    event OnHighlightST(string state_id)
        SetInfoText("Enable / Disable safe check before saving")
    endevent

    event OnSelectST(string state_id)
        DisableAutoSave = !DisableAutoSave
        SetToggleOptionValueST(DisableAutoSave, false, "DisableAutoSaveState")
    endevent
EndState

State MSGSafeSaveState
    event OnHighlightST(string state_id)
        SetInfoText("Enable / Disable safe save notificaiton")
    endevent

    event OnSelectST(string state_id)
        MSGSafeSave = !MSGSafeSave
        SetToggleOptionValueST(MSGSafeSave, false, "MSGSafeSaveState")
    endevent
EndState

state SaveDelayState
	event OnDefaultST(string state_id)
		savedelay = 300
	endevent

	event OnSliderOpenST(string state_id)
        SetSliderDialog(savedelay, 30.0, 1200.0, 60.0, 600)
	endevent
	
	event OnSliderAcceptST(string state_id, float f)
		savedelay = f as int
		SetSliderOptionValueST(f)
	endevent
endstate

State SleepToSaveState
    event OnHighlightST(string state_id)
        SetInfoText("A save will be made at wake-up (not interrupted)")
    endevent

    event OnSelectST(string state_id)
        SleepToSave = !SleepToSave
        SetToggleOptionValueST(SleepToSave, false, "SleepToSaveState")
    endevent
EndState

State StoneToSaveState
    event OnHighlightST(string state_id)
        SetInfoText("Pray at Standing Stone to save (Stand near and hold 'Activate' 3 secs)")
    endevent

    event OnSelectST(string state_id)
        StoneToSave = !StoneToSave
        SetToggleOptionValueST(StoneToSave, false, "StoneToSaveState")
    endevent
EndState

State ShrineToSaveState
    event OnHighlightST(string state_id)
        SetInfoText("Pray Gods to save (Stand near and hold 'Activate' 3 secs)")
    endevent

    event OnSelectST(string state_id)
        ShrineToSave = !ShrineToSave
        SetToggleOptionValueST(ShrineToSave, false, "ShrineToSaveState")
    endevent
EndState

state savekeyState
	event OnDefaultST(string state_id)
		savekey = 1
	endevent

	event OnHighlightST(string state_id)
		SetInfoText("Use this key to save instead of using game save system, if hardcore mode is enabled, game will exit after save complete.")
	endevent

	event OnKeyMapChangeST(string state_id, int keycode)
		savekey = keycode
		SetKeyMapOptionValueST(keycode)
	endevent
endstate

;rotating save
State RotatingSaveState
    event OnHighlightST(string state_id)
        SetInfoText("Enable / Disable rotating save system. Before enabling, don't forget to follow instruction from mod description page")
    endevent

    event OnSelectST(string state_id)
        RotatingSave = !RotatingSave
        if RotatingSave
            RegenID()
            if !RegenIDSuccess && !BypassCheck
                RotatingSave = false
                debug.messagebox("ID Check fail - rotating save disabled" )
            endif
        elseif RotatingSave && BypassCheck
            RegenID()
        endif
        SetToggleOptionValueST(RotatingSave, false, "RotatingSaveState")
    endevent
EndState

State IncludeManualSaveState
    event OnHighlightST(string state_id)
        SetInfoText("Save performed by pressing the shortcut will use a slot.")
    endevent

    event OnSelectST(string state_id)
        IncludeManualSave = !IncludeManualSave
        SetToggleOptionValueST(IncludeManualSave, false, "IncludeManualSaveState")
    endevent
EndState

State BypassCheckState
    event OnHighlightST(string state_id)
        SetInfoText("Bypass name check, use if system fail to confirm your character name or if you use a non latin set.")
    endevent

    event OnSelectST(string state_id)
        BypassCheck = !BypassCheck
        SetToggleOptionValueST(BypassCheck, false, "BypassCheckState")
        if BypassCheck
            RegenID()
        endif
    endevent
EndState

state RotatingSaveNbState
	event OnDefaultST(string state_id)
		RotatingSaveNb = 10
	endevent

	event OnSliderOpenST(string state_id)
        SetSliderDialog(RotatingSaveNb, 5.0, 20.0, 1.0, 10)
	endevent
	
	event OnSliderAcceptST(string state_id, float f)
		RotatingSavenb = f as int
		SetSliderOptionValueST(f)
	endevent
endstate
;hardcore mode
State HardcoreModeState
    event OnHighlightST(string state_id)
        SetInfoText("Enable I'm Not a Milk Drinker mode, check help for more explanation")
    endevent

    event OnSelectST(string state_id)
        HardcoreMode = !HardcoreMode
        SetToggleOptionValueST(HardcoreMode, true, "HardcoreModeState")
        if HardCoreMode
            allowedtoload = false
            SetOptionFlagsST(OPTION_FLAG_NONE, true, "TrueHeroModeState")
            SetOptionFlagsST(OPTION_FLAG_NONE, false, "ImmersiveSaveState")
        else
            allowedtoload = true
            SetOptionFlagsST(OPTION_FLAG_DISABLED, true, "TrueHeroModeState")
            SetOptionFlagsST(OPTION_FLAG_DISABLED, true, "ImmersiveSaveState")
            TrueHeroMode = false
            ImmersiveSave = false
            SetToggleOptionValueST(TrueHeroMode, true, "TrueHeroModeState")
            SetToggleOptionValueST(ImmersiveSave, false, "ImmersiveSaveState")
        endif
    endevent
EndState

State TrueHeroModeState
    event OnHighlightST(string state_id)
        SetInfoText("Enable Let Me Be a True Hero mode, check help for more explanation")
    endevent

    event OnSelectST(string state_id)
        TrueHeroMode = !TrueHeroMode
        SetToggleOptionValueST(TrueHeroMode, false, "TrueHeroModeState")
    endevent
EndState

State ImmersiveSaveState
    event OnHighlightST(string state_id)
        SetInfoText("Immersive save are not marked and can be load without using Safety Net")
    endevent

    event OnSelectST(string state_id)
        ImmersiveSave = !ImmersiveSave
        SetToggleOptionValueST(ImmersiveSave, false, "ImmersiveSaveState")
    endevent
EndState

state QuitdelayState
	event OnDefaultST(string state_id)
		Quitdelay = 15
	endevent

	event OnSliderOpenST(string state_id)
        SetSliderDialog(Quitdelay, 10.0, 60.0, 1.0, 15)
	endevent

    event OnHighlightST(string state_id)
        SetInfoText("Raise it if game quit when you reload a manual save")
    endevent
	
	event OnSliderAcceptST(string state_id, float f)
		Quitdelay = f as int
		SetSliderOptionValueST(f)
	endevent
endstate

state ReGeneratePlayerIDState
    event OnSelectST(string state_id)
        RegenID()
    endevent

    event OnHighlightST(string state_id)
        SetInfoText("Regenerate Player Unique ID - use at your own risk")
    endEvent
endstate

state GenerateTestSaveState
    event OnSelectST(string state_id)
        Debug.trace("--------SSSO:  Test save")
        ;Closing MCM
        CloseMCM(close_journal = true)
        GenerateSave(false,true)
    endevent

    event OnHighlightST(string state_id)
        SetInfoText("Generate save, use only for debug")
    endEvent
endstate

state SetUniqueHashState
	event OnHighlightST(string state_id)
		SetInfoText("Refers to description page to fill this properly")
	endevent

	event OnInputOpenST(string state_id)
		SetInputDialogStartText(UniqueHash)
	endevent
	
	event OnInputAcceptST(string state_id, string str)
		UniqueHash = str
	endevent
endstate

State DebugCheckState
    event OnHighlightST(string state_id)
        SetInfoText("Enable may debug messages")
    endevent

    event OnSelectST(string state_id)
        DebugCheck = !DebugCheck
        SetToggleOptionValueST(DebugCheck, false, "DebugCheckState")
    endevent
EndState
;===============    FUNCTIONS  ==========================================;
int function GetVersion()
    return 115
endfunction

function CheckRequirement()
    int nl_mcm_version = nl_mcm_globalinfo.CurrentVersion()
    if nl_mcm_version < 109
        Debug.messagebox("Your NL_MCM version ("+ nl_mcm_version + ") is outdated, Install last version !")
        return
    EndIf
    if !jcontainers.isInstalled()
		AddTextOptionST("preset_jcontainers", FONT_INFO("JContainers is not installed"), "", 0)
        Debug.messagebox("JContainer is missing, Install last version !")
	endif
endfunction

function ModStart()
    reset = true
    If ModEnable
        If !(GetIniBool("bSaveOnPause") || GetIniBool("bSaveOnTravel") || GetIniBool("bSaveOnWait") || GetIniBool("bSaveOnRest"))
            SetIniBool("bDisableAutoSave:SaveGame", True)
        EndIf
        if HardcoreMode
            allowedtoload = false
        else
            allowedtoload = true
        endif
        UnregisterForUpdate()
        Saveperformed = false
        RegisterForSingleUpdate(savedelay)
        UnregisterForAllKeys()
        if savekey != 1
            RegisterForKey(savekey)
        endif
        if HardcoreMode
            allowedtoload = false
        endif
        if SleepToSave
            RegisterForSleep()
        else
            UnRegisterForSleep()
        endif
        if StoneToSave || ShrineToSave
            RegisterForControl("Activate")
        elseif !ShrineToSave && !StoneToSave
            UnregisterForAllControls()
        endif
    EndIf
endfunction

function grantload()
    if quitdelay < 10
        quitdelay = 10
    endif
    if debugcheck
        debug.messagebox("Save Allowed to load " + allowedtoload)
    else
        debug.trace("--------SSSO: Allowedtoload variable status =" + allowedtoload)
    endif 
    if !allowedtoload && Game.GetModByName("IAmaMilkDrinker.esp") != 255
        debug.messagebox("Plugin detected - new save allowed to load will be generated soon, don't move")
        wait(20)
        debug.notification("Wait a little bit, Milk drinker!")
        wait(20)
        keypressed = true
        debug.messagebox("Milk Drinker, game will shutdown - don't forget to disable milkdrinker.esp plugin")
        wait(0.1)
        GenerateSave(false)
        wait(quitdelay)
        if Game.GetModByName("IAmaMilkDrinker.esp") != 255
            debug.trace("--------SSSO: Unauthorised savegame loaded, Bypass Plugin detected, loading granted, new authorised savegame generated, game exit now!")
            if debugcheck
                debug.messagebox("should quit!")
            else
                Debug.QuitGame()
            endif
        endif
    elseif !allowedtoload
        debug.messagebox("Embrass your Milk Drinker nature and activate the plugin to be allowed to load this save.")
        wait(0.1)
        debug.messagebox("Game will shut down")
        wait(0.1)
        debug.trace("--------SSSO: Unauthorised savegame loaded, Bypass Plugin not detected, game exit now!")
        if debugcheck
            debug.messagebox("should quit!")
        else
            Debug.QuitGame()
        endif
    elseif allowedtoload && Game.GetModByName("IAmaMilkDrinker.esp") != 255
        debug.messagebox("Plugin detected - please disable milkdrinker.esp")
        wait(0.1)
        debug.messagebox("Game will shut down")
        wait(0.1)
        debug.trace("--------SSSO: Authorised savegame loaded, Bypass Plugin detected, error, game exit now!")
        if debugcheck
            debug.messagebox("should quit!")
        else
            Debug.QuitGame()
        endif
    endif
    ModStart()
endfunction

function SafeCheck()
    if debugcheck
        debug.notification("Safe Script started")
    endif
    
    reset = false ; if this becomes true later, it means the game was loaded while the loop was running in which case it needs to break so that it's properly restarted by the event
	Int attempt = 0
	Int combatwait = 0
	Cell previouscell = None
	Int saveready = 0
	While saveready < 2
		previouscell = PlayerRef.GetParentCell()
		Wait(2 - saveready)
		If reset || !ModEnable ; if the user has manually set the Interval to less than 10 seconds (or uninstalled the mod!), this will stop the script
			Return
		EndIf
		If !PlayerRef.IsInCombat()
			combatwait = attempt ; restart for the next combat
		Else
			Wait(2) ; some additional wait because we're not particularly interested in saving during combat
		EndIf
		If	(PlayerRef.IsInCombat() && attempt < combatwait + 20) \
			|| PlayerRef.GetAnimationVariableFloat("Speed") > 400 * attempt * attempt / (attempt * attempt + 3000 + 3000 * PlayerRef.IsInCombat() as Int) \
			|| (PlayerRef.GetAnimationVariableBool("IsAttacking") || PlayerRef.GetAnimationVariableInt("iState") == 10 || PlayerRef.GetAnimationVariableInt("iWantBlock") || PlayerRef.GetAnimationVariableBool("bInJumpState") || PlayerRef.GetAnimationVariableBool("IsShouting")) \
			|| ((Game.GetCameraState() && Game.GetCameraState() < 9 || Game.GetCameraState() == 11) || (PlayerRef.GetAnimationVariableBool("bAnimationDriven") && !Game.IsCamSwitchControlsEnabled()) || PlayerRef.GetAnimationVariableBool("bIsSynced") || PlayerRef.GetAnimationVariableBool("IsEquipping") || PlayerRef.GetAnimationVariableBool("IsUnequipping")) \
			|| UI.IsMenuOpen("Dialogue Menu") \
			|| PlayerRef.GetParentCell() != previouscell \
			|| activity
			; DO NOT SAVE WHILE in the first minute of combat since most combat CTDs usually happen in the first seconds where modded effects start applying
			; or while walking, even if slowly -- especially during combat, relaxing the condition as time goes by; saving while running is generally unsafe due to the changes it causes, but at some point "generally unsafe" becomes more safe than not saving at all
			; or blocking, bashing, jumping etc; it's generally safe to save during such events but its really annoying to autosave while the player is drawing their bow (iWantBlock checks all block states including bashing; iState is 10 when casting)
			; or cutting firewood, using a crafting menu, attempting to sit but not while actually sitting, bleeding, playing music and similar animations (bIsSynced is true when mounting/unmounting a horse or standing up from a chair); a save cannot be performed in such conditions and we would only reset our timer, thus creating large time gaps
			; or during dialogue for the same reason as above
			; or we were in a different cell a few seconds ago; autosaves performed during cell transitions are risky
			; or the player was hit (the activity boolean may be used for more purposes in new versions)
			saveready = 0
			attempt += 1
			activity = false
		Else
			saveready += 1
		EndIf
	EndWhile
    if debugcheck
        debug.notification("Safe Script end")
    endif
endfunction

function GenerateSave(bool autosave, bool special = false)
    loading = false
    Saveperformed = true
    ;debug
    if debugcheck
        debug.trace("-------------SSSO Generate save -------------")
        debug.trace("loading " + loading)
        debug.trace("special " + special)
        debug.trace("autosave " + autosave)
        debug.trace("keypressed " + keypressed)
        debug.trace("allowedtoload " + allowedtoload)
        debug.trace("HardcoreMode " + HardcoreMode)
        debug.trace("TrueHeroMode " + TrueHeroMode)
    endif
    UnregisterForAllKeys()
    if Saveprotection
        SafeCheck()
    endif

    if special && TrueHeroMode
        debug.trace("--------SSSO: Test save in TrueHero mode - not allowed to load")
        allowedtoload = false
        manualsave = false
        automaticsave = false
        testsave = true
    elseif special
        debug.trace("--------SSSO: Test save - allowed to load")
        allowedtoload = true
        manualsave = false
        automaticsave = false
        testsave = true
    elseif keypressed && autosave
        debug.trace("--------SSSO: Immersive Save - allowed to load")
        allowedtoload = true
        manualsave = true
        automaticsave = false
        testsave = false
        keypressed = false
    elseif keypressed
        debug.trace("--------SSSO: Save by pressing key - allowed to load")
        allowedtoload = true
        manualsave = true
        automaticsave = false   
        testsave = false
    elseif !HardcoreMode
        debug.trace("--------SSSO: Save with hardcore mode disabled - allowed to load")
        manualsave = false
        automaticsave = true
        allowedtoload = true
        testsave = false
    elseif HardcoreMode && TrueHeroMode && autosave
        debug.trace("--------SSSO: Save auto in TrueHero mode - not allowed to load")
        manualsave = false
        automaticsave = true
        allowedtoload = false
        testsave = false
    elseif HardcoreMode && autosave
        debug.trace("--------SSSO: Save auto hardcore mode - allowed to load")
        manualsave = false
        automaticsave = true
        allowedtoload = true
        testsave = false
    elseif HardcoreMode ; maybe useless as save are performed only with auto or keypress
        debug.trace("--------SSSO: Save in hardcore mode - not allowed to load")
        manualsave = false
        automaticsave = true
        allowedtoload = false
        testsave = false
    endif

    lastsavetimestamp = (Game.GetRealHoursPassed())
    previousloadstatus = allowedtoload
    if debugcheck
        debug.trace("--------SSSO: Allowed to load: " + allowedtoload)
    endif
    
    if RotatingSave && autosave || RotatingSave && IncludeManualSave
        if Saveindex > RotatingSavenb
            Saveindex = 1
        endif
        ;Building save name

        string savename = ("Save" + SaveIndex + "_"+ UniqueHash +"_Rotate_0000" + SaveIndex + "_20220621142000_1_1")
        Debug.trace("--------SSSO: Game will be saved under: " + savename)
        if MSGSafeSave && !autosave
            Debug.Notification("Manual SafeSaving...")
        elseif MSGSafeSave && autosave
            Debug.Notification("Auto SafeSaving...")
        endif
        if keypressed && HardcoreMode && !autosave
            debug.messagebox("You have chosen to return to the real world... Wait until the game quits completely, your progress will be saved.")
            wait(0.1)
        endif
        ;increasing index
        SaveIndex += 1
        game.savegame(savename)
    else
        if keypressed && HardcoreMode && !autosave
            debug.messagebox("You have chosen to return to the real world... Wait until the game quits completely, your progress will be saved.")
            wait(0.1)
        endif
        Game.RequestSave()
    endif
    if keypressed && HardcoreMode && !autosave
        if quitdelay < 10
            quitdelay = 10
        endif
        wait(quitdelay)
    endif
    if debugcheck
        debug.trace("-------------SSSO boot check -------------")
        debug.trace("loading " + loading)
        debug.trace("special " + special)
        debug.trace("autosave " + autosave)
        debug.trace("keypressed " + keypressed)
        debug.trace("allowedtoload " + allowedtoload)
        debug.trace("HardcoreMode " + HardcoreMode)
        debug.trace("TrueHeroMode " + TrueHeroMode)
    endif
    if !loading
        if keypressed && HardcoreMode && !autosave
                if debugcheck
                    debug.messagebox("should quit!")
                    keypressed = false
                else
                    debug.notification("Bye bye")
                    debug.trace("--------SSSO: Hardcore mode enabled, Manual Save issued, game exit now!")
                    wait(1)
                    Debug.QuitGame()
                endif
            return
        endif
        reset = true
        UnregisterForAllKeys() 
        if keypressed
            Wait(10) ; prevent too frequent use of expedited saves (this won't be triggered by MCM changes)
        endif
        if savekey != 1
            RegisterForKey(savekey)
        endif
    endif
    keypressed = false
    RegisterForSingleUpdate(10)
endfunction

function RegenID()
    parseIDConfig()
    String UniqueHashTemp = SetID()
    debug.trace("============= SSSO Player ID ReGeneration start =============")
    if BypassCheck
        UniqueHash = UniqueHashTemp
        RegenIDSuccess = true
    else
        debug.trace("Unique profile hash is :" + UniqueHashTemp)
        int Hexnamestart = (Find(UniqueHashTemp,"_", (Find(UniqueHashTemp,"_") + 1)) +1) 
        String hexname = Substring(UniqueHashTemp,Hexnamestart)
        debug.trace("Player Hexname is :" + hexname)
        PlayerNamefromHex = convertHextoASCII(Hexname)
        debug.trace("Player name from Hex is :" + PlayerNamefromHex)
        If Playername == PlayerNamefromHex
            debug.trace("Names Match - UniqueHash Updated")
            UniqueHash = UniqueHashTemp
            RegenIDSuccess = true
        Else
            debug.trace("Names Mismatch - Abort")
            RegenIDSuccess = false
        EndIf
    endif
    ForcePageReset()
    debug.trace("============= SSSO Player ID ReGeneration stop =============")
endfunction

string function SetID()
    return JDB.solveStr(".ProfileID.information" + ".ID")
endfunction

function parseIDConfig()
    int config
    if BypassCheck
        config = JValue.readFromFile("Data/SSSOConf/bypass.txt")
    else
        config = JValue.readFromFile("Data/SSSOConf/" + Playername + ".txt")
    endif
    JDB.setObj("ProfileID", config)
endfunction

string function convertHextoASCII(string Hexname)
    Int iHex = GetLength(Hexname)
    Int i = 0
    String name
    while i < iHex
        string Hex= GetNthChar(Hexname,(i)) + GetNthChar(Hexname,i + 1)
        Int table = 1
        Int index = ArrayHasString(HexTable1,Hex)
        if index == -1
            table = 2
            index = ArrayHasString(HexTable2,Hex)
        EndIf
        If table == 1
            name = name + ASCIITable1[index]
        else
            name = name + ASCIITable2[index]
        EndIf
        i +=2
    endwhile
    return name
endfunction


int function ArrayHasString(String[] akMyArray, String asMyString) global
    int i = 0
    while i < akMyArray.Length
        if akMyArray[i] == asMyString
            return i
        else
            i += 1
        endif
    endWhile
    return -1
endFunction

function HexConvTable()
    ;Fill ASCII Caracther Array
    ASCIITable1[0]=" " ;Space
    ASCIITable1[1]="!" ;Exclamation mark
    ASCIITable1[2]="\"" ;Double quote
    ASCIITable1[3]="#" ;Number
    ASCIITable1[4]="$" ;Dollar
    ASCIITable1[5]="%" ;Percent
    ASCIITable1[6]="&" ;Ampersand
    ASCIITable1[7]="'" ;Single quote
    ASCIITable1[8]="(" ;Left parenthesis
    ASCIITable1[9]=")" ;Right parenthesis
    ASCIITable1[10]="*" ;Asterisk
    ASCIITable1[11]="+" ;Plus
    ASCIITable1[12]="," ;Comma
    ASCIITable1[13]="-" ;Minus
    ASCIITable1[14]="." ;Period
    ASCIITable1[15]="/" ;Slash
    ASCIITable1[16]="0" ;Zero
    ASCIITable1[17]="1" ;One
    ASCIITable1[18]="2" ;Two
    ASCIITable1[19]="3" ;Three
    ASCIITable1[20]="4" ;Four
    ASCIITable1[21]="5" ;Five
    ASCIITable1[22]="6" ;Six
    ASCIITable1[23]="7" ;Seven
    ASCIITable1[24]="8" ;Eight
    ASCIITable1[25]="9" ;Nine
    ASCIITable1[26]=":" ;Colon
    ASCIITable1[27]=";" ;Semicolon
    ASCIITable1[28]="<" ;Less than
    ASCIITable1[29]="=" ;Equal sign
    ASCIITable1[30]=">" ;Greater than
    ASCIITable1[31]="?" ;Question mark
    ASCIITable1[32]="@" ;At sign
    ASCIITable1[33]="A" ;Uppercase A
    ASCIITable1[34]="B" ;Uppercase B
    ASCIITable1[35]="C" ;Uppercase C
    ASCIITable1[36]="D" ;Uppercase D
    ASCIITable1[37]="E" ;Uppercase E
    ASCIITable1[38]="F" ;Uppercase F
    ASCIITable1[39]="G" ;Uppercase G
    ASCIITable1[40]="H" ;Uppercase H
    ASCIITable1[41]="I" ;Uppercase I
    ASCIITable1[42]="J" ;Uppercase J
    ASCIITable1[43]="K" ;Uppercase K
    ASCIITable1[44]="L" ;Uppercase L
    ASCIITable1[45]="M" ;Uppercase M
    ASCIITable1[46]="N" ;Uppercase N
    ASCIITable1[47]="O" ;Uppercase O
    ASCIITable1[48]="P" ;Uppercase P
    ASCIITable1[49]="Q" ;Uppercase Q
    ASCIITable1[50]="R" ;Uppercase R
    ASCIITable1[51]="S" ;Uppercase S
    ASCIITable1[52]="T" ;Uppercase T
    ASCIITable1[53]="U" ;Uppercase U
    ASCIITable1[54]="V" ;Uppercase V
    ASCIITable1[55]="W" ;Uppercase W
    ASCIITable1[56]="X" ;Uppercase X
    ASCIITable1[57]="Y" ;Uppercase Y
    ASCIITable1[58]="Z" ;Uppercase Z
    ASCIITable1[59]="[" ;Left square bracket
    ASCIITable1[60]="\\" ;backslash
    ASCIITable1[61]="]" ;Right square bracket
    ASCIITable1[62]="^" ;Caret / circumflex
    ASCIITable1[63]="_" ;Underscore
    ASCIITable1[64]="`" ;Grave / accent
    ASCIITable1[65]="a" ;Lowercase a
    ASCIITable1[66]="b" ;Lowercase b
    ASCIITable1[67]="c" ;Lowercase c
    ASCIITable1[68]="d" ;Lowercase d
    ASCIITable1[69]="e" ;Lowercase e
    ASCIITable1[70]="f" ;Lowercase
    ASCIITable1[71]="g" ;Lowercase g
    ASCIITable1[72]="h" ;Lowercase h
    ASCIITable1[73]="i" ;Lowercase i
    ASCIITable1[74]="j" ;Lowercase j
    ASCIITable1[75]="k" ;Lowercase k
    ASCIITable1[76]="l" ;Lowercase l
    ASCIITable1[77]="m" ;Lowercase m
    ASCIITable1[78]="n" ;Lowercase n
    ASCIITable1[79]="o" ;Lowercase o
    ASCIITable1[80]="p" ;Lowercase p
    ASCIITable1[81]="q" ;Lowercase q
    ASCIITable1[82]="r" ;Lowercase r
    ASCIITable1[83]="s" ;Lowercase s
    ASCIITable1[84]="t" ;Lowercase t
    ASCIITable1[85]="u" ;Lowercase u
    ASCIITable1[86]="v" ;Lowercase v
    ASCIITable1[87]="w" ;Lowercase w
    ASCIITable1[88]="x" ;Lowercase x
    ASCIITable1[89]="y" ;Lowercase y
    ASCIITable1[90]="z" ;Lowercase z
    ASCIITable1[91]="{" ;Left curly bracket
    ASCIITable1[92]="|" ;Vertical bar
    ASCIITable1[93]="}" ;Right curly bracket
    ASCIITable1[94]="~" ;Tilde
    ASCIITable1[96]="€" ;Euro sign
    ASCIITable1[97]="‚" ;Single low-9 quotation mark
    ASCIITable1[98]="ƒ" ;Latin small letter f with hook
    ASCIITable1[99]="„" ;Double low-9 quotation mark
    ASCIITable1[100]="…" ;Horizontal ellipsis
    ASCIITable1[101]="†" ;Dagger
    ASCIITable1[102]="‡" ;Double dagger
    ASCIITable1[103]="ˆ" ;Modifier letter circumflex accent
    ASCIITable1[104]="‰" ;Per mille sign
    ASCIITable1[105]="Š" ;Latin capital letter S with caron
    ASCIITable1[106]="‹" ;Single left-pointing angle quotation
    ASCIITable1[107]="Œ" ;Latin capital ligature OE
    ASCIITable1[108]="Ž" ;Latin capital letter Z with caron

    ;Split array to stay under 128

    ASCIITable2[0]="‘" ;Left single quotation mark
    ASCIITable2[1]="’" ;Right single quotation mark
    ASCIITable2[2]="“" ;Left double quotation mark
    ASCIITable2[3]="”" ;Right double quotation mark
    ASCIITable2[4]="•" ;Bullet
    ASCIITable2[5]="–" ;En dash
    ASCIITable2[6]="—" ;Em dash
    ASCIITable2[7]="˜" ;Small tilde
    ASCIITable2[8]="™" ;Trademark sign
    ASCIITable2[9]="š" ;Latin small letter S with caron
    ASCIITable2[10]="›" ;Single right-pointing angle quotation mark
    ASCIITable2[11]="œ" ;Latin small ligature oe
    ASCIITable2[12]="ž" ;Latin small letter z with caron
    ASCIITable2[13]="Ÿ" ;Latin capital letter Y with diaeresis
    ASCIITable2[15]="¡" ;Inverted exclamation mark
    ASCIITable2[16]="¢" ;Cent sign
    ASCIITable2[17]="£" ;Pound sign
    ASCIITable2[18]="¤" ;Currency sign
    ASCIITable2[19]="¥" ;Yen sign
    ASCIITable2[20]="¦" ;Pipe, broken vertical bar
    ASCIITable2[21]="§" ;Section sign
    ASCIITable2[22]="¨" ;Spacing diaeresis - umlaut
    ASCIITable2[23]="©" ;Copyright sign
    ASCIITable2[24]="ª" ;Feminine ordinal indicator
    ASCIITable2[25]="«" ;Left double angle quotes
    ASCIITable2[26]="¬" ;Not sign
    ASCIITable2[27]="¯" ;Spacing macron - overline
    ASCIITable2[28]="°" ;Degree sign
    ASCIITable2[29]="±" ;Plus-or-minus sign
    ASCIITable2[30]="²" ;Superscript two - squared
    ASCIITable2[31]="³" ;Superscript three - cubed
    ASCIITable2[32]="´" ;Acute accent - spacing acute
    ASCIITable2[33]="µ" ;Micro sign
    ASCIITable2[34]="¶" ;Pilcrow sign - paragraph sign
    ASCIITable2[35]="·" ;Middle dot - Georgian comma
    ASCIITable2[36]="¸" ;Spacing cedilla
    ASCIITable2[37]="¹" ;Superscript one
    ASCIITable2[38]="º" ;Masculine ordinal indicator
    ASCIITable2[39]="»" ;Right double angle quotes
    ASCIITable2[40]="¼" ;Fraction one quarter
    ASCIITable2[41]="½" ;Fraction one half
    ASCIITable2[42]="¾" ;Fraction three quarters
    ASCIITable2[43]="¿" ;Inverted question mark
    ASCIITable2[44]="À" ;Latin capital letter A with grave
    ASCIITable2[45]="Á" ;Latin capital letter A with acute
    ASCIITable2[46]="Â" ;Latin capital letter A with circumflex
    ASCIITable2[47]="Ã" ;Latin capital letter A with tilde
    ASCIITable2[48]="Ä" ;Latin capital letter A with diaeresis
    ASCIITable2[49]="Å" ;Latin capital letter A with ring above
    ASCIITable2[50]="Æ" ;Latin capital letter AE
    ASCIITable2[51]="Ç" ;Latin capital letter C with cedilla
    ASCIITable2[52]="È" ;Latin capital letter E with grave
    ASCIITable2[53]="É" ;Latin capital letter E with acute
    ASCIITable2[54]="Ê" ;Latin capital letter E with circumflex
    ASCIITable2[55]="Ë" ;Latin capital letter E with diaeresis
    ASCIITable2[56]="Ì" ;Latin capital letter I with grave
    ASCIITable2[57]="Í" ;Latin capital letter I with acute
    ASCIITable2[58]="Î" ;Latin capital letter I with circumflex
    ASCIITable2[59]="Ï" ;Latin capital letter I with diaeresis
    ASCIITable2[60]="Ð" ;Latin capital letter ETH
    ASCIITable2[61]="Ñ" ;Latin capital letter N with tilde
    ASCIITable2[62]="Ò" ;Latin capital letter O with grave
    ASCIITable2[63]="Ó" ;Latin capital letter O with acute
    ASCIITable2[64]="Ô" ;Latin capital letter O with circumflex
    ASCIITable2[65]="Õ" ;Latin capital letter O with tilde
    ASCIITable2[66]="Ö" ;Latin capital letter O with diaeresis
    ASCIITable2[67]="×" ;Multiplication sign
    ASCIITable2[68]="Ø" ;Latin capital letter O with slash
    ASCIITable2[69]="Ù" ;Latin capital letter U with grave
    ASCIITable2[70]="Ú" ;Latin capital letter U with acute
    ASCIITable2[71]="Û" ;Latin capital letter U with circumflex
    ASCIITable2[72]="Ü" ;Latin capital letter U with diaeresis
    ASCIITable2[73]="Ý" ;Latin capital letter Y with acute
    ASCIITable2[74]="Þ" ;Latin capital letter THORN
    ASCIITable2[75]="ß" ;Latin small letter sharp s - ess-zed
    ASCIITable2[76]="à" ;Latin small letter a with grave
    ASCIITable2[77]="á" ;Latin small letter a with acute
    ASCIITable2[78]="â" ;Latin small letter a with circumflex
    ASCIITable2[79]="ã" ;Latin small letter a with tilde
    ASCIITable2[80]="ä" ;Latin small letter a with diaeresis
    ASCIITable2[81]="å" ;Latin small letter a with ring above
    ASCIITable2[82]="æ" ;Latin small letter ae
    ASCIITable2[83]="ç" ;Latin small letter c with cedilla
    ASCIITable2[84]="è" ;Latin small letter e with grave
    ASCIITable2[85]="é" ;Latin small letter e with acute
    ASCIITable2[86]="ê" ;Latin small letter e with circumflex
    ASCIITable2[87]="ë" ;Latin small letter e with diaeresis
    ASCIITable2[88]="ì" ;Latin small letter i with grave
    ASCIITable2[89]="í" ;Latin small letter i with acute
    ASCIITable2[90]="î" ;Latin small letter i with circumflex
    ASCIITable2[91]="ï" ;Latin small letter i with diaeresis
    ASCIITable2[92]="ð" ;Latin small letter eth
    ASCIITable2[93]="ñ" ;Latin small letter n with tilde
    ASCIITable2[94]="ò" ;Latin small letter o with grave
    ASCIITable2[95]="ó" ;Latin small letter o with acute
    ASCIITable2[96]="ô" ;Latin small letter o with circumflex
    ASCIITable2[97]="õ" ;Latin small letter o with tilde
    ASCIITable2[98]="ö" ;Latin small letter o with diaeresis
    ASCIITable2[99]="÷" ;Division sign
    ASCIITable2[100]="ø" ;Latin small letter o with slash
    ASCIITable2[101]="ù" ;Latin small letter u with grave
    ASCIITable2[102]="ú" ;Latin small letter u with acute
    ASCIITable2[103]="û" ;Latin small letter u with circumflex
    ASCIITable2[104]="ü" ;Latin small letter u with diaeresis
    ASCIITable2[105]="ý" ;Latin small letter y with acute
    ASCIITable2[106]="þ" ;Latin small letter thorn
    ASCIITable2[107]="ÿ" ;Latin small letter y with diaeresis
    
    ; Fill Hex Table

    HexTable1[0]="20" ;Space
    HexTable1[1]="21" ;Exclamation mark
    HexTable1[2]="22" ;Double quote
    HexTable1[3]="23" ;Number
    HexTable1[4]="24" ;Dollar
    HexTable1[5]="25" ;Percent
    HexTable1[6]="26" ;Ampersand
    HexTable1[7]="27" ;Single quote
    HexTable1[8]="28" ;Left parenthesis
    HexTable1[9]="29" ;Right parenthesis
    HexTable1[10]="2A" ;Asterisk
    HexTable1[11]="2B" ;Plus
    HexTable1[12]="2C" ;Comma
    HexTable1[13]="2D" ;Minus
    HexTable1[14]="2E" ;Period
    HexTable1[15]="2F" ;Slash
    HexTable1[16]="30" ;Zero
    HexTable1[17]="31" ;One
    HexTable1[18]="32" ;Two
    HexTable1[19]="33" ;Three
    HexTable1[20]="34" ;Four
    HexTable1[21]="35" ;Five
    HexTable1[22]="36" ;Six
    HexTable1[23]="37" ;Seven
    HexTable1[24]="38" ;Eight
    HexTable1[25]="39" ;Nine
    HexTable1[26]="3A" ;Colon
    HexTable1[27]="3B" ;Semicolon
    HexTable1[28]="3C" ;Less than
    HexTable1[29]="3D" ;Equal sign
    HexTable1[30]="3E" ;Greater than
    HexTable1[31]="3F" ;Question mark
    HexTable1[32]="40" ;At sign
    HexTable1[33]="41" ;Uppercase A
    HexTable1[34]="42" ;Uppercase B
    HexTable1[35]="43" ;Uppercase C
    HexTable1[36]="44" ;Uppercase D
    HexTable1[37]="45" ;Uppercase E
    HexTable1[38]="46" ;Uppercase F
    HexTable1[39]="47" ;Uppercase G
    HexTable1[40]="48" ;Uppercase H
    HexTable1[41]="49" ;Uppercase I
    HexTable1[42]="4A" ;Uppercase J
    HexTable1[43]="4B" ;Uppercase K
    HexTable1[44]="4C" ;Uppercase L
    HexTable1[45]="4D" ;Uppercase M
    HexTable1[46]="4E" ;Uppercase N
    HexTable1[47]="4F" ;Uppercase O
    HexTable1[48]="50" ;Uppercase P
    HexTable1[49]="51" ;Uppercase Q
    HexTable1[50]="52" ;Uppercase R
    HexTable1[51]="53" ;Uppercase S
    HexTable1[52]="54" ;Uppercase T
    HexTable1[53]="55" ;Uppercase U
    HexTable1[54]="56" ;Uppercase V
    HexTable1[55]="57" ;Uppercase W
    HexTable1[56]="58" ;Uppercase X
    HexTable1[57]="59" ;Uppercase Y
    HexTable1[58]="5A" ;Uppercase Z
    HexTable1[59]="5B" ;Left square bracket
    HexTable1[60]="5C" ;backslash
    HexTable1[61]="5D" ;Right square bracket
    HexTable1[62]="5E" ;Caret / circumflex
    HexTable1[63]="5F" ;Underscore
    HexTable1[64]="60" ;Grave / accent
    HexTable1[65]="61" ;Lowercase a
    HexTable1[66]="62" ;Lowercase b
    HexTable1[67]="63" ;Lowercase c
    HexTable1[68]="64" ;Lowercase d
    HexTable1[69]="65" ;Lowercase e
    HexTable1[70]="66" ;Lowercase
    HexTable1[71]="67" ;Lowercase g
    HexTable1[72]="68" ;Lowercase h
    HexTable1[73]="69" ;Lowercase i
    HexTable1[74]="6A" ;Lowercase j
    HexTable1[75]="6B" ;Lowercase k
    HexTable1[76]="6C" ;Lowercase l
    HexTable1[77]="6D" ;Lowercase m
    HexTable1[78]="6E" ;Lowercase n
    HexTable1[79]="6F" ;Lowercase o
    HexTable1[80]="70" ;Lowercase p
    HexTable1[81]="71" ;Lowercase q
    HexTable1[82]="72" ;Lowercase r
    HexTable1[83]="73" ;Lowercase s
    HexTable1[84]="74" ;Lowercase t
    HexTable1[85]="75" ;Lowercase u
    HexTable1[86]="76" ;Lowercase v
    HexTable1[87]="77" ;Lowercase w
    HexTable1[88]="78" ;Lowercase x
    HexTable1[89]="79" ;Lowercase y
    HexTable1[90]="7A" ;Lowercase z
    HexTable1[91]="7B" ;Left curly bracket
    HexTable1[92]="7C" ;Vertical bar
    HexTable1[93]="7D" ;Right curly bracket
    HexTable1[94]="7E" ;Tilde
    HexTable1[96]="80" ;Euro sign
    HexTable1[97]="82" ;Single low-9 quotation mark
    HexTable1[98]="83" ;Latin small letter f with hook
    HexTable1[99]="84" ;Double low-9 quotation mark
    HexTable1[100]="85" ;Horizontal ellipsis
    HexTable1[101]="86" ;Dagger
    HexTable1[102]="87" ;Double dagger
    HexTable1[103]="88" ;Modifier letter circumflex accent
    HexTable1[104]="89" ;Per mille sign
    HexTable1[105]="8A" ;Latin capital letter S with caron
    HexTable1[106]="8B" ;Single left-pointing angle quotation
    HexTable1[107]="8C" ;Latin capital ligature OE
    HexTable1[108]="8E" ;Latin capital letter Z with caron
    HexTable2[0]="91" ;Left single quotation mark
    HexTable2[1]="92" ;Right single quotation mark
    HexTable2[2]="93" ;Left double quotation mark
    HexTable2[3]="94" ;Right double quotation mark
    HexTable2[4]="95" ;Bullet
    HexTable2[5]="96" ;En dash
    HexTable2[6]="97" ;Em dash
    HexTable2[7]="98" ;Small tilde
    HexTable2[8]="99" ;Trademark sign
    HexTable2[9]="9A" ;Latin small letter S with caron
    HexTable2[10]="9B" ;Single right-pointing angle quotation mark
    HexTable2[11]="9C" ;Latin small ligature oe
    HexTable2[12]="9E" ;Latin small letter z with caron
    HexTable2[13]="9F" ;Latin capital letter Y with diaeresis
    HexTable2[15]="A1" ;Inverted exclamation mark
    HexTable2[16]="A2" ;Cent sign
    HexTable2[17]="A3" ;Pound sign
    HexTable2[18]="A4" ;Currency sign
    HexTable2[19]="A5" ;Yen sign
    HexTable2[20]="A6" ;Pipe, broken vertical bar
    HexTable2[21]="A7" ;Section sign
    HexTable2[22]="A8" ;Spacing diaeresis - umlaut
    HexTable2[23]="A9" ;Copyright sign
    HexTable2[24]="AA" ;Feminine ordinal indicator
    HexTable2[25]="AB" ;Left double angle quotes
    HexTable2[26]="AC" ;Not sign
    HexTable2[27]="AF" ;Spacing macron - overline
    HexTable2[28]="B0" ;Degree sign
    HexTable2[29]="B1" ;Plus-or-minus sign
    HexTable2[30]="B2" ;Superscript two - squared
    HexTable2[31]="B3" ;Superscript three - cubed
    HexTable2[32]="B4" ;Acute accent - spacing acute
    HexTable2[33]="B5" ;Micro sign
    HexTable2[34]="B6" ;Pilcrow sign - paragraph sign
    HexTable2[35]="B7" ;Middle dot - Georgian comma
    HexTable2[36]="B8" ;Spacing cedilla
    HexTable2[37]="B9" ;Superscript one
    HexTable2[38]="BA" ;Masculine ordinal indicator
    HexTable2[39]="BB" ;Right double angle quotes
    HexTable2[40]="BC" ;Fraction one quarter
    HexTable2[41]="BD" ;Fraction one half
    HexTable2[42]="BE" ;Fraction three quarters
    HexTable2[43]="BF" ;Inverted question mark
    HexTable2[44]="C0" ;Latin capital letter A with grave
    HexTable2[45]="C1" ;Latin capital letter A with acute
    HexTable2[46]="C2" ;Latin capital letter A with circumflex
    HexTable2[47]="C3" ;Latin capital letter A with tilde
    HexTable2[48]="C4" ;Latin capital letter A with diaeresis
    HexTable2[49]="C5" ;Latin capital letter A with ring above
    HexTable2[50]="C6" ;Latin capital letter AE
    HexTable2[51]="C7" ;Latin capital letter C with cedilla
    HexTable2[52]="C8" ;Latin capital letter E with grave
    HexTable2[53]="C9" ;Latin capital letter E with acute
    HexTable2[54]="CA" ;Latin capital letter E with circumflex
    HexTable2[55]="CB" ;Latin capital letter E with diaeresis
    HexTable2[56]="CC" ;Latin capital letter I with grave
    HexTable2[57]="CD" ;Latin capital letter I with acute
    HexTable2[58]="CE" ;Latin capital letter I with circumflex
    HexTable2[59]="CF" ;Latin capital letter I with diaeresis
    HexTable2[60]="D0" ;Latin capital letter ETH
    HexTable2[61]="D1" ;Latin capital letter N with tilde
    HexTable2[62]="D2" ;Latin capital letter O with grave
    HexTable2[63]="D3" ;Latin capital letter O with acute
    HexTable2[64]="D4" ;Latin capital letter O with circumflex
    HexTable2[65]="D5" ;Latin capital letter O with tilde
    HexTable2[66]="D6" ;Latin capital letter O with diaeresis
    HexTable2[67]="D7" ;Multiplication sign
    HexTable2[68]="D8" ;Latin capital letter O with slash
    HexTable2[69]="D9" ;Latin capital letter U with grave
    HexTable2[70]="DA" ;Latin capital letter U with acute
    HexTable2[71]="DB" ;Latin capital letter U with circumflex
    HexTable2[72]="DC" ;Latin capital letter U with diaeresis
    HexTable2[73]="DD" ;Latin capital letter Y with acute
    HexTable2[74]="DE" ;Latin capital letter THORN
    HexTable2[75]="DF" ;Latin small letter sharp s - ess-zed
    HexTable2[76]="E0" ;Latin small letter a with grave
    HexTable2[77]="E1" ;Latin small letter a with acute
    HexTable2[78]="E2" ;Latin small letter a with circumflex
    HexTable2[79]="E3" ;Latin small letter a with tilde
    HexTable2[80]="E4" ;Latin small letter a with diaeresis
    HexTable2[81]="E5" ;Latin small letter a with ring above
    HexTable2[82]="E6" ;Latin small letter ae
    HexTable2[83]="E7" ;Latin small letter c with cedilla
    HexTable2[84]="E8" ;Latin small letter e with grave
    HexTable2[85]="E9" ;Latin small letter e with acute
    HexTable2[86]="EA" ;Latin small letter e with circumflex
    HexTable2[87]="EB" ;Latin small letter e with diaeresis
    HexTable2[88]="EC" ;Latin small letter i with grave
    HexTable2[89]="ED" ;Latin small letter i with acute
    HexTable2[90]="EE" ;Latin small letter i with circumflex
    HexTable2[91]="EF" ;Latin small letter i with diaeresis
    HexTable2[92]="F0" ;Latin small letter eth
    HexTable2[93]="F1" ;Latin small letter n with tilde
    HexTable2[94]="F2" ;Latin small letter o with grave
    HexTable2[95]="F3" ;Latin small letter o with acute
    HexTable2[96]="F4" ;Latin small letter o with circumflex
    HexTable2[97]="F5" ;Latin small letter o with tilde
    HexTable2[98]="F6" ;Latin small letter o with diaeresis
    HexTable2[99]="F7" ;Division sign
    HexTable2[100]="F8" ;Latin small letter o with slash
    HexTable2[101]="F9" ;Latin small letter u with grave
    HexTable2[102]="FA" ;Latin small letter u with acute
    HexTable2[103]="FB" ;Latin small letter u with circumflex
    HexTable2[104]="FC" ;Latin small letter u with diaeresis
    HexTable2[105]="FD" ;Latin small letter y with acute
    HexTable2[106]="FE" ;Latin small letter thorn
    HexTable2[107]="FF" ;Latin small letter y with diaeresis
endfunction


Int function SaveData()
    Int jObj = JMap.object()
    jmap.SetInt(jObj, "ModEnable", ModEnable as int)
    jmap.SetInt(jObj, "Saveprotection", Saveprotection as int)
    jmap.SetInt(jObj, "MSGSafeSave", MSGSafeSave as int)
    jmap.SetInt(jObj, "Savedelay", Savedelay as int)
    jmap.SetInt(jObj, "savekey", savekey as int)
    jmap.SetInt(jObj, "RotatingSave", RotatingSave as int)
    jmap.SetInt(jObj, "IncludeManualSave", IncludeManualSave as int)
    jmap.SetInt(jObj, "RotatingSaveNb", RotatingSaveNb as int)
    jmap.SetInt(jObj, "HardcoreMode", HardcoreMode as int)
    jmap.SetInt(jObj, "TrueHeroMode", TrueHeroMode as int)
    jmap.SetInt(jObj, "Quitdelay", Quitdelay as int)
    jmap.SetInt(jObj, "SleepToSave", SleepToSave as int)
    jmap.SetInt(jObj, "StoneToSave", StoneToSave as int)
    jmap.SetInt(jObj, "ShrineToSave", ShrineToSave as int)
    return jObj
endFunction

function LoadData(Int jObj)
    ModEnable = (jmap.getInt(jObj, "ModEnable") as bool)
    Saveprotection = (jmap.getInt(jObj, "Saveprotection") as bool)
    MSGSafeSave = (jmap.getInt(jObj, "MSGSafeSave") as bool)
    Savedelay = (jmap.getInt(jObj, "Savedelay", 300))
    savekey = (jmap.getInt(jObj, "savekey", 1))
    RotatingSave = ((jmap.getInt(jObj, "RotatingSave") as bool))
    IncludeManualSave = ((jmap.getInt(jObj, "IncludeManualSave") as bool))
    RotatingSaveNb = (jmap.getInt(jObj, "RotatingSaveNb", 10))
    HardcoreMode = (jmap.getInt(jObj, "HardcoreMode") as bool)
    TrueHeroMode = (jmap.getInt(jObj, "TrueHeroMode") as bool)
    Quitdelay = (jmap.getInt(jObj, "Quitdelay", 15))
    SleepToSave = (jmap.getInt(jObj, "SleepToSave") as bool)
    StoneToSave = (jmap.getInt(jObj, "StoneToSave") as bool)
    ShrineToSave = (jmap.getInt(jObj, "ShrineToSave") as bool)
    RegisterForKey(savekey)
endFunction