public static bool Prefix(Character __instance, Vector3 _direction) { var self = __instance; // only use this hook for local players. return orig everything else if (self.IsAI || !self.IsPhotonPlayerLocal) { return(true); } float staminaCost = (float)CombatOverhaul.config.GetValue(Settings.Custom_Dodge_Cost); if (self.Inventory.SkillKnowledge.GetItemFromItemID(8205130)) // feather dodge { staminaCost *= 0.5f; } // if dodge cancelling is NOT enabled, just do a normal dodge check. if (!(bool)CombatOverhaul.config.GetValue(Settings.Dodge_Cancelling)) { if (At.GetValue(typeof(Character), self, "m_currentlyChargingAttack") is bool m_currentlyChargingAttack && At.GetValue(typeof(Character), self, "m_preparingToSleep") is bool m_preparingToSleep && At.GetValue(typeof(Character), self, "m_nextIsLocomotion") is bool m_nextIsLocomotion && At.GetValue(typeof(Character), self, "m_dodgeAllowedInAction") is int m_dodgeAllowedInAction) { if (self.Stats.MovementSpeed > 0f && !m_preparingToSleep && (!self.LocomotionAction || m_currentlyChargingAttack) && (m_nextIsLocomotion || m_dodgeAllowedInAction > 0)) { if (!self.Dodging) { Instance.SendDodge(self, staminaCost, _direction); } return(false); } } } else // cancelling enabled. check if we should allow the dodge { if (Instance.PlayerLastHitTimes.ContainsKey(self.UID) && Time.time - Instance.PlayerLastHitTimes[self.UID] < (float)CombatOverhaul.config.GetValue(Settings.Dodge_DelayAfterHit)) { // Debug.Log("Player has hit within the last few seconds. Dodge not allowed!"); return(false); } Character.HurtType hurtType = (Character.HurtType)At.GetValue(typeof(Character), self, "m_hurtType"); // manual fix (game sometimes does not reset HurtType to NONE when animation ends. float timeout = (float)CombatOverhaul.config.GetValue(Settings.Dodge_DelayAfterStagger); if (hurtType == Character.HurtType.Knockdown) { timeout = (float)CombatOverhaul.config.GetValue(Settings.Dodge_DelayAfterKD); } if ((float)At.GetValue(typeof(Character), self, "m_timeOfLastStabilityHit") is float lasthit && Time.time - lasthit > timeout) { hurtType = Character.HurtType.NONE; At.SetValue(hurtType, typeof(Character), self, "m_hurtType"); } // if we're not currently dodging or staggered, force an animation cancel dodge (provided we have enough stamina). if (!self.Dodging && hurtType == Character.HurtType.NONE) { Instance.SendDodge(self, staminaCost, _direction); } // send a fix to force m_dodging to false after a short delay. // this is a fix for if the player dodges while airborne, the game wont reset their m_dodging to true when they land. Instance.StartCoroutine(Instance.DodgeLateFix(self)); } return(false); }
public static void Postfix(Character __instance, Vector3 _direction, bool ___m_pendingDeath, ref int ___m_dodgeAllowedInAction) { if (!CombatTweaksMod.Dodge_Cancelling.Value) { return; } if (!__instance.IsPhotonPlayerLocal || __instance.IsAI || __instance.Dodging) { return; } if (___m_pendingDeath) { return; } // check player has enough stamina if (!(bool)At.Invoke(__instance, "HasEnoughStamina", (float)__instance.DodgeStamCost)) { return; } if (PlayerLastHitTimes.ContainsKey(__instance.UID) && Time.time - PlayerLastHitTimes[__instance.UID] < CombatTweaksMod.Dodge_DelayAfterPlayerHits.Value) { // Debug.Log("Player has hit within the last few seconds. Dodge not allowed!"); return; } Character.HurtType hurtType = (Character.HurtType)At.GetField(__instance, "m_hurtType"); // manual fix (game sometimes does not reset HurtType to NONE when animation ends. float timeout; if (hurtType == Character.HurtType.Knockdown) { timeout = CombatTweaksMod.Dodge_DelayAfterKnockdown.Value; } else { timeout = CombatTweaksMod.Dodge_DelayAfterStagger.Value; } if ((float)At.GetField(__instance, "m_timeOfLastStabilityHit") is float lasthit && Time.time - lasthit > timeout) { hurtType = Character.HurtType.NONE; At.SetField(__instance, "m_hurtType", hurtType); } // if we're not currently staggered, force an animation cancel dodge (provided we have enough stamina). if (hurtType == Character.HurtType.NONE) { //SendDodge(__instance, __instance.DodgeStamCost, _direction); __instance.Stats.UseStamina(TagSourceManager.Dodge, __instance.DodgeStamCost); ___m_dodgeAllowedInAction = 0; if (__instance.CharacterCamera && __instance.CharacterCamera.InZoomMode) { __instance.SetZoomMode(false); } __instance.ForceCancel(false, true); __instance.ResetCastType(); __instance.photonView.RPC("SendDodgeTriggerTrivial", PhotonTargets.All, new object[] { _direction }); At.Invoke(__instance, "ActionPerformed", true); __instance.Invoke("ResetDodgeTrigger", 0.5f); } // send a fix to force m_dodging to false after a short delay. // this is a fix for if the player dodges while airborne, the game wont reset their m_dodging to true when they land. CombatTweaksMod.Instance.StartCoroutine(DodgeLateFix(__instance)); }