using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ValheimPinger")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimPinger")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e579368d-bfd6-4ba5-95b0-111aa8fad153")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("HotkeyToPingbyShineblind", "HotkeyToPing", "1.0.0")]
public class HotkeyToPing : BaseUnityPlugin
{
private static GameObject currentArrowObject;
private static ConfigEntry<KeyCode> keyboardPingKey;
private static ConfigEntry<KeyCode> controllerPingKey;
private static ConfigEntry<Color> pingColor;
private Coroutine followCoroutine;
private Coroutine bounceCoroutine;
private static ConfigEntry<bool> playerPointAtLocation;
private Vector3 groundPosition;
private static ConfigEntry<bool> showArrow;
private static ConfigEntry<bool> showRings;
private const float BOUNCE_HEIGHT = 2f;
private const float BOUNCE_SPEED = 0.2f;
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
Harmony val = new Harmony("com.yourname.pingmod");
val.PatchAll();
keyboardPingKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Primary Ping Key", (KeyCode)116, "The primary key to ping the location.");
controllerPingKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Secondary Ping Key", (KeyCode)0, "The secondary key to ping the location. Set to None to disable.");
pingColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Appearance", "Local Ping Color (map ping is always blue)", Color.cyan, "The color for the ping arrow and circle.");
playerPointAtLocation = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PlayerPointAtLocation", true, "Enable/disable player pointing at location.");
showArrow = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ShowArrow", true, "Show the arrow indicator when pinging.");
showRings = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ShowRings", true, "Show the expanding rings when ping is complete.");
}
private void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
bool keyDown = ZInput.GetKeyDown(keyboardPingKey.Value, true);
bool flag = (int)controllerPingKey.Value != 0 && ZInput.GetKeyDown(controllerPingKey.Value, true);
bool key = ZInput.GetKey(keyboardPingKey.Value, true);
bool flag2 = (int)controllerPingKey.Value != 0 && ZInput.GetKey(controllerPingKey.Value, true);
bool keyUp = ZInput.GetKeyUp(keyboardPingKey.Value, true);
bool flag3 = (int)controllerPingKey.Value != 0 && ZInput.GetKeyUp(controllerPingKey.Value, true);
if (keyDown || flag)
{
StartFollow();
}
if ((key || flag2) && playerPointAtLocation.Value)
{
AimPlayerTowardsCamera();
}
if (keyUp || flag3)
{
StopFollowAndPing();
}
}
private void AimPlayerTowardsCamera()
{
//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_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Player.m_localPlayer == (Object)null))
{
Vector3 forward = ((Component)Camera.main).transform.forward;
forward.y = 0f;
((Vector3)(ref forward)).Normalize();
((Component)Player.m_localPlayer).transform.rotation = Quaternion.LookRotation(forward);
}
}
private void StartFollow()
{
if (!((Object)(object)Player.m_localPlayer == (Object)null))
{
followCoroutine = ((MonoBehaviour)this).StartCoroutine(FollowCamera());
}
}
private IEnumerator FollowCamera()
{
bool keyHeld = true;
RaycastHit hit = default(RaycastHit);
RaycastHit groundHit = default(RaycastHit);
while (keyHeld)
{
keyHeld = ZInput.GetKey(keyboardPingKey.Value, true) || ((int)controllerPingKey.Value != 0 && ZInput.GetKey(controllerPingKey.Value, true));
if (!keyHeld)
{
break;
}
if (playerPointAtLocation.Value)
{
AimPlayerTowardsCamera();
}
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
int layerMask = LayerMask.GetMask(new string[12]
{
"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "character_noenv",
"vehicle", "item"
});
if (Physics.Raycast(ray, ref hit, 1000f, layerMask))
{
Vector3 pingPosition = ((RaycastHit)(ref hit)).point;
if (Physics.Raycast(pingPosition + Vector3.up * 2f, Vector3.down, ref groundHit, 5f, layerMask))
{
pingPosition = ((RaycastHit)(ref groundHit)).point;
}
groundPosition = pingPosition;
if (showArrow.Value)
{
if ((Object)(object)currentArrowObject == (Object)null)
{
ShowPingArrow(pingPosition);
StartBounceAnimation();
}
else
{
FacePlayer();
}
}
groundHit = default(RaycastHit);
}
yield return null;
hit = default(RaycastHit);
}
}
private void ShowPingArrow(Vector3 position)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)currentArrowObject != (Object)null) && showArrow.Value)
{
currentArrowObject = new GameObject("PingArrow");
currentArrowObject.transform.position = position + Vector3.up * 3f;
TextMeshPro val = currentArrowObject.AddComponent<TextMeshPro>();
((TMP_Text)val).text = "↓";
((TMP_Text)val).fontSize = 55f;
((Graphic)val).color = pingColor.Value;
((TMP_Text)val).alignment = (TextAlignmentOptions)514;
((TMP_Text)val).outlineWidth = 0.05f;
((TMP_Text)val).outlineColor = Color32.op_Implicit(Color.black);
Canvas val2 = currentArrowObject.AddComponent<Canvas>();
val2.renderMode = (RenderMode)2;
val2.sortingOrder = 10001000;
FacePlayer();
}
}
private void StartBounceAnimation()
{
if (bounceCoroutine == null && showArrow.Value)
{
bounceCoroutine = ((MonoBehaviour)this).StartCoroutine(BounceArrow());
}
}
private IEnumerator BounceArrow()
{
float time = 0f;
bool keyHeld = true;
while (keyHeld && (Object)(object)currentArrowObject != (Object)null)
{
keyHeld = ZInput.GetKey(keyboardPingKey.Value, true) || ((int)controllerPingKey.Value != 0 && ZInput.GetKey(controllerPingKey.Value, true));
if (!keyHeld)
{
break;
}
time += Time.deltaTime * 0.2f;
float height = Mathf.Abs(Mathf.Sin(time * (float)Math.PI)) * 2f;
Vector3 arrowPosition = groundPosition + Vector3.up * (3f + height);
currentArrowObject.transform.position = arrowPosition;
yield return null;
}
}
private void FacePlayer()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: 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_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)currentArrowObject == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null))
{
Vector3 val = ((Component)Player.m_localPlayer).transform.position - currentArrowObject.transform.position;
val.y = 0f;
((Vector3)(ref val)).Normalize();
currentArrowObject.transform.rotation = Quaternion.LookRotation(val);
}
}
private void StopFollowAndPing()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
if (followCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(followCoroutine);
followCoroutine = null;
}
if (bounceCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(bounceCoroutine);
bounceCoroutine = null;
}
Vector3 zero = Vector3.zero;
if ((Object)(object)currentArrowObject != (Object)null)
{
zero = groundPosition;
Object.Destroy((Object)(object)currentArrowObject);
currentArrowObject = null;
if (showRings.Value)
{
((MonoBehaviour)this).StartCoroutine(CreateExpandingCircles(zero));
}
}
else
{
zero = groundPosition;
if (showRings.Value && zero != Vector3.zero)
{
((MonoBehaviour)this).StartCoroutine(CreateExpandingCircles(zero));
}
}
if (playerPointAtLocation.Value)
{
Player localPlayer = Player.m_localPlayer;
if (localPlayer != null)
{
localPlayer.StartEmote("point", true);
}
}
if (zero != Vector3.zero)
{
Chat.instance.SendPing(zero);
}
}
private IEnumerator CreateExpandingCircles(Vector3 position)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (showRings.Value)
{
((MonoBehaviour)this).StartCoroutine(CreateSingleExpandingCircle(position, Vector3.up * 1f));
((MonoBehaviour)this).StartCoroutine(CreateSingleExpandingCircle(position, Vector3.zero));
yield return null;
}
}
private IEnumerator CreateSingleExpandingCircle(Vector3 position, Vector3 spawnOffset)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (!showRings.Value)
{
yield break;
}
GameObject circleObject = new GameObject("ExpandingCircle");
LineRenderer lineRenderer = circleObject.AddComponent<LineRenderer>();
lineRenderer.positionCount = 51;
lineRenderer.startWidth = 0.2f;
lineRenderer.endWidth = 0.2f;
((Renderer)lineRenderer).material = new Material(Shader.Find("Sprites/Default"));
lineRenderer.startColor = pingColor.Value;
lineRenderer.endColor = pingColor.Value;
float elapsedTime = 0f;
float duration = 6f;
float maxRadius = 6f;
while (elapsedTime < duration)
{
elapsedTime += Time.deltaTime;
float radius = Mathf.Lerp(0f, maxRadius, elapsedTime / duration);
float angleStep = 7.2f;
for (int i = 0; i <= 50; i++)
{
float angle = (float)i * angleStep;
float x = Mathf.Cos((float)Math.PI / 180f * angle) * radius;
float z = Mathf.Sin((float)Math.PI / 180f * angle) * radius;
lineRenderer.SetPosition(i, position + spawnOffset + new Vector3(x, 0f, z));
}
yield return null;
}
Object.Destroy((Object)(object)circleObject);
}
}