feat: Implement a comprehensive global event bus with new event handlers and integrate player health and collection events.
This commit is contained in:
23
scripts/Constants.cs
Normal file
23
scripts/Constants.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace Mr.BrickAdventures;
|
||||
|
||||
/// <summary>
|
||||
/// Constants for autoload paths and other commonly used values.
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
// Autoload paths
|
||||
public const string EventBusPath = "/root/EventBus";
|
||||
public const string GameManagerPath = "/root/GameManager";
|
||||
public const string SaveSystemPath = "/root/SaveSystem";
|
||||
public const string SpeedRunManagerPath = "/root/SpeedRunManager";
|
||||
public const string GhostManagerPath = "/root/GhostManager";
|
||||
public const string AchievementManagerPath = "/root/AchievementManager";
|
||||
public const string StatisticsManagerPath = "/root/StatisticsManager";
|
||||
public const string SkillManagerPath = "/root/SkillManager";
|
||||
public const string FloatingTextManagerPath = "/root/FloatingTextManager";
|
||||
public const string UIManagerPath = "/root/UIManager";
|
||||
public const string ConsoleManagerPath = "/root/ConsoleManager";
|
||||
|
||||
// Group names
|
||||
public const string CoinsGroup = "coins";
|
||||
}
|
||||
1
scripts/Constants.cs.uid
Normal file
1
scripts/Constants.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bn7o3n3bomvrd
|
||||
@@ -1,4 +1,5 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Events;
|
||||
@@ -10,11 +11,10 @@ public partial class GhostEventHandler : Node
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_ghostManager = GetNode<GhostManager>("/root/GhostManager");
|
||||
var eventBus = GetNode<EventBus>("/root/EventBus");
|
||||
|
||||
eventBus.LevelStarted += OnLevelStarted;
|
||||
eventBus.LevelCompleted += OnLevelCompleted;
|
||||
_ghostManager = GetNode<GhostManager>(Constants.GhostManagerPath);
|
||||
|
||||
EventBus.Instance.LevelStarted += OnLevelStarted;
|
||||
EventBus.Instance.LevelCompleted += OnLevelCompleted;
|
||||
}
|
||||
|
||||
private void OnLevelStarted(int levelIndex, Node currentScene)
|
||||
@@ -23,7 +23,7 @@ public partial class GhostEventHandler : Node
|
||||
_ghostManager.StartRecording(levelIndex);
|
||||
_ghostManager.SpawnGhostPlayer(levelIndex, currentScene);
|
||||
}
|
||||
|
||||
|
||||
private void OnLevelCompleted(int levelIndex, Node currentScene, double completionTime)
|
||||
{
|
||||
_ghostManager.StopRecording(true, completionTime);
|
||||
|
||||
34
scripts/Events/ScoreEventHandler.cs
Normal file
34
scripts/Events/ScoreEventHandler.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Handles coin collection events and updates the session state.
|
||||
/// Replaces the manual signal wiring in ScoreComponent.
|
||||
/// </summary>
|
||||
public partial class ScoreEventHandler : Node
|
||||
{
|
||||
private GameManager _gameManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_gameManager = GetNode<GameManager>(Constants.GameManagerPath);
|
||||
|
||||
EventBus.Instance.CoinCollected += OnCoinCollected;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (EventBus.Instance != null)
|
||||
EventBus.Instance.CoinCollected -= OnCoinCollected;
|
||||
}
|
||||
|
||||
private void OnCoinCollected(int amount, Vector2 position)
|
||||
{
|
||||
var currentCoins = (int)_gameManager.CurrentSessionState["coins_collected"];
|
||||
_gameManager.CurrentSessionState["coins_collected"] = currentCoins + amount;
|
||||
GD.Print($"ScoreEventHandler: Collected {amount} coins. Total session coins: {currentCoins + amount}");
|
||||
}
|
||||
}
|
||||
1
scripts/Events/ScoreEventHandler.cs.uid
Normal file
1
scripts/Events/ScoreEventHandler.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cs4cfk7g5vh2v
|
||||
@@ -1,4 +1,5 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Events;
|
||||
@@ -10,10 +11,9 @@ public partial class SpeedRunEventHandler : Node
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_speedRunManager = GetNode<SpeedRunManager>("/root/SpeedRunManager");
|
||||
var eventBus = GetNode<EventBus>("/root/EventBus");
|
||||
|
||||
eventBus.LevelCompleted += OnLevelCompleted;
|
||||
_speedRunManager = GetNode<SpeedRunManager>(Constants.SpeedRunManagerPath);
|
||||
|
||||
EventBus.Instance.LevelCompleted += OnLevelCompleted;
|
||||
}
|
||||
|
||||
private void OnLevelCompleted(int levelIndex, Node currentScene, double completionTime)
|
||||
|
||||
62
scripts/Events/StatisticsEventHandler.cs
Normal file
62
scripts/Events/StatisticsEventHandler.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Handles game events and updates statistics accordingly.
|
||||
/// Listens to EventBus signals and increments relevant stats.
|
||||
/// </summary>
|
||||
public partial class StatisticsEventHandler : Node
|
||||
{
|
||||
private StatisticsManager _statisticsManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_statisticsManager = GetNode<StatisticsManager>(Constants.StatisticsManagerPath);
|
||||
|
||||
// Subscribe to events
|
||||
EventBus.Instance.CoinCollected += OnCoinCollected;
|
||||
EventBus.Instance.EnemyDefeated += OnEnemyDefeated;
|
||||
EventBus.Instance.PlayerDied += OnPlayerDied;
|
||||
EventBus.Instance.LevelCompleted += OnLevelCompleted;
|
||||
EventBus.Instance.ChildRescued += OnChildRescued;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (EventBus.Instance == null) return;
|
||||
|
||||
EventBus.Instance.CoinCollected -= OnCoinCollected;
|
||||
EventBus.Instance.EnemyDefeated -= OnEnemyDefeated;
|
||||
EventBus.Instance.PlayerDied -= OnPlayerDied;
|
||||
EventBus.Instance.LevelCompleted -= OnLevelCompleted;
|
||||
EventBus.Instance.ChildRescued -= OnChildRescued;
|
||||
}
|
||||
|
||||
private void OnCoinCollected(int amount, Vector2 position)
|
||||
{
|
||||
_statisticsManager.IncrementStat("coins_collected", amount);
|
||||
}
|
||||
|
||||
private void OnEnemyDefeated(Node enemy, Vector2 position)
|
||||
{
|
||||
_statisticsManager.IncrementStat("enemies_defeated");
|
||||
}
|
||||
|
||||
private void OnPlayerDied(Vector2 position)
|
||||
{
|
||||
_statisticsManager.IncrementStat("deaths");
|
||||
}
|
||||
|
||||
private void OnLevelCompleted(int levelIndex, Node currentScene, double completionTime)
|
||||
{
|
||||
_statisticsManager.IncrementStat("levels_completed");
|
||||
}
|
||||
|
||||
private void OnChildRescued(Vector2 position)
|
||||
{
|
||||
_statisticsManager.IncrementStat("children_rescued");
|
||||
}
|
||||
}
|
||||
1
scripts/Events/StatisticsEventHandler.cs.uid
Normal file
1
scripts/Events/StatisticsEventHandler.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://l68tjau3k6bw
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
@@ -35,7 +36,7 @@ public partial class CollectableComponent : Node
|
||||
if (Owner.HasNode("FadeAwayComponent"))
|
||||
_hasFadeAway = true;
|
||||
|
||||
_floatingTextManager = GetNode<FloatingTextManager>("/root/FloatingTextManager");
|
||||
_floatingTextManager = GetNode<FloatingTextManager>(Constants.FloatingTextManagerPath);
|
||||
}
|
||||
|
||||
private async void OnArea2DBodyEntered(Node2D body)
|
||||
@@ -53,12 +54,18 @@ public partial class CollectableComponent : Node
|
||||
{
|
||||
case CollectableType.Coin:
|
||||
_floatingTextManager?.ShowCoin((int)Data.Amount, ownerNode.GlobalPosition);
|
||||
EventBus.EmitCoinCollected((int)Data.Amount, ownerNode.GlobalPosition);
|
||||
break;
|
||||
case CollectableType.Health:
|
||||
_floatingTextManager?.ShowMessage("Healed!", ownerNode.GlobalPosition);
|
||||
EventBus.EmitItemCollected(Data.Type, Data.Amount, ownerNode.GlobalPosition);
|
||||
break;
|
||||
case CollectableType.Kid:
|
||||
_floatingTextManager?.ShowMessage("Rescued!", ownerNode.GlobalPosition);
|
||||
EventBus.EmitChildRescued(ownerNode.GlobalPosition);
|
||||
break;
|
||||
default:
|
||||
EventBus.EmitItemCollected(Data.Type, Data.Amount, ownerNode.GlobalPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
@@ -23,7 +24,7 @@ public partial class EnemyDeathComponent : Node
|
||||
GD.PushError("EnemyDeathComponent: Health is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Health.Death += OnDeath;
|
||||
}
|
||||
|
||||
@@ -34,6 +35,12 @@ public partial class EnemyDeathComponent : Node
|
||||
|
||||
private async Task Die()
|
||||
{
|
||||
// Emit enemy defeated event for statistics and other systems
|
||||
if (Owner is Node2D ownerNode)
|
||||
{
|
||||
EventBus.EmitEnemyDefeated(Owner, ownerNode.GlobalPosition);
|
||||
}
|
||||
|
||||
CollisionShape.SetDisabled(true);
|
||||
var tween = CreateTween();
|
||||
tween.TweenProperty(Owner, "scale", Vector2.Zero, TweenDuration);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
@@ -11,22 +12,22 @@ public partial class HealthComponent : Node2D
|
||||
[Export] public float MaxHealth { get; set; } = 1.0f;
|
||||
[Export] public AudioStreamPlayer2D HurtSfx { get; set; }
|
||||
[Export] public AudioStreamPlayer2D HealSfx { get; set; }
|
||||
|
||||
|
||||
[Signal] public delegate void HealthChangedEventHandler(float delta, float totalHealth);
|
||||
[Signal] public delegate void DeathEventHandler();
|
||||
|
||||
|
||||
private FloatingTextManager _floatingTextManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_floatingTextManager = GetNode<FloatingTextManager>("/root/FloatingTextManager");
|
||||
_floatingTextManager = GetNode<FloatingTextManager>(Constants.FloatingTextManagerPath);
|
||||
}
|
||||
|
||||
|
||||
public void SetHealth(float newValue)
|
||||
{
|
||||
_ = ApplyHealthChange(newValue);
|
||||
}
|
||||
|
||||
|
||||
public void IncreaseHealth(float delta)
|
||||
{
|
||||
_ = ApplyHealthChange(Health + delta);
|
||||
@@ -46,7 +47,7 @@ public partial class HealthComponent : Node2D
|
||||
|
||||
if (delta == 0.0f)
|
||||
return;
|
||||
|
||||
|
||||
if (delta < 0.0f)
|
||||
_floatingTextManager?.ShowDamage(Mathf.Abs(delta), GlobalPosition);
|
||||
else
|
||||
@@ -64,16 +65,27 @@ public partial class HealthComponent : Node2D
|
||||
await HurtSfx.ToSignal(HurtSfx, AudioStreamPlayer2D.SignalName.Finished);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Health = newHealth;
|
||||
|
||||
if (Health <= 0f)
|
||||
{
|
||||
EmitSignalDeath();
|
||||
// Emit global event if this is the player
|
||||
if (Owner is PlayerController)
|
||||
EventBus.EmitPlayerDied(GlobalPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSignalHealthChanged(delta, Health);
|
||||
// Emit global events if this is the player
|
||||
if (Owner is PlayerController)
|
||||
{
|
||||
if (delta < 0f)
|
||||
EventBus.EmitPlayerDamaged(Mathf.Abs(delta), Health, GlobalPosition);
|
||||
else
|
||||
EventBus.EmitPlayerHealed(delta, Health, GlobalPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user