targeting action button

This commit is contained in:
XtraCube committed 2024-08-25 21:51:22 -04:00
1 parent 70320d7c19
commit b62d1b6565
4 files changed
+116 -23

No files matched your search

@@ -0,0 +1,40 @@
using MiraAPI.Hud;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Buttons;
public class ExampleTargetButton : CustomActionButton<PlayerControl>
{
public override string Name => "Shoot";
public override float Cooldown => 0f;
public override float EffectDuration => 0f;
public override int MaxUses => 0;
public override LoadableAsset<Sprite> Sprite => ExampleAssets.ExampleButton;
protected override void OnClick()
{
PlayerControl.LocalPlayer.CmdCheckMurder(Target);
}
public override PlayerControl GetTarget()
{
return PlayerControl.LocalPlayer.Data.Role.FindClosestTarget();
}
public override void SetOutline(bool active)
{
Target?.cosmetics.SetOutline(active, new Il2CppSystem.Nullable<Color>(Color.red));
}
public override bool IsTargetValid(PlayerControl target)
{
return PlayerControl.LocalPlayer.Data.Role.IsValidTarget(target.Data);
}
public override bool Enabled(RoleBehaviour role)
{
return role.IsImpostor;
}
}
+52 -11
View File
@@ -1,4 +1,6 @@
using MiraAPI.Utilities.Assets;
#nullable enable
using MiraAPI.Utilities;
using MiraAPI.Utilities.Assets;
using UnityEngine;
using UnityEngine.Events;
@@ -59,7 +61,7 @@ public abstract class CustomActionButton
/// <summary>
/// The button object in game. This is created by Mira API automatically.
/// </summary>
protected ActionButton Button { get; private set; }
protected ActionButton? Button { get; private set; }
internal void CreateButton(Transform parent)
{
@@ -109,7 +111,10 @@ public abstract class CustomActionButton
/// <param name="sprite">The new sprite to override with</param>
public void OverrideSprite(Sprite sprite)
{
Button.graphic.sprite = sprite;
if (Button != null)
{
Button.graphic.sprite = sprite;
}
}
/// <summary>
@@ -118,7 +123,7 @@ public abstract class CustomActionButton
/// <param name="name">The new name to override with</param>
public void OverrideName(string name)
{
Button.OverrideText(name);
Button?.OverrideText(name);
}
/// <summary>
@@ -164,7 +169,7 @@ public abstract class CustomActionButton
/// <param name="role">Passed in from HudManager.SetHudActive, the current role of the player.</param>
public virtual void SetActive(bool visible, RoleBehaviour role)
{
Button.ToggleVisible(visible && Enabled(role));
Button?.ToggleVisible(visible && Enabled(role));
}
/// <summary>
@@ -172,7 +177,7 @@ public abstract class CustomActionButton
/// This method takes into account cooldowns, effects, and uses, before calling the <see cref="OnClick"/> method.
/// It can be overridden for custom behavior.
/// </summary>
public virtual void ClickHandler()
protected virtual void ClickHandler()
{
if (!CanUse())
{
@@ -182,11 +187,11 @@ public abstract class CustomActionButton
if (LimitedUses)
{
UsesLeft--;
Button.SetUsesRemaining(UsesLeft);
Button?.SetUsesRemaining(UsesLeft);
}
OnClick();
Button.SetDisabled();
Button?.SetDisabled();
if (HasEffect)
{
EffectActive = true;
@@ -219,15 +224,51 @@ public abstract class CustomActionButton
if (CanUse())
{
Button.SetEnabled();
Button?.SetEnabled();
}
else
{
Button.SetDisabled();
Button?.SetDisabled();
}
Button.SetCoolDown(Timer, EffectActive ? EffectDuration : Cooldown);
Button?.SetCoolDown(Timer, EffectActive ? EffectDuration : Cooldown);
FixedUpdate(playerControl);
}
}
public abstract class CustomActionButton<T> : CustomActionButton where T : MonoBehaviour
{
public T? Target { get; private set; }
public virtual float Distance => PlayerControl.LocalPlayer.Data.Role.GetAbilityDistance();
public virtual string ColliderTag => null;
public virtual bool IsTargetValid(T target)
{
return target;
}
public virtual T? GetTarget()
{
return PlayerControl.LocalPlayer.GetNearestObjectOfType<T>(Distance, ColliderTag, IsTargetValid);
}
public abstract void SetOutline(bool active);
public override bool CanUse()
{
var newTarget = GetTarget();
if (newTarget != Target)
{
SetOutline(false);
}
Target = newTarget;
SetOutline(true);
return base.CanUse() && Target;
}
}
-3
View File
@@ -3,9 +3,6 @@ using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using MiraAPI.PluginLoading;
using Reactor;
using Reactor.Patches;
using System;
using System.Text;
using MiraAPI.Utilities;
using Reactor.Networking;
using Reactor.Networking.Attributes;
+24 -9
View File
@@ -1,4 +1,5 @@
#nullable enable
using System;
using System.Collections.Generic;
using MiraAPI.GameOptions;
using System.Linq;
@@ -10,10 +11,16 @@ namespace MiraAPI.Utilities;
public static class Extensions
{
public static void SetOutline(this SpriteRenderer spriteRenderer, bool active, Color color)
{
spriteRenderer.material.SetFloat(ShaderID.Outline, active ? 1f : 0f);
spriteRenderer.material.SetColor(ShaderID.OutlineColor, color);
}
public static string? Truncate(this string? value, int maxLength, string truncationSuffix = "…")
{
return value?.Length > maxLength
? value.Substring(0, maxLength) + truncationSuffix
? value[..maxLength] + truncationSuffix
: value;
}
@@ -73,7 +80,7 @@ public static class Extensions
public static bool IsColorDark(this Color color)
{
return color.r < 0.5f && color.g < 0.5f && color.b < 0.5f;
return color.r < 0.5f && color is { g: < 0.5f, b: < 0.5f };
}
public static DeadBody? NearestDeadBody(this PlayerControl playerControl, float radius)
@@ -86,6 +93,16 @@ public static class Extensions
.FirstOrDefault(component => component && !component.Reported);
}
public static T? GetNearestObjectOfType<T>(this PlayerControl playerControl, float radius, string? colliderTag=null, Func<T, bool>? predicate=null) where T : Component
{
var results = new Il2CppSystem.Collections.Generic.List<Collider2D>();
Physics2D.OverlapCircle(playerControl.GetTruePosition(), radius, Helpers.Filter, results);
return results.ToArray()
.Where(collider2D => colliderTag == null || collider2D.CompareTag(colliderTag))
.Select(collider2D => collider2D.GetComponent<T>())
.FirstOrDefault(predicate ?? (component => component));
}
public static PlayerControl? GetClosestPlayer(this PlayerControl playerControl, bool includeImpostors, float distance)
{
PlayerControl? result = null;
@@ -96,14 +113,12 @@ public static class Extensions
var truePosition = playerControl.GetTruePosition();
foreach (var playerInfo in GameData.Instance.AllPlayers)
var filteredPlayers = GameData.Instance.AllPlayers.ToArray()
.Where(playerInfo => !playerInfo.Disconnected && playerInfo.PlayerId != playerControl.PlayerId && !playerInfo.IsDead &&
(includeImpostors || !playerInfo.Role.IsImpostor));
foreach (var playerInfo in filteredPlayers)
{
if (playerInfo.Disconnected || playerInfo.PlayerId == playerControl.PlayerId ||
playerInfo.IsDead || !includeImpostors && playerInfo.Role.IsImpostor)
{
continue;
}
var @object = playerInfo.Object;
if (!@object)
{