Skip to content

Commit 1a987e9

Browse files
committed
Some refactoring, replacement of prefix by transpiler, added a synced creature type whitelist
1 parent 4839668 commit 1a987e9

11 files changed

+112
-48
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using FluentAssertions;
4+
using HarmonyLib;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
using NitroxTest.Patcher;
7+
8+
namespace NitroxPatcher.Patches.Dynamic;
9+
10+
[TestClass]
11+
public class Vehicle_TorpedoShot_PatchTest
12+
{
13+
[TestMethod]
14+
public void Sanity()
15+
{
16+
IEnumerable<CodeInstruction> originalIl = PatchTestHelper.GetInstructionsFromMethod(Vehicle_TorpedoShot_Patch.TARGET_METHOD);
17+
IEnumerable<CodeInstruction> transformedIl = Vehicle_TorpedoShot_Patch.Transpiler(originalIl);
18+
transformedIl.Count().Should().Be(originalIl.Count() + 3);
19+
}
20+
}

NitroxClient/GameLogic/AI.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ public class AI
2525
typeof(AttackLastTarget), typeof(AttackCyclops)
2626
];
2727

28+
/// <summary>
29+
/// In the future, ensure all creatures are synced. We want each of them to be individually
30+
/// checked (that all their actions are synced) before marking them as synced.
31+
/// </summary>
32+
private readonly HashSet<Type> syncedCreatureWhitelist =
33+
[
34+
typeof(ReaperLeviathan), typeof(SeaDragon)
35+
];
36+
2837
public AI(IPacketSender packetSender)
2938
{
3039
this.packetSender = packetSender;
@@ -36,7 +45,7 @@ public AI(IPacketSender packetSender)
3645

3746
public void BroadcastNewAction(NitroxId creatureId, Creature creature, CreatureAction newAction)
3847
{
39-
if (creature is not ReaperLeviathan)
48+
if (!syncedCreatureWhitelist.Contains(creature.GetType()))
4049
{
4150
return;
4251
}
@@ -119,4 +128,9 @@ public bool IsCreatureActionWhitelisted(CreatureAction creatureAction)
119128
{
120129
return creatureActionWhitelist.Contains(creatureAction.GetType());
121130
}
131+
132+
public bool IsCreatureWhitelisted(Creature creature)
133+
{
134+
return syncedCreatureWhitelist.Contains(creature.GetType());
135+
}
122136
}

NitroxClient/GameLogic/BulletManager.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
namespace NitroxClient.GameLogic;
1010

11+
/// <summary>
12+
/// Registers one stasis sphere per connected remote player, and syncs their behaviour.<br/>
13+
/// Also syncs remote torpedo (of all types) shots and hits.
14+
/// </summary>
1115
public class BulletManager
1216
{
1317
private readonly PlayerManager playerManager;
@@ -77,10 +81,7 @@ public void TorpedoTargetAcquired(NitroxId bulletId, NitroxId targetId, Vector3
7781

7882
public void ShootStasisSphere(ushort playerId, Vector3 position, Quaternion rotation, float speed, float lifeTime, float chargeNormalized)
7983
{
80-
if (!stasisSpherePerPlayerId.TryGetValue(playerId, out StasisSphere cloneSphere) || !cloneSphere)
81-
{
82-
cloneSphere = EnsurePlayerHasSphere(playerId);
83-
}
84+
StasisSphere cloneSphere = EnsurePlayerHasSphere(playerId);
8485

8586
cloneSphere.Shoot(position, rotation, speed, lifeTime, chargeNormalized);
8687
}
@@ -89,15 +90,15 @@ public void StasisSphereHit(ushort playerId, Vector3 position, Quaternion rotati
8990
{
9091
StasisSphere cloneSphere = EnsurePlayerHasSphere(playerId);
9192

92-
// Setup the sphere in case it the shot was sent earlier
93+
// Setup the sphere in case the shot was sent earlier
9394
cloneSphere.Shoot(position, rotation, 0, 0, chargeNormalized);
9495
// We override this field (set by .Shoot) with the right data
9596
cloneSphere._consumption = consumption;
9697

9798
// Code from Bullet.Update when finding an object to hit
9899
cloneSphere._visible = true;
99100
cloneSphere.OnMadeVisible();
100-
cloneSphere.OnHit(default);
101+
cloneSphere.EnableField();
101102
cloneSphere.Deactivate();
102103
}
103104

NitroxClient/GameLogic/RemotePlayer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ static void CopyEmitter(FMOD_CustomEmitter src, FMOD_CustomEmitter dst)
421421
private void SetupMixins()
422422
{
423423
InfectedMixin = Body.AddComponent<InfectedMixin>();
424-
InfectedMixin.shaderKeyWord = "UWE_PLAYERINFECTION";
424+
InfectedMixin.shaderKeyWord = InfectedMixin.uwe_playerinfection;
425425
Renderer renderer = PlayerModel.transform.Find("male_geo/diveSuit/diveSuit_hands_geo").GetComponent<Renderer>();
426426
InfectedMixin.renderers = [renderer];
427427

@@ -432,7 +432,7 @@ private void SetupMixins()
432432
broadcastKillOnDeath = false
433433
};
434434
LiveMixin.health = 100;
435-
// We set the remote player to invincible because we only want this component to detectable but not to work
435+
// We set the remote player to invincible because we only want this component to be detectable but not to work
436436
LiveMixin.invincible = true;
437437
}
438438

NitroxPatcher/Patches/Dynamic/AggressiveWhenSeeTarget_ScanForAggressionTarget_Patch.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ public static bool Prefix(AggressiveWhenSeeTarget __instance)
2323
return true;
2424
}
2525

26-
2726
return false;
2827
}
2928

@@ -47,6 +46,11 @@ public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructio
4746

4847
public static void BroadcastTargetChange(AggressiveWhenSeeTarget aggressiveWhenSeeTarget, GameObject aggressionTarget)
4948
{
49+
if (!Resolve<AI>().IsCreatureWhitelisted(aggressiveWhenSeeTarget.creature))
50+
{
51+
return;
52+
}
53+
5054
// If the function was called to this point, either it'll return because it doesn't have an id or it'll be evident that we have ownership over the aggressive creature
5155
LastTarget lastTarget = aggressiveWhenSeeTarget.lastTarget;
5256
// If there's already (likely another) locked target, we get its id over aggressionTarget

NitroxPatcher/Patches/Dynamic/AttackCyclops_OnCollisionEnter_Patch.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ public sealed partial class AttackCyclops_OnCollisionEnter_Patch : NitroxPatch,
1717
{
1818
public static readonly MethodInfo TARGET_METHOD = Reflect.Method((AttackCyclops t) => t.OnCollisionEnter(default));
1919

20+
public static bool Prefix(AttackCyclops __instance)
21+
{
22+
return !__instance.TryGetNitroxId(out NitroxId creatureId) ||
23+
Resolve<SimulationOwnership>().HasAnyLockType(creatureId);
24+
}
25+
2026
/*
2127
* REPLACE:
2228
* if (Player.main != null && Player.main.currentSub != null && Player.main.currentSub.isCyclops && Player.main.currentSub.gameObject == collision.gameObject)
@@ -41,10 +47,4 @@ public static bool ShouldCollisionAnnoyCreature(Collision collision)
4147
{
4248
return AttackCyclops_UpdateAggression_Patch.IsTargetAValidInhabitedCyclops(collision.gameObject);
4349
}
44-
45-
public static bool Prefix(AttackCyclops __instance)
46-
{
47-
return !__instance.TryGetNitroxId(out NitroxId creatureId) ||
48-
Resolve<SimulationOwnership>().HasAnyLockType(creatureId);
49-
}
5050
}

NitroxPatcher/Patches/Dynamic/AttackCyclops_UpdateAggression_Patch.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ public static bool IsTargetAValidInhabitedCyclops(IEcoTarget target)
8888
public static bool IsTargetAValidInhabitedCyclops(GameObject targetObject)
8989
{
9090
// Is a Cyclops
91-
if (!targetObject.GetComponent<CyclopsNoiseManager>())
91+
if (!targetObject.TryGetComponent(out SubRoot subRoot) || !subRoot.isCyclops)
9292
{
9393
return false;
9494
}
9595

9696
// Has the local player inside
97-
if (Player.main && Player.main.currentSub && Player.main.currentSub.gameObject == targetObject)
97+
if (Player.main && Player.main.currentSub == subRoot)
9898
{
9999
return true;
100100
}

NitroxPatcher/Patches/Dynamic/Creature_ChooseBestAction_Patch.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ public static bool Prefix(Creature __instance, out NitroxId __state, ref Creatur
1414
{
1515
if (!__instance.TryGetIdOrWarn(out __state, true))
1616
{
17-
Log.WarnOnce($"[{nameof(Creature_ChooseBestAction_Patch)}] Couldn't find an id on {__instance.GetFullHierarchyPath()}");
1817
return true;
1918
}
2019
if (Resolve<SimulationOwnership>().HasAnyLockType(__state))

NitroxPatcher/Patches/Dynamic/SeamothTorpedoWhirlpool_Register_Patch.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public sealed partial class SeamothTorpedoWhirlpool_Register_Patch : NitroxPatch
1212
{
1313
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((SeamothTorpedoWhirlpool t) => t.Register(default, ref Reflect.Ref<Rigidbody>.Field));
1414

15-
public static bool Prefix(Collider other, ref bool __result)
15+
public static bool Prefix(Collider other)
1616
{
1717
return !other.GetComponentInParent<RemotePlayerIdentifier>(true);
1818
}

NitroxPatcher/Patches/Dynamic/StasisSphere_OnHit_Patch.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,27 @@
99
namespace NitroxPatcher.Patches.Dynamic;
1010

1111
/// <summary>
12-
/// Prevents remote stasis sphere from triggering hit effets (they're triggered with packets)
12+
/// Prevents remote stasis sphere from triggering hit effets (they're triggered with packets).
13+
/// Broadcasts local player's stasis sphere hits
1314
/// </summary>
1415
public sealed partial class StasisSphere_OnHit_Patch : NitroxPatch, IDynamicPatch
1516
{
1617
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((StasisSphere t) => t.OnHit(default));
1718

18-
private static ushort LocalPlayerId => Resolve<LocalPlayer>().PlayerId;
19-
20-
public static void Prefix(StasisSphere __instance)
19+
public static bool Prefix(StasisSphere __instance)
2120
{
2221
if (__instance.GetComponent<BulletManager.RemotePlayerBullet>())
2322
{
24-
return;
23+
return false;
2524
}
2625

26+
ushort localPlayerId = Resolve<LocalPlayer>().PlayerId;
2727
NitroxVector3 position = __instance.tr.position.ToDto();
2828
NitroxQuaternion rotation = __instance.tr.rotation.ToDto();
2929
// Calculate the chargeNormalized value which was passed to StasisSphere.Shoot
3030
float chargeNormalized = Mathf.Unlerp(__instance.minRadius, __instance.maxRadius, __instance.radius);
3131

32-
Resolve<IPacketSender>().Send(new StasisSphereHit(LocalPlayerId, position, rotation, chargeNormalized, __instance._consumption));
33-
return;
32+
Resolve<IPacketSender>().Send(new StasisSphereHit(localPlayerId, position, rotation, chargeNormalized, __instance._consumption));
33+
return true;
3434
}
3535
}

0 commit comments

Comments
 (0)