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

fix lay-down system #534

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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.Shared/Buckle/SharedBuckleSystem.Buckle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ private void Buckle(Entity<BuckleComponent> buckle, Entity<StrapComponent> strap
_standing.Stand(buckle, force: true);
break;
case StrapPosition.Down:
_standing.Down(buckle, false, false);
_standing.Down(buckle, false, false, force:true);
break;
}

Expand Down
14 changes: 9 additions & 5 deletions Content.Shared/Standing/SharedLayingDownSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,13 @@ private void OnChangeState(ChangeLayingDownEvent ev, EntitySessionEventArgs args
private void OnStandingUpDoAfter(EntityUid uid, StandingStateComponent component, StandingUpDoAfterEvent args)
{
if (args.Handled || args.Cancelled
|| HasComp<KnockedDownComponent>(uid)
|| _mobState.IsIncapacitated(uid)
|| !_standing.Stand(uid))
|| HasComp<KnockedDownComponent>(uid)
|| _mobState.IsIncapacitated(uid)
|| !_standing.Stand(uid))
{
component.CurrentState = StandingState.Lying;
return;
}

component.CurrentState = StandingState.Standing;
}
Expand Down Expand Up @@ -127,15 +130,16 @@ public bool TryLieDown(EntityUid uid, LayingDownComponent? layingDown = null, St
{
if (!Resolve(uid, ref standingState, false)
|| !Resolve(uid, ref layingDown, false)
|| standingState.CurrentState is not StandingState.Standing)
|| standingState.CurrentState is not StandingState.Standing
|| _standing.IsDown(uid))
{
if (behavior == DropHeldItemsBehavior.AlwaysDrop)
RaiseLocalEvent(uid, new DropHandItemsEvent());

return false;
}

_standing.Down(uid, true, behavior != DropHeldItemsBehavior.NoDrop, standingState);
_standing.Down(uid, true, behavior != DropHeldItemsBehavior.NoDrop, standingState: standingState);
return true;
}
}
Expand Down
107 changes: 46 additions & 61 deletions Content.Shared/Standing/StandingStateSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public sealed class StandingStateSystem : EntitySystem
[Dependency] private readonly MovementSpeedModifierSystem _movement = default!;
[Dependency] private readonly SharedBuckleSystem _buckle = default!;

// If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited.
private const int StandingCollisionLayer = (int) CollisionGroup.MidImpassable;

public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null)
Expand All @@ -32,44 +31,54 @@ public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null)
public bool Down(EntityUid uid,
bool playSound = true,
bool dropHeldItems = true,
bool force = false,
StandingStateComponent? standingState = null,
AppearanceComponent? appearance = null,
HandsComponent? hands = null)
HandsComponent? hands = null,
LayingDownComponent? layingDown = null)
{
// TODO: This should actually log missing comps...
if (!Resolve(uid, ref standingState, false))
return false;

// Optional component.
Resolve(uid, ref appearance, ref hands, false);
// Optional components
Resolve(uid, ref appearance, ref hands, ref layingDown, false);

if (standingState.CurrentState is StandingState.Lying or StandingState.GettingUp)
if (standingState.CurrentState is StandingState.Lying)
return true;

// This is just to avoid most callers doing this manually saving boilerplate
// 99% of the time you'll want to drop items but in some scenarios (e.g. buckling) you don't want to.
// We do this BEFORE downing because something like buckle may be blocking downing but we want to drop hand items anyway
// and ultimately this is just to avoid boilerplate in Down callers + keep their behavior consistent.
// Even if we're getting up, we want to reset to lying down
if (standingState.CurrentState is StandingState.GettingUp)
{
standingState.CurrentState = StandingState.Lying;
Dirty(uid, standingState);
return true;
}

if (dropHeldItems && hands != null)
RaiseLocalEvent(uid, new DropHandItemsEvent(), false);

if (TryComp(uid, out BuckleComponent? buckle) && buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle))
return false;
// Only check buckle if we're not forcing
if (!force)
{
if (TryComp(uid, out BuckleComponent? buckle) &&
buckle.Buckled &&
!_buckle.TryUnbuckle(uid, uid, buckleComp: buckle))
return false;

var msg = new DownAttemptEvent();
RaiseLocalEvent(uid, msg, false);
var msg = new DownAttemptEvent();
RaiseLocalEvent(uid, msg, false);

if (msg.Cancelled)
return false;
if (msg.Cancelled)
return false;
}

standingState.CurrentState = StandingState.Lying;

Dirty(uid, standingState);
RaiseLocalEvent(uid, new DownedEvent(), false);

// Seemed like the best place to put it
_appearance.SetData(uid, RotationVisuals.RotationState, RotationState.Horizontal, appearance);

// Change collision masks to allow going under certain entities like flaps and tables
if (TryComp(uid, out FixturesComponent? fixtureComponent))
{
foreach (var (key, fixture) in fixtureComponent.Fixtures)
Expand All @@ -82,12 +91,7 @@ public bool Down(EntityUid uid,
}
}

// check if component was just added or streamed to client
// if true, no need to play sound - mob was down before player could seen that
if (standingState.LifeStage <= ComponentLifeStage.Starting)
return true;

if (playSound)
if (standingState.LifeStage > ComponentLifeStage.Starting && playSound)
_audio.PlayPredicted(standingState.DownSound, uid, null);

_movement.RefreshMovementSpeedModifiers(uid);
Expand All @@ -97,20 +101,27 @@ public bool Down(EntityUid uid,
public bool Stand(EntityUid uid,
StandingStateComponent? standingState = null,
AppearanceComponent? appearance = null,
LayingDownComponent? layingDown = null,
bool force = false)
{
// TODO: This should actually log missing comps...
if (!Resolve(uid, ref standingState, false))
return false;

// Optional component.
Resolve(uid, ref appearance, false);
Resolve(uid, ref appearance, ref layingDown, false);

if (standingState.CurrentState is StandingState.Standing
|| TryComp(uid, out BuckleComponent? buckle)
&& buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle))
// Already standing
if (standingState.CurrentState is StandingState.Standing)
return true;

if (!force && TryComp(uid, out BuckleComponent? buckle))
{
if (buckle.Buckled)
{
if (!_buckle.TryUnbuckle(uid, uid, buckleComp: buckle))
return false;
}
}

if (!force)
{
var msg = new StandAttemptEvent();
Expand Down Expand Up @@ -141,35 +152,9 @@ public bool Stand(EntityUid uid,
}
}

public sealed class DropHandItemsEvent : EventArgs
{
}

/// <summary>
/// Subscribe if you can potentially block a down attempt.
/// </summary>
public sealed class DownAttemptEvent : CancellableEntityEventArgs
{
}

/// <summary>
/// Subscribe if you can potentially block a stand attempt.
/// </summary>
public sealed class StandAttemptEvent : CancellableEntityEventArgs
{
}

/// <summary>
/// Raised when an entity becomes standing
/// </summary>
public sealed class StoodEvent : EntityEventArgs
{
}

/// <summary>
/// Raised when an entity is not standing
/// </summary>
public sealed class DownedEvent : EntityEventArgs
{
}
public sealed class DropHandItemsEvent : EventArgs { }
public sealed class DownAttemptEvent : CancellableEntityEventArgs { }
public sealed class StandAttemptEvent : CancellableEntityEventArgs { }
public sealed class StoodEvent : EntityEventArgs { }
public sealed class DownedEvent : EntityEventArgs { }
}
Loading