-- This file should be in your Game folder (usually C:\Program Files (x86)\Steam\steamapps\common\ELDEN RING\Game) + quickDodge. This file path should be C:\Program Files (x86)\Steam\steamapps\common\ELDEN RING\Game\quickDodge\quickDodge.lua BACKSTEP_REPLACE_BACKWARDS_DODGE = FALSE -- When dodging backwards, backstep instead. SPRINTING_R2_ON_BACKSTEP_R2 = FALSE -- When pressing R2 from a backstep, execute the sprinting R2 instead of standing R2. INSTANT_SPRINTING_FROM_DODGE = TRUE -- If you hold the dodge button from a dodge, you exit it in a sprint. SPRINTING_ATTACKS_WHILE_HOLDING_DODGE = TRUE -- If you hold the dodge button from a dodge, instead of queueing a dodge attack, you queue a sprinting attack FAST_DODGE_R2 = FALSE -- When exiting from a dodge, the R2 attack is noticeably faster FIRST_R1_CHAINS_TO_SECOND_R2 = FALSE -- Your standing R1 chains to your second standing R2 instead of the first standing R2. DODGE_R1_CHAINS_TO_SECOND_R2 = FALSE SPRINT_R1_CHAINS_TO_SECOND_R2 = FALSE BACKSTEP_R1_CHAINS_TO_SECOND_R2 = FALSE SPRINT_R2_CHAINS_TO_SECOND_R2 = FALSE DODGE_CANCEL_GRACE_PERIOD = 2.3 -- Measured in seconds. Can dodge cancel out of attacks within the first few seconds here. CUSTOM_WEIGHT_OVERRIDE = -1 -- -1 for inactive, 1 for Light, 2 for Medium, 3 for Heavy, 4 for Overweight -- If you see this message you have the Normal version. -- Table to hold the backup functions rawset(_G, "backupEnv", {}) -- Function to create a replacement function createReplacement(functionName, originalFunction, newFunction) -- Check if the function already exists in the backup environment using rawget if rawget(backupEnv, functionName) == nil then -- Store the original function in the backup environment backupEnv[functionName] = originalFunction end -- Create a wrapper that calls the new function return function(...) -- Call the new function return newFunction(...) end end -- Function to restore the original function function restoreFunction(functionName) -- Check if the backup environment has the original function using rawget local originalFunction = rawget(backupEnv, functionName) if originalFunction then -- Return the original function return originalFunction elseif rawget(_G, functionName) then return rawget(_G, functionName) else return nil end end -- Function to create a detour function createDetour(originalFunction, newFunction) -- Store the original function in the new function's environment local original = originalFunction -- Create a wrapper that calls the new function first, then the original function return function(...) -- Call the new function newFunction(...) -- Call the original function return original(...) end end -- Function to create a detour function createPostDetour(originalFunction, newFunction) -- Store the original function in the new function's environment local original = originalFunction -- Create a wrapper that calls the new function first, then the original function return function(...) -- Call the original function local originalResult = original(...) -- Call the new function newFunction(...) return originalResult end end function customWeightOverride() if CUSTOM_WEIGHT_OVERRIDE == -1 then return end if CUSTOM_WEIGHT_OVERRIDE == 1 then SetVariable("MoveWeightIndex", MOVE_WEIGHT_LIGHT) SetVariable("EvasionWeightIndex", EVASION_WEIGHT_INDEX_LIGHT) elseif CUSTOM_WEIGHT_OVERRIDE == 2 then SetVariable("MoveWeightIndex", MOVE_WEIGHT_NORMAL) SetVariable("EvasionWeightIndex", EVASION_WEIGHT_INDEX_MEDIUM) elseif CUSTOM_WEIGHT_OVERRIDE == 3 then SetVariable("MoveWeightIndex", MOVE_WEIGHT_HEAVY) SetVariable("EvasionWeightIndex", EVASION_WEIGHT_INDEX_HEAVY) elseif CUSTOM_WEIGHT_OVERRIDE == 4 then SetVariable("MoveWeightIndex", MOVE_WEIGHT_HEAVY) SetVariable("EvasionWeightIndex", EVASION_WEIGHT_INDEX_OVERWEIGHT) end end SetWeightIndex = createPostDetour(SetWeightIndex, customWeightOverride) rawset(_G, "sprintToggle", false) rawset(_G, "prevL3", false) rawset(_G, "wasMoving", false) rawset(_G, "stopTime", 0) function rebindSprint() -- Solo ejecutar para el jugador, no para NPCs if env(IsCOMPlayer) == TRUE then return end -- Cancelar sprint si no hay stamina if env(GetStamina) <= 0 then sprintToggle = false return end local l3Now = env(ActionDuration, ACTION_ARM_L3) > 0 local dodgeNow = env(ActionDuration, ACTION_ARM_DODGE) > 0 local moveLevel = GetVariable("MoveSpeedLevel") local isLocked = env(IsLocked) == TRUE ---------------------------------------------------------------- -- AUTO-CANCEL POR FIJAR OBJETIVO (LOCK-ON) ---------------------------------------------------------------- if isLocked then sprintToggle = false end ---------------------------------------------------------------- -- TOGGLE SOLO SI NO HAY LOCK-ON ---------------------------------------------------------------- -- Toggle SOLO en el pulso de L3, sin dodge, y sin lock-on if l3Now and not prevL3 and not dodgeNow and not isLocked then sprintToggle = not sprintToggle end prevL3 = l3Now ---------------------------------------------------------------- -- AUTO-CANCEL POR PARAR MOVIMIENTO ---------------------------------------------------------------- if moveLevel > 0.05 then wasMoving = true stopTime = 0 else if wasMoving then if stopTime == 0 then stopTime = os.clock() elseif os.clock() - stopTime > 0.04 then sprintToggle = false wasMoving = false end end end ---------------------------------------------------------------- -- AUTO-CANCEL POR ACCIONES ---------------------------------------------------------------- if env(ActionRequest, ACTION_ARM_R1) == TRUE or env(ActionRequest, ACTION_ARM_R2) == TRUE or env(ActionRequest, ACTION_ARM_SP_MOVE) == TRUE or env(ActionRequest, ACTION_ARM_BACKSTEP) == TRUE then sprintToggle = false wasMoving = false stopTime = 0 end if c_IsStealth == TRUE then wasMoving = false stopTime = 0 end ---------------------------------------------------------------- -- APLICAR SPRINT ---------------------------------------------------------------- if sprintToggle and moveLevel > 0.05 then act(2002, 100220) end end Update = createPostDetour(Update, rebindSprint) rawset(_G, "g_EventsLog", { ["CMSG"] = "", ["TIME"] = 0 }) function LogEventsAndTiming(state) g_EventsLog["CMSG"] = state g_EventsLog["TIME"] = os.clock() end ExecEvent = createDetour(ExecEvent, LogEventsAndTiming) ACTION_ARM_L3_BACK = ACTION_ARM_L3 function SprintCancelOnAttack(state) -- Solo ejecutar para el jugador, no para NPCs if env(IsCOMPlayer) == TRUE then return end if sprintToggle ~= true then return end if type(state) ~= "string" then return end if string.find(state, "Attack") then sprintToggle = false end end ExecEvent = createPostDetour(ExecEvent, SprintCancelOnAttack) rawset(_G, "g_LastL3Press", 0) rawset(_G, "g_LastDodgePress", 0) rawset(_G, "g_CrouchBlocked", false) function ExecEvasionMonkeyPatchPre() -- Solo ejecutar para el jugador, no para NPCs if env(IsCOMPlayer) == TRUE then return end if c_HasActionRequest == FALSE then return FALSE end -- Trackear inputs para detectar L3 + Dodge de forma más confiable local l3Pressed = env(ActionRequest, ACTION_ARM_L3) == TRUE local dodgePressed = env(ActionRequest, ACTION_ARM_SP_MOVE) == TRUE or env(ActionDuration, ACTION_ARM_SP_MOVE) > 0 local currentTime = os.clock() -- Actualizar timestamps if l3Pressed then g_LastL3Press = currentTime end if dodgePressed then g_LastDodgePress = currentTime end -- Bloquear crouch durante ataques y por un tiempo después local isRecentAttack = (currentTime - g_EventsLog["TIME"] < 0.4) and (string.find(g_EventsLog["CMSG"] or "", "ttack") or string.find(g_EventsLog["CMSG"] or "", "olling")) g_CrouchBlocked = isRecentAttack -- Solo permitir crouch si L3 Y Dodge están presionados simultáneamente -- (dentro de 0.15 segundos uno del otro) Y no hay ataques recientes local simultaneousPress = math.abs(g_LastL3Press - g_LastDodgePress) < 0.15 local bothActive = l3Pressed and dodgePressed if bothActive and simultaneousPress and not g_CrouchBlocked then if c_IsStealth == FALSE then StealthTransitionIndexUpdate() ExecEvent("W_Stealth_to_Stealth_Idle") c_HasActionRequest = TRUE return TRUE elseif c_IsStealth == TRUE then StealthTransitionIndexUpdate() ExecEvent("W_Stealth_to_Idle") c_HasActionRequest = TRUE return TRUE end end -- Solo bloquear L3 si realmente necesitamos evitar el crouch ACTION_ARM_L3 = 666 end function ExecEvasionMonkeyPatchPost() -- Solo ejecutar para el jugador, no para NPCs if env(IsCOMPlayer) == TRUE then return end ACTION_ARM_L3 = ACTION_ARM_L3_BACK end -- TK NOTE: REBIND CROUCH TO L3 + DODGE ExecEvasion = createDetour(ExecEvasion, ExecEvasionMonkeyPatchPre) ExecEvasion = createPostDetour(ExecEvasion, ExecEvasionMonkeyPatchPost) function fixDodges() -- Solo ejecutar para el jugador, no para NPCs if env(IsCOMPlayer) == TRUE then return end c_RollingAngle = GetVariable("MoveAngle") c_ArtsRollingAngle = GetVariable("MoveAngle") end -- TK NOTE: USE MOVE ANGLE (Stick/WASD) for dodge dir instead of RollAngle (the direction your character is moving which only updates sometimes) GetConstVariable = createPostDetour(GetConstVariable, fixDodges) rawset(_G, "canUpdateSelf", true) function checkForUpdates() -- Solo ejecutar para el jugador, no para NPCs if env(IsCOMPlayer) == TRUE then return end if (env(ActionDuration, ACTION_ARM_SP_MOVE) > 15000) and (env(ActionDuration, ACTION_ARM_R1) > 15000) and (env(ActionDuration, ACTION_ARM_L1) > 15000) and canUpdateSelf then updateSelf() canUpdateSelf = false act(1000, -100000) end end function updateSelf() -- Define the URL of the Lua script to download local url = "https://raw.githubusercontent.com/FWang1221/ERDodgeAndOtherShittyThings/master/quickDodge.lua" -- Define the command to download the file using curl (cross-platform) local download_command = 'curl -o quickDodge/quickDodge.lua ' .. url -- Download the Lua script using os.execute os.execute(download_command) end -- TK NOTE: CHECK MOD FOR UPDATES AND UPDATE WHEN YOU HOLD R1 + L1 + Dodge for 15 seconds Update = createDetour(Update, checkForUpdates) -- TK NOTE: This replaces GetEvasionRequestCustom in c0000.hks, you can compare the two to see what's different function GetEvasionRequestCustom() -- Solo ejecutar versión custom para el jugador, usar original para NPCs if env(IsCOMPlayer) == TRUE then return backupEnv["GetEvasionRequest"]() end local dodgeDecider = FALSE -- TK NOTE: ACTION_ARM_SP_MOVE is dodge PRESS, ACTION_ARM_ROLLING is normal base game dodge (release+direction) dodgeDecider = env(ActionRequest, ACTION_ARM_ROLLING) -- TK NOTE: This handles dodge cancelling an attack if (os.clock() - g_EventsLog["TIME"] < DODGE_CANCEL_GRACE_PERIOD) and (string.find(g_EventsLog["CMSG"], "ttack")) then if env(ActionDuration, ACTION_ARM_SP_MOVE) > 0 then dodgeDecider = TRUE -- TK NOTE: Added this to go back to stick based dodge direction when attack cancelling since roll direction doesn't update during an attack c_RollingAngle = GetVariable("MoveAngle") c_ArtsRollingAngle = GetVariable("MoveAngle") end end local move_angle = GetVariable("MoveAngle") local stick_level = GetVariable("MoveSpeedLevel") if env(GetStamina) < STAMINA_MINIMUM or env(ActionDuration, ACTION_ARM_L3) > 0 then return ATTACK_REQUEST_INVALID end if (dodgeDecider == TRUE and stick_level > 0.05) then if (move_angle > 135 or move_angle < -135) and BACKSTEP_REPLACE_BACKWARDS_DODGE == TRUE then return ATTACK_REQUEST_BACKSTEP else return ATTACK_REQUEST_ROLLING end elseif env(ActionDuration, ACTION_ARM_L1) > 0 then if env(ActionRequest, ACTION_ARM_EMERGENCYSTEP) == TRUE then if env(IsEmergencyEvasionPossible, 0) == TRUE or env(IsEmergencyEvasionPossible, 1) == TRUE then return ATTACK_REQUEST_EMERGENCYSTEP end elseif env(ActionRequest, ACTION_ARM_BACKSTEP) == TRUE then return ATTACK_REQUEST_BACKSTEP else return ATTACK_REQUEST_INVALID end elseif env(ActionRequest, ACTION_ARM_BACKSTEP) == TRUE then return ATTACK_REQUEST_BACKSTEP end return ATTACK_REQUEST_INVALID end function DefaultBackStep_onUpdateCustom() act(DisallowAdditiveTurning, TRUE) if EvasionCommonFunction(FALL_TYPE_DEFAULT, "W_AttackRightBackstep", "W_AttackRightHeavyDash", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothBackstep", "W_AttackBothHeavyDash", QUICKTYPE_BACKSTEP) == TRUE then return end end function Rolling_onUpdateCustom() act(DisallowAdditiveTurning, TRUE) SetThrowAtkInvalid() if env(GetSpEffectID, 100390) == TRUE then ResetDamageCount() end SetEnableAimMode() if SPRINTING_ATTACKS_WHILE_HOLDING_DODGE == TRUE and env(ActionDuration, ACTION_ARM_SP_MOVE) > 0 then if EvasionCommonFunction(FALL_TYPE_DEFAULT, "W_AttackRightLightDash", "W_AttackRightHeavyDash", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothDash", "W_AttackBothHeavyDash", QUICKTYPE_ROLLING) == TRUE then return end elseif FAST_DODGE_R2 == TRUE then if EvasionCommonFunction(FALL_TYPE_DEFAULT, "W_AttackRightLightStep", "W_AttackRightHeavy1End", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLightStep", "W_AttackBothHeavy1End", QUICKTYPE_ROLLING) == TRUE then return end else if EvasionCommonFunction(FALL_TYPE_DEFAULT, "W_AttackRightLightStep", "W_AttackRightHeavy1Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLightStep", "W_AttackBothHeavy1Start", QUICKTYPE_ROLLING) == TRUE then return end end if env(IsAnimEnd, 1) == TRUE then ExecEventAllBody("W_Idle") return end SetRollingTurnCondition(FALSE) if env(ActionDuration, ACTION_ARM_SP_MOVE) > 0 and SPRINTING_ATTACKS_WHILE_HOLDING_DODGE == TRUE then SetVariable("ToggleDash", 1) end end function AttackRightLight1_onUpdateCustom() local r1 = "W_AttackRightLight2" if g_ComboReset == TRUE then r1 = "W_AttackRightLight1" end if FIRST_R1_CHAINS_TO_SECOND_R2 == TRUE then if AttackCommonFunction(r1, "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLight2", "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end else if AttackCommonFunction(r1, "W_AttackRightHeavy1Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLight2", "W_AttackBothHeavy1Start", FALSE, TRUE, 1) == TRUE then return end end end function AttackBothLight1_onUpdateCustom() local b1 = "W_AttackBothLight2" if g_ComboReset == TRUE then b1 = "W_AttackBothLight1" end if FIRST_R1_CHAINS_TO_SECOND_R2 == TRUE then if AttackCommonFunction("W_AttackRightLight2", "W_AttackRightHeavy2Start", "W_AttackBothLeft2", "W_AttackLeftHeavy1", b1, "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end else if AttackCommonFunction("W_AttackRightLight2", "W_AttackRightHeavy1Start", "W_AttackBothLeft2", "W_AttackLeftHeavy1", b1, "W_AttackBothHeavy1Start", FALSE, TRUE, 1) == TRUE then return end end end function AttackRightLightStep_onUpdateCustom() local r1 = "W_AttackRightLightSubStart" if g_ComboReset == TRUE then r1 = "W_AttackRightLight1" end if AttackCommonFunction(r1, "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLight1", "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end function AttackBothLightStep_onUpdateCustom() local b1 = "W_AttackBothLightSubStart" if g_ComboReset == TRUE then b1 = "W_AttackBothLight1" end if AttackCommonFunction("W_AttackRightLight1", "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", b1, "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end function AttackRightLightDash_onUpdateCustom() local r1 = "W_AttackRightLightSubStart" if g_ComboReset == TRUE then r1 = "W_AttackRightLight1" end if AttackCommonFunction(r1, "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLight1", "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end function AttackBothDash_onUpdateCustom() local b1 = "W_AttackBothLightSubStart" if g_ComboReset == TRUE then b1 = "W_AttackBothLight1" end if AttackCommonFunction("W_AttackRightLight1", "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", b1, "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end function AttackRightBackstep_onUpdateCustom() local r1 = "W_AttackRightLightSubStart" if g_ComboReset == TRUE then r1 = "W_AttackRightLight1" end if AttackCommonFunction(r1, "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLight1", "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end function AttackBothBackstep_onUpdateCustom() local b1 = "W_AttackBothLightSubStart" if g_ComboReset == TRUE then b1 = "W_AttackBothLight1" end if AttackCommonFunction("W_AttackRightLight1", "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", b1, "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end function AttackRightHeavyDash_onUpdateCustom() local r1 = "W_AttackRightLightSubStart" if g_ComboReset == TRUE then r1 = "W_AttackRightLight1" end if AttackCommonFunction(r1, "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLight1", "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end function AttackBothHeavyDash_onUpdateCustom() local b1 = "W_AttackBothLightSubStart" if g_ComboReset == TRUE then b1 = "W_AttackBothLight1" end if AttackCommonFunction("W_AttackRightLight1", "W_AttackRightHeavy2Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", b1, "W_AttackBothHeavy2Start", FALSE, TRUE, 1) == TRUE then return end end -- ============================================================================ -- NUEVAS FUNCIONES PARA ATAQUES DE MANO IZQUIERDA (L1/L2) -- ============================================================================ function AttackLeftLight1_onUpdateCustom() if AttackCommonFunction("W_AttackRightLight1", "W_AttackRightHeavy1Start", "W_AttackLeftLight1", "W_AttackLeftHeavy1", "W_AttackBothLight1", "W_AttackBothHeavy1Start", FALSE, TRUE, 0) == TRUE then return end end function AttackLeftHeavy1_onUpdateCustom() if AttackCommonFunction("W_AttackRightLight1", "W_AttackRightHeavy1Start", nil, "W_AttackLeftHeavy2", "W_AttackBothLight1", "W_AttackBothHeavy1Start", FALSE, TRUE, 0) == TRUE then return end end -- ============================================================================ --TK NOTE: Replace the default game evasion request with the custom one. Mostly just affects dodge on press and attack dodge cancelling GetEvasionRequest = createReplacement("GetEvasionRequest", GetEvasionRequest, GetEvasionRequestCustom) rawset(_G, "g_LastSettingsCheckTime", 0) -- TK NOTE: This bit reads the settings file and enables most of the stuff there by replacing the base game functions/logic with these ones -- Might be able to figure out what's going on here more easily by comparing the custom functions to the non-custom ones found in c0000.hks I haven't looked at these yet myself function applySettings() if SPRINTING_R2_ON_BACKSTEP_R2 == TRUE then DefaultBackStep_onUpdate = createReplacement("DefaultBackStep_onUpdate", DefaultBackStep_onUpdate, DefaultBackStep_onUpdateCustom) else DefaultBackStep_onUpdate = restoreFunction("DefaultBackStep_onUpdate") end -- Do not override the game's `Rolling_onUpdate` so HKS rolling handlers -- (including SPEED_COMBO logic) run. The mod's custom rolling override -- forced a constant step attack and prevented combo follow-ups. Rolling_onUpdate = restoreFunction("Rolling_onUpdate") if FIRST_R1_CHAINS_TO_SECOND_R2 == TRUE then AttackRightLight1_onUpdate = createReplacement("AttackRightLight1_onUpdate", AttackRightLight1_onUpdate, AttackRightLight1_onUpdateCustom) AttackBothLight1_onUpdate = createReplacement("AttackBothLight1_onUpdate", AttackBothLight1_onUpdate, AttackBothLight1_onUpdateCustom) else AttackRightLight1_onUpdate = restoreFunction("AttackRightLight1_onUpdate") AttackBothLight1_onUpdate = restoreFunction("AttackBothLight1_onUpdate") end if DODGE_R1_CHAINS_TO_SECOND_R2 == TRUE then AttackRightLightStep_onUpdate = createReplacement("AttackRightLightStep_onUpdate", AttackRightLightStep_onUpdate, AttackRightLightStep_onUpdateCustom) AttackBothLightStep_onUpdate = createReplacement("AttackBothLightStep_onUpdate", AttackBothLightStep_onUpdate, AttackBothLightStep_onUpdateCustom) else AttackRightLightStep_onUpdate = restoreFunction("AttackRightLightStep_onUpdate") AttackBothLightStep_onUpdate = restoreFunction("AttackBothLightStep_onUpdate") end if SPRINT_R1_CHAINS_TO_SECOND_R2 == TRUE then AttackRightLightDash_onUpdate = createReplacement("AttackRightLightDash_onUpdate", AttackRightLightDash_onUpdate, AttackRightLightDash_onUpdateCustom) AttackBothDash_onUpdate = createReplacement("AttackBothDash_onUpdate", AttackBothDash_onUpdate, AttackBothDash_onUpdateCustom) else AttackRightLightDash_onUpdate = restoreFunction("AttackRightLightDash_onUpdate") AttackBothDash_onUpdate = restoreFunction("AttackBothDash_onUpdate") end if BACKSTEP_R1_CHAINS_TO_SECOND_R2 == TRUE then AttackRightBackstep_onUpdate = createReplacement("AttackRightBackstep_onUpdate", AttackRightBackstep_onUpdate, AttackRightBackstep_onUpdateCustom) AttackBothBackstep_onUpdate = createReplacement("AttackBothBackstep_onUpdate", AttackBothBackstep_onUpdate, AttackBothBackstep_onUpdateCustom) else AttackRightBackstep_onUpdate = restoreFunction("AttackRightBackstep_onUpdate") AttackBothBackstep_onUpdate = restoreFunction("AttackBothBackstep_onUpdate") end if SPRINT_R2_CHAINS_TO_SECOND_R2 == TRUE or true then AttackRightHeavyDash_onUpdate = createReplacement("AttackRightHeavyDash_onUpdate", AttackRightHeavyDash_onUpdate, AttackRightHeavyDash_onUpdateCustom) AttackBothHeavyDash_onUpdate = createReplacement("AttackBothHeavyDash_onUpdate", AttackBothHeavyDash_onUpdate, AttackBothHeavyDash_onUpdateCustom) else AttackRightHeavyDash_onUpdate = restoreFunction("AttackRightHeavyDash_onUpdate") AttackBothHeavyDash_onUpdate = restoreFunction("AttackBothHeavyDash_onUpdate") end -- ============================================================================ -- APLICAR FUNCIONES PERSONALIZADAS PARA ATAQUES DE MANO IZQUIERDA -- ============================================================================ -- Siempre activas para permitir dodge cancel en ataques L1/L2 AttackLeftLight1_onUpdate = createReplacement("AttackLeftLight1_onUpdate", AttackLeftLight1_onUpdate, AttackLeftLight1_onUpdateCustom) AttackLeftHeavy1_onUpdate = createReplacement("AttackLeftHeavy1_onUpdate", AttackLeftHeavy1_onUpdate, AttackLeftHeavy1_onUpdateCustom) -- ============================================================================ end function checkSettings() if os.clock() - g_LastSettingsCheckTime > 1 then g_LastSettingsCheckTime = os.clock() else return end local filePath = "quickDodge/quickDodgeSettings.txt" -- Function to check if a file exists local function fileExists(file) local f = io.open(file, "r") if f then io.close(f) return true else return false end end -- Function to run the file local function runFile(file) pcall(loadfile(file)) end -- Function to create the file with specified content local function createFile(file, content) local f = io.open(file, "w") f:write(content) io.close(f) end -- Main logic if fileExists(filePath) then runFile(filePath) success, error = pcall(applySettings()) if not success then createFile("quickDodge/errors.txt", error) end else createFile(filePath, [[ BACKSTEP_REPLACE_BACKWARDS_DODGE = FALSE -- When dodging backwards, backstep instead. SPRINTING_R2_ON_BACKSTEP_R2 = FALSE -- When pressing R2 from a backstep, execute the sprinting R2 instead of standing R2. INSTANT_SPRINTING_FROM_DODGE = TRUE -- If you hold the dodge button from a dodge, you exit it in a sprint. SPRINTING_ATTACKS_WHILE_HOLDING_DODGE = TRUE -- If you hold the dodge button from a dodge, instead of queueing a dodge attack, you queue a sprinting attack FAST_DODGE_R2 = TRUE -- When exiting from a dodge, the R2 attack is noticeably faster FIRST_R1_CHAINS_TO_SECOND_R2 = FALSE -- Your standing R1 chains to your second standing R2 instead of the first standing R2. DODGE_R1_CHAINS_TO_SECOND_R2 = FALSE SPRINT_R1_CHAINS_TO_SECOND_R2 = FALSE BACKSTEP_R1_CHAINS_TO_SECOND_R2 = FALSE SPRINT_R2_CHAINS_TO_SECOND_R2 = FALSE DODGE_CANCEL_GRACE_PERIOD = 0.3 -- Measured in seconds. Can dodge cancel out of attacks within the first few seconds here. CUSTOM_WEIGHT_OVERRIDE = -1 -- -1 for inactive, 1 for Light, 2 for Medium, 3 for Heavy, 4 for Overweight ]]) end end Update = createDetour(Update, checkSettings)