]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Carry over other mutations when doing species mutation (#20551)
authordrteaspoon420 <87363733+drteaspoon420@users.noreply.github.com>
Sun, 1 Oct 2023 17:52:45 +0000 (20:52 +0300)
committerGitHub <noreply@github.com>
Sun, 1 Oct 2023 17:52:45 +0000 (09:52 -0800)
Content.Server/Botany/SeedPrototype.cs
Content.Server/Botany/Systems/MutationSystem.cs

index 3d700f2775e99a840f304a8dbb0aaf5b563850ba..82d5b8de10b270cf34363500385b50befda10677 100644 (file)
@@ -56,9 +56,26 @@ public enum HarvestType : byte
 [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.
@@ -293,4 +310,82 @@ public partial class SeedData
 
         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,
+
+            Seedless = Seedless,
+            Viable = Viable,
+            Slip = Slip,
+            Sentient = Sentient,
+            Ligneous = Ligneous,
+
+            PlantRsi = other.PlantRsi,
+            PlantIconState = other.PlantIconState,
+            Bioluminescent = Bioluminescent,
+            CanScream = CanScream,
+            TurnIntoKudzu = TurnIntoKudzu,
+            BioluminescentColor = BioluminescentColor,
+            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)
+        {
+            Chemicals.TryAdd(otherChem.Key, otherChem.Value);
+        }
+
+        // Removing the inherent chemicals from the old species. Leaving mutated/crossbread ones intact.
+        foreach (var originalChem in Chemicals)
+        {
+            if (!other.Chemicals.ContainsKey(originalChem.Key) && originalChem.Value.Inherent)
+            {
+                Chemicals.Remove(originalChem.Key);
+            }
+        }
+
+        return newSeed;
+    }
 }
index 13ef8e37818c8ab34cd4a1f9340e63ee1c8a0b48..94a450ebeffb14ac754a8237e69c51d7b1b23d0f 100644 (file)
@@ -3,6 +3,7 @@ using Robust.Shared.Random;
 using Content.Shared.Chemistry.Reagent;
 using System.Linq;
 using Content.Shared.Atmos;
+using FastAccessors;
 
 namespace Content.Server.Botany;
 
@@ -269,6 +270,7 @@ public sealed class MutationSystem : EntitySystem
             {
                 seedChemQuantity.Min = 1;
                 seedChemQuantity.Max = 1 + amount;
+                seedChemQuantity.Inherent = false;
             }
             int potencyDivisor = (int) Math.Ceiling(100.0f / seedChemQuantity.Max);
             seedChemQuantity.PotencyDivisor = potencyDivisor;
@@ -295,10 +297,7 @@ public sealed class MutationSystem : EntitySystem
             return;
         }
 
-        var oldSeed = seed.Clone();
-        seed = protoSeed.Clone();
-        seed.Potency = oldSeed.Potency;
-        seed.Yield = oldSeed.Yield;
+        seed = seed.SpeciesChange(protoSeed);
     }
 
     private Color RandomColor(Color color, int bits, int totalbits, float mult)
@@ -330,12 +329,14 @@ public sealed class MutationSystem : EntitySystem
             {
                 val[otherChem.Key] = Random(0.5f) ? otherChem.Value : val[otherChem.Key];
             }
-            // if target plant doesn't have this chemical, has 50% chance to add it. 
+            // if target plant doesn't have this chemical, has 50% chance to add it.
             else
             {
                 if (Random(0.5f))
                 {
-                    val.Add(otherChem.Key, otherChem.Value);
+                    var fixedChem = otherChem.Value;
+                    fixedChem.Inherent = false;
+                    val.Add(otherChem.Key, fixedChem);
                 }
             }
         }