Skip to content

Commit 1d21ae4

Browse files
committed
Revive button fixes, end game fixes
1 parent 9e0c5a0 commit 1d21ae4

11 files changed

Lines changed: 178 additions & 59 deletions

File tree

NewMod/Buttons/Necromancer/ReviveButton.cs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using MiraAPI.Keybinds;
99
using AmongUs.GameOptions;
1010
using Reactor.Utilities;
11+
using MiraAPI.Utilities;
12+
using System.Linq;
1113

1214
namespace NewMod.Buttons.Necromancer
1315
{
@@ -56,24 +58,26 @@ public class ReviveButton : CustomActionButton
5658
/// </summary>
5759
protected override void OnClick()
5860
{
59-
var closestBody = Utils.GetClosestBody();
60-
var killedPlayer = GameData.Instance.GetPlayerById(closestBody.ParentId)?.Object;
61+
var local = PlayerControl.LocalPlayer;
6162

62-
var killer = Utils.GetKiller(killedPlayer);
63-
if (killer != null && killer.PlayerId == PlayerControl.LocalPlayer.PlayerId)
64-
{
65-
Coroutines.Start(CoroutinesHelper.CoNotify("Heads up: you tried to revive someone you killed, one use has been consumed"));
66-
return;
67-
}
63+
var body = Helpers.GetNearestDeadBodies(
64+
local.GetTruePosition(),
65+
ShipStatus.Instance.MaxLightRadius,
66+
Helpers.CreateFilter(Constants.NotShipMask))
67+
.Where(b => b != null && !PranksterUtilities.IsPranksterBody(b))
68+
.OrderBy(b => Vector2.Distance(local.GetTruePosition(), b.TruePosition))
69+
.FirstOrDefault();
70+
71+
if (body == null) return;
6872

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

7175
Utils.HandleRevive(
72-
PlayerControl.LocalPlayer,
73-
closestBody.ParentId,
76+
local,
77+
body.ParentId,
7478
RoleTypes.Impostor,
75-
closestBody.transform.position.x,
76-
closestBody.transform.position.y
79+
body.transform.position.x,
80+
body.transform.position.y
7781
);
7882
}
7983
/// <summary>
@@ -92,15 +96,28 @@ public override bool Enabled(RoleBehaviour role)
9296
/// <returns>True if all requirements to use this button are met; otherwise false.</returns>
9397
public override bool CanUse()
9498
{
95-
if (Timer > 0) return false;
96-
if (UsesLeft <= 0) return false;
99+
var bodiesInRange = Helpers.GetNearestDeadBodies(
100+
PlayerControl.LocalPlayer.transform.position,
101+
ShipStatus.Instance.MaxLightRadius,
102+
Helpers.CreateFilter(Constants.NotShipMask));
103+
104+
bool canUse = bodiesInRange.Any(body =>
105+
{
106+
if (PranksterUtilities.IsPranksterBody(body)) return false;
107+
108+
var killedPlayer = GameData.Instance.GetPlayerById(body.ParentId)?.Object;
109+
if (killedPlayer == null) return false;
110+
111+
var killer = Utils.GetKiller(killedPlayer);
112+
if (killer.PlayerId == PlayerControl.LocalPlayer.PlayerId)
113+
return false;
97114

98-
var closestBody = Utils.GetClosestBody();
99-
if (closestBody == null) return false;
115+
return true;
116+
});
100117

101-
if (PranksterUtilities.IsPranksterBody(closestBody)) return false;
118+
NewMod.Instance.Log.LogMessage($"[ReviveButton] CanUse: {canUse}");
102119

103-
return true;
120+
return canUse;
104121
}
105122
}
106123
}

NewMod/NewModEventHandler.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Reflection;
55
using MiraAPI.Events;
66
using MiraAPI.Events.Vanilla.Gameplay;
7+
using NewMod.Utilities;
78

89
namespace NewMod
910
{
@@ -63,6 +64,8 @@ public static void OnRoundStart(RoundStartEvent evt)
6364
if (!evt.TriggeredByIntro) return;
6465

6566
HudManager.Instance.Chat.enabled = false;
67+
68+
Utils.ResetKillTracking();
6669
}
6770
}
6871
}

NewMod/Patches/EndGamePatch.cs

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ namespace NewMod.Patches
2525
{
2626
public static class EndGamePatch
2727
{
28+
public static bool EndGameTriggered = false;
29+
30+
[RegisterEvent]
31+
public static void OnGameStart(RoundStartEvent evt)
32+
{
33+
EndGameTriggered = false;
34+
EndGameResult.CachedWinners.Clear();
35+
}
36+
2837
[RegisterEvent]
2938
public static void OnGameEnd(GameEndEvent evt)
3039
{
@@ -68,6 +77,7 @@ public static void OnGameEnd(GameEndEvent evt)
6877
{
6978
poolablePlayer.SetFlipX(i % 2 == 0);
7079
}
80+
7181
poolablePlayer.UpdateFromPlayerOutfit(
7282
playerData.Outfit,
7383
PlayerMaterial.MaskType.None,
@@ -151,6 +161,7 @@ public static void OnGameEnd(GameEndEvent evt)
151161
endGameManager.WinText.transform.position.y - 0.5f,
152162
endGameManager.WinText.transform.position.z);
153163
customWinTextObject.transform.localScale = new Vector3(0.7f, 0.7f, 1f);
164+
154165
var customWinTextComponent = customWinTextObject.GetComponent<TMPro.TMP_Text>();
155166
customWinTextComponent.text = customWinText;
156167
customWinTextComponent.color = customWinColor;
@@ -173,6 +184,7 @@ public static string GetRoleName(CachedPlayerData playerData, out Color roleColo
173184
{
174185
return $"{newmodRole.RoleName}\n<size=65%>{Utils.GetFactionDisplay((INewModRole)customRole)}</size>";
175186
}
187+
176188
return customRole.RoleName;
177189
}
178190
else
@@ -214,6 +226,20 @@ private static Color GetRoleColor(RoleTypes roleType)
214226
return Color.white;
215227
}
216228
}
229+
230+
public static bool EndCustomGame(GameOverReason reason, Action winners = null)
231+
{
232+
if (EndGameTriggered) return true;
233+
if (EndGameResult.CachedWinners.Count > 0) return true;
234+
235+
EndGameTriggered = true;
236+
237+
EndGameResult.CachedWinners.Clear();
238+
winners?.Invoke();
239+
240+
GameManager.Instance.RpcEndGame(reason, false);
241+
return true;
242+
}
217243
}
218244

219245
[HarmonyPatch(typeof(LogicGameFlowNormal), nameof(LogicGameFlowNormal.CheckEndCriteria))]
@@ -222,7 +248,10 @@ public static class CheckGameEndPatch
222248
public static bool Prefix(ShipStatus __instance)
223249
{
224250
if (DestroyableSingleton<TutorialManager>.InstanceExists) return true;
251+
if (!AmongUsClient.Instance.AmHost) return true;
225252
if (Time.timeSinceLevelLoad < 2f) return true;
253+
if (EndGamePatch.EndGameTriggered) return false;
254+
226255
if (CheckForEndGameFaction<WraithCaller>(__instance, (GameOverReason)NewModEndReasons.WraithCallerWin)) return false;
227256
if (CheckForEndGameFaction<Shade>(__instance, (GameOverReason)NewModEndReasons.ShadeWin)) return false;
228257
if (CheckForEndGameFaction<PulseBlade>(__instance, (GameOverReason)NewModEndReasons.PulseBladeWin)) return false;
@@ -231,18 +260,22 @@ public static bool Prefix(ShipStatus __instance)
231260
if (CheckEndGameForRole<SpecialAgent>(__instance, (GameOverReason)NewModEndReasons.SpecialAgentWin)) return false;
232261
if (CheckEndGameForRole<Prankster>(__instance, (GameOverReason)NewModEndReasons.PranksterWin, 3)) return false;
233262
if (CheckEndGameForRole<EnergyThief>(__instance, (GameOverReason)NewModEndReasons.EnergyThiefWin)) return false;
263+
if (CheckEndGameForRole<InjectorRole>(__instance, (GameOverReason)NewModEndReasons.InjectorWin)) return false;
264+
234265
return true;
235266
}
267+
236268
public static bool CheckForEndGameFaction<TFaction>(ShipStatus __instance, GameOverReason winReason, int maxCount = 1) where TFaction : INewModRole
237269
{
238270
var players = PlayerControl.AllPlayerControls.ToArray()
239-
.Where(p => p.Data.Role is TFaction)
240-
.Take(maxCount)
241-
.ToList();
271+
.Where(p => p.Data.Role is TFaction)
272+
.Take(maxCount)
273+
.ToList();
242274

243275
foreach (var player in players)
244276
{
245277
bool shouldEndGame = false;
278+
Action extraWinners = null;
246279

247280
if (typeof(TFaction) == typeof(PulseBlade))
248281
{
@@ -260,51 +293,58 @@ public static bool CheckForEndGameFaction<TFaction>(ShipStatus __instance, GameO
260293
shouldEndGame = true;
261294
}
262295
}
296+
263297
if (typeof(TFaction) == typeof(Tyrant))
264298
{
265299
if (Tyrant.ApexThroneReady && Tyrant.ApexThroneOutcomeSet)
266300
{
267301
shouldEndGame = true;
268302

269-
var tyrantRole = player.Data.Role as Tyrant;
270-
byte champId = tyrantRole.GetChampion();
271-
var champion = Utils.PlayerById(champId);
303+
extraWinners = () =>
304+
{
305+
var tyrantRole = player.Data.Role as Tyrant;
306+
byte champId = tyrantRole.GetChampion();
307+
var champion = Utils.PlayerById(champId);
272308

273-
bool championWin = Tyrant.Outcome == Tyrant.ThroneOutcome.ChampionSideWin;
309+
bool championWin = Tyrant.Outcome == Tyrant.ThroneOutcome.ChampionSideWin;
274310

275-
if (champion && championWin)
276-
{
277-
EndGameResult.CachedWinners.Add(new(champion.Data));
278-
}
311+
if (champion && championWin)
312+
{
313+
EndGameResult.CachedWinners.Add(new(champion.Data));
314+
}
315+
};
279316
}
280317
}
318+
281319
if (typeof(TFaction) == typeof(WraithCaller))
282320
{
283321
int required = (int)OptionGroupSingleton<WraithCallerOptions>.Instance.RequiredNPCsToSend;
284322
int current = WraithCallerUtilities.GetKillsNPC(player.PlayerId);
285323
shouldEndGame = current >= required;
286324
}
325+
287326
if (typeof(TFaction) == typeof(Shade))
288327
{
289328
Shade.ShadeKills.TryGetValue(player.PlayerId, out var count);
290329
int required = (int)OptionGroupSingleton<ShadeOptions>.Instance.RequiredKills;
291330
shouldEndGame = count >= required;
292331
}
332+
293333
if (shouldEndGame)
294334
{
295-
GameManager.Instance.RpcEndGame(winReason, false);
296-
CustomStatsManager.IncrementRoleWin((INewModRole)player.Data.Role);
297-
return true;
335+
return EndGamePatch.EndCustomGame(winReason, extraWinners);
298336
}
299337
}
338+
300339
return false;
301340
}
341+
302342
public static bool CheckEndGameForRole<T>(ShipStatus __instance, GameOverReason winReason, int maxCount = 1) where T : RoleBehaviour
303343
{
304344
var rolePlayers = PlayerControl.AllPlayerControls.ToArray()
305-
.Where(p => p.Data.Role is T)
306-
.Take(maxCount)
307-
.ToList();
345+
.Where(p => p.Data.Role is T)
346+
.Take(maxCount)
347+
.ToList();
308348

309349
foreach (var player in rolePlayers)
310350
{
@@ -316,40 +356,43 @@ public static bool CheckEndGameForRole<T>(ShipStatus __instance, GameOverReason
316356
bool isSabotageActive = Utils.IsSabotage();
317357
shouldEndGame = tasksCompleted && isSabotageActive;
318358
}
359+
319360
if (typeof(T) == typeof(EnergyThief))
320361
{
321362
int drainCount = Utils.GetDrainCount(player.PlayerId);
322363
int requiredDrainCount = (int)OptionGroupSingleton<EnergyThiefOptions>.Instance.RequiredDrainCount;
323-
324364
shouldEndGame = drainCount >= requiredDrainCount;
325365
}
366+
326367
if (typeof(T) == typeof(Prankster))
327368
{
328369
int WinReportCount = 2;
329370
int currentReportCount = PranksterUtilities.GetReportCount(player.PlayerId);
330371
shouldEndGame = currentReportCount >= WinReportCount;
331372
}
373+
332374
if (typeof(T) == typeof(SpecialAgent))
333375
{
334376
int missionSuccessCount = Utils.GetMissionSuccessCount(player.PlayerId);
335377
int missionFailureCount = Utils.GetMissionFailureCount(player.PlayerId);
336378
int netScore = missionSuccessCount - missionFailureCount;
337379
shouldEndGame = netScore >= OptionGroupSingleton<SpecialAgentOptions>.Instance.RequiredMissionsToWin;
338380
}
381+
339382
if (typeof(T) == typeof(InjectorRole))
340383
{
341384
int injectedCount = Utils.GetInjectedCount();
342385
int required = (int)OptionGroupSingleton<InjectorOptions>.Instance.RequiredInjectCount;
343386
shouldEndGame = injectedCount >= required;
344387
}
388+
345389
if (shouldEndGame)
346390
{
347-
GameManager.Instance.RpcEndGame(winReason, false);
348-
CustomStatsManager.IncrementRoleWin((ICustomRole)player.Data.Role);
349-
return true;
391+
return EndGamePatch.EndCustomGame(winReason);
350392
}
351393
}
394+
352395
return false;
353396
}
354397
}
355-
}
398+
}

NewMod/Patches/RolePatch.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Linq;
55
using AmongUs.GameOptions;
66
using HarmonyLib;
7-
using Hazel;
87
using MiraAPI.GameOptions;
98
using MiraAPI.Roles;
109
using MiraAPI.Utilities;
@@ -31,7 +30,7 @@ public static void Postfix(RoleManager __instance)
3130
private static IEnumerator CoAdjustNeutrals()
3231
{
3332
yield return null;
34-
yield return new WaitForSeconds(0.05f);
33+
yield return new WaitForSeconds(0.06f);
3534

3635
var opts = OptionGroupSingleton<GeneralOption>.Instance;
3736
int target = Mathf.RoundToInt(opts.TotalNeutrals);
@@ -220,7 +219,7 @@ private static IEnumerator CoAdjustNeutrals()
220219
Logger<NewMod>.Instance.LogMessage("-------------- NEUTRAL ADJUST: END --------------");
221220
}
222221

223-
public struct Candidate
222+
public class Candidate
224223
{
225224
public ICustomRole Role;
226225
public int Left;

NewMod/Patches/Roles/EnergyThief/OnGameEnd.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] EndGam
1515
Utils.ResetMissionFailureCount();
1616
Utils.ResetInjections();
1717
Utils.ResetStrikeCount();
18+
Utils.ResetKillTracking();
1819
PranksterUtilities.ResetReportCount();
1920
VisionaryUtilities.DeleteAllScreenshots();
2021
WraithCallerUtilities.ClearAll();

NewMod/Roles/ImpostorRoles/Necromancer.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ public class NecromancerRole : ImpostorRole, ICustomRole
2424
public TeamIntroConfiguration TeamConfiguration => new()
2525
{
2626
IntroTeamDescription = RoleDescription,
27-
IntroTeamColor = RoleColor
27+
IntroTeamColor = RoleColor
2828
};
29+
public override bool DidWin(GameOverReason reason)
30+
{
31+
if (reason == (GameOverReason)NewModEndReasons.TyrantWin ||
32+
reason == (GameOverReason)NewModEndReasons.ShadeWin ||
33+
reason == (GameOverReason)NewModEndReasons.WraithCallerWin ||
34+
reason == (GameOverReason)NewModEndReasons.SpecialAgentWin ||
35+
reason == (GameOverReason)NewModEndReasons.PranksterWin ||
36+
reason == (GameOverReason)NewModEndReasons.EnergyThiefWin ||
37+
reason == (GameOverReason)NewModEndReasons.InjectorWin ||
38+
reason == (GameOverReason)NewModEndReasons.DoubleAgentWin)
39+
{
40+
return false;
41+
}
42+
43+
return base.DidWin(reason);
44+
}
2945
}

0 commit comments

Comments
 (0)