]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
New botany mutations (#13646)
authorDuke <112821543+DukeVanity@users.noreply.github.com>
Mon, 6 Mar 2023 01:11:13 +0000 (04:11 +0300)
committerGitHub <noreply@github.com>
Mon, 6 Mar 2023 01:11:13 +0000 (21:11 -0400)
Content.Server/Botany/SeedPrototype.cs
Content.Server/Botany/Systems/BotanySystem.Produce.cs
Content.Server/Botany/Systems/MutationSystem.cs
Content.Server/Botany/Systems/PlantHolderSystem.cs
Resources/Prototypes/Entities/Objects/Misc/kudzu.yml

index b5c748b000c6ea44402d9fdf798652262cd7fb75..d47bc42f7e2fc59717aaee77113001c231cf779a 100644 (file)
@@ -1,4 +1,3 @@
-using System.ComponentModel;
 using Content.Server.Botany.Components;
 using Content.Server.Botany.Systems;
 using Content.Shared.Atmos;
@@ -7,11 +6,10 @@ 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;
+using Robust.Shared.Audio;
 
 namespace Content.Server.Botany;
 
-
-
 [Prototype("seed")]
 public sealed class SeedPrototype : SeedData, IPrototype
 {
@@ -144,6 +142,8 @@ public class SeedData
 
     [DataField("weedTolerance")] public float WeedTolerance = 5f;
 
+    [DataField("weedHighLevelThreshold")] public float WeedHighLevelThreshold = 10f;
+
     #endregion
 
     #region General traits
@@ -155,6 +155,8 @@ public class SeedData
     [DataField("maturation")] public float Maturation;
     [DataField("production")] public float Production;
     [DataField("growthStages")] public int GrowthStages = 6;
+
+    [ViewVariables(VVAccess.ReadWrite)]
     [DataField("harvestRepeat")] public HarvestType HarvestRepeat = HarvestType.NoRepeat;
 
     [DataField("potency")] public float Potency = 1f;
@@ -208,12 +210,20 @@ public class SeedData
 
     [DataField("plantIconState")] public string PlantIconState { get; set; } = "produce";
 
-    [DataField("bioluminescent")] public bool Bioluminescent;
+    [DataField("screamSound")]
+    public SoundSpecifier ScreamSound = new SoundPathSpecifier("/Audio/Voice/Human/malescream_1.ogg");
 
+
+    [DataField("screaming")] public bool CanScream;
+
+    [DataField("bioluminescent")] public bool Bioluminescent;
     [DataField("bioluminescentColor")] public Color BioluminescentColor { get; set; } = Color.White;
 
     public float BioluminescentRadius = 2f;
 
+    [DataField("kudzuPrototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] public string KudzuPrototype = "WeakKudzu";
+
+    [DataField("turnIntoKudzu")] public bool TurnIntoKudzu;
     [DataField("splatPrototype")] public string? SplatPrototype { get; set; }
 
     #endregion
@@ -265,6 +275,8 @@ public class SeedData
             PlantRsi = PlantRsi,
             PlantIconState = PlantIconState,
             Bioluminescent = Bioluminescent,
+            CanScream = CanScream,
+            TurnIntoKudzu = TurnIntoKudzu,
             BioluminescentColor = BioluminescentColor,
             SplatPrototype = SplatPrototype,
 
index bc9bfbad8bacbd1b0c05ae9884d7d6ae7c94a0de..552b60a3fb7dd011ddc8f308b4745d92131ac8af 100644 (file)
@@ -1,5 +1,4 @@
 using Content.Server.Botany.Components;
-using Content.Shared.Chemistry.Components;
 using Content.Shared.FixedPoint;
 using Robust.Server.GameObjects;
 
@@ -18,17 +17,17 @@ public sealed partial class BotanySystem
             sprite.LayerSetState(0, seed.PlantIconState);
         }
 
-        Solution.ReagentQuantity[] reagents = new Solution.ReagentQuantity[seed.Chemicals.Count];
-        int i = 0;
+        var solutionContainer = _solutionContainerSystem.EnsureSolution(uid, produce.SolutionName);
+
+        solutionContainer.RemoveAllSolution();
         foreach (var (chem, quantity) in seed.Chemicals)
         {
             var amount = FixedPoint2.New(quantity.Min);
             if (quantity.PotencyDivisor > 0 && seed.Potency > 0)
                 amount += FixedPoint2.New(seed.Potency / quantity.PotencyDivisor);
             amount = FixedPoint2.New((int) MathHelper.Clamp(amount.Float(), quantity.Min, quantity.Max));
-            reagents[i++] = new(chem, amount);
+            solutionContainer.MaxVolume += amount;
+            solutionContainer.AddReagent(chem, amount);
         }
-
-        _solutionContainerSystem.EnsureSolution(uid, produce.SolutionName, reagents);
     }
 }
index df2b4e3380a4624b3eafa13599574f7322f7b020..b9258494e374bcdb62a9efec8dfd51e6489e3c89 100644 (file)
@@ -19,7 +19,7 @@ public class MutationSystem : EntitySystem
     public void MutateSeed(SeedData seed, float severity)
     {
         // Add up everything in the bits column and put the number here.
-        const int totalbits = 215;
+        const int totalbits = 245;
 
         // Tolerances (55)
         MutateFloat(ref seed.NutrientConsumption   , 0.05f , 1.2f , 5 , totalbits , severity);
@@ -45,13 +45,17 @@ public class MutationSystem : EntitySystem
         // Kill the plant (30)
         MutateBool(ref seed.Viable         , false , 30 , totalbits , severity);
 
-        // Fun (70)
+        // Fun (90)
         MutateBool(ref seed.Seedless       , true  , 10 , totalbits , severity);
         MutateBool(ref seed.Slip           , true  , 10 , totalbits , severity);
         MutateBool(ref seed.Sentient       , true  , 10 , totalbits , severity);
         MutateBool(ref seed.Ligneous       , true  , 10 , totalbits , severity);
         MutateBool(ref seed.Bioluminescent , true  , 10 , totalbits , severity);
+        MutateBool(ref seed.TurnIntoKudzu  , true  , 10 , totalbits , severity);
+        MutateBool(ref seed.CanScream      , true  , 10 , totalbits , severity);
         seed.BioluminescentColor = RandomColor(seed.BioluminescentColor, 10, totalbits, severity);
+        // ConstantUpgade (10)
+        MutateHarvestType(ref seed.HarvestRepeat   , 10 , totalbits , severity);
     }
 
     public SeedData Cross(SeedData a, SeedData b)
@@ -85,6 +89,8 @@ public class MutationSystem : EntitySystem
         CrossBool(ref result.Sentient, a.Sentient);
         CrossBool(ref result.Ligneous, a.Ligneous);
         CrossBool(ref result.Bioluminescent, a.Bioluminescent);
+        CrossBool(ref result.TurnIntoKudzu, a.TurnIntoKudzu);
+        CrossBool(ref result.CanScream, a.CanScream);
         result.BioluminescentColor = random(0.5f) ? a.BioluminescentColor : result.BioluminescentColor;
 
         // Hybrids have a high chance of being seedless. Balances very
@@ -171,6 +177,19 @@ public class MutationSystem : EntitySystem
         val = polarity;
     }
 
+    private void MutateHarvestType(ref HarvestType val, int bits, int totalbits, float mult)
+    {
+        float p = mult * bits/totalbits;
+        if (!random(p))
+            return;
+
+        if (val == HarvestType.NoRepeat)
+            val = HarvestType.Repeat;
+
+        else if (val == HarvestType.Repeat)
+            val = HarvestType.SelfHarvest;
+    }
+
     private Color RandomColor(Color color, int bits, int totalbits, float mult)
     {
         float p = mult*bits/totalbits;
index 6091b98a536fa8a0a3dbee800d5b63ecbb72c9d7..5a5c0fbba2e743eecf1e9e585b56027874d93e28 100644 (file)
@@ -23,6 +23,7 @@ using Robust.Shared.Timing;
 using Robust.Shared.Audio;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
+using Content.Server.Coordinates.Helpers;
 
 namespace Content.Server.Botany.Systems
 {
@@ -32,7 +33,7 @@ namespace Content.Server.Botany.Systems
         [Dependency] private readonly IPrototypeManager _prototype = default!;
         [Dependency] private readonly MutationSystem _mutation = default!;
         [Dependency] private readonly AppearanceSystem _appearance = default!;
-        [Dependency] private readonly AudioSystem _audio = default!;
+        [Dependency] private readonly SharedAudioSystem _audio = default!;
         [Dependency] private readonly PopupSystem _popupSystem = default!;
         [Dependency] private readonly IGameTiming _gameTiming = default!;
         [Dependency] private readonly TagSystem _tagSystem = default!;
@@ -78,8 +79,8 @@ namespace Content.Server.Botany.Systems
             {
                 var displayName = Loc.GetString(component.Seed.DisplayName);
                 args.PushMarkup(Loc.GetString("plant-holder-component-something-already-growing-message",
-                                      ("seedName", displayName),
-                                      ("toBeForm", displayName.EndsWith('s') ? "are" : "is")));
+                        ("seedName", displayName),
+                        ("toBeForm", displayName.EndsWith('s') ? "are" : "is")));
 
                 if (component.Health <= component.Seed.Endurance / 2)
                 {
@@ -133,7 +134,7 @@ namespace Content.Server.Botany.Systems
                 if (component.Seed == null)
                 {
                     if (!_botanySystem.TryGetSeed(seeds, out var seed))
-                        return ;
+                        return;
 
                     var name = Loc.GetString(seed.Name);
                     var noun = Loc.GetString(seed.Noun);
@@ -209,7 +210,7 @@ namespace Content.Server.Botany.Systems
 
                 _audio.PlayPvs(spray.SpraySound, args.Used, AudioParams.Default.WithVariation(0.125f));
 
-                var split =_solutionSystem.Drain(solutionEntity, solution, amount);
+                var split = _solutionSystem.Drain(solutionEntity, solution, amount);
 
                 if (split.Volume == 0)
                 {
@@ -222,7 +223,7 @@ namespace Content.Server.Botany.Systems
                     ("owner", uid),
                     ("amount", split.Volume)), args.User, PopupType.Medium);
 
-               _solutionSystem.TryAddSolution(targetEntity, targetSolution, split);
+                _solutionSystem.TryAddSolution(targetEntity, targetSolution, split);
 
                 ForceUpdateByExternalCause(uid, component);
 
@@ -257,6 +258,11 @@ namespace Content.Server.Botany.Systems
                     ("seedName", displayName)), args.User);
                 component.Health -= (_random.Next(3, 5) * 10);
 
+                if (component.Seed != null && component.Seed.CanScream)
+                {
+                    _audio.PlayPvs(component.Seed.ScreamSound, uid, AudioParams.Default.WithVolume(-2));
+                }
+
                 if (_random.Prob(0.3f))
                     component.Sampled = true;
 
@@ -283,8 +289,8 @@ namespace Content.Server.Botany.Systems
                 if (_solutionSystem.TryGetSolution(args.Used, produce.SolutionName, out var solution2))
                 {
                     // This deliberately discards overfill.
-                   _solutionSystem.TryAddSolution(args.Used, solution2,
-                       _solutionSystem.SplitSolution(args.Used, solution2, solution2.Volume));
+                    _solutionSystem.TryAddSolution(args.Used, solution2,
+                        _solutionSystem.SplitSolution(args.Used, solution2, solution2.Volume));
 
                     ForceUpdateByExternalCause(uid, component);
                 }
@@ -303,6 +309,7 @@ namespace Content.Server.Botany.Systems
             // TODO
         }
 
+
         public void Update(EntityUid uid, PlantHolderComponent? component = null)
         {
             if (!Resolve(uid, ref component))
@@ -331,14 +338,31 @@ namespace Content.Server.Botany.Systems
             }
 
             // Weeds like water and nutrients! They may appear even if there's not a seed planted.
-            if (component.WaterLevel > 10 && component.NutritionLevel > 2 && _random.Prob(component.Seed == null ? 0.05f : 0.01f))
+            if (component.WaterLevel > 10 && component.NutritionLevel > 2)
             {
-                component.WeedLevel += 1 * HydroponicsSpeedMultiplier * component.WeedCoefficient;
+                var chance = 0f;
+                if (component.Seed == null)
+                    chance = 0.05f;
+                else if (component.Seed.TurnIntoKudzu)
+                    chance = 1f;
+                else
+                    chance = 0.01f;
+
+                if (_random.Prob(chance))
+                    component.WeedLevel += 1 + HydroponicsSpeedMultiplier * component.WeedCoefficient;
 
                 if (component.DrawWarnings)
                     component.UpdateSpriteAfterUpdate = true;
             }
 
+            if (component.Seed != null && component.Seed.TurnIntoKudzu
+                && component.WeedLevel >= component.Seed.WeedHighLevelThreshold)
+            {
+                Spawn(component.Seed.KudzuPrototype, Transform(uid).Coordinates.SnapToGrid(EntityManager));
+                component.Seed.TurnIntoKudzu = false;
+                component.Health = 0;
+            }
+
             // There's a chance for a weed explosion to happen if weeds take over.
             // Plants that are themselves weeds (WeedTolerance > 8) are unaffected.
             if (component.WeedLevel >= 10 && _random.Prob(0.1f))
@@ -399,7 +423,7 @@ namespace Content.Server.Botany.Systems
             if (!component.Seed.Viable)
             {
                 AffectGrowth(uid, -1, component);
-                component.Health -= 6*healthMod;
+                component.Health -= 6 * healthMod;
             }
 
             // Make sure the plant is not starving.
@@ -435,6 +459,7 @@ namespace Content.Server.Botany.Systems
                 if (component.DrawWarnings)
                     component.UpdateSpriteAfterUpdate = true;
             }
+
             var environment = _atmosphere.GetContainingMixture(uid, true, true) ?? GasMixture.SpaceGas;
 
             if (component.Seed.ConsumeGasses.Count > 0)
@@ -670,6 +695,9 @@ namespace Content.Server.Botany.Systems
             component.Harvest = false;
             component.LastProduce = component.Age;
 
+            if (component.Seed != null && component.Seed.CanScream)
+                _audio.PlayPvs(component.Seed.ScreamSound, uid, AudioParams.Default.WithVolume(-2));
+
             if (component.Seed?.HarvestRepeat == HarvestType.NoRepeat)
                 RemovePlant(uid, component);
 
@@ -832,8 +860,7 @@ namespace Content.Server.Botany.Systems
             {
                 if (component.DrawWarnings)
                 {
-                    _appearance.SetData(uid, PlantHolderVisuals.HealthLight,
-                        component.Health <= component.Seed.Endurance / 2f);
+                    _appearance.SetData(uid, PlantHolderVisuals.HealthLight, component.Health <= component.Seed.Endurance / 2f);
                 }
 
                 if (component.Dead)
index 4d141dceb5a279eaacda7d92168209777468c7d4..331056cb08f8f186d7f8f9ee1506699da2aea7cb 100644 (file)
       walkSpeedModifier: 0.2
       sprintSpeedModifier: 0.2
 
+- type: entity
+  id: WeakKudzu
+  parent: Kudzu
+  components:
+    - type: Spreader
+      growthResult: WeakKudzu
+      chance: 0.3
+
 - type: entity
   id: FleshKudzu
   name: tendons