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;
                }
            }
        }
예제 #2
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;
                }
            }
        }