LunarInfantry/Assets/Scripts/PlayerEntityMovement.cs
2026-01-10 02:37:44 -08:00

176 lines
5 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
public class PlayerEntityMovement : MonoBehaviour
{
//unsure if this should also move enemies but who knows!
#region Statication
public static PlayerEntityMovement instance;
private void Awake()
{
if (instance != null && instance != this)
{
Destroy(gameObject);
return;
}
instance = this;
}
#endregion
[SerializeField] private Grid gameplayGrid;
public PlayerEntity selectedEntity;
public GameObject templateObject;
public bool isMoving;
private Vector3 mouseWorldPos;
private Vector3 mouseGridPos;
private Camera cam;
private float debounceTime;
[SerializeField] private float debounceDuration;
private List<TileObject> currentMovableTiles = new();
private Queue<TileObject> frontier = new();
private HashSet<TileObject> visited = new();
private Dictionary<TileObject, TileObject> currentPaths = new();
private Dictionary<TileObject, int> movementCosts = new();
public List<TileObject> pathRequested;
private TileObject requestedTile;
private void Start()
{
cam = Camera.main;
}
private void Update()
{
mouseWorldPos = cam.ScreenToWorldPoint(Input.mousePosition);
mouseGridPos = gameplayGrid.GetCellCenterWorld(gameplayGrid.WorldToCell(mouseWorldPos));
if (debounceTime > 0)
{
debounceTime -= Time.deltaTime;
}
if (isMoving)
{
if (Input.GetMouseButton(1))
{
Deselect();
}
TileObject newTile = GridManager.instance.GetTile(mouseGridPos);
if (requestedTile != newTile)
{
requestedTile = newTile;
foreach (TileObject tile in pathRequested)
{
tile.sprite.color = new Color(137,137,137);
}
PathfindToTarget();
}
templateObject.transform.position = mouseGridPos;
if (Input.GetMouseButtonDown(0) && debounceTime <= 0 && SelectLocation())
{
isMoving = false;
}
}
}
public void SelectEntity(PlayerEntity entitySelected)
{
selectedEntity = entitySelected;
isMoving = true;
debounceTime = debounceDuration;
UncolorGrid();
frontier.Clear();
visited.Clear();
currentPaths.Clear();
pathRequested.Clear();
currentMovableTiles.Clear();
movementCosts.Clear();
GetAllTiles();
CreateTemplate();
}
private void UncolorGrid()
{
foreach (TileObject tileObject in currentMovableTiles)
{
tileObject.sprite.color = new Color(137,137,137);
}
}
private void GetAllTiles()
{
frontier.Enqueue(selectedEntity.currentTile);
movementCosts.TryAdd(selectedEntity.currentTile, 0);
while (frontier.Count > 0)
{
TileObject currentTile = frontier.Dequeue();
if (movementCosts[currentTile] <= selectedEntity.maxMovement)
{
currentMovableTiles.Add(currentTile);
}
foreach (TileObject neighboringTiles in currentTile.neighbors)
{
int newCost = movementCosts[currentTile] + 1;
if (!visited.Contains(neighboringTiles))
{
visited.Add(neighboringTiles);
frontier.Enqueue(neighboringTiles);
currentPaths.TryAdd(neighboringTiles, currentTile);
movementCosts.TryAdd(neighboringTiles, newCost);
}
}
}
foreach (TileObject tileObject in currentMovableTiles)
{
tileObject.sprite.color = Color.green;
}
}
private void PathfindToTarget()
{
pathRequested.Clear();
TileObject currentTile = requestedTile;
while (currentTile != selectedEntity.currentTile)
{
pathRequested.Add(currentTile);
currentTile = currentPaths[currentTile];
}
pathRequested.Reverse();
foreach (TileObject tile in pathRequested)
{
tile.sprite.color = Color.blue;
}
}
private bool SelectLocation()
{
if (!requestedTile || requestedTile.blocked || requestedTile.hasUnit || !currentMovableTiles.Contains(requestedTile))
{
return false;
}
selectedEntity.currentTile.hasUnit = false;
requestedTile.hasUnit = true;
StartCoroutine(selectedEntity.MoveToLocation(pathRequested.ToArray()));
templateObject.SetActive(false);
UncolorGrid();
ActionUIHandler.instance.ShowUI(selectedEntity);
return true;
}
private void Deselect()
{
isMoving = false;
}
private void CreateTemplate()
{
templateObject.SetActive(true);
templateObject.transform.position = mouseGridPos;
}
}