MessyDrinker for dogs (#38852)

This commit is contained in:
ScarKy0
2025-08-06 15:00:32 +02:00
committed by GitHub
parent 5181219f89
commit 3d0a506f6d
6 changed files with 89 additions and 2 deletions

View File

@@ -0,0 +1,22 @@
using Content.Shared.FixedPoint;
namespace Content.Server.Nutrition.Components;
/// <summary>
/// Entities with this component occasionally spill some of their drink when drinking.
/// </summary>
[RegisterComponent]
public sealed partial class MessyDrinkerComponent : Component
{
[DataField]
public float SpillChance = 0.2f;
/// <summary>
/// The amount of solution that is spilled when <see cref="SpillChance"/> procs.
/// </summary>
[DataField]
public FixedPoint2 SpillAmount = 1.0;
[DataField]
public LocId? SpillMessagePopup;
}

View File

@@ -2,6 +2,7 @@ using Content.Server.Body.Systems;
using Content.Server.Fluids.EntitySystems; using Content.Server.Fluids.EntitySystems;
using Content.Server.Forensics; using Content.Server.Forensics;
using Content.Server.Inventory; using Content.Server.Inventory;
using Content.Server.Nutrition.Events;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.Body.Components; using Content.Shared.Body.Components;
@@ -242,11 +243,18 @@ public sealed class DrinkSystem : SharedDrinkSystem
_audio.PlayPvs(entity.Comp.UseSound, args.Target.Value, AudioParams.Default.WithVolume(-2f).WithVariation(0.25f)); _audio.PlayPvs(entity.Comp.UseSound, args.Target.Value, AudioParams.Default.WithVolume(-2f).WithVariation(0.25f));
_reaction.DoEntityReaction(args.Target.Value, solution, ReactionMethod.Ingestion); var beforeDrinkEvent = new BeforeIngestDrinkEvent(entity.Owner, drained, forceDrink);
_stomach.TryTransferSolution(firstStomach.Value.Owner, drained, firstStomach.Value.Comp1); RaiseLocalEvent(args.Target.Value, ref beforeDrinkEvent);
_forensics.TransferDna(entity, args.Target.Value); _forensics.TransferDna(entity, args.Target.Value);
_reaction.DoEntityReaction(args.Target.Value, solution, ReactionMethod.Ingestion);
if (drained.Volume == 0)
return;
_stomach.TryTransferSolution(firstStomach.Value.Owner, drained, firstStomach.Value.Comp1);
if (!forceDrink && solution.Volume > 0) if (!forceDrink && solution.Volume > 0)
args.Repeat = true; args.Repeat = true;
} }

View File

@@ -0,0 +1,41 @@
using Content.Server.Fluids.EntitySystems;
using Content.Server.Nutrition.Components;
using Content.Server.Nutrition.Events;
using Content.Shared.Popups;
using Robust.Shared.Random;
namespace Content.Server.Nutrition.EntitySystems;
public sealed class MessyDrinkerSystem : EntitySystem
{
[Dependency] private readonly PuddleSystem _puddle = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MessyDrinkerComponent, BeforeIngestDrinkEvent>(OnBeforeIngestDrink);
}
private void OnBeforeIngestDrink(Entity<MessyDrinkerComponent> ent, ref BeforeIngestDrinkEvent ev)
{
if (ev.Solution.Volume <= ent.Comp.SpillAmount)
return;
// Cannot spill if you're being forced to drink.
if (ev.Forced)
return;
if (!_random.Prob(ent.Comp.SpillChance))
return;
if (ent.Comp.SpillMessagePopup != null)
_popup.PopupEntity(Loc.GetString(ent.Comp.SpillMessagePopup), ent, ent, PopupType.MediumCaution);
var split = ev.Solution.SplitSolution(ent.Comp.SpillAmount);
_puddle.TrySpillAt(ent, split, out _);
}
}

View File

@@ -0,0 +1,12 @@
using Content.Shared.Chemistry.Components;
namespace Content.Server.Nutrition.Events;
/// <summary>
/// Raised on the entity drinking. This is right before they actually transfer the solution into the stomach.
/// </summary>
/// <param name="Drink">The drink that is being drank.</param>
/// <param name="Solution">The solution that will be digested.</param>
/// <param name="Forced">Whether the target was forced to drink the solution by somebody else.</param>
[ByRefEvent]
public record struct BeforeIngestDrinkEvent(EntityUid Drink, Solution Solution, bool Forced);

View File

@@ -2859,6 +2859,7 @@
- type: HTN - type: HTN
rootTask: rootTask:
task: RuminantHostileCompound task: RuminantHostileCompound
- type: MessyDrinker
- type: Tag - type: Tag
tags: tags:
- VimPilot - VimPilot
@@ -2905,6 +2906,7 @@
gender: epicene gender: epicene
- type: MobPrice - type: MobPrice
price: 200 price: 200
- type: MessyDrinker
- type: entity - type: entity
parent: MobCorgiBase parent: MobCorgiBase

View File

@@ -370,6 +370,7 @@
- VimPilot - VimPilot
- type: StealTarget - type: StealTarget
stealGroup: AnimalMcGriff stealGroup: AnimalMcGriff
- type: MessyDrinker
- type: entity - type: entity
name: Paperwork name: Paperwork
@@ -466,6 +467,7 @@
- type: Speech - type: Speech
speechVerb: Canine speechVerb: Canine
speechSounds: Dog speechSounds: Dog
- type: MessyDrinker
- type: entity - type: entity
name: Morty name: Morty