mirror of
https://github.com/SDraw/ml_mods_cvr.git
synced 2026-05-04 01:07:02 +00:00
Compare commits
16 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c4fbb1731 | ||
|
|
812b930bed | ||
|
|
c25eaaf754 | ||
|
|
d8bb5881fc | ||
|
|
e04724ed9d | ||
|
|
2a06001100 | ||
|
|
15de34c0bd | ||
|
|
e357f83227 | ||
|
|
49987b5d72 | ||
|
|
e6feaff0ec | ||
|
|
569a521be4 | ||
|
|
bab5346876 | ||
|
|
38cb60567e | ||
|
|
9a2832951d | ||
|
|
7ada4c4d86 | ||
|
|
da9dc508d0 |
63 changed files with 1019 additions and 265 deletions
16
README.md
16
README.md
|
|
@ -1,16 +0,0 @@
|
||||||
Merged set of MelonLoader mods for ChilloutVR.
|
|
||||||
|
|
||||||
**Table for nightly game build 2025r180:**
|
|
||||||
| Full name | Latest version |
|
|
||||||
|:---------:|:--------------:|
|
|
||||||
|[Avatar Motion Tweaker](/ml_amt/README.md)|1.5.2 [:arrow_down:](../../releases/latest/download/r180n/AvatarMotionTweaker.dll)|
|
|
||||||
|[Avatar Synced Look](/ml_asl/README.md)|1.1.2 [:arrow_down:](../../releases/latest/download/r180n/AvatarSyncedLook.dll)|
|
|
||||||
|[Better Fingers Tracking](/ml_bft/README.md)|1.1.3 [:arrow_down:](../../releases/latest/download/r180n/BetterFingersTracking.dll)|
|
|
||||||
|[Leap Motion Extension](/ml_lme/README.md)| 1.6.2 [:arrow_down:](../../releases/latest/download/r180n/LeapMotionExtension.dll)|
|
|
||||||
|[Pickup Arm Movement](/ml_pam/README.md)|1.2.3 [:arrow_down:](../../releases/latest/download/r180n/PickupArmMovement.dll)|
|
|
||||||
|[Players Instance Notifier](/ml_pin/README.md)|1.1.2 [:arrow_down:](../../releases/latest/download/r180n/PlayersInstanceNotifier.dll)|
|
|
||||||
|[Player Movement Copycat](/ml_pmc/README.md)|1.1.2 [:arrow_down:](../../releases/latest/download/r180n/PlayerMovementCopycat.dll)|
|
|
||||||
|[Player Pick Up](/ml_ppu/README.md)|1.0.1 [:arrow_down:](../../releases/latest/download/r180n/PlayerPickUp.dll)|
|
|
||||||
|[Player Ragdoll Mod](/ml_prm/README.md)|1.2.4 [:arrow_down:](../../releases/latest/download/r180n/PlayerRagdollMod.dll)|
|
|
||||||
|[Vive Extended Input](/ml_vei/README.md)|1.1.2 [:arrow_down:](../../releases/latest/download/r180n/ViveExtendedInput.dll)|
|
|
||||||
|[Video Player Cookies](/ml_vpc/README.md)|1.0.2 [:arrow_down:](../../releases/latest/download/r180n/VideoPlayerCookies.dll)|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_amt.AvatarMotionTweaker), "AvatarMotionTweaker", "1.5.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_amt.AvatarMotionTweaker), "AvatarMotionTweaker", "1.5.3", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>AvatarMotionTweaker</Product>
|
<Product>AvatarMotionTweaker</Product>
|
||||||
<PackageId>AvatarMotionTweaker</PackageId>
|
<PackageId>AvatarMotionTweaker</PackageId>
|
||||||
<Version>1.5.2</Version>
|
<Version>1.5.3</Version>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<AssemblyName>AvatarMotionTweaker</AssemblyName>
|
<AssemblyName>AvatarMotionTweaker</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
|
using ABI_RC.Systems.FaceTracking;
|
||||||
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
@ -10,18 +12,23 @@ namespace ml_asl
|
||||||
|
|
||||||
public override void OnInitializeMelon()
|
public override void OnInitializeMelon()
|
||||||
{
|
{
|
||||||
Settings.Init();
|
|
||||||
|
|
||||||
HarmonyInstance.Patch(
|
HarmonyInstance.Patch(
|
||||||
typeof(PlayerSetup).GetMethod("UpdatePlayerAvatarMovementData", BindingFlags.Instance | BindingFlags.NonPublic ),
|
typeof(PlayerSetup).GetMethod("UpdatePlayerAvatarMovementData", BindingFlags.Instance | BindingFlags.NonPublic),
|
||||||
null,
|
null,
|
||||||
new HarmonyLib.HarmonyMethod(typeof(AvatarSyncedLook).GetMethod(nameof(OnPlayerAvatarMovementDataUpdate_Postfix), BindingFlags.Static | BindingFlags.NonPublic ))
|
new HarmonyLib.HarmonyMethod(typeof(AvatarSyncedLook).GetMethod(nameof(OnPlayerAvatarMovementDataUpdate_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnLateInitializeMelon()
|
||||||
|
{
|
||||||
|
Settings.Init();
|
||||||
|
}
|
||||||
|
|
||||||
static void OnPlayerAvatarMovementDataUpdate_Postfix(ref PlayerSetup __instance, PlayerAvatarMovementData ____playerAvatarMovementData)
|
static void OnPlayerAvatarMovementDataUpdate_Postfix(ref PlayerSetup __instance, PlayerAvatarMovementData ____playerAvatarMovementData)
|
||||||
{
|
{
|
||||||
if(Settings.Enabled && (__instance.EyeMovementController != null))
|
try
|
||||||
|
{
|
||||||
|
if(Settings.Enabled && (__instance.EyeMovementController != null) && !FaceTrackingManager.Instance.IsEyeDataAvailable())
|
||||||
{
|
{
|
||||||
____playerAvatarMovementData.EyeTrackingOverride = true;
|
____playerAvatarMovementData.EyeTrackingOverride = true;
|
||||||
|
|
||||||
|
|
@ -31,5 +38,10 @@ namespace ml_asl
|
||||||
____playerAvatarMovementData.EyeTrackingPosition = (__instance.transform.GetMatrix() * ms_back).GetPosition();
|
____playerAvatarMovementData.EyeTrackingPosition = (__instance.transform.GetMatrix() * ms_back).GetPosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_asl.AvatarSyncedLook), "AvatarSyncedLook", "1.1.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_asl.AvatarSyncedLook), "AvatarSyncedLook", "1.1.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>AvatarSyncedLook</Product>
|
<Product>AvatarSyncedLook</Product>
|
||||||
<Version>1.1.2</Version>
|
<Version>1.1.4</Version>
|
||||||
<AssemblyName>AvatarSyncedLook</AssemblyName>
|
<AssemblyName>AvatarSyncedLook</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_bft.BetterFingersTracking), "BetterFingersTracking", "1.1.3", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_bft.BetterFingersTracking), "BetterFingersTracking", "1.1.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>BetterFingersTracking</Product>
|
<Product>BetterFingersTracking</Product>
|
||||||
<Version>1.1.3</Version>
|
<Version>1.1.4</Version>
|
||||||
<AssemblyName>BetterFingersTracking</AssemblyName>
|
<AssemblyName>BetterFingersTracking</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace ml_lme
|
||||||
public override void ModuleAdded()
|
public override void ModuleAdded()
|
||||||
{
|
{
|
||||||
base.ModuleAdded();
|
base.ModuleAdded();
|
||||||
base.InputEnabled = Settings.Enabled;
|
base.InputModuleEnabled = Settings.Enabled;
|
||||||
base.HapticFeedback = false;
|
base.HapticFeedback = false;
|
||||||
|
|
||||||
m_inVR = Utils.IsInVR();
|
m_inVR = Utils.IsInVR();
|
||||||
|
|
@ -159,7 +159,7 @@ namespace ml_lme
|
||||||
|
|
||||||
public override void UpdateInput()
|
public override void UpdateInput()
|
||||||
{
|
{
|
||||||
if(base.InputEnabled)
|
if(base.InputModuleEnabled)
|
||||||
{
|
{
|
||||||
LeapParser.LeapData l_data = LeapManager.Instance.GetLatestData();
|
LeapParser.LeapData l_data = LeapManager.Instance.GetLatestData();
|
||||||
|
|
||||||
|
|
@ -360,7 +360,7 @@ namespace ml_lme
|
||||||
// Settings changes
|
// Settings changes
|
||||||
void OnEnableChanged(bool p_state)
|
void OnEnableChanged(bool p_state)
|
||||||
{
|
{
|
||||||
base.InputEnabled = p_state;
|
base.InputModuleEnabled = p_state;
|
||||||
|
|
||||||
m_handVisibleLeft &= p_state;
|
m_handVisibleLeft &= p_state;
|
||||||
m_handVisibleRight &= p_state;
|
m_handVisibleRight &= p_state;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.6.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.6.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<PackageId>LeapMotionExtension</PackageId>
|
<PackageId>LeapMotionExtension</PackageId>
|
||||||
<Version>1.6.2</Version>
|
<Version>1.6.4</Version>
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>LeapMotionExtension</Product>
|
<Product>LeapMotionExtension</Product>
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_vpc", "ml_vpc\ml_vpc.csproj", "{7CF37B93-9341-422D-845C-9AB96DB4D0A1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_vpc", "ml_vpc\ml_vpc.csproj", "{7CF37B93-9341-422D-845C-9AB96DB4D0A1}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_ppu", "ml_ppu\ml_ppu.csproj", "{F16DF16B-D127-4A2A-81FF-2FD80F320E64}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_ppu", "ml_ppu\ml_ppu.csproj", "{F16DF16B-D127-4A2A-81FF-2FD80F320E64}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{C4C3F080-379F-49DB-ADC6-6328BE884AE3} = {C4C3F080-379F-49DB-ADC6-6328BE884AE3}
|
||||||
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pah", "ml_pah\ml_pah.csproj", "{C4659F60-3FED-4F43-88E4-969907D4C7A6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pah", "ml_pah\ml_pah.csproj", "{C4659F60-3FED-4F43-88E4-969907D4C7A6}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using ABI_RC.Core.Networking.API;
|
using ABI_RC.Core.Networking.API;
|
||||||
using ABI_RC.Core.Networking.API.Responses;
|
using ABI_RC.Core.Networking.API.Responses;
|
||||||
|
using ABI_RC.Core.Networking.API.Responses.DetailsV2;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
@ -178,12 +179,12 @@ namespace ml_pah
|
||||||
|
|
||||||
static async Task RequestAvatarInfoTask(AvatarEntry p_entry)
|
static async Task RequestAvatarInfoTask(AvatarEntry p_entry)
|
||||||
{
|
{
|
||||||
BaseResponse<AvatarDetailsResponse> l_baseResponse = await ApiConnection.MakeRequest<AvatarDetailsResponse>(ApiConnection.ApiOperation.AvatarDetail, new { avatarID = p_entry.m_id });
|
BaseResponse<ContentAvatarResponse> l_baseResponse = await ApiConnection.MakeRequest<ContentAvatarResponse>(ApiConnection.ApiOperation.AvatarDetail, new { avatarID = p_entry.m_id }, "2");
|
||||||
if(l_baseResponse != null)
|
if(l_baseResponse != null)
|
||||||
{
|
{
|
||||||
if(!l_baseResponse.IsSuccessStatusCode) return;
|
if(!l_baseResponse.IsSuccessStatusCode) return;
|
||||||
p_entry.m_name = l_baseResponse.Data.Name;
|
p_entry.m_name = l_baseResponse.Data.Name;
|
||||||
p_entry.m_imageUrl = l_baseResponse.Data.ImageUrl;
|
p_entry.m_imageUrl = l_baseResponse.Data.Image.AbsoluteUri;
|
||||||
p_entry.m_cached = true;
|
p_entry.m_cached = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_pah.PlayerAvatarHistory), "PlayerAvatarHistory", "1.0.0", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_pah.PlayerAvatarHistory), "PlayerAvatarHistory", "1.0.1", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
<PackageId>PlayerAvatarHistory</PackageId>
|
<PackageId>PlayerAvatarHistory</PackageId>
|
||||||
<AssemblyName>PlayerAvatarHistory</AssemblyName>
|
<AssemblyName>PlayerAvatarHistory</AssemblyName>
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
|
<Version>1.0.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_pam.PickupArmMovement), "PickupArmMovement", "1.2.3", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_pam.PickupArmMovement), "PickupArmMovement", "1.2.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPriority(1)]
|
[assembly: MelonLoader.MelonPriority(1)]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<PackageId>PickupArmMovement</PackageId>
|
<PackageId>PickupArmMovement</PackageId>
|
||||||
<Version>1.2.3</Version>
|
<Version>1.2.4</Version>
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>PickupArmMovement</Product>
|
<Product>PickupArmMovement</Product>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
using ABI_RC.Core.AudioEffects;
|
using ABI_RC.Core.AudioEffects;
|
||||||
using ABI_RC.Core.Networking.IO.Social;
|
using ABI_RC.Core.Networking.IO.Social;
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Core.Savior;
|
|
||||||
using ABI_RC.Core.Networking.IO.Instancing;
|
|
||||||
using ABI_RC.Systems.GameEventSystem;
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
@ -111,9 +109,9 @@ namespace ml_pin
|
||||||
|
|
||||||
bool ShouldNotifyInCurrentInstance()
|
bool ShouldNotifyInCurrentInstance()
|
||||||
{
|
{
|
||||||
bool l_isInPublic = ((MetaPort.Instance.CurrentInstancePrivacyType == Instances.InstancePrivacyType.Public) && Settings.NotifyInPublic);
|
bool l_isInPublic = Utils.IsInPublicInstance() && Settings.NotifyInPublic;
|
||||||
bool l_isInFriends = (((MetaPort.Instance.CurrentInstancePrivacyType == Instances.InstancePrivacyType.Friends) || (MetaPort.Instance.CurrentInstancePrivacyType == Instances.InstancePrivacyType.FriendsOfFriends)) && Settings.NotifyInFriends);
|
bool l_isInFriends = Utils.IsInFriendsInstance() && Settings.NotifyInFriends;
|
||||||
bool l_isInPrivate = (((MetaPort.Instance.CurrentInstancePrivacyType == Instances.InstancePrivacyType.EveryoneCanInvite) || (MetaPort.Instance.CurrentInstancePrivacyType == Instances.InstancePrivacyType.OwnerMustInvite)) && Settings.NotifyInPrivate);
|
bool l_isInPrivate = Utils.IsInPrivateInstance() && Settings.NotifyInPrivate;
|
||||||
return (l_isInPublic || l_isInFriends || l_isInPrivate);
|
return (l_isInPublic || l_isInFriends || l_isInPrivate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_pin.PlayersInstanceNotifier), "PlayersInstanceNotifier", "1.1.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_pin.PlayersInstanceNotifier), "PlayersInstanceNotifier", "1.1.3", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using ABI_RC.Core.Networking.IO.Instancing;
|
||||||
using ABI_RC.Core.UI;
|
using ABI_RC.Core.UI;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
|
|
@ -8,5 +9,47 @@ namespace ml_pin
|
||||||
static readonly FieldInfo ms_view = typeof(CohtmlControlledViewWrapper).GetField("_view", BindingFlags.Instance | BindingFlags.NonPublic);
|
static readonly FieldInfo ms_view = typeof(CohtmlControlledViewWrapper).GetField("_view", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
|
||||||
public static void ExecuteScript(this CohtmlControlledViewWrapper p_instance, string p_script) => (ms_view?.GetValue(p_instance) as cohtml.Net.View)?.ExecuteScript(p_script);
|
public static void ExecuteScript(this CohtmlControlledViewWrapper p_instance, string p_script) => (ms_view?.GetValue(p_instance) as cohtml.Net.View)?.ExecuteScript(p_script);
|
||||||
|
|
||||||
|
// Instance info
|
||||||
|
public static bool IsInPublicInstance()
|
||||||
|
{
|
||||||
|
bool l_result = false;
|
||||||
|
switch(Instances.CurrentInstancePrivacyType)
|
||||||
|
{
|
||||||
|
case Instances.InstancePrivacyType.Public:
|
||||||
|
case Instances.InstancePrivacyType.GroupPublic:
|
||||||
|
l_result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return l_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsInFriendsInstance()
|
||||||
|
{
|
||||||
|
bool l_result = false;
|
||||||
|
switch(Instances.CurrentInstancePrivacyType)
|
||||||
|
{
|
||||||
|
case Instances.InstancePrivacyType.Friends:
|
||||||
|
case Instances.InstancePrivacyType.FriendsOfFriends:
|
||||||
|
case Instances.InstancePrivacyType.GroupPlus:
|
||||||
|
l_result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return l_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsInPrivateInstance()
|
||||||
|
{
|
||||||
|
bool l_result = false;
|
||||||
|
switch(Instances.CurrentInstancePrivacyType)
|
||||||
|
{
|
||||||
|
case Instances.InstancePrivacyType.EveryoneCanInvite:
|
||||||
|
case Instances.InstancePrivacyType.OwnerMustInvite:
|
||||||
|
case Instances.InstancePrivacyType.Group:
|
||||||
|
l_result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return l_result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>PlayersInstanceNotifier</Product>
|
<Product>PlayersInstanceNotifier</Product>
|
||||||
<Version>1.1.2</Version>
|
<Version>1.1.3</Version>
|
||||||
<AssemblyName>PlayersInstanceNotifier</AssemblyName>
|
<AssemblyName>PlayersInstanceNotifier</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_pmc.PlayerMovementCopycat), "PlayerMovementCopycat", "1.1.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_pmc.PlayerMovementCopycat), "PlayerMovementCopycat", "1.1.3", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPriority(3)]
|
[assembly: MelonLoader.MelonPriority(3)]
|
||||||
[assembly: MelonLoader.MelonAdditionalDependencies("BTKUILib")]
|
[assembly: MelonLoader.MelonAdditionalDependencies("BTKUILib")]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>PlayerMovementCopycat</Product>
|
<Product>PlayerMovementCopycat</Product>
|
||||||
<Version>1.1.2</Version>
|
<Version>1.1.3</Version>
|
||||||
<AssemblyName>PlayerMovementCopycat</AssemblyName>
|
<AssemblyName>PlayerMovementCopycat</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
||||||
109
ml_ppu/AvatarParameter.cs
Normal file
109
ml_ppu/AvatarParameter.cs
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
using ABI_RC.Core.Util.AnimatorManager;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace ml_ppu
|
||||||
|
{
|
||||||
|
class AvatarParameter
|
||||||
|
{
|
||||||
|
public readonly string m_name;
|
||||||
|
public readonly int m_hash = 0;
|
||||||
|
public readonly bool m_sync;
|
||||||
|
public readonly AnimatorControllerParameterType m_type;
|
||||||
|
readonly AvatarAnimatorManager m_manager = null;
|
||||||
|
|
||||||
|
public AvatarParameter(string p_name, AvatarAnimatorManager p_manager)
|
||||||
|
{
|
||||||
|
m_name = p_name;
|
||||||
|
m_manager = p_manager;
|
||||||
|
|
||||||
|
Regex l_regex = new Regex("^#?" + p_name + '$');
|
||||||
|
foreach(var l_param in m_manager.Animator.parameters)
|
||||||
|
{
|
||||||
|
if(l_regex.IsMatch(l_param.name))
|
||||||
|
{
|
||||||
|
m_name = l_param.name;
|
||||||
|
m_sync = !l_param.name.StartsWith('#');
|
||||||
|
m_hash = l_param.nameHash;
|
||||||
|
m_type = l_param.type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(bool p_value)
|
||||||
|
{
|
||||||
|
if(m_hash != 0)
|
||||||
|
{
|
||||||
|
if(m_sync)
|
||||||
|
m_manager.SetParameter(m_name, p_value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(m_type)
|
||||||
|
{
|
||||||
|
case AnimatorControllerParameterType.Bool:
|
||||||
|
case AnimatorControllerParameterType.Trigger:
|
||||||
|
m_manager.Animator.SetBool(m_hash, p_value);
|
||||||
|
break;
|
||||||
|
case AnimatorControllerParameterType.Int:
|
||||||
|
m_manager.Animator.SetInteger(m_hash, p_value ? 1 : 0);
|
||||||
|
break;
|
||||||
|
case AnimatorControllerParameterType.Float:
|
||||||
|
m_manager.Animator.SetFloat(m_hash, p_value ? 1f : 0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(int p_value)
|
||||||
|
{
|
||||||
|
if(m_hash != 0)
|
||||||
|
{
|
||||||
|
if(m_sync)
|
||||||
|
m_manager.SetParameter(m_name, p_value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(m_type)
|
||||||
|
{
|
||||||
|
case AnimatorControllerParameterType.Bool:
|
||||||
|
case AnimatorControllerParameterType.Trigger:
|
||||||
|
m_manager.Animator.SetBool(m_hash, p_value > 0);
|
||||||
|
break;
|
||||||
|
case AnimatorControllerParameterType.Int:
|
||||||
|
m_manager.Animator.SetInteger(m_hash, p_value);
|
||||||
|
break;
|
||||||
|
case AnimatorControllerParameterType.Float:
|
||||||
|
m_manager.Animator.SetFloat(m_hash, p_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(float p_value)
|
||||||
|
{
|
||||||
|
if(m_hash != 0)
|
||||||
|
{
|
||||||
|
if(m_sync)
|
||||||
|
m_manager.SetParameter(m_name, p_value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(m_type)
|
||||||
|
{
|
||||||
|
case AnimatorControllerParameterType.Bool:
|
||||||
|
case AnimatorControllerParameterType.Trigger:
|
||||||
|
m_manager.Animator.SetBool(m_hash, p_value > 0f);
|
||||||
|
break;
|
||||||
|
case AnimatorControllerParameterType.Int:
|
||||||
|
m_manager.Animator.SetInteger(m_hash, (int)p_value);
|
||||||
|
break;
|
||||||
|
case AnimatorControllerParameterType.Float:
|
||||||
|
m_manager.Animator.SetFloat(m_hash, p_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,6 +33,8 @@ namespace ml_ppu
|
||||||
Vector3 m_lastPosition = Vector3.zero;
|
Vector3 m_lastPosition = Vector3.zero;
|
||||||
Vector3 m_velocity = Vector3.zero;
|
Vector3 m_velocity = Vector3.zero;
|
||||||
|
|
||||||
|
AvatarParameter m_avatarParameter = null;
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
if(Instance != null)
|
if(Instance != null)
|
||||||
|
|
@ -122,6 +124,7 @@ namespace ml_ppu
|
||||||
m_held = false;
|
m_held = false;
|
||||||
|
|
||||||
BetterBetterCharacterController.Instance.SetVelocity(m_velocity * Settings.VelocityMultiplier);
|
BetterBetterCharacterController.Instance.SetVelocity(m_velocity * Settings.VelocityMultiplier);
|
||||||
|
m_avatarParameter?.SetValue(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,6 +137,8 @@ namespace ml_ppu
|
||||||
Animator l_animator = PlayerSetup.Instance.Animator;
|
Animator l_animator = PlayerSetup.Instance.Animator;
|
||||||
if((l_animator != null) && l_animator.isHuman)
|
if((l_animator != null) && l_animator.isHuman)
|
||||||
{
|
{
|
||||||
|
m_avatarParameter = new AvatarParameter("PickedUp", PlayerSetup.Instance.AnimatorManager);
|
||||||
|
|
||||||
IKSystem.Instance.SetAvatarPose(IKSystem.AvatarPose.TPose);
|
IKSystem.Instance.SetAvatarPose(IKSystem.AvatarPose.TPose);
|
||||||
PlayerSetup.Instance.AvatarTransform.localPosition = Vector3.zero;
|
PlayerSetup.Instance.AvatarTransform.localPosition = Vector3.zero;
|
||||||
PlayerSetup.Instance.AvatarTransform.localRotation = Quaternion.identity;
|
PlayerSetup.Instance.AvatarTransform.localRotation = Quaternion.identity;
|
||||||
|
|
@ -171,6 +176,8 @@ namespace ml_ppu
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
m_avatarParameter = null;
|
||||||
|
|
||||||
m_ready = false;
|
m_ready = false;
|
||||||
m_held = false;
|
m_held = false;
|
||||||
|
|
||||||
|
|
@ -264,6 +271,8 @@ namespace ml_ppu
|
||||||
m_lastPosition = l_playerPos;
|
m_lastPosition = l_playerPos;
|
||||||
m_velocity = Vector3.zero;
|
m_velocity = Vector3.zero;
|
||||||
m_held = true;
|
m_held = true;
|
||||||
|
|
||||||
|
m_avatarParameter?.SetValue(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_ppu.PlayerPickUp), "PlayerPickUp", "1.0.1", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_ppu.PlayerPickUp), "PlayerPickUp", "1.0.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonOptionalDependencies("PlayerRagdollMod")]
|
[assembly: MelonLoader.MelonOptionalDependencies("PlayerRagdollMod")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,14 @@ Available mod's settings in BTKUILib's page:
|
||||||
* **Friends only:** allow only friends to pick you up; `true` by default;
|
* **Friends only:** allow only friends to pick you up; `true` by default;
|
||||||
* **Velocity multiplier:** velocity multiplier upon drop/throw; `1.0` by default.
|
* **Velocity multiplier:** velocity multiplier upon drop/throw; `1.0` by default.
|
||||||
|
|
||||||
|
|
||||||
To pick you up remote player should:
|
To pick you up remote player should:
|
||||||
* Make hands `grab` pointers to appear on your side (usually, press controller grip, trigger button or fist gesture, depends on remote player controllers type);
|
* Make hands `grab` pointers to appear on your side (usually, press controller grip, trigger button or fist gesture, depends on remote player controllers type);
|
||||||
* Touch your avatar's torso with both pointers;
|
* Touch your avatar's torso with both pointers;
|
||||||
|
|
||||||
|
Available additional parameters for AAS animator:
|
||||||
|
* **`PickedUp`:** defines current picked up state; boolean.
|
||||||
|
* Note: Can be set as local-only (not synced) if starts with `#` character.
|
||||||
|
|
||||||
# Notes
|
# Notes
|
||||||
* Compatible with PlayerRagdollMod.
|
* Compatible with PlayerRagdollMod.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<AssemblyName>PlayerPickUp</AssemblyName>
|
<AssemblyName>PlayerPickUp</AssemblyName>
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Version>1.0.1</Version>
|
<Version>1.0.2</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ namespace ml_prm
|
||||||
);
|
);
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.Instance |BindingFlags.NonPublic),
|
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.Instance | BindingFlags.NonPublic),
|
||||||
null,
|
null,
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupIKScaling_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupIKScaling_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||||
);
|
);
|
||||||
|
|
@ -73,7 +73,7 @@ namespace ml_prm
|
||||||
);
|
);
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(RootLogic).GetMethod(nameof(RootLogic.SpawnOnWorldInstance),BindingFlags.Instance | BindingFlags.Public),
|
typeof(RootLogic).GetMethod(nameof(RootLogic.SpawnOnWorldInstance), BindingFlags.Instance | BindingFlags.Public),
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnWorldSpawn_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnWorldSpawn_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ namespace ml_prm
|
||||||
Hotkey = 0,
|
Hotkey = 0,
|
||||||
Gravity,
|
Gravity,
|
||||||
PointersReaction,
|
PointersReaction,
|
||||||
IgnoreLocal,
|
|
||||||
CombatReaction,
|
CombatReaction,
|
||||||
AutoRecover,
|
AutoRecover,
|
||||||
Slipperiness,
|
Slipperiness,
|
||||||
|
|
@ -36,7 +35,8 @@ namespace ml_prm
|
||||||
RecoverDelay,
|
RecoverDelay,
|
||||||
FallLimit,
|
FallLimit,
|
||||||
GestureGrab,
|
GestureGrab,
|
||||||
FriendsGrab
|
ImpactSounds,
|
||||||
|
ImpactVolume
|
||||||
}
|
}
|
||||||
|
|
||||||
const string c_ragdollKeyTooltip = "Switch ragdoll mode with '{0}' key";
|
const string c_ragdollKeyTooltip = "Switch ragdoll mode with '{0}' key";
|
||||||
|
|
@ -52,7 +52,6 @@ namespace ml_prm
|
||||||
static ToggleButton ms_hotkeyToggle = null;
|
static ToggleButton ms_hotkeyToggle = null;
|
||||||
static ToggleButton ms_gravityToggle = null;
|
static ToggleButton ms_gravityToggle = null;
|
||||||
static ToggleButton ms_pointersToggle = null;
|
static ToggleButton ms_pointersToggle = null;
|
||||||
static ToggleButton ms_ignoreLocalToggle = null;
|
|
||||||
static ToggleButton ms_combatToggle = null;
|
static ToggleButton ms_combatToggle = null;
|
||||||
static ToggleButton ms_recoveryToggle = null;
|
static ToggleButton ms_recoveryToggle = null;
|
||||||
static ToggleButton ms_slipperinessToggle = null;
|
static ToggleButton ms_slipperinessToggle = null;
|
||||||
|
|
@ -62,12 +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_friendsGrabToggle = 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()
|
||||||
|
|
@ -94,9 +94,6 @@ namespace ml_prm
|
||||||
ms_pointersToggle = ms_category.AddToggle("Pointers reaction", "React to trigger colliders with CVRPointer component of 'ragdoll' type", Settings.PointersReaction);
|
ms_pointersToggle = ms_category.AddToggle("Pointers reaction", "React to trigger colliders with CVRPointer component of 'ragdoll' type", Settings.PointersReaction);
|
||||||
ms_pointersToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.PointersReaction, state);
|
ms_pointersToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.PointersReaction, state);
|
||||||
|
|
||||||
ms_ignoreLocalToggle = ms_category.AddToggle("Ignore local pointers", "Ignore local avatar's CVRPointer components of 'ragdoll' type", Settings.IgnoreLocal);
|
|
||||||
ms_ignoreLocalToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.IgnoreLocal, state);
|
|
||||||
|
|
||||||
ms_combatToggle = ms_category.AddToggle("Combat reaction", "Ragdoll upon combat system death", Settings.CombatReaction);
|
ms_combatToggle = ms_category.AddToggle("Combat reaction", "Ragdoll upon combat system death", Settings.CombatReaction);
|
||||||
ms_combatToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.CombatReaction, state);
|
ms_combatToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.CombatReaction, state);
|
||||||
|
|
||||||
|
|
@ -121,11 +118,11 @@ namespace ml_prm
|
||||||
ms_fallDamageToggle = ms_category.AddToggle("Fall damage", "Enable ragdoll when falling from height", Settings.FallDamage);
|
ms_fallDamageToggle = ms_category.AddToggle("Fall damage", "Enable ragdoll when falling from height", Settings.FallDamage);
|
||||||
ms_fallDamageToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.FallDamage, state);
|
ms_fallDamageToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.FallDamage, state);
|
||||||
|
|
||||||
ms_gestureGrabToggle = ms_category.AddToggle("Gesture grab", "Enable grabbing of ragdolled body parts by remote players with trigger/grab gesture<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_friendsGrabToggle = ms_category.AddToggle("Friends grab only", " ", Settings.FriendsGrab);
|
ms_impactSoundsToggle = ms_category.AddToggle("Impact sounds", "Enable collision sound effects of ragdolled body parts", Settings.ImpactSounds);
|
||||||
ms_friendsGrabToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.FriendsGrab, state);
|
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);
|
||||||
|
|
@ -143,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;
|
||||||
}
|
}
|
||||||
|
|
@ -177,10 +177,6 @@ namespace ml_prm
|
||||||
Settings.SetSetting(Settings.ModSetting.PointersReaction, p_state);
|
Settings.SetSetting(Settings.ModSetting.PointersReaction, p_state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UiIndex.IgnoreLocal:
|
|
||||||
Settings.SetSetting(Settings.ModSetting.IgnoreLocal, p_state);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UiIndex.CombatReaction:
|
case UiIndex.CombatReaction:
|
||||||
Settings.SetSetting(Settings.ModSetting.CombatReaction, p_state);
|
Settings.SetSetting(Settings.ModSetting.CombatReaction, p_state);
|
||||||
break;
|
break;
|
||||||
|
|
@ -217,8 +213,8 @@ namespace ml_prm
|
||||||
Settings.SetSetting(Settings.ModSetting.GestureGrab, p_state);
|
Settings.SetSetting(Settings.ModSetting.GestureGrab, p_state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UiIndex.FriendsGrab:
|
case UiIndex.ImpactSounds:
|
||||||
Settings.SetSetting(Settings.ModSetting.FriendsGrab, p_state);
|
Settings.SetSetting(Settings.ModSetting.ImpactSounds, p_state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -256,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)
|
||||||
|
|
@ -275,9 +275,6 @@ namespace ml_prm
|
||||||
OnToggleUpdate(UiIndex.PointersReaction, true);
|
OnToggleUpdate(UiIndex.PointersReaction, true);
|
||||||
ms_pointersToggle.ToggleValue = true;
|
ms_pointersToggle.ToggleValue = true;
|
||||||
|
|
||||||
OnToggleUpdate(UiIndex.IgnoreLocal, true);
|
|
||||||
ms_ignoreLocalToggle.ToggleValue = true;
|
|
||||||
|
|
||||||
OnToggleUpdate(UiIndex.CombatReaction, true);
|
OnToggleUpdate(UiIndex.CombatReaction, true);
|
||||||
ms_combatToggle.ToggleValue = true;
|
ms_combatToggle.ToggleValue = true;
|
||||||
|
|
||||||
|
|
@ -305,8 +302,8 @@ namespace ml_prm
|
||||||
OnToggleUpdate(UiIndex.GestureGrab, false);
|
OnToggleUpdate(UiIndex.GestureGrab, false);
|
||||||
ms_gestureGrabToggle.ToggleValue = false;
|
ms_gestureGrabToggle.ToggleValue = false;
|
||||||
|
|
||||||
OnToggleUpdate(UiIndex.FriendsGrab, true);
|
OnToggleUpdate(UiIndex.ImpactSounds, true);
|
||||||
ms_friendsGrabToggle.ToggleValue = true;
|
ms_impactSoundsToggle.ToggleValue = true;
|
||||||
|
|
||||||
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f);
|
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f);
|
||||||
ms_velocityMultiplierSlider.SetSliderValue(2f);
|
ms_velocityMultiplierSlider.SetSliderValue(2f);
|
||||||
|
|
@ -322,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(25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnHotkeyKeyChanged(UnityEngine.KeyCode p_keyCode)
|
static void OnHotkeyKeyChanged(UnityEngine.KeyCode p_keyCode)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.2.4", "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")]
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/
|
||||||
* **Use gravity:** enables/disables gravity for ragdoll; `true` by default.
|
* **Use gravity:** enables/disables gravity for ragdoll; `true` by default.
|
||||||
* Note: Forcibly enabled in worlds that don't allow flight.
|
* Note: Forcibly enabled in worlds that don't allow flight.
|
||||||
* **Pointers reaction:** enables ragdoll state when player collides with trigger colliders and particle systems with CVRPointer component of `ragdoll` type (avatars, props and world included); `true` by default.
|
* **Pointers reaction:** enables ragdoll state when player collides with trigger colliders and particle systems with CVRPointer component of `ragdoll` type (avatars, props and world included); `true` by default.
|
||||||
* **Ignore local pointers:** enables/disables ignoring of CVRPointer components of `ragdoll` type on local player's avatar; `true` by default.
|
|
||||||
* **Combat reaction:** enables ragdoll state upon death in worlds with combat system; `true` by default.
|
* **Combat reaction:** enables ragdoll state upon death in worlds with combat system; `true` by default.
|
||||||
* **Auto recover:** enables automatic recovering after specific time delay; `false` by default.
|
* **Auto recover:** enables automatic recovering after specific time delay; `false` by default.
|
||||||
* **Slipperiness:** enables/disable low friction of ragdoll; `false` by default.
|
* **Slipperiness:** enables/disable low friction of ragdoll; `false` by default.
|
||||||
|
|
@ -30,9 +29,10 @@ Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/
|
||||||
* **Buoyancy:** enables floating in fluid volumes; `true` by default.
|
* **Buoyancy:** enables floating in fluid volumes; `true` by default.
|
||||||
* Note: Forcibly enabled in worlds that don't allow flight.
|
* Note: Forcibly enabled in worlds that don't allow flight.
|
||||||
* **Fall damage:** enables ragdoll when falling from specific height; `true` by default.
|
* **Fall damage:** enables ragdoll when falling from specific height; `true` by default.
|
||||||
* **Gesture grab:** enables grabbing of ragdolled body parts by remote players with trigger/grab gesture; `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.
|
||||||
* **Friends grab only:** Allow only friends to be able to grab your radgolled body parts; `true` by default.
|
* **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.
|
||||||
|
|
@ -41,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):
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
using ABI.CCK.Components;
|
using ABI.CCK.Components;
|
||||||
using ABI_RC.Core;
|
using ABI_RC.Core;
|
||||||
using ABI_RC.Core.Networking.IO.Social;
|
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Core.Savior;
|
|
||||||
using ABI_RC.Systems.Movement;
|
using ABI_RC.Systems.Movement;
|
||||||
|
using NAK.Contacts;
|
||||||
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace ml_prm
|
namespace ml_prm
|
||||||
{
|
{
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
class RagdollBodypartHandler : MonoBehaviour, CVRTriggerVolume
|
class RagdollBodypartHandler : MonoBehaviour
|
||||||
{
|
{
|
||||||
const string c_ragdollPointerType = "ragdoll";
|
const string c_ragdollPointerType = "ragdoll";
|
||||||
const string c_grabPointerType = "grab";
|
const string c_grabPointerType = "grab";
|
||||||
|
|
@ -18,14 +18,16 @@ namespace ml_prm
|
||||||
|
|
||||||
Rigidbody m_rigidBody = null;
|
Rigidbody m_rigidBody = null;
|
||||||
public Collider collider { get; set; } = null;
|
public Collider collider { get; set; } = null;
|
||||||
|
ContactReceiver m_contactReciever = null;
|
||||||
|
|
||||||
PhysicsInfluencer m_physicsInfluencer = null;
|
PhysicsInfluencer m_physicsInfluencer = null;
|
||||||
public bool UseBuoyancy { get; set; } = false;
|
public bool UseBuoyancy { get; set; } = false;
|
||||||
|
|
||||||
bool m_attached = false;
|
bool m_attached = false;
|
||||||
CVRPointer m_attachedPointer = null;
|
|
||||||
Transform m_attachTransform = null;
|
Transform m_attachTransform = null;
|
||||||
|
ContactSender m_attachedSender = null;
|
||||||
FixedJoint m_attachJoint = null;
|
FixedJoint m_attachJoint = null;
|
||||||
|
static List<ContactSender> ms_attachedSenders = new List<ContactSender>();
|
||||||
|
|
||||||
// Unity events
|
// Unity events
|
||||||
void Awake()
|
void Awake()
|
||||||
|
|
@ -42,7 +44,28 @@ namespace ml_prm
|
||||||
}
|
}
|
||||||
|
|
||||||
if(collider != null)
|
if(collider != null)
|
||||||
|
{
|
||||||
RemoveGameCollision();
|
RemoveGameCollision();
|
||||||
|
|
||||||
|
var l_constactShape = ContactConversion.FromCollider(collider, true);
|
||||||
|
m_contactReciever = this.gameObject.AddComponent<ContactReceiver>();
|
||||||
|
|
||||||
|
m_contactReciever.shapeType = l_constactShape.shapeType;
|
||||||
|
m_contactReciever.localPosition = l_constactShape.localPosition;
|
||||||
|
m_contactReciever.localRotation = l_constactShape.localRotation;
|
||||||
|
m_contactReciever.radius = l_constactShape.radius;
|
||||||
|
m_contactReciever.height = l_constactShape.height;
|
||||||
|
m_contactReciever.boxSize = l_constactShape.boxSize;
|
||||||
|
|
||||||
|
m_contactReciever.collisionTags = new string[] { c_ragdollPointerType, c_grabPointerType };
|
||||||
|
m_contactReciever.receiverType = ReceiverType.Constant;
|
||||||
|
m_contactReciever.contentTypes = ContentType.World | ContentType.Avatar | ContentType.Prop;
|
||||||
|
m_contactReciever.SourceContentType = ContentType.Player;
|
||||||
|
m_contactReciever.contactValue = 1f;
|
||||||
|
m_contactReciever.drawGizmos = false;
|
||||||
|
|
||||||
|
m_contactReciever.OnContactEnter += this.OnContactEnter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
|
|
@ -64,46 +87,54 @@ namespace ml_prm
|
||||||
|
|
||||||
this.gameObject.name = string.Format("{0} [NoGizmo]", this.gameObject.name);
|
this.gameObject.name = string.Format("{0} [NoGizmo]", this.gameObject.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(collider != null)
|
|
||||||
{
|
|
||||||
CVRParticlePointerManager.volumes.Add(this);
|
|
||||||
CVRParticlePointerManager.UpdateParticleSystems();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnDestroy()
|
void OnDestroy()
|
||||||
{
|
{
|
||||||
if(collider != null)
|
|
||||||
CVRParticlePointerManager.RemoveTrigger(collider);
|
|
||||||
|
|
||||||
Detach();
|
Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
if(m_attached && ((m_attachedPointer == null) || !m_attachedPointer.isActiveAndEnabled))
|
if(m_attached && ((m_attachedSender == null) || !m_attachedSender.isActiveAndEnabled))
|
||||||
Detach();
|
Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnTriggerEnter(Collider p_col)
|
void OnCollisionEnter(Collision p_col)
|
||||||
{
|
{
|
||||||
if(m_ready && (RagdollController.Instance != null))
|
if(Settings.ImpactSounds && m_ready && !m_rigidBody.isKinematic && (p_col.gameObject.layer != CVRLayers.PlayerClone))
|
||||||
{
|
{
|
||||||
CVRPointer l_pointer = p_col.GetComponent<CVRPointer>();
|
if(p_col.impulse.magnitude > 5f)
|
||||||
|
SoundManager.Instance.PlaySound(SoundManager.ImpactType.Soft);
|
||||||
// Ragdolling
|
}
|
||||||
if(Settings.PointersReaction && !RagdollController.Instance.IsRagdolled())
|
|
||||||
{
|
|
||||||
if((l_pointer != null) && (l_pointer.type == c_ragdollPointerType) && l_pointer.enabled && !IgnoreCheck(l_pointer.transform))
|
|
||||||
RagdollController.Instance.Ragdoll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Attachment
|
void OnContactEnter(ContactCollisionInfo p_col)
|
||||||
if(!m_attached && RagdollController.Instance.IsRagdolled())
|
|
||||||
{
|
{
|
||||||
if((l_pointer != null) && (l_pointer.type == c_grabPointerType) && RestrictionsCheck(p_col.transform.root))
|
if(m_ready && (RagdollController.Instance != null) && ContactManager.Exists)
|
||||||
Attach(l_pointer);
|
{
|
||||||
|
ContactSender l_sender = ContactManager.Instance.GetSenderById(p_col.senderContactId);
|
||||||
|
if((l_sender != null) && (l_sender.collisionTags != null))
|
||||||
|
{
|
||||||
|
foreach(string l_tag in l_sender.collisionTags)
|
||||||
|
{
|
||||||
|
switch(l_tag)
|
||||||
|
{
|
||||||
|
case c_ragdollPointerType:
|
||||||
|
{
|
||||||
|
if(Settings.PointersReaction && !RagdollController.Instance.IsRagdolled() && RestrictionsCheck(l_sender.transform.root))
|
||||||
|
RagdollController.Instance.Ragdoll();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case c_grabPointerType:
|
||||||
|
{
|
||||||
|
if(!m_attached && RagdollController.Instance.IsRagdolled() && RestrictionsCheck(l_sender.transform.root))
|
||||||
|
Attach(l_sender);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -196,16 +227,16 @@ namespace ml_prm
|
||||||
RemoveGameCollision();
|
RemoveGameCollision();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attach(CVRPointer p_pointer)
|
void Attach(ContactSender p_sender)
|
||||||
{
|
{
|
||||||
if(!m_attached && (collider != null) && (m_rigidBody != null))
|
if(!m_attached && (collider != null) && (m_rigidBody != null) && !ms_attachedSenders.Contains(p_sender))
|
||||||
{
|
{
|
||||||
m_attachedPointer = p_pointer;
|
m_attachedSender = p_sender;
|
||||||
|
|
||||||
GameObject l_attachPoint = new GameObject("[AttachPoint]");
|
GameObject l_attachPoint = new GameObject("[AttachPoint]");
|
||||||
l_attachPoint.layer = CVRLayers.PlayerNetwork;
|
l_attachPoint.layer = CVRLayers.Default;
|
||||||
m_attachTransform = l_attachPoint.transform;
|
m_attachTransform = l_attachPoint.transform;
|
||||||
m_attachTransform.parent = p_pointer.transform;
|
m_attachTransform.parent = p_sender.transform;
|
||||||
|
|
||||||
Rigidbody l_body = l_attachPoint.AddComponent<Rigidbody>();
|
Rigidbody l_body = l_attachPoint.AddComponent<Rigidbody>();
|
||||||
l_body.isKinematic = true;
|
l_body.isKinematic = true;
|
||||||
|
|
@ -216,6 +247,7 @@ namespace ml_prm
|
||||||
m_attachJoint.breakForce = Mathf.Infinity;
|
m_attachJoint.breakForce = Mathf.Infinity;
|
||||||
m_attachJoint.breakTorque = Mathf.Infinity;
|
m_attachJoint.breakTorque = Mathf.Infinity;
|
||||||
|
|
||||||
|
ms_attachedSenders.Add(p_sender);
|
||||||
m_attached = true;
|
m_attached = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -232,7 +264,10 @@ namespace ml_prm
|
||||||
Object.Destroy(m_attachJoint);
|
Object.Destroy(m_attachJoint);
|
||||||
m_attachJoint = null;
|
m_attachJoint = null;
|
||||||
|
|
||||||
m_attachedPointer = null;
|
if(!ReferenceEquals(m_attachedSender, null))
|
||||||
|
ms_attachedSenders.Remove(m_attachedSender);
|
||||||
|
m_attachedSender = null;
|
||||||
|
|
||||||
m_attached = false;
|
m_attached = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -246,32 +281,12 @@ namespace ml_prm
|
||||||
BetterBetterCharacterController.Instance.IgnoreCollision(collider);
|
BetterBetterCharacterController.Instance.IgnoreCollision(collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CVRTriggerVolume
|
internal void RestoreContact()
|
||||||
public void TriggerEnter(CVRPointer pointer)
|
|
||||||
{
|
|
||||||
if(Settings.PointersReaction && (pointer != null) && pointer.enabled && (pointer.type == c_ragdollPointerType) && !IgnoreCheck(pointer.transform) && (RagdollController.Instance != null) && !RagdollController.Instance.IsRagdolled())
|
|
||||||
RagdollController.Instance.Ragdoll();
|
|
||||||
}
|
|
||||||
public void TriggerExit(CVRPointer pointer)
|
|
||||||
{
|
{
|
||||||
|
if((m_contactReciever != null) && ContactManager.Exists)
|
||||||
|
ContactManager.Instance.RestoreContact(m_contactReciever, m_contactReciever.isActiveAndEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static utility
|
static bool RestrictionsCheck(Transform p_transform) => (p_transform != PlayerSetup.Instance.transform);
|
||||||
static bool IgnoreCheck(Transform p_transform)
|
|
||||||
{
|
|
||||||
return (Settings.IgnoreLocal && (p_transform.root == PlayerSetup.Instance.transform));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool RestrictionsCheck(Transform p_transform)
|
|
||||||
{
|
|
||||||
if(p_transform == PlayerSetup.Instance.transform)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
PlayerDescriptor l_playerDescriptor = p_transform.GetComponent<PlayerDescriptor>();
|
|
||||||
if(l_playerDescriptor != null)
|
|
||||||
return (!Settings.FriendsGrab || Friends.FriendsWith(l_playerDescriptor.ownerId));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,7 @@ namespace ml_prm
|
||||||
IKSystem.Instance.applyOriginalHipRotation = true;
|
IKSystem.Instance.applyOriginalHipRotation = true;
|
||||||
|
|
||||||
PlayerSetup.Instance.AnimatorManager.CancelEmote = true;
|
PlayerSetup.Instance.AnimatorManager.CancelEmote = true;
|
||||||
m_ragdolledParameter.SetValue(true);
|
m_ragdolledParameter?.SetValue(true);
|
||||||
|
|
||||||
if(!WorldManager.IsSafeWorld())
|
if(!WorldManager.IsSafeWorld())
|
||||||
{
|
{
|
||||||
|
|
@ -677,6 +677,7 @@ namespace ml_prm
|
||||||
|
|
||||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||||
{
|
{
|
||||||
|
l_handler.RestoreContact();
|
||||||
l_handler.SetVelocity(l_velocity);
|
l_handler.SetVelocity(l_velocity);
|
||||||
l_handler.SetAngularVelocity(Vector3.zero);
|
l_handler.SetAngularVelocity(Vector3.zero);
|
||||||
}
|
}
|
||||||
|
|
@ -689,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -706,7 +710,7 @@ namespace ml_prm
|
||||||
if(m_vrIK != null)
|
if(m_vrIK != null)
|
||||||
m_vrIK.solver.Reset();
|
m_vrIK.solver.Reset();
|
||||||
|
|
||||||
m_ragdolledParameter.SetValue(false);
|
m_ragdolledParameter?.SetValue(false);
|
||||||
|
|
||||||
m_puppet.localPosition = Vector3.zero;
|
m_puppet.localPosition = Vector3.zero;
|
||||||
m_puppet.localRotation = Quaternion.identity;
|
m_puppet.localRotation = Quaternion.identity;
|
||||||
|
|
|
||||||
67
ml_prm/ResourcesHandler.cs
Normal file
67
ml_prm/ResourcesHandler.cs
Normal 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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,6 @@ namespace ml_prm
|
||||||
AngularDrag,
|
AngularDrag,
|
||||||
Gravity,
|
Gravity,
|
||||||
PointersReaction,
|
PointersReaction,
|
||||||
IgnoreLocal,
|
|
||||||
CombatReaction,
|
CombatReaction,
|
||||||
AutoRecover,
|
AutoRecover,
|
||||||
RecoverDelay,
|
RecoverDelay,
|
||||||
|
|
@ -35,7 +34,8 @@ namespace ml_prm
|
||||||
FallDamage,
|
FallDamage,
|
||||||
FallLimit,
|
FallLimit,
|
||||||
GestureGrab,
|
GestureGrab,
|
||||||
FriendsGrab
|
ImpactSounds,
|
||||||
|
ImpactVolume
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Hotkey { get; private set; } = true;
|
public static bool Hotkey { get; private set; } = true;
|
||||||
|
|
@ -45,7 +45,6 @@ namespace ml_prm
|
||||||
public static float AngularDrag { get; private set; } = 2f;
|
public static float AngularDrag { get; private set; } = 2f;
|
||||||
public static bool Gravity { get; private set; } = true;
|
public static bool Gravity { get; private set; } = true;
|
||||||
public static bool PointersReaction { get; private set; } = true;
|
public static bool PointersReaction { get; private set; } = true;
|
||||||
public static bool IgnoreLocal { get; private set; } = true;
|
|
||||||
public static bool CombatReaction { get; private set; } = true;
|
public static bool CombatReaction { get; private set; } = true;
|
||||||
public static bool AutoRecover { get; private set; } = false;
|
public static bool AutoRecover { get; private set; } = false;
|
||||||
public static float RecoverDelay { get; private set; } = 3f;
|
public static float RecoverDelay { get; private set; } = 3f;
|
||||||
|
|
@ -57,8 +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 FriendsGrab { get; private set; } = true;
|
public static bool ImpactSounds { get; private set; } = true;
|
||||||
public static float GrabDistance { get; private set; } = 0.1f;
|
public static float ImpactVolume { get; private set; } = 0.25f;
|
||||||
|
|
||||||
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>();
|
||||||
|
|
@ -67,7 +66,6 @@ namespace ml_prm
|
||||||
public static readonly SettingEvent<float> OnAngularDragChanged = new SettingEvent<float>();
|
public static readonly SettingEvent<float> OnAngularDragChanged = new SettingEvent<float>();
|
||||||
public static readonly SettingEvent<bool> OnGravityChanged = new SettingEvent<bool>();
|
public static readonly SettingEvent<bool> OnGravityChanged = new SettingEvent<bool>();
|
||||||
public static readonly SettingEvent<bool> OnPointersReactionChanged = new SettingEvent<bool>();
|
public static readonly SettingEvent<bool> OnPointersReactionChanged = new SettingEvent<bool>();
|
||||||
public static readonly SettingEvent<bool> OnIgnoreLocalChanged = new SettingEvent<bool>();
|
|
||||||
public static readonly SettingEvent<bool> OnCombatReactionChanged = new SettingEvent<bool>();
|
public static readonly SettingEvent<bool> OnCombatReactionChanged = new SettingEvent<bool>();
|
||||||
public static readonly SettingEvent<bool> OnAutoRecoverChanged = new SettingEvent<bool>();
|
public static readonly SettingEvent<bool> OnAutoRecoverChanged = new SettingEvent<bool>();
|
||||||
public static readonly SettingEvent<float> OnRecoverDelayChanged = new SettingEvent<float>();
|
public static readonly SettingEvent<float> OnRecoverDelayChanged = new SettingEvent<float>();
|
||||||
|
|
@ -79,8 +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> OnFriendsGrabChanged = new SettingEvent<bool>();
|
public static readonly SettingEvent<bool> OnImpactSoundsChanged = new SettingEvent<bool>();
|
||||||
public static readonly SettingEvent<float> OnGrabDistanceChanged = new SettingEvent<float>();
|
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;
|
||||||
|
|
@ -98,7 +96,6 @@ namespace ml_prm
|
||||||
ms_category.CreateEntry(ModSetting.AngularDrag.ToString(), AngularDrag, null, null, true),
|
ms_category.CreateEntry(ModSetting.AngularDrag.ToString(), AngularDrag, null, null, true),
|
||||||
ms_category.CreateEntry(ModSetting.Gravity.ToString(), Gravity, null, null, true),
|
ms_category.CreateEntry(ModSetting.Gravity.ToString(), Gravity, null, null, true),
|
||||||
ms_category.CreateEntry(ModSetting.PointersReaction.ToString(), PointersReaction, null, null, true),
|
ms_category.CreateEntry(ModSetting.PointersReaction.ToString(), PointersReaction, null, null, true),
|
||||||
ms_category.CreateEntry(ModSetting.IgnoreLocal.ToString(), IgnoreLocal, null, null, true),
|
|
||||||
ms_category.CreateEntry(ModSetting.CombatReaction.ToString(), CombatReaction, null, null, true),
|
ms_category.CreateEntry(ModSetting.CombatReaction.ToString(), CombatReaction, null, null, true),
|
||||||
ms_category.CreateEntry(ModSetting.AutoRecover.ToString(), AutoRecover, null, null, true),
|
ms_category.CreateEntry(ModSetting.AutoRecover.ToString(), AutoRecover, null, null, true),
|
||||||
ms_category.CreateEntry(ModSetting.RecoverDelay.ToString(), RecoverDelay, null, null, true),
|
ms_category.CreateEntry(ModSetting.RecoverDelay.ToString(), RecoverDelay, null, null, true),
|
||||||
|
|
@ -110,7 +107,8 @@ namespace ml_prm
|
||||||
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.FriendsGrab.ToString(), FriendsGrab, 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);
|
||||||
|
|
@ -122,7 +120,6 @@ namespace ml_prm
|
||||||
AngularDrag = Mathf.Clamp((float)ms_entries[(int)ModSetting.AngularDrag].BoxedValue, 0f, 50f);
|
AngularDrag = Mathf.Clamp((float)ms_entries[(int)ModSetting.AngularDrag].BoxedValue, 0f, 50f);
|
||||||
Gravity = (bool)ms_entries[(int)ModSetting.Gravity].BoxedValue;
|
Gravity = (bool)ms_entries[(int)ModSetting.Gravity].BoxedValue;
|
||||||
PointersReaction = (bool)ms_entries[(int)ModSetting.PointersReaction].BoxedValue;
|
PointersReaction = (bool)ms_entries[(int)ModSetting.PointersReaction].BoxedValue;
|
||||||
IgnoreLocal = (bool)ms_entries[(int)ModSetting.IgnoreLocal].BoxedValue;
|
|
||||||
CombatReaction = (bool)ms_entries[(int)ModSetting.CombatReaction].BoxedValue;
|
CombatReaction = (bool)ms_entries[(int)ModSetting.CombatReaction].BoxedValue;
|
||||||
AutoRecover = (bool)ms_entries[(int)ModSetting.AutoRecover].BoxedValue;
|
AutoRecover = (bool)ms_entries[(int)ModSetting.AutoRecover].BoxedValue;
|
||||||
RecoverDelay = Mathf.Clamp((float)ms_entries[(int)ModSetting.RecoverDelay].BoxedValue, 1f, 10f);
|
RecoverDelay = Mathf.Clamp((float)ms_entries[(int)ModSetting.RecoverDelay].BoxedValue, 1f, 10f);
|
||||||
|
|
@ -134,7 +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;
|
||||||
FriendsGrab = (bool)ms_entries[(int)ModSetting.FriendsGrab].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)
|
||||||
|
|
@ -181,13 +179,6 @@ namespace ml_prm
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModSetting.IgnoreLocal:
|
|
||||||
{
|
|
||||||
IgnoreLocal = (bool)p_value;
|
|
||||||
OnIgnoreLocalChanged.Invoke(IgnoreLocal);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ModSetting.CombatReaction:
|
case ModSetting.CombatReaction:
|
||||||
{
|
{
|
||||||
CombatReaction = (bool)p_value;
|
CombatReaction = (bool)p_value;
|
||||||
|
|
@ -251,10 +242,10 @@ namespace ml_prm
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModSetting.FriendsGrab:
|
case ModSetting.ImpactSounds:
|
||||||
{
|
{
|
||||||
FriendsGrab = (bool)p_value;
|
ImpactSounds = (bool)p_value;
|
||||||
OnFriendsGrabChanged.Invoke(FriendsGrab);
|
OnImpactSoundsChanged.Invoke(ImpactSounds);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -293,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
141
ml_prm/SoundManager.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
using ABI.CCK.Components;
|
using ABI.CCK.Components;
|
||||||
using ABI_RC.Core.Player;
|
|
||||||
using ABI_RC.Core.Savior;
|
|
||||||
using ABI_RC.Systems.IK;
|
|
||||||
using ABI_RC.Systems.Movement;
|
using ABI_RC.Systems.Movement;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ABI_RC.Core.InteractionSystem;
|
using ABI_RC.Core.InteractionSystem;
|
||||||
|
using NAK.Contacts;
|
||||||
|
|
||||||
namespace ml_prm
|
namespace ml_prm
|
||||||
{
|
{
|
||||||
|
|
@ -18,6 +16,8 @@ namespace ml_prm
|
||||||
static readonly FieldInfo ms_influencerTouchingVolumes = typeof(PhysicsInfluencer).GetField("_touchingVolumes", BindingFlags.Instance | BindingFlags.NonPublic);
|
static readonly FieldInfo ms_influencerTouchingVolumes = typeof(PhysicsInfluencer).GetField("_touchingVolumes", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
static readonly FieldInfo ms_influencerSubmergedColliders = typeof(PhysicsInfluencer).GetField("_submergedColliders", BindingFlags.Instance | BindingFlags.NonPublic);
|
static readonly FieldInfo ms_influencerSubmergedColliders = typeof(PhysicsInfluencer).GetField("_submergedColliders", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
static readonly FieldInfo ms_lastCVRSeat = typeof(BetterBetterCharacterController).GetField("_lastCvrSeat", BindingFlags.Instance | BindingFlags.NonPublic);
|
static readonly FieldInfo ms_lastCVRSeat = typeof(BetterBetterCharacterController).GetField("_lastCvrSeat", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
static readonly FieldInfo ms_contactList = typeof(ContactManager).GetField("contactList", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
static readonly FieldInfo ms_pendingRemove = typeof(ContactManager).GetField("pendingRemove", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
|
||||||
public static void ClearFluidVolumes(this BetterBetterCharacterController p_instance) => (ms_touchingVolumes?.GetValue(p_instance) as List<FluidVolume>)?.Clear();
|
public static void ClearFluidVolumes(this BetterBetterCharacterController p_instance) => (ms_touchingVolumes?.GetValue(p_instance) as List<FluidVolume>)?.Clear();
|
||||||
|
|
||||||
|
|
@ -35,6 +35,18 @@ namespace ml_prm
|
||||||
|
|
||||||
public static CVRSeat GetCurrentSeat(this BetterBetterCharacterController p_instance) => (ms_lastCVRSeat?.GetValue(p_instance) as CVRSeat);
|
public static CVRSeat GetCurrentSeat(this BetterBetterCharacterController p_instance) => (ms_lastCVRSeat?.GetValue(p_instance) as CVRSeat);
|
||||||
|
|
||||||
|
public static bool IsRegistered(this ContactManager p_instance, ContactBase p_contact) => (ms_contactList?.GetValue(p_instance) as List<ContactBase>).Contains(p_contact);
|
||||||
|
|
||||||
|
public static void RestoreContact(this ContactManager p_instance, ContactBase p_contact, bool p_state)
|
||||||
|
{
|
||||||
|
if(p_instance.IsRegistered(p_contact))
|
||||||
|
(ms_pendingRemove?.GetValue(p_instance) as HashSet<int>).Remove(p_contact.ContactId);
|
||||||
|
else
|
||||||
|
p_instance.Register(p_contact);
|
||||||
|
|
||||||
|
p_instance.SetEnabled(p_contact.ContactId, p_state);
|
||||||
|
}
|
||||||
|
|
||||||
// Unity specific
|
// Unity specific
|
||||||
public static void CopyGlobal(this Transform p_source, Transform p_target)
|
public static void CopyGlobal(this Transform p_source, Transform p_target)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<PackageId>PlayerRagdollMod</PackageId>
|
<PackageId>PlayerRagdollMod</PackageId>
|
||||||
<Version>1.2.4</Version>
|
<Version>1.2.7</Version>
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>PlayerRagdollMod</Product>
|
<Product>PlayerRagdollMod</Product>
|
||||||
|
|
@ -22,6 +22,19 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="resources/person.png" />
|
<EmbeddedResource Include="resources/person.png" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_hard1.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_hard2.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_hard3.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_hard4.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_hard5.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_hard6.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_soft1.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_soft2.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_soft3.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_soft4.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_soft5.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_soft6.wav" />
|
||||||
|
<EmbeddedResource Include="resources\sounds\body_medium_impact_soft7.wav" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -65,6 +78,11 @@
|
||||||
<Private>false</Private>
|
<Private>false</Private>
|
||||||
<SpecificVersion>false</SpecificVersion>
|
<SpecificVersion>false</SpecificVersion>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AudioModule">
|
||||||
|
<HintPath>D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AudioModule.dll</HintPath>
|
||||||
|
<SpecificVersion>false</SpecificVersion>
|
||||||
|
<Private>false</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="UnityEngine.ClothModule">
|
<Reference Include="UnityEngine.ClothModule">
|
||||||
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.ClothModule.dll</HintPath>
|
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/UnityEngine.ClothModule.dll</HintPath>
|
||||||
<Private>false</Private>
|
<Private>false</Private>
|
||||||
|
|
@ -90,6 +108,16 @@
|
||||||
<Private>false</Private>
|
<Private>false</Private>
|
||||||
<SpecificVersion>false</SpecificVersion>
|
<SpecificVersion>false</SpecificVersion>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||||
|
<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>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
|
|
||||||
BIN
ml_prm/resources/sounds/body_medium_impact_hard1.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_hard1.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_hard2.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_hard2.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_hard3.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_hard3.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_hard4.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_hard4.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_hard5.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_hard5.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_hard6.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_hard6.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_soft1.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_soft1.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_soft2.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_soft2.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_soft3.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_soft3.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_soft4.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_soft4.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_soft5.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_soft5.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_soft6.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_soft6.wav
Normal file
Binary file not shown.
BIN
ml_prm/resources/sounds/body_medium_impact_soft7.wav
Normal file
BIN
ml_prm/resources/sounds/body_medium_impact_soft7.wav
Normal file
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_vei.ViveExtendedInput), "ViveExtendedInput", "1.1.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_vei.ViveExtendedInput), "ViveExtendedInput", "1.1.3", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<PackageId>ViveExtendedInput</PackageId>
|
<PackageId>ViveExtendedInput</PackageId>
|
||||||
<Version>1.1.2</Version>
|
<Version>1.1.3</Version>
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Product>ViveExtendedInput</Product>
|
<Product>ViveExtendedInput</Product>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using ABI_RC.VideoPlayer;
|
using ABI_RC.VideoPlayer;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
@ -10,17 +11,66 @@ namespace ml_vpc
|
||||||
|
|
||||||
public override void OnInitializeMelon()
|
public override void OnInitializeMelon()
|
||||||
{
|
{
|
||||||
HarmonyInstance.Patch(typeof(YoutubeDl).GetMethod("GetVideoMetaDataAsync", BindingFlags.NonPublic | BindingFlags.Static),
|
HarmonyInstance.Patch(typeof(YoutubeDl).GetMethod("GetVideoMetaDataAsync", BindingFlags.Public | BindingFlags.Static),
|
||||||
new HarmonyLib.HarmonyMethod(typeof(VideoPlayerCookies).GetMethod(nameof(OnGetYoutubeVideoMetaData_Prefix), BindingFlags.NonPublic | BindingFlags.Static))
|
new HarmonyLib.HarmonyMethod(typeof(VideoPlayerCookies).GetMethod(nameof(OnGetYoutubeVideoMetaData_Prefix), BindingFlags.NonPublic | BindingFlags.Static))
|
||||||
);
|
);
|
||||||
|
|
||||||
ms_cookiesPath = Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, "cookies.txt");
|
ms_cookiesPath = Path.Combine(MelonLoader.Utils.MelonEnvironment.UserDataDirectory, "cookies.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnGetYoutubeVideoMetaData_Prefix(ref string parameter)
|
public override void OnLateInitializeMelon()
|
||||||
{
|
{
|
||||||
if(File.Exists(ms_cookiesPath))
|
Settings.Init();
|
||||||
parameter += string.Format(" --cookies \"{0}\"", ms_cookiesPath);
|
}
|
||||||
|
|
||||||
|
static void OnGetYoutubeVideoMetaData_Prefix(ref string youtubeUrl, ref string existingParameters)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Settings.Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (Settings.Mode)
|
||||||
|
{
|
||||||
|
case Settings.CookieMode.File:
|
||||||
|
if (File.Exists(ms_cookiesPath))
|
||||||
|
existingParameters += string.Format("--cookies \"{0}\"", ms_cookiesPath);
|
||||||
|
else
|
||||||
|
MelonLoader.MelonLogger.Warning("Cookies file not found in: '" + ms_cookiesPath + "'");
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserFirefox:
|
||||||
|
existingParameters += "--cookies-from-browser firefox";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserBrave:
|
||||||
|
existingParameters += "--cookies-from-browser brave";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserChrome:
|
||||||
|
existingParameters += "--cookies-from-browser chrome";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserChromium:
|
||||||
|
existingParameters += "--cookies-from-browser chromium";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserEdge:
|
||||||
|
existingParameters += "--cookies-from-browser edge";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserOpera:
|
||||||
|
existingParameters += "--cookies-from-browser opera";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserSafari:
|
||||||
|
existingParameters += "--cookies-from-browser safari";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserVivaldi:
|
||||||
|
existingParameters += "--cookies-from-browser vivaldi";
|
||||||
|
break;
|
||||||
|
case Settings.CookieMode.BrowserWhale:
|
||||||
|
existingParameters += "--cookies-from-browser whale";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Warning(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
[assembly: MelonLoader.MelonInfo(typeof(ml_vpc.VideoPlayerCookies), "VideoPlayerCookies", "1.0.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
[assembly: MelonLoader.MelonInfo(typeof(ml_vpc.VideoPlayerCookies), "VideoPlayerCookies", "1.0.5", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
[assembly: MelonLoader.MelonAdditionalCredits("kafeijao, Slime")]
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,39 @@ This mod allows yt-dlp to use cookies for playing YouTube videos.
|
||||||
* Put `VideoPlayerCookies.dll` in `Mods` folder of game
|
* Put `VideoPlayerCookies.dll` in `Mods` folder of game
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
Available mod's settings in `Settings - General - Video Player Cookies`:
|
||||||
|
* **Enabled:** Whether this mod adds cookie parameters or not; `true` by default.
|
||||||
|
* **Cookie fetch mode:** cookies fetch method; `Cookie text file` by default.
|
||||||
|
* **Cookie text file** *(default)* fetches cookies from your `cookies.txt` file, check [How to create cookies.txt](#how-to-create-cookiestxt)
|
||||||
|
* **Browser Firefox** fetches cookies directly from FireFox browser. *requires to be logged-in on YouTube in FireFox*
|
||||||
|
* **Browser Brave** fetches cookies directly from Brave browser. *requires to be logged-in on YouTube in Brave*
|
||||||
|
* **Browser Chrome** fetches cookies directly from Chrome browser. *requires to be logged-in on YouTube in Chrome*
|
||||||
|
* **Browser Chromium** fetches cookies directly from Chromium browser. *requires to be logged-in on YouTube in Chromium*
|
||||||
|
* **Browser Edge** fetches cookies directly from Edge browser. *requires to be logged-in on YouTube in Edge*
|
||||||
|
* **Browser Opera** fetches cookies directly from Opera browser. *requires to be logged-in on YouTube in Opera*
|
||||||
|
* **Browser Safari** fetches cookies directly from Safari browser. *requires to be logged-in on YouTube in Safari*
|
||||||
|
* **Browser Vivaldi** fetches cookies directly from Vivaldi browser. *requires to be logged-in on YouTube in Vivaldi*
|
||||||
|
* **Browser Whale** fetches cookies directly from Whale browser. *requires to be logged-in on YouTube in Whale*
|
||||||
|
|
||||||
|
# How to create cookies.txt
|
||||||
* Acquire cookies for YouTube from your browser:
|
* Acquire cookies for YouTube from your browser:
|
||||||
* Chromium-based browsers: [Get cookies.txt LOCALLY](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc) extension
|
* Chromium-based browsers: [Get cookies.txt LOCALLY](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc) extension
|
||||||
* Firefox-based browsers: [cookies.txt](https://addons.mozilla.org/en-US/firefox/addon/cookies-txt) extension
|
* Firefox-based browsers: [cookies.txt](https://addons.mozilla.org/en-US/firefox/addon/cookies-txt) extension
|
||||||
* Save result as file named `cookies.txt` in `<game_folder>/UserData` folder
|
* Save result as file named `cookies.txt` in `<game_folder>/UserData` folder
|
||||||
|
|
||||||
|
# How to make it work on Linux (Tested on CachyOS / Arch with Firefox)
|
||||||
|
Because of Linux / Proton, the cookies.txt doesn't seem to work well, instead it's better to use browser mode, the following tutorial explains how to set it up (tested using Firefox)
|
||||||
|
|
||||||
|
* Go to the mod settings and select your browser
|
||||||
|
* Put a video and wait for it to fail, then look at the logs
|
||||||
|
* It should tell you an error because it can't find your cookies in a path, for Firefox it looks like `AppData/Local/Packages/Mozilla.Firefox_n80bbvh6b1yt2/LocalCache/Roaming/Mozilla/Firefox/Profiles/`
|
||||||
|
* Go to AppData in the drive_c of the game, on Arch this is usually located at `/home/[USER]/.local/share/Steam/steamapps/compatdata/661130/pfx/drive_c/users/steamuser/Appdata`
|
||||||
|
* Create all the folders that it requires until the last one, for Firefox this means the folders `Packages`, `Mozilla.Firefox_n80bbvh6b1yt2`, `LocalCache`, `Roaming`, `Mozilla` and `Firefox` but don't create the last one (`Profiles`) yet unless you don't intend to use your real browser
|
||||||
|
* Because your cookies could change or expire, instead of giving it the files once, we'll use a symlink to the real firefox on your machine. This is completely up to you and you could just copy the files or get them from somewhere else
|
||||||
|
* Now you can create a link that points to the folder of your browser on Linux. For Firefox, this is the `Profiles` folder that should point to `/home/[USER]/.mozilla/firefox/`
|
||||||
|
* If you followed all the steps, the next video you put should successfully get the cookies from your browser
|
||||||
|
|
||||||
|
|
||||||
# Notes
|
# Notes
|
||||||
* After first use yt-dlp will remove unnecessary cookies from file automatically.
|
* After first use yt-dlp will remove unnecessary cookies from file automatically.
|
||||||
* Cookies contain private information and access to your YouTube account, **do not share them to anyone**.
|
* Cookies contain private information and access to your YouTube account, **do not share them to anyone**.
|
||||||
|
|
|
||||||
30
ml_vpc/ResourcesHandler.cs
Normal file
30
ml_vpc/ResourcesHandler.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace ml_vpc
|
||||||
|
{
|
||||||
|
static class ResourcesHandler
|
||||||
|
{
|
||||||
|
readonly static string ms_namespace = typeof(ResourcesHandler).Namespace;
|
||||||
|
|
||||||
|
public static string GetEmbeddedResource(string p_name)
|
||||||
|
{
|
||||||
|
string l_result = "";
|
||||||
|
Assembly l_assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Stream l_libraryStream = l_assembly.GetManifestResourceStream(ms_namespace + ".resources." + p_name);
|
||||||
|
StreamReader l_streadReader = new StreamReader(l_libraryStream);
|
||||||
|
l_result = l_streadReader.ReadToEnd();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return l_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
144
ml_vpc/Settings.cs
Normal file
144
ml_vpc/Settings.cs
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
using ABI_RC.Core.InteractionSystem;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ml_vpc
|
||||||
|
{
|
||||||
|
static class Settings
|
||||||
|
{
|
||||||
|
internal class SettingEvent<T>
|
||||||
|
{
|
||||||
|
event Action<T> m_action;
|
||||||
|
public void AddListener(Action<T> p_listener) => m_action += p_listener;
|
||||||
|
public void RemoveListener(Action<T> p_listener) => m_action -= p_listener;
|
||||||
|
public void Invoke(T p_value) => m_action?.Invoke(p_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CookieMode
|
||||||
|
{
|
||||||
|
File = 0,
|
||||||
|
BrowserFirefox,
|
||||||
|
BrowserBrave,
|
||||||
|
BrowserChrome, // This one might not work
|
||||||
|
BrowserChromium,
|
||||||
|
BrowserEdge,
|
||||||
|
BrowserOpera,
|
||||||
|
BrowserSafari,
|
||||||
|
BrowserVivaldi,
|
||||||
|
BrowserWhale,
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ModSetting
|
||||||
|
{
|
||||||
|
Enabled = 0,
|
||||||
|
Mode,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Enabled { get; private set; } = true;
|
||||||
|
public static CookieMode Mode { get; private set; } = CookieMode.File;
|
||||||
|
|
||||||
|
static MelonLoader.MelonPreferences_Category ms_category = null;
|
||||||
|
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
|
||||||
|
|
||||||
|
public static readonly SettingEvent<bool> OnEnabledChanged = new SettingEvent<bool>();
|
||||||
|
public static readonly SettingEvent<CookieMode> OnModeChanged = new SettingEvent<CookieMode>();
|
||||||
|
|
||||||
|
internal static void Init()
|
||||||
|
{
|
||||||
|
ms_category = MelonLoader.MelonPreferences.CreateCategory("VPC", null, true);
|
||||||
|
|
||||||
|
ms_entries = new List<MelonLoader.MelonPreferences_Entry>()
|
||||||
|
{
|
||||||
|
ms_category.CreateEntry(nameof(ModSetting.Enabled), Enabled),
|
||||||
|
ms_category.CreateEntry(nameof(ModSetting.Mode), (int)CookieMode.File),
|
||||||
|
};
|
||||||
|
|
||||||
|
Enabled = (bool)ms_entries[(int)ModSetting.Enabled].BoxedValue;
|
||||||
|
Mode = (CookieMode)ms_entries[(int)ModSetting.Mode].BoxedValue;
|
||||||
|
|
||||||
|
MelonLoader.MelonCoroutines.Start(WaitMainMenuUi());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static System.Collections.IEnumerator WaitMainMenuUi()
|
||||||
|
{
|
||||||
|
while(ViewManager.Instance == null)
|
||||||
|
yield return null;
|
||||||
|
while(ViewManager.Instance.cohtmlView == null)
|
||||||
|
yield return null;
|
||||||
|
while(ViewManager.Instance.cohtmlView.Listener == null)
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
ViewManager.Instance.cohtmlView.Listener.ReadyForBindings += () =>
|
||||||
|
{
|
||||||
|
ViewManager.Instance.cohtmlView.View.BindCall("OnToggleUpdate_" + ms_category.Identifier, new Action<string, string>(OnToggleUpdate));
|
||||||
|
ViewManager.Instance.cohtmlView.View.BindCall("OnDropdownUpdate_" + ms_category.Identifier, new Action<string, string>(OnDropdownUpdate));
|
||||||
|
|
||||||
|
};
|
||||||
|
ViewManager.Instance.cohtmlView.Listener.FinishLoad += (_) =>
|
||||||
|
{
|
||||||
|
ViewManager.Instance.cohtmlView.View.ExecuteScript(ResourcesHandler.GetEmbeddedResource("mods_extension.js"));
|
||||||
|
ViewManager.Instance.cohtmlView.View.ExecuteScript(ResourcesHandler.GetEmbeddedResource("mod_menu.js"));
|
||||||
|
MelonLoader.MelonCoroutines.Start(UpdateMenuSettings());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static System.Collections.IEnumerator UpdateMenuSettings()
|
||||||
|
{
|
||||||
|
while(!ViewManager.Instance.IsReady || !ViewManager.Instance.IsViewShown)
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
foreach(var l_entry in ms_entries)
|
||||||
|
ViewManager.Instance.cohtmlView.View.TriggerEvent("updateModSetting", ms_category.Identifier, l_entry.DisplayName, l_entry.GetValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnToggleUpdate(string p_name, string p_value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(Enum.TryParse(p_name, out ModSetting l_setting) && bool.TryParse(p_value, out bool l_value))
|
||||||
|
{
|
||||||
|
switch(l_setting)
|
||||||
|
{
|
||||||
|
case ModSetting.Enabled:
|
||||||
|
{
|
||||||
|
Enabled = l_value;
|
||||||
|
OnEnabledChanged.Invoke(Enabled);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_entries[(int)l_setting].BoxedValue = l_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnDropdownUpdate(string p_name, string p_value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(Enum.TryParse(p_name, out ModSetting l_setting) && int.TryParse(p_value, out int l_value))
|
||||||
|
{
|
||||||
|
switch(l_setting)
|
||||||
|
{
|
||||||
|
case ModSetting.Mode:
|
||||||
|
{
|
||||||
|
Mode = (CookieMode)l_value;
|
||||||
|
OnModeChanged.Invoke(Mode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_entries[(int)l_setting].BoxedValue = l_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
ml_vpc/Utils.cs
Normal file
12
ml_vpc/Utils.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
using ABI_RC.Core.UI;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace ml_vpc
|
||||||
|
{
|
||||||
|
static class Utils
|
||||||
|
{
|
||||||
|
static readonly FieldInfo ms_view = typeof(CohtmlControlledViewWrapper).GetField("_view", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
public static void ExecuteScript(this CohtmlControlledViewWrapper p_instance, string p_script) => (ms_view?.GetValue(p_instance) as cohtml.Net.View)?.ExecuteScript(p_script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<AssemblyName>VideoPlayerCookies</AssemblyName>
|
<AssemblyName>VideoPlayerCookies</AssemblyName>
|
||||||
<Authors>SDraw</Authors>
|
<Authors>SDraw</Authors>
|
||||||
<Company>SDraw</Company>
|
<Company>SDraw</Company>
|
||||||
<Version>1.0.2</Version>
|
<Version>1.0.5</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
|
@ -18,6 +18,11 @@
|
||||||
<Exec Command="copy /y "$(TargetPath)" "$(CVRPath)/Mods/"" />
|
<Exec Command="copy /y "$(TargetPath)" "$(CVRPath)/Mods/"" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="../js/mods_extension.js" Link="resources/mods_extension.js" />
|
||||||
|
<EmbeddedResource Include="resources/mod_menu.js" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="0Harmony">
|
<Reference Include="0Harmony">
|
||||||
<HintPath>$(CVRPath)/MelonLoader/net35/0Harmony.dll</HintPath>
|
<HintPath>$(CVRPath)/MelonLoader/net35/0Harmony.dll</HintPath>
|
||||||
|
|
@ -29,6 +34,16 @@
|
||||||
<Private>false</Private>
|
<Private>false</Private>
|
||||||
<SpecificVersion>false</SpecificVersion>
|
<SpecificVersion>false</SpecificVersion>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="cohtml.Net">
|
||||||
|
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/cohtml.Net.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
<SpecificVersion>false</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Cohtml.Runtime">
|
||||||
|
<HintPath>$(CVRPath)/ChilloutVR_Data/Managed/Cohtml.Runtime.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
<SpecificVersion>false</SpecificVersion>
|
||||||
|
</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>
|
||||||
|
|
|
||||||
37
ml_vpc/resources/mod_menu.js
Normal file
37
ml_vpc/resources/mod_menu.js
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
let l_block = document.createElement('div');
|
||||||
|
l_block.innerHTML = `
|
||||||
|
<div class ="settings-subcategory">
|
||||||
|
<div class ="subcategory-name">Video Player Cookies</div>
|
||||||
|
<div class ="subcategory-description"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class ="row-wrapper">
|
||||||
|
<div class ="option-caption" data-tooltip="Whether the mod is enabled or not">Enabled: </div>
|
||||||
|
<div class ="option-input">
|
||||||
|
<div id="Enabled" class ="inp_toggle no-scroll" data-current="true"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class ="row-wrapper">
|
||||||
|
<div class ="option-caption" data-tooltip="The way cookies are fetched">Cookie fetch mode: </div>
|
||||||
|
<div class ="option-input">
|
||||||
|
<div id="Mode" class ="inp_dropdown no-scroll" data-options="0:Cookie text file,1:Browser Firefox,2:Browser Brave,3:Browser Chrome,4:Browser Chromium,5:Browser Edge,6:Browser Opera,7:Browser Safari,8:Browser Vivaldi,9:Browser Whale" data-current="0"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.getElementById('settings-general').appendChild(l_block);
|
||||||
|
|
||||||
|
// Toggles
|
||||||
|
for (let l_toggle of l_block.querySelectorAll('.inp_toggle'))
|
||||||
|
modsExtension.addSetting('VPC', l_toggle.id, modsExtension.createToggle(l_toggle, 'OnToggleUpdate_VPC'));
|
||||||
|
|
||||||
|
// Sliders
|
||||||
|
for (let l_slider of l_block.querySelectorAll('.inp_slider'))
|
||||||
|
modsExtension.addSetting('VPC', l_slider.id, modsExtension.createSlider(l_slider, 'OnSliderUpdate_VPC'));
|
||||||
|
|
||||||
|
// Dropdowns
|
||||||
|
for (let l_dropdown of l_block.querySelectorAll('.inp_dropdown'))
|
||||||
|
modsExtension.addSetting('VPC', l_dropdown.id, modsExtension.createDropdown(l_dropdown, 'OnDropdownUpdate_VPC'));
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue