@@ -50,60 +50,65 @@ function Update(self)
50
50
51
51
-- Ensure the gun is held by a valid, player-controlled Actor.
52
52
if not parent or not IsActor (parent ) then
53
- self :Deactivate ()
53
+ self :Deactivate () -- If not held by an actor, deactivate.
54
54
return
55
55
end
56
56
57
- local parentActor = ToActor (parent )
57
+ local parentActor = ToActor (parent ) -- Cast to Actor base type
58
+ -- Specific casting to AHuman or ACrab can be done if needed for type-specific logic
58
59
59
60
if not parentActor :IsPlayerControlled () or parentActor .Status >= Actor .DYING then
60
- self :Deactivate ()
61
+ self :Deactivate () -- Deactivate if not player controlled or if player is dying.
61
62
return
62
63
end
63
64
64
65
local controller = parentActor :GetController ()
65
66
if not controller then
66
- self :Deactivate ()
67
+ self :Deactivate () -- Should not happen if IsPlayerControlled is true, but good check.
67
68
return
68
69
end
69
70
71
+ -- REMOVE/COMMENT OUT this section that deactivates in background:
72
+ --[[
73
+ if parentActor.EquippedBGItem and parentActor.EquippedBGItem.ID == self.ID and parentActor.EquippedItem then
74
+ self:Deactivate()
75
+ // Potentially return here if no further logic should run for a BG equipped grapple gun.
76
+ end
77
+ --]]
78
+
79
+ -- Allow gun to stay active in background for rope functionality
80
+
70
81
-- Magazine handling (visual representation of the hook's availability)
71
82
if self .Magazine and MovableMan :IsParticle (self .Magazine ) then
72
83
local magazineParticle = ToMOSParticle (self .Magazine )
73
84
74
- -- Check if we have an active grapple
75
- local hasActiveGrapple = false
76
- for mo in MovableMan .AddedActors do
77
- if mo and mo .PresetName == " Grapple Gun Claw" and mo .parentGun and mo .parentGun .ID == self .ID then
78
- hasActiveGrapple = true
79
- break
80
- end
81
- end
82
-
83
- -- Update magazine based on grapple state
84
- if hasActiveGrapple then
85
- magazineParticle .RoundCount = 0 -- Empty when grapple is out
86
- magazineParticle .Scale = 0 -- Hidden
87
- self .hasGrappleActive = true
88
- elseif self .hasGrappleActive and not hasActiveGrapple then
89
- -- Grapple just returned, restore ammo
90
- magazineParticle .RoundCount = 1
91
- magazineParticle .Scale = 1
92
- magazineParticle .Frame = 0
93
- self .hasGrappleActive = false
94
- end
95
-
96
- -- Set stance offset when hook is loaded
97
- if magazineParticle .Scale == 1 then
98
- local parentSprite = ToMOSprite (self :GetParent ())
85
+ -- Double tapping crouch retrieves the hook (if a grapple is active)
86
+ -- This logic seems to be for initiating a retrieve action from the gun itself.
87
+ -- The actual unhooking is handled by the Grapple.lua script's tap detection.
88
+ -- This section might be redundant if Grapple.lua's tap detection is comprehensive.
89
+ if magazineParticle .Scale == 1 then -- Assuming Scale 1 means hook is "loaded" / available to fire
90
+ -- The following stance offsets seem to be for when the hook is *not* fired yet.
91
+ -- Consider if this is the correct condition.
92
+ local parentSprite = ToMOSprite (self :GetParent ()) -- Assuming self:GetParent() is the gun's sprite component
99
93
if parentSprite then
100
94
local spriteWidth = parentSprite :GetSpriteWidth () or 0
101
95
self .StanceOffset = Vector (spriteWidth , 1 )
102
96
self .SharpStanceOffset = Vector (spriteWidth , 1 )
103
97
end
98
+
99
+ -- REMOVE the entire crouch-tap section from the gun - it should only be in the hook
100
+ -- The gun should NOT handle unhooking directly
101
+
102
+ -- Only keep this for other gun functionality, NOT for unhooking:
103
+ if controller :IsState (Controller .WEAPON_RELOAD ) then
104
+ -- Gun's own reload logic here (if any)
105
+ -- Do NOT send unhook signals from here
106
+ end
107
+
104
108
end
105
109
106
110
-- Guide arrow visibility logic
111
+ -- Show if magazine scale is 0 (hook is fired) AND not sharp aiming, OR if parent is moving fast.
107
112
local shouldShowGuide = false
108
113
if magazineParticle .Scale == 0 and not controller :IsState (Controller .AIM_SHARP ) then
109
114
shouldShowGuide = true
@@ -112,26 +117,77 @@ function Update(self)
112
117
end
113
118
self .guide = shouldShowGuide
114
119
else
115
- self .guide = false
120
+ self .guide = false -- No magazine or not a particle, so no guide based on it.
116
121
end
117
122
118
123
-- Draw the guide arrow if enabled and valid
119
124
if self .guide and self .arrow and self .arrow .ID ~= rte .NoMOID then
120
125
local frame = 0
121
126
if parentActor .Vel and parentActor .Vel :MagnitudeIsGreaterThan (12 ) then
122
- frame = 1
127
+ frame = 1 -- Use a different arrow frame for higher speeds
123
128
end
124
129
125
- local eyePos = parentActor .EyePos or Vector (0 ,0 )
126
- local startPos = (parentActor .Pos + eyePos + self .Pos )/ 3
130
+ -- Calculate positions for drawing the arrow
131
+ -- EyePos might not exist on all Actor types, ensure parentActor has it or use a fallback.
132
+ local eyePos = parentActor .EyePos or Vector (0 ,0 )
133
+ local startPos = (parentActor .Pos + eyePos + self .Pos )/ 3 -- Averaged position
127
134
local aimAngle = parentActor :GetAimAngle (true )
128
- local aimDistance = parentActor .AimDistance or 50
135
+ local aimDistance = parentActor .AimDistance or 50 -- Default AimDistance if not present
129
136
local guidePos = startPos + Vector (aimDistance + (parentActor .Vel and parentActor .Vel .Magnitude or 0 ), 0 ):RadRotate (aimAngle )
130
137
138
+ -- Ensure the arrow MO still exists before trying to draw with it
131
139
if MovableMan :IsValid (self .arrow ) then
132
140
PrimitiveMan :DrawBitmapPrimitive (ActivityMan :GetActivity ():ScreenOfPlayer (controller .Player ), guidePos , self .arrow , aimAngle , frame )
133
141
else
134
- self .arrow = nil
142
+ self .arrow = nil -- Arrow MO was deleted, nullify reference
143
+ end
144
+ end
145
+
146
+ -- Check if we have an active grapple
147
+ local hasActiveGrapple = false
148
+ for mo in MovableMan .AddedActors do
149
+ if mo and mo .PresetName == " Grapple Gun Claw" and mo .parentGun and mo .parentGun .ID == self .ID then
150
+ hasActiveGrapple = true
151
+ break
152
+ end
153
+ end
154
+
155
+ -- Update magazine based on grapple state
156
+ if self .Magazine and MovableMan :IsParticle (self .Magazine ) then
157
+ local mag = ToMOSParticle (self .Magazine )
158
+ if hasActiveGrapple then
159
+ mag .RoundCount = 0 -- Empty when grapple is out
160
+ self .hasGrappleActive = true
161
+ elseif self .hasGrappleActive and not hasActiveGrapple then
162
+ -- Grapple just returned, restore ammo
163
+ mag .RoundCount = 1
164
+ self .hasGrappleActive = false
165
+ end
166
+ end
167
+
168
+ -- Ensure magazine is visually "full" and ready if no grapple is active.
169
+ -- This assumes the HDFirearm's standard magazine logic handles firing.
170
+ -- If a grapple claw MO (the projectile) is active, Grapple.lua will hide the magazine.
171
+ -- This section ensures it's visible when no grapple is out.
172
+ if self .Magazine and MovableMan :IsParticle (self .Magazine ) then
173
+ local magParticle = ToMOSParticle (self .Magazine )
174
+ local isActiveGrapple = false
175
+ -- Check if there's an active grapple associated with this gun
176
+ for mo_instance in MovableMan :GetMOsByPreset (" Grapple Gun Claw" ) do
177
+ if mo_instance and mo_instance .parentGun and mo_instance .parentGun .ID == self .ID then
178
+ isActiveGrapple = true
179
+ break
180
+ end
181
+ end
182
+
183
+ if not isActiveGrapple then
184
+ magParticle .RoundCount = 1 -- Visually full
185
+ magParticle .Scale = 1 -- Visible
186
+ magParticle .Frame = 0 -- Standard frame
187
+ else
188
+ magParticle .Scale = 0 -- Hidden by active grapple (Grapple.lua also does this)
189
+ magParticle .RoundCount = 0 -- Visually empty
190
+
135
191
end
136
192
end
137
193
end
0 commit comments