Skip to content

Commit

Permalink
ling last resort ability (and bug fix) (space-wizards#527)
Browse files Browse the repository at this point in the history
* last resort (and bug fix)

* last resort part 2

* ling and absorbed body cant be put on meat spike

* done???

* 2 minutes timer

* rabbit said so (butcher)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* rabbit said so (:)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* requested changes

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
yglop and coderabbitai[bot] authored Aug 27, 2024
1 parent ce37e18 commit c1592f3
Show file tree
Hide file tree
Showing 18 changed files with 310 additions and 21 deletions.
56 changes: 56 additions & 0 deletions Content.Server/Goobstation/Changeling/ChangelingEggSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Robust.Shared.Timing;
using Robust.Server.GameObjects;
using Content.Shared.Changeling;
using Content.Shared.Mind;
using Content.Server.Body.Systems;
using Content.Shared.Store.Components;

namespace Content.Server.Changeling;

public sealed partial class ChangelingEggSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly BodySystem _bodySystem = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;


public override void Update(float frameTime)
{
base.Update(frameTime);

if (!_timing.IsFirstTimePredicted)
return;

foreach (var comp in EntityManager.EntityQuery<ChangelingEggComponent>())
{
var uid = comp.Owner;

if (_timing.CurTime < comp.UpdateTimer)
continue;

comp.UpdateTimer = _timing.CurTime + TimeSpan.FromSeconds(comp.UpdateCooldown);

Cycle(uid, comp);
}
}
public void Cycle(EntityUid uid, ChangelingEggComponent comp)
{
if (comp.active == false)
{
comp.active = true;
return;
}

var newUid = Spawn("MobMonkey", Transform(uid).Coordinates);

var mind = EnsureComp<MindComponent>(newUid);
_mind.TransferTo(comp.lingMind, newUid);

var ling = EnsureComp<ChangelingComponent>(newUid);
ling = comp.lingComp;

EntityManager.AddComponent(newUid, comp.lingStore);

_bodySystem.GibBody((EntityUid) uid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public void SubscribeAbilities()
SubscribeLocalEvent<ChangelingComponent, StingMuteEvent>(OnStingMute);
SubscribeLocalEvent<ChangelingComponent, StingTransformEvent>(OnStingTransform);
SubscribeLocalEvent<ChangelingComponent, StingFakeArmbladeEvent>(OnStingFakeArmblade);
SubscribeLocalEvent<ChangelingComponent, StingLayEggsEvent>(OnLayEgg);

SubscribeLocalEvent<ChangelingComponent, ActionAnatomicPanaceaEvent>(OnAnatomicPanacea);
SubscribeLocalEvent<ChangelingComponent, ActionAugmentedEyesightEvent>(OnAugmentedEyesight);
Expand Down Expand Up @@ -437,6 +438,50 @@ private void OnStingFakeArmblade(EntityUid uid, ChangelingComponent comp, ref St

PlayMeatySound(target, comp);
}
public void OnLayEgg(EntityUid uid, ChangelingComponent comp, ref StingLayEggsEvent args)
{
var target = args.Target;

if (!_mobState.IsDead(target))
{
_popup.PopupEntity(Loc.GetString("changeling-absorb-fail-incapacitated"), uid, uid);
return;
}
if (HasComp<AbsorbedComponent>(target))
{
_popup.PopupEntity(Loc.GetString("changeling-absorb-fail-absorbed"), uid, uid);
return;
}
if (!HasComp<AbsorbableComponent>(target))
{
_popup.PopupEntity(Loc.GetString("changeling-absorb-fail-unabsorbable"), uid, uid);
return;
}

var mind = _mind.GetMind(uid);
if (mind == null)
return;
if (!TryComp<StoreComponent>(uid, out var storeComp))
return;

comp.IsInLastResort = false;
comp.IsInLesserForm = true;

var eggComp = EnsureComp<ChangelingEggComponent>(target);
eggComp.lingComp = comp;
eggComp.lingMind = (EntityUid) mind;
eggComp.lingStore = _serialization.CreateCopy(storeComp, notNullableOverride: true);

EnsureComp<AbsorbedComponent>(target);
var dmg = new DamageSpecifier(_proto.Index(AbsorbedDamageGroup), 200);
_damage.TryChangeDamage(target, dmg, false, false);
_blood.ChangeBloodReagent(target, "FerrochromicAcid");
_blood.SpillAllSolutions(target);

PlayMeatySound((EntityUid) uid, comp);

_bodySystem.GibBody((EntityUid) uid);
}

#endregion

Expand Down Expand Up @@ -557,25 +602,50 @@ public void OnLastResort(EntityUid uid, ChangelingComponent comp, ref ActionLast
if (!TryUseAbility(uid, comp, args))
return;

// todo: implement
comp.IsInLastResort = true;

var newUid = TransformEntity(
uid,
protoId: "MobHeadcrab",
comp: comp,
dropInventory: true,
transferDamage: false);

if (newUid == null)
{
comp.IsInLastResort = false;
comp.Chemicals += Comp<ChangelingActionComponent>(args.Action).ChemicalCost;
return;
}

_explosionSystem.QueueExplosion(
(EntityUid) newUid,
typeId: "Default",
totalIntensity: 1,
slope: 4,
maxTileIntensity: 2);

_actions.AddAction((EntityUid) newUid, "ActionLayEgg");

PlayMeatySound((EntityUid) newUid, comp);
}
public void OnLesserForm(EntityUid uid, ChangelingComponent comp, ref ActionLesserFormEvent args)
{
if (!TryUseAbility(uid, comp, args))
return;

comp.IsInLesserForm = true;
var newUid = TransformEntity(uid, protoId: "MobMonkey", comp: comp);
if (newUid == null)
{
comp.IsInLesserForm = false;
comp.Chemicals += Comp<ChangelingActionComponent>(args.Action).ChemicalCost;
return;
}

PlayMeatySound((EntityUid) newUid, comp);
var loc = Loc.GetString("changeling-transform-others", ("user", Identity.Entity((EntityUid) newUid, EntityManager)));
_popup.PopupEntity(loc, (EntityUid) newUid, PopupType.LargeCaution);

comp.IsInLesserForm = true;
}
public void OnSpacesuit(EntityUid uid, ChangelingComponent comp, ref ActionSpacesuitEvent args)
{
Expand Down
27 changes: 22 additions & 5 deletions Content.Server/Goobstation/Changeling/ChangelingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
using Content.Shared.Mobs.Components;
using Content.Server.Stunnable;
using Content.Shared.Jittering;
using Content.Server.Explosion.EntitySystems;
using System.Linq;

namespace Content.Server.Changeling;
Expand Down Expand Up @@ -98,6 +99,8 @@ public sealed partial class ChangelingSystem : EntitySystem
[Dependency] private readonly SharedPuddleSystem _puddle = default!;
[Dependency] private readonly StunSystem _stun = default!;
[Dependency] private readonly SharedJitteringSystem _jitter = default!;
[Dependency] private readonly ExplosionSystem _explosionSystem = default!;
[Dependency] private readonly BodySystem _bodySystem = default!;

public EntProtoId ArmbladePrototype = "ArmBladeChangeling";
public EntProtoId FakeArmbladePrototype = "FakeArmBladeChangeling";
Expand Down Expand Up @@ -297,7 +300,7 @@ public bool TryUseAbility(EntityUid uid, ChangelingComponent comp, BaseActionEve
return false;
}

if (!lingAction.UseInLesserForm && comp.IsInLesserForm)
if ((!lingAction.UseInLesserForm && comp.IsInLesserForm) || (!lingAction.UseInLastResort && comp.IsInLastResort))
{
_popup.PopupEntity(Loc.GetString("changeling-action-fail-lesserform"), uid, uid);
return false;
Expand Down Expand Up @@ -452,14 +455,22 @@ public bool TryStealDNA(EntityUid uid, EntityUid target, ChangelingComponent com
newComp.MaxBiomass = comp.MaxBiomass;

newComp.IsInLesserForm = comp.IsInLesserForm;
newComp.IsInLastResort = comp.IsInLastResort;
newComp.CurrentForm = comp.CurrentForm;

newComp.TotalAbsorbedEntities = comp.TotalAbsorbedEntities;
newComp.TotalStolenDNA = comp.TotalStolenDNA;

return comp;
}
private EntityUid? TransformEntity(EntityUid uid, TransformData? data = null, EntProtoId? protoId = null, ChangelingComponent? comp = null, bool persistentDna = false)
private EntityUid? TransformEntity(
EntityUid uid,
TransformData? data = null,
EntProtoId? protoId = null,
ChangelingComponent? comp = null,
bool dropInventory = false,
bool transferDamage = true,
bool persistentDna = false)
{
EntProtoId? pid = null;

Expand All @@ -476,12 +487,14 @@ public bool TryStealDNA(EntityUid uid, EntityUid target, ChangelingComponent com
var config = new PolymorphConfiguration()
{
Entity = (EntProtoId) pid,
TransferDamage = true,
TransferDamage = transferDamage,
Forced = true,
Inventory = PolymorphInventoryChange.Transfer,
Inventory = (dropInventory) ? PolymorphInventoryChange.Drop : PolymorphInventoryChange.Transfer,
RevertOnCrit = false,
RevertOnDeath = false
};


var newUid = _polymorph.PolymorphEntity(uid, config);

if (newUid == null)
Expand Down Expand Up @@ -553,7 +566,11 @@ public bool TryTransform(EntityUid target, ChangelingComponent comp, bool sting
EntityUid? newUid = null;
if (sting)
newUid = TransformEntity(target, data: data, persistentDna: persistentDna);
else newUid = TransformEntity(target, data: data, comp: comp, persistentDna: persistentDna);
else
{
comp.IsInLesserForm = false;
newUid = TransformEntity(target, data: data, comp: comp, persistentDna: persistentDna);
}

if (newUid != null)
{
Expand Down
14 changes: 14 additions & 0 deletions Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using Robust.Shared.Player;
using Robust.Shared.Random;
using static Content.Shared.Kitchen.Components.KitchenSpikeComponent;
using Content.Shared.Changeling; // Goobstation

namespace Content.Server.Kitchen.EntitySystems
{
Expand Down Expand Up @@ -223,6 +224,19 @@ private bool Spikeable(EntityUid uid, EntityUid userUid, EntityUid victimUid,
return false;
}

// Goobstation - start
if (HasComp<ChangelingComponent>(victimUid))
{
_popupSystem.PopupEntity(Loc.GetString("comp-kitchen-spike-deny-changeling", ("victim", Identity.Entity(victimUid, EntityManager)), ("this", uid)), victimUid, userUid);
return false;
}
if (HasComp<AbsorbedComponent>(victimUid))
{
_popupSystem.PopupEntity(Loc.GetString("comp-kitchen-spike-deny-absorbed", ("victim", Identity.Entity(victimUid, EntityManager)), ("this", uid)), victimUid, userUid);
return false;
}
// Goobstation - end

switch (butcherable.Type)
{
case ButcheringType.Spike:
Expand Down
3 changes: 3 additions & 0 deletions Content.Shared/Goobstation/Changeling/Changeling.Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public sealed partial class ChangelingActionComponent : Component

[DataField] public float BiomassCost = 0;

[DataField] public bool UseInLastResort = false;

[DataField] public bool UseInLesserForm = false;

[DataField] public float RequireAbsorbed = 0;
Expand Down Expand Up @@ -49,6 +51,7 @@ public sealed partial class StingLethargicEvent : EntityTargetActionEvent { }
public sealed partial class StingMuteEvent : EntityTargetActionEvent { }
public sealed partial class StingFakeArmbladeEvent : EntityTargetActionEvent { }
public sealed partial class StingTransformEvent : EntityTargetActionEvent { }
public sealed partial class StingLayEggsEvent : EntityTargetActionEvent { }

#endregion

Expand Down
2 changes: 2 additions & 0 deletions Content.Shared/Goobstation/Changeling/ChangelingComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public sealed partial class ChangelingComponent : Component

public bool IsInLesserForm = false;

public bool IsInLastResort = false;


public Dictionary<string, EntityUid?> Equipment = new();

Expand Down
21 changes: 21 additions & 0 deletions Content.Shared/Goobstation/Changeling/ChangelingEggComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Content.Shared.Mind;
using Content.Shared.Store.Components;
using Robust.Shared.GameStates;

namespace Content.Shared.Changeling;

[RegisterComponent, NetworkedComponent]

public sealed partial class ChangelingEggComponent : Component
{
public ChangelingComponent lingComp;
public EntityUid lingMind;
public StoreComponent lingStore;

/// <summary>
/// Countdown before spawning monkey.
/// </summary>
public TimeSpan UpdateTimer = TimeSpan.Zero;
public float UpdateCooldown = 120f;
public bool active = false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ evolutionmenu-utility-fleshmend-name = Fleshmend
evolutionmenu-utility-fleshmend-desc =
Rapidly heal yourself of all bruises and burns.
Costs 35 chemicals.
evolutionmenu-utility-lastresort-name = Last Resort
evolutionmenu-utility-lastresort-desc =
Abandon your current body and escape in the form of a headslug.
Costs 20 chemicals.
evolutionmenu-utility-lesserform-name = Lesser Form
evolutionmenu-utility-lesserform-desc =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
comp-kitchen-spike-deny-collect = { CAPITALIZE(THE($this)) } already has something on it, finish collecting its meat first!
comp-kitchen-spike-deny-butcher = { CAPITALIZE(THE($victim)) } can't be butchered on { THE($this) }.
comp-kitchen-spike-deny-changeling = { CAPITALIZE(THE($victim)) } resists being put on { THE($this) }.
comp-kitchen-spike-deny-absorbed = { CAPITALIZE(THE($victim)) } has nothing left to butcher.
comp-kitchen-spike-deny-butcher-knife = { CAPITALIZE(THE($victim)) } can't be butchered on { THE($this) }, you need to butcher it using a knife.
comp-kitchen-spike-deny-not-dead = { CAPITALIZE(THE($victim)) } can't be butchered. { CAPITALIZE(SUBJECT($victim)) } { CONJUGATE-BE($victim) } is not dead!
Expand Down
Loading

0 comments on commit c1592f3

Please sign in to comment.