using System.Collections; using System.Collections.Generic; using UnityEngine; using Objects; namespace Level { public class LevelBuilder : MonoBehaviour { // Static private static LevelBuilder instance; // Events public delegate void LevelDestroyedHandler(); public event LevelDestroyedHandler LevelDestroyed; public delegate void LevelInitializedHandler(); public event LevelInitializedHandler LevelInitialized; // Public public Sprite blockSprite; public Sprite environmentSprite; public Sprite groundSprite; public GameObject spritePrefab; public GameObject cratePrefab; public Grid grid; public LevelBuilderButtons levelBuilderButtons; // Private private int width; private int height; private LayoutCell[][] layout; private Vector3Int firstCellPos; private LevelSaveSystem levelSaveSystem = new LevelSaveSystem(); // Properties public static LevelBuilder Instance => instance; // Methods private void Awake() { if (instance != null && instance != this) { Destroy(gameObject); return; } instance = this; } private void Update() { if (GameManager.Instance.currentState == GameState.Editing && Input.GetMouseButtonDown(0)) { // Get the mouse position Vector3 mousePosition = Input.mousePosition; // Convert the mouse position to world space if needed Vector3 worldMousePosition = Camera.main.ScreenToWorldPoint(mousePosition); EditCellAt(worldMousePosition); } if (Input.GetKeyDown(KeyCode.T)) { Save(); } } public void CreateLayout(int w, int h) { LevelDestroyed?.Invoke(); width = w; height = h; // Offset first cell by half of width and height firstCellPos = new Vector3Int(-width / 2, -height / 2, 0); layout = new LayoutCell[height][]; for (int y = 0; y < height; y++) { layout[y] = new LayoutCell[width]; for (int x = 0; x < width; x++) { Vector3Int cellPos = new Vector3Int(firstCellPos.x + x, firstCellPos.y + y, 0); layout[y][x] = new LayoutCell(cellPos, new Vector2Int(x, y)); } } LevelInitialized?.Invoke(); } public LevelData CreateLevelData() { LayoutCell.LayoutCellData[][] layoutData = new LayoutCell.LayoutCellData[height][]; for (int y = 0; y < height; y++) { layoutData[y] = new LayoutCell.LayoutCellData[width]; for (int x = 0; x < width; x++) { layoutData[y][x] = layout[y][x].cellData; } } LevelData levelData = new LevelData(); levelData.layout = layoutData; levelData.width = width; levelData.height = height; return levelData; } public void LoadLevelData(LevelData levelData) { CreateLayout(levelData.width, levelData.height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { LayoutCell cell = layout[y][x]; cell.cellData = levelData.layout[y][x]; cell.UpdateSprites(); if (cell.cellData.cellContent == LayoutCell.LayoutCellData.CellContent.Crate) { cell.PlaceCrate(); } else if (cell.cellData.cellContent == LayoutCell.LayoutCellData.CellContent.Player) { Player.Instance.Teleport(cell); } } } } public void Save() { LevelData levelData = CreateLevelData(); Save(levelData); } public void Save(LevelData levelData) { levelSaveSystem.Save(levelData); } public void Load() { levelSaveSystem.Load(); } public LayoutCell GetCellAtLayout(Vector2Int layoutPosition) { // Check that cell with these indices exists in array // if (0 < layoutPosition.y < height && 0 < layoutPosition.x < width) if (layoutPosition.y >= 0 && layoutPosition.y < height && layoutPosition.x >= 0 && layoutPosition.x < width) { return layout[layoutPosition.y][layoutPosition.x]; } else { return null; } } public LayoutCell WorldToLayoutCell(Vector3 worldPos) { Vector3Int cellPos = grid.WorldToCell(worldPos); Vector2Int layoutPosition = ((Vector2Int) (cellPos - firstCellPos)); return GetCellAtLayout(layoutPosition); } public bool UnoccupiedTargetExists() { // This can be optimized by creating a mapping to all target points // But I'm not doing that for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (layout[y][x].cellData.isTarget && layout[y][x].cellData.cellContent != LayoutCell.LayoutCellData.CellContent.Crate) { return true; } } } return false; } private void EditCellAt(Vector3 worldPos) { LayoutCell layoutCell = WorldToLayoutCell(worldPos); if (layoutCell == null) { return; } LevelBuilderButtons.PlacementOption placementOption = levelBuilderButtons.CurrentOption; layoutCell.ChangeEnv(placementOption); } } }