Example #1
0
        public virtual bool RunProjectileImpact(Projectile projectile)
        {
            // Some projectiles get destroyed on collision.
            if (projectile.CollisionType == ProjectileCollisionType.DestroyOnCollide)
            {
                projectile.Destroy();
                return(true);
            }

            // Some projectiles bounce.
            if (projectile.CollisionType == ProjectileCollisionType.BounceOnFloor)
            {
                DirCardinal dir = CollideDetect.GetDirectionOfCollision(projectile, this);

                if (dir == DirCardinal.Down)
                {
                    projectile.physics.AlignUp(this);
                    projectile.BounceOnGround();
                    return(false);
                }

                projectile.Destroy(dir);
                return(true);
            }

            // Standard Collision
            return(false);
        }
Example #2
0
        // Shell is Below
        public override bool CollideObjUp(GameObject obj)
        {
            // Collides with another shell.
            if (obj is Shell)
            {
                if (obj.physics.velocity.X == 0 && obj.physics.velocity.Y == 0)
                {
                    obj.Destroy(); return(false);
                }
                else
                {
                    this.Destroy(); return(false);
                }
            }

            // If the Shell is stationary:
            if (this.physics.velocity.X == 0 && this.physics.velocity.Y.RoundInt == 0)
            {
                if (obj is Character)
                {
                    Character character = (Character)obj;
                    character.heldItem.KickItem(this, character.FaceRight ? DirCardinal.Right : DirCardinal.Left);
                    ActionMap.Jump.StartAction(character, 2, 0, 4, true);
                    return(true);
                }

                if (obj is Enemy)
                {
                    Enemy enemy = (Enemy)obj;
                    enemy.BounceUp(enemy.posX + enemy.bounds.MidX, 2);
                }

                // Start Shell Moving
                int xDiff = CollideDetect.GetRelativeX(this, obj);
                this.physics.velocity.X = FInt.Create(xDiff > 0 ? this.KickStrength : -this.KickStrength);
                this.room.PlaySound(Systems.sounds.shellBoop, 0.2f, this.posX + 16, this.posY + 16);
                this.animate.SetAnimation(null, this.physics.velocity.X > 0 ? AnimCycleMap.Cycle4 : AnimCycleMap.Cycle4Reverse, 7, 1);

                return(false);
            }

            // If the Shell is moving:

            // Character will end the shell's movement and jump upward.
            if (obj is Character)
            {
                ActionMap.Jump.StartAction((Character)obj, 4, 0, 4, true);
                this.physics.StopX();
                this.animate.DisableAnimation();
                return(base.CollideObjUp(obj));
            }

            // Damage Enemies
            if (obj is Enemy)
            {
                ((Enemy)obj).ReceiveWound();
            }

            return(false);
        }
Example #3
0
        public override bool RunCharacterImpact(Character character)
        {
            DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, this);

            if (dir == DirCardinal.Down && this.subType == (byte)GhostSubType.Hat)
            {
                ActionMap.Jump.StartAction(character, 2, 0, 4, true);
            }
            else
            {
                if (this.subType != (byte)GhostSubType.Hide)
                {
                    if (this.subType == (byte)GhostSubType.Hat && this.posY - character.posY > 25)
                    {
                        return(false);
                    }
                    character.wounds.ReceiveWoundDamage(DamageStrength.Standard);
                }
            }

            if (this.subType == (byte)GhostSubType.Slimer)
            {
                return(Impact.StandardImpact(character, this, dir));
            }

            return(false);
        }
Example #4
0
        public override bool RunCharacterImpact(Character character)
        {
            DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, this);

            if (dir == DirCardinal.Left)
            {
                TileCharBasicImpact.RunWallImpact(character, dir, DirCardinal.None);
            }
            else if (dir == DirCardinal.Right)
            {
                TileCharBasicImpact.RunWallImpact(character, dir, DirCardinal.None);
            }

            // Character is Beneath
            else if (dir == DirCardinal.Up)
            {
                if (this.physics.velocity.Y > 0)
                {
                    character.wounds.ReceiveWoundDamage(DamageStrength.Standard);

                    // Will kill if character is on ground.
                    if (character.physics.touch.toBottom)
                    {
                        character.wounds.ReceiveWoundDamage(DamageStrength.InstantKill);
                        return(true);
                    }
                }

                TileCharBasicImpact.RunWallImpact(character, dir, DirCardinal.None);
            }

            return(Impact.StandardImpact(character, this, dir));
        }
Example #5
0
        public void CollisionDetection()
        {
            Character ch   = this.character;
            Physics   phys = ch.physics;

            // Setup Character
            phys.StopX(); phys.StopY();           // Reset the Character's Velocity
            phys.MoveToPos(600, 300);             // Reset the Character's Position
            phys.SetGravity(FInt.Create(0));
            phys.intend = FVector.Create(3, 3);

            // Setup Shroom
            Shroom shroom = new Shroom(this.roomScene, (byte)ShroomSubType.Black, FVector.Create(700, 300), null);

            shroom.physics.intend = FVector.Create(-1, -1);

            // Confirm that Physics Alignments, IsOverlapping, GetOverlapX, GetOverlapY are working correctly:
            shroom.physics.AlignRight(ch);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == false);

            shroom.physics.MoveToPosX(shroom.posX - 1);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == true);
            Debug.Assert(CollideDetect.GetOverlapX(ch, shroom, true) == 1);

            shroom.physics.AlignLeft(ch);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == false);

            shroom.physics.MoveToPosX(shroom.posX + 1);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == true);
            Debug.Assert(CollideDetect.GetOverlapX(shroom, ch, true) == 1);

            shroom.physics.AlignUp(ch);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == false);

            shroom.physics.MoveToPosY(shroom.posY + 1);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == true);
            Debug.Assert(CollideDetect.GetOverlapY(shroom, ch, true) == 1);

            shroom.physics.AlignDown(ch);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == false);

            shroom.physics.MoveToPosY(shroom.posY - 1);
            Debug.Assert(CollideDetect.IsOverlapping(ch, shroom) == true);
            Debug.Assert(CollideDetect.GetOverlapY(ch, shroom, true) == 1);

            // Move Away (no longer overlapping, off by 2)
            shroom.physics.MoveToPosY(shroom.posY + 3);
            Debug.Assert(CollideDetect.GetOverlapY(ch, shroom, true) == -2);
        }
Example #6
0
        public virtual bool RunProjectileImpact(Projectile projectile)
        {
            // Can only be damaged if the projectile was cast by a Character.
            if (projectile.ByCharacterId == 0)
            {
                return(false);
            }

            // Special behavior for Magi-Balls. Projectiles faded out don't function.
            if (projectile is ProjectileMagi)
            {
                ProjectileMagi magi = (ProjectileMagi)projectile;
                if (!magi.CanDamage)
                {
                    return(false);
                }
            }

            // Check if the enemy is resistant to the projectile. In most cases, destroy the projectile without harming the enemy.
            bool canResist = this.CanResistDamage(projectile.Damage);

            // If the projectile typicallly passes through walls, allow it to pass through indestructable enemies.
            if (canResist && projectile.CollisionType <= ProjectileCollisionType.IgnoreWallsDestroy)
            {
                return(false);
            }

            DirCardinal dir = CollideDetect.GetDirectionOfCollision(projectile, this);

            // Destroy the Projectile (unless it ignores walls)
            if (projectile.CollisionType != ProjectileCollisionType.IgnoreWallsSurvive || projectile is ProjectileMagi)
            {
                projectile.Destroy(dir);
            }

            // Wound the Enemy
            if (!canResist)
            {
                this.ReceiveWound();
            }

            return(true);
        }
Example #7
0
        public virtual bool RunCharacterImpact(Character character)
        {
            DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, this);

            if (dir == DirCardinal.Down)
            {
                this.GetJumpedOn(character);
            }

            else if (character.hat is SpikeyHat && dir == DirCardinal.Up)
            {
                this.ReceiveWound();
            }

            else
            {
                character.wounds.ReceiveWoundDamage(DamageStrength.Standard);
            }

            return(Impact.StandardImpact(character, this, dir));
        }
Example #8
0
        public bool RunCharacterImpact(Character character)
        {
            // Don't allow interaction if it's too recent.
            if (this.lastTouchId == character.id && this.lastTouchFrame + 20 > Systems.timer.Frame)
            {
                return(false);
            }
            else if (this.lastTouchFrame + 2 > Systems.timer.Frame)
            {
                return(false);
            }

            DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, this);

            // Update Last Touch Details
            this.lastTouchFrame = Systems.timer.Frame;
            this.lastTouchId    = character.id;

            var  xVelHalf = character.physics.velocity.X.RoundInt * 0.5f;
            FInt boost    = FInt.Create(Math.Abs(Math.Round(xVelHalf)));

            sbyte kickBoost  = (sbyte)(this.KickStrength + boost);
            sbyte throwBoost = (sbyte)(this.ThrowStrength + boost + (byte)Math.Round(Math.Abs(character.physics.velocity.Y.RoundInt) * 0.5f));

            // Holding Up increases throw strength. Holding Down is "dribble" and reduces throw + kick strength.
            if (character.input.isDown(IKey.Up))
            {
                throwBoost += 4;
            }
            else if (character.input.isDown(IKey.Down))
            {
                throwBoost -= 4; kickBoost = (sbyte)boost.RoundInt;
            }

            // Facing the same direction as the sport ball increases strength, and vice versa.
            if (dir == DirCardinal.Right)
            {
                if (character.FaceRight)
                {
                    kickBoost += 2; throwBoost += 1;
                }
                else
                {
                    this.CollidePosLeft(character.posX + character.bounds.Right);

                    // Boost the ball in the direction based on character speed, if character moving toward ball.
                    if (character.physics.velocity.X.RoundInt > 0)
                    {
                        this.physics.velocity.X += boost;
                    }

                    return(true);
                }

                // Holding toward direction of ball increases kick strength.
                if (character.input.isDown(IKey.Right))
                {
                    kickBoost += 2;
                }
            }

            else if (dir == DirCardinal.Left)
            {
                if (!character.FaceRight)
                {
                    kickBoost += 2; throwBoost += 1;
                }
                else
                {
                    this.CollidePosRight(character.posX + character.bounds.Left - this.bounds.Right);

                    // Boost the ball in the direction based on character speed, if character moving toward ball.
                    if (character.physics.velocity.X.RoundInt > 0)
                    {
                        this.physics.velocity.X -= boost;
                    }

                    return(true);
                }

                // Holding toward direction of ball increases kick strength.
                if (character.input.isDown(IKey.Left))
                {
                    kickBoost += 2;
                }
            }

            // Holding A Button and/or Y Button increases kick strength.
            if (character.input.isDown(IKey.AButton))
            {
                kickBoost += 2;
            }
            if (character.input.isDown(IKey.YButton))
            {
                kickBoost += 2;
            }
            if (character.input.isDown(IKey.BButton))
            {
                throwBoost += 2;
            }

            // Vertical Collisions affect throw boost.
            if (dir == DirCardinal.Up)
            {
                throwBoost += 4;
            }
            else if (dir == DirCardinal.Down)
            {
                throwBoost -= 4;
            }

            if (throwBoost < 0)
            {
                throwBoost = 0;
            }

            // Horizontal Hits
            if (dir == DirCardinal.Right)
            {
                this.physics.velocity.X += kickBoost;
                this.physics.velocity.Y -= throwBoost;
                return(false);
            }
            else if (dir == DirCardinal.Left)
            {
                this.physics.velocity.X -= kickBoost;
                this.physics.velocity.Y -= throwBoost;
                return(false);
            }

            // Vertical Hits
            if (dir == DirCardinal.Down)
            {
                this.physics.velocity.X += FInt.Create(xVelHalf * 2);
                this.physics.velocity.Y += throwBoost;
            }
            else if (dir == DirCardinal.Up)
            {
                this.physics.velocity.X += FInt.Create(xVelHalf * 2);
                this.physics.velocity.Y  = FInt.Create(-throwBoost);
            }

            return(false);
        }
Example #9
0
        public void Step()
        {
            if (!GameIdle)
            {
                return;
            }

            List <AbstrUnit> ToRemoveList = new List <AbstrUnit>();

            Inform.Step();

            foreach (var unit in Factory.Units.Where(u => (u is IMovable)))
            {
                if (!GameIdle)
                {
                    break;
                }

                if (unit is IMovable)
                {
                    bool move = true;
                    foreach (var obj in Factory.Units.Where(u => (u is ISolid)))
                    {
                        if (unit is ISolid && !(obj == unit))
                        {
                            if (obj is Area && unit is Actor)
                            {
                                if (CollideDetect.TestCollide((unit as ISolid), obj as ISolid))
                                {
                                    switch ((obj as Area).Type)
                                    {
                                    case Areas.Exit:
                                        GameStop();
                                        curMap += 1;
                                        System.Windows.Forms.MessageBox.Show("Win!!!\n" + Inform.GetString());
                                        break;

                                    case Areas.Coin:
                                        (obj as Area).Dispose();
                                        Inform.AddScore();
                                        ToRemoveList.Add(obj);
                                        break;

                                    case Areas.Dmg:
                                        Inform.AddSolidScore(-1);
                                        Inform.ClearScore();
                                        GameStop();
                                        break;
                                    }
                                }
                            }

                            else
                            if (!(obj is Area) && CollideDetect.TestMoveCollide((unit as IMovable), obj as ISolid))
                            {
                                move = false;
                            }
                        }
                    }

                    if (move)
                    {
                        (unit as IMovable).Move();
                    }
                    if (!move && unit is EVR)
                    {
                        (unit as EVR).ChangeDir();
                    }
                }
            }

            if (ToRemoveList.Count > 0)
            {
                foreach (var obj in ToRemoveList)
                {
                    Factory.Units.Remove(obj);
                }
                ToRemoveList.Clear();
            }

            if (!GameIdle)
            {
                if (curMap < Maps.Count)
                {
                    Inform.Pause();
                    LoadMap(curMap);
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("fin");
                }
            }
        }