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 _plantQuery; /// /// This handles swab examination text /// so you can tell if they are used or not. /// [SubscribeLocalEvent] private void OnExamined(Entity 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")); } /// /// Handles swabbing a plant. /// [SubscribeLocalEvent] private void OnAfterInteract(Entity 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, }); } /// /// Save seed data or cross-pollenate. /// [SubscribeLocalEvent] private void OnDoAfter(Entity 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; } }