Skip to content

Commit 41863a1

Browse files
v1.2.8 Update
v1.2.8
2 parents 4f8d9ba + e6f03f1 commit 41863a1

40 files changed

Lines changed: 1016 additions & 387 deletions
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using MiraAPI.GameOptions;
2+
using MiraAPI.Hud;
3+
using MiraAPI.Keybinds;
4+
using MiraAPI.Utilities.Assets;
5+
using UnityEngine;
6+
using NewMod.Components;
7+
using SH = NewMod.Roles.NeutralRoles.Shade;
8+
using NewMod.Options.Roles.ShadeOptions;
9+
10+
namespace NewMod.Buttons.Shade
11+
{
12+
/// <summary>
13+
/// Custom action button for the Shade role.
14+
/// Deploys a Shadow Zone where the Shade becomes invisible and gains kill power.
15+
/// </summary>
16+
public class ShadeButton : CustomActionButton
17+
{
18+
/// <summary>
19+
/// Display name of the button.
20+
/// </summary>
21+
public override string Name => "Deploy Shadow";
22+
23+
/// <summary>
24+
/// Cooldown duration between zone deployments.
25+
/// </summary>
26+
public override float Cooldown => OptionGroupSingleton<ShadeOptions>.Instance.Cooldown;
27+
28+
/// <summary>
29+
/// Maximum number of uses.
30+
/// </summary>
31+
public override int MaxUses => (int)OptionGroupSingleton<ShadeOptions>.Instance.MaxUses;
32+
33+
/// <summary>
34+
/// Button HUD placement.
35+
/// </summary>
36+
public override ButtonLocation Location => ButtonLocation.BottomLeft;
37+
38+
/// <summary>
39+
/// Default keybind.
40+
/// </summary>
41+
public override MiraKeybind Keybind => MiraGlobalKeybinds.PrimaryAbility;
42+
43+
/// <summary>
44+
/// Button icon.
45+
/// </summary>
46+
public override LoadableAsset<Sprite> Sprite => NewModAsset.DeployZone;
47+
48+
/// <summary>
49+
/// Button enabled only for the Shade role.
50+
/// </summary>
51+
public override bool Enabled(RoleBehaviour role) => role is SH;
52+
53+
/// <summary>
54+
/// Deploys a shadow zone at the Shade's position.
55+
/// </summary>
56+
protected override void OnClick()
57+
{
58+
var player = PlayerControl.LocalPlayer;
59+
60+
Vector2 pos = player.GetTruePosition();
61+
62+
float radius = OptionGroupSingleton<ShadeOptions>.Instance.Radius;
63+
float dur = OptionGroupSingleton<ShadeOptions>.Instance.Duration;
64+
65+
ShadowZone.RpcDeployZone(player, pos, radius, dur);
66+
}
67+
}
68+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using Reactor.Utilities.Attributes;
3+
using UnityEngine;
4+
5+
namespace NewMod.Components.ScreenEffects
6+
{
7+
[RegisterInIl2Cpp]
8+
public class DistorationWaveEffect(IntPtr ptr) : MonoBehaviour(ptr)
9+
{
10+
public float amplitude = 0.05f;
11+
public float frequency = 5f;
12+
public float speed = 1f;
13+
public float radius = 0.25f;
14+
public float falloff = 1f;
15+
public Vector2 center = new Vector2(0.5f, 0.5f);
16+
public Color tint = Color.white;
17+
private readonly Shader _shader = NewModAsset.DistorationWaveShader.LoadAsset();
18+
public Material _mat;
19+
20+
public void OnEnable()
21+
{
22+
_mat = new Material(_shader) { hideFlags = HideFlags.DontSave };
23+
}
24+
25+
public void OnDisable()
26+
{
27+
Destroy(_mat);
28+
}
29+
30+
public void OnRenderImage(RenderTexture src, RenderTexture dst)
31+
{
32+
_mat.SetFloat("_Amplitude", amplitude);
33+
_mat.SetFloat("_Frequency", frequency);
34+
_mat.SetFloat("_Speed", speed);
35+
_mat.SetFloat("_Radius", radius);
36+
_mat.SetFloat("_Falloff", falloff);
37+
_mat.SetVector("_Center", center);
38+
_mat.SetColor("_Tint", tint);
39+
Graphics.Blit(src, dst, _mat);
40+
}
41+
}
42+
}

NewMod/Components/ScreenEffects/GlitchEffect.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class GlitchEffect(IntPtr ptr) : MonoBehaviour(ptr)
1414
public float speed = 4f;
1515
private readonly Shader _shader = NewModAsset.GlitchShader.LoadAsset();
1616
public Material _mat;
17+
1718
public void OnEnable()
1819
{
1920
_mat = new Material(_shader) { hideFlags = HideFlags.DontSave };
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using Reactor.Utilities.Attributes;
3+
using UnityEngine;
4+
5+
namespace NewMod.Components.ScreenEffects
6+
{
7+
[RegisterInIl2Cpp]
8+
public class ShadowFluxEffect(IntPtr ptr) : MonoBehaviour(ptr)
9+
{
10+
public Texture2D texture = NewModAsset.NoiseTex.LoadAsset();
11+
public float noiseScale = 2f;
12+
public float speed = 0.3f;
13+
public float edgeWidth = 0.25f;
14+
public float threshold = 0.55f;
15+
public float opacity = 0.75f;
16+
public float darkness = 0.8f;
17+
public Color tint = Color.white;
18+
public static Shader _shader = NewModAsset.ShadowFluxShader.LoadAsset();
19+
public Material _mat;
20+
21+
public void OnEnable()
22+
{
23+
_mat = new Material(_shader) { hideFlags = HideFlags.DontSave };
24+
_mat.SetTexture("_NoiseTex", texture);
25+
}
26+
public void OnDisable()
27+
{
28+
Destroy(_mat);
29+
}
30+
public void OnRenderImage(RenderTexture src, RenderTexture dst)
31+
{
32+
_mat.SetFloat("_NoiseScale", noiseScale);
33+
_mat.SetFloat("_Speed", speed);
34+
_mat.SetFloat("_EdgeWidth", edgeWidth);
35+
_mat.SetFloat("_Threshold", threshold);
36+
_mat.SetFloat("_Opacity", opacity);
37+
_mat.SetFloat("_Darkness", darkness);
38+
_mat.SetColor("_Tint", tint);
39+
Graphics.Blit(src, dst, _mat);
40+
}
41+
}
42+
}

NewMod/Components/ShadowZone.cs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using MiraAPI.GameOptions;
5+
using NewMod.Components.ScreenEffects;
6+
using NewMod.Options.Roles.ShadeOptions;
7+
using NewMod.Roles.NeutralRoles;
8+
using NewMod.Utilities;
9+
using Reactor.Networking.Attributes;
10+
using Reactor.Utilities;
11+
using Reactor.Utilities.Attributes;
12+
using UnityEngine;
13+
14+
namespace NewMod.Components
15+
{
16+
[RegisterInIl2Cpp]
17+
public class ShadowZone(IntPtr ptr) : MonoBehaviour(ptr)
18+
{
19+
public byte shadeId;
20+
public float radius;
21+
public float duration;
22+
private float timer;
23+
private bool active;
24+
public static readonly List<ShadowZone> zones = new();
25+
26+
public void Awake()
27+
{
28+
if (!zones.Contains(this))
29+
zones.Add(this);
30+
}
31+
32+
public void OnDestroy()
33+
{
34+
zones.Remove(this);
35+
}
36+
37+
private bool Contains(Vector2 pos)
38+
{
39+
return Vector2.Distance(pos, (Vector2)transform.position) <= radius;
40+
}
41+
42+
public void Update()
43+
{
44+
timer += Time.deltaTime;
45+
if (timer >= duration)
46+
{
47+
Coroutines.Start(CoroutinesHelper.RemoveCameraEffect(Camera.main, 0f));
48+
active = false;
49+
Destroy(gameObject);
50+
return;
51+
}
52+
53+
var lp = PlayerControl.LocalPlayer;
54+
var hud = HudManager.Instance;
55+
var killButton = hud.KillButton;
56+
57+
bool inside = Contains(lp.GetTruePosition());
58+
var mode = OptionGroupSingleton<ShadeOptions>.Instance.Behavior;
59+
var cam = Camera.main;
60+
61+
if (inside && !active)
62+
{
63+
cam.gameObject.AddComponent<ShadowFluxEffect>();
64+
if (lp.PlayerId == shadeId && lp.Data.Role is Shade)
65+
{
66+
if (mode is ShadeOptions.ShadowMode.Invisible or ShadeOptions.ShadowMode.Both)
67+
{
68+
lp.cosmetics.SetPhantomRoleAlpha(0);
69+
lp.cosmetics.nameText.gameObject.SetActive(false);
70+
}
71+
72+
killButton.gameObject.SetActive(true);
73+
killButton.currentTarget = null;
74+
}
75+
active = true;
76+
}
77+
78+
if (inside && active && lp.PlayerId == shadeId && lp.Data.Role is Shade)
79+
{
80+
if (mode is ShadeOptions.ShadowMode.KillEnabled or ShadeOptions.ShadowMode.Both)
81+
{
82+
var list = new Il2CppSystem.Collections.Generic.List<PlayerControl>();
83+
lp.Data.Role.GetPlayersInAbilityRangeSorted(list);
84+
var players = list.ToArray().Where(p => p.PlayerId != lp.PlayerId && !p.Data.IsDead).ToList();
85+
var closest = players.Count > 0 ? players[0] : null;
86+
87+
if (killButton.currentTarget && killButton.currentTarget != closest)
88+
killButton.currentTarget.ToggleHighlight(false, RoleTeamTypes.Impostor);
89+
90+
killButton.currentTarget = closest;
91+
if (closest != null)
92+
closest.ToggleHighlight(true, RoleTeamTypes.Impostor);
93+
}
94+
}
95+
else if (!inside && active)
96+
{
97+
Coroutines.Start(CoroutinesHelper.RemoveCameraEffect(cam, 0f));
98+
if (lp.PlayerId == shadeId)
99+
{
100+
lp.cosmetics.SetPhantomRoleAlpha(1);
101+
lp.cosmetics.nameText.gameObject.SetActive(true);
102+
103+
if (killButton.currentTarget)
104+
{
105+
killButton.currentTarget.ToggleHighlight(false, RoleTeamTypes.Impostor);
106+
killButton.currentTarget = null;
107+
}
108+
killButton.gameObject.SetActive(false);
109+
}
110+
active = false;
111+
}
112+
}
113+
114+
public static ShadowZone Create(byte id, Vector2 pos, float r, float dur)
115+
{
116+
var go = new GameObject("ShadowZone");
117+
var z = go.AddComponent<ShadowZone>();
118+
z.shadeId = id;
119+
z.radius = r;
120+
z.duration = dur;
121+
go.transform.position = pos;
122+
return z;
123+
}
124+
125+
[MethodRpc((uint)CustomRPC.DeployZone)]
126+
public static void RpcDeployZone(PlayerControl source, Vector2 pos, float radius, float duration)
127+
{
128+
Create(source.PlayerId, pos, radius, duration);
129+
}
130+
131+
public static bool IsInsideAny(Vector2 pos)
132+
{
133+
return zones.Any(z => z && z.Contains(pos));
134+
}
135+
}
136+
}

NewMod/CustomRPC.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ public enum CustomRPC
1414
SuppressionDome,
1515
WitnessTrap,
1616
NotifyChampion,
17-
SummonNPC
17+
SummonNPC,
18+
BeaconPulse,
19+
DeployZone
1820
}

0 commit comments

Comments
 (0)