diff --git a/src/client/ChassisController.luau b/src/client/ChassisController.luau index abd3a5d..2b6a5ae 100644 --- a/src/client/ChassisController.luau +++ b/src/client/ChassisController.luau @@ -29,6 +29,11 @@ local ChassisController = {} local heartbeatConn: RBXScriptConnection? = nil local seatedConn: RBXScriptConnection? = nil +-- The seat the live heartbeatConn is bound to. On respawn the old car is +-- destroyed and a new one spawned; the connection stays alive but drives the +-- DESTROYED car's motors. Tracking the seat lets the watchdog notice that the +-- loop is stale and re-arm against the new car. +local drivingSeat: VehicleSeat? = nil local function findCarModel(seat: VehicleSeat): Model? local model = seat:FindFirstAncestorOfClass("Model") @@ -70,6 +75,7 @@ local function startDriving(seat: VehicleSeat) return end + drivingSeat = seat heartbeatConn = RunService.Heartbeat:Connect(function() local throttle = seat.ThrottleFloat local steer = seat.SteerFloat @@ -106,6 +112,7 @@ local function stopDriving() heartbeatConn:Disconnect() heartbeatConn = nil end + drivingSeat = nil end function ChassisController.init() @@ -141,7 +148,15 @@ function ChassisController.init() local seated = seatPart and seatPart:IsA("VehicleSeat") and seatPart.Name == Chassis.SEAT_NAME - if seated and not heartbeatConn then + -- A live connection bound to a different seat (or to a car that + -- has since been destroyed) is STALE: it keeps driving the old + -- car's motors, so heartbeatConn stays non-nil and the new car + -- never gets armed. Re-arm whenever the bound seat isn't the + -- one we're actually sitting in, or its car left the world. + local stale = heartbeatConn ~= nil + and (drivingSeat ~= seatPart or not seatPart:IsDescendantOf(workspace)) + if seated and (not heartbeatConn or stale) then + stopDriving() startDriving(seatPart :: VehicleSeat) elseif not seated and heartbeatConn then stopDriving()