Added many other things and processings

This commit is contained in:
2026-08-13 17:55:05 +03:00
parent 36ecac038a
commit 3c490bdae8
625 changed files with 929224 additions and 151067 deletions
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
@@ -11,8 +12,8 @@ public enum ItemProcessingWorkstationState : byte
public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationController
{
[Header("Recipe")]
[SerializeField] private ItemProcessingRecipe recipe;
[Header("Recipes")]
[SerializeField] private List<ItemProcessingRecipe> recipes = new();
[Header("Slot")]
[SerializeField] private Transform inputPoint;
@@ -32,16 +33,27 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Server);
private readonly NetworkVariable<int> activeRecipeIndex = new(
-1,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Server);
private NetworkItem currentItem;
private IWorkstationItemControl currentItemControl;
public override bool IsOperating => State == ItemProcessingWorkstationState.Processing;
public ItemProcessingWorkstationState State => state.Value;
public ItemProcessingRecipe Recipe => recipe;
public IReadOnlyList<ItemProcessingRecipe> Recipes => recipes;
public int ActiveRecipeIndex => activeRecipeIndex.Value;
public ItemProcessingRecipe ActiveRecipe => TryGetRecipe(
activeRecipeIndex.Value,
out ItemProcessingRecipe recipe)
? recipe
: null;
public NetworkItem CurrentItem => currentItem;
public bool CanAcceptItem => IsServer && IsSpawned &&
State == ItemProcessingWorkstationState.Empty &&
recipe != null && recipe.InputItem != null &&
recipe.OutputItem != null && recipe.OutputItem.WorldPrefab != null;
recipes.Exists(IsRecipeValid);
public float ProcessProgress
{
@@ -72,6 +84,7 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
state.OnValueChanged += HandleStateChanged;
processStartedAt.OnValueChanged += HandleProcessTimeChanged;
processEndsAt.OnValueChanged += HandleProcessTimeChanged;
activeRecipeIndex.OnValueChanged += HandleActiveRecipeChanged;
if (IsServer)
ResetWorkstationOnServer();
@@ -84,6 +97,7 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
state.OnValueChanged -= HandleStateChanged;
processStartedAt.OnValueChanged -= HandleProcessTimeChanged;
processEndsAt.OnValueChanged -= HandleProcessTimeChanged;
activeRecipeIndex.OnValueChanged -= HandleActiveRecipeChanged;
}
private void Update()
@@ -123,15 +137,19 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
public bool TryAcceptItem(NetworkItem item)
{
if (!CanAcceptItem || item == null || !item.IsSpawned || !recipe.Accepts(item))
if (!CanAcceptItem || item == null || !item.IsSpawned ||
!TryFindRecipe(item, out int recipeIndex, out ItemProcessingRecipe recipe) ||
!TryGetItemControl(item, out IWorkstationItemControl itemControl))
{
return false;
}
NetworkCarryableInteractable carryable =
item.GetComponent<NetworkCarryableInteractable>();
if (carryable == null || !carryable.TryAcquireExternalControl())
if (!itemControl.TryAcquireExternalControl())
return false;
currentItem = item;
currentItemControl = itemControl;
activeRecipeIndex.Value = recipeIndex;
SnapToInputPoint(item.transform);
double now = GetNetworkTime();
@@ -156,6 +174,7 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
private void CompleteProcessingOnServer()
{
ItemProcessingRecipe recipe = ActiveRecipe;
if (currentItem == null || recipe == null ||
recipe.OutputItem == null || recipe.OutputItem.WorldPrefab == null)
{
@@ -169,6 +188,7 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
NetworkObject inputObject = currentItem.NetworkObject;
currentItem = null;
currentItemControl = null;
if (inputObject != null && inputObject.IsSpawned)
inputObject.Despawn(true);
@@ -180,13 +200,12 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
outputObject.Spawn();
currentItem = outputObject.GetComponent<NetworkItem>();
if (currentItem == null ||
outputObject.GetComponent<NetworkCarryableInteractable>() == null)
if (currentItem == null || !TryGetItemControl(currentItem, out _))
{
Debug.LogError(
$"{name} cannot produce '{recipe.OutputItem.DisplayName}': " +
"the output prefab must contain NetworkItem and " +
"NetworkCarryableInteractable.",
"the output prefab must contain NetworkItem and a supported " +
"Carry or Drag interaction component.",
this);
outputObject.Despawn(true);
currentItem = null;
@@ -205,13 +224,12 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
if (!IsServer)
return;
if (State == ItemProcessingWorkstationState.Processing && currentItem != null &&
currentItem.TryGetComponent(out NetworkCarryableInteractable carryable))
{
carryable.TryReleaseExternalControl();
}
if (State == ItemProcessingWorkstationState.Processing && currentItemControl != null)
currentItemControl.TryReleaseExternalControl();
currentItem = null;
currentItemControl = null;
activeRecipeIndex.Value = -1;
processStartedAt.Value = 0d;
processEndsAt.Value = 0d;
state.Value = ItemProcessingWorkstationState.Empty;
@@ -233,4 +251,60 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
ItemProcessingWorkstationState __) => Changed?.Invoke();
private void HandleProcessTimeChanged(double _, double __) => Changed?.Invoke();
private void HandleActiveRecipeChanged(int _, int __) => Changed?.Invoke();
private bool TryFindRecipe(
NetworkItem item,
out int recipeIndex,
out ItemProcessingRecipe recipe)
{
for (int index = 0; index < recipes.Count; index++)
{
ItemProcessingRecipe candidate = recipes[index];
if (IsRecipeValid(candidate) && candidate.Accepts(item))
{
recipeIndex = index;
recipe = candidate;
return true;
}
}
recipeIndex = -1;
recipe = null;
return false;
}
private bool TryGetRecipe(int index, out ItemProcessingRecipe recipe)
{
if (index >= 0 && index < recipes.Count && IsRecipeValid(recipes[index]))
{
recipe = recipes[index];
return true;
}
recipe = null;
return false;
}
private static bool IsRecipeValid(ItemProcessingRecipe recipe) =>
recipe != null && recipe.InputItem != null &&
recipe.OutputItem != null && recipe.OutputItem.WorldPrefab != null;
private static bool TryGetItemControl(
NetworkItem item,
out IWorkstationItemControl itemControl)
{
foreach (MonoBehaviour component in item.GetComponents<MonoBehaviour>())
{
if (component is IWorkstationItemControl candidate)
{
itemControl = candidate;
return true;
}
}
itemControl = null;
return false;
}
}