var hadSlipComponent = EnsureComp(args.Target, out SlipperyComponent slipComponent);
if (!hadSlipComponent)
{
- slipComponent.SuperSlippery = true;
- slipComponent.ParalyzeTime = 5;
- slipComponent.LaunchForwardsMultiplier = 20;
+ slipComponent.SlipData.SuperSlippery = true;
+ slipComponent.SlipData.ParalyzeTime = TimeSpan.FromSeconds(5);
+ slipComponent.SlipData.LaunchForwardsMultiplier = 20;
}
_slipperySystem.TrySlip(args.Target, slipComponent, args.Target, requiresContact: false);
+++ /dev/null
-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;
- }
- }
-}
+++ /dev/null
-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;
- }
- }
-}
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
// loses & then gains reagents in a single tick.
private HashSet<EntityUid> _deletionQueue = [];
// Shouldn't need re-anchoring.
SubscribeLocalEvent<PuddleComponent, AnchorStateChangedEvent>(OnAnchorChanged);
SubscribeLocalEvent<PuddleComponent, SolutionContainerChangedEvent>(OnSolutionUpdate);
- SubscribeLocalEvent<PuddleComponent, ComponentInit>(OnPuddleInit);
SubscribeLocalEvent<PuddleComponent, SpreadNeighborsEvent>(OnPuddleSpread);
SubscribeLocalEvent<PuddleComponent, SlipEvent>(OnPuddleSlip);
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)
{
if (args.SolutionId != entity.Comp.SolutionName)
}
_deletionQueue.Remove(entity);
- UpdateSlip(entity, entity.Comp, args.Solution);
+ UpdateSlip((entity, entity.Comp), args.Solution);
UpdateSlow(entity, args.Solution);
UpdateEvaporation(entity, args.Solution);
UpdateAppearance(entity, entity.Comp);
_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;
- var isSuperSlippery = false;
- // 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;
+ if (!TryComp<StepTriggerComponent>(entity, out var comp))
+ return;
- // Utilize the defaults from their relevant systems... this sucks, and is a bandaid
- var launchForwardsMultiplier = SlipperyComponent.DefaultLaunchForwardsMultiplier;
- var paralyzeTime = SlipperyComponent.DefaultParalyzeTime;
- var requiredSlipSpeed = StepTriggerComponent.DefaultRequiredTriggeredSpeed;
+ // This is the base amount of reagent needed before a puddle can be considered slippery. Is defined based on
+ // the sprite threshold for a puddle larger than 5 pixels.
+ var smallPuddleThreshold = FixedPoint2.New(entity.Comp.OverflowVolume.Float() * LowThreshold);
+
+ // 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)
{
var reagentProto = _prototypeManager.Index<ReagentPrototype>(reagent.Prototype);
- if (!reagentProto.Slippery)
- continue;
- slipperyAmount += quantity;
+ // 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 (slipperyAmount <= amountRequired)
+ if (reagentProto.SlipData == null)
continue;
- isSlippery = true;
- foreach (var tileReaction in reagentProto.TileReactions)
- {
- if (tileReaction is not SpillTileReaction spillTileReaction)
- continue;
- isSuperSlippery = spillTileReaction.SuperSlippery;
- launchForwardsMultiplier = launchForwardsMultiplier < spillTileReaction.LaunchForwardsMultiplier ? spillTileReaction.LaunchForwardsMultiplier : launchForwardsMultiplier;
- requiredSlipSpeed = requiredSlipSpeed > spillTileReaction.RequiredSlipSpeed ? spillTileReaction.RequiredSlipSpeed : requiredSlipSpeed;
- paralyzeTime = paralyzeTime < spillTileReaction.ParalyzeTime ? spillTileReaction.ParalyzeTime : paralyzeTime;
- }
+ slipperyUnits += quantity;
+ // Aggregate launch speed based on quantity
+ launchMult += reagentProto.SlipData.LaunchForwardsMultiplier * quantity;
+ // Aggregate stun times based on quantity
+ stunTimer += reagentProto.SlipData.ParalyzeTime * (float)quantity;
+
+ if (reagentProto.SlipData.SuperSlippery)
+ superSlipperyUnits += quantity;
}
- if (isSlippery)
- {
- var comp = EnsureComp<StepTriggerComponent>(entityUid);
- _stepTrigger.SetActive(entityUid, true, comp);
- var friction = EnsureComp<TileFrictionModifierComponent>(entityUid);
- _tile.SetModifier(entityUid, TileFrictionController.DefaultFriction * 0.5f, friction);
+ // Turn on the step trigger if it's slippery
+ _stepTrigger.SetActive(entity, slipperyUnits > smallPuddleThreshold, comp);
- if (!TryComp<SlipperyComponent>(entityUid, out var slipperyComponent))
- return;
- slipperyComponent.SuperSlippery = isSuperSlippery;
- _stepTrigger.SetRequiredTriggerSpeed(entityUid, requiredSlipSpeed);
- slipperyComponent.LaunchForwardsMultiplier = launchForwardsMultiplier;
- slipperyComponent.ParalyzeTime = paralyzeTime;
+ // 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);
- }
- else if (TryComp<StepTriggerComponent>(entityUid, out var comp))
+ // 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)
{
- _stepTrigger.SetActive(entityUid, false, comp);
- RemCompDeferred<TileFrictionModifierComponent>(entityUid);
+ slipComp.SlipData.LaunchForwardsMultiplier = (float)(launchMult/slipperyUnits);
+ slipComp.SlipData.ParalyzeTime = (stunTimer/(float)slipperyUnits);
}
+
+ // Only make it super slippery if there is enough super slippery units for its own puddle
+ slipComp.SlipData.SuperSlippery = superSlipperyUnits >= smallPuddleThreshold;
+
+ // Lower tile friction based on how slippery it is, lets items slide across a puddle of lube
+ slipComp.SlipData.SlipFriction = (float)(puddleFriction/solution.Volume);
+ _tile.SetModifier(entity, TileFrictionController.DefaultFriction * slipComp.SlipData.SlipFriction);
+
+ Dirty(entity, slipComp);
}
private void UpdateSlow(EntityUid uid, Solution solution)
using Content.Shared.EntityEffects;
using Content.Shared.Database;
using Content.Shared.Nutrition;
+using Content.Shared.Prototypes;
+using Content.Shared.Slippery;
using Robust.Shared.Audio;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
[DataField]
public bool MetamorphicChangeColor { get; private set; } = true;
+
/// <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>
[DataField]
- public bool Slippery;
+ public SlipperyEffectEntry? SlipData;
/// <summary>
/// The speed at which the reagent evaporates over time.
[DataField]
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>
/// Should this reagent work on the dead?
/// </summary>
[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]
public Entity<SolutionComponent>? Solution;
}
{
base.Initialize();
- SubscribeLocalEvent<SlidingComponent, TileFrictionEvent>(OnSlideAttempt);
SubscribeLocalEvent<SlidingComponent, StoodEvent>(OnStand);
SubscribeLocalEvent<SlidingComponent, StartCollideEvent>(OnStartCollide);
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>
/// Remove the component when the entity stands up again.
/// </summary>
/// </summary>
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;
component.CollidingEntities.Add(args.OtherEntity);
- component.FrictionModifier = 0;
Dirty(uid, component);
}
return;
if (component.CollidingEntities.Count == 0)
- component.FrictionModifier = SharedStunSystem.KnockDownModifier;
+ RemComp<SlidingComponent>(uid);
Dirty(uid, component);
}
using Content.Shared.StepTrigger.Components;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
namespace Content.Shared.Slippery
{
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class SlipperyComponent : Component
{
- public const float DefaultParalyzeTime = 1.5f;
- public const float DefaultLaunchForwardsMultiplier = 1.5f;
/// <summary>
/// Path to the sound to be played when a mob slips.
/// </summary>
public SoundSpecifier SlipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg");
/// <summary>
- /// How many seconds the mob will be paralyzed for.
+ /// Loads the data needed to determine how slippery something is.
/// </summary>
[DataField, AutoNetworkedField]
- [Access(Other = AccessPermissions.ReadWrite)]
- public float ParalyzeTime = DefaultParalyzeTime;
+ public SlipperyEffectEntry SlipData = new();
+ }
+ /// <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>
/// The entity's speed will be multiplied by this to slip it forwards.
/// </summary>
- [DataField, AutoNetworkedField]
- [Access(Other = AccessPermissions.ReadWrite)]
- public float LaunchForwardsMultiplier = DefaultLaunchForwardsMultiplier;
+ [DataField]
+ public float LaunchForwardsMultiplier = 1.5f;
+
+ /// <summary>
+ /// Minimum speed entity must be moving to slip.
+ /// </summary>
+ [DataField]
+ public float RequiredSlipSpeed = 3.5f;
/// <summary>
/// If this is true, any slipping entity loses its friction until
/// it's not colliding with any SuperSlippery entities anymore.
+ /// They also will fail any attempts to stand up unless they have no-slips.
/// </summary>
- [DataField, AutoNetworkedField]
- [Access(Other = AccessPermissions.ReadWrite)]
+ [DataField]
public bool SuperSlippery;
+
+ /// <summary>
+ /// This is used to store the friction modifier that is used on a sliding entity.
+ /// </summary>
+ [DataField]
+ public float SlipFriction;
}
}
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
SubscribeLocalEvent<SlowedOverSlipperyComponent, SlipAttemptEvent>(OnSlowedOverSlipAttempt);
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<SlowedOverSlipperyComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnSlowedOverSlipAttempt(e, c, ev.Args));
SubscribeLocalEvent<SlowedOverSlipperyComponent, InventoryRelayedEvent<GetSlowedOverSlipperyModifierEvent>>(OnGetSlowedOverSlipperyModifier);
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;
var attemptEv = new SlipAttemptEvent();
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);
sliding.CollidingEntities.Add(uid);
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.
if (playSound)
[Access(typeof(StepTriggerSystem))]
public sealed partial class StepTriggerComponent : Component
{
- public const float DefaultRequiredTriggeredSpeed = 3.5f;
/// <summary>
/// List of entities that are currently colliding with the entity.
/// </summary>
/// Entities will only be triggered if their speed exceeds this limit.
/// </summary>
[DataField, AutoNetworkedField]
- public float RequiredTriggeredSpeed = DefaultRequiredTriggeredSpeed;
+ public float RequiredTriggeredSpeed = 3.5f;
/// <summary>
/// If any entities occupy the blacklist on the same tile then steptrigger won't work.
components:
- type: Clickable
- type: Slippery
+ - type: TileFrictionModifier
+ modifier: 0.3
- type: Transform
noRot: true
anchored: true
rootTask:
task: HonkbotCompound
- type: Slippery
- launchForwardsMultiplier: 2
+ slipData:
+ launchForwardsMultiplier: 2
- type: Speech
speechVerb: Cluwne
- type: StepTrigger
- type: Slippery
slipSound:
path: /Audio/Effects/glass_step.ogg
- launchForwardsMultiplier: 0
+ slipData:
+ launchForwardsMultiplier: 0
- type: DamageUserOnTrigger
damage:
types:
- ReagentId: Nutriment
Quantity: 5
- type: Slippery
- paralyzeTime: 3
- launchForwardsMultiplier: 3
+ slipData:
+ paralyzeTime: 3
+ launchForwardsMultiplier: 3
- type: StepTrigger
intersectRatio: 0.2
- type: CollisionWake
- type: UseDelay
delay: 0.8
- type: Slippery
- paralyzeTime: 0
+ slipData:
+ paralyzeTime: 0
slipSound:
collection: Parp
params:
- type: Slippery
slipSound:
path: /Audio/Effects/glass_step.ogg
- launchForwardsMultiplier: 0
+ slipData:
+ launchForwardsMultiplier: 0
- type: TriggerOnStepTrigger
- type: DamageUserOnTrigger
damage:
- type: SolutionContainerVisuals
fillBaseName: syndie-
- type: Slippery
- paralyzeTime: 3
- launchForwardsMultiplier: 3
+ slipData:
+ paralyzeTime: 3
+ launchForwardsMultiplier: 3
- type: Item
heldPrefix: syndie
- type: FlavorProfile
layers:
- state: syndie-soaplet
- type: Slippery
- paralyzeTime: 1.5 # these things are tiny
- launchForwardsMultiplier: 1.5
+ slipData:
+ paralyzeTime: 1.5 # these things are tiny
+ launchForwardsMultiplier: 1.5
- type: StepTrigger
intersectRatio: 0.04
- type: Item
- type: SolutionContainerVisuals
fillBaseName: omega-
- type: Slippery
- paralyzeTime: 5.0
- launchForwardsMultiplier: 3.0
+ slipData:
+ paralyzeTime: 5.0
+ launchForwardsMultiplier: 3.0
- type: Item
heldPrefix: omega
- type: SolutionContainerManager
name: reagent-name-ethanol
parent: BaseAlcohol
desc: reagent-desc-ethanol
- slippery: true
physicalDesc: reagent-physical-desc-strong-smelling
flavor: alcohol
color: "#b05b3c"
id: BaseDrink
group: Drinks
abstract: true
- slippery: true
+ slipData:
+ requiredSlipSpeed: 3.5
metabolisms:
Drink:
effects:
amount: 1
tileReactions:
- !type:ExtinguishTileReaction { }
- - !type:SpillIfPuddlePresentTileReaction { }
- type: reagent
id: BaseSoda
id: BaseAlcohol
group: Drinks
abstract: true
+ slipData:
+ requiredSlipSpeed: 3.5
+ friction: 0.4
metabolisms:
Drink:
effects:
name: reagent-name-water
parent: BaseDrink
desc: reagent-desc-water
- slippery: true
evaporationSpeed: 0.3
absorbent: true
physicalDesc: reagent-physical-desc-translucent
recognizable: true
boilingPoint: 100.0
meltingPoint: 0.0
+ friction: 0.4
metabolisms:
Drink:
effects:
id: Ice
name: reagent-name-ice
desc: reagent-desc-ice
+ slipData:
+ requiredSlipSpeed: 3.5
physicalDesc: reagent-physical-desc-frosty
flavor: cold
color: "#bed8e6"
recognizable: true
meltingPoint: 0.0
boilingPoint: 100.0
+ friction: 0.05 #Copied from Ice Crust
plantMetabolism:
- !type:PlantAdjustWater
amount: 1
color: "#fb7125"
recognizable: true
physicalDesc: reagent-physical-desc-sticky
- slippery: false
viscosity: 0.55 #Start using syrup to attach your remote recievers to your microwaves!
- tileReactions:
- - !type:SpillTileReaction
metabolisms:
Food:
# 12 diona blood for 1 unit of syrup, this stuff better be worthwhile.
metamorphicChangeColor: false
recognizable: true
physicalDesc: reagent-physical-desc-ferrous
- slippery: false
metabolisms:
Drink:
effects:
color: "#808A51"
recognizable: true
physicalDesc: reagent-physical-desc-slimy
- slippery: false
- type: reagent
id: Slime
color: "#2cf274"
recognizable: true
physicalDesc: reagent-physical-desc-viscous
- slippery: false
viscosity: 0.25
- tileReactions:
- - !type:SpillTileReaction
metabolisms:
Food:
# Delicious!
color: "#cd7314"
recognizable: true
physicalDesc: reagent-physical-desc-sticky
- slippery: false
viscosity: 0.10
- tileReactions:
- - !type:SpillTileReaction
metabolisms:
Food:
# Sweet!
color: "#162581"
recognizable: true
physicalDesc: reagent-physical-desc-metallic
- slippery: false
- type: reagent
parent: Blood
color: "#7a8bf2"
recognizable: true
physicalDesc: reagent-physical-desc-pungent
- slippery: false
- type: reagent
id: ZombieBlood
physicalDesc: reagent-physical-desc-necrotic
flavor: bitter
color: "#2b0700"
- slippery: false
metabolisms:
Drink:
# Disgusting!
flavor: terrible
color: "#d8d8b0"
physicalDesc: reagent-physical-desc-exotic-smelling
- slippery: false
footstepSound:
collection: FootstepBlood
params:
flavor: terrible
color: "#87ab08"
physicalDesc: reagent-physical-desc-pungent
- slippery: true
+ slipData:
+ requiredSlipSpeed: 4.0 #It's not as slippery as water
+ friction: 0.4
metabolisms:
Drink:
effects:
physicalDesc: reagent-physical-desc-neural
flavor: mindful
color: "#C584B8"
- slippery: false
metabolisms:
Drink:
effects:
flavor: bitter
color: "#E6E6DA"
physicalDesc: reagent-physical-desc-crystalline
- slippery: false
- type: reagent
id: Rororium
id: SpaceLube
name: reagent-name-space-lube
desc: reagent-desc-space-lube
- slippery: true
+ slipData:
+ requiredSlipSpeed: 1
+ superSlippery: true
physicalDesc: reagent-physical-desc-shiny
flavor: funny
color: "#77b58e"
recognizable: true
boilingPoint: 290.0 # Glycerin
meltingPoint: 18.2
- tileReactions:
- - !type:SpillTileReaction
- requiredSlipSpeed: 1
- superSlippery: true
+ friction: 0.0
- type: reagent
id: SpaceGlue
boilingPoint: 250.0
meltingPoint: 380.0
viscosity: 0.5
- tileReactions:
- - !type:SpillTileReaction
reactiveEffects:
Acidic:
methods: [ Touch ]
id: Razorium
name: reagent-name-razorium
group: Toxins
- slippery: true
+ slipData:
+ requiredSlipSpeed: 3.5
desc: reagent-desc-razorium
physicalDesc: reagent-physical-desc-reflective
flavor: sharp
id: Fresium
name: reagent-name-fresium
group: Toxins
- slippery: true
+ slipData:
+ requiredSlipSpeed: 3.5
desc: reagent-desc-fresium
physicalDesc: reagent-physical-desc-frosty
flavor: cold
physicalDesc: reagent-physical-desc-funny
flavor: funny
color: "#FF4DD2"
- slippery: true #clown juice gotta slip
+ slipData:
+ requiredSlipSpeed: 3.5 #clown juice gotta slip
metabolisms:
Medicine:
effects:
parent: BasePyrotechnic
desc: reagent-desc-welding-fuel
physicalDesc: reagent-physical-desc-oily
- slippery: true
+ slipData:
+ requiredSlipSpeed: 3.5
flavor: bitter
flavorMinimum: 0.01
color: "#a76b1c"
recognizable: true
boilingPoint: -84.7 # Acetylene. Close enough.
meltingPoint: -80.7
+ friction: 0.4
tileReactions:
- !type:FlammableTileReaction {}
metabolisms:
flavor: bitter
color: "#9e6b38"
boilingPoint: 190.0 # Perfluorooctanoic Acid.
- meltingPoint: 45.0
\ No newline at end of file
+ meltingPoint: 45.0
flavor: sour
color: "#48b3b8"
physicalDesc: reagent-physical-desc-ferrous
- slippery: false
metabolisms:
Drink:
effects: