Skip to content

Commit 8fe0c16

Browse files
authored
Merge branch 'dev' into more-random-multiplayer-state
2 parents 2c703fe + 5de030a commit 8fe0c16

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1700
-331
lines changed

Source/Client/AsyncTime/AsyncTimeComp.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,22 @@ public void SetDesiredTimeSpeed(TimeSpeed speed)
6565

6666
public int TickableId => map.uniqueID;
6767

68+
public int GameStartAbsTick
69+
{
70+
get
71+
{
72+
if (gameStartAbsTickMap == 0)
73+
{
74+
gameStartAbsTickMap = Find.TickManager?.gameStartAbsTick ?? 0;
75+
}
76+
77+
return gameStartAbsTickMap;
78+
}
79+
}
80+
6881
public Map map;
6982
public int mapTicks;
83+
private int gameStartAbsTickMap;
7084
private TimeSpeed timeSpeedInt;
7185
public bool forcedNormalSpeed;
7286
public int eventCount;
@@ -84,9 +98,10 @@ public void SetDesiredTimeSpeed(TimeSpeed speed)
8498

8599
public Queue<ScheduledCommand> cmds = new();
86100

87-
public AsyncTimeComp(Map map)
101+
public AsyncTimeComp(Map map, int gameStartAbsTick = 0)
88102
{
89103
this.map = map;
104+
this.gameStartAbsTickMap = gameStartAbsTick;
90105

91106
// Use the world's constant rand seed and map tile ID as our initial randState.
92107
// Only fill the seed part, leave the iterations out.
@@ -202,6 +217,8 @@ public void ExposeData()
202217
Scribe_Values.Look(ref mapTicks, "mapTicks");
203218
Scribe_Values.Look(ref timeSpeedInt, "timeSpeed");
204219

220+
Scribe_Values.Look(ref gameStartAbsTickMap, "gameStartAbsTickMap");
221+
205222
Scribe_Deep.Look(ref storyteller, "storyteller");
206223

207224
Scribe_Deep.Look(ref storyWatcher, "storyWatcher");
@@ -400,6 +417,8 @@ void RestoreState()
400417
designator.DesignateThing(thing);
401418
designator.Finalize(true);
402419
}
420+
421+
SyncMethods.TryDirtyCurrentPawnTable(designator);
403422
}
404423
finally
405424
{
@@ -443,5 +462,4 @@ public enum DesignatorMode : byte
443462
MultiCell,
444463
Thing
445464
}
446-
447465
}

Source/Client/AsyncTime/SetMapTime.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,31 @@ static void Prefix(ref Func<string> textGetter)
163163
}
164164
}
165165

166+
[HarmonyPatch(typeof(CompCauseGameCondition), nameof(CompCauseGameCondition.EnforceConditionOn))]
167+
static class MapConditionCauserMapTime
168+
{
169+
static void Prefix(Map map, ref TimeSnapshot? __state)
170+
{
171+
if (Multiplayer.Client == null) return;
172+
__state = TimeSnapshot.GetAndSetFromMap(map);
173+
}
174+
175+
static void Finalizer(TimeSnapshot? __state) => __state?.Set();
176+
}
177+
166178
public struct TimeSnapshot
167179
{
168180
public int ticks;
169181
public TimeSpeed speed;
170182
public TimeSlower slower;
183+
public int gameStartAbsTick;
171184

172185
public void Set()
173186
{
174187
Find.TickManager.ticksGameInt = ticks;
175188
Find.TickManager.slower = slower;
176189
Find.TickManager.curTimeSpeed = speed;
190+
Find.TickManager.gameStartAbsTick = gameStartAbsTick;
177191
}
178192

179193
public static TimeSnapshot Current()
@@ -182,7 +196,8 @@ public static TimeSnapshot Current()
182196
{
183197
ticks = Find.TickManager.ticksGameInt,
184198
speed = Find.TickManager.curTimeSpeed,
185-
slower = Find.TickManager.slower
199+
slower = Find.TickManager.slower,
200+
gameStartAbsTick = Find.TickManager.gameStartAbsTick
186201
};
187202
}
188203

@@ -198,6 +213,7 @@ public static TimeSnapshot Current()
198213
tickManager.ticksGameInt = mapComp.mapTicks;
199214
tickManager.slower = mapComp.slower;
200215
tickManager.CurTimeSpeed = mapComp.DesiredTimeSpeed;
216+
tickManager.gameStartAbsTick = mapComp.GameStartAbsTick;
201217

202218
return prev;
203219
}

Source/Client/AsyncTime/StorytellerPatches.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,17 @@ static IEnumerable<IncidentTargetTagDef> Postfix(IEnumerable<IncidentTargetTagDe
139139
}
140140
}
141141
}
142+
143+
[HarmonyPatch(typeof(StorytellerUtility), nameof(StorytellerUtility.DefaultThreatPointsNow))]
144+
static class FixMultifactionPocketMapDefaultThreatPointsNow
145+
{
146+
static bool Prefix(IIncidentTarget target)
147+
{
148+
// StorytellerUtility.DefaultThreatPointsNow uses Find.AnyPlayerHomeMap if
149+
// the target map is a pocket map. In such a situation, we stop the method
150+
// from executing if Find.AnyPlayerHomeMap would return null, as otherwise
151+
// we'll end up with a very frequent error spam from spectator faction and
152+
// any other factions without a map.
153+
return Multiplayer.Client == null || target is not Map { IsPocketMap: true } || Find.AnyPlayerHomeMap != null;
154+
}
155+
}

Source/Client/Comp/Map/MultiplayerMapComp.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ public MultiplayerMapComp(Map map)
3535
sessionManager = new(map);
3636
}
3737

38-
public CaravanFormingSession CreateCaravanFormingSession(bool reform, Action onClosed, bool mapAboutToBeRemoved, IntVec3? meetingSpot = null)
38+
public CaravanFormingSession CreateCaravanFormingSession(Faction faction, bool reform, Action onClosed, bool mapAboutToBeRemoved, IntVec3? meetingSpot = null)
3939
{
4040
var caravanForming = sessionManager.GetFirstOfType<CaravanFormingSession>();
4141
if (caravanForming == null)
4242
{
43-
caravanForming = new CaravanFormingSession(map, reform, onClosed, mapAboutToBeRemoved, meetingSpot);
43+
caravanForming = new CaravanFormingSession(faction, map, reform, onClosed, mapAboutToBeRemoved, meetingSpot);
4444
if (!sessionManager.AddSession(caravanForming))
4545
{
4646
// Shouldn't happen if the session doesn't exist already, show an error just in case
@@ -51,12 +51,12 @@ public CaravanFormingSession CreateCaravanFormingSession(bool reform, Action onC
5151
return caravanForming;
5252
}
5353

54-
public TransporterLoading CreateTransporterLoadingSession(List<CompTransporter> transporters)
54+
public TransporterLoading CreateTransporterLoadingSession(Faction faction, List<CompTransporter> transporters)
5555
{
5656
var transporterLoading = sessionManager.GetFirstOfType<TransporterLoading>();
5757
if (transporterLoading == null)
5858
{
59-
transporterLoading = new TransporterLoading(map, transporters);
59+
transporterLoading = new TransporterLoading(faction, map, transporters);
6060
if (!sessionManager.AddSession(transporterLoading))
6161
{
6262
// Shouldn't happen if the session doesn't exist already, show an error just in case

Source/Client/Comp/World/MultiplayerWorldComp.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void ExposeData()
3737

3838
sessionManager.ExposeSessions();
3939
// Ensure a pause lock session exists if there's any pause locks registered
40-
if (!PauseLockSession.pauseLocks.NullOrEmpty())
40+
if (!PauseLockSession.pauseLocks.NullOrEmpty() && Scribe.mode == LoadSaveMode.PostLoadInit)
4141
sessionManager.AddSession(new PauseLockSession(null));
4242

4343
DoBackCompat();
@@ -78,6 +78,18 @@ void RemoveOpponentFaction()
7878
AddSpectatorFaction();
7979
RemoveOpponentFaction();
8080
}
81+
82+
// Fix old save files by ensuring all factions have access to Anomaly research if
83+
// it was enabled. This needs to be done since Anomaly state is shared by all players.
84+
var anomaly = Find.Anomaly;
85+
// Don't use anomaly.Level, as it'll return 0 due to monolith not being
86+
// spawned. If we want to include that check then we'd need to move this
87+
// code into a postfix to Building_VoidMonolith:SpawnSetup.
88+
if (anomaly.level > 0 && anomaly.monolith != null)
89+
{
90+
foreach (var (_, data) in factionData)
91+
data.researchManager.Notify_MonolithLevelChanged(anomaly.level);
92+
}
8193
}
8294

8395
private void ExposeFactionData()

Source/Client/Desyncs/SaveableDesyncInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ private string GetDesyncDetails()
9393
.AppendLine($"Player Count|||{Multiplayer.session.players.Count}")
9494
.AppendLine($"Async time active|||{Multiplayer.GameComp.asyncTime}")
9595
.AppendLine($"Multifaction active|||{Multiplayer.GameComp.multifaction}")
96+
.AppendLine($"Map Count|||{Find.Maps?.Count.ToStringSafe()}")
9697
.AppendLine("\n###CPU Info###")
9798
.AppendLine($"Processor Name|||{SystemInfo.processorType}")
9899
.AppendLine($"Processor Speed (MHz)|||{SystemInfo.processorFrequency}")

Source/Client/Factions/Blueprints.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> inst
177177
static class SpawnBuildingAsPossiblePatch
178178
{
179179
static MethodInfo SpawningWipes = AccessTools.Method(typeof(GenSpawn), nameof(GenSpawn.SpawningWipes));
180-
public static MethodInfo ThingListGet = AccessTools.Method(typeof(List<Thing>), "get_Item");
181-
static FieldInfo ThingDefField = AccessTools.Field(typeof(Thing), "def");
180+
public static MethodInfo ThingListGet = AccessTools.IndexerGetter(typeof(List<Thing>), [typeof(int)]);
181+
static FieldInfo ThingDefField = AccessTools.Field(typeof(Thing), nameof(Thing.def));
182182

183183
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts)
184184
{

0 commit comments

Comments
 (0)