Botany (#2357)
* plants and seeds go brrrr * update plants * P L A N T * brrrr * Hydroponics actually work! How about that? * Reuse resource path in visualizer * They lied to us. * Several stuffs * more werk * Add a bunch of plants * Logs go brr. * Brrr moment. * Remove unused method * Important comment. * Seed inventory, yo! * tomato moment * Balance consumption * Makes hydroponics pourable * Adds plant metabolism effect for sugar, the same as glucose. * Eggplant moment * Apple moment * Corn moment * Chanterelle mushroom moment * prototype tweaks * Seed extractor moment * typo * IPlantMetabolizable doc improvement * I should trust my gut instinct more often. * egg-plant..... * localization * Make WaterLevel and NutritionLevel setters private * Less code repetition! Wooo!
@@ -1,22 +1,41 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Shared.GameObjects.Components.Atmos;
|
using Content.Shared.GameObjects.Components.Atmos;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using YamlDotNet.RepresentationModel;
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Atmos
|
namespace Content.Client.GameObjects.Components.Atmos
|
||||||
{
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
public class FireVisualizer : AppearanceVisualizer
|
public class FireVisualizer : AppearanceVisualizer
|
||||||
{
|
{
|
||||||
private int _fireStackAlternateState = 3;
|
private int _fireStackAlternateState = 3;
|
||||||
private string _normalState;
|
private string _normalState;
|
||||||
private string _alternateState;
|
private string _alternateState;
|
||||||
|
private string _sprite;
|
||||||
|
|
||||||
|
public override void InitializeEntity(IEntity entity)
|
||||||
|
{
|
||||||
|
base.InitializeEntity(entity);
|
||||||
|
|
||||||
|
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||||
|
|
||||||
|
sprite.LayerMapReserveBlank(FireVisualLayers.Fire);
|
||||||
|
sprite.LayerSetVisible(FireVisualLayers.Fire, false);
|
||||||
|
}
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
public override void LoadData(YamlMappingNode node)
|
||||||
{
|
{
|
||||||
base.LoadData(node);
|
base.LoadData(node);
|
||||||
|
|
||||||
|
if (node.TryGetNode("sprite", out var sprite))
|
||||||
|
{
|
||||||
|
_sprite = sprite.AsString();
|
||||||
|
}
|
||||||
|
|
||||||
if (node.TryGetNode("fireStackAlternateState", out var fireStack))
|
if (node.TryGetNode("fireStackAlternateState", out var fireStack))
|
||||||
{
|
{
|
||||||
_fireStackAlternateState = fireStack.AsInt();
|
_fireStackAlternateState = fireStack.AsInt();
|
||||||
@@ -52,6 +71,7 @@ namespace Content.Client.GameObjects.Components.Atmos
|
|||||||
{
|
{
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||||
|
|
||||||
|
sprite.LayerSetRSI(FireVisualLayers.Fire, _sprite);
|
||||||
sprite.LayerSetVisible(FireVisualLayers.Fire, onFire);
|
sprite.LayerSetVisible(FireVisualLayers.Fire, onFire);
|
||||||
|
|
||||||
if(fireStacks > _fireStackAlternateState && !string.IsNullOrEmpty(_alternateState))
|
if(fireStacks > _fireStackAlternateState && !string.IsNullOrEmpty(_alternateState))
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
using Content.Shared.GameObjects.Components.Botany;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class PlantHolderVisualizer : AppearanceVisualizer
|
||||||
|
{
|
||||||
|
public override void InitializeEntity(IEntity entity)
|
||||||
|
{
|
||||||
|
base.InitializeEntity(entity);
|
||||||
|
|
||||||
|
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||||
|
|
||||||
|
sprite.LayerMapReserveBlank(PlantHolderLayers.Plant);
|
||||||
|
sprite.LayerMapReserveBlank(PlantHolderLayers.HealthLight);
|
||||||
|
sprite.LayerMapReserveBlank(PlantHolderLayers.WaterLight);
|
||||||
|
sprite.LayerMapReserveBlank(PlantHolderLayers.NutritionLight);
|
||||||
|
sprite.LayerMapReserveBlank(PlantHolderLayers.AlertLight);
|
||||||
|
sprite.LayerMapReserveBlank(PlantHolderLayers.HarvestLight);
|
||||||
|
|
||||||
|
var hydroTools = new ResourcePath("Constructible/Hydroponics/hydro_tools.rsi");
|
||||||
|
|
||||||
|
sprite.LayerSetSprite(PlantHolderLayers.HealthLight,
|
||||||
|
new SpriteSpecifier.Rsi(hydroTools, "over_lowhealth3"));
|
||||||
|
sprite.LayerSetSprite(PlantHolderLayers.WaterLight,
|
||||||
|
new SpriteSpecifier.Rsi(hydroTools, "over_lowwater3"));
|
||||||
|
sprite.LayerSetSprite(PlantHolderLayers.NutritionLight,
|
||||||
|
new SpriteSpecifier.Rsi(hydroTools, "over_lownutri3"));
|
||||||
|
sprite.LayerSetSprite(PlantHolderLayers.AlertLight,
|
||||||
|
new SpriteSpecifier.Rsi(hydroTools, "over_alert3"));
|
||||||
|
sprite.LayerSetSprite(PlantHolderLayers.HarvestLight,
|
||||||
|
new SpriteSpecifier.Rsi(hydroTools, "over_harvest3"));
|
||||||
|
|
||||||
|
// Let's make those invisible for now.
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.Plant, false);
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.HealthLight, false);
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.WaterLight, false);
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.NutritionLight, false);
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.AlertLight, false);
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.HarvestLight, false);
|
||||||
|
|
||||||
|
// Pretty unshaded lights!
|
||||||
|
sprite.LayerSetShader(PlantHolderLayers.HealthLight, "unshaded");
|
||||||
|
sprite.LayerSetShader(PlantHolderLayers.WaterLight, "unshaded");
|
||||||
|
sprite.LayerSetShader(PlantHolderLayers.NutritionLight, "unshaded");
|
||||||
|
sprite.LayerSetShader(PlantHolderLayers.AlertLight, "unshaded");
|
||||||
|
sprite.LayerSetShader(PlantHolderLayers.HarvestLight, "unshaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnChangeData(AppearanceComponent component)
|
||||||
|
{
|
||||||
|
base.OnChangeData(component);
|
||||||
|
|
||||||
|
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||||
|
|
||||||
|
if (component.TryGetData<SpriteSpecifier>(PlantHolderVisuals.Plant, out var specifier))
|
||||||
|
{
|
||||||
|
var valid = !specifier.Equals(SpriteSpecifier.Invalid);
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.Plant, valid);
|
||||||
|
if(valid)
|
||||||
|
sprite.LayerSetSprite(PlantHolderLayers.Plant, specifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.TryGetData<bool>(PlantHolderVisuals.HealthLight, out var health))
|
||||||
|
{
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.HealthLight, health);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.TryGetData<bool>(PlantHolderVisuals.WaterLight, out var water))
|
||||||
|
{
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.WaterLight, water);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.TryGetData<bool>(PlantHolderVisuals.NutritionLight, out var nutrition))
|
||||||
|
{
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.NutritionLight, nutrition);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.TryGetData<bool>(PlantHolderVisuals.AlertLight, out var alert))
|
||||||
|
{
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.AlertLight, alert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.TryGetData<bool>(PlantHolderVisuals.HarvestLight, out var harvest))
|
||||||
|
{
|
||||||
|
sprite.LayerSetVisible(PlantHolderLayers.HarvestLight, harvest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PlantHolderLayers
|
||||||
|
{
|
||||||
|
Plant,
|
||||||
|
HealthLight,
|
||||||
|
WaterLight,
|
||||||
|
NutritionLight,
|
||||||
|
AlertLight,
|
||||||
|
HarvestLight,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,38 @@
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Nutrition
|
namespace Content.Client.GameObjects.Components.Nutrition
|
||||||
{
|
{
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public class CreamPiedVisualizer : AppearanceVisualizer
|
public class CreamPiedVisualizer : AppearanceVisualizer
|
||||||
{
|
{
|
||||||
|
private string _state;
|
||||||
|
|
||||||
|
public override void InitializeEntity(IEntity entity)
|
||||||
|
{
|
||||||
|
base.InitializeEntity(entity);
|
||||||
|
|
||||||
|
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||||
|
|
||||||
|
sprite.LayerMapReserveBlank(CreamPiedVisualLayers.Pie);
|
||||||
|
sprite.LayerSetRSI(CreamPiedVisualLayers.Pie, "Effects/creampie.rsi");
|
||||||
|
sprite.LayerSetVisible(CreamPiedVisualLayers.Pie, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadData(YamlMappingNode node)
|
||||||
|
{
|
||||||
|
base.LoadData(node);
|
||||||
|
|
||||||
|
if (node.TryGetNode("state", out var otherNode))
|
||||||
|
{
|
||||||
|
_state = otherNode.AsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
public override void OnChangeData(AppearanceComponent component)
|
||||||
{
|
{
|
||||||
base.OnChangeData(component);
|
base.OnChangeData(component);
|
||||||
@@ -23,6 +49,7 @@ namespace Content.Client.GameObjects.Components.Nutrition
|
|||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||||
|
|
||||||
sprite.LayerSetVisible(CreamPiedVisualLayers.Pie, pied);
|
sprite.LayerSetVisible(CreamPiedVisualLayers.Pie, pied);
|
||||||
|
sprite.LayerSetState(CreamPiedVisualLayers.Pie, _state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace Content.Server.Atmos
|
|||||||
{
|
{
|
||||||
private readonly AtmosphereSystem _atmosphereSystem;
|
private readonly AtmosphereSystem _atmosphereSystem;
|
||||||
|
|
||||||
|
public static GasMixture SpaceGas => new GasMixture() {Volume = 2500f, Immutable = true, Temperature = Atmospherics.TCMB};
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private float[] _moles = new float[Atmospherics.TotalNumberOfGases];
|
private float[] _moles = new float[Atmospherics.TotalNumberOfGases];
|
||||||
|
|
||||||
|
|||||||
354
Content.Server/Botany/Seed.cs
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.Atmos;
|
||||||
|
using Content.Shared.Interfaces;
|
||||||
|
using Content.Shared.Utility;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.Interfaces.Serialization;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
|
namespace Content.Server.Botany
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public struct SeedChemQuantity
|
||||||
|
{
|
||||||
|
public int Min;
|
||||||
|
public int Max;
|
||||||
|
public int PotencyDivisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Prototype("seed")]
|
||||||
|
public class Seed : IPrototype, IIndexedPrototype, IExposeData
|
||||||
|
{
|
||||||
|
private const string SeedPrototype = "SeedBase";
|
||||||
|
|
||||||
|
public string ID { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unique identifier of this seed. Do NOT set this.
|
||||||
|
/// </summary>
|
||||||
|
public int Uid { get; internal set; } = -1;
|
||||||
|
|
||||||
|
#region Tracking
|
||||||
|
[ViewVariables] public string Name { get; set; }
|
||||||
|
[ViewVariables] public string SeedName { get; set; }
|
||||||
|
[ViewVariables] public string SeedNoun { get; set; }
|
||||||
|
[ViewVariables] public string DisplayName { get; set; }
|
||||||
|
[ViewVariables] public bool RoundStart { get; private set; }
|
||||||
|
[ViewVariables] public bool Mysterious { get; set; }
|
||||||
|
[ViewVariables] public bool Immutable { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Output
|
||||||
|
[ViewVariables] public List<string> ProductPrototypes { get; set; }
|
||||||
|
[ViewVariables] public Dictionary<string, SeedChemQuantity> Chemicals { get; set; }
|
||||||
|
[ViewVariables] public Dictionary<Gas, float> ConsumeGasses { get; set; }
|
||||||
|
[ViewVariables]public Dictionary<Gas, float> ExudeGasses { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Tolerances
|
||||||
|
[ViewVariables] public float NutrientConsumption { get; set; }
|
||||||
|
[ViewVariables] public float WaterConsumption { get; set; }
|
||||||
|
[ViewVariables] public float IdealHeat { get; set; }
|
||||||
|
[ViewVariables] public float HeatTolerance { get; set; }
|
||||||
|
[ViewVariables] public float IdealLight { get; set; }
|
||||||
|
[ViewVariables] public float LightTolerance { get; set; }
|
||||||
|
[ViewVariables] public float ToxinsTolerance { get; set; }
|
||||||
|
[ViewVariables] public float LowPressureTolerance { get; set; }
|
||||||
|
[ViewVariables] public float HighPressureTolerance { get; set; }
|
||||||
|
[ViewVariables] public float PestTolerance { get; set; }
|
||||||
|
[ViewVariables] public float WeedTolerance { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region General traits
|
||||||
|
[ViewVariables] public float Endurance { get; set; }
|
||||||
|
[ViewVariables] public int Yield { get; set; }
|
||||||
|
[ViewVariables] public float Lifespan { get; set; }
|
||||||
|
[ViewVariables] public float Maturation { get; set; }
|
||||||
|
[ViewVariables] public float Production { get; set; }
|
||||||
|
[ViewVariables] public int GrowthStages { get; set; }
|
||||||
|
[ViewVariables] public HarvestType HarvestRepeat { get; set; }
|
||||||
|
[ViewVariables] public float Potency { get; set; }
|
||||||
|
// No, I'm not removing these.
|
||||||
|
//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 Ligneous { get; set; }
|
||||||
|
// public bool Teleporting { get; set; }
|
||||||
|
// public PlantJuicy Juicy { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Cosmetics
|
||||||
|
[ViewVariables]public ResourcePath PlantRsi { get; set; }
|
||||||
|
[ViewVariables] public string PlantIconState { get; set; }
|
||||||
|
[ViewVariables] public bool Bioluminescent { get; set; }
|
||||||
|
[ViewVariables] public Color BioluminescentColor { get; set; }
|
||||||
|
[ViewVariables] public string SplatPrototype { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
serializer.DataField(this, x => x.ID, "id", string.Empty);
|
||||||
|
serializer.DataField(this, x => x.Name, "name", string.Empty);
|
||||||
|
serializer.DataField(this, x => x.SeedName, "seedName", string.Empty);
|
||||||
|
serializer.DataField(this, x => x.SeedNoun, "seedNoun", "seeds");
|
||||||
|
serializer.DataField(this, x => x.DisplayName, "displayName", string.Empty);
|
||||||
|
serializer.DataField(this, x => x.RoundStart, "roundStart", true);
|
||||||
|
serializer.DataField(this, x => x.Mysterious, "mysterious", false);
|
||||||
|
serializer.DataField(this, x => x.Immutable, "immutable", false);
|
||||||
|
serializer.DataField(this, x => x.ProductPrototypes, "productPrototypes", new List<string>());
|
||||||
|
serializer.DataField(this, x => x.Chemicals, "chemicals", new Dictionary<string, SeedChemQuantity>());
|
||||||
|
serializer.DataField(this, x => x.ConsumeGasses, "consumeGasses", new Dictionary<Gas, float>());
|
||||||
|
serializer.DataField(this, x => x.ExudeGasses, "exudeGasses", new Dictionary<Gas, float>());
|
||||||
|
serializer.DataField(this, x => x.NutrientConsumption, "nutrientConsumption", 0.25f);
|
||||||
|
serializer.DataField(this, x => x.WaterConsumption, "waterConsumption", 3f);
|
||||||
|
serializer.DataField(this, x => x.IdealHeat, "idealHeat", 293f);
|
||||||
|
serializer.DataField(this, x => x.HeatTolerance, "heatTolerance", 20f);
|
||||||
|
serializer.DataField(this, x => x.IdealLight, "idealLight", 7f);
|
||||||
|
serializer.DataField(this, x => x.LightTolerance, "lightTolerance", 5f);
|
||||||
|
serializer.DataField(this, x => x.ToxinsTolerance, "toxinsTolerance", 4f);
|
||||||
|
serializer.DataField(this, x => x.LowPressureTolerance, "lowPressureTolerance", 25f);
|
||||||
|
serializer.DataField(this, x => x.HighPressureTolerance, "highPressureTolerance", 200f);
|
||||||
|
serializer.DataField(this, x => x.PestTolerance, "pestTolerance", 5f);
|
||||||
|
serializer.DataField(this, x => x.WeedTolerance, "weedTolerance", 5f);
|
||||||
|
serializer.DataField(this, x => x.Endurance, "endurance", 100f);
|
||||||
|
serializer.DataField(this, x => x.Yield, "yield", 0);
|
||||||
|
serializer.DataField(this, x => x.Lifespan, "lifespan", 0f);
|
||||||
|
serializer.DataField(this, x => x.Maturation, "maturation", 0f);
|
||||||
|
serializer.DataField(this, x => x.Production, "production", 0f);
|
||||||
|
serializer.DataField(this, x => x.GrowthStages, "growthStages", 6);
|
||||||
|
serializer.DataField(this, x => x.HarvestRepeat, "harvestRepeat", HarvestType.NoRepeat);
|
||||||
|
serializer.DataField(this, x => x.Potency, "potency", 1f);
|
||||||
|
serializer.DataField(this, x => x.Ligneous, "ligneous", false);
|
||||||
|
serializer.DataField(this, x => x.PlantRsi, "plantRsi", null);
|
||||||
|
serializer.DataField(this, x => x.PlantIconState, "plantIconState", "produce");
|
||||||
|
serializer.DataField(this, x => x.Bioluminescent, "bioluminescent", false);
|
||||||
|
serializer.DataField(this, x => x.BioluminescentColor, "bioluminescentColor", Color.White);
|
||||||
|
serializer.DataField(this, x => x.SplatPrototype, "splatPrototype", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadFrom(YamlMappingNode mapping)
|
||||||
|
{
|
||||||
|
var serializer = YamlObjectSerializer.NewReader(mapping);
|
||||||
|
ExposeData(serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Seed Clone()
|
||||||
|
{
|
||||||
|
var newSeed = new Seed()
|
||||||
|
{
|
||||||
|
ID = ID,
|
||||||
|
Name = Name,
|
||||||
|
SeedName = SeedName,
|
||||||
|
SeedNoun = SeedNoun,
|
||||||
|
RoundStart = RoundStart,
|
||||||
|
Mysterious = Mysterious,
|
||||||
|
|
||||||
|
ProductPrototypes = new List<string>(ProductPrototypes),
|
||||||
|
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,
|
||||||
|
|
||||||
|
PlantRsi = PlantRsi,
|
||||||
|
PlantIconState = PlantIconState,
|
||||||
|
Bioluminescent = Bioluminescent,
|
||||||
|
BioluminescentColor = BioluminescentColor,
|
||||||
|
SplatPrototype = SplatPrototype,
|
||||||
|
};
|
||||||
|
|
||||||
|
return newSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEntity SpawnSeedPacket(EntityCoordinates transformCoordinates, IEntityManager entityManager = null)
|
||||||
|
{
|
||||||
|
entityManager ??= IoCManager.Resolve<IEntityManager>();
|
||||||
|
|
||||||
|
var seed = entityManager.SpawnEntity(SeedPrototype, transformCoordinates);
|
||||||
|
|
||||||
|
var seedComp = seed.EnsureComponent<SeedComponent>();
|
||||||
|
seedComp.Seed = this;
|
||||||
|
|
||||||
|
if (seed.TryGetComponent(out SpriteComponent sprite))
|
||||||
|
{
|
||||||
|
// Seed state will always be seed. Blame the spriter if that's not the case!
|
||||||
|
sprite.LayerSetSprite(0, new SpriteSpecifier.Rsi(PlantRsi, "seed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
seed.Name = Loc.GetString($"packet of {SeedName} {SeedNoun}");
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddToDatabase()
|
||||||
|
{
|
||||||
|
var plantSystem = EntitySystem.Get<PlantSystem>();
|
||||||
|
if (plantSystem.AddSeedToDatabase(this))
|
||||||
|
{
|
||||||
|
Name = Uid.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IEntity> AutoHarvest(EntityCoordinates position, int yieldMod = 1)
|
||||||
|
{
|
||||||
|
if (position.IsValid(IoCManager.Resolve<IEntityManager>()) && ProductPrototypes != null &&
|
||||||
|
ProductPrototypes.Count > 0)
|
||||||
|
return GenerateProduct(position, yieldMod);
|
||||||
|
|
||||||
|
return Enumerable.Empty<IEntity>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IEntity> Harvest(IEntity user, int yieldMod = 1)
|
||||||
|
{
|
||||||
|
AddToDatabase();
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
return Enumerable.Empty<IEntity>();
|
||||||
|
|
||||||
|
if (ProductPrototypes == null || ProductPrototypes.Count == 0 || Yield <= 0)
|
||||||
|
{
|
||||||
|
user.PopupMessageCursor(Loc.GetString("You fail to harvest anything useful."));
|
||||||
|
return Enumerable.Empty<IEntity>();
|
||||||
|
}
|
||||||
|
|
||||||
|
user.PopupMessageCursor(Loc.GetString($"You harvest from the {DisplayName}"));
|
||||||
|
return GenerateProduct(user.Transform.Coordinates, yieldMod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IEntity> GenerateProduct(EntityCoordinates position, int yieldMod = 1)
|
||||||
|
{
|
||||||
|
var totalYield = 0;
|
||||||
|
if (Yield > -1)
|
||||||
|
{
|
||||||
|
if (yieldMod < 0)
|
||||||
|
{
|
||||||
|
yieldMod = 1;
|
||||||
|
totalYield = Yield;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
totalYield = Yield * yieldMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalYield = Math.Max(1, totalYield);
|
||||||
|
}
|
||||||
|
|
||||||
|
var random = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||||
|
|
||||||
|
var products = new List<IEntity>();
|
||||||
|
|
||||||
|
for (var i = 0; i < totalYield; i++)
|
||||||
|
{
|
||||||
|
var product = random.Pick(ProductPrototypes);
|
||||||
|
|
||||||
|
var entity = entityManager.SpawnEntity(product, position);
|
||||||
|
entity.RandomOffset(0.25f);
|
||||||
|
products.Add(entity);
|
||||||
|
|
||||||
|
var produce = entity.EnsureComponent<ProduceComponent>();
|
||||||
|
|
||||||
|
produce.Seed = this;
|
||||||
|
produce.Grown();
|
||||||
|
|
||||||
|
if (Mysterious)
|
||||||
|
{
|
||||||
|
entity.Name += "?";
|
||||||
|
entity.Description += Loc.GetString(" On second thought, something about this one looks strange.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Seed Diverge(bool modified)
|
||||||
|
{
|
||||||
|
return Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckHarvest(IEntity user, IEntity held = null)
|
||||||
|
{
|
||||||
|
return (!Ligneous || (Ligneous && held != null && held.HasComponent<BotanySharpComponent>()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Content.Server/Chemistry/PlantMetabolism/AdjustAttribute.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
public abstract class AdjustAttribute : IPlantMetabolizable
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||||
|
|
||||||
|
public float Amount { get; private set; }
|
||||||
|
public float Prob { get; private set; }
|
||||||
|
|
||||||
|
public void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
serializer.DataField(this, x => x.Amount, "amount", 1f);
|
||||||
|
serializer.DataField(this, x => x.Prob, "prob", 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the plant holder can metabolize the reagent or not. Checks if it has an alive plant by default.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plantHolder">The entity holding the plant</param>
|
||||||
|
/// <param name="plantHolderComponent">The plant holder component</param>
|
||||||
|
/// <param name="mustHaveAlivePlant">Whether to check if it has an alive plant or not</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool CanMetabolize(IEntity plantHolder, [NotNullWhen(true)] out PlantHolderComponent? plantHolderComponent, bool mustHaveAlivePlant = true)
|
||||||
|
{
|
||||||
|
plantHolderComponent = null;
|
||||||
|
|
||||||
|
if (plantHolder.Deleted || !plantHolder.TryGetComponent(out plantHolderComponent)
|
||||||
|
|| mustHaveAlivePlant && (plantHolderComponent.Seed == null || plantHolderComponent.Dead))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Prob >= 1f)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return !(Prob <= 0f) && _robustRandom.Prob(Prob);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Content.Server/Chemistry/PlantMetabolism/AdjustHealth.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustHealth : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.Health += Amount;
|
||||||
|
plantHolderComp.CheckHealth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustMutationLevel : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.MutationLevel += Amount * plantHolderComp.MutationMod * customPlantMetabolism;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustMutationMod : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.MutationMod += Amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Content.Server/Chemistry/PlantMetabolism/AdjustNutrition.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustNutrition : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.AdjustNutrient(Amount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Content.Server/Chemistry/PlantMetabolism/AdjustPests.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustPests : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.PestLevel += Amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Content.Server/Chemistry/PlantMetabolism/AdjustToxins.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustToxins : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.Toxins += Amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Content.Server/Chemistry/PlantMetabolism/AdjustWater.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustWater : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.AdjustWater(Amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Content.Server/Chemistry/PlantMetabolism/AdjustWeeds.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AdjustWeeds : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.WeedLevel += Amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Content.Server/Chemistry/PlantMetabolism/AffectGrowth.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class AffectGrowth : AdjustAttribute
|
||||||
|
{
|
||||||
|
public override void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (!CanMetabolize(plantHolder, out var plantHolderComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plantHolderComp.AffectGrowth((int) Amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
Content.Server/Chemistry/PlantMetabolism/Clonexadone.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class Clonexadone : IPlantMetabolizable
|
||||||
|
{
|
||||||
|
public void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1)
|
||||||
|
{
|
||||||
|
if (plantHolder.Deleted || !plantHolder.TryGetComponent(out PlantHolderComponent? plantHolderComp)
|
||||||
|
|| plantHolderComp.Seed == null || plantHolderComp.Dead)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var deviation = 0;
|
||||||
|
var seed = plantHolderComp.Seed;
|
||||||
|
var random = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
if (plantHolderComp.Age > seed.Maturation)
|
||||||
|
deviation = (int) Math.Max(seed.Maturation - 1, plantHolderComp.Age - random.Next(7, 10));
|
||||||
|
else
|
||||||
|
deviation = (int) (seed.Maturation / seed.GrowthStages);
|
||||||
|
plantHolderComp.Age -= deviation;
|
||||||
|
plantHolderComp.SkipAging++;
|
||||||
|
plantHolderComp.ForceUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
Content.Server/Chemistry/PlantMetabolism/Diethylamine.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class Diethylamine : IPlantMetabolizable
|
||||||
|
{
|
||||||
|
public void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1)
|
||||||
|
{
|
||||||
|
if (plantHolder.Deleted || !plantHolder.TryGetComponent(out PlantHolderComponent? plantHolderComp)
|
||||||
|
|| plantHolderComp.Seed == null || plantHolderComp.Dead ||
|
||||||
|
plantHolderComp.Seed.Immutable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var random = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
|
||||||
|
var chance = MathHelper.Lerp(15f, 125f, plantHolderComp.Seed.Lifespan) * 2f * customPlantMetabolism;
|
||||||
|
if (random.Prob(chance))
|
||||||
|
{
|
||||||
|
plantHolderComp.CheckForDivergence(true);
|
||||||
|
plantHolderComp.Seed.Lifespan++;
|
||||||
|
}
|
||||||
|
|
||||||
|
chance = MathHelper.Lerp(15f, 125f, plantHolderComp.Seed.Endurance) * 2f * customPlantMetabolism;
|
||||||
|
if (random.Prob(chance))
|
||||||
|
{
|
||||||
|
plantHolderComp.CheckForDivergence(true);
|
||||||
|
plantHolderComp.Seed.Endurance++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Content.Server/Chemistry/PlantMetabolism/RobustHarvest.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.PlantMetabolism
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class RobustHarvest : IPlantMetabolizable
|
||||||
|
{
|
||||||
|
public void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f)
|
||||||
|
{
|
||||||
|
if (plantHolder.Deleted || !plantHolder.TryGetComponent(out PlantHolderComponent? plantHolderComp)
|
||||||
|
|| plantHolderComp.Seed == null || plantHolderComp.Dead ||
|
||||||
|
plantHolderComp.Seed.Immutable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var random = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
|
||||||
|
var chance = MathHelper.Lerp(15f, 150f, plantHolderComp.Seed.Potency) * 3.5f * customPlantMetabolism;
|
||||||
|
|
||||||
|
if (random.Prob(chance))
|
||||||
|
{
|
||||||
|
plantHolderComp.CheckForDivergence(true);
|
||||||
|
plantHolderComp.Seed.Potency++;
|
||||||
|
}
|
||||||
|
|
||||||
|
chance = MathHelper.Lerp(6f, 2f, plantHolderComp.Seed.Yield) * 0.15f * customPlantMetabolism;
|
||||||
|
|
||||||
|
if (random.Prob(chance))
|
||||||
|
{
|
||||||
|
plantHolderComp.CheckForDivergence(true);
|
||||||
|
plantHolderComp.Seed.Yield--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,12 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components;
|
using Robust.Shared.GameObjects.Components;
|
||||||
|
using Robust.Shared.GameObjects.Components.Transform;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
@@ -17,18 +19,22 @@ namespace Content.Server.GameObjects.Components
|
|||||||
{
|
{
|
||||||
public override string Name => "Anchorable";
|
public override string Name => "Anchorable";
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
serializer.DataField(this, x => x.Tool, "tool", ToolQuality.Anchoring);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public ToolQuality Tool { get; private set; } = ToolQuality.Anchoring;
|
public ToolQuality Tool { get; private set; } = ToolQuality.Anchoring;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
int IInteractUsing.Priority => 1;
|
int IInteractUsing.Priority => 1;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool Snap { get; private set; }
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
serializer.DataField(this, x => x.Tool, "tool", ToolQuality.Anchoring);
|
||||||
|
serializer.DataField(this, x => x.Snap, "snap", false);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a tool can change the anchored status.
|
/// Checks if a tool can change the anchored status.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -73,6 +79,9 @@ namespace Content.Server.GameObjects.Components
|
|||||||
var physics = Owner.GetComponent<IPhysicsComponent>();
|
var physics = Owner.GetComponent<IPhysicsComponent>();
|
||||||
physics.Anchored = true;
|
physics.Anchored = true;
|
||||||
|
|
||||||
|
if (Snap)
|
||||||
|
Owner.SnapToGrid(SnapGridOffset.Center, Owner.EntityManager);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class BotanySharpComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "BotanySharp";
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Content.Server/GameObjects/Components/Botany/HoeComponent.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class HoeComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "Hoe";
|
||||||
|
}
|
||||||
|
}
|
||||||
35
Content.Server/GameObjects/Components/Botany/LogComponent.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Content.Shared.Utility;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class LogComponent : Component, IInteractUsing
|
||||||
|
{
|
||||||
|
public override string Name => "Log";
|
||||||
|
|
||||||
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (!ActionBlockerSystem.CanInteract(eventArgs.User))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eventArgs.Using.HasComponent<BotanySharpComponent>())
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
var plank = Owner.EntityManager.SpawnEntity("WoodPlank1", Owner.Transform.Coordinates);
|
||||||
|
plank.RandomOffset(0.25f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Owner.Delete();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,850 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Content.Server.Atmos;
|
||||||
|
using Content.Server.Botany;
|
||||||
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
|
using Content.Server.GameObjects.Components.Fluids;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
|
using Content.Shared.Audio;
|
||||||
|
using Content.Shared.Chemistry;
|
||||||
|
using Content.Shared.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.Interfaces;
|
||||||
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Content.Shared.Utility;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.ComponentDependencies;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.Interfaces.Timing;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class PlantHolderComponent : Component, IInteractUsing, IInteractHand, IActivate, IReagentReaction, IExamine
|
||||||
|
{
|
||||||
|
public const float HydroponicsSpeedMultiplier = 1f;
|
||||||
|
public const float HydroponicsConsumptionMultiplier = 4f;
|
||||||
|
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
|
public override string Name => "PlantHolder";
|
||||||
|
|
||||||
|
[ViewVariables] private int _lastProduce;
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)] private int _missingGas;
|
||||||
|
private readonly TimeSpan _cycleDelay = TimeSpan.FromSeconds(15f);
|
||||||
|
[ViewVariables] private TimeSpan _lastCycle = TimeSpan.Zero;
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)] private bool _updateSpriteAfterUpdate;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool DrawWarnings { get; private set; } = false;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float WaterLevel { get; private set; } = 100f;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float NutritionLevel { get; private set; } = 100f;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float PestLevel { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float WeedLevel { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Toxins { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public int Age { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public int SkipAging { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool Dead { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool Harvest { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool Sampled { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public int YieldMod { get; set; } = 1;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float MutationMod { get; set; } = 1f;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float MutationLevel { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Health { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float WeedCoefficient { get; set; } = 1f;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public Seed? Seed { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool ImproperHeat { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool ImproperPressure { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool ImproperLight { get; set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool ForceUpdate { get; set; }
|
||||||
|
|
||||||
|
[ComponentDependency] private readonly SolutionContainerComponent? _solutionContainer = default!;
|
||||||
|
[ComponentDependency] private readonly AppearanceComponent? _appearanceComponent = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
if(!Owner.EnsureComponent<SolutionContainerComponent>(out var solution))
|
||||||
|
Logger.Warning($"Entity {Owner} with a PlantHolderComponent did not have a SolutionContainerComponent.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
serializer.DataField(this, x => x.DrawWarnings, "drawWarnings", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WeedInvasion()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
UpdateReagents();
|
||||||
|
|
||||||
|
var curTime = _gameTiming.CurTime;
|
||||||
|
|
||||||
|
if (ForceUpdate)
|
||||||
|
ForceUpdate = false;
|
||||||
|
else if (curTime < (_lastCycle + _cycleDelay))
|
||||||
|
{
|
||||||
|
if(_updateSpriteAfterUpdate)
|
||||||
|
UpdateSprite();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastCycle = curTime;
|
||||||
|
|
||||||
|
|
||||||
|
// Weeds like water and nutrients! They may appear even if there's not a seed planted.
|
||||||
|
if (WaterLevel > 10 && NutritionLevel > 2 && _random.Prob(Seed == null ? 0.05f : 0.01f))
|
||||||
|
{
|
||||||
|
WeedLevel += 1 * HydroponicsSpeedMultiplier * WeedCoefficient;
|
||||||
|
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's a chance for a weed explosion to happen if weeds take over.
|
||||||
|
// Plants that are themselves weeds (WeedTolerance > 8) are unaffected.
|
||||||
|
if (WeedLevel >= 10 && _random.Prob(0.1f))
|
||||||
|
{
|
||||||
|
if (Seed == null || WeedLevel >= Seed.WeedTolerance + 2)
|
||||||
|
WeedInvasion();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have no seed planted, or the plant is dead, stop processing here.
|
||||||
|
if (Seed == null || Dead)
|
||||||
|
{
|
||||||
|
if (_updateSpriteAfterUpdate)
|
||||||
|
UpdateSprite();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's a small chance the pest population increases.
|
||||||
|
// Can only happen when there's a live seed planted.
|
||||||
|
if (_random.Prob(0.01f))
|
||||||
|
{
|
||||||
|
PestLevel += 0.5f * HydroponicsSpeedMultiplier;
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance plant age here.
|
||||||
|
if (SkipAging > 0)
|
||||||
|
SkipAging--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(_random.Prob(0.8f))
|
||||||
|
Age += (int)(1 * HydroponicsSpeedMultiplier);
|
||||||
|
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nutrient consumption.
|
||||||
|
if (Seed.NutrientConsumption > 0 && NutritionLevel > 0 && _random.Prob(0.75f))
|
||||||
|
{
|
||||||
|
NutritionLevel -= MathF.Max(0f, Seed.NutrientConsumption * HydroponicsSpeedMultiplier);
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Water consumption.
|
||||||
|
if (Seed.WaterConsumption > 0 && WaterLevel > 0 && _random.Prob(0.75f))
|
||||||
|
{
|
||||||
|
WaterLevel -= MathF.Max(0f, Seed.NutrientConsumption * HydroponicsConsumptionMultiplier * HydroponicsSpeedMultiplier);
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var healthMod = _random.Next(1, 3) * HydroponicsSpeedMultiplier;
|
||||||
|
|
||||||
|
// Make sure the plant is not starving.
|
||||||
|
if (_random.Prob(0.35f))
|
||||||
|
{
|
||||||
|
if (NutritionLevel > 2)
|
||||||
|
{
|
||||||
|
Health += healthMod;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AffectGrowth(-1);
|
||||||
|
Health -= healthMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the plant is not thirsty.
|
||||||
|
if (_random.Prob(0.35f))
|
||||||
|
{
|
||||||
|
if (WaterLevel > 10)
|
||||||
|
{
|
||||||
|
Health += healthMod;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AffectGrowth(-1);
|
||||||
|
Health -= healthMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tileAtmos = Owner.Transform.Coordinates.GetTileAtmosphere();
|
||||||
|
var environment = tileAtmos?.Air ?? GasMixture.SpaceGas;
|
||||||
|
|
||||||
|
if (Seed.ConsumeGasses.Count > 0)
|
||||||
|
{
|
||||||
|
_missingGas = 0;
|
||||||
|
|
||||||
|
foreach (var (gas, amount) in Seed.ConsumeGasses)
|
||||||
|
{
|
||||||
|
if (environment.GetMoles(gas) < amount)
|
||||||
|
{
|
||||||
|
_missingGas++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
environment.AdjustMoles(gas, -amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_missingGas > 0)
|
||||||
|
{
|
||||||
|
Health -= _missingGas * HydroponicsSpeedMultiplier;
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed pressure resistance.
|
||||||
|
var pressure = environment.Pressure;
|
||||||
|
if (pressure < Seed.LowPressureTolerance || pressure > Seed.HighPressureTolerance)
|
||||||
|
{
|
||||||
|
Health -= healthMod;
|
||||||
|
ImproperPressure = true;
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImproperPressure = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed ideal temperature.
|
||||||
|
if (MathF.Abs(environment.Temperature - Seed.IdealHeat) > Seed.HeatTolerance)
|
||||||
|
{
|
||||||
|
Health -= healthMod;
|
||||||
|
ImproperHeat = true;
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImproperHeat = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gas production.
|
||||||
|
var exudeCount = Seed.ExudeGasses.Count;
|
||||||
|
if (exudeCount > 0)
|
||||||
|
{
|
||||||
|
foreach (var (gas, amount) in Seed.ExudeGasses)
|
||||||
|
{
|
||||||
|
environment.AdjustMoles(gas, MathF.Max(1f, MathF.Round((amount * MathF.Round(Seed.Potency)) / exudeCount)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toxin levels beyond the plant's tolerance cause damage.
|
||||||
|
// They are, however, slowly reduced over time.
|
||||||
|
if (Toxins > 0)
|
||||||
|
{
|
||||||
|
var toxinUptake = MathF.Max(1, MathF.Round(Toxins / 10f));
|
||||||
|
if (Toxins > Seed.ToxinsTolerance)
|
||||||
|
{
|
||||||
|
Health -= toxinUptake;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toxins -= toxinUptake;
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weed levels.
|
||||||
|
if (PestLevel > 0)
|
||||||
|
{
|
||||||
|
// TODO: Carnivorous plants?
|
||||||
|
if (PestLevel > Seed.PestTolerance)
|
||||||
|
{
|
||||||
|
Health -= HydroponicsSpeedMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weed levels.
|
||||||
|
if (WeedLevel > 0)
|
||||||
|
{
|
||||||
|
// TODO: Parasitic plants.
|
||||||
|
if (WeedLevel >= Seed.WeedTolerance)
|
||||||
|
{
|
||||||
|
Health -= HydroponicsSpeedMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Age > Seed.Lifespan)
|
||||||
|
{
|
||||||
|
Health -= _random.Next(3, 5) * HydroponicsSpeedMultiplier;
|
||||||
|
if (DrawWarnings)
|
||||||
|
_updateSpriteAfterUpdate = true;
|
||||||
|
}
|
||||||
|
else if(Age < 0) // Revert back to seed packet!
|
||||||
|
{
|
||||||
|
Seed.SpawnSeedPacket(Owner.Transform.Coordinates);
|
||||||
|
RemovePlant();
|
||||||
|
ForceUpdate = true;
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckHealth();
|
||||||
|
|
||||||
|
if (Harvest && Seed.HarvestRepeat == HarvestType.SelfHarvest)
|
||||||
|
AutoHarvest();
|
||||||
|
|
||||||
|
// If enough time has passed since the plant was harvested, we're ready to harvest again!
|
||||||
|
if (!Dead && Seed.ProductPrototypes.Count > 0)
|
||||||
|
{
|
||||||
|
if (Age > Seed.Production)
|
||||||
|
{
|
||||||
|
if ((Age - _lastProduce) > Seed.Production && !Harvest)
|
||||||
|
{
|
||||||
|
Harvest = true;
|
||||||
|
_lastProduce = Age;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Harvest)
|
||||||
|
{
|
||||||
|
Harvest = false;
|
||||||
|
_lastProduce = Age;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckLevelSanity();
|
||||||
|
|
||||||
|
if(_updateSpriteAfterUpdate)
|
||||||
|
UpdateSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckLevelSanity()
|
||||||
|
{
|
||||||
|
if (Seed != null)
|
||||||
|
Health = MathHelper.Clamp(Health, 0, Seed.Endurance);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Health = 0f;
|
||||||
|
Dead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutationLevel = MathHelper.Clamp(MutationLevel, 0f, 100f);
|
||||||
|
NutritionLevel = MathHelper.Clamp(NutritionLevel, 0f, 100f);
|
||||||
|
WaterLevel = MathHelper.Clamp(WaterLevel, 0f, 100f);
|
||||||
|
PestLevel = MathHelper.Clamp(PestLevel, 0f, 10f);
|
||||||
|
WeedLevel = MathHelper.Clamp(WeedLevel, 0f, 10f);
|
||||||
|
Toxins = MathHelper.Clamp(Toxins, 0f, 100f);
|
||||||
|
YieldMod = MathHelper.Clamp(YieldMod, 0, 2);
|
||||||
|
MutationMod = MathHelper.Clamp(MutationMod, 0f, 3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DoHarvest(IEntity user)
|
||||||
|
{
|
||||||
|
if (Seed == null || user.Deleted || !ActionBlockerSystem.CanInteract(user))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Harvest && !Dead)
|
||||||
|
{
|
||||||
|
if (user.TryGetComponent(out HandsComponent? hands))
|
||||||
|
{
|
||||||
|
if (!Seed.CheckHarvest(user, hands.GetActiveHand?.Owner))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if (!Seed.CheckHarvest(user))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Seed.Harvest(user, YieldMod);
|
||||||
|
AfterHarvest();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Dead) return false;
|
||||||
|
|
||||||
|
RemovePlant();
|
||||||
|
AfterHarvest();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AutoHarvest()
|
||||||
|
{
|
||||||
|
if (Seed == null || !Harvest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Seed.AutoHarvest(Owner.Transform.Coordinates);
|
||||||
|
AfterHarvest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AfterHarvest()
|
||||||
|
{
|
||||||
|
Harvest = false;
|
||||||
|
_lastProduce = Age;
|
||||||
|
|
||||||
|
if(Seed?.HarvestRepeat == HarvestType.NoRepeat)
|
||||||
|
RemovePlant();
|
||||||
|
|
||||||
|
CheckLevelSanity();
|
||||||
|
UpdateSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckHealth()
|
||||||
|
{
|
||||||
|
if (Health <= 0)
|
||||||
|
{
|
||||||
|
Die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Die()
|
||||||
|
{
|
||||||
|
Dead = true;
|
||||||
|
Harvest = false;
|
||||||
|
MutationLevel = 0;
|
||||||
|
YieldMod = 1;
|
||||||
|
MutationMod = 1;
|
||||||
|
ImproperLight = false;
|
||||||
|
ImproperHeat = false;
|
||||||
|
ImproperPressure = false;
|
||||||
|
WeedLevel += 1 * HydroponicsSpeedMultiplier;
|
||||||
|
PestLevel = 0;
|
||||||
|
UpdateSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePlant()
|
||||||
|
{
|
||||||
|
YieldMod = 1;
|
||||||
|
MutationMod = 1;
|
||||||
|
PestLevel = 0;
|
||||||
|
Seed = null;
|
||||||
|
Dead = false;
|
||||||
|
Age = 0;
|
||||||
|
Sampled = false;
|
||||||
|
Harvest = false;
|
||||||
|
ImproperLight = false;
|
||||||
|
ImproperPressure = false;
|
||||||
|
ImproperHeat = false;
|
||||||
|
|
||||||
|
UpdateSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AffectGrowth(int amount)
|
||||||
|
{
|
||||||
|
if (Seed == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (amount > 0)
|
||||||
|
{
|
||||||
|
if (Age < Seed.Maturation)
|
||||||
|
Age += amount;
|
||||||
|
else if (!Harvest && Seed.Yield <= 0f)
|
||||||
|
_lastProduce -= amount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Age < Seed.Maturation)
|
||||||
|
SkipAging++;
|
||||||
|
else if (!Harvest && Seed.Yield <= 0f)
|
||||||
|
_lastProduce += amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AdjustNutrient(float amount)
|
||||||
|
{
|
||||||
|
NutritionLevel += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AdjustWater(float amount)
|
||||||
|
{
|
||||||
|
WaterLevel += amount;
|
||||||
|
|
||||||
|
// Water dilutes toxins.
|
||||||
|
if (amount > 0)
|
||||||
|
{
|
||||||
|
Toxins -= amount * 4f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateReagents()
|
||||||
|
{
|
||||||
|
if (_solutionContainer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_solutionContainer.Solution.TotalVolume <= 0 || MutationLevel >= 25)
|
||||||
|
{
|
||||||
|
if (MutationLevel >= 0)
|
||||||
|
{
|
||||||
|
Mutate(Math.Min(MutationLevel, 25));
|
||||||
|
MutationLevel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var one = ReagentUnit.New(1);
|
||||||
|
|
||||||
|
foreach (var (reagent, amount) in _solutionContainer.ReagentList.ToArray())
|
||||||
|
{
|
||||||
|
var reagentProto = _prototypeManager.Index<ReagentPrototype>(reagent);
|
||||||
|
reagentProto.ReactionPlant(Owner);
|
||||||
|
_solutionContainer.Solution.RemoveReagent(reagent, amount < one ? amount : one);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckLevelSanity();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Mutate(float severity)
|
||||||
|
{
|
||||||
|
// TODO: Coming soon in "Botany 2: Plant boogaloo".
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSprite()
|
||||||
|
{
|
||||||
|
_updateSpriteAfterUpdate = false;
|
||||||
|
|
||||||
|
if (_appearanceComponent == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Seed != null)
|
||||||
|
{
|
||||||
|
if(DrawWarnings)
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.HealthLight, Health <= (Seed.Endurance / 2f));
|
||||||
|
|
||||||
|
if (Dead)
|
||||||
|
{
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.Plant, new SpriteSpecifier.Rsi(Seed.PlantRsi, "dead"));
|
||||||
|
}
|
||||||
|
else if (Harvest)
|
||||||
|
{
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.Plant, new SpriteSpecifier.Rsi(Seed.PlantRsi, "harvest"));
|
||||||
|
}
|
||||||
|
else if (Age < Seed.Maturation)
|
||||||
|
{
|
||||||
|
var growthStage = Math.Max(1, (int)((Age * Seed.GrowthStages) / Seed.Maturation));
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.Plant, new SpriteSpecifier.Rsi(Seed.PlantRsi,$"stage-{growthStage}"));
|
||||||
|
_lastProduce = Age;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.Plant, new SpriteSpecifier.Rsi(Seed.PlantRsi,$"stage-{Seed.GrowthStages}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.Plant, SpriteSpecifier.Invalid);
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.HealthLight, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DrawWarnings) return;
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.WaterLight, WaterLevel <= 10);
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.NutritionLight, NutritionLevel <= 2);
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.AlertLight, WeedLevel >= 5 || PestLevel >= 5 || Toxins >= 40 || ImproperHeat || ImproperLight || ImproperPressure || _missingGas > 0);
|
||||||
|
_appearanceComponent.SetData(PlantHolderVisuals.HarvestLight, Harvest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckForDivergence(bool modified)
|
||||||
|
{
|
||||||
|
// Make sure we're not modifying a "global" seed.
|
||||||
|
// If this seed is not in the global seed list, then no products of this line have been harvested yet.
|
||||||
|
// It is then safe to assume it's restricted to this tray.
|
||||||
|
if (Seed == null) return;
|
||||||
|
var plantSystem = EntitySystem.Get<PlantSystem>();
|
||||||
|
if (plantSystem.Seeds.ContainsKey(Seed.Uid))
|
||||||
|
Seed = Seed.Diverge(modified);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
var user = eventArgs.User;
|
||||||
|
var usingItem = eventArgs.Using;
|
||||||
|
|
||||||
|
if (usingItem == null || usingItem.Deleted || !ActionBlockerSystem.CanInteract(user))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (usingItem.TryGetComponent(out SeedComponent? seeds))
|
||||||
|
{
|
||||||
|
if (Seed == null)
|
||||||
|
{
|
||||||
|
if (seeds.Seed == null)
|
||||||
|
{
|
||||||
|
user.PopupMessageCursor(Loc.GetString("The packet seems to be empty. You throw it away."));
|
||||||
|
usingItem.Delete();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
user.PopupMessageCursor(Loc.GetString("You plant the {0} {1}.", seeds.Seed.SeedName, seeds.Seed.SeedNoun));
|
||||||
|
|
||||||
|
Seed = seeds.Seed;
|
||||||
|
Dead = false;
|
||||||
|
Age = 1;
|
||||||
|
Health = Seed.Endurance;
|
||||||
|
_lastCycle = _gameTiming.CurTime;
|
||||||
|
|
||||||
|
usingItem.Delete();
|
||||||
|
|
||||||
|
CheckLevelSanity();
|
||||||
|
UpdateSprite();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
user.PopupMessageCursor(Loc.GetString("The {0} already has seeds in it!", Owner.Name));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usingItem.HasComponent<HoeComponent>())
|
||||||
|
{
|
||||||
|
if (WeedLevel > 0)
|
||||||
|
{
|
||||||
|
user.PopupMessageCursor(Loc.GetString("You remove the weeds from the {0}.", Owner.Name));
|
||||||
|
user.PopupMessageOtherClients(Loc.GetString("{0} starts uprooting the weeds.", user.Name));
|
||||||
|
WeedLevel = 0;
|
||||||
|
UpdateSprite();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.PopupMessageCursor(Loc.GetString("This plot is devoid of weeds! It doesn't need uprooting."));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usingItem.TryGetComponent(out SolutionContainerComponent? solution) && solution.CanRemoveSolutions)
|
||||||
|
{
|
||||||
|
var amount = 5f;
|
||||||
|
var sprayed = false;
|
||||||
|
|
||||||
|
if (usingItem.TryGetComponent(out SprayComponent? spray))
|
||||||
|
{
|
||||||
|
sprayed = true;
|
||||||
|
amount = 1f;
|
||||||
|
EntitySystem.Get<AudioSystem>().PlayFromEntity(spray.SpraySound, usingItem, AudioHelpers.WithVariation(0.125f));
|
||||||
|
}
|
||||||
|
|
||||||
|
var chemAmount = ReagentUnit.New(amount);
|
||||||
|
|
||||||
|
var split = solution.Solution.SplitSolution(chemAmount <= solution.Solution.TotalVolume ? chemAmount : solution.Solution.TotalVolume);
|
||||||
|
|
||||||
|
user.PopupMessageCursor(Loc.GetString(sprayed ? $"You spray {Owner.Name} with {usingItem.Name}." : $"You transfer {split.TotalVolume.ToString()}u to {Owner.Name}"));
|
||||||
|
|
||||||
|
_solutionContainer?.TryAddSolution(split);
|
||||||
|
|
||||||
|
SkipAging++; // We're forcing an update cycle, so one age hasn't passed.
|
||||||
|
ForceUpdate = true;
|
||||||
|
Update();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usingItem.HasComponent<PlantSampleTakerComponent>())
|
||||||
|
{
|
||||||
|
if (Seed == null)
|
||||||
|
{
|
||||||
|
user.PopupMessageCursor(Loc.GetString("There is nothing to take a sample of!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Sampled)
|
||||||
|
{
|
||||||
|
user.PopupMessageCursor(Loc.GetString("This plant has already been sampled."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dead)
|
||||||
|
{
|
||||||
|
user.PopupMessageCursor(Loc.GetString("This plant is dead."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var seed = Seed.SpawnSeedPacket(user.Transform.Coordinates);
|
||||||
|
seed.RandomOffset(0.25f);
|
||||||
|
user.PopupMessageCursor(Loc.GetString($"You take a sample from the {Seed.DisplayName}."));
|
||||||
|
Health -= (_random.Next(3, 5) * 10);
|
||||||
|
|
||||||
|
if (_random.Prob(0.3f))
|
||||||
|
Sampled = true;
|
||||||
|
|
||||||
|
// Just in case.
|
||||||
|
CheckLevelSanity();
|
||||||
|
SkipAging++; // We're forcing an update cycle, so one age hasn't passed.
|
||||||
|
ForceUpdate = true;
|
||||||
|
Update();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usingItem.HasComponent<BotanySharpComponent>())
|
||||||
|
{
|
||||||
|
return DoHarvest(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReagentUnit ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume)
|
||||||
|
{
|
||||||
|
if(_solutionContainer == null)
|
||||||
|
return ReagentUnit.Zero;
|
||||||
|
|
||||||
|
_solutionContainer.TryAddReagent(reagent.ID, volume, out var accepted);
|
||||||
|
return accepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReagentUnit ReagentReactInjection(ReagentPrototype reagent, ReagentUnit volume)
|
||||||
|
{
|
||||||
|
if(_solutionContainer == null)
|
||||||
|
return ReagentUnit.Zero;
|
||||||
|
|
||||||
|
_solutionContainer.TryAddReagent(reagent.ID, volume, out var accepted);
|
||||||
|
return accepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool InteractHand(InteractHandEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
// DoHarvest does the sanity checks.
|
||||||
|
return DoHarvest(eventArgs.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate(ActivateEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
// DoHarvest does the sanity checks.
|
||||||
|
DoHarvest(eventArgs.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Examine(FormattedMessage message, bool inDetailsRange)
|
||||||
|
{
|
||||||
|
if (!inDetailsRange)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Seed == null)
|
||||||
|
{
|
||||||
|
message.AddMarkup(Loc.GetString("It has nothing planted in it.\n"));
|
||||||
|
}
|
||||||
|
else if (!Dead)
|
||||||
|
{
|
||||||
|
message.AddMarkup(Loc.GetString($"[color=green]{Seed.DisplayName}[/color] {(Seed.DisplayName.EndsWith('s') ? "are" : "is")} growing here.\n"));
|
||||||
|
|
||||||
|
if(Health <= Seed.Endurance / 2)
|
||||||
|
message.AddMarkup(Loc.GetString($"The plant looks [color=red]{(Age > Seed.Lifespan ? "old and wilting" : "unhealthy")}[/color].\n"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message.AddMarkup(Loc.GetString("It is full of [color=red]dead plant matter[/color].\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(WeedLevel >= 5)
|
||||||
|
message.AddMarkup(Loc.GetString("It is filled with [color=green]weeds[/color]!\n"));
|
||||||
|
|
||||||
|
if(PestLevel >= 5)
|
||||||
|
message.AddMarkup(Loc.GetString("It is filled with [color=gray]tiny worms[/color]!\n"));
|
||||||
|
|
||||||
|
message.AddMarkup(Loc.GetString($"Water: [color=cyan]{(int)WaterLevel}[/color]\n"));
|
||||||
|
message.AddMarkup(Loc.GetString($"Nutrient: [color=orange]{(int)NutritionLevel}[/color]\n"));
|
||||||
|
|
||||||
|
if (DrawWarnings)
|
||||||
|
{
|
||||||
|
if(Toxins > 40f)
|
||||||
|
message.AddMarkup(Loc.GetString("The [color=red]toxicity level alert[/color] is flashing red.\n"));
|
||||||
|
|
||||||
|
if(ImproperLight)
|
||||||
|
message.AddMarkup(Loc.GetString("The [color=yellow]improper light level alert[/color] is blinking.\n"));
|
||||||
|
|
||||||
|
if(ImproperHeat)
|
||||||
|
message.AddMarkup(Loc.GetString("The [color=orange]improper temperature level alert[/color] is blinking.\n"));
|
||||||
|
|
||||||
|
if(ImproperPressure)
|
||||||
|
message.AddMarkup(Loc.GetString("The [color=lightblue]improper environment pressure alert[/color] is blinking.\n"));
|
||||||
|
|
||||||
|
if(_missingGas > 0)
|
||||||
|
message.AddMarkup(Loc.GetString("The [color=cyan]improper gas environment alert[/color] is blinking.\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class PlantSampleTakerComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "PlantSampleTaker";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using Content.Server.Botany;
|
||||||
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
|
using Content.Shared.Chemistry;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class ProduceComponent : Component
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
public override string Name => "Produce";
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public Seed Seed { get; set; } = null;
|
||||||
|
|
||||||
|
public float Potency => Seed.Potency;
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
|
||||||
|
serializer.DataReadFunction<string>("seed", null,
|
||||||
|
(s) =>
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(s))
|
||||||
|
Seed = _prototypeManager.Index<Seed>(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Grown()
|
||||||
|
{
|
||||||
|
if (Seed == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out SpriteComponent sprite))
|
||||||
|
{
|
||||||
|
sprite.LayerSetRSI(0, Seed.PlantRsi);
|
||||||
|
sprite.LayerSetState(0, Seed.PlantIconState);
|
||||||
|
}
|
||||||
|
|
||||||
|
var solutionContainer = Owner.EnsureComponent<SolutionContainerComponent>();
|
||||||
|
|
||||||
|
solutionContainer.RemoveAllSolution();
|
||||||
|
|
||||||
|
foreach (var (chem, quantity) in Seed.Chemicals)
|
||||||
|
{
|
||||||
|
var amount = ReagentUnit.New(quantity.Min);
|
||||||
|
if(quantity.PotencyDivisor > 0 && Potency > 0)
|
||||||
|
amount += ReagentUnit.New(Potency/quantity.PotencyDivisor);
|
||||||
|
amount = ReagentUnit.New((int) MathHelper.Clamp(amount.Float(), quantity.Min, quantity.Max));
|
||||||
|
solutionContainer.MaxVolume += amount;
|
||||||
|
solutionContainer.Solution.AddReagent(chem, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using Content.Server.Botany;
|
||||||
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class SeedComponent : Component, IExamine
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
|
public override string Name => "Seed";
|
||||||
|
[ViewVariables]
|
||||||
|
public Seed Seed { get; set; } = null;
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
|
||||||
|
serializer.DataReadFunction<string>("seed", null,
|
||||||
|
(s) =>
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(s))
|
||||||
|
Seed = _prototypeManager.Index<Seed>(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Examine(FormattedMessage message, bool inDetailsRange)
|
||||||
|
{
|
||||||
|
if (!inDetailsRange)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Seed == null)
|
||||||
|
{
|
||||||
|
message.AddMarkup(Loc.GetString("It doesn't seem to contain any seeds.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.AddMarkup(Loc.GetString($"It has a picture of [color=yellow]{Seed.DisplayName}[/color] on the front.\n"));
|
||||||
|
|
||||||
|
if(!Seed.RoundStart)
|
||||||
|
message.AddMarkup(Loc.GetString($"It's tagged as variety [color=lightgray]no. {Seed.Uid}[/color].\n"));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message.AddMarkup(Loc.GetString($"Plant Yield: [color=lightblue]{Seed.Yield}[/color]\n"));
|
||||||
|
message.AddMarkup(Loc.GetString($"Plant Potency: [color=lightblue]{Seed.Potency}[/color]\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
|
using Content.Server.Utility;
|
||||||
|
using Content.Shared.GameObjects.Components.Botany;
|
||||||
|
using Content.Shared.Interfaces;
|
||||||
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.ComponentDependencies;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class SeedExtractorComponent : Component, IInteractUsing
|
||||||
|
{
|
||||||
|
[ComponentDependency] private readonly PowerReceiverComponent? _powerReceiver = default!;
|
||||||
|
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
public override string Name => "SeedExtractor";
|
||||||
|
|
||||||
|
// TODO: Upgradeable machines.
|
||||||
|
private int _minSeeds = 1;
|
||||||
|
private int _maxSeeds = 4;
|
||||||
|
|
||||||
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (!_powerReceiver?.Powered ?? false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eventArgs.Using.TryGetComponent(out ProduceComponent? produce) && produce.Seed != null)
|
||||||
|
{
|
||||||
|
eventArgs.User.PopupMessageCursor(Loc.GetString("You extract some seeds from the {0}.", eventArgs.Using.Name));
|
||||||
|
|
||||||
|
eventArgs.Using.Delete();
|
||||||
|
|
||||||
|
var random = _random.Next(_minSeeds, _maxSeeds);
|
||||||
|
|
||||||
|
for (var i = 0; i < random; i++)
|
||||||
|
{
|
||||||
|
produce.Seed.SpawnSeedPacket(Owner.Transform.Coordinates, Owner.EntityManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,6 +67,8 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
set => _sprayVelocity = value;
|
set => _sprayVelocity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string SpraySound => _spraySound;
|
||||||
|
|
||||||
public ReagentUnit CurrentVolume => Owner.GetComponentOrNull<SolutionContainerComponent>()?.CurrentVolume ?? ReagentUnit.Zero;
|
public ReagentUnit CurrentVolume => Owner.GetComponentOrNull<SolutionContainerComponent>()?.CurrentVolume ?? ReagentUnit.Zero;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
|
|||||||
70
Content.Server/GameObjects/EntitySystems/PlantSystem.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.Botany;
|
||||||
|
using Content.Server.GameObjects.Components.Botany;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Timing;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class PlantSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IComponentManager _componentManager = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
|
private int _nextUid = 0;
|
||||||
|
private readonly Dictionary<int, Seed> _seeds = new Dictionary<int,Seed>();
|
||||||
|
|
||||||
|
private float _timer = 0f;
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<int, Seed> Seeds => _seeds;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
foreach (var seed in _prototypeManager.EnumeratePrototypes<Seed>())
|
||||||
|
{
|
||||||
|
AddSeedToDatabase(seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddSeedToDatabase(Seed seed)
|
||||||
|
{
|
||||||
|
// If it's not -1, it's already in the database. Probably.
|
||||||
|
if (seed.Uid != -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
seed.Uid = GetNextSeedUid();
|
||||||
|
_seeds[seed.Uid] = seed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetNextSeedUid()
|
||||||
|
{
|
||||||
|
return _nextUid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
_timer += frameTime;
|
||||||
|
if (_timer < 3f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_timer = 0f;
|
||||||
|
|
||||||
|
foreach (var plantHolder in _componentManager.EntityQuery<PlantHolderComponent>())
|
||||||
|
{
|
||||||
|
plantHolder.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,9 +23,11 @@ namespace Content.Shared.Chemistry
|
|||||||
private string _description;
|
private string _description;
|
||||||
private string _physicalDescription;
|
private string _physicalDescription;
|
||||||
private Color _substanceColor;
|
private Color _substanceColor;
|
||||||
private List<IMetabolizable> _metabolism;
|
|
||||||
private string _spritePath;
|
private string _spritePath;
|
||||||
|
private List<IMetabolizable> _metabolism;
|
||||||
private List<ITileReaction> _tileReactions;
|
private List<ITileReaction> _tileReactions;
|
||||||
|
private List<IPlantMetabolizable> _plantMetabolism;
|
||||||
|
private float _customPlantMetabolism = 1f;
|
||||||
|
|
||||||
public string ID => _id;
|
public string ID => _id;
|
||||||
public string Name => _name;
|
public string Name => _name;
|
||||||
@@ -34,8 +36,9 @@ namespace Content.Shared.Chemistry
|
|||||||
public Color SubstanceColor => _substanceColor;
|
public Color SubstanceColor => _substanceColor;
|
||||||
|
|
||||||
//List of metabolism effects this reagent has, should really only be used server-side.
|
//List of metabolism effects this reagent has, should really only be used server-side.
|
||||||
public List<IMetabolizable> Metabolism => _metabolism;
|
public IReadOnlyList<IMetabolizable> Metabolism => _metabolism;
|
||||||
public List<ITileReaction> TileReactions => _tileReactions;
|
public IReadOnlyList<ITileReaction> TileReactions => _tileReactions;
|
||||||
|
public IReadOnlyList<IPlantMetabolizable> PlantMetabolism => _plantMetabolism;
|
||||||
public string SpriteReplacementPath => _spritePath;
|
public string SpriteReplacementPath => _spritePath;
|
||||||
|
|
||||||
public ReagentPrototype()
|
public ReagentPrototype()
|
||||||
@@ -53,16 +56,19 @@ namespace Content.Shared.Chemistry
|
|||||||
serializer.DataField(ref _physicalDescription, "physicalDesc", string.Empty);
|
serializer.DataField(ref _physicalDescription, "physicalDesc", string.Empty);
|
||||||
serializer.DataField(ref _substanceColor, "color", Color.White);
|
serializer.DataField(ref _substanceColor, "color", Color.White);
|
||||||
serializer.DataField(ref _spritePath, "spritePath", string.Empty);
|
serializer.DataField(ref _spritePath, "spritePath", string.Empty);
|
||||||
|
serializer.DataField(ref _customPlantMetabolism, "customPlantMetabolism", 1f);
|
||||||
|
|
||||||
if (_moduleManager.IsServerModule)
|
if (_moduleManager.IsServerModule)
|
||||||
{
|
{
|
||||||
serializer.DataField(ref _metabolism, "metabolism", new List<IMetabolizable> { new DefaultMetabolizable() });
|
serializer.DataField(ref _metabolism, "metabolism", new List<IMetabolizable> { new DefaultMetabolizable() });
|
||||||
serializer.DataField(ref _tileReactions, "tileReactions", new List<ITileReaction> { });
|
serializer.DataField(ref _tileReactions, "tileReactions", new List<ITileReaction> { });
|
||||||
|
serializer.DataField(ref _plantMetabolism, "plantMetabolism", new List<IPlantMetabolizable> { });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_metabolism = new List<IMetabolizable> { new DefaultMetabolizable() };
|
_metabolism = new List<IMetabolizable> { new DefaultMetabolizable() };
|
||||||
_tileReactions = new List<ITileReaction>();
|
_tileReactions = new List<ITileReaction>(0);
|
||||||
|
_plantMetabolism = new List<IPlantMetabolizable>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,5 +142,16 @@ namespace Content.Shared.Chemistry
|
|||||||
|
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ReactionPlant(IEntity plantHolder)
|
||||||
|
{
|
||||||
|
if (plantHolder == null || plantHolder.Deleted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var plantMetabolizable in _plantMetabolism)
|
||||||
|
{
|
||||||
|
plantMetabolizable.Metabolize(plantHolder, _customPlantMetabolism);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.GameObjects.Components.Botany
|
||||||
|
{
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum PlantHolderVisuals
|
||||||
|
{
|
||||||
|
Plant,
|
||||||
|
HealthLight,
|
||||||
|
WaterLight,
|
||||||
|
NutritionLight,
|
||||||
|
AlertLight,
|
||||||
|
HarvestLight,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -127,6 +127,7 @@ namespace Content.Shared.GameObjects.Components
|
|||||||
Glass,
|
Glass,
|
||||||
Plasteel,
|
Plasteel,
|
||||||
Cable,
|
Cable,
|
||||||
|
Wood,
|
||||||
MVCable,
|
MVCable,
|
||||||
HVCable,
|
HVCable,
|
||||||
Gold,
|
Gold,
|
||||||
|
|||||||
17
Content.Shared/Interfaces/Chemistry/IPlantMetabolizable.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Content.Shared.Chemistry;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Interfaces.Chemistry
|
||||||
|
{
|
||||||
|
public interface IPlantMetabolizable : IExposeData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Metabolize <paramref name="customPlantMetabolism"/> unit(s) of a reagent.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plantHolder">Entity holding the plant</param>
|
||||||
|
/// <param name="customPlantMetabolism">Units to metabolize</param>
|
||||||
|
void Metabolize(IEntity plantHolder, float customPlantMetabolism = 1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
Content.Shared/Utility/EntityPrototypeHelpers.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.Utility
|
||||||
|
{
|
||||||
|
public static class EntityPrototypeHelpers
|
||||||
|
{
|
||||||
|
public static bool HasComponent<T>(string prototype, IPrototypeManager? prototypeManager = null, IComponentFactory? componentFactory = null) where T : IComponent
|
||||||
|
{
|
||||||
|
return HasComponent(prototype, typeof(T), prototypeManager, componentFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool HasComponent(string prototype, Type component, IPrototypeManager? prototypeManager = null, IComponentFactory? componentFactory = null)
|
||||||
|
{
|
||||||
|
prototypeManager ??= IoCManager.Resolve<IPrototypeManager>();
|
||||||
|
componentFactory ??= IoCManager.Resolve<IComponentFactory>();
|
||||||
|
|
||||||
|
var registration = componentFactory.GetRegistration(component);
|
||||||
|
|
||||||
|
if (!prototypeManager.TryIndex(prototype, out EntityPrototype proto))
|
||||||
|
{
|
||||||
|
return proto.Components.ContainsKey(registration.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,3 +4,16 @@
|
|||||||
description: For when you need seeds fast. Hands down the best seed selection on the station!
|
description: For when you need seeds fast. Hands down the best seed selection on the station!
|
||||||
animationDuration: 1.3
|
animationDuration: 1.3
|
||||||
spriteName: seeds
|
spriteName: seeds
|
||||||
|
startingInventory:
|
||||||
|
WheatSeeds: 10
|
||||||
|
BananaSeeds: 10
|
||||||
|
CarrotSeeds: 10
|
||||||
|
LemonSeeds: 10
|
||||||
|
PotatoSeeds: 10
|
||||||
|
SugarcaneSeeds: 10
|
||||||
|
TowercapSeeds: 10
|
||||||
|
TomatoSeeds: 10
|
||||||
|
EggplantSeeds: 10
|
||||||
|
AppleSeeds: 10
|
||||||
|
CornSeeds: 10
|
||||||
|
ChanterelleSeeds: 10
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
- type: entity
|
||||||
|
id: SeedExtractor
|
||||||
|
name: seed extractor
|
||||||
|
description: Extracts seeds from produce.
|
||||||
|
placement:
|
||||||
|
mode: SnapgridCenter
|
||||||
|
components:
|
||||||
|
- type: Clickable
|
||||||
|
- type: InteractionOutline
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: sextractor
|
||||||
|
- type: Physics
|
||||||
|
mass: 25
|
||||||
|
anchored: true
|
||||||
|
shapes:
|
||||||
|
- !type:PhysShapeAabb
|
||||||
|
bounds: "-0.4,-0.25,0.4,0.25"
|
||||||
|
layer:
|
||||||
|
- Opaque
|
||||||
|
- Impassable
|
||||||
|
- MobImpassable
|
||||||
|
- VaultImpassable
|
||||||
|
- type: SnapGrid
|
||||||
|
offset: Center
|
||||||
|
- type: Anchorable
|
||||||
|
- type: SeedExtractor
|
||||||
|
- type: PowerReceiver
|
||||||
47
Resources/Prototypes/Entities/Constructible/hydroponics.yml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
- type: entity
|
||||||
|
name: soil
|
||||||
|
id: hydroponicsSoil
|
||||||
|
placement:
|
||||||
|
mode: SnapgridCenter
|
||||||
|
components:
|
||||||
|
- type: Clickable
|
||||||
|
- type: InteractionOutline
|
||||||
|
- type: Physics
|
||||||
|
anchored: true
|
||||||
|
hard: false
|
||||||
|
shapes:
|
||||||
|
- !type:PhysShapeAabb
|
||||||
|
mask:
|
||||||
|
- Impassable
|
||||||
|
- MobImpassable
|
||||||
|
- VaultImpassable
|
||||||
|
- type: Destructible
|
||||||
|
deadThreshold: 50
|
||||||
|
resistances: metallicResistances
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: soil
|
||||||
|
- type: PlantHolder
|
||||||
|
drawWarnings: false
|
||||||
|
- type: SolutionContainer
|
||||||
|
maxVol: 200
|
||||||
|
caps: AddTo, NoExamine
|
||||||
|
- type: Pourable
|
||||||
|
- type: SnapGrid
|
||||||
|
offset: Center
|
||||||
|
- type: Appearance
|
||||||
|
visuals:
|
||||||
|
- type: PlantHolderVisualizer
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: hydroponics tray
|
||||||
|
parent: hydroponicsSoil
|
||||||
|
id: hydroponicsTray
|
||||||
|
components:
|
||||||
|
- type: Anchorable
|
||||||
|
snap: true
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: hydrotray3
|
||||||
|
- type: PlantHolder
|
||||||
|
drawWarnings: true
|
||||||
@@ -167,10 +167,12 @@
|
|||||||
- type: RotationVisualizer
|
- type: RotationVisualizer
|
||||||
- type: BuckleVisualizer
|
- type: BuckleVisualizer
|
||||||
- type: FireVisualizer
|
- type: FireVisualizer
|
||||||
|
sprite: Mobs/Effects/onfire.rsi
|
||||||
normalState: Generic_mob_burning
|
normalState: Generic_mob_burning
|
||||||
alternateState: Standing
|
alternateState: Standing
|
||||||
fireStackAlternateState: 3
|
fireStackAlternateState: 3
|
||||||
- type: CreamPiedVisualizer
|
- type: CreamPiedVisualizer
|
||||||
|
state: creampie_human
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
- type: Climbing
|
- type: Climbing
|
||||||
- type: Cuffable
|
- type: Cuffable
|
||||||
|
|||||||
212
Resources/Prototypes/Entities/Objects/Consumable/botany.yml
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
- type: entity
|
||||||
|
parent: BaseItem
|
||||||
|
id: ProduceBase
|
||||||
|
abstract: true
|
||||||
|
components:
|
||||||
|
- type: SolutionContainer
|
||||||
|
caps: NoExamine
|
||||||
|
- type: Sprite
|
||||||
|
state: produce
|
||||||
|
- type: Produce
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: wheat
|
||||||
|
description: Sigh... wheat... a-grain?
|
||||||
|
id: Wheat
|
||||||
|
parent: ProduceBase
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/wheat.rsi
|
||||||
|
- type: SolutionContainer
|
||||||
|
caps: NoExamine
|
||||||
|
contents:
|
||||||
|
chem.Nutrient: 5
|
||||||
|
chem.Flour: 5
|
||||||
|
- type: Produce
|
||||||
|
seed: wheat
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: sugarcane
|
||||||
|
description: Sickly sweet.
|
||||||
|
id: Sugarcane
|
||||||
|
parent: ProduceBase
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/sugarcane.rsi
|
||||||
|
- type: SolutionContainer
|
||||||
|
caps: NoExamine
|
||||||
|
contents:
|
||||||
|
chem.Nutrient: 5
|
||||||
|
chem.Flour: 5
|
||||||
|
- type: Produce
|
||||||
|
seed: sugarcane
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: tower-cap log
|
||||||
|
description: It's better than bad, it's good!
|
||||||
|
id: Log
|
||||||
|
parent: ProduceBase
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/towercap.rsi
|
||||||
|
- type: SolutionContainer
|
||||||
|
caps: NoExamine
|
||||||
|
- type: MeleeWeapon
|
||||||
|
- type: Produce
|
||||||
|
seed: towercap
|
||||||
|
- type: Log
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: banana
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodBanana
|
||||||
|
description: Rich in potassium.
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
trash: TrashBananaPeel
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/banana.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: banana
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: carrot
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodCarrot
|
||||||
|
description: It's good for the eyes!
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/carrot.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: carrots
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: lemon
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodLemon
|
||||||
|
description: When life gives you lemons, be grateful they aren't limes
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/lemon.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: lemon
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: potato
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodPotato
|
||||||
|
description: The space Irish starved to death after their potato crops died. Sadly they were unable to fish for space carp due to it being the queen's space. Bringing this up to any space IRA member will drive them insane with anger.
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/potato.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: potato
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: tomato
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodTomato
|
||||||
|
description: I say to-mah-to, you say tom-mae-to.
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/tomato.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: tomato
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: eggplant
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodEggplant
|
||||||
|
description: Maybe there's a chicken inside?
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/eggplant.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: eggplant
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: apple
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodApple
|
||||||
|
description: It's a little piece of Eden.
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/apple.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: apple
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: ear of corn
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodCorn
|
||||||
|
description: Needs some butter!
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
trash: TrashCornCob
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/corn.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: corn
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: chanterelle cluster
|
||||||
|
parent: ProduceBase
|
||||||
|
id: FoodMushroom
|
||||||
|
description: "Cantharellus Cibarius: These jolly yellow little shrooms sure look tasty!"
|
||||||
|
components:
|
||||||
|
- type: Food
|
||||||
|
- type: SolutionContainer
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.Nutriment
|
||||||
|
Quantity: 6
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/chanterelle.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: chanterelle
|
||||||
@@ -931,7 +931,8 @@
|
|||||||
Quantity: 2
|
Quantity: 2
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Consumable/Food/egg.rsi
|
sprite: Objects/Consumable/Food/egg.rsi
|
||||||
|
- type: Produce
|
||||||
|
seed: eggy
|
||||||
- type: Item
|
- type: Item
|
||||||
sprite: Objects/Consumable/Food/egg.rsi
|
sprite: Objects/Consumable/Food/egg.rsi
|
||||||
|
|
||||||
@@ -2857,24 +2858,6 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Consumable/Food/milkape.rsi
|
sprite: Objects/Consumable/Food/milkape.rsi
|
||||||
|
|
||||||
|
|
||||||
- type: entity
|
|
||||||
name: banana
|
|
||||||
parent: FoodBase
|
|
||||||
id: FoodBanana
|
|
||||||
description: Rich in potassium.
|
|
||||||
components:
|
|
||||||
- type: Food
|
|
||||||
trash: TrashBananaPeel
|
|
||||||
- type: SolutionContainer
|
|
||||||
contents:
|
|
||||||
reagents:
|
|
||||||
- ReagentId: chem.Nutriment
|
|
||||||
Quantity: 6
|
|
||||||
- type: Sprite
|
|
||||||
sprite: Objects/Consumable/Food/banana.rsi
|
|
||||||
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: memory leek
|
name: memory leek
|
||||||
parent: FoodBase
|
parent: FoodBase
|
||||||
|
|||||||
@@ -46,7 +46,8 @@
|
|||||||
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: corn cob (trash)
|
name: corn cob
|
||||||
|
description: A reminder of meals gone by.
|
||||||
parent: TrashBase
|
parent: TrashBase
|
||||||
id: TrashCornCob
|
id: TrashCornCob
|
||||||
components:
|
components:
|
||||||
@@ -188,9 +189,8 @@
|
|||||||
id: TrashBananaPeel
|
id: TrashBananaPeel
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Consumable/Food/banana.rsi
|
sprite: Objects/Specific/Hydroponics/banana.rsi
|
||||||
state: peel
|
state: peel
|
||||||
|
|
||||||
- type: Slippery
|
- type: Slippery
|
||||||
intersectPercentage: 0.2
|
intersectPercentage: 0.2
|
||||||
- type: Physics
|
- type: Physics
|
||||||
|
|||||||
@@ -6,9 +6,6 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/utensils.rsi
|
sprite: Objects/Misc/utensils.rsi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: UtensilBase
|
parent: UtensilBase
|
||||||
id: Fork
|
id: Fork
|
||||||
@@ -17,7 +14,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
state: fork
|
state: fork
|
||||||
|
- type: Hoe
|
||||||
- type: Utensil
|
- type: Utensil
|
||||||
types:
|
types:
|
||||||
- Fork
|
- Fork
|
||||||
|
|||||||
142
Resources/Prototypes/Entities/Objects/Specific/seeds.yml
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
- type: entity
|
||||||
|
parent: BaseItem
|
||||||
|
id: SeedBase
|
||||||
|
abstract: true
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
- type: SolutionContainer
|
||||||
|
caps: NoExamine
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/seeds.rsi
|
||||||
|
state: seed
|
||||||
|
netsync: true
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of wheat seeds
|
||||||
|
id: WheatSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: wheat
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/wheat.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of banana seeds
|
||||||
|
id: BananaSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: banana
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/banana.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of carrot seeds
|
||||||
|
id: CarrotSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: carrots
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/carrot.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of lemon seeds
|
||||||
|
id: LemonSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: lemon
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/lemon.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of potato seeds
|
||||||
|
id: PotatoSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: potato
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/potato.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of sugarcane seeds
|
||||||
|
id: SugarcaneSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: sugarcane
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/sugarcane.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of tower cap seeds
|
||||||
|
id: TowercapSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: towercap
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/towercap.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of tomato seeds
|
||||||
|
id: TomatoSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: tomato
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/tomato.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of eggplant seeds
|
||||||
|
id: EggplantSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: eggplant
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/eggplant.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of apple seeds
|
||||||
|
id: AppleSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: apple
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/apple.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of corn seeds
|
||||||
|
id: CornSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: apple
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/corn.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of chanterelle spores
|
||||||
|
id: ChanterelleSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: chanterelle
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/chanterelle.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of egg-plant seeds
|
||||||
|
id: EggySeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seed: eggy
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/eggy.rsi
|
||||||
100
Resources/Prototypes/Entities/Objects/Tools/botany_tools.yml
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
- type: entity
|
||||||
|
name: mini hoe
|
||||||
|
parent: BaseItem
|
||||||
|
id: MiniHoe
|
||||||
|
description: It's used for removing weeds or scratching your back.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: hoe
|
||||||
|
- type: ItemCooldown
|
||||||
|
- type: MeleeWeapon
|
||||||
|
- type: Item
|
||||||
|
- type: Hoe
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Plant-B-Gone
|
||||||
|
id: PlantBGoneSpray
|
||||||
|
parent: SprayBottle
|
||||||
|
description: Kills those pesky weeds!
|
||||||
|
suffix: "Filled"
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: plantbgone
|
||||||
|
- type: SolutionContainer
|
||||||
|
maxVol: 100
|
||||||
|
caps: RemoveFrom, NoExamine
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.PlantBGone
|
||||||
|
Quantity: 100
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: weed spray
|
||||||
|
id: WeedSpray
|
||||||
|
parent: SprayBottle
|
||||||
|
description: It's a toxic mixture, in spray form, to kill small weeds.
|
||||||
|
suffix: "Filled"
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: weedspray
|
||||||
|
- type: SolutionContainer
|
||||||
|
maxVol: 50
|
||||||
|
caps: RemoveFrom, NoExamine
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.WeedKiller
|
||||||
|
Quantity: 50
|
||||||
|
- type: Pourable
|
||||||
|
transferAmount: 1.0
|
||||||
|
- type: Spillable
|
||||||
|
- type: ItemCooldown
|
||||||
|
- type: Spray
|
||||||
|
transferAmount: 1
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: pest spray
|
||||||
|
id: PestSpray
|
||||||
|
parent: WeedSpray
|
||||||
|
description: It's some pest eliminator spray! Do not inhale!
|
||||||
|
suffix: "Filled"
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
state: pestspray
|
||||||
|
- type: SolutionContainer
|
||||||
|
maxVol: 50
|
||||||
|
caps: RemoveFrom, NoExamine
|
||||||
|
contents:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: chem.PestKiller
|
||||||
|
Quantity: 50
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: scythe
|
||||||
|
parent: BaseItem
|
||||||
|
id: Scythe
|
||||||
|
description: A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: scythe
|
||||||
|
- type: ItemCooldown
|
||||||
|
- type: MeleeWeapon
|
||||||
|
- type: BotanySharp
|
||||||
|
- type: Item
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: hatchet
|
||||||
|
parent: BaseItem
|
||||||
|
id: Hatchet
|
||||||
|
description: A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Hydroponics/hydro_tools.rsi
|
||||||
|
state: hatchet
|
||||||
|
- type: ItemCooldown
|
||||||
|
- type: MeleeWeapon
|
||||||
|
- type: BotanySharp
|
||||||
|
- type: Item
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
yellow: "#d58c18"
|
yellow: "#d58c18"
|
||||||
- type: Item
|
- type: Item
|
||||||
sprite: Objects/Tools/wirecutters.rsi
|
sprite: Objects/Tools/wirecutters.rsi
|
||||||
|
- type: PlantSampleTaker
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: screwdriver
|
name: screwdriver
|
||||||
|
|||||||
@@ -163,8 +163,21 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
name: wood plank
|
name: wood plank
|
||||||
id: WoodPlank
|
id: WoodPlank
|
||||||
parent: BaseItem
|
parent: MaterialStack
|
||||||
|
suffix: Full
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
# TODO: Specify a material.
|
||||||
sprite: Objects/Materials/materials.rsi
|
- type: Sprite
|
||||||
state: wood_plank
|
sprite: Objects/Materials/materials.rsi
|
||||||
|
state: wood_plank
|
||||||
|
- type: Stack
|
||||||
|
stacktype: enum.StackType.Wood
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: WoodPlank1
|
||||||
|
name: wood plank
|
||||||
|
parent: WoodPlank
|
||||||
|
suffix: 1
|
||||||
|
components:
|
||||||
|
- type: Stack
|
||||||
|
count: 1
|
||||||
|
|||||||
288
Resources/Prototypes/Hydroponics/seeds.yml
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
- type: seed
|
||||||
|
id: wheat
|
||||||
|
name: wheat
|
||||||
|
seedName: wheat
|
||||||
|
displayName: wheat stalks
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/wheat.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- Wheat
|
||||||
|
lifespan: 25
|
||||||
|
maturation: 6
|
||||||
|
production: 1
|
||||||
|
yield: 4
|
||||||
|
potency: 5
|
||||||
|
idealLight: 8
|
||||||
|
nutrientConsumption: 0.15
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 20
|
||||||
|
PotencyDivisor: 20
|
||||||
|
chem.Flour:
|
||||||
|
Min: 5
|
||||||
|
Max: 20
|
||||||
|
PotencyDivisor: 20
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: banana
|
||||||
|
name: banana
|
||||||
|
seedName: banana
|
||||||
|
displayName: banana plant
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/banana.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodBanana
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 50
|
||||||
|
maturation: 6
|
||||||
|
production: 6
|
||||||
|
yield: 3
|
||||||
|
idealLight: 9
|
||||||
|
waterConsumption: 6
|
||||||
|
idealHeat: 298
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 20
|
||||||
|
PotencyDivisor: 20
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: carrots
|
||||||
|
name: carrot
|
||||||
|
seedName: carrot
|
||||||
|
displayName: carrots
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/carrot.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodCarrot
|
||||||
|
lifespan: 25
|
||||||
|
maturation: 10
|
||||||
|
production: 1
|
||||||
|
yield: 5
|
||||||
|
potency: 10
|
||||||
|
growthStages: 3
|
||||||
|
waterConsumption: 6
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 20
|
||||||
|
PotencyDivisor: 20
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: lemon
|
||||||
|
name: lemon
|
||||||
|
seedName: lemon
|
||||||
|
displayName: lemon trees
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/lemon.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodLemon
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 55
|
||||||
|
maturation: 6
|
||||||
|
production: 6
|
||||||
|
yield: 4
|
||||||
|
potency: 10
|
||||||
|
idealLight: 8
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 20
|
||||||
|
PotencyDivisor: 20
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: potato
|
||||||
|
name: potato
|
||||||
|
seedName: potato
|
||||||
|
displayName: potatoes
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/potato.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodPotato
|
||||||
|
lifespan: 30
|
||||||
|
maturation: 10
|
||||||
|
production: 1
|
||||||
|
yield: 4
|
||||||
|
potency: 10
|
||||||
|
growthStages: 4
|
||||||
|
waterConsumption: 6
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 10
|
||||||
|
PotencyDivisor: 10
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: sugarcane
|
||||||
|
name: sugarcane
|
||||||
|
seedName: sugarcane
|
||||||
|
displayName: sugarcanes
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/sugarcane.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- Sugarcane
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 60
|
||||||
|
maturation: 3
|
||||||
|
production: 6
|
||||||
|
yield: 4
|
||||||
|
potency: 10
|
||||||
|
growthStages: 3
|
||||||
|
idealHeat: 298
|
||||||
|
chemicals:
|
||||||
|
chem.Sugar:
|
||||||
|
Min: 4
|
||||||
|
Max: 5
|
||||||
|
PotencyDivisor: 5
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: towercap
|
||||||
|
name: towercap
|
||||||
|
seedName: tower cap
|
||||||
|
displayName: tower caps
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/towercap.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- Log
|
||||||
|
lifespan: 80
|
||||||
|
maturation: 15
|
||||||
|
ligneous: true
|
||||||
|
production: 1
|
||||||
|
yield: 5
|
||||||
|
potency: 1
|
||||||
|
growthStages: 3
|
||||||
|
waterConsumption: 6
|
||||||
|
lightTolerance: 6
|
||||||
|
idealLight: 288
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: tomato
|
||||||
|
name: tomato
|
||||||
|
seedName: tomato
|
||||||
|
displayName: tomato plant
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/tomato.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodTomato
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 25
|
||||||
|
maturation: 8
|
||||||
|
production: 6
|
||||||
|
yield: 2
|
||||||
|
potency: 10
|
||||||
|
waterConsumption: 6
|
||||||
|
nutrientConsumption: 0.25
|
||||||
|
idealLight: 8
|
||||||
|
idealHeat: 298
|
||||||
|
juicy: true
|
||||||
|
splatPrototype: PuddleSplatter
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 10
|
||||||
|
PotencyDivisor: 10
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: eggplant
|
||||||
|
name: eggplant
|
||||||
|
seedName: eggplant
|
||||||
|
displayName: eggplants
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/eggplant.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodEggplant
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 25
|
||||||
|
maturation: 6
|
||||||
|
production: 6
|
||||||
|
yield: 2
|
||||||
|
potency: 20
|
||||||
|
idealLight: 9
|
||||||
|
idealHeat: 298
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 10
|
||||||
|
PotencyDivisor: 10
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: apple
|
||||||
|
name: apple
|
||||||
|
seedName: apple
|
||||||
|
displayName: apple tree
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/apple.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodApple
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 55
|
||||||
|
maturation: 6
|
||||||
|
production: 6
|
||||||
|
yield: 5
|
||||||
|
potency: 10
|
||||||
|
idealLight: 6
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 10
|
||||||
|
PotencyDivisor: 10
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: corn
|
||||||
|
name: corn
|
||||||
|
seedName: corn
|
||||||
|
displayName: ears of corn
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/corn.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodCorn
|
||||||
|
lifespan: 25
|
||||||
|
maturation: 8
|
||||||
|
production: 6
|
||||||
|
yield: 3
|
||||||
|
potency: 20
|
||||||
|
growthStages: 3
|
||||||
|
idealLight: 8
|
||||||
|
waterConsumption: 6
|
||||||
|
idealHeat: 298
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 10
|
||||||
|
PotencyDivisor: 10
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: chanterelle
|
||||||
|
name: chanterelle
|
||||||
|
seedName: chanterelle
|
||||||
|
seedNoun: spores
|
||||||
|
displayName: chanterelle mushrooms
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/chanterelle.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodMushroom
|
||||||
|
lifespan: 35
|
||||||
|
maturation: 7
|
||||||
|
production: 1
|
||||||
|
yield: 5
|
||||||
|
potency: 1
|
||||||
|
growthStages: 3
|
||||||
|
lightTolerance: 6
|
||||||
|
waterConsumption: 6
|
||||||
|
idealHeat: 288
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 25
|
||||||
|
PotencyDivisor: 25
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: eggy
|
||||||
|
name: eggy
|
||||||
|
seedName: egg-plant
|
||||||
|
displayName: egg-plants
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/eggy.rsi
|
||||||
|
productPrototypes:
|
||||||
|
- FoodEgg
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 75
|
||||||
|
maturation: 6
|
||||||
|
production: 12
|
||||||
|
yield: 2
|
||||||
|
potency: 20
|
||||||
|
idealLight: 9
|
||||||
|
idealHeat: 298
|
||||||
|
chemicals:
|
||||||
|
chem.Nutriment:
|
||||||
|
Min: 1
|
||||||
|
Max: 10
|
||||||
|
PotencyDivisor: 10
|
||||||
@@ -7,6 +7,11 @@
|
|||||||
metabolism:
|
metabolism:
|
||||||
- !type:DefaultFood
|
- !type:DefaultFood
|
||||||
rate: 1
|
rate: 1
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 1
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: 0.5
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.H2SO4
|
id: chem.H2SO4
|
||||||
@@ -16,6 +21,13 @@
|
|||||||
color: "#BF8C00"
|
color: "#BF8C00"
|
||||||
boilingPoint: 337.0
|
boilingPoint: 337.0
|
||||||
meltingPoint: 10.31
|
meltingPoint: 10.31
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 10
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -2
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -4
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.H2O
|
id: chem.H2O
|
||||||
@@ -31,6 +43,9 @@
|
|||||||
tileReactions:
|
tileReactions:
|
||||||
- !type:ExtinguishTileReaction {}
|
- !type:ExtinguishTileReaction {}
|
||||||
- !type:SpillIfPuddlePresentTileReaction {}
|
- !type:SpillIfPuddlePresentTileReaction {}
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: 1
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Ice
|
id: chem.Ice
|
||||||
@@ -40,6 +55,9 @@
|
|||||||
color: "#bed8e6"
|
color: "#bed8e6"
|
||||||
meltingPoint: 0.0
|
meltingPoint: 0.0
|
||||||
boilingPoint: 100.0
|
boilingPoint: 100.0
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: 1
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Phoron
|
id: chem.Phoron
|
||||||
@@ -73,6 +91,13 @@
|
|||||||
color: "#ffffff"
|
color: "#ffffff"
|
||||||
boilingPoint: 340282300000000000000000000000000000000 #Fun fact: Glucose can't boil. So let's just set it to the maximum float value.
|
boilingPoint: 340282300000000000000000000000000000000 #Fun fact: Glucose can't boil. So let's just set it to the maximum float value.
|
||||||
meltingPoint: 146.0
|
meltingPoint: 146.0
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.1
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: 2
|
||||||
|
- !type:AdjustPests
|
||||||
|
amount: 2
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Ammonia
|
id: chem.Ammonia
|
||||||
@@ -82,6 +107,11 @@
|
|||||||
color: "#77b58e"
|
color: "#77b58e"
|
||||||
boilingPoint: -33.0
|
boilingPoint: -33.0
|
||||||
meltingPoint: -77.7
|
meltingPoint: -77.7
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 1
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: 0.5
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Bleach
|
id: chem.Bleach
|
||||||
@@ -100,6 +130,20 @@
|
|||||||
color: "#a1000b"
|
color: "#a1000b"
|
||||||
boilingPoint: 55.5
|
boilingPoint: 55.5
|
||||||
meltingPoint: -50.0
|
meltingPoint: -50.0
|
||||||
|
customPlantMetabolism: 0.1
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.1
|
||||||
|
- !type:AdjustPests
|
||||||
|
prob: 0.1
|
||||||
|
amount: -1
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: 0.1
|
||||||
|
- !type:AffectGrowth
|
||||||
|
prob: 0.2
|
||||||
|
amount: 1
|
||||||
|
- !type:Diethylamine {}
|
||||||
|
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.FoamingAgent
|
id: chem.FoamingAgent
|
||||||
@@ -118,6 +162,13 @@
|
|||||||
color: "#a1000b"
|
color: "#a1000b"
|
||||||
boilingPoint: 78.2 # This isn't a real chemical...
|
boilingPoint: 78.2 # This isn't a real chemical...
|
||||||
meltingPoint: -19.4
|
meltingPoint: -19.4
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 20
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -4
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -8
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.SpaceCleaner
|
id: chem.SpaceCleaner
|
||||||
@@ -152,6 +203,19 @@
|
|||||||
color: "#a1000b"
|
color: "#a1000b"
|
||||||
boilingPoint: 1465.0
|
boilingPoint: 1465.0
|
||||||
meltingPoint: 800.7
|
meltingPoint: 800.7
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: -3
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: -0.3
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 8
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -2
|
||||||
|
- !type:AdjustPests
|
||||||
|
amount: -1
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -2
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Thermite
|
id: chem.Thermite
|
||||||
@@ -173,6 +237,10 @@
|
|||||||
color: "#00ff5f"
|
color: "#00ff5f"
|
||||||
boilingPoint: 340282300000000000000000000000000000000 # Ethidium bromide, which doesn't boil.
|
boilingPoint: 340282300000000000000000000000000000000 # Ethidium bromide, which doesn't boil.
|
||||||
meltingPoint: 261.0
|
meltingPoint: 261.0
|
||||||
|
customPlantMetabolism: 2
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustMutationLevel
|
||||||
|
amount: 1
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.WeldingFuel
|
id: chem.WeldingFuel
|
||||||
@@ -184,3 +252,110 @@
|
|||||||
meltingPoint: -80.7
|
meltingPoint: -80.7
|
||||||
tileReactions:
|
tileReactions:
|
||||||
- !type:FlammableTileReaction {}
|
- !type:FlammableTileReaction {}
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.EZNutrient
|
||||||
|
name: EZ nutrient
|
||||||
|
desc: Give your plants some of those EZ nutrients!
|
||||||
|
color: "#664330"
|
||||||
|
physicalDesc: thick
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 1
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.Left4Zed
|
||||||
|
name: left-4-zed
|
||||||
|
desc: A cocktail of mutagenic compounds, which cause plant life to become highly unstable.
|
||||||
|
color: "#5b406c"
|
||||||
|
physicalDesc: heterogeneous
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 1
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -0.5
|
||||||
|
- !type:AdjustMutationMod
|
||||||
|
prob: 0.3
|
||||||
|
amount: 0.2
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.RobustHarvest
|
||||||
|
name: robust harvest
|
||||||
|
desc: Plant-enhancing hormones, good for increasing potency.
|
||||||
|
color: "#3e901c"
|
||||||
|
physicalDesc: robust
|
||||||
|
customPlantMetabolism: 0.1
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.05
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
prob: 0.025
|
||||||
|
amount: 1
|
||||||
|
- !type:AdjustPests
|
||||||
|
prob: 0.025
|
||||||
|
amount: 1
|
||||||
|
- !type:RobustHarvest {}
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.PlantBGone
|
||||||
|
name: plant-B-gone
|
||||||
|
desc: A harmful toxic mixture to kill plantlife. Do not ingest!
|
||||||
|
color: "#49002E"
|
||||||
|
physicalDesc: bubbling
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 6
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -8
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -20
|
||||||
|
- !type:AdjustMutationMod
|
||||||
|
amount: 0.1
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.WeedKiller
|
||||||
|
name: weed killer
|
||||||
|
desc: A mixture that targets weeds.
|
||||||
|
color: "#968395"
|
||||||
|
physicalDesc: bubbling
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 4
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -6
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.PestKiller
|
||||||
|
name: pest killer
|
||||||
|
desc: A mixture that targets pests.
|
||||||
|
color: "#9e9886"
|
||||||
|
physicalDesc: bubbling
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 4
|
||||||
|
- !type:AdjustPests
|
||||||
|
amount: -6
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.Toxin
|
||||||
|
name: toxin
|
||||||
|
desc: A Toxic chemical.
|
||||||
|
color: "#cf3600"
|
||||||
|
physicalDesc: opaque
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 10
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: chem.Sugar
|
||||||
|
name: sugar
|
||||||
|
desc: Sickly sweet.
|
||||||
|
color: "#ffffff"
|
||||||
|
physicalDesc: opaque
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.1
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: 2
|
||||||
|
- !type:AdjustPests
|
||||||
|
amount: 2
|
||||||
|
|||||||
@@ -29,6 +29,11 @@
|
|||||||
physicalDesc: bubbly
|
physicalDesc: bubbly
|
||||||
color: "#cfa85f"
|
color: "#cfa85f"
|
||||||
spritePath: beerglass.rsi
|
spritePath: beerglass.rsi
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.25
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: 0.7
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Vodka
|
id: chem.Vodka
|
||||||
@@ -156,6 +161,13 @@
|
|||||||
metabolism:
|
metabolism:
|
||||||
- !type:DefaultDrink
|
- !type:DefaultDrink
|
||||||
rate: 1
|
rate: 1
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.1
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: 1
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: 0.1
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Coffee
|
id: chem.Coffee
|
||||||
@@ -196,6 +208,11 @@
|
|||||||
metabolism:
|
metabolism:
|
||||||
- !type:DefaultDrink
|
- !type:DefaultDrink
|
||||||
rate: 1
|
rate: 1
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.1
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: 0.9
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.SpoiledMilk
|
id: chem.SpoiledMilk
|
||||||
@@ -235,4 +252,4 @@
|
|||||||
color: "#9d5fb8"
|
color: "#9d5fb8"
|
||||||
metabolism:
|
metabolism:
|
||||||
- !type:DefaultDrink
|
- !type:DefaultDrink
|
||||||
rate: 1
|
rate: 1
|
||||||
|
|||||||
@@ -78,6 +78,15 @@
|
|||||||
color: "#808080"
|
color: "#808080"
|
||||||
boilingPoint: -188.11
|
boilingPoint: -188.11
|
||||||
meltingPoint: -219.67
|
meltingPoint: -219.67
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: -0.5
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 25
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -4
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -2
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Si
|
id: chem.Si
|
||||||
@@ -96,6 +105,15 @@
|
|||||||
color: "#a2ff00"
|
color: "#a2ff00"
|
||||||
meltingPoint: -101.5
|
meltingPoint: -101.5
|
||||||
boilingPoint: -34.04
|
boilingPoint: -34.04
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: -0.5
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 15
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -3
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -1
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Li
|
id: chem.Li
|
||||||
@@ -123,6 +141,13 @@
|
|||||||
color: "#ede4e4"
|
color: "#ede4e4"
|
||||||
meltingPoint: 44.2
|
meltingPoint: 44.2
|
||||||
boilingPoint: 280.5
|
boilingPoint: 280.5
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustNutrition
|
||||||
|
amount: 0.1
|
||||||
|
- !type:AdjustWater
|
||||||
|
amount: -0.5
|
||||||
|
- !type:AdjustWeeds
|
||||||
|
amount: -2
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.K
|
id: chem.K
|
||||||
@@ -141,6 +166,17 @@
|
|||||||
color: "#00ff04"
|
color: "#00ff04"
|
||||||
meltingPoint: 700.0
|
meltingPoint: 700.0
|
||||||
boilingPoint: 1737.0
|
boilingPoint: 1737.0
|
||||||
|
customPlantMetabolism: 2
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustMutationLevel
|
||||||
|
amount: 0.6
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 4
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: -1.5
|
||||||
|
- !type:AdjustMutationMod
|
||||||
|
prob: 0.2
|
||||||
|
amount: 0.1
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Na
|
id: chem.Na
|
||||||
|
|||||||
@@ -18,6 +18,11 @@
|
|||||||
desc: A broad-spectrum anti-toxin, which treats toxin damage in the blood stream. Overdosing will cause vomiting, dizzyness and pain.
|
desc: A broad-spectrum anti-toxin, which treats toxin damage in the blood stream. Overdosing will cause vomiting, dizzyness and pain.
|
||||||
physicalDesc: translucent
|
physicalDesc: translucent
|
||||||
color: "#3a1d8a"
|
color: "#3a1d8a"
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: -10
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: 1
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Arithrazine
|
id: chem.Arithrazine
|
||||||
@@ -39,6 +44,11 @@
|
|||||||
desc: Required for the proper function of cryogenics. Heals all standard types of damage very swiftly, but only works in temperatures under 170K (usually this means cryo cells). Can also slowly heal clone damage, such as caused by cloning or Slimes.
|
desc: Required for the proper function of cryogenics. Heals all standard types of damage very swiftly, but only works in temperatures under 170K (usually this means cryo cells). Can also slowly heal clone damage, such as caused by cloning or Slimes.
|
||||||
physicalDesc: fizzy
|
physicalDesc: fizzy
|
||||||
color: "#0091ff"
|
color: "#0091ff"
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: -3
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: 3
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Clonexadone
|
id: chem.Clonexadone
|
||||||
@@ -46,6 +56,11 @@
|
|||||||
desc: Heals standard damage in the same as Cryoxadone, with the same temperature requirement. Significantly more effective than the former at treating cellular damage, although both can be used simultaneously. Best used in cryo cells.
|
desc: Heals standard damage in the same as Cryoxadone, with the same temperature requirement. Significantly more effective than the former at treating cellular damage, although both can be used simultaneously. Best used in cryo cells.
|
||||||
physicalDesc: bubbly
|
physicalDesc: bubbly
|
||||||
color: "#0666ff"
|
color: "#0666ff"
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: -5
|
||||||
|
- !type:AdjustHealth
|
||||||
|
amount: 5
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Citalopram
|
id: chem.Citalopram
|
||||||
@@ -235,6 +250,9 @@
|
|||||||
desc: A hallucinogenic compound that is illegal under space law. A synthetic drug derived from Mindbreaker toxin, it blocks some neurological signals to the respiratory system which causes choking.
|
desc: A hallucinogenic compound that is illegal under space law. A synthetic drug derived from Mindbreaker toxin, it blocks some neurological signals to the respiratory system which causes choking.
|
||||||
physicalDesc: strong-smelling
|
physicalDesc: strong-smelling
|
||||||
color: "#5f959c"
|
color: "#5f959c"
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 10
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Impedrezene
|
id: chem.Impedrezene
|
||||||
@@ -263,6 +281,9 @@
|
|||||||
desc: A potent hallucinogenic compound that is illegal under space law. Formerly known as LSD.
|
desc: A potent hallucinogenic compound that is illegal under space law. Formerly known as LSD.
|
||||||
physicalDesc: opaque
|
physicalDesc: opaque
|
||||||
color: "#77b58e"
|
color: "#77b58e"
|
||||||
|
plantMetabolism:
|
||||||
|
- !type:AdjustToxins
|
||||||
|
amount: 10
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: chem.Soporific
|
id: chem.Soporific
|
||||||
|
|||||||
@@ -284,7 +284,7 @@
|
|||||||
solids:
|
solids:
|
||||||
FoodFlatDough: 2
|
FoodFlatDough: 2
|
||||||
FoodMeat: 2
|
FoodMeat: 2
|
||||||
FoodEggPlant: 1
|
FoodEggplant: 1
|
||||||
FoodCheeseWedge: 1
|
FoodCheeseWedge: 1
|
||||||
|
|
||||||
#Soups & Stew
|
#Soups & Stew
|
||||||
@@ -334,8 +334,6 @@
|
|||||||
solids:
|
solids:
|
||||||
FoodMiloSoup: 1
|
FoodMiloSoup: 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#Handy template for copy **pasta**. Get it? Pasta? Aw whatever fuck you.
|
#Handy template for copy **pasta**. Get it? Pasta? Aw whatever fuck you.
|
||||||
# - type: microwaveMealRecipe
|
# - type: microwaveMealRecipe
|
||||||
# id:
|
# id:
|
||||||
|
|||||||
@@ -134,3 +134,47 @@
|
|||||||
flashRange: 0.2
|
flashRange: 0.2
|
||||||
scaled: true #Scaled proportionally to amount of potassium and water
|
scaled: true #Scaled proportionally to amount of potassium and water
|
||||||
maxScale: 30 #Explosion strength stops scaling at 30 potassium + 30 water
|
maxScale: 30 #Explosion strength stops scaling at 30 potassium + 30 water
|
||||||
|
|
||||||
|
- type: reaction
|
||||||
|
id: react.EZNutrient
|
||||||
|
reactants:
|
||||||
|
chem.N:
|
||||||
|
amount: 1
|
||||||
|
chem.P:
|
||||||
|
amount: 1
|
||||||
|
chem.K:
|
||||||
|
amount: 1
|
||||||
|
products:
|
||||||
|
chem.EZNutrient: 3
|
||||||
|
|
||||||
|
- type: reaction
|
||||||
|
id: react.RobustHarvest
|
||||||
|
reactants:
|
||||||
|
chem.EZNutrient:
|
||||||
|
amount: 1
|
||||||
|
chem.H2SO4:
|
||||||
|
amount: 1
|
||||||
|
catalyst: true
|
||||||
|
products:
|
||||||
|
chem.RobustHarvest: 1
|
||||||
|
|
||||||
|
- type: reaction
|
||||||
|
id: react.Left4Zed
|
||||||
|
reactants:
|
||||||
|
chem.EZNutrient:
|
||||||
|
amount: 1
|
||||||
|
chem.Ra:
|
||||||
|
amount: 1
|
||||||
|
catalyst: true
|
||||||
|
products:
|
||||||
|
chem.Left4Zed: 1
|
||||||
|
|
||||||
|
- type: reaction
|
||||||
|
id: react.PlantBGone
|
||||||
|
reactants:
|
||||||
|
chem.Toxin:
|
||||||
|
amount: 1
|
||||||
|
chem.H2O:
|
||||||
|
amount: 4
|
||||||
|
products:
|
||||||
|
chem.PlantBGone: 5
|
||||||
|
|||||||
|
After Width: | Height: | Size: 375 B |
|
After Width: | Height: | Size: 394 B |
|
After Width: | Height: | Size: 377 B |
|
After Width: | Height: | Size: 659 B |
|
After Width: | Height: | Size: 653 B |
|
After Width: | Height: | Size: 662 B |
|
After Width: | Height: | Size: 655 B |
|
After Width: | Height: | Size: 664 B |
|
After Width: | Height: | Size: 672 B |
|
After Width: | Height: | Size: 668 B |
|
After Width: | Height: | Size: 660 B |
|
After Width: | Height: | Size: 354 B |
|
After Width: | Height: | Size: 355 B |
|
After Width: | Height: | Size: 680 B |
|
After Width: | Height: | Size: 692 B |
|
After Width: | Height: | Size: 693 B |
|
After Width: | Height: | Size: 684 B |
|
After Width: | Height: | Size: 673 B |
|
After Width: | Height: | Size: 682 B |
|
After Width: | Height: | Size: 677 B |
|
After Width: | Height: | Size: 555 B |
|
After Width: | Height: | Size: 601 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 543 B |
|
After Width: | Height: | Size: 547 B |
@@ -0,0 +1 @@
|
|||||||
|
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA 3.0", "copyright": "Taken from https://github.com/vgstation-coders/vgstation13 at 1dbcf389b0ec6b2c51b002df5fef8dd1519f8068", "states": [{"name": "claypot", "directions": 1, "delays": [[1.0]]}, {"name": "claypot-item", "directions": 1, "delays": [[1.0]]}, {"name": "claypot-large", "directions": 1, "delays": [[1.0]]}, {"name": "cyan", "directions": 1, "delays": [[1.0]]}, {"name": "cyan black stripe", "directions": 1, "delays": [[1.0]]}, {"name": "cyan blue stripe", "directions": 1, "delays": [[1.0]]}, {"name": "cyan lime stripe", "directions": 1, "delays": [[1.0]]}, {"name": "cyan purple stripe", "directions": 1, "delays": [[1.0]]}, {"name": "cyan red stripe", "directions": 1, "delays": [[1.0]]}, {"name": "cyan white stripe", "directions": 1, "delays": [[1.0]]}, {"name": "cyan yellow stripe", "directions": 1, "delays": [[1.0]]}, {"name": "deathspray", "directions": 1, "delays": [[1.0]]}, {"name": "disk", "directions": 1, "delays": [[0.1, 0.1, 0.1]]}, {"name": "green black stripe", "directions": 1, "delays": [[1.0]]}, {"name": "green blue stripe", "directions": 1, "delays": [[1.0]]}, {"name": "green lime stripe", "directions": 1, "delays": [[1.0]]}, {"name": "green purple stripe", "directions": 1, "delays": [[1.0]]}, {"name": "green red stripe", "directions": 1, "delays": [[1.0]]}, {"name": "green white stripe", "directions": 1, "delays": [[1.0]]}, {"name": "green yellow stripe", "directions": 1, "delays": [[1.0]]}, {"name": "hydrocover", "directions": 1, "delays": [[1.0]]}, {"name": "hydrotray", "directions": 1, "delays": [[1.0]]}, {"name": "hydrotray2", "directions": 1, "delays": [[1.0]]}, {"name": "hydrotray3", "directions": 1, "delays": [[1.0]]}, {"name": "moldcreep0", "directions": 1, "delays": [[1.0]]}, {"name": "moldcreep1", "directions": 1, "delays": [[1.0]]}, {"name": "moldcreep2", "directions": 1, "delays": [[1.0]]}, {"name": "nolabelspray", "directions": 1, "delays": [[1.0]]}, {"name": "over_alert3", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "over_harvest3", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "over_lowhealth3", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "over_lownutri", "directions": 1, "delays": [[1.0]]}, {"name": "over_lownutri3", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "over_lowwater3", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "pestspray", "directions": 1, "delays": [[1.0]]}, {"name": "plantbag", "directions": 1, "delays": [[1.0]]}, {"name": "plantbgone", "directions": 1, "delays": [[1.0]]}, {"name": "portaseeder", "directions": 1, "delays": [[1.0]]}, {"name": "seedbag", "directions": 1, "delays": [[1.0]]}, {"name": "sextractor", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "soil", "directions": 1, "delays": [[1.0]]}, {"name": "spaceworms", "directions": 1, "delays": [[0.4, 0.4, 0.4, 0.4]]}, {"name": "spawner", "directions": 1, "delays": [[1.0]]}, {"name": "sprayparts", "directions": 1, "delays": [[1.0]]}, {"name": "traitcopier", "directions": 1, "delays": [[1.0]]}, {"name": "traitgun", "directions": 1, "delays": [[1.0]]}, {"name": "traitscanner", "directions": 1, "delays": [[1.0]]}, {"name": "vine_flowers", "directions": 1, "delays": [[1.0]]}, {"name": "vine_fruit", "directions": 1, "delays": [[1.0]]}, {"name": "weedspray", "directions": 1, "delays": [[1.0]]}, {"name": "scythe", "directions": 1, "delays": [[1.0]]}, {"name": "hoe", "directions": 1, "delays": [[1.0]]}, {"name": "hatchet", "directions": 1, "delays": [[1.0]]}]}
|
||||||
|
After Width: | Height: | Size: 307 B |
|
After Width: | Height: | Size: 504 B |
|
After Width: | Height: | Size: 856 B |
|
After Width: | Height: | Size: 299 B |
|
After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 260 B |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 137 B |
|
After Width: | Height: | Size: 300 B |
|
After Width: | Height: | Size: 306 B |
|
After Width: | Height: | Size: 368 B |
|
After Width: | Height: | Size: 663 B |
|
After Width: | Height: | Size: 274 B |
|
After Width: | Height: | Size: 683 B |
|
After Width: | Height: | Size: 450 B |
|
After Width: | Height: | Size: 585 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 435 B |
|
After Width: | Height: | Size: 3.5 KiB |