Skip to content

Commit fe9c445

Browse files
authored
Add sync for StoryHandTarget (SubnauticaNitrox#2595)
1 parent 450c2b0 commit fe9c445

File tree

9 files changed

+162
-0
lines changed

9 files changed

+162
-0
lines changed

Nitrox.Model.Subnautica/DataStructures/GameLogic/Entities/Metadata/EntityMetadata.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ namespace Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata
4141
[ProtoInclude(82, typeof(PlantableMetadata))]
4242
[ProtoInclude(83, typeof(FruitPlantMetadata))]
4343
[ProtoInclude(84, typeof(DrillableMetadata))]
44+
[ProtoInclude(85, typeof(PrecursorComputerTerminalMetadata))]
45+
[ProtoInclude(86, typeof(GenericConsoleMetadata))]
4446
public abstract class EntityMetadata
4547
{
4648
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
using BinaryPack.Attributes;
4+
5+
namespace Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata;
6+
7+
[Serializable]
8+
[DataContract]
9+
public class GenericConsoleMetadata : EntityMetadata
10+
{
11+
[DataMember(Order = 1)]
12+
public bool GotUsed { get; }
13+
14+
[IgnoreConstructor]
15+
protected GenericConsoleMetadata()
16+
{
17+
}
18+
19+
public GenericConsoleMetadata(bool gotUsed)
20+
{
21+
GotUsed = gotUsed;
22+
}
23+
24+
public override string ToString()
25+
{
26+
return $"[GenericConsoleMetadata GotUsed: {GotUsed}]";
27+
}
28+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
using BinaryPack.Attributes;
4+
5+
namespace Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata;
6+
7+
[Serializable]
8+
[DataContract]
9+
public class PrecursorComputerTerminalMetadata : EntityMetadata
10+
{
11+
[DataMember(Order = 1)]
12+
public bool Used { get; }
13+
14+
[IgnoreConstructor]
15+
protected PrecursorComputerTerminalMetadata()
16+
{
17+
// Constructor for serialization. Has to be "protected" for json serialization.
18+
}
19+
20+
public PrecursorComputerTerminalMetadata(bool used)
21+
{
22+
Used = used;
23+
}
24+
25+
public override string ToString()
26+
{
27+
return $"[PrecursorComputerTerminalMetadata Used: {Used}]";
28+
}
29+
}

Nitrox.Test/Server/Serialization/WorldPersistenceTest.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,12 @@ private static void EntityTest(Entity entity, Entity entityAfter)
336336
Assert.IsTrue(metadata.ChunkHealth.SequenceEqual(metadataAfter.ChunkHealth));
337337
Assert.AreEqual(metadata.TimeLastDrilled, metadataAfter.TimeLastDrilled);
338338
break;
339+
case PrecursorComputerTerminalMetadata metadata when entityAfter.Metadata is PrecursorComputerTerminalMetadata metadataAfter:
340+
Assert.AreEqual(metadata.Used, metadataAfter.Used);
341+
break;
342+
case GenericConsoleMetadata metadata when entityAfter.Metadata is GenericConsoleMetadata metadataAfter:
343+
Assert.AreEqual(metadata.GotUsed, metadataAfter.GotUsed);
344+
break;
339345
default:
340346
Assert.Fail($"Runtime type of {nameof(Entity)}.{nameof(Entity.Metadata)} is not equal: {entity.Metadata?.GetType().Name} - {entityAfter.Metadata?.GetType().Name}");
341347
break;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata;
2+
using NitroxClient.GameLogic.Spawning.Metadata.Extractor.Abstract;
3+
4+
namespace NitroxClient.GameLogic.Spawning.Metadata.Extractor;
5+
6+
public class GenericConsoleMetadataExtractor : EntityMetadataExtractor<GenericConsole, GenericConsoleMetadata>
7+
{
8+
public override GenericConsoleMetadata Extract(GenericConsole entity)
9+
{
10+
return new(entity.gotUsed);
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata;
2+
using NitroxClient.GameLogic.Spawning.Metadata.Extractor.Abstract;
3+
4+
namespace NitroxClient.GameLogic.Spawning.Metadata.Extractor;
5+
6+
public class PrecursorComputerTerminalMetadataExtractor : EntityMetadataExtractor<PrecursorComputerTerminal, PrecursorComputerTerminalMetadata>
7+
{
8+
public override PrecursorComputerTerminalMetadata Extract(PrecursorComputerTerminal entity)
9+
{
10+
return new(entity.used);
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata;
2+
using NitroxClient.GameLogic.Spawning.Metadata.Processor.Abstract;
3+
using UnityEngine;
4+
5+
namespace NitroxClient.GameLogic.Spawning.Metadata.Processor;
6+
7+
public class GenericConsoleMetadataProcessor : EntityMetadataProcessor<GenericConsoleMetadata>
8+
{
9+
public override void ProcessMetadata(GameObject gameObject, GenericConsoleMetadata metadata)
10+
{
11+
GenericConsole console = gameObject.GetComponent<GenericConsole>();
12+
if (console && !console.gotUsed && metadata.GotUsed)
13+
{
14+
// OnStoryHandTarget sets gotUsed and updates visual state (icon color, hand target).
15+
// This is equivalent to deserializing fields since OnProtoDeserialize just calls UpdateState().
16+
console.OnStoryHandTarget();
17+
}
18+
}
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata;
2+
using NitroxClient.GameLogic.Spawning.Metadata.Processor.Abstract;
3+
using UnityEngine;
4+
5+
namespace NitroxClient.GameLogic.Spawning.Metadata.Processor;
6+
7+
public class PrecursorComputerTerminalMetadataProcessor : EntityMetadataProcessor<PrecursorComputerTerminalMetadata>
8+
{
9+
public override void ProcessMetadata(GameObject gameObject, PrecursorComputerTerminalMetadata metadata)
10+
{
11+
PrecursorComputerTerminal terminal = gameObject.GetComponent<PrecursorComputerTerminal>();
12+
if (terminal && !terminal.used && metadata.Used)
13+
{
14+
terminal.OnStoryHandTarget();
15+
}
16+
}
17+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Reflection;
2+
using NitroxClient.Communication.Abstract;
3+
using NitroxClient.GameLogic;
4+
using Nitrox.Model.DataStructures;
5+
using Nitrox.Model.Subnautica.DataStructures.GameLogic.Entities.Metadata;
6+
using Nitrox.Model.Subnautica.Packets;
7+
8+
namespace NitroxPatcher.Patches.Dynamic;
9+
10+
public sealed partial class StoryHandTarget_OnHandClick_Patch : NitroxPatch, IDynamicPatch
11+
{
12+
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((StoryHandTarget t) => t.OnHandClick(default(GUIHand)));
13+
14+
public static void Postfix(StoryHandTarget __instance)
15+
{
16+
if (__instance.destroyGameObject == __instance.gameObject &&
17+
__instance.gameObject.TryGetNitroxId(out NitroxId destroyId))
18+
{
19+
Resolve<IPacketSender>().Send(new EntityDestroyed(destroyId));
20+
return;
21+
}
22+
23+
if (__instance.informGameObject)
24+
{
25+
if (__instance.informGameObject.TryGetComponent(out PrecursorComputerTerminal terminal) &&
26+
__instance.informGameObject.TryGetNitroxId(out NitroxId terminalId))
27+
{
28+
Resolve<Entities>().BroadcastMetadataUpdate(terminalId, new PrecursorComputerTerminalMetadata(terminal.used));
29+
}
30+
else if (__instance.informGameObject.TryGetComponent(out GenericConsole console) &&
31+
__instance.informGameObject.TryGetNitroxId(out NitroxId consoleId))
32+
{
33+
Resolve<Entities>().BroadcastMetadataUpdate(consoleId, new GenericConsoleMetadata(console.gotUsed));
34+
}
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)