Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Content.Shared/Metabolism/MetabolizerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public sealed partial class MetabolizerComponent : Component
/// </summary>
[DataField]
[Access(typeof(MetabolizerSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
[AutoNetworkedField] // DEN
public HashSet<ProtoId<MetabolizerTypePrototype>>? MetabolizerTypes;

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions Content.Shared/Metabolism/MetabolizerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public override void Initialize()

SubscribeLocalEvent<MetabolizerComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<MetabolizerComponent, BodyRelayedEvent<ApplyMetabolicMultiplierEvent>>(OnApplyMetabolicMultiplier);

InitializeDen(); // DEN - metabolizer extension
}

private void OnMapInit(Entity<MetabolizerComponent> ent, ref MapInitEvent args)
Expand Down
80 changes: 80 additions & 0 deletions Content.Shared/_DEN/Metabolism/MetabolizerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Linq;
using Content.Shared.Body;
using Content.Shared.Whitelist;
using Robust.Shared.Prototypes;

namespace Content.Shared.Metabolism;

public sealed partial class MetabolizerSystem
{
[Dependency] private BodySystem _body = default!;
[Dependency] private EntityWhitelistSystem _whitelist = default!;

private void InitializeDen()
{
SubscribeLocalEvent<BodyComponent, AddTraitMetabolizerEvent>(_body.RelayEvent);
SubscribeLocalEvent<BodyComponent, RemoveTraitMetabolizerEvent>(_body.RelayEvent);

SubscribeLocalEvent<MetabolizerComponent, BodyRelayedEvent<AddTraitMetabolizerEvent>>(OnAddTraitMetabolizerEvent);
SubscribeLocalEvent<MetabolizerComponent, BodyRelayedEvent<RemoveTraitMetabolizerEvent>>(OnRemoveTraitMetabolizerEvent);
}

/// <summary>
/// Adds metabolizers to metabolizer organs that pass a whitelist.
/// </summary>
/// <param name="ent">The metabolizer organ.</param>
private void OnAddTraitMetabolizerEvent(Entity<MetabolizerComponent> ent,
ref BodyRelayedEvent<AddTraitMetabolizerEvent> args)
{
if (args.Args.Metabolizers.Count == 0
|| _whitelist.IsWhitelistFail(args.Args.OrganWhitelist, ent))
return;

var metabolizers = args.Args.Metabolizers;

if (ent.Comp.MetabolizerTypes != null)
metabolizers = metabolizers.Union(ent.Comp.MetabolizerTypes).ToHashSet();

ent.Comp.MetabolizerTypes = metabolizers;
Comment thread
portfiend marked this conversation as resolved.
Dirty(ent);
}

/// <summary>
/// Removes metabolizers from metabolizer organs that pass a whitelist.
/// </summary>
/// <param name="ent">The metabolizer organ.</param>
private void OnRemoveTraitMetabolizerEvent(Entity<MetabolizerComponent> ent,
ref BodyRelayedEvent<RemoveTraitMetabolizerEvent> args)
{
if (args.Args.Metabolizers.Count == 0
|| ent.Comp.MetabolizerTypes == null
|| _whitelist.IsWhitelistFail(args.Args.OrganWhitelist, ent))
return;

// TODO: add smarter handling for this
var metabolizers = ent.Comp.MetabolizerTypes
.Except(args.Args.Metabolizers)
.ToHashSet();

ent.Comp.MetabolizerTypes = metabolizers;
Comment thread
portfiend marked this conversation as resolved.
Dirty(ent);
}
}

/// <summary>
/// An event that adds metabolizers to subscribed entities that pass the whitelist.
/// </summary>
/// <param name="Metabolizers">The metabolizers to add.</param>
/// <param name="OrganWhitelist">The whitelist for organs to add metabolizers to.</param>
[ByRefEvent]
public record struct AddTraitMetabolizerEvent(HashSet<ProtoId<MetabolizerTypePrototype>> Metabolizers,
EntityWhitelist? OrganWhitelist = null);

/// <summary>
/// An event that removes metabolizers from subscribed entities that pass the whitelist.
/// </summary>
/// <param name="Metabolizers">The metabolizers to add.</param>
/// <param name="OrganWhitelist">The whitelist for organs to add metabolizers to.</param>
[ByRefEvent]
public record struct RemoveTraitMetabolizerEvent(HashSet<ProtoId<MetabolizerTypePrototype>> Metabolizers,
EntityWhitelist? OrganWhitelist = null);
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Content.Shared.Metabolism;
using Content.Shared.Whitelist;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
Expand Down Expand Up @@ -58,3 +60,35 @@ public void OnTraitRemoved(EntityUid owner, EntityManager entityManager)
}
}
}

/// <summary>
/// A trait that adds a metabolizer to this entity's organs.
/// </summary>
[UsedImplicitly]
public sealed partial class AddMetabolizerTrait : ITraitFunction
{
/// <summary>
/// A set of metabolizers to add to this entity's organs.
/// </summary>
[DataField] public HashSet<ProtoId<MetabolizerTypePrototype>> MetabolizerTypes = [];

/// <summary>
/// A whitelist of allowed organs to use for this trait.
/// </summary>
/// <remarks>
/// For example: you can have this only apply to the heart or lungs by whitelisting Heart or Lung components.
/// </remarks>
[DataField] public EntityWhitelist? OrganWhitelist = null;

public void OnTraitAdded(EntityUid owner, EntityManager entityManager)
{
var ev = new AddTraitMetabolizerEvent(MetabolizerTypes, OrganWhitelist);
entityManager.EventBus.RaiseLocalEvent(owner, ref ev);
}

public void OnTraitRemoved(EntityUid owner, EntityManager entityManager)
{
var ev = new RemoveTraitMetabolizerEvent(MetabolizerTypes, OrganWhitelist);
entityManager.EventBus.RaiseLocalEvent(owner, ref ev);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
metabolizer-type-detritivore = Detritivore
1 change: 1 addition & 0 deletions Resources/Locale/en-US/_DEN/traits/categories.ftl
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
trait-category-perks = Perks
trait-category-species-morphs = Morphotypes
trait-category-species-specific = Species-specific
4 changes: 4 additions & 0 deletions Resources/Locale/en-US/_DEN/traits/perks.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
trait-detritivore-name = Detritivore
trait-detritivore-desc =
You can digest gastrotoxin (rotting food), mold, and trash without being
poisoned, and sate your hunger by doing so!
10 changes: 5 additions & 5 deletions Resources/Prototypes/Body/Animals/rat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
suffix: Rat
components:
- type: Metabolizer
metabolizerTypes: [ Rat ]
metabolizerTypes: [ Rat, Detritivore ] # DEN: Add Detritivore

- type: entity
id: BaseMobRat
Expand All @@ -16,7 +16,7 @@
body_organs: !type:AllSelector
children:
- id: OrganRatLungs
- id: OrganAnimalHeart
- id: OrganAnimalStomach
- id: OrganAnimalLiver
- id: OrganAnimalKidneys
- id: OrganDetritivoreHeart # DEN: OrganAnimalHeart -> OrganDetritivoreHeart
- id: OrganDetritivoreStomach # DEN: OrganAnimalStomach -> OrganDetritivoreStomach
- id: OrganDetritivoreLiver # DEN: OrganAnimalLiver -> OrganDetritivoreLiver
- id: OrganDetritivoreKidneys # DEN: OrganAnimalKidneys -> OrganDetritivoreKidneys
2 changes: 1 addition & 1 deletion Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1923,7 +1923,7 @@

- type: entity
name: mouse
parent: [SimpleMobBase, BaseMobAnimal, SolutionVermin, BaseSlicingRefinable]
parent: [BaseMobDetritivore, SimpleMobBase, SolutionVermin, BaseSlicingRefinable] # DEN: BaseMobAnimal -> BaseMobDetritivore
id: MobMouse
description: Squeak!
components:
Expand Down
67 changes: 63 additions & 4 deletions Resources/Prototypes/Reagents/toxins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@
Bloodstream:
effects:
- !type:HealthChange
conditions: # DEN: Detritivore metabolism
- !type:MetabolizerTypeCondition
type: [ Detritivore ]
inverted: true
damage:
types:
Poison: 2
Expand All @@ -101,7 +105,15 @@
- !type:ReagentCondition
reagent: GastroToxin
min: 2
- !type:MetabolizerTypeCondition # DEN: Detritivore metabolism
type: [ Detritivore ]
inverted: true
probability: 0.2
- !type:SatiateHunger # DEN: Detritivore metabolism
# DEN Comment: This cannot be in Digestion or the metabolism will break.
conditions:
- !type:MetabolizerTypeCondition
type: [ Detritivore ]

- type: reagent
id: Mold
Expand All @@ -116,9 +128,18 @@
Bloodstream:
effects:
- !type:HealthChange
conditions: # DEN: Detritivore metabolism
- !type:MetabolizerTypeCondition
type: [ Detritivore ]
inverted: true
damage:
types:
Poison: 1
- !type:SatiateHunger # DEN: Detritivores can digest mold.
# DEN Comment: This cannot be in Digestion or the metabolism will break.
conditions:
- !type:MetabolizerTypeCondition
type: [ Detritivore ]

- type: reagent
id: PolytrinicAcid
Expand Down Expand Up @@ -454,6 +475,16 @@
damage:
types:
Poison: 2
conditions: # DEN: Detritivores aren't poisoned by vent crud
- !type:MetabolizerTypeCondition
type: [ Detritivore ]
inverted: true
- !type:SatiateHunger # DEN: Detritivores can process vent crud
# DEN Comment: This cannot be in Digestion or the metabolism will break.
factor: 0.75
conditions:
- !type:MetabolizerTypeCondition
type: [ Detritivore ]

- type: reagent
id: Romerol
Expand Down Expand Up @@ -488,7 +519,7 @@
- !type:PopupMessage
conditions:
- !type:MetabolizerTypeCondition
type: [ Animal, Vox ]
type: [ Animal, Vox, Detritivore ] # DEN: Add Detritivore
inverted: true
type: Local
visualType: MediumCaution
Expand All @@ -498,12 +529,12 @@
probability: 0.1
conditions:
- !type:MetabolizerTypeCondition
type: [ Animal, Vox, Plant ]
type: [ Animal, Vox, Plant, Detritivore ] # DEN: Add Detritivore
inverted: true
- !type:HealthChange
conditions:
- !type:MetabolizerTypeCondition
type: [ Animal, Vox, Plant ]
type: [ Animal, Vox, Plant, Detritivore ] # DEN: Add Detritivore
inverted: true
damage:
types:
Expand All @@ -518,13 +549,16 @@
- !type:AdjustReagent
conditions:
- !type:MetabolizerTypeCondition
type: [ Animal ]
type: [ Animal, Detritivore ] # DEN: Add Detritivore
reagent: Protein
amount: 0.5
- !type:AdjustReagent
conditions:
- !type:MetabolizerTypeCondition
type: [ Vox ]
- !type:MetabolizerTypeCondition # DEN: Prevent redundant metabolism for detritivore vox
type: [ Detritivore ]
inverted: true
reagent: Protein
amount: 0.25

Expand Down Expand Up @@ -762,6 +796,31 @@
conditions:
- !type:MetabolizerTypeCondition
type: [Vox]
- !type:SatiateHunger # DEN: Detritivores can process trash
factor: 0.75
conditions:
- !type:MetabolizerTypeCondition
type: [ Detritivore ]
- !type:MetabolizerTypeCondition
inverted: true
type: [Vox]
- !type:HealthChange # DEN: Add poison effect to trash
damage:
types:
Poison: 2
conditions:
- !type:MetabolizerTypeCondition
inverted: true
type: [ Vox, Detritivore ]
- !type:Vomit # DEN: Add poison effect to trash
probability: 0.2
conditions:
- !type:ReagentCondition
reagent: ToxinTrash
min: 2
- !type:MetabolizerTypeCondition # DEN: Detritivore metabolism
type: [ Vox, Detritivore ]
inverted: true

- type: reagent
id: Hemorrhinol
Expand Down
54 changes: 54 additions & 0 deletions Resources/Prototypes/_DEN/Body/Animals/detritivore.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
- type: entity
id: OrganDetritivoreMetabolizer
abstract: true
components:
- type: Metabolizer
metabolizerTypes: [ Animal, Detritivore ]

- type: entity
parent: OrganBaseOrganic
id: OrganDetritivore
abstract: true
suffix: Detritivore

- type: entity
parent: OrganDetritivore
id: OrganDetritivoreInternal
abstract: true
components:
- type: Sprite
sprite: Mobs/Species/Human/organs.rsi # TODO: Custom detritivore organ sprites

- type: entity
parent: [ OrganBaseLungs, OrganDetritivoreInternal, OrganDetritivoreMetabolizer ]
id: OrganDetritivoreLungs

- type: entity
parent: [ OrganBaseHeart, OrganDetritivoreInternal, OrganDetritivoreMetabolizer ]
id: OrganDetritivoreHeart

- type: entity
parent: [ OrganBaseStomach, OrganDetritivoreInternal, OrganDetritivoreMetabolizer ]
id: OrganDetritivoreStomach

- type: entity
parent: [ OrganBaseLiver, OrganDetritivoreInternal, OrganDetritivoreMetabolizer ]
id: OrganDetritivoreLiver

- type: entity
parent: [ OrganBaseKidneys, OrganDetritivoreInternal, OrganDetritivoreMetabolizer ]
id: OrganDetritivoreKidneys

- type: entity
abstract: true
id: BaseMobDetritivore
components:
- type: EntityTableContainerFill
containers:
body_organs: !type:AllSelector
children:
- id: OrganDetritivoreLungs
- id: OrganDetritivoreHeart
- id: OrganDetritivoreStomach
- id: OrganDetritivoreLiver
- id: OrganDetritivoreKidneys
5 changes: 5 additions & 0 deletions Resources/Prototypes/_DEN/Chemistry/metabolizer_types.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Hardy digestion for trash eaters and decomposers.
# Can consume gastrotoxin, trash, and mold safely, and derive nutrition from doing so.
- type: metabolizerType
id: Detritivore
name: metabolizer-type-detritivore
5 changes: 5 additions & 0 deletions Resources/Prototypes/_DEN/EntityTraits/categories.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
- type: traitCategory
id: Perks
name: trait-category-perks
priority: -8

- type: traitCategory
id: SpeciesMorphs
name: trait-category-species-morphs
Expand Down
Loading
Loading