protected override void DoDraw(IBatchRenderer sbatch, FRectangle bounds)
        {
            if (_needsTabRecalc)
            {
                RecalcTabData();
            }

            sbatch.FillRectangle(bounds, Background);

            float rowHeight = FontSize + 2 * LineWidth;
            float py        = 0;

            // Header
            {
                sbatch.FillRectangle(new FRectangle(bounds.X, bounds.Y, bounds.Width - ScrollWidth, rowHeight), HeaderBackground);
                float x = 0;
                for (int i = 0; i < _columns.Count; i++)
                {
                    if (FloatMath.IsZero(_columns[i].RealWidth))
                    {
                        continue;
                    }

                    FontRenderHelper.DrawTextCentered(
                        sbatch,
                        Font,
                        FontSize,
                        _columns[i].Text,
                        HeaderForeground,
                        new FPoint(bounds.Left + x + _columns[i].RealWidth / 2f, bounds.Top + rowHeight / 2f));

                    x += _columns[i].RealWidth;
                }
                sbatch.DrawLine(bounds.Left, bounds.Top + rowHeight, bounds.Right - ScrollWidth, bounds.Top + rowHeight, LineColor, LineWidth);

                py += rowHeight;
            }

            // rows
            for (int di = (int)ScrollPosition; di < _data.Count; di++)
            {
                if (py + rowHeight > Height)
                {
                    break;
                }

                float x = 0;
                for (int ci = 0; ci < _columns.Count; ci++)
                {
                    if (FloatMath.IsZero(_columns[ci].RealWidth))
                    {
                        continue;
                    }

                    FontRenderHelper.DrawTextVerticallyCentered(
                        sbatch,
                        Font,
                        FontSize,
                        _data[di].Data[ci],
                        _data[di].ForegroundOverride ?? Foreground,
                        new FPoint(bounds.Left + x + LineWidth * 2, bounds.Top + py + rowHeight / 2f));

                    x += _columns[ci].RealWidth;
                }
                sbatch.DrawLine(bounds.Left, bounds.Top + py + rowHeight, bounds.Right - ScrollWidth, bounds.Top + py + rowHeight, LineColor, LineWidth);

                py += rowHeight;
            }

            // scroll
            {
                var colPerPage = (int)(Height / rowHeight) - 1;
                var perc       = FloatMath.Clamp(((int)ScrollPosition) / (1f * _data.Count - colPerPage), 0, 1);

                var pos = perc * (Height - ScrollHeight);

                sbatch.FillRectangle(new FRectangle(bounds.Right - ScrollWidth, bounds.Top + pos, ScrollWidth, ScrollHeight), ScrollThumbColor);
            }

            // Vert Lines
            {
                float x = 0;
                for (int i = 0; i < _columns.Count; i++)
                {
                    x += _columns[i].RealWidth;
                    sbatch.DrawLine(bounds.Left + x, bounds.Top, bounds.Left + x, bounds.Bottom, LineColor, LineWidth);
                }
            }

            sbatch.DrawRectangle(bounds, LineColor, LineWidth);
        }
Exemple #2
0
 public static void SetByteFloorRange(out byte target, float min, float max, float v)
 {
     SetByteFloor(out target, FloatMath.Clamp((v - min) / (max - min), 0f, 1f) * 255);
 }
Exemple #3
0
 private Vector4 Limit(Vector4 color)
 {
     return(new Vector4(FloatMath.Clamp(color.X, 0f, 255f), FloatMath.Clamp(color.Y, 0f, 255f), FloatMath.Clamp(color.Z, 0f, 255f), FloatMath.Clamp(color.W, 0f, 255f)));
 }
Exemple #4
0
        // test of rays hit each other
        private bool RayParallality(FPoint v1s, FPoint v1e, float v1d, FPoint v2s, FPoint v2e, float v2d, bool reflTolerant, out FPoint intersect, out float u)
        {
            var a1 = (v1e - v1s).ToAngle();
            var a2 = (v2e - v2s).ToAngle();

            var maxAngle = reflTolerant ? FloatMath.RAD_POS_004 : FloatMath.RAD_POS_090;

            if (FloatMath.DiffRadiansAbs(a1, a2) < maxAngle)
            {
                // same direction

                var u1 = v2s.ProjectOntoLine(v1s, v1e);
                var u2 = v1s.ProjectOntoLine(v2s, v2e);

                if (u1 > 0 && u1 < 1)
                {
                    intersect = Math2D.PointOnLine(u1, v1s, v1e);
                    u         = u1;
                    return(true);
                }
                if (u2 > 0 && u2 < 1)
                {
                    intersect = v1s;
                    u         = 0;
                    return(true);
                }
            }
            else if (FloatMath.DiffRadiansAbs(a1 + FloatMath.RAD_POS_180, a2) < maxAngle)
            {
                var u1s = FloatMath.Clamp(v2e.ProjectOntoLine(v1s, v1e), 0f, 1f);
                var u1e = FloatMath.Clamp(v2s.ProjectOntoLine(v1s, v1e), 0f, 1f);
                var u2s = FloatMath.Clamp(v1e.ProjectOntoLine(v2s, v2e), 0f, 1f);
                var u2e = FloatMath.Clamp(v1s.ProjectOntoLine(v2s, v2e), 0f, 1f);

                var v1rs = (u1s == 0) ? v1s : Math2D.PointOnLine(u1s, v1s, v1e);
                var v1re = (u1e == 1) ? v1e : Math2D.PointOnLine(u1e, v1s, v1e);
                var v2rs = (u2s == 0) ? v2s : Math2D.PointOnLine(u2s, v2s, v2e);
                var v2re = (u1e == 1) ? v2e : Math2D.PointOnLine(u2e, v2s, v2e);

                var distStart = (v1rs - v2re).LengthSquared();
                var distEnd   = (v1re - v2rs).LengthSquared();

                if (distStart < RAY_WIDTH * RAY_WIDTH && distEnd < RAY_WIDTH * RAY_WIDTH)
                {
                    var pc = FPoint.MiddlePoint(v1s, v2s);

                    pc = pc + (v1s - v2s).WithLength((v1d - v2d) / 2f);

                    var pcu1 = pc.ProjectOntoLine(v1s, v1e);
                    if (pcu1 < 0)
                    {
                        pc = v1s;
                    }
                    if (pcu1 > 1)
                    {
                        pc = v1e;
                    }

                    var pcu2 = pc.ProjectOntoLine(v2s, v2e);
                    if (pcu2 < 0)
                    {
                        pc = v2s;
                    }
                    if (pcu2 > 1)
                    {
                        pc = v2e;
                    }

                    intersect = pc;
                    u         = pc.ProjectOntoLine(v1s, v1e);
                    return(true);
                }
                else if (distStart < RAY_WIDTH * RAY_WIDTH)
                {
                    var drStart = FloatMath.Sqrt(distStart);
                    var drEnd   = FloatMath.Sqrt(distEnd);
                    var perc    = (RAY_WIDTH - drStart) / (drEnd - drStart);

                    u1e = u1s + (u1e - u1s) * perc;
                    u2s = u2e + (u2s - u2e) * perc;

                    v1re = Math2D.PointOnLine(u1e, v1s, v1e);
                    v2rs = Math2D.PointOnLine(u2s, v2s, v2e);

                    var v1rd = v1d + u1s * (v1e - v1s).Length();
                    var v2rd = v2d + u2s * (v2e - v2s).Length();



                    var pc = FPoint.MiddlePoint(v1rs, v2rs);

                    pc = pc + (v1rs - v2rs).WithLength((v1rd - v2rd) / 2f);

                    var pcu1 = pc.ProjectOntoLine(v1rs, v1re);
                    if (pcu1 < u1s)
                    {
                        pc = v1rs;
                    }
                    if (pcu1 > u1e)
                    {
                        pc = v1re;
                    }

                    var pcu2 = pc.ProjectOntoLine(v2rs, v2re);
                    if (pcu2 < u2s)
                    {
                        pc = v2rs;
                    }
                    if (pcu2 > u2e)
                    {
                        pc = v2re;
                    }

                    intersect = pc;
                    u         = pc.ProjectOntoLine(v1s, v1e);
                    return(true);
                }
                else if (distEnd < RAY_WIDTH * RAY_WIDTH)
                {
                    var drStart = FloatMath.Sqrt(distStart);
                    var drEnd   = FloatMath.Sqrt(distEnd);
                    var perc    = (RAY_WIDTH - drEnd) / (drStart - drEnd);

                    u1s = u1e + (u1s - u1e) * perc;
                    u2e = u2s + (u2e - u2s) * perc;

                    v1rs = Math2D.PointOnLine(u1s, v1s, v1e);
                    v2re = Math2D.PointOnLine(u2e, v2s, v2e);

                    var v1rd = v1d + u1s * (v1e - v1s).Length();
                    var v2rd = v2d + u2s * (v2e - v2s).Length();



                    var pc = FPoint.MiddlePoint(v1rs, v2rs);

                    pc = pc + (v1rs - v2rs).WithLength((v1rd - v2rd) / 2f);

                    var pcu1 = pc.ProjectOntoLine(v1rs, v1re);
                    if (pcu1 < u1s)
                    {
                        pc = v1rs;
                    }
                    if (pcu1 > u1e)
                    {
                        pc = v1re;
                    }

                    var pcu2 = pc.ProjectOntoLine(v2rs, v2re);
                    if (pcu2 < u2s)
                    {
                        pc = v2rs;
                    }
                    if (pcu2 > u2e)
                    {
                        pc = v2re;
                    }

                    intersect = pc;
                    u         = pc.ProjectOntoLine(v1s, v1e);
                    return(true);
                }
            }



            intersect = FPoint.Zero;
            u         = float.NaN;

            return(false);
        }
Exemple #5
0
        protected void SimulateWorld(float deltaTime, List <ICollidableComponent> physicsComponents)
        {
            foreach (var body in physicsComponents)
            {
                if (!body.Awake)
                {
                    continue;
                }

                body.SleepAccumulator++;

                // if the body cannot move, nothing to do here
                if (!body.CanMove())
                {
                    continue;
                }

                var linearVelocity = Vector2.Zero;

                foreach (var controller in body.Controllers.Values)
                {
                    controller.UpdateBeforeProcessing();
                    linearVelocity += controller.LinearVelocity;
                }

                // i'm not sure if this is the proper way to solve this, but
                // these are not kinematic bodies, so we need to preserve the previous
                // velocity.
                //if (body.LinearVelocity.LengthSquared < linearVelocity.LengthSquared)
                body.LinearVelocity = linearVelocity;

                // Integrate forces
                const float damping = 0.98f; // space/air friction, so everything eventually stops moving
                body.LinearVelocity  += body.Force * body.InvMass * deltaTime * damping;
                body.AngularVelocity += body.Torque * body.InvI * deltaTime * damping;

                // forces are instantaneous, so these properties are cleared
                // once integrated. If you want to apply a continuous force,
                // it has to be re-applied every tick.
                body.Force  = Vector2.Zero;
                body.Torque = 0f;
            }

            // Calculate collisions and store them in the cache
            ProcessCollisions(physicsComponents);

            // Remove all entities that were deleted during collision handling
            physicsComponents.RemoveAll(p => p.Deleted);

            // Process frictional forces
            foreach (var physics in physicsComponents)
            {
                ProcessFriction(physics, deltaTime);
            }

            foreach (var physics in physicsComponents)
            {
                foreach (var controller in physics.Controllers.Values)
                {
                    controller.UpdateAfterProcessing();
                }
            }

            // Remove all entities that were deleted due to the controller
            physicsComponents.RemoveAll(p => p.Deleted);

            const int solveIterationsAt60 = 4;

            var multiplier = deltaTime / (1f / 60);

            var divisions = FloatMath.Clamp(
                MathF.Round(solveIterationsAt60 * multiplier, MidpointRounding.AwayFromZero),
                1,
                20
                );

            if (_timing.InSimulation)
            {
                divisions = 1;
            }

            for (var i = 0; i < divisions; i++)
            {
                foreach (var physics in physicsComponents)
                {
                    if (physics.Awake && physics.CanMove())
                    {
                        UpdatePosition(physics, deltaTime / divisions);
                    }
                }

                for (var j = 0; j < divisions; ++j)
                {
                    if (FixClipping(_collisionCache, divisions))
                    {
                        break;
                    }
                }
            }
        }
        protected void SendForwardMiniguns(ref int idx)
        {
            var data = Screen.GetEntities <MinigunCannon>().ToList();

            if (data.Count == 0)
            {
                return;
            }

            if (idx + 2 >= MAX_PACKAGE_SIZE_BYTES)
            {
                SendAndReset(ref idx);
            }

            MSG_FORWARD[idx] = AREA_MINIGUNS;
            idx++;

            byte arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_MINIGUN);

            int posSize = idx;

            MSG_FORWARD[posSize] = 0xFF;
            idx++;

            int i = 0;

            foreach (var cannon in data)
            {
                if (!ShouldSendData(cannon))
                {
                    continue;
                }

                // [8: ID] [3: Fraction] [5: Boost] [8: RotationActual] [8: RotationTarget] [8: Health] [8:Charge] [8:Shield]

                NetworkDataTools.SetByte(out MSG_FORWARD[idx + 0], cannon.BlueprintCannonID);
                NetworkDataTools.SetSplitByte(out MSG_FORWARD[idx + 1], Screen.GetFractionID(cannon.Fraction), cannon.IntegerBoost, 3, 5, 3, 5);
                NetworkDataTools.SetByte(out MSG_FORWARD[idx + 2], NetworkDataTools.ConvertFromRadians(cannon.Rotation.ActualValue, 8));
                NetworkDataTools.SetByte(out MSG_FORWARD[idx + 3], NetworkDataTools.ConvertFromRadians(cannon.Rotation.TargetValue, 8));
                NetworkDataTools.SetByteFloor(out MSG_FORWARD[idx + 4], FloatMath.Clamp(cannon.CannonHealth.TargetValue, 0f, 1f) * 255);
                NetworkDataTools.SetByteFloor(out MSG_FORWARD[idx + 5], FloatMath.Clamp(cannon.BarrelCharge, 0f, 1f) * 255);
                NetworkDataTools.SetByteFloorRange(out MSG_FORWARD[idx + 6], 0, Cannon.MAX_SHIELD_TIME, cannon.ShieldTime);

                idx += PLEN_MINIGUN;

                i++;
                if (i >= arrsize)
                {
                    MSG_FORWARD[posSize] = (byte)i;
                    SendAndReset(ref idx);
                    MSG_FORWARD[idx] = AREA_MINIGUNS;
                    idx++;
                    i      -= arrsize;
                    arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_MINIGUN);
                    posSize = idx;
                    MSG_FORWARD[posSize] = 0xFF;
                    idx++;
                }
            }
            MSG_FORWARD[posSize] = (byte)i;
        }
Exemple #7
0
        public FPoint ProjectPointOntoLineSegment(FPoint lineStart, FPoint lineEnd)
        {
            float u = FloatMath.Clamp(ProjectOntoLine(lineStart, lineEnd), 0f, 1f);

            return(lineStart + (lineEnd - lineStart) * u);
        }
Exemple #8
0
 private static float LogisticCurve(float x, float slope, float exponent, float yOffset, float xOffset)
 {
     return(FloatMath.Clamp(
                exponent * (1 / (1 + (float)Math.Pow(Math.Log(1000) * slope, -1 * x + xOffset))) + yOffset, 0.0f, 1.0f));
 }
Exemple #9
0
 private static float QuadraticCurve(float x, float slope, float exponent, float yOffset, float xOffset)
 {
     return(FloatMath.Clamp(slope * (float)Math.Pow(x - xOffset, exponent) + yOffset, 0.0f, 1.0f));
 }
Exemple #10
0
        private void ProcessInputs_(ProcessInputsEvent _)
        {
            this.motor_.ClearScheduled();

            var primaryAnalogStick = this.gamepad_[AnalogStickType.PRIMARY];
            var heldAxes           = primaryAnalogStick.RawAxes;
            //var runButton = this.gamepad_[FaceButtonType.SECONDARY];
            var isRunning = true;

            var heldX = FinMath.Abs(heldAxes.X) > GamepadConstants.DEADZONE
                      ? heldAxes.X
                      : 0;

            this.motor_.ScheduleMoveAttempt(heldX, isRunning);

            var heldY             = heldAxes.Y;
            var minHeldDuckAmount = -.75f;

            if (this.stateMachine_.CanDuck)
            {
                var maxHeldDuckAmount = -.25f;
                this.toDuckFraction_ = 1 -
                                       (FloatMath.Clamp(minHeldDuckAmount,
                                                        heldY,
                                                        maxHeldDuckAmount) -
                                        minHeldDuckAmount) /
                                       (maxHeldDuckAmount - minHeldDuckAmount);
            }
            else if (this.stateMachine_.IsDucked)
            {
                this.toDuckFraction_ = 1;
            }
            else
            {
                this.toDuckFraction_ = 0;
            }

            this.duckFraction_ += (this.toDuckFraction_ - this.duckFraction_) / 2;

            if (heldY <= minHeldDuckAmount)
            {
                this.motor_.ScheduleDuckStartAttempt();
            }
            else
            {
                this.motor_.ScheduleDuckStopAttempt();
            }

            var jumpButton = this.gamepad_[FaceButtonType.PRIMARY];

            if (jumpButton.IsPressed)
            {
                this.motor_.ScheduleJumpStartAttempt();
            }
            else if (jumpButton.IsReleased)
            {
                this.motor_.ScheduleJumpStopAttempt();
            }

            this.motor_.ProcessInputs();
        }
Exemple #11
0
        public override FPoint Get(float len)
        {
            len = FloatMath.Clamp(len, 0, Length);

            return(startPoint + direction * len);
        }
Exemple #12
0
        //[MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void HighPressureMovements()
        {
            // TODO ATMOS finish this

            if (PressureDifference > 15)
            {
                if (_soundCooldown == 0)
                {
                    EntitySystem.Get <AudioSystem>().PlayAtCoords("/Audio/Effects/space_wind.ogg",
                                                                  GridIndices.ToGridCoordinates(_mapManager, GridIndex), AudioHelpers.WithVariation(0.125f).WithVolume(FloatMath.Clamp(PressureDifference / 10, 10, 100)));
                }
            }


            foreach (var entity in _entityManager.GetEntitiesIntersecting(_mapManager.GetGrid(GridIndex).ParentMapId, Box2.UnitCentered.Translated(GridIndices)))
            {
                if (!entity.TryGetComponent(out ICollidableComponent physics) ||
                    !entity.TryGetComponent(out MovedByPressureComponent pressure))
                {
                    continue;
                }

                var pressureMovements = physics.EnsureController <HighPressureMovementController>();
                if (pressure.LastHighPressureMovementAirCycle < _gridAtmosphereComponent.UpdateCounter)
                {
                    pressureMovements.ExperiencePressureDifference(_gridAtmosphereComponent.UpdateCounter, PressureDifference, _pressureDirection, 0, PressureSpecificTarget?.GridIndices.ToGridCoordinates(_mapManager, GridIndex) ?? GridCoordinates.InvalidGrid);
                }
            }

            if (PressureDifference > 100)
            {
                // Do space wind graphics here!
            }

            _soundCooldown++;
            if (_soundCooldown > 75)
            {
                _soundCooldown = 0;
            }
        }
Exemple #13
0
        protected override void LayoutUpdateOverride()
        {
            base.LayoutUpdateOverride();

            if (ChildCount != 2)
            {
                return;
            }

            var first  = GetChild(0);
            var second = GetChild(1);

            var firstExpand = Vertical
                ? (first.SizeFlagsVertical & SizeFlags.Expand) != 0
                : (first.SizeFlagsHorizontal & SizeFlags.Expand) != 0;
            var secondExpand = Vertical
                ? (second.SizeFlagsVertical & SizeFlags.Expand) != 0
                : (second.SizeFlagsHorizontal & SizeFlags.Expand) != 0;

            var firstMinSize  = Vertical ? first.CombinedMinimumSize.Y : first.CombinedMinimumSize.X;
            var secondMinSize = Vertical ? second.CombinedMinimumSize.Y : second.CombinedMinimumSize.X;

            var size = Vertical ? Height : Width;

            var ratio = first.SizeFlagsStretchRatio / (first.SizeFlagsStretchRatio + second.SizeFlagsStretchRatio);

            switch (_splitState)
            {
            case SplitState.Manual:
                // min sizes of children may have changed, ensure the offset still respects the defined limits
                _splitCenter = ClampSplitCenter(_splitCenter, firstMinSize, secondMinSize);
                break;

            case SplitState.Auto:
            {
                if (firstExpand && secondExpand)
                {
                    _splitCenter = size * ratio - SplitWidth / 2;
                }
                else if (firstExpand)
                {
                    _splitCenter = size - secondMinSize - SplitWidth;
                }
                else
                {
                    _splitCenter = firstMinSize;
                }

                _splitCenter += FloatMath.Clamp(0f, firstMinSize - _splitCenter, size - secondMinSize - SplitWidth - _splitCenter);
                break;
            }
            }

            if (Vertical)
            {
                FitChildInBox(first, new UIBox2(0, 0, Width, _splitCenter));
                FitChildInBox(second, new UIBox2(0, _splitCenter + SplitWidth, Width, Height));
            }
            else
            {
                FitChildInBox(first, new UIBox2(0, 0, _splitCenter, Height));
                FitChildInBox(second, new UIBox2(_splitCenter + SplitWidth, 0, Width, Height));
            }
        }
Exemple #14
0
 protected override void Set(float value) =>
 this.impl_ = FloatMath.Clamp(this.Min, value, this.Max);