diff --git a/Content.Server/_DEN/Geras/GerasComponent.cs b/Content.Server/_DEN/Geras/GerasComponent.cs new file mode 100644 index 00000000000..a721b665edd --- /dev/null +++ b/Content.Server/_DEN/Geras/GerasComponent.cs @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2024 DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> +// SPDX-FileCopyrightText: 2024 sleepyyapril +// SPDX-FileCopyrightText: 2025 sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> +// +// SPDX-License-Identifier: AGPL-3.0-or-later AND MIT + +using Content.Shared.Actions; +using Content.Shared.Polymorph; +using Robust.Shared.Prototypes; + +namespace Content.Server._DEN.Geras; + +/// +/// This component assigns the entity with a polymorph action. +/// +[RegisterComponent] +public sealed partial class GerasComponent : Component +{ + [DataField] public ProtoId GerasPolymorphId = "SlimeMorphGeras"; + + [DataField] public EntProtoId GerasAction = "ActionMorphGeras"; + + [DataField] public EntityUid? GerasActionEntity; +} diff --git a/Content.Server/_DEN/Geras/GerasSystem.cs b/Content.Server/_DEN/Geras/GerasSystem.cs new file mode 100644 index 00000000000..fdf4592449b --- /dev/null +++ b/Content.Server/_DEN/Geras/GerasSystem.cs @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: 2024 DEATHB4DEFEAT +// SPDX-FileCopyrightText: 2025 Sir Warock +// SPDX-FileCopyrightText: 2025 sleepyyapril +// +// SPDX-License-Identifier: MIT AND AGPL-3.0-or-later + +using Content.Server.Polymorph.Systems; +using Content.Shared.Zombies; +using Content.Server.Actions; +using Content.Server.Body.Components; +using Content.Server.Popups; +using Content.Shared.Chemistry.Reagent; +using Content.Shared._DEN.Geras; +using Content.Shared.Humanoid; +using Content.Shared.Sprite; +using Robust.Shared.Player; + +namespace Content.Server._DEN.Geras; + +/// +public sealed class GerasSystem : SharedGerasSystem +{ + [Dependency] private readonly PolymorphSystem _polymorphSystem = default!; + [Dependency] private readonly ActionsSystem _actionsSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnMorphIntoGeras); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnZombification); + } + + private void OnZombification(EntityUid uid, GerasComponent component, EntityZombifiedEvent args) + { + _actionsSystem.RemoveAction(uid, component.GerasActionEntity); + } + + private void OnMapInit(EntityUid uid, GerasComponent component, MapInitEvent args) + { + // try to add geras action + _actionsSystem.AddAction(uid, ref component.GerasActionEntity, component.GerasAction); + } + + private void OnMorphIntoGeras(EntityUid uid, GerasComponent component, MorphIntoGeras args) + { + if (HasComp(uid)) + return; // i hate zomber. + + var colors = GrabHumanoidColors(uid); // begin imp + + var ent = _polymorphSystem.PolymorphEntity(uid, component.GerasPolymorphId); + + if (colors != null) // match the colors of the slime geras to the skin color of the slime + { + (var skinColor, var eyeColor) = colors.Value; + if (TryComp(ent, out var randomSprite)) // we have to do this using RandomSpriteComponent, otherwise I'd be making a whole species prototype just for this. + { + foreach (var entry in randomSprite.Selected) + { + var state = randomSprite.Selected[entry.Key]; + state.Color = entry.Key switch + { + "colorMap" => skinColor, + "eyesMap" => eyeColor, + _ => state.Color + }; + randomSprite.Selected[entry.Key] = state; + } + Dirty(ent.Value, randomSprite); + } + } // end imp + + if (!ent.HasValue) + return; + + _popupSystem.PopupEntity(Loc.GetString("geras-popup-morph-message-others", ("entity", ent.Value)), ent.Value, Filter.PvsExcept(ent.Value), true); + _popupSystem.PopupEntity(Loc.GetString("geras-popup-morph-message-user"), ent.Value, ent.Value); + + args.Handled = true; + } + private (Color, Color)? GrabHumanoidColors(EntityUid entity) // imp + { + if (TryComp(entity, out var humanoid)) //Get Humanoid Appearance + { + var skinColor = humanoid.SkinColor; + var eyeColor = humanoid.EyeColor; + return (skinColor, eyeColor); + } + return null; // if (for some reason - like perhaps admin intervention) a non-humanoid or someone with no bloodstream ascends, we don't want to try to modify the colors. + } +} diff --git a/Content.Shared/_DEN/Geras/SharedGerasSystem.cs b/Content.Shared/_DEN/Geras/SharedGerasSystem.cs new file mode 100644 index 00000000000..6d0371c9728 --- /dev/null +++ b/Content.Shared/_DEN/Geras/SharedGerasSystem.cs @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2024 DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> +// +// SPDX-License-Identifier: AGPL-3.0-or-later AND MIT + +using Content.Shared.Actions; + +namespace Content.Shared._DEN.Geras; + +/// +/// Geras is the god of old age, and A geras is the small morph of a slime. This system allows the slimes to have the morphing action. +/// +public abstract class SharedGerasSystem : EntitySystem +{ + +} + +public sealed partial class MorphIntoGeras : InstantActionEvent +{ + +} diff --git a/Resources/Locale/en-US/_DEN/geras/geras.ftl b/Resources/Locale/en-US/_DEN/geras/geras.ftl new file mode 100644 index 00000000000..f0697324c20 --- /dev/null +++ b/Resources/Locale/en-US/_DEN/geras/geras.ftl @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2024 DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> +# SPDX-FileCopyrightText: 2025 sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> +# +# SPDX-License-Identifier: AGPL-3.0-or-later AND MIT + +geras-popup-morph-message-user = You shift and morph into a small version of you! +geras-popup-morph-message-others = {CAPITALIZE(THE($entity))} shifts and morphs into a blob of slime! \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index 34589128efd..0b6303aa406 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -135,6 +135,7 @@ - type: Damageable damageContainer: Biological damageModifierSet: Slime + - type: Geras # Den - type: PassiveDamage # Around 8 damage a minute healed # Omu start, add back slime regen allowedStates: - Alive diff --git a/Resources/Prototypes/_DEN/Actions/types.yml b/Resources/Prototypes/_DEN/Actions/types.yml new file mode 100644 index 00000000000..a1db8889667 --- /dev/null +++ b/Resources/Prototypes/_DEN/Actions/types.yml @@ -0,0 +1,15 @@ +- type: entity + id: ActionMorphGeras + name: Morph into Geras + description: Morphs you into a Geras - a miniature version of you which allows you to move fast, but cannot access your inventory. + categories: [ HideSpawnMenu ] + components: + - type: Action + itemIconStyle: BigAction + useDelay: 10 # prevent spam + priority: -20 + icon: + sprite: Mobs/Aliens/slimes.rsi + state: blue_adult_slime + - type: InstantAction + event: !type:MorphIntoGeras diff --git a/Resources/Prototypes/_DEN/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/_DEN/Entities/Mobs/NPCs/slimes.yml new file mode 100644 index 00000000000..5eaec1996ee --- /dev/null +++ b/Resources/Prototypes/_DEN/Entities/Mobs/NPCs/slimes.yml @@ -0,0 +1,175 @@ +- type: entity + name: basic slime + id: BaseMobAdultSlimes + parent: [ SimpleMobBase, MobCombat ] + abstract: true + description: It looks so much like jelly. I wonder what it tastes like? + components: + - type: Sprite + drawdepth: Mobs + sprite: _DEN/Mobs/Aliens/slimes.rsi + layers: + - map: [ "enum.DamageStateVisualLayers.Base" ] + state: blue_adult_slime + - type: Carriable + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.30 + density: 80 + mask: + - MobMask + layer: + - MobLayer + - type: MobThresholds + thresholds: + 0: Alive + 60: Dead # Floof + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 4 + - type: FootstepModifier + footstepSoundCollection: + path: /Audio/Effects/Footsteps/slime1.ogg + params: + volume: 3 + - type: Tag + tags: + - FootstepSound + - DoorBumpOpener + - type: Butcherable + butcheringType: Knife + spawned: + - id: FoodMeatSlime + amount: 2 + - type: Respirator + damage: + types: + Asphyxiation: 0.2 + damageRecovery: + types: + Asphyxiation: -1.0 + maxSaturation: 15 + - type: Damageable + damageContainer: Biological + damageModifierSet: Slime + - type: Bloodstream + bloodReagent: Slime + bloodlossDamage: + types: + Bloodloss: + 0.5 + bloodlossHealDamage: + types: + Bloodloss: + -0.25 + - type: Barotrauma + damage: + types: + Blunt: 0.45 + - type: Reactive + groups: + Flammable: [ Touch ] + Extinguish: [ Touch ] + reactions: + - reagents: [ Water, SpaceCleaner ] + methods: [ Touch ] + effects: + - !type:WashCreamPieReaction + - reagents: [ Water ] + methods: [ Touch ] + effects: + - !type:HealthChange + scaleByQuantity: true + damage: + types: + Heat: 3 + - !type:PopupMessage + type: Local + messages: [ "slime-hurt-by-water-popup" ] + probability: 0.25 + - type: Body + prototype: Slimes + requiredLegs: 1 + - type: MeleeWeapon + altDisarm: false + soundHit: + path: /Audio/Weapons/punch3.ogg + angle: 0 + animation: WeaponArcPunch + damage: + types: + Blunt: 6 + Structural: 4 + Caustic: 4 + - type: InteractionPopup + successChance: 0.5 + interactSuccessString: petting-success-slimes + interactFailureString: petting-failure-generic + - type: Speech + speechVerb: Slime + speechSounds: Slime + - type: TypingIndicator + proto: slime + - type: SurgeryTarget + - type: UserInterface + interfaces: + enum.SurgeryUIKey.Key: + type: SurgeryBui + - type: Fauna # Lavaland Change + +- type: entity + name: geras + description: A geras of a slime - the name is ironic, isn't it? + id: MobSlimesGeras + parent: BaseMobAdultSlimes + categories: [ HideSpawnMenu ] + components: + # they portable... + - type: MovementSpeedModifier + baseWalkSpeed: 3 + baseSprintSpeed: 6 # +1 from normal movement speed + - type: MobThresholds + thresholds: + 0: Alive + 100: Dead # weak af tho + - type: NpcFactionMember + factions: + - NanoTrasen + - type: MultiHandedItem + - type: Item + size: Huge + - type: Sprite + layers: + - map: [ "colorMap" ] + state: slime_geras + - map: [ "faceMap" ] + state: aslime_mischievous + shader: unshaded + - map: [ "eyesMap" ] + state: slime_geras_eyes + shader: unshaded + - type: RandomSprite + selected: + colorMap: + slime_geras: "#0000FF" + eyesMap: + slime_geras_eyes: "#0000FF" + - type: Speech + speechVerb: Slime + speechSounds: Slime + allowedEmotes: ['Squish', 'Bubble', 'Pop'] # Imp: add Bubble, Pop + - type: TypingIndicator + proto: slime + - type: Vocal # Omu start + sounds: + Male: MaleSlime + Female: FemaleSlime + Unsexed: MaleSlime # Omu end + - type: MeleeWeapon + attackRate: 2 + damage: + types: + Blunt: 4 diff --git a/Resources/Prototypes/_DEN/Polymorphs/polymorph.yml b/Resources/Prototypes/_DEN/Polymorphs/polymorph.yml new file mode 100644 index 00000000000..18b7dc2653a --- /dev/null +++ b/Resources/Prototypes/_DEN/Polymorphs/polymorph.yml @@ -0,0 +1,10 @@ +- type: polymorph + id: SlimeMorphGeras + configuration: + entity: MobSlimesGeras + transferName: true + transferHumanoidAppearance: false + inventory: None + transferDamage: true + revertOnDeath: true + revertOnCrit: true diff --git a/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml b/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml index 0ca987c2f1a..2865a89d7a8 100644 --- a/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml +++ b/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml @@ -25,6 +25,9 @@ SPDX-License-Identifier: AGPL-3.0-or-later They exhale nitrous oxide and are unaffected by it. Their body processes only two toxins at a time compared to three. + Slimepeople can morph into a [bold]"geras"[/bold] (an archaic slimefolk term), which is a smaller slime form[/bold]. It's handy for a quick getaway. A geras is small enough to pick up (with two hands) + and fits in a duffelbag. + Slimepeople have an [bold]internal 2x3 storage inventory[/bold] inside of their slime membrane. Anyone can see what's inside and take it out of you without asking, so be careful. diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_3.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_3.png new file mode 100644 index 00000000000..c5667beba53 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_3.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_angry.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_angry.png new file mode 100644 index 00000000000..2b01286b195 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_angry.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_mischievous.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_mischievous.png new file mode 100644 index 00000000000..286f7caa61e Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/aslime_mischievous.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/blue_adult_slime.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/blue_adult_slime.png new file mode 100644 index 00000000000..880c345fe9c Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/blue_adult_slime.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/blue_adult_slime_dead.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/blue_adult_slime_dead.png new file mode 100644 index 00000000000..860f1c1b41c Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/blue_adult_slime_dead.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/green_adult_slime.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/green_adult_slime.png new file mode 100644 index 00000000000..0ad27c50e16 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/green_adult_slime.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/green_adult_slime_dead.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/green_adult_slime_dead.png new file mode 100644 index 00000000000..7aca93b9692 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/green_adult_slime_dead.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/meta.json b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/meta.json new file mode 100644 index 00000000000..974edb90d55 --- /dev/null +++ b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/meta.json @@ -0,0 +1,155 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from the tgstation at https://github.com/tgstation/tgstation/blob/832cecdbb1118fc8b45fbc1d41a1a928d5be2eef/icons/mob/simple/slimes.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "blue_adult_slime", + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15 + ] + ] + }, + { + "name": "blue_adult_slime_dead" + }, + { + "name": "green_adult_slime", + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15 + ] + ] + }, + { + "name": "green_adult_slime_dead" + }, + { + "name": "yellow_adult_slime", + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15 + ] + ] + }, + { + "name": "yellow_adult_slime_dead" + }, + { + "name": "aslime_3", + "directions": 4 + }, + { + "name": "rainbow_slime_extract", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "rainbow_baby_slime", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "rainbow_baby_slime_dead", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "aslime_angry", + "directions": 4 + }, + { + "name": "aslime_mischievous", + "directions": 4 + }, + { + "name": "slime_geras", + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15 + ] + ] + }, + { + "name": "slime_geras_eyes", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_baby_slime.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_baby_slime.png new file mode 100644 index 00000000000..73e07be2aed Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_baby_slime.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_baby_slime_dead.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_baby_slime_dead.png new file mode 100644 index 00000000000..dd5f6099ab6 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_baby_slime_dead.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_slime_extract.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_slime_extract.png new file mode 100644 index 00000000000..2c09eea441f Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/rainbow_slime_extract.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/slime_geras.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/slime_geras.png new file mode 100644 index 00000000000..15d9f6066b9 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/slime_geras.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/slime_geras_eyes.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/slime_geras_eyes.png new file mode 100644 index 00000000000..66c5fa0fdb0 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/slime_geras_eyes.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/yellow_adult_slime.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/yellow_adult_slime.png new file mode 100644 index 00000000000..9a6c1b2813c Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/yellow_adult_slime.png differ diff --git a/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/yellow_adult_slime_dead.png b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/yellow_adult_slime_dead.png new file mode 100644 index 00000000000..9506fba32f0 Binary files /dev/null and b/Resources/Textures/_DEN/Mobs/Aliens/slimes.rsi/yellow_adult_slime_dead.png differ