public void detectMovementInputs(On.LocalCharacterControl.orig_DetectMovementInputs orig, LocalCharacterControl self) { Type tSelf = self.GetType(); // Remove the need for reflection as much as possible // These need to be manually set Vector2 sm_moveInput; Vector3 sm_modifMoveInput; // This should update anything changed inside of it Character m_character = self.Character; if (self.InputLocked) { sm_moveInput = Vector2.zero; sm_modifMoveInput = (Vector3)Vector2.zero; // Exit condition, so set stuff m_moveInput.SetValue(self, sm_moveInput); m_modifMoveInput.SetValue(self, sm_modifMoveInput); if (!m_character.Sprinting) { return; } m_character.SprintInput(false); } else { // Static methods are great sm_moveInput.x = ControlsInput.MoveHorizontal(m_character.OwnerPlayerSys.PlayerID); sm_moveInput.y = ControlsInput.MoveVertical(m_character.OwnerPlayerSys.PlayerID); // If we're autorunning if ((bool)m_autoRun.GetValue(self)) { if ((double)sm_moveInput.y == 0.0) { sm_moveInput.y = 1f; } else { StopAutoRun.Invoke(self, null); } } // Make sure the magnitude of our input vector is at max 1 sm_moveInput = (Vector2)Vector3.ClampMagnitude((Vector3)sm_moveInput, 1f); // Switch to 3D vector sm_modifMoveInput = (Vector3)sm_moveInput; // Sprinting if (ControlsInput.Sprint(m_character.OwnerPlayerSys.PlayerID) && m_character.InLocomotion && m_character.Stats.CanSprint() && ((!m_character.LocomotionAction || (double)m_character.MobileCastMoveMult == -1.0) && (double)sm_moveInput.sqrMagnitude > 0.100000001490116)) { // We can cast this because m_sprintTime is always a float m_sprintTime.SetValue(self, (float)m_sprintTime.GetValue(self) + Time.deltaTime); if (m_character.Sneaking) { m_character.StealthInput(false); } if (m_character.CurrentlyChargingAttack && !m_character.CancelChargingSent) { m_character.CancelCharging(); } // I think this normalize call is pointless sm_modifMoveInput.Normalize(); sm_modifMoveInput *= m_character.Speed * 1.75f; m_sprintFacing.SetValue(self, true); m_character.SprintInput(true); if (m_character.BlockDesired) { m_character.BlockInput(false); } } else // Not sprinting { m_sprintTime.SetValue(self, 0.0f); // Do the calculations for our speed normally, then apply modifiers // Having your weapon unsheathed makes you 12.5% slower sm_modifMoveInput *= !m_character.Sheathed ? m_character.Speed * 0.875f : m_character.Speed; // Modify speed based on sneaking status if (m_character.Sneaking) { // Vanilla values have movement speed capped at 2.3 while sneaking, with a 30% increase with the skill float sneakMod = baseSneakSpeed; // Handle "Stealth Training" skill if (m_character.Inventory.SkillKnowledge.IsItemLearned(8205190)) { sneakMod *= stealthTrainingBonus; } sm_modifMoveInput *= sneakMod; } if (m_character.Sprinting) { m_character.SprintInput(false); } if (m_character.Blocking || m_character.CurrentlyChargingAttack) { sm_modifMoveInput *= 0.6f; } if (!m_character.LocomotionAllowed) { sm_modifMoveInput *= 0.1f; } if (m_character.LocomotionAction && (double)m_character.MobileCastMoveMult > 0.0) { sm_modifMoveInput *= m_character.MobileCastMoveMultSmooth; } if (m_character.Sliding) { sm_modifMoveInput *= 0.6f; } if (m_character.Falling) { sm_modifMoveInput *= 0.3f; } if (self.FaceLikeCamera) { Vector2 modifMoveInput = (Vector2)sm_modifMoveInput; float num = 0.1f; sm_modifMoveInput.y *= (float)(1.0 + (double)Mathf.Abs(modifMoveInput.x) * (double)num); sm_modifMoveInput.x *= (float)(1.0 + (double)Mathf.Abs(modifMoveInput.y) * (double)num); } m_sprintFacing.SetValue(self, false); } // General movement modifiers sm_modifMoveInput *= self.MovementMultiplier * m_character.Stats.MovementSpeed; if (m_character.PreparingToSleep) { sm_modifMoveInput *= 0.0f; } // There is an exit condition ahead, so set values m_modifMoveInput.SetValue(self, sm_modifMoveInput); m_moveInput.SetValue(self, sm_moveInput); if ((m_character.CharacterUI == null || !m_character.CharacterUI.IsMenuJustToggled) && ControlsInput.DodgeButton(m_character.OwnerPlayerSys.PlayerID)) { Transform horiControl = (Transform)m_horiControl.GetValue(self); m_character.DodgeInput(horiControl.forward * sm_moveInput.y + horiControl.right * sm_moveInput.x); StopAutoRun.Invoke(self, null); } if (ControlsInput.AutoRun(m_character.OwnerPlayerSys.PlayerID)) { m_autoRun.SetValue(self, !(bool)m_autoRun.GetValue(self)); } if (!((bool)m_character.CharacterUI) || m_character.CharacterUI.IsMenuJustToggled || (ControlsInput.QuickSlotToggled(m_character.OwnerPlayerSys.PlayerID) || !ControlsInput.StealthButton(m_character.OwnerPlayerSys.PlayerID))) { return; } m_character.StealthInput(!m_character.Sneaking); } }