Skip to content

Commit f26e6bd

Browse files
committed
Final Shade Role
1 parent 426ea38 commit f26e6bd

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

NewMod/Components/ShadowZone.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ namespace NewMod.Components
1313
public class ShadowZone(IntPtr ptr) : MonoBehaviour(ptr)
1414
{
1515
public byte shadeId;
16-
public float radius = 2.5f;
17-
public float duration = 20f;
16+
public float radius;
17+
public float duration;
1818
public float _t;
1919
public bool _on;
2020
public static List<ShadowZone> zones = new();

NewMod/Options/Roles/ShadeOptions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
namespace NewMod.Options.Roles.ShadeOptions
77
{
8-
/// <summary>
9-
/// Configurable gameplay options for the Shade role.
10-
/// </summary>
118
public class ShadeOptions : AbstractOptionGroup<Shade>
129
{
1310
public override string GroupName => "Shade Options";
@@ -24,6 +21,9 @@ public class ShadeOptions : AbstractOptionGroup<Shade>
2421
[ModdedNumberOption("Shadow Radius", min: 1f, max: 6f, suffixType: MiraNumberSuffixes.None)]
2522
public float Radius { get; set; } = 3f;
2623

24+
[ModdedNumberOption("Required Kills To Win", min: 1f, max: 5f, suffixType: MiraNumberSuffixes.None)]
25+
public float RequiredKills { get; set; } = 3f;
26+
2727
[ModdedEnumOption("Shadow Behavior", typeof(ShadowMode))]
2828
public ShadowMode Behavior { get; set; } = ShadowMode.Invisible;
2929

NewMod/Patches/EndGamePatch.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using MiraAPI.Utilities;
2020
using NewMod.Options.Roles.EnergyThiefOptions;
2121
using NewMod.Options.Roles.WraithCallerOptions;
22+
using NewMod.Options.Roles.ShadeOptions;
2223

2324
namespace NewMod.Patches
2425
{
@@ -131,6 +132,11 @@ public static void OnGameEnd(GameEndEvent evt)
131132
customWinColor = GetRoleColor(GetRoleType<WraithCaller>());
132133
endGameManager.BackgroundBar.material.SetColor("_Color", customWinColor);
133134
break;
135+
case (GameOverReason)NewModEndReasons.ShadeWin:
136+
customWinText = "Darkness Consumes All";
137+
customWinColor = GetRoleColor(GetRoleType<Shade>());
138+
endGameManager.BackgroundBar.material.SetColor("_Color", customWinColor);
139+
break;
134140
default:
135141
customWinText = string.Empty;
136142
customWinColor = Color.white;
@@ -218,6 +224,7 @@ public static bool Prefix(ShipStatus __instance)
218224
if (DestroyableSingleton<TutorialManager>.InstanceExists) return true;
219225
if (Time.timeSinceLevelLoad < 2f) return true;
220226
if (CheckForEndGameFaction<WraithCaller>(__instance, (GameOverReason)NewModEndReasons.WraithCallerWin)) return false;
227+
if (CheckForEndGameFaction<Shade>(__instance, (GameOverReason)NewModEndReasons.ShadeWin)) return false;
221228
if (CheckForEndGameFaction<PulseBlade>(__instance, (GameOverReason)NewModEndReasons.PulseBladeWin)) return false;
222229
if (CheckForEndGameFaction<Tyrant>(__instance, (GameOverReason)NewModEndReasons.TyrantWin)) return false;
223230
if (CheckEndGameForRole<DoubleAgent>(__instance, (GameOverReason)NewModEndReasons.DoubleAgentWin)) return false;
@@ -277,6 +284,12 @@ public static bool CheckForEndGameFaction<TFaction>(ShipStatus __instance, GameO
277284
int current = WraithCallerUtilities.GetKillsNPC(player.PlayerId);
278285
shouldEndGame = current >= required;
279286
}
287+
if (typeof(TFaction) == typeof(Shade))
288+
{
289+
Shade.ShadeKills.TryGetValue(player.PlayerId, out var count);
290+
int required = (int)OptionGroupSingleton<ShadeOptions>.Instance.RequiredKills;
291+
shouldEndGame = count >= required;
292+
}
280293
if (shouldEndGame)
281294
{
282295
GameManager.Instance.RpcEndGame(winReason, false);

NewMod/Patches/Roles/EnergyThief/OnGameEnd.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using HarmonyLib;
22
using NewMod.Utilities;
33
using NewMod.Roles.ImpostorRoles;
4+
using NewMod.Roles.NeutralRoles;
45

56
namespace NewMod.Patches.Roles.EnergyThief;
67

@@ -17,6 +18,7 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] EndGam
1718
PranksterUtilities.ResetReportCount();
1819
VisionaryUtilities.DeleteAllScreenshots();
1920
WraithCallerUtilities.ClearAll();
21+
Shade.ShadeKills.Clear();
2022
Revenant.HasUsedFeignDeath = false;
2123
Revenant.FeignDeathStates.Remove(PlayerControl.LocalPlayer.PlayerId);
2224
Revenant.StalkingStates[PlayerControl.LocalPlayer.PlayerId] = false;

NewMod/Roles/NeutralRoles/Shade.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1+
using System.Collections.Generic;
12
using System.Linq;
23
using System.Text;
34
using Il2CppInterop.Runtime.Attributes;
5+
using MiraAPI.Events;
6+
using MiraAPI.Events.Vanilla.Gameplay;
47
using MiraAPI.GameOptions;
58
using MiraAPI.Roles;
69
using MiraAPI.Utilities;
710
using NewMod.Components;
811
using NewMod.Options.Roles.ShadeOptions;
912
using NewMod.Utilities;
13+
using Reactor.Utilities;
1014
using UnityEngine;
1115

1216
namespace NewMod.Roles.NeutralRoles
1317
{
1418
public class Shade : ImpostorRole, INewModRole
1519
{
20+
public static readonly Dictionary<byte, int> ShadeKills = new();
1621
public string RoleName => "Shade";
1722
public string RoleDescription => "Lurk. Fade. Kill unseen.";
1823
public string RoleLongDescription => "Deploy a shadow field that grants invisibility and lethal power within its darkness.";
@@ -55,10 +60,35 @@ public StringBuilder SetTabText()
5560

5661
return tabText;
5762
}
58-
5963
public override bool DidWin(GameOverReason gameOverReason)
6064
{
6165
return gameOverReason == (GameOverReason)NewModEndReasons.ShadeWin;
6266
}
67+
68+
[RegisterEvent]
69+
public static void OnAfterMurder(AfterMurderEvent evt)
70+
{
71+
var killer = evt.Source;
72+
var victim = evt.Target;
73+
74+
Utils.RecordOnKill(killer, victim);
75+
76+
if (killer.Data.Role is not Shade shadeRole)
77+
return;
78+
79+
if (!ShadowZone.IsInsideAny(victim.GetTruePosition()))
80+
return;
81+
82+
byte id = killer.PlayerId;
83+
ShadeKills[id] = ShadeKills.GetValueOrDefault(id) + 1;
84+
85+
if (killer.AmOwner)
86+
{
87+
int required = (int)OptionGroupSingleton<ShadeOptions>.Instance.RequiredKills;
88+
Coroutines.Start(CoroutinesHelper.CoNotify(
89+
$"<color=#8E44AD>Shadow Harvest</color>\nKills: {ShadeKills[id]}/{required}"
90+
));
91+
}
92+
}
6393
}
6494
}

0 commit comments

Comments
 (0)