Jump to content

Help making a SPERG SE patch for CACO


Recommended Posts

EDIT: OMG NEVERMIND, I guess it just works now.


Hello, I'm seeking a bit of insight and help, if you could, please.

I like using SPERG port to SE and Complete Alchemy and Cooking Overhaul. In the patches hub there's already a patch to make SPERG and CACO compatible, it merges the perks, mainly.

 

However in SPERG there's a function that, when you consume a piece of food, it adds towards an attribute experience (health exp, stamina exp, magicka, exp) and when you reach N exp, you get a permanent point in such attribute. The patch omited to address for that on CACO's food items and I wanted to fix it.

 

The way SPERG script works is to run whenever a potion is consumed (and checks if it's a food item), and then check the potion effects, it loops through them and then it checks the keywords of the magic effect, and if they match magicAlchRestoreHealth, it adds to health_exp, if it is magicAlchRestoreStamina, it adds to stamina_exp, etc, it also checks for magicAlchFortifyHealth, etc.

 

I checked CACO on Creation Kit and noticed the author added new 24 magic effects for the food items (regen fortificantion, and attribute fortification), such magic effects of course have more appropriate keywords, magicAlchRestoreAttribute were removed, and the magicAlchFortifyAttribute was replaced by foodEffectFortifyAttribute_CACO.

 

First I tried to add those CACO keywords on the script to take them on account, but after compiling, it didn't work, eating health related items wouldn't trigger a health level up. I suck at papyrus honestly, I know little of it so I thought I was just missing some reference or whatever. I scrapped that and just made a .esp in creation kit that gives all those CACO food effects old inappropiate keywords, I just added magicAlchRestoreHealth to all 8 health related effects, and so on.

But after putting my plugin right after CACO and trying all sorts of load orders with just those 3 mods, I couldn't make it work, although it was the simplest way to fix it.

May you have an idea in what else could CACO do to food items or food magic effects that could mess with sperg's script functions? Here is the script source, it has some other functions unrelated to food exp mechanic:

Scriptname SPEExpScript extends SPEPlayerOnlyAbility
{Grants the player additional skill experience for certain tasks.}

;simple xp variables
GlobalVariable Property SPEShoutExp Auto
GlobalVariable Property SPEPotionExp Auto
GlobalVariable Property SPEIngredientExp Auto
Keyword Property MagicShout Auto

;armor xp variables
GlobalVariable Property SPEArmorExp Auto
GlobalVariable Property SPEHeavyPieces Auto
GlobalVariable Property SPELightPieces Auto

;food exp variables
GlobalVariable Property SPEFoodExpMode Auto

Keyword Property MagicAlchRestoreHealth Auto
Keyword Property MagicAlchRestoreMagicka Auto
Keyword Property MagicAlchRestoreStamina Auto

Keyword Property MagicAlchFortifyHealRate Auto
Keyword Property MagicAlchFortifyMagickaRate Auto
MagicEffect Property FoodFortifyMagicka Auto

Keyword Property MagicAlchBeneficial Auto
Keyword Property MagicAlchHarmful Auto

Message Property SPEStaminaUp Auto
Message Property SPECarryWeightUp Auto
Message Property SPEHealthUp Auto
Message Property SPEMagickaUp Auto

;statics
float Property ExpMultiplier = 1.10 Auto
float Property nextHealth = 100.0 Auto
float Property nextMagicka = 100.0 Auto
float Property nextStamina = 100.0 Auto

;local variables
int Property Timeout = 90 Auto
int ArmorCounter = 0
int ArmorAdvances = 0
int MaxAdvances = 15
bool initialized = false
float healthExp = 0.0
float magickaExp = 0.0
float staminaExp = 0.0
float carryWeightGains = 0.0
bool levelStats = false
bool running = false

Function Initialize()
	RegisterForModEvent("SPE_RunStart", "OnRunStart")
	RegisterForModEvent("SPE_RunStop", "OnRunStop")
	RegisterForModEvent("SPE_ResetArmorExp", "ResetArmorExp")
EndFunction

Event OnSpellCast(Form akSpell)

	Potion isPotion = akSpell as Potion
	Ingredient isIngredient = akSpell as Ingredient
	If akSpell != NONE && akSpell.HasKeyword(MagicShout)
		If PlayerRef.IsInCombat() && SPEShoutExp.GetValue() == 1
			float RecoveryMult = PlayerRef.GetAV("ShoutRecoveryMult")
			If RecoveryMult > 0
				Game.AdvanceSkill("Speechcraft", PlayerRef.GetVoiceRecoveryTime() / RecoveryMult) ;Fus (15s) = 42 gold sale
			Else
				Game.AdvanceSkill("Speechcraft", 15.0)
			EndIf
		EndIf
	ElseIf isIngredient
		If SPEIngredientExp.GetValue() == 1
			Game.AdvanceSkill("Alchemy", 10.00)
		EndIf
	ElseIf isPotion
		If isPotion.IsFood() && SPEFoodExpMode.GetValue() == 1
			CalculateFoodExp(isPotion)
		ElseIf akSpell.HasKeyword(MagicAlchBeneficial) || akSpell.HasKeyword(MagicAlchHarmful)
			If SPEPotionExp.GetValue() == 1
				Game.AdvanceSkill("Alchemy", 30.00) ;equivalent to making a potion with a value of 40 gold
			EndIf
		ElseIf SPEFoodExpMode.GetValue() != 0 ;food is alch xp mode, or fallback from no SKSE
			Game.AdvanceSkill("Alchemy", 3.00)
		EndIf
	EndIf
EndEvent

Event OnUpdate()
	If levelStats
		levelStats = false
		LevelStats()
	EndIf
	If running
		Step()
		RegisterForSingleUpdate(1)
	EndIf
EndEvent

Event OnLocationChange(Location akOldLoc, Location akNewLoc)
	ArmorAdvances = 0
EndEvent

Function OnRunStart(string eventName, string strArg, float numArg, Form sender)
	If SPEArmorExp.GetValue() != 0
		ArmorAdvances = 0
		running = true
		RegisterForSingleUpdate(0)
	EndIf
EndFunction

Function OnRunStop(string eventName, string strArg, float numArg, Form sender)
	running = false
EndFunction

Function Step()
	If ArmorAdvances < MaxAdvances
		ArmorCounter += 1
		While ArmorCounter >= SPEArmorExp.GetValue()
			ArmorAdvances += 1
			ArmorCounter -= (SPEArmorExp.GetValue() as int)
			int skillExp = SPEHeavyPieces.GetValue() as int
			If skillExp > 0
				Game.AdvanceSkill("HeavyArmor", skillExp)
			EndIf
			skillExp = SPELightPieces.GetValue() as int
			If skillExp > 0
				Game.AdvanceSkill("LightArmor", skillExp)
			EndIf
		EndWhile
	EndIf
EndFunction

Function ResetArmorExp(string eventName, string strArg, float numArg, Form sender)
	If SPEArmorExp.GetValue() != 0
		MaxAdvances = (Timeout / SPEArmorExp.GetValue()) as Int
	EndIf
EndFunction

Function CalculateFoodExp(Potion food)
	int i = food.GetNumEffects()
	MagicEffect currentEffect
	While i > 0
		i -= 1
		currentEffect = food.GetNthEffectMagicEffect(i)
		If currentEffect.HasKeyword(MagicAlchRestoreStamina)
			If food.HasKeyword(MagicAlchHarmful) ;alcohol
				staminaExp += (food.GetNthEffectMagnitude(i) / 10)
			Else ;food
				staminaExp += Math.pow(food.GetNthEffectMagnitude(i) as float, 0.7)
				staminaExp += Math.pow(food.GetNthEffectDuration(i) as float, 0.3)
			EndIf
		ElseIf currentEffect.HasKeyword(MagicAlchRestoreHealth) || currentEffect.HasKeyword(MagicAlchFortifyHealRate)
			If food.HasKeyword(MagicAlchHarmful) ;alcohol
				healthExp += (food.GetNthEffectMagnitude(i) / 10)
			Else ;food
				healthExp += Math.pow(food.GetNthEffectMagnitude(i) as float, 0.7)
				healthExp += Math.pow(food.GetNthEffectDuration(i) as float, 0.3)
			EndIf
		ElseIf currentEffect.HasKeyword(MagicAlchRestoreMagicka) || currentEffect == FoodFortifyMagicka
			If food.HasKeyword(MagicAlchHarmful) ;alcohol
				magickaExp += (food.GetNthEffectMagnitude(i) / 10)
			Else ;food
				magickaExp += Math.pow(food.GetNthEffectMagnitude(i) as float, 0.7)
				magickaExp += Math.pow(food.GetNthEffectDuration(i) as float, 0.3)
			EndIf
		EndIf
	EndWhile
	levelStats = true
	RegisterForSingleUpdate(0)
EndFunction

Function LevelStats()

	;calculate stamina and carry weight gains
	int statGains = 0
	While staminaExp >= nextStamina
		statGains += 1
		carryWeightGains += 0.5
		staminaExp -= nextStamina
		nextStamina *= ExpMultiplier
	EndWhile
	
	;mod stamina
	If statGains >= 1
		SPEStaminaUp.Show(statGains)
		PlayerRef.SetAV("Stamina", PlayerRef.GetBaseAV("Stamina") + statGains)
	EndIf
	
	;mod carry weight
	statGains = 0
	While carryWeightGains >= 1
		statGains += 1
		carryWeightGains -= 1
	EndWhile
	If statGains >= 1
		PlayerRef.SetAV("CarryWeight", PlayerRef.GetBaseAV("CarryWeight") + statGains)
		SPECarryWeightUp.Show(statGains)
	EndIf
	
	;calculate and mod health gains
	statGains = 0
	While healthExp >= nextHealth
		statGains += 1
		healthExp -= nextHealth
		nextHealth *= ExpMultiplier
	EndWhile
	If statGains >= 1
		PlayerRef.SetAV("Health", PlayerRef.GetBaseAV("Health") + statGains)
		SPEHealthUp.Show(statGains)
	EndIf
	
	;calculate and mod magicka gains
	statGains = 0
	While magickaExp >= nextMagicka
		statGains += 1
		magickaExp -= nextMagicka
		nextMagicka *= ExpMultiplier
	EndWhile
	If statGains >= 1
		PlayerRef.SetAV("Magicka", PlayerRef.GetBaseAV("Magicka") + statGains)
		SPEMagickaUp.Show(statGains)
	EndIf
EndFunction

And here is a picture of my edits on the .esp I tried to make:

https://ibb.co/Thk4bhD

EDIT: Alternatively Sperg lets you pick between increasing stats or Alchemy exp when eating food. using Alchemy exp option works with no problem. I made sure to use Stat Gain option in testing.

Thank you very much.

Edited by GasilAlvarado
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...