diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs index eb971f54b..ddff2d5a1 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs @@ -3217,8 +3217,6 @@ namespace Barotrauma.Networking roundStartTime = DateTime.Now; - GameMain.LuaCs.Hook.Call("roundStart"); - startGameCoroutine = null; yield return CoroutineStatus.Success; } diff --git a/Barotrauma/BarotraumaShared/LocalMods/[DebugOnlyTest]TestLuaMod/Lua/init.lua b/Barotrauma/BarotraumaShared/LocalMods/[DebugOnlyTest]TestLuaMod/Lua/init.lua index f8f41c492..a3252fc85 100644 --- a/Barotrauma/BarotraumaShared/LocalMods/[DebugOnlyTest]TestLuaMod/Lua/init.lua +++ b/Barotrauma/BarotraumaShared/LocalMods/[DebugOnlyTest]TestLuaMod/Lua/init.lua @@ -1 +1,25 @@ -print("Hello!") \ No newline at end of file +print("Hello!") + +Hook.Add("character.created", "test", function(character) + print("character.created: ", character) +end) + +Hook.Add("character.death", "test", function(character) + print("character.death: ", character) +end) + +Hook.Add("character.giveJobItems", "test", function(character) + print("character.giveJobItems: ", character) +end) + +Hook.Add("roundStart", "test", function() + print("roundStart") +end) + +Hook.Add("roundEnd", "test", function() + print("roundEnd") +end) + +Hook.Add("missionsEnded", "test", function() + print("missionsEnded") +end) \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs index 46ee0b105..3436ec8a6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs @@ -5126,7 +5126,6 @@ namespace Barotrauma AchievementManager.OnCharacterKilled(this, CauseOfDeath); } - GameMain.LuaCs.Hook.Call("character.death", this, causeOfDeathAffliction); KillProjSpecific(causeOfDeath, causeOfDeathAffliction, log); if (info != null) diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs index f3782f134..b29059ecb 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs @@ -408,7 +408,6 @@ namespace Barotrauma public void LoadPreviousSave() { - GameMain.LuaCs.Hook.Call("roundEnd"); AchievementManager.OnRoundEnded(this, roundInterrupted: true); Submarine.Unload(); SaveUtil.LoadGame(DataPath); @@ -761,7 +760,6 @@ namespace Barotrauma GUI.PreventPauseMenuToggle = false; HintManager.OnRoundStarted(); - GameMain.LuaCs.Hook.Call("roundStart"); EnableEventLogNotificationIcon(enabled: false); LogStartRoundStats(); @@ -1089,9 +1087,6 @@ namespace Barotrauma { RoundEnding = true; -#if CLIENT - GameMain.LuaCs.Hook.Call("roundEnd"); -#endif //Clear the grids to allow for garbage collection Powered.Grids.Clear(); Powered.ChangedConnections.Clear(); @@ -1110,8 +1105,6 @@ namespace Barotrauma character.CheckTalents(AbilityEffectType.OnRoundEnd); } - GameMain.LuaCs.Hook.Call("missionsEnded", missions); - #if CLIENT if (GUI.PauseMenuOpen) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/IEvents.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/IEvents.cs index afffcaa7b..a392928f7 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/IEvents.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/IEvents.cs @@ -133,6 +133,25 @@ internal interface IEventCharacterCreated : IEvent } } +internal interface IEventCharacterDeath : IEvent +{ + void OnCharacterDeath(Character character, Affliction causeOfDeathAffliction, CauseOfDeathType causeOfDeathType); + + static IEventCharacterDeath IEvent.GetLuaRunner(IDictionary luaFunc) + => new LuaWrapper(luaFunc); + + public sealed class LuaWrapper : LuaWrapperBase, IEventCharacterDeath + { + public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) + { + } + + public void OnCharacterDeath(Character character, Affliction causeOfDeathAffliction, CauseOfDeathType causeOfDeathType) + { + LuaFuncs[nameof(OnCharacterDeath)](character, causeOfDeathAffliction, causeOfDeathType); + } + } +} /* internal interface IEventHumanCPRFailed : IEvent @@ -223,6 +242,49 @@ public interface IEventRoundStarted : IEvent } } +/// +/// Called when a round has ended. +/// +public interface IEventRoundEnded : IEvent +{ + void OnRoundEnd(); + + static IEventRoundEnded IEvent.GetLuaRunner(IDictionary luaFunc) + => new LuaWrapper(luaFunc); + + public sealed class LuaWrapper : LuaWrapperBase, IEventRoundEnded + { + public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) + { + } + + public void OnRoundEnd() + { + LuaFuncs[nameof(OnRoundEnd)](); + } + } +} + +internal interface IEventMissionsEnded : IEvent +{ + void OnMissionsEnded(IReadOnlyList missions); + + static IEventMissionsEnded IEvent.GetLuaRunner(IDictionary luaFunc) + => new LuaWrapper(luaFunc); + + public sealed class LuaWrapper : LuaWrapperBase, IEventMissionsEnded + { + public LuaWrapper(IDictionary luaFuncs) : base(luaFuncs) + { + } + + public void OnMissionsEnded(IReadOnlyList missions) + { + LuaFuncs[nameof(OnMissionsEnded)](missions); + } + } +} + /// /// Called on game loop normal update. /// diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/HarmonyEventPatchesService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/HarmonyEventPatchesService.cs index 916858880..5054bc0ba 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/HarmonyEventPatchesService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/HarmonyEventPatchesService.cs @@ -4,6 +4,9 @@ using Barotrauma.Networking; using HarmonyLib; using Microsoft.Xna.Framework; using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; using static Barotrauma.ContentPackageManager; namespace Barotrauma.LuaCs; @@ -23,6 +26,9 @@ internal class HarmonyEventPatchesService : IService _loggerService = loggerService; Harmony = new Harmony("LuaCsForBarotrauma.Events"); Harmony.PatchAll(typeof(HarmonyEventPatchesService)); +#if SERVER + Harmony.PatchAll(typeof(HarmonyEventPatchesService.Patch_StartGame_End)); +#endif } [HarmonyPatch(typeof(CoroutineManager), nameof(CoroutineManager.Update)), HarmonyPostfix] @@ -32,6 +38,35 @@ internal class HarmonyEventPatchesService : IService _loggerService.ProcessLogs(); } +#if CLIENT + [HarmonyPatch(typeof(GameSession), nameof(GameSession.StartRound), new Type[] + { + typeof(LevelData), typeof(bool), typeof(SubmarineInfo), typeof(SubmarineInfo) + }), HarmonyPostfix] + public static void GameSession_StartRound_Post() + { + _eventService.PublishEvent(x => x.OnRoundStart()); + } +#endif + + [HarmonyPatch(typeof(GameSession), nameof(GameSession.EndRound)), HarmonyPrefix] + public static void GameSession_EndRound_Pre() + { + _eventService.PublishEvent(x => x.OnRoundEnd()); + } + + [HarmonyPatch(typeof(GameSession), nameof(GameSession.LoadPreviousSave)), HarmonyPrefix] + public static void GameSession_LoadPreviousSave_Pre() + { + _eventService.PublishEvent(x => x.OnRoundEnd()); + } + + [HarmonyPatch(typeof(GameSession), nameof(GameSession.EndMissions)), HarmonyPostfix] + public static void GameSession_EndMission_Post(GameSession __instance) + { + _eventService.PublishEvent(x => x.OnMissionsEnded(__instance.Missions.ToList())); + } + [HarmonyPatch(typeof(Screen), nameof(Screen.Select)), HarmonyPostfix] public static void Screen_Selected_Post(Screen __instance) { @@ -110,6 +145,12 @@ internal class HarmonyEventPatchesService : IService _eventService.PublishEvent(x => x.OnCharacterCreated(__result)); } + [HarmonyPatch(typeof(Character), nameof(Character.Kill)), HarmonyPostfix] + public static void Character_Kill_Post(Character __instance, Affliction causeOfDeathAffliction, CauseOfDeathType causeOfDeath) + { + _eventService.PublishEvent(x => x.OnCharacterDeath(__instance, causeOfDeathAffliction, causeOfDeath)); + } + [HarmonyPatch(typeof(Character), nameof(Character.GiveJobItems)), HarmonyPostfix] public static void Character_GiveJobItems_Post(Character __instance, WayPoint spawnPoint, bool isPvPMode) { @@ -127,4 +168,34 @@ internal class HarmonyEventPatchesService : IService IsDisposed = true; Harmony.UnpatchSelf(); } + +#if SERVER + [HarmonyPatch] + class Patch_StartGame_End + { + static MethodBase TargetMethod() + { + var original = AccessTools.Method( + typeof(GameServer), + "StartGame" + ); + + return AccessTools.EnumeratorMoveNext(original); + } + + [HarmonyPostfix] + static void Postfix(object __instance, bool __result) + { + if (!__result) { return; } + + var enumerator = __instance as IEnumerator; + if (enumerator == null) { return; } + + if (enumerator.Current == CoroutineStatus.Success) + { + _eventService.PublishEvent(x => x.OnRoundStart()); + } + } + } +#endif } diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs index 3e92804fe..5a3b2dbfb 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs @@ -171,11 +171,19 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService private void RegisterLuaEvents() { - _eventService.RegisterLuaEventAlias("think", "OnUpdate"); - _eventService.RegisterLuaEventAlias("keyUpdate", "OnKeyUpdate"); - _eventService.RegisterLuaEventAlias("character.created", "OnCharacterCreated"); - _eventService.RegisterLuaEventAlias("character.giveJobItems", "OnGiveCharacterJobItems"); - _eventService.RegisterLuaEventAlias("afflictionUpdate", "OnAfflictionUpdate"); + _eventService.RegisterLuaEventAlias("think", nameof(IEventUpdate.OnUpdate)); + _eventService.RegisterLuaEventAlias("keyUpdate", nameof(IEventKeyUpdate.OnKeyUpdate)); + _eventService.RegisterLuaEventAlias("afflictionUpdate", nameof(IEventAfflictionUpdate.OnAfflictionUpdate)); + + _eventService.RegisterLuaEventAlias("character.created", nameof(IEventCharacterCreated.OnCharacterCreated)); + _eventService.RegisterLuaEventAlias("character.death", nameof(IEventCharacterDeath.OnCharacterDeath)); + _eventService.RegisterLuaEventAlias("character.giveJobItems", nameof(IEventGiveCharacterJobItems.OnGiveCharacterJobItems)); + + _eventService.RegisterLuaEventAlias("roundStart", nameof(IEventRoundStarted.OnRoundStart)); + _eventService.RegisterLuaEventAlias("roundEnd", nameof(IEventRoundEnded.OnRoundEnd)); + _eventService.RegisterLuaEventAlias("missionsEnded", nameof(IEventMissionsEnded.OnMissionsEnded)); + + } private void SetupEnvironment(bool enableSandbox)