Merge branch 'master' into 2021-12-03-remove-IEntity-komm-süsser-todd
# Conflicts: # Content.Client/Crayon/CrayonDecalVisualizer.cs # Content.Client/Tabletop/TabletopSystem.cs # Content.IntegrationTests/Tests/InventoryHelpersTest.cs # Content.Server/AI/EntitySystems/AiSystem.cs # Content.Server/AI/Utility/AiLogic/UtilityAI.cs # Content.Server/AME/AMENodeGroup.cs # Content.Server/Administration/AdminVerbSystem.cs # Content.Server/Body/Systems/RespiratorSystem.cs # Content.Server/Chemistry/Components/InjectorComponent.cs # Content.Server/Chemistry/TileReactions/CleanTileReaction.cs # Content.Server/Chemistry/TileReactions/SpillTileReaction.cs # Content.Server/Crayon/CrayonComponent.cs # Content.Server/Doors/Components/ServerDoorComponent.cs # Content.Server/Explosion/EntitySystems/TriggerSystem.cs # Content.Server/Fluids/Components/MopComponent.cs # Content.Server/Fluids/Components/SpillExtensions.cs # Content.Server/Fluids/EntitySystems/PuddleSystem.cs # Content.Server/Instruments/InstrumentSystem.cs # Content.Server/Nutrition/EntitySystems/DrinkSystem.cs # Content.Server/Nutrition/EntitySystems/FoodSystem.cs # Content.Server/PneumaticCannon/PneumaticCannonSystem.cs # Content.Server/Storage/Components/EntityStorageComponent.cs # Content.Server/Storage/Components/StorageFillComponent.cs # Content.Server/Stunnable/StunbatonSystem.cs # Content.Server/Throwing/ThrowHelper.cs # Content.Server/Weapon/Ranged/Barrels/BarrelSystem.cs # Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs # Content.Server/Weapon/Ranged/ServerRangedWeaponComponent.cs # Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs # Content.Shared/Damage/Components/DamageableComponent.cs # Content.Shared/Damage/Systems/DamageableSystem.cs # Content.Shared/MobState/Components/MobStateComponent.cs # Content.Shared/Slippery/SharedSlipperySystem.cs
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Fluids.Components;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Audio;
|
||||
@@ -20,6 +21,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
public class CreamPieSystem : SharedCreamPieSystem
|
||||
{
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionsSystem = default!;
|
||||
[Dependency] private readonly SpillableSystem _spillableSystem = default!;
|
||||
|
||||
protected override void SplattedCreamPie(EntityUid uid, CreamPieComponent creamPie)
|
||||
{
|
||||
@@ -27,7 +29,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
|
||||
if (IoCManager.Resolve<IEntityManager>().TryGetComponent<FoodComponent?>(creamPie.Owner, out var foodComp) && _solutionsSystem.TryGetSolution(creamPie.Owner, foodComp.SolutionName, out var solution))
|
||||
{
|
||||
solution.SpillAt(creamPie.Owner, "PuddleSmear", false);
|
||||
_spillableSystem.SpillAt(creamPie.Owner, solution, "PuddleSmear", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Server.Chemistry.Components.SolutionManager;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Fluids.Components;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.ActionBlocker;
|
||||
@@ -14,6 +15,7 @@ using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Helpers;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
@@ -42,6 +44,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||
[Dependency] private readonly SharedAdminLogSystem _logSystem = default!;
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
|
||||
[Dependency] private readonly SpillableSystem _spillableSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -51,12 +54,26 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
SubscribeLocalEvent<DrinkComponent, ComponentInit>(OnDrinkInit);
|
||||
SubscribeLocalEvent<DrinkComponent, LandEvent>(HandleLand);
|
||||
SubscribeLocalEvent<DrinkComponent, UseInHandEvent>(OnUse);
|
||||
SubscribeLocalEvent<DrinkComponent, HandDeselectedEvent>(OnDrinkDeselected);
|
||||
SubscribeLocalEvent<DrinkComponent, AfterInteractEvent>(AfterInteract);
|
||||
SubscribeLocalEvent<DrinkComponent, ExaminedEvent>(OnExamined);
|
||||
SubscribeLocalEvent<SharedBodyComponent, ForceDrinkEvent>(OnForceDrink);
|
||||
SubscribeLocalEvent<ForceDrinkCancelledEvent>(OnForceDrinkCancelled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the user is currently forcing someone do drink, this cancels the attempt if they swap hands or
|
||||
/// otherwise loose the item. Prevents force-feeding dual-wielding.
|
||||
/// </summary>
|
||||
private void OnDrinkDeselected(EntityUid uid, DrinkComponent component, HandDeselectedEvent args)
|
||||
{
|
||||
if (component.CancelToken != null)
|
||||
{
|
||||
component.CancelToken.Cancel();
|
||||
component.CancelToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmpty(EntityUid uid, DrinkComponent? component = null)
|
||||
{
|
||||
if(!Resolve(uid, ref component))
|
||||
@@ -185,7 +202,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
UpdateAppearance(component);
|
||||
|
||||
var solution = _solutionContainerSystem.Drain(uid, interactions, interactions.DrainAvailable);
|
||||
solution.SpillAt(uid, "PuddleSmear");
|
||||
_spillableSystem.SpillAt(uid, solution, "PuddleSmear");
|
||||
|
||||
SoundSystem.Play(Filter.Pvs(uid), component.BurstSound.GetSound(), uid, AudioParams.Default.WithVolume(-4));
|
||||
}
|
||||
@@ -235,6 +252,14 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
if (!Resolve(uid, ref drink))
|
||||
return false;
|
||||
|
||||
// if currently being used to force-feed, cancel that action.
|
||||
if (drink.CancelToken != null)
|
||||
{
|
||||
drink.CancelToken.Cancel();
|
||||
drink.CancelToken = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!drink.Opened)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-not-open",
|
||||
@@ -260,13 +285,8 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_foodSystem.IsMouthBlocked(userUid, out var blocker))
|
||||
{
|
||||
var name = EntityManager.GetComponent<MetaDataComponent>(blocker.Value).EntityName;
|
||||
_popupSystem.PopupEntity(Loc.GetString("food-system-remove-mask", ("entity", name)),
|
||||
userUid, Filter.Entities(userUid));
|
||||
if (_foodSystem.IsMouthBlocked(userUid, userUid))
|
||||
return true;
|
||||
}
|
||||
|
||||
var transferAmount = FixedPoint2.Min(drink.TransferAmount, drinkSolution.DrainAvailable);
|
||||
var drain = _solutionContainerSystem.Drain(uid, drinkSolution, transferAmount);
|
||||
@@ -281,7 +301,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
|
||||
if (EntityManager.HasComponent<RefillableSolutionComponent>(uid))
|
||||
{
|
||||
drain.SpillAt(userUid, "PuddleSmear");
|
||||
_spillableSystem.SpillAt(userUid, drain, "PuddleSmear");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -312,8 +332,12 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
return false;
|
||||
|
||||
// cannot stack do-afters
|
||||
if (drink.InUse)
|
||||
return false;
|
||||
if (drink.CancelToken != null)
|
||||
{
|
||||
drink.CancelToken.Cancel();
|
||||
drink.CancelToken = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!EntityManager.HasComponent<SharedBodyComponent>(targetUid))
|
||||
return false;
|
||||
@@ -333,13 +357,8 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_foodSystem.IsMouthBlocked(targetUid, out var blocker))
|
||||
{
|
||||
var name = EntityManager.GetComponent<MetaDataComponent>(blocker.Value).EntityName;
|
||||
_popupSystem.PopupEntity(Loc.GetString("food-system-remove-mask", ("entity", name)),
|
||||
userUid, Filter.Entities(userUid));
|
||||
if (_foodSystem.IsMouthBlocked(targetUid, userUid))
|
||||
return true;
|
||||
}
|
||||
|
||||
EntityManager.TryGetComponent(userUid, out MetaDataComponent? meta);
|
||||
var userName = meta?.EntityName ?? string.Empty;
|
||||
@@ -347,7 +366,8 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
_popupSystem.PopupEntity(Loc.GetString("drink-component-force-feed", ("user", userName)),
|
||||
userUid, Filter.Entities(targetUid));
|
||||
|
||||
_doAfterSystem.DoAfter(new DoAfterEventArgs(userUid, drink.ForceFeedDelay, target: targetUid)
|
||||
drink.CancelToken = new();
|
||||
_doAfterSystem.DoAfter(new DoAfterEventArgs(userUid, drink.ForceFeedDelay, drink.CancelToken.Token, targetUid)
|
||||
{
|
||||
BreakOnUserMove = true,
|
||||
BreakOnDamage = true,
|
||||
@@ -355,13 +375,12 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
BreakOnTargetMove = true,
|
||||
MovementThreshold = 1.0f,
|
||||
TargetFinishedEvent = new ForceDrinkEvent(userUid, drink, drinkSolution),
|
||||
BroadcastCancelledEvent = new ForceDrinkCancelledEvent(drink)
|
||||
BroadcastCancelledEvent = new ForceDrinkCancelledEvent(drink),
|
||||
});
|
||||
|
||||
// logging
|
||||
_logSystem.Add(LogType.ForceFeed, LogImpact.Medium, $"{userUid} is forcing {targetUid} to drink {uid}");
|
||||
|
||||
drink.InUse = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -370,7 +389,10 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
/// </summary>
|
||||
private void OnForceDrink(EntityUid uid, SharedBodyComponent body, ForceDrinkEvent args)
|
||||
{
|
||||
args.Drink.InUse = false;
|
||||
if (args.Drink.Deleted)
|
||||
return;
|
||||
|
||||
args.Drink.CancelToken = null;
|
||||
var transferAmount = FixedPoint2.Min(args.Drink.TransferAmount, args.DrinkSolution.DrainAvailable);
|
||||
var drained = _solutionContainerSystem.Drain((args.Drink).Owner, args.DrinkSolution, transferAmount);
|
||||
|
||||
@@ -379,7 +401,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
_popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-cannot-drink-other"),
|
||||
uid, Filter.Entities(args.User));
|
||||
|
||||
drained.SpillAt(uid, "PuddleSmear");
|
||||
_spillableSystem.SpillAt(uid, drained, "PuddleSmear");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -392,7 +414,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
_popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough-other"),
|
||||
uid, Filter.Entities(args.User));
|
||||
|
||||
drained.SpillAt(uid, "PuddleSmear");
|
||||
_spillableSystem.SpillAt(uid, drained, "PuddleSmear");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -416,31 +438,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
|
||||
private void OnForceDrinkCancelled(ForceDrinkCancelledEvent args)
|
||||
{
|
||||
args.Drink.InUse = false;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ForceDrinkEvent : EntityEventArgs
|
||||
{
|
||||
public readonly EntityUid User;
|
||||
public readonly DrinkComponent Drink;
|
||||
public readonly Solution DrinkSolution;
|
||||
|
||||
public ForceDrinkEvent(EntityUid user, DrinkComponent drink, Solution drinkSolution)
|
||||
{
|
||||
User = user;
|
||||
Drink = drink;
|
||||
DrinkSolution = drinkSolution;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ForceDrinkCancelledEvent : EntityEventArgs
|
||||
{
|
||||
public readonly DrinkComponent Drink;
|
||||
|
||||
public ForceDrinkCancelledEvent( DrinkComponent drink)
|
||||
{
|
||||
Drink = drink;
|
||||
args.Drink.CancelToken = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ using Content.Server.Popups;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.FixedPoint;
|
||||
@@ -27,7 +26,11 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Player;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Server.Inventory.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Hands;
|
||||
|
||||
namespace Content.Server.Nutrition.EntitySystems
|
||||
{
|
||||
@@ -51,9 +54,24 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
|
||||
SubscribeLocalEvent<FoodComponent, UseInHandEvent>(OnUseFoodInHand);
|
||||
SubscribeLocalEvent<FoodComponent, AfterInteractEvent>(OnFeedFood);
|
||||
SubscribeLocalEvent<FoodComponent, HandDeselectedEvent>(OnFoodDeselected);
|
||||
SubscribeLocalEvent<FoodComponent, GetInteractionVerbsEvent>(AddEatVerb);
|
||||
SubscribeLocalEvent<SharedBodyComponent, ForceFeedEvent>(OnForceFeed);
|
||||
SubscribeLocalEvent<ForceFeedCancelledEvent>(OnForceFeedCancelled);
|
||||
SubscribeLocalEvent<InventoryComponent, IngestionAttemptEvent>(OnInventoryIngestAttempt);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the user is currently force feeding someone, this cancels the attempt if they swap hands or otherwise
|
||||
/// loose the item. Prevents force-feeding dual-wielding.
|
||||
/// </summary>
|
||||
private void OnFoodDeselected(EntityUid uid, FoodComponent component, HandDeselectedEvent args)
|
||||
{
|
||||
if (component.CancelToken != null)
|
||||
{
|
||||
component.CancelToken.Cancel();
|
||||
component.CancelToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -119,6 +137,14 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
if (!Resolve(uid, ref food))
|
||||
return false;
|
||||
|
||||
// if currently being used to force-feed, cancel that action.
|
||||
if (food.CancelToken != null)
|
||||
{
|
||||
food.CancelToken.Cancel();
|
||||
food.CancelToken = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (uid == user || //Suppresses self-eating
|
||||
EntityManager.TryGetComponent<MobStateComponent>(uid, out var mobState) && mobState.IsAlive()) // Suppresses eating alive mobs
|
||||
return false;
|
||||
@@ -137,11 +163,8 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
!_bodySystem.TryGetComponentsOnMechanisms<StomachComponent>(user, out var stomachs, body))
|
||||
return false;
|
||||
|
||||
if (IsMouthBlocked(user, out var blocker))
|
||||
if (IsMouthBlocked(user, user))
|
||||
{
|
||||
var name = EntityManager.GetComponent<MetaDataComponent>(blocker.Value).EntityName;
|
||||
_popupSystem.PopupEntity(Loc.GetString("food-system-remove-mask", ("entity", name)),
|
||||
user, Filter.Entities(user));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -218,6 +241,9 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
|
||||
private void AddEatVerb(EntityUid uid, FoodComponent component, GetInteractionVerbsEvent ev)
|
||||
{
|
||||
if (component.CancelToken != null)
|
||||
return;
|
||||
|
||||
if (uid == ev.User ||
|
||||
!ev.CanInteract ||
|
||||
!ev.CanAccess ||
|
||||
@@ -250,6 +276,14 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
if (!Resolve(uid, ref food))
|
||||
return false;
|
||||
|
||||
// if currently being used to force-feed, cancel that action.
|
||||
if (food.CancelToken != null)
|
||||
{
|
||||
food.CancelToken.Cancel();
|
||||
food.CancelToken = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!EntityManager.HasComponent<SharedBodyComponent>(target))
|
||||
return false;
|
||||
|
||||
@@ -264,11 +298,8 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsMouthBlocked(target, out var blocker))
|
||||
if (IsMouthBlocked(target, user))
|
||||
{
|
||||
var name = EntityManager.GetComponent<MetaDataComponent>(blocker.Value).EntityName;
|
||||
_popupSystem.PopupEntity(Loc.GetString("food-system-remove-mask", ("entity", name)),
|
||||
user, Filter.Entities(user));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -281,7 +312,8 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
_popupSystem.PopupEntity(Loc.GetString("food-system-force-feed", ("user", userName)),
|
||||
user, Filter.Entities(target));
|
||||
|
||||
_doAfterSystem.DoAfter(new DoAfterEventArgs(user, food.ForceFeedDelay, target: target)
|
||||
food.CancelToken = new();
|
||||
_doAfterSystem.DoAfter(new DoAfterEventArgs(user, food.ForceFeedDelay, food.CancelToken.Token, target)
|
||||
{
|
||||
BreakOnUserMove = true,
|
||||
BreakOnDamage = true,
|
||||
@@ -295,13 +327,15 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
// logging
|
||||
_logSystem.Add(LogType.ForceFeed, LogImpact.Medium, $"{user} is forcing {target} to eat {uid}");
|
||||
|
||||
food.InUse = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnForceFeed(EntityUid uid, SharedBodyComponent body, ForceFeedEvent args)
|
||||
{
|
||||
args.Food.InUse = false;
|
||||
if (args.Food.Deleted)
|
||||
return;
|
||||
|
||||
args.Food.CancelToken = null;
|
||||
|
||||
if (!_bodySystem.TryGetComponentsOnMechanisms<StomachComponent>(uid, out var stomachs, body))
|
||||
return;
|
||||
@@ -361,7 +395,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
if (!Resolve(uid, ref food) || !Resolve(target, ref body, false))
|
||||
return;
|
||||
|
||||
if (IsMouthBlocked(target, out _))
|
||||
if (IsMouthBlocked(target))
|
||||
return;
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution(uid, food.SolutionName, out var foodSolution))
|
||||
@@ -438,66 +472,57 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
|
||||
private void OnForceFeedCancelled(ForceFeedCancelledEvent args)
|
||||
{
|
||||
args.Food.InUse = false;
|
||||
args.Food.CancelToken = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is an entity's mouth accessible, or is it blocked by something like a mask? Does not actually check if
|
||||
/// the user has a mouth. Body system when?
|
||||
/// Block ingestion attempts based on the equipped mask or head-wear
|
||||
/// </summary>
|
||||
public bool IsMouthBlocked(EntityUid uid, [NotNullWhen(true)] out EntityUid? blockingEntity,
|
||||
InventoryComponent? inventory = null)
|
||||
private void OnInventoryIngestAttempt(EntityUid uid, InventoryComponent component, IngestionAttemptEvent args)
|
||||
{
|
||||
blockingEntity = null;
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
if (!Resolve(uid, ref inventory, false))
|
||||
return false;
|
||||
IngestionBlockerComponent blocker;
|
||||
|
||||
// check masks
|
||||
if (inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.MASK, out ItemComponent? mask))
|
||||
if (component.TryGetSlotItem(EquipmentSlotDefines.Slots.MASK, out ItemComponent? mask) &&
|
||||
EntityManager.TryGetComponent(mask.Owner, out blocker) &&
|
||||
blocker.Enabled)
|
||||
{
|
||||
// For now, lets just assume that any masks always covers the mouth
|
||||
// TODO MASKS if the ability is added to raise/lower masks, this needs to be updated.
|
||||
blockingEntity = mask.Owner;
|
||||
return true;
|
||||
args.Blocker = mask.Owner;
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// check helmets. Note that not all helmets cover the face.
|
||||
if (inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.HEAD, out ItemComponent? head) &&
|
||||
EntityManager.TryGetComponent(((IComponent) head).Owner, out TagComponent tag) &&
|
||||
tag.HasTag("ConcealsFace"))
|
||||
if (component.TryGetSlotItem(EquipmentSlotDefines.Slots.HEAD, out ItemComponent? head) &&
|
||||
EntityManager.TryGetComponent(head.Owner, out blocker) &&
|
||||
blocker.Enabled)
|
||||
{
|
||||
blockingEntity = head.Owner;
|
||||
return true;
|
||||
args.Blocker = head.Owner;
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check whether the target's mouth is blocked by equipment (masks or head-wear).
|
||||
/// </summary>
|
||||
/// <param name="uid">The target whose equipment is checked</param>
|
||||
/// <param name="popupUid">Optional entity that will receive an informative pop-up identifying the blocking
|
||||
/// piece of equipment.</param>
|
||||
/// <returns></returns>
|
||||
public bool IsMouthBlocked(EntityUid uid, EntityUid? popupUid = null)
|
||||
{
|
||||
var attempt = new IngestionAttemptEvent();
|
||||
RaiseLocalEvent(uid, attempt, false);
|
||||
if (attempt.Cancelled && attempt.Blocker != null && popupUid != null)
|
||||
{
|
||||
var name = EntityManager.GetComponent<MetaDataComponent>(attempt.Blocker.Value).EntityName;
|
||||
_popupSystem.PopupEntity(Loc.GetString("food-system-remove-mask", ("entity", name)),
|
||||
uid, Filter.Entities(popupUid.Value));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ForceFeedEvent : EntityEventArgs
|
||||
{
|
||||
public readonly EntityUid User;
|
||||
public readonly FoodComponent Food;
|
||||
public readonly Solution FoodSolution;
|
||||
public readonly List<UtensilComponent> Utensils;
|
||||
|
||||
public ForceFeedEvent(EntityUid user, FoodComponent food, Solution foodSolution, List<UtensilComponent> utensils)
|
||||
{
|
||||
User = user;
|
||||
Food = food;
|
||||
FoodSolution = foodSolution;
|
||||
Utensils = utensils;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ForceFeedCancelledEvent : EntityEventArgs
|
||||
{
|
||||
public readonly FoodComponent Food;
|
||||
|
||||
public ForceFeedCancelledEvent(FoodComponent food)
|
||||
{
|
||||
Food = food;
|
||||
return attempt.Cancelled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user