Puddle Code Slipping Cleanup (#35845)

* Init Commit

* windows yelling at me to update commit

* working commit, need prediciton and more dehardcoding

* Project 0 warnings

* Working Commit (Near Final)

* ryder got confused commit

* I love Merge Conflicts :)

* Working commit, no prediction

* Forgot the yaml changes

* Comments and typos

* Apparently while the reduced launch mult of lube was initialized it was never used so I revered back to default

* Fixed an incorrect divisor

* bit of cleanup

* Prediciton fixed, and puddles now affect all entities

* FORGOT TO RENAME A VERY IMPORTANT VARIABLE OOPS

* Really big I forgor moment

* Even bigger I forgor moment

* four more merge conflicts to fix four more oopsies

* fixed actual divide by zero moment and also im very dumb

* Even bigger I forgor moment

* four more merge conflicts to fix four more oopsies

* fixed actual divide by zero moment and also im very dumb

* Fix all test fails

* code cleanup

* Webedit whitespace

* Code cleaup

* whitespace webedit

* whitespace webedit

* whitespace webedit

* whitespace removal

* Comments and cleanup

* Re-Added 20 warnings as per Ork's request

* Cleanups

* Spacing fix

* bugfixes and cleanup

* Small bugfix

* Actually dirty the slipComp for real

* Added Friction field to Reagent Prototype per design discussion

* Sliding system is kill
This commit is contained in:
Princess Cheeseballs
2025-04-20 14:27:12 -07:00
committed by GitHub
parent c2857c5247
commit 251cfbd8be
27 changed files with 177 additions and 222 deletions

View File

@@ -877,9 +877,9 @@ public sealed partial class AdminVerbSystem
var hadSlipComponent = EnsureComp(args.Target, out SlipperyComponent slipComponent); var hadSlipComponent = EnsureComp(args.Target, out SlipperyComponent slipComponent);
if (!hadSlipComponent) if (!hadSlipComponent)
{ {
slipComponent.SuperSlippery = true; slipComponent.SlipData.SuperSlippery = true;
slipComponent.ParalyzeTime = 5; slipComponent.SlipData.ParalyzeTime = TimeSpan.FromSeconds(5);
slipComponent.LaunchForwardsMultiplier = 20; slipComponent.SlipData.LaunchForwardsMultiplier = 20;
} }
_slipperySystem.TrySlip(args.Target, slipComponent, args.Target, requiresContact: false); _slipperySystem.TrySlip(args.Target, slipComponent, args.Target, requiresContact: false);

View File

@@ -1,30 +0,0 @@
using Content.Server.Fluids.EntitySystems;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reaction;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
using JetBrains.Annotations;
using Robust.Shared.Map;
namespace Content.Server.Chemistry.TileReactions
{
[UsedImplicitly]
[DataDefinition]
public sealed partial class SpillIfPuddlePresentTileReaction : ITileReaction
{
public FixedPoint2 TileReact(TileRef tile,
ReagentPrototype reagent,
FixedPoint2 reactVolume,
IEntityManager entityManager,
List<ReagentData>? data)
{
var spillSystem = entityManager.System<PuddleSystem>();
if (reactVolume < 5 || !spillSystem.TryGetPuddle(tile, out _))
return FixedPoint2.Zero;
return spillSystem.TrySpillAt(tile, new Solution(reagent.ID, reactVolume, data), out _, sound: false, tileReact: false)
? reactVolume
: FixedPoint2.Zero;
}
}
}

View File

@@ -1,60 +0,0 @@
using Content.Server.Fluids.EntitySystems;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reaction;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
using Content.Shared.Slippery;
using Content.Shared.StepTrigger.Components;
using Content.Shared.StepTrigger.Systems;
using JetBrains.Annotations;
using Robust.Shared.Map;
namespace Content.Server.Chemistry.TileReactions
{
[UsedImplicitly]
[DataDefinition]
public sealed partial class SpillTileReaction : ITileReaction
{
[DataField("launchForwardsMultiplier")] public float LaunchForwardsMultiplier = 1;
[DataField("requiredSlipSpeed")] public float RequiredSlipSpeed = 6;
[DataField("paralyzeTime")] public float ParalyzeTime = 1;
/// <summary>
/// <see cref="SlipperyComponent.SuperSlippery"/>
/// </summary>
[DataField("superSlippery")] public bool SuperSlippery;
public FixedPoint2 TileReact(TileRef tile,
ReagentPrototype reagent,
FixedPoint2 reactVolume,
IEntityManager entityManager,
List<ReagentData>? data)
{
if (reactVolume < 5)
return FixedPoint2.Zero;
if (entityManager.EntitySysManager.GetEntitySystem<PuddleSystem>()
.TrySpillAt(tile, new Solution(reagent.ID, reactVolume, data), out var puddleUid, false, false))
{
var slippery = entityManager.EnsureComponent<SlipperyComponent>(puddleUid);
slippery.LaunchForwardsMultiplier = LaunchForwardsMultiplier;
slippery.ParalyzeTime = ParalyzeTime;
slippery.SuperSlippery = SuperSlippery;
entityManager.Dirty(puddleUid, slippery);
var step = entityManager.EnsureComponent<StepTriggerComponent>(puddleUid);
entityManager.EntitySysManager.GetEntitySystem<StepTriggerSystem>().SetRequiredTriggerSpeed(puddleUid, RequiredSlipSpeed, step);
var slow = entityManager.EnsureComponent<SpeedModifierContactsComponent>(puddleUid);
var speedModifier = 1 - reagent.Viscosity;
entityManager.EntitySysManager.GetEntitySystem<SpeedModifierContactsSystem>().ChangeModifiers(puddleUid, speedModifier, slow);
return reactVolume;
}
return FixedPoint2.Zero;
}
}
}

View File

@@ -71,8 +71,6 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
private static string[] _standoutReagents = [Blood, Slime, CopperBlood]; private static string[] _standoutReagents = [Blood, Slime, CopperBlood];
public static readonly float PuddleVolume = 1000;
// Using local deletion queue instead of the standard queue so that we can easily "undelete" if a puddle // Using local deletion queue instead of the standard queue so that we can easily "undelete" if a puddle
// loses & then gains reagents in a single tick. // loses & then gains reagents in a single tick.
private HashSet<EntityUid> _deletionQueue = []; private HashSet<EntityUid> _deletionQueue = [];
@@ -94,7 +92,6 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
// Shouldn't need re-anchoring. // Shouldn't need re-anchoring.
SubscribeLocalEvent<PuddleComponent, AnchorStateChangedEvent>(OnAnchorChanged); SubscribeLocalEvent<PuddleComponent, AnchorStateChangedEvent>(OnAnchorChanged);
SubscribeLocalEvent<PuddleComponent, SolutionContainerChangedEvent>(OnSolutionUpdate); SubscribeLocalEvent<PuddleComponent, SolutionContainerChangedEvent>(OnSolutionUpdate);
SubscribeLocalEvent<PuddleComponent, ComponentInit>(OnPuddleInit);
SubscribeLocalEvent<PuddleComponent, SpreadNeighborsEvent>(OnPuddleSpread); SubscribeLocalEvent<PuddleComponent, SpreadNeighborsEvent>(OnPuddleSpread);
SubscribeLocalEvent<PuddleComponent, SlipEvent>(OnPuddleSlip); SubscribeLocalEvent<PuddleComponent, SlipEvent>(OnPuddleSlip);
@@ -327,11 +324,6 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
TickEvaporation(); TickEvaporation();
} }
private void OnPuddleInit(Entity<PuddleComponent> entity, ref ComponentInit args)
{
_solutionContainerSystem.EnsureSolution(entity.Owner, entity.Comp.SolutionName, out _, FixedPoint2.New(PuddleVolume));
}
private void OnSolutionUpdate(Entity<PuddleComponent> entity, ref SolutionContainerChangedEvent args) private void OnSolutionUpdate(Entity<PuddleComponent> entity, ref SolutionContainerChangedEvent args)
{ {
if (args.SolutionId != entity.Comp.SolutionName) if (args.SolutionId != entity.Comp.SolutionName)
@@ -344,7 +336,7 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
} }
_deletionQueue.Remove(entity); _deletionQueue.Remove(entity);
UpdateSlip(entity, entity.Comp, args.Solution); UpdateSlip((entity, entity.Comp), args.Solution);
UpdateSlow(entity, args.Solution); UpdateSlow(entity, args.Solution);
UpdateEvaporation(entity, args.Solution); UpdateEvaporation(entity, args.Solution);
UpdateAppearance(entity, entity.Comp); UpdateAppearance(entity, entity.Comp);
@@ -389,62 +381,89 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
_appearance.SetData(uid, PuddleVisuals.SolutionColor, color, appearance); _appearance.SetData(uid, PuddleVisuals.SolutionColor, color, appearance);
} }
private void UpdateSlip(EntityUid entityUid, PuddleComponent component, Solution solution) private void UpdateSlip(Entity<PuddleComponent> entity, Solution solution)
{ {
var isSlippery = false; if (!TryComp<StepTriggerComponent>(entity, out var comp))
var isSuperSlippery = false; return;
// The base sprite is currently at 0.3 so we require at least 2nd tier to be slippery or else it's too hard to see.
var amountRequired = FixedPoint2.New(component.OverflowVolume.Float() * LowThreshold);
var slipperyAmount = FixedPoint2.Zero;
// Utilize the defaults from their relevant systems... this sucks, and is a bandaid // This is the base amount of reagent needed before a puddle can be considered slippery. Is defined based on
var launchForwardsMultiplier = SlipperyComponent.DefaultLaunchForwardsMultiplier; // the sprite threshold for a puddle larger than 5 pixels.
var paralyzeTime = SlipperyComponent.DefaultParalyzeTime; var smallPuddleThreshold = FixedPoint2.New(entity.Comp.OverflowVolume.Float() * LowThreshold);
var requiredSlipSpeed = StepTriggerComponent.DefaultRequiredTriggeredSpeed;
// Stores how many units of slippery reagents a puddle has
var slipperyUnits = FixedPoint2.Zero;
// Stores how many units of super slippery reagents a puddle has
var superSlipperyUnits = FixedPoint2.Zero;
// These three values will be averaged later and all start at zero so the calculations work
// A cumulative weighted amount of minimum speed to slip values
var puddleFriction = FixedPoint2.Zero;
// A cumulative weighted amount of minimum speed to slip values
var slipStepTrigger = FixedPoint2.Zero;
// A cumulative weighted amount of launch multipliers from slippery reagents
var launchMult = FixedPoint2.Zero;
// A cumulative weighted amount of stun times from slippery reagents
var stunTimer = TimeSpan.Zero;
// Check if the puddle is big enough to slip in to avoid doing unnecessary logic
if (solution.Volume <= smallPuddleThreshold)
{
_stepTrigger.SetActive(entity, false, comp);
_tile.SetModifier(entity, TileFrictionController.DefaultFriction);
return;
}
if (!TryComp<SlipperyComponent>(entity, out var slipComp))
return;
foreach (var (reagent, quantity) in solution.Contents) foreach (var (reagent, quantity) in solution.Contents)
{ {
var reagentProto = _prototypeManager.Index<ReagentPrototype>(reagent.Prototype); var reagentProto = _prototypeManager.Index<ReagentPrototype>(reagent.Prototype);
if (!reagentProto.Slippery) // Calculate the minimum speed needed to slip in the puddle. Average the overall slip thresholds for all reagents
var deltaSlipTrigger = reagentProto.SlipData?.RequiredSlipSpeed ?? entity.Comp.DefaultSlippery;
slipStepTrigger += quantity * deltaSlipTrigger;
// Aggregate Friction based on quantity
puddleFriction += reagentProto.Friction * quantity;
if (reagentProto.SlipData == null)
continue; continue;
slipperyAmount += quantity;
if (slipperyAmount <= amountRequired) slipperyUnits += quantity;
continue; // Aggregate launch speed based on quantity
isSlippery = true; launchMult += reagentProto.SlipData.LaunchForwardsMultiplier * quantity;
// Aggregate stun times based on quantity
stunTimer += reagentProto.SlipData.ParalyzeTime * (float)quantity;
foreach (var tileReaction in reagentProto.TileReactions) if (reagentProto.SlipData.SuperSlippery)
superSlipperyUnits += quantity;
}
// Turn on the step trigger if it's slippery
_stepTrigger.SetActive(entity, slipperyUnits > smallPuddleThreshold, comp);
// This is based of the total volume and not just the slippery volume because there is a default
// slippery for all reagents even if they aren't technically slippery.
slipComp.SlipData.RequiredSlipSpeed = (float)(slipStepTrigger / solution.Volume);
_stepTrigger.SetRequiredTriggerSpeed(entity, slipComp.SlipData.RequiredSlipSpeed);
// Divide these both by only total amount of slippery reagents.
// A puddle with 10 units of lube vs a puddle with 10 of lube and 20 catchup should stun and launch forward the same amount.
if (slipperyUnits > 0)
{ {
if (tileReaction is not SpillTileReaction spillTileReaction) slipComp.SlipData.LaunchForwardsMultiplier = (float)(launchMult/slipperyUnits);
continue; slipComp.SlipData.ParalyzeTime = (stunTimer/(float)slipperyUnits);
isSuperSlippery = spillTileReaction.SuperSlippery;
launchForwardsMultiplier = launchForwardsMultiplier < spillTileReaction.LaunchForwardsMultiplier ? spillTileReaction.LaunchForwardsMultiplier : launchForwardsMultiplier;
requiredSlipSpeed = requiredSlipSpeed > spillTileReaction.RequiredSlipSpeed ? spillTileReaction.RequiredSlipSpeed : requiredSlipSpeed;
paralyzeTime = paralyzeTime < spillTileReaction.ParalyzeTime ? spillTileReaction.ParalyzeTime : paralyzeTime;
}
} }
if (isSlippery) // Only make it super slippery if there is enough super slippery units for its own puddle
{ slipComp.SlipData.SuperSlippery = superSlipperyUnits >= smallPuddleThreshold;
var comp = EnsureComp<StepTriggerComponent>(entityUid);
_stepTrigger.SetActive(entityUid, true, comp);
var friction = EnsureComp<TileFrictionModifierComponent>(entityUid);
_tile.SetModifier(entityUid, TileFrictionController.DefaultFriction * 0.5f, friction);
if (!TryComp<SlipperyComponent>(entityUid, out var slipperyComponent)) // Lower tile friction based on how slippery it is, lets items slide across a puddle of lube
return; slipComp.SlipData.SlipFriction = (float)(puddleFriction/solution.Volume);
slipperyComponent.SuperSlippery = isSuperSlippery; _tile.SetModifier(entity, TileFrictionController.DefaultFriction * slipComp.SlipData.SlipFriction);
_stepTrigger.SetRequiredTriggerSpeed(entityUid, requiredSlipSpeed);
slipperyComponent.LaunchForwardsMultiplier = launchForwardsMultiplier;
slipperyComponent.ParalyzeTime = paralyzeTime;
} Dirty(entity, slipComp);
else if (TryComp<StepTriggerComponent>(entityUid, out var comp))
{
_stepTrigger.SetActive(entityUid, false, comp);
RemCompDeferred<TileFrictionModifierComponent>(entityUid);
}
} }
private void UpdateSlow(EntityUid uid, Solution solution) private void UpdateSlow(EntityUid uid, Solution solution)

View File

@@ -9,6 +9,8 @@ using Content.Shared.Chemistry.Reaction;
using Content.Shared.EntityEffects; using Content.Shared.EntityEffects;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Nutrition; using Content.Shared.Nutrition;
using Content.Shared.Prototypes;
using Content.Shared.Slippery;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -98,11 +100,12 @@ namespace Content.Shared.Chemistry.Reagent
[DataField] [DataField]
public bool MetamorphicChangeColor { get; private set; } = true; public bool MetamorphicChangeColor { get; private set; } = true;
/// <summary> /// <summary>
/// If this reagent is part of a puddle is it slippery. /// If not null, makes something slippery. Also defines slippery interactions like stun time and launch mult.
/// </summary> /// </summary>
[DataField] [DataField]
public bool Slippery; public SlipperyEffectEntry? SlipData;
/// <summary> /// <summary>
/// The speed at which the reagent evaporates over time. /// The speed at which the reagent evaporates over time.
@@ -130,6 +133,13 @@ namespace Content.Shared.Chemistry.Reagent
[DataField] [DataField]
public float Viscosity; public float Viscosity;
/// <summary>
/// Linear Friction Multiplier for a reagent
/// 0 - frictionless, 1 - no effect on friction
/// </summary>
[DataField]
public float Friction = 1.0f;
/// <summary> /// <summary>
/// Should this reagent work on the dead? /// Should this reagent work on the dead?
/// </summary> /// </summary>

View File

@@ -19,6 +19,12 @@ namespace Content.Shared.Fluids.Components
[DataField("solution")] public string SolutionName = "puddle"; [DataField("solution")] public string SolutionName = "puddle";
/// <summary>
/// Default minimum speed someone must be moving to slip for all reagents.
/// </summary>
[DataField]
public float DefaultSlippery = 5.5f;
[ViewVariables] [ViewVariables]
public Entity<SolutionComponent>? Solution; public Entity<SolutionComponent>? Solution;
} }

View File

@@ -11,20 +11,11 @@ public sealed class SlidingSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<SlidingComponent, TileFrictionEvent>(OnSlideAttempt);
SubscribeLocalEvent<SlidingComponent, StoodEvent>(OnStand); SubscribeLocalEvent<SlidingComponent, StoodEvent>(OnStand);
SubscribeLocalEvent<SlidingComponent, StartCollideEvent>(OnStartCollide); SubscribeLocalEvent<SlidingComponent, StartCollideEvent>(OnStartCollide);
SubscribeLocalEvent<SlidingComponent, EndCollideEvent>(OnEndCollide); SubscribeLocalEvent<SlidingComponent, EndCollideEvent>(OnEndCollide);
} }
/// <summary>
/// Modify the friction by the frictionModifier stored on the component.
/// </summary>
private void OnSlideAttempt(EntityUid uid, SlidingComponent component, ref TileFrictionEvent args)
{
args.Modifier = component.FrictionModifier;
}
/// <summary> /// <summary>
/// Remove the component when the entity stands up again. /// Remove the component when the entity stands up again.
/// </summary> /// </summary>
@@ -38,11 +29,10 @@ public sealed class SlidingSystem : EntitySystem
/// </summary> /// </summary>
private void OnStartCollide(EntityUid uid, SlidingComponent component, ref StartCollideEvent args) private void OnStartCollide(EntityUid uid, SlidingComponent component, ref StartCollideEvent args)
{ {
if (!TryComp<SlipperyComponent>(args.OtherEntity, out var slippery) || !slippery.SuperSlippery) if (!TryComp<SlipperyComponent>(args.OtherEntity, out var slippery) || !slippery.SlipData.SuperSlippery)
return; return;
component.CollidingEntities.Add(args.OtherEntity); component.CollidingEntities.Add(args.OtherEntity);
component.FrictionModifier = 0;
Dirty(uid, component); Dirty(uid, component);
} }
@@ -55,7 +45,7 @@ public sealed class SlidingSystem : EntitySystem
return; return;
if (component.CollidingEntities.Count == 0) if (component.CollidingEntities.Count == 0)
component.FrictionModifier = SharedStunSystem.KnockDownModifier; RemComp<SlidingComponent>(uid);
Dirty(uid, component); Dirty(uid, component);
} }

View File

@@ -1,6 +1,7 @@
using Content.Shared.StepTrigger.Components; using Content.Shared.StepTrigger.Components;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Slippery namespace Content.Shared.Slippery
{ {
@@ -13,8 +14,6 @@ namespace Content.Shared.Slippery
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class SlipperyComponent : Component public sealed partial class SlipperyComponent : Component
{ {
public const float DefaultParalyzeTime = 1.5f;
public const float DefaultLaunchForwardsMultiplier = 1.5f;
/// <summary> /// <summary>
/// Path to the sound to be played when a mob slips. /// Path to the sound to be played when a mob slips.
/// </summary> /// </summary>
@@ -23,25 +22,47 @@ namespace Content.Shared.Slippery
public SoundSpecifier SlipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg"); public SoundSpecifier SlipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg");
/// <summary> /// <summary>
/// How many seconds the mob will be paralyzed for. /// Loads the data needed to determine how slippery something is.
/// </summary> /// </summary>
[DataField, AutoNetworkedField] [DataField, AutoNetworkedField]
[Access(Other = AccessPermissions.ReadWrite)] public SlipperyEffectEntry SlipData = new();
public float ParalyzeTime = DefaultParalyzeTime; }
/// <summary>
/// Stores the data for slipperiness that way reagents and this component can use it.
/// </summary>
[DataDefinition, Serializable, NetSerializable]
public sealed partial class SlipperyEffectEntry
{
/// <summary>
/// How many seconds the mob will be paralyzed for.
/// </summary>
[DataField]
public TimeSpan ParalyzeTime = TimeSpan.FromSeconds(1.5);
/// <summary> /// <summary>
/// The entity's speed will be multiplied by this to slip it forwards. /// The entity's speed will be multiplied by this to slip it forwards.
/// </summary> /// </summary>
[DataField, AutoNetworkedField] [DataField]
[Access(Other = AccessPermissions.ReadWrite)] public float LaunchForwardsMultiplier = 1.5f;
public float LaunchForwardsMultiplier = DefaultLaunchForwardsMultiplier;
/// <summary>
/// Minimum speed entity must be moving to slip.
/// </summary>
[DataField]
public float RequiredSlipSpeed = 3.5f;
/// <summary> /// <summary>
/// If this is true, any slipping entity loses its friction until /// If this is true, any slipping entity loses its friction until
/// it's not colliding with any SuperSlippery entities anymore. /// it's not colliding with any SuperSlippery entities anymore.
/// They also will fail any attempts to stand up unless they have no-slips.
/// </summary> /// </summary>
[DataField, AutoNetworkedField] [DataField]
[Access(Other = AccessPermissions.ReadWrite)]
public bool SuperSlippery; public bool SuperSlippery;
/// <summary>
/// This is used to store the friction modifier that is used on a sliding entity.
/// </summary>
[DataField]
public float SlipFriction;
} }
} }

View File

@@ -39,7 +39,6 @@ public sealed class SlipperySystem : EntitySystem
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt); SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
SubscribeLocalEvent<SlowedOverSlipperyComponent, SlipAttemptEvent>(OnSlowedOverSlipAttempt); SubscribeLocalEvent<SlowedOverSlipperyComponent, SlipAttemptEvent>(OnSlowedOverSlipAttempt);
SubscribeLocalEvent<ThrownItemComponent, SlipCausingAttemptEvent>(OnThrownSlipAttempt); SubscribeLocalEvent<ThrownItemComponent, SlipCausingAttemptEvent>(OnThrownSlipAttempt);
// as long as slip-resistant mice are never added, this should be fine (otherwise a mouse-hat will transfer it's power to the wearer).
SubscribeLocalEvent<NoSlipComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnNoSlipAttempt(e, c, ev.Args)); SubscribeLocalEvent<NoSlipComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnNoSlipAttempt(e, c, ev.Args));
SubscribeLocalEvent<SlowedOverSlipperyComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnSlowedOverSlipAttempt(e, c, ev.Args)); SubscribeLocalEvent<SlowedOverSlipperyComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnSlowedOverSlipAttempt(e, c, ev.Args));
SubscribeLocalEvent<SlowedOverSlipperyComponent, InventoryRelayedEvent<GetSlowedOverSlipperyModifierEvent>>(OnGetSlowedOverSlipperyModifier); SubscribeLocalEvent<SlowedOverSlipperyComponent, InventoryRelayedEvent<GetSlowedOverSlipperyModifierEvent>>(OnGetSlowedOverSlipperyModifier);
@@ -93,7 +92,7 @@ public sealed class SlipperySystem : EntitySystem
public void TrySlip(EntityUid uid, SlipperyComponent component, EntityUid other, bool requiresContact = true) public void TrySlip(EntityUid uid, SlipperyComponent component, EntityUid other, bool requiresContact = true)
{ {
if (HasComp<KnockedDownComponent>(other) && !component.SuperSlippery) if (HasComp<KnockedDownComponent>(other) && !component.SlipData.SuperSlippery)
return; return;
var attemptEv = new SlipAttemptEvent(); var attemptEv = new SlipAttemptEvent();
@@ -114,9 +113,9 @@ public sealed class SlipperySystem : EntitySystem
if (TryComp(other, out PhysicsComponent? physics) && !HasComp<SlidingComponent>(other)) if (TryComp(other, out PhysicsComponent? physics) && !HasComp<SlidingComponent>(other))
{ {
_physics.SetLinearVelocity(other, physics.LinearVelocity * component.LaunchForwardsMultiplier, body: physics); _physics.SetLinearVelocity(other, physics.LinearVelocity * component.SlipData.LaunchForwardsMultiplier, body: physics);
if (component.SuperSlippery && requiresContact) if (component.SlipData.SuperSlippery && requiresContact)
{ {
var sliding = EnsureComp<SlidingComponent>(other); var sliding = EnsureComp<SlidingComponent>(other);
sliding.CollidingEntities.Add(uid); sliding.CollidingEntities.Add(uid);
@@ -126,7 +125,7 @@ public sealed class SlipperySystem : EntitySystem
var playSound = !_statusEffects.HasStatusEffect(other, "KnockedDown"); var playSound = !_statusEffects.HasStatusEffect(other, "KnockedDown");
_stun.TryParalyze(other, TimeSpan.FromSeconds(component.ParalyzeTime), true); _stun.TryParalyze(other, component.SlipData.ParalyzeTime, true);
// Preventing from playing the slip sound when you are already knocked down. // Preventing from playing the slip sound when you are already knocked down.
if (playSound) if (playSound)

View File

@@ -8,7 +8,6 @@ namespace Content.Shared.StepTrigger.Components;
[Access(typeof(StepTriggerSystem))] [Access(typeof(StepTriggerSystem))]
public sealed partial class StepTriggerComponent : Component public sealed partial class StepTriggerComponent : Component
{ {
public const float DefaultRequiredTriggeredSpeed = 3.5f;
/// <summary> /// <summary>
/// List of entities that are currently colliding with the entity. /// List of entities that are currently colliding with the entity.
/// </summary> /// </summary>
@@ -38,7 +37,7 @@ public sealed partial class StepTriggerComponent : Component
/// Entities will only be triggered if their speed exceeds this limit. /// Entities will only be triggered if their speed exceeds this limit.
/// </summary> /// </summary>
[DataField, AutoNetworkedField] [DataField, AutoNetworkedField]
public float RequiredTriggeredSpeed = DefaultRequiredTriggeredSpeed; public float RequiredTriggeredSpeed = 3.5f;
/// <summary> /// <summary>
/// If any entities occupy the blacklist on the same tile then steptrigger won't work. /// If any entities occupy the blacklist on the same tile then steptrigger won't work.

View File

@@ -113,6 +113,8 @@
components: components:
- type: Clickable - type: Clickable
- type: Slippery - type: Slippery
- type: TileFrictionModifier
modifier: 0.3
- type: Transform - type: Transform
noRot: true noRot: true
anchored: true anchored: true

View File

@@ -179,6 +179,7 @@
rootTask: rootTask:
task: HonkbotCompound task: HonkbotCompound
- type: Slippery - type: Slippery
slipData:
launchForwardsMultiplier: 2 launchForwardsMultiplier: 2
- type: Speech - type: Speech
speechVerb: Cluwne speechVerb: Cluwne

View File

@@ -125,6 +125,7 @@
- type: Slippery - type: Slippery
slipSound: slipSound:
path: /Audio/Effects/glass_step.ogg path: /Audio/Effects/glass_step.ogg
slipData:
launchForwardsMultiplier: 0 launchForwardsMultiplier: 0
- type: DamageUserOnTrigger - type: DamageUserOnTrigger
damage: damage:

View File

@@ -16,6 +16,7 @@
- ReagentId: Nutriment - ReagentId: Nutriment
Quantity: 5 Quantity: 5
- type: Slippery - type: Slippery
slipData:
paralyzeTime: 3 paralyzeTime: 3
launchForwardsMultiplier: 3 launchForwardsMultiplier: 3
- type: StepTrigger - type: StepTrigger

View File

@@ -1742,6 +1742,7 @@
- type: UseDelay - type: UseDelay
delay: 0.8 delay: 0.8
- type: Slippery - type: Slippery
slipData:
paralyzeTime: 0 paralyzeTime: 0
slipSound: slipSound:
collection: Parp collection: Parp

View File

@@ -69,6 +69,7 @@
- type: Slippery - type: Slippery
slipSound: slipSound:
path: /Audio/Effects/glass_step.ogg path: /Audio/Effects/glass_step.ogg
slipData:
launchForwardsMultiplier: 0 launchForwardsMultiplier: 0
- type: TriggerOnStepTrigger - type: TriggerOnStepTrigger
- type: DamageUserOnTrigger - type: DamageUserOnTrigger

View File

@@ -127,6 +127,7 @@
- type: SolutionContainerVisuals - type: SolutionContainerVisuals
fillBaseName: syndie- fillBaseName: syndie-
- type: Slippery - type: Slippery
slipData:
paralyzeTime: 3 paralyzeTime: 3
launchForwardsMultiplier: 3 launchForwardsMultiplier: 3
- type: Item - type: Item
@@ -152,6 +153,7 @@
layers: layers:
- state: syndie-soaplet - state: syndie-soaplet
- type: Slippery - type: Slippery
slipData:
paralyzeTime: 1.5 # these things are tiny paralyzeTime: 1.5 # these things are tiny
launchForwardsMultiplier: 1.5 launchForwardsMultiplier: 1.5
- type: StepTrigger - type: StepTrigger
@@ -218,6 +220,7 @@
- type: SolutionContainerVisuals - type: SolutionContainerVisuals
fillBaseName: omega- fillBaseName: omega-
- type: Slippery - type: Slippery
slipData:
paralyzeTime: 5.0 paralyzeTime: 5.0
launchForwardsMultiplier: 3.0 launchForwardsMultiplier: 3.0
- type: Item - type: Item

View File

@@ -133,7 +133,6 @@
name: reagent-name-ethanol name: reagent-name-ethanol
parent: BaseAlcohol parent: BaseAlcohol
desc: reagent-desc-ethanol desc: reagent-desc-ethanol
slippery: true
physicalDesc: reagent-physical-desc-strong-smelling physicalDesc: reagent-physical-desc-strong-smelling
flavor: alcohol flavor: alcohol
color: "#b05b3c" color: "#b05b3c"

View File

@@ -2,7 +2,8 @@
id: BaseDrink id: BaseDrink
group: Drinks group: Drinks
abstract: true abstract: true
slippery: true slipData:
requiredSlipSpeed: 3.5
metabolisms: metabolisms:
Drink: Drink:
effects: effects:
@@ -18,7 +19,6 @@
amount: 1 amount: 1
tileReactions: tileReactions:
- !type:ExtinguishTileReaction { } - !type:ExtinguishTileReaction { }
- !type:SpillIfPuddlePresentTileReaction { }
- type: reagent - type: reagent
id: BaseSoda id: BaseSoda
@@ -46,6 +46,9 @@
id: BaseAlcohol id: BaseAlcohol
group: Drinks group: Drinks
abstract: true abstract: true
slipData:
requiredSlipSpeed: 3.5
friction: 0.4
metabolisms: metabolisms:
Drink: Drink:
effects: effects:

View File

@@ -435,7 +435,6 @@
name: reagent-name-water name: reagent-name-water
parent: BaseDrink parent: BaseDrink
desc: reagent-desc-water desc: reagent-desc-water
slippery: true
evaporationSpeed: 0.3 evaporationSpeed: 0.3
absorbent: true absorbent: true
physicalDesc: reagent-physical-desc-translucent physicalDesc: reagent-physical-desc-translucent
@@ -444,6 +443,7 @@
recognizable: true recognizable: true
boilingPoint: 100.0 boilingPoint: 100.0
meltingPoint: 0.0 meltingPoint: 0.0
friction: 0.4
metabolisms: metabolisms:
Drink: Drink:
effects: effects:
@@ -454,12 +454,15 @@
id: Ice id: Ice
name: reagent-name-ice name: reagent-name-ice
desc: reagent-desc-ice desc: reagent-desc-ice
slipData:
requiredSlipSpeed: 3.5
physicalDesc: reagent-physical-desc-frosty physicalDesc: reagent-physical-desc-frosty
flavor: cold flavor: cold
color: "#bed8e6" color: "#bed8e6"
recognizable: true recognizable: true
meltingPoint: 0.0 meltingPoint: 0.0
boilingPoint: 100.0 boilingPoint: 100.0
friction: 0.05 #Copied from Ice Crust
plantMetabolism: plantMetabolism:
- !type:PlantAdjustWater - !type:PlantAdjustWater
amount: 1 amount: 1

View File

@@ -174,10 +174,7 @@
color: "#fb7125" color: "#fb7125"
recognizable: true recognizable: true
physicalDesc: reagent-physical-desc-sticky physicalDesc: reagent-physical-desc-sticky
slippery: false
viscosity: 0.55 #Start using syrup to attach your remote recievers to your microwaves! viscosity: 0.55 #Start using syrup to attach your remote recievers to your microwaves!
tileReactions:
- !type:SpillTileReaction
metabolisms: metabolisms:
Food: Food:
# 12 diona blood for 1 unit of syrup, this stuff better be worthwhile. # 12 diona blood for 1 unit of syrup, this stuff better be worthwhile.

View File

@@ -13,7 +13,6 @@
metamorphicChangeColor: false metamorphicChangeColor: false
recognizable: true recognizable: true
physicalDesc: reagent-physical-desc-ferrous physicalDesc: reagent-physical-desc-ferrous
slippery: false
metabolisms: metabolisms:
Drink: Drink:
effects: effects:
@@ -56,7 +55,6 @@
color: "#808A51" color: "#808A51"
recognizable: true recognizable: true
physicalDesc: reagent-physical-desc-slimy physicalDesc: reagent-physical-desc-slimy
slippery: false
- type: reagent - type: reagent
id: Slime id: Slime
@@ -67,10 +65,7 @@
color: "#2cf274" color: "#2cf274"
recognizable: true recognizable: true
physicalDesc: reagent-physical-desc-viscous physicalDesc: reagent-physical-desc-viscous
slippery: false
viscosity: 0.25 viscosity: 0.25
tileReactions:
- !type:SpillTileReaction
metabolisms: metabolisms:
Food: Food:
# Delicious! # Delicious!
@@ -91,10 +86,7 @@
color: "#cd7314" color: "#cd7314"
recognizable: true recognizable: true
physicalDesc: reagent-physical-desc-sticky physicalDesc: reagent-physical-desc-sticky
slippery: false
viscosity: 0.10 viscosity: 0.10
tileReactions:
- !type:SpillTileReaction
metabolisms: metabolisms:
Food: Food:
# Sweet! # Sweet!
@@ -118,7 +110,6 @@
color: "#162581" color: "#162581"
recognizable: true recognizable: true
physicalDesc: reagent-physical-desc-metallic physicalDesc: reagent-physical-desc-metallic
slippery: false
- type: reagent - type: reagent
parent: Blood parent: Blood
@@ -130,7 +121,6 @@
color: "#7a8bf2" color: "#7a8bf2"
recognizable: true recognizable: true
physicalDesc: reagent-physical-desc-pungent physicalDesc: reagent-physical-desc-pungent
slippery: false
- type: reagent - type: reagent
id: ZombieBlood id: ZombieBlood
@@ -140,7 +130,6 @@
physicalDesc: reagent-physical-desc-necrotic physicalDesc: reagent-physical-desc-necrotic
flavor: bitter flavor: bitter
color: "#2b0700" color: "#2b0700"
slippery: false
metabolisms: metabolisms:
Drink: Drink:
# Disgusting! # Disgusting!
@@ -202,7 +191,6 @@
flavor: terrible flavor: terrible
color: "#d8d8b0" color: "#d8d8b0"
physicalDesc: reagent-physical-desc-exotic-smelling physicalDesc: reagent-physical-desc-exotic-smelling
slippery: false
footstepSound: footstepSound:
collection: FootstepBlood collection: FootstepBlood
params: params:
@@ -216,7 +204,9 @@
flavor: terrible flavor: terrible
color: "#87ab08" color: "#87ab08"
physicalDesc: reagent-physical-desc-pungent physicalDesc: reagent-physical-desc-pungent
slippery: true slipData:
requiredSlipSpeed: 4.0 #It's not as slippery as water
friction: 0.4
metabolisms: metabolisms:
Drink: Drink:
effects: effects:
@@ -238,7 +228,6 @@
physicalDesc: reagent-physical-desc-neural physicalDesc: reagent-physical-desc-neural
flavor: mindful flavor: mindful
color: "#C584B8" color: "#C584B8"
slippery: false
metabolisms: metabolisms:
Drink: Drink:
effects: effects:

View File

@@ -165,7 +165,6 @@
flavor: bitter flavor: bitter
color: "#E6E6DA" color: "#E6E6DA"
physicalDesc: reagent-physical-desc-crystalline physicalDesc: reagent-physical-desc-crystalline
slippery: false
- type: reagent - type: reagent
id: Rororium id: Rororium

View File

@@ -68,17 +68,16 @@
id: SpaceLube id: SpaceLube
name: reagent-name-space-lube name: reagent-name-space-lube
desc: reagent-desc-space-lube desc: reagent-desc-space-lube
slippery: true slipData:
requiredSlipSpeed: 1
superSlippery: true
physicalDesc: reagent-physical-desc-shiny physicalDesc: reagent-physical-desc-shiny
flavor: funny flavor: funny
color: "#77b58e" color: "#77b58e"
recognizable: true recognizable: true
boilingPoint: 290.0 # Glycerin boilingPoint: 290.0 # Glycerin
meltingPoint: 18.2 meltingPoint: 18.2
tileReactions: friction: 0.0
- !type:SpillTileReaction
requiredSlipSpeed: 1
superSlippery: true
- type: reagent - type: reagent
id: SpaceGlue id: SpaceGlue
@@ -90,8 +89,6 @@
boilingPoint: 250.0 boilingPoint: 250.0
meltingPoint: 380.0 meltingPoint: 380.0
viscosity: 0.5 viscosity: 0.5
tileReactions:
- !type:SpillTileReaction
reactiveEffects: reactiveEffects:
Acidic: Acidic:
methods: [ Touch ] methods: [ Touch ]

View File

@@ -170,7 +170,8 @@
id: Razorium id: Razorium
name: reagent-name-razorium name: reagent-name-razorium
group: Toxins group: Toxins
slippery: true slipData:
requiredSlipSpeed: 3.5
desc: reagent-desc-razorium desc: reagent-desc-razorium
physicalDesc: reagent-physical-desc-reflective physicalDesc: reagent-physical-desc-reflective
flavor: sharp flavor: sharp
@@ -209,7 +210,8 @@
id: Fresium id: Fresium
name: reagent-name-fresium name: reagent-name-fresium
group: Toxins group: Toxins
slippery: true slipData:
requiredSlipSpeed: 3.5
desc: reagent-desc-fresium desc: reagent-desc-fresium
physicalDesc: reagent-physical-desc-frosty physicalDesc: reagent-physical-desc-frosty
flavor: cold flavor: cold
@@ -305,7 +307,8 @@
physicalDesc: reagent-physical-desc-funny physicalDesc: reagent-physical-desc-funny
flavor: funny flavor: funny
color: "#FF4DD2" color: "#FF4DD2"
slippery: true #clown juice gotta slip slipData:
requiredSlipSpeed: 3.5 #clown juice gotta slip
metabolisms: metabolisms:
Medicine: Medicine:
effects: effects:

View File

@@ -149,13 +149,15 @@
parent: BasePyrotechnic parent: BasePyrotechnic
desc: reagent-desc-welding-fuel desc: reagent-desc-welding-fuel
physicalDesc: reagent-physical-desc-oily physicalDesc: reagent-physical-desc-oily
slippery: true slipData:
requiredSlipSpeed: 3.5
flavor: bitter flavor: bitter
flavorMinimum: 0.01 flavorMinimum: 0.01
color: "#a76b1c" color: "#a76b1c"
recognizable: true recognizable: true
boilingPoint: -84.7 # Acetylene. Close enough. boilingPoint: -84.7 # Acetylene. Close enough.
meltingPoint: -80.7 meltingPoint: -80.7
friction: 0.4
tileReactions: tileReactions:
- !type:FlammableTileReaction {} - !type:FlammableTileReaction {}
metabolisms: metabolisms:

View File

@@ -171,7 +171,6 @@
flavor: sour flavor: sour
color: "#48b3b8" color: "#48b3b8"
physicalDesc: reagent-physical-desc-ferrous physicalDesc: reagent-physical-desc-ferrous
slippery: false
metabolisms: metabolisms:
Drink: Drink:
effects: effects: