diff --git a/Content.Server/GameObjects/Components/Recycling/RecyclableComponent.cs b/Content.Server/GameObjects/Components/Recycling/RecyclableComponent.cs
new file mode 100644
index 0000000000..2a8617573f
--- /dev/null
+++ b/Content.Server/GameObjects/Components/Recycling/RecyclableComponent.cs
@@ -0,0 +1,51 @@
+using System;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Serialization;
+
+namespace Content.Server.GameObjects.Components.Recycling
+{
+ [RegisterComponent]
+ public class RecyclableComponent : Component
+ {
+ ///
+ /// The prototype that will be spawned on recycle.
+ ///
+ private string _prototype;
+
+ ///
+ /// The amount of things that will be spawned on recycle.
+ ///
+ private int _amount;
+
+ ///
+ /// Whether this is "safe" to recycle or not.
+ /// If this is false, the recycler's safety must be disabled to recycle it.
+ ///
+ private bool _safe;
+ public override string Name => "Recyclable";
+
+ public bool Safe => _safe;
+
+ public override void ExposeData(ObjectSerializer serializer)
+ {
+ base.ExposeData(serializer);
+ serializer.DataField(ref _prototype, "prototype", string.Empty);
+ serializer.DataField(ref _safe, "safe", true);
+ serializer.DataField(ref _amount, "amount", 1);
+ }
+
+ public void Recycle(float efficiency = 1f)
+ {
+ if(!string.IsNullOrEmpty(_prototype))
+ {
+ for (var i = 0; i < Math.Max(_amount * efficiency, 1); i++)
+ {
+ Owner.EntityManager.SpawnEntity(_prototype, Owner.Transform.Coordinates);
+ }
+
+ }
+
+ Owner.Delete();
+ }
+ }
+}
diff --git a/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs b/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs
index 64485491b5..e5f6943739 100644
--- a/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs
+++ b/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs
@@ -1,10 +1,8 @@
#nullable enable
using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
using Content.Server.GameObjects.Components.Conveyor;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
-using Content.Shared.Construction;
using Content.Shared.GameObjects.Components.Body;
using Content.Shared.GameObjects.Components.Recycling;
using Content.Shared.Physics;
@@ -31,14 +29,14 @@ namespace Content.Server.GameObjects.Components.Recycling
///
/// Whether or not sentient beings will be recycled
///
- [ViewVariables]
+ [ViewVariables(VVAccess.ReadWrite)]
private bool _safe;
///
/// The percentage of material that will be recovered
///
- [ViewVariables]
- private int _efficiency; // TODO
+ [ViewVariables(VVAccess.ReadWrite)]
+ private float _efficiency;
private bool Powered =>
!Owner.TryGetComponent(out PowerReceiverComponent? receiver) ||
@@ -62,18 +60,10 @@ namespace Content.Server.GameObjects.Components.Recycling
private bool CanGib(IEntity entity)
{
+ // We suppose this entity has a Recyclable component.
return entity.HasComponent() && !_safe && Powered;
}
- private bool CanRecycle(IEntity entity, [NotNullWhen(true)] out ConstructionPrototype? prototype)
- {
- prototype = null;
-
- // TODO CONSTRUCTION fix this
-
- return Powered;
- }
-
private void Recycle(IEntity entity)
{
if (!_intersecting.Contains(entity))
@@ -82,6 +72,11 @@ namespace Content.Server.GameObjects.Components.Recycling
}
// TODO: Prevent collision with recycled items
+
+ // Can only recycle things that are recyclable... And also check the safety of the thing to recycle.
+ if (!entity.TryGetComponent(out RecyclableComponent? recyclable) || !recyclable.Safe && _safe) return;
+
+ // Mobs are a special case!
if (CanGib(entity))
{
entity.Delete(); // TODO: Gib
@@ -89,14 +84,7 @@ namespace Content.Server.GameObjects.Components.Recycling
return;
}
- if (!CanRecycle(entity, out var prototype))
- {
- return;
- }
-
- // TODO CONSTRUCTION fix this
-
- entity.Delete();
+ recyclable.Recycle(_efficiency);
}
private bool CanRun()
@@ -179,7 +167,7 @@ namespace Content.Server.GameObjects.Components.Recycling
base.ExposeData(serializer);
serializer.DataField(ref _safe, "safe", true);
- serializer.DataField(ref _efficiency, "efficiency", 25);
+ serializer.DataField(ref _efficiency, "efficiency", 0.25f);
}
void ICollideBehavior.CollideWith(IEntity collidedWith)
diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml
index e7920cd0a1..eea4b34452 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/human.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml
@@ -200,6 +200,8 @@
- type: Puller
- type: Butcherable
meat: FoodMeat
+ - type: Recyclable
+ safe: false
- type: entity
save: false