コード例 #1
0
ファイル: TankGame.cs プロジェクト: Willco2/MultiTanks
        public static void FinishPickingColor(Vector3 color)           // Called from ColorPicker client, tells server what color the player chose
        {
            var cl = ConsoleSystem.Caller;

            cl.Camera = null;             // Remove client's priority camera so Pawn camera can be used
            cl.SetScore("mtk_customcolor", color);

            var player = new TankPlayer();

            cl.Pawn = player;
            player.Respawn();
        }
コード例 #2
0
        public override void OnPlayerControlTick(TankPlayer player, bool allowDebug)
        {
            Position = player.Base.Position;
            if (Input.Down(InputButton.Jump))
            {
                return;
            }

            if (frameCount < 5)               // Wait for server to tell client which way we're actually facing
            {
                frameCount++;
                return;
            }

            var desiredHeadRot = Rotation.FromYaw(Input.Rotation.Yaw());

            Rotation = Rotation.Lerp(Rotation, desiredHeadRot, Time.Delta * HeadSpinSpeed);
        }
コード例 #3
0
ファイル: TankCannon.cs プロジェクト: Willco2/MultiTanks
        public void FireRocket(TankPlayer player, Vector3 cannonEnd)
        {
            timeSinceCannonFire = 0;
            if (!Host.IsServer)
            {
                return;
            }
            var rocket = new Rocket {
                Position    = cannonEnd,
                Rotation    = Rotation,
                Shooter     = player,
                RenderColor = player.GetClientOwner().GetScore("mtk_customcolor", Vector3.Zero).ToColor().ToColor32()
            };

            rocket.SetupPhysicsFromModel(PhysicsMotionType.Keyframed);

            using (Prediction.Off()) {
                Particles.Create("particles/tank_shoot.vpcf", cannonEnd).SetForward(0, Rotation.Forward);
                Sound.FromWorld("shoot", cannonEnd);
            }
        }
コード例 #4
0
ファイル: TankCannon.cs プロジェクト: Willco2/MultiTanks
        public override void OnPlayerControlTick(TankPlayer player, bool allowDebug)
        {
            var extents        = CollisionBounds.Maxs;
            var cannonEndLocal = extents.WithY(0) + Vector3.Down * 4;
            var cannonStart    = player.Base.Position + cannonEndLocal.WithX(0);
            var cannonEnd      = player.Base.Position + player.Head.Rotation * cannonEndLocal;
            var cannonTr       = Trace.Ray(cannonStart, cannonEnd).Radius(4).WithoutTags("rocket").Run();

            if (allowDebug)
            {
                DebugOverlay.Sphere(cannonTr.EndPos, 4, cannonTr.Hit ? Color.Red : Color.Green, true);
                DebugOverlay.Line(cannonStart, cannonEnd, Color.Blue, 0, false);
            }

            float retractTime = CannonCooldown * 0.1f, expandTime = CannonCooldown * 0.6f, cannonRecoilDistance = 16;
            float cannonRecoilOffset = 0;

            if (timeSinceCannonFire < retractTime)               // Retracting
            {
                cannonRecoilOffset = cannonRecoilDistance * (timeSinceCannonFire / retractTime);
            }
            else if (timeSinceCannonFire < expandTime + retractTime)                 // Expanding
            {
                cannonRecoilOffset = cannonRecoilDistance - cannonRecoilDistance * ((timeSinceCannonFire - retractTime) / expandTime);
            }

            cannonRecoilOffset *= MathF.Pow(cannonTr.Distance / extents.x, 2);             // Reduces recoil the more the cannon is pushed in due to collision
            float cannonOffset = (cannonRecoilOffset - cannonTr.Distance).Clamp(float.MinValue, -28.5f);

            LocalPosition = Vector3.Backward * (extents.x + cannonOffset);

            if (Input.Down(InputButton.Attack1) && timeSinceCannonFire > CannonCooldown)
            {
                cannonEnd = Position + player.Head.Rotation * cannonEndLocal;                 // Recalc cannon end after recoil and retracting was applied
                FireRocket(player, cannonEnd);
            }
        }
コード例 #5
0
        public override void OnPlayerControlTick(TankPlayer player, bool allowDebug)
        {
            float throttle  = Input.Forward;
            float steering  = Input.Left * (throttle >= 0 ? 1 : -1) * TurnSpeed;
            var   moveDelta = Rotation.Forward * throttle * MoveSpeed;

            // Corner world position
            var frontLeft  = moveDelta + Position + Rotation * (extents * new Vector3(1, 1, 0.5f));
            var frontRight = moveDelta + Position + Rotation * (extents * new Vector3(1, -1, 0.5f));
            var backLeft   = moveDelta + Position + Rotation * (extents * new Vector3(-1, 1, 0.5f));
            var backRight  = moveDelta + Position + Rotation * extents * new Vector3(-1, -1, 0.5f);
            var center     = moveDelta + Position + extents * new Vector3(0, 0, 0.5f);

            // Base world directions
            var frontDir      = Rotation.Forward;
            var leftDir       = Rotation.Left;
            var backDir       = Rotation.Backward;
            var rightDir      = Rotation.Right;
            var frontLeftDir  = (frontDir + leftDir).Normal;
            var frontRightDir = (frontDir + rightDir).Normal;
            var backLeftDir   = (backDir + leftDir).Normal;
            var backRightDir  = (backDir + rightDir).Normal;

            float testDistance = 2 * MoveSpeed;

            if (allowDebug)
            {
                /*DebugOverlay.Axis(frontLeft, Rotation);
                *  DebugOverlay.Axis(frontRight, Rotation);
                *  DebugOverlay.Axis(backLeft, Rotation);
                *  DebugOverlay.Axis(backRight, Rotation);*/
                DebugOverlay.Sphere(frontLeft, testDistance, Color.Red);
                DebugOverlay.Sphere(frontRight, testDistance, Color.Red);
                DebugOverlay.Sphere(backLeft, testDistance, Color.Red);
                DebugOverlay.Sphere(backRight, testDistance, Color.Red);
            }

            var cornerResults = new TraceResult[12];

            cornerResults[0]  = Trace.Ray(frontLeft, frontLeft + frontDir * testDistance).Run();           // Forward
            cornerResults[1]  = Trace.Ray(frontLeft, frontLeft + leftDir * testDistance).Run();            // Side
            cornerResults[2]  = Trace.Ray(frontLeft, frontLeft + frontRightDir * testDistance).Run();      // Diagonal inward
            cornerResults[3]  = Trace.Ray(frontRight, frontRight + frontDir * testDistance).Run();
            cornerResults[4]  = Trace.Ray(frontRight, frontRight + rightDir * testDistance).Run();
            cornerResults[5]  = Trace.Ray(frontRight, frontRight + frontLeftDir * testDistance).Run();
            cornerResults[6]  = Trace.Ray(backLeft, backLeft + backDir * testDistance).Run();
            cornerResults[7]  = Trace.Ray(backLeft, backLeft + leftDir * testDistance).Run();
            cornerResults[8]  = Trace.Ray(backLeft, backLeft + backRightDir * testDistance).Run();
            cornerResults[9]  = Trace.Ray(backRight, backRight + backDir * testDistance).Run();
            cornerResults[10] = Trace.Ray(backRight, backRight + rightDir * testDistance).Run();
            cornerResults[11] = Trace.Ray(backRight, backRight + backLeftDir * testDistance).Run();

            // Turn off movement and don't collide if both front or back corners are colliding (but only if pushing against an axis-aligned wall)
            bool  noMove = (cornerResults[0].Hit && cornerResults[3].Hit) || (cornerResults[6].Hit && cornerResults[9].Hit);
            float yaw    = Rotation.Yaw();

            noMove &= yaw.SnapToGrid(90).AlmostEqual(yaw, 2);
            if (noMove)
            {
                moveDelta = 0;
            }

            for (int i = 0; i < cornerResults.Length; i++)
            {
                var result = cornerResults[i];
                if (!result.Hit)
                {
                    if (allowDebug)
                    {
                        DebugOverlay.Line(result.StartPos, result.StartPos + result.Direction * testDistance * 8, Color.Green, 0, false);
                    }
                    continue;
                }
                if (i % 3 != 0 && cornerResults[i - (i % 3)].Hit)                   // Skip the side and diagonal tests if the primary one already hit
                {
                    if (allowDebug)
                    {
                        DebugOverlay.Line(result.StartPos, result.StartPos + result.Direction * testDistance * 8, Color.Yellow, 0, false);
                    }
                    continue;
                }
                if (i % 3 == 0 && noMove)
                {
                    continue;
                }
                if (allowDebug)
                {
                    DebugOverlay.Line(result.StartPos, result.StartPos + result.Direction * testDistance * 8, Color.Red, 0, false);
                }

                Position += result.Normal * (testDistance - result.Distance);
                float torque = Vector3.Cross(result.StartPos - center, result.Normal).z *Time.Delta;
                Rotation *= Rotation.FromYaw(torque);
                if (allowDebug)
                {
                    DebugOverlay.Line(result.EndPos, result.EndPos + result.Normal * MathF.Abs(torque) * 50, Color.Blue, 0, false);
                }
            }

            var edgeResults = new TraceResult[8];

            edgeResults[0] = Trace.Ray(frontLeft, frontRight).Run();
            edgeResults[2] = Trace.Ray(backLeft, backRight).Run();
            edgeResults[4] = Trace.Ray(frontLeft, backLeft).Run();
            edgeResults[6] = Trace.Ray(frontRight, backRight).Run();

            for (int i = 0; i < edgeResults.Length; i += 2)
            {
                var result = edgeResults[i];
                if (result.Hit)                   // Only run the partner trace if the first one on that edge hits
                {
                    if (i == 0)
                    {
                        edgeResults[i + 1] = Trace.Ray(frontRight, frontLeft).Run();
                    }
                    else if (i == 2)
                    {
                        edgeResults[i + 1] = Trace.Ray(backRight, backLeft).Run();
                    }
                    else if (i == 4)
                    {
                        edgeResults[i + 1] = Trace.Ray(backLeft, frontLeft).Run();
                    }
                    else if (i == 6)
                    {
                        edgeResults[i + 1] = Trace.Ray(backRight, frontRight).Run();
                    }
                }
                else
                {
                    continue;
                }

                if (allowDebug)
                {
                    DebugOverlay.Line(result.StartPos, result.EndPos, 0, false);
                }
                Vector3 correctionDir = Vector3.Zero;
                if (i == 0)
                {
                    correctionDir = frontDir;
                }
                else if (i == 2)
                {
                    correctionDir = backDir;
                }
                else if (i == 4)
                {
                    correctionDir = leftDir;
                }
                else if (i == 6)
                {
                    correctionDir = rightDir;
                }

                float distance = Vector3.DistanceBetween(result.EndPos, edgeResults[i + 1].EndPos);
                float angle    = Vector3.GetAngle(result.EndPos - result.StartPos, result.Normal) - 90;

                float correction = distance * 0.5f * MathF.Sin(2 * angle.DegreeToRadian());                 // How much to push out of the corner, finds the altitude of a right triangle
                Position -= correctionDir * correction;

                var   avgPos = (result.EndPos + edgeResults[i + 1].EndPos) * 0.5f;
                float torque = Vector3.Cross(avgPos - center, -correctionDir).z *Time.Delta;
                Rotation *= Rotation.FromYaw(torque);

                if (allowDebug)
                {
                    DebugOverlay.Line(avgPos, avgPos - correctionDir * MathF.Abs(torque) * 50, Color.Cyan, 0, false);
                    DebugOverlay.Line(result.EndPos, edgeResults[i + 1].EndPos, Color.Red, 0, false);
                    DebugOverlay.Line(result.EndPos, result.EndPos + correctionDir * correction * 10, Color.Green, 0, false);
                    DebugOverlay.Line(edgeResults[i + 1].EndPos, edgeResults[i + 1].EndPos + correctionDir * correction * 10, Color.Green, 0, false);
                }
            }

            moveDelta = moveDelta.WithZ(0);
            Position += moveDelta;
            Rotation *= Rotation.FromYaw(steering);
        }
コード例 #6
0
ファイル: PlayerEntity.cs プロジェクト: Willco2/MultiTanks
 public abstract void OnPlayerControlTick(TankPlayer player, bool allowDebug);