using System; using System.Collections.Generic; using System.Reflection; using Barotrauma.LuaCs.Data; using Barotrauma.Networking; namespace Barotrauma.LuaCs.Events; /* * The following is a collection of interfaces that types can implement to be registered events. * Note: Internally-marked interfaces should be consumed using a publicizer. This is due to the Barotrauma source * types being internal by default. */ public interface IEvent { bool IsLuaRunner() => false; public abstract class LuaWrapperBase : IEvent { protected readonly IDictionary LuaFuncs; protected LuaWrapperBase(IDictionary luaFuncs) => LuaFuncs = luaFuncs; public bool IsLuaRunner() => true; } } public interface IEvent : IEvent where T : class, IEvent { static virtual T GetLuaRunner(IDictionary luaFunc) { throw new InvalidOperationException($"Lua runners forbidden for {typeof(T).Name}"); } } #region RuntimeServiceEvents /// /// Called when the current (game state) changes. Upstream Type 'Screen' is internal. /// internal interface IEventScreenSelected : IEvent { void OnScreenSelected(Screen screen); } /// /// Called whenever the list of all (enabled and disabled) on disk has changed. /// internal interface IEventAllPackageListChanged : IEvent { void OnAllPackageListChanged(IEnumerable corePackages, IEnumerable regularPackages); } /// /// Called whenever the list of enabled has changed. /// internal interface IEventEnabledPackageListChanged : IEvent { void OnEnabledPackageListChanged(CorePackage package, IEnumerable regularPackages); } internal interface IEventReloadAllPackages : IEvent { void OnReloadAllPackages(); } internal interface IEventSettingInstanceLifetime : IEvent { void OnSettingInstanceCreated(T configInstance) where T : ISettingBase; void OnSettingInstanceDisposed(T configInstance) where T : ISettingBase; } #endregion #region GameEvents internal interface IEventAfflictionUpdate : IEvent { void OnAfflictionUpdate(Affliction affliction, CharacterHealth characterHealth, Limb targetLimb, float deltaTime); static IEventAfflictionUpdate IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventAfflictionUpdate { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnAfflictionUpdate(Affliction affliction, CharacterHealth characterHealth, Limb targetLimb, float deltaTime) { LuaFuncs[nameof(OnAfflictionUpdate)](affliction, characterHealth, targetLimb, deltaTime); } } } internal interface IEventGiveCharacterJobItems : IEvent { void OnGiveCharacterJobItems(Character character, WayPoint spawnPoint, bool isPvPMode); static IEventGiveCharacterJobItems IEvent.GetLuaRunner( IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventGiveCharacterJobItems { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnGiveCharacterJobItems(Character character, WayPoint spawnPoint, bool isPvPMode) { LuaFuncs[nameof(OnGiveCharacterJobItems)](character, spawnPoint, isPvPMode); } } } internal interface IEventCharacterCreated : IEvent { void OnCharacterCreated(Character character); static IEventCharacterCreated IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventCharacterCreated { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnCharacterCreated(Character character) { LuaFuncs[nameof(OnCharacterCreated)](character); } } } /* internal interface IEventHumanCPRFailed : IEvent { void OnHumanCPRFailed(Character character); static IEventHumanCPRFailed IEvent.GetLuaRunner(IDictionary luaFunc) => new { IsLuaRunner = Return.Arguments(() => true), OnHumanCPRFailed = ReturnVoid.Arguments((Character character) => luaFunc[nameof(OnHumanCPRFailed)](character)) }.ActLike(); } internal interface IEventHumanCPRSuccess : IEvent { void OnHumanCPRSuccess(Character character); static IEventHumanCPRSuccess IEvent.GetLuaRunner(IDictionary luaFunc) => new { IsLuaRunner = Return.Arguments(() => true), OnHumanCPRSuccess = ReturnVoid.Arguments((Character character) => luaFunc[nameof(OnHumanCPRSuccess)](character)) }.ActLike(); } */ public interface IEventKeyUpdate : IEvent { void OnKeyUpdate(double deltaTime); static IEventKeyUpdate IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventKeyUpdate { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnKeyUpdate(double deltaTime) { LuaFuncs[nameof(OnKeyUpdate)](deltaTime); } } } /// /// Called as soon as round begins to load before any loading takes place. /// public interface IEventRoundStarting : IEvent { void OnRoundStarting(); static IEventRoundStarting IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventRoundStarting { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnRoundStarting() { LuaFuncs[nameof(OnRoundStarting)](); } } } /// /// Called when a round has started and fully loaded. /// public interface IEventRoundStarted : IEvent { void OnRoundStart(); static IEventRoundStarted IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventRoundStarted { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnRoundStart() { LuaFuncs[nameof(OnRoundStart)](); } } } /// /// Called on game loop normal update. /// public interface IEventUpdate : IEvent { void OnUpdate(double fixedDeltaTime); static IEventUpdate IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventUpdate { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnUpdate(double deltaTime) { LuaFuncs[nameof(OnUpdate)](deltaTime); } } } /// /// Called on game loop draw update. /// public interface IEventDrawUpdate : IEvent { void OnDrawUpdate(double deltaTime); static IEventDrawUpdate IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventDrawUpdate { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnDrawUpdate(double deltaTime) { LuaFuncs[nameof(OnDrawUpdate)](deltaTime); } } } #endregion #region Networking #region Networking-Server #if SERVER public interface IEventClientRawNetMessageReceived : IEvent { void OnReceivedClientNetMessage(IReadMessage netMessage, ClientPacketHeader serverPacketHeader, NetworkConnection sender); } /// /// Called when a client connects to the server and has loaded into the lobby. /// interface IEventClientConnected : IEvent { /// /// Called when a client connects to the server. /// /// The connecting client. void OnClientConnected(Client client); static IEventClientConnected IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventClientConnected { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnClientConnected(Client client) { LuaFuncs[nameof(OnClientConnected)](client); } } } #endif #endregion #region Networking-Client #if CLIENT public interface IEventServerRawNetMessageReceived : IEvent { void OnReceivedServerNetMessage(IReadMessage netMessage, ServerPacketHeader serverPacketHeader); } /// /// Called when the client has connected to the server and loaded to the lobby. /// public interface IEventServerConnected : IEvent { void OnServerConnected(); static IEventServerConnected IEvent.GetLuaRunner(IDictionary luaFunc) => new LuaWrapper(luaFunc); public sealed class LuaWrapper : LuaWrapperBase, IEventServerConnected { public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) { } public void OnServerConnected() { LuaFuncs[nameof(OnServerConnected)](); } } } #endif #endregion #endregion #region Assembly_PluginEvents /// /// Called on plugin normal, use this for basic/core loading that does not rely on any other modded content. /// public interface IEventPluginInitialize : IEvent { void Initialize(); } /// /// Called once all plugins have been loaded. if you have integrations with any other mod, put that code here. /// public interface IEventPluginLoadCompleted : IEvent { void OnLoadCompleted(); } /// /// Called before Barotrauma initializes plugins. Use if you want to patch another plugin's behaviour 'unofficially'. /// WARNING: This method is called before Initialize()! /// public interface IEventPluginPreInitialize : IEvent { void PreInitPatching(); } /// /// Called whenever a new assembly is loaded. /// public interface IEventAssemblyLoaded : IEvent { void OnAssemblyLoaded(Assembly assembly); } /// /// Called whenever an is instanced. /// public interface IEventAssemblyContextCreated : IEvent { void OnAssemblyCreated(IAssemblyLoaderService loaderService); } /// /// Called whenever an begins unloading. /// public interface IEventAssemblyContextUnloading : IEvent { void OnAssemblyUnloading(WeakReference loaderService); } public interface IEventAssemblyUnloading : IEvent { void OnAssemblyUnloading(Assembly assembly); } #endregion