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;
|
||||
|
||||
[ViewVariables]
|
||||
protected ICollidableComponent? PulledObject;
|
||||
public ICollidableComponent? PulledObject { get; protected set; }
|
||||
|
||||
[ViewVariables]
|
||||
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
|
||||
dead: dead
|
||||
- type: Pullable
|
||||
- type: Butcherable
|
||||
meat: FoodMeat
|
||||
|
||||
- type: entity
|
||||
save: false
|
||||
|
||||
@@ -1705,9 +1705,12 @@
|
||||
reagents:
|
||||
- ReagentId: chem.Nutriment
|
||||
Quantity: 10
|
||||
maxVol: 11 # needs room for water
|
||||
caps: AddTo, RemoveFrom, FitsInDispenser
|
||||
- type: Sprite
|
||||
sprite: Objects/Consumable/Food/monkeycube.rsi
|
||||
|
||||
- type: Rehydratable
|
||||
target: MonkeyMob_Content
|
||||
|
||||
- type: entity
|
||||
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