Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 43 additions & 39 deletions NewMod/Buttons/Necromancer/ReviveButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using NewMod.Utilities;
using MiraAPI.Keybinds;
using AmongUs.GameOptions;
using Reactor.Utilities;
using MiraAPI.Utilities;
using System.Linq;

Expand Down Expand Up @@ -53,22 +52,53 @@ public class ReviveButton : CustomActionButton
/// </summary>
public override LoadableAsset<Sprite> Sprite => NewModAsset.NecromancerButton;

private DeadBody GetReviveTarget()
{
var local = PlayerControl.LocalPlayer;
var localPos = local.GetTruePosition();

return Helpers.GetNearestDeadBodies(
localPos,
ShipStatus.Instance.MaxLightRadius,
Helpers.CreateFilter(Constants.NotShipMask))
.Where(body => body != null && IsValidReviveTarget(local, body))
.OrderBy(body => Vector2.Distance(localPos, body.TruePosition))
.FirstOrDefault();
}

public static bool IsValidReviveTarget(PlayerControl local, DeadBody body)
{
if (PranksterUtilities.IsPranksterBody(body))
return false;

var killedPlayer = GameData.Instance.GetPlayerById(body.ParentId)?.Object;
if (killedPlayer == null)
return false;

var killer = Utils.GetKiller(killedPlayer);

if (killer != null && killer.PlayerId == local.PlayerId)
return false;

return true;
}

/// <summary>
/// Checks whether the player can currently use the revive button, ensuring cooldowns, ability uses, and conditions are met.
/// </summary>
/// <returns>True if all requirements to use this button are met; otherwise false.</returns
public override bool CanUse()
{
return GetReviveTarget() != null;
}

/// <summary>
/// Invoked when the revive button is clicked. Plays a sound and revives the nearest dead body.
/// </summary>
protected override void OnClick()
{
var local = PlayerControl.LocalPlayer;

var body = Helpers.GetNearestDeadBodies(
local.GetTruePosition(),
ShipStatus.Instance.MaxLightRadius,
Helpers.CreateFilter(Constants.NotShipMask))
.Where(b => b != null && !PranksterUtilities.IsPranksterBody(b))
.OrderBy(b => Vector2.Distance(local.GetTruePosition(), b.TruePosition))
.FirstOrDefault();

if (body == null) return;
var body = GetReviveTarget();

SoundManager.Instance.PlaySound(NewModAsset.ReviveSound?.LoadAsset(), false, 2f);

Expand All @@ -79,8 +109,10 @@ protected override void OnClick()
body.transform.position.x,
body.transform.position.y
);

NecromancerRole.RevivedPlayers[body.ParentId] = local.PlayerId;
}

/// <summary>
/// Determines whether this button is enabled for the role, returning true if the role is <see cref="NecromancerRole"/>.
/// </summary>
Expand All @@ -90,33 +122,5 @@ public override bool Enabled(RoleBehaviour role)
{
return role is NecromancerRole;
}

/// <summary>
/// Checks whether the player can currently use the revive button, ensuring cooldowns, ability uses, and conditions are met.
/// </summary>
/// <returns>True if all requirements to use this button are met; otherwise false.</returns>
public override bool CanUse()
{
var bodiesInRange = Helpers.GetNearestDeadBodies(
PlayerControl.LocalPlayer.transform.position,
ShipStatus.Instance.MaxLightRadius,
Helpers.CreateFilter(Constants.NotShipMask));

bool canUse = bodiesInRange.Any(body =>
{
if (PranksterUtilities.IsPranksterBody(body)) return false;

var killedPlayer = GameData.Instance.GetPlayerById(body.ParentId)?.Object;
if (killedPlayer == null) return false;

var killer = Utils.GetKiller(killedPlayer);
if (killer.PlayerId == PlayerControl.LocalPlayer.PlayerId)
return false;

return true;
});

return canUse;
}
}
}
2 changes: 1 addition & 1 deletion NewMod/Buttons/Revenant/DoomAwakening.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class DoomAwakening : CustomActionButton
/// <returns>True if the role is <see cref="RV"/>, otherwise false.</returns>
public override bool Enabled(RoleBehaviour role)
{
return role is RV;
return role is RV && RV.StalkingStates.ContainsKey(PlayerControl.LocalPlayer.PlayerId);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion NewMod/Buttons/Revenant/FeignDeathButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class FeignDeathButton : CustomActionButton
/// <summary>
/// The icon or sprite used for this button. Here, set to an empty sprite.
/// </summary>
public override LoadableAsset<Sprite> Sprite => MiraAssets.Empty;
public override LoadableAsset<Sprite> Sprite => NewModAsset.FeignDeath;

/// <summary>
/// Specifies whether the button is enabled for the given role, ensuring Feign Death hasn't been used yet.
Expand Down
29 changes: 23 additions & 6 deletions NewMod/Buttons/RevivedKillButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
using MiraAPI.Keybinds;
using MiraAPI.Utilities.Assets;
using NewMod.Roles.ImpostorRoles;
using Reactor.Utilities;
using AmongUs.GameOptions;
using System.Linq;
using UnityEngine;
using MiraAPI.Networking;
using MiraAPI.Utilities;
Expand All @@ -20,27 +18,44 @@ public class RevivedKillButton : CustomActionButton<PlayerControl>
public override MiraKeybind Keybind => MiraGlobalKeybinds.PrimaryAbility;
public override ButtonLocation Location => ButtonLocation.BottomRight;
public override LoadableAsset<Sprite> Sprite => NewModAsset.VanillaKillButton;

private static bool CanUseRevivedKillButton()
{
var local = PlayerControl.LocalPlayer;
return local != null && NecromancerRole.RevivedPlayers.ContainsKey(local.PlayerId);
}

public override bool Enabled(RoleBehaviour role)
{
return NecromancerRole.RevivedPlayers.ContainsKey(PlayerControl.LocalPlayer.PlayerId);
return CanUseRevivedKillButton();
}

protected override void FixedUpdate(PlayerControl playerControl)
{
Button?.ToggleVisible(CanUseRevivedKillButton());
}

public override PlayerControl GetTarget()
{
return PlayerControl.LocalPlayer.GetClosestPlayer(true, Distance);
}

public override bool IsTargetValid(PlayerControl target)
{
return target.PlayerId != PlayerControl.LocalPlayer.PlayerId;
return CanUseRevivedKillButton() &&
target != null &&
target.PlayerId != PlayerControl.LocalPlayer.PlayerId &&
!target.Data.IsDead && !target.Data.Disconnected;
}

public override void SetOutline(bool active)
{
Target.cosmetics.SetOutline(active, new Il2CppSystem.Nullable<Color>(Palette.ImpostorRed));
}

public override bool CanUse()
{
if (!NecromancerRole.RevivedPlayers.ContainsKey(PlayerControl.LocalPlayer.PlayerId)) return false;
return true;
return base.CanUse() && CanUseRevivedKillButton();
}

protected override void OnClick()
Expand All @@ -58,6 +73,8 @@ protected override void OnClick()
);

NecromancerRole.RevivedPlayers.Remove(local.PlayerId);
ResetTarget();
Button?.ToggleVisible(false);
}
}
}
1 change: 1 addition & 0 deletions NewMod/Buttons/Visionary/CaptureButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ protected override void OnClick()
{
var timestamp = System.DateTime.UtcNow.ToString("yyyy-MM-dd_HH-mm-ss");
string path = Path.Combine(VisionaryUtilities.ScreenshotDirectory, $"screenshot_{timestamp}.png");
NewMod.Instance.Log.LogMessage($"Screenshot will be saved to: {path}");
Coroutines.Start(Utils.CaptureScreenshot(path));
}

Expand Down
2 changes: 1 addition & 1 deletion NewMod/Buttons/WraithCaller/CallWraith.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ protected override void OnClick()
player =>
{
menu.Close();
WraithCallerUtilities.RpcRequestSummonNPC(PlayerControl.LocalPlayer, player);
WraithCallerUtilities.RequestSummonNPC(PlayerControl.LocalPlayer, player);
SetTimerPaused(false);
});

Expand Down
12 changes: 9 additions & 3 deletions NewMod/Components/ScreenEffects/ShadowFluxEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@ namespace NewMod.Components.ScreenEffects
[RegisterInIl2Cpp]
public class ShadowFluxEffect(IntPtr ptr) : MonoBehaviour(ptr)
{
public Texture2D texture = NewModAsset.NoiseTex.LoadAsset();
public float noiseScale = 2f;
public float speed = 0.3f;
public float edgeWidth = 0.25f;
public float threshold = 0.55f;
public float opacity = 0.75f;
public float darkness = 0.8f;
public Color tint = Color.white;
public static Shader _shader = NewModAsset.ShadowFluxShader.LoadAsset();
public Material _mat;

public void OnEnable()
{
_mat = new Material(_shader) { hideFlags = HideFlags.DontSave };
var shader = NewModAsset.ShadowFluxShader.LoadAsset();
var texture = NewModAsset.NoiseTex.LoadAsset();

if (shader == null)
{
NewMod.Instance.Log.LogError("ShadowFluxEffect - Shader null");
}

_mat = new Material(shader) { hideFlags = HideFlags.DontSave };
_mat.SetTexture("_NoiseTex", texture);
}
public void OnDisable()
Expand Down
45 changes: 40 additions & 5 deletions NewMod/Components/ShadowZone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,36 +42,60 @@ private bool Contains(Vector2 pos)
public void Update()
{
timer += Time.deltaTime;

var lp = PlayerControl.LocalPlayer;
var hud = HudManager.Instance;
var killButton = hud.KillButton;

if (timer >= duration)
{
Coroutines.Start(CoroutinesHelper.RemoveCameraEffect(Camera.main, 0f));

if (active && lp.PlayerId == shadeId)
{
lp.cosmetics.SetPhantomRoleAlpha(1);
lp.cosmetics.ToggleHat(true);
lp.cosmetics.ToggleVisor(true);
lp.cosmetics.TogglePet(true);
lp.cosmetics.nameText.gameObject.SetActive(true);

if (killButton.currentTarget)
{
killButton.currentTarget.ToggleHighlight(false, RoleTeamTypes.Impostor);
killButton.currentTarget = null;
}

killButton.gameObject.SetActive(false);
}

active = false;
Destroy(gameObject);
return;
}

var lp = PlayerControl.LocalPlayer;
var hud = HudManager.Instance;
var killButton = hud.KillButton;

bool inside = Contains(lp.GetTruePosition());
var mode = OptionGroupSingleton<ShadeOptions>.Instance.Behavior;
var cam = Camera.main;

if (inside && !active)
{
cam.gameObject.AddComponent<ShadowFluxEffect>();

if (lp.PlayerId == shadeId && lp.Data.Role is Shade)
{
if (mode is ShadeOptions.ShadowMode.Invisible or ShadeOptions.ShadowMode.Both)
{
lp.cosmetics.SetPhantomRoleAlpha(0);
lp.cosmetics.ToggleHat(false);
lp.cosmetics.ToggleVisor(false);
lp.cosmetics.TogglePet(false);
lp.cosmetics.nameText.gameObject.SetActive(false);
}

killButton.gameObject.SetActive(true);
killButton.currentTarget = null;
}

active = true;
}

Expand All @@ -81,32 +105,43 @@ public void Update()
{
var list = new Il2CppSystem.Collections.Generic.List<PlayerControl>();
lp.Data.Role.GetPlayersInAbilityRangeSorted(list);
var players = list.ToArray().Where(p => p.PlayerId != lp.PlayerId && !p.Data.IsDead).ToList();

var players = list.ToArray()
.Where(p => p.PlayerId != lp.PlayerId && !p.Data.IsDead)
.ToList();

var closest = players.Count > 0 ? players[0] : null;

if (killButton.currentTarget && killButton.currentTarget != closest)
killButton.currentTarget.ToggleHighlight(false, RoleTeamTypes.Impostor);

killButton.currentTarget = closest;

if (closest != null)
closest.ToggleHighlight(true, RoleTeamTypes.Impostor);
}
}
else if (!inside && active)
{
Coroutines.Start(CoroutinesHelper.RemoveCameraEffect(cam, 0f));

if (lp.PlayerId == shadeId)
{
lp.cosmetics.SetPhantomRoleAlpha(1);
lp.cosmetics.ToggleHat(true);
lp.cosmetics.TogglePet(false);
lp.cosmetics.ToggleVisor(false);
lp.cosmetics.nameText.gameObject.SetActive(true);

if (killButton.currentTarget)
{
killButton.currentTarget.ToggleHighlight(false, RoleTeamTypes.Impostor);
killButton.currentTarget = null;
}

killButton.gameObject.SetActive(false);
}

active = false;
}
}
Expand Down
Loading
Loading