-
Notifications
You must be signed in to change notification settings - Fork 20
Enhance Grapple Gun with unhook functionality and modular improvements #198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Enhance Grapple Gun with unhook functionality and modular improvements #198
Conversation
Adds pie menu unhook, refines grapple gun release Introduces an "Unhook" option to the grapple gun's pie menu for easier disengagement. Improves grapple release controls: - Reload key (R) now only unhooks if the player is currently holding the grapple gun. - Double-tapping crouch now only unhooks if the player is *not* holding the grapple gun, preventing accidental release when intending to crouch or manually control the rope. Also includes a minor typo correction in the grapple logic.
- Added unhook functionality to the Grapple Gun's pie menu, allowing players to unhook only if the grapple claw can release. - Introduced a new icon for the unhook action in the pie menu. - Created a comprehensive RopeInputController to manage user input for rope length control, including shift + mouse wheel functionality and double-tap detection for unhooking. - Developed a RopePhysics module to handle the physics simulation of the rope, including collision resolution, segment management, and tension calculations. - Implemented a RopeRenderer module for visualizing the rope, including segment drawing based on tension and a tension indicator above the player. - Added a RopeStateManager to manage the state transitions and physics effects based on the grapple's state, including attachment detection and length limits. Enhance Grapple Gun with modular design and improved mechanics Refactors the grapple gun by introducing dedicated modules for rope physics, rendering, input control, and state management. This modular approach improves code organization and facilitates more advanced rope behaviors. Key improvements include: - A new physics simulation for the rope, featuring dynamic segmentation, collision resolution, and tension calculations. - Enhanced user input options, such as shift + mouse wheel for adjusting rope length and a double-tap mechanic for unhooking. - Visual upgrades to the rope, including segment-based drawing that reflects tension and an on-screen tension indicator. - An updated pie menu with an unhook action, which is only available when the grapple claw can be released. - Adjustments to grapple parameters like maximum length and climb speed to refine gameplay. Enhances Grapple Gun with modularity and improved mechanics Refactors the grapple gun by introducing dedicated modules for rope physics, rendering, input control, and state management. This modular approach enables: - Advanced rope physics with dynamic segmentation, collision resolution, and tension calculations. - Enhanced input options, including shift + mouse wheel for rope length adjustment and double-tap to unhook. - Improved visual feedback with tension-based rope rendering and an on-screen indicator. - A pie menu unhook action that is conditional on the grapple's ability to release. - Adjustments to grapple parameters, such as maximum length and climb speed, to refine gameplay.
- Standardizes module import paths across grapple gun scripts by removing the "Base.rte." prefix. - Improves grapple stability by adding checks to ensure the parent entity is a valid actor with a controller before performing updates, preventing potential errors. - Corrects Lua comparison operator from `!=` to `~=` for proper syntax. - Fixes logic for determining rope break conditions when under high tension. - Adjusts the conditions under which the rope tension indicator is displayed. - Introduces new, currently unused, rope physics functions in `RopePhysics.lua` as groundwork for future simulation enhancements.
…pplication Enhances rope physics for collision and constraints. Improves collision detection by using precise raycasting for all rope segments and updates the response to accurately halt segments at impact. Introduces an iterative constraint relaxation method that ensures the rope maintains its target total length. This method correctly anchors rope ends and handles coincident segment points for greater stability. Refactors and enhances rope physics simulation Refactors rope physics logic, centralizing it into a dedicated module. Enhances collision detection with precise raycasting for all segments, ensuring segments halt accurately at impact and rebound to prevent phasing. Introduces an iterative constraint relaxation method to maintain target rope length. This includes spring damping to prevent extreme tension forces on actors and improve stability, particularly for anchored ends. Adds light rope smoothing to reduce jaggedness and refines rope length management. Rope rendering now features a color gradient, and debug information is updated. Adjusts various physics parameters, including segment limits and pull ratios, for improved grappling behavior.
Implements a new grapple rope system based on pure Verlet constraints for robust, non-stretchy behavior. - Overhauls rope physics, removing old spring/force systems and stretch mechanics. - Makes the rope virtually unbreakable with an extremely high tension threshold (500% stretch). - Centralizes rope length control and simplifies related logic. - Enhances actor and target MO protection systems to ensure stability with the new rigid physics. - Updates debug rendering to display detailed rope state information. Make grapple rope rigid and virtually unbreakable Replaces the previous spring-based system with a pure Verlet constraint model, resulting in a non-stretchy and highly robust rope. The rope is now virtually unbreakable, only snapping at an extremely high tension threshold (500% stretch). Rope length control is centralized and simplified. Actor and target MO protection systems are enhanced to ensure stability with the new rigid physics. Debug rendering is updated to display detailed rope state information.
Introduces a maximum shooting distance, stopping the grapple hook if it doesn't attach within this range. Applies full rope physics simulation during the hook's flight phase, leading to more realistic rope behavior before attachment. If the player moves away while the airborne hook is at its maximum extension, the player is now pulled to maintain rope tension. Consolidates and refines the logic for handling rope length limits.
- Improves code readability and maintainability by adding extensive comments and documentation throughout the rope physics module. This includes module-level explanations, detailed function descriptions, and clarifications for complex logic. - Adjusts physics iteration counts for rope simulation, aiming to enhance accuracy for various rope lengths.
- Increases grapple maximum line length for extended reach. - Adjusts grapple's initial velocity to fully inherit parent's velocity. - Enhances parent gun detection radius. - Re-enables logic to set last segment positions, affecting in-flight rope behavior. - Improves rope physics stability by preventing potential division by zero errors. - Dynamically optimizes physics iterations in rope simulation. - Corrects rope segment distance calculation in constraint application.
Enhances player swinging mechanics by precisely managing position and tangential velocity when the rope is at maximum length and anchored to terrain. This ensures smooth movement along the tethered arc. Improves how maximum rope length is enforced during hook flight and when attached to objects, deferring to physics constraints for a more natural tethering effect rather than abruptly stopping the hook. Refines the initialization of rope segment positions and their historical states for both the player and hook ends. This leads to more accurate initial rope deployment and better response to movement. Standardizes the number of physics iterations for consistent simulation quality and simplifies rope rendering by always drawing segments. Additionally, adjusts the shift-scroll speed for finer rope length control and modifies target acquisition to better handle complex, multi-part objects.
- Defers grapple initialization to the first `Update` call, ensuring parent actor and gun are valid, which prevents potential early-frame errors. - Overhauls the rope physics module with more robust Verlet integration and constraint satisfaction, leading to more stable and realistic rigid rope behavior. - Improves state management, particularly for attachment collision detection and handling of grappled objects. - Streamlines input handling and clarifies module responsibilities for better maintainability. - Updates visual guide arrow logic and pie menu actions for consistency and reliability.
Improves rope behavior during flight by implementing Verlet physics for intermediate segments, resulting in a more natural drape and movement. Increases precision of hook attachment by refining raycasting logic with multiple checks and adjusted parameters for terrain and movable objects, including filtering out very small objects.
Centralizes input handling into a dedicated controller, clarifying unhook conditions: R-key requires holding the gun, while double-crouch tap works when not holding it. Introduces precise rope length adjustment using Shift + Mousewheel. Allows the grapple gun to remain active and its rope controllable even when equipped in the background hand. Updates grapple sound effects and core parameters like fire velocity and maximum line length. Improves attachment collision checks and fixes a rope rendering issue.
Improves the grapple gun's behavior for a more consistent and reliable experience. - Standardizes unhooking: R-key (reload) unhooks when the gun is equipped, while a double-crouch tap unhooks when the gun is not actively held but present in inventory. - Allows the grapple line to persist and be controlled even if the gun is unequipped, as long as it remains in the player's inventory. - Significantly tightens grapple attachment collision detection for more precise and predictable sticking to terrain and objects. - Ensures the gun's magazine visually reflects the grapple's state, appearing empty and hidden when the grapple is active, and full when retracted. - Adds a safeguard in firearm logic to prevent issues if a magazine attempts to pop a non-existent round.
- Introduced a Logger module for conditional logging, allowing for better debugging and tracking of state changes. - Integrated logging calls throughout RopeStateManager to capture key events, state transitions, and collision checks. - Enhanced the checkAttachmentCollisions method with detailed logs for terrain and MO collision detection. - Added logging for length limit checks and stretch mode applications to monitor grapple behavior. - Implemented various log levels (DEBUG, INFO, WARN, ERROR) to categorize log messages effectively. Enhances GrappleGun debugging and gun tracking Introduces comprehensive logging throughout the GrappleGun modules for improved diagnostics and easier troubleshooting of complex behaviors. This provides detailed tracing of the grapple's lifecycle, including initialization, state transitions, input processing, collision events, and interactions with its parent firearm. The logic for validating and maintaining the grapple's association with the firearm is also significantly refined and thoroughly logged, improving robustness in scenarios such as gun switching or dropping.
- Centralizes magazine state restoration logic in `RopeInputController` to ensure the gun's magazine correctly resets when the grapple is destroyed. This includes an attempt to re-establish the gun reference if initially lost. - Adds sound playback when the grapple is unhooked by firing the gun, enhancing audio feedback. - Strengthens validation of the parent gun reference within `RopeInputController` to more robustly handle scenarios where the gun might be invalid or inaccessible, preventing potential errors.
Introduces a dedicated `KEYBOARD_SHIFT` state for more reliable Shift key detection, replacing previous workarounds using jump or crouch states. Updates the Grapple Gun's `RopeInputController` to: - Utilize the new `KEYBOARD_SHIFT` state for precise rope length adjustment with Shift+Mousewheel. - Clear mouse scroll states after handling Shift+Mousewheel input, preventing unintended weapon switching. - Improves the input handling logic for clarity and returns a boolean to indicate if the precise control was activated.
- Adds a new configurable input action to the settings menu. - Increases the size of the input mapping list to accommodate more entries. - Prevents potential crashes by adding a null check when initializing input labels. - Removes the `INPUT_SHIFT` binding from Lua scripts.
Replaces `print` statements with `Logger.debug` and `Logger.info` calls. This improves log management by allowing for different log levels and easier filtering of log messages.
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! A few things in weird places (also can't say too much about the lua, seems to work so probably good) and a general "formatting": This is a no spaces project. All tabs indent! For c++ please use clang-format. For lua idk but replace spaces indent with tabs please.
Co-authored-by: Copilot <[email protected]>
Replaces grapple gun's custom logger with a reference to a common logger module, streamlining logging across scripts. Removes a specific update mechanism for the `KEYBOARD_SHIFT` state within the C++ controller logic. Applies whitespace reformatting (spaces to tabs) across several Lua files for consistency.
…GrappleGun Improves GrappleGun shift input and refactors Logger path - Enhances shift key detection for GrappleGun's precise rope control, using a more robust method for increased reliability. - Updates GrappleGun scripts to reference a common, centralized path for the Logger module. - Removes an obsolete Lua binding for the shift key, as direct shift state checking is now preferred. - Includes minor code cleanup in the input mapping settings UI.
Cleans up input handling by removing the `INPUT_SHIFT` element and the `KEYBOARD_SHIFT` control state as they are no longer required.
Removes the UI elements for a "Shift" key input binding from the settings screen. Also removes the corresponding `KEYBOARD_SHIFT` control state from Lua bindings, as this specific binding is no longer used.
…val in RopeInputController
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds unhook functionality to the Grapple Gun pie menu, refactors the grapple system into dedicated modules, improves logging, and refines input/UI behavior for stability and organization.
- Introduce null checks in the settings input mapping GUI to prevent crashes.
- Add safety handling for missing rounds in firearm update logic.
- Implement a new Lua Logger module for conditional debugging.
- Refactor Grapple Gun code (rendering, pie actions, main logic) into separate scripts and update configurations.
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
Source/Menus/SettingsInputMappingGUI.cpp | Added null checks around GUI label/button initialization |
Source/Entities/HDFirearm.cpp | Check for null pRound and skip processing if none is available |
Data/Base.rte/Scripts/Logger.lua | New conditional logging module with log levels |
Data/Base.rte/GUIs/SettingsGUI.ini | Increased CollectionBox height to accommodate new UI elements |
Data/Base.rte/Devices/Tools/GrappleGun/Scripts/RopeRenderer.lua | New module handling rope rendering and debug overlay |
Data/Base.rte/Devices/Tools/GrappleGun/Pie.lua | Added Unhook pie slice and validation helper |
Data/Base.rte/Devices/Tools/GrappleGun/GrappleGun.lua & GrappleGun.ini | Overhauled input handling, tap logic, guide arrow, and ammo state |
Comments suppressed due to low confidence (3)
Source/Menus/SettingsInputMappingGUI.cpp:39
- The
if (m_InputMapButton[i])
block is empty, and an extra closing brace appears to close the for-loop prematurely. Remove this empty check or populate it with the intended initialization, and verify brace alignment to avoid logic errors.
if (m_InputMapButton[i]) { // Add null check to prevent crash
Data/Base.rte/Devices/Tools/GrappleGun/GrappleGun.lua:71
- [nitpick] The large commented-out deactivation block clutters the logic. Remove or extract dead code into a clear comment/note to improve readability and maintainability.
--[[]
-- if parentActor.EquippedBGItem and parentActor.EquippedBGItem.ID == self.ID and parentActor.EquippedItem then
self:Deactivate()
-- end
--]]
Source/Entities/HDFirearm.cpp:728
- Using
continue
here likely causes a compile error if not inside a loop. Confirm the intended control flow—if this is meant to exit the function usereturn
, or if inside a loop usebreak
/continue
within that loop context.
if (!pRound) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested in game a bit, look and feel is really good. However having Keyboard only and Controller support broken is not ok, even if multimouse exists.
m_InputMapButton[i] = dynamic_cast<GUIButton*>(m_GUIControlManager->GetControl("ButtonInputKey" + std::to_string(i + 1))); | ||
// Add null check to prevent crash | ||
if (m_InputMapButton[i]) { | ||
// Optionally, initialize button text or state here if needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty check
Logger.debug("RopeInputController.handleShiftMousewheelControls() - Equipment and attachment checks passed") | ||
|
||
-- Check for actual SHIFT key using UInputMan | ||
local shiftHeld = UInputMan.FlagShiftState |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never hardcode keys in official modules please. Maybe run or crouch, but we also got a few weapon action keys that could be used, no need to invent anything new.
return | ||
end | ||
|
||
print("[ROPE PULLING DEBUG] Starting rope pulling handler") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use logger or remove, spams console
|
||
-- Handle SHIFT + Mousewheel for precise control first | ||
if RopeInputController.handleShiftMousewheelControls(grappleInstance, controller) then | ||
print("[ROPE PULLING DEBUG] SHIFT + Mousewheel handled, returning") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
print spam
|
||
-- 1. Check for Terrain Collision (primary ray) - require much higher strength | ||
Logger.debug("RopeStateManager.checkAttachmentCollisions() - Performing primary terrain ray cast") | ||
local terrainHit = SceneMan:CastStrengthRay(grappleInstance.Pos, collisionRay, 15, hitPoint, 0, rte.airID, grappleInstance.mapWrapsX) -- Increased from 5 to 15 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Produces this error sometimes, making the grapple gun just fire the grappler with broken rope and instantly reloading
ERROR: ...te/Devices/Tools/GrappleGun/Scripts/RopeStateManager.lua:101: attempt to index upvalue 'rte' (a nil value)
-- Handle regular mouse wheel control | ||
RopeInputController.handleMouseWheelControl(grappleInstance, controller) | ||
|
||
-- Handle directional key controls | ||
RopeInputController.handleDirectionalControl(grappleInstance, controller) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
broken controller and keyboard only support
end | ||
|
||
-- Handle directional key controls for climbing | ||
function RopeInputController.handleDirectionalControl(grappleInstance, controller) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please fix, can't have broken controller and keyboard only support.
Looks great! Helium's comments are all valid though. In terms of controls- we can just check the actor controller state. For example, shift key is typically the run button, so just check if the actor is told to run instead of checking the shift key directly. |
Introduce unhook functionality to the Grapple Gun's pie menu, allowing for easier disengagement. Refactor the grapple system into dedicated modules for improved organization and performance, enhancing rope physics, rendering, and input control. Implement robust logging for better debugging and refine input handling for a more consistent user experience. Adjust various parameters to optimize stability.