Lathe Refactor and ECS (#11201)

* lathe and material storage refactor

* materialStorage ECS

it kinda sus tho

* beginning the lathe shitcode dive

* couple lathe visuals and lathe system

* lathe changes and such

* dynamic lathe databases

* rewrote internal logic

on to ui

* da newI

* material display clientside

* misc ui changes

* component state handling and various other things

* moar

* Update Content.Shared/Lathe/LatheComponent.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* first volley of sloth review

* more fixes

* losin' my mind

* all da changes

* test fix and other review

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
Nemanja
2022-09-16 19:49:05 -04:00
committed by GitHub
parent b62ab67fcb
commit 2e7dcb1ed8
40 changed files with 1225 additions and 1554 deletions

View File

@@ -1,41 +0,0 @@
using Content.Shared.Lathe;
using Content.Shared.Research.Prototypes;
using Robust.Server.GameObjects;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Robust.Shared.Audio;
namespace Content.Server.Lathe.Components
{
[RegisterComponent]
public sealed class LatheComponent : SharedLatheComponent
{
/// <summary>
/// The lathe's construction queue
/// </summary>
[DataField("queue", customTypeSerializer: typeof(PrototypeIdListSerializer<LatheRecipePrototype>))]
public List<string> Queue { get; } = new();
// TODO queue serializer.
/// <summary>
/// How long the inserting animation will play
/// </summary>
[ViewVariables]
public float InsertionTime = 0.79f; // 0.01 off for animation timing
/// <summary>
/// Update accumulator for the insertion time
/// </suummary>
[DataField("insertionAccumulator")]
public float InsertionAccumulator = 0f;
/// <summary>
/// The sound that plays when the lathe is producing an item, if any
/// </summary>
[DataField("producingSound")]
public SoundSpecifier? ProducingSound;
/// <summmary>
/// The lathe's UI.
/// </summary>
[ViewVariables] public BoundUserInterface? UserInterface;
}
}

View File

@@ -1,43 +0,0 @@
using Content.Shared.Lathe;
using Content.Shared.Research.Prototypes;
namespace Content.Server.Lathe.Components
{
[RegisterComponent]
[ComponentReference(typeof(SharedLatheDatabaseComponent))]
public sealed class LatheDatabaseComponent : SharedLatheDatabaseComponent
{
/// <summary>
/// Whether new recipes can be added to this database or not.
/// </summary>
[ViewVariables]
[DataField("static")]
public bool Static { get; private set; } = false;
public override ComponentState GetComponentState()
{
return new LatheDatabaseState(GetRecipeIdList());
}
public override void Clear()
{
if (Static) return;
base.Clear();
Dirty();
}
public override void AddRecipe(LatheRecipePrototype recipe)
{
if (Static) return;
base.AddRecipe(recipe);
Dirty();
}
public override bool RemoveRecipe(LatheRecipePrototype recipe)
{
if (Static || !base.RemoveRecipe(recipe)) return false;
Dirty();
return true;
}
}
}

View File

@@ -2,7 +2,7 @@ namespace Content.Server.Lathe.Components
{
/// <summary>
/// For EntityQuery to keep track of which lathes are inserting
/// <summary>
/// </summary>
[RegisterComponent]
public sealed class LatheInsertingComponent : Component
{

View File

@@ -1,24 +1,15 @@
using Content.Shared.Research.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Lathe.Components;
namespace Content.Server.Lathe.Components
/// <summary>
/// For EntityQuery to keep track of which lathes are producing
/// </summary>
[RegisterComponent]
public sealed class LatheProducingComponent : Component
{
/// <summary>
/// For EntityQuery to keep track of which lathes are producing
/// <summary>
[RegisterComponent]
public sealed class LatheProducingComponent : Component
{
/// <summary>
/// The recipe the lathe is currently producing
/// </summary>
[DataField("recipe", required:true, customTypeSerializer:typeof(PrototypeIdSerializer<LatheRecipePrototype>))]
public string? Recipe;
/// <summary>
/// Remaining production time, in seconds.
/// </summary>
[DataField("timeRemaining", required: true)]
public float TimeRemaining;
}
/// How much production time has passed, in seconds.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float AccumulatedTime;
}

View File

@@ -1,110 +0,0 @@
using Content.Shared.Lathe;
using Content.Shared.Whitelist;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Content.Shared.Materials;
using Robust.Shared.Audio;
namespace Content.Server.Lathe.Components
{
[RegisterComponent]
[ComponentReference(typeof(SharedMaterialStorageComponent))]
public sealed class MaterialStorageComponent : SharedMaterialStorageComponent
{
[ViewVariables]
protected override Dictionary<string, int> Storage { get; set; } = new();
/// <summary>
/// How much material the storage can store in total.
/// </summary>
[ViewVariables]
public int StorageLimit => _storageLimit;
[DataField("StorageLimit")]
private int _storageLimit = -1;
/// <summary>
/// Whitelist for specifying the kind of items that can be insert into this entity.
/// </summary>
[ViewVariables]
[DataField("whitelist")]
public EntityWhitelist? EntityWhitelist;
/// <summary>
/// Whitelist generated on runtime for what specific materials can be inserted into this entity.
/// </summary>
[ViewVariables]
[DataField("materialWhiteList", customTypeSerializer: typeof(PrototypeIdListSerializer<MaterialPrototype>))]
public List<string> MaterialWhiteList = new();
/// <summary>
/// The sound that plays when inserting an item into the storage
/// </summary>
[DataField("insertingSound")]
public SoundSpecifier? InsertingSound;
public override ComponentState GetComponentState()
{
return new MaterialStorageState(Storage);
}
/// <summary>
/// Checks if the storage can take a volume of material without surpassing its own limits.
/// </summary>
/// <param name="amount">The volume of material</param>
/// <returns></returns>
public bool CanTakeAmount(int amount)
{
return CurrentAmount + amount <= StorageLimit;
}
/// <summary>
/// Checks if it can insert a material.
/// </summary>
/// <param name="id">Material ID</param>
/// <param name="amount">How much to insert</param>
/// <returns>Whether it can insert the material or not.</returns>
public bool CanInsertMaterial(string id, int amount)
{
return (CanTakeAmount(amount) || StorageLimit < 0) && (!Storage.ContainsKey(id) || Storage[id] + amount >= 0);
}
/// <summary>
/// Inserts material into the storage.
/// </summary>
/// <param name="id">Material ID</param>
/// <param name="amount">How much to insert</param>
/// <returns>Whether it inserted it or not.</returns>
public bool InsertMaterial(string id, int amount)
{
if (!CanInsertMaterial(id, amount)) return false;
if (!Storage.ContainsKey(id))
Storage.Add(id, 0);
Storage[id] += amount;
Dirty();
return true;
}
/// <summary>
/// Removes material from the storage.
/// </summary>
/// <param name="id">Material ID</param>
/// <param name="amount">How much to remove</param>
/// <returns>Whether it removed it or not.</returns>
public bool RemoveMaterial(string id, int amount)
{
return InsertMaterial(id, -amount);
}
// forgive me I needed to write a crumb of e/c code to not go fucking insane i swear i will ecs this entire shitty fucking system one day
public int GetMaterialAmount(string id)
{
if (!Storage.TryGetValue(id, out var amount))
return 0;
return amount;
}
}
}

View File

@@ -1,53 +0,0 @@
using System.Linq;
using Content.Server.Research.Components;
using Content.Shared.Lathe;
using Content.Shared.Research.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Server.Lathe.Components
{
[RegisterComponent]
[ComponentReference(typeof(SharedLatheDatabaseComponent))]
public sealed class ProtolatheDatabaseComponent : SharedProtolatheDatabaseComponent
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public override ComponentState GetComponentState()
{
return new ProtolatheDatabaseState(GetRecipeIdList());
}
/// <summary>
/// Adds unlocked recipes from technologies to the database.
/// </summary>
public void Sync()
{
if (!IoCManager.Resolve<IEntityManager>().TryGetComponent(Owner, out TechnologyDatabaseComponent? database)) return;
foreach (var technology in database.Technologies)
{
foreach (var id in technology.UnlockedRecipes)
{
var recipe = (LatheRecipePrototype) _prototypeManager.Index(typeof(LatheRecipePrototype), id);
UnlockRecipe(recipe);
}
}
Dirty();
}
/// <summary>
/// Unlocks a recipe but only if it's one of the allowed recipes on this protolathe.
/// </summary>
/// <param name="recipe">The recipe</param>
/// <returns>Whether it could add it or not.</returns>
public bool UnlockRecipe(LatheRecipePrototype recipe)
{
if (!ProtolatheRecipes.Contains(recipe)) return false;
AddRecipe(recipe);
return true;
}
}
}