diff --git a/Content.Server/Body/Systems/RespiratorSystem.cs b/Content.Server/Body/Systems/RespiratorSystem.cs index 046ba70cc19..9f56bedb4c3 100644 --- a/Content.Server/Body/Systems/RespiratorSystem.cs +++ b/Content.Server/Body/Systems/RespiratorSystem.cs @@ -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 override void Update(float frameTime) respirator.NextUpdate += respirator.UpdateInterval; - if (_mobState.IsDead(uid)) + if (_mobState.IsDead(uid) || HasComp(uid)) // GoobStation: BreathingImmunity continue; // Begin DeltaV Code: Addition: diff --git a/Content.Server/_Shitmed/Body/Organ/StatusEffectOrganComponent.cs b/Content.Server/_Shitmed/Body/Organ/StatusEffectOrganComponent.cs new file mode 100644 index 00000000000..640f61d5e8e --- /dev/null +++ b/Content.Server/_Shitmed/Body/Organ/StatusEffectOrganComponent.cs @@ -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 +{ + /// + /// List of status effects and components to refresh while the organ is installed. + /// + [DataField(required: true)] + public Dictionary, string> Refresh = new(); + + /// + /// How long to wait between each refresh. + /// Effects can only last at most this long once the organ is removed. + /// + [DataField] + public TimeSpan Delay = TimeSpan.FromSeconds(5); + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] + public TimeSpan NextUpdate = TimeSpan.Zero; +} diff --git a/Content.Server/_Shitmed/Body/Organ/StatusEffectOrganSystem.cs b/Content.Server/_Shitmed/Body/Organ/StatusEffectOrganSystem.cs new file mode 100644 index 00000000000..b3394b7dd91 --- /dev/null +++ b/Content.Server/_Shitmed/Body/Organ/StatusEffectOrganSystem.cs @@ -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(); + 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(body, out var effects)) + continue; + + foreach (var (key, component) in comp.Refresh) + { + _effects.TryAddStatusEffect(body, key, comp.Delay, refresh: true, component, effects); + } + } + } +} diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs index eed0c897728..b28b0ca891d 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs @@ -106,12 +106,13 @@ private void EnablePart(Entity partEnt) public void ChangeSlotState(Entity partEnt, bool disable) { if (partEnt.Comp.Body is not null + && TryComp(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); } diff --git a/Content.Shared/_Shitmed/Body/Components/BreathingImmunityComponent.cs b/Content.Shared/_Shitmed/Body/Components/BreathingImmunityComponent.cs new file mode 100644 index 00000000000..7add1f261ed --- /dev/null +++ b/Content.Shared/_Shitmed/Body/Components/BreathingImmunityComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Shared._Shitmed.Body.Components; + +/// +/// GoobStation: Disables a mobs need for air when this component is added. +/// It will neither breathe nor take airloss damage. +/// +[RegisterComponent] +public sealed partial class BreathingImmunityComponent : Component; diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index 2695d84b63c..6b8c3d8810c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -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 diff --git a/Resources/Prototypes/_Goobstation/Body/Organs/Animal/space.yml b/Resources/Prototypes/_Goobstation/Body/Organs/Animal/space.yml new file mode 100644 index 00000000000..d565a7f2e7f --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Body/Organs/Animal/space.yml @@ -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 diff --git a/Resources/Prototypes/_Goobstation/Body/Parts/animal.yml b/Resources/Prototypes/_Goobstation/Body/Parts/animal.yml index 75985dfca30..005a1744099 100644 --- a/Resources/Prototypes/_Goobstation/Body/Parts/animal.yml +++ b/Resources/Prototypes/_Goobstation/Body/Parts/animal.yml @@ -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 diff --git a/Resources/Prototypes/_Goobstation/Body/Prototypes/Animal/carp.yml b/Resources/Prototypes/_Goobstation/Body/Prototypes/Animal/carp.yml new file mode 100644 index 00000000000..81bf6a4bd5c --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Body/Prototypes/Animal/carp.yml @@ -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 diff --git a/Resources/Prototypes/_Goobstation/status_effects.yml b/Resources/Prototypes/_Goobstation/status_effects.yml new file mode 100644 index 00000000000..5e62d994021 --- /dev/null +++ b/Resources/Prototypes/_Goobstation/status_effects.yml @@ -0,0 +1,3 @@ +- type: statusEffect + id: BreathingImmunity + alwaysAllowed: true # Used by space animal lungs to work on anything diff --git a/Resources/Prototypes/_Shitmed/Entities/Surgery/surgeries.yml b/Resources/Prototypes/_Shitmed/Entities/Surgery/surgeries.yml index 7a3955e086a..6e24499c2fa 100644 --- a/Resources/Prototypes/_Shitmed/Entities/Surgery/surgeries.yml +++ b/Resources/Prototypes/_Shitmed/Entities/Surgery/surgeries.yml @@ -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 diff --git a/Resources/Prototypes/status_effects.yml b/Resources/Prototypes/status_effects.yml index 49e5ccc5794..1eeaf93b095 100644 --- a/Resources/Prototypes/status_effects.yml +++ b/Resources/Prototypes/status_effects.yml @@ -36,6 +36,7 @@ - type: statusEffect id: PressureImmunity + alwaysAllowed: true # GoobStation: Used by space animal heart to work on anything - type: statusEffect id: Muted diff --git a/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/meta.json b/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/meta.json new file mode 100644 index 00000000000..cdecf550def --- /dev/null +++ b/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/meta.json @@ -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" + } + ] +} diff --git a/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/tail.png b/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/tail.png new file mode 100644 index 00000000000..bb0b9458102 Binary files /dev/null and b/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/tail.png differ diff --git a/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/torso.png b/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/torso.png new file mode 100644 index 00000000000..ab0f5ff82f0 Binary files /dev/null and b/Resources/Textures/_Goobstation/Mobs/Aliens/Carps/carp_parts.rsi/torso.png differ