CatStation/Content.Shared/Botany/Systems/BotanySystem.Produce.cs
SlothBasket b1323acc43
Botany Refactor Bugfixes and Value adjustments (#45752)
* Fixes Cryoxadone De-Age, properly adjusts lastHarvest. If age would be reduced below 0 reverts plant to seed with current genetics.

* Botany Bugfixes. Cryoxadone De-Age fix. Cryox Regression to seed re-added. Seedless Produce no longer have seeds. Proper Temp tollerance ranges restored. Production no longer clamped to maturation.

* Restore Content Server+Client run configuration

* Fix formatting in Content Server+Client run configuration

* Address botany review feedback

* review

* fix weed

* fix

* fix 2

* Update PlantSystem.cs

* refactor: revert to EntityTerminatingEvent and leave warning for next generations

---------

Co-authored-by: Pok245 <113675512+Pok27@users.noreply.github.com>
Co-authored-by: Fildrance <fildrance@gmail.com>
2026-09-03 14:57:34 +00:00

90 lines
3.3 KiB
C#

using Content.Shared.Botany.Components;
using Content.Shared.Botany.Items.Components;
using Content.Shared.EntityEffects;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Random.Helpers;
using JetBrains.Annotations;
using Robust.Shared.Map;
using Robust.Shared.Random;
namespace Content.Shared.Botany.Systems;
public sealed partial class BotanySystem
{
[Dependency] private SharedEntityEffectsSystem _entityEffects = default!;
[SubscribeLocalEvent]
private void OnProduceExamined(Entity<ProduceComponent> ent, ref ExaminedEvent args)
{
if (!TryGetPlantComponent<PlantComponent>(ent.Comp.PlantData, ent.Comp.PlantProtoId, out var plant))
return;
using (args.PushGroup(nameof(ProduceComponent)))
{
foreach (var m in plant.Mutations)
{
// Don't show mutations that have no effect on produce (sentience)
if (!m.AppliesToProduce)
continue;
if (m.Description != null)
args.PushMarkup(Loc.GetString(m.Description));
}
}
}
private void ProduceGrown(Entity<ProduceComponent> ent)
{
if (!TryGetPlantComponent<PlantComponent>(ent.Comp.PlantData, ent.Comp.PlantProtoId, out var plant)
|| !TryGetPlantComponent<PlantChemicalsComponent>(ent.Comp.PlantData, ent.Comp.PlantProtoId, out var chems))
return;
foreach (var mutation in plant.Mutations)
{
if (mutation.AppliesToProduce)
_entityEffects.TryApplyEffect(ent.Owner, mutation.Effect);
}
_solutionContainer.EnsureSolution(ent.Owner, ent.Comp.TargetSolution, out var solution);
solution.Comp.Solution.RemoveAllSolution();
foreach (var (chem, quantity) in chems.Chemicals)
{
var amount = quantity.Min;
if (quantity.PotencyDivisor > 0 && plant.Potency > 0)
amount += plant.Potency / quantity.PotencyDivisor;
amount = FixedPoint2.Clamp(amount, quantity.Min, quantity.Max);
solution.Comp.Solution.MaxVolume += amount;
solution.Comp.Solution.AddReagent(chem, amount);
}
}
/// <summary>
/// Spawns a produce item from a plant and produces the produce.
/// </summary>
[PublicAPI]
public void SpawnProduce(
Entity<PlantComponent?, PlantDataComponent?> ent,
EntityCoordinates position,
int amount)
{
if (!Resolve(ent, ref ent.Comp1, ref ent.Comp2, false))
return;
var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent));
for (var i = 0; i < amount; i++)
{
var product = random.Pick(ent.Comp2.ProductPrototypes);
var entity = PredictedSpawnAtPosition(product, position);
_randomHelper.RandomOffset(entity, 0.25f, random);
var produce = EnsureComp<ProduceComponent>(entity);
produce.PlantProtoId = MetaData(ent.Owner).EntityPrototype!.ID;
produce.PlantData = ClonePlantSnapshotData(ent.Owner, parent: entity);
Dirty(entity, produce);
ProduceGrown((entity, produce));
_appearance.SetData(entity, ProduceVisuals.Potency, ent.Comp1.Potency);
}
}
}