private void OnPlayerGetThrownFromGrab(IPlayer thrownPlayer)
        {
            if (!Player.IsBot && !IsThrowingFromGrab)
            {
                return;
            }

            var grabPosition = thrownPlayer.GetWorldPosition();
            var targets      = GetThrowTargets(thrownPlayer.UniqueID);

            foreach (var target in targets)
            {
                var results = Game.RayCast(grabPosition, target.GetWorldPosition(), new RayCastInput()
                {
                    FilterOnMaskBits = true,
                    AbsorbProjectile = RayCastFilterMode.True,
                    MaskBits         = CategoryBits.Player + CategoryBits.StaticGround,
                    ClosestHitOnly   = true,
                }).Where(r => r.HitObject != null && r.ObjectID != thrownPlayer.UniqueID);

                if (results.Any())
                {
                    var result = results.Single();

                    if (result.IsPlayer)
                    {
                        var hitObject      = result.HitObject;
                        var throwDirection = Vector2.Normalize(hitObject.GetWorldPosition() - grabPosition);
                        var throwTime      = Game.TotalElapsedGameTime;

                        Game.DrawArea(hitObject.GetAABB(), Color.Cyan);
                        Game.DrawLine(grabPosition, grabPosition + throwDirection * 30, Color.Cyan);
                        thrownPlayer.SetLinearVelocity(throwDirection * 20 + Vector2.UnitY * 4);
                        thrownPlayer.TrackAsMissile(true);

                        Events.PlayerDamageCallback damageCB = null;
                        damageCB = Events.PlayerDamageCallback.Start((IPlayer player, PlayerDamageArgs args) =>
                        {
                            if (thrownPlayer.IsRemoved ||
                                !thrownPlayer.IsMissile && player.UniqueID != thrownPlayer.UniqueID ||
                                ScriptHelper.IsElapsed(throwTime, 2000))
                            {
                                damageCB.Stop();
                            }
                            if (thrownPlayer.GetAABB().Intersects(player.GetAABB()) && args.DamageType == PlayerDamageEventType.Fall)
                            {
                                var velocity = player.GetLinearVelocity() * 1.75f;
                                velocity.Y   = Math.Max(4f, velocity.Y + 4f); // bounce up a little to counter the friction
                                velocity     = MathExtension.ClampMagnitude(velocity, 20);
                                player.SetLinearVelocity(velocity);
                            }
                        });
                    }
                    return;
                }
            }
        }
Example #2
0
        public override void OnProjectileHit(ProjectileHitArgs args)
        {
            base.OnProjectileHit(args);

            var hitObject = GetObject(args);

            if (!args.IsPlayer && hitObject.GetBodyType() == BodyType.Static)
            {
                return;
            }

            var angles = new float[] { MathExtension.ToRadians(35), MathExtension.ToRadians(70) };
            var angle  = MathExtension.NormalizeAngle(ScriptHelper.GetAngle(Instance.Direction));

            if (angle > MathHelper.PIOver2 && angle <= MathExtension.PI_3Over2)
            {
                angles = ScriptHelper.Flip(angles, FlipDirection.Horizontal);
            }

            var position      = Instance.Position;
            var pushDirection = Instance.Direction;
            var upDirection   = RandomHelper.Direction(angles[0], angles[1], true);
            var modifiers     = GetForceModifier();
            var velocity      = hitObject.GetLinearVelocity();

            if (args.IsPlayer)
            {
                velocity += Instance.Direction * 4 + upDirection * 14 * modifiers;
                hitObject.SetLinearVelocity(MathExtension.ClampMagnitude(velocity, 15));
            }
            else
            {
                var mass      = hitObject.GetMass();
                var magnitude = MathHelper.Clamp(1f / mass / 7f, 3, 30) * modifiers;
                velocity += Instance.Direction * magnitude + upDirection * magnitude / 10;
                hitObject.SetLinearVelocity(velocity);
                //ScriptHelper.LogDebug(hitObject.Name, mass, magnitude);
            }

            //if (Game.IsEditorTest)
            //{
            //    ScriptHelper.RunIn(() =>
            //    {
            //        if (args.IsPlayer)
            //            Game.DrawText(modifiers.ToString(), position);
            //        Game.DrawLine(position, position + pushDirection * 3);
            //        Game.DrawLine(position, position + upDirection * 3, Color.Yellow);
            //        Game.DrawLine(position, position + velocity, Color.Green);
            //    }, 2000);
            //}
        }