Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Death markers setting #2253

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4f8d334
Added boilerplate for DeathMarkers setting
OhmV-IR Feb 15, 2025
9c528c4
Create beacons on all clients
OhmV-IR Jan 8, 2025
aa32a3d
Fix syntax error
OhmV-IR Jan 8, 2025
bc433fe
Shift to using the existing PlayerDeathEvent packet to trigger the be…
OhmV-IR Jan 10, 2025
46618e4
Make death beacons player exclusive(only spawns for the player that t…
OhmV-IR Jan 10, 2025
887fc59
Disconnecting also despawns all active death beacons
OhmV-IR Jan 10, 2025
c309ada
Fix death beacons getting synced to other players and not disappearin…
OhmV-IR Jan 12, 2025
68a3130
Remove unnecessary logging
OhmV-IR Jan 12, 2025
90822ec
Remove unnecessary method, various semantic updates to prep for PR
OhmV-IR Jan 12, 2025
b12d092
Fixed a random import that was accidentally added
OhmV-IR Jan 12, 2025
c6ad6ef
Update NitroxServer/ConsoleCommands/SetDeathMarkersCommand.cs
OhmV-IR Jan 12, 2025
54596ac
Fixed deathbeacons on land
OhmV-IR Jan 12, 2025
30ab97a
Switch to using blank gameobjects instead of actual beacons
OhmV-IR Jan 12, 2025
c20ea8c
Added missing using
OhmV-IR Jan 16, 2025
e231019
Removed unneeded changes
OhmV-IR Jan 16, 2025
481dc6a
Moved DeathBeacon class to its own file
OhmV-IR Jan 16, 2025
d631a82
changed field to const and named deathbeacon GO
OhmV-IR Jan 16, 2025
48e7a6d
Use InvokeRepeating and sqrMagnitude to check distances for better pe…
OhmV-IR Jan 16, 2025
afaf90f
Add translation string for death beacon label
OhmV-IR Jan 16, 2025
4968b3e
implement various code review requsted changes
OhmV-IR Jan 16, 2025
0ccbe3f
Fix error in building
OhmV-IR Jan 16, 2025
f20e5e0
Add beacon fade out
OhmV-IR Jan 16, 2025
47c5829
Fixed add and sort usings, as well as added a whitespace
OhmV-IR Jan 17, 2025
3b4f648
set DeathMarkers setting to true by default
OhmV-IR Jan 18, 2025
4f9fa44
Fix DeathMarkers for NitroxLauncher(tested in-game for this commit)
OhmV-IR Feb 15, 2025
74beffe
Added missing namespace declaration
OhmV-IR Feb 19, 2025
99d9ce4
Moved spawning of death beacon to PlayerDeath in PlayerDeathBroadcaster
OhmV-IR Feb 19, 2025
870f6a6
Update NitroxModel/Packets/DeathMarkersChanged.cs
OhmV-IR Feb 24, 2025
a03e883
Update NitroxServer/ConsoleCommands/SetDeathMarkersCommand.cs
OhmV-IR Feb 24, 2025
120fa35
Add newline between namespace and class
OhmV-IR Feb 24, 2025
a52d626
Merge branch 'DeathMarkers' of https://github.com/OhmV-IR/NitroxModde…
OhmV-IR Feb 24, 2025
5262c91
Fix missing import
OhmV-IR Feb 24, 2025
b63420f
change setdeathmarkers to deathmarkers cmd name
OhmV-IR Feb 27, 2025
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
@@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using NitroxClient.Communication.Abstract;

namespace NitroxClient.Communication.MultiplayerSession.ConnectionState
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using NitroxClient.Communication.Packets.Processors.Abstract;
using NitroxClient.GameLogic;
using NitroxModel.Packets;

namespace NitroxClient.Communication.Packets.Processors;

public class DeathMarkersChangedProcessor : ClientPacketProcessor<DeathMarkersChanged>
{
private readonly LocalPlayer localPlayer;

public DeathMarkersChangedProcessor(LocalPlayer localPlayer)
{
this.localPlayer = localPlayer;
}

public override void Process(DeathMarkersChanged packet)
{
localPlayer.MarkDeathPointsWithBeacon = packet.MarkDeathPointsWithBeacon;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using NitroxClient.Communication.Packets.Processors.Abstract;
using NitroxClient.Communication.Packets.Processors.Abstract;
using NitroxClient.GameLogic;
using NitroxModel.Helper;
using NitroxModel.Packets;
Expand All @@ -20,7 +20,6 @@ public override void Process(PlayerDeathEvent playerDeath)
Log.Debug($"{player.PlayerName} died");
Log.InGame(Language.main.Get("Nitrox_PlayerDied").Replace("{PLAYER}", player.PlayerName));
player.PlayerDeathEvent.Trigger(player);

// TODO: Add any death related triggers (i.e. scoreboard updates, rewards, etc.)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public PlayerInitialSyncProcessor(Items item, ItemContainers itemContainers, Loc
AddStep(sync => SetPlayerStats(sync.PlayerStatsData));
AddStep(sync => SetPlayerGameMode(sync.GameMode));
AddStep(sync => SetPlayerKeepInventoryOnDeath(sync.KeepInventoryOnDeath));
AddStep(sync => SetPlayerMarkDeathPointsWithBeacon(sync.MarkDeathPointsWithBeacon));
}

private void SetPlayerPermissions(Perms permissions)
Expand Down Expand Up @@ -141,4 +142,9 @@ private void SetPlayerKeepInventoryOnDeath(bool keepInventoryOnDeath)
{
localPlayer.KeepInventoryOnDeath = keepInventoryOnDeath;
}

private void SetPlayerMarkDeathPointsWithBeacon(bool markDeathPointsWithBeacon)
{
localPlayer.MarkDeathPointsWithBeacon = markDeathPointsWithBeacon;
}
}
3 changes: 2 additions & 1 deletion NitroxClient/GameLogic/LocalPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ public class LocalPlayer : ILocalNitroxPlayer
/// </summary>
public ushort? PlayerId => multiplayerSession?.Reservation?.PlayerId;
public PlayerSettings PlayerSettings => multiplayerSession.PlayerSettings;

public Perms Permissions { get; set; }
public IntroCinematicMode IntroCinematicMode { get; set; }
public bool KeepInventoryOnDeath { get; set; }
public bool MarkDeathPointsWithBeacon { get; set; }

public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetSender, ThrottledPacketSender throttledPacketSender)
{
Expand All @@ -53,6 +53,7 @@ public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetS
Permissions = Perms.PLAYER;
IntroCinematicMode = IntroCinematicMode.NONE;
KeepInventoryOnDeath = false;
MarkDeathPointsWithBeacon = false;
}

public void BroadcastLocation(Vector3 location, Vector3 velocity, Quaternion bodyRotation, Quaternion aimingRotation)
Expand Down
39 changes: 39 additions & 0 deletions NitroxClient/MonoBehaviours/Gui/InGame/DeathBeacon.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using NitroxModel.DataStructures.Unity;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;

namespace NitroxClient.MonoBehaviours.Gui.InGame;

public class DeathBeacon : MonoBehaviour
{
private const float DESPAWN_DISTANCE = 20f;
private const float DESPAWN_DISTANCE_SQUARED = DESPAWN_DISTANCE * DESPAWN_DISTANCE;
private const float CHECK_RATE = 1.5f; // in seconds

public static void SpawnDeathBeacon(NitroxVector3 location, string playerName)
{
GameObject beacon = new($"{playerName}DeathBeacon");
beacon.transform.position = location.ToUnity();
PingInstance signal = beacon.AddComponent<PingInstance>();
signal.pingType = PingType.Signal;
signal.origin = beacon.transform;
signal.minDist = DESPAWN_DISTANCE + 15f;
signal._label = Language.main.Get("Nitrox_PlayerDeathBeaconLabel").Replace("{PLAYER}", playerName);
beacon.AddComponent<DeathBeacon>();
signal.displayPingInManager = true;
signal.Initialize();
}

private void Start()
{
InvokeRepeating(nameof(CheckPlayerDistance), 0, CHECK_RATE);
}

private void CheckPlayerDistance()
{
if ((Player.main.transform.position - transform.position).sqrMagnitude <= DESPAWN_DISTANCE_SQUARED)
{
Destroy(gameObject);
}
}
}
6 changes: 6 additions & 0 deletions NitroxClient/MonoBehaviours/PlayerDeathBroadcaster.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using NitroxClient.GameLogic;
using NitroxClient.MonoBehaviours.Gui.InGame;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;

namespace NitroxClient.MonoBehaviours;
Expand All @@ -16,6 +18,10 @@ public void Awake()

private void PlayerDeath(Player player)
{
if (localPlayer.MarkDeathPointsWithBeacon)
{
DeathBeacon.SpawnDeathBeacon(player.transform.position.ToDto(), localPlayer.PlayerName);
}
localPlayer.BroadcastDeath(player.transform.position);
}

Expand Down
14 changes: 14 additions & 0 deletions NitroxModel/Packets/DeathMarkersChanged.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace NitroxModel.Packets;

[Serializable]
public class DeathMarkersChanged : Packet
{
public bool MarkDeathPointsWithBeacon { get; }

public DeathMarkersChanged(bool markDeathPointsWithBeacon)
{
MarkDeathPointsWithBeacon = markDeathPointsWithBeacon;
}
}
9 changes: 7 additions & 2 deletions NitroxModel/Packets/InitialPlayerSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class InitialPlayerSync : Packet
public bool IsFirstPlayer { get; }
public Dictionary<NitroxId, int> BuildOperationIds { get; }
public bool KeepInventoryOnDeath { get; }
public bool MarkDeathPointsWithBeacon { get; }

public InitialPlayerSync(NitroxId playerGameObjectId,
bool firstTimeConnecting,
Expand All @@ -59,7 +60,8 @@ public InitialPlayerSync(NitroxId playerGameObjectId,
TimeData timeData,
bool isFirstPlayer,
Dictionary<NitroxId, int> buildOperationIds,
bool keepInventoryOnDeath)
bool keepInventoryOnDeath,
bool markDeathPointsWithBeacon)
{
AssignedEscapePodId = assignedEscapePodId;
PlayerGameObjectId = playerGameObjectId;
Expand All @@ -84,6 +86,7 @@ public InitialPlayerSync(NitroxId playerGameObjectId,
IsFirstPlayer = isFirstPlayer;
BuildOperationIds = buildOperationIds;
KeepInventoryOnDeath = keepInventoryOnDeath;
MarkDeathPointsWithBeacon = markDeathPointsWithBeacon;
}

/// <remarks>Used for deserialization</remarks>
Expand All @@ -110,7 +113,8 @@ public InitialPlayerSync(
TimeData timeData,
bool isFirstPlayer,
Dictionary<NitroxId, int> buildOperationIds,
bool keepInventoryOnDeath)
bool keepInventoryOnDeath,
bool markDeathPointsWithBeacon)
{
AssignedEscapePodId = assignedEscapePodId;
PlayerGameObjectId = playerGameObjectId;
Expand All @@ -135,6 +139,7 @@ public InitialPlayerSync(
IsFirstPlayer = isFirstPlayer;
BuildOperationIds = buildOperationIds;
KeepInventoryOnDeath = keepInventoryOnDeath;
MarkDeathPointsWithBeacon = markDeathPointsWithBeacon;
}
}
}
3 changes: 3 additions & 0 deletions NitroxModel/Serialization/SubnauticaServerConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public class SubnauticaServerConfig : NitroxConfig<SubnauticaServerConfig>
[PropertyDescription("Prevents players from losing items on death")]
public bool KeepInventoryOnDeath { get; set; } = false;

[PropertyDescription("Places a beacon where players die")]
public bool MarkDeathPointsWithBeacon { get; set; } = true;

[PropertyDescription("Measured in milliseconds")]
public int SaveInterval
{
Expand Down
3 changes: 2 additions & 1 deletion NitroxPatcher/Patches/Dynamic/Player_OnKill_Patch.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
Expand All @@ -12,6 +12,7 @@ public sealed partial class Player_OnKill_Patch : NitroxPatch, IDynamicPatch
private static readonly MethodInfo TARGET_METHOD = Reflect.Method((Player t) => t.OnKill(default(DamageType)));

private static readonly MethodInfo SKIP_METHOD = Reflect.Method(() => GameModeUtils.IsPermadeath());

public static IEnumerable<CodeInstruction> Transpiler(MethodBase original, IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> instructionList = instructions.ToList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ public override void Process(PlayerJoiningMultiplayerSession packet, INitroxConn
storyManager.GetTimeData(),
isFirstPlayer,
BuildingManager.GetEntitiesOperations(globalRootEntities),
serverConfig.KeepInventoryOnDeath
serverConfig.KeepInventoryOnDeath,
serverConfig.MarkDeathPointsWithBeacon
);

player.SendPacket(initialPlayerSync);
Expand Down
42 changes: 42 additions & 0 deletions NitroxServer/ConsoleCommands/SetDeathMarkersCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.IO;
using NitroxModel.DataStructures.GameLogic;
using NitroxModel.Packets;
using NitroxModel.Serialization;
using NitroxServer.ConsoleCommands.Abstract;
using NitroxServer.ConsoleCommands.Abstract.Type;
using NitroxServer.GameLogic;

namespace NitroxServer.ConsoleCommands;

internal class SetDeathMarkersCommand : Command
{
private readonly PlayerManager playerManager;
private readonly SubnauticaServerConfig serverConfig;
private readonly Server server;

public SetDeathMarkersCommand(PlayerManager playerManager, SubnauticaServerConfig serverConfig, Server server) : base("deathmarkers", Perms.ADMIN, "Sets \"Death Markers\" setting to on/off. If \"on\", a beacon will appear at the location where a player dies.")
{
this.playerManager = playerManager;
this.serverConfig = serverConfig;
this.server = server;
AddParameter(new TypeBoolean("state", true, "on/off to enable/disable death markers"));
}

protected override void Execute(CallArgs args)
{
bool newDeathMarkersState = args.Get<bool>(0);
using (serverConfig.Update(Path.Combine(KeyValueStore.Instance.GetSavesFolderDir(), server.Name)))
{
if (serverConfig.MarkDeathPointsWithBeacon != newDeathMarkersState)
{
serverConfig.MarkDeathPointsWithBeacon = newDeathMarkersState;
playerManager.SendPacketToAllPlayers(new DeathMarkersChanged(newDeathMarkersState));
SendMessageToAllPlayers($"MarkDeathPointsWithBeacon changed to \"{newDeathMarkersState}\" by {args.SenderName}");
}
else
{
SendMessage(args.Sender, $"MarkDeathPointsWithBeacon already set to {newDeathMarkersState}");
}
}
}
}