diff --git a/mod/Unfound Loot.esp b/mod/Unfound Loot.esp new file mode 100644 index 0000000..fbafa34 Binary files /dev/null and b/mod/Unfound Loot.esp differ diff --git a/mod/Unfound Loot.url b/mod/Unfound Loot.url new file mode 100644 index 0000000..d976917 --- /dev/null +++ b/mod/Unfound Loot.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://mod.pub/falloutnv/24-unfound-loot diff --git a/src/EULxCalculateBaseRemovalChance.gek b/src/EULxCalculateBaseRemovalChance.gek new file mode 100644 index 0000000..1dd806e --- /dev/null +++ b/src/EULxCalculateBaseRemovalChance.gek @@ -0,0 +1,93 @@ +scn EULxCalculateBaseRemovalChance + +ref rActor +float fRemovalChance +int iTemp +float fTemp + +begin function { rActor } + + set fRemovalChance to EULxActorBaseRemovalChance / 100 + + DebugPrint "Base removal chance for %n: %.2f" rActor fRemovalChance + + + ; Luck factor + + set fTemp to (( EULxLuckModifier / 10 ) * playerRef.getAV luck) / 100 + set fTemp to 1 - fTemp + set fRemovalChance to fRemovalChance * fTemp + + DebugPrint "Base removal chance (luck factored in) : %.2f" fRemovalChance + + + ; Creature type factor + + set iTemp to rActor.GetCreatureType + + if iTemp == -1 ; NPC + + if rActor.GetIsRace Ghoul + DebugPrint "Target is intelligent ghoul" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorGhoulMod + else + DebugPrint "Target is human" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorHumanMod + endif + + else + + set fTemp to 0 + + if iTemp == 5 + DebugPrint "Target is lootless (feral ghoul or other)" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorFeralGhoulMod + elseif iTemp == 4 ; supermutant + DebugPrint "Target is mutant" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorSupermutantMod + elseif iTemp == 6 ; robot + DebugPrint "Target is robot" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorRobotMod + set fTemp to playerRef.getAV repair + else + DebugPrint "Target is butcherable (insect, animal, abomination)" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorAnimalMod + set fTemp to playerRef.getAV survival + endif + + ; Skill factor + + if fTemp + if EULxActorSkillMod + set fTemp to EULxActorSkillMod * fTemp / 1000 ;0 = no effect, 0.5 = half as likely item removal, 1 = no item removal + set fTemp to 1 - fTemp + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance fTemp + endif + endif + + endif + + DebugPrint "Base removal chance (creature/npc type and player skills factored in) : %.2f" fRemovalChance + + + ; Limb damage factor (unfortunately, available only after killed NPC ends ragdolling) + +; set iTemp to 14 +; set fTemp to 0 ; num severed limbs +; while iTemp > -1 +; set iTemp to iTemp - 1 +; if rActor.isLimbGone iTemp +; set fTemp to fTemp + 1 +; DebugPrint "%n's limb %g is gone." rActor iTemp +; endif +; loop +; +; set fTemp to 1 + (fTemp * 0.5) +; set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance fTemp +; +; DebugPrint "Base removal chance (corpse limb damage factored in) : %.2f" fRemovalChance + + + SetFunctionValue fRemovalChance + +end \ No newline at end of file diff --git a/src/EULxDelootifyCellItems.gek b/src/EULxDelootifyCellItems.gek new file mode 100644 index 0000000..6fdfe07 --- /dev/null +++ b/src/EULxDelootifyCellItems.gek @@ -0,0 +1,213 @@ +scn EULxDelootifyCellItems + +ref rCell +ref rItem +int iType +int iEquipType +ref rBase +long iValue +long iCount +float fCount +float fRemovalChance + +begin function { rCell } + + DebugPrint "Scanning cell %n for removable items" rCell + + set rItem to GetFirstRefInCell rCell 201 0 0 + + while rItem + + set rBase to rItem.GetBaseForm + set iType to GetType rBase + + if iType == 31 ; misc + if rBase == Caps001 || rBase == PrewarMoney + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + set fRemovalChance to EULxCalcMiscRemovalChance + endif + elseif iType == 47 ; ingestible + + if ListGetFormIndex EULxProtectedItemsFood rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + set rItem to getNextRef + continue + endif + + set iEquipType to GetEquipType rBase + + if iEquipType == 11 || GetIngestibleFlag rBase 4 ; meds + set fRemovalChance to EULxCalcMedsRemovalChance + elseif iEquipType == 10 ; chems + set fRemovalChance to EULxCalcChemsRemovalChance + elseif iEquipType == 13 ; alcohol + set fRemovalChance to EULxCalcAlcoholRemovalChance + else ; food + set fRemovalChance to EULxCalcFoodRemovalChance + endif + + elseif iType == 41 ; ammo + set fRemovalChance to EULxCalcAmmoRemovalChance + elseif iType == 40 ; weapon + set fRemovalChance to EULxCalcWeaponRemovalChance + elseif iType == 24 ; armor + + if ListGetFormIndex EULxProtectedItemsArmor rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + set rItem to getNextRef + continue + endif + + set fRemovalChance to EULxCalcArmorRemovalChance + elseif iType == 116 ; currency + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + set rItem to GetNextRef + continue + endif + + if IsQuestItem rBase + DebugPrint "%n is a quest item, skipping." rBase + set rItem to getNextRef + continue + endif + + if iType == 40 || iType == 24 ; weapons and armor + call EULxReduceItemHealth playerRef rItem + endif + + if rItem.GetDisabled + DebugPrint "%n is disabled, skipping." rBase + set rItem to getNextRef + continue + endif + + if rItem.GetReferenceFlag 33554432 + DebugPrint "%n has the No AI Acquire flag, skipping." rItem + set rItem to getNextRef + continue + endif + + if rItem.GetOwner + DebugPrint "%n is an owned item, skipping." rBase + set rItem to getNextRef + continue + endif + + set iValue to GetSourceModIndex rBase + + if iValue > GetSourceModIndex rItem + + DebugPrint "%n is a mod-added item, added via ref override, skipping." rBase + + set rItem to getNextRef + continue + + elseif iValue > EULxDLCIndex ; Mod-added base + if GetSourceModIndex rBase != GetSourceModIndex rCell ; Different origin from the cell (same would mean new area or DLC - normal processing) + if GetSourceModIndex rItem != GetSourceModIndex rCell ; item placed by other mod + + ; Mod-added foreign base AND reference in a cell of any origin. Skip this. + ; Cells with matching base or item origin are processed normally. + + DebugPrint "%n is a mod-added item, skipping." rBase + + set rItem to getNextRef + continue + + endif + endif + endif + + set iValue to GetValue rBase + + if iType == 31 && rBase != Caps001 ; misc item + + if iValue < 5 + if iValue == 0 + DebugPrint "%n has zero value, skipping." rBase + set rItem to getNextRef + continue + endif + if GetWeight rBase + DebugPrint "%n is trash, cutting removal chance in half." rBase + set fRemovalChance to fRemovalChance / 2 + endif + endif + + if IsScripted rBase + DebugPrint "%n is scripted, skipping." rBase + set rItem to getNextRef + continue + endif + + if ListGetFormIndex EULxProtectedItemsMisc rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + set rItem to getNextRef + continue + endif + + endif + + if iValue > EULxMaxItemValue + DebugPrint "%n is an expensive item, skipping." rBase + set rItem to getNextRef + continue + endif + + if AuxiliaryVariableGetFloat "S" 0 rBase == 0 ; the item is encountered for the first time + DebugPrint "Adding %n to ever scanned list, should only see this once" rBase + AuxiliaryVariableSetFloat "S" 1 0 rBase + set rItem to getNextRef + continue + endif + + set iCount to rItem.GetRefCount + + if iCount > 1 ; Item stack + + DebugPrint "Found stack: %g %n, removal chance %g." iCount rBase fRemovalChance + + set fRemovalChance to Rand 0 fRemovalChance + + DebugPrint "Rolled a dice, removing %g%% from the stack." fRemovalChance + + set fCount to iCount * ( fRemovalChance / 100 ) + if Ceil fCount - fCount > 0.5 ; Number rounding implementation + set iCount to Floor fCount + else + set iCount to Ceil fCount + endif + + ; iCount items to remove + + set iValue to rItem.GetRefCount + set iCount to iValue - iCount + + ; iCount items to leave + + if iCount <= 0 + DebugPrint "Disabling full stack of %g %n." iValue rBase + rItem.disable + rItem.MarkForDelete + elseif iCount < iValue + DebugPrint "Reducing stack of %g %n to %g items." iValue rBase iCount + rItem.SetRefCount iCount + else + DebugPrint "Stack of %g %n, removal chance 0, skipping." iValue rBase + endif + + elseif GetRandomPercent < fRemovalChance + + DebugPrint "Disabling %n." rBase + rItem.disable + rItem.MarkForDelete + + endif + + set rItem to GetNextRef + + loop + +end \ No newline at end of file diff --git a/src/EULxDelootifyContainer.gek b/src/EULxDelootifyContainer.gek new file mode 100644 index 0000000..139e7b2 --- /dev/null +++ b/src/EULxDelootifyContainer.gek @@ -0,0 +1,168 @@ +scn EULxDelootifyContainer + +ref rCell +ref rContainer +ref rItem +int iType +int iEquipType +ref rBase +int i +int iLimit +long iValue +long iCount +float fCount +float fRemovalChance +array_var itemsToRemoveRefs +array_var itemsToRemoveCounts + +begin function { rCell, rContainer } + + DebugPrint "Delootifying %n..." rContainer + + foreach rItem <- rContainer + + set rBase to rItem.GetBaseForm + set iType to GetType rBase + + DebugPrint "Scanning %n: found %n" rContainer rBase + + if iType == 31 ; misc + if rBase == Caps001 || rBase == PrewarMoney + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + set fRemovalChance to EULxCalcMiscRemovalChance + endif + elseif iType == 47 ; ingestible + + if ListGetFormIndex EULxProtectedItemsFood rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + set iEquipType to GetEquipType rBase + + if iEquipType == 11 || GetIngestibleFlag rBase 4 ; meds + set fRemovalChance to EULxCalcMedsRemovalChance + elseif iEquipType == 10 ; chems + set fRemovalChance to EULxCalcChemsRemovalChance + elseif iEquipType == 13 ; alcohol + set fRemovalChance to EULxCalcAlcoholRemovalChance + else ; food + set fRemovalChance to EULxCalcFoodRemovalChance + endif + + elseif iType == 41 ; ammo + set fRemovalChance to EULxCalcAmmoRemovalChance + elseif iType == 40 ; weapon + set fRemovalChance to EULxCalcWeaponRemovalChance + elseif iType == 24 ; armor + + if ListGetFormIndex EULxProtectedItemsArmor rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + set fRemovalChance to EULxCalcArmorRemovalChance + elseif iType == 116 ; currency + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + DebugPrint "%n is non-removable, type %g." rBase iType + continue + endif + + if IsQuestItem rBase + DebugPrint "%n is a quest item, skipping." rBase + continue + endif + + if iType == 24 || iType == 40 ; weapons and armor + call EULxReduceItemHealth rContainer rItem + endif + + set iValue to GetValue rBase + + if iType == 31 && rBase != Caps001 ; misc item + + if iValue < 5 + if iValue == 0 + DebugPrint "%n has zero value, skipping." rBase + continue + endif + if GetWeight rBase > 0 + DebugPrint "%n is trash, cutting removal chance in half." rBase + set fRemovalChance to fRemovalChance / 2 + endif + endif + + if IsScripted rBase + DebugPrint "%n is scripted, skipping." rBase + continue + endif + + if ListGetFormIndex EULxProtectedItemsMisc rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + endif + + if iValue > EULxMaxItemValue + DebugPrint "%n value exceeds maximum, skipping." rBase + continue + endif + + if AuxiliaryVariableGetFloat "S" 0 rBase == 0 ; the item is encountered for the first time + DebugPrint "Adding %n to ever scanned list, should only see this once" rBase + AuxiliaryVariableSetFloat "S" 1 0 rBase + continue + endif + + set iCount to rItem.GetRefCount + DebugPrint "Found %g %n(s) in %n." iCount rBase rContainer + + if iCount > 1 + if iType != 41 && rBase != Caps001 ; do not apply random removal to ammo and caps + set fRemovalChance to Rand 0 fRemovalChance + endif + set fCount to iCount * ( fRemovalChance / 100 ) + if Ceil fCount - fCount > 0.5 ; Number rounding implementation + set iCount to Floor fCount + else + set iCount to Ceil fCount + endif + DebugPrint "Removing %g of %n, removal chance %.2f." iCount rBase fRemovalChance + elseif GetRandomPercent >= fRemovalChance + DebugPrint "%n was skipped because due to removal chance %.2f." rBase fRemovalChance + continue + endif + + if iCount > 0 + ; RemoveMeIR and variations cause CTD here. + + if itemsToRemoveRefs == 0 + let itemsToRemoveRefs := ar_construct "array" + let itemsToRemoveCounts := ar_construct "array" + endif + + ar_append itemsToRemoveRefs rBase + ar_append itemsToRemoveCounts iCount + else + DebugPrint "%n was skipped because due to removal chance %.2f." rBase fRemovalChance + endif + loop + + set i to 0 + set iLimit to ar_size itemsToRemoveRefs + + while i < iLimit + let rBase := itemsToRemoveRefs[i] + let iCount := itemsToRemoveCounts[i] + DebugPrint "Removing %g of %n from %n" iCount rBase rContainer + rContainer.RemoveItem rBase iCount 1 + set i to i + 1 + loop + + let itemsToRemoveRefs := ar_null + let itemsToRemoveCounts := ar_null + +end \ No newline at end of file diff --git a/src/EULxDelootifyNPC.gek b/src/EULxDelootifyNPC.gek new file mode 100644 index 0000000..6c94c34 --- /dev/null +++ b/src/EULxDelootifyNPC.gek @@ -0,0 +1,257 @@ +scn EULxDelootifyNPC + +ref rNPC +ref rItem +int iType +int iEquipType +ref rBase +long iValue + +float fBasefRemovalChance +float fRemovalChance + +int i +int iLimit +array_var itemsToRemoveRefs +array_var itemsToRemoveCounts + +float fCount +int iCount + +int bDisintegrated + +begin function { rNPC, bDisintegrated } + + set fBasefRemovalChance to call EULxCalculateBaseRemovalChance rNPC + + if fBasefRemovalChance <= 0 + DebugPrint "Base removal chance for %n <= 0, skipping." rNPC + return + endif + + DebugPrint "Scanning %n's inventory." rNPC + + let itemsToRemoveRefs := ar_construct "array" + let itemsToRemoveCounts := ar_construct "array" + + foreach rItem <- rNPC + + set rBase to rItem.GetBaseForm + set iType to GetObjectType rBase + + if iType == 24 || iType == 40 || iType == 41 + + if IsPlayable rBase == 0 + DebugPrint "Skipping non-playable item: %n" rBase + continue + endif + + if iType == 24 ; armor + + if bDisintegrated == 0 + + call EULxReduceItemHealth rNPC rItem + + if rItem.IsEquipped + DebugPrint "Skipping equipped item in OnDying (IsEquipped): %n" rBase + continue + endif + + ; Sometimes, IsEquipped stops working, we fallback to GetEquipped + if rNPC.GetEquipped rBase + DebugPrint "Skipping equipped item in OnDying (GetEquipped): %n" rBase + continue + endif + + endif + + if ListGetFormIndex EULxProtectedItemsArmor rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + endif + + if iType == 40 && bDisintegrated == 0 + + call EULxReduceItemHealth rNPC rItem + + if EULxActorRemoveEquippedWeapons == 0 + if rItem.IsEquipped + DebugPrint "Skipping equipped item in OnDying (IsEquipped): %n" rBase + continue + endif + endif + + endif + + endif + + if iType == 46 + DebugPrint "Skipping key: %n" rItem + continue + endif + + if iType == 25 + DebugPrint "Skipping book: %n" rItem + continue + endif + + if iType == 49 + DebugPrint "Skipping note: %n" rItem + continue + endif + + if iType == 103 + DebugPrint "Skipping weapon mod: %n" rItem + continue + endif + + if iType == 108 + DebugPrint "Skipping casino chip: %n" rItem + continue + endif + + if iType == 115 + DebugPrint "Skipping caravan card: %n" rItem + continue + endif + + if IsQuestItem rBase + DebugPrint "Skipping quest item: %n" rBase + continue + endif + + if ListGetFormIndex EULxDeathItems rBase != -1 + DebugPrint "Skipping death item: %n" rBase + continue + endif + + set iValue to GetValue rBase + + if iType == 31 && rBase != Caps001 ; misc item + + if iValue < 5 + if iValue == 0 + DebugPrint "%n has zero value, skipping." rBase + continue + endif + if GetWeight rBase > 0 + DebugPrint "%n is trash, cutting removal chance in half." rBase + set fRemovalChance to fRemovalChance / 2 + endif + endif + + if IsScripted rBase + DebugPrint "%n is scripted, skipping." rBase + continue + endif + + if ListGetFormIndex EULxProtectedItemsMisc rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + endif + + if iValue > EULxMaxItemValue + DebugPrint "%n value exceeds max value, skipping." rBase + continue + endif + + if iType == 41 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorAmmoRemovalMod + elseif iType == 24 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorArmorRemovalMod + elseif iType == 40 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorWeaponRemovalMod + elseif iType == 116 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorCurrencyRemovalMod + elseif iType == 31 + if rBase == Caps001 || rBase == PrewarMoney + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorCurrencyRemovalMod + else + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorMiscRemovalMod + endif + elseif iType == 47 + if ListGetFormIndex EULxProtectedItemsFood rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + set iEquipType to GetEquipType rBase + + if iEquipType == 11 || GetIngestibleFlag rBase 4 ; meds + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorMedsRemovalMod + elseif iEquipType == 10 ; chems + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorChemsRemovalMod + elseif iEquipType == 13 ; alcohol + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorAlcoholRemovalMod + else + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorFoodRemovalMod + endif + else + continue + endif + + set fRemovalChance to fRemovalChance * 100 + + if fRemovalChance <= 0 + DebugPrint "Removal chance of %n is 0, skipping." rBase + continue + endif + + if bDisintegrated + set fRemovalChance to fRemovalChance * EULxActorDisintegratedMod + DebugPrint "%n has been disintegrated/gooified, setting removal chance to %.2f%%" rNPC fRemovalChance + endif + + set iCount to rItem.GetRefCount + + DebugPrint "Removal chance of %n: %g vs total in corpse %g" rBase fRemovalChance iCount + + if iCount > 1 + if iType != 41 && rBase != Caps001 ; do not apply random removal to ammo and caps + set fRemovalChance to Rand 0 fRemovalChance + endif + set fCount to iCount * ( fRemovalChance / 100 ) + if Ceil fCount - fCount > 0.5 ; Number rounding implementation + set iCount to Floor fCount + else + set iCount to Ceil fCount + endif + DebugPrint "Removing %g of %n, removal chance %g." iCount rBase fRemovalChance + elseif GetRandomPercent >= fRemovalChance + DebugPrint "%n was skipped." rBase + continue + endif + + if iCount > 0 + ar_Append itemsToRemoveRefs rBase + ar_Append itemsToRemoveCounts iCount + else + DebugPrint "%n was skipped." rBase + endif + loop + + printd "SCAN COMPLETE!" + + ; NB: The game will CTD if we remove items in the main loop. + + set i to 0 + set iLimit to ar_size itemsToRemoveRefs + + while i < iLimit + let rBase := itemsToRemoveRefs[i] + let iCount := itemsToRemoveCounts[i] + DebugPrint "Removing %g of %n from %n" iCount rBase rNPC + rNPC.removeItem rBase iCount 1 + set i to i + 1 + loop + + let itemsToRemoveRefs := ar_null + let itemsToRemoveCounts := ar_null + + printd "Corpse loot reduction block exited." + +end diff --git a/src/EULxINILoadSettings.gek b/src/EULxINILoadSettings.gek new file mode 100644 index 0000000..657b69a --- /dev/null +++ b/src/EULxINILoadSettings.gek @@ -0,0 +1,70 @@ +scn EULxINILoadSettings + +string_var sFile + +begin function {} + + if FileExists "config\Unfound Loot.ini" == 0 + MessageBoxEx "File Data\Config\Unfound Loot.ini was not found!" + return + endif + + if GetINIFloat "General:Saved" "Unfound Loot.ini" == 0 + MessageBoxEx "Unfound Loot.ini was not saved through the panel, won't reload." + return + endif + + let sFile := "Unfound Loot.ini" + + ; General + + set EULxMaxItemValue to GetINIFloat "General:MaxItemValue" $sFile + set EULxLuckModifier to GetINIFloat "General:LuckModifier" $sFile + set EULxMaxWeaponCondition to GetINIFloat "General:MaxWeaponCondition" $sFile + set EULxMaxArmorCondition to GetINIFloat "General:MaxArmorCondition" $sFile + + ; World + + set EULxWorldLootRemovalEnabled to GetINIFloat "World:LootRemovalEnabled" $sFile + set EULxWorldBaseRemovalChance to GetINIFloat "World:BaseRemovalChance" $sFile + set EULxWorldSkipLocked to GetINIFloat "World:SkipLocked" $sFile + + set EULxWorldWeaponRemovalMod to GetINIFloat "World:WeaponRemovalMod" $sFile + set EULxWorldAmmoRemovalMod to GetINIFloat "World:AmmoRemovalMod" $sFile + set EULxWorldArmorRemovalMod to GetINIFloat "World:ArmorRemovalMod" $sFile + set EULxWorldCurrencyRemovalMod to GetINIFloat "World:CurrencyRemovalMod" $sFile + set EULxWorldAlcoholRemovalMod to GetINIFloat "World:AlcoholRemovalMod" $sFile + set EULxWorldChemsRemovalMod to GetINIFloat "World:ChemsRemovalMod" $sFile + set EULxWorldMedsRemovalMod to GetINIFloat "World:MedsRemovalMod" $sFile + set EULxWorldFoodRemovalMod to GetINIFloat "World:FoodRemovalMod" $sFile + set EULxWorldMiscRemovalMod to GetINIFloat "World:MiscRemovalMod" $sFile + + ; Actors + + set EULxActorLootRemovalEnabled to GetINIFloat "Actors:LootRemovalEnabled" $sFile + set EULxActorBaseRemovalChance to GetINIFloat "Actors:BaseRemovalChance" $sFile + set EULxActorRemoveEquippedWeapons to GetINIFloat "Actors:RemoveEquippedWeapons" $sFile + set EULxActorBreakOnDecapitation to GetINIFloat "Actors:BreakOnDecapitation" $sFile + + set EULxActorWeaponRemovalMod to GetINIFloat "Actors:WeaponRemovalMod" $sFile + set EULxActorAmmoRemovalMod to GetINIFloat "Actors:AmmoRemovalMod" $sFile + set EULxActorArmorRemovalMod to GetINIFloat "Actors:ArmorRemovalMod" $sFile + set EULxActorCurrencyRemovalMod to GetINIFloat "Actors:CurrencyRemovalMod" $sFile + set EULxActorAlcoholRemovalMod to GetINIFloat "Actors:AlcoholRemovalMod" $sFile + set EULxActorChemsRemovalMod to GetINIFloat "Actors:ChemsRemovalMod" $sFile + set EULxActorMedsRemovalMod to GetINIFloat "Actors:MedsRemovalMod" $sFile + set EULxActorFoodRemovalMod to GetINIFloat "Actors:FoodRemovalMod" $sFile + set EULxActorMiscRemovalMod to GetINIFloat "Actors:MiscRemovalMod" $sFile + + set EULxActorAnimalMod to GetINIFloat "Actors:AnimalMod" $sFile + set EULxActorRobotMod to GetINIFloat "Actors:RobotMod" $sFile + set EULxActorFeralGhoulMod to GetINIFloat "Actors:FeralGhoulMod" $sFile + set EULxActorHumanMod to GetINIFloat "Actors:HumanMod" $sFile + set EULxActorGhoulMod to GetINIFloat "Actors:GhoulMod" $sFile + set EULxActorSupermutantMod to GetINIFloat "Actors:SupermutantMod" $sFile + + set EULxActorDisintegratedMod to GetINIFloat "Actors:DisintegratedMod" $sFile + + sv_destruct sFile + +end diff --git a/src/EULxINISaveSettings.gek b/src/EULxINISaveSettings.gek new file mode 100644 index 0000000..64ecbbe --- /dev/null +++ b/src/EULxINISaveSettings.gek @@ -0,0 +1,64 @@ +scn EULxINISaveSettings + +string_var sFile + +begin function {} + + let sFile := "Unfound Loot.ini" + + ; Control mark + + SetINIFloat "General:Saved" 1 $sFile + + ; General + + SetINIFloat "General:MaxItemValue" EULxMaxItemValue $sFile + SetINIFloat "General:LuckModifier" EULxLuckModifier $sFile + SetINIFloat "General:MaxWeaponCondition" EULxMaxWeaponCondition $sFile + SetINIFloat "General:MaxArmorCondition" EULxMaxArmorCondition $sFile + + ; World + + SetINIFloat "World:LootRemovalEnabled" EULxWorldLootRemovalEnabled $sFile + SetINIFloat "World:BaseRemovalChance" EULxWorldBaseRemovalChance $sFile + SetINIFloat "World:SkipLocked" EULxWorldSkipLocked $sFile + + SetINIFloat "World:WeaponRemovalMod" EULxWorldWeaponRemovalMod $sFile + SetINIFloat "World:AmmoRemovalMod" EULxWorldAmmoRemovalMod $sFile + SetINIFloat "World:ArmorRemovalMod" EULxWorldArmorRemovalMod $sFile + SetINIFloat "World:CurrencyRemovalMod" EULxWorldCurrencyRemovalMod $sFile + SetINIFloat "World:AlcoholRemovalMod" EULxWorldAlcoholRemovalMod $sFile + SetINIFloat "World:ChemsRemovalMod" EULxWorldChemsRemovalMod $sFile + SetINIFloat "World:MedsRemovalMod" EULxWorldMedsRemovalMod $sFile + SetINIFloat "World:FoodRemovalMod" EULxWorldFoodRemovalMod $sFile + SetINIFloat "World:MiscRemovalMod" EULxWorldMiscRemovalMod $sFile + + ; Actors + + SetINIFloat "Actors:LootRemovalEnabled" EULxActorLootRemovalEnabled $sFile + SetINIFloat "Actors:BaseRemovalChance" EULxActorBaseRemovalChance $sFile + SetINIFloat "Actors:RemoveEquippedWeapons" EULxActorRemoveEquippedWeapons $sFile + SetINIFloat "Actors:BreakOnDecapitation" EULxActorBreakOnDecapitation $sFile + + SetINIFloat "Actors:WeaponRemovalMod" EULxActorWeaponRemovalMod $sFile + SetINIFloat "Actors:AmmoRemovalMod" EULxActorAmmoRemovalMod $sFile + SetINIFloat "Actors:ArmorRemovalMod" EULxActorArmorRemovalMod $sFile + SetINIFloat "Actors:CurrencyRemovalMod" EULxActorCurrencyRemovalMod $sFile + SetINIFloat "Actors:AlcoholRemovalMod" EULxActorAlcoholRemovalMod $sFile + SetINIFloat "Actors:ChemsRemovalMod" EULxActorChemsRemovalMod $sFile + SetINIFloat "Actors:MedsRemovalMod" EULxActorMedsRemovalMod $sFile + SetINIFloat "Actors:FoodRemovalMod" EULxActorFoodRemovalMod $sFile + SetINIFloat "Actors:MiscRemovalMod" EULxActorMiscRemovalMod $sFile + + SetINIFloat "Actors:AnimalMod" EULxActorAnimalMod $sFile + SetINIFloat "Actors:RobotMod" EULxActorRobotMod $sFile + SetINIFloat "Actors:FeralGhoulMod" EULxActorFeralGhoulMod $sFile + SetINIFloat "Actors:HumanMod" EULxActorHumanMod $sFile + SetINIFloat "Actors:GhoulMod" EULxActorGhoulMod $sFile + SetINIFloat "Actors:SupermutantMod" EULxActorSupermutantMod $sFile + + SetINIFloat "Actors:DisintegratedMod" EULxActorDisintegratedMod $sFile + + sv_destruct sFile + +end diff --git a/src/EULxMCMAddElement.gek b/src/EULxMCMAddElement.gek new file mode 100644 index 0000000..09e42f8 --- /dev/null +++ b/src/EULxMCMAddElement.gek @@ -0,0 +1,50 @@ +scn EULxMCMAddElement + +int i +int iSlot +string_var sTitle +float fType +float fValue + +begin _function { fType, sTitle, fValue } + + set i to 36 + while i > 0 + if 1 == GetMCMFloat 1 i "_enable" + set iSlot to i + 1 + break + endif + set i to i - 1 + loop + + if iSlot == 0 + set iSlot to 1 + endif + + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_enable" 1 + SetUIString "StartMenu/MCM/*:1/*:" + $iSlot + "/_title" $sTitle + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_type" fType + + if fType == 2 || fType == 4 || fType == 5 + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_value" fValue + elseif fType == 2.5 + SetUIStringEx "StartMenu/MCM/*:1/*:" + $iSlot + "/value/*:1/string" "%.1f" fValue + elseif fType == 0 + + if sTitle + ; header font + if 0 < GetUIFloat "HUDMainMenu\_DUIF3" ; DarnifiedUI + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_altFont" 3 + else + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_altFont" 1 + endif + endif + + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_highlight" 0 + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_brightness" 180 + + endif + + sv_destruct sTitle + +end diff --git a/src/EULxMCMAddScale.gek b/src/EULxMCMAddScale.gek new file mode 100644 index 0000000..5fa3483 --- /dev/null +++ b/src/EULxMCMAddScale.gek @@ -0,0 +1,24 @@ +scn EULxMCMAddScale + +string_var sTitle +string_var sSuffix +float fValue +float fDecimals +float fValueMin +float fValueMax +float fValueIncrement + +begin function { sTitle, fValue, sSuffix, fValueMin, fValueMax, fDecimals, fValueIncrement } + + SetUIString "StartMenu/MCM/*:2/_title" $sTitle + SetUIString "StartMenu/MCM/*:2/_suffixText" $sSuffix + SetUIFloat "StartMenu/MCM/_Value" fValue + SetUIFloat "StartMenu/MCM/_ValueDecimal" fDecimals + SetUIFloat "StartMenu/MCM/_ValueIncrement" fValueIncrement + SetUIFloat "StartMenu/MCM/_ValueMax" fValueMax + SetUIFloat "StartMenu/MCM/_ValueMin" fValueMin + + sv_destruct sTitle + sv_destruct sSuffix + +end diff --git a/src/EULxOnCellEnter.gek b/src/EULxOnCellEnter.gek new file mode 100644 index 0000000..35a1e52 --- /dev/null +++ b/src/EULxOnCellEnter.gek @@ -0,0 +1,32 @@ +scn EULxOnCellEnter + +ref rCell +array_var aCells +int i + +begin function { rCell } + + if GetCellFlag rCell 0 ; interior + if IsCellVisited rCell + return + endif + call EULxOnSeen rCell + else + let aCells := GetBufferedCells 0 + let i := ar_size aCells + while i > 0 + let i -= 1 + let rCell := aCells[i] + if IsCellVisited rCell == 0 + if RefMapGetFlt "*v" rCell == 0 + RefMapSetFlt "*v" 1 rCell + call EULxOnSeen rCell + endif + elseif RefMapGetType "*v" rCell + RefMapErase "*v" rCell + endif + loop + let aCells := ar_null + endif + +end diff --git a/src/EULxOnDisintegration.gek b/src/EULxOnDisintegration.gek new file mode 100644 index 0000000..4b3828a --- /dev/null +++ b/src/EULxOnDisintegration.gek @@ -0,0 +1,15 @@ +scn EULxOnDisintegration + +ref rActor +ref rBaseEffect + +begin function { rActor, rBaseEffect } + + if rActor == playerRef + return + endif + + DebugPrint "%n has been disintegrated/gooified, making second pass" rActor + call EULxDelootifyNPC rActor 1 + +end diff --git a/src/EULxOnDrop.gek b/src/EULxOnDrop.gek new file mode 100644 index 0000000..5a82171 --- /dev/null +++ b/src/EULxOnDrop.gek @@ -0,0 +1,27 @@ +scn EULxOnDrop + +ref rDropper +ref rItem +int iType + +begin function { rDropper, rItem } + + if rDropper == playerRef + return + endif + + if rDropper.GetDead ; items, dropped on death, handled in OnDying + return + endif + + DebugPrint "%n dropped %n being alive, skipping removal." rDropper rItem + + set iType to rItem.GetType + + if iType != 40 && iType != 24 + return + endif + + call EULxReduceItemHealth playerRef rItem + +end diff --git a/src/EULxOnDying.gek b/src/EULxOnDying.gek new file mode 100644 index 0000000..0456d6f --- /dev/null +++ b/src/EULxOnDying.gek @@ -0,0 +1,65 @@ +scn EULxOnDying + +ref rActor +ref rTemp +int i +int iType +float fBasefRemovalChance +float fRemovalChance +array_var aItems + +begin function { rActor } + + if EULxActorLootRemovalEnabled == 0 || rActor == playerRef + return + endif + + if rActor.GetPlayerTeammate + DebugPrint "%n is a teammate, skipping" rActor + return + endif + + DebugPrint "%n has been killed" rActor + + call EULxDelootifyNPC rActor 0 + + let aItems := rActor.GetDroppedRefs + set i to ar_size aItems + + if i > 0 + + set fBasefRemovalChance to call EULxCalculateBaseRemovalChance rActor + + while i > 0 + set i to i - 1 + let rTemp := aItems[i] + + if EULxActorRemoveEquippedWeapons == 0 + call EULxReduceItemHealth playerRef rTemp + continue + endif + + ; Normally, NPCs do not drop anything besides weapons, we skip other types for now + if rTemp.GetType != 40 + continue + endif + + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorWeaponRemovalMod + set fRemovalChance to fRemovalChance * 100 + + DebugPrint "%n dropped %n, removal chance %.2f%%" rActor rTemp fRemovalChance + + if GetRandomPercent >= fRemovalChance + call EULxReduceItemHealth playerRef rTemp + else + DebugPrint "Disabling dropped %n" rTemp + rTemp.disable + rTemp.MarkForDelete + endif + loop + + elseif i == 0 + let aItems := ar_null + endif + +end diff --git a/src/EULxOnGameLoad.gek b/src/EULxOnGameLoad.gek new file mode 100644 index 0000000..b7863dc --- /dev/null +++ b/src/EULxOnGameLoad.gek @@ -0,0 +1,44 @@ +scn EULxOnGameLoad + +; NB: the print function is silent in the PostLoadGame event handlers + +int iSuccess + +begin function { iSuccess } + + ; Get main DLCs' indexes for better detection of mod-added items + set EULxDLCIndex to 0 + + if IsModLoaded "TaleOfTwoWastelands.esm" + set EULxDLCIndex to GetModIndex "TaleOfTwoWastelands.esm" + elseif IsModLoaded "GunRunnersArsenal.esm" + set EULxDLCIndex to GetModIndex "GunRunnersArsenal.esm" + elseif IsModLoaded "LonesomeRoad.esm" + set EULxDLCIndex to GetModIndex "LonesomeRoad.esm" + elseif IsModLoaded "OldWorldBlues.esm" + set EULxDLCIndex to GetModIndex "OldWorldBlues.esm" + elseif IsModLoaded "HonestHearts.esm" + set EULxDLCIndex to GetModIndex "HonestHearts.esm" + elseif IsModLoaded "DeadMoney.esm" + set EULxDLCIndex to GetModIndex "DeadMoney.esm" + endif + + SetGameMainLoopCallback EULxOnGameMode 1 3 1 + + RefMapDestroy "*v" + + if EULxVersion < 3 + set EULxVersion to 3 + + set EULxActorDisintegratedMod to 2 + + if EULxSaveToINI + if FileExists "config\Unfound Loot.ini" + if GetINIFloat "General:Saved" "Unfound Loot.ini" + SetINIFloat "Actors:DisintegratedMod" EULxActorDisintegratedMod "Unfound Loot.ini" + endif + endif + endif + endif + +end diff --git a/src/EULxOnGameMode.gek b/src/EULxOnGameMode.gek new file mode 100644 index 0000000..6e8a1bc --- /dev/null +++ b/src/EULxOnGameMode.gek @@ -0,0 +1,18 @@ +scn EULxOnGameMode + +begin function {} + + SetGameMainLoopCallback EULxOnGameMode 0 + + SetJohnnyOnDyingEventHandler EULxActorLootRemovalEnabled EULxOnDying 0 + SetJohnnyOnLimbGoneEventHandler EULxActorBreakOnDecapitation EULxOnLimbGone 0 + + if IsModLoaded "JIP MiniMap.esp" == 0 + SetJohnnySeenDataEventHandler EULxWorldLootRemovalEnabled EULxOnSeen 0 + endif + + if GetGameRestarted + SetEventHandler "OnMagicEffectHit" EULxOnDisintegration "second"::EULxDisintegrationEffects + endif + +end diff --git a/src/EULxOnLimbGone.gek b/src/EULxOnLimbGone.gek new file mode 100644 index 0000000..e4d04f9 --- /dev/null +++ b/src/EULxOnLimbGone.gek @@ -0,0 +1,52 @@ +scn EULxOnLimbGone + +ref rActor +int iLimb +ref rItem + +begin function { rActor, iLimb } + + if EULxActorBreakOnDecapitation == 0 + SetJohnnyOnLimbGoneEventHandler 0 EULxOnLimbGone 0 + return + endif + + if rActor.GetIsCreature + return + endif + + if iLimb == 1 + + set rItem to rActor.GetEquippedItemRef 9 ; headband + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 10 ; hat + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 11 ; eyeglasses + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 14 ; mask + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 16 ; mouth object + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + endif + +end diff --git a/src/EULxOnNewGame.gek b/src/EULxOnNewGame.gek new file mode 100644 index 0000000..7bc4887 --- /dev/null +++ b/src/EULxOnNewGame.gek @@ -0,0 +1,14 @@ +scn EULxOnNewGame + +begin function {} + + call EULxOnGameLoad 1 + + if FileExists "config\Unfound Loot.ini" + if GetINIFloat "General:Saved" "Unfound Loot.ini" + call EULxINILoadSettings + set EULxSaveToINI to 1 + endif + endif + +end diff --git a/src/EULxOnPause.gek b/src/EULxOnPause.gek new file mode 100644 index 0000000..2d7fa49 --- /dev/null +++ b/src/EULxOnPause.gek @@ -0,0 +1,14 @@ +scn EULxOnPause + +int iMenuMode + +begin function { iMenuMode } + + printd "Unfound Loot: Starting MCM quest" + + ; Safeguard from rogue value changers + SetValue EULxMCMMiscItem 23370 + + StartQuest EULxQuest + +end diff --git a/src/EULxOnSeen.gek b/src/EULxOnSeen.gek new file mode 100644 index 0000000..9fdc4d1 --- /dev/null +++ b/src/EULxOnSeen.gek @@ -0,0 +1,106 @@ +scn EULxOnSeen + +ref rCell +ref rTemp +ref rItem +int iTemp +int iPrecalc +int bSkip + +begin function { rCell } + + if EULxWorldLootRemovalEnabled == 0 + return + endif + + if GetOwnerOfCell rCell + DebugPrint "%n is an owned cell, skipping." rCell + return + endif + + if ListGetFormIndex EULxProtectedCells rCell != -1 + DebugPrint "%n is a protected cell, skipping." rCell + return + endif + + ; Splitting this into separate UDFs is nice and all, but not very performance-friendly. + ; Instead, we do most basic checks here, and all the hard work in separate functions. + + + ; Do not call EULxDelootifyCellItems if the cell has no items + + if GetFirstRefInCell rCell 201 0 0 + set iPrecalc to 1 + call EULxPrecalculateRemovalChance + call EULxDelootifyCellItems rCell + endif + + + DebugPrint "Scanning %n (%i) for containers" rCell rCell + + set iTemp to GetSourceModIndex rCell + + set rTemp to GetFirstRefInCell rCell 27 0 0 + + while rTemp + + set bSkip to 0 + + if rTemp.GetDisabled + DebugPrint "%n is disabled, skipping." rTemp + set rTemp to GetNextRef + continue + elseif rTemp.IsPersistent + DebugPrint "%n is persistent, skipping." rTemp + set rTemp to GetNextRef + continue + elseif rTemp.GetContainerInventoryCount == 0 + DebugPrint "%n is empty, skipping." rTemp + set rTemp to GetNextRef + continue + elseif rTemp.GetLocked && EULxWorldSkipLocked + DebugPrint "%n is locked, skipping loot reduction." rTemp + set bSkip to 1 + elseif rTemp.HasScriptBlock 2 ; OnActivate + DebugPrint "%n is scripted, skipping loot reduction." rTemp + set bSkip to 1 + elseif rTemp.GetReferenceFlag 33554432 + DebugPrint "%n has the No AI Acquire flag, skipping loot reduction." rTemp + set bSkip to 1 + elseif rTemp.GetOwner + DebugPrint "%n is owned, skipping loot reduction." rTemp + set bSkip to 1 + elseif eval 0 < ar_size (rTemp.GetAllItems 49) + DebugPrint "%n contains a note, skipping loot reduction." rTemp + set bSkip to 1 + endif + + if bSkip == 0 + if GetSourceModIndex rTemp != iTemp + DebugPrint "%n is a mod-added container, skipping." rTemp + set bSkip to 1 + endif + endif + + if bSkip + foreach rItem <- rTemp + if rItem.GetType == 24 || rItem.GetType == 40 + call EULxReduceItemHealth rTemp rItem + endif + loop + set rTemp to GetNextRef + continue + endif + + if iPrecalc == 0 + set iPrecalc to 1 + call EULxPrecalculateRemovalChance + endif + + call EULxDelootifyContainer rCell rTemp + + set rTemp to GetNextRef + + loop + +end diff --git a/src/EULxPrecalculateRemovalChance.gek b/src/EULxPrecalculateRemovalChance.gek new file mode 100644 index 0000000..61f52cb --- /dev/null +++ b/src/EULxPrecalculateRemovalChance.gek @@ -0,0 +1,41 @@ +scn EULxPrecalculateRemovalChance + +float fTemp + +begin function {} + + set fTemp to (( EULxLuckModifier / 10 ) * playerRef.getAV luck) / 100 + set fTemp to 1 - fTemp + set fTemp to EULxWorldBaseRemovalChance * fTemp + set fTemp to fTemp / 100 + + ;DebugPrint "Base removal chance %g, luck effect %g%% - new base removal chance %g%%" EULxWorldBaseRemovalChance EULxLuckModifier fTemp + + set EULxCalcArmorRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldArmorRemovalMod + set EULxCalcArmorRemovalChance to EULxCalcArmorRemovalChance * 100 + + set EULxCalcMiscRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldMiscRemovalMod + set EULxCalcMiscRemovalChance to EULxCalcMiscRemovalChance * 100 + + set EULxCalcWeaponRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldWeaponRemovalMod + set EULxCalcWeaponRemovalChance to EULxCalcWeaponRemovalChance * 100 + + set EULxCalcAmmoRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldAmmoRemovalMod + set EULxCalcAmmoRemovalChance to EULxCalcAmmoRemovalChance * 100 + + set EULxCalcCurrencyRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldCurrencyRemovalMod + set EULxCalcCurrencyRemovalChance to EULxCalcCurrencyRemovalChance * 100 + + set EULxCalcChemsRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldChemsRemovalMod + set EULxCalcChemsRemovalChance to EULxCalcChemsRemovalChance * 100 + + set EULxCalcMedsRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldMedsRemovalMod + set EULxCalcMedsRemovalChance to EULxCalcMedsRemovalChance * 100 + + set EULxCalcAlcoholRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldAlcoholRemovalMod + set EULxCalcAlcoholRemovalChance to EULxCalcAlcoholRemovalChance * 100 + + set EULxCalcFoodRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldFoodRemovalMod + set EULxCalcFoodRemovalChance to EULxCalcFoodRemovalChance * 100 + +end diff --git a/src/EULxPresetSetterFUNCTION.gek b/src/EULxPresetSetterFUNCTION.gek new file mode 100644 index 0000000..c1b91dc --- /dev/null +++ b/src/EULxPresetSetterFUNCTION.gek @@ -0,0 +1,164 @@ +scn EULxPresetSetterFUNCTION + +int iPreset ; 1=balanced, 2=hardcore, 3=realistic +int bAll + +begin function { iPreset, bAll } + + printToConsole "Unfound Loot: Setting up preset %g" iPreset + + if bAll || EULxQuest.iSubMenu == 1 + + ; General + + set EULxMaxItemValue to 5000 ; excludes most uniques + set EULxMaxWeaponCondition to 40 ; 40% condition + set EULxMaxArmorCondition to 40 ; 40% condition + set EULxLuckModifier to 10 ; 10% luck effect + + endif + + if bAll || EULxQuest.iSubMenu == 2 + + ; World-placed Items + + set EULxWorldLootRemovalEnabled to 1 + set EULxWorldBaseRemovalChance to 85 + set EULxWorldSkipLocked to 1 + + set EULxWorldWeaponRemovalMod to 1.0 + set EULxWorldArmorRemovalMod to 0.5 ; less chance of removing rad suits and such + + set EULxWorldAlcoholRemovalMod to 1.0 + set EULxWorldChemsRemovalMod to 1.0 + set EULxWorldMedsRemovalMod to 1.0 + set EULxWorldFoodRemovalMod to 1.3 + + set EULxWorldMiscRemovalMod to .60 ; keep interiors pretty + set EULxWorldAmmoRemovalMod to 1.0 + set EULxWorldCurrencyRemovalMod to 1.2 + + endif + + if bAll || EULxQuest.iSubMenu == 3 + + ; Corpse Loot + + set EULxActorLootRemovalEnabled to 1 + set EULxActorBaseRemovalChance to 80 + set EULxActorSkillMod to 1.0 ; from 95/90 to 90/85 percent removal at 100 skill (robot and animal only) + set EULxActorAnimalMod to 0.6 ; animals usually have stuff on them + set EULxActorRobotMod to 1.0 + set EULxActorFeralGhoulMod to 1.0 + set EULxActorHumanMod to 1.0 + set EULxActorGhoulMod to 1.0 + set EULxActorSupermutantMod to 1.0 + set EULxActorWeaponRemovalMod to 1.0 + set EULxActorArmorRemovalMod to 1.0 + + set EULxActorAlcoholRemovalMod to 1.0 + set EULxActorChemsRemovalMod to 1.0 + set EULxActorMedsRemovalMod to 1.0 + set EULxActorFoodRemovalMod to 1.0 + + set EULxActorMiscRemovalMod to 1.0 + set EULxActorCurrencyRemovalMod to 0.8 + set EULxActorAmmoRemovalMod to 0.3 ; leave a little more ammo for the player + set EULxActorRemoveEquippedWeapons to 0 + set EULxActorBreakOnDecapitation to 1 + set EULxActorDisintegratedMod to 2 + + endif + + if bAll == 0 + return + endif + + if iPreset == 1 ; Balanced + + set EULxMaxItemValue to 3500 + set EULxMaxWeaponCondition to 30 + set EULxMaxArmorCondition to 30 + + set EULxWorldBaseRemovalChance to 95 + set EULxWorldArmorRemovalMod to 1.0 + set EULxWorldMiscRemovalMod to .80 ;sparse interiors + set EULxWorldAmmoRemovalMod to 2.0 ;too much ammo as is + set EULxWorldCurrencyRemovalMod to 1.0 + + set EULxWorldAlcoholRemovalMod to 1.0 + set EULxWorldChemsRemovalMod to 1.0 + set EULxWorldMedsRemovalMod to 1.0 + set EULxWorldFoodRemovalMod to 1.3 + + set EULxActorBaseRemovalChance to 95 + set EULxActorAnimalMod to 0.75 ;sparse animals + set EULxActorAmmoRemovalMod to 0.4 + set EULxActorCurrencyRemovalMod to 1.0 + + set EULxActorAlcoholRemovalMod to EULxWorldAlcoholRemovalMod + set EULxActorChemsRemovalMod to EULxWorldChemsRemovalMod + set EULxActorMedsRemovalMod to EULxWorldMedsRemovalMod + set EULxActorFoodRemovalMod to 0.8 + + elseif iPreset == 2 ; Hardcore + + set EULxMaxItemValue to 9999 ; remove almost anything + set EULxMaxWeaponCondition to 20 + set EULxMaxArmorCondition to 20 + set EULxLuckModifier to 0 + + set EULxWorldSkipLocked to 0 + + set EULxWorldBaseRemovalChance to 95 + set EULxWorldWeaponRemovalMod to 1.5 + set EULxWorldArmorRemovalMod to 0.6 + set EULxWorldMiscRemovalMod to 0.33 ; junk doesnt get picked up + set EULxWorldAmmoRemovalMod to 1.3 + set EULxWorldCurrencyRemovalMod to 1.5 + + set EULxWorldAlcoholRemovalMod to 1.5 + set EULxWorldChemsRemovalMod to 1.2 + set EULxWorldMedsRemovalMod to 1.2 + set EULxWorldFoodRemovalMod to 1.5 ; + + set EULxActorBaseRemovalChance to 90 + set EULxActorAnimalMod to 0.1 ;animals usually have stuff on them + set EULxActorRobotMod to 0.5 + set EULxActorFeralGhoulMod to 2.0 + set EULxActorMiscRemovalMod to 2.0 + set EULxActorCurrencyRemovalMod to 2.0 + + set EULxActorAlcoholRemovalMod to EULxWorldAlcoholRemovalMod + set EULxActorChemsRemovalMod to EULxWorldChemsRemovalMod + set EULxActorMedsRemovalMod to EULxWorldMedsRemovalMod + set EULxActorFoodRemovalMod to 0.2 + + elseif iPreset == 3 ; Realistic + + set EULxMaxWeaponCondition to 35 + set EULxMaxArmorCondition to 35 + + set EULxWorldBaseRemovalChance to 66 + set EULxWorldWeaponRemovalMod to 1.5 + set EULxWorldCurrencyRemovalMod to 2.0 + + set EULxWorldAlcoholRemovalMod to 2.0 + set EULxWorldChemsRemovalMod to 1.5 + set EULxWorldMedsRemovalMod to 1.2 + set EULxWorldFoodRemovalMod to 2.0 + + set EULxActorBaseRemovalChance to 66 + set EULxActorAnimalMod to 0.1 ;animals usually have stuff on them + set EULxActorCurrencyRemovalMod to 2.0 + + set EULxActorAlcoholRemovalMod to EULxWorldAlcoholRemovalMod + set EULxActorChemsRemovalMod to EULxWorldChemsRemovalMod + set EULxActorMedsRemovalMod to EULxWorldMedsRemovalMod + set EULxActorFoodRemovalMod to 0.2 + + endif + + call EULxPrecalculateRemovalChance + +end \ No newline at end of file diff --git a/src/EULxProbabilityMultiplierFUNCTION.gek b/src/EULxProbabilityMultiplierFUNCTION.gek new file mode 100644 index 0000000..11e4f2a --- /dev/null +++ b/src/EULxProbabilityMultiplierFUNCTION.gek @@ -0,0 +1,23 @@ +scn EULxProbabilityMultiplierFUNCTION + +float fBaseProbability +float fMultiplier +float fTemp +float fBaseProbabilityOfNotHappening + +begin function { fBaseProbability, fMultiplier } + + set fBaseProbabilityOfNotHappening to 1 - fBaseProbability + + if fMultiplier < 1 + set fTemp to fBaseProbability * fMultiplier + else + set fTemp to pow fBaseProbabilityOfNotHappening fMultiplier + set fTemp to 1 - fTemp + endif + + ;DebugPrint "ProbabilityMultiplierFunction called, prob %.4f mult: %.4f, returning %.4f" fBaseProbability fMultiplier fTemp + + setFunctionValue fTemp + +end diff --git a/src/EULxQuestScript.gek b/src/EULxQuestScript.gek new file mode 100644 index 0000000..34543d7 --- /dev/null +++ b/src/EULxQuestScript.gek @@ -0,0 +1,698 @@ +scn EULxQuestScript + +int iMouseover +int iOption +int iSubMenu +float fValue +ref rTemp + +begin GameMode + StopQuest EULxQuest ; No zombies allowed! +end + +begin MenuMode 4 + + StopQuest EULxQuest + + if GetGameRestarted == 0 + return + endif + + if GetPluginVersion "JohnnyGuitarNVSE" < 305 + print "Unfound Loot requires JohnnyGuitar NVSE 3.05+" + MessageBoxEx "Unfound Loot requires JohnnyGuitar NVSE 3.05+" + endif + + if GetPluginVersion "JIP NVSE Plugin" < 55.45 + print "Unfound Loot requires JIP LN NVSE 55.45+" + MessageBoxEx "Unfound Loot requires JIP LN NVSE 55.45+" + endif + + if IsModLoaded "The Mod Configuration Menu.esp" + + set fValue to GetModIndex "The Mod Configuration Menu.esp" + set rTemp to BuildRef fValue 2790 + ListAddForm rTemp EULxMCMMiscItem + + SetOnMenuOpenEventHandler EULxOnPause 1 1013 ; start MCM quest on pause + + else + print "Unfound Loot: MCM not found" + endif + + if IsModLoaded "DeadMoney.esm" + set rTemp to StringToRef "DeadMoney.esm:29E4" ; Sierra Madre Vault + ListAddForm EULxProtectedCells rTemp + endif + + if IsModLoaded "Fallout3.esm" + set rTemp to StringToRef "Fallout3.esm:1B56C" ; TaftTunnel01 + ListAddForm EULxProtectedCells rTemp + set rTemp to StringToRef "Fallout3.esm:CAFDF" ; Gold Ribbon Grocers + ListAddForm EULxProtectedCells rTemp + endif + + set rTemp to 0 + + SetEventHandler "NewGame" EULxOnNewGame + SetEventHandler "PostLoadGame" EULxOnGameLoad + SetEventHandler "OnDrop" EULxOnDrop + + if IsModLoaded "JIP MiniMap.esp" + print "Unfound Loot: JIP MiniMap detected, running in compatibility mode." + SetEventHandler "OnCellEnter" EULxOnCellEnter + endif + + call EULxWhitelistDeathItems + +end + +begin MenuMode 1013 + + if GetUIFloat "StartMenu/MCM/_ActiveMod" != GetSelfModIndex + return + endif + + if GetUIFloat "StartMenu/MCM/_ActiveMenu" != GetValue EULxMCMMiscItem + return + endif + + set iOption to GetUIFloat "StartMenu/MCM/_ActiveOption" + set fValue to GetUIFloat "StartMenu/MCM/_Value" + + if GetUIFloat "StartMenu/MCM/*:5/SubMenu1/_enable" == 0 + SetUIFloat "StartMenu/MCM/_ActiveSubMenu" 1 + + SetUIFloat "StartMenu/MCM/*:5/SubMenu1/_enable" 1 + SetUIString "StartMenu/MCM/*:5/SubMenu1/text/string" "General Options" + SetUIString "StartMenu/MCM/*:8/SubTitle1/string" "General Options" + + SetUIFloat "StartMenu/MCM/*:5/SubMenu2/_enable" 1 + SetUIString "StartMenu/MCM/*:5/SubMenu2/text/string" "World Items" + SetUIString "StartMenu/MCM/*:8/SubTitle2/string" "World Items Reduction" + + SetUIFloat "StartMenu/MCM/*:5/SubMenu3/_enable" 1 + SetUIString "StartMenu/MCM/*:5/SubMenu3/text/string" "Corpse Loot" + SetUIString "StartMenu/MCM/*:8/SubTitle3/string" "Corpse Loot Reduction" + endif + + set iSubMenu to GetUIFloat "StartMenu/MCM/_ActiveSubMenu" + + if GetUIFloat "StartMenu/MCM/_Reset" ; 1 - RESET + SetUIFloat "StartMenu/MCM/_Reset" 0 ; don't run twice + + SetMCMFloatMass 1 1 36 "_enable" 0 + + if iSubMenu == 1 + + SetMCMFloat 1 0 "_columns" 1 + + call EULxMCMAddElement 2 "Max item value" EULxMaxItemValue + call EULxMCMAddElement 2 "Luck effect on base removal chance" EULxLuckModifier + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 2 "Max weapon condition" EULxMaxWeaponCondition + call EULxMCMAddElement 2 "Max armor condition" EULxMaxArmorCondition + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 1 "Select preset (overwrites ALL options)" 0 + call EULxMCMAddElement 1 "Reset all settings" 0 + call EULxMCMAddElement 5 "Enable debug mode for the session" GetDebugMode + + call EULxMCMAddElement 0 "" 0 + + if FileExists "config\Unfound Loot.ini" + call EULxMCMAddElement 0 "Unfound Loot.ini" 0 + call EULxMCMAddElement 5 "Save settings to INI" EULxSaveToINI + call EULxMCMAddElement 1 "Reload settings from INI" 0 + endif + + elseif iSubMenu == 2 + + SetMCMFloat 1 0 "_columns" 2 + + call EULxMCMAddElement 4 "Enabled" EULxWorldLootRemovalEnabled + call EULxMCMAddElement 2 "Base removal chance" EULxWorldBaseRemovalChance + call EULxMCMAddElement 5 "Skip locked containers" EULxWorldSkipLocked + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "Removal chance multipliers" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 2.5 "Weapons" EULxWorldWeaponRemovalMod + call EULxMCMAddElement 2.5 "Ammo" EULxWorldAmmoRemovalMod + call EULxMCMAddElement 2.5 "Apparel" EULxWorldArmorRemovalMod + call EULxMCMAddElement 2.5 "Currencies" EULxWorldCurrencyRemovalMod + call EULxMCMAddElement 2.5 "Alcohol" EULxWorldAlcoholRemovalMod + call EULxMCMAddElement 2.5 "Chems" EULxWorldChemsRemovalMod + call EULxMCMAddElement 2.5 "Meds" EULxWorldMedsRemovalMod + call EULxMCMAddElement 2.5 "Food" EULxWorldFoodRemovalMod + call EULxMCMAddElement 2.5 "Misc items" EULxWorldMiscRemovalMod + + elseif iSubMenu == 3 + + SetMCMFloat 1 0 "_columns" 2 + + call EULxMCMAddElement 4 "Enabled" EULxActorLootRemovalEnabled + call EULxMCMAddElement 2 "Base removal chance" EULxActorBaseRemovalChance + call EULxMCMAddElement 5 "Remove equipped weapons" EULxActorRemoveEquippedWeapons + call EULxMCMAddElement 5 "Gear breaks on decapitation" EULxActorBreakOnDecapitation + call EULxMCMAddElement 2.5 "Disintegration modifier" EULxActorDisintegratedMod + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "Removal chance multipliers by item type" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 2.5 "Weapons" EULxActorWeaponRemovalMod + call EULxMCMAddElement 2.5 "Ammo" EULxActorAmmoRemovalMod + call EULxMCMAddElement 2.5 "Apparel" EULxActorArmorRemovalMod + call EULxMCMAddElement 2.5 "Currencies" EULxActorCurrencyRemovalMod + call EULxMCMAddElement 2.5 "Alcohol" EULxActorAlcoholRemovalMod + call EULxMCMAddElement 2.5 "Chems" EULxActorChemsRemovalMod + call EULxMCMAddElement 2.5 "Meds" EULxActorMedsRemovalMod + call EULxMCMAddElement 2.5 "Food" EULxActorFoodRemovalMod + call EULxMCMAddElement 2.5 "Misc items" EULxActorMiscRemovalMod + + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "Removal chance multipliers by species" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 2.5 "Creatures" EULxActorAnimalMod + call EULxMCMAddElement 2.5 "Robots" EULxActorRobotMod + call EULxMCMAddElement 2.5 "Feral Ghouls" EULxActorFeralGhoulMod + call EULxMCMAddElement 2.5 "Humans" EULxActorHumanMod + call EULxMCMAddElement 2.5 "Ghouls" EULxActorGhoulMod + call EULxMCMAddElement 2.5 "Supermutants" EULxActorSupermutantMod + + + endif + + elseif GetUIFloat "StartMenu/MCM/_Default" ; 2 - DEFAULT + SetUIFloat "StartMenu/MCM/_Default" 0 ; dont run twice + SetUIFloat "StartMenu/MCM/_Reset" 1 ; reset ui + + call EULxPresetSetterFUNCTION 0 0 + + elseif GetUIFloat "StartMenu/MCM/_NewValue" ; 3 - NEW VALUE + SetUIFloat "StartMenu/MCM/_NewValue" 0 ; don't run this section twice + SetUIFloat "StartMenu/MCM/_Reset" 1 ; refresh ui + + if iSubMenu == 1 + + set iOption to GetUIFloat "StartMenu/MCM/_ActiveOption" + set fValue to GetUIFloat "StartMenu/MCM/_Value" + + if iOption == 1 + set EULxMaxItemValue to fValue + elseif iOption == 2 + set EULxLuckModifier to fValue + + elseif iOption == 4 + set EULxMaxWeaponCondition to fValue + + elseif iOption == 5 + set EULxMaxArmorCondition to fValue + + elseif iOption == 7 ; Global Preset + call EULxPresetSetterFUNCTION fValue 1 + + elseif iOption == 8 ; Reset settings + if fValue == 1 + Call EULxPresetSetterFUNCTION 0 1 + SetDebugMode 0 + endif + + elseif iOption == 9 ; Debug mode + SetDebugMode fValue + return + + elseif iOption == 12 + set EULxSaveToINI to fValue + if fValue + call EULxINISaveSettings + endif + + elseif iOption == 13 + if fValue == 1 + call EULxINILoadSettings + SetUIFloat "StartMenu/MCM/_Reset" 1 + else + return + endif + + endif + + elseif iSubMenu == 2 + + if iOption == 1 + set EULxWorldLootRemovalEnabled to fValue + SetJohnnySeenDataEventHandler fValue EULxOnSeen 0 + + elseif iOption == 2 + set EULxWorldBaseRemovalChance to fValue + elseif iOption == 3 + set EULxWorldSkipLocked to fValue + + elseif iOption == 9 + set EULxWorldWeaponRemovalMod to fValue + elseif iOption == 10 + set EULxWorldAmmoRemovalMod to fValue + elseif iOption == 11 + set EULxWorldArmorRemovalMod to fValue + elseif iOption == 12 + set EULxWorldCurrencyRemovalMod to fValue + elseif iOption == 13 + set EULxWorldAlcoholRemovalMod to fValue + elseif iOption == 14 + set EULxWorldChemsRemovalMod to fValue + elseif iOption == 15 + set EULxWorldMedsRemovalMod to fValue + elseif iOption == 16 + set EULxWorldFoodRemovalMod to fValue + elseif iOption == 17 + set EULxWorldMiscRemovalMod to fValue + endif + + elseif iSubMenu == 3 + + if iOption == 1 + set EULxActorLootRemovalEnabled to fValue + SetJohnnyOnDyingEventHandler fValue EULxOnDying 0 + + elseif iOption == 2 + set EULxActorBaseRemovalChance to fValue + elseif iOption == 3 + set EULxActorRemoveEquippedWeapons to fValue + elseif iOption == 4 + set EULxActorBreakOnDecapitation to fValue + SetJohnnyOnLimbGoneEventHandler fValue EULxOnLimbGone 0 + elseif iOption == 5 + set EULxActorDisintegratedMod to fValue + + elseif iOption == 11 + set EULxActorWeaponRemovalMod to fValue + elseif iOption == 12 + set EULxActorAmmoRemovalMod to fValue + elseif iOption == 13 + set EULxActorArmorRemovalMod to fValue + elseif iOption == 14 + set EULxActorCurrencyRemovalMod to fValue + elseif iOption == 15 + set EULxActorAlcoholRemovalMod to fValue + elseif iOption == 16 + set EULxActorChemsRemovalMod to fValue + elseif iOption == 17 + set EULxActorMedsRemovalMod to fValue + elseif iOption == 18 + set EULxActorFoodRemovalMod to fValue + elseif iOption == 19 + set EULxActorMiscRemovalMod to fValue + + elseif iOption == 25 + set EULxActorAnimalMod to fValue + elseif iOption == 26 + set EULxActorRobotMod to fValue + elseif iOption == 27 + set EULxActorFeralGhoulMod to fValue + elseif iOption == 28 + set EULxActorHumanMod to fValue + elseif iOption == 29 + set EULxActorGhoulMod to fValue + elseif iOption == 30 + set EULxActorSupermutantMod to fValue + + endif + + endif + + call EULxPrecalculateRemovalChance + + if EULxSaveToINI + call EULxINISaveSettings + endif + + elseif GetUIFloat "StartMenu/MCM/_ShowList" == 1 ;4 - SHOW LIST + SetUIFloat "StartMenu/MCM/_ShowList" 2 + + if iSubMenu == 1 + + if iOption == 7 + SetUIString "StartMenu/MCM/*:3/_title" "Select global preset (overwrites ALL options)" + + SetUIFloat "StartMenu/MCM/*:3/*:1/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:2/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:3/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:4/_enable" 1 + SetUIString "StartMenu/MCM/*:3/*:1/text/string" "Balanced (recommended)" + SetUIString "StartMenu/MCM/*:3/*:2/text/string" "Hardcore" + SetUIString "StartMenu/MCM/*:3/*:3/text/string" "Realistic" + SetUIString "StartMenu/MCM/*:3/*:4/text/string" "Cancel - retain existing settings" + SetUIFloat "StartMenu/MCM/_Value" 4 + endif + + if iOption == 8 + SetUIString "StartMenu/MCM/*:3/_title" "Reset entire mod" + SetUIFloat "StartMenu/MCM/*:3/*:1/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:2/_enable" 1 + SetUIString "StartMenu/MCM/*:3/*:1/text/string" "Confirm - reset everything" + SetUIString "StartMenu/MCM/*:3/*:2/text/string" "Cancel - retain existing settings" + SetUIFloat "StartMenu/MCM/_Value" 2 + endif + + if iOption == 13 + SetUIString "StartMenu/MCM/*:3/_title" "Reload settings from INI" + SetUIFloat "StartMenu/MCM/*:3/*:1/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:2/_enable" 1 + SetUIString "StartMenu/MCM/*:3/*:1/text/string" "Confirm - reload settings" + SetUIString "StartMenu/MCM/*:3/*:2/text/string" "Cancel - retain existing settings" + SetUIFloat "StartMenu/MCM/_Value" 2 + endif + + endif + + elseif GetUIFloat "StartMenu/MCM/_ShowScale" == 1 ;5 - SHOW SCALE + SetUIFloat "StartMenu/MCM/_ShowScale" 2 + + if iSubMenu == 1 + + if iOption == 1 + call EULxMCMAddScale "Max value of items affected by UL" EULxMaxItemValue " caps" 0 9999 0 10 + + elseif iOption == 2 + call EULxMCMAddScale "Luck effect" EULxLuckModifier "%" 0 100 0 1 + + elseif iOption == 4 + call EULxMCMAddScale "Max weapon condition" EULxMaxWeaponCondition "%" 1 100 0 1 + + elseif iOption == 5 + call EULxMCMAddScale "Max armor condition" EULxMaxArmorCondition "%" 1 100 0 1 + + endif + + elseif iSubMenu == 2 + + if iOption == 2 + call EULxMCMAddScale "Base removal chance" EULxWorldBaseRemovalChance "%" 0 100 0 1 + + elseif iOption == 9 + call EULxMCMAddScale "Weapon multiplier" EULxWorldWeaponRemovalMod "x" 0 10 1 0.1 + elseif iOption == 10 + call EULxMCMAddScale "Ammo multiplier" EULxWorldAmmoRemovalMod "x" 0 10 1 0.1 + elseif iOption == 11 + call EULxMCMAddScale "Armor multiplier" EULxWorldArmorRemovalMod "x" 0 10 1 0.1 + elseif iOption == 12 + call EULxMCMAddScale "Currencies multiplier" EULxWorldCurrencyRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 13 + call EULxMCMAddScale "Alcohol multiplier" EULxWorldAlcoholRemovalMod "x" 0 10 1 0.1 + elseif iOption == 14 + call EULxMCMAddScale "Chems multiplier" EULxWorldChemsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 15 + call EULxMCMAddScale "Meds multiplier" EULxWorldMedsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 16 + call EULxMCMAddScale "Food multiplier" EULxWorldFoodRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 17 + call EULxMCMAddScale "Misc items multiplier" EULxWorldMiscRemovalMod "x" 0 10 1 0.1 + endif + + elseif iSubMenu == 3 + + if iOption == 2 + call EULxMCMAddScale "Base removal chance" EULxActorBaseRemovalChance "%" 0 100 0 1 + + elseif iOption == 5 + call EULxMCMAddScale "Disintegration multiplier" EULxActorDisintegratedMod "x" 0 10 1 0.1 + + elseif iOption == 11 + call EULxMCMAddScale "Weapon multiplier" EULxActorWeaponRemovalMod "x" 0 10 1 0.1 + elseif iOption == 12 + call EULxMCMAddScale "Ammo multiplier" EULxActorAmmoRemovalMod "x" 0 10 1 0.1 + elseif iOption == 13 + call EULxMCMAddScale "Armor multiplier" EULxActorArmorRemovalMod "x" 0 10 1 0.1 + elseif iOption == 14 + call EULxMCMAddScale "Currencies multiplier" EULxActorCurrencyRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 15 + call EULxMCMAddScale "Alcohol multiplier" EULxActorAlcoholRemovalMod "x" 0 10 1 0.1 + elseif iOption == 16 + call EULxMCMAddScale "Chems multiplier" EULxActorChemsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 17 + call EULxMCMAddScale "Meds multiplier" EULxActorMedsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 18 + call EULxMCMAddScale "Food multiplier" EULxActorFoodRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 19 + call EULxMCMAddScale "Misc items multiplier" EULxActorMiscRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 25 + call EULxMCMAddScale "Creatures multiplier" EULxActorAnimalMod "x" 0 10 1 0.1 + elseif iOption == 26 + call EULxMCMAddScale "Robots multiplier" EULxActorRobotMod "x" 0 10 1 0.1 + elseif iOption == 27 + call EULxMCMAddScale "Feral Ghouls multiplier" EULxActorFeralGhoulMod "x" 0 10 1 0.1 + elseif iOption == 28 + call EULxMCMAddScale "Humans multiplier" EULxActorHumanMod "x" 0 10 1 0.1 + elseif iOption == 29 + call EULxMCMAddScale "Ghouls multiplier" EULxActorGhoulMod "x" 0 10 1 0.1 + elseif iOption == 30 + call EULxMCMAddScale "Supermutants multiplier" EULxActorSupermutantMod "x" 0 10 1 0.1 + + endif + + endif + + elseif GetUIFloat "StartMenu/MCM/_DefaultScale" ;6 - DEFAULT SCALE + SetUIFloat "StartMenu/MCM/_DefaultScale" 0 + SetUIFloat "StartMenu/MCM/_ShowScale" 2 + + if iSubMenu == 1 + + if iOption == 1 + SetUIFloat "StartMenu/MCM/_Value" 5000 + elseif iOption == 2 + SetUIFloat "StartMenu/MCM/_Value" 10 + elseif iOption == 4 + SetUIFloat "StartMenu/MCM/_Value" 40 + elseif iOption == 5 + SetUIFloat "StartMenu/MCM/_Value" 40 + endif + + elseif iSubMenu == 2 + + if iOption == 2 + SetUIFloat "StartMenu/MCM/_Value" 85 + + elseif iOption == 9 ; weapons + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 10 ; ammo + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 11 ; armor + SetUIFloat "StartMenu/MCM/_Value" 0.5 + elseif iOption == 12 ; currencies + SetUIFloat "StartMenu/MCM/_Value" 2.0 + + elseif iOption == 13 ; alcohol + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 14 ; chems + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 15 ; meds + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 16 ; food + SetUIFloat "StartMenu/MCM/_Value" 1.3 + + elseif iOption == 17 ; misc + SetUIFloat "StartMenu/MCM/_Value" 0.3 + + endif + + elseif iSubMenu == 3 + + if iOption == 2 + SetUIFloat "StartMenu/MCM/_Value" 80 + + elseif iOption == 5 ; disintegration + SetUIFloat "StartMenu/MCM/_Value" 2.0 + + elseif iOption == 11 ; weapons + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 12 ; ammo + SetUIFloat "StartMenu/MCM/_Value" 0.8 + elseif iOption == 13 ; armor + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 14 ; currencies + SetUIFloat "StartMenu/MCM/_Value" 2.0 + + elseif iOption == 15 ; alcohol + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 16 ; chems + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 17 ; meds + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 18 ; food + SetUIFloat "StartMenu/MCM/_Value" 0.8 + + elseif iOption == 19 ; misc + SetUIFloat "StartMenu/MCM/_Value" 1.0 + + elseif iOption == 25 ; creatures + SetUIFloat "StartMenu/MCM/_Value" 0.5 + elseif iOption == 26 ; robots + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 27 ; feral ghouls + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 28 ; humans + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 29 ; ghouls + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 30 ; supermutants + SetUIFloat "StartMenu/MCM/_Value" 1.0 + + endif + + endif + endif + + if iMouseover != GetUIFloat "StartMenu/MCM/*:1/_optionID" ;7 - MOUSE-OVER + set iMouseover to GetUIFloat "StartMenu/MCM/*:1/_optionID" + if iMouseover + if iSubMenu == 1 + + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + + if iMouseover == 1 + SetUIString "StartMenu/MCM/*:9/string" "Maximum value of items to remove. Items worth more than this will be left alone." + elseif iMouseover == 2 + SetUIString "StartMenu/MCM/*:9/string" "10% effect -> 10 Luck reduces removal by 10%, 1 Luck - by 1%. 100% effect -> 10 Luck reduces it by 100% (modifiers are still in play!), 1 Luck - by 10%. 0 - disable Luck factor." + + elseif iMouseover == 4 + SetUIString "StartMenu/MCM/*:9/string" "Max condition of weapons found in the world. Some containers and items may not be affected. To disable it and use vanilla values, set to 100%." + elseif iMouseover == 5 + SetUIString "StartMenu/MCM/*:9/string" "Max condition of armor found in the world. Some containers and items may not be affected. To disable it and use vanilla values, set to 100%." + + elseif iMouseover == 7 + SetUIString "StartMenu/MCM/*:9/string" "Apply a preset to the entire mod. Overrides all existing settings." + elseif iMouseover == 8 + SetUIString "StartMenu/MCM/*:9/string" "Completely resets all options!" + elseif iMouseover == 9 + SetUIString "StartMenu/MCM/*:9/string" "Show debug info in console for the current session." + + elseif iMouseover == 12 + SetUIString "StartMenu/MCM/*:9/string" "Always save settings to Data\Config\Unfound Loot.ini." + elseif iMouseover == 13 + SetUIString "StartMenu/MCM/*:9/string" "Rewrite existing settings with values from Unfound Loot.ini." + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + elseif iSubMenu == 2 + + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + + if iMouseover == 1 + SetUIString "StartMenu/MCM/*:9/string" "Enable or disable world items reduction." + elseif iMouseover == 2 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance for world-placed and container items. We get a random number between 0 and 100 and compare it with 100. If the number is smaller, the item gets removed." + elseif iMouseover == 3 + SetUIString "StartMenu/MCM/*:9/string" "Do not remove items from locked containers." + + elseif iMouseover == 9 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for weapons. Higher = greater chance of these items being removed." + elseif iMouseover == 10 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for ammo. Higher = greater chance of these items being removed." + elseif iMouseover == 11 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for armor. Higher = greater chance of these items being removed." + elseif iMouseover == 12 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for currencies. Higher = greater chance of these items being removed." + + elseif iMouseover == 13 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for alcohol. Higher = greater chance of these items being removed." + elseif iMouseover == 14 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for chems. Higher = greater chance of these items being removed." + elseif iMouseover == 15 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for healing items. Higher = greater chance of these items being removed." + elseif iMouseover == 16 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for food, water, and soft drinks. Higher = greater chance of these items being removed." + + elseif iMouseover == 17 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for misc items. Higher = greater chance of these items being removed." + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + elseif iSubMenu == 3 + + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + + if iMouseover == 1 + SetUIString "StartMenu/MCM/*:9/string" "Enable or disable corpse loot reduction." + elseif iMouseover == 2 + SetUIString "StartMenu/MCM/*:9/string" "Percentage of corpse's items that will be removed." + elseif iMouseover == 3 + SetUIString "StartMenu/MCM/*:9/string" "Apply removal chance to equipped weapons as well." + elseif iMouseover == 4 + SetUIString "StartMenu/MCM/*:9/string" "Set headgear condition to 0 on decapitation." + elseif iMouseover == 5 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for disintegrated and gooified corpses. Higher = greater chance of these items being removed." + + elseif iMouseover == 11 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for weapons. Higher = greater chance of these items being removed." + elseif iMouseover == 12 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for ammo. Higher = greater chance of these items being removed." + elseif iMouseover == 13 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for armor. Higher = greater chance of these items being removed." + elseif iMouseover == 14 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for currencies. Higher = greater chance of these items being removed." + + elseif iMouseover == 15 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for alcohol. Higher = greater chance of these items being removed." + elseif iMouseover == 16 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for chems. Higher = greater chance of these items being removed." + elseif iMouseover == 17 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for healing items. Higher = greater chance of these items being removed." + elseif iMouseover == 18 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for food, water, and soft drinks. Higher = greater chance of these items being removed." + + elseif iMouseover == 19 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for misc items. Higher = greater chance of these items being removed." + + elseif iMouseover == 25 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for creature corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 26 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for robots. Higher = greater chance of these items being removed." + elseif iMouseover == 27 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for feral ghoul corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 28 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for human corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 29 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for ghoul corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 30 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for supermutant corpses. Higher = greater chance of these items being removed." + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + endif + +end \ No newline at end of file diff --git a/src/EULxReduceItemHealth.gek b/src/EULxReduceItemHealth.gek new file mode 100644 index 0000000..27c5c72 --- /dev/null +++ b/src/EULxReduceItemHealth.gek @@ -0,0 +1,79 @@ +scn EULxReduceItemHealth + +ref rContainer +ref rItem +int iType +int iBaseHealth +int iTargetHealth +int iCurrentHealth +int iMaxCondition + +begin function { rContainer, rItem } + + set iType to rItem.GetType + + if iType == 40 + if rItem.GetWeaponType >= 10 ; mines and throwables + DebugPrint "%n is a mine/throwable, skipping health reduction." rItem + return + endif + set iMaxCondition to EULxMaxWeaponCondition + elseif iType == 24 + set iMaxCondition to EULxMaxArmorCondition + else + return + endif + + if iMaxCondition == 100 + ; use vanilla condition with 100% max health + return + endif + + set iBaseHealth to rItem.GetBaseHealth + + DebugPrint "%n base health: %g points." rItem iBaseHealth + + set iTargetHealth to iMaxCondition + 1 + set iTargetHealth to Rand 1 iTargetHealth + + DebugPrint "%n target health: %g%%" rItem iTargetHealth + + if rContainer == playerRef ; world items + + set iCurrentHealth to rItem.GetCurrentHealth / ( iBaseHealth / 100 ) + + DebugPrint "%n current health (world item): %g%%" rItem iCurrentHealth + + if iCurrentHealth > iTargetHealth + DebugPrint "Changing %n condition: %g%% to %g%%" rItem iCurrentHealth iTargetHealth + set iTargetHealth to iBaseHealth * ( iTargetHealth / 100 ) + + ; Keep at least one point of health for the item to remain equippable + if iTargetHealth < 1 + set iTargetHealth to 1 + endif + + rItem.SetCurrentHealth iTargetHealth + endif + + else ; container or NPC + + set iCurrentHealth to rItem.GetItemRefCurrentHealth / ( iBaseHealth / 100 ) + + DebugPrint "%n current health (inventory item): %g%%" rItem iCurrentHealth + + if iCurrentHealth > iTargetHealth + DebugPrint "Changing %n condition: %g%% to %g%%" rItem iCurrentHealth iTargetHealth + set iTargetHealth to iBaseHealth * ( iTargetHealth / 100 ) + + ; Keep at least one point of health for the item to remain equippable + if iTargetHealth < 1 + set iTargetHealth to 1 + endif + + rItem.SetItemRefCurrentHealth iTargetHealth + endif + + endif + +end \ No newline at end of file diff --git a/src/EULxWhitelistDeathItems.gek b/src/EULxWhitelistDeathItems.gek new file mode 100644 index 0000000..d2d9ccc --- /dev/null +++ b/src/EULxWhitelistDeathItems.gek @@ -0,0 +1,92 @@ +scn EULxWhitelistDeathItems + +int i +int n +ref rPerk +int iEntryCount +ref rList +ref rItem +ref rCertifiedTechItemList +int iModsNum + +begin function {} + + ; Get main DLCs' indexes for better detection of mod-added items + set EULxDLCIndex to 0 + + if IsModLoaded "TaleOfTwoWastelands.esm" + set EULxDLCIndex to GetModIndex "TaleOfTwoWastelands.esm" + elseif IsModLoaded "GunRunnersArsenal.esm" + set EULxDLCIndex to GetModIndex "GunRunnersArsenal.esm" + elseif IsModLoaded "LonesomeRoad.esm" + set EULxDLCIndex to GetModIndex "LonesomeRoad.esm" + elseif IsModLoaded "OldWorldBlues.esm" + set EULxDLCIndex to GetModIndex "OldWorldBlues.esm" + elseif IsModLoaded "HonestHearts.esm" + set EULxDLCIndex to GetModIndex "HonestHearts.esm" + elseif IsModLoaded "DeadMoney.esm" + set EULxDLCIndex to GetModIndex "DeadMoney.esm" + endif + + ListClear VATSSmallExplodingCreatureLIST ; hijacking unused formlists + ListClear EmptyFormList + + set iModsNum to GetNumLoadedMods + set i to EULxDLCIndex + 1 + while i < iModsNum + GetLoadedType VATSSmallExplodingCreatureLIST 86 i 1 + set i to i + 1 + loop + + if ListGetCount VATSSmallExplodingCreatureLIST == 0 + return + endif + + set rCertifiedTechItemList to StringToRef "LonesomeRoad.esm:C42D" + + set i to 0 + while rPerk := ListGetNthForm VATSSmallExplodingCreatureLIST i + + set iEntryCount to GetPerkEntryCount rPerk + set n to 0 + + while n < iEntryCount + if GetNthPerkEntryFunction rPerk n == 21 ; Add Leveled List On Death + + set rList to GetNthPerkEntryForm rPerk n + + if rList + if GetType rList == 52 && rList != rCertifiedTechItemList + ListAddForm EmptyFormList rList + endif + endif + + endif + + set n to n + 1 + loop + + set i to i + 1 + loop + + ListClear VATSSmallExplodingCreatureLIST + + set i to 0 + while rList := ListGetNthForm EmptyFormList i + + set n to 0 + while rItem := GetNthLevItem rList n + + if GetType rItem != 52 ; not leveled list + ListAddForm EULxDeathItems rItem + endif + + set n to n + 1 + loop + + set i to i + 1 + loop + + ListClear EmptyFormList + +end