Skip to content

Commit

Permalink
update space wind
Browse files Browse the repository at this point in the history
  • Loading branch information
VMSolidus committed May 29, 2024
2 parents eebe035 + eba2d1d commit 208656f
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 31 deletions.
6 changes: 6 additions & 0 deletions Content.Server/Atmos/EntitySystems/AtmosphereSystem.CVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public sealed partial class AtmosphereSystem
public float SpaceWindPressureForceDivisorPush { get; private set; }
public float SpaceWindMaxVelocity { get; private set; }
public float SpaceWindMaxPushForce { get; private set; }
public float SpaceWindMinimumCalculatedMass { get; private set; }
public float SpaceWindMaximumCalculatedInverseMass { get; private set; }
public bool MonstermosUseExpensiveAirflow { get; private set; }
public bool MonstermosEqualization { get; private set; }
public bool MonstermosDepressurization { get; private set; }
public bool MonstermosRipTiles { get; private set; }
Expand Down Expand Up @@ -41,6 +44,9 @@ private void InitializeCVars()
Subs.CVar(_cfg, CCVars.SpaceWindPressureForceDivisorPush, value => SpaceWindPressureForceDivisorPush = value, true);
Subs.CVar(_cfg, CCVars.SpaceWindMaxVelocity, value => SpaceWindMaxVelocity = value, true);
Subs.CVar(_cfg, CCVars.SpaceWindMaxPushForce, value => SpaceWindMaxPushForce = value, true);
Subs.CVar(_cfg, CCVars.SpaceWindMinimumCalculatedMass, value => SpaceWindMinimumCalculatedMass = value, true);
Subs.CVar(_cfg, CCVars.SpaceWindMaximumCalculatedInverseMass, value => SpaceWindMaximumCalculatedInverseMass = value, true);
Subs.CVar(_cfg, CCVars.MonstermosUseExpensiveAirflow, value => MonstermosUseExpensiveAirflow = value, true);
Subs.CVar(_cfg, CCVars.MonstermosEqualization, value => MonstermosEqualization = value, true);
Subs.CVar(_cfg, CCVars.MonstermosDepressurization, value => MonstermosDepressurization = value, true);
Subs.CVar(_cfg, CCVars.MonstermosRipTiles, value => MonstermosRipTiles = value, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Random;
using Robust.Shared.Utility;

namespace Content.Server.Atmos.EntitySystems
Expand Down Expand Up @@ -50,7 +51,7 @@ private void UpdateHighPressure(float frameTime)

if (TryComp<PhysicsComponent>(uid, out var body))
{
_physics.SetBodyStatus(body, BodyStatus.OnGround);
_physics.SetBodyStatus(uid, body, BodyStatus.OnGround);
}

if (TryComp<FixturesComponent>(uid, out var fixtures))
Expand All @@ -73,7 +74,7 @@ private void AddMovedByPressure(EntityUid uid, MovedByPressureComponent componen
if (!TryComp<FixturesComponent>(uid, out var fixtures))
return;

_physics.SetBodyStatus(body, BodyStatus.InAir);
_physics.SetBodyStatus(uid, body, BodyStatus.InAir);

foreach (var (id, fixture) in fixtures.Fixtures)
{
Expand All @@ -89,12 +90,15 @@ private void AddMovedByPressure(EntityUid uid, MovedByPressureComponent componen

private void HighPressureMovements(Entity<GridAtmosphereComponent> gridAtmosphere, TileAtmosphere tile, EntityQuery<PhysicsComponent> bodies, EntityQuery<TransformComponent> xforms, EntityQuery<MovedByPressureComponent> pressureQuery, EntityQuery<MetaDataComponent> metas)
{
//!MAGIC EXIT CONDITION THAT MAKES ALMOST 200 LINES RUN 1/100TH AS OFTEN.
if (tile.PressureDifference < SpaceWindMinimumCalculatedMass * SpaceWindMinimumCalculatedMass)
return;
// TODO ATMOS finish this

// Don't play the space wind sound on tiles that are on fire...
if(tile.PressureDifference > 15 && !tile.Hotspot.Valid)
if (tile.PressureDifference > 15 && !tile.Hotspot.Valid)
{
if(_spaceWindSoundCooldown == 0 && !string.IsNullOrEmpty(SpaceWindSound))
if (_spaceWindSoundCooldown == 0 && !string.IsNullOrEmpty(SpaceWindSound))
{
var coordinates = _mapSystem.ToCenterCoordinates(tile.GridIndex, tile.GridIndices);
_audio.PlayPvs(SpaceWindSound, coordinates, AudioParams.Default.WithVariation(0.125f).WithVolume(MathHelper.Clamp(tile.PressureDifference / 10, 10, 100)));
Expand All @@ -118,7 +122,8 @@ private void HighPressureMovements(Entity<GridAtmosphereComponent> gridAtmospher
var gridWorldRotation = xforms.GetComponent(gridAtmosphere).WorldRotation;

// If we're using monstermos, smooth out the yeet direction to follow the flow
if (MonstermosEqualization)
//WTF:This is bad, don't run this. It just makes the throws worse by somehow rounding them to orthogonal
if (!MonstermosEqualization)
{
// We step through tiles according to the pressure direction on the current tile.
// The goal is to get a general direction of the airflow in the area.
Expand Down Expand Up @@ -179,8 +184,32 @@ private void ConsiderPressureDifference(GridAtmosphereComponent gridAtmosphere,
tile.PressureDirection = differenceDirection;
}

//The EE version of this function drops pressureResistanceProbDelta, since it's not needed. If you are for whatever reason calling this function
//And it isn't working, you've probably still got the ResistancePobDelta line included.
//INFO:The EE version of this function drops pressureResistanceProbDelta, since it's not needed. If you are for whatever reason calling this function
//INFO:And it isn't working, you've probably still got the pressureResistanceProbDelta line included.
/// <notes>
/// EXPLANATION:
/// pressureDifference = Force of Air Flow on a given tile
/// physics.Mass = Mass of the object potentially being thrown
/// physics.InvMass = 1 divided by said Mass. More CPU efficient way to do division.
///
/// Objects can only be thrown if the force of air flow is greater than the SQUARE of their mass or {SpaceWindMinimumCalculatedMass}, whichever is heavier
/// This means that the heavier an object is, the exponentially more force is required to move it
/// The force of a throw is equal to the force of air pressure, divided by an object's mass. So not only are heavier objects
/// less likely to be thrown, they are also harder to throw,
/// while lighter objects are yeeted easily, and from great distance.
///
/// For a human sized entity with a standard weight of 80kg and a spacing between a hard vacuum and a room pressurized at 101kpa,
/// The human shall only be moved if he is either very close to the hole, or is standing in a region of high airflow
/// </notes>
/// <param name="ent"></param>
/// <param name="cycle"></param>
/// <param name="pressureDifference"></param>
/// <param name="direction"></param>
/// <param name="throwTarget"></param>
/// <param name="gridWorldRotation"></param>
/// <param name="xform"></param>
/// <param name="physics"></param>

public void ExperiencePressureDifference(
Entity<MovedByPressureComponent> ent,
int cycle,
Expand All @@ -198,28 +227,28 @@ public void ExperiencePressureDifference(
if (!Resolve(uid, ref xform))
return;

// Can we yeet the thing (due to probability, strength, etc.)

if (physics.BodyType != BodyType.Static
&& !float.IsPositiveInfinity(component.MoveResist))
{
var moveForce = pressureDifference * physics.InvMass;

var moveForce = pressureDifference * MathF.Max(physics.InvMass, SpaceWindMaximumCalculatedInverseMass);
if (moveForce > physics.Mass)
{
var maxSafeForceForObject = SpaceWindMaxVelocity * physics.Mass;
moveForce = MathF.Min(moveForce, maxSafeForceForObject);
AddMovedByPressure(uid, component, physics);
// Grid-rotation adjusted direction
var dirVec = (direction.ToAngle() + gridWorldRotation).ToWorldVec();
var maxSafeForceForObject = SpaceWindMaxVelocity * physics.Mass;

// TODO: Technically these directions won't be correct but uhh I'm just here for optimisations buddy not to fix my old bugs.
// TODO: Consider replacing throw target with proper trigonometry angles.
if (throwTarget != EntityCoordinates.Invalid)
{
var pos = ((throwTarget.ToMap(EntityManager).Position - xform.WorldPosition).Normalized() + dirVec).Normalized();
_physics.ApplyLinearImpulse(uid, pos * Math.Clamp(moveForce, 0, maxSafeForceForObject), body: physics);
var pos = throwTarget.ToMap(EntityManager, _transformSystem).Position - xform.WorldPosition + dirVec;
_physics.ApplyLinearImpulse(uid, pos * moveForce, body: physics);
}
else
{
_physics.ApplyLinearImpulse(uid, dirVec * Math.Clamp(moveForce, 0, maxSafeForceForObject), body: physics);
_physics.ApplyLinearImpulse(uid, dirVec * moveForce, body: physics);
}

component.LastHighPressureMovementAirCycle = cycle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private void EqualizePressureInZone(
var logN = MathF.Log2(tileCount);

// Optimization - try to spread gases using an O(n log n) algorithm that has a chance of not working first to avoid O(n^2)
if (giverTilesLength > logN && takerTilesLength > logN)
if (!MonstermosUseExpensiveAirflow && giverTilesLength > logN && takerTilesLength > logN)
{
// Even if it fails, it will speed up the next part.
Array.Sort(_equalizeTiles, 0, tileCount, _monstermosComparer);
Expand Down
5 changes: 3 additions & 2 deletions Content.Server/Temperature/Systems/TemperatureSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,9 @@ public float GetHeatCapacity(EntityUid uid, TemperatureComponent? comp = null, P
{
return Atmospherics.MinimumHeatCapacity;
}

return comp.SpecificHeat * physics.FixturesMass;
if (physics.Mass < 1)
return comp.SpecificHeat;
else return comp.SpecificHeat * physics.FixturesMass;
}

private void OnInit(EntityUid uid, InternalTemperatureComponent comp, MapInitEvent args)
Expand Down
28 changes: 27 additions & 1 deletion Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,7 @@ public static readonly CVarDef<bool>
/// Useful to prevent clipping through objects.
/// </summary>
public static readonly CVarDef<float> SpaceWindMaxVelocity =
CVarDef.Create("atmos.space_wind_max_velocity", 30f, CVar.SERVERONLY);
CVarDef.Create("atmos.space_wind_max_velocity", 25f, CVar.SERVERONLY);

/// <summary>
/// The maximum force that may be applied to an object by pushing (i.e. not throwing) atmospheric pressure differences.
Expand All @@ -1098,6 +1098,25 @@ public static readonly CVarDef<bool>
public static readonly CVarDef<float> SpaceWindMaxPushForce =
CVarDef.Create("atmos.space_wind_max_push_force", 20f, CVar.SERVERONLY);

/// <summary>
/// If an object's mass is below this number, then this number is used in place of mass to determine whether air pressure can throw an object.
/// This has nothing to do with throwing force, only acting as a way of reducing the odds of tiny 5 gram objects from being yeeted by people's breath
/// </summary>
/// <remarks>
/// If you are reading this because you want to change it, consider looking into why almost every item in the game weighs only 5 grams
/// And maybe do your part to fix that? :)
/// </remarks>
public static readonly CVarDef<float> SpaceWindMinimumCalculatedMass =
CVarDef.Create("atmos.space_wind_minimum_calculated_mass", 6f, CVar.SERVERONLY);

/// <summary>
/// Calculated as 1/Mass, where Mass is the physics.Mass of the desired threshold.
/// If an object's inverse mass is lower than this, it is capped at this. Basically, an upper limit to how heavy an object can be
/// before it stops resisting space wind more.
/// </summary>
public static readonly CVarDef<float> SpaceWindMaximumCalculatedInverseMass =
CVarDef.Create("atmos.space_wind_maximum_calculated_inverse_mass", 0.04f, CVar.SERVERONLY);

/// <summary>
/// Whether monstermos tile equalization is enabled.
/// </summary>
Expand Down Expand Up @@ -1150,6 +1169,13 @@ public static readonly CVarDef<bool>
public static readonly CVarDef<float> AtmosSpacingMaxWind =
CVarDef.Create("atmos.mmos_max_wind", 500f, CVar.SERVERONLY);

/// <summary>
/// Increases default airflow calculations to O(n^2) complexity, for use with heavy space wind optimizations. Potato servers BEWARE
/// This solves the problem of objects being trapped in an infinite loop of slamming into a wall repeatedly.
/// </summary>
public static readonly CVarDef<bool> MonstermosUseExpensiveAirflow =
CVarDef.Create("atmos.mmos_expensive_airflow", true, CVar.SERVERONLY);

/// <summary>
/// Whether atmos superconduction is enabled.
/// </summary>
Expand Down
46 changes: 34 additions & 12 deletions Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
shape:
!type:PhysShapeCircle
radius: 0.25
density: 10
density: 0.8
mask:
- FlyingMobMask
layer:
Expand Down Expand Up @@ -87,7 +87,7 @@
shape:
!type:PhysShapeCircle
radius: 0.1
density: 30
density: 0.1
mask:
- FlyingMobMask
layer:
Expand Down Expand Up @@ -334,7 +334,7 @@
shape:
!type:PhysShapeCircle
radius: 0.2
density: 100
density: 0.0007
mask:
- SmallMobMask
layer:
Expand Down Expand Up @@ -438,7 +438,7 @@
shape:
!type:PhysShapeCircle
radius: 0.2
density: 120
density: 0.007
mask:
- SmallMobMask
layer:
Expand Down Expand Up @@ -1542,7 +1542,7 @@
shape:
!type:PhysShapeCircle
radius: 0.2
density: 100
density: 0.76
mask:
- SmallMobMask
layer:
Expand Down Expand Up @@ -2457,7 +2457,7 @@
shape:
!type:PhysShapeCircle
radius: 0.35
density: 50 #They actually are pretty light, I looked it up
density: 16.66
mask:
- MobMask
layer:
Expand Down Expand Up @@ -2539,7 +2539,7 @@
shape:
!type:PhysShapeCircle
radius: 0.35
density: 50
density: 25.5
mask:
- MobMask
layer:
Expand Down Expand Up @@ -2692,7 +2692,7 @@
shape:
!type:PhysShapeCircle
radius: 0.35
density: 15
density: 9
mask:
- MobMask
layer:
Expand Down Expand Up @@ -2844,6 +2844,17 @@
Base: caracal_flop
Dead:
Base: caracal_dead
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeCircle
radius: 0.35
density: 30
mask:
- MobMask
layer:
- MobLayer

- type: entity
name: kitten
Expand Down Expand Up @@ -2877,6 +2888,17 @@
thresholds:
0: Alive
25: Dead
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeCircle
radius: 0.35
density: 2
mask:
- MobMask
layer:
- MobLayer

- type: entity
name: sloth
Expand Down Expand Up @@ -2957,7 +2979,7 @@
shape:
!type:PhysShapeCircle
radius: 0.35
density: 5
density: 4
mask:
- MobMask
layer:
Expand Down Expand Up @@ -3034,7 +3056,7 @@
shape:
!type:PhysShapeCircle
radius: 0.2
density: 120
density: 0.8
mask:
- SmallMobMask
layer:
Expand Down Expand Up @@ -3155,7 +3177,7 @@
shape:
!type:PhysShapeCircle
radius: 0.35
density: 250
density: 750
mask:
- MobMask
layer:
Expand Down Expand Up @@ -3231,7 +3253,7 @@
shape:
!type:PhysShapeCircle
radius: 0.35
density: 100 # High, because wood is heavy.
density: 15
mask:
- MobMask
layer:
Expand Down

0 comments on commit 208656f

Please sign in to comment.