mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 18:31:17 +03:00
* Yay * Do a LOT changes in yml * and again * Finale changes * yml and locale * locale tweak * yml and charp cleanup * fix carpets * and some-some * And some * I want to believe that its last🙏🙏 * 😭 * 😭😭 * clean * fix * AAHHAHAHAHAHAH * fix * FINAL * thisguyusa... * LAST_ONE * wawa * merge2 * sdobfjibwdsjaqaksmzxsowaw2edqw84 * aoaoaooaoaao * this hardcode took 30 minutes of my life * fix aaaa * fix test * FIX BUILD * oops * oops * aaooaoaoa * fuck * oops * refactor: cleanup after merge + use protoId in KitchenSpikeComponent * refactor: fix butcherable stuff again!~ * fix: now actively checks for EdibleComponent on slicing, predicted items splitting * fix: changed knife.yaml to use Slicing tool * fix: no more sounds spam on chop-chop * refactor: cleanups * refactor: default time value for slicable * refactor: whitespaces and extract variables * fix: slicable no longer prevents InteractUsingEvent by marking handled w/o actually handling * feat: chopping trees now requires sawing tool, same for slicing logs * refactor: cleanup after merge * refactor: fix non-related PR changes * refactor: rename locid * refactor: remove unneeded red 'slice' verb name when slicing entities with mob-state. * refactor: simplify test code changes * refactor: better readability for test * refactor: linebreak for unary op * refactor: xml-doc for SliceableComponent corrected to be more fitting. * refactor: cleanup SliceableSystem some more * refactor: use HasComp instead of TryComp in AddSliceVerb * refactor: extracted methods to improve readability * refactor: remove unchecked operator - not needed when casting from uint * refactor: SliceableSystem cleanups, fix logs not being chopped due to solution splitting * fix: slice verb is now showing up even if disabled, slicing is done even if there is no solution to split, replaced direct dependency for sliceable component to food component with default solution-name * refactor: comment about RandomPredicted + toy knife now fits into clown shoes * refactor: remove EdibleComponent dependency from SliceableSystem * refactor: moved SliceableSystem into ToolRefinableSystem * refactor: basic renaming for comps * refactor: cleanup after merge * refactor: reorder methods, renaming, simplify polymorph related conditions on slicing * refactor: xml-doc + reorder yaml fields * refactor: fixing yaml + method renaming, unused usings removed * refactor: removed unused usings * refactor: fix typo * refactor: remove reference for deleted meat proto * refactor: clean up yaml after merge * refactor: fix multiple typos from mass replace * refactor: fix missed field renaming * refactor: ensure all entities that had ToolRefinable got BaseSlicingRefinable (aftermerge cleanup) * refactor: undo solution-related changes for animals.yml * refactor: fix invalid parent set for corgi + fix amount of slices for the rest of pies * refactor: revert Solution to SolutionContainerManager changes after merge * refactor: revert Solution to SolutionContainerManager changes after merge * refactor: fix invalid property name for toolMissingQualityTooltip in yml, fixed missing entity on which AttemptToolRefineEvent is raised * refactor: remove over-indent for components of BaseSlicingRefinable and for Slicing tool quality * refactor: remove over-indentation on MobCarpHolo * empty collection --------- Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru> Co-authored-by: Fildrance <fildrance@gmail.com> Co-authored-by: iaada <iaada@users.noreply.github.com>
393 lines
13 KiB
C#
393 lines
13 KiB
C#
using Content.Shared.Atmos;
|
|
using Content.Shared.Database;
|
|
using Content.Shared.FixedPoint;
|
|
using Content.Shared.Random;
|
|
using Robust.Shared.Audio;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
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 FixedPoint2 Min = FixedPoint2.Epsilon;
|
|
|
|
/// <summary>
|
|
/// Maximum amount of chemical that can be produced after taking plant potency into account.
|
|
/// </summary>
|
|
[DataField("Max")] public FixedPoint2 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 float 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 Make Botany ECS and give it a proper API. I removed the limited access of this class because it's egregious how many systems needed access to it due to a lack of an actual API.
|
|
/// <remarks>
|
|
/// SeedData is no longer restricted because the number of friends is absolutely unreasonable.
|
|
/// This entire data definition is unreasonable. I felt genuine fear looking at this, this is horrific. Send help.
|
|
/// </remarks>
|
|
// TODO: Hit Botany with hammers
|
|
[Virtual, DataDefinition]
|
|
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]
|
|
public List<EntProtoId> 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 tool with sliceable quality 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]
|
|
public List<ProtoId<SeedPrototype>> MutationPrototypes = new();
|
|
|
|
/// <summary>
|
|
/// Log impact for when the seed is planted.
|
|
/// </summary>
|
|
[DataField]
|
|
public LogImpact? PlantLogImpact = null;
|
|
|
|
/// <summary>
|
|
/// Log impact for when the seed is harvested.
|
|
/// </summary>
|
|
[DataField]
|
|
public LogImpact? HarvestLogImpact = null;
|
|
|
|
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<EntProtoId>(ProductPrototypes),
|
|
MutationPrototypes = new List<ProtoId<SeedPrototype>>(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<EntProtoId>(other.ProductPrototypes),
|
|
MutationPrototypes = new List<ProtoId<SeedPrototype>>(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;
|
|
}
|
|
}
|