Added RocketAssemblyStation and ReadyRocket

This commit is contained in:
2026-08-18 16:12:00 +03:00
parent 7a0ee6b519
commit 63d2836dc9
85 changed files with 15087 additions and 3562 deletions
@@ -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();
}
}