| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- using Content.Server.Botany.Components;
- using Content.Server.Botany.Systems;
- using Content.Shared.Atmos;
- using Content.Shared.EntityEffects;
- using Content.Shared.Random;
- using Robust.Shared.Audio;
- using Robust.Shared.Prototypes;
- 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]
- public sealed partial class SeedPrototype : SeedData, IPrototype
- {
- [IdDataField] public string ID { get; private set; } = default!;
- }
- public enum HarvestType : byte
- {
- NoRepeat,
- Repeat,
- SelfHarvest
- }
- /*
- public enum PlantSpread : byte
- {
- NoSpread,
- Creepers,
- Vines,
- }
- public enum PlantMutation : byte
- {
- NoMutation,
- Mutable,
- HighlyMutable,
- }
- public enum PlantCarnivorous : byte
- {
- NotCarnivorous,
- EatPests,
- EatLivingBeings,
- }
- public enum PlantJuicy : byte
- {
- NotJuicy,
- Juicy,
- Slippery,
- }
- */
- [DataDefinition]
- public partial struct SeedChemQuantity
- {
- /// <summary>
- /// Minimum amount of chemical that is added to produce, regardless of the potency
- /// </summary>
- [DataField("Min")] public int Min;
- /// <summary>
- /// Maximum amount of chemical that can be produced after taking plant potency into account.
- /// </summary>
- [DataField("Max")] public int Max;
- /// <summary>
- /// When chemicals are added to produce, the potency of the seed is divided with this value. Final chemical amount is the result plus the `Min` value.
- /// Example: PotencyDivisor of 20 with seed potency of 55 results in 2.75, 55/20 = 2.75. If minimum is 1 then final result will be 3.75 of that chemical, 55/20+1 = 3.75.
- /// </summary>
- [DataField("PotencyDivisor")] public int PotencyDivisor;
- /// <summary>
- /// Inherent chemical is one that is NOT result of mutation or crossbreeding. These chemicals are removed if species mutation is executed.
- /// </summary>
- [DataField("Inherent")] public bool Inherent = true;
- }
- // TODO reduce the number of friends to a reasonable level. Requires ECS-ing things like plant holder component.
- [Virtual, DataDefinition]
- [Access(typeof(BotanySystem), typeof(PlantHolderSystem), typeof(SeedExtractorSystem), typeof(PlantHolderComponent), typeof(EntityEffect), typeof(MutationSystem))]
- public partial class SeedData
- {
- #region Tracking
- /// <summary>
- /// The name of this seed. Determines the name of seed packets.
- /// </summary>
- [DataField("name")]
- public string Name { get; private set; } = "";
- /// <summary>
- /// 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.
- /// </summary>
- [DataField("noun")]
- public string Noun { get; private set; } = "";
- /// <summary>
- /// Name displayed when examining the hydroponics tray. Describes the actual plant, not the seed itself.
- /// </summary>
- [DataField("displayName")]
- public string DisplayName { get; private set; } = "";
- [DataField("mysterious")] public bool Mysterious;
- /// <summary>
- /// If true, the properties of this seed cannot be modified.
- /// </summary>
- [DataField("immutable")] public bool Immutable;
- /// <summary>
- /// 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.
- /// </summary>
- [ViewVariables]
- public bool Unique = false; // seed-prototypes or yaml-defined seeds for entity prototypes will not generally be unique.
- #endregion
- #region Output
- /// <summary>
- /// The entity prototype that is spawned when this type of seed is extracted from produce using a seed extractor.
- /// </summary>
- [DataField("packetPrototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
- public string PacketPrototype = "SeedBase";
- /// <summary>
- /// The entity prototype this seed spawns when it gets harvested.
- /// </summary>
- [DataField("productPrototypes", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
- public List<string> ProductPrototypes = new();
- [DataField] public Dictionary<string, SeedChemQuantity> Chemicals = new();
- [DataField] public Dictionary<Gas, float> ConsumeGasses = new();
- [DataField] public Dictionary<Gas, float> ExudeGasses = new();
- #endregion
- #region Tolerances
- [DataField] public float NutrientConsumption = 0.75f;
- [DataField] public float WaterConsumption = 0.5f;
- [DataField] public float IdealHeat = 293f;
- [DataField] public float HeatTolerance = 10f;
- [DataField] public float IdealLight = 7f;
- [DataField] public float LightTolerance = 3f;
- [DataField] public float ToxinsTolerance = 4f;
- [DataField] public float LowPressureTolerance = 81f;
- [DataField] public float HighPressureTolerance = 121f;
- [DataField] public float PestTolerance = 5f;
- [DataField] public float WeedTolerance = 5f;
- [DataField] public float WeedHighLevelThreshold = 10f;
- #endregion
- #region General traits
- [DataField] public float Endurance = 100f;
- [DataField] public int Yield;
- [DataField] public float Lifespan;
- [DataField] public float Maturation;
- [DataField] public float Production;
- [DataField] public int GrowthStages = 6;
- [DataField] public HarvestType HarvestRepeat = HarvestType.NoRepeat;
- [DataField] public float Potency = 1f;
- /// <summary>
- /// If true, cannot be harvested for seeds. Balances hybrids and
- /// mutations.
- /// </summary>
- [DataField] public bool Seedless = false;
- /// <summary>
- /// If false, rapidly decrease health while growing. Used to kill off
- /// plants with "bad" mutations.
- /// </summary>
- [DataField] public bool Viable = true;
- /// <summary>
- /// If true, a sharp tool is required to harvest this plant.
- /// </summary>
- [DataField] 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; }
- //public PlantCarnivorous Carnivorous { get; set; }
- //public bool Parasite { get; set; }
- //public bool Hematophage { get; set; }
- //public bool Thorny { get; set; }
- //public bool Stinging { get; set; }
- // public bool Teleporting { get; set; }
- // public PlantJuicy Juicy { get; set; }
- #endregion
- #region Cosmetics
- [DataField(required: true)]
- public ResPath PlantRsi { get; set; } = default!;
- [DataField] public string PlantIconState { get; set; } = "produce";
- /// <summary>
- /// Screams random sound from collection SoundCollectionSpecifier
- /// </summary>
- [DataField]
- public SoundSpecifier ScreamSound = new SoundCollectionSpecifier("PlantScreams", AudioParams.Default.WithVolume(-10));
- [DataField("screaming")] public bool CanScream;
- [DataField(customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] public string KudzuPrototype = "WeakKudzu";
- [DataField] public bool TurnIntoKudzu;
- [DataField] public string? SplatPrototype { get; set; }
- #endregion
- /// <summary>
- /// The mutation effects that have been applied to this plant.
- /// </summary>
- [DataField] public List<RandomPlantMutation> Mutations { get; set; } = new();
- /// <summary>
- /// The seed prototypes this seed may mutate into when prompted to.
- /// </summary>
- [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<SeedPrototype>))]
- public List<string> MutationPrototypes = new();
- public SeedData Clone()
- {
- DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed.");
- var newSeed = new SeedData
- {
- Name = Name,
- Noun = Noun,
- DisplayName = DisplayName,
- Mysterious = Mysterious,
- PacketPrototype = PacketPrototype,
- ProductPrototypes = new List<string>(ProductPrototypes),
- MutationPrototypes = new List<string>(MutationPrototypes),
- Chemicals = new Dictionary<string, SeedChemQuantity>(Chemicals),
- ConsumeGasses = new Dictionary<Gas, float>(ConsumeGasses),
- ExudeGasses = new Dictionary<Gas, float>(ExudeGasses),
- NutrientConsumption = NutrientConsumption,
- WaterConsumption = WaterConsumption,
- IdealHeat = IdealHeat,
- HeatTolerance = HeatTolerance,
- IdealLight = IdealLight,
- LightTolerance = LightTolerance,
- ToxinsTolerance = ToxinsTolerance,
- LowPressureTolerance = LowPressureTolerance,
- HighPressureTolerance = HighPressureTolerance,
- PestTolerance = PestTolerance,
- WeedTolerance = WeedTolerance,
- Endurance = Endurance,
- Yield = Yield,
- Lifespan = Lifespan,
- Maturation = Maturation,
- Production = Production,
- GrowthStages = GrowthStages,
- HarvestRepeat = HarvestRepeat,
- Potency = Potency,
- Seedless = Seedless,
- Viable = Viable,
- Ligneous = Ligneous,
- PlantRsi = PlantRsi,
- PlantIconState = PlantIconState,
- CanScream = CanScream,
- TurnIntoKudzu = TurnIntoKudzu,
- SplatPrototype = SplatPrototype,
- Mutations = new List<RandomPlantMutation>(),
- // Newly cloned seed is unique. No need to unnecessarily clone if repeatedly modified.
- Unique = true,
- };
- newSeed.Mutations.AddRange(Mutations);
- return newSeed;
- }
- /// <summary>
- /// Handles copying most species defining data from 'other' to this seed while keeping the accumulated mutations intact.
- /// </summary>
- public SeedData SpeciesChange(SeedData other)
- {
- var newSeed = new SeedData
- {
- Name = other.Name,
- Noun = other.Noun,
- DisplayName = other.DisplayName,
- Mysterious = other.Mysterious,
- PacketPrototype = other.PacketPrototype,
- ProductPrototypes = new List<string>(other.ProductPrototypes),
- MutationPrototypes = new List<string>(other.MutationPrototypes),
- Chemicals = new Dictionary<string, SeedChemQuantity>(Chemicals),
- ConsumeGasses = new Dictionary<Gas, float>(ConsumeGasses),
- ExudeGasses = new Dictionary<Gas, float>(ExudeGasses),
- NutrientConsumption = NutrientConsumption,
- WaterConsumption = WaterConsumption,
- IdealHeat = IdealHeat,
- HeatTolerance = HeatTolerance,
- IdealLight = IdealLight,
- LightTolerance = LightTolerance,
- ToxinsTolerance = ToxinsTolerance,
- LowPressureTolerance = LowPressureTolerance,
- HighPressureTolerance = HighPressureTolerance,
- PestTolerance = PestTolerance,
- WeedTolerance = WeedTolerance,
- Endurance = Endurance,
- Yield = Yield,
- Lifespan = Lifespan,
- Maturation = Maturation,
- Production = Production,
- GrowthStages = other.GrowthStages,
- HarvestRepeat = HarvestRepeat,
- Potency = Potency,
- Mutations = Mutations,
- Seedless = Seedless,
- Viable = Viable,
- Ligneous = Ligneous,
- PlantRsi = other.PlantRsi,
- PlantIconState = other.PlantIconState,
- CanScream = CanScream,
- TurnIntoKudzu = TurnIntoKudzu,
- SplatPrototype = other.SplatPrototype,
- // Newly cloned seed is unique. No need to unnecessarily clone if repeatedly modified.
- Unique = true,
- };
- // Adding the new chemicals from the new species.
- foreach (var otherChem in other.Chemicals)
- {
- newSeed.Chemicals.TryAdd(otherChem.Key, otherChem.Value);
- }
- // Removing the inherent chemicals from the old species. Leaving mutated/crossbread ones intact.
- foreach (var originalChem in newSeed.Chemicals)
- {
- if (!other.Chemicals.ContainsKey(originalChem.Key) && originalChem.Value.Inherent)
- {
- newSeed.Chemicals.Remove(originalChem.Key);
- }
- }
- return newSeed;
- }
- }
|