* 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:
Víctor Aguilera Puerto
2019-04-26 15:51:05 +02:00
committed by Pieter-Jan Briers
parent 092539ae59
commit fe0414eda7
37 changed files with 1580 additions and 13 deletions

View File

@@ -86,6 +86,9 @@
<Compile Include="GameObjects\Components\Items\ItemComponent.cs" />
<Compile Include="GameObjects\Components\Power\ApcBoundUserInterface.cs" />
<Compile Include="GameObjects\Components\Power\PowerCellVisualizer2D.cs" />
<Compile Include="GameObjects\Components\Research\LatheBoundUserInterface.cs" />
<Compile Include="GameObjects\Components\Research\LatheDatabaseComponent.cs" />
<Compile Include="GameObjects\Components\Research\MaterialStorageComponent.cs" />
<Compile Include="GameObjects\Components\Sound\SoundComponent.cs" />
<Compile Include="GameObjects\Components\Storage\ClientStorageComponent.cs" />
<Compile Include="GameObjects\Components\SubFloorHideComponent.cs" />
@@ -114,6 +117,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GameObjects\Components\Items\ClientHandsComponent.cs" />
<Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" />
<Compile Include="Research\LatheMenu.cs" />
<Compile Include="Research\LatheQueueMenu.cs" />
<Compile Include="UserInterface\HandsGui.cs" />
<Compile Include="GameObjects\Components\Power\PowerDebugTool.cs" />
<Compile Include="UserInterface\LobbyGui.cs" />

View File

@@ -28,11 +28,15 @@ using System;
using Content.Client.Chat;
using Content.Client.GameObjects.Components;
using Content.Client.GameObjects.Components.Mobs;
using Content.Client.GameObjects.Components.Research;
using Content.Client.GameObjects.Components.Sound;
using Content.Client.Interfaces.Chat;
using Content.Client.Research;
using Content.Client.UserInterface;
using Content.Shared.GameObjects.Components.Markers;
using Content.Shared.GameObjects.Components.Materials;
using Content.Shared.GameObjects.Components.Mobs;
using Content.Shared.GameObjects.Components.Research;
using Robust.Client.Interfaces.UserInterface;
using Robust.Shared.Log;
@@ -72,7 +76,6 @@ namespace Content.Client
factory.RegisterIgnore("Storeable");
factory.RegisterIgnore("Material");
factory.RegisterIgnore("Stack");
factory.Register<HandsComponent>();
@@ -86,7 +89,10 @@ namespace Content.Client
factory.Register<DamageableComponent>();
factory.Register<ClothingComponent>();
factory.Register<ItemComponent>();
factory.Register<MaterialComponent>();
factory.Register<SoundComponent>();
factory.Register<MaterialStorageComponent>();
factory.RegisterReference<MaterialStorageComponent, SharedMaterialStorageComponent>();
factory.RegisterReference<ClothingComponent, ItemComponent>();
@@ -114,6 +120,11 @@ namespace Content.Client
factory.Register<SharedSpawnPointComponent>();
factory.Register<SharedLatheComponent>();
factory.Register<LatheDatabaseComponent>();
factory.RegisterReference<LatheDatabaseComponent, SharedLatheDatabaseComponent>();
factory.Register<CameraRecoilComponent>();
factory.RegisterReference<CameraRecoilComponent, SharedCameraRecoilComponent>();

View File

@@ -0,0 +1,107 @@
using System.Collections.Generic;
using Content.Client.Research;
using Content.Shared.GameObjects.Components.Research;
using Content.Shared.Research;
using Robust.Client.GameObjects.Components.UserInterface;
using Robust.Client.Interfaces.Graphics;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components.Research
{
public class LatheBoundUserInterface : BoundUserInterface
{
#pragma warning disable CS0649
[Dependency]
private IDisplayManager _displayManager;
[Dependency]
private IPrototypeManager _prototypeManager;
#pragma warning restore
[ViewVariables]
private LatheMenu menu;
[ViewVariables]
private LatheQueueMenu queueMenu;
public MaterialStorageComponent Storage { get; private set; }
public SharedLatheComponent Lathe { get; private set; }
public LatheDatabaseComponent Database { get; private set; }
[ViewVariables]
public Queue<LatheRecipePrototype> QueuedRecipes => _queuedRecipes;
private Queue<LatheRecipePrototype> _queuedRecipes = new Queue<LatheRecipePrototype>();
public LatheBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
SendMessage(new SharedLatheComponent.LatheSyncRequestMessage());
}
protected override void Open()
{
base.Open();
IoCManager.InjectDependencies(this);
if (!Owner.Owner.TryGetComponent(out MaterialStorageComponent storage)
|| !Owner.Owner.TryGetComponent(out SharedLatheComponent lathe)
|| !Owner.Owner.TryGetComponent(out LatheDatabaseComponent database)) return;
Storage = storage;
Lathe = lathe;
Database = database;
menu = new LatheMenu(_displayManager) {Owner = this};
queueMenu = new LatheQueueMenu(_displayManager) { Owner = this };
menu.OnClose += Close;
menu.AddToScreen();
menu.Populate();
menu.PopulateMaterials();
queueMenu.AddToScreen();
menu.QueueButton.OnPressed += (args) => { queueMenu.OpenCentered(); };
storage.OnMaterialStorageChanged += menu.PopulateDisabled;
storage.OnMaterialStorageChanged += menu.PopulateMaterials;
menu.OpenCentered();
}
public void Queue(LatheRecipePrototype recipe, int quantity = 1)
{
SendMessage(new SharedLatheComponent.LatheQueueRecipeMessage(recipe.ID, quantity));
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
switch (message)
{
case SharedLatheComponent.LatheProducingRecipeMessage msg:
if (!_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe)) break;
queueMenu.SetInfo(recipe);
break;
case SharedLatheComponent.LatheStoppedProducingRecipeMessage msg:
queueMenu.ClearInfo();
break;
case SharedLatheComponent.LatheFullQueueMessage msg:
_queuedRecipes.Clear();
foreach (var id in msg.Recipes)
{
if (!_prototypeManager.TryIndex(id, out LatheRecipePrototype recipePrototype)) break;
_queuedRecipes.Enqueue(recipePrototype);
}
queueMenu.PopulateList();
break;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
menu?.Dispose();
queueMenu?.Dispose();
}
}
}

View File

@@ -0,0 +1,30 @@
using Content.Shared.GameObjects.Components.Research;
using Content.Shared.Research;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
namespace Content.Client.GameObjects.Components.Research
{
public class LatheDatabaseComponent : SharedLatheDatabaseComponent
{
#pragma warning disable CS0649
[Dependency]
private IPrototypeManager _prototypeManager;
#pragma warning restore
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
base.HandleComponentState(curState, nextState);
if (!(curState is LatheDatabaseState state)) return;
Clear();
foreach (var ID in state.Recipes)
{
if(!_prototypeManager.TryIndex(ID, out LatheRecipePrototype recipe)) continue;
AddRecipe(recipe);
}
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using Content.Shared.GameObjects.Components.Research;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network;
namespace Content.Client.GameObjects.Components.Research
{
public class MaterialStorageComponent : SharedMaterialStorageComponent
{
protected override Dictionary<string, int> Storage { get; set; } = new Dictionary<string, int>();
public event Action OnMaterialStorageChanged;
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
base.HandleComponentState(curState, nextState);
if (!(curState is MaterialStorageState state)) return;
Storage = state.Storage;
OnMaterialStorageChanged?.Invoke();
}
}
}

View File

@@ -0,0 +1,255 @@
using System.Collections.Generic;
using Content.Client.GameObjects.Components.Research;
using Content.Shared.Materials;
using Content.Shared.Research;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.Utility;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Timers;
using Robust.Shared.Utility;
namespace Content.Client.Research
{
public class LatheMenu : SS14Window
{
#pragma warning disable CS0649
[Dependency]
private IPrototypeManager PrototypeManager;
[Dependency]
private IResourceCache ResourceCache;
#pragma warning restore
private ItemList Items;
private ItemList Materials;
private LineEdit AmountLineEdit;
private LineEdit SearchBar;
public Button QueueButton;
protected override Vector2? CustomSize => (300, 450);
public LatheBoundUserInterface Owner { get; set; }
private List<LatheRecipePrototype> _recipes = new List<LatheRecipePrototype>();
private List<LatheRecipePrototype> _shownRecipes = new List<LatheRecipePrototype>();
public LatheMenu(IDisplayManager displayMan) : base(displayMan)
{
}
public LatheMenu(IDisplayManager displayMan, string name) : base(displayMan, name)
{
}
protected override void Initialize()
{
base.Initialize();
IoCManager.InjectDependencies(this);
HideOnClose = true;
Title = "Lathe Menu";
Visible = false;
var margin = new MarginContainer()
{
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsHorizontal = SizeFlags.FillExpand,
MarginTop = 5f,
MarginLeft = 5f,
MarginRight = -5f,
MarginBottom = -5f,
};
margin.SetAnchorAndMarginPreset(LayoutPreset.Wide);
var vbox = new VBoxContainer()
{
SizeFlagsVertical = SizeFlags.FillExpand,
SeparationOverride = 5,
};
vbox.SetAnchorAndMarginPreset(LayoutPreset.Wide);
var hboxButtons = new HBoxContainer()
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1,
};
QueueButton = new Button()
{
Text = "Queue",
TextAlign = Button.AlignMode.Center,
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1,
};
var spacer = new Control()
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 3,
};
spacer.SetAnchorAndMarginPreset(LayoutPreset.Wide);
var hboxFilter = new HBoxContainer()
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1
};
SearchBar = new LineEdit()
{
PlaceHolder = "Search Designs",
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 3
};
SearchBar.OnTextChanged += Populate;
var filterButton = new Button()
{
Text = "Filter",
TextAlign = Button.AlignMode.Center,
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1,
Disabled = true,
};
Items = new ItemList()
{
SizeFlagsStretchRatio = 8,
SizeFlagsVertical = SizeFlags.FillExpand,
};
Items.OnItemSelected += ItemSelected;
AmountLineEdit = new LineEdit()
{
PlaceHolder = "Amount",
Text = "1",
SizeFlagsHorizontal = SizeFlags.FillExpand,
};
AmountLineEdit.OnTextChanged += PopulateDisabled;
Materials = new ItemList()
{
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 3
};
hboxButtons.AddChild(spacer);
hboxButtons.AddChild(QueueButton);
hboxFilter.AddChild(SearchBar);
hboxFilter.AddChild(filterButton);
vbox.AddChild(hboxButtons);
vbox.AddChild(hboxFilter);
vbox.AddChild(Items);
vbox.AddChild(AmountLineEdit);
vbox.AddChild(Materials);
margin.AddChild(vbox);
Contents.AddChild(margin);
}
public void ItemSelected(ItemList.ItemListSelectedEventArgs args)
{
int.TryParse(AmountLineEdit.Text, out var quantity);
if (quantity <= 0) quantity = 1;
Owner.Queue(_shownRecipes[args.ItemIndex], quantity);
Items.SelectMode = ItemList.ItemListSelectMode.None;
Timer.Spawn(100, () =>
{
Items.Unselect(args.ItemIndex);
Items.SelectMode = ItemList.ItemListSelectMode.Single;
});
}
public void PopulateMaterials()
{
Materials.Clear();
foreach (var (id, amount) in Owner.Storage)
{
if (!PrototypeManager.TryIndex(id, out MaterialPrototype materialPrototype)) continue;
var material = materialPrototype.Material;
Materials.AddItem($"{material.Name} {amount} cm3", material.Icon.Frame0(), false);
}
}
/// <summary>
/// Disables or enables shown recipes depending on whether there are enough materials for it or not.
/// </summary>
public void PopulateDisabled()
{
int.TryParse(AmountLineEdit.Text, out var quantity);
if (quantity <= 0) quantity = 1;
for (var i = 0; i < _shownRecipes.Count; i++)
{
var prototype = _shownRecipes[i];
Items.SetItemDisabled(i, !Owner.Lathe.CanProduce(prototype, quantity));
}
}
/// <inheritdoc cref="PopulateDisabled()"/>
public void PopulateDisabled(LineEdit.LineEditEventArgs args)
{
PopulateDisabled();
}
/// <summary>
/// Adds shown recipes to the ItemList control.
/// </summary>
public void PopulateList()
{
Items.Clear();
for (var i = 0; i < _shownRecipes.Count; i++)
{
var prototype = _shownRecipes[i];
Items.AddItem(prototype.Name, prototype.Icon.Frame0());
}
PopulateDisabled();
}
/// <summary>
/// Populates the list of recipes that will actually be shown, using the current filters.
/// </summary>
public void Populate()
{
_shownRecipes.Clear();
foreach (var prototype in Owner.Database)
{
if (SearchBar.Text.Trim().Length != 0)
{
if (prototype.Name.ToLowerInvariant().Contains(SearchBar.Text.Trim().ToLowerInvariant()))
_shownRecipes.Add(prototype);
continue;
}
_shownRecipes.Add(prototype);
}
PopulateList();
}
/// <inheritdoc cref="Populate"/>
public void Populate(LineEdit.LineEditEventArgs args)
{
Populate();
}
}
}

View File

@@ -0,0 +1,149 @@
using Content.Client.GameObjects.Components.Research;
using Content.Shared.Research;
using Robust.Client.Graphics;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.Utility;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;
namespace Content.Client.Research
{
public class LatheQueueMenu : SS14Window
{
protected override Vector2? CustomSize => (300, 450);
public LatheBoundUserInterface Owner { get; set; }
[ViewVariables]
private ItemList QueueList;
private Label Name;
private Label Description;
private TextureRect Icon;
public LatheQueueMenu(IDisplayManager displayManager) : base(displayManager)
{
}
protected override void Initialize()
{
base.Initialize();
HideOnClose = true;
Title = "Lathe Queue";
Visible = false;
var margin = new MarginContainer()
{
MarginTop = 5f,
MarginLeft = 5f,
MarginRight = -5f,
MarginBottom = -5f,
};
margin.SetAnchorAndMarginPreset(LayoutPreset.Wide);
var vbox = new VBoxContainer();
vbox.SetAnchorAndMarginPreset(LayoutPreset.Wide);
var descMargin = new MarginContainer()
{
MarginTop = 5f,
MarginLeft = 5f,
MarginRight = -5f,
MarginBottom = -5f,
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 2,
};
var hbox = new HBoxContainer()
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
};
Icon = new TextureRect()
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 2,
};
var vboxInfo = new VBoxContainer()
{
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 3,
};
Name = new Label()
{
RectClipContent = true,
SizeFlagsHorizontal = SizeFlags.Fill,
};
Description = new Label()
{
RectClipContent = true,
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsHorizontal = SizeFlags.Fill,
};
QueueList = new ItemList()
{
SizeFlagsHorizontal = SizeFlags.Fill,
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 3,
SelectMode = ItemList.ItemListSelectMode.None
};
vboxInfo.AddChild(Name);
vboxInfo.AddChild(Description);
hbox.AddChild(Icon);
hbox.AddChild(vboxInfo);
descMargin.AddChild(hbox);
vbox.AddChild(descMargin);
vbox.AddChild(QueueList);
margin.AddChild(vbox);
Contents.AddChild(margin);
ClearInfo();
}
public void SetInfo(LatheRecipePrototype recipe)
{
Icon.Texture = recipe.Icon.Frame0();
if (recipe.Name != null)
Name.Text = recipe.Name;
if (recipe.Description != null)
Description.Text = recipe.Description;
}
public void ClearInfo()
{
Icon.Texture = Texture.Transparent;
Name.Text = "-------";
Description.Text = "Not producing anything.";
}
public void PopulateList()
{
QueueList.Clear();
var idx = 1;
foreach (var recipe in Owner.QueuedRecipes)
{
QueueList.AddItem($"{idx}. {recipe.Name}", recipe.Icon.Frame0(), false);
idx++;
}
}
}
}

View File

@@ -108,6 +108,9 @@
<Compile Include="GameObjects\Components\Power\PowerTransferComponent.cs" />
<Compile Include="GameObjects\Components\Projectiles\ProjectileComponent.cs" />
<Compile Include="GameObjects\Components\Projectiles\ThrownItemComponent.cs" />
<Compile Include="GameObjects\Components\Research\LatheComponent.cs" />
<Compile Include="GameObjects\Components\Research\LatheDatabaseComponent.cs" />
<Compile Include="GameObjects\Components\Research\MaterialStorageComponent.cs" />
<Compile Include="GameObjects\Components\Sound\SoundComponent.cs" />
<Compile Include="GameObjects\Components\Weapon\Melee\MeleeWeaponComponent.cs" />
<Compile Include="GameObjects\Components\Weapon\Ranged\Hitscan\HitscanWeaponComponent.cs" />
@@ -125,6 +128,7 @@
<Compile Include="GameObjects\EntitySystems\DoorSystem.cs" />
<Compile Include="GameObjects\EntitySystems\HandHeldLightSystem.cs" />
<Compile Include="GameObjects\EntitySystems\HandsSystem.cs" />
<Compile Include="GameObjects\EntitySystems\LatheSystem.cs" />
<Compile Include="GameObjects\EntitySystems\MoverSystem.cs" />
<Compile Include="GameObjects\EntitySystems\PowerApcSystem.cs" />
<Compile Include="GameObjects\EntitySystems\PowerSmesSystem.cs" />
@@ -198,8 +202,6 @@
<None Include="app.config" />
<Compile Include="GameObjects\Components\Power\SmesComponent.cs" />
<Compile Include="GameObjects\Components\Power\ApcComponent.cs" />
<Compile Include="Materials\Material.cs" />
<Compile Include="GameObjects\Components\Materials\MaterialComponent.cs" />
<Compile Include="GameObjects\Components\Stack\StackComponent.cs" />
<Compile Include="GameObjects\Components\Construction\ConstructorComponent.cs" />
<Compile Include="GameObjects\Components\Construction\ConstructionComponent.cs" />

View File

@@ -26,7 +26,6 @@ using Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan;
using Content.Server.GameObjects.Components.Weapon.Ranged.Projectile;
using Content.Server.GameObjects.Components.Projectiles;
using Content.Server.GameObjects.Components.Weapon.Melee;
using Content.Server.GameObjects.Components.Materials;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.Components.Construction;
using Content.Server.GameObjects.Components.Mobs;
@@ -40,6 +39,7 @@ using Content.Server.GameObjects.Components.Weapon.Ranged;
using Content.Server.GameTicking;
using Content.Server.Interfaces;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.GameObjects.Components.Materials;
using Content.Shared.GameObjects.Components.Inventory;
using Content.Shared.GameObjects.Components.Markers;
using Content.Shared.GameObjects.Components.Mobs;
@@ -50,6 +50,8 @@ using Content.Server.GameObjects.Components.Destructible;
using Content.Server.GameObjects.Components.Movement;
using Content.Server.Interfaces.Chat;
using Content.Server.Interfaces.GameObjects.Components.Movement;
using Content.Server.GameObjects.Components.Research;
using Content.Shared.GameObjects.Components.Research;
namespace Content.Server
{
@@ -127,6 +129,8 @@ namespace Content.Server
factory.Register<ApcComponent>();
factory.Register<MaterialComponent>();
factory.Register<StackComponent>();
factory.Register<MaterialStorageComponent>();
factory.RegisterReference<MaterialStorageComponent, SharedMaterialStorageComponent>();
factory.Register<ConstructionComponent>();
factory.Register<ConstructorComponent>();
@@ -139,6 +143,11 @@ namespace Content.Server
factory.Register<SpawnPointComponent>();
factory.RegisterReference<SpawnPointComponent, SharedSpawnPointComponent>();
factory.Register<LatheComponent>();
factory.Register<LatheDatabaseComponent>();
factory.RegisterReference<LatheDatabaseComponent, SharedLatheDatabaseComponent>();
factory.Register<BallisticBulletComponent>();
factory.Register<BallisticMagazineComponent>();

View 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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View 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());
}
}
}
}
}

View File

@@ -74,9 +74,13 @@
<Compile Include="GameObjects\Components\Items\ClothingComponentState.cs" />
<Compile Include="GameObjects\Components\Items\ItemComponentState.cs" />
<Compile Include="GameObjects\Components\Markers\SharedSpawnPointComponent.cs" />
<Compile Include="GameObjects\Components\Materials\MaterialComponent.cs" />
<Compile Include="GameObjects\Components\Mobs\SharedCameraRecoilComponent.cs" />
<Compile Include="GameObjects\Components\Power\PowerShared.cs" />
<Compile Include="GameObjects\Components\Power\SharedPowerCellComponent.cs" />
<Compile Include="GameObjects\Components\Research\SharedLatheComponent.cs" />
<Compile Include="GameObjects\Components\Research\SharedLatheDatabaseComponent.cs" />
<Compile Include="GameObjects\Components\Research\SharedMaterialStorageComponent.cs" />
<Compile Include="GameObjects\Components\Sound\SharedSoundComponent.cs" />
<Compile Include="GameObjects\Components\Storage\SharedStorageComponent.cs" />
<Compile Include="GameObjects\Components\Weapons\Ranged\SharedBallisticMagazineComponent.cs" />
@@ -90,6 +94,7 @@
<Compile Include="Interfaces\ISharedNotifyManager.cs" />
<Compile Include="GameObjects\Verb.cs" />
<Compile Include="Maps\ContentTileDefinition.cs" />
<Compile Include="Materials\Material.cs" />
<Compile Include="Physics\CollisionGroup.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GameObjects\Components\Items\SharedHandsComponent.cs" />
@@ -100,6 +105,7 @@
<ItemGroup>
<None Include="app.config" />
<Compile Include="Input\ContentKeyFunctions.cs" />
<Compile Include="Research\LatheRecipePrototype.cs" />
<Compile Include="SharedGameTicker.cs" />
<Compile Include="SharedNotifyManager.cs" />
<Compile Include="Utility\ContentHelpers.cs" />

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic;
using Content.Server.Materials;
using Content.Shared.Materials;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.Interfaces.Serialization;
@@ -8,7 +8,7 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Server.GameObjects.Components.Materials
namespace Content.Shared.GameObjects.Components.Materials
{
/// <summary>
/// Component to store data such as "this object is made out of steel".
@@ -19,7 +19,8 @@ namespace Content.Server.GameObjects.Components.Materials
public const string SerializationCache = "mat";
public override string Name => "Material";
Dictionary<object, Material> MaterialTypes;
public Dictionary<object, Material> MaterialTypes => _materialTypes;
private Dictionary<object, Material> _materialTypes;
public override void ExposeData(ObjectSerializer serializer)
{
@@ -33,11 +34,11 @@ namespace Content.Server.GameObjects.Components.Materials
if (serializer.TryGetCacheData(SerializationCache, out Dictionary<object, Material> cached))
{
MaterialTypes = cached.ShallowClone();
_materialTypes = cached.ShallowClone();
return;
}
MaterialTypes = new Dictionary<object, Material>();
_materialTypes = new Dictionary<object, Material>();
if (serializer.TryReadDataField("materials", out List<MaterialDataEntry> list))
{
@@ -46,12 +47,12 @@ namespace Content.Server.GameObjects.Components.Materials
foreach (var entry in list)
{
var proto = protoMan.Index<MaterialPrototype>(entry.Value);
MaterialTypes[entry.Key] = proto.Material;
_materialTypes[entry.Key] = proto.Material;
index++;
}
}
serializer.SetCacheData(SerializationCache, MaterialTypes.ShallowClone());
serializer.SetCacheData(SerializationCache, _materialTypes.ShallowClone());
}
class MaterialDataEntry : IExposeData

View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using Content.Shared.Materials;
using Content.Shared.Research;
using Mono.Cecil;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Content.Shared.GameObjects.Components.Research
{
public class SharedLatheComponent : Component
{
public override string Name => "Lathe";
public override uint? NetID => ContentNetIDs.LATHE;
#pragma warning disable CS0649
[Dependency]
protected IPrototypeManager _prototypeManager;
#pragma warning restore
public bool CanProduce(LatheRecipePrototype recipe, int quantity = 1)
{
if (!Owner.TryGetComponent(out SharedMaterialStorageComponent storage)
|| !Owner.TryGetComponent(out SharedLatheDatabaseComponent database)) return false;
if (!database.Contains(recipe)) return false;
foreach (var (material, amount) in recipe.RequiredMaterials)
{
if (storage[material] <= (amount * quantity)) return false;
}
return true;
}
public bool CanProduce(string ID, int quantity = 1)
{
return _prototypeManager.TryIndex(ID, out LatheRecipePrototype recipe) && CanProduce(recipe, quantity);
}
/// <summary>
/// Sent to the server to sync material storage and the recipe queue.
/// </summary>
[Serializable, NetSerializable]
public class LatheSyncRequestMessage : BoundUserInterfaceMessage
{
public LatheSyncRequestMessage()
{
}
}
/// <summary>
/// Sent to the client when the lathe is producing a recipe.
/// </summary>
[Serializable, NetSerializable]
public class LatheProducingRecipeMessage : BoundUserInterfaceMessage
{
public readonly string ID;
public LatheProducingRecipeMessage(string id)
{
ID = id;
}
}
/// <summary>
/// Sent to the client when the lathe stopped/finished producing a recipe.
/// </summary>
[Serializable, NetSerializable]
public class LatheStoppedProducingRecipeMessage : BoundUserInterfaceMessage
{
public LatheStoppedProducingRecipeMessage()
{
}
}
/// <summary>
/// Sent to the client to let it know about the recipe queue.
/// </summary>
[Serializable, NetSerializable]
public class LatheFullQueueMessage : BoundUserInterfaceMessage
{
public readonly Queue<string> Recipes;
public LatheFullQueueMessage(Queue<string> recipes)
{
Recipes = recipes;
}
}
/// <summary>
/// Sent to the server when a client queues a new recipe.
/// </summary>
[Serializable, NetSerializable]
public class LatheQueueRecipeMessage : BoundUserInterfaceMessage
{
public readonly string ID;
public readonly int Quantity;
public LatheQueueRecipeMessage(string id, int quantity)
{
ID = id;
Quantity = quantity;
}
}
[NetSerializable, Serializable]
public enum LatheUiKey
{
Key,
}
}
}

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Content.Shared.Research;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.GameObjects.Components.Research
{
public class SharedLatheDatabaseComponent : Component, IEnumerable<LatheRecipePrototype>
{
public override string Name => "LatheDatabase";
public sealed override uint? NetID => ContentNetIDs.LATHE_DATABASE;
public sealed override Type StateType => typeof(LatheDatabaseState);
private List<LatheRecipePrototype> _recipes = new List<LatheRecipePrototype>();
/// <summary>
/// Removes all recipes from the database if it's not static.
/// </summary>
/// <returns>Whether it could clear the database or not.</returns>
public virtual void Clear()
{
_recipes.Clear();
}
/// <summary>
/// Adds a recipe to the database if it's not static.
/// </summary>
/// <param name="recipe">The recipe to be added.</param>
/// <returns>Whether it could be added or not</returns>
public virtual void AddRecipe(LatheRecipePrototype recipe)
{
_recipes.Add(recipe);
}
/// <summary>
/// Removes a recipe from the database if it's not static.
/// </summary>
/// <param name="recipe">The recipe to be removed.</param>
/// <returns>Whether it could be removed or not</returns>
public virtual bool RemoveRecipe(LatheRecipePrototype recipe)
{
return _recipes.Remove(recipe);
}
/// <summary>
/// Returns whether the database contains the recipe or not.
/// </summary>
/// <param name="recipe">The recipe to check</param>
/// <returns>Whether the database contained the recipe or not.</returns>
public virtual bool Contains(LatheRecipePrototype recipe)
{
return _recipes.Contains(recipe);
}
/// <summary>
/// Returns whether the database contains the recipe or not.
/// </summary>
/// <param name="id">The recipe id to check</param>
/// <returns>Whether the database contained the recipe or not.</returns>
public virtual bool Contains(string id)
{
foreach (var recipe in _recipes)
{
if (recipe.ID == id) return true;
}
return false;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
var recipes = serializer.ReadDataField("recipes", new List<string>());
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
foreach (var id in recipes)
{
if (!prototypeManager.TryIndex(id, out LatheRecipePrototype recipe)) continue;
_recipes.Add(recipe);
}
}
public IEnumerator<LatheRecipePrototype> GetEnumerator()
{
return _recipes.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
[NetSerializable, Serializable]
public class LatheDatabaseState : ComponentState
{
public readonly List<string> Recipes;
public LatheDatabaseState(List<string> recipes) : base(ContentNetIDs.LATHE_DATABASE)
{
Recipes = recipes;
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Content.Shared.Materials;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Shared.GameObjects.Components.Research
{
public class SharedMaterialStorageComponent : Component, IEnumerable<KeyValuePair<string, int>>
{
[ViewVariables]
protected virtual Dictionary<string, int> Storage { get; set; }
public override string Name => "MaterialStorage";
public sealed override uint? NetID => ContentNetIDs.MATERIAL_STORAGE;
public sealed override Type StateType => typeof(MaterialStorageState);
public int this[string ID]
{
get
{
if (!Storage.ContainsKey(ID))
return 0;
return Storage[ID];
}
}
public int this[Material material]
{
get
{
var ID = material.ID;
if (!Storage.ContainsKey(ID))
return 0;
return Storage[ID];
}
}
/// <summary>
/// The total volume of material stored currently.
/// </summary>
[ViewVariables] public int CurrentAmount
{
get
{
var value = 0;
foreach (var amount in Storage.Values)
{
value += amount;
}
return value;
}
}
public IEnumerator<KeyValuePair<string, int>> GetEnumerator()
{
return Storage.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
[NetSerializable, Serializable]
public class MaterialStorageState : ComponentState
{
public readonly Dictionary<string, int> Storage;
public MaterialStorageState(Dictionary<string, int> storage) : base(ContentNetIDs.MATERIAL_STORAGE)
{
Storage = storage;
}
}
}

View File

@@ -18,5 +18,8 @@
public const uint ITEM = 1013;
public const uint CLOTHING = 1014;
public const uint ENTITYSTORAGE = 1015;
public const uint LATHE = 1016;
public const uint LATHE_DATABASE = 1017;
public const uint MATERIAL_STORAGE = 1018;
}
}

View File

@@ -1,17 +1,18 @@
using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
namespace Content.Server.Materials
namespace Content.Shared.Materials
{
/// <summary>
/// Materials are read-only storage for the properties of specific materials.
/// Properties should be intrinsic (or at least as much is necessary for game purposes).
/// </summary>
public class Material : IExposeData
public class Material : IExposeData
{
public string Name => _name;
private string _name = "unobtanium";
@@ -72,6 +73,26 @@ namespace Content.Server.Materials
public double BluntDamage => _bluntDamage;
private double _bluntDamage = 1;
/// <summary>
/// An icon used to represent the material in graphic interfaces.
/// </summary>
public SpriteSpecifier Icon => _icon;
private SpriteSpecifier _icon = SpriteSpecifier.Invalid;
public string ID
{
get
{
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
foreach (var prototype in prototypeManager.EnumeratePrototypes<MaterialPrototype>())
{
if (prototype.Material == this) return prototype.ID;
}
return null;
}
}
public void ExposeData(ObjectSerializer serializer)
{
serializer.DataField(ref _name, "name", "unobtanium", alwaysWrite: true);
@@ -87,6 +108,7 @@ namespace Content.Server.Materials
serializer.DataField(ref _hardness, "hardness", 1, alwaysWrite: true);
serializer.DataField(ref _sharpDamage, "sharpdamage", 1, alwaysWrite: true);
serializer.DataField(ref _bluntDamage, "bluntdamage", 1, alwaysWrite: true);
serializer.DataField(ref _icon, "icon", SpriteSpecifier.Invalid, alwaysWrite: true);
}
}

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using Content.Shared.GameObjects.Components.Research;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
namespace Content.Shared.Research
{
[NetSerializable, Serializable, Prototype("latheRecipe")]
public class LatheRecipePrototype : IPrototype, IIndexedPrototype
{
private string _name;
private string _id;
private SpriteSpecifier _icon;
private string _description;
private string _result;
private int _completeTime;
private Dictionary<string, int> _requiredMaterials;
public string ID => _id;
/// <summary>
/// Name displayed in the lathe GUI.
/// </summary>
public string Name
{
get
{
if (_name.Trim().Length != 0) return _name;
var protoMan = IoCManager.Resolve<IPrototypeManager>();
if (protoMan == null) return _description;
protoMan.TryIndex(_result, out EntityPrototype prototype);
if (prototype?.Name != null)
_name = prototype.Name;
return _name;
}
}
/// <summary>
/// Short description displayed in the lathe GUI.
/// </summary>
public string Description
{
get
{
if (_description.Trim().Length != 0) return _description;
var protoMan = IoCManager.Resolve<IPrototypeManager>();
if (protoMan == null) return _description;
protoMan.TryIndex(_result, out EntityPrototype prototype);
if (prototype?.Description != null)
_description = prototype.Description;
return _description;
}
}
/// <summary>
/// Texture path used in the lathe GUI.
/// </summary>
public SpriteSpecifier Icon => _icon;
/// <summary>
/// The prototype name of the resulting entity when the recipe is printed.
/// </summary>
public string Result => _result;
/// <summary>
/// The materials required to produce this recipe.
/// Takes a material ID as string.
/// </summary>
public Dictionary<string, int> RequiredMaterials
{
get => _requiredMaterials;
private set => _requiredMaterials = value;
}
/// <summary>
/// How many milliseconds it'll take for the lathe to finish this recipe.
/// Might lower depending on the lathe's upgrade level.
/// </summary>
public int CompleteTime => _completeTime;
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataField(ref _name, "name", string.Empty);
serializer.DataField(ref _id, "id", string.Empty);
serializer.DataField(ref _description, "description", string.Empty);
serializer.DataField(ref _icon, "icon", SpriteSpecifier.Invalid);
serializer.DataField(ref _result, "result", null);
serializer.DataField(ref _completeTime, "completetime", 2500);
serializer.DataField(ref _requiredMaterials, "materials", new Dictionary<string, int>());
}
}
}

View File

@@ -0,0 +1,65 @@
using SS14.Shared.Prototypes;
using SS14.Shared.Serialization;
using SS14.Shared.Utility;
using YamlDotNet.RepresentationModel;
namespace Content.Shared.Research
{
[Prototype("latheRecipe")]
public class LatheRecipePrototype : IPrototype, IIndexedPrototype
{
private string _name;
private string _id;
private SpriteSpecifier _icon;
private string _description;
private string _result;
private bool _hacked;
private string _latheType;
public string ID => _id;
/// <summary>
/// Name displayed in the lathe GUI.
/// </summary>
public string Name => _name;
/// <summary>
/// Short description displayed in the lathe GUI.
/// </summary>
public string Description => _description;
/// <summary>
/// Texture path used in the lathe GUI.
/// </summary>
public SpriteSpecifier Icon => _icon;
/// <summary>
/// The prototype name of the resulting entity when the recipe is printed.
/// </summary>
public string Result => _result;
/// <summary>
/// Whether the lathe should be hacked to unlock this recipe.
/// </summary>
public bool Hacked => _hacked;
/// <summary>
/// The type of lathe that'll print this recipe.
/// TODO: Replace with an enum before merging, henk!
/// </summary>
public string LatheType => _latheType;
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
_name = serializer.ReadDataField<string>("name");
serializer.DataField(ref _id, "id", string.Empty);
serializer.DataField(ref _description, "description", string.Empty);
serializer.DataField(ref _icon, "icon", SpriteSpecifier.Invalid);
serializer.DataField(ref _result, "result", null);
serializer.DataField(ref _hacked, "hacked", false);
serializer.DataField(ref _latheType, "lathetype", "default");
}
}
}

View File

@@ -0,0 +1,37 @@
- type: entity
id: autolathe
name: "Autolathe"
components:
- type: Clickable
- type: Sprite
sprite: Buildings/autolathe.rsi
state: idle
- type: Icon
sprite: Buildings/autolathe.rsi
state: idle
- type: BoundingBox
- type: Collidable
- type: SnapGrid
offset: Center
- type: Lathe
- type: LatheDatabase
static: true
recipes:
- Brutepack
- Ointment
- LightTube
- LightBulb
- MetalStack
- GlassStack
- Wirecutter
- Screwdriver
- Welder
- Wrench
- CableStack
- Crowbar
- Multitool
- type: MaterialStorage
- type: UserInterface
interfaces:
- key: enum.LatheUiKey.Key
type: LatheBoundUserInterface

View File

@@ -46,6 +46,14 @@
- type: Icon
texture: Objects/sheet_glass.png
- type: entity
id: GlassSheet1
name: Glass Sheet 1
parent: GlassStack
components:
- type: Stack
count: 1
- type: entity
name: Cable Coil
id: CableStack

View File

@@ -0,0 +1,17 @@
- type: latheRecipe
id: Brutepack
icon: Objects/brutepack.png
result: Brutepack
completetime: 500
materials:
steel: 400
glass: 125
- type: latheRecipe
id: Ointment
icon: Objects/ointment.png
result: Ointment
completetime: 500
materials:
steel: 400
glass: 125

View File

@@ -0,0 +1,17 @@
- type: latheRecipe
id: LightTube
icon: Objects/light_tube.rsi/normal.png
result: LightTube
completetime: 500
materials:
steel: 60
glass: 100
- type: latheRecipe
id: LightBulb
icon: Objects/light_bulb.rsi/normal.png
result: LightBulb
completetime: 500
materials:
steel: 30
glass: 50

View File

@@ -0,0 +1,15 @@
- type: latheRecipe
id: MetalStack
icon: Objects/sheet_metal.png
result: SteelSheet1
completetime: 500
materials:
steel: 3750
- type: latheRecipe
id: GlassStack
icon: Objects/sheet_glass.png
result: GlassSheet1
completetime: 500
materials:
glass: 3750

View File

@@ -0,0 +1,59 @@
- type: latheRecipe
id: Wirecutter
icon: Objects/wirecutter.png
result: Wirecutter
completetime: 500
materials:
steel: 80
- type: latheRecipe
id: Screwdriver
icon: Objects/screwdriver.png
result: Screwdriver
completetime: 500
materials:
steel: 75
- type: latheRecipe
id: Welder
icon: Objects/welder.png
result: Welder
completetime: 500
materials:
steel: 70
glass: 30
- type: latheRecipe
id: Wrench
icon: Objects/wrench.png
result: Wrench
completetime: 500
materials:
steel: 70
glass: 30
- type: latheRecipe
id: CableStack
icon: Objects/cable_coil.png
result: CableStack
completetime: 500
materials:
steel: 50
glass: 50
- type: latheRecipe
id: Crowbar
icon: Objects/crowbar.png
result: Crowbar
completetime: 500
materials:
steel: 50
- type: latheRecipe
id: Multitool
icon: Objects/multitool.png
result: Multitool
completetime: 500
materials:
steel: 50
glass: 20

View File

@@ -2,6 +2,7 @@
id: steel
name: Steel
color: gray
icon: Objects/sheet_metal.png
density: 7700
electricresistivity: 6.9e-7
thermalconductivity: 18
@@ -11,6 +12,7 @@
id: glass
name: Glass
color: '#e8f0ff33'
icon: Objects/sheet_glass.png
density: 2500
electricresistivity: 1.0e+13
thermalconductivity: 0.9

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/blob/master/icons/obj/machines/excelsior/autolathe.dmi", "states": [{"name": "closing", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "idle", "directions": 1, "delays": [[1.0]]}, {"name": "opening", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "panel", "directions": 1, "delays": [[1.0]]}, {"name": "stanok", "directions": 1, "delays": [[1.0]]}, {"name": "workdone", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.5, 0.1, 0.1, 0.5]]}, {"name": "working", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 B