131 lines
2.8 KiB
C#
131 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
// TODO: The actual building logic and the construction logic should be separated!
|
|
[RequireComponent(typeof(BoxCollider2D), typeof(SpriteRenderer))]
|
|
public class Building : MonoBehaviour
|
|
{
|
|
private struct WorkOrder
|
|
{
|
|
public float startTime;
|
|
public float duration;
|
|
public Action completed;
|
|
}
|
|
|
|
[Serializable]
|
|
public struct UnitCommand
|
|
{
|
|
public Unit unit;
|
|
public Key keyControl;
|
|
public int cost;
|
|
public float buildDuration;
|
|
}
|
|
|
|
[NonSerialized] public BoxCollider2D buildingCollider;
|
|
|
|
public int maxQueueCount;
|
|
public float constructionTime;
|
|
public bool startBuilt;
|
|
public int buildingCost;
|
|
public List<UnitCommand> buildableUnits;
|
|
|
|
[NonSerialized] public bool isUnderConstruction = true;
|
|
|
|
private readonly Queue<WorkOrder> _workQueue = new Queue<WorkOrder>();
|
|
private WorkOrder _currentWorkOrder;
|
|
|
|
private bool _hasCurrentWorkOrder;
|
|
|
|
// In seconds.
|
|
private float _currentConstructionProgress;
|
|
private readonly Color _constructionColor = Color.black;
|
|
private SpriteRenderer _sprite;
|
|
|
|
private Transform _transform;
|
|
|
|
private void Start()
|
|
{
|
|
buildingCollider = GetComponent<BoxCollider2D>();
|
|
_sprite = GetComponent<SpriteRenderer>();
|
|
isUnderConstruction = !startBuilt;
|
|
_transform = transform;
|
|
}
|
|
|
|
public void UpdateBuildProgress(float amount)
|
|
{
|
|
if (isUnderConstruction)
|
|
{
|
|
_currentConstructionProgress += amount;
|
|
if (_currentConstructionProgress >= constructionTime)
|
|
{
|
|
isUnderConstruction = false;
|
|
}
|
|
|
|
_sprite.color = Color.Lerp(_constructionColor, Color.white,
|
|
_currentConstructionProgress / constructionTime);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (_hasCurrentWorkOrder)
|
|
{
|
|
if (Time.time > _currentWorkOrder.startTime + _currentWorkOrder.duration)
|
|
{
|
|
_currentWorkOrder.completed();
|
|
_hasCurrentWorkOrder = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Could probably do all this once we complete the order.
|
|
// Would also need to do it when we receive an order.
|
|
if (_workQueue.Count > 0)
|
|
{
|
|
_currentWorkOrder = _workQueue.Dequeue();
|
|
_currentWorkOrder.startTime = Time.time;
|
|
_hasCurrentWorkOrder = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ProcessKeyInput(Key key)
|
|
{
|
|
if (isUnderConstruction)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (var command in buildableUnits)
|
|
{
|
|
if (command.keyControl == key)
|
|
{
|
|
if (command.cost > Team.Minerals)
|
|
{
|
|
// TODO: announcer.
|
|
Debug.LogWarning("You've not enough minerals");
|
|
break;
|
|
}
|
|
|
|
if (maxQueueCount > _workQueue.Count)
|
|
{
|
|
Team.Minerals -= command.cost;
|
|
_workQueue.Enqueue(new WorkOrder
|
|
{
|
|
startTime = Time.time,
|
|
duration = command.buildDuration,
|
|
completed = () =>
|
|
{
|
|
var unitGo = Instantiate(command.unit,
|
|
_transform.position, _transform.rotation);
|
|
Team.AllUnits.Add(unitGo);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|