diff --git a/Assets/Scripts/Game/Player/PlayerSpeedChanger.cs b/Assets/Scripts/Game/Player/PlayerSpeedChanger.cs index 0ea93e5356..8f6a5371a1 100644 --- a/Assets/Scripts/Game/Player/PlayerSpeedChanger.cs +++ b/Assets/Scripts/Game/Player/PlayerSpeedChanger.cs @@ -30,16 +30,20 @@ public class PlayerSpeedChanger : MonoBehaviour public const float classicToUnitySpeedUnitRatio = 39.5f; // was estimated from comparing a walk over the same distance in classic and DF Unity public const float dfWalkBase = 150f; private const float dfCrouchBase = 50f; - private const float dfRideBase = dfWalkBase + 225f; - private const float dfCartBase = dfWalkBase + 100f; + private const float dfRideBase = 375f; + private const float dfCartBase = 250f; public bool walkSpeedOverride = true; private float currentWalkSpeed = 0; - private Dictionary walkSpeedModifierList = new Dictionary(); + private Dictionary walkSpeedModifiers = new Dictionary(); public bool runSpeedOverride = true; private float currentRunSpeed = 0; - private Dictionary runSpeedModifierList = new Dictionary(); + private Dictionary runSpeedModifiers = new Dictionary(); + + public bool rideSpeedOverride = true; + private float currentRideSpeed = 0; + private Dictionary rideSpeedModifiers = new Dictionary(); public delegate bool CanPlayerRun(); public CanPlayerRun CanRun { get; set; } @@ -51,8 +55,12 @@ public class PlayerSpeedChanger : MonoBehaviour public bool updateWalkSpeed; public bool updateRunSpeed; + public bool updateRideSpeed; + private float previousBaseWalkSpeed; private float previousBaseRunSpeed; + private float previousBaseRideSpeed; + private float baseSpeed = 0; private void Start() @@ -62,6 +70,7 @@ private void Start() CanRun = CanRunUnlessRiding; currentWalkSpeed = GetWalkSpeed(GameManager.Instance.PlayerEntity); currentRunSpeed = GetRunSpeed(); + currentRideSpeed = GetRideSpeed(); } /// @@ -110,19 +119,15 @@ public void ApplyInputSpeedAdjustment(ref float speed) isRunning = CanRun() && runningMode; isSneaking = !isRunning && sneakingMode; } - else + else if (!CanRun()) { - if (!CanRun()) - isRunning = false; - // you can't switch running on/off while in mid air + isRunning = false; // you can't switch running on/off while in mid air } if (isRunning) { speed = RefreshRunSpeed(); - - //switch sneaking off if was previously sneaking - sneakingMode = false; + sneakingMode = false; //switch sneaking off if was previously sneaking } else if (isSneaking) { @@ -131,6 +136,11 @@ public void ApplyInputSpeedAdjustment(ref float speed) speed -= (1 / classicToUnitySpeedUnitRatio); } + if (playerMotor.IsRiding) + { + speed = RefreshRideSpeed(); + } + InputManager.Instance.MaximizeJoystickMovement = isRunning; } @@ -148,15 +158,20 @@ public float GetBaseSpeed() { Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; float playerSpeed = player.Stats.LiveSpeed; - if (playerMotor == null) // fixes null reference bug. + if (playerMotor == null) playerMotor = GameManager.Instance.PlayerMotor; // crouching speed penalty doesn't apply if swimming. if (playerMotor.IsCrouching && !levitateMotor.IsSwimming) baseSpeed = (playerSpeed + dfCrouchBase) / classicToUnitySpeedUnitRatio; else if (playerMotor.IsRiding) { - float rideSpeed = (GameManager.Instance.TransportManager.TransportMode == TransportModes.Cart) ? dfCartBase : dfRideBase; - baseSpeed = (playerSpeed + rideSpeed) / classicToUnitySpeedUnitRatio; + float currentRideBase = 0; + bool playerIsRidingHorseWithNoCart = GameManager.Instance.TransportManager.TransportMode == TransportModes.Horse; + if (playerIsRidingHorseWithNoCart) + currentRideBase = dfRideBase; + else + currentRideBase = dfCartBase; + baseSpeed = (playerSpeed + currentRideBase) / classicToUnitySpeedUnitRatio; } else { @@ -168,8 +183,8 @@ public float GetBaseSpeed() /// /// Add custom walk speed modifier to speed modifer dictionary. Returns unique ID for referencing of custom speedModifier for future manipulation. /// - /// the amount to change players base walk speed by percentages. AKA, .75 will lower player movement by 25%. Using 0 or negatives will do nothing but return null. /// The Unique Universal ID created and provided when original value was added to dictionary. Store this value to reference your speed modifier later. + /// the amount to change players base walk speed by percentages. AKA, .75 will lower player movement by 25%. Using 0 or negatives will do nothing but return null. /// will cause routine to also update the player speed using the list to sequentially multiply the current base value by the list modifier values. /// public bool AddWalkSpeedMod(out string UID, float walkSpeedModifier = 0, bool refreshWalkSpeed = true) @@ -181,7 +196,7 @@ public bool AddWalkSpeedMod(out string UID, float walkSpeedModifier = 0, bool re if (walkSpeedModifier > 0) { UID = System.Guid.NewGuid().ToString(); - walkSpeedModifierList.Add(UID, walkSpeedModifier); + walkSpeedModifiers.Add(UID, walkSpeedModifier); added = true; } //trigger an update to the walk speed loop to push updated walk speed value. @@ -193,9 +208,9 @@ public bool AddWalkSpeedMod(out string UID, float walkSpeedModifier = 0, bool re /// /// Add custom walk speed modifier to speed modifer dictionary. Returns unique ID for referencing of custom speedModifier for future manipulation. /// - /// the amount to change players base walk speed by percentages. AKA, .75 will lower player movement by 25%. Using 0 or negatives will do nothing but return null. /// The Unique Universal ID created and provided when original value was added to dictionary. Store this value to reference your speed modifier later. - /// will cause routine to also update the player speed using the list to sequentially multiply the current base value by the list modifier values. + /// the amount to change players base walk speed by percentages. AKA, .75 will lower player movement by 25%. Using 0 or negatives will do nothing but return null. + /// will cause routine to also update the player speed using the list to sequentially multiply the current base value by the list modifier values. /// public bool AddRunSpeedMod(out string UID, float speedModifier = 0, bool refreshRunSpeed = true) { @@ -206,7 +221,7 @@ public bool AddRunSpeedMod(out string UID, float speedModifier = 0, bool refresh if (speedModifier > 0) { UID = System.Guid.NewGuid().ToString(); - runSpeedModifierList.Add(UID, speedModifier); + runSpeedModifiers.Add(UID, speedModifier); added = true; } @@ -216,14 +231,39 @@ public bool AddRunSpeedMod(out string UID, float speedModifier = 0, bool refresh return added; } + /// + /// Add custom ride speed modifier to speed modifer dictionary. Returns unique ID for referencing of custom speedModifier for future manipulation. + /// + /// The Unique Universal ID created and provided when original value was added to dictionary. Store this value to reference your speed modifier later. + /// the amount to change players base ride speed by percentages. AKA, .75 will lower player movement by 25%. Using 0 or negatives will do nothing but return null. + /// will cause routine to also update the player speed using the list to sequentially multiply the current base value by the list modifier values. + /// + public bool AddRideSpeedMod(out string UID, float speedModifier = 0, bool refreshRideSpeed = true) + { + bool added = false; + UID = null; + + //if they set a speed modifier greater than 0, grab the list index using count, and add item (which will be at the lastID index spot). + if (speedModifier > 0) + { + UID = System.Guid.NewGuid().ToString(); + rideSpeedModifiers.Add(UID, speedModifier); + added = true; + } + + //trigger an update to the ride speed loop to push updated ride speed value. + updateRideSpeed = refreshRideSpeed; + + return added; + } + /// /// Remove custom speed modifier from speed modifer dictionary using stored UID. Returns true if removed, false if not found. Ensure to set if it is a run or walk speed modifier being removed. /// - /// the amount to change players base walk speed by percentages. AKA, .75 will lower player movement by 25%. Using 0 or negatives will do nothing but return null. /// The Unique Universal ID created and provided when original value was added to dictionary. Store this value to reference your speed modifier later. - /// will cause routine to also update the player speed using the list to sequentially multiply the current base value by the list modifier values. + /// will cause routine to also update the player speed using the list to sequentially multiply the current base value by the list modifier values. /// - public bool RemoveSpeedMod(string UID, bool removeRunSpeed = false, bool refreshSpeed = true) + public bool RemoveSpeedMod(string UID, bool refreshSpeed = true) { //setup false bool for manipulation. bool removed = false; @@ -232,162 +272,113 @@ public bool RemoveSpeedMod(string UID, bool removeRunSpeed = false, bool refresh if (UID == "" || UID == null) return removed; - //if there is a modifier put in, see if dictionary contains it in the unique keys, and then remove and return true. - if (!removeRunSpeed && walkSpeedModifierList.ContainsKey(UID)) - { - walkSpeedModifierList.Remove(UID); - removed = true; - } - - //if there is a modifier put in, see if dictionary contains it in the unique keys, and then remove and return true. - if (removeRunSpeed && runSpeedModifierList.ContainsKey(UID)) - { - runSpeedModifierList.Remove(UID); - removed = true; - } + //look through all three lists to see if the UID is in any of them. If it is, remove and flag boolean(s) true. + bool walkSpeedModifierIsRemoved = walkSpeedModifiers.Remove(UID); + bool runSpeedModifierIsRemoved = runSpeedModifiers.Remove(UID); + bool rideSpeedModifierIsRemoved = rideSpeedModifiers.Remove(UID); + removed = walkSpeedModifierIsRemoved || runSpeedModifierIsRemoved || rideSpeedModifierIsRemoved; //trigger an update to the walk speed loop to push updated walk speed value. updateWalkSpeed = refreshSpeed; updateRunSpeed = refreshSpeed; + updateRideSpeed = refreshSpeed; return removed; } /// - /// Clears our associated modifier list of all values. default to clearing out both run and walk speed modifier list. + /// Clears modifiers on walk, run and ride speeds. + /// Default values will clear out all three groups of modifiers. /// - /// clear out walk speed modifier list. - /// clear out run speed modifier list - public bool ResetSpeed(bool walkSpeedReset = true, bool runSpeedReset = true) + /// clear out walk speed modifiers. + /// clear out run speed modifiers + /// clear out ride speed modifiers + public bool ResetSpeed(bool walkSpeedReset = true, bool runSpeedReset = true, bool rideSpeedReset = true) { bool reset = false; - - //if walk speed is reset, reset all needed properties to reset walk speed. - if (walkSpeedReset) - { - walkSpeedModifierList.Clear(); - reset = true; - updateWalkSpeed = true; - } - - //if run speed is reset, reset all needed properties to reset run speed. - if (runSpeedReset) - { - runSpeedModifierList.Clear(); - reset = true; - updateRunSpeed = true; - } - + if (walkSpeedReset) { walkSpeedModifiers.Clear(); reset = updateWalkSpeed = true; } + if (runSpeedReset) { runSpeedModifiers.Clear(); reset = updateRunSpeed = true; } + if (rideSpeedReset) { rideSpeedModifiers.Clear(); reset = updateRideSpeed = true; } return reset; } /// - /// Updates the players walk speed using for loop and dictionary values to ensure proper sequential processing to get proper end speed. - /// Processing of modifiers is processed by their addition order. First added by modder is multiplied first, and so on. + /// Refresh walk speed based on modifiers and override settings. /// + /// public float RefreshWalkSpeed() { - //setup and grab needed base values for computing end speed. - float baseWalkSpeed = GetWalkSpeed(GameManager.Instance.PlayerEntity); - float overrideSpeed = 0; - - //if there are no modifiers in the dictionary, return the base walk speed before modifying it. - if (walkSpeedModifierList.Count == 0 || walkSpeedOverride == false) - return baseWalkSpeed; - - //checks to see if players base run speed updated, and if so, triggers new speed update loop below. - if (previousBaseWalkSpeed != baseWalkSpeed) - { - previousBaseWalkSpeed = baseWalkSpeed; - updateWalkSpeed = true; - } - - //if updateWalkSpeed switch is turned to true, update walk speed using an if then and while loop. - if (updateWalkSpeed) - { - //shunt collection as a numerator into a object var to be used. - using (var modifierValue = walkSpeedModifierList.GetEnumerator()) - { - //if the first item is moved do this, calculate speed using base speed as the starting point. - if (modifierValue.MoveNext()) - { - overrideSpeed = baseWalkSpeed * modifierValue.Current.Value; - - //once first move next is done to get speed from base value, start while loop to sequentally calculate subsequent values. - while (modifierValue.MoveNext()) - { - overrideSpeed = overrideSpeed * modifierValue.Current.Value; - } - } - } - - //assign override speed and switch updateWalkSpeed to false to stop it from looping every time it is called. - //only want it to loop when collection changes - AKA, add, remove, ect - or modder forces switch flip. - currentWalkSpeed = overrideSpeed; - updateWalkSpeed = false; - } - - //return the final modified walk speed. - return currentWalkSpeed; + float baseSpeed = GetWalkSpeed(); + return RefreshSpeed(baseSpeed, walkSpeedModifiers, walkSpeedOverride, ref previousBaseWalkSpeed, ref updateWalkSpeed, ref currentWalkSpeed); } /// - /// Updates the players walk speed using for loop and dictionary values to ensure proper sequential processing to get proper end speed. - /// Processing of modifiers is processed by their addition order. First added by modder is multiplied first, and so on. + /// Refresh run speed based on modifiers and override settings. /// + /// public float RefreshRunSpeed() { - //setup and grab needed base values for computing end speed. - float baseRunSpeed = GetRunSpeed(); - float overrideSpeed = 0; + float baseSpeed = GetRunSpeed(); + return RefreshSpeed(baseSpeed, runSpeedModifiers, runSpeedOverride, ref previousBaseRunSpeed, ref updateRunSpeed, ref currentRunSpeed); + } - //if there are no modifiers in the dictionary, return the base walk speed before modifying it. - if (runSpeedModifierList.Count == 0 || runSpeedOverride == false) - return baseRunSpeed; + /// + /// Refresh ride speed based on modifiers and override settings. + /// + /// + public float RefreshRideSpeed() + { + float baseSpeed = GetRideSpeed(); + return RefreshSpeed(baseSpeed, rideSpeedModifiers, rideSpeedOverride, ref previousBaseRideSpeed, ref updateRideSpeed, ref currentRideSpeed); + } - //checks to see if players base run speed updated, and if so, triggers new speed update loop below. - if (previousBaseRunSpeed != baseRunSpeed) + /// + /// Refresh speed based on modifiers and override settings. + /// + /// + /// + /// + /// + /// + /// + /// + private float RefreshSpeed(float baseSpeed, IDictionary modifiers, bool overrideEnabled, ref float previousBaseSpeed, ref bool updateFlag, ref float currentSpeed) + { + // If there are no modifiers or override is disabled, return the base speed. + if (modifiers.Count == 0 || !overrideEnabled) + return baseSpeed; + + // If the base speed has changed, store it and flag that an update is needed. + if (previousBaseSpeed != baseSpeed) { - previousBaseRunSpeed = baseRunSpeed; - updateRunSpeed = true; + previousBaseSpeed = baseSpeed; + updateFlag = true; } - //if updateWalkSpeed switch is turned to true, update walk speed using an if then and while loop. - if (updateRunSpeed) + // Process the modifiers only if flagged for an update. + if (updateFlag) { - //shunt collection as a numerator into a object var to be used. - using (var modifierValue = runSpeedModifierList.GetEnumerator()) - { - //if the first item is moved do this, calculate speed using base speed as the starting point. - if (modifierValue.MoveNext()) - { - overrideSpeed = baseRunSpeed * modifierValue.Current.Value; - - //once first move next is done to get speed from base value, start while loop to sequentally calculate subsequent values. - while (modifierValue.MoveNext()) - { - overrideSpeed = overrideSpeed * modifierValue.Current.Value; - } - } - } - - //assign override speed and switch updateWalkSpeed to false to stop it from looping every time it is called. - //only want it to loop when collection changes - AKA, add, remove, ect - or modder forces switch flip. - currentRunSpeed = overrideSpeed; - updateRunSpeed = false; + float overrideSpeed = baseSpeed; + + // Process each modifier in sequence. + foreach (var modifier in modifiers) + overrideSpeed *= modifier.Value; + + // Update the current speed and reset the update flag. + currentSpeed = overrideSpeed; + updateFlag = false; } - //return the final modified walk speed. - return currentRunSpeed; + return currentSpeed; } /// /// Get LiveSpeed adjusted for walking /// - /// the PlayerEntity to use /// - public float GetWalkSpeed(Entity.PlayerEntity player) + public float GetWalkSpeed() { + Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; float drag = 0.5f * (100 - (player.Stats.LiveSpeed >= 30 ? player.Stats.LiveSpeed : 30)); return (player.Stats.LiveSpeed + dfWalkBase - drag) / classicToUnitySpeedUnitRatio; } @@ -395,7 +386,6 @@ public float GetWalkSpeed(Entity.PlayerEntity player) /// /// Get LiveSpeed adjusted for running /// - /// /// public float GetRunSpeed() { @@ -404,6 +394,23 @@ public float GetRunSpeed() return baseRunSpeed * (1.35f + (player.Skills.GetLiveSkillValue(DFCareer.Skills.Running) / 200f)); } + /// + /// Get LiveSpeed adjusted for riding + /// + /// + public float GetRideSpeed() + { + Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; + float currentRideBase = 0; + bool playerIsRidingHorseWithNoCart = GameManager.Instance.TransportManager.TransportMode == TransportModes.Horse; + if (playerIsRidingHorseWithNoCart) + currentRideBase = dfRideBase; + else + currentRideBase = dfCartBase; + float baseRideSpeed = (player.Stats.LiveSpeed + currentRideBase) / classicToUnitySpeedUnitRatio; ; + return baseRideSpeed; + } + /// /// Get LiveSpeed adjusted for swimming /// @@ -422,5 +429,12 @@ public float GetClimbingSpeed(float baseSpeed) float climbingBoost = player.IsEnhancedClimbing ? 2f : 1f; return (baseSpeed / 3) * climbingBoost; } + + /// + /// Legacy method signature for older mods to keep working. Use GetWalkSpeed() instead. + /// + /// + /// + public float GetWalkSpeed(Entity.PlayerEntity player) { return GetWalkSpeed(); } } } \ No newline at end of file