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:
20kdc
2020-09-26 14:28:55 +01:00
committed by GitHub
parent 84ce845ea3
commit 4b9d488c1e
12 changed files with 296 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

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

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