Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grab #30011

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open

Grab #30011

Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Content.Server/Alert/Click/StopPulling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public void AlertClicked(EntityUid player)
if (entManager.TryGetComponent(player, out PullerComponent? puller) &&
entManager.TryGetComponent(puller.Pulling, out PullableComponent? pullableComp))
{
ps.TryStopPull(puller.Pulling.Value, pullableComp, user: player);
ps.TryStopPull(puller.Pulling.Value, pullableComp, user: player, ignoreGrab: true);
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion Content.Server/Body/Systems/RespiratorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Content.Shared.Movement.Pulling.Systems;
using Content.Shared.Movement.Pulling.Components;

namespace Content.Server.Body.Systems;

Expand Down Expand Up @@ -59,6 +61,13 @@ private void OnUnpaused(Entity<RespiratorComponent> ent, ref EntityUnpausedEvent
ent.Comp.NextUpdate += args.PausedTime;
}

public bool CanBreathe(EntityUid uid)
{
if (TryComp<PullableComponent>(uid, out var pullable) && pullable.GrabStage == GrabStage.Suffocate)
return false;
return true;
}

public override void Update(float frameTime)
{
base.Update(frameTime);
Expand Down Expand Up @@ -91,7 +100,7 @@ public override void Update(float frameTime)
}
}

if (respirator.Saturation < respirator.SuffocationThreshold)
if (respirator.Saturation < respirator.SuffocationThreshold || !CanBreathe(uid))
{
if (_gameTiming.CurTime >= respirator.LastGaspEmoteTime + respirator.GaspEmoteCooldown)
{
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Hands/Systems/HandsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private void OnDisarmed(EntityUid uid, HandsComponent component, DisarmedEvent a

// Break any pulls
if (TryComp(uid, out PullerComponent? puller) && TryComp(puller.Pulling, out PullableComponent? pullable))
_pullingSystem.TryStopPull(puller.Pulling.Value, pullable);
_pullingSystem.TryStopPull(puller.Pulling.Value, pullable, ignoreGrab: true);

var offsetRandomCoordinates = _transformSystem.GetMoverCoordinates(args.Target).Offset(_random.NextVector2(1f, 1.5f));
if (!ThrowHeldItem(args.Target, offsetRandomCoordinates))
Expand Down
4 changes: 2 additions & 2 deletions Content.Server/Implants/SubdermalImplantSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Content.Server.Cuffs;
using Content.Server.Cuffs;
using Content.Server.Forensics;
using Content.Server.Humanoid;
using Content.Server.Implants.Components;
Expand Down Expand Up @@ -108,7 +108,7 @@ private void OnScramImplant(EntityUid uid, SubdermalImplantComponent component,
// We need stop the user from being pulled so they don't just get "attached" with whoever is pulling them.
// This can for example happen when the user is cuffed and being pulled.
if (TryComp<PullableComponent>(ent, out var pull) && _pullingSystem.IsPulled(ent, pull))
_pullingSystem.TryStopPull(ent, pull);
_pullingSystem.TryStopPull(ent, pull, ignoreGrab: true);

var xform = Transform(ent);
var targetCoords = SelectRandomTileInRange(xform, implant.TeleportRadius);
Expand Down
2 changes: 1 addition & 1 deletion Content.Shared/Administration/SharedAdminFrozenSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void OnStartup(EntityUid uid, AdminFrozenComponent component, ComponentS
{
if (TryComp<PullableComponent>(uid, out var pullable))
{
_pulling.TryStopPull(uid, pullable);
_pulling.TryStopPull(uid, pullable, ignoreGrab: true);
}

UpdateCanMove(uid, component, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void OnAnchorComplete(EntityUid uid, AnchorableComponent component, TryA

if (TryComp<PullableComponent>(uid, out var pullable) && pullable.Puller != null)
{
_pulling.TryStopPull(uid, pullable);
_pulling.TryStopPull(uid, pullable, ignoreGrab: true);
}

// TODO: Anchoring snaps rn anyway!
Expand Down
24 changes: 24 additions & 0 deletions Content.Shared/MartialArts/Components/GrabThrownComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Content.Shared.Alert;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Content.Shared.Movement.Pulling.Systems;
using Robust.Shared.Timing;
using Content.Shared.Damage;
using Content.Shared.Physics;
using Robust.Shared.Physics;

namespace Content.Shared.MartialArts.Components; // Added a new category because im planning to make martials combat soon. And throwing is kinda... Martial-artistic?

[RegisterComponent, NetworkedComponent]
public sealed partial class GrabThrownComponent : Component
{
public DamageSpecifier? DamageOnCollide;

public DamageSpecifier? WallDamageOnCollide;

public float? StaminaDamageOnCollide;

public int? SavedCollisionMask;

public int? SavedCollisionLayer;
}
117 changes: 117 additions & 0 deletions Content.Shared/MartialArts/Systems/GrabThrownSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using Content.Shared.Stunnable;
using Content.Shared.Damage.Components;
using Content.Shared.Effects;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Physics.Events;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Content.Shared.MartialArts.Components;
using Content.Shared.Damage;
using Content.Shared.Throwing;
using Content.Shared.Damage.Systems;
using System.Numerics;
using Robust.Shared.Physics.Systems;
using Content.Shared.Physics;
using Robust.Shared.Physics;
using System.Linq;
using Content.Shared.Movement.Systems;

namespace Content.Shared.MartialArts.Systems;

public sealed class GrabThrownSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
[Dependency] private readonly StaminaSystem _stamina = default!;
[Dependency] private readonly ThrowingSystem _throwing = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;

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

SubscribeLocalEvent<GrabThrownComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<GrabThrownComponent, ComponentShutdown>(OnShutdown);

SubscribeLocalEvent<GrabThrownComponent, StartCollideEvent>(HandleCollide);
}

private void HandleCollide(EntityUid uid, GrabThrownComponent component, ref StartCollideEvent args)
{
if (!HasComp<ThrownItemComponent>(uid))
{
RemComp<GrabThrownComponent>(uid);
return;
}

if (!args.OurFixture.Hard || !args.OtherFixture.Hard)
return;

if (!EntityManager.HasComponent<DamageableComponent>(uid))
return;

var speed = args.OurBody.LinearVelocity.Length();


if (component.StaminaDamageOnCollide != null)
_stamina.TakeStaminaDamage(uid, component.StaminaDamageOnCollide.Value);
var damageScale = speed;

if (component.DamageOnCollide != null)
_damageable.TryChangeDamage(uid, component.DamageOnCollide * damageScale);

if (component.WallDamageOnCollide != null)
_damageable.TryChangeDamage(args.OtherEntity, component.WallDamageOnCollide * damageScale);

//if (_gameTiming.IsFirstTimePredicted)
// _audio.PlayPvs(component.SoundHit, uid, AudioParams.Default.WithVariation(0.125f).WithVolume(-0.125f));
_color.RaiseEffect(Color.Red, new List<EntityUid>() { uid }, Filter.Pvs(uid, entityManager: EntityManager));

RemComp<GrabThrownComponent>(uid);
}

public void OnStartup(EntityUid uid, GrabThrownComponent component, ComponentStartup args)
{
if (TryComp<FixturesComponent>(uid, out var fixtures) && fixtures.FixtureCount >= 1)
{
var fixture = fixtures.Fixtures.First();

component.SavedCollisionMask = fixture.Value.CollisionMask;
component.SavedCollisionLayer = fixture.Value.CollisionLayer;

_physics.SetCollisionMask(uid, fixture.Key, fixture.Value, (int) CollisionGroup.FlyingMobMask, fixtures);
_physics.SetCollisionLayer(uid, fixture.Key, fixture.Value, (int) CollisionGroup.FlyingMobLayer, fixtures);
}
}

public void OnShutdown(EntityUid uid, GrabThrownComponent component, ComponentShutdown args)
{
if (TryComp<FixturesComponent>(uid, out var fixtures) && fixtures.FixtureCount >= 1)
{
var fixture = fixtures.Fixtures.First();

if (component.SavedCollisionLayer != null && component.SavedCollisionMask != null)
{
_physics.SetCollisionMask(uid, fixture.Key, fixture.Value, component.SavedCollisionMask.Value, fixtures);
_physics.SetCollisionLayer(uid, fixture.Key, fixture.Value, component.SavedCollisionLayer.Value, fixtures);
}
}
}

public void Throw(EntityUid uid, Vector2 vector, float? staminaDamage = null, DamageSpecifier? damageToUid = null, DamageSpecifier? damageToWall = null)
{
_throwing.TryThrow(uid, vector, 4f, animated: false);

var comp = EnsureComp<GrabThrownComponent>(uid);
comp.StaminaDamageOnCollide = staminaDamage;
comp.DamageOnCollide = damageToUid;
comp.WallDamageOnCollide = damageToWall;

}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
using Robust.Shared.Map;
using Robust.Shared.GameStates;

namespace Content.Server.Movement.Components;
namespace Content.Shared.Movement.Pulling.Components;

/// <summary>
/// Added when an entity is being ctrl-click moved when pulled.
/// </summary>
[RegisterComponent]
[RegisterComponent, NetworkedComponent]
public sealed partial class PullMovingComponent : Component
{
// Not serialized to indicate THIS CODE SUCKS, fix pullcontroller first
// Sorry but I need it here - FaDeOkno
[ViewVariables]
public EntityCoordinates MovingTo;
}
11 changes: 11 additions & 0 deletions Content.Shared/Movement/Pulling/Components/PullableComponent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Content.Shared.Alert;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Content.Shared.Movement.Pulling.Systems;
using Robust.Shared.Timing;

namespace Content.Shared.Movement.Pulling.Components;

Expand Down Expand Up @@ -41,4 +43,13 @@ public sealed partial class PullableComponent : Component

[DataField]
public ProtoId<AlertPrototype> PulledAlert = "Pulled";

[AutoNetworkedField, DataField]
public GrabStage GrabStage = GrabStage.No;

[AutoNetworkedField, DataField]
public float GrabEscapeChance = 1f;

[AutoNetworkedField]
public TimeSpan NextEscapeAttempt = TimeSpan.Zero;
}
23 changes: 22 additions & 1 deletion Content.Shared/Movement/Pulling/Components/PullerComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Content.Shared.Alert;
using Content.Shared.Alert;
using Content.Shared.Movement.Pulling.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
Expand Down Expand Up @@ -43,4 +43,25 @@ public sealed partial class PullerComponent : Component

[DataField]
public ProtoId<AlertPrototype> PullingAlert = "Pulling";

[AutoNetworkedField, DataField]
public GrabStage GrabStage = GrabStage.No;

[DataField]
public float SoftStageEscapeChance = 0.7f;

[DataField]
public float HardStageEscapeChance = 0.4f;

[DataField]
public float SuffocateStageEscapeChance = 0.1f;

[AutoNetworkedField]
public TimeSpan NextStageChange = TimeSpan.Zero;

[DataField]
public float SuffocateGrabStaminaDamage = 10f;

[DataField]
public float GrabThrowDamageModifier = 1f;
}
Loading
Loading