diff --git a/Content.Server/Botany/Components/PlantHolderComponent.cs b/Content.Server/Botany/Components/PlantHolderComponent.cs
index 3eb4d76015..e5083e3ae0 100644
--- a/Content.Server/Botany/Components/PlantHolderComponent.cs
+++ b/Content.Server/Botany/Components/PlantHolderComponent.cs
@@ -87,7 +87,7 @@ namespace Content.Server.Botany.Components
public float WeedCoefficient { get; set; } = 1f;
[ViewVariables(VVAccess.ReadWrite)]
- public SeedPrototype? Seed { get; set; }
+ public SeedData? Seed { get; set; }
[ViewVariables(VVAccess.ReadWrite)]
public bool ImproperHeat { get; set; }
@@ -613,15 +613,14 @@ namespace Content.Server.Botany.Components
appearanceComponent.SetData(PlantHolderVisuals.HarvestLight, Harvest);
}
- public void CheckForDivergence(bool modified)
+ ///
+ /// Check if the currently contained seed is unique. If it is not, clone it so that we have a unique seed.
+ /// Necessary to avoid modifying global seeds.
+ ///
+ public void EnsureUniqueSeed()
{
- // Make sure we're not modifying a "global" seed.
- // If this seed is not in the global seed list, then no products of this line have been harvested yet.
- // It is then safe to assume it's restricted to this tray.
- if (Seed == null) return;
- var plantSystem = EntitySystem.Get();
- if (plantSystem.Seeds.ContainsKey(Seed.Uid))
- Seed = Seed.Diverge(modified);
+ if (Seed != null && !Seed.Unique)
+ Seed = Seed.Clone();
}
public void ForceUpdateByExternalCause()
diff --git a/Content.Server/Botany/Components/ProduceComponent.cs b/Content.Server/Botany/Components/ProduceComponent.cs
index b926429b6f..c81c7d1046 100644
--- a/Content.Server/Botany/Components/ProduceComponent.cs
+++ b/Content.Server/Botany/Components/ProduceComponent.cs
@@ -1,7 +1,5 @@
using Content.Server.Botany.Systems;
-using Robust.Shared.Analyzers;
-using Robust.Shared.GameObjects;
-using Robust.Shared.Serialization.Manager.Attributes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Botany.Components;
@@ -11,5 +9,15 @@ public sealed class ProduceComponent : Component
{
[DataField("targetSolution")] public string SolutionName { get; set; } = "food";
- [DataField("seed", required: true)] public string SeedName = default!;
+ ///
+ /// Seed data used to create a when this produce has its seeds extracted.
+ ///
+ [DataField("seed")]
+ public SeedData? Seed;
+
+ ///
+ /// Seed data used to create a when this produce has its seeds extracted.
+ ///
+ [DataField("seedId", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public readonly string? SeedId;
}
diff --git a/Content.Server/Botany/Components/SeedComponent.cs b/Content.Server/Botany/Components/SeedComponent.cs
index 0dab08a280..d61b828907 100644
--- a/Content.Server/Botany/Components/SeedComponent.cs
+++ b/Content.Server/Botany/Components/SeedComponent.cs
@@ -1,7 +1,4 @@
using Content.Server.Botany.Systems;
-using Robust.Shared.Analyzers;
-using Robust.Shared.GameObjects;
-using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Botany.Components
@@ -9,7 +6,18 @@ namespace Content.Server.Botany.Components
[RegisterComponent, Friend(typeof(BotanySystem))]
public sealed class SeedComponent : Component
{
- [DataField("seed", required: true, customTypeSerializer:typeof(PrototypeIdSerializer))]
- public string SeedName = default!;
+ ///
+ /// Seed data containing information about the plant type & properties that this seed can grow seed. If
+ /// null, will instead attempt to get data from a seed prototype, if one is defined. See .
+ ///
+ [DataField("seed")]
+ public SeedData? Seed;
+
+ ///
+ /// Name of a base seed prototype that is used if is null.
+ ///
+ [DataField("seedId", customTypeSerializer:typeof(PrototypeIdSerializer))]
+ public readonly string? SeedId;
}
}
diff --git a/Content.Server/Botany/SeedPrototype.cs b/Content.Server/Botany/SeedPrototype.cs
index ee45530925..72297fc060 100644
--- a/Content.Server/Botany/SeedPrototype.cs
+++ b/Content.Server/Botany/SeedPrototype.cs
@@ -1,25 +1,21 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
using Content.Server.Botany.Components;
using Content.Server.Botany.Systems;
using Content.Shared.Atmos;
-using Content.Shared.Popups;
-using Content.Shared.Random.Helpers;
-using Content.Shared.Tag;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Localization;
-using Robust.Shared.Map;
-using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
-using Robust.Shared.Random;
-using Robust.Shared.Serialization.Manager.Attributes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Robust.Shared.Utility;
namespace Content.Server.Botany;
+
+
+[Prototype("seed")]
+public sealed class SeedPrototype : SeedData, IPrototype
+{
+ [IdDataField] public string ID { get; private init; } = default!;
+}
+
public enum HarvestType : byte
{
NoRepeat,
@@ -65,33 +61,53 @@ public struct SeedChemQuantity
[DataField("PotencyDivisor")] public int PotencyDivisor;
}
-[Prototype("seed")]
-public sealed class SeedPrototype : IPrototype
+// TODO reduce the number of friends to a reasonable level. Requires ECS-ing things like plant holder component.
+[Virtual, DataDefinition]
+[Friend(typeof(BotanySystem), typeof(PlantHolderSystem), typeof(SeedExtractorSystem), typeof(PlantHolderComponent))]
+public class SeedData
{
- public const string Prototype = "SeedBase";
-
- [IdDataFieldAttribute] public string ID { get; private init; } = default!;
+ #region Tracking
+ ///
+ /// The name of this seed. Determines the name of seed packets.
+ ///
+ [DataField("name")] public string Name = string.Empty;
///
- /// Unique identifier of this seed. Do NOT set this.
+ /// The noun for this type of seeds. E.g. for fungi this should probably be "spores" instead of "seeds". Also
+ /// used to determine the name of seed packets.
///
- public int Uid { get; internal set; } = -1;
+ [DataField("noun")] public string Noun = "seeds";
- #region Tracking
-
- [DataField("name")] public string Name = string.Empty;
- [DataField("seedName")] public string SeedName = string.Empty;
- [DataField("seedNoun")] public string SeedNoun = "seeds";
+ ///
+ /// Name displayed when examining the hydroponics tray. Describes the actual plant, not the seed itself.
+ ///
[DataField("displayName")] public string DisplayName = string.Empty;
- [DataField("roundStart")] public bool RoundStart = true;
[DataField("mysterious")] public bool Mysterious;
+
+ ///
+ /// If true, the properties of this seed cannot be modified.
+ ///
[DataField("immutable")] public bool Immutable;
+ ///
+ /// If true, there is only a single reference to this seed and it's properties can be directly modified without
+ /// needing to clone the seed.
+ ///
+ [ViewVariables]
+ public bool Unique = false; // seed-prototypes or yaml-defined seeds for entity prototypes will not generally be unique.
#endregion
#region Output
+ ///
+ /// The entity prototype that is spawned when this type of seed is extracted from produce using a seed extractor.
+ ///
+ [DataField("packetPrototype", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string PacketPrototype = "SeedBase";
+ ///
+ /// The entity prototype this seed spawns when it gets harvested.
+ ///
[DataField("productPrototypes", customTypeSerializer: typeof(PrototypeIdListSerializer))]
public List ProductPrototypes = new();
@@ -137,7 +153,13 @@ public sealed class SeedPrototype : IPrototype
[DataField("potency")] public float Potency = 1f;
+ ///
+ /// If true, a sharp tool is required to harvest this plant.
+ ///
+ [DataField("ligneous")] public bool Ligneous;
+
// No, I'm not removing these.
+ // if you re-add these, make sure that they get cloned.
//public PlantSpread Spread { get; set; }
//public PlantMutation Mutation { get; set; }
//public float AlterTemperature { get; set; }
@@ -146,8 +168,6 @@ public sealed class SeedPrototype : IPrototype
//public bool Hematophage { get; set; }
//public bool Thorny { get; set; }
//public bool Stinging { get; set; }
-
- [DataField("ligneous")] public bool Ligneous;
// public bool Teleporting { get; set; }
// public PlantJuicy Juicy { get; set; }
@@ -168,17 +188,18 @@ public sealed class SeedPrototype : IPrototype
#endregion
- public SeedPrototype Clone()
+ public SeedData Clone()
{
- var newSeed = new SeedPrototype
+ DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed.");
+
+ var newSeed = new SeedData
{
- ID = ID,
Name = Name,
- SeedName = SeedName,
- SeedNoun = SeedNoun,
- RoundStart = RoundStart,
+ Noun = Noun,
+ DisplayName = DisplayName,
Mysterious = Mysterious,
+ PacketPrototype = PacketPrototype,
ProductPrototypes = new List(ProductPrototypes),
Chemicals = new Dictionary(Chemicals),
ConsumeGasses = new Dictionary(ConsumeGasses),
@@ -209,14 +230,14 @@ public sealed class SeedPrototype : IPrototype
PlantIconState = PlantIconState,
Bioluminescent = Bioluminescent,
BioluminescentColor = BioluminescentColor,
- SplatPrototype = SplatPrototype
+ SplatPrototype = SplatPrototype,
+
+ Ligneous = Ligneous,
+
+ // Newly cloned seed is unique. No need to unnecessarily clone if repeatedly modified.
+ Unique = true,
};
return newSeed;
}
-
- public SeedPrototype Diverge(bool modified)
- {
- return Clone();
- }
}
diff --git a/Content.Server/Botany/Systems/BotanySystem.Plant.cs b/Content.Server/Botany/Systems/BotanySystem.Plant.cs
index 67f9aa66cf..9fd6c400b5 100644
--- a/Content.Server/Botany/Systems/BotanySystem.Plant.cs
+++ b/Content.Server/Botany/Systems/BotanySystem.Plant.cs
@@ -1,12 +1,8 @@
-using System.Collections.Generic;
using Content.Server.Botany.Components;
using Content.Server.Chemistry.EntitySystems;
using Content.Server.Popups;
using Content.Shared.GameTicking;
-using Content.Shared.Tag;
using JetBrains.Annotations;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
@@ -20,49 +16,13 @@ namespace Content.Server.Botany.Systems
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
- private int _nextUid = 0;
private float _timer = 0f;
- public readonly Dictionary Seeds = new();
-
public override void Initialize()
{
base.Initialize();
- SubscribeLocalEvent(Reset);
-
InitializeSeeds();
-
- PopulateDatabase();
- }
-
- private void PopulateDatabase()
- {
- _nextUid = 0;
-
- Seeds.Clear();
-
- foreach (var seed in _prototypeManager.EnumeratePrototypes())
- {
- seed.Uid = GetNextSeedUid();
- Seeds[seed.Uid] = seed;
- }
- }
-
- public bool AddSeedToDatabase(SeedPrototype seed)
- {
- // If it's not -1, it's already in the database. Probably.
- if (seed.Uid != -1)
- return false;
-
- seed.Uid = GetNextSeedUid();
- Seeds[seed.Uid] = seed;
- return true;
- }
-
- private int GetNextSeedUid()
- {
- return _nextUid++;
}
public override void Update(float frameTime)
@@ -80,10 +40,5 @@ namespace Content.Server.Botany.Systems
plantHolder.Update();
}
}
-
- public void Reset(RoundRestartCleanupEvent ev)
- {
- PopulateDatabase();
- }
}
}
diff --git a/Content.Server/Botany/Systems/BotanySystem.Produce.cs b/Content.Server/Botany/Systems/BotanySystem.Produce.cs
index fbd06e1afb..552b60a3fb 100644
--- a/Content.Server/Botany/Systems/BotanySystem.Produce.cs
+++ b/Content.Server/Botany/Systems/BotanySystem.Produce.cs
@@ -1,8 +1,6 @@
-using Content.Server.Botany.Components;
+using Content.Server.Botany.Components;
using Content.Shared.FixedPoint;
using Robust.Server.GameObjects;
-using Robust.Shared.GameObjects;
-using Robust.Shared.Maths;
namespace Content.Server.Botany.Systems;
@@ -10,7 +8,7 @@ public sealed partial class BotanySystem
{
public void ProduceGrown(EntityUid uid, ProduceComponent produce)
{
- if (!_prototypeManager.TryIndex(produce.SeedName, out var seed))
+ if (!TryGetSeed(produce, out var seed))
return;
if (TryComp(uid, out SpriteComponent? sprite))
diff --git a/Content.Server/Botany/Systems/BotanySystem.Seed.cs b/Content.Server/Botany/Systems/BotanySystem.Seed.cs
index 21d55bb661..279ec2b34f 100644
--- a/Content.Server/Botany/Systems/BotanySystem.Seed.cs
+++ b/Content.Server/Botany/Systems/BotanySystem.Seed.cs
@@ -1,5 +1,6 @@
-using System;
+using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Botany.Components;
using Content.Server.Kitchen.Components;
@@ -26,35 +27,64 @@ public sealed partial class BotanySystem
SubscribeLocalEvent(OnExamined);
}
+ public bool TryGetSeed(SeedComponent comp, [NotNullWhen(true)] out SeedData? seed)
+ {
+ if (comp.Seed != null)
+ {
+ seed = comp.Seed;
+ return true;
+ }
+
+ if (comp.SeedId != null
+ && _prototypeManager.TryIndex(comp.SeedId, out SeedPrototype? protoSeed))
+ {
+ seed = protoSeed;
+ return true;
+ }
+
+ seed = null;
+ return false;
+ }
+
+ public bool TryGetSeed(ProduceComponent comp, [NotNullWhen(true)] out SeedData? seed)
+ {
+ if (comp.Seed != null)
+ {
+ seed = comp.Seed;
+ return true;
+ }
+
+ if (comp.SeedId != null
+ && _prototypeManager.TryIndex(comp.SeedId, out SeedPrototype? protoSeed))
+ {
+ seed = protoSeed;
+ return true;
+ }
+
+ seed = null;
+ return false;
+ }
+
private void OnExamined(EntityUid uid, SeedComponent component, ExaminedEvent args)
{
if (!args.IsInDetailsRange)
return;
- if (!_prototypeManager.TryIndex(component.SeedName, out var seed))
+ if (!TryGetSeed(component, out var seed))
return;
args.PushMarkup(Loc.GetString($"seed-component-description", ("seedName", seed.DisplayName)));
-
- if (!seed.RoundStart)
- {
- args.PushMarkup(Loc.GetString($"seed-component-has-variety-tag", ("seedUid", seed.Uid)));
- }
- else
- {
- args.PushMarkup(Loc.GetString($"seed-component-plant-yield-text", ("seedYield", seed.Yield)));
- args.PushMarkup(Loc.GetString($"seed-component-plant-potency-text", ("seedPotency", seed.Potency)));
- }
+ args.PushMarkup(Loc.GetString($"seed-component-plant-yield-text", ("seedYield", seed.Yield)));
+ args.PushMarkup(Loc.GetString($"seed-component-plant-potency-text", ("seedPotency", seed.Potency)));
}
#region SeedPrototype prototype stuff
- public EntityUid SpawnSeedPacket(SeedPrototype proto, EntityCoordinates transformCoordinates)
+ public EntityUid SpawnSeedPacket(SeedData proto, EntityCoordinates transformCoordinates)
{
- var seed = Spawn(SeedPrototype.Prototype, transformCoordinates);
-
+ var seed = Spawn(proto.PacketPrototype, transformCoordinates);
var seedComp = EnsureComp(seed);
- seedComp.SeedName = proto.ID;
+ seedComp.Seed = proto;
if (TryComp(seed, out SpriteComponent? sprite))
{
@@ -63,13 +93,13 @@ public sealed partial class BotanySystem
sprite.LayerSetSprite(0, new SpriteSpecifier.Rsi(proto.PlantRsi, "seed"));
}
- string val = Loc.GetString("botany-seed-packet-name", ("seedName", proto.SeedName), ("seedNoun", proto.SeedNoun));
+ string val = Loc.GetString("botany-seed-packet-name", ("seedName", proto.Name), ("seedNoun", proto.Noun));
MetaData(seed).EntityName = val;
return seed;
}
- public IEnumerable AutoHarvest(SeedPrototype proto, EntityCoordinates position, int yieldMod = 1)
+ public IEnumerable AutoHarvest(SeedData proto, EntityCoordinates position, int yieldMod = 1)
{
if (position.IsValid(EntityManager) &&
proto.ProductPrototypes.Count > 0)
@@ -78,10 +108,8 @@ public sealed partial class BotanySystem
return Enumerable.Empty();
}
- public IEnumerable Harvest(SeedPrototype proto, EntityUid user, int yieldMod = 1)
+ public IEnumerable Harvest(SeedData proto, EntityUid user, int yieldMod = 1)
{
- if (AddSeedToDatabase(proto)) proto.Name = proto.Uid.ToString();
-
if (proto.ProductPrototypes.Count == 0 || proto.Yield <= 0)
{
_popupSystem.PopupCursor(Loc.GetString("botany-harvest-fail-message"),
@@ -94,16 +122,13 @@ public sealed partial class BotanySystem
return GenerateProduct(proto, Transform(user).Coordinates, yieldMod);
}
- public IEnumerable GenerateProduct(SeedPrototype proto, EntityCoordinates position, int yieldMod = 1)
+ public IEnumerable GenerateProduct(SeedData proto, EntityCoordinates position, int yieldMod = 1)
{
var totalYield = 0;
if (proto.Yield > -1)
{
if (yieldMod < 0)
- {
- yieldMod = 1;
totalYield = proto.Yield;
- }
else
totalYield = proto.Yield * yieldMod;
@@ -112,6 +137,9 @@ public sealed partial class BotanySystem
var products = new List();
+ if (totalYield > 1 || proto.HarvestRepeat != HarvestType.NoRepeat)
+ proto.Unique = false;
+
for (var i = 0; i < totalYield; i++)
{
var product = _robustRandom.Pick(proto.ProductPrototypes);
@@ -122,7 +150,7 @@ public sealed partial class BotanySystem
var produce = EnsureComp(entity);
- produce.SeedName = proto.ID;
+ produce.Seed = proto;
ProduceGrown(entity, produce);
if (TryComp(entity, out var appearance))
@@ -141,7 +169,7 @@ public sealed partial class BotanySystem
return products;
}
- public bool CanHarvest(SeedPrototype proto, EntityUid? held = null)
+ public bool CanHarvest(SeedData proto, EntityUid? held = null)
{
return !proto.Ligneous || proto.Ligneous && held != null && HasComp(held);
}
diff --git a/Content.Server/Botany/Systems/PlantHolderSystem.cs b/Content.Server/Botany/Systems/PlantHolderSystem.cs
index c02b9c7c81..af79a31683 100644
--- a/Content.Server/Botany/Systems/PlantHolderSystem.cs
+++ b/Content.Server/Botany/Systems/PlantHolderSystem.cs
@@ -98,12 +98,12 @@ namespace Content.Server.Botany.Systems
{
if (component.Seed == null)
{
- if (!_prototypeManager.TryIndex(seeds.SeedName, out var seed))
- return;
-
+ if (!_botanySystem.TryGetSeed(seeds, out var seed))
+ return ;
+
_popupSystem.PopupCursor(Loc.GetString("plant-holder-component-plant-success-message",
- ("seedName", seed.SeedName),
- ("seedNoun", seed.SeedNoun)), Filter.Entities(args.User));
+ ("seedName", seed.Name),
+ ("seedNoun", seed.Noun)), Filter.Entities(args.User));
component.Seed = seed;
component.Dead = false;
@@ -215,6 +215,7 @@ namespace Content.Server.Botany.Systems
return;
}
+ component.Seed.Unique = false;
var seed = _botanySystem.SpawnSeedPacket(component.Seed, Transform(args.User).Coordinates);
seed.RandomOffset(0.25f);
_popupSystem.PopupCursor(Loc.GetString("plant-holder-component-take-sample-message",
diff --git a/Content.Server/Botany/Systems/SeedExtractorSystem.cs b/Content.Server/Botany/Systems/SeedExtractorSystem.cs
index 16c9d40972..9e427884a1 100644
--- a/Content.Server/Botany/Systems/SeedExtractorSystem.cs
+++ b/Content.Server/Botany/Systems/SeedExtractorSystem.cs
@@ -1,4 +1,4 @@
-using Content.Server.Botany.Components;
+using Content.Server.Botany.Components;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Shared.Interaction;
@@ -14,7 +14,6 @@ namespace Content.Server.Botany.Systems;
public sealed class SeedExtractorSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly BotanySystem _botanySystem = default!;
@@ -32,7 +31,7 @@ public sealed class SeedExtractorSystem : EntitySystem
if (TryComp(args.Used, out ProduceComponent? produce))
{
- if (!_prototypeManager.TryIndex(produce.SeedName, out var seed))
+ if (!_botanySystem.TryGetSeed(produce, out var seed))
return;
_popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message",("name", args.Used)),
@@ -43,6 +42,9 @@ public sealed class SeedExtractorSystem : EntitySystem
var random = _random.Next(component.MinSeeds, component.MaxSeeds);
var coords = Transform(uid).Coordinates;
+ if (random > 1)
+ seed.Unique = false;
+
for (var i = 0; i < random; i++)
{
_botanySystem.SpawnSeedPacket(seed, coords);
diff --git a/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/PlantDiethylamine.cs b/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/PlantDiethylamine.cs
index e447f8fc3b..4cf01b63df 100644
--- a/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/PlantDiethylamine.cs
+++ b/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/PlantDiethylamine.cs
@@ -20,13 +20,13 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
if (random.Prob(0.1f))
{
- plantHolderComp.CheckForDivergence(true);
+ plantHolderComp.EnsureUniqueSeed();
plantHolderComp.Seed.Lifespan++;
}
if (random.Prob(0.1f))
{
- plantHolderComp.CheckForDivergence(true);
+ plantHolderComp.EnsureUniqueSeed();
plantHolderComp.Seed.Endurance++;
}
}
diff --git a/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/RobustHarvest.cs b/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/RobustHarvest.cs
index e5e4993bce..26accde182 100644
--- a/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/RobustHarvest.cs
+++ b/Content.Server/Chemistry/ReagentEffects/PlantMetabolism/RobustHarvest.cs
@@ -20,13 +20,13 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
if (plantHolderComp.Seed.Potency < 100 && random.Prob(0.1f))
{
- plantHolderComp.CheckForDivergence(true);
+ plantHolderComp.EnsureUniqueSeed();
plantHolderComp.Seed.Potency++;
}
if (plantHolderComp.Seed.Yield > 1 && random.Prob(0.1f))
{
- plantHolderComp.CheckForDivergence(true);
+ plantHolderComp.EnsureUniqueSeed();
plantHolderComp.Seed.Yield--;
}
}
diff --git a/Content.Server/Kitchen/Components/SharpComponent.cs b/Content.Server/Kitchen/Components/SharpComponent.cs
index e79e2d2ee0..abe9d3074d 100644
--- a/Content.Server/Kitchen/Components/SharpComponent.cs
+++ b/Content.Server/Kitchen/Components/SharpComponent.cs
@@ -1,4 +1,4 @@
-namespace Content.Server.Kitchen.Components;
+namespace Content.Server.Kitchen.Components;
///
/// Applies to items that are capable of butchering entities, or
@@ -7,6 +7,7 @@
[RegisterComponent]
public sealed class SharpComponent : Component
{
+ // TODO just make this a tool type.
public HashSet Butchering = new();
[DataField("butcherDelayModifier")]
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml
index e7cf0dd543..532b22403f 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml
@@ -49,7 +49,7 @@
- ReagentId: Flour
Quantity: 10
- type: Produce
- seed: wheat
+ seedId: wheat
- type: entity
name: oat bushel
@@ -66,7 +66,7 @@
- ReagentId: Oats
Quantity: 10
- type: Produce
- seed: oat
+ seedId: oat
- type: Extractable
juiceSolution:
reagents:
@@ -88,7 +88,7 @@
- ReagentId: Glucose
Quantity: 10
- type: Produce
- seed: sugarcane
+ seedId: sugarcane
- type: entity
name: tower-cap log
@@ -104,7 +104,7 @@
types:
Blunt: 10
- type: Produce
- seed: towercap
+ seedId: towercap
- type: Log
- type: entity
@@ -130,7 +130,7 @@
- ReagentId: Histamine
Quantity: 25
- type: Produce
- seed: nettle
+ seedId: nettle
- type: MeleeChemicalInjector
transferAmount: 6 #To OD someone you would need 2 nettles and about 6-7 hits, the DOT is likely to crit them if they are running away with almost no health
- type: Extractable
@@ -158,7 +158,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/banana.rsi
- type: Produce
- seed: banana
+ seedId: banana
- type: Extractable
juiceSolution:
reagents:
@@ -233,7 +233,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/carrot.rsi
- type: Produce
- seed: carrots
+ seedId: carrots
- type: Extractable
juiceSolution:
reagents:
@@ -258,7 +258,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/lemon.rsi
- type: Produce
- seed: lemon
+ seedId: lemon
- type: Extractable
juiceSolution:
reagents:
@@ -285,7 +285,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/pineapple.rsi
- type: Produce
- seed: pineapple
+ seedId: pineapple
- type: Extractable
juiceSolution:
reagents:
@@ -313,7 +313,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/potato.rsi
- type: Produce
- seed: potato
+ seedId: potato
- type: Extractable
juiceSolution:
reagents:
@@ -338,7 +338,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/tomato.rsi
- type: Produce
- seed: tomato
+ seedId: tomato
- type: Extractable
grindableSolutionName: food
juiceSolution:
@@ -419,7 +419,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/eggplant.rsi
- type: Produce
- seed: eggplant
+ seedId: eggplant
- type: entity
name: apple
@@ -439,7 +439,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/apple.rsi
- type: Produce
- seed: apple
+ seedId: apple
- type: Extractable
juiceSolution:
reagents:
@@ -466,7 +466,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/corn.rsi
- type: Produce
- seed: corn
+ seedId: corn
- type: Extractable
juiceSolution:
reagents:
@@ -506,7 +506,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/onion.rsi
- type: Produce
- seed: onion
+ seedId: onion
- type: SliceableFood
count: 5
slice: FoodOnionSlice
@@ -529,7 +529,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/onion_red.rsi
- type: Produce
- seed: onionred
+ seedId: onionred
- type: SliceableFood
count: 4
slice: FoodOnionRedSlice
@@ -549,7 +549,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/chanterelle.rsi
- type: Produce
- seed: chanterelle
+ seedId: chanterelle
# Slices
@@ -623,7 +623,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/chili.rsi
- type: Produce
- seed: chili
+ seedId: chili
- type: entity
name: aloe
@@ -643,7 +643,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/aloe.rsi
- type: Produce
- seed: aloe
+ seedId: aloe
- type: Extractable
grindableSolutionName: food
@@ -665,7 +665,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/poppy.rsi
- type: Produce
- seed: poppy
+ seedId: poppy
- type: Extractable
grindableSolutionName: food
@@ -687,7 +687,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/lingzhi.rsi
- type: Produce
- seed: lingzhi
+ seedId: lingzhi
- type: Extractable
grindableSolutionName: food
@@ -715,7 +715,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/ambrosia_vulgaris.rsi
- type: Produce
- seed: ambrosiaVulgaris
+ seedId: ambrosiaVulgaris
- type: Extractable
grindableSolutionName: food
- type: Clothing
@@ -739,7 +739,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/galaxythistle.rsi
- type: Produce
- seed: galaxythistle
+ seedId: galaxythistle
- type: Extractable
grindableSolutionName: food
@@ -761,7 +761,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/fly_amanita.rsi
- type: Produce
- seed: flyAmanita
+ seedId: flyAmanita
- type: Extractable
grindableSolutionName: food
@@ -783,6 +783,6 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/gatfruit.rsi
- type: Produce
- seed: gatfruit
+ seedId: gatfruit
- type: Food
trash: RevolverPredator
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml
index 261ff15106..7a006081bb 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml
@@ -9,7 +9,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/cannabis.rsi
- type: Produce
- seed: cannabis
+ seedId: cannabis
- type: Food
- type: SolutionContainerManager
solutions:
@@ -71,7 +71,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/tobacco.rsi
- type: Produce
- seed: tobacco
+ seedId: tobacco
- type: entity
name: dried tobacco leaves
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml
index 48f2f4e32e..271a4f6c88 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml
@@ -17,7 +17,7 @@
id: WheatSeeds
components:
- type: Seed
- seed: wheat
+ seedId: wheat
- type: Sprite
sprite: Objects/Specific/Hydroponics/wheat.rsi
@@ -27,7 +27,7 @@
id: OatSeeds
components:
- type: Seed
- seed: oat
+ seedId: oat
- type: Sprite
sprite: Objects/Specific/Hydroponics/oat.rsi
@@ -37,7 +37,7 @@
id: BananaSeeds
components:
- type: Seed
- seed: banana
+ seedId: banana
- type: Sprite
sprite: Objects/Specific/Hydroponics/banana.rsi
@@ -47,7 +47,7 @@
id: CarrotSeeds
components:
- type: Seed
- seed: carrots
+ seedId: carrots
- type: Sprite
sprite: Objects/Specific/Hydroponics/carrot.rsi
@@ -57,7 +57,7 @@
id: LemonSeeds
components:
- type: Seed
- seed: lemon
+ seedId: lemon
- type: Sprite
sprite: Objects/Specific/Hydroponics/lemon.rsi
@@ -67,7 +67,7 @@
id: PineappleSeeds
components:
- type: Seed
- seed: pineapple
+ seedId: pineapple
- type: Sprite
sprite: Objects/Specific/Hydroponics/pineapple.rsi
@@ -77,7 +77,7 @@
id: PotatoSeeds
components:
- type: Seed
- seed: potato
+ seedId: potato
- type: Sprite
sprite: Objects/Specific/Hydroponics/potato.rsi
@@ -87,7 +87,7 @@
id: SugarcaneSeeds
components:
- type: Seed
- seed: sugarcane
+ seedId: sugarcane
- type: Sprite
sprite: Objects/Specific/Hydroponics/sugarcane.rsi
@@ -97,7 +97,7 @@
id: TowercapSeeds
components:
- type: Seed
- seed: towercap
+ seedId: towercap
- type: Sprite
sprite: Objects/Specific/Hydroponics/towercap.rsi
@@ -107,7 +107,7 @@
id: TomatoSeeds
components:
- type: Seed
- seed: tomato
+ seedId: tomato
- type: Sprite
sprite: Objects/Specific/Hydroponics/tomato.rsi
@@ -117,7 +117,7 @@
id: EggplantSeeds
components:
- type: Seed
- seed: eggplant
+ seedId: eggplant
- type: Sprite
sprite: Objects/Specific/Hydroponics/eggplant.rsi
@@ -127,7 +127,7 @@
id: AppleSeeds
components:
- type: Seed
- seed: apple
+ seedId: apple
- type: Sprite
sprite: Objects/Specific/Hydroponics/apple.rsi
@@ -137,7 +137,7 @@
id: CornSeeds
components:
- type: Seed
- seed: corn
+ seedId: corn
- type: Sprite
sprite: Objects/Specific/Hydroponics/corn.rsi
@@ -147,7 +147,7 @@
id: ChanterelleSeeds
components:
- type: Seed
- seed: chanterelle
+ seedId: chanterelle
- type: Sprite
sprite: Objects/Specific/Hydroponics/chanterelle.rsi
@@ -157,7 +157,7 @@
id: EggySeeds
components:
- type: Seed
- seed: eggy
+ seedId: eggy
- type: Sprite
sprite: Objects/Specific/Hydroponics/eggy.rsi
@@ -168,7 +168,7 @@
id: TobaccoSeeds
components:
- type: Seed
- seed: tobacco
+ seedId: tobacco
- type: Sprite
sprite: Objects/Specific/Hydroponics/tobacco.rsi
@@ -179,7 +179,7 @@
id: CannabisSeeds
components:
- type: Seed
- seed: cannabis
+ seedId: cannabis
- type: Sprite
sprite: Objects/Specific/Hydroponics/cannabis.rsi
@@ -190,7 +190,7 @@
id: NettleSeeds
components:
- type: Seed
- seed: nettle
+ seedId: nettle
- type: Sprite
sprite: Objects/Specific/Hydroponics/nettle.rsi
@@ -201,7 +201,7 @@
id: ChiliSeeds
components:
- type: Seed
- seed: chili
+ seedId: chili
- type: Sprite
sprite: Objects/Specific/Hydroponics/chili.rsi
@@ -212,7 +212,7 @@
id: AloeSeeds
components:
- type: Seed
- seed: aloe
+ seedId: aloe
- type: Sprite
sprite: Objects/Specific/Hydroponics/aloe.rsi
@@ -223,7 +223,7 @@
id: PoppySeeds
components:
- type: Seed
- seed: poppy
+ seedId: poppy
- type: Sprite
sprite: Objects/Specific/Hydroponics/poppy.rsi
@@ -234,7 +234,7 @@
id: LingzhiSeeds
components:
- type: Seed
- seed: lingzhi
+ seedId: lingzhi
- type: Sprite
sprite: Objects/Specific/Hydroponics/lingzhi.rsi
@@ -245,7 +245,7 @@
id: AmbrosiaVulgarisSeeds
components:
- type: Seed
- seed: ambrosiaVulgaris
+ seedId: ambrosiaVulgaris
- type: Sprite
sprite: Objects/Specific/Hydroponics/ambrosia_vulgaris.rsi
@@ -256,7 +256,7 @@
id: GalaxythistleSeeds
components:
- type: Seed
- seed: galaxythistle
+ seedId: galaxythistle
- type: Sprite
sprite: Objects/Specific/Hydroponics/galaxythistle.rsi
@@ -267,7 +267,7 @@
id: FlyAmanitaSeeds
components:
- type: Seed
- seed: flyAmanita
+ seedId: flyAmanita
- type: Sprite
sprite: Objects/Specific/Hydroponics/fly_amanita.rsi
@@ -278,7 +278,7 @@
id: GatfruitSeeds
components:
- type: Seed
- seed: gatfruit
+ seedId: gatfruit
- type: Sprite
sprite: Objects/Specific/Hydroponics/gatfruit.rsi
@@ -289,6 +289,6 @@
id: OnionSeeds
components:
- type: Seed
- seed: onion
+ seedId: onion
- type: Sprite
sprite: Objects/Specific/Hydroponics/onion.rsi
diff --git a/Resources/Prototypes/Hydroponics/seeds.yml b/Resources/Prototypes/Hydroponics/seeds.yml
index 4b7ce8d462..9a591aed3f 100644
--- a/Resources/Prototypes/Hydroponics/seeds.yml
+++ b/Resources/Prototypes/Hydroponics/seeds.yml
@@ -1,7 +1,6 @@
- type: seed
id: wheat
name: wheat
- seedName: wheat
displayName: wheat stalks
plantRsi: Objects/Specific/Hydroponics/wheat.rsi
productPrototypes:
@@ -26,7 +25,6 @@
- type: seed
id: oat
name: oat
- seedName: oat
displayName: oat stalks
plantRsi: Objects/Specific/Hydroponics/oat.rsi
productPrototypes:
@@ -51,7 +49,6 @@
- type: seed
id: banana
name: banana
- seedName: banana
displayName: banana plant
plantRsi: Objects/Specific/Hydroponics/banana.rsi
productPrototypes:
@@ -77,7 +74,6 @@
- type: seed
id: carrots
name: carrot
- seedName: carrot
displayName: carrots
plantRsi: Objects/Specific/Hydroponics/carrot.rsi
productPrototypes:
@@ -102,7 +98,6 @@
- type: seed
id: lemon
name: lemon
- seedName: lemon
displayName: lemon trees
plantRsi: Objects/Specific/Hydroponics/lemon.rsi
productPrototypes:
@@ -127,7 +122,6 @@
- type: seed
id: pineapple
name: pineapple
- seedName: pineapple
displayName: pineapple plant
plantRsi: Objects/Specific/Hydroponics/pineapple.rsi
productPrototypes:
@@ -157,7 +151,6 @@
- type: seed
id: potato
name: potato
- seedName: potato
displayName: potatoes
plantRsi: Objects/Specific/Hydroponics/potato.rsi
productPrototypes:
@@ -182,7 +175,6 @@
- type: seed
id: sugarcane
name: sugarcane
- seedName: sugarcane
displayName: sugarcanes
plantRsi: Objects/Specific/Hydroponics/sugarcane.rsi
productPrototypes:
@@ -203,8 +195,7 @@
- type: seed
id: towercap
- name: towercap
- seedName: tower cap
+ name: tower cap
displayName: tower caps
plantRsi: Objects/Specific/Hydroponics/towercap.rsi
productPrototypes:
@@ -223,7 +214,6 @@
- type: seed
id: tomato
name: tomato
- seedName: tomato
displayName: tomato plant
plantRsi: Objects/Specific/Hydroponics/tomato.rsi
productPrototypes:
@@ -253,7 +243,6 @@
- type: seed
id: eggplant
name: eggplant
- seedName: eggplant
displayName: eggplants
plantRsi: Objects/Specific/Hydroponics/eggplant.rsi
productPrototypes:
@@ -279,7 +268,6 @@
- type: seed
id: apple
name: apple
- seedName: apple
displayName: apple tree
plantRsi: Objects/Specific/Hydroponics/apple.rsi
productPrototypes:
@@ -304,7 +292,6 @@
- type: seed
id: corn
name: corn
- seedName: corn
displayName: ears of corn
plantRsi: Objects/Specific/Hydroponics/corn.rsi
productPrototypes:
@@ -331,7 +318,6 @@
- type: seed
id: onion
name: onion
- seedName: onion
displayName: onions
plantRsi: Objects/Specific/Hydroponics/onion.rsi
productPrototypes:
@@ -358,7 +344,6 @@
- type: seed
id: onionred
name: red onion
- seedName: red onion
displayName: red onions
plantRsi: Objects/Specific/Hydroponics/onion_red.rsi
productPrototypes:
@@ -385,8 +370,7 @@
- type: seed
id: chanterelle
name: chanterelle
- seedName: chanterelle
- seedNoun: spores
+ noun: spores
displayName: chanterelle mushrooms
plantRsi: Objects/Specific/Hydroponics/chanterelle.rsi
productPrototypes:
@@ -408,8 +392,7 @@
- type: seed
id: eggy
- name: eggy
- seedName: egg-plant
+ name: egg-plant
displayName: egg-plants
plantRsi: Objects/Specific/Hydroponics/eggy.rsi
productPrototypes:
@@ -431,7 +414,6 @@
- type: seed
id: cannabis
name: cannabis
- seedName: cannabis
displayName: cannabis
plantRsi: Objects/Specific/Hydroponics/cannabis.rsi
productPrototypes:
@@ -454,7 +436,6 @@
- type: seed
id: tobacco
name: tobacco
- seedName: tobacco
displayName: tobacco plant
plantRsi: Objects/Specific/Hydroponics/tobacco.rsi
productPrototypes:
@@ -477,7 +458,6 @@
- type: seed
id: nettle
name: nettle
- seedName: nettle
displayName: nettles
plantRsi: Objects/Specific/Hydroponics/nettle.rsi
productPrototypes:
@@ -500,7 +480,6 @@
- type: seed
id: chili
name: chili
- seedName: chili
displayName: chilis
plantRsi: Objects/Specific/Hydroponics/chili.rsi
productPrototypes:
@@ -530,7 +509,6 @@
- type: seed
id: poppy
name: poppy
- seedName: poppy
displayName: poppies
plantRsi: Objects/Specific/Hydroponics/poppy.rsi
productPrototypes:
@@ -555,7 +533,6 @@
- type: seed
id: aloe
name: aloe
- seedName: aloe
displayName: aloe
plantRsi: Objects/Specific/Hydroponics/aloe.rsi
productPrototypes:
@@ -580,7 +557,6 @@
- type: seed
id: lingzhi
name: lingzhi
- seedName: lingzhi
displayName: lingzhi
plantRsi: Objects/Specific/Hydroponics/lingzhi.rsi
productPrototypes:
@@ -605,7 +581,6 @@
- type: seed
id: ambrosiaVulgaris
name: ambrosia vulgaris
- seedName: ambrosiaVulgaris
displayName: ambrosia vulgaris
plantRsi: Objects/Specific/Hydroponics/ambrosia_vulgaris.rsi
productPrototypes:
@@ -642,7 +617,6 @@
- type: seed
id: galaxythistle
name: galaxythistle
- seedName: galaxythistle
displayName: galaxythistle
plantRsi: Objects/Specific/Hydroponics/galaxythistle.rsi
productPrototypes:
@@ -663,7 +637,6 @@
- type: seed
id: flyAmanita
name: fly amanita
- seedname: flyAmanita
displayName: fly amanita
plantRsi: Objects/Specific/Hydroponics/fly_amanita.rsi
productPrototypes:
@@ -688,7 +661,6 @@
- type: seed
id: gatfruit
name: gatfruit
- seedName: gatfruit
displayName: gatfruit tree
plantRsi: Objects/Specific/Hydroponics/gatfruit.rsi
productPrototypes: