Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.Reflection;
using NitroxClient.GameLogic.PlayerLogic;
using UnityEngine;

namespace NitroxPatcher.Patches.Dynamic;

/// <summary>
/// Makes ion cube pedestals (the ones with ion cubes on top that rise up) react to remote players.
/// </summary>
public sealed partial class PrecursorActivatedPillar_OnTriggerEnter_Patch : NitroxPatch, IDynamicPatch
{
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((PrecursorActivatedPillar t) => t.OnTriggerEnter(default));

public static bool Prefix(PrecursorActivatedPillar __instance, Collider col, bool ___active, ref bool ___extended, ref bool ___isFullyExtended, FMODAsset ___openSound, FMOD_CustomLoopingEmitter ___openedLoopingSound)
{
if (!___active)
{
return false;
}

GameObject entityRoot = UWE.Utils.GetEntityRoot(col.gameObject);
if (!entityRoot)
{
entityRoot = col.gameObject;
}

bool isLocalPlayer = entityRoot.GetComponentInChildren<Player>() != null;
bool isRemotePlayer = entityRoot.GetComponentInChildren<RemotePlayerIdentifier>() != null;

if (!isLocalPlayer && !isRemotePlayer)
{
return false;
}

// Track player count for proper exit handling
PrecursorActivatedPillar_OnTriggerExit_Patch.IncrementPlayerCount(__instance);

// Only play sounds and animate if not already extended
if (!___extended)
{
if (___openSound)
{
Utils.PlayFMODAsset(___openSound, __instance.transform, 20f);
}
if (___openedLoopingSound)
{
___openedLoopingSound.Play();
}
___extended = true;
___isFullyExtended = false;
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Reflection;
using FMOD.Studio;
using NitroxClient.GameLogic.PlayerLogic;
using UnityEngine;

namespace NitroxPatcher.Patches.Dynamic;

/// <summary>
/// Prevents ion cube pedestals from retracting when a player leaves if other players are still nearby.
/// </summary>
public sealed partial class PrecursorActivatedPillar_OnTriggerExit_Patch : NitroxPatch, IDynamicPatch
{
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((PrecursorActivatedPillar t) => t.OnTriggerExit(default));

/// <summary>
/// Tracks the number of players currently in each pillar's trigger zone.
/// </summary>
private static readonly Dictionary<int, int> playerCountByPillar = [];

public static void IncrementPlayerCount(PrecursorActivatedPillar pillar)
{
int id = pillar.GetInstanceID();
playerCountByPillar.TryGetValue(id, out int count);
playerCountByPillar[id] = count + 1;
}

public static bool Prefix(PrecursorActivatedPillar __instance, Collider col, ref bool ___extended, ref bool ___isFullyExtended, FMODAsset ___closeSound, FMOD_CustomLoopingEmitter ___openedLoopingSound)
{
GameObject entityRoot = UWE.Utils.GetEntityRoot(col.gameObject);
if (!entityRoot)
{
entityRoot = col.gameObject;
}

bool isLocalPlayer = entityRoot.GetComponentInChildren<Player>() != null;
bool isRemotePlayer = entityRoot.GetComponentInChildren<RemotePlayerIdentifier>() != null;

if (!isLocalPlayer && !isRemotePlayer)
{
return false;
}

// Decrement player count (only if we have a count for this pillar)
int id = __instance.GetInstanceID();
int newCount = 0;
if (playerCountByPillar.TryGetValue(id, out int count) && count > 0)
{
newCount = count - 1;
playerCountByPillar[id] = newCount;
}

// Only retract if no players remain
if (newCount <= 0)
{
if (___closeSound)
{
Utils.PlayFMODAsset(___closeSound, __instance.transform, 20f);
}
if (___openedLoopingSound)
{
___openedLoopingSound.Stop(STOP_MODE.ALLOWFADEOUT);
}
___extended = false;
___isFullyExtended = true;
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Reflection;
using NitroxClient.GameLogic.PlayerLogic;
using UnityEngine;

namespace NitroxPatcher.Patches.Dynamic;

/// <summary>
/// Makes precursor key terminal pedestals (tablet pedestals) react to remote players.
/// </summary>
public sealed partial class PrecursorKeyTerminalTrigger_OnTriggerEnter_Patch : NitroxPatch, IDynamicPatch
{
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((PrecursorKeyTerminalTrigger t) => t.OnTriggerEnter(default));

public static bool Prefix(PrecursorKeyTerminalTrigger __instance, Collider col)
{
bool isLocalPlayer = col.gameObject.Equals(Player.main.gameObject);
bool isRemotePlayer = col.GetComponentInParent<RemotePlayerIdentifier>() != null;

if (!isLocalPlayer && !isRemotePlayer)
{
return false;
}

// Track player count for proper exit handling
PrecursorKeyTerminalTrigger_OnTriggerExit_Patch.IncrementPlayerCount(__instance);

// Only send OpenDeck if this is the first player entering
if (PrecursorKeyTerminalTrigger_OnTriggerExit_Patch.GetPlayerCount(__instance) == 1)
{
__instance.SendMessageUpwards("OpenDeck");
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Reflection;
using NitroxClient.GameLogic.PlayerLogic;
using UnityEngine;

namespace NitroxPatcher.Patches.Dynamic;

/// <summary>
/// Prevents precursor key terminal pedestals from closing when a player leaves if other players are still nearby.
/// </summary>
public sealed partial class PrecursorKeyTerminalTrigger_OnTriggerExit_Patch : NitroxPatch, IDynamicPatch
{
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((PrecursorKeyTerminalTrigger t) => t.OnTriggerExit(default));

/// <summary>
/// Tracks the number of players currently in each trigger zone.
/// </summary>
private static readonly Dictionary<int, int> playerCountByTrigger = [];

public static void IncrementPlayerCount(PrecursorKeyTerminalTrigger trigger)
{
int id = trigger.GetInstanceID();
playerCountByTrigger.TryGetValue(id, out int count);
playerCountByTrigger[id] = count + 1;
}

public static int GetPlayerCount(PrecursorKeyTerminalTrigger trigger)
{
int id = trigger.GetInstanceID();
playerCountByTrigger.TryGetValue(id, out int count);
return count;
}

public static bool Prefix(PrecursorKeyTerminalTrigger __instance, Collider col)
{
bool isLocalPlayer = col.gameObject.Equals(Player.main.gameObject);
bool isRemotePlayer = col.GetComponentInParent<RemotePlayerIdentifier>() != null;

if (!isLocalPlayer && !isRemotePlayer)
{
return false;
}

// Decrement player count (only if we have a count for this trigger)
int id = __instance.GetInstanceID();
int newCount = 0;
if (playerCountByTrigger.TryGetValue(id, out int count) && count > 0)
{
newCount = count - 1;
playerCountByTrigger[id] = newCount;
}

// Only close if no players remain
if (newCount <= 0)
{
__instance.SendMessageUpwards("CloseDeck");
}

return false;
}
}
Loading