New botany mutations (#13646)
This commit is contained in:
@@ -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,
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user