Impact sounds

This commit is contained in:
SDraw 2026-04-18 22:42:47 +03:00
parent 15de34c0bd
commit 2a06001100
No known key found for this signature in database
GPG key ID: BB95B4DAB2BB8BB5
23 changed files with 401 additions and 96 deletions

View file

@ -5,12 +5,14 @@ namespace ml_prm
public class PlayerRagdollMod : MelonLoader.MelonMod public class PlayerRagdollMod : MelonLoader.MelonMod
{ {
RagdollController m_controller = null; RagdollController m_controller = null;
SoundManager m_soundManager = null;
public override void OnInitializeMelon() public override void OnInitializeMelon()
{ {
Settings.Init(); Settings.Init();
GameEvents.Init(HarmonyInstance); GameEvents.Init(HarmonyInstance);
WorldManager.Init(); WorldManager.Init();
ResourcesHandler.ExtractResources();
} }
public override void OnLateInitializeMelon() public override void OnLateInitializeMelon()
@ -26,6 +28,8 @@ namespace ml_prm
yield return null; yield return null;
m_controller = new UnityEngine.GameObject("[PlayerRagdollMod]").AddComponent<RagdollController>(); m_controller = new UnityEngine.GameObject("[PlayerRagdollMod]").AddComponent<RagdollController>();
m_soundManager = new SoundManager(m_controller.transform);
m_soundManager.LoadSounds();
} }
System.Collections.IEnumerator WaitForWhitelist() System.Collections.IEnumerator WaitForWhitelist()
@ -40,6 +44,8 @@ namespace ml_prm
{ {
WorldManager.DeInit(); WorldManager.DeInit();
m_soundManager = null;
if(m_controller != null) if(m_controller != null)
UnityEngine.Object.Destroy(m_controller.gameObject); UnityEngine.Object.Destroy(m_controller.gameObject);
m_controller = null; m_controller = null;

View file

@ -34,7 +34,9 @@ namespace ml_prm
AngularDrag, AngularDrag,
RecoverDelay, RecoverDelay,
FallLimit, FallLimit,
GestureGrab GestureGrab,
ImpactSounds,
ImpactVolume
} }
const string c_ragdollKeyTooltip = "Switch ragdoll mode with '{0}' key"; const string c_ragdollKeyTooltip = "Switch ragdoll mode with '{0}' key";
@ -59,11 +61,13 @@ namespace ml_prm
static ToggleButton ms_buoyancyToggle = null; static ToggleButton ms_buoyancyToggle = null;
static ToggleButton ms_fallDamageToggle = null; static ToggleButton ms_fallDamageToggle = null;
static ToggleButton ms_gestureGrabToggle = null; static ToggleButton ms_gestureGrabToggle = null;
static ToggleButton ms_impactSoundsToggle = null;
static SliderFloat ms_velocityMultiplierSlider = null; static SliderFloat ms_velocityMultiplierSlider = null;
static SliderFloat ms_movementDragSlider = null; static SliderFloat ms_movementDragSlider = null;
static SliderFloat ms_angularMovementDragSlider = null; static SliderFloat ms_angularMovementDragSlider = null;
static SliderFloat ms_recoverDelaySlider = null; static SliderFloat ms_recoverDelaySlider = null;
static SliderFloat ms_fallLimitSlider = null; static SliderFloat ms_fallLimitSlider = null;
static SliderFloat ms_impactVolumeSlider = null;
static Button ms_resetButton = null; static Button ms_resetButton = null;
internal static void Init() internal static void Init()
@ -117,6 +121,9 @@ namespace ml_prm
ms_gestureGrabToggle = ms_category.AddToggle("Grab attaching", "Enable attaching of ragdolled body parts to pointers of 'grab' type<p>Warning: can lead to unpredictable physics behaviour in some cases", Settings.GestureGrab); ms_gestureGrabToggle = ms_category.AddToggle("Grab attaching", "Enable attaching of ragdolled body parts to pointers of 'grab' type<p>Warning: can lead to unpredictable physics behaviour in some cases", Settings.GestureGrab);
ms_gestureGrabToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.GestureGrab, state); ms_gestureGrabToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.GestureGrab, state);
ms_impactSoundsToggle = ms_category.AddToggle("Impact sounds", "Enable collision sound effects of ragdolled body parts", Settings.ImpactSounds);
ms_impactSoundsToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.ImpactSounds, state);
ms_velocityMultiplierSlider = ms_category.AddSlider("Velocity multiplier", "Velocity multiplier upon entering ragdoll state", Settings.VelocityMultiplier, 1f, 50f); ms_velocityMultiplierSlider = ms_category.AddSlider("Velocity multiplier", "Velocity multiplier upon entering ragdoll state", Settings.VelocityMultiplier, 1f, 50f);
ms_velocityMultiplierSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.VelocityMultiplier, value); ms_velocityMultiplierSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.VelocityMultiplier, value);
@ -133,6 +140,9 @@ namespace ml_prm
ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(Settings.FallLimit)); ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(Settings.FallLimit));
ms_fallLimitSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.FallLimit, value); ms_fallLimitSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.FallLimit, value);
ms_impactVolumeSlider = ms_category.AddSlider("Impact volume", "Volume of collision of ragdolled body parts", Settings.ImpactVolume * 100f, 0f, 100f);
ms_impactVolumeSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.ImpactVolume, value);
ms_resetButton = ms_category.AddButton("Reset settings", "", "Reset mod settings to default"); ms_resetButton = ms_category.AddButton("Reset settings", "", "Reset mod settings to default");
ms_resetButton.OnPress += Reset; ms_resetButton.OnPress += Reset;
} }
@ -202,6 +212,10 @@ namespace ml_prm
case UiIndex.GestureGrab: case UiIndex.GestureGrab:
Settings.SetSetting(Settings.ModSetting.GestureGrab, p_state); Settings.SetSetting(Settings.ModSetting.GestureGrab, p_state);
break; break;
case UiIndex.ImpactSounds:
Settings.SetSetting(Settings.ModSetting.ImpactSounds, p_state);
break;
} }
} }
catch(Exception e) catch(Exception e)
@ -238,6 +252,10 @@ namespace ml_prm
ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(p_value)); ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(p_value));
} }
break; break;
case UiIndex.ImpactVolume:
Settings.SetSetting(Settings.ModSetting.ImpactVolume, p_value * 0.01f);
break;
} }
} }
catch(Exception e) catch(Exception e)
@ -284,6 +302,9 @@ namespace ml_prm
OnToggleUpdate(UiIndex.GestureGrab, false); OnToggleUpdate(UiIndex.GestureGrab, false);
ms_gestureGrabToggle.ToggleValue = false; ms_gestureGrabToggle.ToggleValue = false;
OnToggleUpdate(UiIndex.ImpactSounds, true);
ms_impactSoundsToggle.ToggleValue = true;
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f); OnSliderUpdate(UiIndex.VelocityMultiplier, 2f);
ms_velocityMultiplierSlider.SetSliderValue(2f); ms_velocityMultiplierSlider.SetSliderValue(2f);
@ -298,6 +319,9 @@ namespace ml_prm
OnSliderUpdate(UiIndex.FallLimit, 9.899494f); OnSliderUpdate(UiIndex.FallLimit, 9.899494f);
ms_fallLimitSlider.SetSliderValue(9.899494f); ms_fallLimitSlider.SetSliderValue(9.899494f);
OnSliderUpdate(UiIndex.ImpactVolume, 100f);
ms_impactVolumeSlider.SetSliderValue(100f);
} }
static void OnHotkeyKeyChanged(UnityEngine.KeyCode p_keyCode) static void OnHotkeyKeyChanged(UnityEngine.KeyCode p_keyCode)

View file

@ -1,4 +1,4 @@
[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.2.6", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] [assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.2.7", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")] [assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
[assembly: MelonLoader.MelonPriority(2)] [assembly: MelonLoader.MelonPriority(2)]
[assembly: MelonLoader.MelonAdditionalDependencies("BTKUILib")] [assembly: MelonLoader.MelonAdditionalDependencies("BTKUILib")]

View file

@ -31,6 +31,8 @@ Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/
* **Fall damage:** enables ragdoll when falling from specific height; `true` by default. * **Fall damage:** enables ragdoll when falling from specific height; `true` by default.
* **Grab attaching:** enables attaching of ragdolled body parts to pointers with `grab` type of avatars, props and world(s); `false` by default. * **Grab attaching:** enables attaching of ragdolled body parts to pointers with `grab` type of avatars, props and world(s); `false` by default.
* Note: Can lead to unpredictable physics behaviour in some cases. * Note: Can lead to unpredictable physics behaviour in some cases.
* **Impact sounds:** enables collision sound effects of ragdolled body parts; `true` by default.
* Note: Sounds can be replaced in `(game_folder)/UserData/PlayerRagdollMod` folder.
* **Velocity multiplier:** velocity force multiplier based on player's movement direction; `2.0` by default. * **Velocity multiplier:** velocity force multiplier based on player's movement direction; `2.0` by default.
* Note: Limited according to world's fly multiplier. * Note: Limited according to world's fly multiplier.
* Note: Forcibly set to `1.0` in worlds that don't allow flight. * Note: Forcibly set to `1.0` in worlds that don't allow flight.
@ -39,6 +41,7 @@ Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/
* **Angular movement drag:** angular movement resistance; `2.0` by default. * **Angular movement drag:** angular movement resistance; `2.0` by default.
* **Recover delay:** time delay for enabled `Auto recover` in seconds; `3.0` by default. * **Recover delay:** time delay for enabled `Auto recover` in seconds; `3.0` by default.
* **Fall limit:** height limit for fall damage; `5.0` by default. * **Fall limit:** height limit for fall damage; `5.0` by default.
* **Impact volume:** collision sounds volume of ragdolled body parts; `100.0` by default.
* **Reset settings:** resets mod settings to default. * **Reset settings:** resets mod settings to default.
Optional mod's settings in [UIExpansionKit](https://github.com/ddakebono/ChilloutMods): Optional mod's settings in [UIExpansionKit](https://github.com/ddakebono/ChilloutMods):

View file

@ -100,6 +100,15 @@ namespace ml_prm
Detach(); Detach();
} }
void OnCollisionEnter(Collision p_col)
{
if(Settings.ImpactSounds && m_ready && !m_rigidBody.isKinematic && (p_col.gameObject.layer != CVRLayers.PlayerClone))
{
if(p_col.impulse.magnitude > 5f)
SoundManager.Instance.PlaySound(SoundManager.ImpactType.Soft);
}
}
void OnContactEnter(ContactCollisionInfo p_col) void OnContactEnter(ContactCollisionInfo p_col)
{ {
if(m_ready && (RagdollController.Instance != null) && ContactManager.Exists) if(m_ready && (RagdollController.Instance != null) && ContactManager.Exists)

View file

@ -690,6 +690,9 @@ namespace ml_prm
m_lastRagdollPosition = m_puppetReferences.hips.position; m_lastRagdollPosition = m_puppetReferences.hips.position;
m_downTime = 0f; m_downTime = 0f;
if(Settings.ImpactSounds)
SoundManager.Instance.PlaySound(SoundManager.ImpactType.Hard);
m_ragdolled = true; m_ragdolled = true;
} }
} }

View file

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace ml_prm
{
static class ResourcesHandler
{
const string c_modName = "PlayerRagdollMod";
readonly static string ms_namespace = typeof(ResourcesHandler).Namespace;
static readonly List<string> ms_audioResources = new List<string>()
{
"body_medium_impact_hard1.wav",
"body_medium_impact_hard2.wav",
"body_medium_impact_hard3.wav",
"body_medium_impact_hard4.wav",
"body_medium_impact_hard5.wav",
"body_medium_impact_hard6.wav",
"body_medium_impact_soft1.wav",
"body_medium_impact_soft2.wav",
"body_medium_impact_soft3.wav",
"body_medium_impact_soft4.wav",
"body_medium_impact_soft5.wav",
"body_medium_impact_soft6.wav",
"body_medium_impact_soft7.wav"
};
public static void ExtractResources()
{
string l_dirPath = MelonLoader.Utils.MelonEnvironment.UserDataDirectory;
if(!Directory.Exists(l_dirPath))
Directory.CreateDirectory(l_dirPath);
l_dirPath = Path.Combine(l_dirPath, c_modName);
if(!Directory.Exists(l_dirPath))
Directory.CreateDirectory(l_dirPath);
foreach(string l_name in ms_audioResources)
{
string l_filePath = Path.Combine(l_dirPath, l_name);
if(!File.Exists(l_filePath))
ExtractAudioFile(l_name, l_filePath);
}
}
static void ExtractAudioFile(string p_name, string p_path)
{
Assembly l_assembly = Assembly.GetExecutingAssembly();
try
{
Stream l_resourceStream = l_assembly.GetManifestResourceStream(ms_namespace + ".resources.sounds." + p_name);
Stream l_fileStream = File.Create(p_path);
l_resourceStream.CopyTo(l_fileStream);
l_fileStream.Flush();
l_fileStream.Close();
l_resourceStream.Close();
}
catch(Exception)
{
MelonLoader.MelonLogger.Warning("Unable to write '" + p_path + "' file, problems can occur.");
}
}
}
}

View file

@ -33,7 +33,9 @@ namespace ml_prm
Buoyancy, Buoyancy,
FallDamage, FallDamage,
FallLimit, FallLimit,
GestureGrab GestureGrab,
ImpactSounds,
ImpactVolume
} }
public static bool Hotkey { get; private set; } = true; public static bool Hotkey { get; private set; } = true;
@ -54,6 +56,8 @@ namespace ml_prm
public static bool FallDamage { get; private set; } = true; public static bool FallDamage { get; private set; } = true;
public static float FallLimit { get; private set; } = 9.899494f; public static float FallLimit { get; private set; } = 9.899494f;
public static bool GestureGrab { get; private set; } = false; public static bool GestureGrab { get; private set; } = false;
public static bool ImpactSounds { get; private set; } = true;
public static float ImpactVolume { get; private set; } = 1f;
public static readonly SettingEvent<bool> OnHotkeyChanged = new SettingEvent<bool>(); public static readonly SettingEvent<bool> OnHotkeyChanged = new SettingEvent<bool>();
public static readonly SettingEvent<KeyCode> OnHotkeyKeyChanged = new SettingEvent<KeyCode>(); public static readonly SettingEvent<KeyCode> OnHotkeyKeyChanged = new SettingEvent<KeyCode>();
@ -73,6 +77,8 @@ namespace ml_prm
public static readonly SettingEvent<bool> OnFallDamageChanged = new SettingEvent<bool>(); public static readonly SettingEvent<bool> OnFallDamageChanged = new SettingEvent<bool>();
public static readonly SettingEvent<float> OnFallLimitChanged = new SettingEvent<float>(); public static readonly SettingEvent<float> OnFallLimitChanged = new SettingEvent<float>();
public static readonly SettingEvent<bool> OnGestureGrabChanged = new SettingEvent<bool>(); public static readonly SettingEvent<bool> OnGestureGrabChanged = new SettingEvent<bool>();
public static readonly SettingEvent<bool> OnImpactSoundsChanged = new SettingEvent<bool>();
public static readonly SettingEvent<float> OnImpactVolumeChanged = new SettingEvent<float>();
static MelonLoader.MelonPreferences_Category ms_category = null; static MelonLoader.MelonPreferences_Category ms_category = null;
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null; static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
@ -100,7 +106,9 @@ namespace ml_prm
ms_category.CreateEntry(ModSetting.Buoyancy.ToString(), Buoyancy, null, null, true), ms_category.CreateEntry(ModSetting.Buoyancy.ToString(), Buoyancy, null, null, true),
ms_category.CreateEntry(ModSetting.FallDamage.ToString(), FallDamage, null, null, true), ms_category.CreateEntry(ModSetting.FallDamage.ToString(), FallDamage, null, null, true),
ms_category.CreateEntry(ModSetting.FallLimit.ToString(), FallLimit, null, null, true), ms_category.CreateEntry(ModSetting.FallLimit.ToString(), FallLimit, null, null, true),
ms_category.CreateEntry(ModSetting.GestureGrab.ToString(), GestureGrab, null, null, true) ms_category.CreateEntry(ModSetting.GestureGrab.ToString(), GestureGrab, null, null, true),
ms_category.CreateEntry(ModSetting.ImpactSounds.ToString(), ImpactSounds, null, null, true),
ms_category.CreateEntry(ModSetting.ImpactVolume.ToString(), ImpactVolume, null, null, true)
}; };
ms_entries[(int)ModSetting.HotkeyKey].OnEntryValueChangedUntyped.Subscribe(OnMelonSettingSave_HotkeyKey); ms_entries[(int)ModSetting.HotkeyKey].OnEntryValueChangedUntyped.Subscribe(OnMelonSettingSave_HotkeyKey);
@ -123,6 +131,8 @@ namespace ml_prm
FallDamage = (bool)ms_entries[(int)ModSetting.FallDamage].BoxedValue; FallDamage = (bool)ms_entries[(int)ModSetting.FallDamage].BoxedValue;
FallLimit = Mathf.Clamp((float)ms_entries[(int)ModSetting.FallLimit].BoxedValue, 4.5f, 44.5f); FallLimit = Mathf.Clamp((float)ms_entries[(int)ModSetting.FallLimit].BoxedValue, 4.5f, 44.5f);
GestureGrab = (bool)ms_entries[(int)ModSetting.GestureGrab].BoxedValue; GestureGrab = (bool)ms_entries[(int)ModSetting.GestureGrab].BoxedValue;
ImpactSounds = (bool)ms_entries[(int)ModSetting.ImpactSounds].BoxedValue;
ImpactVolume = Mathf.Clamp((float)ms_entries[(int)ModSetting.ImpactVolume].BoxedValue, 0f, 1f);
} }
static void OnMelonSettingSave_HotkeyKey(object p_oldValue, object p_newValue) static void OnMelonSettingSave_HotkeyKey(object p_oldValue, object p_newValue)
@ -232,6 +242,13 @@ namespace ml_prm
} }
break; break;
case ModSetting.ImpactSounds:
{
ImpactSounds = (bool)p_value;
OnImpactSoundsChanged.Invoke(ImpactSounds);
}
break;
// Floats // Floats
case ModSetting.VelocityMultiplier: case ModSetting.VelocityMultiplier:
{ {
@ -267,6 +284,13 @@ namespace ml_prm
OnFallLimitChanged.Invoke(FallLimit); OnFallLimitChanged.Invoke(FallLimit);
} }
break; break;
case ModSetting.ImpactVolume:
{
ImpactVolume = (float)p_value;
OnImpactVolumeChanged.Invoke(ImpactVolume);
}
break;
} }
if(ms_entries != null) if(ms_entries != null)

141
ml_prm/SoundManager.cs Normal file
View file

@ -0,0 +1,141 @@
using ABI_RC.Core;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
namespace ml_prm
{
public class SoundManager
{
enum SoundType
{
ImpactHard1 = 0,
ImpactHard2,
ImpactHard3,
ImpactHard4,
ImpactHard5,
ImpactHard6,
ImpactSoft1,
ImpactSoft2,
ImpactSoft3,
ImpactSoft4,
ImpactSoft5,
ImpactSoft6,
ImpactSoft7,
Count
}
public enum ImpactType
{
Hard = 0,
Soft
}
const string c_modName = "PlayerRagdollMod";
public static SoundManager Instance { get; private set; } = null;
bool m_loaded = false;
readonly AudioClip[] m_clips = null;
AudioSource m_audioSource = null;
public SoundManager(Transform p_root)
{
m_clips = new AudioClip[(int)SoundType.Count];
for(int i = 0; i < (int)SoundType.Count; i++)
m_clips[i] = null;
GameObject l_audioSource = new GameObject("[ImpactSource]");
l_audioSource.transform.parent = p_root;
l_audioSource.transform.localPosition = Vector3.zero;
l_audioSource.transform.localRotation = Quaternion.identity;
m_audioSource = l_audioSource.AddComponent<AudioSource>();
m_audioSource.playOnAwake = false;
m_audioSource.loop = false;
m_audioSource.minDistance = 2f;
m_audioSource.maxDistance = 5f;
m_audioSource.dopplerLevel = 0f;
m_audioSource.panStereo = 0f;
m_audioSource.spatialBlend = 0f; // 2D
m_audioSource.spread = 0f;
m_audioSource.rolloffMode = AudioRolloffMode.Linear;
m_audioSource.outputAudioMixerGroup = RootLogic.Instance.mainSfx;
Instance = this;
}
~SoundManager()
{
if(Instance == this)
Instance = null;
if(m_audioSource != null)
Object.Destroy(m_audioSource);
m_audioSource = null;
}
internal void LoadSounds()
{
if(!m_loaded)
{
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactHard1, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_hard1.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactHard2, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_hard2.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactHard3, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_hard3.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactHard4, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_hard4.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactHard5, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_hard5.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactHard6, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_hard6.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactSoft1, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_soft1.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactSoft2, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_soft2.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactSoft3, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_soft3.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactSoft4, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_soft4.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactSoft5, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_soft5.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactSoft6, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_soft6.wav")));
MelonLoader.MelonCoroutines.Start(LoadAudioClip(SoundType.ImpactSoft7, Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, c_modName, "body_medium_impact_soft7.wav")));
m_loaded = true;
}
}
IEnumerator LoadAudioClip(SoundType p_type, string p_path)
{
using UnityWebRequest l_uwr = UnityWebRequestMultimedia.GetAudioClip("file://" + p_path, AudioType.WAV);
((DownloadHandlerAudioClip)l_uwr.downloadHandler).streamAudio = true;
yield return l_uwr.SendWebRequest();
if((l_uwr.result == UnityWebRequest.Result.ConnectionError) || (l_uwr.result == UnityWebRequest.Result.ProtocolError))
{
MelonLoader.MelonLogger.Warning(l_uwr.error);
yield break;
}
AudioClip l_content;
AudioClip l_clip = (l_content = DownloadHandlerAudioClip.GetContent(l_uwr));
yield return l_content;
if(!l_uwr.isDone || (l_clip == null))
yield break;
m_clips[(int)p_type] = l_clip;
}
public void PlaySound(ImpactType p_type)
{
if(m_loaded)
{
int l_index = -1;
switch(p_type)
{
case ImpactType.Hard:
l_index = (int)SoundType.ImpactHard1 + Random.Range(0, 6);
break;
case ImpactType.Soft:
l_index = (int)SoundType.ImpactSoft1 + Random.Range(0, 7);
break;
}
if((l_index != -1) && (m_clips[l_index] != null))
m_audioSource.PlayOneShot(m_clips[l_index], Settings.ImpactVolume);
}
}
}
}

View file

@ -1,99 +1,127 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.1</TargetFramework>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<PackageId>PlayerRagdollMod</PackageId> <PackageId>PlayerRagdollMod</PackageId>
<Version>1.2.6</Version> <Version>1.2.7</Version>
<Authors>SDraw</Authors> <Authors>SDraw</Authors>
<Company>SDraw</Company> <Company>SDraw</Company>
<Product>PlayerRagdollMod</Product> <Product>PlayerRagdollMod</Product>
<AssemblyName>PlayerRagdollMod</AssemblyName> <AssemblyName>PlayerRagdollMod</AssemblyName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="resources/person.png" /> <None Remove="resources/person.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="resources/person.png" /> <EmbeddedResource Include="resources/person.png" />
</ItemGroup> <EmbeddedResource Include="resources\sounds\body_medium_impact_hard1.wav" />
<EmbeddedResource Include="resources\sounds\body_medium_impact_hard2.wav" />
<ItemGroup> <EmbeddedResource Include="resources\sounds\body_medium_impact_hard3.wav" />
<Reference Include="0Harmony"> <EmbeddedResource Include="resources\sounds\body_medium_impact_hard4.wav" />
<HintPath>$(CVRPath)/MelonLoader/net35/0Harmony.dll</HintPath> <EmbeddedResource Include="resources\sounds\body_medium_impact_hard5.wav" />
<Private>false</Private> <EmbeddedResource Include="resources\sounds\body_medium_impact_hard6.wav" />
<SpecificVersion>false</SpecificVersion> <EmbeddedResource Include="resources\sounds\body_medium_impact_soft1.wav" />
</Reference> <EmbeddedResource Include="resources\sounds\body_medium_impact_soft2.wav" />
<Reference Include="Assembly-CSharp"> <EmbeddedResource Include="resources\sounds\body_medium_impact_soft3.wav" />
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/Assembly-CSharp.dll</HintPath> <EmbeddedResource Include="resources\sounds\body_medium_impact_soft4.wav" />
<Private>false</Private> <EmbeddedResource Include="resources\sounds\body_medium_impact_soft5.wav" />
<SpecificVersion>false</SpecificVersion> <EmbeddedResource Include="resources\sounds\body_medium_impact_soft6.wav" />
</Reference> <EmbeddedResource Include="resources\sounds\body_medium_impact_soft7.wav" />
<Reference Include="Assembly-CSharp-firstpass"> </ItemGroup>
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/Assembly-CSharp-firstpass.dll</HintPath>
<Private>false</Private> <ItemGroup>
<SpecificVersion>false</SpecificVersion> <Reference Include="0Harmony">
</Reference> <HintPath>$(CVRPath)/MelonLoader/net35/0Harmony.dll</HintPath>
<Reference Include="BTKUILib"> <Private>false</Private>
<HintPath>$(CVRPath)/Mods/BTKUILib.dll</HintPath> <SpecificVersion>false</SpecificVersion>
<Private>false</Private> </Reference>
<SpecificVersion>false</SpecificVersion> <Reference Include="Assembly-CSharp">
</Reference> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/Assembly-CSharp.dll</HintPath>
<Private>false</Private>
<SpecificVersion>false</SpecificVersion>
</Reference>
<Reference Include="Assembly-CSharp-firstpass">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/Assembly-CSharp-firstpass.dll</HintPath>
<Private>false</Private>
<SpecificVersion>false</SpecificVersion>
</Reference>
<Reference Include="BTKUILib">
<HintPath>$(CVRPath)/Mods/BTKUILib.dll</HintPath>
<Private>false</Private>
<SpecificVersion>false</SpecificVersion>
</Reference>
<Reference Include="ECM2"> <Reference Include="ECM2">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/ECM2.dll</HintPath> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/ECM2.dll</HintPath>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="MelonLoader"> <Reference Include="MelonLoader">
<HintPath>$(CVRPath)/MelonLoader/net35/MelonLoader.dll</HintPath> <HintPath>$(CVRPath)/MelonLoader/net35/MelonLoader.dll</HintPath>
<Private>false</Private> <Private>false</Private>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
</Reference> </Reference>
<Reference Include="UnityEngine"> <Reference Include="UnityEngine">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.dll</HintPath> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.dll</HintPath>
<Private>false</Private> <Private>false</Private>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
</Reference> </Reference>
<Reference Include="UnityEngine.AnimationModule"> <Reference Include="UnityEngine.AnimationModule">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.AnimationModule.dll</HintPath> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.AnimationModule.dll</HintPath>
<Private>false</Private> <Private>false</Private>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
</Reference> </Reference>
<Reference Include="UnityEngine.ClothModule"> <Reference Include="UnityEngine.AudioModule">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.ClothModule.dll</HintPath> <HintPath>D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AudioModule.dll</HintPath>
<Private>false</Private> <SpecificVersion>false</SpecificVersion>
<SpecificVersion>false</SpecificVersion> <Private>false</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.CoreModule"> <Reference Include="UnityEngine.ClothModule">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.CoreModule.dll</HintPath> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.ClothModule.dll</HintPath>
<Private>false</Private> <Private>false</Private>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
</Reference> </Reference>
<Reference Include="UnityEngine.InputLegacyModule"> <Reference Include="UnityEngine.CoreModule">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.InputLegacyModule.dll</HintPath> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.CoreModule.dll</HintPath>
<Private>false</Private> <Private>false</Private>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
</Reference> </Reference>
<Reference Include="UnityEngine.PhysicsModule"> <Reference Include="UnityEngine.InputLegacyModule">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.PhysicsModule.dll</HintPath> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.InputLegacyModule.dll</HintPath>
<Private>false</Private> <Private>false</Private>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
</Reference> </Reference>
<Reference Include="UnityEngine.ParticleSystemModule"> <Reference Include="UnityEngine.PhysicsModule">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.ParticleSystemModule.dll</HintPath> <HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.PhysicsModule.dll</HintPath>
<Private>false</Private> <Private>false</Private>
<SpecificVersion>false</SpecificVersion> <SpecificVersion>false</SpecificVersion>
</Reference> </Reference>
</ItemGroup> <Reference Include="UnityEngine.ParticleSystemModule">
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.ParticleSystemModule.dll</HintPath>
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> <Private>false</Private>
<Exec Command="copy /y &quot;$(TargetPath)&quot; &quot;$(CVRPath)/Mods/&quot;" /> <SpecificVersion>false</SpecificVersion>
</Target> </Reference>
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
</Project> <HintPath>D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
<Private>false</Private>
<SpecificVersion>false</SpecificVersion>
</Reference>
<Reference Include="UnityEngine.UnityWebRequestModule">
<HintPath>D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.UnityWebRequestModule.dll</HintPath>
<Private>false</Private>
<SpecificVersion>false</SpecificVersion>
</Reference>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy /y &quot;$(TargetPath)&quot; &quot;$(CVRPath)/Mods/&quot;" />
</Target>
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.