-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRainWorldGame.cs
More file actions
245 lines (212 loc) · 9.12 KB
/
Copy pathRainWorldGame.cs
File metadata and controls
245 lines (212 loc) · 9.12 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MoreSlugcats;
using RWCustom;
using UnityEngine;
using Watcher;
using System.Diagnostics;
namespace TimeStopDependency
{
public partial class TimeStopDependency
{
private bool RainWorldGame_AllowRainCounterToTick(On.RainWorldGame.orig_AllowRainCounterToTick orig, RainWorldGame self)
{
if (self.GetCustomData().isTimeStopActive) return false;
return orig(self);
}
internal delegate float orig_TimeSpeedFac(RainWorldGame self);
internal static float RainWorldGame_TimeSpeedFac_get(orig_TimeSpeedFac orig, RainWorldGame self)
{
if (self.GetCustomData().isTimeStopActive && !self.GetCustomData().allowEffectsGraohicUpdate)
{
return 0f;
}
return orig(self);
}
private void RainWorldGame_GrafUpdate(MonoMod.Cil.ILContext il)
{
var c = new ILCursor(il);
c.GotoNext(
MoveType.After,
x => x.MatchLdarg(1),
y => y.MatchStloc(0),
x => x.MatchLdarg(0),
x => x.MatchLdfld(typeof(RainWorldGame).GetField("pauseUpdate"))
);
c.MoveAfterLabels();
c.Emit(OpCodes.Ldarg_0);
bool CheckForTimeStopInRainWorlGameGrafUpdate(bool pauseUpdate, RainWorldGame this_arg)
{
if (pauseUpdate || this_arg.GetCustomData().isTimeStopActive) return true;
return false;
}
c.EmitDelegate<Func<bool, RainWorldGame, bool>>(CheckForTimeStopInRainWorlGameGrafUpdate);
Logger.LogInfo("Finisning RainWorlGame.GrafUpdate IL modification.");
}
private void RainWorldGame_Update(MonoMod.Cil.ILContext il)
{
var c = new ILCursor(il);
var d = new ILCursor(il);
c.GotoNext(
MoveType.After,
x => x.MatchLdarg(0),
x => x.MatchLdfld(typeof(RainWorldGame).GetField("pauseUpdate"))
);
c.MoveAfterLabels();
c.Emit(OpCodes.Ldarg_0);
bool CheckForTimeStopInRainWorlGameUpdateForGlobalRain(bool pauseUpdate, RainWorldGame this_arg)
{
if (pauseUpdate || this_arg.GetCustomData().isTimeStopActive) return true;
return false;
}
c.EmitDelegate<Func<bool, RainWorldGame, bool>>(CheckForTimeStopInRainWorlGameUpdateForGlobalRain);
d.GotoNext(
MoveType.After,
x => x.MatchLdarg(0),
x => x.MatchLdfld(typeof(RainWorldGame).GetField("desintegrationTracker")),
x => x.MatchBrfalse(out _),
x => x.MatchLdarg(0),
x => x.MatchLdfld(typeof(RainWorldGame).GetField("pauseUpdate"))
);
d.MoveAfterLabels();
d.Emit(OpCodes.Ldarg_0);
bool CheckForTimeStopInRainWorlGameUpdateForDesintegrationTracker(bool pauseUpdate, RainWorldGame this_arg)
{
if (pauseUpdate || this_arg.GetCustomData().isTimeStopActive) return true;
return false;
}
d.EmitDelegate<Func<bool, RainWorldGame, bool>>(CheckForTimeStopInRainWorlGameUpdateForDesintegrationTracker);
Logger.LogInfo("Finisning RainWorlGame.GameUpdate IL modification.");
}
}
public static class RainWorlGameCWT
{
static ConditionalWeakTable<RainWorldGame, Data> table = new ConditionalWeakTable<RainWorldGame, Data>();
public static Data GetCustomData(this RainWorldGame self) => table.GetOrCreateValue(self);
public class Data
{
internal bool isTimeStopActive;
internal bool allowEffectsGraohicUpdate;
internal bool canSlugNPCUpdate;
}
}
public static class RainWorldGameExtensions
{
public static void SwitchTimeState(this RainWorldGame rwg)
{
if (!rwg.GetCustomData().isTimeStopActive)
{
FreezeTime(rwg);
}
else
{
UnfreezeTime(rwg);
}
}
public static void FreezeTime(this RainWorldGame rwg)
{
if (rwg.GetCustomData().isTimeStopActive) return;
rwg.GetCustomData().isTimeStopActive = true;
}
public static void UnfreezeTime(this RainWorldGame rwg)
{
if (!rwg.GetCustomData().isTimeStopActive) return;
rwg.GetCustomData().isTimeStopActive = false;
}
public static bool IsTimeStopActive(this RainWorldGame rwg)
{
return rwg.GetCustomData().isTimeStopActive;
}
/// <summary>
/// Gives SlugNPC and Pups ability to move during Time Stop if Player type is present in TimeStopImmuneTypes.
/// </summary>
public static void AllowSlugNPCUpdate(this RainWorldGame rwg)
{
if (rwg.GetCustomData().canSlugNPCUpdate) return;
rwg.GetCustomData().canSlugNPCUpdate = true;
}
/// <summary>
/// Revokes SlugNPCs and Pups ability to move during Time Stop if Player type is present in TimeStopImmuneTypes.
/// </summary>
public static void DisllowSlugNPCUpdate(this RainWorldGame rwg)
{
if (!rwg.GetCustomData().canSlugNPCUpdate) return;
rwg.GetCustomData().canSlugNPCUpdate = false;
}
/// <summary>
/// Returns whenever or not SlugNPCs and Pups have ability to move during Time Stop if Player type is present in TimeStopImmuneTypes.
/// </summary>
public static bool CanSlugNPCUpdate(this RainWorldGame rwg)
{
return rwg.GetCustomData().canSlugNPCUpdate;
}
/// <summary>
/// Allows some decorative graphics and sound controllers to update in Time Stop state.
/// Sets TimeSpeedFac to original value.
/// </summary>
public static void AllowEffectsUpdateDuringTimeStop(this RainWorldGame rwg)
{
if (rwg.GetCustomData().allowEffectsGraohicUpdate) return;
rwg.GetCustomData().allowEffectsGraohicUpdate = true;
}
/// <summary>
/// Prevents some decorative graphics and sound controllers from updating in Time Stop state.
/// Sets TimeSpeedFac to 0f.
/// </summary>
public static void DisallowEffectsUpdateDuringTimeStop(this RainWorldGame rwg)
{
if (!rwg.GetCustomData().allowEffectsGraohicUpdate) return;
rwg.GetCustomData().allowEffectsGraohicUpdate = false;
}
/// <summary>
/// Returns whenever or not some decorative graphics and sound controllers can update.
/// </summary>
public static bool IsEffectsUpdateAllowed(this RainWorldGame rwg)
{
return rwg.GetCustomData().allowEffectsGraohicUpdate;
}
/// <summary>
/// Adds class type to the TimeStopImmuneTypes list
/// </summary>
public static void AddImmuneType(this RainWorldGame rwg, Type type)
{
Assembly callingAssembly = Assembly.GetCallingAssembly();
string assemblyName = callingAssembly?.GetName().Name ?? "Unknown";
string assemblyVersion = callingAssembly?.GetName().Version?.ToString() ?? "Unknown";
if (!TimeStopDependency.TimeStopImmuneTypes.Contains(type))
{
TimeStopDependency.TimeStopImmuneTypes.Add(type);
TimeStopDependency.Logger.LogMessage($"Added immune type: {type.Name} " +
$"| Caller: {callingAssembly?.FullName} " +
$"| Mod: {assemblyName} v{assemblyVersion}");
string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {assemblyName} v{assemblyVersion}] Added immune type {type.Name}";
TimeStopDependency.LogToImmuneFile(logEntry);
}
}
/// <summary>
/// Removes class type from TimeStopImmuneTypes
/// </summary>
public static void RemoveImmuneType(this RainWorldGame rwg, Type type)
{
Assembly callingAssembly = Assembly.GetCallingAssembly();
string assemblyName = callingAssembly?.GetName().Name ?? "Unknown";
string assemblyVersion = callingAssembly?.GetName().Version?.ToString() ?? "Unknown";
if (TimeStopDependency.TimeStopImmuneTypes.Contains(type))
{
TimeStopDependency.TimeStopImmuneTypes.Remove(type);
TimeStopDependency.Logger.LogMessage($"Removed immune type: {type.Name} " +
$"| Caller: {callingAssembly?.FullName} " +
$"| Mod: {assemblyName} v{assemblyVersion}");
string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {assemblyName} v{assemblyVersion}] Removed immune type {type.Name}";
TimeStopDependency.LogToImmuneFile(logEntry);
}
}
}
}