Skip to content

Commit 4bad057

Browse files
committed
Refine grapple controls and enable background functionality
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.
1 parent f13173c commit 4bad057

File tree

5 files changed

+174
-174
lines changed

5 files changed

+174
-174
lines changed

Data/Base.rte/Devices/Tools/GrappleGun/Grapple.lua

Lines changed: 41 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ function Create(self)
2020
-- self.initializationOk = true -- This flag is effectively replaced by checking self.actionMode == 0 in Update.
2121

2222
-- Core grapple properties
23-
self.fireVel = 30 -- Initial velocity of the hook. Overwrites .ini FireVel.
24-
self.hookRadius = 50 -- Reduced from 360 for more precise parent finding
23+
self.fireVel = 40 -- Initial velocity of the hook. Overwrites .ini FireVel.
24+
self.hookRadius = 360 -- Reduced from 360 for more precise parent finding
2525

26-
self.maxLineLength = 600 -- Maximum allowed length of the rope.
26+
self.maxLineLength = 1000 -- Maximum allowed length of the rope.
2727
self.maxShootDistance = self.maxLineLength * 0.95 -- Hook will detach if it travels further than this before sticking.
2828
self.setLineLength = 0 -- Target length set by input/logic.
2929
self.lineStrength = 10000 -- Force threshold for breaking (effectively unbreakable).
@@ -82,6 +82,17 @@ function Create(self)
8282
-- Parent gun, parent actor, and related properties (Vel, anchor points, parentRadius)
8383
-- will be determined and set in the first Update call.
8484
-- No self.ToDelete = true will be set in Create.
85+
86+
-- Add these new flags:
87+
self.shouldUnhook = false -- Flag set by gun to signal unhook
88+
-- self.reloadKeyPressed = false -- Track R key state to prevent spam
89+
90+
-- Keep only the tap detection variables:
91+
self.tapCounter = 0
92+
self.canTap = false
93+
self.tapTime = 150
94+
self.tapAmount = 2
95+
self.tapTimer = Timer()
8596
end
8697

8798
function Update(self)
@@ -186,29 +197,6 @@ function Update(self)
186197
return
187198
end
188199

189-
local controller = parentActor:GetController()
190-
if not controller then
191-
self.ToDelete = true
192-
return
193-
end
194-
local player = controller.Player or 0
195-
196-
-- Handle pie menu modes
197-
if self.parentGun then
198-
local mode = self.parentGun:GetNumberValue("GrappleMode")
199-
if mode ~= 0 then
200-
if mode == 3 then -- Unhook via Pie Menu
201-
self.ToDelete = true
202-
if self.parentGun then
203-
self.parentGun:RemoveNumberValue("GrappleMode")
204-
end
205-
else
206-
self.pieSelection = mode
207-
self.parentGun:RemoveNumberValue("GrappleMode")
208-
end
209-
end
210-
end
211-
212200
-- Standard update flags
213201
self.ToSettle = false -- Grapple claw should not settle
214202

@@ -357,34 +345,37 @@ function Update(self)
357345
-- Player-specific controls and unhooking mechanisms
358346
if IsAHuman(parentActor) or IsACrab(parentActor) then
359347
if parentActor:IsPlayerControlled() then
360-
-- R key unhooking functionality
361-
local isHoldingGrapple = false
362-
363-
-- Check if holding grapple in main hand
364-
if self.parent.EquippedItem and self.parentGun and self.parent.EquippedItem.ID == self.parentGun.ID then
365-
isHoldingGrapple = true
366-
end
367-
368-
-- Check if holding grapple in off-hand
369-
local isHoldingInBG = self.parent.EquippedBGItem and self.parentGun and
370-
self.parent.EquippedBGItem.ID == self.parentGun.ID
371-
372-
-- If reload key pressed while holding grapple gun, unhook
373-
if controller:IsState(Controller.WEAPON_RELOAD) and (isHoldingGrapple or isHoldingInBG) then
374-
print("R key unhook triggered!") -- Debug message
375-
self.ToDelete = true
376-
return -- Exit immediately to prevent other checks
377-
end
378-
379-
-- Unhook with double-tap crouch (ONLY when NOT holding the gun)
380-
if not isHoldingGrapple and not isHoldingInBG then
348+
local controller = self.parent:GetController()
349+
if controller then
350+
-- ONLY use RopeInputController for all input handling
351+
352+
-- 1. R key to unhook (when holding gun)
353+
if RopeInputController.handleReloadKeyUnhook(self, controller) then
354+
print("Unhooking via R key!")
355+
self.ToDelete = true
356+
return
357+
end
358+
359+
-- 2. Double crouch-tap to unhook (when NOT holding gun)
381360
if RopeInputController.handleTapDetection(self, controller) then
382-
print("Double-tap unhook triggered!") -- Debug message
361+
print("Unhooking via double crouch!")
362+
self.ToDelete = true
363+
return
364+
end
365+
366+
-- 3. Pie menu unhook
367+
if RopeInputController.handlePieMenuSelection(self) then
368+
print("Unhooking via pie menu!")
383369
self.ToDelete = true
384-
return -- Exit immediately
370+
return
385371
end
372+
373+
-- 4. Other rope controls
374+
RopeInputController.handleRopePulling(self)
375+
RopeInputController.handleAutoRetraction(self, false)
386376
end
387377
end
378+
388379
-- Gun stance offset when holding the gun
389380
if self.parentGun and self.parentGun.RootID == parentActor.ID then
390381
if MovableMan:IsParticle(self.parentGun.Magazine) then -- Check if Magazine is a particle
@@ -394,27 +385,7 @@ function Update(self)
394385
self.parentGun.StanceOffset = Vector(self.lineLength, 0):RadRotate(offsetAngle)
395386
end
396387
end
397-
398-
-- Delegate all input handling to RopeInputController
399-
-- 1. Pie menu selection (unhook, retract, extend)
400-
if RopeInputController.handlePieMenuSelection(self) then
401-
self.ToDelete = true
402-
if self.parentGun then self.parentGun:RemoveNumberValue("GrappleMode") end
403-
return
404-
end
405-
-- 2. R key (reload) to unhook
406-
if RopeInputController.handleReloadKeyUnhook(self, controller) then
407-
self.ToDelete = true
408-
return
409-
end
410-
-- 3. Double-tap crouch to unhook (only if not holding gun)
411-
if RopeInputController.handleTapDetection(self, controller) then
412-
self.ToDelete = true
413-
return
414-
end
415-
-- 4. Mousewheel and directional controls for rope length
416-
RopeInputController.handleRopePulling(self)
417-
388+
418389
-- Render the rope
419390
RopeRenderer.drawRope(self, player)
420391

Data/Base.rte/Devices/Tools/GrappleGun/GrappleGun.lua

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ function Update(self)
5151
return
5252
end
5353

54-
local parentActor = ToActor(parent) -- Cast to Actor base type.
55-
-- Specific casting to AHuman or ACrab can be done if needed for type-specific logic.
54+
local parentActor = ToActor(parent) -- Cast to Actor base type
55+
-- Specific casting to AHuman or ACrab can be done if needed for type-specific logic
5656

5757
if not parentActor:IsPlayerControlled() or parentActor.Status >= Actor.DYING then
5858
self:Deactivate() -- Deactivate if not player controlled or if player is dying.
@@ -65,12 +65,15 @@ function Update(self)
6565
return
6666
end
6767

68-
-- Deactivate if equipped in the background arm and a foreground item exists,
69-
-- to allow the foreground item (e.g., another weapon) to be used.
68+
-- REMOVE/COMMENT OUT this section that deactivates in background:
69+
--[[
7070
if parentActor.EquippedBGItem and parentActor.EquippedBGItem.ID == self.ID and parentActor.EquippedItem then
7171
self:Deactivate()
72-
-- Potentially return here if no further logic should run for a BG equipped grapple gun.
72+
// Potentially return here if no further logic should run for a BG equipped grapple gun.
7373
end
74+
--]]
75+
76+
-- Allow gun to stay active in background for rope functionality
7477

7578
-- Magazine handling (visual representation of the hook's availability)
7679
if self.Magazine and MovableMan:IsParticle(self.Magazine) then
@@ -90,31 +93,15 @@ function Update(self)
9093
self.SharpStanceOffset = Vector(spriteWidth, 1)
9194
end
9295

93-
-- Crouch-tap logic (potentially for recalling an active hook)
94-
if controller:IsState(Controller.BODY_PRONE) then
95-
if self.canTap then
96-
controller:SetState(Controller.BODY_PRONE, false) -- Prevent continuous prone state
97-
self.tapTimerJump:Reset()
98-
-- self.didTap = true; -- Mark that a tap occurred (if used elsewhere)
99-
self.canTap = false
100-
self.tapCounter = self.tapCounter + 1
101-
end
102-
else
103-
self.canTap = true -- Allow first tap when not prone
104-
end
105-
106-
if self.tapTimerJump:IsPastSimMS(self.tapTime) then
107-
self.tapCounter = 0 -- Reset counter if too much time has passed
108-
else
109-
if self.tapCounter >= self.tapAmount then
110-
-- If enough taps, activate the gun. This might be intended to fire/recall.
111-
-- If a grapple is already out, Grapple.lua's tap detection should handle recall.
112-
-- If no grapple is out, this would fire a new one.
113-
-- Clarify the intent: is this to fire, or to send a signal to an existing grapple?
114-
self:Activate() -- This will typically fire the HDFirearm.
115-
self.tapCounter = 0
116-
end
96+
-- REMOVE the entire crouch-tap section from the gun - it should only be in the hook
97+
-- The gun should NOT handle unhooking directly
98+
99+
-- Only keep this for other gun functionality, NOT for unhooking:
100+
if controller:IsState(Controller.WEAPON_RELOAD) then
101+
-- Gun's own reload logic here (if any)
102+
-- Do NOT send unhook signals from here
117103
end
104+
118105
end
119106

120107
-- Guide arrow visibility logic
@@ -174,6 +161,8 @@ function Update(self)
174161
magParticle.Frame = 0 -- Standard frame
175162
else
176163
magParticle.Scale = 0 -- Hidden by active grapple (Grapple.lua also does this)
164+
magParticle.RoundCount = 0 -- Visually empty
165+
177166
end
178167
end
179168
end

0 commit comments

Comments
 (0)