they did surgery on a fish (#889)

* add breathing immunity and organ status effects

* they did surgery on a fish

* fix error for installing parts on non-humanoids

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
deltanedas 2024-11-18 01:27:12 +00:00 committed by deltanedas
parent 67b0a95b2f
commit a778a9b8d8
15 changed files with 189 additions and 2 deletions

View File

@ -1,6 +1,7 @@
using Content.Server.Administration.Logs;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Body.Components;
using Content.Shared._Shitmed.Body.Components; // GoobStation
using Content.Shared._Shitmed.Body.Organ; // Shitmed Change
using Content.Server.Chat.Systems;
using Content.Server.EntityEffects.EffectConditions;
@ -72,7 +73,7 @@ public sealed class RespiratorSystem : EntitySystem
respirator.NextUpdate += respirator.UpdateInterval;
if (_mobState.IsDead(uid))
if (_mobState.IsDead(uid) || HasComp<BreathingImmunityComponent>(uid)) // GoobStation: BreathingImmunity
continue;
// Begin DeltaV Code: Addition:

View File

@ -0,0 +1,26 @@
using Content.Shared.StatusEffect;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server._Shitmed.Body.Organ;
[RegisterComponent, Access(typeof(StatusEffectOrganSystem))]
[AutoGenerateComponentPause]
public sealed partial class StatusEffectOrganComponent : Component
{
/// <summary>
/// List of status effects and components to refresh while the organ is installed.
/// </summary>
[DataField(required: true)]
public Dictionary<ProtoId<StatusEffectPrototype>, string> Refresh = new();
/// <summary>
/// How long to wait between each refresh.
/// Effects can only last at most this long once the organ is removed.
/// </summary>
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(5);
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan NextUpdate = TimeSpan.Zero;
}

View File

@ -0,0 +1,33 @@
using Content.Shared.Body.Organ;
using Content.Shared.StatusEffect;
using Robust.Shared.Timing;
namespace Content.Server._Shitmed.Body.Organ;
public sealed class StatusEffectOrganSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly StatusEffectsSystem _effects = default!;
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<StatusEffectOrganComponent, OrganComponent>();
var now = _timing.CurTime;
while (query.MoveNext(out var uid, out var comp, out var organ))
{
if (now < comp.NextUpdate || organ.Body is not {} body)
continue;
comp.NextUpdate = now + comp.Delay;
if (!TryComp<StatusEffectsComponent>(body, out var effects))
continue;
foreach (var (key, component) in comp.Refresh)
{
_effects.TryAddStatusEffect(body, key, comp.Delay, refresh: true, component, effects);
}
}
}
}

View File

@ -106,12 +106,13 @@ public partial class SharedBodySystem
public void ChangeSlotState(Entity<BodyPartComponent> partEnt, bool disable)
{
if (partEnt.Comp.Body is not null
&& TryComp<InventoryComponent>(partEnt.Comp.Body, out var inventory) // GoobStation: Prevent error for non-humanoids
&& GetBodyPartCount(partEnt.Comp.Body.Value, partEnt.Comp.PartType) == 1
&& TryGetPartSlotContainerName(partEnt.Comp.PartType, out var containerNames))
{
foreach (var containerName in containerNames)
{
_inventorySystem.SetSlotStatus(partEnt.Comp.Body.Value, containerName, disable);
_inventorySystem.SetSlotStatus(partEnt.Comp.Body.Value, containerName, disable, inventory); // GoobStation: pass inventory
var ev = new RefreshInventorySlotsEvent(containerName);
RaiseLocalEvent(partEnt.Comp.Body.Value, ev);
}

View File

@ -0,0 +1,8 @@
namespace Content.Shared._Shitmed.Body.Components;
/// <summary>
/// GoobStation: Disables a mobs need for air when this component is added.
/// It will neither breathe nor take airloss damage.
/// </summary>
[RegisterComponent]
public sealed partial class BreathingImmunityComponent : Component;

View File

@ -86,6 +86,13 @@
interactFailureString: petting-failure-carp
interactFailureSound:
path: /Audio/Effects/bite.ogg
- type: Body # GoobStation: Special carp organs
prototype: Carp
- type: SurgeryTarget # GoobStation
- type: UserInterface # GoobStation
interfaces:
enum.SurgeryUIKey.Key:
type: SurgeryBui
- type: entity
parent: BaseMobCarp

View File

@ -0,0 +1,17 @@
- type: entity
parent: OrganAnimalLungs
id: OrganSpaceAnimalLungs
name: space animal lungs
components:
- type: StatusEffectOrgan
refresh:
BreathingImmunity: BreathingImmunity
- type: entity
parent: OrganAnimalHeart
id: OrganSpaceAnimalHeart
name: space animal heart
components:
- type: StatusEffectOrgan
refresh:
PressureImmunity: PressureImmunity

View File

@ -8,3 +8,41 @@
- type: Sprite
layers:
- state: head_m
- type: entity
abstract: true
parent: PartAnimal
id: BaseCarpPart
components:
- type: Sprite
sprite: _Goobstation/Mobs/Aliens/Carps/carp_parts.rsi
- type: entity
categories: [ HideSpawnMenu ]
parent: BaseCarpPart
id: TailCarp
name: carp tail
description: Unique glands in this tail let space carp fly in a vacuum.
components:
- type: Sprite
layers:
- state: tail
- type: BodyPart
partType: Tail
- type: MovementBodyPart
walkSpeed: 2.5
sprintSpeed: 3.5
# TODO: Make it actually needed. Legs are hardcoded to be the only parts that matter for movement.
# TODO: space flight stuff
- type: entity
categories: [ HideSpawnMenu ]
parent: BaseCarpPart
id: TorsoCarp
name: carp torso
components:
- type: Sprite
layers:
- state: torso
- type: BodyPart
partType: Torso

View File

@ -0,0 +1,17 @@
- type: body
id: Carp
name: carp
root: torso
slots:
torso:
part: TorsoAnimal
connections:
- tail
organs:
lungs: OrganSpaceAnimalLungs # Immunity to airloss
stomach: OrganAnimalStomach
liver: OrganAnimalLiver
heart: OrganSpaceAnimalHeart # Immunity to cold
kidneys: OrganAnimalKidneys
tail:
part: TailCarp

View File

@ -0,0 +1,3 @@
- type: statusEffect
id: BreathingImmunity
alwaysAllowed: true # Used by space animal lungs to work on anything

View File

@ -281,6 +281,24 @@
part: Foot
symmetry: Right
- type: entity
parent: SurgeryBase
id: SurgeryAttachTail
name: Attach Tail
categories: [ HideSpawnMenu ]
components:
- type: Surgery
requirement: SurgeryOpenIncision
steps:
- SurgeryStepInsertFeature
- SurgeryStepSealWounds
- type: SurgeryPartCondition
part: Torso
- type: SurgeryPartRemovedCondition
connection: tail
part: Tail
symmetry: None
#- type: entity
# parent: SurgeryBase
# id: SurgeryAlienEmbryoRemoval

View File

@ -36,6 +36,7 @@
- type: statusEffect
id: PressureImmunity
alwaysAllowed: true # GoobStation: Used by space animal heart to work on anything
- type: statusEffect
id: Muted

View File

@ -0,0 +1,17 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from and modified by deltanedas (github) for GoobStation",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "tail"
},
{
"name": "torso"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B