Move more events to be Harmony patches

This commit is contained in:
Evil Factory
2026-02-13 18:44:27 -03:00
parent dff38f7609
commit 36471f2239
7 changed files with 171 additions and 16 deletions
@@ -3217,8 +3217,6 @@ namespace Barotrauma.Networking
roundStartTime = DateTime.Now; roundStartTime = DateTime.Now;
GameMain.LuaCs.Hook.Call("roundStart");
startGameCoroutine = null; startGameCoroutine = null;
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
@@ -1 +1,25 @@
print("Hello!") 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)
@@ -5126,7 +5126,6 @@ namespace Barotrauma
AchievementManager.OnCharacterKilled(this, CauseOfDeath); AchievementManager.OnCharacterKilled(this, CauseOfDeath);
} }
GameMain.LuaCs.Hook.Call("character.death", this, causeOfDeathAffliction);
KillProjSpecific(causeOfDeath, causeOfDeathAffliction, log); KillProjSpecific(causeOfDeath, causeOfDeathAffliction, log);
if (info != null) if (info != null)
@@ -408,7 +408,6 @@ namespace Barotrauma
public void LoadPreviousSave() public void LoadPreviousSave()
{ {
GameMain.LuaCs.Hook.Call("roundEnd");
AchievementManager.OnRoundEnded(this, roundInterrupted: true); AchievementManager.OnRoundEnded(this, roundInterrupted: true);
Submarine.Unload(); Submarine.Unload();
SaveUtil.LoadGame(DataPath); SaveUtil.LoadGame(DataPath);
@@ -761,7 +760,6 @@ namespace Barotrauma
GUI.PreventPauseMenuToggle = false; GUI.PreventPauseMenuToggle = false;
HintManager.OnRoundStarted(); HintManager.OnRoundStarted();
GameMain.LuaCs.Hook.Call("roundStart");
EnableEventLogNotificationIcon(enabled: false); EnableEventLogNotificationIcon(enabled: false);
LogStartRoundStats(); LogStartRoundStats();
@@ -1089,9 +1087,6 @@ namespace Barotrauma
{ {
RoundEnding = true; RoundEnding = true;
#if CLIENT
GameMain.LuaCs.Hook.Call("roundEnd");
#endif
//Clear the grids to allow for garbage collection //Clear the grids to allow for garbage collection
Powered.Grids.Clear(); Powered.Grids.Clear();
Powered.ChangedConnections.Clear(); Powered.ChangedConnections.Clear();
@@ -1110,8 +1105,6 @@ namespace Barotrauma
character.CheckTalents(AbilityEffectType.OnRoundEnd); character.CheckTalents(AbilityEffectType.OnRoundEnd);
} }
GameMain.LuaCs.Hook.Call("missionsEnded", missions);
#if CLIENT #if CLIENT
if (GUI.PauseMenuOpen) if (GUI.PauseMenuOpen)
{ {
@@ -133,6 +133,25 @@ internal interface IEventCharacterCreated : IEvent<IEventCharacterCreated>
} }
} }
internal interface IEventCharacterDeath : IEvent<IEventCharacterDeath>
{
void OnCharacterDeath(Character character, Affliction causeOfDeathAffliction, CauseOfDeathType causeOfDeathType);
static IEventCharacterDeath IEvent<IEventCharacterDeath>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventCharacterDeath
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public void OnCharacterDeath(Character character, Affliction causeOfDeathAffliction, CauseOfDeathType causeOfDeathType)
{
LuaFuncs[nameof(OnCharacterDeath)](character, causeOfDeathAffliction, causeOfDeathType);
}
}
}
/* /*
internal interface IEventHumanCPRFailed : IEvent<IEventHumanCPRFailed> internal interface IEventHumanCPRFailed : IEvent<IEventHumanCPRFailed>
@@ -223,6 +242,49 @@ public interface IEventRoundStarted : IEvent<IEventRoundStarted>
} }
} }
/// <summary>
/// Called when a round has ended.
/// </summary>
public interface IEventRoundEnded : IEvent<IEventRoundEnded>
{
void OnRoundEnd();
static IEventRoundEnded IEvent<IEventRoundEnded>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventRoundEnded
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public void OnRoundEnd()
{
LuaFuncs[nameof(OnRoundEnd)]();
}
}
}
internal interface IEventMissionsEnded : IEvent<IEventMissionsEnded>
{
void OnMissionsEnded(IReadOnlyList<Mission> missions);
static IEventMissionsEnded IEvent<IEventMissionsEnded>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventMissionsEnded
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public void OnMissionsEnded(IReadOnlyList<Mission> missions)
{
LuaFuncs[nameof(OnMissionsEnded)](missions);
}
}
}
/// <summary> /// <summary>
/// Called on game loop normal update. /// Called on game loop normal update.
/// </summary> /// </summary>
@@ -4,6 +4,9 @@ using Barotrauma.Networking;
using HarmonyLib; using HarmonyLib;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using static Barotrauma.ContentPackageManager; using static Barotrauma.ContentPackageManager;
namespace Barotrauma.LuaCs; namespace Barotrauma.LuaCs;
@@ -23,6 +26,9 @@ internal class HarmonyEventPatchesService : IService
_loggerService = loggerService; _loggerService = loggerService;
Harmony = new Harmony("LuaCsForBarotrauma.Events"); Harmony = new Harmony("LuaCsForBarotrauma.Events");
Harmony.PatchAll(typeof(HarmonyEventPatchesService)); Harmony.PatchAll(typeof(HarmonyEventPatchesService));
#if SERVER
Harmony.PatchAll(typeof(HarmonyEventPatchesService.Patch_StartGame_End));
#endif
} }
[HarmonyPatch(typeof(CoroutineManager), nameof(CoroutineManager.Update)), HarmonyPostfix] [HarmonyPatch(typeof(CoroutineManager), nameof(CoroutineManager.Update)), HarmonyPostfix]
@@ -32,6 +38,35 @@ internal class HarmonyEventPatchesService : IService
_loggerService.ProcessLogs(); _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<IEventRoundStarted>(x => x.OnRoundStart());
}
#endif
[HarmonyPatch(typeof(GameSession), nameof(GameSession.EndRound)), HarmonyPrefix]
public static void GameSession_EndRound_Pre()
{
_eventService.PublishEvent<IEventRoundEnded>(x => x.OnRoundEnd());
}
[HarmonyPatch(typeof(GameSession), nameof(GameSession.LoadPreviousSave)), HarmonyPrefix]
public static void GameSession_LoadPreviousSave_Pre()
{
_eventService.PublishEvent<IEventRoundEnded>(x => x.OnRoundEnd());
}
[HarmonyPatch(typeof(GameSession), nameof(GameSession.EndMissions)), HarmonyPostfix]
public static void GameSession_EndMission_Post(GameSession __instance)
{
_eventService.PublishEvent<IEventMissionsEnded>(x => x.OnMissionsEnded(__instance.Missions.ToList()));
}
[HarmonyPatch(typeof(Screen), nameof(Screen.Select)), HarmonyPostfix] [HarmonyPatch(typeof(Screen), nameof(Screen.Select)), HarmonyPostfix]
public static void Screen_Selected_Post(Screen __instance) public static void Screen_Selected_Post(Screen __instance)
{ {
@@ -110,6 +145,12 @@ internal class HarmonyEventPatchesService : IService
_eventService.PublishEvent<IEventCharacterCreated>(x => x.OnCharacterCreated(__result)); _eventService.PublishEvent<IEventCharacterCreated>(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<IEventCharacterDeath>(x => x.OnCharacterDeath(__instance, causeOfDeathAffliction, causeOfDeath));
}
[HarmonyPatch(typeof(Character), nameof(Character.GiveJobItems)), HarmonyPostfix] [HarmonyPatch(typeof(Character), nameof(Character.GiveJobItems)), HarmonyPostfix]
public static void Character_GiveJobItems_Post(Character __instance, WayPoint spawnPoint, bool isPvPMode) public static void Character_GiveJobItems_Post(Character __instance, WayPoint spawnPoint, bool isPvPMode)
{ {
@@ -127,4 +168,34 @@ internal class HarmonyEventPatchesService : IService
IsDisposed = true; IsDisposed = true;
Harmony.UnpatchSelf(); 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<CoroutineStatus>;
if (enumerator == null) { return; }
if (enumerator.Current == CoroutineStatus.Success)
{
_eventService.PublishEvent<IEventRoundStarted>(x => x.OnRoundStart());
}
}
}
#endif
} }
@@ -171,11 +171,19 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
private void RegisterLuaEvents() private void RegisterLuaEvents()
{ {
_eventService.RegisterLuaEventAlias<IEventUpdate>("think", "OnUpdate"); _eventService.RegisterLuaEventAlias<IEventUpdate>("think", nameof(IEventUpdate.OnUpdate));
_eventService.RegisterLuaEventAlias<IEventKeyUpdate>("keyUpdate", "OnKeyUpdate"); _eventService.RegisterLuaEventAlias<IEventKeyUpdate>("keyUpdate", nameof(IEventKeyUpdate.OnKeyUpdate));
_eventService.RegisterLuaEventAlias<IEventCharacterCreated>("character.created", "OnCharacterCreated"); _eventService.RegisterLuaEventAlias<IEventAfflictionUpdate>("afflictionUpdate", nameof(IEventAfflictionUpdate.OnAfflictionUpdate));
_eventService.RegisterLuaEventAlias<IEventGiveCharacterJobItems>("character.giveJobItems", "OnGiveCharacterJobItems");
_eventService.RegisterLuaEventAlias<IEventAfflictionUpdate>("afflictionUpdate", "OnAfflictionUpdate"); _eventService.RegisterLuaEventAlias<IEventCharacterCreated>("character.created", nameof(IEventCharacterCreated.OnCharacterCreated));
_eventService.RegisterLuaEventAlias<IEventCharacterDeath>("character.death", nameof(IEventCharacterDeath.OnCharacterDeath));
_eventService.RegisterLuaEventAlias<IEventGiveCharacterJobItems>("character.giveJobItems", nameof(IEventGiveCharacterJobItems.OnGiveCharacterJobItems));
_eventService.RegisterLuaEventAlias<IEventRoundStarted>("roundStart", nameof(IEventRoundStarted.OnRoundStart));
_eventService.RegisterLuaEventAlias<IEventRoundEnded>("roundEnd", nameof(IEventRoundEnded.OnRoundEnd));
_eventService.RegisterLuaEventAlias<IEventMissionsEnded>("missionsEnded", nameof(IEventMissionsEnded.OnMissionsEnded));
} }
private void SetupEnvironment(bool enableSandbox) private void SetupEnvironment(bool enableSandbox)