Show sabotages on map

This commit is contained in:
D1GQ committed 2026-02-26 15:02:36 -06:00
1 parent fea6fa4847
commit d23fc1e13c
3 files changed
+117 -8

No files matched your search

+26 -1
View File
@@ -2,11 +2,29 @@
namespace BetterAmongUs.Modules;
/// <summary>
/// Provides functionality for grouping vents and assigning colors to vent groups.
/// </summary>
internal static class VentGroups
{
/// <summary>
/// Dictionary mapping each vent ID to the lowest ID in its group.
/// </summary>
private static readonly Dictionary<int, int> ventToLowestId = [];
/// <summary>
/// Dictionary mapping group IDs (lowest vent ID in the group) to their assigned colors.
/// </summary>
private static readonly Dictionary<int, Color> groupColors = [];
/// <summary>
/// Calculates all vent groups by performing a breadth-first search through connected vents.
/// </summary>
/// <param name="vents">Array of all vents in the scene to process.</param>
/// <remarks>
/// Groups vents that are connected via Left, Right, or Center references.
/// Each group is assigned a color, and the lowest vent ID in the group becomes the group identifier.
/// </remarks>
internal static void CalculateAllVentGroups(Vent[] vents)
{
ventToLowestId.Clear();
@@ -82,6 +100,13 @@ internal static class VentGroups
}
}
/// <summary>
/// Gets the group color for a specific vent.
/// </summary>
/// <param name="vent">The vent to get the group color for.</param>
/// <returns>
/// The color assigned to the vent's group, or <see cref="Color.black"/> if the vent hasn't been processed.
/// </returns>
internal static Color GetVentGroupColor(Vent vent)
{
if (ventToLowestId.TryGetValue(vent.Id, out int lowestId))
@@ -91,4 +116,4 @@ internal static class VentGroups
return Color.black;
}
}
}
+56
View File
@@ -0,0 +1,56 @@
using UnityEngine;
namespace BetterAmongUs.Mono;
/// <summary>
/// Animates a map icon by smoothly scaling it up and down when conditions are met.
/// </summary>
internal class AnimatedMapIcon : MonoBehaviour
{
/// <summary>
/// Event that determines whether the icon should animate.
/// Returns true if animation should occur, false otherwise.
/// </summary>
internal event Func<bool>? ShouldAnimate;
private Vector3 originalScale;
/// <summary>
/// The multiplier applied to the original scale when fully animated.
/// </summary>
private readonly float scaleMultiplier = 1.2f;
/// <summary>
/// The speed of the animation loop.
/// </summary>
private readonly float animationSpeed = 2f;
/// <summary>
/// Initializes the component by storing the original scale of the icon.
/// </summary>
private void Awake()
{
originalScale = transform.localScale;
}
/// <summary>
/// Updates the icon scale each frame based on the animation state.
/// When ShouldAnimate returns true, creates a smooth ping-pong scaling effect.
/// When ShouldAnimate returns false, resets to the original scale.
/// </summary>
private void Update()
{
if (ShouldAnimate?.Invoke() == true)
{
float pingPong = Mathf.PingPong(Time.time * animationSpeed, 1f);
float t = Mathf.SmoothStep(0f, 1f, pingPong);
Vector3 targetScale = originalScale * (1f + (scaleMultiplier - 1f) * t);
transform.localScale = targetScale;
}
else
{
transform.localScale = originalScale;
}
}
}
@@ -1,6 +1,7 @@
using BetterAmongUs.Helpers;
using BetterAmongUs.Modules;
using BetterAmongUs.Modules.Support;
using BetterAmongUs.Mono;
using HarmonyLib;
using UnityEngine;
@@ -46,6 +47,12 @@ internal static class MiniMapBehaviourPatch
{
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_MinimapIcons)) return;
foreach (var button in __instance.infectedOverlay.allButtons)
{
button.spriteRenderer.color = new Color(1f, 1f, 1f, 0.8f);
button.transform.localScale = new Vector3(0.6f, 0.6f, 1f);
}
if (_icons == null)
{
var icons = new GameObject("Icons")
@@ -79,19 +86,40 @@ internal static class MiniMapBehaviourPatch
icon.transform.localScale = Vector3.one * 0.25f;
SetPosFromShip(zipline.transform.position, icon.transform, new Vector3(0f, 0.16f, UsableLayerOffset));
}
foreach (var console in UnityEngine.Object.FindObjectsOfType<Console>())
{
foreach (var taskType in console.TaskTypes)
{
if (taskType is TaskTypes.FixLights or TaskTypes.FixComms or TaskTypes.RestoreOxy or TaskTypes.ResetReactor or TaskTypes.ResetSeismic)
{
var icon = CreateIcon(console.Image.sprite, "ConsoleIcon");
icon.color = Color.white * 0.7f;
icon.transform.localScale = Vector3.one * 0.5f;
SetPosFromShip(console.transform.position, icon.transform, new Vector3(0f, 0f, UsableLayerOffset));
var animatedMapIcon = icon.gameObject.AddComponent<AnimatedMapIcon>();
animatedMapIcon.ShouldAnimate += () =>
{
return console.FindTask(PlayerControl.LocalPlayer) != null;
};
break;
}
}
}
}
}
private static void CreateVentIcon(Vent vent)
{
var icon = CreateIcon(Utils.LoadSprite("BetterAmongUs.Resources.Images.Icons.Vent.png", 280), "VentIcon");
icon.color = VentGroups.GetVentGroupColor(vent) * 0.8f;
var icon = CreateIcon(Utils.LoadSprite("BetterAmongUs.Resources.Images.Icons.Vent.png", 380), "VentIcon");
var color = VentGroups.GetVentGroupColor(vent);
icon.color = new Color(color.r, color.g, color.b, 0.7f);
SetPosFromShip(vent.transform.position, icon.transform, new Vector3(0f, 0f, VentLayerOffset));
Vent[] nearbyVents = [vent.Left, vent.Right, vent.Center];
float maxSpreadShift = 1f;
float minSpreadShift = 0.3f;
float maxSpreadShift = 0.5f;
float minSpreadShift = 0.2f;
float closeDistance = 10f;
for (int i = 0; i < nearbyVents.Length; i++)
@@ -99,7 +127,7 @@ internal static class MiniMapBehaviourPatch
Vent neighborVent = nearbyVents[i];
if (neighborVent)
{
var arrowIcon = CreateIcon(Utils.LoadSprite("BetterAmongUs.Resources.Images.Icons.Arrow.png", 500), "VentArrowIcon");
var arrowIcon = CreateIcon(Utils.LoadSprite("BetterAmongUs.Resources.Images.Icons.Arrow.png", 600), "VentArrowIcon");
arrowIcon.color = VentGroups.GetVentGroupColor(neighborVent);
arrowIcon.transform.SetParent(icon.transform);
@@ -158,7 +186,7 @@ internal static class MiniMapBehaviourPatch
if (systemConsole.MinigamePrefab.name == "EmergencyMinigame")
{
var icon = CreateIcon(Utils.LoadSprite("BetterAmongUs.Resources.Images.Icons.Meeting.png", 500), "MeetingIcon");
icon.color = Color.white * 0.7f;
icon.color = new Color(1f, 1f, 1f, 0.7f);
icon.transform.localScale = Vector3.one * 0.35f;
SetPosFromShip(usable.Cast<MonoBehaviour>().transform.position, icon.transform, new Vector3(0f, 0f, UsableLayerOffset));
return;
@@ -175,7 +203,7 @@ internal static class MiniMapBehaviourPatch
if (HudManager.Instance.UseButton.fastUseSettings.TryGetValue(usable.UseIcon, out var settings))
{
var icon = CreateIcon(settings.Image, "UsableIcon");
icon.color = Color.white * 0.7f;
icon.color = new Color(1f, 1f, 1f, 0.7f);
icon.transform.localScale = Vector3.one * 0.35f;
SetPosFromShip(usable.Cast<MonoBehaviour>().transform.position, icon.transform, new Vector3(0f, 0f, UsableLayerOffset));
}