Skip to content

Commit c85575d

Browse files
committed
Improves grapple gun magazine reset and sounds
- 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.
1 parent 6488b40 commit c85575d

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,10 @@ function Update (self)
788788
Logger.info("Grapple Update() - Gun fired while grapple active")
789789
if self.actionMode == 1 then -- If flying, just delete
790790
Logger.info("Grapple Update() - Flying mode: marking for deletion")
791+
if self.returnSound then
792+
self.returnSound:Play(parentActor.Pos)
793+
Logger.debug("Grapple Update() - Return sound played for gun fire unhook (flying)")
794+
end
791795
self.ToDelete = true
792796
elseif self.actionMode > 1 then -- If attached, mark as ready to release
793797
Logger.info("Grapple Update() - Attached mode: marking ready to release")
@@ -798,6 +802,10 @@ function Update (self)
798802
if self.canRelease and self.parentGun.FiredFrame and
799803
(self.parentGun.Vel.Y ~= -1 or self.parentGun:IsActivated()) then
800804
Logger.info("Grapple Update() - Release condition met, marking for deletion")
805+
if self.returnSound then
806+
self.returnSound:Play(parentActor.Pos)
807+
Logger.debug("Grapple Update() - Return sound played for gun fire unhook (attached)")
808+
end
801809
self.ToDelete = true
802810
end
803811
end
@@ -928,18 +936,21 @@ function Destroy(self)
928936
Logger.debug("Grapple Destroy() - Crank sound instance marked for deletion")
929937
end
930938

939+
-- Try to restore magazine state via the input controller first
940+
RopeInputController.restoreMagazineState(self)
941+
931942
-- Clean up references on the parent gun
932943
if self.parentGun and self.parentGun.ID ~= rte.NoMOID then
933944
Logger.debug("Grapple Destroy() - Cleaning up parent gun references")
934945
self.parentGun.HUDVisible = true
935946
self.parentGun:RemoveNumberValue("GrappleMode")
936947
self.parentGun.StanceOffset = Vector(0,0)
937948

938-
-- Restore and show magazine when grapple is destroyed
949+
-- Restore and show magazine when grapple is destroyed (fallback)
939950
if self.parentGun.Magazine then
940951
self.parentGun.Magazine.RoundCount = 1 -- Restore to 1 round when grapple returns
941952
self.parentGun.Magazine.Scale = 1 -- Make magazine visible again
942-
Logger.debug("Grapple Destroy() - Magazine restored and made visible")
953+
Logger.debug("Grapple Destroy() - Magazine restored and made visible (fallback)")
943954
end
944955
end
945956

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

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,8 @@ function RopeInputController.refreshGunReference(grappleInstance)
537537
-- Only refresh if we don't have a valid reference
538538
if grappleInstance.parentGun then
539539
local success, presetName = pcall(function() return grappleInstance.parentGun.PresetName end)
540-
if success and presetName == "Grapple Gun" then
540+
local idSuccess, gunID = pcall(function() return grappleInstance.parentGun.ID end)
541+
if success and presetName == "Grapple Gun" and idSuccess and gunID and gunID ~= rte.NoMOID then
541542
Logger.debug("RopeInputController.refreshGunReference() - Current gun reference is valid, no refresh needed")
542543
return true -- Current reference is fine
543544
end
@@ -577,18 +578,63 @@ function RopeInputController.refreshGunReference(grappleInstance)
577578
end
578579

579580
if foundGun and grappleInstance.parentGun then
580-
-- Update magazine state for the refreshed gun
581-
if grappleInstance.parentGun.Magazine and MovableMan:IsParticle(grappleInstance.parentGun.Magazine) then
582-
local mag = ToMOSParticle(grappleInstance.parentGun.Magazine)
583-
mag.RoundCount = 0 -- Keep showing as "fired"
584-
mag.Scale = 0 -- Keep hidden while grapple is active
585-
Logger.debug("RopeInputController.refreshGunReference() - Updated magazine state for refreshed gun")
581+
-- Test if we can actually access the gun's properties
582+
local testSuccess, testID = pcall(function() return grappleInstance.parentGun.ID end)
583+
if testSuccess and testID and testID ~= rte.NoMOID then
584+
-- Update magazine state for the refreshed gun
585+
local magSuccess, magazine = pcall(function() return grappleInstance.parentGun.Magazine end)
586+
if magSuccess and magazine and MovableMan:IsParticle(magazine) then
587+
local mag = ToMOSParticle(magazine)
588+
mag.RoundCount = 0 -- Keep showing as "fired"
589+
mag.Scale = 0 -- Keep hidden while grapple is active
590+
Logger.debug("RopeInputController.refreshGunReference() - Updated magazine state for refreshed gun")
591+
end
592+
return true
593+
else
594+
Logger.warn("RopeInputController.refreshGunReference() - Found gun but cannot access its properties")
595+
grappleInstance.parentGun = nil
596+
return false
586597
end
587-
return true
588598
end
589599

590600
Logger.warn("RopeInputController.refreshGunReference() - Could not find any grapple gun")
591601
return false
592602
end
593603

604+
-- Restore magazine state when grapple is being destroyed
605+
function RopeInputController.restoreMagazineState(grappleInstance)
606+
if not grappleInstance.parentGun then
607+
Logger.debug("RopeInputController.restoreMagazineState() - No parent gun to restore")
608+
-- Try to find gun one more time for restoration
609+
if RopeInputController.refreshGunReference(grappleInstance) then
610+
Logger.debug("RopeInputController.restoreMagazineState() - Found gun during restoration attempt")
611+
else
612+
return false
613+
end
614+
end
615+
616+
-- Don't call refreshGunReference again if we already have a gun reference
617+
-- Test the gun reference directly
618+
local success, gunID = pcall(function() return grappleInstance.parentGun.ID end)
619+
if success and gunID and gunID ~= rte.NoMOID then
620+
Logger.info("RopeInputController.restoreMagazineState() - Restoring magazine state for gun (ID: %d)", gunID)
621+
622+
-- Restore magazine visibility and ammo count
623+
local magSuccess, magazine = pcall(function() return grappleInstance.parentGun.Magazine end)
624+
if magSuccess and magazine and MovableMan:IsParticle(magazine) then
625+
local mag = ToMOSParticle(magazine)
626+
mag.RoundCount = 1 -- Restore ammo
627+
mag.Scale = 1 -- Make magazine visible again
628+
Logger.info("RopeInputController.restoreMagazineState() - Magazine restored (visible, ammo: 1)")
629+
return true
630+
else
631+
Logger.warn("RopeInputController.restoreMagazineState() - No magazine found to restore")
632+
end
633+
else
634+
Logger.warn("RopeInputController.restoreMagazineState() - Gun ID invalid or inaccessible")
635+
end
636+
637+
return false
638+
end
639+
594640
return RopeInputController

0 commit comments

Comments
 (0)