Skip to content
Open
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
24 changes: 24 additions & 0 deletions Content.Server/_DEN/Geras/GerasComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2024 DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com>
// SPDX-FileCopyrightText: 2024 sleepyyapril <flyingkarii@gmail.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;
using Content.Shared.Polymorph;
using Robust.Shared.Prototypes;

namespace Content.Server._DEN.Geras;

/// <summary>
/// This component assigns the entity with a polymorph action.
/// </summary>
[RegisterComponent]
public sealed partial class GerasComponent : Component
{
[DataField] public ProtoId<PolymorphPrototype> GerasPolymorphId = "SlimeMorphGeras";

[DataField] public EntProtoId GerasAction = "ActionMorphGeras";

[DataField] public EntityUid? GerasActionEntity;
}
93 changes: 93 additions & 0 deletions Content.Server/_DEN/Geras/GerasSystem.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <inheritdoc/>
public sealed class GerasSystem : SharedGerasSystem
{
[Dependency] private readonly PolymorphSystem _polymorphSystem = default!;
[Dependency] private readonly ActionsSystem _actionsSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;

/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<GerasComponent, MorphIntoGeras>(OnMorphIntoGeras);
SubscribeLocalEvent<GerasComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<GerasComponent, EntityZombifiedEvent>(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<ZombieComponent>(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<RandomSpriteComponent>(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<HumanoidAppearanceComponent>(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.
}
}
21 changes: 21 additions & 0 deletions Content.Shared/_DEN/Geras/SharedGerasSystem.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// 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.
/// </summary>
public abstract class SharedGerasSystem : EntitySystem
{

}

public sealed partial class MorphIntoGeras : InstantActionEvent
{

}
7 changes: 7 additions & 0 deletions Resources/Locale/en-US/_DEN/geras/geras.ftl
Original file line number Diff line number Diff line change
@@ -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!
1 change: 1 addition & 0 deletions Resources/Prototypes/Entities/Mobs/Species/slime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions Resources/Prototypes/_DEN/Actions/types.yml
Original file line number Diff line number Diff line change
@@ -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
175 changes: 175 additions & 0 deletions Resources/Prototypes/_DEN/Entities/Mobs/NPCs/slimes.yml
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions Resources/Prototypes/_DEN/Polymorphs/polymorph.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- type: polymorph
id: SlimeMorphGeras
configuration:
entity: MobSlimesGeras
transferName: true
transferHumanoidAppearance: false
inventory: None
transferDamage: true
revertOnDeath: true
revertOnCrit: true
3 changes: 3 additions & 0 deletions Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading