Shitmed Update 2 - bottom text (#956)

* full fucking send

* ope forgot to remove the EE scripts

* fix test

* fix shitcode fail

* DELTA THAT VALUE IS NULLABLE

* whoopsie daysie

* fixed???

* chat is this real
This commit is contained in:
gluesniffler 2024-11-24 21:02:23 -04:00 committed by deltanedas
parent 7eb7900db1
commit fd11cee0e0
319 changed files with 3155 additions and 294 deletions

View File

@ -89,9 +89,13 @@ namespace Content.Client.Input
human.AddFunction(ContentKeyFunctions.TargetHead);
human.AddFunction(ContentKeyFunctions.TargetTorso);
human.AddFunction(ContentKeyFunctions.TargetLeftArm);
human.AddFunction(ContentKeyFunctions.TargetLeftHand);
human.AddFunction(ContentKeyFunctions.TargetRightArm);
human.AddFunction(ContentKeyFunctions.TargetRightHand);
human.AddFunction(ContentKeyFunctions.TargetLeftLeg);
human.AddFunction(ContentKeyFunctions.TargetLeftFoot);
human.AddFunction(ContentKeyFunctions.TargetRightLeg);
human.AddFunction(ContentKeyFunctions.TargetRightFoot);
// Shitmed Change End
// actions should be common (for ghosts, mobs, etc)

View File

@ -243,9 +243,13 @@ namespace Content.Client.Options.UI.Tabs
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);
// Shitmed Change End
AddHeader("ui-options-header-misc");
@ -258,6 +262,14 @@ namespace Content.Client.Options.UI.Tabs
{
AddButton(boundKey);
}
<<<<<<< HEAD
=======
// goobstation
foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
{
AddButton(boundKey);
}
>>>>>>> a3b45e4bd6 (Shitmed Update 2 - bottom text (#956))
AddHeader("ui-options-header-shuttle");
AddButton(ContentKeyFunctions.ShuttleStrafeUp);

View File

@ -32,20 +32,20 @@ public sealed class TargetingSystem : SharedTargetingSystem
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>();
}

View File

@ -5,5 +5,10 @@ namespace Content.Server.Body.Components
[RegisterComponent, Access(typeof(BrainSystem))]
public sealed partial class BrainComponent : Component
{
/// <summary>
/// Shitmed Change: Is this brain currently controlling the entity?
/// </summary>
[DataField]
public bool Active = true;
}
}

View File

@ -171,6 +171,16 @@ public sealed class BodySystem : SharedBodySystem
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;

View File

@ -27,29 +27,34 @@ namespace Content.Server.Body.Systems
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;
// Prevents revival, should kill the user within a given timespan too.
EnsureComp<DebrainedComponent>(args.OldBody);
EnsureComp<DelayedDeathComponent>(args.OldBody);
HandleMind(uid, args.OldBody);
brain.Active = false;
if (!CheckOtherBrains(args.OldBody))
{
// Prevents revival, should kill the user within a given timespan too.
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.TryGetBodyOrganEntityComps<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);
}
}
// Shitmed Change End
private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
private void HandleMind(EntityUid newEntity, EntityUid oldEntity, BrainComponent? brain = null)
{
if (TerminatingOrDeleted(newEntity) || TerminatingOrDeleted(oldEntity))
return;
@ -65,8 +70,34 @@ namespace Content.Server.Body.Systems
return;
_mindSystem.TransferTo(mindId, newEntity, mind: mind);
if (brain != null)
brain.Active = true;
}
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;
}
// Shitmed Change End
private void OnPointAttempt(Entity<BrainComponent> ent, ref PointAttemptEvent args)
{
args.Cancel();

View File

@ -1,4 +1,5 @@
using Content.Shared.Body.Components;
using Content.Shared.Body.Part; // Shitmed Change
using Content.Shared.Inventory;
using Content.Shared.Popups;
using JetBrains.Annotations;
@ -25,8 +26,16 @@ public sealed partial class BurnBodyBehavior : IThresholdBehavior
}
}
sharedPopupSystem.PopupCoordinates(Loc.GetString("bodyburn-text-others", ("name", bodyId)), transformSystem.GetMoverCoordinates(bodyId), PopupType.LargeCaution);
system.EntityManager.QueueDeleteEntity(bodyId);
if (system.EntityManager.TryGetComponent<BodyPartComponent>(bodyId, out var bodyPart))
{
if (bodyPart.CanSever
&& system.BodySystem.BurnPart(bodyId, bodyPart))
sharedPopupSystem.PopupCoordinates(Loc.GetString("bodyburn-text-others", ("name", bodyId)), transformSystem.GetMoverCoordinates(bodyId), PopupType.LargeCaution);
}
else
{
sharedPopupSystem.PopupCoordinates(Loc.GetString("bodyburn-text-others", ("name", bodyId)), transformSystem.GetMoverCoordinates(bodyId), PopupType.LargeCaution);
system.EntityManager.QueueDeleteEntity(bodyId);
}
}
}

View File

@ -0,0 +1,62 @@
using Content.Server._Shitmed.DelayedDeath;
using Content.Shared._Shitmed.Body.Organ;
using Content.Shared.Body.Systems;
using Content.Shared.Mind;
using Content.Server.Popups;
using Content.Shared.Speech;
using Content.Shared.Standing;
using Content.Shared.Stunnable;
namespace Content.Server._Shitmed.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.TryGetBodyOrganEntityComps<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();
}
}

View File

@ -0,0 +1,87 @@
using Content.Server.Body.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Events;
using Content.Shared._Shitmed.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);
}
}
}

View File

@ -0,0 +1,55 @@
using Content.Server.Emp;
using Content.Shared.Body.Part;
using Content.Shared.Body.Organ;
using Content.Shared._Shitmed.Body.Organ;
using Content.Shared._Shitmed.Body.Events;
using Content.Shared._Shitmed.Cybernetics;
namespace Content.Server._Shitmed.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);
}
}
}
}

View File

@ -142,12 +142,13 @@ public sealed class SurgerySystem : SharedSurgerySystem
private void OnSurgerySpecialDamageChange(Entity<SurgerySpecialDamageChangeEffectComponent> ent, ref SurgeryStepDamageChangeEvent args)
{
// Im killing this shit soon too, inshallah.
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"
/*else if (ent.Comp.DamageType == "Eye"
&& TryComp(ent, out BlindableComponent? blindComp)
&& blindComp.EyeDamage > 0)
_blindableSystem.AdjustEyeDamage((args.Body, blindComp), -blindComp!.EyeDamage);
_blindableSystem.AdjustEyeDamage((args.Body, blindComp), -blindComp!.EyeDamage);*/
}
private void OnStepScreamComplete(Entity<SurgeryStepEmoteEffectComponent> ent, ref SurgeryStepEvent args)

View File

@ -1,6 +1,7 @@
using Content.Shared.Body.Systems;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; // Shitmed Change
using Content.Shared._Shitmed.Medical.Surgery.Tools; // Shitmed Change
namespace Content.Shared.Body.Organ;
@ -28,13 +29,13 @@ public sealed partial class OrganComponent : Component, ISurgeryToolComponent //
/// without referencing the prototype or hardcoding.
/// </summary>
[DataField]
[DataField, AlwaysPushInheritance]
public string SlotId = "";
[DataField]
[DataField, AlwaysPushInheritance]
public string ToolName { get; set; } = "An organ";
[DataField]
[DataField, AlwaysPushInheritance]
public float Speed { get; set; } = 1f;
/// <summary>
@ -42,5 +43,30 @@ public sealed partial class OrganComponent : Component, ISurgeryToolComponent //
/// </summary>
[DataField, AutoNetworkedField]
public bool? Used { get; set; }
/// <summary>
/// When attached, the organ will ensure these components on the entity, and delete them on removal.
/// </summary>
[DataField]
public ComponentRegistry? OnAdd;
/// <summary>
/// When removed, the organ will ensure these components on the entity, and add them on removal.
/// </summary>
[DataField]
public ComponentRegistry? OnRemove;
/// <summary>
/// Is this organ working or not?
/// </summary>
[DataField, AutoNetworkedField]
public bool Enabled = true;
/// <summary>
/// Can this organ be enabled or disabled? Used mostly for prop, damaged or useless organs.
/// </summary>
[DataField]
public bool CanEnable = true;
// Shitmed Change End
}

View File

@ -11,6 +11,7 @@ using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared._Shitmed.Medical.Surgery.Tools;
using Content.Shared._Shitmed.Targeting;
using Robust.Shared.Prototypes;
namespace Content.Shared.Body.Part;
@ -40,13 +41,13 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
[DataField, AutoNetworkedField]
public FixedPoint2 VitalDamage = 100;
[DataField]
[DataField, AlwaysPushInheritance]
public string ToolName { get; set; } = "A body part";
[DataField, AutoNetworkedField]
public bool? Used { get; set; } = null;
[DataField]
[DataField, AlwaysPushInheritance]
public float Speed { get; set; } = 1f;
/// <summary>
@ -55,6 +56,12 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
[DataField]
public float MinIntegrity;
/// <summary>
/// Whether this body part can be severed or not
/// </summary>
[DataField, AutoNetworkedField]
public bool CanSever = true;
/// <summary>
/// Shitmed Change: Whether this body part is enabled or not.
/// </summary>
@ -67,6 +74,12 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
[DataField]
public bool CanEnable = true;
/// <summary>
/// Whether this body part can attach children or not.
/// </summary>
[DataField]
public bool CanAttachChildren = true;
/// <summary>
/// Shitmed Change: How long it takes to run another self heal tick on the body part.
/// </summary>
@ -113,7 +126,7 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
/// <summary>
/// Shitmed Change: The ID of the base layer for this body part.
/// </summary>
[DataField, AutoNetworkedField]
[DataField, AutoNetworkedField, AlwaysPushInheritance]
public string? BaseLayerId;
/// <summary>
@ -133,11 +146,11 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
{ TargetIntegrity.Healthy, 10 },
};
// Shitmed Change End
[DataField, AutoNetworkedField]
[DataField, AutoNetworkedField, AlwaysPushInheritance]
public BodyPartType PartType = BodyPartType.Other;
// TODO BODY Replace with a simulation of organs
/// <summary>
/// Whether or not the owning <see cref="Body"/> will die if all
@ -146,9 +159,23 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
[DataField("vital"), AutoNetworkedField]
public bool IsVital;
[DataField, AutoNetworkedField]
[DataField, AutoNetworkedField, AlwaysPushInheritance]
public BodyPartSymmetry Symmetry = BodyPartSymmetry.None;
/// <summary>
/// When attached, the part will ensure these components on the entity, and delete them on removal.
/// </summary>
[DataField, AlwaysPushInheritance]
public ComponentRegistry? OnAdd;
/// <summary>
/// When removed, the part will ensure these components on the entity, and add them on removal.
/// </summary>
[DataField, AlwaysPushInheritance]
public ComponentRegistry? OnRemove;
// Shitmed Change End
/// <summary>
/// Child body parts attached to this body part.
/// </summary>

View File

@ -27,7 +27,6 @@ using Content.Shared.Rejuvenate;
using Content.Shared.Standing;
using Content.Shared._Shitmed.Targeting;
using Robust.Shared.Timing;
namespace Content.Shared.Body.Systems;
public partial class SharedBodySystem
@ -366,7 +365,7 @@ public partial class SharedBodySystem
// Shitmed Change Start
public virtual HashSet<EntityUid> GibPart(
public virtual HashSet<EntityUid> GibPart(
EntityUid partId,
BodyPartComponent? part = null,
bool launchGibs = true,
@ -382,7 +381,7 @@ public partial class SharedBodySystem
if (part.Body is { } bodyEnt)
{
if (IsPartRoot(bodyEnt, partId, part: part))
if (IsPartRoot(bodyEnt, partId, part: part) || !part.CanSever)
return gibs;
ChangeSlotState((partId, part), true);
@ -414,6 +413,26 @@ public partial class SharedBodySystem
return gibs;
}
public virtual bool BurnPart(EntityUid partId,
BodyPartComponent? part = null)
{
if (!Resolve(partId, ref part, logMissing: false))
return false;
if (part.Body is { } bodyEnt)
{
if (IsPartRoot(bodyEnt, partId, part: part))
return false;
ChangeSlotState((partId, part), true);
RemovePartChildren((partId, part), bodyEnt);
QueueDel(partId);
return true;
}
return false;
}
private void OnProfileLoadFinished(EntityUid uid, BodyComponent component, ProfileLoadFinishedEvent args)
{
if (!HasComp<HumanoidAppearanceComponent>(uid)

View File

@ -3,13 +3,35 @@ using Content.Shared.Body.Components;
using Content.Shared.Body.Events;
using Content.Shared.Body.Organ;
using Content.Shared.Body.Part;
using Content.Shared.Damage; // Shitmed Change
using Robust.Shared.Containers;
// Shitmed Change
using Content.Shared.Damage;
using Content.Shared._Shitmed.BodyEffects;
using Content.Shared._Shitmed.Body.Events;
using Content.Shared._Shitmed.Body.Organ;
namespace Content.Shared.Body.Systems;
public partial class SharedBodySystem
{
// Shitmed Change Start
private void InitializeOrgans()
{
SubscribeLocalEvent<OrganComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<OrganComponent, OrganEnableChangedEvent>(OnOrganEnableChanged);
}
private void OnMapInit(Entity<OrganComponent> ent, ref MapInitEvent args)
{
if (ent.Comp.OnAdd is not null || ent.Comp.OnRemove is not null)
EnsureComp<OrganEffectComponent>(ent);
}
// Shitmed Change End
private void AddOrgan(
Entity<OrganComponent> organEnt,
EntityUid bodyUid,
@ -21,11 +43,14 @@ public partial class SharedBodySystem
if (organEnt.Comp.Body is not null)
{
// Shitmed Change Start
organEnt.Comp.OriginalBody = organEnt.Comp.Body;
var addedInBodyEv = new OrganAddedToBodyEvent(bodyUid, parentPartUid);
RaiseLocalEvent(organEnt, ref addedInBodyEv);
var organEnabledEv = new OrganEnableChangedEvent(true);
RaiseLocalEvent(organEnt, ref organEnabledEv);
}
// Shitmed Change Start
if (TryComp(parentPartUid, out DamageableComponent? damageable)
&& damageable.TotalDamage > 200)
TrySetOrganUsed(organEnt, true, organEnt.Comp);
@ -41,7 +66,11 @@ public partial class SharedBodySystem
if (organEnt.Comp.Body is { Valid: true } bodyUid)
{
organEnt.Comp.OriginalBody = organEnt.Comp.Body; // Shitmed Change
// Shitmed Change Start
organEnt.Comp.OriginalBody = organEnt.Comp.Body;
var organDisabledEv = new OrganEnableChangedEvent(false);
RaiseLocalEvent(organEnt, ref organDisabledEv);
// Shitmed Change End
var removedInBodyEv = new OrganRemovedFromBodyEvent(bodyUid, parentPartUid);
RaiseLocalEvent(organEnt, ref removedInBodyEv);
}
@ -231,5 +260,49 @@ public partial class SharedBodySystem
return true;
}
private void OnOrganEnableChanged(Entity<OrganComponent> organEnt, ref OrganEnableChangedEvent args)
{
if (!organEnt.Comp.CanEnable && args.Enabled)
return;
organEnt.Comp.Enabled = args.Enabled;
if (args.Enabled)
EnableOrgan(organEnt);
else
DisableOrgan(organEnt);
if (organEnt.Comp.Body is { Valid: true } bodyEnt)
RaiseLocalEvent(organEnt, new OrganComponentsModifyEvent(bodyEnt, args.Enabled));
Dirty(organEnt, organEnt.Comp);
}
private void EnableOrgan(Entity<OrganComponent> organEnt)
{
if (!TryComp(organEnt.Comp.Body, out BodyComponent? body))
return;
// I hate having to hardcode these checks so much.
if (HasComp<EyesComponent>(organEnt))
{
var ev = new OrganEnabledEvent(organEnt);
RaiseLocalEvent(organEnt, ref ev);
}
}
private void DisableOrgan(Entity<OrganComponent> organEnt)
{
if (!TryComp(organEnt.Comp.Body, out BodyComponent? body))
return;
// I hate having to hardcode these checks so much.
if (HasComp<EyesComponent>(organEnt))
{
var ev = new OrganDisabledEvent(organEnt);
RaiseLocalEvent(organEnt, ref ev);
}
}
// Shitmed Change End
}

View File

@ -11,12 +11,13 @@ using Robust.Shared.Containers;
using Robust.Shared.Utility;
// Shitmed Change Start
using Content.Shared.Humanoid;
using Content.Shared._Shitmed.Body.Events;
using Content.Shared._Shitmed.Body.Part;
using Content.Shared._Shitmed.BodyEffects;
using Content.Shared._Shitmed.Targeting.Events;
using Content.Shared.Humanoid;
using Content.Shared.Inventory;
using Content.Shared.Random;
using Content.Shared._Shitmed.Targeting.Events;
namespace Content.Shared.Body.Systems;
@ -50,12 +51,14 @@ public partial class SharedBodySystem
_slots.AddItemSlot(ent, ent.Comp.ContainerName, ent.Comp.ItemInsertionSlot);
Dirty(ent, ent.Comp);
}
// Shitmed Change Start
if (ent.Comp.OnAdd is not null || ent.Comp.OnRemove is not null)
EnsureComp<BodyPartEffectComponent>(ent);
foreach (var connection in ent.Comp.Children.Keys)
{
Containers.EnsureContainer<ContainerSlot>(ent, GetPartSlotContainerId(connection));
}
// Shitmed Change End
}
private void OnBodyPartRemove(Entity<BodyPartComponent> ent, ref ComponentRemove args)
@ -70,12 +73,21 @@ public partial class SharedBodySystem
return;
partEnt.Comp.Enabled = args.Enabled;
Dirty(partEnt, partEnt.Comp);
if (args.Enabled)
{
EnablePart(partEnt);
if (partEnt.Comp.Body is { Valid: true } bodyEnt)
RaiseLocalEvent(partEnt, new BodyPartComponentsModifyEvent(bodyEnt, true));
}
else
{
DisablePart(partEnt);
if (partEnt.Comp.Body is { Valid: true } bodyEnt)
RaiseLocalEvent(partEnt, new BodyPartComponentsModifyEvent(bodyEnt, false));
}
Dirty(partEnt, partEnt.Comp);
}
private void EnablePart(Entity<BodyPartComponent> partEnt)
@ -301,6 +313,9 @@ public partial class SharedBodySystem
Dirty(partEnt, partEnt.Comp);
partEnt.Comp.Body = bodyEnt;
if (partEnt.Comp.Enabled && partEnt.Comp.Body is { Valid: true } body) // Shitmed Change
RaiseLocalEvent(partEnt, new BodyPartComponentsModifyEvent(body, true));
var ev = new BodyPartAddedEvent(slotId, partEnt);
RaiseLocalEvent(bodyEnt, ref ev);
@ -314,8 +329,14 @@ public partial class SharedBodySystem
{
Resolve(bodyEnt, ref bodyEnt.Comp, logMissing: false);
Dirty(partEnt, partEnt.Comp);
partEnt.Comp.OriginalBody = partEnt.Comp.Body; // Shitmed Change
partEnt.Comp.ParentSlot = null; // Shitmed Change
// Shitmed Change Start
partEnt.Comp.OriginalBody = partEnt.Comp.Body;
if (partEnt.Comp.Body is { Valid: true } body)
RaiseLocalEvent(partEnt, new BodyPartComponentsModifyEvent(body, false));
partEnt.Comp.ParentSlot = null;
// Shitmed Change End
var ev = new BodyPartRemovedEvent(slotId, partEnt);
RaiseLocalEvent(bodyEnt, ref ev);
@ -975,8 +996,8 @@ public partial class SharedBodySystem
{
containerNames = partType switch
{
BodyPartType.Arm => new() { "gloves" },
BodyPartType.Leg => new() { "shoes" },
BodyPartType.Hand => new() { "gloves" },
BodyPartType.Foot => new() { "shoes" },
BodyPartType.Head => new() { "eyes", "ears", "head", "mask" },
_ => new()
};
@ -997,6 +1018,14 @@ public partial class SharedBodySystem
return count;
}
public string GetSlotFromBodyPart(BodyPartComponent part)
{
if (part.Symmetry != BodyPartSymmetry.None)
return $"{part.Symmetry.ToString().ToLower()} {part.PartType.ToString().ToLower()}";
else
return part.PartType.ToString().ToLower();
}
// Shitmed Change End
/// <summary>

View File

@ -1,3 +1,4 @@
using Content.Shared.Body.Part; // Shitmed Change
using Content.Shared.Damage;
using Content.Shared.Movement.Systems;
using Content.Shared.Standing;
@ -42,7 +43,7 @@ public abstract partial class SharedBodySystem : EntitySystem
InitializeBody();
InitializeParts();
InitializeOrgans();
// Shitmed Change Start
// To try and mitigate the server load due to integrity checks, we set up a Job Queue.
InitializeIntegrityQueue();

View File

@ -24,7 +24,7 @@ namespace Content.Shared.Damage
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly INetManager _netMan = default!;
[Dependency] private readonly SharedBodySystem _body = default!; // Shitmed Change
[Dependency] private readonly SharedBodySystem _body = default!; // Shitmed Change
[Dependency] private readonly IRobustRandom _random = default!; // Shitmed Change
[Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
@ -146,13 +146,21 @@ namespace Content.Shared.Damage
return damage;
}
var before = new BeforeDamageChangedEvent(damage, origin, targetPart, canSever ?? true, canEvade ?? false, partMultiplier ?? 1.00f); // Shitmed Change
var before = new BeforeDamageChangedEvent(damage, origin, targetPart); // Shitmed Change
RaiseLocalEvent(uid.Value, ref before);
if (before.Cancelled
|| before.Evaded) // Shitmed Change
if (before.Cancelled)
return null;
// Shitmed Change Start
var partDamage = new TryChangePartDamageEvent(damage, origin, targetPart, canSever ?? true, canEvade ?? false, partMultiplier ?? 1.00f);
RaiseLocalEvent(uid.Value, ref partDamage);
if (partDamage.Evaded || partDamage.Cancelled)
return null;
// Shitmed Change End
// Apply resistances
if (!ignoreResistances)
{
@ -224,6 +232,19 @@ namespace Content.Shared.Damage
// Setting damage does not count as 'dealing' damage, even if it is set to a larger value, so we pass an
// empty damage delta.
DamageChanged(uid, component, new DamageSpecifier());
// Shitmed Change Start
if (HasComp<TargetingComponent>(uid))
{
foreach (var (part, _) in _body.GetBodyChildren(uid))
{
if (!TryComp(part, out DamageableComponent? damageComp))
continue;
SetAllDamage(part, damageComp, newValue);
}
}
// Shitmed Change End
}
public void SetDamageModifierSetId(EntityUid uid, string damageModifierSetId, DamageableComponent? comp = null)
@ -267,11 +288,6 @@ namespace Content.Shared.Damage
TryComp<MobThresholdsComponent>(uid, out var thresholds);
_mobThreshold.SetAllowRevives(uid, true, thresholds); // do this so that the state changes when we set the damage
SetAllDamage(uid, component, 0);
// Shitmed Start
if (HasComp<TargetingComponent>(uid))
foreach (var part in _body.GetBodyChildren(uid))
RaiseLocalEvent(part.Id, new RejuvenateEvent());
// Shitmed End
_mobThreshold.SetAllowRevives(uid, false, thresholds);
}
@ -303,6 +319,16 @@ namespace Content.Shared.Damage
/// </summary>
[ByRefEvent]
public record struct BeforeDamageChangedEvent(
DamageSpecifier Damage,
EntityUid? Origin = null,
TargetBodyPart? TargetPart = null, // Shitmed Change
bool Cancelled = false);
/// <summary>
/// Shitmed Change: Raised on parts before damage is done so we can cancel the damage if they evade.
/// </summary>
[ByRefEvent]
public record struct TryChangePartDamageEvent(
DamageSpecifier Damage,
EntityUid? Origin = null,
// Shitmed Change

View File

@ -2,6 +2,7 @@ using Content.Shared.Damage.Components;
using Content.Shared.Rejuvenate;
using Content.Shared.Slippery;
using Content.Shared.StatusEffect;
using Content.Shared.Body.Systems; // Shitmed Change
namespace Content.Shared.Damage.Systems;
@ -9,6 +10,8 @@ public abstract class SharedGodmodeSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly SharedBodySystem _bodySystem = default!; // Shitmed Change
public override void Initialize()
{
base.Initialize();
@ -50,6 +53,9 @@ public abstract class SharedGodmodeSystem : EntitySystem
// Rejuv to cover other stuff
RaiseLocalEvent(uid, new RejuvenateEvent());
foreach (var (id, _) in _bodySystem.GetBodyChildren(uid)) // Shitmed Change
EnableGodmode(id);
}
public virtual void DisableGodmode(EntityUid uid, GodmodeComponent? godmode = null)
@ -63,6 +69,9 @@ public abstract class SharedGodmodeSystem : EntitySystem
}
RemComp<GodmodeComponent>(uid);
foreach (var (id, _) in _bodySystem.GetBodyChildren(uid)) // Shitmed Change
DisableGodmode(id);
}
/// <summary>

View File

@ -87,6 +87,19 @@ public sealed class BlindableSystem : EntitySystem
blindable.Comp.MinDamage = amount;
UpdateEyeDamage(blindable, false);
}
// Shitmed Change Start
public void TransferBlindness(BlindableComponent newSight, BlindableComponent oldSight, EntityUid newEntity)
{
newSight.IsBlind = oldSight.IsBlind;
newSight.EyeDamage = oldSight.EyeDamage;
newSight.LightSetup = oldSight.LightSetup;
newSight.GraceFrame = oldSight.GraceFrame;
newSight.MinDamage = oldSight.MinDamage;
newSight.MaxDamage = oldSight.MaxDamage;
UpdateEyeDamage((newEntity, newSight), true);
}
// Shitmed Change End
}
/// <summary>

View File

@ -65,11 +65,15 @@ namespace Content.Shared.Input
public static readonly BoundKeyFunction TargetHead = "TargetHead";
public static readonly BoundKeyFunction TargetTorso = "TargetTorso";
public static readonly BoundKeyFunction TargetLeftArm = "TargetLeftArm";
public static readonly BoundKeyFunction TargetLeftHand = "TargetLeftHand";
public static readonly BoundKeyFunction TargetRightArm = "TargetRightArm";
public static readonly BoundKeyFunction TargetRightHand = "TargetRightHand";
public static readonly BoundKeyFunction TargetLeftLeg = "TargetLeftLeg";
public static readonly BoundKeyFunction TargetLeftFoot = "TargetLeftFoot";
public static readonly BoundKeyFunction TargetRightLeg = "TargetRightLeg";
public static readonly BoundKeyFunction TargetRightFoot = "TargetRightFoot";
// Shitmed Change End
public static readonly BoundKeyFunction ArcadeUp = "ArcadeUp";
public static readonly BoundKeyFunction ArcadeDown = "ArcadeDown";
public static readonly BoundKeyFunction ArcadeLeft = "ArcadeLeft";

View File

@ -8,15 +8,23 @@ namespace Content.Shared.Overlays;
/// <summary>
/// This component allows you to see health bars above damageable mobs.
/// </summary>
<<<<<<< HEAD
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState(true)]
=======
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] // Shitmed Change
>>>>>>> a3b45e4bd6 (Shitmed Update 2 - bottom text (#956))
public sealed partial class ShowHealthBarsComponent : Component
{
/// <summary>
/// Displays health bars of the damage containers.
/// </summary>
<<<<<<< HEAD
[DataField]
[AutoNetworkedField]
=======
[DataField, AutoNetworkedField] // Shitmed Change
>>>>>>> a3b45e4bd6 (Shitmed Update 2 - bottom text (#956))
public List<ProtoId<DamageContainerPrototype>> DamageContainers = new()
{
"Biological"

View File

@ -7,15 +7,24 @@ namespace Content.Shared.Overlays;
/// <summary>
/// This component allows you to see health status icons above damageable mobs.
/// </summary>
<<<<<<< HEAD
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState(true)]
=======
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] // Shitmed Change
>>>>>>> a3b45e4bd6 (Shitmed Update 2 - bottom text (#956))
public sealed partial class ShowHealthIconsComponent : Component
{
/// <summary>
/// Displays health status icons of the damage containers.
/// </summary>
<<<<<<< HEAD
[DataField]
[AutoNetworkedField]
=======
[DataField, AutoNetworkedField] // Shitmed Change
>>>>>>> a3b45e4bd6 (Shitmed Update 2 - bottom text (#956))
public List<ProtoId<DamageContainerPrototype>> DamageContainers = new()
{
"Biological"

View File

@ -3,13 +3,13 @@ using Robust.Shared.GameStates;
namespace Content.Shared.Prying.Components;
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] // Shitmed Change
public sealed partial class PryingComponent : Component
{
/// <summary>
/// Whether the entity can pry open powered doors
/// </summary>
[DataField]
[DataField, AutoNetworkedField] // Shitmed Change
public bool PryPowered;
/// <summary>
@ -22,7 +22,7 @@ public sealed partial class PryingComponent : Component
/// Modifier on the prying time.
/// Lower values result in more time.
/// </summary>
[DataField]
[DataField, AutoNetworkedField] // Shitmed Change
public float SpeedModifier = 1.0f;
/// <summary>

View File

@ -26,3 +26,5 @@ public readonly record struct BodyPartEnabledEvent(Entity<BodyPartComponent> Par
[ByRefEvent]
public readonly record struct BodyPartDisabledEvent(Entity<BodyPartComponent> Part);
public readonly record struct BodyPartComponentsModifyEvent(EntityUid Body, bool Add);

View File

@ -0,0 +1,13 @@
using Content.Shared.Body.Organ;
namespace Content.Shared._Shitmed.Body.Organ;
public readonly record struct OrganComponentsModifyEvent(EntityUid Body, bool Add);
[ByRefEvent]
public readonly record struct OrganEnableChangedEvent(bool Enabled);
[ByRefEvent]
public readonly record struct OrganEnabledEvent(Entity<OrganComponent> Organ);
[ByRefEvent]
public readonly record struct OrganDisabledEvent(Entity<OrganComponent> Organ);

View File

@ -64,7 +64,7 @@ public partial class SharedBodySystem
private void InitializeIntegrityQueue()
{
_queryTargeting = GetEntityQuery<TargetingComponent>();
SubscribeLocalEvent<BodyComponent, BeforeDamageChangedEvent>(OnBeforeDamageChanged);
SubscribeLocalEvent<BodyComponent, TryChangePartDamageEvent>(OnTryChangePartDamage);
SubscribeLocalEvent<BodyComponent, DamageModifyEvent>(OnBodyDamageModify);
SubscribeLocalEvent<BodyPartComponent, DamageModifyEvent>(OnPartDamageModify);
SubscribeLocalEvent<BodyPartComponent, DamageChangedEvent>(OnDamageChanged);
@ -106,7 +106,7 @@ public partial class SharedBodySystem
}
}
private void OnBeforeDamageChanged(Entity<BodyComponent> ent, ref BeforeDamageChangedEvent args)
private void OnTryChangePartDamage(Entity<BodyComponent> ent, ref TryChangePartDamageEvent args)
{
// If our target has a TargetingComponent, that means they will take limb damage
// And if their attacker also has one, then we use that part.
@ -223,6 +223,7 @@ public partial class SharedBodySystem
var delta = args.DamageDelta;
if (args.CanSever
&& partEnt.Comp.CanSever
&& partIdSlot is not null
&& delta != null
&& !HasComp<BodyPartReattachedComponent>(partEnt)

View File

@ -0,0 +1,26 @@
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared._Shitmed.BodyEffects;
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentPause]
public sealed partial class BodyPartEffectComponent : Component
{
/// <summary>
/// The components that are active on the part and will be refreshed every 5s
/// </summary>
[DataField]
public ComponentRegistry Active = new();
/// <summary>
/// How long to wait between each refresh.
/// Effects can only last at most this long once the organ is removed.
/// </summary>
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(5);
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan NextUpdate = TimeSpan.Zero;
}

View File

@ -0,0 +1,96 @@
using Content.Shared._Shitmed.Body.Events;
using Content.Shared.Body.Part;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Timing;
using System.Linq;
namespace Content.Shared._Shitmed.BodyEffects;
public partial class BodyPartEffectSystem : EntitySystem
{
[Dependency] private readonly IComponentFactory _compFactory = default!;
[Dependency] private readonly ISerializationManager _serManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BodyPartComponent, BodyPartComponentsModifyEvent>(OnPartComponentsModify);
}
// While I would love to kill this function, problem is that if we happen to have two parts that add the same
// effect, removing one will remove both of them, since we cant tell what the source of a Component is.
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<BodyPartEffectComponent, BodyPartComponent>();
var now = _gameTiming.CurTime;
while (query.MoveNext(out var uid, out var comp, out var part))
{
if (now < comp.NextUpdate || !comp.Active.Any() || part.Body is not { } body)
continue;
comp.NextUpdate = now + comp.Delay;
AddComponents(body, uid, comp.Active);
}
}
private void OnPartComponentsModify(Entity<BodyPartComponent> partEnt,
ref BodyPartComponentsModifyEvent ev)
{
if (partEnt.Comp.OnAdd != null)
{
if (ev.Add)
AddComponents(ev.Body, partEnt, partEnt.Comp.OnAdd);
else
RemoveComponents(ev.Body, partEnt, partEnt.Comp.OnAdd);
}
if (partEnt.Comp.OnRemove != null)
{
if (ev.Add)
AddComponents(ev.Body, partEnt, partEnt.Comp.OnRemove);
else
RemoveComponents(ev.Body, partEnt, partEnt.Comp.OnRemove);
}
Dirty(partEnt, partEnt.Comp);
}
private void AddComponents(EntityUid body,
EntityUid part,
ComponentRegistry reg,
BodyPartEffectComponent? effectComp = null)
{
if (!Resolve(part, ref effectComp, logMissing: false))
return;
foreach (var (key, comp) in reg)
{
var compType = comp.Component.GetType();
if (HasComp(body, compType))
continue;
var newComp = (Component) _serManager.CreateCopy(comp.Component, notNullableOverride: true);
EntityManager.AddComponent(body, newComp, true);
effectComp.Active[key] = comp;
}
}
private void RemoveComponents(EntityUid body,
EntityUid part,
ComponentRegistry reg,
BodyPartEffectComponent? effectComp = null)
{
if (!Resolve(part, ref effectComp, logMissing: false))
return;
foreach (var (key, comp) in reg)
{
RemComp(body, comp.Component.GetType());
effectComp.Active.Remove(key);
}
}
}

View File

@ -0,0 +1,27 @@
// We keep this clone of the other component since I don't know yet if I'll need organ specific functions in the future.
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared._Shitmed.BodyEffects;
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentPause]
public sealed partial class OrganEffectComponent : Component
{
/// <summary>
/// The components that are active on the part and will be refreshed every 5s
/// </summary>
[DataField]
public ComponentRegistry Active = new();
/// <summary>
/// How long to wait between each refresh.
/// Effects can only last at most this long once the organ is removed.
/// </summary>
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(5);
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan NextUpdate = TimeSpan.Zero;
}

View File

@ -0,0 +1,110 @@
// We keep this clone of the other system since I don't know yet if I'll need organ specific functions in the future.
// will delete or refactor as time goes on.
using Content.Shared._Shitmed.Body.Organ;
using Content.Shared.Body.Organ;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Timing;
using System.Linq;
using Robust.Shared.Network;
namespace Content.Shared._Shitmed.BodyEffects;
public partial class OrganEffectSystem : EntitySystem
{
[Dependency] private readonly IComponentFactory _compFactory = default!;
[Dependency] private readonly ISerializationManager _serManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly INetManager _net = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<OrganComponent, OrganComponentsModifyEvent>(OnOrganComponentsModify);
}
// While I would love to kill this function, problem is that if we happen to have two parts that add the same
// effect, removing one will remove both of them, since we cant tell what the source of a Component is.
public override void Update(float frameTime)
{
base.Update(frameTime);
if (!_net.IsServer) // TODO: Kill this once I figure out whats breaking the Diagnostic Cybernetics.
return;
var query = EntityQueryEnumerator<OrganEffectComponent, OrganComponent>();
var now = _gameTiming.CurTime;
while (query.MoveNext(out var uid, out var comp, out var part))
{
if (now < comp.NextUpdate || !comp.Active.Any() || part.Body is not { } body)
continue;
comp.NextUpdate = now + comp.Delay;
AddComponents(body, uid, comp.Active);
}
}
private void OnOrganComponentsModify(Entity<OrganComponent> organEnt,
ref OrganComponentsModifyEvent ev)
{
if (!_net.IsServer) // TODO: Kill this once I figure out whats breaking the Diagnostic Cybernetics.
return;
if (organEnt.Comp.OnAdd != null)
{
if (ev.Add)
AddComponents(ev.Body, organEnt, organEnt.Comp.OnAdd);
else
RemoveComponents(ev.Body, organEnt, organEnt.Comp.OnAdd);
}
if (organEnt.Comp.OnRemove != null)
{
if (ev.Add)
AddComponents(ev.Body, organEnt, organEnt.Comp.OnRemove);
else
RemoveComponents(ev.Body, organEnt, organEnt.Comp.OnRemove);
}
}
private void AddComponents(EntityUid body,
EntityUid part,
ComponentRegistry reg,
OrganEffectComponent? effectComp = null)
{
if (!Resolve(part, ref effectComp, logMissing: false))
return;
foreach (var (key, comp) in reg)
{
var compType = comp.Component.GetType();
if (HasComp(body, compType))
continue;
var newComp = (Component) _serManager.CreateCopy(comp.Component, notNullableOverride: true);
newComp.Owner = body;
EntityManager.AddComponent(body, newComp, true);
effectComp.Active[key] = comp;
if (newComp.NetSyncEnabled)
{
Dirty(body, newComp);
Dirty(part, effectComp);
}
}
}
private void RemoveComponents(EntityUid body,
EntityUid part,
ComponentRegistry reg,
OrganEffectComponent? effectComp = null)
{
if (!Resolve(part, ref effectComp, logMissing: false))
return;
foreach (var (key, comp) in reg)
{
RemComp(body, comp.Component.GetType());
effectComp.Active.Remove(key);
}
}
}

View File

@ -0,0 +1,18 @@
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._Shitmed.BodyEffects.Subsystems;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class GenerateChildPartComponent : Component
{
[DataField(required: true)]
public EntProtoId Id = "";
[DataField, AutoNetworkedField]
public EntityUid? ChildPart;
[DataField]
public bool Active = false;
}

View File

@ -0,0 +1,69 @@
using Content.Shared.Body.Part;
using Content.Shared.Body.Systems;
using Content.Shared._Shitmed.Body.Events;
using Robust.Shared.Map;
using Robust.Shared.Timing;
using Robust.Shared.Network;
using System.Numerics;
namespace Content.Shared._Shitmed.BodyEffects.Subsystems;
public sealed class GenerateChildPartSystem : EntitySystem
{
[Dependency] private readonly SharedBodySystem _bodySystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly INetManager _net = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GenerateChildPartComponent, BodyPartComponentsModifyEvent>(OnPartComponentsModify);
}
private void OnPartComponentsModify(EntityUid uid, GenerateChildPartComponent component, ref BodyPartComponentsModifyEvent args)
{
if (args.Add)
CreatePart(uid, component);
//else
//DeletePart(uid, component);
}
private void CreatePart(EntityUid uid, GenerateChildPartComponent component)
{
if (!TryComp(uid, out BodyPartComponent? partComp)
|| partComp.Body is null
|| component.Active)
return;
// I pinky swear to also move this to the server side properly next update :)
if (_net.IsServer)
{
var childPart = Spawn(component.Id, new EntityCoordinates(partComp.Body.Value, Vector2.Zero));
if (!TryComp(childPart, out BodyPartComponent? childPartComp))
return;
var slotName = _bodySystem.GetSlotFromBodyPart(childPartComp);
_bodySystem.TryCreatePartSlot(uid, slotName, childPartComp.PartType, out var _);
_bodySystem.AttachPart(uid, slotName, childPart, partComp, childPartComp);
component.ChildPart = childPart;
component.Active = true;
Dirty(childPart, childPartComp);
}
_bodySystem.ChangeSlotState((uid, partComp), false);
}
// Still unusued, gotta figure out what I want to do with this function outside of fuckery with mantis blades.
private void DeletePart(EntityUid uid, GenerateChildPartComponent component)
{
if (!TryComp(uid, out BodyPartComponent? partComp))
return;
_bodySystem.ChangeSlotState((uid, partComp), true);
var ev = new BodyPartDroppedEvent((uid, partComp));
RaiseLocalEvent(uid, ref ev);
QueueDel(uid);
}
}

View File

@ -0,0 +1,16 @@
using Robust.Shared.GameStates;
namespace Content.Shared._Shitmed.Cybernetics;
/// <summary>
/// Component for cybernetic implants that can be installed in entities
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class CyberneticsComponent : Component
{
/// <summary>
/// Is the cybernetic implant disabled by EMPs, etc?
/// </summary>
[DataField, AutoNetworkedField]
public bool Disabled = false;
}

View File

@ -0,0 +1,17 @@
using Content.Shared.Body.Part;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._Shitmed.Medical.Surgery.Conditions;
// Quite the redundant name eh?
[RegisterComponent, NetworkedComponent]
public sealed partial class SurgeryComponentConditionComponent : Component
{
[DataField]
public ComponentRegistry Component;
[DataField]
public bool Inverse;
}

View File

@ -104,6 +104,17 @@ public abstract partial class SharedSurgerySystem
}
}
if (ent.Comp.BodyAdd != null)
{
foreach (var reg in ent.Comp.BodyAdd.Values)
{
var compType = reg.Component.GetType();
if (HasComp(args.Body, compType))
continue;
AddComp(args.Body, _compFactory.GetComponent(compType));
}
}
if (ent.Comp.BodyRemove != null)
{
foreach (var reg in ent.Comp.BodyRemove.Values)
@ -151,6 +162,18 @@ public abstract partial class SharedSurgerySystem
}
}
if (ent.Comp.BodyAdd != null)
{
foreach (var reg in ent.Comp.BodyAdd.Values)
{
if (!HasComp(args.Body, reg.Component.GetType()))
{
args.Cancelled = true;
return;
}
}
}
if (ent.Comp.BodyRemove != null)
{
foreach (var reg in ent.Comp.BodyRemove.Values)
@ -253,12 +276,9 @@ public abstract partial class SharedSurgerySystem
bonus *= 0.2;
var adjustedDamage = new DamageSpecifier(ent.Comp.Damage);
var bonusPerType = bonus / group.Length;
foreach (var type in group)
{
adjustedDamage.DamageDict[type] -= bonusPerType;
}
adjustedDamage.DamageDict[type] -= bonus;
var ev = new SurgeryStepDamageEvent(args.User, args.Body, args.Part, args.Surgery, adjustedDamage, 0.5f);
RaiseLocalEvent(args.Body, ref ev);
@ -619,7 +639,7 @@ public abstract partial class SharedSurgerySystem
foreach (var tool in validTools.Keys)
{
if (TryComp(tool, out SurgeryToolComponent? toolComp) &&
toolComp.EndSound != null)
toolComp.StartSound != null)
{
_audio.PlayEntity(toolComp.StartSound, user, tool);
}
@ -632,7 +652,8 @@ public abstract partial class SharedSurgerySystem
var ev = new SurgeryDoAfterEvent(args.Surgery, args.Step);
// TODO: Move 2 seconds to a field of SurgeryStepComponent
var duration = 2f / speed;
var duration = GetSurgeryDuration(step, user, body, speed);
if (TryComp(user, out SurgerySpeedModifierComponent? surgerySpeedMod)
&& surgerySpeedMod is not null)
duration = duration / surgerySpeedMod.SpeedModifier;
@ -664,6 +685,18 @@ public abstract partial class SharedSurgerySystem
}
}
private float GetSurgeryDuration(EntityUid surgeryStep, EntityUid user, EntityUid target, float toolSpeed)
{
if (!TryComp(surgeryStep, out SurgeryStepComponent? stepComp))
return 2f; // Shouldnt really happen but just a failsafe.
var speed = toolSpeed;
if (TryComp(user, out SurgerySpeedModifierComponent? surgerySpeedMod))
speed *= surgerySpeedMod.SpeedModifier;
return stepComp.Duration / speed;
}
private (Entity<SurgeryComponent> Surgery, int Step)? GetNextStep(EntityUid body, EntityUid part, Entity<SurgeryComponent?> surgery, List<EntityUid> requirements)
{
if (!Resolve(surgery, ref surgery.Comp))

View File

@ -58,6 +58,7 @@ public abstract partial class SharedSurgerySystem : EntitySystem
SubscribeLocalEvent<SurgeryTargetComponent, SurgeryDoAfterEvent>(OnTargetDoAfter);
SubscribeLocalEvent<SurgeryCloseIncisionConditionComponent, SurgeryValidEvent>(OnCloseIncisionValid);
//SubscribeLocalEvent<SurgeryLarvaConditionComponent, SurgeryValidEvent>(OnLarvaValid);
SubscribeLocalEvent<SurgeryComponentConditionComponent, SurgeryValidEvent>(OnComponentConditionValid);
SubscribeLocalEvent<SurgeryPartConditionComponent, SurgeryValidEvent>(OnPartConditionValid);
SubscribeLocalEvent<SurgeryOrganConditionComponent, SurgeryValidEvent>(OnOrganConditionValid);
SubscribeLocalEvent<SurgeryWoundedConditionComponent, SurgeryValidEvent>(OnWoundedValid);
@ -127,6 +128,21 @@ public abstract partial class SharedSurgerySystem : EntitySystem
if (infected != null && infected.SpawnedLarva != null)
args.Cancelled = true;
}*/
private void OnComponentConditionValid(Entity<SurgeryComponentConditionComponent> ent, ref SurgeryValidEvent args)
{
var present = true;
foreach (var reg in ent.Comp.Component.Values)
{
var compType = reg.Component.GetType();
if (!HasComp(args.Part, compType))
present = false;
}
if (ent.Comp.Inverse ? present : !present)
args.Cancelled = true;
}
private void OnPartConditionValid(Entity<SurgeryPartConditionComponent> ent, ref SurgeryValidEvent args)
{
if (!TryComp<BodyPartComponent>(args.Part, out var part))
@ -177,7 +193,7 @@ public abstract partial class SharedSurgerySystem : EntitySystem
return;
}
var results = _body.GetBodyChildrenOfType(args.Body, ent.Comp.Part, symmetry: ent.Comp.Symmetry);
var results = _body.GetBodyChildrenOfType(args.Body, ent.Comp.Part, symmetry: ent.Comp.Symmetry).ToList();
if (results is not { } || !results.Any())
return;

View File

@ -14,9 +14,15 @@ public sealed partial class SurgeryStepComponent : Component
[DataField]
public ComponentRegistry? Add;
[DataField]
public ComponentRegistry? BodyAdd;
[DataField]
public ComponentRegistry? Remove;
[DataField]
public ComponentRegistry? BodyRemove;
[DataField]
public float Duration = 2f;
}

View File

@ -3,4 +3,10 @@ using Robust.Shared.GameStates;
namespace Content.Shared._Shitmed.Medical.Surgery.Tools;
[RegisterComponent, NetworkedComponent]
public sealed partial class BoneSetterComponent : Component;
public sealed partial class BoneSetterComponent : Component, ISurgeryToolComponent
{
public string ToolName => "a bone setter";
public bool? Used { get; set; } = null;
[DataField]
public float Speed { get; set; } = 1f;
}

View File

@ -3,9 +3,9 @@ using Robust.Shared.GameStates;
namespace Content.Shared._Shitmed.Medical.Surgery.Tools;
[RegisterComponent, NetworkedComponent]
public sealed partial class SurgicalDrillComponent : Component, ISurgeryToolComponent
public sealed partial class DrillComponent : Component, ISurgeryToolComponent
{
public string ToolName => "a surgical drill";
public string ToolName => "a drill";
public bool? Used { get; set; } = null;
[DataField]
public float Speed { get; set; } = 1f;

View File

@ -23,7 +23,7 @@ public sealed class SurgeryToolExamineSystem : EntitySystem
SubscribeLocalEvent<HemostatComponent, SurgeryToolExaminedEvent>(OnExamined);
SubscribeLocalEvent<RetractorComponent, SurgeryToolExaminedEvent>(OnExamined);
SubscribeLocalEvent<ScalpelComponent, SurgeryToolExaminedEvent>(OnExamined);
SubscribeLocalEvent<SurgicalDrillComponent, SurgeryToolExaminedEvent>(OnExamined);
SubscribeLocalEvent<DrillComponent, SurgeryToolExaminedEvent>(OnExamined);
SubscribeLocalEvent<TendingComponent, SurgeryToolExaminedEvent>(OnExamined);
SubscribeLocalEvent<TweezersComponent, SurgeryToolExaminedEvent>(OnExamined);

View File

@ -1,3 +1,4 @@
using Content.Shared._Shitmed.Body.Organ; // Shitmed Change
using Content.Shared.Body.Components; // Shitmed Change
using Content.Shared.DoAfter;
using Content.Shared.Gravity;
@ -120,7 +121,8 @@ public abstract class SharedLayingDownSystem : EntitySystem
TerminatingOrDeleted(uid) ||
// Shitmed Change
!TryComp<BodyComponent>(uid, out var body) ||
body.LegEntities.Count == 0)
body.LegEntities.Count == 0 ||
HasComp<DebrainedComponent>(uid))
return false;
var args = new DoAfterArgs(EntityManager, uid, layingDown.StandingUpTime, new StandingUpDoAfterEvent(), uid)

View File

@ -50,3 +50,4 @@ surgery-popup-step-SurgeryStepInsertHeart = {$user} is inserting a heart into {$
surgery-popup-step-SurgeryStepInsertStomach = {$user} is inserting a stomach into {$target}'s {$part}!
surgery-popup-step-SurgeryStepSealOrganWound = {$user} is sealing the wounds on {$target}'s {$part}.
surgery-popup-step-SurgeryStepLobotomize = {$user} is drilling a hole into {$target}'s {$part}.

View File

@ -71,3 +71,8 @@ research-technology-advanced-spray = Advanced Spray
research-technology-bluespace-cargo-transport = Bluespace Cargo Transport
research-technology-quantum-fiber-weaving = Quantum Fiber Weaving
research-technology-bluespace-chemistry = Bluespace Chemistry
## Shitmed Change
research-technology-advanced-treatment = Advanced Treatment
research-technology-high-end-surgery = High End Surgical Tools
research-technology-cybernetic-enhancements = Cybernetic Enhancements

View File

@ -9,6 +9,8 @@
- state: lung-l
- state: lung-r
- type: Lung
- type: Organ
slotId: lungs
- type: Metabolizer
updateInterval: 2.0
removeEmpty: true

View File

@ -7,7 +7,7 @@
abstract: true
components:
- type: Damageable
damageContainer: Biological
damageContainer: OrganicPart # Shitmed Change
- type: BodyPart
- type: ContainerContainer
containers:

View File

@ -17,6 +17,7 @@
- left arm
- right leg
- left leg
- head # Shitmed Change
organs:
heart: OrganHumanHeart
lungs: OrganHarpyLungs

View File

@ -23,6 +23,7 @@
- left arm
- right leg
- left leg
- head # Shitmed Change
right arm:
part: RightArmRodentia
connections:

View File

@ -23,6 +23,7 @@
- left arm
- right leg
- left leg
- head # Shitmed Change
right arm:
part: RightArmVulpkanin
connections:

View File

@ -42,13 +42,13 @@
damage:
types:
Piercing: 3
- type: Tending # Shitmed
speed: 0.55
- type: SurgeryTool # Shitmed
startSound:
path: /Audio/_Shitmed/Medical/Surgery/retractor1.ogg
endSound:
path: /Audio/_Shitmed/Medical/Surgery/hemostat1.ogg
# - type: Tending # Shitmed TODO: Uncomment this when surgeries arent tied to interaction events, but verbs.
# speed: 0.55
# - type: SurgeryTool # Shitmed
# startSound:
# path: /Audio/_Shitmed/Medical/Surgery/retractor1.ogg
# endSound:
# path: /Audio/_Shitmed/Medical/Surgery/hemostat1.ogg
#TODO: I want the luxury pen to write a cool font like Merriweather in the future.

View File

@ -1,3 +1,5 @@
# Im not even gonna bother marking this file with Shitmed Change(s), I'm fucking with almost everything.
# Base
- type: entity
@ -11,7 +13,7 @@
- type: Tag
tags:
- SurgeryTool
- type: SurgeryTool # Shitmed Change
- type: SurgeryTool
# Cautery
@ -22,10 +24,10 @@
description: A surgical tool used to cauterize open wounds.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/cautery.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/cautery.rsi
state: cautery
- type: Item
sprite: Objects/Specific/Medical/Surgery/cautery.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/cautery.rsi
storedRotation: 90
- type: MeleeWeapon
damage:
@ -50,10 +52,10 @@
description: A surgical drill for making holes into hard material.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/drill.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/drill.rsi
state: drill
- type: Item
sprite: Objects/Specific/Medical/Surgery/drill.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/drill.rsi
shape:
- 0,0,1,0
- 1,1,1,1
@ -69,7 +71,7 @@
- type: SurgeryTool
startSound:
path: /Audio/_Shitmed/Medical/Surgery/saw.ogg
- type: SurgicalDrill
- type: Drill
# Scalpel
@ -89,10 +91,10 @@
types:
- Knife
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/scalpel.rsi
state: scalpel
- type: Item
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/scalpel.rsi
storedRotation: 90
- type: MeleeWeapon
wideAnimationRotation: 90
@ -118,8 +120,11 @@
description: A pointy piece of glass, abraded to an edge and wrapped in tape for a handle. # Could become a decent tool or weapon with right tool mods.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
state: shiv
- type: Item
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
storedRotation: 90
heldPrefix: shiv
- type: entity
@ -129,8 +134,11 @@
description: Made of more expensive materials, sharper and generally more reliable.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
state: advanced
- type: Item
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
storedRotation: 90
heldPrefix: advanced
- type: MeleeWeapon
damage:
@ -146,14 +154,17 @@
description: A scalpel which uses a directed laser to slice instead of a blade, for more precise surgery while also cauterizing as it cuts.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
state: laser
- type: Item
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
storedRotation: 90
heldPrefix: laser
- type: Scalpel # Shitmed
speed: 1.5
# TODO: prevent bleeding from incisions
# Scissors
# Retractor
- type: entity
name: retractor
@ -162,10 +173,10 @@
description: A surgical tool used to hold open incisions.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/retractor.rsi
state: retractor
- type: Item
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/retractor.rsi
storedRotation: 90
# Shitmed Change
- type: SurgeryTool
@ -175,6 +186,8 @@
path: /Audio/_Shitmed/Medical/Surgery/retractor2.ogg
- type: Retractor
# Hemostat
- type: entity
name: hemostat
id: Hemostat
@ -182,11 +195,11 @@
description: A surgical tool used to compress blood vessels to prevent bleeding.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi # Shitmed Change
sprite: _Shitmed/Objects/Specific/Medical/Surgery/hemostat.rsi # Shitmed Change
state: hemostat
- type: Item
heldPrefix: hemostat
sprite: Objects/Specific/Medical/Surgery/scissors.rsi # Shitmed Change
sprite: _Shitmed/Objects/Specific/Medical/Surgery/hemostat.rsi # Shitmed Change
storedRotation: 90
# Shitmed Change
- type: SurgeryTool
@ -220,7 +233,7 @@
description: A container for bone gel that often needs to be refilled from a specialized machine.
components:
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/bone_gel.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/bone-gel.rsi
state: bone-gel
- type: BoneGel
@ -282,9 +295,11 @@
description: For heavy duty cutting.
components:
- type: Sprite
state: electric
sprite: _Shitmed/Objects/Specific/Medical/Surgery/circular-saw.rsi
state: circular-saw
- type: Item
heldPrefix: electric
size: Normal
sprite: _Shitmed/Objects/Specific/Medical/Surgery/circular-saw.rsi
- type: MeleeWeapon
damage:
groups:
@ -303,8 +318,12 @@
description: You think you can cut anything with it.
components:
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/saw.rsi
state: advanced
- type: Item
size: Normal
sprite: Objects/Specific/Medical/Surgery/saw.rsi
storedRotation: 90
heldPrefix: advanced
- type: MeleeWeapon
attackRate: 1.5
@ -313,111 +332,135 @@
- type: BoneSaw # Shitmed
speed: 2
# ORGANS - SHITMED
# Shitmed Tools
- type: entity
parent: OrganHumanHeart
id: BioSynthHeart
name: bio-synthetic heart
description: This heart can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: OrganHumanLiver
id: BioSynthLiver
name: bio-synthetic liver
description: This liver can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: OrganHumanLungs
id: BioSynthLungs
name: bio-synthetic lungs
description: These lungs can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: OrganHumanEyes
id: BioSynthEyes
name: bio-synthetic eyes
description: These eyes can be transplanted into any living organism and it will adapt to its recipient.
# PARTS - SHITMED
- type: entity
parent: LeftArmHuman
id: BioSynthLeftArm
name: bio-synthetic left arm
description: This left arm can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightArmHuman
id: BioSynthRightArm
name: bio-synthetic right arm
description: This right arm can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: LeftHandHuman
id: BioSynthLeftHand
name: bio-synthetic left hand
description: This left hand can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightHandHuman
id: BioSynthRightHand
name: bio-synthetic right hand
description: This right hand can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: LeftLegHuman
id: BioSynthLeftLeg
name: bio-synthetic left leg
description: This left leg can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightLegHuman
id: BioSynthRightLeg
name: bio-synthetic right leg
description: This right leg can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: LeftFootHuman
id: BioSynthLeftFoot
name: bio-synthetic left foot
description: This left foot can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightFootHuman
id: BioSynthRightFoot
name: bio-synthetic right foot
description: This right foot can be transplanted into any living organism and it will adapt to its recipient.
# JOKE ITEMS - SHITMED
- type: entity
parent: LeftArmHuman
id: PizzaLeftArm
name: pizza left arm
description: For when you want to turn someone into a Space John's.
name: searing tool
id: EnergyCautery
parent: Cautery
description: A cautery with an energy tip, also serves as a drill in its powered state.
components:
- type: BodyPart
partType: Arm
symmetry: Left
toolName: "a left arm"
baseLayerId: MobPizzaLArm
- type: Sprite
sprite: _Shitmed/Mobs/Species/Misc/Pizza/parts.rsi
state: "l_arm"
sprite: _Shitmed/Objects/Specific/Medical/Surgery/e-cautery.rsi
state: e-cautery-on
- type: Item
sprite: _Shitmed/Objects/Specific/Medical/Surgery/e-cautery.rsi
inhandVisuals:
left:
- state: inhand-left-on
right:
- state: inhand-right-on
- type: SurgeryTool
startSound:
path: /Audio/_Shitmed/Medical/Surgery/cautery1.ogg
endSound:
path: /Audio/_Shitmed/Medical/Surgery/cautery2.ogg
- type: MeleeWeapon
damage:
types:
Piercing: 10
Heat: 1
- type: Cautery
speed: 1.5
- type: Drill
speed: 1.5
- type: entity
parent: RightArmHuman
id: PizzaRightArm
name: pizza right arm
description: For when you want to turn someone into a Space John's.
name: energy scalpel
id: EnergyScalpel
parent: Scalpel
description: A scalpel which uses an energy blade, also serves as a saw in its powered state.
components:
- type: BodyPart
partType: Arm
symmetry: Right
toolName: "a right arm"
baseLayerId: MobPizzaRArm
- type: Sprite
sprite: _Shitmed/Mobs/Species/Misc/Pizza/parts.rsi
state: "r_arm"
sprite: _Shitmed/Objects/Specific/Medical/Surgery/e-scalpel.rsi
state: e-scalpel-on
- type: Item
sprite: _Shitmed/Objects/Specific/Medical/Surgery/e-scalpel.rsi
inhandVisuals:
left:
- state: inhand-left-on
right:
- state: inhand-right-on
- type: SurgeryTool
startSound:
path: /Audio/_Shitmed/Medical/Surgery/scalpel1.ogg
endSound:
path: /Audio/_Shitmed/Medical/Surgery/scalpel2.ogg
- type: MeleeWeapon
damage:
types:
Slash: 10
Heat: 1
- type: Scalpel
speed: 1.5
- type: BoneSaw
speed: 1.5
- type: entity
name: mechanical pinches
id: AdvancedRetractor
parent: Retractor
description: A retractor with mechanical pinches, also serves as a hemostat in its powered state.
components:
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/adv-retractor.rsi
state: adv-retractor-on
- type: Item
sprite: _Shitmed/Objects/Specific/Medical/Surgery/adv-retractor.rsi
inhandVisuals:
left:
- state: inhand-left-on
right:
- state: inhand-right-on
- type: SurgeryTool
startSound:
path: /Audio/_Shitmed/Medical/Surgery/retractor1.ogg
endSound:
path: /Audio/_Shitmed/Medical/Surgery/retractor2.ogg
- type: MeleeWeapon
damage:
types:
Slash: 6.5
Heat: 1
- type: Hemostat
speed: 1.5
- type: Retractor
speed: 1.5
- type: Tweezers
speed: 1.5
- type: Tending
speed: 1.5
- type: entity
name: medical multitool
id: OmnimedTool
parent: BaseToolSurgery
components:
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/omnimed.rsi
state: omnimed
- type: Item
sprite: _Shitmed/Objects/Specific/Medical/Surgery/omnimed.rsi
- type: SurgeryTool
startSound:
path: /Audio/_Shitmed/Medical/Surgery/saw.ogg
- type: Hemostat
speed: 2
- type: Scalpel
speed: 2
- type: Drill
speed: 2
- type: BoneSetter
speed: 2
- type: Retractor
speed: 2
- type: Cautery
speed: 2
- type: BoneGel
speed: 2
- type: BoneSaw
speed: 2
- type: Tweezers
speed: 2
- type: Tending
speed: 2

View File

@ -654,3 +654,44 @@
- type: Construction # DeltaV: construction for adding explosive payload to the dud version
graph: BorgModuleMartyr
node: live
# Shitmed Modules
- type: entity
id: BorgModuleSurgery
parent: [ BaseBorgModuleMedical, BaseProviderBorgModule ]
name: surgery cyborg module
components:
- type: Sprite
layers:
- state: medical
- state: icon-surgery
- type: ItemBorgModule
items:
- Scalpel
- Drill
- Hemostat
- Retractor
- Cautery
- SawElectric
- BoneGel
- type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: surgery-module }
- type: entity
id: BorgModuleAdvancedSurgery
parent: [ BaseBorgModuleMedical, BaseProviderBorgModule ]
name: advanced surgery cyborg module
components:
- type: Sprite
layers:
- state: medical
- state: icon-advanced-surgery
- type: ItemBorgModule
items:
- EnergyScalpel
- EnergyCautery
- AdvancedRetractor
- BoneGel
- type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-surgery-module }

View File

@ -377,6 +377,9 @@
- PowerCellHyper
- FireExtinguisherBluespace
# End DeltaV additions
- EnergyScalpel # Shitmed Change
- EnergyCautery # Shitmed Change
- AdvancedRetractor # Shitmed Change
- type: EmagLatheRecipes
emagDynamicRecipes:
- BorgModuleFauna
@ -649,6 +652,7 @@
- RightLegBorg
- LightHeadBorg
- TorsoBorg
- BorgModuleSurgery # Shitmed Change
dynamicRecipes:
- ProximitySensor
- BorgModuleAdvancedCleaning
@ -687,6 +691,14 @@
- BorgModuleSecurityChase
- BorgModuleSecurityEscalate
- JetpackVoid
# Shitmed Change
- BorgModuleAdvancedSurgery
- JawsOfLifeLeftArm
- JawsOfLifeRightArm
- SpeedLeftLeg
- SpeedRightLeg
- BasicCyberneticEyes
# Shitmed End
- type: EmagLatheRecipes
emagDynamicRecipes:
- ClothingOuterHardsuitJuggernautReverseEngineered
@ -912,6 +924,8 @@
- WeaponColdCannon
- WeaponBeamCannon
# End DeltaV additions
- SecurityCyberneticEyes # Shitmed Change
- MedicalCyberneticEyes # Shitmed Change
- type: MaterialStorage
whitelist:
tags:
@ -1048,6 +1062,12 @@
- ClothingEyesHudMedical # Nyano
- ChemicalPayload # Nyano
- SyringeCryostasis
# Shitmed Change
- EnergyScalpel
- EnergyCautery
- AdvancedRetractor
- OmnimedTool
- MedicalCyberneticEyes
- type: Machine
board: MedicalTechFabCircuitboard
- type: StealTarget

View File

@ -17,6 +17,7 @@
- left arm
- right leg
- left leg
- head # Shitmed Change
organs:
heart: OrganAnimalHeart
lungs: OrganHumanLungs

View File

@ -226,7 +226,8 @@
Steel: 100
Plastic: 100
# Shitmed Change
# Shitmed Recipes
- type: latheRecipe
id: BoneGel
result: BoneGel
@ -234,3 +235,53 @@
materials:
Plastic: 200
Plasma: 200
- type: latheRecipe
id: MedicalCyberneticEyes
result: MedicalCyberneticEyes
category: Robotics
completetime: 5
materials:
Steel: 1000
Glass: 500
Plastic: 500
Gold: 300
Silver: 300
- type: latheRecipe
id: EnergyScalpel
result: EnergyScalpel
completetime: 2
materials:
Steel: 600
Glass: 150
Gold: 150
- type: latheRecipe
id: AdvancedRetractor
result: AdvancedRetractor
completetime: 2
materials:
Steel: 600
Glass: 150
Silver: 150
- type: latheRecipe
id: EnergyCautery
result: EnergyCautery
completetime: 2
materials:
Steel: 600
Glass: 150
Plasma: 150
- type: latheRecipe
id: OmnimedTool
result: OmnimedTool
completetime: 2
materials:
Steel: 600
Glass: 150
Gold: 150
Silver: 150
Plasma: 150

View File

@ -202,3 +202,86 @@
parent: BaseBorgModuleRecipe
id: BorgModuleHarvesting
result: BorgModuleHarvesting
# Shitmed Recipes
- type: latheRecipe
id: BorgModuleSurgery
result: BorgModuleSurgery
category: Robotics
completetime: 3
materials:
Steel: 250
Glass: 250
Plastic: 250
- type: latheRecipe
id: BorgModuleAdvancedSurgery
result: BorgModuleAdvancedSurgery
category: Robotics
completetime: 3
materials:
Steel: 500
Glass: 500
Plastic: 250
Gold: 50
- type: latheRecipe
id: JawsOfLifeLeftArm
result: JawsOfLifeLeftArm
category: Robotics
completetime: 5
materials:
Steel: 1000
Glass: 500
Plastic: 500
Gold: 300
Silver: 300
- type: latheRecipe
id: JawsOfLifeRightArm
result: JawsOfLifeRightArm
category: Robotics
completetime: 5
materials:
Steel: 1000
Glass: 500
Plastic: 500
Gold: 300
Silver: 300
- type: latheRecipe
id: SpeedLeftLeg
result: SpeedLeftLeg
category: Robotics
completetime: 5
materials:
Steel: 1000
Glass: 500
Plastic: 500
Gold: 300
Silver: 300
- type: latheRecipe
id: SpeedRightLeg
result: SpeedRightLeg
category: Robotics
completetime: 5
materials:
Steel: 1000
Glass: 500
Plastic: 500
Gold: 300
Silver: 300
- type: latheRecipe
id: BasicCyberneticEyes
result: BasicCyberneticEyes
category: Robotics
completetime: 5
materials:
Steel: 1000
Glass: 500
Plastic: 500
Gold: 300
Silver: 300

View File

@ -714,3 +714,17 @@
Plastic: 1000
Plasma: 500
Glass: 500
# Shitmed Recipes
- type: latheRecipe
id: SecurityCyberneticEyes
result: SecurityCyberneticEyes
category: Robotics
completetime: 5
materials:
Steel: 1000
Glass: 500
Plastic: 500
Gold: 300
Silver: 300

View File

@ -130,18 +130,42 @@
- CryostasisBeaker
- SyringeCryostasis
# Shitmed Change Start
- type: technology
id: MechanizedTreatment
name: research-technology-mechanized-treatment
id: AdvancedTreatment
name: research-technology-advanced-treatment
icon:
sprite: Mobs/Silicon/chassis.rsi
state: medical
sprite: _Shitmed/Objects/Specific/Medical/Surgery/e-scalpel.rsi
state: e-scalpel-on
discipline: CivilianServices
tier: 2
cost: 5000
recipeUnlocks:
- BorgModuleAdvancedTreatment
- BorgModuleDefibrillator
- EnergyScalpel
- EnergyCautery
- AdvancedRetractor
- BorgModuleAdvancedSurgery
- type: technology
id: CyberneticEnhancements
name: research-technology-cybernetic-enhancements
icon:
sprite: _Shitmed/Mobs/Species/IPC/organs.rsi
state: eyes
discipline: CivilianServices
tier: 2
cost: 15000
recipeUnlocks:
- JawsOfLifeLeftArm
- JawsOfLifeRightArm
- SpeedLeftLeg
- SpeedRightLeg
- BasicCyberneticEyes
- SecurityCyberneticEyes
- MedicalCyberneticEyes
# Shitmed Change End
- type: technology
id: AdvancedCleaning

View File

@ -3,15 +3,15 @@
id: OrganSpaceAnimalLungs
name: space animal lungs
components:
- type: StatusEffectOrgan
refresh:
BreathingImmunity: BreathingImmunity
- type: Organ
onAdd:
- type: BreathingImmunity
- type: entity
parent: OrganAnimalHeart
id: OrganSpaceAnimalHeart
name: space animal heart
components:
- type: StatusEffectOrgan
refresh:
PressureImmunity: PressureImmunity
- type: Organ
onAdd:
- type: PressureImmunity

View File

@ -0,0 +1,51 @@
- type: entity
parent: OrganHumanEyes
abstract: true
id: BaseCyberneticEyes
components:
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/IPC/organs.rsi
state: "eyes"
- type: entity
parent: BaseCyberneticEyes
id: BasicCyberneticEyes
name: cybernetic eyes
description: A pair of cybernetic eyes that enhance your vision, and protect you from eye damage.
components:
- type: Organ
onAdd:
- type: FlashImmunity
- type: EyeProtection
- type: entity
parent: BaseCyberneticEyes
id: SecurityCyberneticEyes
name: cybernetic security eyes
description: A pair of cybernetic eyes that enhance your vision, featuring an integrated SecHUD.
components:
- type: Organ
onAdd:
- type: FlashImmunity
- type: EyeProtection
- type: ShowJobIcons
- type: ShowMindShieldIcons
- type: ShowCriminalRecordIcons
- type: entity
parent: BaseCyberneticEyes
id: MedicalCyberneticEyes
name: cybernetic diagnostic eyes
description: A pair of cybernetic eyes that enhance your vision, featuring an integrated MedHUD.
components:
- type: Organ
onAdd:
- type: FlashImmunity
- type: EyeProtection
- type: ShowHealthBars
damageContainers:
- Biological
- type: ShowHealthIcons
damageContainers:
- Biological

View File

@ -0,0 +1,23 @@
- type: entity
parent: OrganHumanHeart
id: BioSynthHeart
name: bio-synthetic heart
description: This heart can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: OrganHumanLiver
id: BioSynthLiver
name: bio-synthetic liver
description: This liver can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: OrganHumanLungs
id: BioSynthLungs
name: bio-synthetic lungs
description: These lungs can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: OrganHumanEyes
id: BioSynthEyes
name: bio-synthetic eyes
description: These eyes can be transplanted into any living organism and it will adapt to its recipient.

View File

@ -0,0 +1,169 @@
- type: entity
id: LeftArmCybernetic
parent: LeftArmHuman
abstract: true
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopLArm
- type: GenerateChildPart
id: LeftHandCybernetic
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_arm-combined"
- type: entity
id: RightArmCybernetic
parent: RightArmHuman
abstract: true
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopRArm
- type: GenerateChildPart
id: RightHandCybernetic
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_arm-combined"
- type: entity
id: LeftLegCybernetic
parent: LeftLegHuman
abstract: true
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopLLeg
- type: GenerateChildPart
id: LeftFootCybernetic
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_leg-combined"
- type: entity
id: RightLegCybernetic
parent: RightLegHuman
abstract: true
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopRLeg
- type: GenerateChildPart
id: RightFootCybernetic
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_leg-combined"
- type: entity
id: LeftHandCybernetic
parent: LeftHandHuman
name: cybernetic left hand
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopLHand
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_hand"
- type: entity
id: RightHandCybernetic
parent: RightHandHuman
name: cybernetic right hand
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopRHand
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_hand"
- type: entity
id: LeftFootCybernetic
parent: LeftFootHuman
name: cybernetic left foot
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopLFoot
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_foot"
- type: entity
id: RightFootCybernetic
parent: RightFootHuman
name: cybernetic right foot
components:
- type: Damageable
damageContainer: Silicon
- type: BodyPart
baseLayerId: MobCyberneticBishopRFoot
- type: Cybernetics
- type: Sprite
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_foot"
- type: entity
parent: LeftArmCybernetic
id: JawsOfLifeLeftArm
name: J.W.L left arm
description: A cybernetic left arm with the ability to pry doors open.
components:
- type: BodyPart
onAdd:
- type: Prying
speedModifier: 1.5
pryPowered: true
- type: entity
parent: RightArmCybernetic
id: JawsOfLifeRightArm
name: J.W.L right arm
description: A cybernetic right arm with the ability to pry doors open.
components:
- type: BodyPart
onAdd:
- type: Prying
speedModifier: 1.5
pryPowered: true
- type: entity
parent: LeftLegCybernetic
id: SpeedLeftLeg
name: S.P.E.E.D left leg
description: A cybernetic left leg that allows its wearer to run faster.
components:
- type: MovementBodyPart
walkSpeed: 3.125
sprintSpeed: 5.625
- type: BodyPart
onAdd:
- type: NoSlip
- type: entity
parent: RightLegCybernetic
id: SpeedRightLeg
name: S.P.E.E.D right leg
description: A cybernetic left leg that allows its wearer to run faster.
components:
- type: MovementBodyPart
walkSpeed: 3.125
sprintSpeed: 5.625
- type: BodyPart
onAdd:
- type: NoSlip

View File

@ -0,0 +1,79 @@
- type: entity
parent: LeftArmHuman
id: BioSynthLeftArm
name: bio-synthetic left arm
description: This left arm can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightArmHuman
id: BioSynthRightArm
name: bio-synthetic right arm
description: This right arm can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: LeftHandHuman
id: BioSynthLeftHand
name: bio-synthetic left hand
description: This left hand can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightHandHuman
id: BioSynthRightHand
name: bio-synthetic right hand
description: This right hand can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: LeftLegHuman
id: BioSynthLeftLeg
name: bio-synthetic left leg
description: This left leg can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightLegHuman
id: BioSynthRightLeg
name: bio-synthetic right leg
description: This right leg can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: LeftFootHuman
id: BioSynthLeftFoot
name: bio-synthetic left foot
description: This left foot can be transplanted into any living organism and it will adapt to its recipient.
- type: entity
parent: RightFootHuman
id: BioSynthRightFoot
name: bio-synthetic right foot
description: This right foot can be transplanted into any living organism and it will adapt to its recipient.
# JOKE ITEMS
- type: entity
parent: LeftArmHuman
id: PizzaLeftArm
name: pizza left arm
description: For when you want to turn someone into a Space John's.
components:
- type: BodyPart
partType: Arm
symmetry: Left
toolName: "a left arm"
baseLayerId: MobPizzaLArm
- type: Sprite
sprite: _Shitmed/Mobs/Species/Misc/Pizza/parts.rsi
state: "l_arm"
- type: entity
parent: RightArmHuman
id: PizzaRightArm
name: pizza right arm
description: For when you want to turn someone into a Space John's.
components:
- type: BodyPart
partType: Arm
symmetry: Right
toolName: "a right arm"
baseLayerId: MobPizzaRArm
- type: Sprite
sprite: _Shitmed/Mobs/Species/Misc/Pizza/parts.rsi
state: "r_arm"

View File

@ -398,7 +398,6 @@
inverse: true
reattaching: true
- type: entity
parent: SurgeryBase
id: SurgeryRemoveHeart
@ -589,6 +588,41 @@
inverse: true
reattaching: true
- type: entity
parent: SurgeryBase
id: SurgeryLobotomize
name: Lobotomize
categories: [ HideSpawnMenu ]
components:
- type: Surgery
requirement: SurgeryOpenIncision
steps:
- SurgeryStepLobotomize
- SurgeryStepCloseIncision
- type: SurgeryComponentCondition
component:
- type: OhioAccent
inverse: true
- type: SurgeryPartCondition
part: Head
- type: entity
parent: SurgeryBase
id: SurgeryMendBrainTissue
name: Mend brain tissue
categories: [ HideSpawnMenu ]
components:
- type: Surgery
requirement: SurgeryOpenIncision
steps:
- SurgeryStepMendBrainTissue
- SurgeryStepCloseIncision
- type: SurgeryComponentCondition
component:
- type: OhioAccent
- type: SurgeryPartCondition
part: Head
# Fluff/Joke Surgeries
#- type: entity

View File

@ -15,8 +15,9 @@
- type: Scalpel
add:
- type: IncisionOpen
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/scalpel.rsi
state: scalpel
- type: SurgeryDamageChangeEffect
damage:
@ -36,8 +37,9 @@
- type: Hemostat
add:
- type: BleedersClamped
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/hemostat.rsi
state: hemostat
- type: SurgeryDamageChangeEffect
damage:
@ -56,8 +58,9 @@
- type: Retractor
add:
- type: SkinRetracted
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/retractor.rsi
state: retractor
- type: entity
@ -71,9 +74,10 @@
- type: BoneSaw
add:
- type: RibcageSawed
duration: 4
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/saw.rsi
state: saw
sprite: _Shitmed/Objects/Specific/Medical/Surgery/circular-saw.rsi
state: circular-saw
- type: SurgeryStepEmoteEffect
- type: entity
@ -87,8 +91,9 @@
- type: Retractor
add:
- type: RibcageOpen
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/retractor.rsi
state: retractor
#- type: entity
@ -137,8 +142,9 @@
- type: Retractor
remove:
- type: RibcageOpen
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/retractor.rsi
state: retractor
- type: entity
@ -152,8 +158,9 @@
- type: BoneGel
remove:
- type: RibcageSawed
duration: 2
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/bone_gel.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/bone-gel.rsi
state: bone-gel
- type: entity
@ -173,8 +180,9 @@
- type: IncisionOpen
- type: BodyPartReattached
- type: InternalBleedersClamped
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/cautery.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/cautery.rsi
state: cautery
- type: SurgeryDamageChangeEffect
damage:
@ -194,6 +202,7 @@
- type: SurgeryStep
tool:
- type: BodyPart
duration: 6
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/manipulation.rsi
state: insertion
@ -213,9 +222,10 @@
- type: BleedersClamped
- type: IncisionOpen
- type: InternalBleedersClamped
duration: 2
- type: SurgeryAffixPartStep
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/cautery.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/cautery.rsi
state: cautery
- type: SurgeryStepEmoteEffect
- type: SurgeryDamageChangeEffect
@ -237,9 +247,10 @@
- type: BoneSaw
add:
- type: BodyPartSawed
duration: 4
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/saw.rsi
state: saw
sprite: _Shitmed/Objects/Specific/Medical/Surgery/circular-saw.rsi
state: circular-saw
- type: SurgeryStepEmoteEffect
- type: entity
@ -253,8 +264,9 @@
- type: Hemostat
add:
- type: InternalBleedersClamped
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/hemostat.rsi
state: hemostat
- type: SurgeryDamageChangeEffect
damage:
@ -277,9 +289,10 @@
- type: BleedersClamped
- type: InternalBleedersClamped
- type: IncisionOpen
duration: 8
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/saw.rsi
state: saw
sprite: _Shitmed/Objects/Specific/Medical/Surgery/circular-saw.rsi
state: circular-saw
- type: SurgeryRemovePartStep
- type: SurgeryStepEmoteEffect
@ -296,8 +309,9 @@
- type: Scalpel
add:
- type: IncisionOpen
duration: 3
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/scalpel.rsi
state: scalpel
- type: SurgeryStepEmoteEffect
@ -310,8 +324,9 @@
- type: SurgeryStep
tool:
- type: Tending
duration: 1
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/hemostat.rsi
state: hemostat
- type: SurgeryTendWoundsEffect
damage:
@ -328,8 +343,9 @@
- type: SurgeryStep
tool:
- type: Tending
duration: 1
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/hemostat.rsi
state: hemostat
- type: SurgeryTendWoundsEffect
mainGroup: Burn
@ -349,8 +365,9 @@
- type: Cautery
remove:
- type: IncisionOpen
duration: 2
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/cautery.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/cautery.rsi
state: cautery
- type: SurgeryDamageChangeEffect
damage:
@ -368,6 +385,7 @@
categories: [ HideSpawnMenu ]
components:
- type: SurgeryStep
duration: 4
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/manipulation.rsi
state: insertion
@ -382,6 +400,7 @@
categories: [ HideSpawnMenu ]
components:
- type: SurgeryStep
duration: 4
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/manipulation.rsi
state: insertion
@ -400,8 +419,9 @@
- type: SurgeryStep
tool:
- type: Tweezers
duration: 8
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/scissors.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/hemostat.rsi
state: hemostat
- type: SurgeryRemoveOrganStep
- type: SurgeryStepEmoteEffect
@ -415,6 +435,7 @@
- type: SurgeryStep
tool:
- type: Organ
duration: 6
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/manipulation.rsi
state: insertion
@ -459,10 +480,6 @@
id: SurgeryStepInsertEyes
name: Add eyes
categories: [ HideSpawnMenu ]
components:
- type: SurgerySpecialDamageChangeEffect
damageType: Eye
isConsumable: true
- type: entity
parent: SurgeryStepInsertOrgan
@ -483,9 +500,10 @@
- type: SurgeryStep
tool:
- type: Cautery
duration: 2
- type: SurgeryAffixOrganStep
- type: Sprite
sprite: Objects/Specific/Medical/Surgery/cautery.rsi
sprite: _Shitmed/Objects/Specific/Medical/Surgery/cautery.rsi
state: cautery
- type: SurgeryStepEmoteEffect
- type: SurgeryDamageChangeEffect
@ -494,6 +512,48 @@
Heat: -5
sleepModifier: 2
- type: entity
parent: SurgeryStepBase
id: SurgeryStepLobotomize
name: Lobotomize patient
categories: [ HideSpawnMenu ]
components:
- type: SurgeryStep
tool:
- type: Drill
bodyAdd:
- type: OhioAccent
- type: RatvarianLanguage
- type: SlurredAccent
duration: 5
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/drill.rsi
state: drill
- type: SurgeryStepEmoteEffect
- type: SurgeryDamageChangeEffect
damage:
types:
Piercing: 10
- type: entity
parent: SurgeryStepBase
id: SurgeryStepMendBrainTissue
name: Mend brain tissue
categories: [ HideSpawnMenu ]
components:
- type: SurgeryStep
tool:
- type: Hemostat
duration: 5
bodyRemove:
- type: OhioAccent
- type: RatvarianLanguage
- type: SlurredAccent
- type: Sprite
sprite: _Shitmed/Objects/Specific/Medical/Surgery/drill.rsi
state: drill
- type: SurgeryStepEmoteEffect
# The lengths I go to just for a joke... I HATE HARDCODING AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Maybe I should modify species prototypes to include tails and ears properly...

View File

@ -0,0 +1,47 @@
- type: humanoidBaseSprite
id: MobCyberneticBishopLArm
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_arm-combined"
- type: humanoidBaseSprite
id: MobCyberneticBishopRArm
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_arm-combined"
- type: humanoidBaseSprite
id: MobCyberneticBishopLLeg
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_leg-combined"
- type: humanoidBaseSprite
id: MobCyberneticBishopRLeg
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_leg-combined"
- type: humanoidBaseSprite
id: MobCyberneticBishopLHand
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_hand"
- type: humanoidBaseSprite
id: MobCyberneticBishopRHand
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_hand"
- type: humanoidBaseSprite
id: MobCyberneticBishopLFoot
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "l_foot"
- type: humanoidBaseSprite
id: MobCyberneticBishopRFoot
baseSprite:
sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi
state: "r_foot"

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

View File

@ -61,6 +61,12 @@
{
"name":"treatment-module"
},
{
"name":"surgery-module"
},
{
"name":"adv-surgery-module"
},
{
"name":"adv-diagnosis-module"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

View File

@ -103,6 +103,12 @@
{
"name": "icon-treatment"
},
{
"name": "icon-surgery"
},
{
"name": "icon-advanced-surgery"
},
{
"name": "icon-syndicate"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,15 @@
{
"version": 1,
"copyright": "Sprites from Paradise Station (https://github.com/ParadiseSS13/Paradise)",
"license": "CC-BY-SA-3.0",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "head",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

View File

@ -0,0 +1,95 @@
{
"version": 1,
"copyright": "Sprites originally from Paradise Station (https://github.com/ParadiseSS13/Paradise). Monochromatic version made by: DayOS (https://github.com/Day-OS)",
"license": "CC-BY-SA-3.0",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "l_foot",
"directions": 4
},
{
"name": "r_foot",
"directions": 4
},
{
"name": "l_leg-primary",
"directions": 4
},
{
"name": "l_leg-secondary",
"directions": 4
},
{
"name": "l_leg-combined",
"directions": 4
},
{
"name": "r_leg-primary",
"directions": 4
},
{
"name": "r_leg-secondary",
"directions": 4
},
{
"name": "r_leg-combined",
"directions": 4
},
{
"name": "torso-primary",
"directions": 4
},
{
"name": "torso-secondary",
"directions": 4
},
{
"name": "l_arm-primary",
"directions": 4
},
{
"name": "l_arm-secondary",
"directions": 4
},
{
"name": "l_arm-tertiary",
"directions": 4
},
{
"name": "l_arm-combined",
"directions": 4
},
{
"name": "r_arm-primary",
"directions": 4
},
{
"name": "r_arm-secondary",
"directions": 4
},
{
"name": "r_arm-tertiary",
"directions": 4
},
{
"name": "r_arm-combined",
"directions": 4
},
{
"name": "l_hand",
"directions": 4
},
{
"name": "r_hand",
"directions": 4
},
{
"name": "head",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

View File

@ -0,0 +1,19 @@
{
"version": 1,
"copyright": "Sprites originally from Paradise Station (https://github.com/ParadiseSS13/Paradise). Monochromatic version made by: DayOS (https://github.com/Day-OS)",
"license": "CC-BY-SA-3.0",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "head",
"directions": 4
},
{
"name": "head-2",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Some files were not shown because too many files have changed in this diff Show More