The Grovelling-to-the-Chef Games (monkey cubes and meat spikes) (#2117)
* Rehydratable component -> monkey cubes now have some of their behaviour * Placeholder kitchen spike entity * KitchenSpike component: the kitchen spike now has basic functionality still placeholder sprite though * Kitchen Spike: Import meatspike assets from CEV-Eris * Kitchen Spike: Actually use sprites somewhat * Kitchen Spike: Forgot I removed the MeatParts property from Butcherable * Monkey cubes: Use IReagentReaction even though it doesn't quite work yet. Butcherable: remove imports * Monkey cubes/Rehydratable: Re-add ISolutionChange * Update Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,92 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.Body.Digestive;
|
||||||
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
|
using Content.Shared.Chemistry;
|
||||||
|
using Content.Shared.Interfaces;
|
||||||
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Content.Shared.Utility;
|
||||||
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Chemistry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Basically, monkey cubes.
|
||||||
|
/// But specifically, this component deletes the entity and spawns in a new entity when the entity is exposed to a given reagent.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
[ComponentReference(typeof(IReagentReaction))]
|
||||||
|
[ComponentReference(typeof(ISolutionChange))]
|
||||||
|
public class RehydratableComponent : Component, IReagentReaction, ISolutionChange
|
||||||
|
{
|
||||||
|
public override string Name => "Rehydratable";
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private string _catalystPrototype = "";
|
||||||
|
[ViewVariables]
|
||||||
|
private string? _targetPrototype;
|
||||||
|
|
||||||
|
private bool _expanding;
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
serializer.DataField(ref _catalystPrototype, "catalyst", "chem.H2O");
|
||||||
|
serializer.DataField(ref _targetPrototype, "target", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReagentUnit IReagentReaction.ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume) => Reaction(reagent, volume);
|
||||||
|
ReagentUnit IReagentReaction.ReagentReactInjection(ReagentPrototype reagent, ReagentUnit volume) => Reaction(reagent, volume);
|
||||||
|
|
||||||
|
private ReagentUnit Reaction(ReagentPrototype reagent, ReagentUnit volume)
|
||||||
|
{
|
||||||
|
if ((volume > ReagentUnit.Zero) && (reagent.ID == _catalystPrototype))
|
||||||
|
{
|
||||||
|
Expand();
|
||||||
|
}
|
||||||
|
return ReagentUnit.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISolutionChange.SolutionChanged(SolutionChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
var solution = eventArgs.Owner.GetComponent<SolutionContainerComponent>();
|
||||||
|
if (solution.Solution.GetReagentQuantity(_catalystPrototype) > ReagentUnit.Zero)
|
||||||
|
{
|
||||||
|
Expand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try not to make this public if you can help it.
|
||||||
|
private void Expand()
|
||||||
|
{
|
||||||
|
if (_expanding)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_expanding = true;
|
||||||
|
Owner.PopupMessageEveryone(Loc.GetString("{0:TheName} expands!", Owner));
|
||||||
|
if (!string.IsNullOrEmpty(_targetPrototype))
|
||||||
|
{
|
||||||
|
Owner.EntityManager.SpawnEntity(_targetPrototype, Owner.Transform.Coordinates);
|
||||||
|
}
|
||||||
|
Owner.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Kitchen
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the entity can be thrown on a kitchen spike for butchering.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public class ButcherableComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "Butcherable";
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public string? MeatPrototype => _meatPrototype;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private string? _meatPrototype;
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
serializer.DataField(ref _meatPrototype, "meat", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Content.Server.GameObjects.Components.Body;
|
||||||
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Interfaces.Chat;
|
||||||
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Utility;
|
||||||
|
using Content.Shared.Chemistry;
|
||||||
|
using Content.Shared.GameObjects.Components.Body;
|
||||||
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
|
using Content.Shared.Interfaces;
|
||||||
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Content.Shared.Kitchen;
|
||||||
|
using Content.Shared.Prototypes.Kitchen;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Server.GameObjects.Components.Container;
|
||||||
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Timers;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Kitchen
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
[ComponentReference(typeof(IActivate))]
|
||||||
|
public class KitchenSpikeComponent : Component, IActivate, ISuicideAct
|
||||||
|
{
|
||||||
|
public override string Name => "KitchenSpike";
|
||||||
|
|
||||||
|
private int _meatParts;
|
||||||
|
private string? _meatPrototype;
|
||||||
|
private string _meatSource1p = "?";
|
||||||
|
private string _meatSource0 = "?";
|
||||||
|
|
||||||
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
var victim = eventArgs.User.GetComponent<HandsComponent>().PulledObject?.Owner;
|
||||||
|
|
||||||
|
var sprite = Owner.GetComponent<SpriteComponent>();
|
||||||
|
|
||||||
|
if (victim == null)
|
||||||
|
{
|
||||||
|
if (_meatParts == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_meatParts--;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_meatPrototype))
|
||||||
|
{
|
||||||
|
Owner.EntityManager.SpawnEntity(_meatPrototype, Owner.Transform.Coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_meatParts != 0)
|
||||||
|
{
|
||||||
|
eventArgs.User.PopupMessage(_meatSource1p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprite.LayerSetState(0, "spike");
|
||||||
|
eventArgs.User.PopupMessage(_meatSource0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (_meatParts > 0)
|
||||||
|
{
|
||||||
|
Owner.PopupMessage(eventArgs.User, Loc.GetString("The spike already has something on it, finish collecting its meat first!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!victim.TryGetComponent<ButcherableComponent>(out var food))
|
||||||
|
{
|
||||||
|
Owner.PopupMessage(eventArgs.User, Loc.GetString("{0:theName} can't be butchered on the spike.", victim));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_meatPrototype = food.MeatPrototype;
|
||||||
|
_meatParts = 5;
|
||||||
|
_meatSource1p = Loc.GetString("You remove some meat from {0:theName}.", victim);
|
||||||
|
_meatSource0 = Loc.GetString("You remove the last piece of meat from {0:theName}!", victim);
|
||||||
|
|
||||||
|
sprite.LayerSetState(0, "spikebloody");
|
||||||
|
|
||||||
|
Owner.PopupMessageEveryone(Loc.GetString("{0:theName} has forced {1:theName} onto the spike, killing them instantly!", eventArgs.User, victim));
|
||||||
|
victim.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SuicideKind Suicide(IEntity victim, IChatManager chat)
|
||||||
|
{
|
||||||
|
var othersMessage = Loc.GetString("{0:theName} has thrown themselves on a meat spike!", victim);
|
||||||
|
victim.PopupMessageOtherClients(othersMessage);
|
||||||
|
|
||||||
|
var selfMessage = Loc.GetString("You throw yourself on a meat spike!");
|
||||||
|
victim.PopupMessage(selfMessage);
|
||||||
|
|
||||||
|
return SuicideKind.Piercing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ namespace Content.Shared.GameObjects.Components.Items
|
|||||||
public sealed override uint? NetID => ContentNetIDs.HANDS;
|
public sealed override uint? NetID => ContentNetIDs.HANDS;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
protected ICollidableComponent? PulledObject;
|
public ICollidableComponent? PulledObject { get; protected set; }
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
protected bool IsPulling => PulledObject != null;
|
protected bool IsPulling => PulledObject != null;
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
- type: entity
|
||||||
|
id: KitchenSpike
|
||||||
|
name: meat spike
|
||||||
|
description: A spike for collecting meat from animals.
|
||||||
|
components:
|
||||||
|
- type: Clickable
|
||||||
|
- type: InteractionOutline
|
||||||
|
- type: Collidable
|
||||||
|
shapes:
|
||||||
|
- !type:PhysShapeAabb
|
||||||
|
mask:
|
||||||
|
- Impassable
|
||||||
|
layer:
|
||||||
|
- Impassable
|
||||||
|
- type: Sprite
|
||||||
|
# temp to make clickmask work
|
||||||
|
sprite: Constructible/Misc/kitchen.rsi
|
||||||
|
state: spike
|
||||||
|
- type: Anchorable
|
||||||
|
- type: Pullable
|
||||||
|
- type: Destructible
|
||||||
|
deadThreshold: 50
|
||||||
|
- type: KitchenSpike
|
||||||
@@ -60,6 +60,8 @@
|
|||||||
normal: monkey
|
normal: monkey
|
||||||
dead: dead
|
dead: dead
|
||||||
- type: Pullable
|
- type: Pullable
|
||||||
|
- type: Butcherable
|
||||||
|
meat: FoodMeat
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
save: false
|
save: false
|
||||||
|
|||||||
@@ -1705,9 +1705,12 @@
|
|||||||
reagents:
|
reagents:
|
||||||
- ReagentId: chem.Nutriment
|
- ReagentId: chem.Nutriment
|
||||||
Quantity: 10
|
Quantity: 10
|
||||||
|
maxVol: 11 # needs room for water
|
||||||
|
caps: AddTo, RemoveFrom, FitsInDispenser
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Consumable/Food/monkeycube.rsi
|
sprite: Objects/Consumable/Food/monkeycube.rsi
|
||||||
|
- type: Rehydratable
|
||||||
|
target: MonkeyMob_Content
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: FoodBase
|
parent: FoodBase
|
||||||
|
|||||||
18
Resources/Prototypes/Recipes/Construction/kitchen.yml
Normal file
18
Resources/Prototypes/Recipes/Construction/kitchen.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
- type: construction
|
||||||
|
name: meat spike
|
||||||
|
id: KitchenSpike
|
||||||
|
category: Items/Kitchen
|
||||||
|
keywords: [kitchen]
|
||||||
|
description:
|
||||||
|
icon: Constructible/Misc/kitchen.rsi/spike.png
|
||||||
|
result: KitchenSpike
|
||||||
|
objectType: Structure
|
||||||
|
steps:
|
||||||
|
# Replace with Metal Rods whenever
|
||||||
|
# also this should be done with a Welding tool if that is specifiable
|
||||||
|
- material: Metal
|
||||||
|
amount: 3
|
||||||
|
reverse:
|
||||||
|
# logic here: BOLT_TURNING -> Wrench -> Anchoring
|
||||||
|
tool: Anchoring
|
||||||
|
|
||||||
12
Resources/Textures/Constructible/Misc/kitchen.rsi/meta.json
Normal file
12
Resources/Textures/Constructible/Misc/kitchen.rsi/meta.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version":1,
|
||||||
|
"size":{"x":32,"y":32},
|
||||||
|
"license":"CC-BY-SA-3.0",
|
||||||
|
"copyright":"Taken from https://github.com/discordia-space/CEV-Eris/blob/2b969adc2dfd3e9621bf3597c5cbffeb3ac8c9f0/icons/obj/kitchen.dmi",
|
||||||
|
"states":[
|
||||||
|
{"name":"spike","directions":1,"delays":[[1.0]]},
|
||||||
|
{"name":"spikebloody","directions":1,"delays":[[1.0]]},
|
||||||
|
{"name":"spikebloodygreen","directions":1,"delays":[[1.0]]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
BIN
Resources/Textures/Constructible/Misc/kitchen.rsi/spike.png
Normal file
BIN
Resources/Textures/Constructible/Misc/kitchen.rsi/spike.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 344 B |
Binary file not shown.
|
After Width: | Height: | Size: 956 B |
Binary file not shown.
|
After Width: | Height: | Size: 1007 B |
Reference in New Issue
Block a user