using Content.Shared.Botany.Components; using Content.Shared.Botany.Events; using Content.Shared.Botany.Items.Components; using Content.Shared.Botany.Systems; using Content.Shared.Botany.Traits.Components; using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Random.Helpers; using Robust.Shared.Random; using Robust.Shared.Timing; namespace Content.Shared.Botany.Items.Systems; /// /// System for taking a sample of a plant. /// public sealed partial class BotanySampleTakerSystem : EntitySystem { [Dependency] private BotanySystem _botany = default!; [Dependency] private IGameTiming _timing = default!; [Dependency] private PlantHolderSystem _plantHolder = default!; [Dependency] private PlantSystem _plant = default!; [Dependency] private SharedPopupSystem _popup = default!; [Dependency] private EntityQuery _holderQuery; [Dependency] private EntityQuery _dataQuery; [Dependency] private EntityQuery _plantQuery; [SubscribeLocalEvent] private void OnAfterInteract(Entity ent, ref AfterInteractEvent args) { if (args.Target == null || args.Handled || !args.CanReach || !_plantQuery.HasComp(args.Target)) return; var ev = new PlantSampleAttemptEvent(ent, args.User); RaiseLocalEvent(args.Target.Value, ref ev); args.Handled = true; } [SubscribeLocalEvent] private void OnPlantSampleAttempt(Entity ent, ref PlantSampleAttemptEvent args) { if (args.Cancelled) return; if (!_holderQuery.TryComp(ent.Owner, out var holder) || !_dataQuery.TryComp(ent.Owner, out var plantData)) return; if (_plantHolder.IsDead((ent.Owner, holder))) { _popup.PopupCursor(Loc.GetString("plant-sample-component-dead-plant-popup"), args.User); return; } // Prevent early sampling, unless the plant is fully grown. var growthStage = _plant.GetGrowthStageValue(ent.AsNullable()); if (growthStage < ent.Comp.GrowthStages && growthStage <= args.Sample.Comp.MinSampleStage) { _popup.PopupCursor(Loc.GetString("plant-sample-component-early-sample-popup"), args.User); return; } var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent)); // Damage the plant. _plantHolder.AdjustsHealth((ent.Owner, holder), -random.NextFloat(args.Sample.Comp.SampleDamage.Min, args.Sample.Comp.SampleDamage.Max)); // Produce a seed packet snapshot. float? healthOverride = holder.ReadyForHarvest ? null : holder.Health; var protoId = MetaData(ent.Owner).EntityPrototype!.ID; _botany.SpawnSeedPacket(plantData, protoId, ent.Owner, Transform(args.User).Coordinates, args.User, healthOverride); var name = Loc.GetString(plantData.Name); _popup.PopupCursor(Loc.GetString("plant-sample-component-take-sample-popup", ("seedName", name)), args.User); if (random.Prob(args.Sample.Comp.SampleProbability)) EnsureComp(ent.Owner); } }