Created
November 10, 2023 10:24
-
-
Save Cruxial0/114499f5b825a1dbda90cc209d3ac21e to your computer and use it in GitHub Desktop.
Workstation system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ResourceNode : Workstation | |
{ | |
[SerializeField] private ResourceType resourceType; | |
[SerializeField] private float collectInterval = 30f; | |
[SerializeField] private int supply = 300; | |
private int _currSupply = 300; | |
protected override void Start() { | |
_currSupply = supply; | |
base.Start(); | |
} | |
private void Update() { | |
foreach (var unit in PresentUnits) { | |
IncrementUnitTimer(unit); | |
if (_unitTimers[unit] < collectInterval) continue; | |
ResetUnitTimer(unit); | |
// Define a delta value based on the unit's scavenger level | |
var change = unit.Levels.Scavenger.Level + 1; | |
_currSupply -= change; | |
// Add resources and unit experience | |
ResourceManager.Instance.AllocateResources(resourceType, change); | |
unit.SetExp(workType, Random.Range(0, 3)); | |
if (_currSupply <= 0) { | |
RemoveUnits(); | |
MessageReciever.Instance.Message(MessageType.ResourceDepleted, $"{resourceType} Node was depleted"); | |
Destroy(gameObject); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[RequireComponent(typeof(ContextMenuItem))] | |
public class Workstation : MonoBehaviour | |
{ | |
/// <summary> | |
/// Max amount of workers on this workstation | |
/// </summary> | |
[Range(0, 10)] [SerializeField] protected int maxWorkers; | |
/// <summary> | |
/// The radius around the building where the units will attatch to | |
/// </summary> | |
[Range(0, 30)] [SerializeField] protected float workerAttachmentRadius = 2f; | |
/// <summary> | |
/// The profession related to this workstation | |
/// </summary> | |
[SerializeField] protected Profession workType; | |
/// <summary> | |
/// How units behave at this workstation *(currently not implemented)* | |
/// </summary> | |
[SerializeField] protected WorkstationUnitBehaviour unitBehaviour = WorkstationUnitBehaviour.None; | |
protected Dictionary<Unit, float> _unitTimers = new(); | |
private float _adjacencyTimer = 1f; | |
private float _currTimeout; | |
private ContextMenuItem _contextMenuItem; | |
protected virtual void Start() { | |
_contextMenuItem = GetComponent<ContextMenuItem>(); | |
} | |
/// <summary> | |
/// A list of users assigned to this workstation | |
/// </summary> | |
protected List<Unit> Units = new(); | |
/// <summary> | |
/// Units that are working at this workstation | |
/// </summary> | |
protected List<Unit> PresentUnits = new(); | |
/// <summary> | |
/// Adds a unit to this workstation | |
/// </summary> | |
public virtual void AddUnit(Unit unit) { | |
if(Units.Count >= maxWorkers) return; | |
unit.SetWorkstation(this); | |
Units.Add(unit); | |
_unitTimers.TryAdd(unit, 0f); | |
unit.Killed += HandleUnitDeath; | |
} | |
/// <summary> | |
/// Tries to add a unit to this workstation. Returns false if there is no more space in the workstation. | |
/// </summary> | |
public virtual bool TryAddUnit(Unit unit) { | |
if (Units.Count >= maxWorkers) return false; | |
AddUnit(unit); | |
return true; | |
} | |
/// <summary> | |
/// Removes all units from this workstation | |
/// </summary> | |
public void RemoveUnits() { | |
foreach (var unit in Units) { | |
RemoveUnit(unit, true); | |
} | |
Units.Clear(); | |
} | |
/// <summary> | |
/// Removes a unit from this workstation | |
/// </summary> | |
public virtual void RemoveUnit(Unit unit, bool skipRemove = false) { | |
if(!skipRemove) Units.Remove(unit); | |
unit.SetWorkstation(null); | |
unit.StopWork(); | |
if (_unitTimers.ContainsKey(unit)) _unitTimers.Remove(unit); | |
unit.Killed -= HandleUnitDeath; | |
} | |
/// <summary> | |
/// Calls a specific unit to this workstation | |
/// </summary> | |
public virtual void CallUnit(Unit unit) { | |
unit.MoveTo(transform.position + GetRandomPositionInCircle()); | |
unit.StartWork(); | |
} | |
/// <summary> | |
/// Calls all assigned units to this workstation | |
/// </summary> | |
public virtual void CallAssignedUnits() { | |
foreach (var unit in Units) { | |
unit.MoveTo(transform.position + GetRandomPositionInCircle()); | |
} | |
} | |
public virtual void FixedUpdate() { | |
_currTimeout += Time.fixedDeltaTime; | |
if(_currTimeout < _adjacencyTimer) return; | |
PresentUnits = Units.Where(x => | |
Vector3.Distance(x.transform.position, this.transform.position) < workerAttachmentRadius + 1f).ToList(); | |
_contextMenuItem.workers = PresentUnits; | |
} | |
/// <summary> | |
/// Increments the work timer for the specified unit based on Time.deltaTime or Time.fixedDeltaTime | |
/// </summary> | |
protected virtual void IncrementUnitTimer(Unit unit, bool useFixedDeltaTime = false) { | |
if (_unitTimers.ContainsKey(unit)) | |
_unitTimers[unit] += useFixedDeltaTime ? Time.fixedDeltaTime : Time.deltaTime; | |
else _unitTimers.Add(unit, 0f); | |
} | |
/// <summary> | |
/// Resets the unit's timer to 0 | |
/// </summary> | |
protected virtual void ResetUnitTimer(Unit unit) { | |
if (_unitTimers.ContainsKey(unit)) _unitTimers[unit] = 0f; | |
} | |
private Vector3 GetRandomPositionInCircle() { | |
float angle = Random.Range(0, 360) * Mathf.PI * 2f / workerAttachmentRadius; | |
return new Vector3(Mathf.Cos(angle) * workerAttachmentRadius, 0, Mathf.Sin(angle) * workerAttachmentRadius); | |
} | |
/// <summary> | |
/// Makes sure units are removed upon death | |
/// </summary> | |
private void HandleUnitDeath(object sender, Unit e) { | |
Units.Remove(e); | |
if (PresentUnits.Contains(e)) PresentUnits.Remove(e); | |
if (_unitTimers.ContainsKey(e)) _unitTimers.Remove(e); | |
} | |
#if UNITY_EDITOR | |
/// <summary> | |
/// Creates a visual representation in the unity editor of where the units will stand | |
/// </summary> | |
private void OnDrawGizmosSelected() { | |
Handles.color = Color.cyan; | |
Handles.DrawWireDisc(transform.localPosition, Vector3.up, workerAttachmentRadius); | |
} | |
#endif | |
} | |
public enum WorkstationUnitBehaviour | |
{ | |
None, | |
Disappear, | |
WorkAnimation | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment