mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-13 04:11:13 +03:00
* Restarting files from scratch * reduce file count, more progress * Additional partial work * update 1 * update 2 * TODO execution * fix * Update PlantGrowthComponent.cs * fix 1 * growth correction * PlantGrowthComponent * update 99 * last update * oops * Update vegan-meatball.yml * Data loss * ToxinsComponent * Default components * minor fix * PlantTraitsComponent * fix error * fix error 2 * Copy growth components * last update within this PR * AutoHarvestGrowth remote * Viable * fix * Fix growth rate * Improvements to the YAML * merge update * fix * code cleanup * TODO * fix * oops * oops 2 * more TODO * fix names * fix names oops * Harvest bug fixes * fix tests * refactor: cleanup after mering master * Update ConsumeExudeGasGrowthSystem.cs * refactor: make this piece of happiness and ponies work * review * oops * fix <summary> * Separation of plant components into PlantComponent and PlantTraitsComponent and cleaning * EnsureUniqueSeed * refactor: change Resolve to TryComp where appropriate * refactor: review comments - try get for components, clenaups * refactor: minor yaml cleanups * fixing trifles * botany-rework-part-3 * API and mutations * minor fixes * Update WeedPestGrowthSystem.cs * Update plants.yml * PlantChemicals * YAMLLinter * review and some lost code * YAMLLinter part 2 * plants.yml * Aaaa tests * seedId * clone plant component * Update clone.yml * refactor: remove suppress possible null reference exception * refactor: changed HasPlantAlive to TryGetAlivePlant, minor cleanup * Separation of tray and plant * oops * PlantingPlant * a little more cleaning * oops 2 * botany-rework-part-4 * predict and API * Field OldAgeDamage * oops * YMAL * YMAL 2 * YMAAAAAL * Update PlantToxinsSystem.cs * review * Update randomMutations.yml * minor fix design * Updates the plants visuals not every frame * bug fixes * some fixes * bugfix and renames * Dirty * Replace ComponentRegistry * unnecessary API * fix merge * build * build 2 * Review by AJCM * del PlantDataComponent and fix harvest * fix all * final review * Update PlantTrayVisualizerSystem.cs * fix merge * Update PlantTraitsComponent.cs * Traits LocId fix * Update SpawnEntitiesBehavior.cs * aaaaaaaaa * fix all part 2 * PlantDataComponent revert * aoao * fix all part 3 * Update PlantTraitsComponent.cs * Update clone.yml * Reviews --------- Co-authored-by: PraxisMapper <praxismapper@gmail.com> Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru> Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Co-authored-by: AJCM-git <ajcm_mail@disroot.org>
182 lines
7.1 KiB
C#
182 lines
7.1 KiB
C#
using JetBrains.Annotations;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using Content.Shared.Botany.Components;
|
|
using Content.Shared.Botany.Items.Components;
|
|
using Content.Shared.Chemistry.EntitySystems;
|
|
using Content.Shared.Cloning;
|
|
using Content.Shared.Examine;
|
|
using Content.Shared.Hands.EntitySystems;
|
|
using Content.Shared.Random;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Shared.Botany.Systems;
|
|
|
|
public sealed partial class BotanySystem : EntitySystem
|
|
{
|
|
[Dependency] private IComponentFactory _componentFactory = default!;
|
|
[Dependency] private IGameTiming _timing = default!;
|
|
[Dependency] private MetaDataSystem _metaData = default!;
|
|
[Dependency] private PlantSystem _plant = default!;
|
|
[Dependency] private RandomHelperSystem _randomHelper = default!;
|
|
[Dependency] private SharedAppearanceSystem _appearance = default!;
|
|
[Dependency] private SharedCloningSystem _cloning = default!;
|
|
[Dependency] private SharedHandsSystem _hands = default!;
|
|
[Dependency] private SharedSolutionContainerSystem _solutionContainer = default!;
|
|
[Dependency] private SharedTransformSystem _transform = default!;
|
|
|
|
public readonly ProtoId<CloningSettingsPrototype> SettingsId = "PlantClone";
|
|
public readonly ProtoId<CloningSettingsPrototype> LifecycleSettingsId = "PlantLifecycleClone";
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnExamined(Entity<SeedComponent> ent, ref ExaminedEvent args)
|
|
{
|
|
if (!args.IsInDetailsRange)
|
|
return;
|
|
|
|
if (!TryGetPlantComponent<PlantComponent>(ent.Comp.PlantData, ent.Comp.PlantProtoId, out var plant)
|
|
|| !TryGetPlantComponent<PlantDataComponent>(ent.Comp.PlantData, ent.Comp.PlantProtoId, out var plantData))
|
|
return;
|
|
|
|
using (args.PushGroup(nameof(SeedComponent), 1))
|
|
{
|
|
var name = Loc.GetString(plantData.Name);
|
|
args.PushMarkup(Loc.GetString("seed-component-description", ("seedName", name)));
|
|
args.PushMarkup(_plant.GetPlantStateMarkup(ent.Owner, plant));
|
|
}
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnSeedShutdown(Entity<SeedComponent> ent, ref ComponentShutdown args)
|
|
{
|
|
DeletePlantSnapshot(ent.Comp.PlantData);
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnProduceShutdown(Entity<ProduceComponent> ent, ref ComponentShutdown args)
|
|
{
|
|
DeletePlantSnapshot(ent.Comp.PlantData);
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnSwabShutdown(Entity<BotanySwabComponent> ent, ref ComponentShutdown args)
|
|
{
|
|
DeletePlantSnapshot(ent.Comp.PlantData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to get a plant component from a snapshot or prototype.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of component to get.</typeparam>
|
|
/// <param name="snapshot">The snapshot to get the component from.</param>
|
|
/// <param name="plantProtoId">The prototype ID to get the component from.</param>
|
|
/// <param name="plant">The plant component if found.</param>
|
|
[PublicAPI]
|
|
public bool TryGetPlantComponent<T>(EntityUid? snapshot, EntProtoId? plantProtoId, [NotNullWhen(true)] out T? plant)
|
|
where T : class, IComponent, new()
|
|
{
|
|
plant = null;
|
|
|
|
if (snapshot != null && TryComp(snapshot, out plant))
|
|
return true;
|
|
|
|
if (plantProtoId == null)
|
|
return false;
|
|
|
|
if (!ProtoMan.TryIndex(plantProtoId.Value, out var proto))
|
|
return false;
|
|
|
|
return proto.TryComp(out plant, _componentFactory);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clones a component snapshot of a plant.
|
|
/// </summary>
|
|
/// <param name="source">The entity to clone the snapshot from.</param>
|
|
/// <param name="parent">The entity that should own the snapshot, if any.</param>
|
|
/// <param name="cloneLifecycle">If true, also clone lifecycle state into the snapshot.</param>
|
|
[PublicAPI]
|
|
public EntityUid? ClonePlantSnapshotData(EntityUid source, EntityUid? parent = null, bool cloneLifecycle = false)
|
|
{
|
|
var settingsId = cloneLifecycle ? LifecycleSettingsId : SettingsId;
|
|
if (!ProtoMan.TryIndex(settingsId, out var settings))
|
|
return null;
|
|
|
|
var snapshot = EntityManager.CreateEntityUninitialized(null);
|
|
_cloning.CloneComponents(source, snapshot, settings);
|
|
EntityManager.InitializeAndStartEntity(snapshot, doMapInit: false);
|
|
|
|
if (parent is { } parentUid)
|
|
_transform.SetParent(snapshot, parentUid);
|
|
|
|
return snapshot;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes a stored plant snapshot, if one exists.
|
|
/// </summary>
|
|
[PublicAPI]
|
|
public void DeletePlantSnapshot(EntityUid? snapshot)
|
|
{
|
|
if (snapshot == null)
|
|
return;
|
|
|
|
PredictedQueueDel(snapshot.Value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies the component data stored in a plant snapshot to a target entity.
|
|
/// </summary>
|
|
/// <param name="snapshot">The snapshot entity to copy component data from.</param>
|
|
/// <param name="target">The entity to apply the snapshot data to.</param>
|
|
/// <param name="cloneLifecycle">If true, also copy lifecycle state.</param>
|
|
[PublicAPI]
|
|
public void ApplyPlantSnapshotData(EntityUid? snapshot, EntityUid target, bool cloneLifecycle = false)
|
|
{
|
|
if (snapshot == null)
|
|
return;
|
|
|
|
var settingsId = cloneLifecycle ? LifecycleSettingsId : SettingsId;
|
|
if (!ProtoMan.TryIndex(settingsId, out var settings))
|
|
return;
|
|
|
|
_cloning.CloneComponents(snapshot.Value, target, settings);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Internal method to spawn a seed packet from a plant component.
|
|
/// </summary>
|
|
/// <param name="plantData">The plant data component to spawn.</param>
|
|
/// <param name="plantProtoId">The plant prototype ID to store in the seed component.</param>
|
|
/// <param name="snapshot">The component snapshot to store in the seed component.</param>
|
|
/// <param name="coords">The coordinates to spawn the seed packet at.</param>
|
|
/// <param name="user">The user who is spawning the seed packet.</param>
|
|
/// <param name="healthOverride">The health override to store in the seed component.</param>
|
|
/// <returns>The spawned seed packet entity.</returns>
|
|
[PublicAPI]
|
|
public EntityUid SpawnSeedPacket(
|
|
PlantDataComponent plantData,
|
|
EntProtoId plantProtoId,
|
|
EntityUid? snapshot,
|
|
EntityCoordinates coords,
|
|
EntityUid user,
|
|
float? healthOverride = null)
|
|
{
|
|
var seedItem = PredictedSpawnAtPosition(plantData.PacketPrototype, coords);
|
|
var seedComp = EnsureComp<SeedComponent>(seedItem);
|
|
seedComp.PlantProtoId = plantProtoId;
|
|
seedComp.PlantData = snapshot.HasValue
|
|
? ClonePlantSnapshotData(snapshot.Value, parent: seedItem)
|
|
: null;
|
|
seedComp.HealthOverride = healthOverride;
|
|
Dirty(seedItem, seedComp);
|
|
|
|
var name = Loc.GetString(plantData.Name);
|
|
var noun = Loc.GetString(plantData.Noun);
|
|
_metaData.SetEntityName(seedItem, Loc.GetString("botany-seed-packet-name", ("seedName", name), ("seedNoun", noun)));
|
|
|
|
_hands.TryPickupAnyHand(user, seedItem);
|
|
return seedItem;
|
|
}
|
|
}
|