diff --git a/mod/Hardcore Helper.esp b/mod/Hardcore Helper.esp new file mode 100644 index 0000000..0c8e6af Binary files /dev/null and b/mod/Hardcore Helper.esp differ diff --git a/mod/Hardcore Helper.url b/mod/Hardcore Helper.url new file mode 100644 index 0000000..9109b66 --- /dev/null +++ b/mod/Hardcore Helper.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://mod.pub/falloutnv/5-hardcore-helper diff --git a/src/EHHGameMode.gek b/src/EHHGameMode.gek new file mode 100644 index 0000000..227bf6e --- /dev/null +++ b/src/EHHGameMode.gek @@ -0,0 +1,215 @@ +scn EHHGameMode + +int i +ref rItem +ref rSelectedFood +ref rAquaPura +int iEffectNum +int iEffectIndex +int iCachedPenalty +int iCurrentPenalty +int iLowestPenalty +int iValue +int bNeedDrink +int bNeedFood +int iHunger +int bPPInfected +array_var aInventoryItems + +begin function {} + + if playerRef.IsHardcore == 0 + return + endif + + if EHHAutoDrink + + if eval (playerRef.GetAV Dehydration > GetHardcoreStageThreshold Water1 - EHHThresholdOffset) && (playerRef.HasMagicEffect RestoreDehydrationLevel == 0) + + let bNeedDrink := 1 + + let i := 0 + while rItem := ListGetNthForm EHHDrinks i + if playerRef.GetItemCount rItem + MessageEx "Drinking %n..." rItem + playerRef.EquipItem rItem 0 1 + let bNeedDrink := 0 + break + endif + let i += 1 + loop + + if bNeedDrink == 0 + return + endif + + if EHHBrokenSteel + let rAquaPura := GetFormFromMod "BrokenSteel.esm" "104F" + if playerRef.GetItemCount rAquaPura + let bPPInfected := GetStageDone (GetFormFromMod "Fallout3.esm" "14E93") 100 + if bPPInfected == 0 + MessageEx "Drinking %n..." rAquaPura + playerRef.EquipItem rAquaPura 0 1 + return + endif + endif + endif + + ; Try other options + let bNeedDrink := EHHEatWateryFood + + endif + + endif + + if EHHAutoEat + let iHunger := playerRef.GetAV hunger + let bNeedFood := (iHunger > GetHardcoreStageThreshold hunger1 - EHHThresholdOffset) && (playerRef.HasMagicEffect RestoreStarvationLevel == 0) + endif + + if bNeedDrink || bNeedFood + + let aInventoryItems := playerRef.GetAllItems 47 1 1 1 + let i := ar_size aInventoryItems + let iLowestPenalty := -1 + + while (i -= 1) >= 0 + let rItem := aInventoryItems[i] + + if eval (GetEquipType rItem != 12 && GetEquipType rItem != 0) || 0 == GetIngestibleFlag rItem 2 || GetIngestibleFlag rItem 4 ; skip non-food and medicine + continue + endif + + if ListGetFormIndex EHHDrinks rItem != -1 + continue + endif + + let iCurrentPenalty := 0 + let iEffectNum := GetNumEffects rItem + + if bNeedFood + let iEffectIndex := -1 + while (iEffectIndex += 1) < iEffectNum + if GetNthEffectBase rItem iEffectIndex == RestoreStarvationLevel + let iValue := GetNthEffectTraitNumeric rItem iEffectIndex 0 + let iCurrentPenalty += 1000 - iValue + if iHunger < iValue + let iCurrentPenalty += 500 + endif + break + endif + loop + endif + + if bNeedDrink + if bPPInfected + if rItem == rAquaPura + continue + endif + endif + let iEffectIndex := -1 + while (iEffectIndex += 1) < iEffectNum + if GetNthEffectBase rItem iEffectIndex == RestoreDehydrationLevel + let iCurrentPenalty += 1000 - GetNthEffectTraitNumeric rItem iEffectIndex 0 + break + endif + loop + endif + + if iCurrentPenalty == 0 + continue + endif + + ; Cache item ratings for the game session + if RefMapGetType "*r" rItem + let iCurrentPenalty += RefMapGetFlt "*r" rItem + else + let iCachedPenalty := 0 + let iEffectIndex := -1 + while (iEffectIndex += 1) < iEffectNum + if GetNthEffectBase rItem iEffectIndex == DamageRadiationLevel + let iValue = GetNthEffectTraitNumeric rItem iEffectIndex 0 + let iCachedPenalty += iValue * 5 + if iValue >= 10 + ; push irradiated items down + let iCachedPenalty += 1000 + endif + break + endif + loop + + let iCachedPenalty += Ceil (GetValueAlt rItem) + let iCachedPenalty -= 5 * Ceil (GetWeight rItem) + + if ListGetFormIndex WaterLIST rItem == -1 + if eval 0 < ar_size (GetFormRecipes rItem) + ; push ingredients down + let iCachedPenalty += 10000 + endif + endif + + RefMapSetFlt "*r" iCachedPenalty rItem + let iCurrentPenalty += iCachedPenalty + endif + +; printc "%n=%g" rItem iCurrentPenalty + + if EHHEatIngredients == 0 + if iCurrentPenalty >= 10000 + continue + endif + endif + + if iLowestPenalty == -1 || iCurrentPenalty < iLowestPenalty + let iLowestPenalty := iCurrentPenalty + let rSelectedFood := rItem + endif + + loop + +; print "=================================" + let aInventoryItems := ar_null + + if rSelectedFood + if eval ListGetFormIndex NonAlchoholicDrinks rSelectedFood != -1 || ListGetFormIndex WaterLIST rSelectedFood != -1 + MessageEx "Drinking %n..." rSelectedFood + else + MessageEx "Eating %n..." rSelectedFood + endif + playerRef.EquipItem rSelectedFood 0 1 + return + endif + + endIf + + if EHHAutoRadAway + + if eval (playerRef.GetAV RadiationRads > GetHardcoreStageThreshold Rad1 - EHHThresholdOffset) && (playerRef.HasMagicEffect RestoreRadiationLevel == 0) + if playerRef.GetItemCount RadAway + MessageEx "Injecting RadAway..." + playerRef.EquipItem RadAway 0 1 + return + endif + endif + + endif + + if EHHAutoUppers + + if eval (playerRef.GetAV SleepDeprevation > GetHardcoreStageThreshold sleep1 - EHHThresholdOffset) && (playerRef.HasMagicEffect RestoreSleepDeprivationLevel == 0) + + let i := 0 + while rItem := ListGetNthForm EHHUppers i + if playerRef.GetItemCount rItem + MessageEx "Time to get some sleep! Meanwhile, consuming %n..." rItem + playerRef.EquipItem rItem 0 1 + break + endif + let i += 1 + loop + + endif + + endif + +end diff --git a/src/EHHMenuMode1013.gek b/src/EHHMenuMode1013.gek new file mode 100644 index 0000000..a41eb8b --- /dev/null +++ b/src/EHHMenuMode1013.gek @@ -0,0 +1,90 @@ +scn EHHMenuMode1013 + +int isEnabled +int iOption +float fValue + +begin function {} + + if GetUIFloat "StartMenu/MCM/_Reset" ; RESET + + if PlayerRef.IsHardcore + let isEnabled := 1 + else + let isEnabled := 2 + endif + + SetUIFloat "StartMenu/MCM/_Reset" 0 + SetUIFloat "StartMenu/MCM/*:1/_columns" 2 + + SetMCMFloat 1 1 "_enable" isEnabled + SetMCMString 1 1 "_title" "Automatic eating" + SetMCMFloat 1 1 "_type" 5 + SetMCMFloat 1 1 "_value" EHHAutoEat + + SetMCMFloat 1 2 "_enable" isEnabled + SetMCMString 1 2 "_title" "Eat ingredients" + SetMCMFloat 1 2 "_type" 5 + SetMCMFloat 1 2 "_value" EHHEatIngredients + + SetMCMFloat 1 3 "_enable" isEnabled + SetMCMString 1 3 "_title" "Automatic drinking" + SetMCMFloat 1 3 "_type" 5 + SetMCMFloat 1 3 "_value" EHHAutoDrink + + SetMCMFloat 1 4 "_enable" isEnabled + SetMCMString 1 4 "_title" "Quench thirst with food" + SetMCMFloat 1 4 "_type" 5 + SetMCMFloat 1 4 "_value" EHHEatWateryFood + + SetMCMFloat 1 5 "_enable" isEnabled + SetMCMString 1 5 "_title" "Automatic RadAway" + SetMCMFloat 1 5 "_type" 5 + SetMCMFloat 1 5 "_value" EHHAutoRadAway + + SetMCMFloat 1 7 "_enable" isEnabled + SetMCMString 1 7 "_title" "Automatic uppers" + SetMCMFloat 1 7 "_type" 5 + SetMCMFloat 1 7 "_value" EHHAutoUppers + + if isEnabled == 2 + SetMCMFloat 1 11 "_enable" 1 + SetMCMString 1 11 "_title" "Hardcore mode disabled" + SetMCMFloat 1 11 "_type" 0 + endif + + elseif GetUIFloat "StartMenu/MCM/_NewValue" ; NEW VALUE + + set iOption to GetUIFloat "StartMenu/MCM/_ActiveOption" + set fValue to GetUIFloat "StartMenu/MCM/_Value" + + SetUIFloat "StartMenu/MCM/_NewValue" 0 + SetUIFloat "StartMenu/MCM/_Reset" 1 + + if iOption == 1 + set EHHAutoEat to fValue + elseif iOption == 2 + set EHHEatIngredients to fValue + elseif iOption == 3 + set EHHAutoDrink to fValue + elseif iOption == 4 + set EHHEatWateryFood to fValue + elseif iOption == 5 + set EHHAutoRadAway to fValue + elseif iOption == 7 + set EHHAutoUppers to fValue + endif + + endif + + if GetUIFloat "StartMenu/MCM/*:1/_optionID" == 2 + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + SetUIString "StartMenu/MCM/*:9/string" "If unchecked, items, included in any recipe, won't be eaten automatically." + elseif GetUIFloat "StartMenu/MCM/*:1/_optionID" == 4 + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + SetUIString "StartMenu/MCM/*:9/string" "Some food items also hydrate in addition to satiation. This option allows to eat such food when you have no water in inventory." + elseif GetUIFloat "StartMenu/MCM/*:9/visible" == 1 + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + +end diff --git a/src/EHHMenuMode4.gek b/src/EHHMenuMode4.gek new file mode 100644 index 0000000..548624a --- /dev/null +++ b/src/EHHMenuMode4.gek @@ -0,0 +1,55 @@ +scn EHHMenuMode4 + +ref rItem + +begin function {} + + SetGameMainLoopCallback EHHGameMode 1 800 1 + + ; Fixing vanilla bugs + SetIngestibleFlag MS05FinNukaPie 2 1 + SetIngestibleFlag StrangeMeatPie 2 1 + + let EHHBrokenSteel := IsModLoaded "BrokenSteel.esm" + + if EHHBrokenSteel + set rItem to GetFormFromMod "BrokenSteel.esm" "6F62" ; Aqua Cura + if IsFormValid rItem + if ListGetFormIndex EHHDrinks rItem == -1 + ListAddForm EHHDrinks rItem 0 + endif + endif + endif + + if IsModLoaded "HonestHearts.esm" + let rItem := GetFormFromMod "HonestHearts.esm" "11112" ; Black Coffee + if IsFormValid rItem + if ListGetFormIndex EHHUppers rItem == -1 + ListAddForm EHHUppers rItem 0 + endif + endif + endif + + if IsModLoaded "TaleOfTwoWastelands.esm" + let rItem := GetFormFromMod "TaleOfTwoWastelands.esm" "DFC2" ; Spicy Quantum Sauce + if IsFormValid rItem + if ListGetFormIndex EHHUppers rItem == -1 + ListAddForm EHHUppers rItem + endif + endif + endif + + if IsModLoaded "The Mod Configuration Menu.esp" == 0 + print "Hardcore Helper: MCM not found" + return + endif + + ListAddForm (BuildRef (GetModIndex "The Mod Configuration Menu.esp") 2790) EHHMCMItem + + SetOnMenuOpenEventHandler (begin function {int i} + if GetQuestRunning EHHQuest == 0 + StartQuest EHHQuest + endif + end) 1 1013 + +end diff --git a/src/EHHQuestScript.gek b/src/EHHQuestScript.gek new file mode 100644 index 0000000..8d3bc09 --- /dev/null +++ b/src/EHHQuestScript.gek @@ -0,0 +1,39 @@ +scn EHHQuestScript + +begin GameMode + StopQuest EHHQuest +end + +begin MenuMode 4 + + StopQuest EHHQuest + + if GetGameRestarted == 0 + return + endif + + if GetNVSEVersionFull < 6.22 + MessageBoxEx "Hardcore Helper requires xNVSE 6.22+." + endif + + if GetPluginVersion "JIP LN NVSE" < 56.31 + MessageBoxEx "Hardcore Helper requires JIP LN 56.31+." + endif + + call EHHMenuMode4 + +end + +begin MenuMode 1013 + + if GetUIFloat "StartMenu/MCM/_ActiveMod" != GetSelfModIndex + return + endif + + if GetUIFloat "StartMenu/MCM/_ActiveMenu" != GetItemValue EHHMCMItem + return + endif + + call EHHMenuMode1013 + +end