New botany mutations (#13646)

This commit is contained in:
Duke
2023-03-06 04:11:13 +03:00
committed by GitHub
parent fbca794c94
commit 8640f0b0a3
5 changed files with 90 additions and 25 deletions

View File

@@ -1,4 +1,3 @@
using System.ComponentModel;
using Content.Server.Botany.Components; using Content.Server.Botany.Components;
using Content.Server.Botany.Systems; using Content.Server.Botany.Systems;
using Content.Shared.Atmos; 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;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.Audio;
namespace Content.Server.Botany; namespace Content.Server.Botany;
[Prototype("seed")] [Prototype("seed")]
public sealed class SeedPrototype : SeedData, IPrototype public sealed class SeedPrototype : SeedData, IPrototype
{ {
@@ -144,6 +142,8 @@ public class SeedData
[DataField("weedTolerance")] public float WeedTolerance = 5f; [DataField("weedTolerance")] public float WeedTolerance = 5f;
[DataField("weedHighLevelThreshold")] public float WeedHighLevelThreshold = 10f;
#endregion #endregion
#region General traits #region General traits
@@ -155,6 +155,8 @@ public class SeedData
[DataField("maturation")] public float Maturation; [DataField("maturation")] public float Maturation;
[DataField("production")] public float Production; [DataField("production")] public float Production;
[DataField("growthStages")] public int GrowthStages = 6; [DataField("growthStages")] public int GrowthStages = 6;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("harvestRepeat")] public HarvestType HarvestRepeat = HarvestType.NoRepeat; [DataField("harvestRepeat")] public HarvestType HarvestRepeat = HarvestType.NoRepeat;
[DataField("potency")] public float Potency = 1f; [DataField("potency")] public float Potency = 1f;
@@ -208,12 +210,20 @@ public class SeedData
[DataField("plantIconState")] public string PlantIconState { get; set; } = "produce"; [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; [DataField("bioluminescentColor")] public Color BioluminescentColor { get; set; } = Color.White;
public float BioluminescentRadius = 2f; 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; } [DataField("splatPrototype")] public string? SplatPrototype { get; set; }
#endregion #endregion
@@ -265,6 +275,8 @@ public class SeedData
PlantRsi = PlantRsi, PlantRsi = PlantRsi,
PlantIconState = PlantIconState, PlantIconState = PlantIconState,
Bioluminescent = Bioluminescent, Bioluminescent = Bioluminescent,
CanScream = CanScream,
TurnIntoKudzu = TurnIntoKudzu,
BioluminescentColor = BioluminescentColor, BioluminescentColor = BioluminescentColor,
SplatPrototype = SplatPrototype, SplatPrototype = SplatPrototype,

View File

@@ -1,5 +1,4 @@
using Content.Server.Botany.Components; using Content.Server.Botany.Components;
using Content.Shared.Chemistry.Components;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
@@ -18,17 +17,17 @@ public sealed partial class BotanySystem
sprite.LayerSetState(0, seed.PlantIconState); sprite.LayerSetState(0, seed.PlantIconState);
} }
Solution.ReagentQuantity[] reagents = new Solution.ReagentQuantity[seed.Chemicals.Count]; var solutionContainer = _solutionContainerSystem.EnsureSolution(uid, produce.SolutionName);
int i = 0;
solutionContainer.RemoveAllSolution();
foreach (var (chem, quantity) in seed.Chemicals) foreach (var (chem, quantity) in seed.Chemicals)
{ {
var amount = FixedPoint2.New(quantity.Min); var amount = FixedPoint2.New(quantity.Min);
if (quantity.PotencyDivisor > 0 && seed.Potency > 0) if (quantity.PotencyDivisor > 0 && seed.Potency > 0)
amount += FixedPoint2.New(seed.Potency / quantity.PotencyDivisor); amount += FixedPoint2.New(seed.Potency / quantity.PotencyDivisor);
amount = FixedPoint2.New((int) MathHelper.Clamp(amount.Float(), quantity.Min, quantity.Max)); 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);
} }
} }

View File

@@ -19,7 +19,7 @@ public class MutationSystem : EntitySystem
public void MutateSeed(SeedData seed, float severity) public void MutateSeed(SeedData seed, float severity)
{ {
// Add up everything in the bits column and put the number here. // Add up everything in the bits column and put the number here.
const int totalbits = 215; const int totalbits = 245;
// Tolerances (55) // Tolerances (55)
MutateFloat(ref seed.NutrientConsumption , 0.05f , 1.2f , 5 , totalbits , severity); MutateFloat(ref seed.NutrientConsumption , 0.05f , 1.2f , 5 , totalbits , severity);
@@ -45,13 +45,17 @@ public class MutationSystem : EntitySystem
// Kill the plant (30) // Kill the plant (30)
MutateBool(ref seed.Viable , false , 30 , totalbits , severity); MutateBool(ref seed.Viable , false , 30 , totalbits , severity);
// Fun (70) // Fun (90)
MutateBool(ref seed.Seedless , true , 10 , totalbits , severity); MutateBool(ref seed.Seedless , true , 10 , totalbits , severity);
MutateBool(ref seed.Slip , true , 10 , totalbits , severity); MutateBool(ref seed.Slip , true , 10 , totalbits , severity);
MutateBool(ref seed.Sentient , true , 10 , totalbits , severity); MutateBool(ref seed.Sentient , true , 10 , totalbits , severity);
MutateBool(ref seed.Ligneous , true , 10 , totalbits , severity); MutateBool(ref seed.Ligneous , true , 10 , totalbits , severity);
MutateBool(ref seed.Bioluminescent , 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); seed.BioluminescentColor = RandomColor(seed.BioluminescentColor, 10, totalbits, severity);
// ConstantUpgade (10)
MutateHarvestType(ref seed.HarvestRepeat , 10 , totalbits , severity);
} }
public SeedData Cross(SeedData a, SeedData b) public SeedData Cross(SeedData a, SeedData b)
@@ -85,6 +89,8 @@ public class MutationSystem : EntitySystem
CrossBool(ref result.Sentient, a.Sentient); CrossBool(ref result.Sentient, a.Sentient);
CrossBool(ref result.Ligneous, a.Ligneous); CrossBool(ref result.Ligneous, a.Ligneous);
CrossBool(ref result.Bioluminescent, a.Bioluminescent); 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; result.BioluminescentColor = random(0.5f) ? a.BioluminescentColor : result.BioluminescentColor;
// Hybrids have a high chance of being seedless. Balances very // Hybrids have a high chance of being seedless. Balances very
@@ -171,6 +177,19 @@ public class MutationSystem : EntitySystem
val = polarity; 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) private Color RandomColor(Color color, int bits, int totalbits, float mult)
{ {
float p = mult*bits/totalbits; float p = mult*bits/totalbits;

View File

@@ -23,6 +23,7 @@ using Robust.Shared.Timing;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using Content.Server.Coordinates.Helpers;
namespace Content.Server.Botany.Systems namespace Content.Server.Botany.Systems
{ {
@@ -32,7 +33,7 @@ namespace Content.Server.Botany.Systems
[Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly MutationSystem _mutation = default!; [Dependency] private readonly MutationSystem _mutation = default!;
[Dependency] private readonly AppearanceSystem _appearance = 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 PopupSystem _popupSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!;
@@ -257,6 +258,11 @@ namespace Content.Server.Botany.Systems
("seedName", displayName)), args.User); ("seedName", displayName)), args.User);
component.Health -= (_random.Next(3, 5) * 10); 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)) if (_random.Prob(0.3f))
component.Sampled = true; component.Sampled = true;
@@ -303,6 +309,7 @@ namespace Content.Server.Botany.Systems
// TODO // TODO
} }
public void Update(EntityUid uid, PlantHolderComponent? component = null) public void Update(EntityUid uid, PlantHolderComponent? component = null)
{ {
if (!Resolve(uid, ref component)) 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. // 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) if (component.DrawWarnings)
component.UpdateSpriteAfterUpdate = true; 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. // There's a chance for a weed explosion to happen if weeds take over.
// Plants that are themselves weeds (WeedTolerance > 8) are unaffected. // Plants that are themselves weeds (WeedTolerance > 8) are unaffected.
if (component.WeedLevel >= 10 && _random.Prob(0.1f)) if (component.WeedLevel >= 10 && _random.Prob(0.1f))
@@ -435,6 +459,7 @@ namespace Content.Server.Botany.Systems
if (component.DrawWarnings) if (component.DrawWarnings)
component.UpdateSpriteAfterUpdate = true; component.UpdateSpriteAfterUpdate = true;
} }
var environment = _atmosphere.GetContainingMixture(uid, true, true) ?? GasMixture.SpaceGas; var environment = _atmosphere.GetContainingMixture(uid, true, true) ?? GasMixture.SpaceGas;
if (component.Seed.ConsumeGasses.Count > 0) if (component.Seed.ConsumeGasses.Count > 0)
@@ -670,6 +695,9 @@ namespace Content.Server.Botany.Systems
component.Harvest = false; component.Harvest = false;
component.LastProduce = component.Age; 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) if (component.Seed?.HarvestRepeat == HarvestType.NoRepeat)
RemovePlant(uid, component); RemovePlant(uid, component);
@@ -832,8 +860,7 @@ namespace Content.Server.Botany.Systems
{ {
if (component.DrawWarnings) if (component.DrawWarnings)
{ {
_appearance.SetData(uid, PlantHolderVisuals.HealthLight, _appearance.SetData(uid, PlantHolderVisuals.HealthLight, component.Health <= component.Seed.Endurance / 2f);
component.Health <= component.Seed.Endurance / 2f);
} }
if (component.Dead) if (component.Dead)

View File

@@ -78,6 +78,14 @@
walkSpeedModifier: 0.2 walkSpeedModifier: 0.2
sprintSpeedModifier: 0.2 sprintSpeedModifier: 0.2
- type: entity
id: WeakKudzu
parent: Kudzu
components:
- type: Spreader
growthResult: WeakKudzu
chance: 0.3
- type: entity - type: entity
id: FleshKudzu id: FleshKudzu
name: tendons name: tendons