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

Multiple fixes #2089

Merged
merged 4 commits into from
Oct 29, 2023
Merged
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
Prev Previous commit
Next Next commit
Fix and improve vitals for remote players
  • Loading branch information
tornac1234 committed Oct 26, 2023
commit 553c693e8fea0329d146d27e23a257fd69fa357a
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
using NitroxClient.Communication.Packets.Processors.Abstract;
using NitroxClient.Communication.Packets.Processors.Abstract;
using NitroxClient.GameLogic.HUD;
using NitroxClient.MonoBehaviours.Gui.HUD;
using NitroxModel.Packets;

namespace NitroxClient.Communication.Packets.Processors
namespace NitroxClient.Communication.Packets.Processors;

public class PlayerStatsProcessor : ClientPacketProcessor<PlayerStats>
{
class PlayerStatsProcessor : ClientPacketProcessor<PlayerStats>
{
private readonly PlayerVitalsManager vitalsManager;
private readonly PlayerVitalsManager vitalsManager;

public PlayerStatsProcessor(PlayerVitalsManager vitalsManager)
{
this.vitalsManager = vitalsManager;
}
public PlayerStatsProcessor(PlayerVitalsManager vitalsManager)
{
this.vitalsManager = vitalsManager;
}

public override void Process(PlayerStats playerStats)
public override void Process(PlayerStats playerStats)
{
if (vitalsManager.TryFindForPlayer(playerStats.PlayerId, out RemotePlayerVitals vitals))
{
RemotePlayerVitals vitals = vitalsManager.CreateForPlayer(playerStats.PlayerId);

vitals.SetOxygen(playerStats.Oxygen, playerStats.MaxOxygen);
vitals.SetHealth(playerStats.Health);
vitals.SetFood(playerStats.Food);
Expand Down
41 changes: 19 additions & 22 deletions NitroxClient/GameLogic/HUD/PlayerVitalsManager.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,33 @@
using System.Collections.Generic;
using System.Collections.Generic;
using NitroxClient.MonoBehaviours.Gui.HUD;
using UnityEngine;

namespace NitroxClient.GameLogic.HUD
namespace NitroxClient.GameLogic.HUD;

public class PlayerVitalsManager
{
public class PlayerVitalsManager
{
private readonly Dictionary<ushort, RemotePlayerVitals> vitalsByPlayerId = new Dictionary<ushort, RemotePlayerVitals>();
private PlayerManager PlayerManager { get; }
private readonly Dictionary<ushort, RemotePlayerVitals> vitalsByPlayerId = new();

public PlayerVitalsManager(PlayerManager playerManager)
public RemotePlayerVitals CreateOrFindForPlayer(RemotePlayer remotePlayer)
{
if (!vitalsByPlayerId.TryGetValue(remotePlayer.PlayerId, out RemotePlayerVitals vitals))
{
PlayerManager = playerManager;
vitalsByPlayerId[remotePlayer.PlayerId] = vitals = RemotePlayerVitals.CreateForPlayer(remotePlayer);
}
return vitals;
}

public void RemoveForPlayer(ushort playerId)
public void RemoveForPlayer(ushort playerId)
{
if (vitalsByPlayerId.TryGetValue(playerId, out RemotePlayerVitals vitals))
{
RemotePlayerVitals removedPlayerVitals = CreateForPlayer(playerId);
vitalsByPlayerId.Remove(playerId);

Object.Destroy(removedPlayerVitals);
Object.Destroy(vitals.gameObject);
}
}

public RemotePlayerVitals CreateForPlayer(ushort playerId)
{
if (!vitalsByPlayerId.TryGetValue(playerId, out RemotePlayerVitals vitals))
{
vitals = RemotePlayerVitals.CreateForPlayer(playerId);
vitalsByPlayerId[playerId] = vitals;
}

return vitals;
}
public bool TryFindForPlayer(ushort playerId, out RemotePlayerVitals vitals)
{
return vitalsByPlayerId.TryGetValue(playerId, out vitals);
}
}
128 changes: 63 additions & 65 deletions NitroxClient/GameLogic/LocalPlayer.cs
Original file line number Diff line number Diff line change
@@ -1,107 +1,105 @@
using System;
using System;
using NitroxClient.Communication.Abstract;
using NitroxClient.GameLogic.PlayerLogic.PlayerModel;
using NitroxClient.GameLogic.PlayerLogic.PlayerModel.Abstract;
using NitroxClient.Helpers;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel_Subnautica.DataStructures;
using NitroxModel.DataStructures;
using NitroxModel.DataStructures.GameLogic;
using NitroxModel.DataStructures.Util;
using NitroxModel.MultiplayerSession;
using NitroxModel.Packets;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;
using UnityEngine.Rendering;
using Object = UnityEngine.Object;

namespace NitroxClient.GameLogic
namespace NitroxClient.GameLogic;

public class LocalPlayer : ILocalNitroxPlayer
{
public class LocalPlayer : ILocalNitroxPlayer
{
private readonly IMultiplayerSession multiplayerSession;
private readonly IPacketSender packetSender;
private readonly ThrottledPacketSender throttledPacketSender;
private readonly Lazy<GameObject> body;
private readonly Lazy<GameObject> playerModel;
private readonly Lazy<GameObject> bodyPrototype;
private readonly IMultiplayerSession multiplayerSession;
private readonly IPacketSender packetSender;
private readonly ThrottledPacketSender throttledPacketSender;
private readonly Lazy<GameObject> body;
private readonly Lazy<GameObject> playerModel;
private readonly Lazy<GameObject> bodyPrototype;

public GameObject Body => body.Value;
public GameObject Body => body.Value;

public GameObject PlayerModel => playerModel.Value;
public GameObject PlayerModel => playerModel.Value;

public GameObject BodyPrototype => bodyPrototype.Value;
public GameObject BodyPrototype => bodyPrototype.Value;

public string PlayerName => multiplayerSession.AuthenticationContext.Username;
public ushort PlayerId => multiplayerSession.Reservation.PlayerId;
public PlayerSettings PlayerSettings => multiplayerSession.PlayerSettings;
public string PlayerName => multiplayerSession.AuthenticationContext.Username;
public ushort PlayerId => multiplayerSession.Reservation.PlayerId;
public PlayerSettings PlayerSettings => multiplayerSession.PlayerSettings;

public Perms Permissions;
public Perms Permissions;

public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetSender, ThrottledPacketSender throttledPacketSender)
public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetSender, ThrottledPacketSender throttledPacketSender)
{
this.multiplayerSession = multiplayerSession;
this.packetSender = packetSender;
this.throttledPacketSender = throttledPacketSender;
body = new Lazy<GameObject>(() => Player.main.RequireGameObject("body"));
playerModel = new Lazy<GameObject>(() => Body.RequireGameObject("player_view"));
bodyPrototype = new Lazy<GameObject>(CreateBodyPrototype);
Permissions = Perms.PLAYER;
}

public void BroadcastLocation(Vector3 location, Vector3 velocity, Quaternion bodyRotation, Quaternion aimingRotation, Optional<VehicleMovementData> vehicle)
{
Movement movement;
if (vehicle.HasValue)
{
this.multiplayerSession = multiplayerSession;
this.packetSender = packetSender;
this.throttledPacketSender = throttledPacketSender;
body = new Lazy<GameObject>(() => Player.main.RequireGameObject("body"));
playerModel = new Lazy<GameObject>(() => Body.RequireGameObject("player_view"));
bodyPrototype = new Lazy<GameObject>(CreateBodyPrototype);
Permissions = Perms.PLAYER;
movement = new VehicleMovement(PlayerId, vehicle.Value);
}

public void BroadcastLocation(Vector3 location, Vector3 velocity, Quaternion bodyRotation, Quaternion aimingRotation, Optional<VehicleMovementData> vehicle)
else
{
Movement movement;
if (vehicle.HasValue)
{
movement = new VehicleMovement(multiplayerSession.Reservation.PlayerId, vehicle.Value);
}
else
{
movement = new PlayerMovement(multiplayerSession.Reservation.PlayerId, location.ToDto(), velocity.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto());
}

packetSender.Send(movement);
movement = new PlayerMovement(PlayerId, location.ToDto(), velocity.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto());
}

public void AnimationChange(AnimChangeType type, AnimChangeState state) => packetSender.Send(new AnimationChangeEvent(multiplayerSession.Reservation.PlayerId, (int)type, (int)state));
packetSender.Send(movement);
}

public void BroadcastStats(float oxygen, float maxOxygen, float health, float food, float water, float infectionAmount) => packetSender.Send(new PlayerStats(multiplayerSession.Reservation.PlayerId, oxygen, maxOxygen, health, food, water, infectionAmount));
public void AnimationChange(AnimChangeType type, AnimChangeState state) => packetSender.Send(new AnimationChangeEvent(PlayerId, (int)type, (int)state));

public void BroadcastDeath(Vector3 deathPosition) => packetSender.Send(new PlayerDeathEvent(multiplayerSession.Reservation.PlayerId, deathPosition.ToDto()));
public void BroadcastStats(float oxygen, float maxOxygen, float health, float food, float water, float infectionAmount) => packetSender.Send(new PlayerStats(PlayerId, oxygen, maxOxygen, health, food, water, infectionAmount));

public void BroadcastSubrootChange(Optional<NitroxId> subrootId) => packetSender.Send(new SubRootChanged(multiplayerSession.Reservation.PlayerId, subrootId));
public void BroadcastDeath(Vector3 deathPosition) => packetSender.Send(new PlayerDeathEvent(PlayerId, deathPosition.ToDto()));

public void BroadcastEscapePodChange(Optional<NitroxId> escapePodId) => packetSender.Send(new EscapePodChanged(multiplayerSession.Reservation.PlayerId, escapePodId));
public void BroadcastSubrootChange(Optional<NitroxId> subrootId) => packetSender.Send(new SubRootChanged(PlayerId, subrootId));

public void BroadcastWeld(NitroxId id, float healthAdded) => packetSender.Send(new WeldAction(id, healthAdded));
public void BroadcastEscapePodChange(Optional<NitroxId> escapePodId) => packetSender.Send(new EscapePodChanged(PlayerId, escapePodId));

public void BroadcastHeldItemChanged(NitroxId itemId, PlayerHeldItemChanged.ChangeType techType, NitroxTechType isFirstTime) => packetSender.Send(new PlayerHeldItemChanged(multiplayerSession.Reservation.PlayerId, itemId, techType, isFirstTime));
public void BroadcastWeld(NitroxId id, float healthAdded) => packetSender.Send(new WeldAction(id, healthAdded));

public void BroadcastQuickSlotsBindingChanged(Optional<NitroxId>[] slotItemIds) => throttledPacketSender.SendThrottled(new PlayerQuickSlotsBindingChanged(slotItemIds), (packet) => 1);
public void BroadcastHeldItemChanged(NitroxId itemId, PlayerHeldItemChanged.ChangeType techType, NitroxTechType isFirstTime) => packetSender.Send(new PlayerHeldItemChanged(PlayerId, itemId, techType, isFirstTime));

private GameObject CreateBodyPrototype()
{
GameObject prototype = Body;
public void BroadcastQuickSlotsBindingChanged(Optional<NitroxId>[] slotItemIds) => throttledPacketSender.SendThrottled(new PlayerQuickSlotsBindingChanged(slotItemIds), (packet) => 1);

// Cheap fix for showing head, much easier since male_geo contains many different heads
prototype.GetComponentInParent<Player>().head.shadowCastingMode = ShadowCastingMode.On;
GameObject clone = Object.Instantiate(prototype, Multiplayer.Main.transform, false);
prototype.GetComponentInParent<Player>().head.shadowCastingMode = ShadowCastingMode.ShadowsOnly;
private GameObject CreateBodyPrototype()
{
GameObject prototype = Body;

// Cheap fix for showing head, much easier since male_geo contains many different heads
prototype.GetComponentInParent<Player>().head.shadowCastingMode = ShadowCastingMode.On;
GameObject clone = Object.Instantiate(prototype, Multiplayer.Main.transform, false);
prototype.GetComponentInParent<Player>().head.shadowCastingMode = ShadowCastingMode.ShadowsOnly;

clone.SetActive(false);
clone.name = "RemotePlayerPrototype";
clone.SetActive(false);
clone.name = "RemotePlayerPrototype";

// Removing items that are held in hand
foreach (Transform child in clone.transform.Find($"player_view/{PlayerEquipmentConstants.ITEM_ATTACH_POINT_GAME_OBJECT_NAME}"))
// Removing items that are held in hand
foreach (Transform child in clone.transform.Find($"player_view/{PlayerEquipmentConstants.ITEM_ATTACH_POINT_GAME_OBJECT_NAME}"))
{
if (!child.gameObject.name.Contains("attach1_"))
{
if (!child.gameObject.name.Contains("attach1_"))
{
Object.DestroyImmediate(child.gameObject);
}
Object.DestroyImmediate(child.gameObject);
}

return clone;
}

return clone;
}
}
7 changes: 5 additions & 2 deletions NitroxClient/GameLogic/PlayerManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NitroxClient.GameLogic.HUD;
using NitroxClient.GameLogic.PlayerLogic.PlayerModel;
using NitroxClient.MonoBehaviours.Discord;
using NitroxModel.DataStructures;
Expand All @@ -12,14 +13,16 @@ namespace NitroxClient.GameLogic
public class PlayerManager
{
private readonly PlayerModelManager playerModelManager;
private readonly PlayerVitalsManager playerVitalsManager;
private readonly Dictionary<ushort, RemotePlayer> playersById = new Dictionary<ushort, RemotePlayer>();

public OnCreate onCreate;
public OnRemove onRemove;

public PlayerManager(PlayerModelManager playerModelManager)
public PlayerManager(PlayerModelManager playerModelManager, PlayerVitalsManager playerVitalsManager)
{
this.playerModelManager = playerModelManager;
this.playerVitalsManager = playerVitalsManager;
}

public Optional<RemotePlayer> Find(ushort playerId)
Expand Down Expand Up @@ -47,7 +50,7 @@ public RemotePlayer Create(PlayerContext playerContext)
Validate.NotNull(playerContext);
Validate.IsFalse(playersById.ContainsKey(playerContext.PlayerId));

RemotePlayer remotePlayer = new(playerContext, playerModelManager);
RemotePlayer remotePlayer = new(playerContext, playerModelManager, playerVitalsManager);

playersById.Add(remotePlayer.PlayerId, remotePlayer);
onCreate(remotePlayer.PlayerId.ToString(), remotePlayer);
Expand Down
12 changes: 9 additions & 3 deletions NitroxClient/GameLogic/RemotePlayer.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using NitroxClient.GameLogic.HUD;
using NitroxClient.GameLogic.PlayerLogic;
using NitroxClient.GameLogic.PlayerLogic.PlayerModel;
using NitroxClient.GameLogic.PlayerLogic.PlayerModel.Abstract;
using NitroxClient.MonoBehaviours;
using NitroxClient.MonoBehaviours.Gui.HUD;
using NitroxClient.Unity.Helper;
using NitroxModel.MultiplayerSession;
using UnityEngine;
Expand All @@ -18,6 +19,7 @@ public class RemotePlayer : INitroxPlayer
private static readonly int animatorPlayerIn = Animator.StringToHash("player_in");

private readonly PlayerModelManager playerModelManager;
private readonly PlayerVitalsManager playerVitalsManager;

public PlayerContext PlayerContext { get; }
public GameObject Body { get; private set; }
Expand All @@ -28,6 +30,7 @@ public class RemotePlayer : INitroxPlayer
public AnimationController AnimationController { get; private set; }
public ItemsContainer Inventory { get; private set; }
public Transform ItemAttachPoint { get; private set; }
public RemotePlayerVitals vitals { get; private set; }

public ushort PlayerId => PlayerContext.PlayerId;
public string PlayerName => PlayerContext.PlayerName;
Expand All @@ -42,10 +45,11 @@ public class RemotePlayer : INitroxPlayer

public readonly Event<RemotePlayer> PlayerDisconnectEvent = new();

public RemotePlayer(PlayerContext playerContext, PlayerModelManager modelManager)
public RemotePlayer(PlayerContext playerContext, PlayerModelManager playerModelManager, PlayerVitalsManager playerVitalsManager)
{
PlayerContext = playerContext;
playerModelManager = modelManager;
this.playerModelManager = playerModelManager;
this.playerVitalsManager = playerVitalsManager;
}

public void InitializeGameObject(GameObject playerBody)
Expand Down Expand Up @@ -82,6 +86,8 @@ public void InitializeGameObject(GameObject playerBody)
playerModelManager.RegisterEquipmentVisibilityHandler(PlayerModel);
SetupBody();
SetupSkyAppliers();

vitals = playerVitalsManager.CreateOrFindForPlayer(this);
}

public void Attach(Transform transform, bool keepWorldTransform = false)
Expand Down
Loading