177 lines
5.0 KiB
C#
177 lines
5.0 KiB
C#
|
using System;
|
||
|
using UnityEngine;
|
||
|
|
||
|
// TODO: maybe instead of inheritance I could use behaviours
|
||
|
// So the Unit will still be a thing, and that's what the CameraController interfaces with
|
||
|
// But then commands will be sent to any attached behaviour (worker, marine, etc).
|
||
|
// and that behaviour can do whatever it needs.
|
||
|
// Now that I think about it more, maybe more granular behaviours (move, mine, build, attack, etc).
|
||
|
public class Worker : Unit
|
||
|
{
|
||
|
private enum WorkerState
|
||
|
{
|
||
|
None,
|
||
|
Building,
|
||
|
Mining,
|
||
|
Moving
|
||
|
}
|
||
|
|
||
|
public Building barracksGo;
|
||
|
public float mineDuration;
|
||
|
public int mineralHarvestAmount;
|
||
|
|
||
|
private WorkerState _currentState;
|
||
|
|
||
|
private Building _constructionBuilding;
|
||
|
|
||
|
private Minerals _minerals;
|
||
|
private Vector2 _mineralPatch;
|
||
|
private Vector2 _commandCenter;
|
||
|
private int _currentMineralsHeld;
|
||
|
private float _mineStartTime;
|
||
|
|
||
|
protected override void Start()
|
||
|
{
|
||
|
base.Start();
|
||
|
_currentState = WorkerState.None;
|
||
|
}
|
||
|
|
||
|
private void Update()
|
||
|
{
|
||
|
// TODO: maybe a function pointer instead of this switch?
|
||
|
switch (_currentState)
|
||
|
{
|
||
|
case WorkerState.None:
|
||
|
// Literally do nothing.
|
||
|
break;
|
||
|
case WorkerState.Building:
|
||
|
BuildBarracks();
|
||
|
break;
|
||
|
case WorkerState.Mining:
|
||
|
MineMinerals();
|
||
|
break;
|
||
|
case WorkerState.Moving:
|
||
|
MovementRoutine();
|
||
|
break;
|
||
|
default:
|
||
|
throw new ArgumentOutOfRangeException();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void MineMinerals()
|
||
|
{
|
||
|
_currentState = WorkerState.Mining;
|
||
|
if (_currentMineralsHeld <= 0)
|
||
|
{
|
||
|
if ((Vector2) _transform.position != _mineralPatch)
|
||
|
{
|
||
|
MoveTo(_mineralPatch);
|
||
|
_doThingAfterMove = () =>
|
||
|
{
|
||
|
_mineStartTime = Time.time;
|
||
|
MineMinerals();
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// TODO: wait to mine minerals;
|
||
|
if (Time.time >= _mineStartTime + mineDuration)
|
||
|
{
|
||
|
var amount = mineralHarvestAmount;
|
||
|
if (_minerals.amount < amount)
|
||
|
{
|
||
|
amount = _minerals.amount;
|
||
|
}
|
||
|
|
||
|
_minerals.amount -= amount;
|
||
|
_currentMineralsHeld = amount;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((Vector2) _transform.position != _commandCenter)
|
||
|
{
|
||
|
MoveTo(_commandCenter);
|
||
|
_doThingAfterMove = MineMinerals;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Team.Minerals += _currentMineralsHeld;
|
||
|
_currentMineralsHeld = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void BuildBarracks()
|
||
|
{
|
||
|
// Since we are in the Building state, just assume we have a construction building.
|
||
|
if (_constructionBuilding.isUnderConstruction)
|
||
|
{
|
||
|
_constructionBuilding.UpdateBuildProgress(Time.deltaTime);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// change state
|
||
|
_currentState = WorkerState.None;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void InstantiateBarracks()
|
||
|
{
|
||
|
if (barracksGo.buildingCost > Team.Minerals)
|
||
|
{
|
||
|
Debug.LogWarning("You've not enough minerals!");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Team.Minerals -= barracksGo.buildingCost;
|
||
|
_constructionBuilding = Instantiate(barracksGo,
|
||
|
_transform.position + new Vector3(0.5f, 0, 0),
|
||
|
_transform.rotation);
|
||
|
Team.AllBuildings.Add(_constructionBuilding);
|
||
|
_currentState = WorkerState.Building;
|
||
|
_doThingAfterMove = null;
|
||
|
}
|
||
|
|
||
|
protected override void CancelCurrentTask()
|
||
|
{
|
||
|
_currentState = WorkerState.None;
|
||
|
_doThingAfterMove = null;
|
||
|
// Might be able to just set the building to null all the time?
|
||
|
if (_currentState == WorkerState.Building)
|
||
|
{
|
||
|
_constructionBuilding = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void MoveTo(Vector3 position)
|
||
|
{
|
||
|
base.MoveTo(position);
|
||
|
_currentState = WorkerState.Moving;
|
||
|
}
|
||
|
|
||
|
// Called when the user selects the build barracks command.
|
||
|
public void BuildBarracks(Vector3 position)
|
||
|
{
|
||
|
MoveTo(position);
|
||
|
_doThingAfterMove = InstantiateBarracks;
|
||
|
}
|
||
|
|
||
|
// Called when the user right clicks on an unfinished building.
|
||
|
public void ConstructBuilding(Building building, Vector3 position)
|
||
|
{
|
||
|
MoveTo(position);
|
||
|
_constructionBuilding = building;
|
||
|
_doThingAfterMove = () => _currentState = WorkerState.Building;
|
||
|
}
|
||
|
|
||
|
public void StartMining(Minerals patch, Vector2 patchLocation, Vector2 commandCenterLocation)
|
||
|
{
|
||
|
_mineralPatch = patchLocation;
|
||
|
_commandCenter = commandCenterLocation;
|
||
|
_minerals = patch;
|
||
|
_currentState = WorkerState.Mining;
|
||
|
}
|
||
|
}
|