Skip to content

Commit

Permalink
Update 2.0, Time Master and Investigator rewrite
Browse files Browse the repository at this point in the history
Rewriting of the Time Master and the Investigator
The time master now stores the position of all players..
The animation of the footprints is now managed by a coroutine.
  • Loading branch information
Hardel-DW committed Mar 12, 2021
1 parent ba6a284 commit a285d2d
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 159 deletions.
2 changes: 1 addition & 1 deletion RolesMods/Patch/EndGamePatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static void ResetGlobalVariable() {
GlobalVariable.isGameStarted = false;
Systems.Investigator.FootPrint.allFootprint.Clear();
HelperRoles.ClearRoles();
Systems.TimeMaster.Time.pointsInTime.Clear();
Systems.TimeMaster.Time.ClearGameHistory();
}
}
}
11 changes: 1 addition & 10 deletions RolesMods/Patch/HandleRpcPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static bool Prefix([HarmonyArgument(0)] byte callId, [HarmonyArgument(1)]
return false;
}

if (callId == (byte) CustomRPC.SetLighter) {
if (callId == (byte) CustomRPC.SetPsychic) {
GlobalVariable.PsychicList.Clear();
List<byte> selectedPlayers = reader.ReadBytesAndSize().ToList();

Expand All @@ -62,15 +62,6 @@ public static bool Prefix([HarmonyArgument(0)] byte callId, [HarmonyArgument(1)]
return false;
}

if (callId == (byte) CustomRPC.TimeRevive) {
PlayerControl player = PlayerControlUtils.FromPlayerId(reader.ReadByte());
player.Revive();
var body = Object.FindObjectsOfType<DeadBody>().FirstOrDefault(b => b.ParentId == player.PlayerId);

if (body != null)
Object.Destroy(body.gameObject);
return false;
}

if (callId == (byte) CustomRPC.SendOverlayPsychic) {
bool show = reader.ReadBoolean();
Expand Down
2 changes: 1 addition & 1 deletion RolesMods/Patch/StartPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public static void Postfix(ShipStatus __instance) {
GlobalVariable.texts.Clear();
GlobalVariable.herePoints.Clear();

Systems.TimeMaster.Time.pointsInTime.Clear();
Systems.TimeMaster.Time.ClearGameHistory();
Systems.Investigator.FootPrint.allFootprint.Clear();
GlobalVariable.buttonTime.MaxTimer = RolesMods.TimeMasterCooldown.GetValue();
GlobalVariable.buttonTime.EffectDuration = RolesMods.TimeMasterDuration.GetValue() / 2;
Expand Down
2 changes: 1 addition & 1 deletion RolesMods/RolesMods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class RolesMods : BasePlugin {
// Investigator CustomOptions
public static CustomToggleOption EnableInvestigator = CustomOption.AddToggle("Enable Investigator", false);
public static CustomNumberOption NumberInvestigator = CustomOption.AddNumber("Number Investigator", 1f, 1f, 10f, 1f);
public static CustomNumberOption footPrintSize = CustomOption.AddNumber("Footprint Size", 0.25f, 0.5f, 0.05f, 0.05f);
public static CustomNumberOption footPrintSize = CustomOption.AddNumber("Footprint Size", 0.75f, 0.3f, 1f, 0.1f);
public static CustomNumberOption fontPrintInterval = CustomOption.AddNumber("Footprint Interval", 1f, 0.25f, 5f, 0.25f);
public static CustomNumberOption fontPrintDuration = CustomOption.AddNumber("Footprint Duration", 10f, 3f, 30f, 1f);
public static CustomToggleOption AnonymousFootPrint = CustomOption.AddToggle("Anonymous Footprint", false);
Expand Down
64 changes: 21 additions & 43 deletions RolesMods/Systems/Investigator/FootPrint.cs
Original file line number Diff line number Diff line change
@@ -1,76 +1,54 @@
using RolesMods.Utility;
using Reactor;
using RolesMods.Utility;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace RolesMods.Systems.Investigator {
class FootPrint {
public static List<FootPrint> allFootprint = new List<FootPrint>();

private readonly float footPrintSize;
private Color footPrintColor;
private Vector3 footPrintPosition;
private readonly float footPrintDuration;
private readonly int footPrintUnixTime;
private GameObject footPrint;
private Vector2 velocity;
private SpriteRenderer spriteRenderer;
private readonly PlayerControl player;
public PlayerControl player;
public Vector2 position;

public FootPrint(float footPrintSize, float footPrintDuration, PlayerControl player) {
this.footPrintSize = footPrintSize;
this.footPrintColor = Palette.PlayerColors[(int) player.Data.ColorId];
this.footPrintPosition = player.transform.position;
this.footPrintDuration = footPrintDuration;
this.velocity = player.gameObject.GetComponent<Rigidbody2D>().velocity;
this.player = player;
this.footPrintUnixTime = (int) DateTimeOffset.Now.ToUnixTimeSeconds();

this.position = player.transform.position;
if (RolesMods.AnonymousFootPrint.GetValue())
this.footPrintColor = new Color(0.2f, 0.2f, 0.2f, 1f);

Start();
}

private void Start() {
footPrint = new GameObject("FootPrint");
footPrint.transform.position = footPrintPosition;
footPrint.transform.localPosition = footPrintPosition;
footPrint.transform.position = position;
footPrint.transform.localPosition = position;
footPrint.transform.localScale = new Vector2(footPrintSize, footPrintSize);
footPrint.transform.SetParent(player.transform.parent);
footPrint.transform.Rotate(Vector3.forward * Vector2.SignedAngle(Vector2.up, velocity));
footPrint.transform.Rotate(Vector3.forward * Vector2.SignedAngle(Vector2.up, player.gameObject.GetComponent<Rigidbody2D>().velocity));

spriteRenderer = footPrint.AddComponent<SpriteRenderer>();
spriteRenderer.sprite = HelperSprite.LoadSpriteFromEmbeddedResources("RolesMods.Resources.Footprint.png", 100f);
spriteRenderer.sprite = ResourceLoader.FootprintSprite;
spriteRenderer.color = footPrintColor;

footPrint.SetActive(true);
allFootprint.Add(this);
Coroutines.Start(CoFadeOutAndDestroy(footPrintDuration));
}

private void DestroyThis() {
UnityEngine.Object.Destroy(footPrint);
allFootprint.Remove(this);
}
public IEnumerator CoFadeOutAndDestroy(float duration) {
for (float time = 0f; time < duration; time += Time.deltaTime) {
footPrintColor = Palette.PlayerColors[(int) player.Data.ColorId];

public void Update() {
int currentUnixTime = (int) DateTimeOffset.Now.ToUnixTimeSeconds();
float alpha = Mathf.Max((1f - ((currentUnixTime - footPrintUnixTime) / footPrintDuration)), 0f);
this.footPrintColor = Palette.PlayerColors[(int) player.Data.ColorId];

if (alpha < 0 || alpha > 1)
alpha = 0;
if (spriteRenderer)
spriteRenderer.color = new Color(footPrintColor.r, footPrintColor.g, footPrintColor.b, Mathf.Clamp(1f - time / duration, 0f, 1f));

footPrintColor = new Color(footPrintColor.r, footPrintColor.g, footPrintColor.b, alpha);
spriteRenderer.color = footPrintColor;

if (footPrintUnixTime + (int) footPrintDuration < currentUnixTime)
DestroyThis();
}
yield return null;
}

public Vector3 FootPrintPosition {
get => footPrintPosition;
UnityEngine.Object.Destroy(footPrint);
allFootprint.Remove(this);
}

public PlayerControl Player => player;
}
}
27 changes: 7 additions & 20 deletions RolesMods/Systems/Investigator/UpdatePlayer.cs
Original file line number Diff line number Diff line change
@@ -1,55 +1,42 @@
using HarmonyLib;
using RolesMods.Utility;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace RolesMods.Systems.Investigator {
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.FixedUpdate))]
public static class UpdatePlayerPatch {
public static float time = 0.0f;
public static float interpolationPeriodNew = RolesMods.fontPrintInterval.GetValue();

public static float timeUpdate = 0.0f;
public static float interpolationPeriodUpdate = 1f;

public static void Postfix(PlayerControl __instance) {
float interpolationPeriod = RolesMods.fontPrintInterval.GetValue();

if (GlobalVariable.isGameStarted && GlobalVariable.InvestigatorsList != null && HelperRoles.IsInvestigator(PlayerControl.LocalPlayer.PlayerId)) {

// New Footprint
time += Time.deltaTime;
if (time >= interpolationPeriodNew) {
time -= interpolationPeriodNew;
if (time >= interpolationPeriod) {
time -= interpolationPeriod;

if (HelperRoles.IsInvestigator(PlayerControl.LocalPlayer.PlayerId)) {
foreach (var player in PlayerControl.AllPlayerControls) {
if (player != null && !player.Data.IsDead && player.PlayerId != PlayerControl.LocalPlayer.PlayerId) {
bool canPlace = true;

foreach (var footprint in FootPrint.allFootprint)
if (player.PlayerId == footprint.Player.PlayerId && Vector3.Distance(footprint.FootPrintPosition, PlayerControlUtils.Position(player)) < 0.25f)
if (player.PlayerId == footprint.player.PlayerId && Vector3.Distance(footprint.position, PlayerControlUtils.Position(player)) < 0.05f)
canPlace = false;

if (!RolesMods.VentFootprintVisible.GetValue() && ShipStatus.Instance != null)
foreach (var vent in ShipStatus.Instance.AllVents.ToList())
if (Vector2.Distance(vent.gameObject.transform.position, PlayerControlUtils.Position(player)) < 1f)
canPlace = false;

if (canPlace) new FootPrint(RolesMods.footPrintSize.GetValue(), RolesMods.fontPrintDuration.GetValue(), player);
if (canPlace)
new FootPrint(RolesMods.footPrintSize.GetValue(), RolesMods.fontPrintDuration.GetValue(), player);
}
}
}
}

// Update
timeUpdate += Time.deltaTime;
if (timeUpdate >= interpolationPeriodUpdate) {
timeUpdate -= interpolationPeriodUpdate;

foreach (var footprint in FootPrint.allFootprint.ToList()) {
footprint.Update();
}
}
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions RolesMods/Systems/TimeMaster/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ private static void OnUpdate(CooldownButton button) {
if (PlayerControl.LocalPlayer.PlayerId == GlobalVariable.TimeMaster.PlayerId)
if (PlayerControl.LocalPlayer.Data.IsDead)
button.SetCanUse(false);
else
button.SetCanUse(true);
else button.SetCanUse(true);

if (Time.isRewinding)
for (int i = 0; i < 2; i++)
Time.Rewind();
Time.Rewind();
else
Time.Record();
}
Expand Down
16 changes: 16 additions & 0 deletions RolesMods/Systems/TimeMaster/GameHistory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using UnityEngine;

namespace RolesMods.Systems.TimeMaster {
public class GameHistory {
public Vector3 position;
public DateTime positionTime;
public Vector2 velocity;

public GameHistory(Vector3 position, DateTime positionTime, Vector2 velocity) {
this.position = position;
this.positionTime = positionTime;
this.velocity = velocity;
}
}
}
119 changes: 70 additions & 49 deletions RolesMods/Systems/TimeMaster/Time.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,72 +6,73 @@

namespace RolesMods.Systems.TimeMaster {
public static class Time {
public static Dictionary<byte, List<GameHistory>> PlayersPositions = new Dictionary<byte, List<GameHistory>>();
public static Dictionary<byte, DateTime> DeadPlayers = new Dictionary<byte, DateTime>();

public static float recordTime = RolesMods.TimeMasterDuration.GetValue();
public static bool isRewinding = false;
internal static List<TimePoint> pointsInTime = new List<TimePoint>();
private static long deadtime;
private static bool isDead = false;

public static void Record() {
if (pointsInTime.Count > Mathf.Round(recordTime / UnityEngine.Time.fixedDeltaTime))
pointsInTime.RemoveAt(pointsInTime.Count - 1);

if (PlayerControl.LocalPlayer != null) {
pointsInTime.Insert(0, new TimePoint(
PlayerControl.LocalPlayer.transform.position,
PlayerControl.LocalPlayer.gameObject.GetComponent<Rigidbody2D>().velocity,
DateTimeOffset.Now.ToUnixTimeSeconds()
));

if (PlayerControl.LocalPlayer.Data.IsDead && !isDead) {
isDead = true;
deadtime = DateTimeOffset.Now.ToUnixTimeSeconds();
}
foreach (var player in PlayerControl.AllPlayerControls) {
if (!PlayersPositions.ContainsKey(player.PlayerId))
PlayersPositions[player.PlayerId] = new List<GameHistory>();

if (!PlayerControl.LocalPlayer.Data.IsDead && isDead) {
isDead = false;
deadtime = 0;
}
var currentPlayer = PlayersPositions.FirstOrDefault(d => d.Key == player.PlayerId);
while (currentPlayer.Value.Count >= Mathf.Round(RolesMods.TimeMasterDuration.GetValue() / UnityEngine.Time.fixedDeltaTime))
currentPlayer.Value.RemoveAt(currentPlayer.Value.Count - 1);
currentPlayer.Value.Insert(0, new GameHistory(player.transform.position, DateTime.UtcNow, player.gameObject.GetComponent<Rigidbody2D>().velocity));

if (player.Data.IsDead && !DeadPlayers.ContainsKey(player.PlayerId))
DeadPlayers[player.PlayerId] = DateTime.UtcNow;
}
}

public static void Rewind() {
if (pointsInTime.Count > 0) {

if (!PlayerControl.LocalPlayer.inVent) {
TimePoint currentTimePoint = pointsInTime[0];

PlayerControl.LocalPlayer.transform.position = currentTimePoint.Position;
PlayerControl.LocalPlayer.gameObject.GetComponent<Rigidbody2D>().velocity = currentTimePoint.Velocity;

if (isDead && currentTimePoint.Unix < deadtime && PlayerControl.LocalPlayer.Data.IsDead && RolesMods.EnableReiveTimeMaster.GetValue()) {
PlayerControl.LocalPlayer.Revive();
var body = UnityEngine.Object.FindObjectsOfType<DeadBody>().FirstOrDefault(b => b.ParentId == PlayerControl.LocalPlayer.PlayerId);
foreach (var player in PlayerControl.AllPlayerControls) {
if (!PlayersPositions.ContainsKey(player.PlayerId))
continue;

List<GameHistory> gameHistory = PlayersPositions.FirstOrDefault(d => d.Key == player.PlayerId).Value;

if (gameHistory.Count > 0) {
if (!player.inVent) {
var currentGemeHistory = gameHistory[0];
player.transform.position = currentGemeHistory.position;
player.gameObject.GetComponent<Rigidbody2D>().velocity = currentGemeHistory.velocity;

if (RolesMods.EnableReiveTimeMaster.GetValue() && player.Data.IsDead)
if (DeadPlayers.ContainsKey(player.PlayerId))
if (currentGemeHistory.positionTime < DeadPlayers[player.PlayerId])
TimeMasterRevive(player.PlayerId);

if (Minigame.Instance) {
try {
Minigame.Instance.Close();
} catch { }
}
}

if (body != null)
UnityEngine.Object.Destroy(body.gameObject);
gameHistory.RemoveAt(0);
}
}

deadtime = 0;
isDead = false;
bool CanStopRewind = true;
foreach (var player in PlayerControl.AllPlayerControls) {
if (!PlayersPositions.ContainsKey(player.PlayerId))
continue;

MessageWriter write = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte) CustomRPC.TimeRevive, SendOption.None, -1);
write.Write(PlayerControl.LocalPlayer.PlayerId);
AmongUsClient.Instance.FinishRpcImmediately(write);
}

if (Minigame.Instance) {
try {
Minigame.Instance.Close();
} catch { }
}
}
List<GameHistory> gameHistory = PlayersPositions.FirstOrDefault(d => d.Key == player.PlayerId).Value;
if (gameHistory.Count != 0 || gameHistory == null)
CanStopRewind = false;
}

pointsInTime.RemoveAt(0);
} else StopRewind();
if (CanStopRewind)
StopRewind();
}

public static void StartRewind() {
RolesMods.Logger.LogInfo(RolesMods.EnableReiveTimeMaster.GetValue());

isRewinding = true;
PlayerControl.LocalPlayer.moveable = false;
HudManager.Instance.FullScreen.color = new Color(0f, 0.5f, 0.8f, 0.3f);
Expand All @@ -85,6 +86,26 @@ public static void StopRewind() {
isRewinding = false;
PlayerControl.LocalPlayer.moveable = true;
HudManager.Instance.FullScreen.enabled = false;
HudManager.Instance.FullScreen.color = new Color(1f, 0f, 0f, 0.3f);
}

public static void TimeMasterRevive(byte playerId) {
foreach (PlayerControl player in PlayerControl.AllPlayerControls) {
if (player.PlayerId == playerId) {
player.Revive();
var body = UnityEngine.Object.FindObjectsOfType<DeadBody>().FirstOrDefault(b => b.ParentId == playerId);
if (body != null)
UnityEngine.Object.Destroy(body.gameObject);

if (DeadPlayers.ContainsKey(player.PlayerId))
DeadPlayers.Remove(player.PlayerId);
}
}
}

public static void ClearGameHistory() {
PlayersPositions.Clear();
DeadPlayers.Clear();
}
}
}
Loading

0 comments on commit a285d2d

Please sign in to comment.