/// <summary> /// Raised directed at a victim when someone has force fed them a drink. /// </summary> private void OnDrink(EntityUid uid, SharedBodyComponent body, DrinkEvent args) { 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); var forceDrink = uid != args.User; if (!_bodySystem.TryGetComponentsOnMechanisms <StomachComponent>(uid, out var stomachs, body)) { _popupSystem.PopupEntity( forceDrink ? Loc.GetString("drink-component-try-use-drink-cannot-drink-other") : Loc.GetString("drink-component-try-use-drink-had-enough"), uid, Filter.Entities(args.User)); if (EntityManager.HasComponent <RefillableSolutionComponent>(uid)) { _spillableSystem.SpillAt(args.User, drained, "PuddleSmear"); return; } _solutionContainerSystem.Refill(uid, args.DrinkSolution, drained); return; } var firstStomach = stomachs.FirstOrNull( stomach => _stomachSystem.CanTransferSolution((stomach.Comp).Owner, drained)); // All stomach are full or can't handle whatever solution we have. if (firstStomach == null) { _popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough-other"), uid, Filter.Entities(args.User)); _spillableSystem.SpillAt(uid, drained, "PuddleSmear"); return; } if (forceDrink) { EntityManager.TryGetComponent(uid, out MetaDataComponent? targetMeta); var targetName = targetMeta?.EntityName ?? string.Empty; EntityManager.TryGetComponent(args.User, out MetaDataComponent? userMeta); var userName = userMeta?.EntityName ?? string.Empty; _popupSystem.PopupEntity( Loc.GetString("drink-component-force-feed-success", ("user", userName)), uid, Filter.Entities(uid)); _popupSystem.PopupEntity( Loc.GetString("drink-component-force-feed-success-user", ("target", targetName)), args.User, Filter.Entities(args.User)); } else { _popupSystem.PopupEntity( Loc.GetString("drink-component-try-use-drink-success-slurp"), args.User, Filter.Pvs(args.User)); } SoundSystem.Play(Filter.Pvs(uid), args.Drink.UseSound.GetSound(), uid, AudioParams.Default.WithVolume(-2f)); drained.DoEntityReaction(uid, ReactionMethod.Ingestion); _stomachSystem.TryTransferSolution(firstStomach.Value.Comp.Owner, drained, firstStomach.Value.Comp); }
/// <summary> /// Attempt to drink some of a drink. Returns true if any interaction took place, including generation of /// pop-up messages. /// </summary> private bool TryUseDrink(EntityUid uid, EntityUid userUid, DrinkComponent?drink = null) { 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", ("owner", Name: EntityManager.GetComponent <MetaDataComponent>(drink.Owner).EntityName)), uid, Filter.Entities(userUid)); return(true); } if (!EntityManager.TryGetComponent(userUid, out SharedBodyComponent? body)) { return(false); } if (!_solutionContainerSystem.TryGetDrainableSolution((drink).Owner, out var drinkSolution) || drinkSolution.DrainAvailable <= 0) { _popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-is-empty", ("entity", Name: EntityManager.GetComponent <MetaDataComponent>(drink.Owner).EntityName)), uid, Filter.Entities(userUid)); return(true); } if (!_bodySystem.TryGetComponentsOnMechanisms <StomachComponent>(userUid, out var stomachs, body)) { _popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-cannot-drink"), userUid, Filter.Entities(userUid)); return(true); } if (_foodSystem.IsMouthBlocked(userUid, userUid)) { return(true); } var transferAmount = FixedPoint2.Min(drink.TransferAmount, drinkSolution.DrainAvailable); var drain = _solutionContainerSystem.Drain(uid, drinkSolution, transferAmount); var firstStomach = stomachs.FirstOrNull( stomach => _stomachSystem.CanTransferSolution((stomach.Comp).Owner, drain)); // All stomach are full or can't handle whatever solution we have. if (firstStomach == null) { _popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), userUid, Filter.Entities(userUid)); if (EntityManager.HasComponent <RefillableSolutionComponent>(uid)) { _spillableSystem.SpillAt(userUid, drain, "PuddleSmear"); return(true); } _solutionContainerSystem.Refill(uid, drinkSolution, drain); return(true); } SoundSystem.Play(Filter.Pvs(userUid), drink.UseSound.GetSound(), userUid, AudioParams.Default.WithVolume(-2f)); _popupSystem.PopupEntity(Loc.GetString("drink-component-try-use-drink-success-slurp"), userUid, Filter.Pvs(userUid)); drain.DoEntityReaction(userUid, ReactionMethod.Ingestion); _stomachSystem.TryTransferSolution((firstStomach.Value.Comp).Owner, drain, firstStomach.Value.Comp); return(true); }
private void OnFeed(EntityUid uid, SharedBodyComponent body, FeedEvent args) { if (args.Food.Deleted) { return; } args.Food.CancelToken = null; if (!_bodySystem.TryGetComponentsOnMechanisms <StomachComponent>(uid, out var stomachs, body)) { return; } var transferAmount = args.Food.TransferAmount != null ? FixedPoint2.Min((FixedPoint2)args.Food.TransferAmount, args.FoodSolution.CurrentVolume) : args.FoodSolution.CurrentVolume; var split = _solutionContainerSystem.SplitSolution((args.Food).Owner, args.FoodSolution, transferAmount); var firstStomach = stomachs.FirstOrNull( stomach => _stomachSystem.CanTransferSolution((stomach.Comp).Owner, split)); var forceFeed = uid != args.User; // No stomach so just popup a message that they can't eat. if (firstStomach == null) { _solutionContainerSystem.TryAddSolution(uid, args.FoodSolution, split); _popupSystem.PopupEntity( forceFeed ? Loc.GetString("food-system-you-cannot-eat-any-more-other") : Loc.GetString("food-system-you-cannot-eat-any-more") , uid, Filter.Entities(args.User)); return; } split.DoEntityReaction(uid, ReactionMethod.Ingestion); _stomachSystem.TryTransferSolution(firstStomach.Value.Comp.Owner, split, firstStomach.Value.Comp); if (forceFeed) { EntityManager.TryGetComponent(uid, out MetaDataComponent? targetMeta); var targetName = targetMeta?.EntityName ?? string.Empty; EntityManager.TryGetComponent(args.User, out MetaDataComponent? userMeta); var userName = userMeta?.EntityName ?? string.Empty; _popupSystem.PopupEntity(Loc.GetString("food-system-force-feed-success", ("user", userName)), uid, Filter.Entities(uid)); _popupSystem.PopupEntity(Loc.GetString("food-system-force-feed-success-user", ("target", targetName)), args.User, Filter.Entities(args.User)); } else { _popupSystem.PopupEntity(Loc.GetString(args.Food.EatMessage, ("food", args.Food.Owner)), args.User, Filter.Entities(args.User)); } SoundSystem.Play(Filter.Pvs(uid), args.Food.UseSound.GetSound(), uid, AudioParams.Default.WithVolume(-1f)); // Try to break all used utensils foreach (var utensil in args.Utensils) { _utensilSystem.TryBreak((utensil).Owner, args.User); } if (args.Food.UsesRemaining > 0) { return; } if (string.IsNullOrEmpty(args.Food.TrashPrototype)) { EntityManager.QueueDeleteEntity(args.Food.Owner); } else { DeleteAndSpawnTrash(args.Food, args.User); } }
/// <summary> /// Tries to eat some food /// </summary> /// <param name="uid">Food entity.</param> /// <param name="user">Feeding initiator.</param> /// <returns>True if an interaction occurred (i.e., food was consumed, or a pop-up message was created)</returns> public bool TryUseFood(EntityUid uid, EntityUid user, FoodComponent?food = null) { 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); } if (!_solutionContainerSystem.TryGetSolution(uid, food.SolutionName, out var solution)) { return(false); } if (food.UsesRemaining <= 0) { _popupSystem.PopupEntity(Loc.GetString("food-system-try-use-food-is-empty", ("entity", uid)), user, Filter.Entities(user)); DeleteAndSpawnTrash(food, user); return(true); } if (!EntityManager.TryGetComponent(user, out SharedBodyComponent ? body) || !_bodySystem.TryGetComponentsOnMechanisms <StomachComponent>(user, out var stomachs, body)) { return(false); } if (IsMouthBlocked(user, user)) { return(true); } var usedUtensils = new List <UtensilComponent>(); if (!TryGetRequiredUtensils(user, food, out var utensils)) { return(true); } if (!user.InRangeUnobstructed(uid, popup: true)) { return(true); } var transferAmount = food.TransferAmount != null?FixedPoint2.Min((FixedPoint2)food.TransferAmount, solution.CurrentVolume) : solution.CurrentVolume; var split = _solutionContainerSystem.SplitSolution(uid, solution, transferAmount); var firstStomach = stomachs.FirstOrNull( stomach => _stomachSystem.CanTransferSolution((stomach.Comp).Owner, split)); if (firstStomach == null) { _solutionContainerSystem.TryAddSolution(uid, solution, split); _popupSystem.PopupEntity(Loc.GetString("food-system-you-cannot-eat-any-more"), user, Filter.Entities(user)); return(true); } // TODO: Account for partial transfer. split.DoEntityReaction(user, ReactionMethod.Ingestion); _stomachSystem.TryTransferSolution((firstStomach.Value.Comp).Owner, split, firstStomach.Value.Comp); SoundSystem.Play(Filter.Pvs(user), food.UseSound.GetSound(), user, AudioParams.Default.WithVolume(-1f)); _popupSystem.PopupEntity(Loc.GetString(food.EatMessage, ("food", food.Owner)), user, Filter.Entities(user)); // Try to break all used utensils foreach (var utensil in usedUtensils) { _utensilSystem.TryBreak((utensil).Owner, user); } if (food.UsesRemaining > 0) { return(true); } if (string.IsNullOrEmpty(food.TrashPrototype)) { EntityManager.QueueDeleteEntity((food).Owner); } else { DeleteAndSpawnTrash(food, user); } return(true); }