commit ced0b5a10cad343acafb53f8a5e5bafa0893f5a3 Author: adro Date: Sat Jul 23 00:33:18 2022 +0200 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..acda385 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vs +.vscode +/bin +/obj diff --git a/ModEntry.cs b/ModEntry.cs new file mode 100644 index 0000000..66ddad3 --- /dev/null +++ b/ModEntry.cs @@ -0,0 +1,76 @@ +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?.getExtraMillisecondsPerInGameMinuteForThisLocation() ?? 0); + private static bool LocalSTP => Game1.shouldTimePass(true); + private readonly Dictionary 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 paused = playerTimeData.Count(x => !x.Value.STP); + float timeSpeedFactor = 1f - paused / players; + + totalElapsedGTI += Game1.gameTimeInterval * timeSpeedFactor; + Game1.gameTimeInterval = 0; + + float averageGTI = playerTimeData.Sum(x => x.Value.GTI) / players; + if (totalElapsedGTI >= averageGTI) + totalElapsedGTI -= Game1.gameTimeInterval = (int) averageGTI; + } + } +} diff --git a/Relativity.csproj b/Relativity.csproj new file mode 100644 index 0000000..a501927 --- /dev/null +++ b/Relativity.csproj @@ -0,0 +1,11 @@ + + + + net5.0 + + + + + + + diff --git a/Relativity.sln b/Relativity.sln new file mode 100644 index 0000000..31f0681 --- /dev/null +++ b/Relativity.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32630.192 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Relativity", "Relativity.csproj", "{94E8EB0F-BDB4-44CB-8946-D3D75F33E419}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {94E8EB0F-BDB4-44CB-8946-D3D75F33E419}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {94E8EB0F-BDB4-44CB-8946-D3D75F33E419}.Debug|Any CPU.Build.0 = Debug|Any CPU + {94E8EB0F-BDB4-44CB-8946-D3D75F33E419}.Release|Any CPU.ActiveCfg = Release|Any CPU + {94E8EB0F-BDB4-44CB-8946-D3D75F33E419}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {71995C25-CD9A-4B89-A109-6AEBE22ADF7E} + EndGlobalSection +EndGlobal diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..53fc02e --- /dev/null +++ b/manifest.json @@ -0,0 +1,10 @@ +{ + "Name": "Relativity", + "Author": "AdroSlice", + "Version": "1.0.0", + "Description": "Slows down multiplayer time based on how many players would normally not have time pass in singleplayer.", + "UniqueID": "AdroSlice.Relativity", + "EntryDll": "Relativity.dll", + "MinimumApiVersion": "3.0.0", + "UpdateKeys": [] +} \ No newline at end of file