Exemple #1
0
        public void DropItem()
        {
            if (this.objHeld == null)
            {
                return;
            }

            Item item = this.objHeld;

            item.intangible = Systems.timer.Frame + 7;

            // Check what Main Layer has present at the throw-release tile:
            TilemapLevel tilemap = this.character.room.tilemap;

            bool isBlocked = false;
            bool faceRight = this.character.FaceRight;

            isBlocked = CollideTile.IsBlockingSquare(tilemap, faceRight ? item.GridX2 : item.GridX, item.GridY, DirCardinal.Up);

            // If the drop tiles are blocked, see if we can drop it in the tile below.
            if (isBlocked)
            {
                int limitY = item.GridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.TileHeight;
                int dist   = limitY - (item.posY + item.bounds.Top);

                // If we only have to drop it 24 pixels (or less), we can just lower the item slightly.
                if (dist < 24)
                {
                    item.physics.MoveToPosY(limitY - item.bounds.Top);
                    isBlocked = CollideTile.IsBlockingSquare(tilemap, faceRight ? item.GridX2 : item.GridX, item.GridY, DirCardinal.Up);
                }
            }

            // If the tile is still blocked, then a Y-reposition didn't work. We'll have to move it to character's tile.
            if (isBlocked)
            {
                int limitX;

                // NOTE: MUST have it like this. I don't understand the nuanced difference here, but it works.
                if (faceRight)
                {
                    limitX = item.GridX2 * (byte)TilemapEnum.TileWidth;
                }
                else
                {
                    limitX = item.GridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.TileWidth;
                }

                item.physics.MoveToPosX(limitX - (faceRight ? item.bounds.Right : item.bounds.Left));
            }

            // Assign Minimal Drop Physics (to smooth natural look)
            item.physics.velocity.X = FInt.Create(this.character.physics.velocity.X.RoundInt / 3);
            item.physics.velocity.Y = FInt.Create(-1.5);

            // Play Drop Sound
            this.character.room.PlaySound(Systems.sounds.wooshSubtle, 0.5f, this.character.posX + 16, this.character.posY + 16);

            this.ResetHeldItem();
        }
Exemple #2
0
        private void DetermineSlamDistance()
        {
            TilemapLevel tilemap = this.actor.room.tilemap;

            // We know the slammer's starting position.
            short gridX = this.actor.GridX;
            short gridY = this.actor.GridY;

            this.viewY      = this.actor.posY + ((byte)TilemapEnum.TileHeight * 2);
            this.viewHeight = 0;

            // Scan for solid tiles beneath the slammer, up to 17 below (for a full screen)
            for (short testY = (short)(gridY + 2); testY < gridY + 19; testY++)
            {
                if (testY > tilemap.YCount + (byte)TilemapEnum.GapUp)
                {
                    return;
                }

                // If there is a blocking tile at this height below the slammer, we can determine it's final Y-position after a slam:
                if (CollideTile.IsBlockingSquare(tilemap, gridX, testY, DirCardinal.Up) || CollideTile.IsBlockingSquare(tilemap, (short)(gridX + 1), testY, DirCardinal.Up))
                {
                    this.endY       = testY * (byte)TilemapEnum.TileHeight;
                    this.viewHeight = (short)(this.endY - this.viewY - 10);
                    break;
                }
            }
        }
Exemple #3
0
 public TestTileCollisions()
 {
     this.levelScene = (LevelScene)Systems.scene;
     this.roomScene  = (RoomScene)this.levelScene.rooms[0];
     this.character  = Systems.localServer.MyCharacter;
     this.tilemap    = this.roomScene.tilemap;
 }
Exemple #4
0
        private void DoTeleport()
        {
            CharacterStatus status = this.character.status;

            // End the Teleport Action (to prevent re-teleportation)
            this.character.status.action.EndAction(this.character);

            // Get X, Y Coordinates from Distance and Radian
            float trueRotation = Radians.Normalize(status.actionFloat1);
            int   xCoord       = (int)Radians.GetXFromRotation(trueRotation, status.actionNum1) + character.posX + character.bounds.MidX;
            int   yCoord       = (int)Radians.GetYFromRotation(trueRotation, status.actionNum1) + character.posY + character.bounds.MidY;

            // Make sure teleportation is within world bounds.
            if (yCoord < (byte)TilemapEnum.GapUpPixel || yCoord > this.character.room.Height + (byte)TilemapEnum.GapUpPixel || xCoord < (byte)TilemapEnum.GapLeftPixel || xCoord > this.character.room.Width + (byte)TilemapEnum.GapRightPixel)
            {
                this.character.room.PlaySound(Systems.sounds.disableCollectable, 0.5f, this.character.posX + 16, this.character.posY + 16);
                return;
            }

            TilemapLevel tilemap = character.room.tilemap;

            // Make sure teleportation is to a valid open area. Blocking tiles will prevent teleportation.
            int xMid = xCoord - this.character.bounds.MidX;
            int yMid = yCoord - this.character.bounds.MidY;

            bool upLeft    = CollideTile.IsBlockingCoord(tilemap, xMid + character.bounds.Left, yMid + character.bounds.Top - 1, DirCardinal.None);
            bool upRight   = CollideTile.IsBlockingCoord(tilemap, xMid + character.bounds.Right, yMid + character.bounds.Bottom - 1, DirCardinal.None);
            bool downLeft  = CollideTile.IsBlockingCoord(tilemap, xMid + character.bounds.Left, yMid + character.bounds.Top - 1, DirCardinal.None);
            bool downRight = CollideTile.IsBlockingCoord(tilemap, xMid + character.bounds.Right, yMid + character.bounds.Bottom - 1, DirCardinal.None);

            // If all positions are blocked, prevent teleport.
            if (upLeft && upRight && downLeft && downRight)
            {
                this.character.room.PlaySound(Systems.sounds.disableCollectable, 0.5f, this.character.posX + 16, this.character.posY + 16);
                return;
            }

            // If some positions are blocked, adjust position:
            if (upLeft && downLeft)
            {
                xMid += 12;
            }
            if (upRight && downRight)
            {
                xMid -= 12;
            }
            if (upLeft && upRight)
            {
                yMid += 12;
            }
            if (downLeft && downRight)
            {
                yMid -= 12;
            }

            this.character.room.PlaySound(Systems.sounds.pop, 1f, this.character.posX + 16, this.character.posY + 16);

            // Teleport Character
            this.character.physics.MoveToPos(xMid, yMid);
        }
Exemple #5
0
        protected override void Initialize()
        {
            // level = new TilemapLevel("./Maps/MagicLandCsv.json");
            // level = new TilemapLevel("./Maps/test.json");
            level = new TilemapLevel("./Maps/level.json");

            base.Initialize();
        }
Exemple #6
0
        public override bool Activate()
        {
            // Make sure the power can be activated
            if (!this.CanActivate())
            {
                return(false);
            }

            // References
            Character character = this.character;

            // Determine Starting Position of Projectile relative to Character
            int posX = character.posX + character.bounds.MidX + (character.FaceRight ? 10 : -30);
            int posY = character.posY + character.bounds.Top + 5;

            // Play Sound
            character.room.PlaySound(this.sound, 1f, posX, posY);

            // Check if the tile placement is blocked:
            TilemapLevel tilemap = this.character.room.tilemap;

            bool isBlocked = CollideTile.IsBlockingCoord(tilemap, posX + 10 + (character.FaceRight ? 6 : -6), posY + 10, character.FaceRight ? DirCardinal.Right : DirCardinal.Left);

            // Prevent Throw
            if (isBlocked)
            {
                return(false);
            }

            // Prepare Velocity
            FInt velX = character.FaceRight ? this.xVel : this.xVel.Inverse;
            FInt velY = this.yVel;

            // Affect the Y-Velocity of the projectile if holding UP or DOWN
            this.AffectByInput(ref velX, ref velY);

            // Apply Character's Momentum (if applicable)
            if (this.multMomentum > 0)
            {
                velX += character.physics.velocity.X * this.multMomentum;
                velY += character.physics.velocity.Y * this.multMomentum * FInt.Create(0.5);
            }

            // Launch Projectile
            this.Launch(posX, posY, velX, velY);

            return(true);
        }
Exemple #7
0
        // Returns TRUE if the character can phase to the horizontal location.
        public bool TestPhasingHorizontal(Character character, TilemapLevel tilemap, short toX, DirCardinal dir)
        {
            bool blocking = CollideTile.IsBlockingSquare(tilemap, toX, character.GridY, dir);

            if (blocking)
            {
                return(false);
            }

            if (character.GridY != character.GridY2)
            {
                blocking = CollideTile.IsBlockingSquare(tilemap, toX, character.GridY2, dir);
            }

            return(!blocking);
        }
Exemple #8
0
        // Returns TRUE if the character can phase to the vertical location.
        public bool TestPhasingVertical(Character character, TilemapLevel tilemap, short toY, DirCardinal dir)
        {
            bool blocking = CollideTile.IsBlockingSquare(tilemap, character.GridX, toY, dir);

            if (blocking)
            {
                return(false);
            }

            if (character.GridX != character.GridX2)
            {
                blocking = CollideTile.IsBlockingSquare(tilemap, character.GridX2, toY, dir);
            }

            return(!blocking);
        }
Exemple #9
0
        public override bool Activate()
        {
            // Make sure the power can be activated
            if (!this.CanActivate())
            {
                return(false);
            }

            // References
            Character character = this.character;

            // Determine Starting Position of Projectile relative to Character
            int posX = character.posX + character.bounds.MidX + (character.FaceRight ? 6 : -30);
            int posY = character.posY + character.bounds.Top + 5;

            // Play Sound
            character.room.PlaySound(this.sound, 1f, posX, posY);

            // Check if the tile placement is blocked (only applies to bolts that collide with tiles).
            if (this is BoltBlue)
            {
                TilemapLevel tilemap = this.character.room.tilemap;

                bool isBlocked = CollideTile.IsBlockingCoord(tilemap, posX + (character.FaceRight ? 10 : 4), posY, character.FaceRight ? DirCardinal.Right : DirCardinal.Left);

                // Prevent Throw
                if (isBlocked)
                {
                    return(false);
                }
            }

            // Prepare Velocity
            FInt velX = character.FaceRight ? FInt.Create(this.xVel) : FInt.Create(-this.xVel);
            FInt velY = FInt.Create(this.yVel);

            // Affect the Y-Velocity of the projectile if holding UP or DOWN
            this.AffectByInput(ref velX, ref velY);

            // Launch Projectile
            this.Launch(character, posX, posY, velX, velY);

            return(true);
        }
Exemple #10
0
        public static void DetonateTNT(RoomScene room, int posX, int posY, short width, short height)
        {
            Systems.camera.BeginCameraShake(13, 7);
            room.PlaySound(Systems.sounds.explosion, 1f, posX + (int)Math.Round(width * 0.5), posY + (int)Math.Round(height * 0.5));

            List <GameObject> objects = CollideRect.FindAllObjectsTouchingArea(
                room.objects[(byte)LoadOrder.Enemy], posX, posY, width, height
                );

            // Loop through Enemies and destroy any that can be destroyed by TNT.
            foreach (GameObject obj in objects)
            {
                Enemy enemy = (Enemy)obj;
                enemy.DamageByTNT();
            }
            ;

            TilemapLevel tilemap = room.tilemap;

            // Destroy Chompers Within Area of Effect
            short startX = Math.Max((short)0, (short)Math.Floor((double)(posX / (byte)TilemapEnum.TileWidth)));
            short startY = Math.Max((short)0, (short)Math.Floor((double)(posY / (byte)TilemapEnum.TileHeight)));
            short endX   = Math.Min(tilemap.XCount, (short)Math.Floor((double)((posX + width) / (byte)TilemapEnum.TileWidth)));
            short endY   = Math.Min((short)(tilemap.YCount + TilemapEnum.GapUp), (short)Math.Floor((double)((posY + height) / (byte)TilemapEnum.TileHeight)));

            // Locate Chompers
            var tilesFound = tilemap.GetTilesByMainIDsWithinArea(new byte[7] {
                (byte)TileEnum.ChomperFire, (byte)TileEnum.ChomperGrass, (byte)TileEnum.ChomperMetal, (byte)TileEnum.Plant, (byte)TileEnum.Box, (byte)TileEnum.Brick, (byte)TileEnum.Leaf
            }, startX, startY, endX, endY);

            var TileDict = Systems.mapper.TileDict;

            foreach (var tileInfo in tilesFound)
            {
                TileObject tile = TileDict[tileInfo.tileId];
                if (tile is Chomper)
                {
                    ((Chomper)tile).DestroyChomper(room, tileInfo.gridX, tileInfo.gridY);
                }
            }
        }
Exemple #11
0
        public void ThrowItem(bool useXMomentum = false)
        {
            if (this.objHeld == null)
            {
                return;
            }
            Item item = this.objHeld;

            // Item will release in the direction the character does.
            item.SetDirection(this.character.FaceRight);

            // Check what Main Layer has present at the throw-release tile:
            TilemapLevel tilemap = this.character.room.tilemap;

            bool isBlocked = CollideTile.IsBlockingSquare(tilemap, item.GridX, item.GridY, DirCardinal.Up);

            if (!isBlocked && item.GridX != item.GridX2)
            {
                isBlocked = CollideTile.IsBlockingSquare(tilemap, item.GridX2, item.GridY, DirCardinal.Up);
            }

            // Prevent Throw
            if (isBlocked)
            {
                this.DropItem();
                return;
            }

            // Assign Item Physics + Thrown Properties
            item.intangible         = Systems.timer.Frame + 5;
            item.releasedMomentum   = useXMomentum ? (sbyte)Math.Round(this.character.physics.velocity.X.RoundInt / 2.5) : (sbyte)0;
            item.physics.velocity.X = FInt.Create(item.releasedMomentum);
            item.physics.velocity.Y = FInt.Create(-item.ThrowStrength);

            // Play Throw Sound
            this.character.room.PlaySound(Systems.sounds.wooshSubtle, 1f, this.character.posX + 16, this.character.posY + 16);

            // No longer holding object:
            this.ResetHeldItem();
        }
Exemple #12
0
        private void PlaceDetectorsAbove(RoomScene room, short gridX, short gridY)
        {
            TilemapLevel tilemap = room.tilemap;

            // Scan for solid tiles above the flag, up to 18 above (for a full screen)
            for (short testY = (short)(gridY - 1); testY > gridY - 18; testY--)
            {
                if (testY < (byte)TilemapEnum.GapUp)
                {
                    return;
                }

                // If there is a blocking tile at this grid sqare, stop placements.
                if (CollideTile.IsBlockingSquare(tilemap, gridX, testY, DirCardinal.Down))
                {
                    return;
                }

                // Otherwise, add a Detector.
                room.tilemap.SetMainTile(gridX, testY, (byte)TileEnum.DetectCheckpointPass, 0);
            }
        }
Exemple #13
0
        private PhaseSuccess PerformBlink()
        {
            Character    character = this.character;
            RoomScene    room      = character.room;
            TilemapLevel tilemap   = room.tilemap;

            // Vertical Phasing
            if (character.input.isDown(IKey.Down) || character.input.isDown(IKey.Up))
            {
                DirCardinal dir = character.input.isDown(IKey.Down) ? DirCardinal.Down : DirCardinal.Up;
                short       toY;

                if (dir == DirCardinal.Down)
                {
                    toY = (short)(character.GridY2 + 2);
                    if (toY >= (short)(tilemap.YCount + (byte)TilemapEnum.GapUp - 1))
                    {
                        return(PhaseSuccess.Success);
                    }
                }
                else
                {
                    toY = (short)(character.GridY - 2);
                    if (toY <= (short)TilemapEnum.GapUp + 1)
                    {
                        return(PhaseSuccess.Success);
                    }
                }

                // Phase to the given location if it's open:
                if (this.TestPhasingVertical(character, tilemap, toY, dir))
                {
                    character.physics.MoveToPosY(toY * (byte)TilemapEnum.TileHeight);
                    return(PhaseSuccess.Success);
                }

                // If the last location is blocked, try the next:
                toY = (short)(toY + (dir == DirCardinal.Down ? 1 : -1));

                if (this.TestPhasingVertical(character, tilemap, toY, dir))
                {
                    character.physics.MoveToPosY(toY * (byte)TilemapEnum.TileHeight);
                    return(PhaseSuccess.Success);
                }
            }

            // Horizontal Phasing
            else if (character.input.isDown(IKey.Left) || character.input.isDown(IKey.Right))
            {
                DirCardinal dir = character.input.isDown(IKey.Left) ? DirCardinal.Left : DirCardinal.Right;
                short       toX;

                if (dir == DirCardinal.Right)
                {
                    toX = (short)(character.GridX2 + 2);
                    if (toX >= (short)(tilemap.XCount + (byte)TilemapEnum.GapLeft - 1))
                    {
                        return(PhaseSuccess.Success);
                    }
                }
                else
                {
                    toX = (short)(character.GridX - 2);
                    if (toX <= (short)TilemapEnum.GapLeft + 1)
                    {
                        return(PhaseSuccess.Success);
                    }
                }

                // Phase to the given location if it's open:
                if (this.TestPhasingHorizontal(character, tilemap, toX, dir))
                {
                    character.physics.MoveToPosX(toX * (byte)TilemapEnum.TileWidth);
                    return(PhaseSuccess.Success);
                }

                // If the last location is blocked, try the next:
                toX = (short)(toX + (dir == DirCardinal.Right ? 1 : -1));

                if (this.TestPhasingHorizontal(character, tilemap, toX, dir))
                {
                    character.physics.MoveToPosX(toX * (byte)TilemapEnum.TileWidth);
                    return(PhaseSuccess.Success);
                }
            }

            // No inputs were provided.
            else
            {
                return(PhaseSuccess.NoAction);
            }

            return(PhaseSuccess.Fail);
        }
Exemple #14
0
        public static void Detonate(RoomScene room, int midX, int midY)
        {
            TilemapLevel tilemap = room.tilemap;

            int gridX = (int)Math.Floor((double)(midX / (byte)TilemapEnum.TileWidth));
            int gridY = (int)Math.Floor((double)(midY / (byte)TilemapEnum.TileHeight));

            // Destroy Enemies Within Area of Effect
            List <GameObject> enemiesFound = CollideRect.FindAllObjectsTouchingArea(room.objects[(byte)LoadOrder.Enemy], midX - 144, midY - 96, 288, 192);

            foreach (GameObject enemy in enemiesFound)
            {
                ((Enemy)enemy).Die(DeathResult.Knockout);
            }

            // Heavily Damage Characters Within Area of Effect
            List <GameObject> charsFound = CollideRect.FindAllObjectsTouchingArea(room.objects[(byte)LoadOrder.Character], midX - 144, midY - 96, 288, 192);

            foreach (GameObject character in charsFound)
            {
                ((Character)character).wounds.ReceiveWoundDamage(DamageStrength.Major, true);
                ((Character)character).wounds.ReceiveWoundDamage(DamageStrength.Major, true);
                ((Character)character).wounds.ReceiveWoundDamage(DamageStrength.Major, true);
            }

            // Destroy Certain Tiles Within Area of Effect
            short startX = (short)Math.Max(0, gridX - 3);
            short startY = (short)Math.Max(0, gridY - 2);
            short endX   = (short)Math.Min(tilemap.XCount + (byte)TilemapEnum.GapLeft - 1, gridX + 3);
            short endY   = (short)Math.Min(tilemap.YCount + (byte)TilemapEnum.GapUp - 1, gridY + 2);

            // Locate Tiles: Chompers, Boxes, Bricks, Leafs, etc.
            var tilesFound = tilemap.GetTilesByMainIDsWithinArea(new byte[7] {
                (byte)TileEnum.ChomperFire, (byte)TileEnum.ChomperGrass, (byte)TileEnum.ChomperMetal, (byte)TileEnum.Plant, (byte)TileEnum.Box, (byte)TileEnum.Brick, (byte)TileEnum.Leaf
            }, startX, startY, endX, endY);

            var TileDict = Systems.mapper.TileDict;

            foreach (var tileInfo in tilesFound)
            {
                TileObject tile = TileDict[tileInfo.tileId];

                if (tile is Chomper)
                {
                    ((Chomper)tile).DestroyChomper(room, tileInfo.gridX, tileInfo.gridY);
                }
                else if (tile is Brick)
                {
                    ((Brick)tile).DestroyBrick(room, tileInfo.gridX, tileInfo.gridY);
                }
                else if (tile is Box)
                {
                    ((Box)tile).DestroyBox(room, tileInfo.gridX, tileInfo.gridY);
                }
                else if (tile is Leaf)
                {
                    ((Leaf)tile).TriggerEvent(room, tileInfo.gridX, tileInfo.gridY, 0);
                }
            }

            // Display Particle Effect
            ExplodeEmitter.BoxExplosion(room, "Particles/GrenadeFrag", midX, midY, 20, 15);
            ExplodeEmitter.BoxExplosion(room, "Particles/GrenadeFrag", midX, midY, 70, 50);

            room.PlaySound(Systems.sounds.explosion, 0.4f, midX, midY);

            // Camera Shake
            Systems.camera.BeginCameraShake(35, 6);
        }