Skip to content

Commit

Permalink
Shitmed Update 2 - [Insert Snarky Remark] (#1271)
Browse files Browse the repository at this point in the history
# Description

![image](https://github.com/user-attachments/assets/b10f1e33-94fb-4ded-a644-b9945b58dbc5)

Honey wake up, another shitmed PR with 5 features and a trillion bugs! I
love bloat.

---

# Known Bugs
- A lot of shit with changelings lol
- Markings suddenly disappear from your entity apparently at random.
Wizden exclusive issue as of now.
- Fire heretics explode when ascending due to part damage shitcode
(sorry)
- Some exceptions/null point references at round end, tentatively
related to salvage corpses.
- Slots having wonky behavior due to not being networked. More of a
broad issue with how I implemented them initially.
- Arachne are FUCKED with surgery, I was incredibly tempted to set them
to roundstart: false, but I'll try to hotfix it this week.

---

# Changelog

:cl: Mocho, Deltanedas
- add: Ported Ghetto Surgery from Deltanedas!
- add: Ported fishops organs from Deltanedas!
- add: Added different step durations to each surgery step.
- add: Added a T2 research for advanced surgical tools
- add: Added a T3 research for an omnitool for surgery.
- add: Added Surgical and Advanced Surgical modules for Mediborgs
- add: Mediborgs can now perform surgery!
- add: Added lobotomies as an operation. Godspeed you psychopaths.
- add: Added cybernetic arms, legs and eyes.
- add: Added EMP weaknesses to all cybernetic parts (the day of
reckoning will come for IPCs soon)
- add: Losing your eyes now blinds you.
- fix: Fixed a few species that did not inherit from BasePart's, thus
taking damage types they shouldn't on their limbs.
- fix: Fixed harpy lungs not being usable in surgeries.
- fix: Fixed biosynthetic and other printable parts not allowing you to
attach body parts to them.
- fix: Fixed fire being able to destroy your chest.
- fix: Fixed entities being able to take over your body by just
inserting a brain or another head on top of you.
- fix: Fixed some shitcode that didnt let rejuvenate or godmode work
properly.
- fix: Fixed bionic arm, and cybernetic eyes traits not working properly
due to shitty networking.
- tweak: Increased tend wounds's speed by double, and bumped up the
values on its calculations. DEATH TO TOPICALS, LEAVE THOSE TO TIDERS.
- tweak: Beheading an entity now doesnt let it move, speak, and forces
it to the ground immediately (literally 1984!!11!!)
- tweak: Changed sprites on most surgical tools to now use /tg/ sprites.
- tweak: Unbound shitmed targeting doll keybinds by default (did you
know we have those).

---------

Signed-off-by: gluesniffler <[email protected]>
Co-authored-by: FoxxoTrystan <[email protected]>
Co-authored-by: goet <[email protected]>
Co-authored-by: Saphire Lattice <[email protected]>
  • Loading branch information
4 people authored Nov 30, 2024
1 parent 7d802e3 commit 2eafa0d
Show file tree
Hide file tree
Showing 227 changed files with 3,351 additions and 475 deletions.
4 changes: 4 additions & 0 deletions Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,13 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.TargetHead);
AddButton(ContentKeyFunctions.TargetTorso);
AddButton(ContentKeyFunctions.TargetLeftArm);
AddButton(ContentKeyFunctions.TargetLeftHand);
AddButton(ContentKeyFunctions.TargetRightArm);
AddButton(ContentKeyFunctions.TargetRightHand);
AddButton(ContentKeyFunctions.TargetLeftLeg);
AddButton(ContentKeyFunctions.TargetLeftFoot);
AddButton(ContentKeyFunctions.TargetRightLeg);
AddButton(ContentKeyFunctions.TargetRightFoot);

AddHeader("ui-options-header-misc");
AddButton(ContentKeyFunctions.TakeScreenshot);
Expand Down
5 changes: 5 additions & 0 deletions Content.Client/Smoking/MatchstickSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Content.Shared.Smoking.Systems;

namespace Content.Client.Smoking;

public sealed class MatchstickSystem : SharedMatchstickSystem;
6 changes: 6 additions & 0 deletions Content.Client/Speech/Components/OhioAccentComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Content.Client.Speech.Components;

// We keep this here because of surgery checks being client-side.
[RegisterComponent]
public sealed partial class OhioAccentComponent : Component
{ }
16 changes: 8 additions & 8 deletions Content.Client/Targeting/TargetingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ public override void Initialize()
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.Torso)))
.Bind(ContentKeyFunctions.TargetLeftArm,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftArm)))
/* .Bind(ContentKeyFunctions.TargetLeftHand,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftHand))) SOON :TM: */
.Bind(ContentKeyFunctions.TargetLeftHand,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftHand)))
.Bind(ContentKeyFunctions.TargetRightArm,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightArm)))
/* .Bind(ContentKeyFunctions.TargetRightHand,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightHand)))*/
.Bind(ContentKeyFunctions.TargetRightHand,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightHand)))
.Bind(ContentKeyFunctions.TargetLeftLeg,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftLeg)))
/* .Bind(ContentKeyFunctions.TargetLeftFoot,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftFoot)))*/
.Bind(ContentKeyFunctions.TargetLeftFoot,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftFoot)))
.Bind(ContentKeyFunctions.TargetRightLeg,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightLeg)))
/* .Bind(ContentKeyFunctions.TargetRightFoot,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightFoot)))*/
.Bind(ContentKeyFunctions.TargetRightFoot,
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightFoot)))
.Register<SharedTargetingSystem>();
}

Expand Down
5 changes: 5 additions & 0 deletions Content.Server/Body/Components/BrainComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,10 @@ namespace Content.Server.Body.Components
[RegisterComponent, Access(typeof(BrainSystem))]
public sealed partial class BrainComponent : Component
{
/// <summary>
/// Is this brain currently controlling the entity?
/// </summary>
[DataField]
public bool Active = true;
}
}
10 changes: 10 additions & 0 deletions Content.Server/Body/Systems/BodySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ public override HashSet<EntityUid> GibPart(
return gibs;
}

public override bool BurnPart(EntityUid partId, BodyPartComponent? part = null)
{
if (!Resolve(partId, ref part, logMissing: false)
|| TerminatingOrDeleted(partId)
|| EntityManager.IsQueuedForDeletion(partId))
return false;

return base.BurnPart(partId, part);
}

protected override void ApplyPartMarkings(EntityUid target, BodyPartAppearanceComponent component)
{
return;
Expand Down
51 changes: 41 additions & 10 deletions Content.Server/Body/Systems/BrainSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
using Content.Server.Ghost.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
using Content.Shared.Body.Systems;
using Content.Shared.Body.Events;
using Content.Shared.Body.Organ;
using Content.Server.DelayedDeath;
using Content.Server.DelayedDeath;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Pointing;
Expand All @@ -25,29 +27,33 @@ public override void Initialize()
SubscribeLocalEvent<BrainComponent, PointAttemptEvent>(OnPointAttempt);
}

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

brain.Active = false;
// Prevents revival, should kill the user within a given timespan too.
EnsureComp<DebrainedComponent>(args.OldBody);
EnsureComp<DelayedDeathComponent>(args.OldBody);
HandleMind(uid, args.OldBody);
if (!CheckOtherBrains(args.OldBody))
{
EnsureComp<DebrainedComponent>(args.OldBody);
HandleMind(uid, args.OldBody);
}
}

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

RemComp<DebrainedComponent>(args.Body);
if (_bodySystem.TryGetBodyOrganComponents<HeartComponent>(args.Body, out var _))
RemComp<DelayedDeathComponent>(args.Body);
HandleMind(args.Body, uid);
if (!CheckOtherBrains(args.Body))
{
RemComp<DebrainedComponent>(args.Body);
HandleMind(args.Body, uid, brain);
}
}

private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
private void HandleMind(EntityUid newEntity, EntityUid oldEntity, BrainComponent? brain = null)
{
if (TerminatingOrDeleted(newEntity) || TerminatingOrDeleted(oldEntity))
return;
Expand All @@ -63,11 +69,36 @@ private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
return;

_mindSystem.TransferTo(mindId, newEntity, mind: mind);
if (brain != null)
brain.Active = true;
}

private void OnPointAttempt(Entity<BrainComponent> ent, ref PointAttemptEvent args)
{
args.Cancel();
}

private bool CheckOtherBrains(EntityUid entity)
{
var hasOtherBrains = false;
if (TryComp<BodyComponent>(entity, out var body))
{
if (TryComp<BrainComponent>(entity, out var bodyBrain))
hasOtherBrains = true;
else
{
foreach (var (organ, _) in _bodySystem.GetBodyOrgans(entity, body))
{
if (TryComp<BrainComponent>(organ, out var brain) && brain.Active)
{
hasOtherBrains = true;
break;
}
}
}
}

return hasOtherBrains;
}
}
}
62 changes: 62 additions & 0 deletions Content.Server/Body/Systems/DebrainedSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Content.Shared.Body.Systems;
using Content.Shared.Body.Organ;
using Content.Server.DelayedDeath;
using Content.Shared.Mind;
using Content.Server.Popups;
using Content.Shared.Speech;
using Content.Shared.Standing;
using Content.Shared.Stunnable;

namespace Content.Server.Body.Systems;

/// <summary>
/// This system handles behavior on entities when they lose their head or their brains are removed.
/// MindComponent fuckery should still be mainly handled on BrainSystem as usual.
/// </summary>
public sealed class DebrainedSystem : EntitySystem
{
[Dependency] private readonly SharedBodySystem _bodySystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly StandingStateSystem _standingSystem = default!;
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<DebrainedComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<DebrainedComponent, ComponentRemove>(OnComponentRemove);
SubscribeLocalEvent<DebrainedComponent, SpeakAttemptEvent>(OnSpeakAttempt);
SubscribeLocalEvent<DebrainedComponent, StandAttemptEvent>(OnStandAttempt);
}

private void OnComponentInit(EntityUid uid, DebrainedComponent _, ComponentInit args)
{
if (TerminatingOrDeleted(uid))
return;

EnsureComp<DelayedDeathComponent>(uid);
EnsureComp<StunnedComponent>(uid);
_standingSystem.Down(uid);
}

private void OnComponentRemove(EntityUid uid, DebrainedComponent _, ComponentRemove args)
{
if (TerminatingOrDeleted(uid))
return;

RemComp<DelayedDeathComponent>(uid);
RemComp<StunnedComponent>(uid);
if (_bodySystem.TryGetBodyOrganComponents<HeartComponent>(uid, out var _))
RemComp<DelayedDeathComponent>(uid);
}

private void OnSpeakAttempt(EntityUid uid, DebrainedComponent _, SpeakAttemptEvent args)
{
_popupSystem.PopupEntity(Loc.GetString("speech-muted"), uid, uid);
args.Cancel();
}

private void OnStandAttempt(EntityUid uid, DebrainedComponent _, StandAttemptEvent args)
{
args.Cancel();
}
}
87 changes: 87 additions & 0 deletions Content.Server/Body/Systems/EyesSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Content.Server.Body.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Events;
using Content.Shared.Body.Organ;
using Content.Shared.Eye.Blinding.Components;
using Content.Shared.Eye.Blinding.Systems;

namespace Content.Server.Body.Systems
{
public sealed class EyesSystem : EntitySystem
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly BlindableSystem _blindableSystem = default!;
[Dependency] private readonly BodySystem _bodySystem = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<EyesComponent, OrganEnabledEvent>(OnOrganEnabled);
SubscribeLocalEvent<EyesComponent, OrganDisabledEvent>(OnOrganDisabled);
}

private void HandleSight(EntityUid newEntity, EntityUid oldEntity)
{
if (TerminatingOrDeleted(newEntity) || TerminatingOrDeleted(oldEntity))
return;

BlindableComponent? newSight;
BlindableComponent? oldSight;
//transfer existing component to organ
if (!TryComp(newEntity, out newSight))
newSight = EnsureComp<BlindableComponent>(newEntity);

if (!TryComp(oldEntity, out oldSight))
oldSight = EnsureComp<BlindableComponent>(oldEntity);

//give new sight all values of old sight
_blindableSystem.TransferBlindness(newSight, oldSight, newEntity);

var hasOtherEyes = false;
//check for other eye components on owning body and owning body organs (if old entity has a body)
if (TryComp<BodyComponent>(oldEntity, out var body))
{
if (TryComp<EyesComponent>(oldEntity, out var bodyEyes)) //some bodies see through their skin!!! (slimes)
hasOtherEyes = true;
else
{
foreach (var (organ, _) in _bodySystem.GetBodyOrgans(oldEntity, body))
{
if (TryComp<EyesComponent>(organ, out var eyes))
{
hasOtherEyes = true;
break;
}
}
//TODO (MS14): Should we do this for body parts too? might be a little overpowered but could be funny/interesting
}
}

//if there are no existing eye components for the old entity - set old sight to be blind otherwise leave it as is
if (!hasOtherEyes && !TryComp<EyesComponent>(oldEntity, out var self))
_blindableSystem.AdjustEyeDamage((oldEntity, oldSight), oldSight.MaxDamage);

}

private void OnOrganEnabled(EntityUid uid, EyesComponent component, OrganEnabledEvent args)
{
if (TerminatingOrDeleted(uid)
|| args.Organ.Comp.Body is not { Valid: true } body)
return;

RemComp<TemporaryBlindnessComponent>(body);
HandleSight(uid, body);
}

private void OnOrganDisabled(EntityUid uid, EyesComponent component, OrganDisabledEvent args)
{
if (TerminatingOrDeleted(uid)
|| args.Organ.Comp.Body is not { Valid: true } body)
return;

EnsureComp<TemporaryBlindnessComponent>(body);
HandleSight(body, uid);
}
}
}
54 changes: 54 additions & 0 deletions Content.Server/Cybernetics/CyberneticsSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Content.Server.Emp;
using Content.Server.Body.Systems;
using Content.Shared.Body.Part;
using Content.Shared.Body.Organ;
using Content.Shared.Cybernetics;

namespace Content.Server.Cybernetics;

internal sealed class CyberneticsSystem : EntitySystem
{
public override void Initialize()
{
SubscribeLocalEvent<CyberneticsComponent, EmpPulseEvent>(OnEmpPulse);
SubscribeLocalEvent<CyberneticsComponent, EmpDisabledRemoved>(OnEmpDisabledRemoved);
}
private void OnEmpPulse(Entity<CyberneticsComponent> cyberEnt, ref EmpPulseEvent ev)
{
if (!cyberEnt.Comp.Disabled)
{
ev.Affected = true;
ev.Disabled = true;
cyberEnt.Comp.Disabled = true;

if (HasComp<OrganComponent>(cyberEnt))
{
var disableEvent = new OrganEnableChangedEvent(false);
RaiseLocalEvent(cyberEnt, ref disableEvent);
}
else if (HasComp<BodyPartComponent>(cyberEnt))
{
var disableEvent = new BodyPartEnableChangedEvent(false);
RaiseLocalEvent(cyberEnt, ref disableEvent);
}
}
}

private void OnEmpDisabledRemoved(Entity<CyberneticsComponent> cyberEnt, ref EmpDisabledRemoved ev)
{
if (cyberEnt.Comp.Disabled)
{
cyberEnt.Comp.Disabled = false;
if (HasComp<OrganComponent>(cyberEnt))
{
var enableEvent = new OrganEnableChangedEvent(true);
RaiseLocalEvent(cyberEnt, ref enableEvent);
}
else if (HasComp<BodyPartComponent>(cyberEnt))
{
var enableEvent = new BodyPartEnableChangedEvent(true);
RaiseLocalEvent(cyberEnt, ref enableEvent);
}
}
}
}
Loading

0 comments on commit 2eafa0d

Please sign in to comment.