diff --git a/src/AcDream.App/Program.cs b/src/AcDream.App/Program.cs index da0f748..e989b6e 100644 --- a/src/AcDream.App/Program.cs +++ b/src/AcDream.App/Program.cs @@ -50,7 +50,7 @@ try catch (Exception ex) { Log.Error(ex, "plugin enable failed: {Id}", plugin.Manifest.Id); } } - using var window = new GameWindow(datDir); + using var window = new GameWindow(datDir, worldGameState, worldEvents); window.Run(); } finally diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 126eccb..868c42e 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -1,3 +1,4 @@ +using AcDream.Core.Plugins; using DatReaderWriter; using DatReaderWriter.Options; using Silk.NET.Input; @@ -10,6 +11,8 @@ namespace AcDream.App.Rendering; public sealed class GameWindow : IDisposable { private readonly string _datDir; + private readonly WorldGameState _worldGameState; + private readonly WorldEvents _worldEvents; private IWindow? _window; private GL? _gl; private IInputContext? _input; @@ -25,7 +28,12 @@ public sealed class GameWindow : IDisposable private TextureCache? _textureCache; private IReadOnlyList _entities = Array.Empty(); - public GameWindow(string datDir) => _datDir = datDir; + public GameWindow(string datDir, WorldGameState worldGameState, WorldEvents worldEvents) + { + _datDir = datDir; + _worldGameState = worldGameState; + _worldEvents = worldEvents; + } public void Run() { @@ -209,14 +217,23 @@ public sealed class GameWindow : IDisposable (lbY - centerY) * 192f, 0f); - hydratedEntities.Add(new AcDream.Core.World.WorldEntity + var hydrated = new AcDream.Core.World.WorldEntity { Id = e.Id, SourceGfxObjOrSetupId = e.SourceGfxObjOrSetupId, Position = e.Position + worldOffset, Rotation = e.Rotation, MeshRefs = meshRefs, - }); + }; + hydratedEntities.Add(hydrated); + + var snapshot = new AcDream.Plugin.Abstractions.WorldEntitySnapshot( + Id: hydrated.Id, + SourceId: hydrated.SourceGfxObjOrSetupId, + Position: hydrated.Position, + Rotation: hydrated.Rotation); + _worldGameState.Add(snapshot); + _worldEvents.FireEntitySpawned(snapshot); } } diff --git a/src/AcDream.Plugins.Smoke/SmokePlugin.cs b/src/AcDream.Plugins.Smoke/SmokePlugin.cs index 310b1a3..d824825 100644 --- a/src/AcDream.Plugins.Smoke/SmokePlugin.cs +++ b/src/AcDream.Plugins.Smoke/SmokePlugin.cs @@ -5,6 +5,7 @@ namespace AcDream.Plugins.Smoke; public sealed class SmokePlugin : IAcDreamPlugin { private IPluginHost? _host; + private int _entitiesSeen; public void Initialize(IPluginHost host) { @@ -12,6 +13,22 @@ public sealed class SmokePlugin : IAcDreamPlugin _host.Log.Info("smoke plugin initialized"); } - public void Enable() => _host?.Log.Info("smoke plugin enabled"); - public void Disable() => _host?.Log.Info("smoke plugin disabled"); + public void Enable() + { + _host?.Log.Info("smoke plugin enabled"); + if (_host is not null) + { + _host.Events.EntitySpawned += OnEntitySpawned; + _host.Log.Info($"smoke plugin sees {_entitiesSeen} entities (replay count at subscribe)"); + } + } + + public void Disable() + { + if (_host is not null) + _host.Events.EntitySpawned -= OnEntitySpawned; + _host?.Log.Info($"smoke plugin disabled (saw {_entitiesSeen} entities total)"); + } + + private void OnEntitySpawned(WorldEntitySnapshot snapshot) => _entitiesSeen++; }