mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2026-02-24 22:16:11 +00:00
mass commit of laziness
This commit is contained in:
parent
ce992c70ee
commit
6d4fc549d9
167 changed files with 5471 additions and 675 deletions
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"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue