Adds eating with utensils (#1136)
* Add Utensil component For eating. With utensils. Added to fork, plastic fork, spoon, plastic spoon and plastic knife. Ignored component on the client. * Add break chance to utensils Set to 20% for plastic ones * Add break sound to utensils * Add utensil kinds None, fork, spoon and knife. For sporks, forknifes and sporknifes, of course. * Add restricting foods by utensils needed * Fix utensils breaking when food isn't eaten * Moved getting held utensils to FoodComponent * Add breaking a clicking utensil even if its not necessary to eat the food * Move use utensil code to a separate method * Add telling a handless entity when they need an utensil to eat The immersion is off the charts * Change food trash to only be held when the food was also being held * Fix Wi-Fi utensils * Remove unnecessary utensil ItemGroup * Made TryUseFood public, removed redundant trash position update * Renamed UtensilKind to UtensilType * Remove eating food when clicking with it on nothing * Disable eating food when clicked directly if it requires an untensil to eat
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Nutrition;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.Utensil;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Utensil
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class UtensilComponent : SharedUtensilComponent, IAfterInteract
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystem;
|
||||
[Dependency] private readonly IRobustRandom _random;
|
||||
#pragma warning restore 649
|
||||
|
||||
protected UtensilType _types = UtensilType.None;
|
||||
|
||||
[ViewVariables]
|
||||
public override UtensilType Types
|
||||
{
|
||||
get => _types;
|
||||
set
|
||||
{
|
||||
_types = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The chance that the utensil has to break with each use.
|
||||
/// A value of 0 means that it is unbreakable.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private float _breakChance;
|
||||
|
||||
/// <summary>
|
||||
/// The sound to be played if the utensil breaks.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private string _breakSound;
|
||||
|
||||
public void AddType(UtensilType type)
|
||||
{
|
||||
Types |= type;
|
||||
}
|
||||
|
||||
public bool HasAnyType(UtensilType type)
|
||||
{
|
||||
return (_types & type) != UtensilType.None;
|
||||
}
|
||||
|
||||
public bool HasType(UtensilType type)
|
||||
{
|
||||
return _types.HasFlag(type);
|
||||
}
|
||||
|
||||
public void RemoveType(UtensilType type)
|
||||
{
|
||||
Types &= ~type;
|
||||
}
|
||||
|
||||
internal void TryBreak(IEntity user)
|
||||
{
|
||||
if (_random.Prob(_breakChance))
|
||||
{
|
||||
_entitySystem.GetEntitySystem<AudioSystem>()
|
||||
.PlayFromEntity(_breakSound, user, AudioParams.Default.WithVolume(-2f));
|
||||
Owner.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
if (serializer.Reading)
|
||||
{
|
||||
var types = serializer.ReadDataField("types", new List<UtensilType>());
|
||||
foreach (var type in types)
|
||||
{
|
||||
AddType(type);
|
||||
}
|
||||
}
|
||||
|
||||
serializer.DataField(ref _breakChance, "breakChance", 0);
|
||||
serializer.DataField(ref _breakSound, "breakSound", "/Audio/items/snap.ogg");
|
||||
}
|
||||
|
||||
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
||||
{
|
||||
TryUseUtensil(eventArgs.User, eventArgs.Target);
|
||||
}
|
||||
|
||||
private void TryUseUtensil(IEntity user, IEntity target)
|
||||
{
|
||||
if (user == null || target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.TryGetComponent(out FoodComponent food))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InteractionChecks.InRangeUnobstructed(user, target.Transform.MapPosition))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
food.TryUseFood(user, null, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user