Skip to content

Commit

Permalink
Fixed a buncho crap
Browse files Browse the repository at this point in the history
  • Loading branch information
gluesniffler committed Oct 31, 2024
1 parent 990fa8a commit 716811d
Show file tree
Hide file tree
Showing 20 changed files with 357 additions and 119 deletions.
21 changes: 9 additions & 12 deletions Content.Server/Medical/HealingSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Content.Server.Administration.Logs;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Shared.Body.Part;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Medical.Components;
using Content.Server.Popups;
Expand Down Expand Up @@ -95,17 +96,13 @@ entity.Comp.DamageContainerID is not null &&
*/
if (healed != null && healed.GetTotal() == 0)
{
if (TryComp<TargetingComponent>(args.User, out var user)
&& TryComp<TargetingComponent>(args.Target, out var target)
&& healing.Damage.GetTotal() < 0)
{
// If they are valid, we check for body part presence,
// and integrity, then apply a direct integrity change.
var (type, symmetry) = _bodySystem.ConvertTargetBodyPart(user.Target);
if (_bodySystem.GetBodyChildrenOfType(args.Target.Value, type, symmetry: symmetry).FirstOrDefault() is { } bodyPart
&& bodyPart.Component.Integrity < bodyPart.Component.MaxIntegrity)
_bodySystem.TryChangeIntegrity(bodyPart, healing.Damage.GetTotal().Float(), false, target.Target, out var _);
}
var parts = _bodySystem.GetBodyChildren(args.Target).ToList();
// We fetch the most damaged body part
var mostDamaged = parts.MinBy(x => x.Component.Integrity);
var targetBodyPart = _bodySystem.GetTargetBodyPart(mostDamaged);

if (targetBodyPart != null)
_bodySystem.TryChangeIntegrity(mostDamaged, healing.Damage.GetTotal().Float(), false, targetBodyPart.Value, out _);
}

var total = healed?.GetTotal() ?? FixedPoint2.Zero;
Expand Down Expand Up @@ -166,7 +163,7 @@ private bool ArePartsDamaged(EntityUid target)

foreach (var part in _bodySystem.GetBodyChildren(target, body))
{
if (part.Component.Integrity < part.Component.MaxIntegrity)
if (part.Component.Integrity < BodyPartComponent.MaxIntegrity)
return true;
}
return false;
Expand Down
15 changes: 8 additions & 7 deletions Content.Server/Medical/Surgery/SurgerySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Content.Shared.Body.Part;
using Content.Server.Chat.Systems;
using Content.Server.Popups;
using Content.Shared.CCVar;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.Interaction;
Expand All @@ -18,9 +19,9 @@
using Content.Server.Atmos.Rotting;
using Content.Shared.Eye.Blinding.Components;
using Content.Shared.Eye.Blinding.Systems;
//using Content.Shared.Medical.Wounds;
using Content.Shared.Prototypes;
using Robust.Server.GameObjects;
using Robust.Shared.Configuration;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
Expand All @@ -32,14 +33,13 @@ public sealed class SurgerySystem : SharedSurgerySystem
{
[Dependency] private readonly BodySystem _body = default!;
[Dependency] private readonly ChatSystem _chat = default!;

[Dependency] private readonly IConfigurationManager _config = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypes = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly RottingSystem _rot = default!;
[Dependency] private readonly BlindableSystem _blindableSystem = default!;
//[Dependency] private readonly WoundsSystem _wounds = default!;

private readonly List<EntProtoId> _surgeries = new();

Expand Down Expand Up @@ -108,12 +108,13 @@ private void OnToolAfterInteract(Entity<SurgeryToolComponent> ent, ref AfterInte
{
return;
}
/* lmao bet
if (user == args.Target)

if (user == args.Target && !_config.GetCVar(CCVars.CanOperateOnSelf))
{
_popup.PopupEntity("You can't perform surgery on yourself!", user, user);
_popup.PopupEntity(Loc.GetString("surgery-error-self-surgery"), user, user);
return;
}*/
}

args.Handled = true;
_ui.OpenUi(args.Target.Value, SurgeryUIKey.Key, user);
RefreshUI(args.Target.Value);
Expand Down
7 changes: 1 addition & 6 deletions Content.Server/Targeting/TargetingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@
using Content.Shared.Mobs;
using Content.Shared.Targeting;
using Content.Shared.Targeting.Events;
using Robust.Server.Audio;
using Robust.Shared.Audio;

namespace Content.Server.Targeting;
public sealed class TargetingSystem : SharedTargetingSystem
{
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly SharedBodySystem _bodySystem = default!;

public override void Initialize()
Expand All @@ -23,8 +20,6 @@ private void OnTargetChange(TargetChangeEvent message, EntitySessionEventArgs ar
if (!TryComp<TargetingComponent>(GetEntity(message.Uid), out var target))
return;

// Todo, get a better sound for this shit.
//_audio.PlayGlobal(target.SwapSound, args.SenderSession, AudioParams.Default.WithVolume(-8f));
target.Target = message.BodyPart;
Dirty(GetEntity(message.Uid), target);
}
Expand Down Expand Up @@ -54,4 +49,4 @@ private void OnMobStateChange(EntityUid uid, TargetingComponent component, MobSt
RaiseNetworkEvent(new TargetIntegrityChangeEvent(GetNetEntity(uid)), uid);
}
}
}
}
13 changes: 11 additions & 2 deletions Content.Shared/Body/Part/BodyPartComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Shared.Medical.Surgery.Tools;
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
using Content.Shared.FixedPoint;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
Expand Down Expand Up @@ -36,6 +37,14 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
[DataField("vital"), AutoNetworkedField]
public bool IsVital;

/// <summary>
/// Amount of damage to deal when the part gets removed.
/// Only works if IsVital is true.
/// </summary>
[DataField, AutoNetworkedField]
public FixedPoint2 VitalDamage = MaxIntegrity;


[DataField, AutoNetworkedField]
public BodyPartSymmetry Symmetry = BodyPartSymmetry.None;

Expand Down Expand Up @@ -66,8 +75,8 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent
/// <summary>
/// What's the max health this body part can have?
/// </summary>
[DataField, AutoNetworkedField]
public float MaxIntegrity = 100f;
[DataField]
public const float MaxIntegrity = 100f;

/// <summary>
/// Whether this body part is enabled or not.
Expand Down
12 changes: 11 additions & 1 deletion Content.Shared/Body/Systems/SharedBodySystem.Body.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Content.Shared.Gibbing.Events;
using Content.Shared.Gibbing.Systems;
using Content.Shared.Inventory;
using Content.Shared.Rejuvenate;
using Content.Shared.Standing;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
Expand Down Expand Up @@ -49,6 +50,7 @@ private void InitializeBody()
SubscribeLocalEvent<BodyComponent, CanDragEvent>(OnBodyCanDrag);
SubscribeLocalEvent<BodyComponent, DamageChangedEvent>(OnDamageChanged);
SubscribeLocalEvent<BodyComponent, StandAttemptEvent>(OnStandAttempt);
SubscribeLocalEvent<BodyComponent, RejuvenateEvent>(OnRejuvenate);
}

private void OnBodyInserted(Entity<BodyComponent> ent, ref EntInsertedIntoContainerMessage args)
Expand Down Expand Up @@ -158,6 +160,14 @@ private void OnDamageChanged(Entity<BodyComponent> ent, ref DamageChangedEvent a
}
}

private void OnRejuvenate(Entity<BodyComponent> ent, ref RejuvenateEvent args)
{
foreach (var part in GetBodyChildren(ent, ent.Comp))
{
TryChangeIntegrity(part, part.Component.Integrity - BodyPartComponent.MaxIntegrity, false, GetTargetBodyPart(part), out _);
}
}

/// <summary>
/// Sets up all of the relevant body parts for a particular body entity and root part.
/// </summary>
Expand Down Expand Up @@ -340,7 +350,7 @@ public virtual HashSet<EntityUid> GibBody(
foreach (var part in parts)
{

_gibbingSystem.TryGibEntityWithRef(bodyId, part.Id, GibType.Gib, GibContentsOption.Skip, ref gibs,
_gibbingSystem.TryGibEntityWithRef(bodyId, part.Id, GibType.Gib, GibContentsOption.Drop, ref gibs,
playAudio: false, launchGibs: true, launchDirection: splatDirection, launchImpulse: GibletLaunchImpulse * splatModifier,
launchImpulseVariance: GibletLaunchImpulseVariance, launchCone: splatCone);

Expand Down
112 changes: 83 additions & 29 deletions Content.Shared/Body/Systems/SharedBodySystem.Integrity.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.Damage;
using Content.Shared.Mobs.Systems;
using Content.Shared.Medical.Surgery.Steps.Parts;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Standing;
using Content.Shared.Targeting;
using Content.Shared.Targeting.Events;
using Robust.Shared.CPUJob.JobQueues;
using Robust.Shared.CPUJob.JobQueues.Queues;
using Robust.Shared.Network;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Content.Shared.Body.Systems;

Expand All @@ -19,45 +24,88 @@ public partial class SharedBodySystem
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly IRobustRandom _random = default!;
private readonly string[] _severingDamageTypes = { "Slash", "Pierce", "Blunt" };
private const double IntegrityJobTime = 0.005;
private readonly JobQueue _integrityJobQueue = new(IntegrityJobTime);

public sealed class IntegrityJob : Job<object>
{
private readonly SharedBodySystem _self;
private readonly Entity<BodyPartComponent> _ent;
public IntegrityJob(SharedBodySystem self, Entity<BodyPartComponent> ent, double maxTime, CancellationToken cancellation = default) : base(maxTime, cancellation)
{
_self = self;
_ent = ent;
}

public IntegrityJob(SharedBodySystem self, Entity<BodyPartComponent> ent, double maxTime, IStopwatch stopwatch, CancellationToken cancellation = default) : base(maxTime, stopwatch, cancellation)
{
_self = self;
_ent = ent;
}

protected override Task<object?> Process()
{
_self.ProcessIntegrityTick(_ent);

return Task.FromResult<object?>(null);
}
}

private EntityQuery<TargetingComponent> _queryTargeting;
private void InitializeIntegrityQueue()
{
_queryTargeting = GetEntityQuery<TargetingComponent>();
}

private void ProcessIntegrityTick(Entity<BodyPartComponent> entity)
{
if (entity.Comp is { Body: { } body, Integrity: > 50 and < BodyPartComponent.MaxIntegrity }
&& _queryTargeting.HasComp(body)
&& !_mobState.IsDead(body))
{
var healing = entity.Comp.SelfHealingAmount;
if (healing + entity.Comp.Integrity > BodyPartComponent.MaxIntegrity)
healing = entity.Comp.Integrity - BodyPartComponent.MaxIntegrity;

TryChangeIntegrity(entity,
healing,
false,
GetTargetBodyPart(entity),
out _);
}
}

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

var query = EntityQueryEnumerator<BodyPartComponent>();
if (!_timing.IsFirstTimePredicted)
return;

using var query = EntityQueryEnumerator<BodyPartComponent>();
while (query.MoveNext(out var ent, out var part))
{
if (!_timing.IsFirstTimePredicted
|| !HasComp<TargetingComponent>(ent))
continue;

part.HealingTimer += frameTime;

if (part.HealingTimer >= part.HealingTime)
{
part.HealingTimer = 0;
if (part.Body is not null
&& part.Integrity > 50
&& part.Integrity < part.MaxIntegrity
&& !_mobState.IsDead(part.Body.Value))
{
var healing = part.SelfHealingAmount;
if (healing + part.Integrity > part.MaxIntegrity)
healing = part.Integrity - part.MaxIntegrity;

TryChangeIntegrity((ent, part), healing,
false, GetTargetBodyPart(part.PartType, part.Symmetry), out _);
}
_integrityJobQueue.EnqueueJob(new IntegrityJob(this, (ent, part), IntegrityJobTime));
}

}
query.Dispose();
}


/// <summary>
/// Propagates damage to the specified parts of the entity.
/// </summary>
private void ApplyPartDamage(Entity<BodyPartComponent> partEnt, DamageSpecifier damage,
BodyPartType targetType, TargetBodyPart targetPart, bool canSever, float partMultiplier)
private void ApplyPartDamage(Entity<BodyPartComponent> partEnt,
DamageSpecifier damage,
BodyPartType targetType,
TargetBodyPart targetPart,
bool canSever,
float partMultiplier)
{
if (partEnt.Comp.Body is null)
return;
Expand All @@ -79,16 +127,19 @@ private void ApplyPartDamage(Entity<BodyPartComponent> partEnt, DamageSpecifier
}
}

public void TryChangeIntegrity(Entity<BodyPartComponent> partEnt, float integrity, bool canSever,
TargetBodyPart? targetPart, out bool severed)
public void TryChangeIntegrity(Entity<BodyPartComponent> partEnt,
float integrity,
bool canSever,
TargetBodyPart? targetPart,
out bool severed)
{
severed = false;
if (!HasComp<TargetingComponent>(partEnt.Comp.Body) || !_timing.IsFirstTimePredicted)
if (!_timing.IsFirstTimePredicted || !_queryTargeting.HasComp(partEnt.Comp.Body))
return;

var partIdSlot = GetParentPartAndSlotOrNull(partEnt)?.Slot;
var originalIntegrity = partEnt.Comp.Integrity;
partEnt.Comp.Integrity = Math.Min(partEnt.Comp.MaxIntegrity, partEnt.Comp.Integrity - integrity);
partEnt.Comp.Integrity = Math.Min(BodyPartComponent.MaxIntegrity, partEnt.Comp.Integrity - integrity);
if (canSever
&& !HasComp<BodyPartReattachedComponent>(partEnt)
&& !partEnt.Comp.Enabled
Expand All @@ -110,9 +161,9 @@ public void TryChangeIntegrity(Entity<BodyPartComponent> partEnt, float integrit
RaiseLocalEvent(partEnt, ref ev);
}

if (partEnt.Comp.Integrity != originalIntegrity
&& TryComp<TargetingComponent>(partEnt.Comp.Body, out var targeting)
&& TryComp<MobStateComponent>(partEnt.Comp.Body, out var _))
if (Math.Abs(partEnt.Comp.Integrity - originalIntegrity) > 0.01
&& _queryTargeting.TryComp(partEnt.Comp.Body, out var targeting)
&& HasComp<MobStateComponent>(partEnt.Comp.Body))
{
var newIntegrity = GetIntegrityThreshold(partEnt.Comp.Integrity, severed, partEnt.Comp.Enabled);
// We need to check if the part is dead to prevent the UI from showing dead parts as alive.
Expand Down Expand Up @@ -161,6 +212,9 @@ public Dictionary<TargetBodyPart, TargetIntegrity> GetBodyPartStatus(EntityUid e
return result;
}

public TargetBodyPart? GetTargetBodyPart(Entity<BodyPartComponent> part) => GetTargetBodyPart(part.Comp.PartType, part.Comp.Symmetry);
public TargetBodyPart? GetTargetBodyPart(BodyPartComponent part) => GetTargetBodyPart(part.PartType, part.Symmetry);

/// <summary>
/// Converts Enums from BodyPartType to their Targeting system equivalent.
/// </summary>
Expand Down
Loading

0 comments on commit 716811d

Please sign in to comment.