Skyrim Scripting 4: Manipulating actor values and functions

Created:

Updated:

,

Last time: We prepared the OnLevelUp functionality and began the feature script and quest object. This time we will be writing functions that grab the values from our mcm sliders and buttons to set actorvalues to a specific value upon leveling up. We will go through modify actor values, writing functions and using functions and variables from 1 script into another.

  1. Open the mcm script we made, I called mine MCMScript_kx
  2. We need to write a new float property for each actor value. Float Property hpGained Auto. This will be used to store the current stat changes, which is important so that we can reverse said changes later.
  3. We then need two integer properties, one for current level and for last level the mod calculated. Int property playerLevel auto. int property levelOfLastCalc auto
  4. Write a function called function ResetStats(). Functions are basically blocks of saved code we can activate by just writing the function name, rather than rewriting the entire contents of the function every time they are needs. We want the mod to remove any stat changes before applying new changes, to reset stats with a button. So we make a function instead of writing it twice or more.
  5. The first thing this function will do is subtract the hpGained from the current health value, effectively resetting it. Game.GetPlayer().SetActorValue(“health”, Game.GetPlayer().GetBaseActorValue(“health”) – hpGained)
  6. Repeat step 5 for each actor value. Again we just doing the 3 attributes for this tutorial,
  7. we next need to set each of our “Gained” properties to 0. hpGained = 0
  8. Lastly for this function we want to play a notification for the user when the stats are reset using the button.
    1. If (resetStatsB == true)
    2. Debug.notification(“Balanced Leveling has removed it’s stat changes”)
    3. endIf
  9. Then set the resetStats boolean to false. resetStatsB = false. This ensures the option in the menu is unticked.
  10. Then of course don’t forget endFunction
  11. Now this function is never called and so currently is just holding instructions that are never triggered. We want them to trigger when the user clicks the Reset Stats button.
    1. Find the ResetStats state
    2. in the OnSelectST event right our function name at the bottom, including the brackets
    3. ResetStats(). Simple as that, everything inside that function will be triggered every time the button is clicked (well once gameplay resumes, the engine pauses most things while in menus).
  12. Next we need another function that will calculate and alter the stats, according to the parameters set.
    1. Function StatCalc()
    2. ResetStats() we wants stats reset before we calculate them, as our calculations are based current player level to ensure they are retroactive.
    3. Update the playerLevel property; playerLevel = Game.GetPlayer().GetLevel()
    4. Calculate and set the new actor value;
    5. Game.GetPlayer().SetActorValue(“health”, (hpF * playerLevel) + Game.GetPlayer().GetBaseActorValue(“health”))
    6. Repeat for each actor value. Then for each we also need to update our gained properties:
    7. hpGained = hpF * playerLevel
    8. Update last level calculated on; levelOfLastCalc = playerLevel
    9. and finally a notification to let the player know the mod is working.
    10. Debug.notification(“Balanced leveling has detected the player has leveled up to level: ” + playerLevel + “!”)
  13. like the other function this one is just unused instructions until we call it.
  14. so we need to call it inside the ForceCalc states onselect state.

and now our core features are working, you can even test them in game. But we are missing one crucial step, triggering the features when the player levels up. This will require calling our new functions from within our separate level up script, which we will do in the next guide.

Scriptname MCMScript_kx extends SKI_ConfigBase  
	
bool property toggleModB Auto
bool property resetStatsB Auto
bool property forceCalcB Auto

float property hpF Auto
float property hpGained Auto
float property magF Auto
float property magGained Auto
float property stamF Auto
float property stamGained Auto

int property playerLevel auto
int property levelOfLastCalc auto ;The level the player was last time stats were calculated
	
event OnPageReset(string page)
	SetCursorFillMode(LEFT_TO_RIGHT)
	
	AddHeaderOption("Mod Settings") ;L1
	AddEmptyOption() ; R1
	
	AddToggleOptionST("ToggleMod", "Toggle Entire Mod", toggleModB) ;L2
	AddToggleOptionST("ResetStats", "Reset mod altered", resetStatsB) ;R2
	AddToggleOptionST("ForceCalc", "Force Stat Calculation", forceCalcB) ;L3
	
	AddEmptyOption() ;R4
	AddHeaderOption("Attributes");L4
	AddEmptyOption() ;R5
	AddSliderOptionST("hp", "Health", hpF)
	AddSliderOptionST("mag", "Magicka", magF)
	AddSliderOptionST("stam", "Stamina", stamF)
endEvent

;toggle states
State ToggleMod
	Event OnSelectST()
		toggleModB = !toggleModB
		SetToggleOptionValueST(toggleModB)
	endEvent
	
	Event OnHighlightST()
		SetInfoText("This turns off all mod features. But it does not reset stats")
	endEvent
endState
State ResetStats
	Event OnSelectST()
		resetStatsB = !resetStatsB
		SetToggleOptionValueST(resetStatsB)
		ResetStats()
	endEvent
	
	Event OnHighlightST()
		SetInfoText("This will remove this mods changes to stats once gameplay is resumed")
	endEvent
endState
State ForceCalc
	Event OnSelectST()
		forceCalcB = !forceCalcB
		SetToggleOptionValueST(forceCalcB)
		if forceCalcB == true
			StatCalc()
			forceCalcB = false
		endIf
	endEvent
	
	Event OnHighlightST()
		SetInfoText("This will retroactively update player stats according to current mod settings once gameplay resumes")
	endEvent
endState
;slider states
State hp
	event OnSliderOpenST()
		SetSliderDialogStartValue(hpF)
		SetSliderDialogDefaultValue(1)
		SetSliderDialogRange(-10, 10)
		SetSliderDialogInterval(1)
	endEvent
	
	Event OnSliderAcceptST(float value)
		hpf = value
		SetSliderOptionValueST(hpF)
	endEvent
	
	event OnHighlightST()
		SetInfoText("Health change per level")
	endEvent
endState
State mag
	event OnSliderOpenST()
		SetSliderDialogStartValue(magF)
		SetSliderDialogDefaultValue(1)
		SetSliderDialogRange(-10, 10)
		SetSliderDialogInterval(1)
	endEvent
	
	Event OnSliderAcceptST(float value)
		magF = value
		SetSliderOptionValueST(magF)
	endEvent
	
	event OnHighlightST()
		SetInfoText("Magicka change per level")
	endEvent
endState
State stam
	event OnSliderOpenST()
		SetSliderDialogStartValue(stamF)
		SetSliderDialogDefaultValue(1)
		SetSliderDialogRange(-10, 10)
		SetSliderDialogInterval(1)
	endEvent
	
	event OnSliderAcceptSt(float value)
		stamF = value
		SetSliderOptionValueST(stamF)
	endEvent
	
	event OnHighlightST()
		SetInfoText("Stamina change per level")
	endEvent
endState

function StatCalc()
	ResetStats()
	
	playerLevel = Game.GetPlayer().GetLevel()
	
	Game.GetPlayer().SetActorValue("health",  (hpF * playerLevel) + Game.GetPlayer().GetBaseActorValue("health"))
	Game.GetPlayer().SetActorValue("magicka", (magF * playerLevel) + Game.GetPlayer().GetBaseActorValue("magicka"))
	Game.GetPlayer().SetActorValue("stamina", (stamF * playerLevel) + Game.GetPlayer().GetBaseActorValue("stamina"))
	
	hpGained = hpF * playerLevel
	magGained = magF * playerLevel
	stamGained = stamF * playerLevel
	
	levelOfLastCalc = playerLevel
	Debug.notification("Balanced leveling has detected the player has leveled up to level: " + playerLevel + "!")
endFunction

function ResetStats()
		Game.GetPlayer().SetActorValue("health", Game.GetPlayer().GetBaseActorValue("health") - hpGained)   ;Remove mods changes
		Game.GetPlayer().SetActorValue("magicka", Game.GetPlayer().GetBaseActorValue("magicka") - magGained)
		Game.GetPlayer().SetActorValue("stamina", Game.GetPlayer().GetBaseActorValue("stamina")- stamGained)	
		
		hpGained = 0 
		stamGained = 0
		magGained = 0
		
		resetStatsB = false
		if (resetStatsB == true)
			Debug.notification("Balanced Leveling has removed it's stat changes")
		endIf		
endFunction