// Path: core/src/me/minidigger/projecttd/components/PathComponent.java
// public class PathComponent implements Component, Pool.Poolable {
// 
//     public int tilesToGoal = -1;
//     public Vector2 nextPoint;
//     public PathFindingSystem.GoalReachedAction completed = (e) -> {
//     };
// 
//     @Override
//     public void reset() {
//         tilesToGoal = -1;
//         nextPoint = null;
//         completed = (e) -> {
//         };
//     }
// }
// 
// Path: core/src/me/minidigger/projecttd/components/TransformComponent.java
// public class TransformComponent implements Component, Pool.Poolable {
// 
//     public Vector2 position;
//     public float rotation = 0f;
// 
//     @Override
//     public void reset() {
//         position = new Vector2();
//         rotation = 0f;
//     }
// }
// 
// Path: core/src/me/minidigger/projecttd/utils/CoordinateUtil.java
// public class CoordinateUtil {
// 
//     private static Vector3 vector3 = new Vector3();
// 
//     public static Vector2 touchToWorld(Vector2 point, Camera camera) {
//         vector3.set(point, 0);
//         camera.unproject(vector3);
//         point.set(vector3.x, vector3.y);
//         return point;
//     }
// 
//     public static Vector2 worldToTouch(Vector2 point, Camera camera) {
//         vector3.set(point, 0);
//         camera.project(vector3);
//         point.set(vector3.x, vector3.y);
//         return point;
//     }
// 
//     public static Vector2 alignToGrid(Vector2 input) {
//         input.x = (int) (input.x) + 0.5f;
//         input.y = (int) (input.y) + 0.5f;
//         return input;
//     }
// }
// 
// Path: core/src/me/minidigger/projecttd/utils/Vector2i.java
// public class Vector2i {
// 
//     public int x;
//     public int y;
// 
//     public Vector2i(int x, int y) {
//         this.x = x;
//         this.y = y;
//     }
// 
//     @Override
//     public String toString() {
//         return "Vector2i{" +
//                 "x=" + x +
//                 ", y=" + y +
//                 '}';
//     }
// }


import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.Family;
import com.badlogic.ashley.systems.IteratingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.math.Vector2;
import me.minidigger.projecttd.components.PathComponent;
import me.minidigger.projecttd.components.TransformComponent;
import me.minidigger.projecttd.utils.CoordinateUtil;
import me.minidigger.projecttd.utils.Vector2i;
import java.util.LinkedList;
import java.util.Queue;
        this.mapWidth = mapWidth;

        map = new TileType[mapWidth][mapHeight];

        TiledMapTileLayer path = (TiledMapTileLayer) tiledMap.getLayers().get("Path");
        TiledMapTileLayer rocks = (TiledMapTileLayer) tiledMap.getLayers().get("Rocks");
        TiledMapTileLayer bushes = (TiledMapTileLayer) tiledMap.getLayers().get("Bushes");

        for (int x = 0; x < map.length; x++) {
            for (int y = 0; y < map[x].length; y++) {
                if (path.getCell(x, y) != null) {
                    map[x][y] = TileType.FLOOR;
                } else if (rocks.getCell(x, y) != null || bushes.getCell(x, y) != null) {
                    map[x][y] = TileType.WALL;
                } else {
                    map[x][y] = TileType.EMPTY;
                }
            }
        }
    }

    public void init(Vector2 goal) {
        goal = goal.set((int) goal.x, (int) goal.y);
        this.goal = goal; // save for later recalculation

        cost = new int[mapWidth][mapHeight];
        visited = new boolean[mapWidth][mapHeight];
        direction = new Vector2[mapWidth][mapHeight];

        // wavefront (bfs)
// Path: core/src/me/minidigger/projecttd/components/PathComponent.java
// public class PathComponent implements Component, Pool.Poolable {
// 
//     public int tilesToGoal = -1;
//     public Vector2 nextPoint;
//     public PathFindingSystem.GoalReachedAction completed = (e) -> {
//     };
// 
//     @Override
//     public void reset() {
//         tilesToGoal = -1;
//         nextPoint = null;
//         completed = (e) -> {
//         };
//     }
// }
// 
// Path: core/src/me/minidigger/projecttd/components/TransformComponent.java
// public class TransformComponent implements Component, Pool.Poolable {
// 
//     public Vector2 position;
//     public float rotation = 0f;
// 
//     @Override
//     public void reset() {
//         position = new Vector2();
//         rotation = 0f;
//     }
// }
// 
// Path: core/src/me/minidigger/projecttd/utils/CoordinateUtil.java
// public class CoordinateUtil {
// 
//     private static Vector3 vector3 = new Vector3();
// 
//     public static Vector2 touchToWorld(Vector2 point, Camera camera) {
//         vector3.set(point, 0);
//         camera.unproject(vector3);
//         point.set(vector3.x, vector3.y);
//         return point;
//     }
// 
//     public static Vector2 worldToTouch(Vector2 point, Camera camera) {
//         vector3.set(point, 0);
//         camera.project(vector3);
//         point.set(vector3.x, vector3.y);
//         return point;
//     }
// 
//     public static Vector2 alignToGrid(Vector2 input) {
//         input.x = (int) (input.x) + 0.5f;
//         input.y = (int) (input.y) + 0.5f;
//         return input;
//     }
// }
// 
// Path: core/src/me/minidigger/projecttd/utils/Vector2i.java
// public class Vector2i {
// 
//     public int x;
//     public int y;
// 
//     public Vector2i(int x, int y) {
//         this.x = x;
//         this.y = y;
//     }
// 
//     @Override
//     public String toString() {
//         return "Vector2i{" +
//                 "x=" + x +
//                 ", y=" + y +
//                 '}';
//     }
// }


// Path: core/src/me/minidigger/projecttd/systems/PathFindingSystem.java
import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.Family;
import com.badlogic.ashley.systems.IteratingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.math.Vector2;
import me.minidigger.projecttd.components.PathComponent;
import me.minidigger.projecttd.components.TransformComponent;
import me.minidigger.projecttd.utils.CoordinateUtil;
import me.minidigger.projecttd.utils.Vector2i;
import java.util.LinkedList;
import java.util.Queue;

        this.mapWidth = mapWidth;

        map = new TileType[mapWidth][mapHeight];

        TiledMapTileLayer path = (TiledMapTileLayer) tiledMap.getLayers().get("Path");
        TiledMapTileLayer rocks = (TiledMapTileLayer) tiledMap.getLayers().get("Rocks");
        TiledMapTileLayer bushes = (TiledMapTileLayer) tiledMap.getLayers().get("Bushes");

        for (int x = 0; x < map.length; x++) {
            for (int y = 0; y < map[x].length; y++) {
                if (path.getCell(x, y) != null) {
                    map[x][y] = TileType.FLOOR;
                } else if (rocks.getCell(x, y) != null || bushes.getCell(x, y) != null) {
                    map[x][y] = TileType.WALL;
                } else {
                    map[x][y] = TileType.EMPTY;
                }
            }
        }
    }

    public void init(Vector2 goal) {
        goal = goal.set((int) goal.x, (int) goal.y);
        this.goal = goal; // save for later recalculation

        cost = new int[mapWidth][mapHeight];
        visited = new boolean[mapWidth][mapHeight];
        direction = new Vector2[mapWidth][mapHeight];

        // wavefront (bfs)
        Queue<Vector2i> queue = new LinkedList<>();