Skip to content

Commit

Permalink
We're swaying on horseback.
Browse files Browse the repository at this point in the history
  • Loading branch information
gluesniffler committed Nov 17, 2024
1 parent 2a5e36e commit 5eeac51
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 34 deletions.
7 changes: 6 additions & 1 deletion Content.Server/Body/Systems/BrainSystem.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Content.Server.Body.Components;
using Content.Server.Ghost.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
using Content.Shared.Body.Events;
using Content.Shared.Body.Organ;
using Content.Server.DelayedDeath;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Pointing;
Expand All @@ -12,7 +14,7 @@ namespace Content.Server.Body.Systems
public sealed class BrainSystem : EntitySystem
{
[Dependency] private readonly SharedMindSystem _mindSystem = default!;

[Dependency] private readonly SharedBodySystem _bodySystem = default!;
// Shitmed-Start
public override void Initialize()
{
Expand All @@ -30,6 +32,7 @@ private void HandleRemoval(EntityUid uid, BrainComponent _, ref OrganRemovedFrom

// Prevents revival, should kill the user within a given timespan too.
EnsureComp<DebrainedComponent>(args.OldBody);
EnsureComp<DelayedDeathComponent>(args.OldBody);
HandleMind(uid, args.OldBody);
}
private void HandleAddition(EntityUid uid, BrainComponent _, ref OrganAddedToBodyEvent args)
Expand All @@ -38,6 +41,8 @@ private void HandleAddition(EntityUid uid, BrainComponent _, ref OrganAddedToBod
return;

RemComp<DebrainedComponent>(args.Body);
if (_bodySystem.TryGetBodyOrganComponents<HeartComponent>(args.Body, out var _))
RemComp<DelayedDeathComponent>(args.Body);
HandleMind(args.Body, uid);
}
// Shitmed-End
Expand Down
38 changes: 38 additions & 0 deletions Content.Server/Body/Systems/HeartSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
using Content.Shared.Body.Events;
using Content.Shared.Body.Organ;
using Content.Server.DelayedDeath;
using Content.Server.Body.Components;
namespace Content.Server.Body.Systems;

public sealed class HeartSystem : EntitySystem
{
[Dependency] private readonly SharedBodySystem _bodySystem = default!;
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<HeartComponent, OrganAddedToBodyEvent>(HandleAddition);
SubscribeLocalEvent<HeartComponent, OrganRemovedFromBodyEvent>(HandleRemoval);
}

private void HandleRemoval(EntityUid uid, HeartComponent _, ref OrganRemovedFromBodyEvent args)
{
if (TerminatingOrDeleted(uid) || TerminatingOrDeleted(args.OldBody))
return;

// TODO: Add some form of very violent bleeding effect.
EnsureComp<DelayedDeathComponent>(args.OldBody);
}

private void HandleAddition(EntityUid uid, HeartComponent _, ref OrganAddedToBodyEvent args)
{
if (TerminatingOrDeleted(uid) || TerminatingOrDeleted(args.Body))
return;

if (_bodySystem.TryGetBodyOrganComponents<BrainComponent>(args.Body, out var _))
RemComp<DelayedDeathComponent>(args.Body);
}
// Shitmed-End
}
4 changes: 2 additions & 2 deletions Content.Server/Body/Systems/RespiratorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public override void Update(float frameTime)

UpdateSaturation(uid, -(float) respirator.UpdateInterval.TotalSeconds, respirator);

if (!_mobState.IsIncapacitated(uid) || HasComp<DebrainedComponent>(uid)) // Shitmed: cannot breathe in crit or when no brain.
if (!_mobState.IsIncapacitated(uid) && !HasComp<DebrainedComponent>(uid)) // Shitmed: cannot breathe in crit or when no brain.
{
switch (respirator.Status)
{
Expand Down Expand Up @@ -185,7 +185,7 @@ private void TakeSuffocationDamage(Entity<RespiratorComponent> ent)
RaiseLocalEvent(ent, new MoodEffectEvent("Suffocating"));
}

_damageableSys.TryChangeDamage(ent, ent.Comp.Damage, interruptsDoAfters: false);
_damageableSys.TryChangeDamage(ent, HasComp<DebrainedComponent>(ent) ? ent.Comp.Damage * 4.5f : ent.Comp.Damage, interruptsDoAfters: false);
}

private void StopSuffocation(Entity<RespiratorComponent> ent)
Expand Down
16 changes: 16 additions & 0 deletions Content.Server/DelayedDeath/DelayedDeathComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Content.Server.DelayedDeath;

[RegisterComponent]
public sealed partial class DelayedDeathComponent : Component
{
/// <summary>
/// How long it takes to kill the entity.
/// </summary>
[DataField]
public float DeathTime = 60;

/// <summary>
/// How long it has been since the delayed death timer started.
/// </summary>
public float DeathTimer;
}
31 changes: 31 additions & 0 deletions Content.Server/DelayedDeath/DelayedDeathSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Content.Shared.Body.Organ;
using Content.Shared.Body.Events;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.Mobs.Systems;
using Robust.Shared.Timing;
using Robust.Shared.Prototypes;
namespace Content.Server.DelayedDeath;

public partial class DelayedDeathSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly IPrototypeManager _prototypes = default!;
public override void Update(float frameTime)
{
base.Update(frameTime);

using var query = EntityQueryEnumerator<DelayedDeathComponent>();
while (query.MoveNext(out var ent, out var component))
{
component.DeathTimer += frameTime;

if (component.DeathTimer >= component.DeathTime && !_mobState.IsDead(ent))
{
var damage = new DamageSpecifier(_prototypes.Index<DamageTypePrototype>("Bloodloss"), 150);
_damageable.TryChangeDamage(ent, damage, partMultiplier: 0f);
}
}
}
}
38 changes: 14 additions & 24 deletions Content.Server/Medical/Surgery/SurgerySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ public override void Initialize()

SubscribeLocalEvent<SurgeryToolComponent, AfterInteractEvent>(OnToolAfterInteract);
SubscribeLocalEvent<SurgeryTargetComponent, SurgeryStepDamageEvent>(OnSurgeryStepDamage);
SubscribeLocalEvent<SurgeryDamageChangeEffectComponent, SurgeryStepEvent>(OnSurgeryDamageChange);
SubscribeLocalEvent<SurgerySpecialDamageChangeEffectComponent, SurgeryStepEvent>(OnSurgerySpecialDamageChange);
// You might be wondering "why aren't we using StepEvent for these two?" reason being that StepEvent fires off regardless of success on the previous functions
// so this would heal entities even if you had a used or incorrect organ.
SubscribeLocalEvent<SurgerySpecialDamageChangeEffectComponent, SurgeryStepDamageChangeEvent>(OnSurgerySpecialDamageChange);
SubscribeLocalEvent<SurgeryDamageChangeEffectComponent, SurgeryStepDamageChangeEvent>(OnSurgeryDamageChange);
SubscribeLocalEvent<SurgeryStepEmoteEffectComponent, SurgeryStepEvent>(OnStepScreamComplete);
SubscribeLocalEvent<SurgeryStepSpawnEffectComponent, SurgeryStepEvent>(OnStepSpawnComplete);
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
Expand Down Expand Up @@ -130,37 +132,25 @@ private void OnToolAfterInteract(Entity<SurgeryToolComponent> ent, ref AfterInte
private void OnSurgeryStepDamage(Entity<SurgeryTargetComponent> ent, ref SurgeryStepDamageEvent args) =>
SetDamage(args.Body, args.Damage, args.PartMultiplier, args.User, args.Part);

private void OnSurgeryDamageChange(Entity<SurgeryDamageChangeEffectComponent> ent, ref SurgeryStepEvent args)
private void OnSurgerySpecialDamageChange(Entity<SurgerySpecialDamageChangeEffectComponent> ent, ref SurgeryStepDamageChangeEvent args)
{
// This unintentionally punishes the user if they have an organ in another hand that is already used.
// Imo surgery shouldn't let you automatically pick tools on both hands anyway, it should only use the one you've got in your selected hand.
if (ent.Comp.IsConsumable
&& args.Tools.Where(tool => TryComp<OrganComponent>(tool, out var organComp)
&& !_body.TrySetOrganUsed(tool, true, organComp)).Any())
return;
if (ent.Comp.DamageType == "Rot")
_rot.ReduceAccumulator(args.Body, TimeSpan.FromSeconds(2147483648)); // BEHOLD, SHITCODE THAT I JUST COPY PASTED. I'll redo it at some point, pinky swear :)
else if (ent.Comp.DamageType == "Eye"
&& TryComp(ent, out BlindableComponent? blindComp)
&& blindComp.EyeDamage > 0)
_blindableSystem.AdjustEyeDamage((args.Body, blindComp), -blindComp!.EyeDamage);
}

private void OnSurgeryDamageChange(Entity<SurgeryDamageChangeEffectComponent> ent, ref SurgeryStepDamageChangeEvent args)
{
var damageChange = ent.Comp.Damage;
if (HasComp<ForcedSleepingComponent>(args.Body))
damageChange = damageChange * ent.Comp.SleepModifier;

SetDamage(args.Body, damageChange, 0.5f, args.User, args.Part);
}

private void OnSurgerySpecialDamageChange(Entity<SurgerySpecialDamageChangeEffectComponent> ent, ref SurgeryStepEvent args)
{
if (ent.Comp.IsConsumable
&& args.Tools.Where(tool => TryComp<OrganComponent>(tool, out var organComp)
&& !_body.TrySetOrganUsed(tool, true, organComp)).Any())
return;

if (ent.Comp.DamageType == "Rot")
_rot.ReduceAccumulator(args.Body, TimeSpan.FromSeconds(2147483648)); // BEHOLD, SHITCODE THAT I JUST COPY PASTED. I'll redo it at some point, pinky swear :)
else if (ent.Comp.DamageType == "Eye"
&& TryComp(args.Body, out BlindableComponent? blindComp)
&& blindComp.EyeDamage > 0)
_blindableSystem.AdjustEyeDamage((args.Body, blindComp), -blindComp!.EyeDamage);
}

private void OnStepScreamComplete(Entity<SurgeryStepEmoteEffectComponent> ent, ref SurgeryStepEvent args)
{
if (HasComp<ForcedSleepingComponent>(args.Body))
Expand Down
1 change: 0 additions & 1 deletion Content.Shared/Body/Organ/DebrainedComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ namespace Content.Shared.Body.Organ;

[RegisterComponent]
public sealed partial class DebrainedComponent : Component;
// TODO: Add a timer to kill the entity if they don't get a new brain in time.
6 changes: 6 additions & 0 deletions Content.Shared/Body/Organ/OrganComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ public sealed partial class OrganComponent : Component, ISurgeryToolComponent
[DataField, AutoNetworkedField]
public EntityUid? Body;

/// <summary>
/// Relevant body this organ originally belonged to.
/// </summary>
[DataField, AutoNetworkedField]
public EntityUid? OriginalBody;

/// <summary>
/// Shitcodey solution to not being able to know what name corresponds to each organ's slot ID
/// without referencing the prototype or hardcoding.
Expand Down
1 change: 1 addition & 0 deletions Content.Shared/Body/Systems/SharedBodySystem.Body.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ public virtual HashSet<EntityUid> GibPart(
if (IsPartRoot(bodyEnt, partId, part: part))
return gibs;

ChangeSlotState((partId, part), true);
RemovePartChildren((partId, part), bodyEnt);
foreach (var organ in GetPartOrgans(partId, part))
{
Expand Down
10 changes: 8 additions & 2 deletions Content.Shared/Body/Systems/SharedBodySystem.Organs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Content.Shared.Body.Events;
using Content.Shared.Body.Organ;
using Content.Shared.Body.Part;
using Content.Shared.Damage;
using Robust.Shared.Containers;

namespace Content.Shared.Body.Systems;
Expand Down Expand Up @@ -36,8 +37,13 @@ private void RemoveOrgan(Entity<OrganComponent> organEnt, EntityUid parentPartUi
{
var removedInBodyEv = new OrganRemovedFromBodyEvent(bodyUid, parentPartUid);
RaiseLocalEvent(organEnt, ref removedInBodyEv);
organEnt.Comp.OriginalBody = bodyUid;
}

if (TryComp(parentPartUid, out DamageableComponent? damageable)
&& damageable.TotalDamage > 200)
TrySetOrganUsed(organEnt, true, organEnt.Comp);

organEnt.Comp.Body = null;
Dirty(organEnt, organEnt.Comp);
}
Expand Down Expand Up @@ -216,10 +222,10 @@ public bool TryGetBodyOrganComponents<T>(
public bool TrySetOrganUsed(EntityUid organId, bool used, OrganComponent? organ = null)
{
if (!Resolve(organId, ref organ)
|| organ.Used == true)
|| organ.Used == used)
return false;

organ.Used = true;
organ.Used = used;
Dirty(organId, organ);
return true;
}
Expand Down
6 changes: 6 additions & 0 deletions Content.Shared/Medical/Surgery/SharedSurgerySystem.Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,12 @@ private void OnAddOrganStep(Entity<SurgeryAddOrganStepComponent> ent, ref Surger
&& _body.InsertOrgan(args.Part, tool, insertedOrgan.SlotId, partComp, insertedOrgan))
{
EnsureComp<OrganReattachedComponent>(tool);
if (_body.TrySetOrganUsed(tool, true, insertedOrgan)
&& insertedOrgan.OriginalBody != args.Body)
{
var ev = new SurgeryStepDamageChangeEvent(args.User, args.Body, args.Part, ent);
RaiseLocalEvent(ent, ref ev);
}
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Content.Shared.Damage;

namespace Content.Shared.Medical.Surgery;

/// <summary>
/// Raised on the target entity.
/// </summary>
[ByRefEvent]
public record struct SurgeryStepDamageChangeEvent(EntityUid User, EntityUid Body, EntityUid Part, EntityUid Step);
2 changes: 1 addition & 1 deletion Resources/Prototypes/Body/Organs/Animal/slimes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
sprite: Mobs/Species/Slime/organs.rsi
state: brain-slime
- type: Stomach
- type: Metabolizer
- type: Organ
slotId: core
- type: Metabolizer
maxReagents: 3
metabolizerTypes: [ Slime ]
removeEmpty: true
Expand Down
3 changes: 1 addition & 2 deletions Resources/Prototypes/Body/Organs/diona.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@
- state: eyeball-l
- state: eyeball-r
- type: Eyes
- type: Organ
slotId: eyes


- type: entity
id: OrganDionaStomach
Expand Down
2 changes: 1 addition & 1 deletion Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
- type: SurgeryTarget
- type: UserInterface
interfaces:
enum.SurgeryUIKey.key:
enum.SurgeryUIKey.Key:
type: SurgeryBui

- type: entity
Expand Down

0 comments on commit 5eeac51

Please sign in to comment.