Adds cow milking (#5293)
This commit is contained in:
@@ -310,6 +310,7 @@ namespace Content.Client.Entry
|
||||
"NukeCodePaper",
|
||||
"GhostRadio",
|
||||
"Armor",
|
||||
"Udder",
|
||||
"PneumaticCannon"
|
||||
};
|
||||
}
|
||||
|
||||
48
Content.Server/Animals/Components/UdderComponent.cs
Normal file
48
Content.Server/Animals/Components/UdderComponent.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Content.Server.Animals.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.Animals.Components
|
||||
{
|
||||
[RegisterComponent, Friend(typeof(UdderSystem))]
|
||||
internal class UdderComponent : Component
|
||||
{
|
||||
public override string Name => "Udder";
|
||||
|
||||
/// <summary>
|
||||
/// The reagent to produce.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[DataField("reagentId")]
|
||||
public string ReagentId = "Milk";
|
||||
|
||||
/// <summary>
|
||||
/// The solution to add reagent to.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[DataField("targetSolution")]
|
||||
public string TargetSolutionName = "udder";
|
||||
|
||||
/// <summary>
|
||||
/// The amount of reagent to be generated on update.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[DataField("quantity")]
|
||||
public FixedPoint2 QuantityPerUpdate = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The time between updates (in seconds).
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[DataField("updateRate")]
|
||||
public float UpdateRate = 5;
|
||||
|
||||
public float AccumulatedFrameTime;
|
||||
|
||||
public bool BeingMilked;
|
||||
}
|
||||
}
|
||||
154
Content.Server/Animals/Systems/UdderSystem.cs
Normal file
154
Content.Server/Animals/Systems/UdderSystem.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using Content.Server.Animals.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Server.Chemistry.Components.SolutionManager;
|
||||
using Content.Server.DoAfter;
|
||||
using Robust.Shared.Localization;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Player;
|
||||
using Content.Server.Popups;
|
||||
|
||||
namespace Content.Server.Animals.Systems
|
||||
{
|
||||
/// <summary>
|
||||
/// Gives ability to living beings with acceptable hunger level to produce milkable reagents.
|
||||
/// </summary>
|
||||
internal class UdderSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<UdderComponent, GetAlternativeVerbsEvent>(AddMilkVerb);
|
||||
SubscribeLocalEvent<UdderComponent, MilkingFinishedEvent>(OnMilkingFinished);
|
||||
SubscribeLocalEvent<UdderComponent, MilkingFailEvent>(OnMilkingFailed);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
foreach (var udder in EntityManager.EntityQuery<UdderComponent>(false))
|
||||
{
|
||||
udder.AccumulatedFrameTime += frameTime;
|
||||
|
||||
if (udder.AccumulatedFrameTime < udder.UpdateRate)
|
||||
continue;
|
||||
|
||||
// Actually there is food digestion so no problem with instant reagent generation "OnFeed"
|
||||
if (udder.Owner.TryGetComponent<HungerComponent>(out var hunger))
|
||||
{
|
||||
hunger.HungerThresholds.TryGetValue(HungerThreshold.Peckish, out var targetThreshold);
|
||||
|
||||
// Is there enough nutrition to produce reagent?
|
||||
if (hunger.CurrentHunger < targetThreshold)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution(udder.OwnerUid, udder.TargetSolutionName, out var solution))
|
||||
continue;
|
||||
|
||||
//TODO: toxins from bloodstream !?
|
||||
_solutionContainerSystem.TryAddReagent(udder.OwnerUid, solution, udder.ReagentId, udder.QuantityPerUpdate, out var accepted);
|
||||
udder.AccumulatedFrameTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void AttemptMilk(EntityUid uid, EntityUid userUid, EntityUid containerUid, UdderComponent? udder = null)
|
||||
{
|
||||
if (!Resolve(uid, ref udder))
|
||||
return;
|
||||
|
||||
if (udder.BeingMilked)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("udder-system-already-milking"), uid, Filter.Entities(userUid));
|
||||
return;
|
||||
}
|
||||
|
||||
udder.BeingMilked = true;
|
||||
|
||||
var doargs = new DoAfterEventArgs(userUid, 5, default, uid)
|
||||
{
|
||||
BreakOnUserMove = true,
|
||||
BreakOnDamage = true,
|
||||
BreakOnStun = true,
|
||||
BreakOnTargetMove = true,
|
||||
MovementThreshold = 1.0f,
|
||||
TargetFinishedEvent = new MilkingFinishedEvent(userUid, containerUid),
|
||||
TargetCancelledEvent = new MilkingFailEvent()
|
||||
};
|
||||
|
||||
_doAfterSystem.DoAfter(doargs);
|
||||
}
|
||||
|
||||
private void OnMilkingFinished(EntityUid uid, UdderComponent udder, MilkingFinishedEvent ev)
|
||||
{
|
||||
udder.BeingMilked = false;
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution(uid, udder.TargetSolutionName, out var solution))
|
||||
return;
|
||||
|
||||
if (!_solutionContainerSystem.TryGetRefillableSolution(ev.ContainerUid, out var targetSolution))
|
||||
return;
|
||||
|
||||
var quantity = solution.TotalVolume;
|
||||
if(quantity == 0)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("udder-system-dry"), uid, Filter.Entities(ev.UserUid));
|
||||
return;
|
||||
}
|
||||
|
||||
if (quantity > targetSolution.AvailableVolume)
|
||||
quantity = targetSolution.AvailableVolume;
|
||||
|
||||
var split = _solutionContainerSystem.SplitSolution(uid, solution, quantity);
|
||||
_solutionContainerSystem.TryAddSolution(ev.ContainerUid, targetSolution, split);
|
||||
|
||||
var container = EntityManager.GetEntity(ev.ContainerUid);
|
||||
_popupSystem.PopupEntity(Loc.GetString("udder-system-success", ("amount", quantity), ("target", container)), uid, Filter.Entities(ev.UserUid));
|
||||
}
|
||||
|
||||
private void OnMilkingFailed(EntityUid uid, UdderComponent component, MilkingFailEvent ev)
|
||||
{
|
||||
component.BeingMilked = false;
|
||||
}
|
||||
|
||||
private void AddMilkVerb(EntityUid uid, UdderComponent component, GetAlternativeVerbsEvent args)
|
||||
{
|
||||
if (args.Using == null ||
|
||||
!args.CanInteract ||
|
||||
!args.Using.HasComponent<RefillableSolutionComponent>())
|
||||
return;
|
||||
|
||||
Verb verb = new();
|
||||
verb.Act = () =>
|
||||
{
|
||||
AttemptMilk(uid, args.User.Uid, args.Using.Uid, component);
|
||||
};
|
||||
verb.Text = Loc.GetString("udder-system-verb-milk");
|
||||
verb.Priority = 2;
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private class MilkingFinishedEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid UserUid;
|
||||
public EntityUid ContainerUid;
|
||||
|
||||
public MilkingFinishedEvent(EntityUid userUid, EntityUid containerUid)
|
||||
{
|
||||
UserUid = userUid;
|
||||
ContainerUid = containerUid;
|
||||
}
|
||||
}
|
||||
|
||||
private class MilkingFailEvent : EntityEventArgs
|
||||
{ }
|
||||
}
|
||||
}
|
||||
7
Resources/Locale/en-US/animals/udder/udder-system.ftl
Normal file
7
Resources/Locale/en-US/animals/udder/udder-system.ftl
Normal file
@@ -0,0 +1,7 @@
|
||||
### Udder system
|
||||
|
||||
udder-system-already-milking = The udder is already being milked.
|
||||
udder-system-success = You fill {THE($target)} with {$amount}u from the udder.
|
||||
udder-system-dry = The udder is dry.
|
||||
|
||||
udder-system-verb-milk = Milk
|
||||
@@ -177,6 +177,18 @@
|
||||
normal: cow
|
||||
crit: dead
|
||||
dead: dead
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
udder:
|
||||
maxVol: 250
|
||||
reagents:
|
||||
- ReagentId: Milk
|
||||
Quantity: 30
|
||||
- type: Udder
|
||||
reagentId: Milk
|
||||
targetSolution: udder
|
||||
quantity: 25
|
||||
updateRate: 30
|
||||
|
||||
- type: entity
|
||||
name: crab
|
||||
|
||||
Reference in New Issue
Block a user