Skip to content
2 changes: 0 additions & 2 deletions Content.Client/ADT/Geras/GerasSystem.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Content.Client.ADT.Geras.Component;
using Content.Shared.ADT.Geras;
using Robust.Client.GameObjects;
using Content.Shared.Item;
using static Robust.Client.GameObjects.SpriteComponent;

namespace Content.Client.ADT.Geras;

Expand Down
86 changes: 84 additions & 2 deletions Content.Server/ADT/Geras/GerasSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.ActionBlocker;
using Content.Shared.Item;
using Content.Shared.Hands;
using Robust.Shared.Utility;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Anomaly.Components;
using Content.Shared.Inventory;
using Content.Shared.Nuke;
using Content.Server.Ghost.Roles.Components;
using Content.Shared.Mind.Components;
using Content.Shared.Storage;
using Robust.Shared.Containers;
using System.Linq;

namespace Content.Server.ADT.Geras;

Expand All @@ -21,8 +30,14 @@ public sealed class GerasSystem : SharedGerasSystem
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GerasComponent, MorphIntoGeras>(OnMorphIntoGeras);
SubscribeLocalEvent<GerasComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<GerasComponent, EntityZombifiedEvent>(OnZombification);
Expand All @@ -42,17 +57,84 @@ private void OnMapInit(EntityUid uid, GerasComponent component, MapInitEvent arg
}
}

private bool HasForbiddenComponent(EntityUid uid)
{
return HasComp<NukeDiskComponent>(uid) ||
HasComp<GhostRoleComponent>(uid) ||
HasComp<MobStateComponent>(uid);
}

private void EjectForbiddenRecursive(EntityUid item, EntityUid owner)
{
if (!TryComp<ContainerManagerComponent>(item, out var containerManager))
return;

foreach (var container in containerManager.Containers.Values)
{
var containedList = container.ContainedEntities.ToArray();
foreach (var contained in containedList)
{
if (HasForbiddenComponent(contained))
{
_container.Remove(contained, container, force: true);
_transform.DropNextTo(contained, owner);
}
else
{
EjectForbiddenRecursive(contained, owner);
}
}
}
}

private void OnMorphIntoGeras(EntityUid uid, GerasComponent component, MorphIntoGeras args)
{
if (HasComp<ZombieComponent>(uid))
return;

if (HasComp<AnomalyComponent>(uid))
{
_popupSystem.PopupEntity(Loc.GetString("geras-popup-cant-use-anomaly"), uid, uid);
return;
}

if (!_actionBlocker.CanInteract(uid, null) || _mobState.IsDead(uid) || _mobState.IsIncapacitated(uid))
{
_popupSystem.PopupEntity(Loc.GetString("geras-popup-cant-use"), uid, uid);
return;
}

if (TryComp<HandsComponent>(uid, out var hands))
{
foreach (var held in _hands.EnumerateHeld(uid))
{
_hands.TryDrop(uid, held, Transform(uid).Coordinates);
}
}

if (TryComp<InventoryComponent>(uid, out var inventoryComp))
{
_inventorySystem.TryUnequip(uid, "outerClothing", force: true);

foreach (var slot in inventoryComp.Slots)
{
if (_inventorySystem.TryGetSlotEntity(uid, slot.Name, out var itemUid) && itemUid.HasValue)
{
var item = itemUid.Value;
if (HasForbiddenComponent(item))
{
_inventorySystem.TryUnequip(uid, slot.Name, force: true);
}
else
{
EjectForbiddenRecursive(item, uid);
}
}
}
}

EjectForbiddenRecursive(uid, uid);

var ent = _polymorphSystem.PolymorphEntity(uid, component.GerasPolymorphId);

if (!ent.HasValue)
Expand Down
74 changes: 69 additions & 5 deletions Content.Server/Polymorph/Systems/PolymorphSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
using Content.Shared.Speech.Muting;
using Content.Shared.ADT.Traits;
using Content.Shared.Storage.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Temperature.Systems;
using Content.Shared.Atmos.Components;
using Content.Shared.Temperature.Components;
//ADT-Geras-Tweak-End
using Content.Server.Inventory;
using Content.Server.Polymorph.Components;
Expand Down Expand Up @@ -69,6 +73,9 @@ public sealed partial class PolymorphSystem : EntitySystem
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly FollowerSystem _follow = default!; // goob edit
[Dependency] private readonly FlammableSystem _flammable = default!; //ADT-Geras-Tweak
[Dependency] private readonly SharedStaminaSystem _stamina = default!; //ADT-Geras-Tweak
[Dependency] private readonly TemperatureSystem _temperatureSystem = default!; //ADT-Geras-Tweak

[Dependency] private readonly ISerializationManager _serialization = default!; // ADT-Changeling-Tweak
private const string RevertPolymorphId = "ActionRevertPolymorph";
Expand Down Expand Up @@ -207,11 +214,16 @@ private void OnPolymorphedTerminating(Entity<PolymorphedEntityComponent> ent, re
/// <returns>The new entity, or null if the polymorph failed.</returns>
public EntityUid? PolymorphEntity(EntityUid uid, PolymorphConfiguration configuration)
{
// If they're morphed, check their current config to see if they can be
// morphed again
if (!configuration.IgnoreAllowRepeatedMorphs
&& TryComp<PolymorphedEntityComponent>(uid, out var currentPoly)
&& !currentPoly.Configuration.AllowRepeatedMorphs)
//ADT-Geras-Tweak-Start
if (configuration.CanNotPolymorphInStorage && HasComp<InsideEntityStorageComponent>(uid))
{
_popup.PopupEntity(Loc.GetString("polymorph-in-storage-forbidden"), uid, uid);
return null;
}
//ADT-Geras-Tweak-End

// if it's already morphed, don't allow it again with this condition active.
if (!configuration.AllowRepeatedMorphs && HasComp<PolymorphedEntityComponent>(uid))
return null;

// If this polymorph has a cooldown, check if that amount of time has passed since the
Expand Down Expand Up @@ -393,6 +405,30 @@ private void OnPolymorphedTerminating(Entity<PolymorphedEntityComponent> ent, re
}
}
}

if (configuration.TransferFlame && TryComp<FlammableComponent>(uid, out var parentFlame))
{
var childFlame = EnsureComp<FlammableComponent>(child);
_flammable.SetFireStacks(child, parentFlame.FireStacks, childFlame, parentFlame.OnFire);
}

if (configuration.TransferStaminaDamage && TryComp<StaminaComponent>(uid, out var parentStam))
{
var childStam = EnsureComp<StaminaComponent>(child);
var parentEffective = _stamina.GetStaminaDamage(uid, parentStam);
var fraction = parentEffective / parentStam.CritThreshold;
var childTarget = fraction * childStam.CritThreshold;
_stamina.TakeStaminaDamage(child, childTarget, childStam, visual: false, ignoreResist: true);
}

if (configuration.TransferTemperature)
{
if (TryComp<TemperatureComponent>(uid, out var parentTemp))
{
var childTemp = EnsureComp<TemperatureComponent>(child);
_temperatureSystem.ForceChangeTemperature(child, parentTemp.CurrentTemperature, childTemp);
}
}
// ADT-Geras-Tweak-End

if (configuration.TransferHumanoidAppearance)
Expand Down Expand Up @@ -589,6 +625,34 @@ private void RetrievePausedEntity(EntityUid user, EntityUid target)
if (TryComp<PolymorphableComponent>(parent, out var polymorphableComponent))
polymorphableComponent.LastPolymorphEnd = _gameTiming.CurTime;

//ADT-Geras-Tweak-Start
if (component.Configuration.TransferFlame && TryComp<FlammableComponent>(uid, out var childFlame))
{
var parentFlame = EnsureComp<FlammableComponent>(parent);
_flammable.SetFireStacks(parent, childFlame.FireStacks, parentFlame, childFlame.OnFire);
}

if (component.Configuration.TransferStaminaDamage && TryComp<StaminaComponent>(uid, out var childStam))
{
var parentStam = EnsureComp<StaminaComponent>(parent);
var childEffective = _stamina.GetStaminaDamage(uid, childStam);
var fraction = childEffective / childStam.CritThreshold;
var parentTarget = fraction * parentStam.CritThreshold;
var parentCurrent = _stamina.GetStaminaDamage(parent, parentStam);
var delta = parentTarget - parentCurrent;
_stamina.TakeStaminaDamage(parent, delta, parentStam, visual: false, ignoreResist: true);
}

if (component.Configuration.TransferTemperature)
{
if (TryComp<TemperatureComponent>(uid, out var childTemp))
{
var parentTemp = EnsureComp<TemperatureComponent>(parent);
_temperatureSystem.ForceChangeTemperature(parent, childTemp.CurrentTemperature, parentTemp);
}
}
//ADT-Geras-Tweak-End

// if an item polymorph was picked up, put it back down after reverting
_transform.AttachToGridOrMap(parent, parentXform);

Expand Down
18 changes: 18 additions & 0 deletions Content.Shared/Polymorph/PolymorphPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,24 @@ public sealed partial record PolymorphConfiguration
[DataField(serverOnly: true)]
public bool TransferQuirks;

/// <summary>
/// Whether or not the entity transfers its flame between forms.
/// </summary>
[DataField(serverOnly: true)]
public bool TransferFlame = true;

/// <summary>
/// Whether or not the entity transfers its stamina damage between forms.
/// </summary>
[DataField(serverOnly: true)]
public bool TransferStaminaDamage = true;

/// <summary>
/// Whether or not the entity transfers its temperature between forms.
/// </summary>
[DataField(serverOnly: true)]
public bool TransferTemperature = true;

/// <summary>
/// Whether or not the entity can polymorph between forms in storage.
/// </summary>
Expand Down
5 changes: 3 additions & 2 deletions Resources/Locale/ru-RU/ADT/geras/geras.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
geras-popup-cant-use = Я не могу сконцентрироваться!
geras-popup-morph-message-user = Ты пытаешься изменить свою форму...
geras-popup-cant-use = Вы не можете сконцентрироваться!
geras-popup-cant-use-anomaly = Вы не можете сконцентрироваться из-за аномалии внутри вас!
geras-popup-morph-message-user = Вы пытаетесь изменить свою форму...
geras-popup-morph-message-others = { $entity } начинает менять свою форму!
2 changes: 1 addition & 1 deletion Resources/Prototypes/ADT/Actions/types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
components:
- type: Action
itemIconStyle: BigAction
useDelay: 60 # prevent spam
useDelay: 5 # prevent spam
priority: -20
checkCanInteract: true
icon:
Expand Down
54 changes: 49 additions & 5 deletions Resources/Prototypes/ADT/Entities/Mobs/NPCs/slimes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
description: A slime.
id: ADTMobSlimesGeras
parent:
- BaseSimpleMob
- BaseMob
- MobDamageable
- MobCombat
- MobBloodstream
- MobFlammable
Expand Down Expand Up @@ -100,16 +101,12 @@
speedModifier: 1
useSound:
path: /Audio/Items/crowbar.ogg
- type: Internals
- type: Buckle
# - type: StandingState #зачем им ползать? хз они даже не готовы
- type: ProjectileIgnoreCrawling
- type: NpcFactionMember
factions:
- NanoTrasen
- type: Climbing
- type: NameIdentifier
group: GenericNumber
- type: SlowOnDamage
speedModifierThresholds:
60: 0.7
Expand Down Expand Up @@ -174,3 +171,50 @@
- type: TimeDespawnDamage
- type: Hands # They still don't have hands.
- type: ComplexInteraction
- type: Temperature
heatDamageThreshold: 325
coldDamageThreshold: 260
currentTemperature: 310.15
specificHeat: 42
coldDamage:
types:
Cold: 0.1
heatDamage:
types:
Heat: 1.5
- type: TemperatureSpeed
thresholds:
293: 0.9
260: 0.6
230: 0.4
- type: ThermalRegulator
metabolismHeat: 800
radiatedHeat: 100
implicitHeatRegulation: 500
sweatHeatRegulation: 2000
shiveringHeatRegulation: 2000
normalBodyTemperature: 310.15
thermalRegulationTemperatureThreshold: 2
- type: StunVisuals
- type: Reactive
groups:
Flammable: [ Touch ]
Extinguish: [ Touch ]
reactions:
- reagents: [ Water, SpaceCleaner ]
methods: [ Touch ]
effects:
- !type:WashCreamPie
- reagents: [ Water ]
methods: [ Touch ]
effects:
- !type:HealthChange
damage:
types:
Heat: 0.05
- !type:PopupMessage
type: Local
visualType: Large
messages: [ "slime-hurt-by-water-popup" ]
probability: 0.25
- type: PickupHumans
3 changes: 3 additions & 0 deletions Resources/Prototypes/ADT/Polymorphs/polymorphs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -554,3 +554,6 @@
transferDamage: true
revertOnDeath: true
revertOnCrit: true
transferFlame: true
transferStaminaDamage: true
transferTemperature: true
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 @@ -146,6 +146,7 @@
tallscale: 1.05
short: true
shortscale: 0.95
- type: Geras
#End ADT tweak

- type: entity
Expand Down
Loading