90 lines
3.4 KiB
C#
90 lines
3.4 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[CreateAssetMenu(
|
|
fileName = "RocketAssemblyRecipe",
|
|
menuName = "FORT-BO/Workstations/Rocket Assembly Recipe")]
|
|
public sealed class RocketAssemblyRecipe : ScriptableObject
|
|
{
|
|
public const int MaximumPartCount = 9;
|
|
|
|
[Header("Recipe")]
|
|
[SerializeField] private string recipeId;
|
|
[SerializeField] private string displayName;
|
|
[Tooltip("Exact assembly order. Element 0 is the lowest rocket part.")]
|
|
[SerializeField] private List<ItemDefinition> requiredPartsBottomToTop = new();
|
|
[SerializeField] private ItemDefinition outputItem;
|
|
[SerializeField] private ItemDefinition defectiveOutputItem;
|
|
[SerializeField, Min(0.05f)] private float assemblyDuration = 5f;
|
|
|
|
[Header("Blueprint")]
|
|
[SerializeField] private string blueprintTitle;
|
|
[SerializeField] private Sprite blueprintImage;
|
|
|
|
public string RecipeId => recipeId;
|
|
public string DisplayName => string.IsNullOrWhiteSpace(displayName) ? name : displayName;
|
|
public IReadOnlyList<ItemDefinition> RequiredPartsBottomToTop => requiredPartsBottomToTop;
|
|
public int RequiredPartCount => requiredPartsBottomToTop.Count;
|
|
public ItemDefinition OutputItem => outputItem;
|
|
public ItemDefinition DefectiveOutputItem => defectiveOutputItem;
|
|
public float AssemblyDuration => assemblyDuration;
|
|
public string BlueprintTitle => string.IsNullOrWhiteSpace(blueprintTitle)
|
|
? DisplayName
|
|
: blueprintTitle;
|
|
public Sprite BlueprintImage => blueprintImage;
|
|
|
|
public bool IsConfigured =>
|
|
requiredPartsBottomToTop.Count is > 0 and <= MaximumPartCount &&
|
|
requiredPartsBottomToTop.TrueForAll(IsReadyRocketPart) &&
|
|
IsSpawnable(outputItem) &&
|
|
IsSpawnable(defectiveOutputItem);
|
|
|
|
public bool Matches(IReadOnlyList<NetworkItem> slottedItems)
|
|
{
|
|
if (!IsConfigured || slottedItems == null ||
|
|
slottedItems.Count < requiredPartsBottomToTop.Count)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (int index = 0; index < requiredPartsBottomToTop.Count; index++)
|
|
{
|
|
NetworkItem item = slottedItems[index];
|
|
if (item == null || !MatchesDefinition(item, requiredPartsBottomToTop[index]))
|
|
return false;
|
|
}
|
|
|
|
for (int index = requiredPartsBottomToTop.Count; index < slottedItems.Count; index++)
|
|
{
|
|
if (slottedItems[index] != null)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void OnValidate()
|
|
{
|
|
recipeId = recipeId?.Trim().ToLowerInvariant();
|
|
displayName = displayName?.Trim();
|
|
blueprintTitle = blueprintTitle?.Trim();
|
|
|
|
if (requiredPartsBottomToTop.Count > MaximumPartCount)
|
|
requiredPartsBottomToTop.RemoveRange(
|
|
MaximumPartCount,
|
|
requiredPartsBottomToTop.Count - MaximumPartCount);
|
|
}
|
|
|
|
private static bool MatchesDefinition(NetworkItem item, ItemDefinition definition) =>
|
|
item.Definition == definition ||
|
|
(!string.IsNullOrEmpty(definition.ItemId) && item.ItemId == definition.ItemId);
|
|
|
|
private static bool IsReadyRocketPart(ItemDefinition definition) =>
|
|
definition != null &&
|
|
definition.Category == ItemCategory.RocketPart &&
|
|
definition.IsAssemblyReady;
|
|
|
|
private static bool IsSpawnable(ItemDefinition definition) =>
|
|
definition != null && definition.WorldPrefab != null;
|
|
}
|