Scriptname RaceMenuPluginXPMSE extends RaceMenuBase

;Camera
string Property NINODE_CAMERA1 = "CME Camera1st [Cam1]" AutoReadOnly
string Property NINODE_CAMERA3 = "CME Camera3rd [Cam3]" AutoReadOnly

string Property NINODE_ROOT = "NPC Root [Root]" AutoReadOnly
string Property NINODE_COM = "NPC COM [COM ]" AutoReadOnly
string Property NINODE_BODY_CME = "CME Body [Body]" AutoReadOnly
string Property NINODE_BODY_LOWER_CME = "CME LBody [LBody]" AutoReadOnly
string Property NINODE_BODY_UPPER_CME = "CME UBody [UBody]" AutoReadOnly
string Property NINODE_NECK_CME = "CME Neck [Neck]" AutoReadOnly
string Property NINODE_PELVIS = "NPC Pelvis [Pelv]" AutoReadOnly
string Property NINODE_PELVIS_CME = "CME Pelvis [Pelv]" AutoReadOnly
string Property NINODE_SPINE_CME = "CME Spine [Spn0]" AutoReadOnly
string Property NINODE_SPINE_1_CME = "CME Spine1 [Spn1]" AutoReadOnly
string Property NINODE_SPINE_2_CME = "CME Spine2 [Spn2]" AutoReadOnly
string Property NINODE_LEFT_THIGH = "NPC L Thigh [LThg]" AutoReadOnly
string Property NINODE_LEFT_THIGH_CME = "CME L Thigh [LThg]" AutoReadOnly
string Property NINODE_RIGHT_THIGH = "NPC R Thigh [RThg]" AutoReadOnly
string Property NINODE_RIGHT_THIGH_CME = "CME R Thigh [RThg]" AutoReadOnly
string Property NINODE_LEFT_CALF = "NPC L Calf [LClf]" AutoReadOnly
string Property NINODE_LEFT_CALF_CME = "CME L Calf [LClf]" AutoReadOnly
string Property NINODE_RIGHT_CALF = "NPC R Calf [RClf]" AutoReadOnly
string Property NINODE_RIGHT_CALF_CME = "CME R Calf [RClf]" AutoReadOnly
string Property NINODE_LEFT_FOOT = "NPC L Foot [Lft ]" AutoReadOnly
string Property NINODE_LEFT_FOOT_CME = "CME L Foot [Lft ]" AutoReadOnly
string Property NINODE_RIGHT_FOOT = "NPC R Foot [Rft ]" AutoReadOnly
string Property NINODE_RIGHT_FOOT_CME = "CME R Foot [Rft ]" AutoReadOnly
string Property NINODE_LEFT_CLAVICLE = "NPC L Clavicle [LClv]" AutoReadOnly
string Property NINODE_LEFT_CLAVICLE_CME = "CME L Clavicle [LClv]" AutoReadOnly
string Property NINODE_RIGHT_CLAVICLE = "NPC R Clavicle [RClv]" AutoReadOnly
string Property NINODE_RIGHT_CLAVICLE_CME = "CME R Clavicle [RClv]" AutoReadOnly
string Property NINODE_LEFT_UPPERARM = "NPC L UpperArm [LUar]" AutoReadOnly
string Property NINODE_LEFT_UPPERARM_CME = "CME L UpperArm [LUar]" AutoReadOnly
string Property NINODE_RIGHT_UPPERARM = "NPC R UpperArm [RUar]" AutoReadOnly
string Property NINODE_RIGHT_UPPERARM_CME = "CME R UpperArm [RUar]" AutoReadOnly
string Property NINODE_LEFT_HAND = "NPC L Hand [LHnd]" AutoReadOnly
string Property NINODE_LEFT_HAND_CME = "CME L Hand [LHnd]" AutoReadOnly
string Property NINODE_RIGHT_HAND = "NPC R Hand [RHnd]" AutoReadOnly
string Property NINODE_RIGHT_HAND_CME = "CME R Hand [RHnd]" AutoReadOnly
string Property NINODE_LEFT_FOREARMTWIST_1 = "NPC L ForearmTwist1 [LLt1]" AutoReadOnly
string Property NINODE_RIGHT_FOREARMTWIST_1 = "NPC R ForearmTwist1 [RLt1]" AutoReadOnly
string Property NINODE_LEFT_FOREARMTWIST_2 = "NPC L ForearmTwist2 [LLt2]" AutoReadOnly
string Property NINODE_RIGHT_FOREARMTWIST_2 = "NPC R ForearmTwist2 [RLt2]" AutoReadOnly

string Property NINODE_AXE = "WeaponAxe" AutoReadOnly
string Property NINODE_MACE = "WeaponMace" AutoReadOnly
string Property NINODE_SWORD = "WeaponSword" AutoReadOnly
string Property NINODE_DAGGER = "WeaponDagger" AutoReadOnly
string Property NINODE_QUIVER = "QUIVER" AutoReadOnly
string Property NINODE_AXE_LEFT = "WeaponAxeLeft" AutoReadOnly
string Property NINODE_MACE_LEFT = "WeaponMaceLeft" AutoReadOnly
string Property NINODE_SWORD_LEFT = "WeaponSwordLeft" AutoReadOnly
string Property NINODE_DAGGER_LEFT = "WeaponDaggerLeft" AutoReadOnly
string Property NINODE_BOLT = "BOLT" AutoReadOnly
string Property NINODE_BOLT_QUIVER = "BOLT_QUIVER" AutoReadOnly
string Property NINODE_SWORD_ALT = "WeaponSwordOnBack" AutoReadOnly
string Property NINODE_SWORD_LEFT_ALT = "WeaponSwordLeftOnBack" AutoReadOnly
string Property NINODE_DAGGER_ALT = "WeaponDaggerAnkle" AutoReadOnly
string Property NINODE_DAGGER_LEFT_ALT = "WeaponDaggerLeftAnkle" AutoReadOnly
string Property NINODE_QUIVER_ALT = "QUIVERLeftHipBolt" AutoReadOnly

;Callbacks Table
string Property CALLBACK_HEAD_POS = "XPMSEChangeHeadPos" AutoReadOnly
string Property CALLBACK_LEFT_UPPERARM_SCALE = "XPMSEChangeLeftUpperArmSize" AutoReadOnly
string Property CALLBACK_RIGHT_UPPERARM_SCALE = "XPMSEChangeRightUpperArmSize" AutoReadOnly
string Property CALLBACK_LEFT_FOREARMTWIST_1_SCALE = "XPMSEChangeLeftForearmTwist" AutoReadOnly
string Property CALLBACK_RIGHT_FOREARMTWIST_1_SCALE = "XPMSEChangeRightForearmTwist" AutoReadOnly
string Property CALLBACK_LEFT_FOREARMTWIST_2_SCALE = "XPMSEChangeLeftForearmTwist2" AutoReadOnly
string Property CALLBACK_RIGHT_FOREARMTWIST_2_SCALE = "XPMSEChangeRightForearmTwist2" AutoReadOnly
string Property CALLBACK_LEFT_HAND_SCALE = "XPMSEChangeLeftHandSize" AutoReadOnly
string Property CALLBACK_RIGHT_HAND_SCALE = "XPMSEChangeRighHandSize" AutoReadOnly
string Property CALLBACK_LEFT_CLAVICLE_SCALE = "XPMSEChangeLeftClavicleSize" AutoReadOnly
string Property CALLBACK_RIGHT_CLAVICLE_SCALE = "XPMSEChangeRightClavicleSize" AutoReadOnly
string Property CALLBACK_WAIST_SCALE = "XPMSEChangeWaistSize" AutoReadOnly
string Property CALLBACK_LEFT_THIGH_SCALE = "XPMSEChangeLeftThighSize" AutoReadOnly
string Property CALLBACK_RIGHT_THIGH_SCALE = "XPMSEChangeRightThighSize" AutoReadOnly
string Property CALLBACK_LEFT_CALF_SCALE = "XPMSEChangeLeftCalfSize" AutoReadOnly
string Property CALLBACK_RIGHT_CALF_SCALE = "XPMSEChangeRightCalfSize" AutoReadOnly
string Property CALLBACK_LEFT_FOOT_SCALE = "XPMSEChangeLeftFootSize" AutoReadOnly
string Property CALLBACK_RIGHT_FOOT_SCALE = "XPMSEChangeRightFootSize" AutoReadOnly
string Property CALLBACK_LEG_SCALE = "XPMSEChangeLegSize" AutoReadOnly
string Property CALLBACK_LEG_LENGTH_THIGH = "XPMSEChangeLegLengthThigh" AutoReadOnly
string Property CALLBACK_LEG_LENGTH_CALF = "XPMSEChangeLegLengthCalf" AutoReadOnly
string Property CALLBACK_SPINE0_LENGTH = "XPMSEChangeSpine0Length" AutoReadOnly
string Property CALLBACK_SPINE1_LENGTH = "XPMSEChangeSpine1Length" AutoReadOnly
string Property CALLBACK_SPINE2_LENGTH = "XPMSEChangeSpine2Length" AutoReadOnly
string Property CALLBACK_SPINE3_LENGTH = "XPMSEChangeSpine3Length" AutoReadOnly

;Arrays
float[] _head_Position
float[] _thigh_Length
float[] _calf_Length
float[] _spine0_Length
float[] _spine1_Length
float[] _spine2_Length
float[] _spine3_Length

; If you are making your own scaling mod, use your own key name
string Property MOD_OVERRIDE_KEY = "RMXPlugin" AutoReadOnly
string Property RMX_LEG_KEY = "RMX_Leg" AutoReadOnly
string Property RMX_LEG_THIGH_KEY = "RMX_Leg_Thigh" AutoReadOnly
string Property RMX_LEG_CALF_KEY = "RMX_Leg_Calf" AutoReadOnly
string Property RMX_SPINE0_KEY = "RMX_Spine0" AutoReadOnly
string Property RMX_SPINE1_KEY = "RMX_Spine1" AutoReadOnly
string Property RMX_SPINE2_KEY = "RMX_Spine2" AutoReadOnly
string Property RMX_SPINE3_KEY = "RMX_Spine3" AutoReadOnly


string Property CATEGORY_KEY = "rsm_body_scale" AutoReadOnly

; NiOverride version data
int Property NIOVERRIDE_VERSION = 3 AutoReadOnly
int Property NIOVERRIDE_SCRIPT_VERSION = 2 AutoReadOnly

bool _versionValid = false

Event OnCategoryRequest()
	AddCategory(CATEGORY_KEY, "$BODY SCALES")
EndEvent

Event OnStartup()
	parent.OnStartup()

	int nioverrideVersion = SKSE.GetPluginVersion("NiOverride")
	int nioverrideScriptVersion = NiOverride.GetScriptVersion()

	; Check NiOverride version, disable most features if this fails
	if nioverrideVersion >= NIOVERRIDE_VERSION && nioverrideScriptVersion >= NIOVERRIDE_SCRIPT_VERSION
		_versionValid = true
	Else
		_versionValid = false
	Endif
EndEvent

; Add Custom sliders here
Event OnSliderRequest(Actor target, ActorBase targetBase, Race actorRace, bool isFemale)
	If NetImmerse.HasNode(target, NINODE_NECK_CME, false)
		_head_Position = GetNodePosition(target, isFemale, NINODE_NECK_CME)
		AddSliderEx("$HeadPos", CATEGORY_HEAD, CALLBACK_HEAD_POS, -4.00, 4.00, 0.01, _head_Position[2])
	Endif
	
	If NetImmerse.HasNode(target, NINODE_LEFT_UPPERARM_CME, false)
		AddSliderEx("$Left Upper Arm", CATEGORY_KEY, CALLBACK_LEFT_UPPERARM_SCALE, 0.80, 1.20, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_UPPERARM))
	Endif	
	If NetImmerse.HasNode(target, NINODE_RIGHT_UPPERARM_CME, false)
		AddSliderEx("$Right Upper Arm", CATEGORY_KEY, CALLBACK_RIGHT_UPPERARM_SCALE, 0.80, 1.20, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_UPPERARM))
	Endif
	
	AddSliderEx("$Left ForearmTwist", CATEGORY_KEY, CALLBACK_LEFT_FOREARMTWIST_1_SCALE, 0.60, 1.40, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_FOREARMTWIST_1))
	AddSliderEx("$Right ForearmTwist", CATEGORY_KEY, CALLBACK_RIGHT_FOREARMTWIST_1_SCALE, 0.60, 1.40, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_FOREARMTWIST_1))
	AddSliderEx("$Left ForearmTwist 2", CATEGORY_KEY, CALLBACK_LEFT_FOREARMTWIST_2_SCALE, 0.60, 1.40, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_FOREARMTWIST_2))
	AddSliderEx("$Right ForearmTwist 2", CATEGORY_KEY, CALLBACK_RIGHT_FOREARMTWIST_2_SCALE, 0.60, 1.40, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_FOREARMTWIST_2))
	If NetImmerse.HasNode(target, NINODE_LEFT_HAND_CME, false)
		AddSliderEx("$Left Hand", CATEGORY_KEY, CALLBACK_LEFT_HAND_SCALE, 0.60, 1.40, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_HAND))
	Endif
	If NetImmerse.HasNode(target, NINODE_RIGHT_HAND_CME, false)
		AddSliderEx("$Right Hand", CATEGORY_KEY, CALLBACK_RIGHT_HAND_SCALE, 0.60, 1.40, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_HAND))
	Endif
	If NetImmerse.HasNode(target, NINODE_LEFT_CLAVICLE_CME, false)
		AddSliderEx("$Left Clavicle", CATEGORY_KEY, CALLBACK_LEFT_CLAVICLE_SCALE, 0.80, 1.20, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_CLAVICLE))
	Endif
	If NetImmerse.HasNode(target, NINODE_RIGHT_CLAVICLE_CME, false)
		AddSliderEx("$Right Clavicle", CATEGORY_KEY, CALLBACK_RIGHT_CLAVICLE_SCALE, 0.80, 1.20, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_CLAVICLE))
	Endif
	If NetImmerse.HasNode(target, NINODE_SPINE_CME, false) && NetImmerse.HasNode(target, NINODE_SPINE_1_CME, false)
		AddSliderEx("$Waist", CATEGORY_KEY, CALLBACK_WAIST_SCALE, 0.80, 1.20, 0.01, GetNodeScale(target, isFemale, NINODE_SPINE_CME))
	Endif
	If NetImmerse.HasNode(target, NINODE_LEFT_THIGH_CME, false)
		AddSliderEx("$Left Thigh", CATEGORY_KEY, CALLBACK_LEFT_THIGH_SCALE, 0.90, 1.10, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_THIGH))
	Endif
	If NetImmerse.HasNode(target, NINODE_RIGHT_THIGH_CME, false)
		AddSliderEx("$Right Thigh", CATEGORY_KEY, CALLBACK_RIGHT_THIGH_SCALE, 0.90, 1.10, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_THIGH))
	Endif
	If NetImmerse.HasNode(target, NINODE_LEFT_CALF_CME, false)
		AddSliderEx("$Left Calf", CATEGORY_KEY, CALLBACK_LEFT_CALF_SCALE, 0.90, 1.10, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_CALF))
	Endif
	If NetImmerse.HasNode(target, NINODE_RIGHT_CALF_CME, false)
		AddSliderEx("$Right Calf", CATEGORY_KEY, CALLBACK_RIGHT_CALF_SCALE, 0.90, 1.10, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_CALF))
	Endif
	If NetImmerse.HasNode(target, NINODE_LEFT_FOOT_CME, false)
		AddSliderEx("$Left Foot", CATEGORY_KEY, CALLBACK_LEFT_FOOT_SCALE, 0.90, 1.10, 0.01, GetNodeScale(target, isFemale, NINODE_LEFT_FOOT))
	Endif
	If NetImmerse.HasNode(target, NINODE_RIGHT_FOOT_CME, false)
		AddSliderEx("$Right Foot", CATEGORY_KEY, CALLBACK_RIGHT_FOOT_SCALE, 0.90, 1.10, 0.01, GetNodeScale(target, isFemale, NINODE_RIGHT_FOOT))
	Endif
	If NetImmerse.HasNode(target, NINODE_RIGHT_FOOT_CME, false)
		AddSliderEx("$Leg Length", CATEGORY_KEY, CALLBACK_LEG_SCALE, 0.90, 1.10, 0.01, GetNodeScaleEX(target, isFemale, NINODE_LEFT_THIGH, RMX_LEG_KEY))
	Endif
	If NetImmerse.HasNode(target, NINODE_LEFT_THIGH_CME, false) && NetImmerse.HasNode(target, NINODE_RIGHT_THIGH_CME, false) && NetImmerse.HasNode(target, NINODE_BODY_CME, false)
		_thigh_Length = GetNodePositionEX(target, isFemale, NINODE_LEFT_THIGH_CME, RMX_LEG_THIGH_KEY)
		AddSliderEx("$Leg Length Thigh", CATEGORY_KEY, CALLBACK_LEG_LENGTH_THIGH, -10.00, 10.00, 0.01, _thigh_Length[2])
	Endif
	If NetImmerse.HasNode(target, NINODE_LEFT_CALF_CME, false) && NetImmerse.HasNode(target, NINODE_RIGHT_CALF_CME, false) && NetImmerse.HasNode(target, NINODE_BODY_CME, false)
		_calf_Length = GetNodePositionEX(target, isFemale, NINODE_LEFT_CALF_CME, RMX_LEG_CALF_KEY)
		AddSliderEx("$Leg Length Calf", CATEGORY_KEY, CALLBACK_LEG_LENGTH_CALF, -10.00, 10.00, 0.01, _calf_Length[2])
	Endif
	If NetImmerse.HasNode(target, NINODE_BODY_UPPER_CME, false) && NetImmerse.HasNode(target, NINODE_CAMERA3, false) && NetImmerse.HasNode(target, NINODE_CAMERA1, true)
		_spine0_Length = GetNodePositionEX(target, isFemale, NINODE_BODY_UPPER_CME, RMX_SPINE0_KEY)
		AddSliderEx("$Spine0 Length", CATEGORY_KEY, CALLBACK_SPINE0_LENGTH, -5.00, 5.00, 0.01, _spine0_Length[2])
	Endif
	If NetImmerse.HasNode(target, NINODE_SPINE_CME, false) && NetImmerse.HasNode(target, NINODE_CAMERA3, false) && NetImmerse.HasNode(target, NINODE_CAMERA1, true)
		_spine1_Length = GetNodePositionEX(target, isFemale, NINODE_SPINE_CME, RMX_SPINE1_KEY)
		AddSliderEx("$Spine1 Length", CATEGORY_KEY, CALLBACK_SPINE1_LENGTH, -5.00, 5.00, 0.01, _spine1_Length[2])
	Endif
	If NetImmerse.HasNode(target, NINODE_SPINE_1_CME, false) && NetImmerse.HasNode(target, NINODE_CAMERA3, false) && NetImmerse.HasNode(target, NINODE_CAMERA1, true)
		_spine2_Length = GetNodePositionEX(target, isFemale, NINODE_SPINE_1_CME, RMX_SPINE2_KEY)
		AddSliderEx("$Spine2 Length", CATEGORY_KEY, CALLBACK_SPINE2_LENGTH, -5.00, 5.00, 0.01, _spine2_Length[2])
	Endif
	If NetImmerse.HasNode(target, NINODE_SPINE_2_CME, false) && NetImmerse.HasNode(target, NINODE_CAMERA3, false) && NetImmerse.HasNode(target, NINODE_CAMERA1, true)
		_spine3_Length = GetNodePositionEX(target, isFemale, NINODE_SPINE_2_CME, RMX_SPINE3_KEY)
		AddSliderEx("$Spine3 Length", CATEGORY_KEY, CALLBACK_SPINE3_LENGTH, -5.00, 5.00, 0.01, _spine3_Length[2])
	Endif
EndEvent

Event OnSliderChanged(string callback, float value)
	bool isFemale = _targetActorBase.GetSex() as bool
	If _versionValid
		If callback == CALLBACK_HEAD_POS
			_head_Position[2] = value
			SetNodePosition(_targetActor, isFemale, NINODE_NECK_CME, _head_Position)
		Elseif callback == CALLBACK_LEFT_UPPERARM_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_UPPERARM, value)
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_UPPERARM_CME, 1/value)
		Elseif callback == CALLBACK_RIGHT_UPPERARM_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_UPPERARM, value)
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_UPPERARM_CME, 1/value)
		Elseif callback == CALLBACK_LEFT_FOREARMTWIST_1_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_FOREARMTWIST_1, value)
		Elseif callback == CALLBACK_RIGHT_FOREARMTWIST_1_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_FOREARMTWIST_1, value)
		Elseif callback == CALLBACK_LEFT_FOREARMTWIST_2_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_FOREARMTWIST_2, value)
		Elseif callback == CALLBACK_RIGHT_FOREARMTWIST_2_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_FOREARMTWIST_2, value)
		Elseif callback == CALLBACK_LEFT_HAND_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_HAND, value)
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_HAND_CME, 1/value)
		Elseif callback == CALLBACK_RIGHT_HAND_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_HAND, value)
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_HAND_CME, 1/value)
		Elseif callback == CALLBACK_LEFT_CLAVICLE_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_CLAVICLE, value)
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_CLAVICLE_CME, 1/value)		
		Elseif callback == CALLBACK_RIGHT_CLAVICLE_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_CLAVICLE, value)
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_CLAVICLE_CME, 1/value)	
		Elseif callback == CALLBACK_WAIST_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_SPINE_CME, value)
			SetNodeScale(_targetActor, isFemale, NINODE_SPINE_1_CME, 1/value)
		Elseif callback == CALLBACK_LEFT_THIGH_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_THIGH, value)
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_THIGH_CME, 1/value)		
		Elseif callback == CALLBACK_RIGHT_THIGH_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_THIGH, value)
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_THIGH_CME, 1/value)	
		Elseif callback == CALLBACK_LEFT_CALF_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_CALF, value)
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_CALF_CME, 1/value)		
		Elseif callback == CALLBACK_RIGHT_CALF_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_CALF, value)
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_CALF_CME, 1/value)				
		Elseif callback == CALLBACK_LEFT_FOOT_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_FOOT, value)
			SetNodeScale(_targetActor, isFemale, NINODE_LEFT_FOOT_CME, 1/value)		
		Elseif callback == CALLBACK_RIGHT_FOOT_SCALE
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_FOOT, value)
			SetNodeScale(_targetActor, isFemale, NINODE_RIGHT_FOOT_CME, 1/value)	
		Elseif callback == CALLBACK_LEG_LENGTH_THIGH
			_thigh_Length[2] = value
			SetNodePositionEX(_targetActor, isFemale, NINODE_LEFT_THIGH_CME, _thigh_Length, RMX_LEG_THIGH_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_RIGHT_THIGH_CME, _thigh_Length, RMX_LEG_THIGH_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_BODY_CME, _thigh_Length, RMX_LEG_THIGH_KEY)
		Elseif callback == CALLBACK_LEG_LENGTH_CALF
			_calf_Length[2] = value
			SetNodePositionEX(_targetActor, isFemale, NINODE_LEFT_CALF_CME, _calf_Length, RMX_LEG_CALF_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_RIGHT_CALF_CME, _calf_Length, RMX_LEG_CALF_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_BODY_CME, _calf_Length, RMX_LEG_CALF_KEY)	
		Elseif callback == CALLBACK_SPINE0_LENGTH
			_spine0_Length[2] = value
			SetNodePositionEX(_targetActor, isFemale, NINODE_BODY_UPPER_CME, _spine0_Length, RMX_SPINE0_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA3, _spine0_Length, RMX_SPINE0_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA1, _spine0_Length, RMX_SPINE0_KEY)
		Elseif callback == CALLBACK_SPINE1_LENGTH
			_spine1_Length[2] = value
			SetNodePositionEX(_targetActor, isFemale, NINODE_SPINE_CME, _spine1_Length, RMX_SPINE1_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA3, _spine1_Length, RMX_SPINE1_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA1, _spine1_Length, RMX_SPINE1_KEY)
		Elseif callback == CALLBACK_SPINE2_LENGTH
			_spine2_Length[2] = value
			SetNodePositionEX(_targetActor, isFemale, NINODE_SPINE_1_CME, _spine2_Length, RMX_SPINE2_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA3, _spine2_Length, RMX_SPINE2_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA1, _spine2_Length, RMX_SPINE2_KEY)
		Elseif callback == CALLBACK_SPINE3_LENGTH
			_spine3_Length[2] = value
			SetNodePositionEX(_targetActor, isFemale, NINODE_SPINE_2_CME, _spine3_Length, RMX_SPINE3_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA3, _spine3_Length, RMX_SPINE3_KEY)
			SetNodePositionEX(_targetActor, isFemale, NINODE_CAMERA1, _spine3_Length, RMX_SPINE3_KEY)
		Elseif callback == CALLBACK_LEG_SCALE
			SetNodeScaleEX(_targetActor, isFemale, NINODE_LEFT_THIGH, value, RMX_LEG_KEY)
			SetNodeScaleEX(_targetActor, isFemale, NINODE_RIGHT_THIGH, value, RMX_LEG_KEY)
			SetNodeScaleEX(_targetActor, isFemale, NINODE_LEFT_CALF, ((value - 1) * 0.2 + 1), RMX_LEG_KEY)
			SetNodeScaleEX(_targetActor, isFemale, NINODE_RIGHT_CALF, ((value - 1) * 0.2 + 1), RMX_LEG_KEY)
			if value < 1.0
				SetNodeScaleEX(_targetActor, isFemale, NINODE_PELVIS, value, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_COM, (68.9113 / (value * value * (9.7 * value + 59.2113))), RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_ROOT,((125.0 * value * value) / (9.7 * ((value + 6.10426) * value * value + 5.78234))), RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_AXE, value, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_AXE_LEFT, value, RMX_LEG_KEY)	
				SetNodeScaleEX(_targetActor, isFemale, NINODE_MACE, value, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_MACE_LEFT, value, RMX_LEG_KEY)	
				If NetImmerse.HasNode(_targetActor, NINODE_SWORD_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_SWORD, value, RMX_LEG_KEY)	
				EndIf
				If NetImmerse.HasNode(_targetActor, NINODE_SWORD_LEFT_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_SWORD_LEFT, value, RMX_LEG_KEY)	
				EndIf
				If NetImmerse.HasNode(_targetActor, NINODE_DAGGER_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_DAGGER, value, RMX_LEG_KEY)	
				EndIf
				If NetImmerse.HasNode(_targetActor, NINODE_DAGGER_LEFT_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_DAGGER_LEFT, value, RMX_LEG_KEY)	
				EndIf
				If !NetImmerse.HasNode(_targetActor, NINODE_QUIVER_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_QUIVER, value, RMX_LEG_KEY)	
				EndIf
				SetNodeScaleEX(_targetActor, isFemale, NINODE_BOLT, value, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_BOLT_QUIVER, value, RMX_LEG_KEY)	
			else
				SetNodeScaleEX(_targetActor, isFemale, NINODE_PELVIS, 1.0, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_COM, (68.9113 / (value * (value * 9.7 + 59.2113))), RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_ROOT, ((125 * value) / (9.7 *((value + 1.17246) * (value + 4.9318)))), RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_AXE, 1.0, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_AXE_LEFT, 1.0, RMX_LEG_KEY)	
				SetNodeScaleEX(_targetActor, isFemale, NINODE_MACE, 1.0, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_AXE_LEFT, 1.0, RMX_LEG_KEY)	
				If NetImmerse.HasNode(_targetActor, NINODE_SWORD_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_SWORD, 1.0, RMX_LEG_KEY)	
				EndIf
				If NetImmerse.HasNode(_targetActor, NINODE_SWORD_LEFT_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_SWORD_LEFT, 1.0, RMX_LEG_KEY)	
				EndIf
				If NetImmerse.HasNode(_targetActor, NINODE_DAGGER_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_DAGGER, 1.0, RMX_LEG_KEY)	
				EndIf
				If NetImmerse.HasNode(_targetActor, NINODE_DAGGER_LEFT_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_DAGGER_LEFT, 1.0, RMX_LEG_KEY)	
				EndIf
				If !NetImmerse.HasNode(_targetActor, NINODE_QUIVER_ALT, false)
					SetNodeScaleEX(_targetActor, isFemale, NINODE_QUIVER, 1.0, RMX_LEG_KEY)	
				EndIf
				SetNodeScaleEX(_targetActor, isFemale, NINODE_BOLT, 1.0, RMX_LEG_KEY)
				SetNodeScaleEX(_targetActor, isFemale, NINODE_BOLT_QUIVER, 1.0, RMX_LEG_KEY)	
			Endif
		Endif	
	Endif
EndEvent

Function SetNodeScale(Actor akActor, bool isFemale, string nodeName, float value)
	If value != 1.0
		NiOverride.AddNodeTransformScale(akActor, false, isFemale, nodeName, MOD_OVERRIDE_KEY, value)
		NiOverride.AddNodeTransformScale(akActor, true, isFemale, nodeName, MOD_OVERRIDE_KEY, value)
	Else
		NiOverride.RemoveNodeTransformScale(akActor, false, isFemale, nodeName, MOD_OVERRIDE_KEY)
		NiOverride.RemoveNodeTransformScale(akActor, true, isFemale, nodeName, MOD_OVERRIDE_KEY)
	Endif
	NiOverride.UpdateNodeTransform(akActor, false, isFemale, nodeName)
	NiOverride.UpdateNodeTransform(akActor, true, isFemale, nodeName)
EndFunction

Function SetNodeScaleEX(Actor akActor, bool isFemale, string nodeName, float value, string modkey)
	If value != 1.0
		NiOverride.AddNodeTransformScale(akActor, false, isFemale, nodeName, modkey, value)
		NiOverride.AddNodeTransformScale(akActor, true, isFemale, nodeName, modkey, value)
	Else
		NiOverride.RemoveNodeTransformScale(akActor, false, isFemale, nodeName, modkey)
		NiOverride.RemoveNodeTransformScale(akActor, true, isFemale, nodeName, modkey)
	Endif
	NiOverride.UpdateNodeTransform(akActor, false, isFemale, nodeName)
	NiOverride.UpdateNodeTransform(akActor, true, isFemale, nodeName)
EndFunction

Function SetNodePosition(Actor akActor, bool isFemale, string nodeName, float[] values)
	If values[0] != 0.0 || values[1] != 0.0 || values[2] != 0.0
		NiOverride.AddNodeTransformPosition(akActor, false, isFemale, nodeName, MOD_OVERRIDE_KEY, values)
		NiOverride.AddNodeTransformPosition(akActor, true, isFemale, nodeName, MOD_OVERRIDE_KEY, values)
	Else
		NiOverride.RemoveNodeTransformPosition(akActor, false, isFemale, nodeName, MOD_OVERRIDE_KEY)
		NiOverride.RemoveNodeTransformPosition(akActor, true, isFemale, nodeName, MOD_OVERRIDE_KEY)
	Endif
	NiOverride.UpdateNodeTransform(akActor, false, isFemale, nodeName)
	NiOverride.UpdateNodeTransform(akActor, true, isFemale, nodeName)
EndFunction

Function SetNodePositionEX(Actor akActor, bool isFemale, string nodeName, float[] values, string modkey)
	If values[0] != 0.0 || values[1] != 0.0 || values[2] != 0.0
		NiOverride.AddNodeTransformPosition(akActor, false, isFemale, nodeName, modkey, values)
		NiOverride.AddNodeTransformPosition(akActor, true, isFemale, nodeName, modkey, values)
	Else
		NiOverride.RemoveNodeTransformPosition(akActor, false, isFemale, nodeName, modkey)
		NiOverride.RemoveNodeTransformPosition(akActor, true, isFemale, nodeName, modkey)
	Endif
	NiOverride.UpdateNodeTransform(akActor, false, isFemale, nodeName)
	NiOverride.UpdateNodeTransform(akActor, true, isFemale, nodeName)
EndFunction

float Function GetNodeScale(Actor akActor, bool isFemale, string nodeName)
	return NiOverride.GetNodeTransformScale(akActor, false, isFemale, nodeName, MOD_OVERRIDE_KEY)
EndFunction

float Function GetNodeScaleEX(Actor akActor, bool isFemale, string nodeName, string modkey)
	return NiOverride.GetNodeTransformScale(akActor, false, isFemale, nodeName, modkey)
EndFunction

float[] Function GetNodePosition(Actor akActor, bool isFemale, string nodeName)
	return NiOverride.GetNodeTransformPosition(akActor, false, isFemale, nodeName, MOD_OVERRIDE_KEY)
EndFunction

float[] Function GetNodePositionEX(Actor akActor, bool isFemale, string nodeName, string modkey)
	return NiOverride.GetNodeTransformPosition(akActor, false, isFemale, nodeName, modkey)
EndFunction