mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2026-01-01 06:07:30 +00:00
mass commit of laziness
This commit is contained in:
parent
ce992c70ee
commit
6d4fc549d9
167 changed files with 5471 additions and 675 deletions
|
|
@ -1,4 +1,4 @@
|
|||
using MelonLoader;
|
||||
using MelonLoader;
|
||||
using NAK.AvatarQueueSystemTweaks.Patches;
|
||||
|
||||
namespace NAK.AvatarQueueSystemTweaks;
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
using System.Collections;
|
||||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.IO;
|
||||
using ABI_RC.Core.Networking.IO.Social;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using MelonLoader;
|
||||
using MelonLoader;
|
||||
using NAK.AvatarQueueSystemTweaks.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk" />
|
||||
109
.Deprecated/BufferParticleFixer/Main.cs
Normal file
109
.Deprecated/BufferParticleFixer/Main.cs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
using System.Reflection;
|
||||
using ABI_RC.Core.Networking.API.Responses;
|
||||
using ABI_RC.Core.Util.AssetFiltering;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.BufferParticleFixer;
|
||||
|
||||
public class BufferParticleFixerMod : MelonMod
|
||||
{
|
||||
private static MelonLogger.Instance Logger;
|
||||
|
||||
private static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(nameof(BufferParticleFixer));
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryFixBufferParticles =
|
||||
Category.CreateEntry(
|
||||
identifier: "fix_buffer_particles",
|
||||
true,
|
||||
display_name: "Fix Buffer Particles",
|
||||
description: "Should the mod attempt to fix buffer particles by modifying their lifetime and sub-emitter settings?");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
Logger = LoggerInstance;
|
||||
|
||||
HarmonyInstance.Patch(
|
||||
typeof(SharedFilter).GetMethod(nameof(SharedFilter.ProcessParticleComponent),
|
||||
BindingFlags.Public | BindingFlags.Static),
|
||||
postfix: new HarmonyMethod(typeof(BufferParticleFixerMod).GetMethod(nameof(OnProcessParticleComponent),
|
||||
BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
}
|
||||
|
||||
private static void OnProcessParticleComponent(
|
||||
string collectionId,
|
||||
Component particleComponent,
|
||||
bool physicsCollision,
|
||||
CompatibilityVersions compatibilityVersion)
|
||||
{
|
||||
if (particleComponent is not ParticleSystem particleSystem)
|
||||
return;
|
||||
|
||||
if (!EntryFixBufferParticles.Value)
|
||||
return;
|
||||
|
||||
// Logger.Msg($"Processing particle system on collection '{collectionId}'.");
|
||||
|
||||
if (!IsLikelyBufferParticle(particleSystem))
|
||||
return;
|
||||
|
||||
Logger.Msg($"Detected likely buffer particle system '{particleSystem.name}' on collection '{collectionId}'. Applying fix...");
|
||||
|
||||
// Set start lifetime to 1000
|
||||
// All sub-emitters to "Spawn on Birth"
|
||||
// https://x.com/hfcRedddd/status/1696914565919813679
|
||||
|
||||
ParticleSystem.MainModule mainModule = particleSystem.main;
|
||||
|
||||
mainModule.startLifetime = 1f;
|
||||
|
||||
for (int i = 0; i < particleSystem.subEmitters.subEmittersCount; i++)
|
||||
{
|
||||
ParticleSystem subEmitter = particleSystem.subEmitters.GetSubEmitterSystem(i);
|
||||
if (subEmitter) particleSystem.subEmitters.SetSubEmitterType(i, ParticleSystemSubEmitterType.Birth);
|
||||
}
|
||||
}
|
||||
|
||||
// https://x.com/hfcRedddd/status/1696913727415537807
|
||||
private static bool IsLikelyBufferParticle(ParticleSystem ps)
|
||||
{
|
||||
// Check if the sub-emitters are children of the particle system
|
||||
Transform psTransform = ps.transform;
|
||||
|
||||
bool hasSubEmitterNotChild = false;
|
||||
|
||||
ParticleSystem.SubEmittersModule subEmitters = ps.subEmitters;
|
||||
int subEmitterCount = subEmitters.subEmittersCount;
|
||||
|
||||
for (int i = 0; i < subEmitterCount; i++)
|
||||
{
|
||||
ParticleSystem subEmitter = subEmitters.GetSubEmitterSystem(i);
|
||||
|
||||
// Skip null sub-emitters
|
||||
if (!subEmitter)
|
||||
{
|
||||
Logger.Warning($"Particle system '{ps.name}' has a null sub-emitter at index {i}.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// If any sub-emitter is not a child of the particle system, it's likely a buffer particle.
|
||||
// This setup is also what shits into our logs...
|
||||
if (!subEmitter.transform.IsChildOf(psTransform))
|
||||
hasSubEmitterNotChild = true;
|
||||
}
|
||||
|
||||
if (hasSubEmitterNotChild)
|
||||
{
|
||||
// Buffer particles have very short lifetimes
|
||||
if (!(ps.main.startLifetime.constant > 0.05f))
|
||||
return true;
|
||||
|
||||
Logger.Msg($"A potential buffer particle system '{ps.name}' has a start lifetime of {ps.main.startLifetime.constant}, which is longer than expected.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
32
.Deprecated/BufferParticleFixer/Properties/AssemblyInfo.cs
Normal file
32
.Deprecated/BufferParticleFixer/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.BufferParticleFixer.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.BufferParticleFixer))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.BufferParticleFixer))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.BufferParticleFixer.BufferParticleFixerMod),
|
||||
nameof(NAK.BufferParticleFixer),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/BufferParticleFixer"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.BufferParticleFixer.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
14
.Deprecated/BufferParticleFixer/README.md
Normal file
14
.Deprecated/BufferParticleFixer/README.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# SearchWithSpacesFix
|
||||
|
||||
Fixes search terms that use spaces.
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Deprecated/BufferParticleFixer/format.json
Normal file
23
.Deprecated/BufferParticleFixer/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "SearchWithSpacesFix",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2024r177",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Fixes search terms that include spaces.",
|
||||
"searchtags": [
|
||||
"search",
|
||||
"spaces",
|
||||
"fix",
|
||||
"meow"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r42/SearchWithSpacesFix.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/SearchWithSpacesFix/",
|
||||
"changelog": "- Initial release",
|
||||
"embedcolor": "#f61963"
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ using System.Reflection;
|
|||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/CVRGizmos"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
|
||||
|
|
|
|||
9
.Deprecated/ChatBoxTweaks/ChatBoxTweaks.csproj
Normal file
9
.Deprecated/ChatBoxTweaks/ChatBoxTweaks.csproj
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>PlayerCloneAttachment</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\playercloneattachment.assets" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
92
.Deprecated/ChatBoxTweaks/Main.cs
Normal file
92
.Deprecated/ChatBoxTweaks/Main.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
using System.Reflection;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.UI.UIRework.Managers;
|
||||
using ABI_RC.Systems.ChatBox;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.LowLevel;
|
||||
using UnityEngine.PlayerLoop;
|
||||
|
||||
namespace NAK.ChatBoxTweaks;
|
||||
|
||||
public class ChatBoxTweaksMod : MelonMod
|
||||
{
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
HarmonyInstance.Patch(
|
||||
typeof(KeyboardManager).GetMethod(nameof(KeyboardManager.OnKeyboardSubmit),
|
||||
BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
prefix: new HarmonyMethod(typeof(ChatBoxTweaksMod).GetMethod(nameof(OnPreKeyboardManagerKeyboardSubmit),
|
||||
BindingFlags.NonPublic | BindingFlags.Static)),
|
||||
postfix: new HarmonyMethod(typeof(ChatBoxTweaksMod).GetMethod(nameof(OnPostKeyboardManagerKeyboardSubmit),
|
||||
BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
}
|
||||
|
||||
private static void OnPreKeyboardManagerKeyboardSubmit(ref KeyboardManager __instance, ref KeyboardManager.OpenSource? __state)
|
||||
{
|
||||
__state = __instance.KeyboardOpenSource;
|
||||
}
|
||||
|
||||
private static void OnPostKeyboardManagerKeyboardSubmit(ref KeyboardManager.OpenSource? __state)
|
||||
{
|
||||
if (__state == KeyboardManager.OpenSource.TextComms) ChatBoxAPI.OpenKeyboard();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public static class NetworkLoopInjector
|
||||
{
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
static void InjectNetworkFixedUpdate()
|
||||
{
|
||||
var playerLoop = PlayerLoop.GetCurrentPlayerLoop();
|
||||
|
||||
// Find the FixedUpdate phase
|
||||
int fixedUpdateIndex = Array.FindIndex(playerLoop.subSystemList, s => s.type == typeof(FixedUpdate));
|
||||
if (fixedUpdateIndex < 0)
|
||||
{
|
||||
Debug.LogError("FixedUpdate not found in player loop!");
|
||||
return;
|
||||
}
|
||||
|
||||
var fixedUpdate = playerLoop.subSystemList[fixedUpdateIndex];
|
||||
|
||||
// Create your custom PlayerLoopSystem
|
||||
var networkSystem = new PlayerLoopSystem
|
||||
{
|
||||
type = typeof(NetworkFixedUpdate),
|
||||
updateDelegate = NetworkFixedUpdate.Run
|
||||
};
|
||||
|
||||
// Insert at the start so it runs before physics, animation, etc.
|
||||
var subs = fixedUpdate.subSystemList.ToList();
|
||||
subs.Insert(0, networkSystem);
|
||||
fixedUpdate.subSystemList = subs.ToArray();
|
||||
|
||||
// Reassign and set back
|
||||
playerLoop.subSystemList[fixedUpdateIndex] = fixedUpdate;
|
||||
PlayerLoop.SetPlayerLoop(playerLoop);
|
||||
|
||||
Debug.Log("[NetworkLoopInjector] Inserted NetworkFixedUpdate at start of FixedUpdate loop");
|
||||
}
|
||||
|
||||
static class NetworkFixedUpdate
|
||||
{
|
||||
static int lastStateFrame = -1;
|
||||
|
||||
public static void Run()
|
||||
{
|
||||
// Apply your networked object state syncs before physics simulation
|
||||
Debug.Log("Last State Frame: " + lastStateFrame + " Current Frame: " + Time.frameCount);
|
||||
lastStateFrame = Time.frameCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
32
.Deprecated/ChatBoxTweaks/Properties/AssemblyInfo.cs
Normal file
32
.Deprecated/ChatBoxTweaks/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.ChatBoxTweaks.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.ChatBoxTweaks))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.ChatBoxTweaks))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.ChatBoxTweaks.ChatBoxTweaksMod),
|
||||
nameof(NAK.ChatBoxTweaks),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/ChatBoxTweaks"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.ChatBoxTweaks.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
22
.Deprecated/ChatBoxTweaks/README.md
Normal file
22
.Deprecated/ChatBoxTweaks/README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# YouAreMyPropNowWeAreHavingSoftTacosLater
|
||||
|
||||
Lets you bring held, attached, and occupied props through world loads. This is configurable in the mod settings.
|
||||
|
||||
https://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO
|
||||
|
||||
There is special logic in place for bringing air vehicles through world loads.
|
||||
If above the ground you will be placed up to 20m above the spawnpoint of the next world.
|
||||
|
||||
## Examples
|
||||
https://fixupx.com/NotAKidoS/status/1910545346922422675
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Deprecated/ChatBoxTweaks/format.json
Normal file
23
.Deprecated/ChatBoxTweaks/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": 262,
|
||||
"name": "YouAreMyPropNowWeAreHavingSoftTacosLater",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2025r180",
|
||||
"loaderversion": "0.7.2",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Lets you bring held, attached, and occupied props through world loads. This is configurable in the mod settings.\nhttps://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO\n\nThere is special logic in place for bringing air vehicles through world loads. If above the ground you will be placed up to 20m above the spawnpoint of the next world.",
|
||||
"searchtags": [
|
||||
"prop",
|
||||
"spawn",
|
||||
"friend",
|
||||
"load"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r47/YouAreMyPropNowWeAreHavingSoftTacosLater.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/YouAreMyPropNowWeAreHavingSoftTacosLater/",
|
||||
"changelog": "- Initial release",
|
||||
"embedcolor": "#f61963"
|
||||
}
|
||||
6
.Deprecated/ChatBubbles/ChatBubbles.csproj
Normal file
6
.Deprecated/ChatBubbles/ChatBubbles.csproj
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>YouAreMineNow</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
236
.Deprecated/ChatBubbles/Main.cs
Normal file
236
.Deprecated/ChatBubbles/Main.cs
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
using System.Reflection;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Util;
|
||||
using ABI_RC.Systems.Communications;
|
||||
using ABI_RC.Systems.GameEventSystem;
|
||||
using ABI_RC.Systems.RuntimeDebug;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.YouAreMyPropNowWeAreHavingSoftTacosLater;
|
||||
|
||||
public class ChatBubblesMod : MelonMod
|
||||
{
|
||||
#region Melon Preferences
|
||||
|
||||
private static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(nameof(YouAreMyPropNowWeAreHavingSoftTacosLater));
|
||||
|
||||
private static readonly MelonPreferences_Entry<KeyCode> EntryChatBubblesKey =
|
||||
Category.CreateEntry("keyboard_bind", KeyCode.Y, display_name: "Chat Bubbles Key",
|
||||
description: "Key to open chat bubble input.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryBubbleDuration =
|
||||
Category.CreateEntry("bubble_duration", 5.0f, display_name: "Bubble Duration",
|
||||
description: "Base duration in seconds for chat bubbles to stay visible.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryDurationPerChar =
|
||||
Category.CreateEntry("duration_per_char", 0.05f, display_name: "Duration Per Character",
|
||||
description: "Additional duration per character in the message.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<int> EntryPoolSize =
|
||||
Category.CreateEntry("pool_size", 20, display_name: "Pool Size",
|
||||
description: "Maximum number of chat bubbles that can be displayed at once.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<Color> EntryBubbleColor =
|
||||
Category.CreateEntry("bubble_color", new Color(1.0f, 1.0f, 1.0f, 1.0f), display_name: "Bubble Color",
|
||||
description: "Color of chat bubble text.");
|
||||
|
||||
#endregion Melon Preferences
|
||||
|
||||
#region Object Pool
|
||||
|
||||
private class ChatBubble
|
||||
{
|
||||
public CVRPlayerEntity Player { get; set; }
|
||||
public string Message { get; set; }
|
||||
public float Duration { get; set; }
|
||||
public float Timer { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Player = null;
|
||||
Message = string.Empty;
|
||||
Duration = 0f;
|
||||
Timer = 0f;
|
||||
IsActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<ChatBubble> _chatBubblePool = [];
|
||||
private readonly List<ChatBubble> _activeBubbles = [];
|
||||
|
||||
private void InitializePool()
|
||||
{
|
||||
MelonLogger.Msg("Initializing chat bubble pool with size: " + EntryPoolSize.Value);
|
||||
_chatBubblePool.Clear();
|
||||
|
||||
for (int i = 0; i < EntryPoolSize.Value; i++)
|
||||
{
|
||||
_chatBubblePool.Add(new ChatBubble());
|
||||
}
|
||||
}
|
||||
|
||||
private ChatBubble GetBubbleFromPool()
|
||||
{
|
||||
// First try to find an inactive bubble
|
||||
foreach (var bubble in _chatBubblePool)
|
||||
{
|
||||
if (!bubble.IsActive)
|
||||
{
|
||||
bubble.Reset();
|
||||
bubble.IsActive = true;
|
||||
_activeBubbles.Add(bubble);
|
||||
return bubble;
|
||||
}
|
||||
}
|
||||
|
||||
// If all bubbles are active, reuse the oldest one
|
||||
if (_activeBubbles.Count > 0)
|
||||
{
|
||||
var oldestBubble = _activeBubbles[0];
|
||||
_activeBubbles.RemoveAt(0);
|
||||
oldestBubble.Reset();
|
||||
oldestBubble.IsActive = true;
|
||||
_activeBubbles.Add(oldestBubble);
|
||||
return oldestBubble;
|
||||
}
|
||||
|
||||
// This should never happen if the pool is initialized properly
|
||||
MelonLogger.Warning("No chat bubbles available in pool!");
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ReturnBubbleToPool(ChatBubble bubble)
|
||||
{
|
||||
bubble.IsActive = false;
|
||||
_activeBubbles.Remove(bubble);
|
||||
}
|
||||
|
||||
#endregion Object Pool
|
||||
|
||||
#region Melon Events
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
MelonLogger.Msg("Initializing Chat Bubbles Mod");
|
||||
InitializePool();
|
||||
|
||||
CVRGameEventSystem.Communications.TextChat.Local.OnMessageReceived.AddListener(OnLocalMessageReceived);
|
||||
CVRGameEventSystem.Communications.TextChat.Direct.OnMessageReceived.AddListener(OnGlobalMessageReceived);
|
||||
CVRGameEventSystem.Communications.TextChat.Global.OnMessageReceived.AddListener(OnDirectMessageReceived);
|
||||
|
||||
HarmonyInstance.Patch(
|
||||
typeof(ViewManager).GetMethod(nameof(ViewManager.SendToWorldUi),
|
||||
BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
postfix: new HarmonyMethod(typeof(ChatBubblesMod).GetMethod(nameof(OnViewManagerSendToWorldUi),
|
||||
BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
|
||||
MelonLogger.Msg("Chat Bubbles Mod initialized successfully");
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
// Process key input to open chat
|
||||
if (Input.GetKeyDown(EntryChatBubblesKey.Value))
|
||||
{
|
||||
if (!CVRSyncHelper.IsConnectedToGameNetwork())
|
||||
return;
|
||||
|
||||
IsInKeyboardToWriteANiceMessage = true;
|
||||
ViewManager.Instance.openMenuKeyboard(string.Empty);
|
||||
}
|
||||
|
||||
// Update and render active chat bubbles
|
||||
UpdateChatBubbles();
|
||||
}
|
||||
|
||||
private void UpdateChatBubbles()
|
||||
{
|
||||
// Make a copy of the list to avoid issues when modifying during iteration
|
||||
var bubblesToUpdate = new List<ChatBubble>(_activeBubbles);
|
||||
|
||||
foreach (var bubble in bubblesToUpdate)
|
||||
{
|
||||
if (bubble.Player == null || bubble.Player.PuppetMaster == null)
|
||||
{
|
||||
ReturnBubbleToPool(bubble);
|
||||
continue;
|
||||
}
|
||||
|
||||
bubble.Timer += Time.deltaTime;
|
||||
|
||||
if (bubble.Timer >= bubble.Duration)
|
||||
{
|
||||
ReturnBubbleToPool(bubble);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Draw the bubble text at the player's nameplate position
|
||||
var nameplatePosition = bubble.Player.PuppetMaster.GetNamePlateWorldPosition();
|
||||
// Offset slightly above the nameplate
|
||||
nameplatePosition.y += 0.2f;
|
||||
|
||||
RuntimeGizmos.DrawText(nameplatePosition, bubble.Message, 5, EntryBubbleColor.Value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Melon Events
|
||||
|
||||
#region Game Events
|
||||
|
||||
public static bool IsInKeyboardToWriteANiceMessage { get; set; }
|
||||
|
||||
private static void OnViewManagerSendToWorldUi(string value)
|
||||
{
|
||||
if (!IsInKeyboardToWriteANiceMessage) return;
|
||||
IsInKeyboardToWriteANiceMessage = false;
|
||||
Comms_Manager.SendLocalTextMessage(value);
|
||||
Comms_Manager.SendDirectTextMessage(CVRPlayerManager.Instance.NetworkPlayers[0].Uuid, value);
|
||||
Comms_Manager.SendGlobalTextMessage(value);
|
||||
MelonLogger.Msg("Sending message: " + value);
|
||||
}
|
||||
|
||||
private void OnLocalMessageReceived(CVRPlayerEntity player, string message)
|
||||
{
|
||||
CreateChatBubble(player, message);
|
||||
MelonLogger.Msg("OnLocalMessageReceived - Player: " + player?.Username + ", Message: " + message);
|
||||
}
|
||||
|
||||
private void OnDirectMessageReceived(CVRPlayerEntity player, string message)
|
||||
{
|
||||
CreateChatBubble(player, message);
|
||||
MelonLogger.Msg("OnDirectMessageReceived - Player: " + player?.Username + ", Message: " + message);
|
||||
}
|
||||
|
||||
private void OnGlobalMessageReceived(CVRPlayerEntity player, string message)
|
||||
{
|
||||
CreateChatBubble(player, message);
|
||||
MelonLogger.Msg("OnGlobalMessageReceived - Player: " + player?.Username + ", Message: " + message);
|
||||
}
|
||||
|
||||
private void CreateChatBubble(CVRPlayerEntity player, string message)
|
||||
{
|
||||
if (player == null || player.PuppetMaster == null)
|
||||
return;
|
||||
|
||||
// Calculate duration based on message length
|
||||
float baseDuration = EntryBubbleDuration.Value;
|
||||
float charDuration = EntryDurationPerChar.Value * message.Length;
|
||||
float totalDuration = Mathf.Clamp(baseDuration + charDuration, baseDuration, 15f);
|
||||
|
||||
ChatBubble bubble = GetBubbleFromPool();
|
||||
if (bubble == null) return;
|
||||
|
||||
bubble.Player = player;
|
||||
bubble.Message = message;
|
||||
bubble.Duration = totalDuration;
|
||||
bubble.Timer = 0f;
|
||||
}
|
||||
|
||||
#endregion Game Events
|
||||
}
|
||||
32
.Deprecated/ChatBubbles/Properties/AssemblyInfo.cs
Normal file
32
.Deprecated/ChatBubbles/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.YouAreMyPropNowWeAreHavingSoftTacosLater.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.YouAreMyPropNowWeAreHavingSoftTacosLater))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.YouAreMyPropNowWeAreHavingSoftTacosLater))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.YouAreMyPropNowWeAreHavingSoftTacosLater.ChatBubblesMod),
|
||||
nameof(NAK.YouAreMyPropNowWeAreHavingSoftTacosLater),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/ChatBubbles"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.YouAreMyPropNowWeAreHavingSoftTacosLater.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
19
.Deprecated/ChatBubbles/README.md
Normal file
19
.Deprecated/ChatBubbles/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# YouAreMyPropNowWeAreHavingSoftTacosLater
|
||||
|
||||
Lets you bring held & attached props through world loads.
|
||||
|
||||
https://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO
|
||||
|
||||
## Examples
|
||||
https://fixupx.com/NotAKidoS/status/1910545346922422675
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Deprecated/ChatBubbles/format.json
Normal file
23
.Deprecated/ChatBubbles/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "YouAreMyPropNowWeAreHavingSoftTacosLater",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2025r179",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Lets you bring held & attached props through world loads.\nhttps://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO",
|
||||
"searchtags": [
|
||||
"prop",
|
||||
"spawn",
|
||||
"friend",
|
||||
"load"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r46/YouAreMyPropNowWeAreHavingSoftTacosLater.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/YouAreMyPropNowWeAreHavingSoftTacosLater/",
|
||||
"changelog": "- Initial Release",
|
||||
"embedcolor": "#00FFFF"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>PlayerCloneAttachment</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\playercloneattachment.assets" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
169
.Deprecated/ControlToUnlockEyes/Main.cs
Normal file
169
.Deprecated/ControlToUnlockEyes/Main.cs
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.FaceTracking;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.ControlToUnlockEyes;
|
||||
|
||||
public class ControlToUnlockEyesMod : MelonMod
|
||||
{
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
HarmonyInstance.Patch(
|
||||
typeof(FaceTrackingManager).GetMethod(nameof(FaceTrackingManager.RegisterBuiltinModules),
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance),
|
||||
postfix: new HarmonyLib.HarmonyMethod(typeof(ControlToUnlockEyesMod).GetMethod(nameof(OnPostFaceTrackingManagerRegisterBuiltinModules),
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static))
|
||||
);
|
||||
}
|
||||
|
||||
private static void OnPostFaceTrackingManagerRegisterBuiltinModules(FaceTrackingManager __instance)
|
||||
=> __instance.RegisterEyeModule(new DefaultEyeModule());
|
||||
|
||||
public class DefaultEyeModule : IEyeTrackingModule
|
||||
{
|
||||
private const float FixedDistance = 10f;
|
||||
private bool _useFixedDistance = true;
|
||||
|
||||
private readonly EyeTrackingData _eyeTrackingData = new();
|
||||
private bool _dataAvailable;
|
||||
private bool _running;
|
||||
|
||||
private ControllerRay _activeRay;
|
||||
private Transform _rayDirectionTransform;
|
||||
|
||||
private CVRHand lastInteractHand = CVRHand.Right;
|
||||
|
||||
public bool Start(bool vr)
|
||||
{
|
||||
_running = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_running = false;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!PlayerSetup.Instance)
|
||||
return;
|
||||
|
||||
UpdateLastInteractHand();
|
||||
UpdateFakedEyeTrackingData();
|
||||
}
|
||||
|
||||
private void UpdateLastInteractHand()
|
||||
{
|
||||
ControllerRay leftRay = PlayerSetup.Instance.vrRayLeft;
|
||||
ControllerRay rightRay = PlayerSetup.Instance.vrRayRight;
|
||||
|
||||
if (!MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
_activeRay = PlayerSetup.Instance.desktopRay;
|
||||
_rayDirectionTransform = _activeRay.rayDirectionTransform;
|
||||
return;
|
||||
}
|
||||
|
||||
bool leftAvailable = IsHandAvailable(leftRay, CVRHand.Left);
|
||||
bool rightAvailable = IsHandAvailable(rightRay, CVRHand.Right);
|
||||
|
||||
if (CVRInputManager.Instance.interactLeftDown && leftAvailable)
|
||||
lastInteractHand = CVRHand.Left;
|
||||
else if (CVRInputManager.Instance.interactRightDown && rightAvailable)
|
||||
lastInteractHand = CVRHand.Right;
|
||||
|
||||
_activeRay = GetLastInteractRay();
|
||||
_rayDirectionTransform = _activeRay.rayDirectionTransform;
|
||||
}
|
||||
|
||||
private void UpdateFakedEyeTrackingData()
|
||||
{
|
||||
_dataAvailable = _activeRay.CanSelectPlayersAndProps();
|
||||
if (!_dataAvailable)
|
||||
return;
|
||||
|
||||
_eyeTrackingData.blinking = false;
|
||||
|
||||
Transform ourCameraTransform = PlayerSetup.Instance.activeCam.transform;
|
||||
|
||||
Vector3 rayForward = _rayDirectionTransform.forward;
|
||||
float rayDistance = _useFixedDistance ? FixedDistance : _activeRay.Hit.distance;
|
||||
|
||||
// TODO: dot product check to flip direction if behind camera
|
||||
|
||||
// Convert to camera-local *direction* (normalized) and multiply by selected distance so the gazePoint
|
||||
// is on a sphere around the camera rather than mapped to a "square".
|
||||
Vector3 localDir = ourCameraTransform.InverseTransformDirection(rayForward).normalized;
|
||||
Vector3 localGazePoint = localDir * rayDistance;
|
||||
|
||||
_eyeTrackingData.gazePoint = localGazePoint;
|
||||
}
|
||||
|
||||
private ControllerRay GetLastInteractRay()
|
||||
{
|
||||
if (!MetaPort.Instance.isUsingVr)
|
||||
return PlayerSetup.Instance.desktopRay;
|
||||
|
||||
ControllerRay leftRay = PlayerSetup.Instance.vrRayLeft;
|
||||
ControllerRay rightRay = PlayerSetup.Instance.vrRayRight;
|
||||
|
||||
if (lastInteractHand == CVRHand.Left && IsHandAvailable(leftRay, CVRHand.Left))
|
||||
return leftRay;
|
||||
if (lastInteractHand == CVRHand.Right && IsHandAvailable(rightRay, CVRHand.Right))
|
||||
return rightRay;
|
||||
|
||||
return GetBestAvailableHand();
|
||||
}
|
||||
|
||||
private ControllerRay GetBestAvailableHand()
|
||||
{
|
||||
if (!MetaPort.Instance.isUsingVr)
|
||||
return PlayerSetup.Instance.desktopRay;
|
||||
|
||||
ControllerRay leftRay = PlayerSetup.Instance.vrRayLeft;
|
||||
ControllerRay rightRay = PlayerSetup.Instance.vrRayRight;
|
||||
|
||||
bool leftAvailable = IsHandAvailable(leftRay, CVRHand.Left);
|
||||
bool rightAvailable = IsHandAvailable(rightRay, CVRHand.Right);
|
||||
|
||||
if (CVRInputManager.Instance.interactLeftDown && leftAvailable)
|
||||
return leftRay;
|
||||
if (CVRInputManager.Instance.interactRightDown && rightAvailable)
|
||||
return rightRay;
|
||||
|
||||
if (lastInteractHand == CVRHand.Left && leftAvailable)
|
||||
return leftRay;
|
||||
if (lastInteractHand == CVRHand.Right && rightAvailable)
|
||||
return rightRay;
|
||||
|
||||
if (rightAvailable) return rightRay;
|
||||
if (leftAvailable) return leftRay;
|
||||
|
||||
return rightRay;
|
||||
}
|
||||
|
||||
private static bool IsHandAvailable(ControllerRay ray, CVRHand hand)
|
||||
{
|
||||
if (ray.grabbedObject)
|
||||
return false;
|
||||
|
||||
if (CVR_MenuManager.Instance.IsViewShown &&
|
||||
CVR_MenuManager.Instance.SelectedQuickMenuHand == hand)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsRunning() => _running;
|
||||
public bool IsDataAvailable() => _dataAvailable;
|
||||
public EyeTrackingData GetTrackingData() => _eyeTrackingData;
|
||||
public string GetModuleName() => "None";
|
||||
public string GetModuleShortName() => "None";
|
||||
}
|
||||
}
|
||||
32
.Deprecated/ControlToUnlockEyes/Properties/AssemblyInfo.cs
Normal file
32
.Deprecated/ControlToUnlockEyes/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.ControlToUnlockEyes.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.ControlToUnlockEyes))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.ControlToUnlockEyes))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.ControlToUnlockEyes.ControlToUnlockEyesMod),
|
||||
nameof(NAK.ControlToUnlockEyes),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/ControlToUnlockEyes"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.ControlToUnlockEyes.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
22
.Deprecated/ControlToUnlockEyes/README.md
Normal file
22
.Deprecated/ControlToUnlockEyes/README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# YouAreMyPropNowWeAreHavingSoftTacosLater
|
||||
|
||||
Lets you bring held, attached, and occupied props through world loads. This is configurable in the mod settings.
|
||||
|
||||
https://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO
|
||||
|
||||
There is special logic in place for bringing air vehicles through world loads.
|
||||
If above the ground you will be placed up to 20m above the spawnpoint of the next world.
|
||||
|
||||
## Examples
|
||||
https://fixupx.com/NotAKidoS/status/1910545346922422675
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Deprecated/ControlToUnlockEyes/format.json
Normal file
23
.Deprecated/ControlToUnlockEyes/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": 262,
|
||||
"name": "YouAreMyPropNowWeAreHavingSoftTacosLater",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2025r180",
|
||||
"loaderversion": "0.7.2",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Lets you bring held, attached, and occupied props through world loads. This is configurable in the mod settings.\nhttps://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO\n\nThere is special logic in place for bringing air vehicles through world loads. If above the ground you will be placed up to 20m above the spawnpoint of the next world.",
|
||||
"searchtags": [
|
||||
"prop",
|
||||
"spawn",
|
||||
"friend",
|
||||
"load"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r47/YouAreMyPropNowWeAreHavingSoftTacosLater.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/YouAreMyPropNowWeAreHavingSoftTacosLater/",
|
||||
"changelog": "- Initial release",
|
||||
"embedcolor": "#f61963"
|
||||
}
|
||||
6
.Deprecated/FuckCameras/FuckCameras.csproj
Normal file
6
.Deprecated/FuckCameras/FuckCameras.csproj
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>YouAreMineNow</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
228
.Deprecated/FuckCameras/Main.cs
Normal file
228
.Deprecated/FuckCameras/Main.cs
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
using ABI_RC.Core.Util.AssetFiltering;
|
||||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.FuckCameras;
|
||||
|
||||
public class FuckCamerasMod : MelonMod
|
||||
{
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
HarmonyInstance.Patch(
|
||||
typeof(SharedFilter).GetMethod(nameof(SharedFilter.ProcessCamera),
|
||||
BindingFlags.Public | BindingFlags.Static),
|
||||
postfix: new HarmonyMethod(typeof(FuckCamerasMod).GetMethod(nameof(OnProcessCamera),
|
||||
BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
}
|
||||
|
||||
private static void OnProcessCamera(string collectionId, Camera camera)
|
||||
=> camera.gameObject.AddComponent<FuckCameraComponent>();
|
||||
|
||||
public class FuckCameraComponent : MonoBehaviour
|
||||
{
|
||||
private Camera _cam;
|
||||
private int _originalMask;
|
||||
|
||||
private Camera _pooledCam;
|
||||
private bool fuck;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_originalMask = _cam.cullingMask;
|
||||
_cam.Reset();
|
||||
// _cam.cullingMask = _originalMask;
|
||||
}
|
||||
|
||||
/*private void OnPreCull()
|
||||
{
|
||||
MelonLogger.Msg("PreCull");
|
||||
if (!TryGetComponent(out _cam)) return;
|
||||
|
||||
if (fuck)
|
||||
{
|
||||
// unset default layer
|
||||
_originalMask &= ~(1 << 0);
|
||||
_cam.cullingMask = _originalMask;
|
||||
Destroy(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_originalMask = _cam.cullingMask;
|
||||
_cam.cullingMask = 0;
|
||||
fuck = true;
|
||||
}*/
|
||||
|
||||
/*private IEnumerator OnPostRender()
|
||||
{
|
||||
MelonLogger.Msg("PostRender");
|
||||
// Restore the original mask if it has not changed since we set it to 0
|
||||
if (_cam.cullingMask == 0) _cam.cullingMask = _originalMask;
|
||||
|
||||
_cam.enabled = false;
|
||||
yield return new WaitForEndOfFrame();
|
||||
_cam.enabled = true;
|
||||
|
||||
MelonLogger.Msg("FuckCameraComponent: OnPostRender called for camera: " + _cam.name);
|
||||
// Destroy now that we have saved the day
|
||||
enabled = false;
|
||||
Destroy(this);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class CameraPoolManager : MonoBehaviour
|
||||
{
|
||||
private static CameraPoolManager _instance;
|
||||
public static CameraPoolManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
GameObject obj = new("CameraPoolManager");
|
||||
obj.SetActive(false);
|
||||
_instance = obj.AddComponent<CameraPoolManager>();
|
||||
DontDestroyOnLoad(obj);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<GameObject> _cameraObjects = new();
|
||||
|
||||
public Camera CreatePooledCamera(Camera source)
|
||||
{
|
||||
var go = new GameObject("PooledCamera");
|
||||
go.SetActive(false);
|
||||
var camera = go.AddComponent<Camera>();
|
||||
camera.CopyFrom(source);
|
||||
_cameraObjects.Add(go);
|
||||
return camera;
|
||||
}
|
||||
|
||||
public void RestoreCameraProperties(Camera target, Camera pooledCam)
|
||||
{
|
||||
// target.CopyFrom(pooledCam);
|
||||
CopyCameraProperties(pooledCam, target);
|
||||
}
|
||||
|
||||
public void ReleasePooledCamera(Camera pooledCam)
|
||||
{
|
||||
if (pooledCam != null)
|
||||
{
|
||||
var go = pooledCam.gameObject;
|
||||
_cameraObjects.Remove(go);
|
||||
Destroy(go);
|
||||
}
|
||||
}
|
||||
|
||||
// Skipped known diffs:
|
||||
// nearClipPlane
|
||||
// farClipPlane
|
||||
// fieldOfView
|
||||
// aspect
|
||||
// cullingMask
|
||||
// useOcclusionCulling
|
||||
// clearFlags
|
||||
// depthTextureMode
|
||||
// pixelRect
|
||||
// targetTexture
|
||||
|
||||
public static void CopyCameraProperties(Camera source, Camera target)
|
||||
{
|
||||
if (source == null || target == null) return;
|
||||
|
||||
target.nearClipPlane = source.nearClipPlane;
|
||||
target.farClipPlane = source.farClipPlane;
|
||||
|
||||
target.fieldOfView = source.fieldOfView;
|
||||
target.aspect = source.aspect;
|
||||
|
||||
int cullingMask = 0;
|
||||
|
||||
cullingMask = (cullingMask & ~(1 << 0)) | (source.cullingMask & (1 << 0));
|
||||
|
||||
cullingMask = (cullingMask & ~(1 << 1)) | (source.cullingMask & (1 << 1));
|
||||
cullingMask = (cullingMask & ~(1 << 2)) | (source.cullingMask & (1 << 2));
|
||||
cullingMask = (cullingMask & ~(1 << 3)) | (source.cullingMask & (1 << 3));
|
||||
cullingMask = (cullingMask & ~(1 << 4)) | (source.cullingMask & (1 << 4));
|
||||
|
||||
cullingMask = (cullingMask & ~(1 << 5)) | (source.cullingMask & (1 << 5));
|
||||
cullingMask = (cullingMask & ~(1 << 6)) | (source.cullingMask & (1 << 6));
|
||||
cullingMask = (cullingMask & ~(1 << 7)) | (source.cullingMask & (1 << 7));
|
||||
cullingMask = (cullingMask & ~(1 << 8)) | (source.cullingMask & (1 << 8));
|
||||
|
||||
cullingMask = (cullingMask & ~(1 << 9)) | (source.cullingMask & (1 << 9));
|
||||
cullingMask = (cullingMask & ~(1 << 10)) | (source.cullingMask & (1 << 10));
|
||||
cullingMask = (cullingMask & ~(1 << 11)) | (source.cullingMask & (1 << 11));
|
||||
cullingMask = (cullingMask & ~(1 << 12)) | (source.cullingMask & (1 << 12));
|
||||
cullingMask = (cullingMask & ~(1 << 13)) | (source.cullingMask & (1 << 13));
|
||||
cullingMask = (cullingMask & ~(1 << 14)) | (source.cullingMask & (1 << 14));
|
||||
cullingMask = (cullingMask & ~(1 << 15)) | (source.cullingMask & (1 << 15));
|
||||
cullingMask = (cullingMask & ~(1 << 16)) | (source.cullingMask & (1 << 16));
|
||||
cullingMask = (cullingMask & ~(1 << 17)) | (source.cullingMask & (1 << 17));
|
||||
cullingMask = (cullingMask & ~(1 << 18)) | (source.cullingMask & (1 << 18));
|
||||
cullingMask = (cullingMask & ~(1 << 19)) | (source.cullingMask & (1 << 19));
|
||||
cullingMask = (cullingMask & ~(1 << 20)) | (source.cullingMask & (1 << 20));
|
||||
cullingMask = (cullingMask & ~(1 << 21)) | (source.cullingMask & (1 << 21));
|
||||
cullingMask = (cullingMask & ~(1 << 22)) | (source.cullingMask & (1 << 22));
|
||||
cullingMask = (cullingMask & ~(1 << 23)) | (source.cullingMask & (1 << 23));
|
||||
cullingMask = (cullingMask & ~(1 << 24)) | (source.cullingMask & (1 << 24));
|
||||
cullingMask = (cullingMask & ~(1 << 25)) | (source.cullingMask & (1 << 25));
|
||||
cullingMask = (cullingMask & ~(1 << 26)) | (source.cullingMask & (1 << 26));
|
||||
cullingMask = (cullingMask & ~(1 << 27)) | (source.cullingMask & (1 << 27));
|
||||
cullingMask = (cullingMask & ~(1 << 28)) | (source.cullingMask & (1 << 28));
|
||||
cullingMask = (cullingMask & ~(1 << 29)) | (source.cullingMask & (1 << 29));
|
||||
cullingMask = (cullingMask & ~(1 << 30)) | (source.cullingMask & (1 << 30));
|
||||
cullingMask = (cullingMask & ~(1 << 31)) | (source.cullingMask & (1 << 31));
|
||||
|
||||
target.cullingMask = cullingMask;
|
||||
|
||||
target.clearFlags = source.clearFlags;
|
||||
target.depthTextureMode = source.depthTextureMode;
|
||||
target.useOcclusionCulling = source.useOcclusionCulling;
|
||||
target.pixelRect = source.pixelRect;
|
||||
target.targetTexture = source.targetTexture;
|
||||
|
||||
target.renderingPath = source.renderingPath;
|
||||
target.allowHDR = source.allowHDR;
|
||||
target.allowMSAA = source.allowMSAA;
|
||||
target.allowDynamicResolution = source.allowDynamicResolution;
|
||||
target.forceIntoRenderTexture = source.forceIntoRenderTexture;
|
||||
target.orthographic = source.orthographic;
|
||||
target.orthographicSize = source.orthographicSize;
|
||||
target.depth = source.depth;
|
||||
target.eventMask = source.eventMask;
|
||||
target.layerCullSpherical = source.layerCullSpherical;
|
||||
target.backgroundColor = source.backgroundColor;
|
||||
target.clearStencilAfterLightingPass = source.clearStencilAfterLightingPass;
|
||||
target.usePhysicalProperties = source.usePhysicalProperties;
|
||||
// target.iso = source.iso;
|
||||
// target.shutterSpeed = source.shutterSpeed;
|
||||
// target.aperture = source.aperture;
|
||||
// target.focusDistance = source.focusDistance;
|
||||
// target.bladeCount = source.bladeCount;
|
||||
// target.curvature = source.curvature;
|
||||
// target.barrelClipping = source.barrelClipping;
|
||||
// target.anamorphism = source.anamorphism;
|
||||
// target.enabled = source.enabled;
|
||||
// target.transform.position = source.transform.position;
|
||||
// target.transform.rotation = source.transform.rotation;
|
||||
// target.transform.localScale = source.transform.localScale;
|
||||
target.focalLength = source.focalLength;
|
||||
target.sensorSize = source.sensorSize;
|
||||
target.lensShift = source.lensShift;
|
||||
target.gateFit = source.gateFit;
|
||||
target.rect = source.rect;
|
||||
|
||||
target.targetDisplay = source.targetDisplay;
|
||||
target.stereoSeparation = source.stereoSeparation;
|
||||
target.stereoConvergence = source.stereoConvergence;
|
||||
target.stereoTargetEye = source.stereoTargetEye;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
.Deprecated/FuckCameras/Properties/AssemblyInfo.cs
Normal file
32
.Deprecated/FuckCameras/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.FuckCameras.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.FuckCameras))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.FuckCameras))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.FuckCameras.FuckCamerasMod),
|
||||
nameof(NAK.FuckCameras),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/FuckCameras"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.FuckCameras.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
19
.Deprecated/FuckCameras/README.md
Normal file
19
.Deprecated/FuckCameras/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# YouAreMyPropNowWeAreHavingSoftTacosLater
|
||||
|
||||
Lets you bring held & attached props through world loads.
|
||||
|
||||
https://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO
|
||||
|
||||
## Examples
|
||||
https://fixupx.com/NotAKidoS/status/1910545346922422675
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Deprecated/FuckCameras/format.json
Normal file
23
.Deprecated/FuckCameras/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "YouAreMyPropNowWeAreHavingSoftTacosLater",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2025r179",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Lets you bring held & attached props through world loads.\nhttps://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO",
|
||||
"searchtags": [
|
||||
"prop",
|
||||
"spawn",
|
||||
"friend",
|
||||
"load"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r46/YouAreMyPropNowWeAreHavingSoftTacosLater.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/YouAreMyPropNowWeAreHavingSoftTacosLater/",
|
||||
"changelog": "- Initial Release",
|
||||
"embedcolor": "#00FFFF"
|
||||
}
|
||||
6
.Deprecated/FuckCohtml2/FuckCohtml2.csproj
Normal file
6
.Deprecated/FuckCohtml2/FuckCohtml2.csproj
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>YouAreMineNow</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
57
.Deprecated/FuckCohtml2/Main.cs
Normal file
57
.Deprecated/FuckCohtml2/Main.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using System.Reflection;
|
||||
using ABI_RC.Core.UI;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
|
||||
namespace NAK.FuckCohtml2;
|
||||
|
||||
public class FuckCohtml2Mod : MelonMod
|
||||
{
|
||||
private static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(nameof(FuckCohtml2));
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryFixShouldAdvance =
|
||||
Category.CreateEntry(
|
||||
identifier: "fix_should_advance",
|
||||
true,
|
||||
display_name: "Fix ShouldAdvance",
|
||||
description: "Fix CohtmlControlledView.ShouldAdvance to respect the Enabled property.");
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryFixShouldRender =
|
||||
Category.CreateEntry(
|
||||
identifier: "fix_should_render",
|
||||
true,
|
||||
display_name: "Fix ShouldRender",
|
||||
description: "Fix CohtmlControlledView.ShouldRender to respect the Enabled property.");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
PatchProperty(nameof(CohtmlControlledView.ShouldAdvance), nameof(OnShouldAdvance));
|
||||
PatchProperty(nameof(CohtmlControlledView.ShouldRender), nameof(OnShouldRender));
|
||||
}
|
||||
|
||||
private void PatchProperty(string propertyName, string handlerName)
|
||||
{
|
||||
PropertyInfo prop = typeof(CohtmlControlledView).GetProperty(propertyName,
|
||||
BindingFlags.Public | BindingFlags.Instance);
|
||||
MethodInfo getter = prop!.GetGetMethod(true);
|
||||
|
||||
MethodInfo postfixMethod = typeof(FuckCohtml2Mod).GetMethod(handlerName,
|
||||
BindingFlags.NonPublic | BindingFlags.Static, null,
|
||||
[typeof(object), typeof(bool).MakeByRefType()], null);
|
||||
|
||||
HarmonyInstance.Patch(getter, postfix: new HarmonyMethod(postfixMethod));
|
||||
}
|
||||
|
||||
private static void OnShouldAdvance(object __instance, ref bool __result)
|
||||
{
|
||||
if (!EntryFixShouldAdvance.Value) return;
|
||||
if (__instance is CohtmlControlledView inst) __result &= inst.Enabled;
|
||||
}
|
||||
|
||||
private static void OnShouldRender(object __instance, ref bool __result)
|
||||
{
|
||||
if (!EntryFixShouldRender.Value) return;
|
||||
if (__instance is CohtmlControlledView inst) __result &= inst.Enabled;
|
||||
}
|
||||
}
|
||||
32
.Deprecated/FuckCohtml2/Properties/AssemblyInfo.cs
Normal file
32
.Deprecated/FuckCohtml2/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.FuckCohtml2.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.FuckCohtml2))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.FuckCohtml2))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.FuckCohtml2.FuckCohtml2Mod),
|
||||
nameof(NAK.FuckCohtml2),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/FuckCohtml2"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.FuckCohtml2.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
19
.Deprecated/FuckCohtml2/README.md
Normal file
19
.Deprecated/FuckCohtml2/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# YouAreMyPropNowWeAreHavingSoftTacosLater
|
||||
|
||||
Lets you bring held & attached props through world loads.
|
||||
|
||||
https://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO
|
||||
|
||||
## Examples
|
||||
https://fixupx.com/NotAKidoS/status/1910545346922422675
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Deprecated/FuckCohtml2/format.json
Normal file
23
.Deprecated/FuckCohtml2/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "YouAreMyPropNowWeAreHavingSoftTacosLater",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2025r179",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Lets you bring held & attached props through world loads.\nhttps://youtu.be/9P6Jeh-VN58?si=eXTPGyKB_0wq1gZO",
|
||||
"searchtags": [
|
||||
"prop",
|
||||
"spawn",
|
||||
"friend",
|
||||
"load"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r46/YouAreMyPropNowWeAreHavingSoftTacosLater.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/YouAreMyPropNowWeAreHavingSoftTacosLater/",
|
||||
"changelog": "- Initial Release",
|
||||
"embedcolor": "#00FFFF"
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ using System.Reflection;
|
|||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/FuckOffUICamera"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>YouAreMineNow</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
39
.Deprecated/IFUCKINGHATECAMERAS/Main.cs
Normal file
39
.Deprecated/IFUCKINGHATECAMERAS/Main.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Util.AnimatorManager;
|
||||
using ABI_RC.Systems.GameEventSystem;
|
||||
using ABI.CCK.Components;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.IFUCKINGHATECAMERAS;
|
||||
|
||||
public class IFUCKINGHATECAMERASMod : MelonMod
|
||||
{
|
||||
private static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(nameof(IFUCKINGHATECAMERAS));
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryRunHack =
|
||||
Category.CreateEntry(
|
||||
identifier: "run_hack",
|
||||
true,
|
||||
display_name: "Run Camera Hack (Avatars Only)?",
|
||||
description: "Should the camera hack run? Btw I fucking hate cameras.");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
CVRGameEventSystem.Avatar.OnRemoteAvatarLoad.AddListener(OnRemoteAvatarLoad);
|
||||
}
|
||||
|
||||
private static void OnRemoteAvatarLoad(CVRPlayerEntity playerEntity, CVRAvatar avatar)
|
||||
{
|
||||
if (!EntryRunHack.Value) return;
|
||||
|
||||
// HACK: Fixes a native crash (animating camera off on first frame) due to culling in specific worlds.
|
||||
// I am unsure the root cause, but the local player doesn't crash, and this is similar to what that does.
|
||||
|
||||
AvatarAnimatorManager AnimatorManager = playerEntity.PuppetMaster.AnimatorManager;
|
||||
AnimatorManager.Animator.cullingMode = AnimatorCullingMode.AlwaysAnimate; // Set culling mode to always animate
|
||||
AnimatorManager.Animator.Update(0f); // Update the animator to force it to do the first frame
|
||||
AnimatorManager.Animator.cullingMode = AnimatorCullingMode.CullUpdateTransforms; // Set to cull update transforms
|
||||
}
|
||||
}
|
||||
32
.Deprecated/IFUCKINGHATECAMERAS/Properties/AssemblyInfo.cs
Normal file
32
.Deprecated/IFUCKINGHATECAMERAS/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.IFUCKINGHATECAMERAS.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.IFUCKINGHATECAMERAS))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.IFUCKINGHATECAMERAS))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.IFUCKINGHATECAMERAS.IFUCKINGHATECAMERASMod),
|
||||
nameof(NAK.IFUCKINGHATECAMERAS),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/IFUCKINGHATECAMERAS"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.IFUCKINGHATECAMERAS.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
19
.Deprecated/IFUCKINGHATECAMERAS/README.md
Normal file
19
.Deprecated/IFUCKINGHATECAMERAS/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Tinyboard
|
||||
|
||||
Makes the keyboard small and smart.
|
||||
|
||||
Few small tweaks to the keyboard:
|
||||
- Shrinks the keyboard to a size that isn't fit for grandma.
|
||||
- Adjusts keyboard placement logic to align with the menu that it spawns from.
|
||||
- Enforces a title on the keyboard input if one is not found.
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Deprecated/IFUCKINGHATECAMERAS/format.json
Normal file
23
.Deprecated/IFUCKINGHATECAMERAS/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "Tinyboard",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2025r180",
|
||||
"loaderversion": "0.7.2",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Few small tweaks to the keyboard:\n- Shrinks the keyboard to a size that isn't fit for grandma.\n- Adjusts keyboard placement logic to align with the menu that it spawns from.\n- Enforces a title on the keyboard input if one is not found.",
|
||||
"searchtags": [
|
||||
"keyboard",
|
||||
"menu",
|
||||
"ui",
|
||||
"input"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r47/Tinyboard.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/Tinyboard/",
|
||||
"changelog": "- Initial release",
|
||||
"embedcolor": "#f61963"
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
using System.Reflection;
|
||||
using ABI_RC.Core.Util.AnimatorManager;
|
||||
using System.Reflection;
|
||||
using ABI_RC.Systems.Movement;
|
||||
using ABI.CCK.Scripts;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using MelonLoader;
|
||||
using MelonLoader;
|
||||
using NAK.KeepVelocityOnExitFlight.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using ABI_RC.Core.EventSystem;
|
||||
using ABI_RC.Core.IO;
|
||||
using ABI_RC.Core.Networking.API.Responses;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using MelonLoader;
|
||||
using MelonLoader;
|
||||
using NAK.LazyPrune.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
|
|
@ -3,22 +3,6 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
[RequireComponent(typeof(Camera))]
|
||||
public class DepthTextureFix : MonoBehaviour
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.InteractionSystem.Base;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace ABI_RC.Core.Player.Interaction
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,214 +1,214 @@
|
|||
using ABI_RC.Core.Player.Interaction.RaycastImpl;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ABI_RC.Core.Player.Interaction
|
||||
{
|
||||
public class CVRPlayerInteractionManager : MonoBehaviour
|
||||
{
|
||||
#region Singleton
|
||||
|
||||
public static CVRPlayerInteractionManager Instance { get; private set; }
|
||||
|
||||
#endregion Singleton
|
||||
|
||||
#region Serialized Fields
|
||||
|
||||
[Header("Hand Components")]
|
||||
[SerializeField] private CVRPlayerHand handVrLeft;
|
||||
[SerializeField] private CVRPlayerHand handVrRight;
|
||||
[SerializeField] private CVRPlayerHand handDesktopRight; // Desktop does not have a left hand
|
||||
|
||||
[Header("Raycast Transforms")]
|
||||
[SerializeField] private Transform raycastTransformVrRight;
|
||||
[SerializeField] private Transform raycastTransformVrLeft;
|
||||
[SerializeField] private Transform raycastTransformDesktopRight;
|
||||
|
||||
[Header("Settings")]
|
||||
[SerializeField] private bool interactionEnabled = true;
|
||||
[SerializeField] private LayerMask interactionLayerMask = -1; // Default to all layers, will be filtered
|
||||
|
||||
#endregion Serialized Fields
|
||||
|
||||
#region Properties
|
||||
|
||||
private CVRPlayerHand _rightHand;
|
||||
private CVRPlayerHand _leftHand;
|
||||
|
||||
private CVRPlayerRaycaster _rightRaycaster;
|
||||
private CVRPlayerRaycaster _leftRaycaster;
|
||||
|
||||
private CVRRaycastResult _rightRaycastResult;
|
||||
private CVRRaycastResult _leftRaycastResult;
|
||||
|
||||
// Input handler
|
||||
private CVRPlayerInputHandler _inputHandler;
|
||||
|
||||
// Interaction flags
|
||||
public bool InteractionEnabled
|
||||
{
|
||||
get => interactionEnabled;
|
||||
set => interactionEnabled = value;
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Unity Events
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
|
||||
// Create the input handler
|
||||
_inputHandler = gameObject.AddComponent<CVRPlayerInputHandler>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Setup interaction for current device mode
|
||||
SetupInteractionForDeviceMode();
|
||||
|
||||
// Listen for VR mode changes
|
||||
MetaPort.Instance.onVRModeSwitch.AddListener(SetupInteractionForDeviceMode);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!interactionEnabled)
|
||||
return;
|
||||
|
||||
// Process right hand
|
||||
if (_rightRaycaster != null)
|
||||
{
|
||||
// Determine raycast flags based on current mode
|
||||
CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_rightHand);
|
||||
|
||||
// Get raycast results
|
||||
_rightRaycastResult = _rightRaycaster.GetRaycastResults(flags);
|
||||
|
||||
// Process input based on raycast results
|
||||
_inputHandler.ProcessInput(CVRHand.Right, _rightRaycastResult);
|
||||
}
|
||||
|
||||
// Process left hand (if available)
|
||||
if (_leftRaycaster != null)
|
||||
{
|
||||
// Determine raycast flags based on current mode
|
||||
CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_leftHand);
|
||||
|
||||
// Get raycast results
|
||||
_leftRaycastResult = _leftRaycaster.GetRaycastResults(flags);
|
||||
|
||||
// Process input based on raycast results
|
||||
_inputHandler.ProcessInput(CVRHand.Left, _leftRaycastResult);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// Clean up event listener
|
||||
if (MetaPort.Instance != null)
|
||||
MetaPort.Instance.onVRModeSwitch.RemoveListener(SetupInteractionForDeviceMode);
|
||||
}
|
||||
|
||||
#endregion Unity Events
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Register a custom tool mode
|
||||
/// </summary>
|
||||
public void RegisterCustomToolMode(System.Action<CVRHand, CVRRaycastResult, InputState> callback)
|
||||
{
|
||||
_inputHandler.RegisterCustomTool(callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregister the current custom tool mode
|
||||
/// </summary>
|
||||
public void UnregisterCustomToolMode()
|
||||
{
|
||||
_inputHandler.UnregisterCustomTool();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the interaction mode
|
||||
/// </summary>
|
||||
public void SetInteractionMode(CVRPlayerInputHandler.InteractionMode mode)
|
||||
{
|
||||
_inputHandler.SetInteractionMode(mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the raycast result for a specific hand
|
||||
/// </summary>
|
||||
public CVRRaycastResult GetRaycastResult(CVRHand hand)
|
||||
{
|
||||
return hand == CVRHand.Left ? _leftRaycastResult : _rightRaycastResult;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void SetupInteractionForDeviceMode()
|
||||
{
|
||||
bool isVr = MetaPort.Instance.isUsingVr;
|
||||
|
||||
if (isVr)
|
||||
{
|
||||
// VR mode
|
||||
_rightHand = handVrRight;
|
||||
_leftHand = handVrLeft;
|
||||
|
||||
// VR uses the controller transform for raycasting
|
||||
_rightRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrRight);
|
||||
_leftRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Desktop mode
|
||||
_rightHand = handDesktopRight;
|
||||
_leftHand = null;
|
||||
|
||||
// Desktop uses the mouse position for raycasting when unlocked
|
||||
Camera desktopCamera = PlayerSetup.Instance.desktopCam;
|
||||
_rightRaycaster = new CVRPlayerRaycasterMouse(raycastTransformDesktopRight, desktopCamera);
|
||||
_leftRaycaster = null;
|
||||
}
|
||||
|
||||
// Set the layer mask for raycasters
|
||||
if (_rightRaycaster != null)
|
||||
_rightRaycaster.SetLayerMask(interactionLayerMask);
|
||||
|
||||
if (_leftRaycaster != null)
|
||||
_leftRaycaster.SetLayerMask(interactionLayerMask);
|
||||
}
|
||||
|
||||
private static CVRPlayerRaycaster.RaycastFlags DetermineRaycastFlags(CVRPlayerHand hand)
|
||||
{
|
||||
// Default to all flags
|
||||
CVRPlayerRaycaster.RaycastFlags flags = CVRPlayerRaycaster.RaycastFlags.All;
|
||||
|
||||
// Check if hand is holding a pickup
|
||||
if (hand != null && hand.IsHoldingObject)
|
||||
{
|
||||
// When holding an object, only check for COHTML interaction
|
||||
flags = CVRPlayerRaycaster.RaycastFlags.CohtmlInteract;
|
||||
}
|
||||
|
||||
// Could add more conditional flag adjustments here based on the current mode
|
||||
// For example, in a teleport tool mode, you might only want world hits
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
// using ABI_RC.Core.Player.Interaction.RaycastImpl;
|
||||
// using ABI_RC.Core.Savior;
|
||||
// using ABI_RC.Systems.InputManagement;
|
||||
// using UnityEngine;
|
||||
//
|
||||
// namespace ABI_RC.Core.Player.Interaction
|
||||
// {
|
||||
// public class CVRPlayerInteractionManager : MonoBehaviour
|
||||
// {
|
||||
// #region Singleton
|
||||
//
|
||||
// public static CVRPlayerInteractionManager Instance { get; private set; }
|
||||
//
|
||||
// #endregion Singleton
|
||||
//
|
||||
// #region Serialized Fields
|
||||
//
|
||||
// [Header("Hand Components")]
|
||||
// [SerializeField] private CVRPlayerHand handVrLeft;
|
||||
// [SerializeField] private CVRPlayerHand handVrRight;
|
||||
// [SerializeField] private CVRPlayerHand handDesktopRight; // Desktop does not have a left hand
|
||||
//
|
||||
// [Header("Raycast Transforms")]
|
||||
// [SerializeField] private Transform raycastTransformVrRight;
|
||||
// [SerializeField] private Transform raycastTransformVrLeft;
|
||||
// [SerializeField] private Transform raycastTransformDesktopRight;
|
||||
//
|
||||
// [Header("Settings")]
|
||||
// [SerializeField] private bool interactionEnabled = true;
|
||||
// [SerializeField] private LayerMask interactionLayerMask = -1; // Default to all layers, will be filtered
|
||||
//
|
||||
// #endregion Serialized Fields
|
||||
//
|
||||
// #region Properties
|
||||
//
|
||||
// private CVRPlayerHand _rightHand;
|
||||
// private CVRPlayerHand _leftHand;
|
||||
//
|
||||
// private CVRPlayerRaycaster _rightRaycaster;
|
||||
// private CVRPlayerRaycaster _leftRaycaster;
|
||||
//
|
||||
// private CVRRaycastResult _rightRaycastResult;
|
||||
// private CVRRaycastResult _leftRaycastResult;
|
||||
//
|
||||
// // Input handler
|
||||
// private CVRPlayerInputHandler _inputHandler;
|
||||
//
|
||||
// // Interaction flags
|
||||
// public bool InteractionEnabled
|
||||
// {
|
||||
// get => interactionEnabled;
|
||||
// set => interactionEnabled = value;
|
||||
// }
|
||||
//
|
||||
// #endregion Properties
|
||||
//
|
||||
// #region Unity Events
|
||||
//
|
||||
// private void Awake()
|
||||
// {
|
||||
// if (Instance != null && Instance != this)
|
||||
// {
|
||||
// Destroy(gameObject);
|
||||
// return;
|
||||
// }
|
||||
// Instance = this;
|
||||
//
|
||||
// // Create the input handler
|
||||
// _inputHandler = gameObject.AddComponent<CVRPlayerInputHandler>();
|
||||
// }
|
||||
//
|
||||
// private void Start()
|
||||
// {
|
||||
// // Setup interaction for current device mode
|
||||
// SetupInteractionForDeviceMode();
|
||||
//
|
||||
// // Listen for VR mode changes
|
||||
// MetaPort.Instance.onVRModeSwitch.AddListener(SetupInteractionForDeviceMode);
|
||||
// }
|
||||
//
|
||||
// private void Update()
|
||||
// {
|
||||
// if (!interactionEnabled)
|
||||
// return;
|
||||
//
|
||||
// // Process right hand
|
||||
// if (_rightRaycaster != null)
|
||||
// {
|
||||
// // Determine raycast flags based on current mode
|
||||
// CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_rightHand);
|
||||
//
|
||||
// // Get raycast results
|
||||
// _rightRaycastResult = _rightRaycaster.GetRaycastResults(flags);
|
||||
//
|
||||
// // Process input based on raycast results
|
||||
// _inputHandler.ProcessInput(CVRHand.Right, _rightRaycastResult);
|
||||
// }
|
||||
//
|
||||
// // Process left hand (if available)
|
||||
// if (_leftRaycaster != null)
|
||||
// {
|
||||
// // Determine raycast flags based on current mode
|
||||
// CVRPlayerRaycaster.RaycastFlags flags = DetermineRaycastFlags(_leftHand);
|
||||
//
|
||||
// // Get raycast results
|
||||
// _leftRaycastResult = _leftRaycaster.GetRaycastResults(flags);
|
||||
//
|
||||
// // Process input based on raycast results
|
||||
// _inputHandler.ProcessInput(CVRHand.Left, _leftRaycastResult);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void OnDestroy()
|
||||
// {
|
||||
// // Clean up event listener
|
||||
// if (MetaPort.Instance != null)
|
||||
// MetaPort.Instance.onVRModeSwitch.RemoveListener(SetupInteractionForDeviceMode);
|
||||
// }
|
||||
//
|
||||
// #endregion Unity Events
|
||||
//
|
||||
// #region Public Methods
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Register a custom tool mode
|
||||
// /// </summary>
|
||||
// public void RegisterCustomToolMode(System.Action<CVRHand, CVRRaycastResult, InputState> callback)
|
||||
// {
|
||||
// _inputHandler.RegisterCustomTool(callback);
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Unregister the current custom tool mode
|
||||
// /// </summary>
|
||||
// public void UnregisterCustomToolMode()
|
||||
// {
|
||||
// _inputHandler.UnregisterCustomTool();
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Set the interaction mode
|
||||
// /// </summary>
|
||||
// public void SetInteractionMode(CVRPlayerInputHandler.InteractionMode mode)
|
||||
// {
|
||||
// _inputHandler.SetInteractionMode(mode);
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Get the raycast result for a specific hand
|
||||
// /// </summary>
|
||||
// public CVRRaycastResult GetRaycastResult(CVRHand hand)
|
||||
// {
|
||||
// return hand == CVRHand.Left ? _leftRaycastResult : _rightRaycastResult;
|
||||
// }
|
||||
//
|
||||
// #endregion Public Methods
|
||||
//
|
||||
// #region Private Methods
|
||||
//
|
||||
// private void SetupInteractionForDeviceMode()
|
||||
// {
|
||||
// bool isVr = MetaPort.Instance.isUsingVr;
|
||||
//
|
||||
// if (isVr)
|
||||
// {
|
||||
// // VR mode
|
||||
// _rightHand = handVrRight;
|
||||
// _leftHand = handVrLeft;
|
||||
//
|
||||
// // VR uses the controller transform for raycasting
|
||||
// _rightRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrRight);
|
||||
// _leftRaycaster = new CVRPlayerRaycasterTransform(raycastTransformVrLeft);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Desktop mode
|
||||
// _rightHand = handDesktopRight;
|
||||
// _leftHand = null;
|
||||
//
|
||||
// // Desktop uses the mouse position for raycasting when unlocked
|
||||
// Camera desktopCamera = PlayerSetup.Instance.desktopCam;
|
||||
// _rightRaycaster = new CVRPlayerRaycasterMouse(raycastTransformDesktopRight, desktopCamera);
|
||||
// _leftRaycaster = null;
|
||||
// }
|
||||
//
|
||||
// // Set the layer mask for raycasters
|
||||
// if (_rightRaycaster != null)
|
||||
// _rightRaycaster.SetLayerMask(interactionLayerMask);
|
||||
//
|
||||
// if (_leftRaycaster != null)
|
||||
// _leftRaycaster.SetLayerMask(interactionLayerMask);
|
||||
// }
|
||||
//
|
||||
// private static CVRPlayerRaycaster.RaycastFlags DetermineRaycastFlags(CVRPlayerHand hand)
|
||||
// {
|
||||
// // Default to all flags
|
||||
// CVRPlayerRaycaster.RaycastFlags flags = CVRPlayerRaycaster.RaycastFlags.All;
|
||||
//
|
||||
// // Check if hand is holding a pickup
|
||||
// if (hand != null && hand.IsHoldingObject)
|
||||
// {
|
||||
// // When holding an object, only check for COHTML interaction
|
||||
// flags = CVRPlayerRaycaster.RaycastFlags.CohtmlInteract;
|
||||
// }
|
||||
//
|
||||
// // Could add more conditional flag adjustments here based on the current mode
|
||||
// // For example, in a teleport tool mode, you might only want world hits
|
||||
//
|
||||
// return flags;
|
||||
// }
|
||||
//
|
||||
// #endregion Private Methods
|
||||
// }
|
||||
// }
|
||||
|
|
@ -1,121 +1,121 @@
|
|||
using ABI_RC.Core.Base;
|
||||
using ABI_RC.Core.Player;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace NAK.SuperAwesomeMod.Components
|
||||
{
|
||||
public class CVRCanvasWrapper : MonoBehaviour
|
||||
{
|
||||
public bool IsInteractable = true;
|
||||
public float MaxInteractDistance = 10f;
|
||||
|
||||
private Canvas _canvas;
|
||||
private GraphicRaycaster _graphicsRaycaster;
|
||||
private static readonly List<RaycastResult> _raycastResults = new();
|
||||
private static readonly PointerEventData _pointerEventData = new(EventSystem.current);
|
||||
|
||||
private static Selectable _workingSelectable;
|
||||
private Camera _camera;
|
||||
private RectTransform _rectTransform;
|
||||
|
||||
#region Unity Events
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!TryGetComponent(out _canvas)
|
||||
|| _canvas.renderMode != RenderMode.WorldSpace)
|
||||
{
|
||||
IsInteractable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_rectTransform = _canvas.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_graphicsRaycaster = _canvas.gameObject.AddComponent<GraphicRaycaster>();
|
||||
_camera = PlayerSetup.Instance.activeCam;
|
||||
_canvas.worldCamera = _camera;
|
||||
}
|
||||
|
||||
#endregion Unity Events
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public bool GetGraphicsHit(Ray worldRay, out RaycastResult result)
|
||||
{
|
||||
result = default;
|
||||
|
||||
if (!IsInteractable || _camera == null) return false;
|
||||
|
||||
// Get the plane of the canvas
|
||||
Plane canvasPlane = new(transform.forward, transform.position);
|
||||
|
||||
// Find where the ray intersects the canvas plane
|
||||
if (!canvasPlane.Raycast(worldRay, out float distance))
|
||||
return false;
|
||||
|
||||
// Get the world point of intersection
|
||||
Vector3 worldHitPoint = worldRay.origin + worldRay.direction * distance;
|
||||
|
||||
// Check if hit point is within max interaction distance
|
||||
if (Vector3.Distance(worldRay.origin, worldHitPoint) > MaxInteractDistance)
|
||||
return false;
|
||||
|
||||
// Check if hit point is within canvas bounds
|
||||
Vector3 localHitPoint = transform.InverseTransformPoint(worldHitPoint);
|
||||
Rect canvasRect = _rectTransform.rect;
|
||||
if (!canvasRect.Contains(new Vector2(localHitPoint.x, localHitPoint.y)))
|
||||
return false;
|
||||
|
||||
// Convert world hit point to screen space
|
||||
Vector2 screenPoint = _camera.WorldToScreenPoint(worldHitPoint);
|
||||
|
||||
// Update pointer event data
|
||||
_pointerEventData.position = screenPoint;
|
||||
_pointerEventData.delta = Vector2.zero;
|
||||
|
||||
// Clear previous results and perform raycast
|
||||
_raycastResults.Clear();
|
||||
_graphicsRaycaster.Raycast(_pointerEventData, _raycastResults);
|
||||
|
||||
// Early out if no hits
|
||||
if (_raycastResults.Count == 0)
|
||||
{
|
||||
//Debug.Log($"No hits on canvas {_canvas.name}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find first valid interactive UI element
|
||||
foreach (RaycastResult hit in _raycastResults)
|
||||
{
|
||||
if (!hit.isValid)
|
||||
{
|
||||
//Debug.Log($"Invalid hit on canvas {_canvas.name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the hit object has a Selectable component and is interactable
|
||||
GameObject hitObject = hit.gameObject;
|
||||
if (!hitObject.TryGetComponent(out _workingSelectable)
|
||||
|| !_workingSelectable.interactable)
|
||||
{
|
||||
//Debug.Log($"Non-interactable hit on canvas {_canvas.name} - {hitObject.name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
//Debug.Log($"Hit on canvas {_canvas.name} with {hitObject.name}");
|
||||
|
||||
result = hit;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
// using ABI_RC.Core.Base;
|
||||
// using ABI_RC.Core.Player;
|
||||
// using UnityEngine;
|
||||
// using UnityEngine.EventSystems;
|
||||
// using UnityEngine.UI;
|
||||
//
|
||||
// namespace NAK.SuperAwesomeMod.Components
|
||||
// {
|
||||
// public class CVRCanvasWrapper : MonoBehaviour
|
||||
// {
|
||||
// public bool IsInteractable = true;
|
||||
// public float MaxInteractDistance = 10f;
|
||||
//
|
||||
// private Canvas _canvas;
|
||||
// private GraphicRaycaster _graphicsRaycaster;
|
||||
// private static readonly List<RaycastResult> _raycastResults = new();
|
||||
// private static readonly PointerEventData _pointerEventData = new(EventSystem.current);
|
||||
//
|
||||
// private static Selectable _workingSelectable;
|
||||
// private Camera _camera;
|
||||
// private RectTransform _rectTransform;
|
||||
//
|
||||
// #region Unity Events
|
||||
//
|
||||
// private void Awake()
|
||||
// {
|
||||
// if (!TryGetComponent(out _canvas)
|
||||
// || _canvas.renderMode != RenderMode.WorldSpace)
|
||||
// {
|
||||
// IsInteractable = false;
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// _rectTransform = _canvas.GetComponent<RectTransform>();
|
||||
// }
|
||||
//
|
||||
// private void Start()
|
||||
// {
|
||||
// _graphicsRaycaster = _canvas.gameObject.AddComponent<GraphicRaycaster>();
|
||||
// _camera = PlayerSetup.Instance.activeCam;
|
||||
// _canvas.worldCamera = _camera;
|
||||
// }
|
||||
//
|
||||
// #endregion Unity Events
|
||||
//
|
||||
// #region Public Methods
|
||||
//
|
||||
// public bool GetGraphicsHit(Ray worldRay, out RaycastResult result)
|
||||
// {
|
||||
// result = default;
|
||||
//
|
||||
// if (!IsInteractable || _camera == null) return false;
|
||||
//
|
||||
// // Get the plane of the canvas
|
||||
// Plane canvasPlane = new(transform.forward, transform.position);
|
||||
//
|
||||
// // Find where the ray intersects the canvas plane
|
||||
// if (!canvasPlane.Raycast(worldRay, out float distance))
|
||||
// return false;
|
||||
//
|
||||
// // Get the world point of intersection
|
||||
// Vector3 worldHitPoint = worldRay.origin + worldRay.direction * distance;
|
||||
//
|
||||
// // Check if hit point is within max interaction distance
|
||||
// if (Vector3.Distance(worldRay.origin, worldHitPoint) > MaxInteractDistance)
|
||||
// return false;
|
||||
//
|
||||
// // Check if hit point is within canvas bounds
|
||||
// Vector3 localHitPoint = transform.InverseTransformPoint(worldHitPoint);
|
||||
// Rect canvasRect = _rectTransform.rect;
|
||||
// if (!canvasRect.Contains(new Vector2(localHitPoint.x, localHitPoint.y)))
|
||||
// return false;
|
||||
//
|
||||
// // Convert world hit point to screen space
|
||||
// Vector2 screenPoint = _camera.WorldToScreenPoint(worldHitPoint);
|
||||
//
|
||||
// // Update pointer event data
|
||||
// _pointerEventData.position = screenPoint;
|
||||
// _pointerEventData.delta = Vector2.zero;
|
||||
//
|
||||
// // Clear previous results and perform raycast
|
||||
// _raycastResults.Clear();
|
||||
// _graphicsRaycaster.Raycast(_pointerEventData, _raycastResults);
|
||||
//
|
||||
// // Early out if no hits
|
||||
// if (_raycastResults.Count == 0)
|
||||
// {
|
||||
// //Debug.Log($"No hits on canvas {_canvas.name}");
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // Find first valid interactive UI element
|
||||
// foreach (RaycastResult hit in _raycastResults)
|
||||
// {
|
||||
// if (!hit.isValid)
|
||||
// {
|
||||
// //Debug.Log($"Invalid hit on canvas {_canvas.name}");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// // Check if the hit object has a Selectable component and is interactable
|
||||
// GameObject hitObject = hit.gameObject;
|
||||
// if (!hitObject.TryGetComponent(out _workingSelectable)
|
||||
// || !_workingSelectable.interactable)
|
||||
// {
|
||||
// //Debug.Log($"Non-interactable hit on canvas {_canvas.name} - {hitObject.name}");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// //Debug.Log($"Hit on canvas {_canvas.name} with {hitObject.name}");
|
||||
//
|
||||
// result = hit;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// #endregion Public Methods
|
||||
// }
|
||||
// }
|
||||
1871
.Deprecated/SuperAwesomeMod/Interaction/ControllerRay.cs
Normal file
1871
.Deprecated/SuperAwesomeMod/Interaction/ControllerRay.cs
Normal file
File diff suppressed because it is too large
Load diff
85
.Deprecated/SuperAwesomeMod/Interaction/Input/CustomInput.cs
Normal file
85
.Deprecated/SuperAwesomeMod/Interaction/Input/CustomInput.cs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace NAK.SuperAwesomeMod.Interaction;
|
||||
|
||||
[DefaultExecutionOrder(1000)]
|
||||
public class CustomBaseInput : BaseInput
|
||||
{
|
||||
private Vector2 mousePositionCache;
|
||||
|
||||
#region Input Overrides
|
||||
|
||||
public override Vector2 mousePosition => Input.mousePosition;
|
||||
|
||||
public override bool GetMouseButton(int button)
|
||||
=> button == (int)CVRHand.Right
|
||||
? CVRInputManager.Instance.interactLeftValue > 0.75f
|
||||
: CVRInputManager.Instance.interactRightValue > 0.75f;
|
||||
|
||||
public override bool GetMouseButtonDown(int button)
|
||||
=> button == (int)CVRHand.Right
|
||||
? CVRInputManager.Instance.interactLeftDown
|
||||
: CVRInputManager.Instance.interactRightDown;
|
||||
|
||||
public override Vector2 mouseScrollDelta => Vector2.zero;
|
||||
|
||||
public override float GetAxisRaw(string axisName)
|
||||
{
|
||||
return axisName switch
|
||||
{
|
||||
"Mouse ScrollWheel" => CVRInputManager.Instance.scrollValue,
|
||||
"Horizontal" => CVRInputManager.Instance.movementVector.x,
|
||||
"Vertical" => CVRInputManager.Instance.movementVector.y,
|
||||
_ => 0f
|
||||
};
|
||||
}
|
||||
|
||||
public override bool GetButtonDown(string buttonName)
|
||||
{
|
||||
return buttonName switch
|
||||
{
|
||||
"Mouse ScrollWheel" => CVRInputManager.Instance.scrollValue > 0.1f,
|
||||
"Horizontal" => CVRInputManager.Instance.movementVector.x > 0.5f,
|
||||
"Vertical" => CVRInputManager.Instance.movementVector.y > 0.5f,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
#endregion Input Overrides
|
||||
|
||||
private CVRHand lastInteractHand;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
mousePositionCache = Input.mousePosition;
|
||||
return;
|
||||
}
|
||||
|
||||
ControllerRay leftRay = PlayerSetup.Instance.vrRayLeft;
|
||||
ControllerRay rightRay = PlayerSetup.Instance.vrRayRight;
|
||||
|
||||
if (leftRay._interactDown) lastInteractHand = leftRay.hand;
|
||||
if (rightRay._interactDown) lastInteractHand = rightRay.hand;
|
||||
|
||||
Camera vrCamera = PlayerSetup.Instance.vrCam;
|
||||
|
||||
// transform the raycast position to screen position
|
||||
Vector3 hitPoint = lastInteractHand == CVRHand.Left
|
||||
? leftRay.HitPoint
|
||||
: rightRay.HitPoint;
|
||||
|
||||
Vector3 screenPoint = vrCamera.WorldToScreenPoint(hitPoint);
|
||||
screenPoint.x = Mathf.Clamp(screenPoint.x, 0, Screen.width);
|
||||
screenPoint.y = Mathf.Clamp(screenPoint.y, 0, Screen.height);
|
||||
mousePositionCache = new Vector2(screenPoint.x, screenPoint.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace NAK.SuperAwesomeMod.Interaction;
|
||||
|
||||
public class CustomInputModule : StandaloneInputModule
|
||||
{
|
||||
bool meow = false;
|
||||
|
||||
#region Unity Events
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
m_InputOverride = gameObject.AddComponent<CustomBaseInput>();
|
||||
|
||||
// Disable other event systems in the scene
|
||||
DisableOtherEventSystems();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
CursorLockMode currentLockState = Cursor.lockState;
|
||||
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
|
||||
base.Process();
|
||||
|
||||
Cursor.lockState = currentLockState;
|
||||
}
|
||||
|
||||
protected override MouseState GetMousePointerEventData(int id)
|
||||
{
|
||||
MouseState pointerEventData = base.GetMousePointerEventData(id);
|
||||
MouseButtonEventData leftEventData = pointerEventData.GetButtonState(PointerEventData.InputButton.Left).eventData;
|
||||
RaycastResult pointerRaycast = leftEventData.buttonData.pointerCurrentRaycast;
|
||||
|
||||
if (meow) leftEventData.buttonData.pointerCurrentRaycast = new RaycastResult();
|
||||
|
||||
return pointerEventData;
|
||||
}
|
||||
|
||||
#endregion Overrides
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void DisableOtherEventSystems()
|
||||
{
|
||||
EventSystem thisEventSystem = GetComponent<EventSystem>();
|
||||
EventSystem[] systems = FindObjectsOfType<EventSystem>();
|
||||
foreach (EventSystem system in systems)
|
||||
{
|
||||
if (system.gameObject.name == "UniverseLibCanvas") continue;
|
||||
if (system != thisEventSystem)
|
||||
{
|
||||
system.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
using ABI_RC.Core.InteractionSystem.Base;
|
||||
using ABI_RC.Core.UI;
|
||||
using ABI.CCK.Components;
|
||||
using NAK.SuperAwesomeMod.Components;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
||||
|
|
@ -108,7 +106,8 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
// Check if there are pickups or interactables in immediate proximity
|
||||
if ((flags & RaycastFlags.ProximityInteract) != 0)
|
||||
{
|
||||
ProcessProximityHits(ray, ref result); // TODO: Offset origin to center of palm based on hand type
|
||||
Ray proximityRay = GetProximityRayFromImpl();
|
||||
ProcessProximityHits(proximityRay, ref result);
|
||||
if (result.isProximityHit)
|
||||
return result;
|
||||
}
|
||||
|
|
@ -150,7 +149,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
int proximityHits = Physics.SphereCastNonAlloc(
|
||||
ray.origin,
|
||||
RAYCAST_SPHERE_RADIUS,
|
||||
Vector3.up,
|
||||
ray.direction,
|
||||
_hits,
|
||||
0.001f,
|
||||
_layerMask,
|
||||
|
|
@ -313,6 +312,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
result.hitInteractable = _workingInteractable;
|
||||
hitValidComponent = true;
|
||||
}
|
||||
|
||||
if (_workingGameObject.TryGetComponent(out _workingPickupable)
|
||||
&& _workingPickupable.CanPickup
|
||||
&& IsCVRPickupableWithinRange(_workingPickupable, hit))
|
||||
|
|
@ -343,6 +343,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
#region Protected Methods
|
||||
|
||||
protected abstract Ray GetRayFromImpl();
|
||||
protected abstract Ray GetProximityRayFromImpl();
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
|
|
@ -375,10 +376,10 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
return hit.distance <= pickupable.MaxGrabDistance;
|
||||
}
|
||||
|
||||
private static bool IsCVRCanvasWrapperWithinRange(CVRCanvasWrapper canvasWrapper, RaycastHit hit)
|
||||
{
|
||||
return hit.distance <= canvasWrapper.MaxInteractDistance;
|
||||
}
|
||||
// private static bool IsCVRCanvasWrapperWithinRange(CVRCanvasWrapper canvasWrapper, RaycastHit hit)
|
||||
// {
|
||||
// return hit.distance <= canvasWrapper.MaxInteractDistance;
|
||||
// }
|
||||
|
||||
#endregion Utility Because Original Methods Are Broken
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,24 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
{
|
||||
public class CVRPlayerRaycasterMouse : CVRPlayerRaycaster
|
||||
{
|
||||
private readonly Camera _camera;
|
||||
#region Constructor
|
||||
|
||||
public CVRPlayerRaycasterMouse(Transform rayOrigin, Camera camera) : base(rayOrigin) { _camera = camera; }
|
||||
|
||||
private readonly Camera _camera;
|
||||
|
||||
#endregion Constructor
|
||||
|
||||
#region Overrides
|
||||
|
||||
protected override Ray GetRayFromImpl() => Cursor.lockState == CursorLockMode.Locked
|
||||
? new Ray(_camera.transform.position, _camera.transform.forward)
|
||||
: _camera.ScreenPointToRay(Input.mousePosition);
|
||||
|
||||
protected override Ray GetProximityRayFromImpl() => Cursor.lockState == CursorLockMode.Locked
|
||||
? new Ray(_camera.transform.position, _camera.transform.forward)
|
||||
: _camera.ScreenPointToRay(Input.mousePosition);
|
||||
|
||||
#endregion Overrides
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,44 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
{
|
||||
public class CVRPlayerRaycasterTransform : CVRPlayerRaycaster
|
||||
{
|
||||
public CVRPlayerRaycasterTransform(Transform rayOrigin) : base(rayOrigin) { }
|
||||
#region Proximity Grab
|
||||
|
||||
public const float ProximityGrabRadiusScaleDefault = 0.1f;
|
||||
private float _proximityDetectionRadiusRelativeValue = ProximityGrabRadiusScaleDefault;
|
||||
private float ProximityDetectionRadius => _proximityDetectionRadiusRelativeValue * PlayerSetup.Instance.GetPlaySpaceScale();
|
||||
|
||||
#endregion Proximity Grab
|
||||
|
||||
#region Constructor
|
||||
|
||||
public CVRPlayerRaycasterTransform(Transform rayOrigin, CVRHand hand) : base(rayOrigin) { _hand = hand; }
|
||||
|
||||
private readonly CVRHand _hand;
|
||||
|
||||
#endregion Constructor
|
||||
|
||||
#region Overrides
|
||||
|
||||
protected override Ray GetRayFromImpl() => new(_rayOrigin.position, _rayOrigin.forward);
|
||||
|
||||
protected override Ray GetProximityRayFromImpl()
|
||||
{
|
||||
Vector3 handPosition = _rayOrigin.position;
|
||||
Vector3 handRight = _rayOrigin.right;
|
||||
|
||||
// Offset the detection center forward, so we don't grab stuff behind our writs
|
||||
handPosition += _rayOrigin.forward * (ProximityDetectionRadius * 0.25f);
|
||||
|
||||
// Offset the detection center away from the palm, so we don't grab stuff behind our hand palm
|
||||
Vector3 palmOffset = handRight * (ProximityDetectionRadius * 0.75f);
|
||||
if (_hand == CVRHand.Left)
|
||||
handPosition += palmOffset;
|
||||
else
|
||||
handPosition -= palmOffset;
|
||||
|
||||
return new Ray(handPosition, _hand == CVRHand.Left ? handRight : -handRight);
|
||||
}
|
||||
|
||||
#endregion Overrides
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
using ABI_RC.Core.InteractionSystem.Base;
|
||||
using ABI_RC.Core.UI;
|
||||
using NAK.SuperAwesomeMod.Components;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
||||
|
|
@ -19,6 +17,7 @@ namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
|||
// Main raycast hit info
|
||||
public RaycastHit hit;
|
||||
public RaycastHit? waterHit; // Only valid if hitWater is true
|
||||
public Vector2 hitScreenPoint; // Screen coordinates of the hit
|
||||
|
||||
// Specific hit components
|
||||
public Pickupable hitPickupable;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ABI_RC.Core.Player.Interaction.RaycastImpl
|
||||
|
|
|
|||
|
|
@ -0,0 +1,362 @@
|
|||
using ABI_RC.Core.Base;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI.CCK.Components;
|
||||
using MelonLoader;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace NAK.SuperAwesomeMod.UExplorer;
|
||||
|
||||
public class UEMenuHelper : MenuPositionHelperBase
|
||||
{
|
||||
#region Singleton
|
||||
|
||||
public static void Create()
|
||||
{
|
||||
if (Instance != null)
|
||||
return;
|
||||
|
||||
_universeLibCanvas = GameObject.Find("UniverseLibCanvas");
|
||||
if (_universeLibCanvas == null)
|
||||
{
|
||||
MelonLogger.Error(
|
||||
"Failed to create UniverseLibCanvas"); // TODO: mod logger, casue https://github.com/knah/VRCMods/pull/227
|
||||
return;
|
||||
}
|
||||
|
||||
_explorerRoot = _universeLibCanvas.transform.Find("com.sinai.unityexplorer_Root").gameObject;
|
||||
|
||||
// Fix the canvas so it renders in the UI camera
|
||||
// _universeLibCanvas.SetLayerRecursive(CVRLayers.UIInternal);
|
||||
|
||||
Transform menuParent = new GameObject("UEMenuParent").transform;
|
||||
menuParent.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
menuParent.localScale = Vector3.one;
|
||||
|
||||
DontDestroyOnLoad(menuParent.gameObject);
|
||||
|
||||
Transform offsetTransform = new GameObject("UEMenuOffset").transform;
|
||||
offsetTransform.SetParent(menuParent, false);
|
||||
offsetTransform.localScale = Vector3.one;
|
||||
|
||||
Transform contentTransform = new GameObject("UEMenuContent").transform;
|
||||
contentTransform.SetParent(offsetTransform, false);
|
||||
contentTransform.localScale = Vector3.one;
|
||||
|
||||
Instance = menuParent.AddComponentIfMissing<UEMenuHelper>();
|
||||
Instance.menuTransform = contentTransform;
|
||||
// Instance._offsetTransform = offsetTransform; // Got in MenuPositionHelperBase.Start
|
||||
|
||||
// Apply the component filters done in worlds
|
||||
// foreach (Component c in _universeLibCanvas.GetComponentsInChildren<Component>(true))
|
||||
// SetupCollidersOnUnityUi(c);
|
||||
|
||||
CVRCanvasWrapper.AddForCanvas(_universeLibCanvas.GetComponent<Canvas>(), true);
|
||||
|
||||
Instance.ConfigureUECanvasRenderMode(RenderMode.WorldSpace);
|
||||
}
|
||||
|
||||
public static UEMenuHelper Instance { get; private set; }
|
||||
|
||||
private static GameObject _universeLibCanvas;
|
||||
private static GameObject _explorerRoot;
|
||||
private static RenderMode _currentRenderMode = RenderMode.WorldSpace;
|
||||
|
||||
#endregion Singleton
|
||||
|
||||
#region Overrides
|
||||
|
||||
public override bool IsMenuOpen => _explorerRoot.activeInHierarchy;
|
||||
|
||||
public override float MenuScaleModifier => !MetaPort.Instance.isUsingVr ? 1f : 0.3f;
|
||||
public override float MenuDistanceModifier => !MetaPort.Instance.isUsingVr ? 1.2f : 1f;
|
||||
|
||||
#endregion Overrides
|
||||
|
||||
#region Unity Events
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.F9))
|
||||
ToggleUeCanvasRenderMode();
|
||||
}
|
||||
|
||||
#endregion Unity Events
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void ToggleUeCanvasRenderMode()
|
||||
{
|
||||
ConfigureUECanvasRenderMode(_currentRenderMode == RenderMode.WorldSpace
|
||||
? RenderMode.ScreenSpaceOverlay
|
||||
: RenderMode.WorldSpace);
|
||||
}
|
||||
|
||||
private void ConfigureUECanvasRenderMode(RenderMode targetMode)
|
||||
{
|
||||
_currentRenderMode = targetMode;
|
||||
var canvases = _universeLibCanvas.GetComponentsInChildren<Canvas>(true);
|
||||
|
||||
if (targetMode == RenderMode.WorldSpace)
|
||||
{
|
||||
foreach (Canvas canvas in canvases)
|
||||
{
|
||||
canvas.renderMode = RenderMode.WorldSpace;
|
||||
canvas.worldCamera = PlayerSetup.Instance.activeCam;
|
||||
}
|
||||
|
||||
_universeLibCanvas.transform.SetParent(menuTransform, false);
|
||||
_universeLibCanvas.transform.localScale = Vector3.one * 0.0032f;
|
||||
|
||||
// Center the canvas on the menuTransform
|
||||
CenterCanvasOnMenuTransform(_universeLibCanvas, menuTransform);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Canvas canvas in canvases)
|
||||
{
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
canvas.worldCamera = null;
|
||||
}
|
||||
|
||||
_universeLibCanvas.transform.SetParent(null, false);
|
||||
_universeLibCanvas.transform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
private void CenterCanvasOnMenuTransform(GameObject canvasRoot, Transform parentTransform)
|
||||
{
|
||||
// Find all the rectTransforms under the canvas, determine their bounds, and center the canvas local position
|
||||
// on the menuTransform
|
||||
|
||||
RectTransform canvasTransform = _explorerRoot.transform as RectTransform;
|
||||
|
||||
// get the extents of the rectTransform
|
||||
Vector3[] corners = new Vector3[4];
|
||||
canvasTransform.GetWorldCorners(corners);
|
||||
|
||||
// now center by offsettings its localPosition
|
||||
Vector3 center = (corners[0] + corners[2]) / 2f;
|
||||
Vector3 extents = (corners[2] - corners[0]) / 2f;
|
||||
Vector3 offset = center - extents;
|
||||
offset.z = 0f; // set z to 0 to avoid depth issues
|
||||
canvasTransform.localPosition = offset;
|
||||
MelonLogger.Msg($"Centered canvas on menuTransform: {canvasTransform.localPosition}");
|
||||
}
|
||||
|
||||
private static bool IsFloatValid(float val)
|
||||
=> (!float.IsNaN(val) && !float.IsInfinity(val));
|
||||
|
||||
private static void SetupCollidersOnUnityUi(Component c)
|
||||
{
|
||||
GameObject go = c.gameObject;
|
||||
|
||||
if (c is Button)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
col.isTrigger = true;
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
|
||||
0.05f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.05f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.05f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.05f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (c is Toggle)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
col.isTrigger = true;
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(Mathf.Max(rectTransform.sizeDelta.x, rectTransform.rect.width),
|
||||
rectTransform.sizeDelta.y, 0.05f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.05f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.05f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.05f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
|
||||
//Check Child if Size = 0
|
||||
if (col.size.x + col.size.y == 0f && go.transform.childCount > 0)
|
||||
{
|
||||
var childRectTransform = go.transform.GetChild(0).GetComponent<RectTransform>();
|
||||
if (childRectTransform != null)
|
||||
{
|
||||
newSize = new Vector3(
|
||||
Mathf.Max(childRectTransform.sizeDelta.x, rectTransform.rect.width),
|
||||
childRectTransform.sizeDelta.y, 0.1f);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.05f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.05f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.05f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c is Slider)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
|
||||
0.05f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.05f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.05f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.05f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
}
|
||||
|
||||
col.isTrigger = true;
|
||||
}
|
||||
|
||||
if (c is EventTrigger)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
|
||||
0.025f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.05f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.05f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.05f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
}
|
||||
|
||||
col.isTrigger = true;
|
||||
}
|
||||
|
||||
if (c is InputField || c is TMP_InputField)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
col.isTrigger = true;
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
|
||||
0.05f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.05f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.05f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.05f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (c is ScrollRect)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
col.isTrigger = true;
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
|
||||
0.025f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.025f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.025f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.025f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (c is Dropdown)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
col.isTrigger = true;
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
|
||||
0.05f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.05f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.05f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.05f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
}
|
||||
}
|
||||
|
||||
//Canvas
|
||||
if (c is Canvas)
|
||||
{
|
||||
BoxCollider col = go.AddComponentIfMissing<BoxCollider>();
|
||||
|
||||
var rectTransform = go.GetComponent<RectTransform>();
|
||||
if (rectTransform)
|
||||
{
|
||||
Vector3 newSize = new Vector3(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y,
|
||||
0.0125f / rectTransform.lossyScale.z);
|
||||
if (!IsFloatValid(newSize.x))
|
||||
newSize.x = 0.0125f;
|
||||
if (!IsFloatValid(newSize.y))
|
||||
newSize.y = 0.0125f;
|
||||
if (!IsFloatValid(newSize.z))
|
||||
newSize.z = 0.0125f;
|
||||
col.size = newSize;
|
||||
|
||||
col.center = new Vector3(col.size.x * (0.5f - rectTransform.pivot.x),
|
||||
col.size.y * (0.5f - rectTransform.pivot.y), 0f);
|
||||
}
|
||||
|
||||
col.isTrigger = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
|
|
@ -1,15 +1,14 @@
|
|||
using System.Reflection;
|
||||
using ABI_RC.Core.Base;
|
||||
using ABI_RC.Core.Base.Jobs;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Player.Interaction.RaycastImpl;
|
||||
using ABI_RC.Core.Util.AssetFiltering;
|
||||
using ABI.CCK.Components;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using NAK.SuperAwesomeMod.Components;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace NAK.SuperAwesomeMod;
|
||||
|
||||
|
|
@ -33,13 +32,13 @@ public class SuperAwesomeModMod : MelonMod
|
|||
BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
|
||||
// patch SharedFilter.ProcessCanvas
|
||||
HarmonyInstance.Patch(
|
||||
typeof(SharedFilter).GetMethod(nameof(SharedFilter.ProcessCanvas),
|
||||
BindingFlags.Public | BindingFlags.Static),
|
||||
postfix: new HarmonyMethod(typeof(SuperAwesomeModMod).GetMethod(nameof(OnProcessCanvas),
|
||||
BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
// // patch SharedFilter.ProcessCanvas
|
||||
// HarmonyInstance.Patch(
|
||||
// typeof(SharedFilter).GetMethod(nameof(SharedFilter.ProcessCanvas),
|
||||
// BindingFlags.Public | BindingFlags.Static),
|
||||
// postfix: new HarmonyMethod(typeof(SuperAwesomeModMod).GetMethod(nameof(OnProcessCanvas),
|
||||
// BindingFlags.NonPublic | BindingFlags.Static))
|
||||
// );
|
||||
|
||||
LoggerInstance.Msg("SuperAwesomeModMod! OnInitializeMelon! :D");
|
||||
}
|
||||
|
|
@ -53,29 +52,43 @@ public class SuperAwesomeModMod : MelonMod
|
|||
|
||||
private static void OnPlayerSetupStart()
|
||||
{
|
||||
CVRRaycastDebugManager.Initialize(PlayerSetup.Instance.desktopCam);
|
||||
// CVRRaycastDebugManager.Initialize(PlayerSetup.Instance.desktopCam);
|
||||
// UEMenuHelper.Create();
|
||||
}
|
||||
|
||||
private static void OnShitLoaded(Component c, List<Task> asyncTasks = null, Scene? scene = null)
|
||||
{
|
||||
if (c == null)
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
if (c.gameObject == null)
|
||||
if (!c.gameObject)
|
||||
return;
|
||||
|
||||
if (c.gameObject.scene.buildIndex > 0)
|
||||
return;
|
||||
|
||||
if ((scene != null)
|
||||
&& (c.gameObject.scene != scene))
|
||||
if ((scene != null) && (c.gameObject.scene != scene))
|
||||
return;
|
||||
|
||||
if (c is Canvas canvas) canvas.gameObject.AddComponent<CVRCanvasWrapper>();
|
||||
|
||||
if (c is InputField input)
|
||||
{
|
||||
input.AddComponentIfMissing<InputFocusIntentDetector>();
|
||||
}
|
||||
|
||||
if (c is TMPro.TMP_InputField tmpInput)
|
||||
{
|
||||
tmpInput.AddComponentIfMissing<InputFocusIntentDetector>();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnProcessCanvas(string collectionId, Canvas canvas)
|
||||
public class InputFocusIntentDetector : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
canvas.gameObject.AddComponent<CVRCanvasWrapper>();
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (TryGetComponent(out TMPro.TMP_InputField input) && input.isActiveAndEnabled)
|
||||
ViewManager.Instance.openMenuKeyboard(input);
|
||||
else if (TryGetComponent(out InputField inputField) && inputField.isActiveAndEnabled)
|
||||
ViewManager.Instance.openMenuKeyboard(inputField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>ASTExtension</RootNamespace>
|
||||
<RootNamespace>SuperAwesomeMod</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BTKUILib">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk" />
|
||||
89
.Experimental/ByeByePerformanceThankYouAMD/Main.cs
Normal file
89
.Experimental/ByeByePerformanceThankYouAMD/Main.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
using System.Collections;
|
||||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.IO;
|
||||
using ABI_RC.Core.Util.Encryption;
|
||||
using ABI_RC.Systems.GameEventSystem;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.ByeByePerformanceThankYouAMD;
|
||||
|
||||
public class ByeByePerformanceThankYouAMDMod : MelonMod
|
||||
{
|
||||
private static MelonLogger.Instance Logger;
|
||||
|
||||
private static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(nameof(ByeByePerformanceThankYouAMD));
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryDisableMaterialInstancing =
|
||||
Category.CreateEntry(
|
||||
identifier: "disable_material_instancing",
|
||||
true,
|
||||
display_name: "Disable Material Instancing",
|
||||
description: "Disables material instancing to mitigate a shit visual issue on AMD");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
Logger = LoggerInstance;
|
||||
ApplyPatches(typeof(CVREncryptionRouter_Patches));
|
||||
}
|
||||
|
||||
private void ApplyPatches(Type type)
|
||||
{
|
||||
try
|
||||
{
|
||||
HarmonyInstance.PatchAll(type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LoggerInstance.Msg($"Failed while patching {type.Name}!");
|
||||
LoggerInstance.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ScanForInstancedMaterials()
|
||||
{
|
||||
if (!EntryDisableMaterialInstancing.Value)
|
||||
return;
|
||||
|
||||
Logger.Msg("An Asset Bundle has loaded, scanning for instanced materials to disable...");
|
||||
|
||||
if (Resources.FindObjectsOfTypeAll(typeof(Material)) is not Material[] allMaterials)
|
||||
{
|
||||
Logger.Msg("No materials found.");
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
foreach (Material material in allMaterials)
|
||||
{
|
||||
if (!material || !material.enableInstancing) continue;
|
||||
material.enableInstancing = false;
|
||||
count++;
|
||||
}
|
||||
|
||||
Logger.Msg($"Finished scanning for instanced materials. Disabled instancing on {count} loaded materials.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CVREncryptionRouter_Patches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CVREncryptionRouter), nameof(CVREncryptionRouter.LoadEncryptedBundle), typeof(bool))]
|
||||
private static void CVREncryptionRouter_LoadEncryptedBundle_Postfix(ref IEnumerator __result)
|
||||
{
|
||||
__result = Wrapper(__result);
|
||||
}
|
||||
|
||||
private static IEnumerator Wrapper(IEnumerator inner)
|
||||
{
|
||||
yield return null; // before start
|
||||
|
||||
while (inner.MoveNext())
|
||||
yield return inner.Current;
|
||||
|
||||
// after finish
|
||||
ByeByePerformanceThankYouAMDMod.ScanForInstancedMaterials();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.ByeByePerformanceThankYouAMD.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.ByeByePerformanceThankYouAMD))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.ByeByePerformanceThankYouAMD))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.ByeByePerformanceThankYouAMD.ByeByePerformanceThankYouAMDMod),
|
||||
nameof(NAK.ByeByePerformanceThankYouAMD),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/ByeByePerformanceThankYouAMD"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.ByeByePerformanceThankYouAMD.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
14
.Experimental/ByeByePerformanceThankYouAMD/README.md
Normal file
14
.Experimental/ByeByePerformanceThankYouAMD/README.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# SearchWithSpacesFix
|
||||
|
||||
Fixes search terms that use spaces.
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
23
.Experimental/ByeByePerformanceThankYouAMD/format.json
Normal file
23
.Experimental/ByeByePerformanceThankYouAMD/format.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "SearchWithSpacesFix",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2024r177",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Fixes search terms that include spaces.",
|
||||
"searchtags": [
|
||||
"search",
|
||||
"spaces",
|
||||
"fix",
|
||||
"meow"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r42/SearchWithSpacesFix.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/SearchWithSpacesFix/",
|
||||
"changelog": "- Initial release",
|
||||
"embedcolor": "#f61963"
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Text;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.UI;
|
||||
using ABI.CCK.Components;
|
||||
using ABI.CCK.Components.ScriptableObjects;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using ABI.CCK.Components;
|
|||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using NAK.CVRLuaToolsExtension.NamedPipes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.CVRLuaToolsExtension;
|
||||
|
||||
|
|
|
|||
103
.Experimental/DummyMenu/Components/DummyMenuManager.cs
Normal file
103
.Experimental/DummyMenu/Components/DummyMenuManager.cs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
using ABI_RC.Core.UI.UIRework;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.DummyMenu;
|
||||
|
||||
public class DummyMenuManager : CVRUIManagerBaseInput
|
||||
{
|
||||
#region Boilerplate
|
||||
|
||||
public static DummyMenuManager Instance { get; private set; }
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
if (Instance && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
base.Start();
|
||||
|
||||
ListenForModSettingChanges();
|
||||
}
|
||||
|
||||
public override void ReloadView()
|
||||
{
|
||||
if (IsViewShown && !ModSettings.EntryReloadMenuEvenWhenOpen.Value) return;
|
||||
TrySetMenuPage();
|
||||
base.ReloadView();
|
||||
}
|
||||
|
||||
public override void OnFinishedLoad(string _)
|
||||
{
|
||||
base.OnFinishedLoad(_);
|
||||
|
||||
// Usually done in OnReadyForBindings, but that isn't called for my menu :)
|
||||
_cohtmlRenderMaterial = _uiRenderer.sharedMaterial;
|
||||
// ReSharper disable thrice Unity.PreferAddressByIdToGraphicsParams
|
||||
_cohtmlRenderMaterial.SetTexture("_DesolvePattern", pattern);
|
||||
_cohtmlRenderMaterial.SetTexture("_DesolveTiming", timing);
|
||||
_cohtmlRenderMaterial.SetTextureScale("_DesolvePattern", new Vector2(16, 9));
|
||||
}
|
||||
|
||||
public void ToggleView()
|
||||
{
|
||||
bool invertShown = !IsViewShown;
|
||||
ToggleView(invertShown);
|
||||
CursorLockManager.Instance.SetUnlockWithId(invertShown, nameof(DummyMenuManager));
|
||||
}
|
||||
|
||||
#endregion Boilerplate
|
||||
|
||||
private void ListenForModSettingChanges()
|
||||
{
|
||||
ModSettings.EntryPageCouiPath.OnEntryValueChanged.Subscribe((oldValue, newValue) =>
|
||||
{
|
||||
DummyMenuMod.Logger.Msg($"Changing COUI page from {oldValue} to {newValue}");
|
||||
cohtmlView.Page = newValue;
|
||||
});
|
||||
|
||||
ModSettings.EntryPageWidth.OnEntryValueChanged.Subscribe((oldValue, newValue) =>
|
||||
{
|
||||
DummyMenuMod.Logger.Msg($"Changing COUI width from {oldValue} to {newValue}");
|
||||
cohtmlView.Width = newValue;
|
||||
DummyMenuPositionHelper.Instance.UpdateAspectRatio(cohtmlView.Width, cohtmlView.Height);
|
||||
});
|
||||
|
||||
ModSettings.EntryPageHeight.OnEntryValueChanged.Subscribe((oldValue, newValue) =>
|
||||
{
|
||||
DummyMenuMod.Logger.Msg($"Changing COUI height from {oldValue} to {newValue}");
|
||||
cohtmlView.Height = newValue;
|
||||
DummyMenuPositionHelper.Instance.UpdateAspectRatio(cohtmlView.Width, cohtmlView.Height);
|
||||
});
|
||||
|
||||
ModSettings.EntryToggleMeToResetModifiers.OnEntryValueChanged.Subscribe((_, newValue) =>
|
||||
{
|
||||
if (!newValue) return;
|
||||
DummyMenuMod.Logger.Msg("Resetting modifiers to default because the toggle was enabled");
|
||||
ModSettings.EntryToggleMeToResetModifiers.Value = false;
|
||||
ModSettings.EntryDesktopMenuScaleModifier.ResetToDefault();
|
||||
ModSettings.EntryDesktopMenuDistanceModifier.ResetToDefault();
|
||||
ModSettings.EntryVrMenuScaleModifier.ResetToDefault();
|
||||
ModSettings.EntryVrMenuDistanceModifier.ResetToDefault();
|
||||
});
|
||||
}
|
||||
|
||||
public void TrySetMenuPage()
|
||||
{
|
||||
string couiPath = ModSettings.EntryPageCouiPath.Value;
|
||||
string fullCouiPath = CreateDummyMenu.GetFullCouiPath(couiPath);
|
||||
if (File.Exists(fullCouiPath))
|
||||
{
|
||||
DummyMenuMod.Logger.Msg($"Found COUI page at {fullCouiPath}. Setting it as the controlledview page.");
|
||||
cohtmlView.Page = "coui://" + couiPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
DummyMenuMod.Logger.Error($"No COUI page found at {fullCouiPath}. Please create one at that path, or change the mod setting to point to an existing file. Using default example page instead.");
|
||||
cohtmlView.Page = "coui://" + CreateDummyMenu.ExampleDummyMenuPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Savior;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.DummyMenu;
|
||||
|
||||
[DefaultExecutionOrder(16000)] // just before ControllerRay
|
||||
public class DummyMenuPositionHelper : MenuPositionHelperBase
|
||||
{
|
||||
public static DummyMenuPositionHelper Instance { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance && Instance != this)
|
||||
{
|
||||
Destroy(this);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public override bool IsMenuOpen => DummyMenuManager.Instance.IsViewShown;
|
||||
public override float MenuScaleModifier => MetaPort.Instance.isUsingVr ? ModSettings.EntryVrMenuScaleModifier.Value : ModSettings.EntryDesktopMenuScaleModifier.Value;
|
||||
public override float MenuDistanceModifier => MetaPort.Instance.isUsingVr ? ModSettings.EntryVrMenuDistanceModifier.Value : ModSettings.EntryDesktopMenuDistanceModifier.Value;
|
||||
|
||||
public void UpdateAspectRatio(float width, float height)
|
||||
{
|
||||
if (width <= 0f || height <= 0f)
|
||||
return;
|
||||
|
||||
_menuAspectRatio = width / height;
|
||||
|
||||
float normalizedWidth = width / Mathf.Max(width, height);
|
||||
float normalizedHeight = height / Mathf.Max(width, height);
|
||||
menuTransform.localScale = new Vector3(normalizedWidth, normalizedHeight, 1f);
|
||||
}
|
||||
}
|
||||
243
.Experimental/DummyMenu/CreateDummyMenu.cs
Normal file
243
.Experimental/DummyMenu/CreateDummyMenu.cs
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.DummyMenu;
|
||||
|
||||
public static class CreateDummyMenu
|
||||
{
|
||||
public static void Create()
|
||||
{
|
||||
CreateDefaultExamplePageIfNeeded();
|
||||
|
||||
GameObject cohtmlRootObject = GameObject.Find("Cohtml");
|
||||
|
||||
// Create menu rig
|
||||
// Cohtml -> Root -> Offset -> Menu
|
||||
GameObject dummyMenuRoot = new("DummyMenuRoot");
|
||||
GameObject dummyMenuOffset = new("DummyMenuOffset");
|
||||
GameObject dummyMenuItself = new("DummyMenu");
|
||||
dummyMenuItself.transform.SetParent(dummyMenuOffset.transform);
|
||||
dummyMenuOffset.transform.SetParent(dummyMenuRoot.transform);
|
||||
dummyMenuRoot.transform.SetParent(cohtmlRootObject.transform);
|
||||
|
||||
// Add dummy menu position helper
|
||||
DummyMenuPositionHelper positionHelper = dummyMenuRoot.AddComponent<DummyMenuPositionHelper>();
|
||||
positionHelper._offsetTransform = dummyMenuOffset.transform;
|
||||
positionHelper.menuTransform = dummyMenuItself.transform;
|
||||
|
||||
// Add components to menu (MeshFilter, MeshRenderer, Animator, CohtmlControlledView)
|
||||
MeshFilter meshFilter = dummyMenuItself.AddComponent<MeshFilter>();
|
||||
MeshRenderer meshRenderer = dummyMenuItself.AddComponent<MeshRenderer>();
|
||||
Animator animator = dummyMenuItself.AddComponent<Animator>();
|
||||
CohtmlControlledView controlledView = dummyMenuItself.AddComponent<CohtmlControlledView>();
|
||||
|
||||
// Add dummy menu manager
|
||||
DummyMenuManager menuManager = dummyMenuItself.AddComponent<DummyMenuManager>();
|
||||
menuManager.cohtmlView = controlledView;
|
||||
menuManager._viewAnimator = animator;
|
||||
menuManager._uiRenderer = meshRenderer;
|
||||
|
||||
// Steal from main menu
|
||||
menuManager.pattern = ViewManager.Instance.pattern;
|
||||
menuManager.timing = ViewManager.Instance.timing;
|
||||
meshFilter.mesh = ViewManager.Instance.GetComponent<MeshFilter>().sharedMesh;
|
||||
meshRenderer.sharedMaterial = null; // assign empty material
|
||||
animator.runtimeAnimatorController = ViewManager.Instance.GetComponent<Animator>().runtimeAnimatorController;
|
||||
|
||||
// Put everything on UI Internal layer
|
||||
dummyMenuRoot.SetLayerRecursive(CVRLayers.UIInternal);
|
||||
|
||||
// Apply initial settings
|
||||
menuManager.TrySetMenuPage();
|
||||
|
||||
float pageWidth = ModSettings.EntryPageWidth.Value;
|
||||
float pageHeight = ModSettings.EntryPageHeight.Value;
|
||||
positionHelper.UpdateAspectRatio(pageWidth, pageHeight);
|
||||
}
|
||||
|
||||
internal const string ExampleDummyMenuPath = "UIResources/DummyMenu/_example.html";
|
||||
internal static string GetFullCouiPath(string couiPath) => Path.Combine(Application.streamingAssetsPath, "Cohtml", couiPath);
|
||||
|
||||
private static void CreateDefaultExamplePageIfNeeded()
|
||||
{
|
||||
// Check if there is a file at our default path
|
||||
string fullPath = GetFullCouiPath(ExampleDummyMenuPath);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
DummyMenuMod.Logger.Msg($"Dummy menu HTML file already exists at {fullPath}. No need to create a new one.");
|
||||
return;
|
||||
}
|
||||
DummyMenuMod.Logger.Msg($"No dummy menu HTML file found at {fullPath}. Creating a default one.");
|
||||
|
||||
// Create the directory if it doesn't exist
|
||||
string directory = Path.GetDirectoryName(fullPath);
|
||||
if (!Directory.Exists(directory)) Directory.CreateDirectory(directory!);
|
||||
|
||||
// Create a default HTML file
|
||||
using StreamWriter writer = new(fullPath, false);
|
||||
writer.Write(DefaultHtmlContent);
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
DummyMenuMod.Logger.Msg($"Created default dummy menu HTML file at {fullPath}. You can now open the dummy menu in-game.");
|
||||
}
|
||||
|
||||
#region Default HTML Content
|
||||
|
||||
private const string DefaultHtmlContent = """
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Cohtml Bubble Pop — 1280×720</title>
|
||||
<style>
|
||||
html,body {
|
||||
height:100%; margin:0;
|
||||
background:#061018;
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
font-family:Arial,Helvetica,sans-serif;
|
||||
}
|
||||
#stage {
|
||||
width:1280px; height:720px;
|
||||
position:relative; overflow:hidden;
|
||||
border-radius:20px;
|
||||
border:6px solid rgba(0,255,255,0.12);
|
||||
box-shadow:0 20px 60px rgba(0,0,0,0.7), inset 0 0 80px rgba(0,255,255,0.03);
|
||||
background:linear-gradient(135deg,#03121a 0%,#071826 60%);
|
||||
-webkit-user-select:none; user-select:none;
|
||||
}
|
||||
.panel {
|
||||
position:absolute; left:50%; top:50%;
|
||||
transform:translate(-50%,-50%);
|
||||
text-align:center; color:#dff9ff;
|
||||
pointer-events:none;
|
||||
z-index:10;
|
||||
}
|
||||
.title {
|
||||
font-size:56px; font-weight:700; letter-spacing:1px;
|
||||
margin:0; text-shadow:0 6px 30px rgba(0,255,255,0.06);
|
||||
}
|
||||
.subtitle { font-size:20px; opacity:0.85; margin-top:6px; }
|
||||
/* bubbles */
|
||||
.bubble {
|
||||
position:absolute; border-radius:50%;
|
||||
pointer-events:auto;
|
||||
will-change:transform,opacity;
|
||||
box-shadow:0 6px 40px rgba(0,255,255,0.12),
|
||||
inset 0 -8px 30px rgba(255,255,255,0.02);
|
||||
display:block; transform-origin:center center;
|
||||
}
|
||||
.pop-anim { animation:pop .28s ease forwards }
|
||||
@keyframes pop {
|
||||
0%{transform:scale(1)}
|
||||
50%{transform:scale(1.25)}
|
||||
100%{transform:scale(0);opacity:0}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="stage" role="application" aria-label="Bubble pop scene">
|
||||
<div class="panel">
|
||||
<h1 class="title">Hello World</h1>
|
||||
<div class="subtitle">Bubble pop — Gameface fixed</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
const stage = document.getElementById('stage');
|
||||
const bubbles = new Set();
|
||||
let lastTime = performance.now();
|
||||
|
||||
function rand(min,max){ return Math.random()*(max-min)+min; }
|
||||
|
||||
function createBubbleAt(x){
|
||||
const rect = stage.getBoundingClientRect();
|
||||
const size = Math.round(rand(28,110));
|
||||
const b = document.createElement('div');
|
||||
b.className='bubble';
|
||||
b.style.width = size + 'px';
|
||||
b.style.height = size + 'px';
|
||||
const left = Math.max(0, Math.min(rect.width - size, x - size/2));
|
||||
b.dataset.x = left;
|
||||
b.dataset.y = rect.height + size;
|
||||
b.style.left = left + 'px';
|
||||
b.style.top = rect.height + 'px';
|
||||
b.style.background =
|
||||
'radial-gradient(circle at 30% 25%, rgba(255,255,255,0.9), rgba(255,255,255,0.25) 10%, rgba(0,200,230,0.18) 40%, rgba(0,40,60,0.06) 100%)';
|
||||
b.style.border = '1px solid rgba(255,255,255,0.08)';
|
||||
b.style.opacity = '0';
|
||||
b._vy = -rand(20,120);
|
||||
b._vx = rand(-40,40);
|
||||
b._rot = rand(-120,120);
|
||||
b._life = 0;
|
||||
b._size = size;
|
||||
b._ttl = rand(4200,12000);
|
||||
b._popped = false;
|
||||
|
||||
b.addEventListener('pointerdown', (e)=>{
|
||||
e.stopPropagation();
|
||||
popBubble(b);
|
||||
});
|
||||
|
||||
stage.appendChild(b);
|
||||
bubbles.add(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
function popBubble(b){
|
||||
if(!b || b._popped) return;
|
||||
b._popped = true;
|
||||
b.classList.add('pop-anim');
|
||||
setTimeout(()=>{ try{ b.remove(); }catch{} bubbles.delete(b); },300);
|
||||
}
|
||||
|
||||
let autoInterval = setInterval(()=>{
|
||||
const rect = stage.getBoundingClientRect();
|
||||
createBubbleAt(rand(40, rect.width - 40));
|
||||
}, 420);
|
||||
|
||||
stage.addEventListener('pointerdown', (e)=>{
|
||||
if(e.target.classList.contains('bubble')) return;
|
||||
const rect = stage.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
createBubbleAt(x);
|
||||
});
|
||||
|
||||
function animate(now){
|
||||
const dt = Math.min(80, now - lastTime);
|
||||
lastTime = now;
|
||||
const rect = stage.getBoundingClientRect();
|
||||
for(const b of Array.from(bubbles)){
|
||||
if(b._popped) continue;
|
||||
b._life += dt;
|
||||
const nx = parseFloat(b.dataset.x) + b._vx * (dt/1000);
|
||||
const ny = parseFloat(b.dataset.y) + b._vy * (dt/1000);
|
||||
b.dataset.x = nx; b.dataset.y = ny;
|
||||
const rot = (b._rot * (b._life/1000));
|
||||
b.style.transform = `rotate(${rot}deg)`;
|
||||
b.style.left = nx + 'px'; b.style.top = ny + 'px';
|
||||
const ttl = b._ttl;
|
||||
if(b._life > ttl){
|
||||
const over = (b._life - ttl)/1000;
|
||||
b.style.opacity = Math.max(0, 1 - over*2);
|
||||
}else{
|
||||
b.style.opacity = Math.min(1, b._life / 200);
|
||||
}
|
||||
if(ny + b._size < -150 || parseFloat(b.style.opacity) <= 0.01){
|
||||
try{ b.remove(); }catch{} bubbles.delete(b);
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
""";
|
||||
|
||||
#endregion Default HTML Content
|
||||
}
|
||||
6
.Experimental/DummyMenu/DummyMenu.csproj
Normal file
6
.Experimental/DummyMenu/DummyMenu.csproj
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>YouAreMineNow</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
21
.Experimental/DummyMenu/Main.cs
Normal file
21
.Experimental/DummyMenu/Main.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using ABI_RC.Systems.GameEventSystem;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.DummyMenu;
|
||||
|
||||
public class DummyMenuMod : MelonMod
|
||||
{
|
||||
internal static MelonLogger.Instance Logger;
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
Logger = LoggerInstance;
|
||||
CVRGameEventSystem.Initialization.OnPlayerSetupStart.AddListener(CreateDummyMenu.Create);
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
if (Input.GetKeyDown(ModSettings.EntryToggleDummyMenu.Value)) DummyMenuManager.Instance.ToggleView();
|
||||
}
|
||||
}
|
||||
64
.Experimental/DummyMenu/ModSettings.cs
Normal file
64
.Experimental/DummyMenu/ModSettings.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
using cohtml;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.DummyMenu;
|
||||
|
||||
public static class ModSettings
|
||||
{
|
||||
private static readonly MelonPreferences_Category Category = MelonPreferences.CreateCategory(nameof(DummyMenu));
|
||||
|
||||
internal static readonly MelonPreferences_Entry<KeyCode> EntryToggleDummyMenu =
|
||||
Category.CreateEntry(
|
||||
identifier: "toggle_dummy_menu",
|
||||
default_value: KeyCode.F3,
|
||||
display_name: "Toggle Menu Key",
|
||||
description: "Key used to toggle the dummy menu.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<string> EntryPageCouiPath =
|
||||
Category.CreateEntry(
|
||||
identifier: "page_coui_path",
|
||||
default_value: "UIResources/DummyMenu/menu.html",
|
||||
display_name: "Page Coui Path",
|
||||
description: "Path to the folder containing the root menu html. This is relative to the StreamingAssets folder.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<int> EntryPageWidth =
|
||||
Category.CreateEntry("page_width", CohtmlView.DefaultWidth,
|
||||
display_name: "Page Width",
|
||||
description: "Width of the menu page in pixels. Default is 1280 pixels.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<int> EntryPageHeight =
|
||||
Category.CreateEntry("page_height", CohtmlView.DefaultHeight,
|
||||
display_name: "Page Height",
|
||||
description: "Height of the menu page in pixels. Default is 720 pixels.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<bool> EntryReloadMenuEvenWhenOpen =
|
||||
Category.CreateEntry("reload_menu_even_when_open", false,
|
||||
display_name: "Reload Menu Even When Open",
|
||||
description: "If enabled, the menu will be reloaded even if it is already open.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<float> EntryVrMenuScaleModifier =
|
||||
Category.CreateEntry("vr_menu_scale_modifier", 0.75f,
|
||||
display_name: "VR Menu Scale Modifier",
|
||||
description: "Adjusts the scale of the menu while in VR. Default is 0.75.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<float> EntryDesktopMenuScaleModifier =
|
||||
Category.CreateEntry("desktop_menu_scale_modifier", 1f,
|
||||
display_name: "Desktop Menu Scale Modifier",
|
||||
description: "Adjusts the scale of the menu while in Desktop mode. Default is 1.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<float> EntryVrMenuDistanceModifier =
|
||||
Category.CreateEntry("vr_menu_distance_modifier", 1f,
|
||||
display_name: "VR Menu Distance Modifier",
|
||||
description: "Adjusts the distance of the menu from the camera while in VR. Default is 1.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<float> EntryDesktopMenuDistanceModifier =
|
||||
Category.CreateEntry("desktop_menu_distance_modifier", 1.2f,
|
||||
display_name: "Desktop Menu Distance Modifier",
|
||||
description: "Adjusts the distance of the menu from the camera while in Desktop mode. Default is 1.2.");
|
||||
|
||||
internal static readonly MelonPreferences_Entry<bool> EntryToggleMeToResetModifiers =
|
||||
Category.CreateEntry("toggle_me_to_reset_modifiers", false,
|
||||
display_name: "Toggle Me To Reset Modifiers",
|
||||
description: "If enabled, toggling the menu will reset any scale/distance modifiers applied by other mods.");
|
||||
}
|
||||
32
.Experimental/DummyMenu/Properties/AssemblyInfo.cs
Normal file
32
.Experimental/DummyMenu/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using MelonLoader;
|
||||
using NAK.DummyMenu.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.DummyMenu))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.DummyMenu))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.DummyMenu.DummyMenuMod),
|
||||
nameof(NAK.DummyMenu),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/DummyMenu"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.DummyMenu.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
using MelonLoader;
|
||||
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ using System.Reflection;
|
|||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/LuaNetworkVariables"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonGame("ChilloutVR", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(255, 246, 25, 99)] // red-pink
|
||||
|
|
@ -27,6 +27,6 @@ using System.Reflection;
|
|||
namespace NAK.LuaNetworkVariables.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.2";
|
||||
public const string Version = "1.0.3";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"_id": 234,
|
||||
"name": "WhereAmIPointing",
|
||||
"modversion": "1.0.1",
|
||||
"gameversion": "2024r175",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Simple mod that makes your controller rays always visible when the menus are open. Useful for when you're trying to aim at something in the distance. Also visualizes which ray is being used for menu interaction.",
|
||||
"searchtags": [
|
||||
"controller",
|
||||
"ray",
|
||||
"line",
|
||||
"tomato"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r40/WhereAmIPointing.dll",
|
||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/WhereAmIPointing/",
|
||||
"changelog": "- Fixed line renderer alpha not being reset when the menu is closed.",
|
||||
"embedcolor": "#f61963"
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using BTKUILib;
|
||||
using BTKUILib.UIObjects;
|
||||
using BTKUILib.UIObjects.Components;
|
||||
using ABI_RC.Systems.UI.UILib;
|
||||
using ABI_RC.Systems.UI.UILib.UIObjects;
|
||||
using ABI_RC.Systems.UI.UILib.UIObjects.Components;
|
||||
using NAK.OriginShift;
|
||||
|
||||
namespace NAK.OriginShiftMod.Integrations;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using BTKUILib;
|
||||
using BTKUILib.UIObjects;
|
||||
using ABI_RC.Systems.UI.UILib;
|
||||
using ABI_RC.Systems.UI.UILib.UIObjects;
|
||||
using NAK.OriginShift;
|
||||
|
||||
namespace NAK.OriginShiftMod.Integrations;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using System.Reflection;
|
||||
using BTKUILib;
|
||||
using BTKUILib.UIObjects;
|
||||
using BTKUILib.UIObjects.Components;
|
||||
using ABI_RC.Systems.UI.UILib;
|
||||
using ABI_RC.Systems.UI.UILib.UIObjects;
|
||||
using ABI_RC.Systems.UI.UILib.UIObjects.Components;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public static class ThirdPersonAddon
|
|||
|
||||
private static IEnumerator FixThirdPersonCompatibility()
|
||||
{
|
||||
yield return null; // wait a frame for the camera to be setup
|
||||
yield return null; // wait a frame for the camera to be setup
|
||||
GameObject thirdPersonCameraObj = GameObject.Find("_PLAYERLOCAL/[CameraRigDesktop]/Camera/ThirdPersonCameraObj");
|
||||
thirdPersonCameraObj.AddComponentIfMissing<OriginShiftOcclusionCullingDisabler>();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
#if !UNITY_EDITOR
|
||||
using System.Globalization;
|
||||
using ABI_RC.Core.UI;
|
||||
using ABI_RC.Core.Util.AssetFiltering;
|
||||
using ABI_RC.Systems.Movement;
|
||||
using MelonLoader;
|
||||
using NAK.OriginShift.Components;
|
||||
using NAK.OriginShiftMod.Integrations;
|
||||
using OriginShift.Integrations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.OriginShift;
|
||||
|
||||
|
|
@ -36,7 +32,6 @@ public class OriginShiftMod : MelonMod
|
|||
|
||||
// Compatibility Mode
|
||||
ApplyPatches(typeof(Patches.PlayerSetupPatches)); // net ik, camera occlusion culling
|
||||
ApplyPatches(typeof(Patches.Comms_ClientPatches)); // voice pos
|
||||
ApplyPatches(typeof(Patches.CVRSyncHelperPatches)); // spawnable pos
|
||||
ApplyPatches(typeof(Patches.PuppetMasterPatches)); // remote player pos
|
||||
ApplyPatches(typeof(Patches.CVRObjectSyncPatches)); // remote object pos
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
//
|
||||
// #region Constants
|
||||
//
|
||||
// private const string ModId = "MelonMod.NAK.RelativeSync";
|
||||
// private const string ModId = "MelonMod.NAK.RelativeSyncJitterFix";
|
||||
//
|
||||
// #endregion
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
using ABI.CCK.Components;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
#if !UNITY_EDITOR
|
||||
using ABI_RC.Core.Util;
|
||||
using ABI_RC.Core.Util.AssetFiltering;
|
||||
#endif
|
||||
|
||||
namespace NAK.OriginShift.Components;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class OriginShiftParticleSystemReceiver : MonoBehaviour
|
|||
_particleSystems = GetComponentsInChildren<ParticleSystem>(true);
|
||||
if (_particleSystems.Length == 0)
|
||||
{
|
||||
OriginShiftMod.Logger.Error("OriginShiftParticleSystemReceiver: No ParticleSystems found on GameObject: " + gameObject.name, this);
|
||||
// OriginShiftMod.Logger.Error("OriginShiftParticleSystemReceiver: No ParticleSystems found on GameObject: " + gameObject.name, this);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class OriginShiftRigidbodyReceiver : MonoBehaviour
|
|||
_rigidbody = GetComponentInChildren<Rigidbody>();
|
||||
if (_rigidbody == null)
|
||||
{
|
||||
OriginShiftMod.Logger.Error("OriginShiftRigidbodyReceiver: No Rigidbody found on GameObject: " + gameObject.name, this);
|
||||
// OriginShiftMod.Logger.Error("OriginShiftRigidbodyReceiver: No Rigidbody found on GameObject: " + gameObject.name, this);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class OriginShiftTrailRendererReceiver : MonoBehaviour
|
|||
_trailRenderers = GetComponentsInChildren<TrailRenderer>(true);
|
||||
if (_trailRenderers.Length == 0)
|
||||
{
|
||||
OriginShiftMod.Logger.Error("OriginShiftTrailRendererReceiver: No TrailRenderers found on GameObject: " + gameObject.name, this);
|
||||
// OriginShiftMod.Logger.Error("OriginShiftTrailRendererReceiver: No TrailRenderers found on GameObject: " + gameObject.name, this);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using ABI_RC.Core.Base;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI.CCK.Components;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using System.Collections;
|
||||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.Player;
|
||||
using NAK.OriginShift.Components;
|
||||
using NAK.OriginShift.Extensions;
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ using ABI_RC.Core.Player;
|
|||
using ABI_RC.Core.Util;
|
||||
using ABI_RC.Systems.Camera;
|
||||
using ABI_RC.Systems.Communications.Networking;
|
||||
using ABI_RC.Systems.GameEventSystem;
|
||||
using ABI_RC.Systems.Movement;
|
||||
using ABI.CCK.Components;
|
||||
using DarkRift;
|
||||
using ECM2;
|
||||
using HarmonyLib;
|
||||
using NAK.OriginShift.Components;
|
||||
using NAK.OriginShift.Hacks;
|
||||
|
|
@ -129,7 +127,7 @@ internal static class PortableCameraPatches
|
|||
[HarmonyPatch(typeof(PortableCamera), nameof(PortableCamera.Start))]
|
||||
private static void Postfix_PortableCamera_Start(ref PortableCamera __instance)
|
||||
{
|
||||
__instance.cameraComponent.AddComponentIfMissing<OriginShiftOcclusionCullingDisabler>();
|
||||
__instance.CameraComponent.AddComponentIfMissing<OriginShiftOcclusionCullingDisabler>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,17 +141,6 @@ internal static class PathingCameraPatches
|
|||
}
|
||||
}
|
||||
|
||||
internal static class Comms_ClientPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Comms_Client), nameof(Comms_Client.SetPosition))]
|
||||
private static void Prefix_Comms_Client_GetPlayerMovementData(ref Vector3 listenerPosition)
|
||||
{
|
||||
if (OriginShiftManager.CompatibilityMode) // adjust root position back to absolute world position
|
||||
listenerPosition = OriginShiftManager.GetAbsolutePosition(listenerPosition);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CVRSyncHelperPatches
|
||||
{
|
||||
[HarmonyPrefix] // outbound spawnable
|
||||
|
|
@ -180,15 +167,11 @@ internal static class CVRSyncHelperPatches
|
|||
|
||||
[HarmonyPrefix] // outbound spawn prop
|
||||
[HarmonyPatch(typeof(CVRSyncHelper), nameof(CVRSyncHelper.SpawnProp))]
|
||||
private static void Prefix_CVRSyncHelper_SpawnProp(ref float posX, ref float posY, ref float posZ)
|
||||
private static void Prefix_CVRSyncHelper_SpawnProp(ref Vector3 position)
|
||||
{
|
||||
if (OriginShiftManager.CompatibilityMode) // adjust root position back to absolute world position
|
||||
{
|
||||
Vector3 position = new(posX, posY, posZ); // imagine not using Vector3
|
||||
position = OriginShiftManager.GetAbsolutePosition(position);
|
||||
posX = position.x;
|
||||
posY = position.y;
|
||||
posZ = position.z;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue