Last active
January 5, 2021 19:14
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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