Skip to content

Instantly share code, notes, and snippets.

@Scrivener07
Last active January 5, 2021 19:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Scrivener07/70367acff281e4c826c7c951e9c3b659 to your computer and use it in GitHub Desktop.
Save Scrivener07/70367acff281e4c826c7c951e9c3b659 to your computer and use it in GitHub Desktop.
A script that gets the player's equipped armor and weapons weight, and reduce the movement speed by that much % as a number.
ScriptName EquipmentSpeed Extends ActiveMagicEffect
{A script that gets the player's equipped armor and weapons weight, and reduce the movement speed by that much % as a number.}
Actor Subject
int Value = 0 ; Used to restore the actor's `Speed` value.
Group Properties
string Property EmptyState = "" AutoReadOnly Hidden
string Property EvaluationState = "Evaluation" AutoReadOnly Hidden
bool Property IsEvaluating Hidden
{Returns true when this script has the `Evaluation` state.}
bool Function Get()
return self.GetState() == EvaluationState
EndFunction
EndProperty
EndGroup
Group AVIF
ActorValue Property CarryWeight Auto Const Mandatory
ActorValue Property SpeedMult Auto Const Mandatory
EndGroup
; Group GMST
; string Property MoveSprintMult = "fMoveSprintMult" AutoReadOnly Hidden
; EndGroup
; Events
;---------------------------------------------
Event OnEffectStart(Actor target, Actor caster)
If (target)
Debug.TraceSelf(self, "OnEffectStart", "Starting..")
Subject = target
Value = 0
RegisterForRemoteEvent(Subject, "OnItemEquipped")
RegisterForRemoteEvent(Subject, "OnItemUnequipped")
RegisterForRemoteEvent(Subject, "OnPlayerModArmorWeapon")
If (IsEvaluating)
Debug.TraceSelf(self, "OnEffectStart", "Ignored")
return
Else
Debug.TraceSelf(self, "OnEffectStart", "Evaluating..")
GotoState(EvaluationState)
EndIf
Else
Debug.TraceSelf(self, "OnEffectStart", "The actor target cannot be none.")
EndIf
EndEvent
Event Actor.OnItemEquipped(Actor sender, Form object, ObjectReference reference)
If (IsEvaluating)
Debug.TraceSelf(self, "Actor.OnItemEquipped", "Ignored")
return
Else
If (Filter(object))
Debug.TraceSelf(self, "Actor.OnItemEquipped", "'"+object.GetName()+"'")
GotoState(EvaluationState)
EndIf
EndIf
EndEvent
Event Actor.OnItemUnequipped(Actor sender, Form object, ObjectReference reference)
If (IsEvaluating)
Debug.TraceSelf(self, "Actor.OnItemUnequipped", "Ignored")
return
Else
If (Filter(object))
Debug.TraceSelf(self, "Actor.OnItemUnequipped", "'"+object.GetName()+"'")
GotoState(EvaluationState)
EndIf
EndIf
EndEvent
; Remarks
; -Optimize this by only evaluating when an *equipped* item is modified.
Event Actor.OnPlayerModArmorWeapon(Actor sender, Form object, ObjectMod omod)
If (IsEvaluating)
Debug.TraceSelf(self, "Actor.OnPlayerModArmorWeapon", "Ignored")
return
Else
If (Filter(object))
Debug.TraceSelf(self, "Actor.OnPlayerModArmorWeapon", "'"+object.GetName()+"'")
GotoState(EvaluationState)
EndIf
EndIf
EndEvent
; States
;---------------------------------------------
State Evaluation
Event OnBeginState(string oldState)
If (Value > 0)
Debug.TraceSelf(self, "Evaluation.OnBeginState", "Restoring previous `SpeedMult` damage of "+Value)
Subject.RestoreValue(SpeedMult, Value)
Value = 0
EndIf
int weight = Weights()
Debug.TraceSelf(self, "Evaluation.OnBeginState", "weight:"+weight)
If (weight > 0)
float capacity = Subject.GetValue(CarryWeight)
Debug.TraceSelf(self, "Evaluation.OnBeginState", "CarryWeight:"+capacity)
float speed = Subject.GetValue(SpeedMult)
Debug.TraceSelf(self, "Evaluation.OnBeginState", "SpeedMult:"+speed)
;---------------------------------------------
float percentage = Math.Ceiling((weight / capacity) * 100)
Debug.TraceSelf(self, "Evaluation.OnBeginState", "Calculated: [("+weight+"/"+capacity+")*100] is "+percentage+"%")
Value = Math.Ceiling(percentage)
Debug.TraceSelf(self, "Evaluation.OnBeginState", "Damaged `SpeedMult` with "+Value)
Subject.DamageValue(SpeedMult, Value)
EndIf
GotoState(EmptyState)
EndEvent
Event OnEndState(string newState)
Debug.TraceSelf(self, "Evaluation.OnEndState", "\n")
Debug.Notification("Equipment weight damages `SpeedMult` for "+Value)
EndEvent
EndState
; Methods
;---------------------------------------------
bool Function Filter(Form object)
{Filters high volume events.}
If (object is Weapon)
return true
ElseIf (object is Armor)
return true
Else
return false
EndIf
EndFunction
int Function WeightFor(int index)
InstanceData:Owner instance = Subject.GetInstanceOwner(index)
If (instance)
int weight = Math.Ceiling(InstanceData.GetWeight(instance))
Debug.TraceSelf(self, "WeightFor<slot:"+index+">", "weight:"+weight)
return weight
Else
Debug.TraceSelf(self, "WeightFor<slot:"+index+">", "The `instance` value is none.")
return 0
EndIf
EndFunction
int Function WeightOf(Form object)
If (object)
If (Filter(object))
int weight = Math.Ceiling(object.GetWeight())
Debug.TraceSelf(self, "WeightOf<"+object+">", "weight:"+weight)
return weight
Else
Debug.TraceSelf(self, "WeightOf<"+object+">", "The `object` value has failed the filter condition.")
return 0
EndIf
Else
Debug.TraceSelf(self, "WeightOf<object>", "The `object` value is none.")
return 0
EndIf
EndFunction
bool Function Contains(Form[] array, Form object)
return array.Find(object) > -1
EndFunction
; Gets the actor's equipped armor and weapon weight.
;
; Remarks
; -Optimize this by further limiting the range of scanned slots.
int Function Weights()
int result = 0
Form[] equipment = new Form[0]
int index = 0
int end = 43 const
while (index < end)
int weight = 0
Actor:WornItem worn = Subject.GetWornItem(index)
weight = WeightFor(index)
If (weight > 0)
result += weight
equipment.Add(worn.Item)
equipment.Add(worn.Model)
Debug.TraceSelf(self, "Weights[slot:"+index+"].Instance", "weight:"+weight+", result:"+result)
EndIf
If (weight == 0 && !Contains(equipment, worn.Item))
weight = WeightOf(worn.Item)
If (weight > 0)
equipment.Add(worn.Item)
equipment.Add(worn.Model)
result += weight
Debug.TraceSelf(self, "Weights[slot:"+index+"].Item", "weight:"+weight+", result:"+result+", name:"+worn.Item.GetName())
Else
Debug.TraceSelf(self, "Weights[slot:"+index+"].Item", "weight:ZERO, result:"+result)
EndIf
EndIf
If (weight == 0 && !Contains(equipment, worn.Model))
weight = WeightOf(worn.Model)
If (weight > 0)
equipment.Add(worn.Item)
equipment.Add(worn.Model)
result += weight
Debug.TraceSelf(self, "Weights[slot:"+index+"].Model", "weight:"+weight+", result:"+result+", name:"+worn.Model.GetName())
Else
Debug.TraceSelf(self, "Weights[slot:"+index+"].Model", "weight:ZERO, result:"+result)
EndIf
EndIf
index += 1
;---------------------------------------------
EndWhile
Debug.TraceSelf(self, "Weights", "Found "+result+" pounds of equipment from `"+equipment+"` items.")
return result
EndFunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment