-- It would technically be faster to patch the Barotrauma.Items.Components.Sonar.Use method. -- But doing so would not allow me to stop the default ping sound from playing. Hook.Patch( "Barotrauma.Item", "Use", function(instance, ptable) if not RealSonar.Config.CustomSonar then return end local instance_sonar = instance.GetComponentString("Sonar") for terminal in RealSonar.sonarItems do if terminal.GetComponentString("Sonar") == instance_sonar and tostring(instance_sonar.CurrentMode) == "Active" then if instance_sonar.UseDirectionalPing then Hook.Call("sonarPingDirectional", nil, nil, terminal) else Hook.Call("sonarPing", nil, nil, terminal) end -- Prevent default ping sound from playing. ptable.PreventExecution = true end end end, Hook.HookMethodType.Before) Hook.Add("sonarPing", "sonarPing", function(effect, deltaTime, item, targets, worldPosition) local terminal_id = item.Prefab.Identifier.Value local sonar = item.GetComponentString("Sonar") -- deltaTime being passed in means that the hook was called from XML if RealSonar.Config.CustomSonar and deltaTime then -- If the terminal is registered cancel the XML status effect. if RealSonar.Config.SonarTerminals[terminal_id] then return true -- Otherwise, add the terminal to the config. else RealSonar.Config.SonarTerminals[terminal_id] = {} RealSonar.Config.SonarTerminals[terminal_id]["damage"] = "high" RealSonar.Config.SonarTerminals[terminal_id]["sounds"] = "default" RealSonar.Config.SonarTerminals[terminal_id]["range"] = sonar.Range table.insert(RealSonar.sonarItems, item) print("Real Sonar: Automatically added '", terminal_id, "' to config with default values.") end end local distance local amount local terminal_type local sonarResistanceData local damageMultiplier local muffleSonar -- Select correct sound-playing function. local soundPreset = "default" if RealSonar.Config.SonarTerminals[terminal_id] then soundPreset = RealSonar.Config.SonarTerminals[terminal_id]["sounds"] end local airSounds = RealSonar.airSounds local waterSounds = RealSonar.waterSounds local suitSounds = RealSonar.suitSounds if soundPreset == "shuttle" then airSounds = RealSonar.airSoundsShuttle waterSounds = RealSonar.waterSoundsShuttle suitSounds = RealSonar.suitSoundsShuttle end terminal_type = RealSonar.getTerminalType(terminal_id) for _, character in pairs(Character.CharacterList) do distance = RealSonar.distanceBetween(item.worldPosition, character.worldPosition) if distance < sonar.Range and not character.isDead then amount = (1 - distance / sonar.Range) * 100 -- Air sounds. if not character.InWater or not RealSonar.isEnabledForTerminal(terminal_id) or not RealSonar.pathToBreach(character) then if character.isPlayer then airSounds(character, amount) end elseif RealSonar.isEnabledForTerminal(terminal_id) and RealSonar.pathToBreach(character) then sonarResistanceData = RealSonar.getSonarResistanceData(character) damageMultiplier = sonarResistanceData[1] muffleSonar = sonarResistanceData[2] -- Damage. RealSonar.GiveAffliction(character, string.format("activesonar%slua", terminal_type), (amount * damageMultiplier) * RealSonar.Config.SonarDamage) -- Stun & slow. if character.isHuman and not muffleSonar then RealSonar.GiveAffliction(character, string.format("sonarshakestun%s", terminal_type), (amount * damageMultiplier) * RealSonar.Config.ImpactVisuals) RealSonar.SetAffliction(character, string.format("sonarslow%s", terminal_type), (amount * damageMultiplier) * RealSonar.Config.SonarSlow) end -- Water sounds & impact visuals. if not muffleSonar and character.isPlayer then RealSonar.GiveAffliction(character, string.format("sonarvisuals%s", terminal_type), (amount * damageMultiplier) * RealSonar.Config.ImpactVisuals) waterSounds(character, amount * damageMultiplier) -- Suit sounds. elseif character.isPlayer then suitSounds(character, amount) end -- Bot messages. if terminal_id ~= "sonarmonitor" and character.isBot and character.IsOnPlayerTeam and not character.IsUnconscious then character.Speak(TextManager.Get("dialogturnoffsonar").Value, nil, 0.5, "dialogturnoffsonar", 5) end end end end -- Cancel the rest of the Status Effect. return true end) Hook.Add("sonarPingDirectional", "sonarPingDirectional", function(effect, deltaTime, item, targets, worldPosition) local terminal_id = item.Prefab.Identifier.Value local sonar = item.GetComponentString("Sonar") -- deltaTime being passed in means that the hook was called from XML if RealSonar.Config.CustomSonar and deltaTime then -- If the terminal is registered cancel the XML status effect. if RealSonar.Config.SonarTerminals[terminal_id] then return true -- Otherwise, add the terminal to the config. else RealSonar.Config.SonarTerminals[terminal_id] = {} RealSonar.Config.SonarTerminals[terminal_id]["damage"] = "high" RealSonar.Config.SonarTerminals[terminal_id]["sounds"] = "default" RealSonar.Config.SonarTerminals[terminal_id]["range"] = sonar.Range table.insert(RealSonar.sonarItems, item) print("Real Sonar: Automatically added '", terminal_id, "' to config with default values.") end end local distance local amount local terminal_type local sonarResistanceData local damageMultiplier local muffleSonar local soundRangeMultiplier = 2.0 local inConeDamageMultiplier = 1.5 local outConeDamageMultiplier = 0.6 -- Select correct sound-playing function. local soundPreset = "default" if RealSonar.Config.SonarTerminals[terminal_id] then soundPreset = RealSonar.Config.SonarTerminals[terminal_id]["sounds"] end local airSoundsDirectional = RealSonar.airSoundsDirectional local waterSoundsDirectional = RealSonar.waterSoundsDirectional local suitSoundsDirectional = RealSonar.suitSoundsDirectional local waterSounds = RealSonar.waterSounds local suitSounds = RealSonar.suitSounds if soundPreset == "shuttle" then airSoundsDirectional = RealSonar.airSoundsShuttleDirectional waterSoundsDirectional = RealSonar.waterSoundsShuttleDirectional suitSoundsDirectional = RealSonar.suitSoundsShuttleDirectional waterSounds = RealSonar.waterSoundsShuttle suitSounds = RealSonar.suitSoundsShuttle end terminal_type = RealSonar.getTerminalType(terminal_id) for _, character in pairs(Character.CharacterList) do distance = RealSonar.distanceBetween(item.worldPosition, character.worldPosition) if distance < sonar.Range and not character.isDead then amount = (1 - distance / sonar.Range) * 100 -- Air sounds. if (not character.InWater or not RealSonar.isEnabledForTerminal(terminal_id) or not RealSonar.pathToBreach(character)) and character.isPlayer then airSoundsDirectional(character, amount) elseif RealSonar.isEnabledForTerminal(terminal_id) and RealSonar.pathToBreach(character) then sonarResistanceData = RealSonar.getSonarResistanceData(character) damageMultiplier = sonarResistanceData[1] muffleSonar = sonarResistanceData[2] -- Being aimed at. if RealSonar.inDirectionalSector(character, item) then -- Damage. RealSonar.GiveAffliction(character, string.format("activesonar%slua", terminal_type), ((amount * damageMultiplier) * inConeDamageMultiplier) * RealSonar.Config.SonarDamage) -- Stun & slow. if character.isHuman and not muffleSonar then RealSonar.GiveAffliction(character, string.format("sonarshakestun%s", terminal_type), ((amount * damageMultiplier) * inConeDamageMultiplier) * RealSonar.Config.ImpactVisuals) RealSonar.SetAffliction(character, string.format("sonarslow%s", terminal_type), ((amount * damageMultiplier) * inConeDamageMultiplier) * RealSonar.Config.SonarSlow) end -- Water sounds & impact visuals. if not muffleSonar and character.isPlayer then RealSonar.GiveAffliction(character, string.format("sonarvisuals%s", terminal_type), ((amount * damageMultiplier) * inConeDamageMultiplier) * RealSonar.Config.ImpactVisuals) waterSounds(character, (amount * damageMultiplier) * soundRangeMultiplier) -- Suit sounds. elseif character.isPlayer then suitSounds(character, (amount * damageMultiplier) * soundRangeMultiplier) end -- Bot messages. if terminal_id ~= "sonarmonitor" and character.isBot and character.IsOnPlayerTeam and not character.IsUnconscious then character.Speak(TextManager.Get("dialogturnoffsonar").Value, nil, 0.5, "dialogturnoffsonar", 5) end -- Not being aimed at. else -- Damage. RealSonar.GiveAffliction(character, string.format("activesonar%slua", terminal_type), ((amount * damageMultiplier) * outConeDamageMultiplier) * RealSonar.Config.SonarDamage) -- Water sounds. if not muffleSonar and character.isPlayer then waterSoundsDirectional(character, amount) -- Suit sounds. elseif character.isPlayer then suitSoundsDirectional(character, amount) end end end end end -- Cancel the rest of the Status Effect. return true end)