114 lines
3.0 KiB
C#
114 lines
3.0 KiB
C#
using System.Linq;
|
|
using Godot;
|
|
using MaxEffort.Code.Core;
|
|
using MaxEffort.Code.Data;
|
|
|
|
namespace MaxEffort.Code.Systems;
|
|
|
|
[GlobalClass]
|
|
public partial class HazardSystem : Node
|
|
{
|
|
[Export] private Godot.Collections.Array<HazardDef> _possibleHazards;
|
|
[Export] private Godot.Collections.Array<Node2D> _spawnLocations;
|
|
[Export] private PackedScene _hazardPrefab; // The visual object to spawn
|
|
[Export] private float _checkInterval = 1.0f; // How often to try spawning
|
|
|
|
private float _currentFocus = 0f;
|
|
private double _timer = 0;
|
|
private RandomNumberGenerator _rng = new();
|
|
|
|
public override void _Ready()
|
|
{
|
|
EventBus.OnFocusChanged += OnFocusChanged;
|
|
EventBus.OnHazardResolved += OnHazardResolved;
|
|
}
|
|
|
|
public override void _ExitTree()
|
|
{
|
|
EventBus.OnFocusChanged -= OnFocusChanged;
|
|
EventBus.OnHazardResolved -= OnHazardResolved;
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
_timer += delta;
|
|
if (_timer >= _checkInterval)
|
|
{
|
|
_timer = 0;
|
|
TrySpawnHazard();
|
|
}
|
|
}
|
|
|
|
public void SetAvailableHazards(Godot.Collections.Array<HazardDef> hazards)
|
|
{
|
|
if (_possibleHazards == null) _possibleHazards = [];
|
|
|
|
_possibleHazards.Clear();
|
|
foreach(var h in hazards) _possibleHazards.Add(h);
|
|
}
|
|
|
|
public void ClearHazards()
|
|
{
|
|
if (_spawnLocations == null) return;
|
|
|
|
// Loop through all locations and destroy active hazards
|
|
foreach (var loc in _spawnLocations)
|
|
{
|
|
foreach (Node child in loc.GetChildren())
|
|
{
|
|
child.QueueFree();
|
|
}
|
|
}
|
|
_timer = 0;
|
|
}
|
|
|
|
private void OnFocusChanged(float focus)
|
|
{
|
|
_currentFocus = focus;
|
|
}
|
|
|
|
private void TrySpawnHazard()
|
|
{
|
|
if (_currentFocus < 0.2f) return;
|
|
|
|
var spawnChance = _currentFocus * 0.5f;
|
|
|
|
if (_rng.Randf() < spawnChance)
|
|
{
|
|
SpawnRandomHazard();
|
|
}
|
|
}
|
|
|
|
private void SpawnRandomHazard()
|
|
{
|
|
if (_possibleHazards.Count == 0 || _hazardPrefab == null || _spawnLocations.Count == 0) return;
|
|
|
|
var emptyLocations = _spawnLocations.Where(loc => loc.GetChildCount() == 0).ToArray();
|
|
|
|
if (emptyLocations.Length == 0) return;
|
|
|
|
var targetLoc = emptyLocations[_rng.Randi() % emptyLocations.Length];
|
|
|
|
var validHazards = _possibleHazards
|
|
.Where(h => h.MinFocusToSpawn <= _currentFocus)
|
|
.ToArray();
|
|
|
|
if (validHazards.Length == 0) return;
|
|
|
|
var selected = validHazards[_rng.Randi() % validHazards.Length];
|
|
|
|
if (_hazardPrefab.Instantiate() is HazardController instance)
|
|
{
|
|
instance.Position = Vector2.Zero;
|
|
targetLoc.AddChild(instance);
|
|
|
|
instance.Initialize(selected);
|
|
EventBus.PublishHazardSpawned(selected.Type);
|
|
}
|
|
}
|
|
|
|
private void OnHazardResolved(HazardType type)
|
|
{
|
|
GD.Print($"Resolved {type}!");
|
|
}
|
|
} |