146 lines
5.3 KiB
C#
146 lines
5.3 KiB
C#
using System;
|
|
using NitroxClient.Communication.Abstract;
|
|
using NitroxClient.GameLogic.PlayerLogic.PlayerModel;
|
|
using NitroxClient.GameLogic.PlayerLogic.PlayerModel.Abstract;
|
|
using NitroxClient.MonoBehaviours;
|
|
using NitroxClient.Unity.Helper;
|
|
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;
|
|
|
|
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;
|
|
|
|
public GameObject Body => body.Value;
|
|
|
|
public GameObject PlayerModel => playerModel.Value;
|
|
|
|
public GameObject BodyPrototype => bodyPrototype.Value;
|
|
|
|
public string PlayerName => multiplayerSession.AuthenticationContext.Username;
|
|
/// <summary>
|
|
/// Gets the player id. The session is lost on disconnect so this can return null.
|
|
/// </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 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;
|
|
IntroCinematicMode = IntroCinematicMode.NONE;
|
|
KeepInventoryOnDeath = false;
|
|
}
|
|
|
|
public void BroadcastLocation(Vector3 location, Vector3 velocity, Quaternion bodyRotation, Quaternion aimingRotation)
|
|
{
|
|
if (!PlayerId.HasValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
PlayerMovement playerMovement = new(PlayerId.Value, location.ToDto(), velocity.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto());
|
|
|
|
packetSender.Send(playerMovement);
|
|
}
|
|
|
|
public void AnimationChange(AnimChangeType type, AnimChangeState state)
|
|
{
|
|
if (PlayerId.HasValue)
|
|
{
|
|
packetSender.Send(new AnimationChangeEvent(PlayerId.Value, (int)type, (int)state));
|
|
}
|
|
}
|
|
|
|
public void BroadcastStats(float oxygen, float maxOxygen, float health, float food, float water, float infectionAmount)
|
|
{
|
|
if (PlayerId.HasValue)
|
|
{
|
|
packetSender.Send(new PlayerStats(PlayerId.Value, oxygen, maxOxygen, health, food, water, infectionAmount));
|
|
}
|
|
}
|
|
|
|
public void BroadcastDeath(Vector3 deathPosition)
|
|
{
|
|
if (PlayerId.HasValue)
|
|
{
|
|
packetSender.Send(new PlayerDeathEvent(PlayerId.Value, deathPosition.ToDto()));
|
|
}
|
|
}
|
|
|
|
public void BroadcastSubrootChange(Optional<NitroxId> subrootId)
|
|
{
|
|
if (PlayerId.HasValue)
|
|
{
|
|
packetSender.Send(new SubRootChanged(PlayerId.Value, subrootId));
|
|
}
|
|
}
|
|
|
|
public void BroadcastEscapePodChange(Optional<NitroxId> escapePodId)
|
|
{
|
|
if (PlayerId.HasValue)
|
|
{
|
|
packetSender.Send(new EscapePodChanged(PlayerId.Value, escapePodId));
|
|
}
|
|
}
|
|
|
|
public void BroadcastWeld(NitroxId id, float healthAdded) => packetSender.Send(new WeldAction(id, healthAdded));
|
|
|
|
public void BroadcastHeldItemChanged(NitroxId itemId, PlayerHeldItemChanged.ChangeType techType, NitroxTechType isFirstTime)
|
|
{
|
|
if (PlayerId.HasValue)
|
|
{
|
|
packetSender.Send(new PlayerHeldItemChanged(PlayerId.Value, itemId, techType, isFirstTime));
|
|
}
|
|
}
|
|
|
|
public void BroadcastQuickSlotsBindingChanged(Optional<NitroxId>[] slotItemIds) => throttledPacketSender.SendThrottled(new PlayerQuickSlotsBindingChanged(slotItemIds), (packet) => 1);
|
|
|
|
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";
|
|
|
|
// 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_"))
|
|
{
|
|
Object.DestroyImmediate(child.gameObject);
|
|
}
|
|
}
|
|
|
|
return clone;
|
|
}
|
|
}
|