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
80 changes: 78 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 _handsSystem = 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,78 @@ private void OnMapInit(EntityUid uid, GerasComponent component, MapInitEvent arg
}
}

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

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

var containedList = storage.Container.ContainedEntities.ToArray();

foreach (var contained in containedList)
{
if (HasForbiddenComponent(contained))
{
_container.Remove(contained, storage.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))
_handsSystem.TryDrop(uid, 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
16 changes: 16 additions & 0 deletions Resources/Prototypes/ADT/Entities/Mobs/NPCs/slimes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,19 @@
- type: TimeDespawnDamage
- type: Hands # They still don't have hands.
- type: ComplexInteraction
- type: Temperature
heatDamageThreshold: 325
coldDamageThreshold: 285
currentTemperature: 310.15
specificHeat: 42
coldDamage:
types:
Cold: 0.1
heatDamage:
types:
Heat: 1.5
- type: TemperatureSpeed
thresholds:
293: 0.8
260: 0.6
230: 0.4
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