Skip to content

Commit 22bce33

Browse files
Merge pull request #15 from CallOfCreator/dev
v1.2.4 Update
2 parents 5b72b2f + 25c2765 commit 22bce33

58 files changed

Lines changed: 1667 additions & 289 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
bin/
22
obj/
33
References/
4-
NewMod/Components
4+
NewMod/Components/Minigames
5+
NewMod/Components/Hidden.cs
56
/packages/
67
riderModule.iml
78
.idea

NewMod/Buttons/EnergyThief/DrainButton.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using ET = NewMod.Roles.NeutralRoles.EnergyThief;
77
using UnityEngine;
88
using NewMod.Utilities;
9+
using Rewired;
910

1011
namespace NewMod.Buttons.EnergyThief
1112
{
@@ -33,6 +34,11 @@ public class DrainButton : CustomActionButton<PlayerControl>
3334
/// The on-screen position of this button.
3435
/// </summary>
3536
public override ButtonLocation Location => ButtonLocation.BottomRight;
37+
38+
/// <summary>
39+
/// Default keybind for EnergyThief's Drain ability.
40+
/// </summary>
41+
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.F;
3642

3743
/// <summary>
3844
/// The duration of the effect applied by this button; in this case, zero.
@@ -50,7 +56,7 @@ public class DrainButton : CustomActionButton<PlayerControl>
5056
/// <returns>The closest valid PlayerControl, or null if none.</returns>
5157
public override PlayerControl GetTarget()
5258
{
53-
return PlayerControl.LocalPlayer.GetClosestPlayer(true, Distance, false, p => !p.Data.IsDead && !p.Data.Disconnected);
59+
return PlayerControl.LocalPlayer.GetClosestPlayer(true, Distance, false, false, p => !p.Data.IsDead && !p.Data.Disconnected);
5460
}
5561

5662
/// <summary>

NewMod/Buttons/Injector/InjectButton.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using MiraAPI.Utilities;
88
using System;
99
using static NewMod.Utilities.Utils;
10+
using Rewired;
1011

1112
namespace NewMod.Buttons.Injector
1213
{
@@ -29,7 +30,7 @@ public class InjectButton : CustomActionButton<PlayerControl>
2930
/// <summary>
3031
/// Maximum allowed injections, configured via <see cref="InjectorOptions"/>.
3132
/// </summary>
32-
public override int MaxUses => OptionGroupSingleton<InjectorOptions>.Instance.MaxSerumUses;
33+
public override int MaxUses => (int)OptionGroupSingleton<InjectorOptions>.Instance.MaxSerumUses;
3334

3435
/// <summary>
3536
/// Effect duration — unused here since injection is instant.
@@ -41,10 +42,15 @@ public class InjectButton : CustomActionButton<PlayerControl>
4142
/// </summary>
4243
public override ButtonLocation Location => ButtonLocation.BottomLeft;
4344

45+
/// <summary>
46+
/// Default keybind for Injector's Inject ability.
47+
/// </summary>
48+
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.C;
49+
4450
/// <summary>
4551
/// Sprite/icon displayed on the button.
4652
/// </summary>
47-
public override LoadableAsset<Sprite> Sprite => MiraAssets.Empty;
53+
public override LoadableAsset<Sprite> Sprite => NewModAsset.InjectButton;
4854

4955
/// <summary>
5056
/// Returns the closest valid player target within range,
@@ -81,10 +87,10 @@ public override bool Enabled(RoleBehaviour role)
8187
/// </summary>
8288
protected override void OnClick()
8389
{
84-
var serumValues = Enum.GetValues(typeof(SerumType));
85-
SerumType randomSerum = (SerumType)serumValues.GetValue(UnityEngine.Random.Range(0, serumValues.Length));
86-
87-
RpcApplySerum(PlayerControl.LocalPlayer, Target, randomSerum);
90+
var values = (SerumType[])Enum.GetValues(typeof(SerumType));
91+
var serum = values[UnityEngine.Random.Range(0, values.Length)];
92+
93+
RpcApplySerum(PlayerControl.LocalPlayer, Target, serum);
8894
}
8995
}
9096
}

NewMod/Buttons/Necromancer/ReviveButton.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using NewMod.Roles.ImpostorRoles;
66
using UnityEngine;
77
using NewMod.Utilities;
8+
using Rewired;
89

910
namespace NewMod.Buttons.Necromancer
1011
{
@@ -33,6 +34,11 @@ public class ReviveButton : CustomActionButton
3334
/// </summary>
3435
public override float EffectDuration => 0f;
3536

37+
/// <summary>
38+
/// Default keybind for Necromancer's Revive ability.
39+
/// </summary>
40+
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.V;
41+
3642
/// <summary>
3743
/// Defines where on the screen this button should appear.
3844
/// </summary>

NewMod/Buttons/Overload/OverloadButton.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using MiraAPI.Hud;
22
using MiraAPI.Utilities.Assets;
33
using NewMod.Roles.NeutralRoles;
4+
using Rewired;
45
using UnityEngine;
56

67
namespace NewMod.Buttons.Overload
@@ -41,6 +42,12 @@ public class OverloadButton : CustomActionButton
4142
/// </summary>
4243
public float absorbedCooldown;
4344

45+
/// <summary>
46+
/// Stores the default key assigned to the absorbed button's action.
47+
/// Mirrors the keybind of the original absorbed button.
48+
/// </summary>
49+
public KeyboardKeyCode absorbedKeybind;
50+
4451
/// <summary>
4552
/// The name displayed on the button.
4653
/// </summary>
@@ -56,6 +63,11 @@ public class OverloadButton : CustomActionButton
5663
/// </summary>
5764
public override int MaxUses => absorbedMaxUses;
5865

66+
/// <summary>
67+
/// Default keybind for Overload's Overload ability.
68+
/// </summary>
69+
public override KeyboardKeyCode Defaultkeybind => absorbedKeybind;
70+
5971
/// <summary>
6072
/// Determines how long the effect from clicking the button lasts. In this case, no duration is set.
6173
/// </summary>
@@ -81,6 +93,7 @@ public void Absorb(CustomActionButton target)
8193
absorbedCooldown = target.Cooldown;
8294
absorbedMaxUses = target.MaxUses;
8395
absorbedSprite = target.Sprite;
96+
absorbedKeybind = target.Defaultkeybind;
8497
absorbedOnClick = () => target.GetType().GetMethod("OnClick", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
8598
?.Invoke(target, null);
8699

NewMod/Buttons/Prankster/FakeBodyButton.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using PRK = NewMod.Roles.NeutralRoles.Prankster;
77
using UnityEngine;
88
using NewMod.Utilities;
9+
using Rewired;
910

1011
namespace NewMod.Buttons.Prankster
1112
{
@@ -34,6 +35,11 @@ public class FakeBodyButton : CustomActionButton
3435
/// </summary>
3536
public override ButtonLocation Location => ButtonLocation.BottomRight;
3637

38+
/// <summary>
39+
/// Default keybind for Prankster's Fake Body ability.
40+
/// </summary>
41+
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.Z;
42+
3743
/// <summary>
3844
/// The duration of any effect caused by this button press; in this case, no effect duration is used.
3945
/// </summary>
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
using System.Collections;
2+
using System.Linq;
3+
using MiraAPI.GameOptions;
4+
using MiraAPI.Hud;
5+
using MiraAPI.Utilities.Assets;
6+
using UnityEngine;
7+
using Pb = NewMod.Roles.ImpostorRoles.PulseBlade;
8+
using MiraAPI.Networking;
9+
using NewMod.Options.Roles.PulseBladeOptions;
10+
using Reactor.Utilities;
11+
using MiraAPI.Utilities;
12+
using NewMod.Utilities;
13+
using Reactor.Networking.Attributes;
14+
using Rewired;
15+
16+
namespace NewMod.Buttons.Pulseblade
17+
{
18+
/// <summary>
19+
/// Custom button for the Pulseblade role to perform a high-speed strike on the closest player in aim direction.
20+
/// The strike teleports the user toward the target and executes a stealthy instant kill.
21+
/// </summary>
22+
public class StrikeButton : CustomActionButton
23+
{
24+
/// <summary>
25+
/// Display name for the button (not shown by default).
26+
/// </summary>
27+
public override string Name => "Strike";
28+
29+
/// <summary>
30+
/// Cooldown between strikes, pulled from <see cref="PulseBladeOptions.StrikeCooldown"/>.
31+
/// </summary>
32+
public override float Cooldown => OptionGroupSingleton<PulseBladeOptions>.Instance.StrikeCooldown;
33+
34+
/// <summary>
35+
/// Maximum number of strike uses, from <see cref="PulseBladeOptions.MaxStrikeUses"/>.
36+
/// </summary>
37+
public override int MaxUses => (int)OptionGroupSingleton<PulseBladeOptions>.Instance.MaxStrikeUses;
38+
39+
/// <summary>
40+
/// Effect duration (not used for this button).
41+
/// </summary>
42+
public override float EffectDuration => 0f;
43+
44+
/// <summary>
45+
/// Placement of the button on the HUD.
46+
/// </summary>
47+
public override ButtonLocation Location => ButtonLocation.BottomRight;
48+
49+
/// <summary>
50+
/// Default keybind for Pulseblade's Strike ability.
51+
/// Requires Shift as a modifier to prevent accidental use.
52+
/// </summary>
53+
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.G;
54+
public override ModifierKey Modifier1 => ModifierKey.Shift;
55+
/// <summary>
56+
/// Sprite used for the button — set to empty;
57+
/// </summary>
58+
public override LoadableAsset<Sprite> Sprite => NewModAsset.StrikeButton;
59+
60+
/// <summary>
61+
/// Determines whether the button is active for a given role.
62+
/// </summary>
63+
/// <param name="role">The current player's role.</param>
64+
/// <returns>True only for Pulseblade role.</returns>
65+
public override bool Enabled(RoleBehaviour role) => role is Pb;
66+
67+
/// <summary>
68+
/// Called when the button is pressed by the player.
69+
/// Searches for a valid target and executes the strike.
70+
/// </summary>
71+
protected override void OnClick()
72+
{
73+
var player = PlayerControl.LocalPlayer;
74+
75+
var target = PlayerControl.AllPlayerControls
76+
.ToArray()
77+
.Where(p => p != player && !p.Data.IsDead && !p.Data.Disconnected && !p.inVent)
78+
.OrderBy(p => Vector2.Distance(player.GetTruePosition(), p.GetTruePosition()))
79+
.FirstOrDefault(p => Vector2.Distance(player.GetTruePosition(), p.GetTruePosition()) <= OptionGroupSingleton<PulseBladeOptions>.Instance.StrikeRange);
80+
81+
RpcPulseStrike(player, target);
82+
}
83+
84+
/// <summary>
85+
/// RPC method to perform a Pulseblade strike on a target.
86+
/// </summary>
87+
/// <param name="source">The player performing the strike.</param>
88+
/// <param name="target">The victim of the strike.</param>
89+
[MethodRpc((uint)CustomRPC.Dash)]
90+
public static void RpcPulseStrike(PlayerControl source, PlayerControl target)
91+
{
92+
Coroutines.Start(DoPulseStrike(source, target));
93+
}
94+
95+
/// <summary>
96+
/// Executes the strike: dashes to the target and performs a kill.
97+
/// Hides the body for a short time.
98+
/// </summary>
99+
/// <param name="killer">The Pulseblade player.</param>
100+
/// <param name="target">The struck victim.</param>
101+
/// <returns>IEnumerator.</returns>
102+
public static IEnumerator DoPulseStrike(PlayerControl killer, PlayerControl target)
103+
{
104+
var sound = NewModAsset.StrikeSound.LoadAsset();
105+
float originalSpeed = killer.MyPhysics.Speed;
106+
float dashSpeed = OptionGroupSingleton<PulseBladeOptions>.Instance.DashSpeed;
107+
108+
killer.moveable = false;
109+
killer.MyPhysics.inputHandler.enabled = false;
110+
killer.MyPhysics.Speed = dashSpeed;
111+
112+
while (Vector2.Distance(killer.GetTruePosition(), target.GetTruePosition()) > 0.1f)
113+
{
114+
Vector2 dir = target.GetTruePosition() - killer.GetTruePosition();
115+
killer.MyPhysics.SetNormalizedVelocity(dir.normalized);
116+
117+
float step = killer.MyPhysics.TrueSpeed * Time.fixedDeltaTime;
118+
if (step >= dir.magnitude) break;
119+
120+
yield return new WaitForFixedUpdate();
121+
}
122+
123+
killer.MyPhysics.SetNormalizedVelocity(Vector2.zero);
124+
killer.MyPhysics.Speed = originalSpeed;
125+
killer.MyPhysics.inputHandler.enabled = true;
126+
killer.moveable = true;
127+
128+
SoundManager.Instance.PlaySound(sound, false, 1f);
129+
130+
killer.RpcCustomMurder(
131+
target,
132+
didSucceed: true,
133+
resetKillTimer: false,
134+
createDeadBody: true,
135+
teleportMurderer: false,
136+
showKillAnim: false,
137+
playKillSound: false
138+
);
139+
140+
Utils.RegisterStrikeKill(killer, target);
141+
142+
var notif = Helpers.CreateAndShowNotification($"Perfect kill {target.Data.PlayerName} eliminated", new(1f, 0.25f, 0.25f), spr: NewModAsset.StrikeIcon.LoadAsset());
143+
notif.Text.SetOutlineThickness(0.30f);
144+
145+
var bodies = Helpers.GetNearestDeadBodies(target.GetTruePosition(), 0.5f, Helpers.CreateFilter(Constants.NotShipMask));
146+
if (bodies != null && bodies.Count > 0)
147+
{
148+
foreach (var b in bodies) if (b) b.gameObject.SetActive(false);
149+
yield return new WaitForSeconds(OptionGroupSingleton<PulseBladeOptions>.Instance.HideBodyDuration);
150+
foreach (var b in bodies) if (b) b.gameObject.SetActive(true);
151+
}
152+
}
153+
}
154+
}

NewMod/Buttons/Revenant/DoomAwakening.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using NewMod.Utilities;
1010
using Reactor.Utilities;
1111
using UnityEngine;
12+
using TMPro;
13+
using Rewired;
1214

1315
namespace NewMod.Buttons.Revenant
1416
{
@@ -37,6 +39,12 @@ public class DoomAwakening : CustomActionButton
3739
/// </summary>
3840
public override ButtonLocation Location => ButtonLocation.BottomLeft;
3941

42+
/// <summary>
43+
/// Default keybind for Doom's Awakening ability.
44+
/// Requires Alt as a modifier to prevent accidental use.
45+
/// </summary>
46+
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.B;
47+
public override ModifierKey Modifier1 => ModifierKey.Alt;
4048
/// <summary>
4149
/// Determines how long the effect lasts. Configured in <see cref="RevenantOptions"/>.
4250
/// </summary>
@@ -191,7 +199,9 @@ public System.Collections.IEnumerator StartDoomAwakening(PlayerControl player)
191199
SoundManager.Instance.StopSound(clip);
192200
RV.StalkingStates.Remove(player.PlayerId);
193201
Coroutines.Start(CoroutinesHelper.CoNotify("<color=green>Doom Awakening ended.</color>"));
194-
Helpers.CreateAndShowNotification($"Doom Awakening killed {killCount} players", Color.red, null, null);
202+
203+
var doomNotif = Helpers.CreateAndShowNotification($"<font=\"LiberationSans SDF\" material=\"LiberationSans SDF - Masked>Doom Awakening killed {killCount} players", Color.red, null, null);
204+
doomNotif.Text.SetOutlineThickness(0.36f);
195205
killedPlayers.Clear();
196206
}
197207
}

NewMod/Buttons/Revenant/FeignDeathButton.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using NewMod.Utilities;
77
using Reactor.Utilities;
88
using UnityEngine;
9+
using Rewired;
910

1011
namespace NewMod.Buttons.Revenant
1112
{
@@ -34,6 +35,13 @@ public class FeignDeathButton : CustomActionButton
3435
/// </summary>
3536
public override ButtonLocation Location => ButtonLocation.BottomRight;
3637

38+
/// <summary>
39+
/// Default keybind for Revenant's Feign Death ability.
40+
/// Requires Ctrl as a modifier to prevent accidental use.
41+
/// </summary>
42+
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.T;
43+
public override ModifierKey Modifier1 => ModifierKey.Control;
44+
3745
/// <summary>
3846
/// The duration of any effect from this button. In this case, zero.
3947
/// </summary>

0 commit comments

Comments
 (0)