forked from rwmt/Multiplayer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSetMapTime.cs
More file actions
210 lines (177 loc) · 7.29 KB
/
SetMapTime.cs
File metadata and controls
210 lines (177 loc) · 7.29 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
using HarmonyLib;
using RimWorld;
using RimWorld.Planet;
using System;
using System.Collections.Generic;
using System.Reflection;
using Multiplayer.Client.Util;
using Verse;
using Verse.Sound;
namespace Multiplayer.Client
{
// Set the map time for GUI methods depending on it
[HarmonyPatch]
static class SetMapTimeForUI
{
static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(MapInterface), nameof(MapInterface.MapInterfaceOnGUI_BeforeMainTabs));
yield return AccessTools.Method(typeof(MapInterface), nameof(MapInterface.MapInterfaceOnGUI_AfterMainTabs));
yield return AccessTools.Method(typeof(MapInterface), nameof(MapInterface.HandleMapClicks));
yield return AccessTools.Method(typeof(MapInterface), nameof(MapInterface.HandleLowPriorityInput));
yield return AccessTools.Method(typeof(MapInterface), nameof(MapInterface.MapInterfaceUpdate));
yield return AccessTools.Method(typeof(AlertsReadout), nameof(AlertsReadout.AlertsReadoutUpdate));
yield return AccessTools.Method(typeof(SoundRoot), nameof(SoundRoot.Update));
yield return AccessTools.Method(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.ChoicesAtFor));
}
[HarmonyPriority(MpPriority.MpFirst)]
internal static void Prefix(ref TimeSnapshot? __state)
{
if (Multiplayer.Client == null || WorldRendererUtility.WorldRenderedNow || Find.CurrentMap == null) return;
__state = TimeSnapshot.GetAndSetFromMap(Find.CurrentMap);
}
[HarmonyPriority(MpPriority.MpLast)]
internal static void Finalizer(TimeSnapshot? __state) => __state?.Set();
}
[HarmonyPatch]
static class MapUpdateTimePatch
{
static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(Map), nameof(Map.MapUpdate));
yield return AccessTools.Method(typeof(Map), nameof(Map.FinalizeLoading));
}
[HarmonyPriority(MpPriority.MpFirst)]
static void Prefix(Map __instance, ref TimeSnapshot? __state)
{
if (Multiplayer.Client == null) return;
__state = TimeSnapshot.GetAndSetFromMap(__instance);
}
[HarmonyPriority(MpPriority.MpLast)]
static void Postfix(TimeSnapshot? __state) => __state?.Set();
}
[HarmonyPatch]
static class PawnPortraitMapTime
{
static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(PortraitsCache), nameof(PortraitsCache.IsAnimated));
}
static void Prefix(Pawn pawn, ref TimeSnapshot? __state)
{
if (Multiplayer.Client == null || Current.ProgramState != ProgramState.Playing) return;
__state = TimeSnapshot.GetAndSetFromMap(pawn.MapHeld);
}
static void Postfix(TimeSnapshot? __state) => __state?.Set();
}
// TODO 1.3: set time on the new renderer
//[HarmonyPatch(typeof(PawnRenderer), nameof(PawnRenderer.RenderPortrait))]
static class PawnRenderPortraitMapTime
{
static void Prefix(PawnRenderer __instance, ref TimeSnapshot? __state)
{
if (Multiplayer.Client == null || Current.ProgramState != ProgramState.Playing) return;
__state = TimeSnapshot.GetAndSetFromMap(__instance.pawn.MapHeld);
}
static void Postfix(TimeSnapshot? __state) => __state?.Set();
}
[HarmonyPatch(typeof(PawnTweener), nameof(PawnTweener.PreDrawPosCalculation))]
static class PreDrawPosCalculationMapTime
{
static void Prefix(PawnTweener __instance, ref TimeSnapshot? __state)
{
if (Multiplayer.Client == null || Current.ProgramState != ProgramState.Playing) return;
__state = TimeSnapshot.GetAndSetFromMap(__instance.pawn.Map);
}
static void Postfix(TimeSnapshot? __state) => __state?.Set();
}
[HarmonyPatch(typeof(DangerWatcher), nameof(DangerWatcher.DangerRating), MethodType.Getter)]
static class DangerRatingMapTime
{
static void Prefix(DangerWatcher __instance, ref TimeSnapshot? __state)
{
if (Multiplayer.Client == null) return;
__state = TimeSnapshot.GetAndSetFromMap(__instance.map);
}
static void Postfix(TimeSnapshot? __state) => __state?.Set();
}
[HarmonyPatch]
static class SustainerUpdateMapTime
{
static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(Sustainer), nameof(Sustainer.SustainerUpdate));
yield return MpMethodUtil.GetLambda(typeof(Sustainer), parentMethodType: MethodType.Constructor, parentArgs: new[] { typeof(SoundDef), typeof(SoundInfo) });
}
static void Prefix(Sustainer __instance, ref TimeSnapshot? __state)
{
if (Multiplayer.game == null) return;
__state = TimeSnapshot.GetAndSetFromMap(__instance.info.Maker.Map);
}
static void Postfix(TimeSnapshot? __state) => __state?.Set();
}
[HarmonyPatch(typeof(Sample), nameof(Sample.Update))]
static class SampleUpdateMapTime
{
static void Prefix(Sample __instance, ref TimeSnapshot? __state)
{
if (Multiplayer.game == null) return;
__state = TimeSnapshot.GetAndSetFromMap(__instance.Map);
}
static void Postfix(TimeSnapshot? __state) => __state?.Set();
}
[HarmonyPatch(typeof(TipSignal), MethodType.Constructor, new[] { typeof(Func<string>), typeof(int) })]
static class TipSignalCtor
{
static void Prefix(ref Func<string> textGetter)
{
if (Multiplayer.game == null) return;
var current = TimeSnapshot.Current();
var getter = textGetter;
textGetter = () =>
{
var prev = TimeSnapshot.Current();
current.Set();
string s = getter();
prev.Set();
return s;
};
}
}
public struct TimeSnapshot
{
public int ticks;
public TimeSpeed speed;
public TimeSlower slower;
public int gameStartAbsTick;
public void Set()
{
Find.TickManager.ticksGameInt = ticks;
Find.TickManager.slower = slower;
Find.TickManager.curTimeSpeed = speed;
Find.TickManager.gameStartAbsTick = gameStartAbsTick;
}
public static TimeSnapshot Current()
{
return new TimeSnapshot
{
ticks = Find.TickManager.ticksGameInt,
speed = Find.TickManager.curTimeSpeed,
slower = Find.TickManager.slower,
gameStartAbsTick = Find.TickManager.gameStartAbsTick
};
}
public static TimeSnapshot? GetAndSetFromMap(Map map)
{
if (map == null) return null;
TimeSnapshot prev = Current();
var tickManager = Find.TickManager;
var mapComp = map.AsyncTime();
tickManager.ticksGameInt = mapComp.mapTicks;
tickManager.slower = mapComp.slower;
tickManager.CurTimeSpeed = mapComp.DesiredTimeSpeed;
tickManager.gameStartAbsTick = mapComp.GameStartAbsTick;
return prev;
}
}
}