using Assets.Scripts.Enums;
|
using Assets.Scripts.Helpers;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using TMPro;
|
using Unity.VisualScripting;
|
using UnityEngine;
|
using UnityEngine.Tilemaps;
|
|
public class GameManager : SettingsManager
|
{
|
public static bool GameIsPaused = false;
|
|
public GameObject damageTextPrefab;
|
public GameObject healthTextPrefab;
|
public GameObject lootTextPrefab;
|
public Canvas playerUI;
|
public Canvas pauseMenuUI;
|
public Canvas worldSpaceUI;
|
public GameObject levelChanger;
|
public Tilemap tilemap;
|
[NonSerialized]
|
public GenerateTileMap generateTileMap;
|
[NonSerialized]
|
public List<Vector3Int> destroyedTiles = new List<Vector3Int>();
|
public GameObject pickups;
|
|
private void Awake()
|
{
|
GameIsPaused = false;
|
SoundManager.instance.ChangeMusic(SoundName.MusicHappy);
|
LoadTileMaps(SaveSystem.isGameLoaded);
|
}
|
|
|
private void LoadTileMaps(bool loadFromSave)
|
{
|
generateTileMap = tilemap.GetComponent<GenerateTileMap>();
|
PauseGame();
|
levelChanger.GetComponent<Animator>().SetBool("SceneLoading", true);
|
if (loadFromSave)
|
{
|
LoadMapState();
|
}
|
Debug.Log("waiting for async map loading");
|
StartCoroutine(generateTileMap.GenerateTiles(LoadTileMapsFinished, destroyedTiles));
|
}
|
|
private void LoadMapState()
|
{
|
SaveDataMap mapState = SaveSystem.LoadMapState();
|
if (mapState != null)
|
{
|
generateTileMap.SetSettingsFromSeed(mapState.seed);
|
if (mapState.destroyedTiles != null && mapState.destroyedTiles.Count > 0)
|
{
|
// TODO rework load map (it's fucky wucky currently as I had to make an extra class for it to jsonify the tiles correctly, as unity does not like lists of arrays or 2d arrays)
|
foreach (DestroyedTile tile in mapState.destroyedTiles)
|
{
|
destroyedTiles.Add(tile.tileCoord.ConvertToVector3Int());
|
} //destroyedTiles.AddRange(mapState.destroyedTiles.Select(tile => { return tile.tileCoord; }).ToList().ConvertToVector3Int());
|
}
|
}
|
}
|
|
public void LoadTileMapsFinished()
|
{
|
Debug.Log("done async map loading");
|
levelChanger.GetComponent<Animator>().SetBool("SceneLoading", false);
|
GameLoaded();
|
}
|
public void GameLoaded()
|
{
|
ResumeGame();
|
pauseMenuUI.GetComponent<Animator>().SetTrigger("GameLoaded");
|
}
|
|
#region characterEvents
|
private void OnEnable()
|
{
|
// add listen events
|
CharacterEvents.characterDamaged += (CharacterTookDamange);
|
CharacterEvents.characterHealed += (CharacterHealed);
|
CharacterEvents.characterDrill += (CharacterDrill);
|
|
}
|
|
private void OnDisable()
|
{
|
// remove listen events
|
CharacterEvents.characterDamaged -= (CharacterTookDamange);
|
CharacterEvents.characterHealed -= (CharacterHealed);
|
CharacterEvents.characterDrill -= (CharacterDrill);
|
}
|
|
public void CharacterTookDamange(GameObject character, int damageReceived)
|
{
|
// Create damage text at character
|
Vector3 spawnPosition = Camera.main.WorldToScreenPoint(character.transform.position);
|
|
TMP_Text tmpText = Instantiate(damageTextPrefab, spawnPosition, Quaternion.identity, pauseMenuUI.transform).GetComponent<TMP_Text>();
|
|
tmpText.text = damageReceived.ToString();
|
|
}
|
public void CharacterHealed(GameObject character, int healthRestored)
|
{
|
// Create heal text at character
|
Vector3 spawnPosition = Camera.main.WorldToScreenPoint(character.transform.position);
|
|
TMP_Text tmpText = Instantiate(healthTextPrefab, spawnPosition, Quaternion.identity, pauseMenuUI.transform).GetComponent<TMP_Text>();
|
|
tmpText.text = healthRestored.ToString();
|
|
}
|
public void CharacterLootObtained(Vector3 position, Item itemReceived, int quantity)
|
{
|
// Offset the position slightly up so it doesn't spawn inside the ground/player
|
position += Vector3.up * 0.5f;
|
|
// Create text in world space (no parent needed)
|
GameObject textObj = Instantiate(lootTextPrefab, position, Quaternion.identity, worldSpaceUI.transform);
|
TextMeshProUGUI tmpText = textObj.GetComponent<TextMeshProUGUI>();
|
tmpText.text = $"+{quantity} ({itemReceived.itemName})";
|
|
// Ensure it's visible to the camera
|
textObj.transform.rotation = Camera.main.transform.rotation;
|
|
}
|
public void CharacterDrill(ContactPoint2D contact, DrillDirection drillDirection)
|
{
|
GridLayout grid = tilemap.transform.GetComponentInParent<GridLayout>();
|
Vector3Int cellCoord = grid.WorldToCell(contact.point);
|
switch (drillDirection)
|
{
|
case DrillDirection.Left:
|
cellCoord.x = cellCoord.x - 1;
|
break;
|
case DrillDirection.Right:
|
cellCoord.x = cellCoord.x + 1;
|
break;
|
case DrillDirection.Down:
|
cellCoord.y = cellCoord.y - 1;
|
break;
|
}
|
|
//Debug.Log("cellCoord: " + grid.CellToWorld(cellCoord));
|
//Debug.Log(tilemap.HasTile(cellCoord));
|
if (tilemap.HasTile(cellCoord))
|
{
|
GameObject tileGameObject = tilemap.GetInstantiatedObject(cellCoord);
|
if (tileGameObject?.GetComponent<Drillable>()?.isDrillable ?? false)
|
{
|
Vector3 cellWorldPosition = grid.CellToWorld(cellCoord);
|
// middle of tile
|
cellWorldPosition.x += 0.5f;
|
cellWorldPosition.y += 0.5f;
|
Dropable dropable = tileGameObject?.GetComponent<Dropable>();
|
if (dropable?.isDropable ?? false)
|
{
|
// Change no drops, only inventory
|
//Instantiate(tileGameObject?.GetComponent<Dropable>().dropable, cellWorldPosition, Quaternion.identity, pickups.transform);
|
Inventory playerInventory = contact.rigidbody.gameObject.GetComponent<Inventory>();
|
if (playerInventory != null)
|
{
|
Item item = dropable.dropable;
|
playerInventory.AddItem(item, dropable.dropAmount);
|
CharacterLootObtained(tileGameObject.transform.position, item, dropable.dropAmount);
|
}
|
}
|
tilemap.SetTile(cellCoord, null);
|
destroyedTiles.Add(cellCoord);
|
CharacterEvents.characterDrillingToPosition.Invoke(cellWorldPosition, drillDirection);
|
}
|
else
|
{
|
//CharacterEvents.characterDrillingToPositionAbort.Invoke(moveToPosition);
|
}
|
}
|
}
|
#endregion
|
|
|
#region GameState
|
|
public static void PauseGame()
|
{
|
Time.timeScale = 0f;
|
GameIsPaused = true;
|
//GameStateEvents.gameStatePauseChanged.Invoke(GameIsPaused);
|
}
|
public static void ResumeGame()
|
{
|
Time.timeScale = 1f;
|
GameIsPaused = false;
|
//GameStateEvents.gameStatePauseChanged.Invoke(GameIsPaused);
|
}
|
#endregion
|
}
|