Added many other things and processings
This commit is contained in:
+92
-18
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user