Skip to content

Commit

Permalink
add ghetto surgery real (DeltaV-Station#884)
Browse files Browse the repository at this point in the history
* move MatchstickComponent to shared

* add Speed field to ISurgeryTool, add Tweezers and Tending tools

* add support for ghetto surgery tools

* use Tending and Tweezers for some steps

* GHETTO SURGERY!!!

* add qualities to fire axe

* fix popups

* :trollface:

* disable coil hemostat

* add examine verb for a tools uses

* work#

* round the speed to 2 decimal places

* remove .

* webedit ops

* shitcode

* undo breaking change

* fix

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
  • Loading branch information
deltanedas authored and deltanedas committed Dec 27, 2024
1 parent 38da68a commit 67b0a95
Show file tree
Hide file tree
Showing 42 changed files with 476 additions and 64 deletions.
5 changes: 5 additions & 0 deletions Content.Client/Smoking/MatchstickSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Content.Shared.Smoking.Systems;

namespace Content.Client.Smoking;

public sealed class MatchstickSystem : SharedMatchstickSystem;
29 changes: 0 additions & 29 deletions Content.Server/Light/Components/MatchstickComponent.cs

This file was deleted.

1 change: 1 addition & 0 deletions Content.Server/Light/EntitySystems/MatchboxSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Server.Storage.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Smoking;
using Content.Shared.Smoking.Components;

namespace Content.Server.Light.EntitySystems
{
Expand Down
18 changes: 12 additions & 6 deletions Content.Server/Light/EntitySystems/MatchstickSystem.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Light.Components;
using Content.Shared.Audio;
using Content.Shared.Interaction;
using Content.Shared.Item;
using Content.Shared.Smoking;
using Content.Shared.Smoking.Components;
using Content.Shared.Smoking.Systems;
using Content.Shared.Temperature;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
Expand All @@ -12,7 +13,7 @@

namespace Content.Server.Light.EntitySystems
{
public sealed class MatchstickSystem : EntitySystem
public sealed class MatchstickSystem : SharedMatchstickSystem
{
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
Expand Down Expand Up @@ -84,18 +85,21 @@ public void Ignite(Entity<MatchstickComponent> matchstick, EntityUid user)
_audio.PlayPvs(component.IgniteSound, matchstick, AudioParams.Default.WithVariation(0.125f).WithVolume(-0.125f));

// Change state
SetState(matchstick, component, SmokableState.Lit);
SetState((matchstick, component), SmokableState.Lit);
_litMatches.Add(matchstick);
matchstick.Owner.SpawnTimer(component.Duration * 1000, delegate
{
SetState(matchstick, component, SmokableState.Burnt);
SetState((matchstick, component), SmokableState.Burnt);
_litMatches.Remove(matchstick);
});
}

private void SetState(EntityUid uid, MatchstickComponent component, SmokableState value)
public override bool SetState(Entity<MatchstickComponent> ent, SmokableState value)
{
component.CurrentState = value;
if (!base.SetState(ent, value))
return false;

var (uid, component) = ent;

if (_lights.TryGetLight(uid, out var pointLightComponent))
{
Expand All @@ -119,6 +123,8 @@ private void SetState(EntityUid uid, MatchstickComponent component, SmokableStat
{
_appearance.SetData(uid, SmokingVisuals.Smoking, component.CurrentState, appearance);
}

return true;
}
}
}
3 changes: 3 additions & 0 deletions Content.Shared/Body/Organ/OrganComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public sealed partial class OrganComponent : Component, ISurgeryToolComponent //
[DataField]
public string ToolName { get; set; } = "An organ";

[DataField]
public float Speed { get; set; } = 1f;

/// <summary>
/// Shitmed Change: If true, the organ will not heal an entity when transplanted into them.
/// </summary>
Expand Down
3 changes: 3 additions & 0 deletions Content.Shared/Body/Part/BodyPartComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
[DataField, AutoNetworkedField]
public bool? Used { get; set; } = null;

[DataField]
public float Speed { get; set; } = 1f;

/// <summary>
/// Shitmed Change: What's the max health this body part can have?
/// </summary>
Expand Down
28 changes: 28 additions & 0 deletions Content.Shared/Smoking/Components/MatchstickComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Content.Shared.Smoking.Systems;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;

namespace Content.Shared.Smoking.Components;

[RegisterComponent, NetworkedComponent, Access(typeof(SharedMatchstickSystem))]
[AutoGenerateComponentState]
public sealed partial class MatchstickComponent : Component
{
/// <summary>
/// Current state to matchstick. Can be <code>Unlit</code>, <code>Lit</code> or <code>Burnt</code>.
/// </summary>
[DataField("state"), AutoNetworkedField]
public SmokableState CurrentState = SmokableState.Unlit;

/// <summary>
/// How long will matchstick last in seconds.
/// </summary>
[DataField]
public int Duration = 10;

/// <summary>
/// Sound played when you ignite the matchstick.
/// </summary>
[DataField(required: true)]
public SoundSpecifier IgniteSound = default!;
}
16 changes: 16 additions & 0 deletions Content.Shared/Smoking/Systems/SharedMatchstickSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Content.Shared.Smoking.Components;

namespace Content.Shared.Smoking.Systems;

public abstract class SharedMatchstickSystem : EntitySystem
{
public virtual bool SetState(Entity<MatchstickComponent> ent, SmokableState state)
{
if (ent.Comp.CurrentState == state)
return false;

ent.Comp.CurrentState = state;
Dirty(ent);
return true;
}
}
42 changes: 28 additions & 14 deletions Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private void OnToolStep(Entity<SurgeryStepComponent> ent, ref SurgeryStepEvent a
{
foreach (var reg in ent.Comp.Tool.Values)
{
if (!AnyHaveComp(args.Tools, reg.Component, out var tool))
if (!AnyHaveComp(args.Tools, reg.Component, out var tool, out _))
return;

if (_net.IsServer &&
Expand Down Expand Up @@ -195,21 +195,21 @@ private void OnToolCanPerform(Entity<SurgeryStepComponent> ent, ref SurgeryCanPe

if (ent.Comp.Tool != null)
{
args.ValidTools ??= new HashSet<EntityUid>();
args.ValidTools ??= new Dictionary<EntityUid, float>();

foreach (var reg in ent.Comp.Tool.Values)
{
if (!AnyHaveComp(args.Tools, reg.Component, out var withComp))
if (!AnyHaveComp(args.Tools, reg.Component, out var tool, out var speed))
{
args.Invalid = StepInvalidReason.MissingTool;

if (reg.Component is ISurgeryToolComponent tool)
args.Popup = $"You need {tool.ToolName} to perform this step!";
if (reg.Component is ISurgeryToolComponent required)
args.Popup = $"You need {required.ToolName} to perform this step!";

return;
}

args.ValidTools.Add(withComp);
args.ValidTools[tool] = speed;
}
}
}
Expand Down Expand Up @@ -593,9 +593,21 @@ private void OnSurgeryTargetStepChosen(Entity<SurgeryTargetComponent> ent, ref S
if (!CanPerformStep(user, body, part, step, true, out _, out _, out var validTools))
return;

if (_net.IsServer && validTools?.Count > 0)
// make the doafter longer for ghetto tools, or shorter for advanced ones
var speed = 1f;
var usedEv = new SurgeryToolUsedEvent(user, body);
foreach (var (tool, toolSpeed) in validTools!)
{
foreach (var tool in validTools)
RaiseLocalEvent(tool, ref usedEv);
if (usedEv.Cancelled)
return;

speed *= toolSpeed;
}

if (_net.IsServer)
{
foreach (var tool in validTools.Keys)
{
if (TryComp(tool, out SurgeryToolComponent? toolComp) &&
toolComp.EndSound != null)
Expand All @@ -609,8 +621,8 @@ private void OnSurgeryTargetStepChosen(Entity<SurgeryTargetComponent> ent, ref S
_rotateToFace.TryFaceCoordinates(user, _transform.GetMapCoordinates(body, xform).Position);

var ev = new SurgeryDoAfterEvent(args.Surgery, args.Step);
// TODO: Make this serialized on a per surgery step basis, and also add penalties based on ghetto tools.
var duration = 2f;
// TODO: Move 2 seconds to a field of SurgeryStepComponent
var duration = 2f * speed;
if (TryComp(user, out SurgerySpeedModifierComponent? surgerySpeedMod)
&& surgerySpeedMod is not null)
duration = duration / surgerySpeedMod.SpeedModifier;
Expand Down Expand Up @@ -687,7 +699,7 @@ public bool PreviousStepsComplete(EntityUid body, EntityUid part, Entity<Surgery

public bool CanPerformStep(EntityUid user, EntityUid body, EntityUid part,
EntityUid step, bool doPopup, out string? popup, out StepInvalidReason reason,
out HashSet<EntityUid>? validTools)
out Dictionary<EntityUid, float>? validTools)
{
var type = BodyPartType.Other;
if (TryComp(part, out BodyPartComponent? partComp))
Expand Down Expand Up @@ -741,18 +753,20 @@ public bool IsStepComplete(EntityUid body, EntityUid part, EntProtoId step, Enti
return !ev.Cancelled;
}

private bool AnyHaveComp(List<EntityUid> tools, IComponent component, out EntityUid withComp)
private bool AnyHaveComp(List<EntityUid> tools, IComponent component, out EntityUid withComp, out float speed)
{
foreach (var tool in tools)
{
if (HasComp(tool, component.GetType()))
if (EntityManager.TryGetComponent(tool, component.GetType(), out var found) && found is ISurgeryToolComponent toolComp)
{
withComp = tool;
speed = toolComp.Speed;
return true;
}
}

withComp = default;
withComp = EntityUid.Invalid;
speed = 1f;
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ public record struct SurgeryCanPerformStepEvent(
SlotFlags TargetSlots,
string? Popup = null,
StepInvalidReason Invalid = StepInvalidReason.None,
HashSet<EntityUid>? ValidTools = null
) : IInventoryRelayEvent;
Dictionary<EntityUid, float>? ValidTools = null
) : IInventoryRelayEvent;
5 changes: 3 additions & 2 deletions Content.Shared/_Shitmed/Surgery/Tools/BoneGelComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Content.Shared._Shitmed.Medical.Surgery.Tools;
public sealed partial class BoneGelComponent : Component, ISurgeryToolComponent
{
public string ToolName => "bone gel";

public bool? Used { get; set; } = null;
}
[DataField]
public float Speed { get; set; } = 1f;
}
4 changes: 3 additions & 1 deletion Content.Shared/_Shitmed/Surgery/Tools/BoneSawComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public sealed partial class BoneSawComponent : Component, ISurgeryToolComponent
{
public string ToolName => "a bone saw";
public bool? Used { get; set; } = null;
}
[DataField]
public float Speed { get; set; } = 1f;
}
4 changes: 3 additions & 1 deletion Content.Shared/_Shitmed/Surgery/Tools/CauteryComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public sealed partial class CauteryComponent : Component, ISurgeryToolComponent
{
public string ToolName => "a cautery";
public bool? Used { get; set; } = null;
}
[DataField]
public float Speed { get; set; } = 1f;
}
4 changes: 3 additions & 1 deletion Content.Shared/_Shitmed/Surgery/Tools/HemostatComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public sealed partial class HemostatComponent : Component, ISurgeryToolComponent
{
public string ToolName => "a hemostat";
public bool? Used { get; set; } = null;
}
[DataField]
public float Speed { get; set; } = 1f;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,11 @@ public interface ISurgeryToolComponent
// Mostly intended for discardable or non-reusable tools.
[DataField]
public bool? Used { get; set; }
}

/// <summary>
/// GoobStation: Multiply the step's doafter by this value.
/// This is per-type so you can have something that's a good scalpel but a bad retractor.
/// </summary>
[DataField]
public float Speed { get; set; }
}
4 changes: 3 additions & 1 deletion Content.Shared/_Shitmed/Surgery/Tools/RetractorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public sealed partial class RetractorComponent : Component, ISurgeryToolComponen
{
public string ToolName => "a retractor";
public bool? Used { get; set; } = null;
}
[DataField]
public float Speed { get; set; } = 1f;
}
4 changes: 3 additions & 1 deletion Content.Shared/_Shitmed/Surgery/Tools/ScalpelComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public sealed partial class ScalpelComponent : Component, ISurgeryToolComponent
{
public string ToolName => "a scalpel";
public bool? Used { get; set; } = null;
}
[DataField]
public float Speed { get; set; } = 1f;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@ public sealed partial class SurgeryToolComponent : Component

[DataField, AutoNetworkedField]
public SoundSpecifier? EndSound;
}
}

/// <summary>
/// GoobStation: Raised on a tool to see if it can be used in a surgery step.
/// If this is cancelled the step can't be completed.
/// </summary>
[ByRefEvent]
public record struct SurgeryToolUsedEvent(EntityUid User, EntityUid Target, bool Cancelled = false);
Loading

0 comments on commit 67b0a95

Please sign in to comment.