private void InitializeEventListeners()
{
SubscribeLocalEvent<HandsComponent, GetStandUpTimeEvent>(OnStandupArgs);
+ SubscribeLocalEvent<HandsComponent, KnockedDownRefreshEvent>(OnKnockedDownRefresh);
}
/// <summary>
time.DoAfterTime *= (float)ent.Comp.Count / (hands + ent.Comp.Count);
}
+
+ private void OnKnockedDownRefresh(Entity<HandsComponent> ent, ref KnockedDownRefreshEvent args)
+ {
+ var freeHands = CountFreeHands(ent.AsNullable());
+ var totalHands = GetHandCount(ent.AsNullable());
+
+ // Can't crawl around without any hands.
+ // Entities without the HandsComponent will always have full crawling speed.
+ if (totalHands == 0)
+ args.SpeedModifier = 0f;
+ else
+ args.SpeedModifier *= (float)freeHands / totalHands;
+ }
}
using Content.Shared.Alert;
using Content.Shared.Buckle.Components;
using Content.Shared.CCVar;
-using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Gravity;
+using Content.Shared.Hands;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Input;
using Content.Shared.Movement.Events;
SubscribeLocalEvent<KnockedDownComponent, BuckleAttemptEvent>(OnBuckleAttempt);
SubscribeLocalEvent<KnockedDownComponent, StandAttemptEvent>(OnStandAttempt);
- // Updating movement a friction
+ // Updating movement and friction
SubscribeLocalEvent<KnockedDownComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshKnockedSpeed);
SubscribeLocalEvent<KnockedDownComponent, RefreshFrictionModifiersEvent>(OnRefreshFriction);
SubscribeLocalEvent<KnockedDownComponent, TileFrictionEvent>(OnKnockedTileFriction);
SubscribeLocalEvent<CrawlerComponent, KnockedDownRefreshEvent>(OnKnockdownRefresh);
SubscribeLocalEvent<CrawlerComponent, DamageChangedEvent>(OnDamaged);
SubscribeLocalEvent<KnockedDownComponent, WeightlessnessChangedEvent>(OnWeightlessnessChanged);
+ SubscribeLocalEvent<KnockedDownComponent, DidEquipHandEvent>(OnHandEquipped);
+ SubscribeLocalEvent<KnockedDownComponent, DidUnequipHandEvent>(OnHandUnequipped);
+ SubscribeLocalEvent<KnockedDownComponent, HandCountChangedEvent>(OnHandCountChanged);
SubscribeLocalEvent<GravityAffectedComponent, KnockDownAttemptEvent>(OnKnockdownAttempt);
SubscribeLocalEvent<GravityAffectedComponent, GetStandUpTimeEvent>(OnGetStandUpTime);
private void OnForceStandup(ForceStandUpEvent msg, EntitySessionEventArgs args)
{
- if (args.SenderSession.AttachedEntity is not {} user)
+ if (args.SenderSession.AttachedEntity is not { } user)
return;
ForceStandUp(user);
RemCompDeferred<KnockedDownComponent>(entity);
}
+ private void OnHandEquipped(Entity<KnockedDownComponent> entity, ref DidEquipHandEvent args)
+ {
+ if (GameTiming.ApplyingState)
+ return; // The result of the change is already networked separately in the same game state
+
+ RefreshKnockedMovement(entity);
+ }
+
+ private void OnHandUnequipped(Entity<KnockedDownComponent> entity, ref DidUnequipHandEvent args)
+ {
+ if (GameTiming.ApplyingState)
+ return; // The result of the change is already networked separately in the same game state
+
+ RefreshKnockedMovement(entity);
+ }
+
+ private void OnHandCountChanged(Entity<KnockedDownComponent> entity, ref HandCountChangedEvent args)
+ {
+ if (GameTiming.ApplyingState)
+ return; // The result of the change is already networked separately in the same game state
+
+ RefreshKnockedMovement(entity);
+ }
+
private void OnKnockdownAttempt(Entity<GravityAffectedComponent> entity, ref KnockDownAttemptEvent args)
{
// Directed, targeted moth attack.
ent.Comp.SpeedModifier = ev.SpeedModifier;
ent.Comp.FrictionModifier = ev.FrictionModifier;
+ Dirty(ent);
_movementSpeedModifier.RefreshMovementSpeedModifiers(ent);
_movementSpeedModifier.RefreshFrictionModifiers(ent);