public AtmosDebugOverlayData(float temperature, float[] moles, AtmosDirection pressureDirection, bool inExcited)
 {
     Temperature       = temperature;
     Moles             = moles;
     PressureDirection = pressureDirection;
     InExcitedGroup    = inExcited;
 }
        /// <summary>
        ///     Returns if the tile in question is "air-blocked" in a certain direction or not.
        ///     This could be due to a number of reasons, such as walls, doors, etc.
        /// </summary>
        /// <param name="coordinates">Coordinates where to get the tile.</param>
        /// <param name="direction">Directions to check.</param>
        /// <returns>Whether the tile is blocked in the directions specified.</returns>
        public bool IsTileAirBlocked(EntityCoordinates coordinates, AtmosDirection direction = AtmosDirection.All)
        {
            if (TryGetGridAndTile(coordinates, out var tuple))
            {
                return(IsTileAirBlocked(tuple.Value.Grid, tuple.Value.Tile, direction));
            }

            return(false);
        }
示例#3
0
 public AtmosDebugOverlayData(float temperature, float[] moles, AtmosDirection pressureDirection, AtmosDirection lastPressureDirection, bool inExcited, AtmosDirection blockDirection)
 {
     Temperature           = temperature;
     Moles                 = moles;
     PressureDirection     = pressureDirection;
     LastPressureDirection = lastPressureDirection;
     InExcitedGroup        = inExcited;
     BlockDirection        = blockDirection;
 }
示例#4
0
    public bool IsTileAirBlocked(EntityUid gridUid, Vector2i tile, AtmosDirection directions = AtmosDirection.All, IMapGridComponent?mapGridComp = null)
    {
        var ev = new IsTileAirBlockedMethodEvent(gridUid, tile, directions, mapGridComp);

        RaiseLocalEvent(gridUid, ref ev);

        // If nothing handled the event, it'll default to true.
        return(ev.Result);
    }
示例#5
0
 public static AtmosDirection GetOpposite(this AtmosDirection direction)
 {
     return(direction switch
     {
         AtmosDirection.North => AtmosDirection.South,
         AtmosDirection.South => AtmosDirection.North,
         AtmosDirection.East => AtmosDirection.West,
         AtmosDirection.West => AtmosDirection.East,
         AtmosDirection.NorthEast => AtmosDirection.SouthWest,
         AtmosDirection.NorthWest => AtmosDirection.SouthEast,
         AtmosDirection.SouthEast => AtmosDirection.NorthWest,
         AtmosDirection.SouthWest => AtmosDirection.NorthEast,
         _ => throw new ArgumentOutOfRangeException(nameof(direction))
     });
        /// <summary>
        ///     Returns if the tile in question is "air-blocked" in a certain direction or not.
        ///     This could be due to a number of reasons, such as walls, doors, etc.
        /// </summary>
        /// <param name="grid">Grid where to get the tile.</param>
        /// <param name="tile">Indices of the tile.</param>
        /// <param name="direction">Directions to check.</param>
        /// <returns>Whether the tile is blocked in the directions specified.</returns>
        public bool IsTileAirBlocked(GridId grid, Vector2i tile, AtmosDirection direction = AtmosDirection.All)
        {
            if (!_mapManager.TryGetGrid(grid, out var mapGrid))
            {
                return(false);
            }

            if (ComponentManager.TryGetComponent(mapGrid.GridEntityId, out GridAtmosphereComponent? gridAtmosphere))
            {
                return(gridAtmosphere.IsAirBlocked(tile, direction));
            }

            return(false);
        }
示例#7
0
        public bool IsAirBlocked(Vector2i indices, AtmosDirection direction = AtmosDirection.All)
        {
            foreach (var obstructingComponent in GetObstructingComponents(indices))
            {
                if (!obstructingComponent.AirBlocked)
                {
                    continue;
                }

                if (obstructingComponent.AirBlockedDirection.HasFlag(direction))
                {
                    return(true);
                }
            }

            return(false);
        }
示例#8
0
        private AtmosDirection Rotate(AtmosDirection myDirection, Angle myAngle)
        {
            var newAirBlockedDirs = AtmosDirection.Invalid;

            if (myAngle == Angle.Zero)
            {
                return(myDirection);
            }

            // TODO ATMOS MULTIZ: When we make multiZ atmos, special case this.
            for (var i = 0; i < Atmospherics.Directions; i++)
            {
                var direction = (AtmosDirection)(1 << i);
                if (!myDirection.IsFlagSet(direction))
                {
                    continue;
                }
                var angle = direction.ToAngle();
                angle             += myAngle;
                newAirBlockedDirs |= angle.ToAtmosDirectionCardinal();
            }

            return(newAirBlockedDirs);
        }
示例#9
0
 public float this[AtmosDirection direction]
 {
     get =>
        public void ExperiencePressureDifference(int cycle, float pressureDifference, AtmosDirection direction,
                                                 float pressureResistanceProbDelta, EntityCoordinates throwTarget)
        {
            if (!Owner.TryGetComponent(out PhysicsComponent? physics))
            {
                return;
            }

            // TODO ATMOS stuns?

            var transform = physics.Owner.Transform;
            var maxForce  = MathF.Sqrt(pressureDifference) * 2.25f;
            var moveProb  = 100f;

            if (PressureResistance > 0)
            {
                moveProb = MathF.Abs((pressureDifference / PressureResistance * ProbabilityBasePercent) -
                                     ProbabilityOffset);
            }

            if (moveProb > ProbabilityOffset && _robustRandom.Prob(MathF.Min(moveProb / 100f, 1f)) &&
                !float.IsPositiveInfinity(MoveResist) &&
                (physics.BodyType != BodyType.Static &&
                 (maxForce >= (MoveResist * MoveForcePushRatio))) ||
                (physics.BodyType == BodyType.Static && (maxForce >= (MoveResist * MoveForceForcePushRatio))))
            {
                if (physics.Owner.HasComponent <IMobStateComponent>())
                {
                    physics.BodyStatus = BodyStatus.InAir;

                    foreach (var fixture in physics.Fixtures)
                    {
                        fixture.CollisionMask &= ~(int)CollisionGroup.VaultImpassable;
                    }

                    Owner.SpawnTimer(2000, () =>
                    {
                        if (Deleted || !Owner.TryGetComponent(out PhysicsComponent? physicsComponent))
                        {
                            return;
                        }

                        // Uhh if you get race conditions good luck buddy.
                        if (physicsComponent.Owner.HasComponent <IMobStateComponent>())
                        {
                            physicsComponent.BodyStatus = BodyStatus.OnGround;
                        }

                        foreach (var fixture in physics.Fixtures)
                        {
                            fixture.CollisionMask |= (int)CollisionGroup.VaultImpassable;
                        }
                    });
 public TileData(float[] explosionTolerance, AtmosDirection blockedDirections)
 {
     ExplosionTolerance = explosionTolerance;
     BlockedDirections  = blockedDirections;
 }
        public void ExperiencePressureDifference(int cycle, float pressureDifference, AtmosDirection direction,
                                                 float pressureResistanceProbDelta, EntityCoordinates throwTarget)
        {
            if (ControlledComponent == null)
            {
                return;
            }

            // TODO ATMOS stuns?

            var transform         = ControlledComponent.Owner.Transform;
            var pressureComponent = ControlledComponent.Owner.GetComponent <MovedByPressureComponent>();
            var maxForce          = MathF.Sqrt(pressureDifference) * 2.25f;
            var moveProb          = 100f;

            if (pressureComponent.PressureResistance > 0)
            {
                moveProb = MathF.Abs((pressureDifference / pressureComponent.PressureResistance * ProbabilityBasePercent) -
                                     ProbabilityOffset);
            }

            if (moveProb > ProbabilityOffset && _robustRandom.Prob(MathF.Min(moveProb / 100f, 1f)) &&
                !float.IsPositiveInfinity(pressureComponent.MoveResist) &&
                (!ControlledComponent.Anchored &&
                 (maxForce >= (pressureComponent.MoveResist * MoveForcePushRatio))) ||
                (ControlledComponent.Anchored && (maxForce >= (pressureComponent.MoveResist * MoveForceForcePushRatio))))
            {
                if (maxForce > ThrowForce)
                {
                    if (throwTarget != EntityCoordinates.Invalid)
                    {
                        var moveForce = maxForce * MathHelper.Clamp(moveProb, 0, 100) / 150f;
                        var pos       = ((throwTarget.Position - transform.Coordinates.Position).Normalized + direction.ToDirection().ToVec()).Normalized;
                        LinearVelocity = pos * moveForce;
                    }

                    else
                    {
                        var moveForce = MathF.Min(maxForce * MathHelper.Clamp(moveProb, 0, 100) / 2500f, 20f);
                        LinearVelocity = direction.ToDirection().ToVec() * moveForce;
                    }

                    pressureComponent.LastHighPressureMovementAirCycle = cycle;
                }
            }
        }
示例#13
0
        public void ExperiencePressureDifference(int cycle, float pressureDifference, AtmosDirection direction,
                                                 float pressureResistanceProbDelta, EntityCoordinates throwTarget)
        {
            if (!_entMan.TryGetComponent(Owner, out PhysicsComponent? physics))
            {
                return;
            }
            if (!_entMan.TryGetComponent(Owner, out FixturesComponent? fixtureComponent))
            {
                return;
            }

            // TODO ATMOS stuns?

            var transform = _entMan.GetComponent <TransformComponent>(physics.Owner);
            var maxForce  = MathF.Sqrt(pressureDifference) * 2.25f;
            var moveProb  = 100f;

            if (PressureResistance > 0)
            {
                moveProb = MathF.Abs((pressureDifference / PressureResistance * ProbabilityBasePercent) -
                                     ProbabilityOffset);
            }

            if (moveProb > ProbabilityOffset && _robustRandom.Prob(MathF.Min(moveProb / 100f, 1f)) &&
                !float.IsPositiveInfinity(MoveResist) &&
                (physics.BodyType != BodyType.Static &&
                 (maxForce >= (MoveResist * MoveForcePushRatio))) ||
                (physics.BodyType == BodyType.Static && (maxForce >= (MoveResist * MoveForceForcePushRatio))))
            {
                if (_entMan.HasComponent <MobStateComponent>(physics.Owner))
                {
                    physics.BodyStatus = BodyStatus.InAir;
                    foreach (var fixture in fixtureComponent.Fixtures.Values)
                    {
                        fixture.CollisionMask &= ~(int)CollisionGroup.VaultImpassable;
                    }

                    Owner.SpawnTimer(2000, () =>
                    {
                        if (Deleted || !_entMan.TryGetComponent(Owner, out PhysicsComponent? physicsComponent))
                        {
                            return;
                        }

                        // Uhh if you get race conditions good luck buddy.
                        if (_entMan.HasComponent <MobStateComponent>(physicsComponent.Owner))
                        {
                            physicsComponent.BodyStatus = BodyStatus.OnGround;
                        }

                        foreach (var fixture in physics.Fixtures)
                        {
                            fixture.CollisionMask |= (int)CollisionGroup.VaultImpassable;
                        }
                    });
                }

                if (maxForce > ThrowForce)
                {
                    // Vera please fix ;-;
                    if (throwTarget != EntityCoordinates.Invalid)
                    {
                        var moveForce = maxForce * MathHelper.Clamp(moveProb, 0, 100) / 15f;
                        var pos       = ((throwTarget.Position - transform.Coordinates.Position).Normalized + direction.ToDirection().ToVec()).Normalized;
                        physics.ApplyLinearImpulse(pos * moveForce);
                    }

                    else
                    {
                        var moveForce = MathF.Min(maxForce * MathHelper.Clamp(moveProb, 0, 100) / 2500f, 20f);
                        physics.ApplyLinearImpulse(direction.ToDirection().ToVec() * moveForce);
                    }

                    LastHighPressureMovementAirCycle = cycle;
                }
            }
        }