Added RocketAssemblyStation and ReadyRocket
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
|
||||
public enum RocketAssemblyQuality : byte
|
||||
{
|
||||
Normal,
|
||||
Defective
|
||||
}
|
||||
|
||||
public struct RocketCriticalImpactState : INetworkSerializable,
|
||||
IEquatable<RocketCriticalImpactState>
|
||||
{
|
||||
public uint Sequence;
|
||||
public Vector3 Point;
|
||||
public float Speed;
|
||||
|
||||
public RocketCriticalImpactState(uint sequence, Vector3 point, float speed)
|
||||
{
|
||||
Sequence = sequence;
|
||||
Point = point;
|
||||
Speed = speed;
|
||||
}
|
||||
|
||||
public void NetworkSerialize<T>(BufferSerializer<T> serializer)
|
||||
where T : IReaderWriter
|
||||
{
|
||||
serializer.SerializeValue(ref Sequence);
|
||||
serializer.SerializeValue(ref Point);
|
||||
serializer.SerializeValue(ref Speed);
|
||||
}
|
||||
|
||||
public bool Equals(RocketCriticalImpactState other) =>
|
||||
Sequence == other.Sequence && Point == other.Point && Speed.Equals(other.Speed);
|
||||
}
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(NetworkItem), typeof(Rigidbody))]
|
||||
public sealed class NetworkRocketItem : NetworkBehaviour
|
||||
{
|
||||
[SerializeField] private NetworkItem networkItem;
|
||||
[SerializeField] private Rigidbody physicsBody;
|
||||
|
||||
private readonly NetworkVariable<RocketAssemblyQuality> assemblyQuality = new(
|
||||
RocketAssemblyQuality.Normal,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkVariable<RocketCriticalImpactState> criticalImpactState = new(
|
||||
default,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
public RocketItemDefinition Definition =>
|
||||
networkItem != null && networkItem.TryGetDefinition(out RocketItemDefinition definition)
|
||||
? definition
|
||||
: null;
|
||||
public string RocketTypeId => Definition != null ? Definition.RocketTypeId : string.Empty;
|
||||
public RocketAssemblyQuality AssemblyQuality => assemblyQuality.Value;
|
||||
public bool IsDefective => AssemblyQuality == RocketAssemblyQuality.Defective;
|
||||
public bool IsCriticallyDamaged => criticalImpactState.Value.Sequence > 0;
|
||||
public uint CriticalImpactSequence => criticalImpactState.Value.Sequence;
|
||||
public Vector3 LastCriticalImpactPoint => criticalImpactState.Value.Point;
|
||||
public float LastCriticalImpactSpeed => criticalImpactState.Value.Speed;
|
||||
|
||||
public event Action Changed;
|
||||
public event Action CriticalImpact;
|
||||
|
||||
private void Reset() => ResolveReferences();
|
||||
|
||||
private void Awake() => ResolveReferences();
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
assemblyQuality.OnValueChanged += HandleAssemblyQualityChanged;
|
||||
criticalImpactState.OnValueChanged += HandleCriticalImpactChanged;
|
||||
|
||||
if (Definition == null)
|
||||
{
|
||||
Debug.LogError(
|
||||
$"{name} has NetworkRocketItem but its NetworkItem does not reference " +
|
||||
"a RocketItemDefinition.",
|
||||
this);
|
||||
}
|
||||
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
assemblyQuality.OnValueChanged -= HandleAssemblyQualityChanged;
|
||||
criticalImpactState.OnValueChanged -= HandleCriticalImpactChanged;
|
||||
}
|
||||
|
||||
private void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
if (!IsServer || !IsSpawned || IsCriticallyDamaged || Definition == null)
|
||||
return;
|
||||
|
||||
float impactSpeed = collision.relativeVelocity.magnitude;
|
||||
if (impactSpeed < Definition.CriticalImpactSpeed)
|
||||
return;
|
||||
|
||||
Vector3 impactPoint = collision.contactCount > 0
|
||||
? collision.GetContact(0).point
|
||||
: transform.position;
|
||||
TryTriggerCriticalImpact(impactPoint, impactSpeed);
|
||||
}
|
||||
|
||||
public bool TryTriggerCriticalImpact(Vector3 impactPoint, float impactSpeed)
|
||||
{
|
||||
if (!IsServer || !IsSpawned || IsCriticallyDamaged || Definition == null ||
|
||||
impactSpeed < Definition.CriticalImpactSpeed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
criticalImpactState.Value = new RocketCriticalImpactState(
|
||||
criticalImpactState.Value.Sequence + 1,
|
||||
impactPoint,
|
||||
impactSpeed);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryInitializeAssemblyQuality(bool isDefectiveResult)
|
||||
{
|
||||
if (!IsServer || !IsSpawned)
|
||||
return false;
|
||||
|
||||
assemblyQuality.Value = isDefectiveResult
|
||||
? RocketAssemblyQuality.Defective
|
||||
: RocketAssemblyQuality.Normal;
|
||||
return true;
|
||||
}
|
||||
|
||||
[ContextMenu("Debug/Trigger Critical Impact (Server Play Mode)")]
|
||||
private void TriggerCriticalImpactFromContextMenu()
|
||||
{
|
||||
if (Application.isPlaying && IsServer && IsSpawned && Definition != null)
|
||||
{
|
||||
TryTriggerCriticalImpact(
|
||||
transform.position,
|
||||
Definition.CriticalImpactSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
private void ResolveReferences()
|
||||
{
|
||||
if (networkItem == null)
|
||||
networkItem = GetComponent<NetworkItem>();
|
||||
|
||||
if (physicsBody == null)
|
||||
physicsBody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
private void HandleAssemblyQualityChanged(
|
||||
RocketAssemblyQuality _,
|
||||
RocketAssemblyQuality __) => Changed?.Invoke();
|
||||
|
||||
private void HandleCriticalImpactChanged(
|
||||
RocketCriticalImpactState previous,
|
||||
RocketCriticalImpactState current)
|
||||
{
|
||||
Changed?.Invoke();
|
||||
if (current.Sequence != previous.Sequence)
|
||||
CriticalImpact?.Invoke();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user