using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance;
using GameNetcodeStuff;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("NameplateTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Configurable client-side mod for player username billboards. Speaking indicators, better visibility, etc.")]
[assembly: AssemblyFileVersion("1.0.6.0")]
[assembly: AssemblyInformationalVersion("1.0.6")]
[assembly: AssemblyProduct("NameplateTweaks")]
[assembly: AssemblyTitle("NameplateTweaks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: UnverifiableCode]
namespace NameplateTweaks;
[BepInPlugin("taffyko.NameplateTweaks", "NameplateTweaks", "1.0.6")]
public class Plugin : BaseUnityPlugin
{
public const string modGUID = "taffyko.NameplateTweaks";
public const string modName = "NameplateTweaks";
public const string modVersion = "1.0.6";
public static ConfigEntry<bool> ConfigEnableSpeakingIndicator;
public static ConfigEntry<bool> ConfigVariableSpeakingIndicatorOpacity;
public static ConfigEntry<bool> ConfigSpeakingIndicatorAlwaysVisible;
public static ConfigEntry<float> ConfigNameplateScale;
public static ConfigEntry<float> ConfigNameplateVisibilityDistance;
public static ConfigEntry<bool> ConfigNameplateScaleWithDistance;
public static ManualLogSource log;
private readonly Harmony harmony = new Harmony("taffyko.NameplateTweaks");
public static Vector3? OriginalNameplateScale = new Vector3(-0.0025f, 0.0025f, 0.0025f);
private void Awake()
{
log = Logger.CreateLogSource("NameplateTweaks");
log.LogInfo((object)"Loading taffyko.NameplateTweaks");
ConfigEnableSpeakingIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("Speaking Indicator", "EnableSpeakingIndicator", true, "Enable a voice-activity speaking indicator above player nameplates");
ConfigVariableSpeakingIndicatorOpacity = ((BaseUnityPlugin)this).Config.Bind<bool>("Speaking Indicator", "VariableSpeakingIndicatorOpacity", true, "Speaking indicator opacity changes depending on volume");
ConfigSpeakingIndicatorAlwaysVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Speaking Indicator", "SpeakingIndicatorAlwaysVisible", true, "Display speaking indicators even when the nameplate is hidden");
ConfigNameplateScale = ((BaseUnityPlugin)this).Config.Bind<float>("Nameplate", "NameplateScale", 1.5f, "Nameplate size multiplier (1.0 is the vanilla size)");
ConfigNameplateVisibilityDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Nameplate", "NameplateVisibilityDistance", 20f, "Distance from the camera within which nameplates are visible (0.0 reverts to vanilla behavior). The length of the ship is ~20 units, for reference");
ConfigNameplateScaleWithDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("Nameplate", "NameplateScaleWithDistance", false, "Scale nameplates so that they retain their apparent size as they get further away");
harmony.PatchAll(Assembly.GetExecutingAssembly());
}
private void OnDestroy()
{
}
}
public class SpeakingIndicator : MonoBehaviour
{
public PlayerControllerB player;
public Canvas canvas;
public GameObject canvasItem;
public CanvasGroup canvasItemAlpha;
public static Dictionary<PlayerControllerB, SpeakingIndicator> speakingIndicators = new Dictionary<PlayerControllerB, SpeakingIndicator>();
private static Texture2D speakingIconTexture = null;
public static Texture2D GetSpeakingIconTexture()
{
if ((Object)(object)speakingIconTexture != (Object)null)
{
return speakingIconTexture;
}
return GameObject.Find("PTTIcon").GetComponent<Image>().sprite.texture;
}
public static SpeakingIndicator GetSpeakingIndicator(PlayerControllerB player)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
speakingIndicators.TryGetValue(player, out var value);
if ((Object)(object)value == (Object)null)
{
GameObject val = new GameObject("SpeakingIndicator");
val.SetActive(false);
value = val.AddComponent<SpeakingIndicator>();
value.player = player;
((Component)value).transform.SetParent(((Component)player).transform, false);
speakingIndicators.Add(player, value);
val.SetActive(true);
}
return value;
}
public void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
canvasItem = new GameObject("SpeakingIndicatorCanvasItem");
canvasItem.transform.SetParent(player.usernameBillboard, false);
canvasItem.AddComponent<CanvasRenderer>();
canvasItemAlpha = canvasItem.AddComponent<CanvasGroup>();
canvasItemAlpha.alpha = 0f;
canvasItem.transform.localPosition = new Vector3(0f, 60f, 0f);
canvasItem.AddComponent<Image>().sprite = Sprite.Create(GetSpeakingIconTexture(), new Rect(0f, 0f, 260f, 280f), new Vector2(130f, 140f), 100f);
}
private float lexp(float a, float b, float t)
{
return Mathf.Lerp(a, b, Mathf.Exp(0f - t));
}
public void Update()
{
VoicePlayerState voicePlayerState = player.voicePlayerState;
if (voicePlayerState != null)
{
float num = Mathf.Clamp(voicePlayerState.Amplitude * 35f, 0f, 1f);
if (Plugin.ConfigVariableSpeakingIndicatorOpacity.Value)
{
if (num > 0.01f)
{
canvasItemAlpha.alpha = lexp(canvasItemAlpha.alpha, num, Time.deltaTime * 100f);
}
else
{
canvasItemAlpha.alpha = lexp(canvasItemAlpha.alpha, num, Time.deltaTime * 50f);
}
}
else if (num > 0.05f)
{
canvasItemAlpha.alpha = 1f;
}
else if (num < 0.01f)
{
canvasItemAlpha.alpha = 0f;
}
}
if (!Plugin.ConfigSpeakingIndicatorAlwaysVisible.Value)
{
canvasItemAlpha.alpha = Math.Min(canvasItemAlpha.alpha, player.usernameAlpha.alpha);
}
if (((NetworkBehaviour)player).IsOwner)
{
canvasItemAlpha.alpha = 0f;
}
if (!Plugin.ConfigEnableSpeakingIndicator.Value)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
public void OnDestroy()
{
speakingIndicators.Remove(player);
Object.Destroy((Object)(object)canvasItem);
}
}
[HarmonyPatch]
public class Patches
{
[HarmonyPatch(typeof(HUDManager), "UpdateSpectateBoxSpeakerIcons")]
[HarmonyPostfix]
public static void UpdateSpectateBoxSpeakerIcons(HUDManager __instance, ref Dictionary<Animator, PlayerControllerB> ___spectatingPlayerBoxes)
{
foreach (var (val3, val4) in ___spectatingPlayerBoxes)
{
if (!((NetworkBehaviour)val4).IsOwner)
{
continue;
}
if (!(IngamePlayerSettings.Instance?.settings?.pushToTalk).GetValueOrDefault())
{
break;
}
PlayerInput playerInput = IngamePlayerSettings.Instance.playerInput;
bool? obj;
if (playerInput == null)
{
obj = null;
}
else
{
InputActionAsset actions = playerInput.actions;
if (actions == null)
{
obj = null;
}
else
{
InputAction obj2 = actions.FindAction("VoiceButton", false);
obj = ((obj2 != null) ? new bool?(obj2.IsPressed()) : null);
}
}
bool? flag = obj;
bool valueOrDefault = flag.GetValueOrDefault();
val3.SetBool("speaking", valueOrDefault);
break;
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
[HarmonyPostfix]
public static void PlayerUpdate(PlayerControllerB __instance)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
((TMP_Text)__instance.usernameBillboardText).text = __instance.playerUsername;
if (Plugin.ConfigEnableSpeakingIndicator.Value)
{
SpeakingIndicator.GetSpeakingIndicator(__instance);
}
__instance.usernameBillboard.position = new Vector3(__instance.playerGlobalHead.position.x, __instance.playerGlobalHead.position.y + 0.55f, __instance.playerGlobalHead.position.z);
if ((Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController)
{
__instance.usernameAlpha.alpha = 0f;
}
else if ((Object)(object)StartOfRound.Instance?.localPlayerController != (Object)null)
{
float num = Vector3.Distance(((Component)StartOfRound.Instance.localPlayerController.gameplayCamera).transform.position, __instance.usernameBillboard.position);
if (num < Plugin.ConfigNameplateVisibilityDistance.Value)
{
__instance.usernameAlpha.alpha = 1f;
((Behaviour)__instance.usernameBillboardText).enabled = true;
((Component)__instance.usernameCanvas).gameObject.SetActive(true);
}
float num2 = 1f;
if (Plugin.ConfigNameplateScaleWithDistance.Value)
{
num2 = 1f + Math.Max(0f, (num - 4f) * 0.11f);
}
__instance.usernameBillboard.localScale = Plugin.OriginalNameplateScale.Value * Plugin.ConfigNameplateScale.Value * num2;
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "NameplateTweaks";
public const string PLUGIN_NAME = "NameplateTweaks";
public const string PLUGIN_VERSION = "1.0.6";
}