CatStation/Content.Shared/Botany/Items/Systems/BotanySwabSystem.cs
SlothBasket b1323acc43
Botany Refactor Bugfixes and Value adjustments (#45752)
* Fixes Cryoxadone De-Age, properly adjusts lastHarvest. If age would be reduced below 0 reverts plant to seed with current genetics.

* Botany Bugfixes. Cryoxadone De-Age fix. Cryox Regression to seed re-added. Seedless Produce no longer have seeds. Proper Temp tollerance ranges restored. Production no longer clamped to maturation.

* Restore Content Server+Client run configuration

* Fix formatting in Content Server+Client run configuration

* Address botany review feedback

* review

* fix weed

* fix

* fix 2

* Update PlantSystem.cs

* refactor: revert to EntityTerminatingEvent and leave warning for next generations

---------

Co-authored-by: Pok245 <113675512+Pok27@users.noreply.github.com>
Co-authored-by: Fildrance <fildrance@gmail.com>
2026-09-03 14:57:34 +00:00

95 lines
3.4 KiB
C#

using Content.Shared.Botany.Components;
using Content.Shared.Botany.Events;
using Content.Shared.Botany.Items.Components;
using Content.Shared.Botany.Systems;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Swab;
namespace Content.Shared.Botany.Items.Systems;
public sealed partial class BotanySwabSystem : EntitySystem
{
[Dependency] private BotanySystem _botany = default!;
[Dependency] private PlantMutationSystem _mutation = default!;
[Dependency] private SharedDoAfterSystem _doAfter = default!;
[Dependency] private SharedPopupSystem _popup = default!;
[Dependency] private EntityQuery<PlantComponent> _plantQuery;
/// <summary>
/// This handles swab examination text
/// so you can tell if they are used or not.
/// </summary>
[SubscribeLocalEvent]
private void OnExamined(Entity<BotanySwabComponent> ent, ref ExaminedEvent args)
{
if (!args.IsInDetailsRange)
return;
if (ent.Comp.PlantData != null)
args.PushMarkup(Loc.GetString("swab-used"));
else
args.PushMarkup(Loc.GetString("swab-unused"));
}
/// <summary>
/// Handles swabbing a plant.
/// </summary>
[SubscribeLocalEvent]
private void OnAfterInteract(Entity<BotanySwabComponent> ent, ref AfterInteractEvent args)
{
if (args.Target == null || !args.CanReach || !_plantQuery.HasComp(args.Target))
return;
_doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, ent.Comp.SwabDelay, new BotanySwabDoAfterEvent(), ent.Owner, target: args.Target, used: ent.Owner)
{
Broadcast = true,
BreakOnMove = true,
NeedHand = true,
});
}
/// <summary>
/// Save seed data or cross-pollenate.
/// </summary>
[SubscribeLocalEvent]
private void OnDoAfter(Entity<BotanySwabComponent> ent, ref BotanySwabDoAfterEvent args)
{
if (args.Cancelled || args.Handled || !_plantQuery.HasComp(args.Args.Target))
return;
var targetPlant = args.Args.Target.Value;
if (ent.Comp.PlantData == null)
{
// Pick up pollen snapshot.
ent.Comp.PlantProtoId = MetaData(targetPlant).EntityPrototype?.ID;
ent.Comp.PlantData = _botany.ClonePlantSnapshotData(targetPlant, parent: ent.Owner);
_popup.PopupEntity(Loc.GetString("botany-swab-from"), targetPlant, args.Args.User);
}
else
{
var pollenData = ent.Comp.PlantData.Value;
_mutation.CrossMutations(pollenData, ent.Comp.PlantProtoId, targetPlant);
// Notify growth systems to apply their per-component cross logic.
var crossEv = new PlantCrossPollinateEvent(pollenData, ent.Comp.PlantProtoId);
RaiseLocalEvent(targetPlant, ref crossEv);
// Swap: store old target pollen on the swab, apply cross to the target using swab pollen.
var oldPollenData = ent.Comp.PlantData;
ent.Comp.PlantProtoId = MetaData(targetPlant).EntityPrototype?.ID;
ent.Comp.PlantData = _botany.ClonePlantSnapshotData(targetPlant, parent: ent.Owner);
_botany.DeletePlantSnapshot(oldPollenData);
_popup.PopupEntity(Loc.GetString("botany-swab-to"), targetPlant, args.Args.User);
}
Dirty(ent);
args.Handled = true;
}
}