mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-18 14:07:53 +03:00
# Description Parkour Training, Sluggish and Snail-Paced have been reworked to be more impactful in everyday space life. A new trait has been added, Bad Knees. **Parkour Training** (-5 points) - No longer modifies laying down - Climbing speed bonus reduced from 65% to 50% - 30% shorter slip stuns - 50% resistance against slows in difficult terrain - Example: Spider webs inflict a 50% slow, reduced by 50% results in a 25% slow. Notably, the reworked Parkour Training is much closer to the CDDA trait [Parkour Expert](https://cddawiki.danmakudan.com/wiki/index.php/Parkour_Expert). Difficult terrain examples: Spider webs, slime/blood puddles, kudzu, space glue **(NEW)** **Bad Knees** (3 points) - Designed to be the opposite of Parkour Training - 50% climbing speed penalty - 40% longer slip stuns - 35% increased slows in difficult terrain - Example: Spider webs inflict a 50% slow, increased by 35% results in a 67.5% slow. Inspired by the CDDA trait of the same name [Bad Knees](https://cddawiki.danmakudan.com/wiki/index.php/Bad_Knees). The stun time for banana peels and puddles is 3 seconds. With Bad Knees, the stun is increased to 4.2 seconds. The time it takes to handcuff someone is 3.5 seconds. Go figure :trollface: **Sluggish** (3 points) - No longer increases the time for laying down and climbing tables (given to Bad Knees instead) - Speed penalty increased from 15% to 16% **Snail-Paced** (5 points) - No longer increases the time for laying down and climbing tables - Speed penalty increased from 30% to 32% - No longer prevents you from slipping when running due to how slow your sprint speed is. Snail-Paced trait users must suffer. ## Media **Parkour Training**  **Bad Knees**  **Sluggish**  **Snail-Paced**  ## Changelog 🆑 Skubman - tweak: The Parkour Training trait has been reworked. It no longer makes you lie down or get up faster, but grants you 30% shorter slip stuns and 50% resistance against slows in difficult terrain. - tweak: The Sluggish and Snail-Paced traits now only reduce your movement speed with no other effects. The speed reductions have been slightly increased from 15% to 16% for Sluggish, and 30% to 32% for Snail-Paced. - add: Added a new 3-point negative trait called Bad Knees. It is the opposite of Parkour Training and it makes you climb tables slower, stunned for longer against slip stuns, and move more slowly in difficult terrain. - tweak: Snail-Paced no longer prevents you from slipping when running. (cherry picked from commit 89354922a0f6fb55111e0ce2b4b19e5f6d6ea0e2)
139 lines
4.8 KiB
C#
139 lines
4.8 KiB
C#
using Content.Shared.Movement.Components;
|
|
using Content.Shared.Whitelist;
|
|
using Robust.Shared.Physics.Components;
|
|
using Robust.Shared.Physics.Events;
|
|
using Robust.Shared.Physics.Systems;
|
|
|
|
namespace Content.Shared.Movement.Systems;
|
|
|
|
public sealed class SpeedModifierContactsSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
|
[Dependency] private readonly MovementSpeedModifierSystem _speedModifierSystem = default!;
|
|
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
|
|
|
// TODO full-game-save
|
|
// Either these need to be processed before a map is saved, or slowed/slowing entities need to update on init.
|
|
private HashSet<EntityUid> _toUpdate = new();
|
|
private HashSet<EntityUid> _toRemove = new();
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
SubscribeLocalEvent<SpeedModifierContactsComponent, StartCollideEvent>(OnEntityEnter);
|
|
SubscribeLocalEvent<SpeedModifierContactsComponent, EndCollideEvent>(OnEntityExit);
|
|
SubscribeLocalEvent<SpeedModifiedByContactComponent, RefreshMovementSpeedModifiersEvent>(MovementSpeedCheck);
|
|
SubscribeLocalEvent<SpeedModifierContactsComponent, ComponentShutdown>(OnShutdown);
|
|
|
|
UpdatesAfter.Add(typeof(SharedPhysicsSystem));
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
base.Update(frameTime);
|
|
|
|
_toRemove.Clear();
|
|
|
|
foreach (var ent in _toUpdate)
|
|
{
|
|
_speedModifierSystem.RefreshMovementSpeedModifiers(ent);
|
|
}
|
|
|
|
foreach (var ent in _toRemove)
|
|
{
|
|
RemComp<SpeedModifiedByContactComponent>(ent);
|
|
}
|
|
|
|
_toUpdate.Clear();
|
|
}
|
|
|
|
public void ChangeModifiers(EntityUid uid, float speed, SpeedModifierContactsComponent? component = null)
|
|
{
|
|
ChangeModifiers(uid, speed, speed, component);
|
|
}
|
|
|
|
public void ChangeModifiers(EntityUid uid, float walkSpeed, float sprintSpeed, SpeedModifierContactsComponent? component = null)
|
|
{
|
|
if (!Resolve(uid, ref component))
|
|
{
|
|
return;
|
|
}
|
|
component.WalkSpeedModifier = walkSpeed;
|
|
component.SprintSpeedModifier = sprintSpeed;
|
|
Dirty(uid, component);
|
|
_toUpdate.UnionWith(_physics.GetContactingEntities(uid));
|
|
}
|
|
|
|
private void OnShutdown(EntityUid uid, SpeedModifierContactsComponent component, ComponentShutdown args)
|
|
{
|
|
if (!TryComp(uid, out PhysicsComponent? phys))
|
|
return;
|
|
|
|
// Note that the entity may not be getting deleted here. E.g., glue puddles.
|
|
_toUpdate.UnionWith(_physics.GetContactingEntities(uid, phys));
|
|
}
|
|
|
|
private void MovementSpeedCheck(EntityUid uid, SpeedModifiedByContactComponent component, RefreshMovementSpeedModifiersEvent args)
|
|
{
|
|
if (!EntityManager.TryGetComponent<PhysicsComponent>(uid, out var physicsComponent))
|
|
return;
|
|
|
|
var walkSpeed = 0.0f;
|
|
var sprintSpeed = 0.0f;
|
|
|
|
bool remove = true;
|
|
var entries = 0;
|
|
foreach (var ent in _physics.GetContactingEntities(uid, physicsComponent))
|
|
{
|
|
if (!TryComp<SpeedModifierContactsComponent>(ent, out var slowContactsComponent))
|
|
continue;
|
|
|
|
if (_whitelistSystem.IsWhitelistPass(slowContactsComponent.IgnoreWhitelist, uid))
|
|
continue;
|
|
|
|
walkSpeed += slowContactsComponent.WalkSpeedModifier;
|
|
sprintSpeed += slowContactsComponent.SprintSpeedModifier;
|
|
remove = false;
|
|
entries++;
|
|
}
|
|
|
|
if (entries > 0)
|
|
{
|
|
walkSpeed /= entries;
|
|
sprintSpeed /= entries;
|
|
|
|
if (TryComp<SpeedModifiedByContactModifierComponent>(uid, out var modifier))
|
|
{
|
|
walkSpeed = Math.Max(Math.Min(modifier.MinWalkMultiplier, walkSpeed),
|
|
// Similar to the formula for movement slow resist in Deadlock
|
|
1 - (1 - walkSpeed) * modifier.WalkModifierEffectiveness);
|
|
|
|
sprintSpeed = Math.Max(Math.Min(modifier.MinSprintMultiplier, sprintSpeed),
|
|
1 - (1 - sprintSpeed) * modifier.SprintModifierEffectiveness);
|
|
}
|
|
|
|
args.ModifySpeed(walkSpeed, sprintSpeed);
|
|
}
|
|
|
|
// no longer colliding with anything
|
|
if (remove)
|
|
_toRemove.Add(uid);
|
|
}
|
|
|
|
private void OnEntityExit(EntityUid uid, SpeedModifierContactsComponent component, ref EndCollideEvent args)
|
|
{
|
|
var otherUid = args.OtherEntity;
|
|
_toUpdate.Add(otherUid);
|
|
}
|
|
|
|
private void OnEntityEnter(EntityUid uid, SpeedModifierContactsComponent component, ref StartCollideEvent args)
|
|
{
|
|
var otherUid = args.OtherEntity;
|
|
if (!HasComp<MovementSpeedModifierComponent>(otherUid))
|
|
return;
|
|
|
|
EnsureComp<SpeedModifiedByContactComponent>(otherUid);
|
|
_toUpdate.Add(otherUid);
|
|
}
|
|
}
|