-
Notifications
You must be signed in to change notification settings - Fork 0
/
ModEntry.cs
75 lines (61 loc) · 3.04 KB
/
ModEntry.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System.Linq;
using System.Collections.Generic;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
namespace Relativity
{
public class ModEntry : Mod
{
// GTI = GameTickInterval, STP = ShouldTimePass
private static int LocalGTI => 7000 + (Game1.currentLocation?.ExtraMillisecondsPerInGameMinute ?? 0);
private static bool LocalSTP => Game1.shouldTimePass(true);
private readonly Dictionary<long, (bool STP, int GTI)> playerTimeData = new();
public override void Entry(IModHelper helper)
{
Helper.Events.Multiplayer.ModMessageReceived += Multiplayer_ModMessageReceived;
Helper.Events.Multiplayer.PeerDisconnected += Multiplayer_PeerDisconnected;
Helper.Events.Multiplayer.PeerConnected += Multiplayer_PeerConnected;
Helper.Events.GameLoop.UpdateTicking += GameLoop_UpdateTicking;
Helper.Events.Player.Warped += Player_Warped;
}
private void Player_Warped(object sender, WarpedEventArgs e) =>
UpdatePeerData(e.Player.UniqueMultiplayerID, (LocalSTP, LocalGTI));
private void Multiplayer_PeerConnected(object sender, PeerConnectedEventArgs e) =>
UpdatePeerData(e.Peer.PlayerID, (LocalSTP, LocalGTI));
private void Multiplayer_PeerDisconnected(object sender, PeerDisconnectedEventArgs e) =>
UpdatePeerData(e.Peer.PlayerID, null);
private void Multiplayer_ModMessageReceived(object sender, ModMessageReceivedEventArgs e)
{
if (!Context.IsMainPlayer || e.FromModID != ModManifest.UniqueID) return;
if (e.Type == "TimeData") UpdatePeerData(e.FromPlayerID, e.ReadAs<(bool, int)>());
}
private void UpdatePeerData(long playerID, (bool, int)? data)
{
if (!Context.IsMainPlayer)
{
Helper.Multiplayer.SendMessage(data, "TimeData", new[] { ModManifest.UniqueID }); ;
return;
}
if (data == null) playerTimeData.Remove(playerID);
else playerTimeData[playerID] = ((bool, int))data;
}
private bool prevSTP = false;
private float totalElapsedGTI = 0;
private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e)
{
if (!Context.IsWorldReady || !Context.IsMultiplayer) return;
if (LocalSTP != prevSTP)
UpdatePeerData(Game1.player.UniqueMultiplayerID, (prevSTP = LocalSTP, LocalGTI));
if (!Context.IsMainPlayer) return;
if (float.IsNaN(totalElapsedGTI)) totalElapsedGTI = 0;
float players = playerTimeData.Count;
float active = playerTimeData.Count(x => x.Value.STP);
totalElapsedGTI += Game1.gameTimeInterval * (active / players);
Game1.gameTimeInterval = 0;
float averageGTI = playerTimeData.Sum(x => x.Value.GTI) / players;
if (totalElapsedGTI >= averageGTI)
totalElapsedGTI -= Game1.gameTimeInterval = (int) averageGTI;
}
}
}