Lathes (#207)
* Recipe stuff. * Lathe GUI and stuff * god dammit * Lathe menu works, yay. * EventArgs henk * Some work * SS14 -> Robust * More SS14 -> Robust * Lathe materials * Lathe works, Lathe GUI, Queue GUI, etc too many changes to name them here * Remove materials button, add ViewVariables and update lathe on connect * Add Autolathe RSI * Adds new recipes, fixes a few bugs. * Remove unused ScrollContainers * Use same delegate for spawn. * Removes client-side LatheComponent in favor of BoundUserInterface * Remove GetMaterial and TryGetMaterial * Use auto-properties in a few places. * Adds LatheDatabase, and a bunch of other changes * Remove useless log. * Remove lathetype from prototypes. * Turns Storage, Lathe and Database into autoproperties * Remove Hacked property from LatheRecipePrototype * Remove unneeded dependency injection from components * Refactors LatheDatabaseComponent to use ComponentState * Refactors MaterialStorageComponent to use ComponentState * Oopsie * Another oopsie * Last oopsie, I hope * Fix missing Close call.
This commit is contained in:
committed by
Pieter-Jan Briers
parent
092539ae59
commit
fe0414eda7
@@ -1,86 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Materials;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Materials
|
||||
{
|
||||
/// <summary>
|
||||
/// Component to store data such as "this object is made out of steel".
|
||||
/// This is not a storage system for say smelteries.
|
||||
/// </summary>
|
||||
public class MaterialComponent : Component
|
||||
{
|
||||
public const string SerializationCache = "mat";
|
||||
public override string Name => "Material";
|
||||
|
||||
Dictionary<object, Material> MaterialTypes;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
// TODO: Writing.
|
||||
if (!serializer.Reading)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (serializer.TryGetCacheData(SerializationCache, out Dictionary<object, Material> cached))
|
||||
{
|
||||
MaterialTypes = cached.ShallowClone();
|
||||
return;
|
||||
}
|
||||
|
||||
MaterialTypes = new Dictionary<object, Material>();
|
||||
|
||||
if (serializer.TryReadDataField("materials", out List<MaterialDataEntry> list))
|
||||
{
|
||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||
int index = 0;
|
||||
foreach (var entry in list)
|
||||
{
|
||||
var proto = protoMan.Index<MaterialPrototype>(entry.Value);
|
||||
MaterialTypes[entry.Key] = proto.Material;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
serializer.SetCacheData(SerializationCache, MaterialTypes.ShallowClone());
|
||||
}
|
||||
|
||||
class MaterialDataEntry : IExposeData
|
||||
{
|
||||
public object Key;
|
||||
public string Value;
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
if (!serializer.Reading)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var refl = IoCManager.Resolve<IReflectionManager>();
|
||||
Value = serializer.ReadDataField<string>("mat");
|
||||
var key = serializer.ReadDataField<string>("key");
|
||||
if (refl.TryParseEnumReference(key, out var @enum))
|
||||
{
|
||||
Key = @enum;
|
||||
return;
|
||||
}
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum MaterialKeys
|
||||
{
|
||||
Stack,
|
||||
}
|
||||
}
|
||||
152
Content.Server/GameObjects/Components/Research/LatheComponent.cs
Normal file
152
Content.Server/GameObjects/Components/Research/LatheComponent.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Stack;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Components.Materials;
|
||||
using Content.Shared.GameObjects.Components.Research;
|
||||
using Content.Shared.Research;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timers;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Research
|
||||
{
|
||||
public class LatheComponent : SharedLatheComponent, IAttackHand, IAttackBy, IActivate
|
||||
{
|
||||
public const int VolumePerSheet = 3750;
|
||||
|
||||
private BoundUserInterface _userInterface;
|
||||
|
||||
[ViewVariables]
|
||||
public Queue<LatheRecipePrototype> Queue { get; } = new Queue<LatheRecipePrototype>();
|
||||
|
||||
[ViewVariables]
|
||||
public bool Producing { get; private set; } = false;
|
||||
|
||||
private LatheRecipePrototype _producingRecipe = null;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(LatheUiKey.Key);
|
||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||
}
|
||||
|
||||
private void UserInterfaceOnOnReceiveMessage(BoundUserInterfaceMessage message)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case LatheQueueRecipeMessage msg:
|
||||
_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe);
|
||||
if (recipe != null)
|
||||
for (var i = 0; i < msg.Quantity; i++)
|
||||
{
|
||||
Queue.Enqueue(recipe);
|
||||
_userInterface.SendMessage(new LatheFullQueueMessage(GetIDQueue()));
|
||||
}
|
||||
break;
|
||||
case LatheSyncRequestMessage msg:
|
||||
if (!Owner.TryGetComponent(out MaterialStorageComponent storage)) return;
|
||||
_userInterface.SendMessage(new LatheFullQueueMessage(GetIDQueue()));
|
||||
if (_producingRecipe != null)
|
||||
_userInterface.SendMessage(new LatheProducingRecipeMessage(_producingRecipe.ID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool Produce(LatheRecipePrototype recipe)
|
||||
{
|
||||
if (Producing || !CanProduce(recipe) || !Owner.TryGetComponent(out MaterialStorageComponent storage)) return false;
|
||||
|
||||
_userInterface.SendMessage(new LatheFullQueueMessage(GetIDQueue()));
|
||||
|
||||
Producing = true;
|
||||
_producingRecipe = recipe;
|
||||
|
||||
foreach (var (material, amount) in recipe.RequiredMaterials)
|
||||
{
|
||||
// This should always return true, otherwise CanProduce fucked up.
|
||||
storage.RemoveMaterial(material, amount);
|
||||
}
|
||||
|
||||
_userInterface.SendMessage(new LatheProducingRecipeMessage(recipe.ID));
|
||||
|
||||
Timer.Spawn(recipe.CompleteTime, () =>
|
||||
{
|
||||
Producing = false;
|
||||
_producingRecipe = null;
|
||||
Owner.EntityManager.TrySpawnEntityAt(recipe.Result, Owner.Transform.GridPosition, out var entity);
|
||||
_userInterface.SendMessage(new LatheStoppedProducingRecipeMessage());
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||
{
|
||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
||||
return;
|
||||
|
||||
_userInterface.Open(actor.playerSession);
|
||||
return;
|
||||
}
|
||||
|
||||
bool IAttackHand.AttackHand(AttackHandEventArgs eventArgs)
|
||||
{
|
||||
|
||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
||||
return false;
|
||||
|
||||
_userInterface.Open(actor.playerSession);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IAttackBy.AttackBy(AttackByEventArgs eventArgs)
|
||||
{
|
||||
if (!Owner.TryGetComponent(out MaterialStorageComponent storage)
|
||||
|| !eventArgs.AttackWith.TryGetComponent(out MaterialComponent material)) return false;
|
||||
|
||||
var multiplier = 1;
|
||||
|
||||
if (eventArgs.AttackWith.TryGetComponent(out StackComponent stack)) multiplier = stack.Count;
|
||||
|
||||
var totalAmount = 0;
|
||||
|
||||
// Check if it can insert all materials.
|
||||
foreach (var mat in material.MaterialTypes.Values)
|
||||
{
|
||||
// TODO: Change how MaterialComponent works so this is not hard-coded.
|
||||
if (!storage.CanInsertMaterial(mat.ID, VolumePerSheet * multiplier)) return false;
|
||||
totalAmount += VolumePerSheet * multiplier;
|
||||
}
|
||||
|
||||
// Check if it can take ALL of the material's volume.
|
||||
if (storage.CanTakeAmount(totalAmount)) return false;
|
||||
|
||||
foreach (var mat in material.MaterialTypes.Values)
|
||||
{
|
||||
|
||||
storage.InsertMaterial(mat.ID, VolumePerSheet * multiplier);
|
||||
}
|
||||
|
||||
eventArgs.AttackWith.Delete();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Queue<string> GetIDQueue()
|
||||
{
|
||||
var queue = new Queue<string>();
|
||||
foreach (var recipePrototype in Queue)
|
||||
{
|
||||
queue.Enqueue(recipePrototype.ID);
|
||||
}
|
||||
|
||||
return queue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.GameObjects.Components.Research;
|
||||
using Content.Shared.Research;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Research
|
||||
{
|
||||
public class LatheDatabaseComponent : SharedLatheDatabaseComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether new recipes can be added to this database or not.
|
||||
/// </summary>
|
||||
public bool Static => _static;
|
||||
private bool _static = false;
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
return new LatheDatabaseState(GetRecipeIdList());
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(ref _static, "static", false);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
if (Static) return;
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public override void AddRecipe(LatheRecipePrototype recipe)
|
||||
{
|
||||
if (Static) return;
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public override bool RemoveRecipe(LatheRecipePrototype recipe)
|
||||
{
|
||||
if (Static || !base.RemoveRecipe(recipe)) return false;
|
||||
Dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<string> GetRecipeIdList()
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
foreach (var recipe in this)
|
||||
{
|
||||
list.Add(recipe.ID);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.GameObjects.Components.Research;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Research
|
||||
{
|
||||
public class MaterialStorageComponent : SharedMaterialStorageComponent
|
||||
{
|
||||
protected override Dictionary<string, int> Storage { get; set; } = new Dictionary<string, int>();
|
||||
|
||||
/// <summary>
|
||||
/// How much material the storage can store in total.
|
||||
/// </summary>
|
||||
public int StorageLimit => _storageLimit;
|
||||
private int _storageLimit;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(ref _storageLimit, "StorageLimit", -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Content.Server/GameObjects/EntitySystems/LatheSystem.cs
Normal file
26
Content.Server/GameObjects/EntitySystems/LatheSystem.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Content.Server.GameObjects.Components.Research;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
|
||||
namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
public class LatheSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
EntityQuery = new TypeEntityQuery(typeof(LatheComponent));
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
foreach (var entity in RelevantEntities)
|
||||
{
|
||||
var comp = entity.GetComponent<LatheComponent>();
|
||||
if (comp.Producing == false && comp.Queue.Count > 0)
|
||||
{
|
||||
comp.Produce(comp.Queue.Dequeue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user