Files
OldThink/Content.Server/Animals/Systems/UdderSystem.cs

129 lines
5.1 KiB
C#
Raw Normal View History

2021-11-14 19:33:16 +03:00
using Content.Server.Animals.Components;
2021-12-05 18:09:01 +01:00
using Content.Server.Chemistry.Components.SolutionManager;
2021-11-14 19:33:16 +03:00
using Content.Server.Chemistry.EntitySystems;
2023-04-02 22:42:30 -04:00
using Content.Server.DoAfter;
2021-11-14 19:33:16 +03:00
using Content.Server.Nutrition.Components;
2021-12-05 18:09:01 +01:00
using Content.Server.Popups;
2023-04-10 15:37:03 +10:00
using Content.Shared.Chemistry.Components;
using Content.Shared.DoAfter;
using Content.Shared.IdentityManagement;
2021-11-14 19:33:16 +03:00
using Content.Shared.Nutrition.Components;
2023-04-02 22:42:30 -04:00
using Content.Shared.Nutrition.EntitySystems;
using Content.Shared.Popups;
using Content.Shared.Udder;
2021-11-14 19:33:16 +03:00
using Content.Shared.Verbs;
namespace Content.Server.Animals.Systems
{
/// <summary>
/// Gives ability to living beings with acceptable hunger level to produce milkable reagents.
/// </summary>
internal sealed class UdderSystem : EntitySystem
2021-11-14 19:33:16 +03:00
{
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
2023-04-02 22:42:30 -04:00
[Dependency] private readonly HungerSystem _hunger = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
2021-11-14 19:33:16 +03:00
[Dependency] private readonly PopupSystem _popupSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<UdderComponent, GetVerbsEvent<AlternativeVerb>>(AddMilkVerb);
SubscribeLocalEvent<UdderComponent, MilkingDoAfterEvent>(OnDoAfter);
2021-11-14 19:33:16 +03:00
}
public override void Update(float frameTime)
{
foreach (var udder in EntityManager.EntityQuery<UdderComponent>(false))
{
udder.AccumulatedFrameTime += frameTime;
2022-03-01 01:11:25 +11:00
while (udder.AccumulatedFrameTime > udder.UpdateRate)
2021-11-14 19:33:16 +03:00
{
2022-03-01 01:11:25 +11:00
udder.AccumulatedFrameTime -= udder.UpdateRate;
2021-11-14 19:33:16 +03:00
2022-03-01 01:11:25 +11:00
// Actually there is food digestion so no problem with instant reagent generation "OnFeed"
if (EntityManager.TryGetComponent<HungerComponent?>(udder.Owner, out var hunger))
{
// Is there enough nutrition to produce reagent?
2023-04-02 22:42:30 -04:00
if (_hunger.GetHungerThreshold(hunger) < HungerThreshold.Peckish)
2022-03-01 01:11:25 +11:00
continue;
}
2021-11-14 19:33:16 +03:00
2022-03-01 01:11:25 +11:00
if (!_solutionContainerSystem.TryGetSolution(udder.Owner, udder.TargetSolutionName,
out var solution))
continue;
//TODO: toxins from bloodstream !?
_solutionContainerSystem.TryAddReagent(udder.Owner, solution, udder.ReagentId,
udder.QuantityPerUpdate, out var accepted);
}
2021-11-14 19:33:16 +03:00
}
}
private void AttemptMilk(EntityUid uid, EntityUid userUid, EntityUid containerUid, UdderComponent? udder = null)
{
if (!Resolve(uid, ref udder))
return;
var doargs = new DoAfterArgs(userUid, 5, new MilkingDoAfterEvent(), uid, uid, used: containerUid)
2021-11-14 19:33:16 +03:00
{
BreakOnUserMove = true,
BreakOnDamage = true,
BreakOnTargetMove = true,
MovementThreshold = 1.0f,
2021-11-14 19:33:16 +03:00
};
_doAfterSystem.TryStartDoAfter(doargs);
2021-11-14 19:33:16 +03:00
}
private void OnDoAfter(EntityUid uid, UdderComponent component, MilkingDoAfterEvent args)
2021-11-14 19:33:16 +03:00
{
if (args.Cancelled || args.Handled || args.Args.Used == null)
return;
if (!_solutionContainerSystem.TryGetSolution(uid, component.TargetSolutionName, out var solution))
return;
if (!_solutionContainerSystem.TryGetRefillableSolution(args.Args.Used.Value, out var targetSolution))
2021-11-14 19:33:16 +03:00
return;
args.Handled = true;
2023-01-12 16:41:40 +13:00
var quantity = solution.Volume;
2021-11-14 19:33:16 +03:00
if(quantity == 0)
{
_popupSystem.PopupEntity(Loc.GetString("udder-system-dry"), uid, args.Args.User);
2021-11-14 19:33:16 +03:00
return;
}
if (quantity > targetSolution.AvailableVolume)
quantity = targetSolution.AvailableVolume;
var split = _solutionContainerSystem.SplitSolution(uid, solution, quantity);
_solutionContainerSystem.TryAddSolution(args.Args.Used.Value, targetSolution, split);
2021-11-14 19:33:16 +03:00
_popupSystem.PopupEntity(Loc.GetString("udder-system-success", ("amount", quantity), ("target", Identity.Entity(args.Args.Used.Value, EntityManager))), uid,
args.Args.User, PopupType.Medium);
2021-11-14 19:33:16 +03:00
}
private void AddMilkVerb(EntityUid uid, UdderComponent component, GetVerbsEvent<AlternativeVerb> args)
2021-11-14 19:33:16 +03:00
{
if (args.Using == null ||
!args.CanInteract ||
2021-12-05 18:09:01 +01:00
!EntityManager.HasComponent<RefillableSolutionComponent>(args.Using.Value))
2021-11-14 19:33:16 +03:00
return;
AlternativeVerb verb = new()
2021-11-14 19:33:16 +03:00
{
2021-12-05 18:09:01 +01:00
Act = () =>
{
AttemptMilk(uid, args.User, args.Using.Value, component);
},
Text = Loc.GetString("udder-system-verb-milk"),
Priority = 2
2021-11-14 19:33:16 +03:00
};
args.Verbs.Add(verb);
}
}
}