예제 #1
0
        // Makes sure all rollers in the group can be pushed in the same direction.
        private bool CanPushRoller(int direction)
        {
            if (IsMoving)
            {
                return(false);
            }

            // Make sure were not pushing out of bounds.
            Point2I newLocation = Location + Directions.ToPoint(direction);

            if (!RoomControl.IsTileInBounds(newLocation))
            {
                return(false);
            }

            // Make sure there are no obstructions.
            int newLayer;

            if (IsMoveObstructed(direction, out newLayer))
            {
                return(false);
            }

            if ((IsVertical && Directions.IsVertical(direction)) || (!IsVertical && Directions.IsHorizontal(direction)))
            {
                return(nextRoller != null ? nextRoller.CanPushRoller(direction) : true);
            }
            return(false);
        }
예제 #2
0
        public override void Update()
        {
            AudioSystem.LoopSoundWhileActive(GameData.SOUND_BOOMERANG_LOOP);

            // Check for boomerangable tiles.
            if (itemBoomerang.Level == Item.Level2)
            {
                Point2I tileLoc = RoomControl.GetTileLocation(position);
                if (tileLoc != tileLocation && RoomControl.IsTileInBounds(tileLoc))
                {
                    Tile tile = RoomControl.GetTopTile(tileLoc);
                    if (tile != null)
                    {
                        tile.OnBoomerang();
                    }
                }
                tileLocation = tileLoc;
            }

            // Pickup collectibles.
            foreach (Collectible collectible in Physics.GetEntitiesMeeting <Collectible>(CollisionBoxType.Soft))
            {
                if (collectible.IsPickupable && collectible.IsCollectibleWithItems)
                {
                    collectibles.Add(collectible);
                    collectible.Destroy();
                    BeginReturn();
                }
            }

            base.Update();
        }
        //-----------------------------------------------------------------------------
        // Internal methods
        //-----------------------------------------------------------------------------

        // Return true if a somaria block would break when spawned at the given tile location.
        private bool CanBlockSpawnAtLocation(Point2I location)
        {
            if (!RoomControl.IsSideScrolling && IsInAir)
            {
                return(false);
            }

            // TODO: check if there is a solid block below when side-scrolling.

            if (!RoomControl.IsTileInBounds(location))
            {
                return(false);
            }

            foreach (Tile t in RoomControl.TileManager.GetTilesAtPosition(Center))
            {
                if (!t.IsSurface || !t.IsCoverableByBlock || t.IsHoleWaterOrLava)
                {
                    return(false);
                }
            }

            /*
             * Tile checkTile = RoomControl.GetTopTile(location);
             * if (checkTile == null)
             *      return true;
             * return (checkTile.Layer != RoomControl.Room.TopLayer &&
             *              checkTile.IsCoverableByBlock && !checkTile.IsHoleWaterOrLava);*/
            return(true);
        }
예제 #4
0
        public override void OnLand()
        {
            // Collide with monsters.
            foreach (Monster monster in Physics.GetEntitiesMeeting <Monster>(CollisionBoxType.Soft))
            {
                monster.TriggerInteraction(InteractionType.ThrownObject, this);
                if (IsDestroyed)
                {
                    return;
                }
            }

            // Collide with surface tiles.
            Point2I tileLoc = RoomControl.GetTileLocation(position);

            if (RoomControl.IsTileInBounds(tileLoc))
            {
                Tile tile = RoomControl.GetTopTile(tileLoc);
                if (tile != null)
                {
                    tile.OnHitByThrownObject(this);
                    if (IsDestroyed)
                    {
                        return;
                    }
                }
            }

            Break();
        }
예제 #5
0
        public override void Update()
        {
            base.Update();

            if (state == TileBridgeState.Creating)
            {
                timer++;
                if (timer >= 10)
                {
                    timer = 0;

                    if (RoomControl.IsTileInBounds(pieceLocation) && GetConnectedTile(pieceLocation) == null)
                    {
                        AudioSystem.PlaySound(GameData.SOUND_BARRIER);
                        TileData pieceTileData = Resources.GetResource <TileData>(
                            isVertical ? "bridge_vertical" : "bridge_horizontal");
                        Tile pieceTile = Tile.CreateTile(pieceTileData);
                        RoomControl.PlaceTileOnHighestLayer(pieceTile, pieceLocation);
                        pieceLocation += Directions.ToPoint(bridgeDirection);
                    }
                    else
                    {
                        state = TileBridgeState.Created;
                    }
                }
            }
            else if (state == TileBridgeState.Destroying)
            {
                timer++;
                if (timer >= 10)
                {
                    timer = 0;
                    TileBridge pieceTile = GetConnectedTile(pieceLocation);

                    if (pieceTile != null)
                    {
                        RoomControl.RemoveTile(pieceTile);
                        AudioSystem.PlaySound(GameData.SOUND_BARRIER);
                    }

                    pieceLocation -= Directions.ToPoint(bridgeDirection);

                    if (pieceLocation == Location)
                    {
                        state = TileBridgeState.Destroyed;
                    }
                }
            }
        }
예제 #6
0
        public override void OnDestroyTimerDone()
        {
            // Burn tiles.
            Point2I location = RoomControl.GetTileLocation(position);

            if (RoomControl.IsTileInBounds(location))
            {
                Tile tile = RoomControl.GetTopTile(location);
                if (tile != null)
                {
                    tile.OnBurn();
                }
            }
            Destroy();
        }
예제 #7
0
        //-----------------------------------------------------------------------------
        // Bridge Methods
        //-----------------------------------------------------------------------------

        public void CreateBridge(bool instantaneous = false, bool rememberState = false)
        {
            if (bridgeDirection >= 0 && (state == TileBridgeState.Destroyed || state == TileBridgeState.Destroying))
            {
                if (state == TileBridgeState.Destroying)
                {
                    pieceLocation += Directions.ToPoint(bridgeDirection);
                }
                else
                {
                    pieceLocation = Location + Directions.ToPoint(bridgeDirection);
                }

                state = TileBridgeState.Creating;
                timer = 0;
            }

            if (instantaneous)
            {
                while (state == TileBridgeState.Creating)
                {
                    if (RoomControl.IsTileInBounds(pieceLocation) && GetConnectedTile(pieceLocation) == null)
                    {
                        TileData pieceTileData = Resources.GetResource <TileData>(
                            isVertical ? "bridge_vertical" : "bridge_horizontal");
                        Tile pieceTile = Tile.CreateTile(pieceTileData);
                        RoomControl.PlaceTileOnHighestLayer(pieceTile, pieceLocation);
                        pieceLocation += Directions.ToPoint(bridgeDirection);
                    }
                    else
                    {
                        state = TileBridgeState.Created;
                        break;
                    }
                }
            }

            if (state == TileBridgeState.Created || state == TileBridgeState.Creating)
            {
                Properties.Set("built", true);
            }
        }
예제 #8
0
        //-----------------------------------------------------------------------------
        // Internal methods
        //-----------------------------------------------------------------------------

        private void PerformDig(PlayerState state)
        {
            // Look for tiles to dig up.
            float    distance = 6.5f;
            Vector2F center   = Player.Center;

            if (Directions.IsVertical(Player.Direction))
            {
                distance = 7.5f;
            }
            else
            {
                center.Y += 4.0f;
            }
            Vector2F hotspot = GMath.Round(center) + (Directions.ToVector(Player.Direction) * distance);
            Point2I  tileLoc = RoomControl.GetTileLocation(hotspot);

            if (!RoomControl.IsTileInBounds(tileLoc))
            {
                return;
            }

            Tile tile = RoomControl.GetTopTile(tileLoc);

            if (tile != null && tile.OnDig(Player.Direction))
            {
                // Spawn dirt effect.
                Effect effect = new Effect();
                effect.Graphics.DepthLayer = DepthLayer.EffectDirt;
                effect.CreateDestroyTimer(15);
                effect.EnablePhysics(PhysicsFlags.HasGravity);
                effect.Physics.Velocity         = Directions.ToVector(Player.Direction) * 0.5f;
                effect.Graphics.IsShadowVisible = false;
                effect.Graphics.PlayAnimation(GameData.ANIM_EFFECT_DIRT);
                effect.Graphics.SubStripIndex = Player.Direction;
                if (Directions.IsHorizontal(Player.Direction))
                {
                    effect.Physics.ZVelocity = 3.0f;
                    effect.Physics.Gravity   = 0.5f;
                }
                else
                {
                    effect.Physics.ZVelocity = 2.5f;
                    effect.Physics.Gravity   = 0.4f;
                }
                RoomControl.SpawnEntity(effect, tile.Center);


                AudioSystem.PlaySound(GameData.SOUND_SHOVEL);
            }
            else
            {
                AudioSystem.PlaySound(GameData.SOUND_EFFECT_CLING);
            }

            // Check for monster interactions.
            Rectangle2I shovelHitBox = new Rectangle2I(-4, -4, 8, 8);

            shovelHitBox.Point += (Point2I)Player.CenterOffset;
            shovelHitBox.ExtendEdge(Player.Direction, 7);
            foreach (Monster monster in Player.Physics.GetEntitiesMeeting <Monster>(shovelHitBox, CollisionBoxType.Soft))
            {
                monster.TriggerInteraction(InteractionType.Shovel, Player);
            }
        }
예제 #9
0
        public override void Update()
        {
            // Check if collided.
            if (physics.IsColliding && eventCollision != null)
            {
                eventCollision();
                if (IsDestroyed)
                {
                    return;
                }
            }

            // Collide with tiles.
            if (physics.IsColliding)
            {
                CollisionType type = CollisionType.RoomEdge;
                Tile          tile = null;

                foreach (CollisionInfo collision in Physics.GetCollisions())
                {
                    type = collision.Type;
                    tile = collision.Tile;
                    break;
                }

                if (tile != null)
                {
                    if (owner == RoomControl.Player)
                    {
                        tile.OnHitByProjectile(this);
                        if (IsDestroyed)
                        {
                            return;
                        }
                    }
                    OnCollideTile(tile, false);
                    if (IsDestroyed)
                    {
                        return;
                    }
                }
                else if (type == CollisionType.RoomEdge)
                {
                    OnCollideRoomEdge();
                    if (IsDestroyed)
                    {
                        return;
                    }
                }
            }

            // Notify surface tiles the projectile is hovering over.
            Point2I tileLoc = RoomControl.GetTileLocation(position);

            if (tileLoc != tileLocation && RoomControl.IsTileInBounds(tileLoc) && zPosition < 10.0f)               // TODO: magic number
            {
                Tile tile = RoomControl.GetTopTile(tileLoc);
                if (tile != null)
                {
                    tile.OnHitByProjectile(this);
                    if (IsDestroyed)
                    {
                        return;
                    }
                }
            }
            tileLocation = tileLoc;

            if (owner is Player)
            {
                // Collide with monster tools.
                foreach (Monster monster in RoomControl.GetEntitiesOfType <Monster>())
                {
                    foreach (UnitTool tool in monster.EquippedTools)
                    {
                        if (Physics.PositionedCollisionBox.Intersects(tool.PositionedCollisionBox))
                        {
                            tool.OnHitProjectile(this);
                            if (IsDestroyed)
                            {
                                return;
                            }
                        }
                    }
                }

                // Collide with monsters.
                foreach (Monster monster in Physics.GetEntitiesMeeting <Monster>(CollisionBoxType.Soft))
                {
                    OnCollideMonster(monster);
                    if (IsDestroyed)
                    {
                        return;
                    }
                }
            }
            else
            {
                Player player = RoomControl.Player;

                // Collide with the player's tools.
                foreach (UnitTool tool in player.EquippedTools)
                {
                    if (Physics.PositionedCollisionBox.Intersects(tool.PositionedCollisionBox))
                    {
                        tool.OnHitProjectile(this);
                        if (IsDestroyed)
                        {
                            return;
                        }
                    }
                }

                // Collide with the player.
                if (Physics.IsMeetingEntity(player, CollisionBoxType.Soft))
                {
                    OnCollidePlayer(player);
                    if (IsDestroyed)
                    {
                        return;
                    }
                }
            }

            if (syncAnimationWithDirection)
            {
                Graphics.SubStripIndex = direction;
            }
            else if (syncAnimationWithAngle)
            {
                Graphics.SubStripIndex = angle;
            }

            base.Update();
        }