Event pain

This commit is contained in:
Evil Factory
2026-02-15 17:58:25 -03:00
parent 13bfffa777
commit f70251fa3b
7 changed files with 294 additions and 39 deletions

View File

@@ -103,10 +103,6 @@ namespace Barotrauma
public void AddObjective<T>(T objective) where T : AIObjective
{
var result = GameMain.LuaCs.Hook.Call<bool?>("AI.addObjective", this, objective);
if (result != null && result.Value) return;
if (objective == null)
{
#if DEBUG

View File

@@ -4605,12 +4605,6 @@ namespace Barotrauma
public AttackResult DamageLimb(Vector2 worldPosition, Limb hitLimb, IEnumerable<Affliction> afflictions, float stun, bool playSound, Vector2 attackImpulse, Character attacker = null, float damageMultiplier = 1, bool allowStacking = true, float penetration = 0f, bool shouldImplode = false, bool ignoreDamageOverlay = false, bool recalculateVitality = true)
{
if (Removed) { return new AttackResult(); }
AttackResult? retAttackResult = GameMain.LuaCs.Hook.Call<AttackResult?>("character.damageLimb", this, worldPosition, hitLimb, afflictions, stun, playSound, attackImpulse, attacker, damageMultiplier, allowStacking, penetration, shouldImplode);
if (retAttackResult != null)
{
return retAttackResult.Value;
}
SetStun(stun);

View File

@@ -651,11 +651,6 @@ namespace Barotrauma
return;
}
var should = GameMain.LuaCs.Hook.Call<bool?>("inventoryPutItem", this, item, user, i, removeItem);
if (should != null && should.Value)
return;
if (Owner == null) { return; }
Inventory prevInventory = item.ParentInventory;
@@ -765,11 +760,6 @@ namespace Barotrauma
if (slots[index].Items.Any(it => !it.IsInteractable(user))) { return false; }
if (!AllowSwappingContainedItems) { return false; }
var should = GameMain.LuaCs.Hook.Call<bool?>("inventoryItemSwap", this, item, user, index, swapWholeStack);
if (should != null)
return should.Value;
//swap to InvSlotType.Any if possible
Inventory otherInventory = item.ParentInventory;
bool otherIsEquipped = false;

View File

@@ -1411,8 +1411,6 @@ namespace Barotrauma
if (Components.Any(ic => ic is Wire) && Components.All(ic => ic is Wire || ic is Holdable)) { isWire = true; }
if (HasTag(Barotrauma.Tags.LogicItem)) { isLogic = true; }
GameMain.LuaCs.Hook.Call<Item>("item.created", this);
ApplyStatusEffects(ActionType.OnSpawn, 1.0f);
// Set max condition multipliers from campaign settings for RecalculateConditionValues()
@@ -3364,10 +3362,6 @@ namespace Barotrauma
}
if (condition <= 0.0f) { return; }
var should = GameMain.LuaCs.Hook.Call<bool?>("item.use", new object[] { this, user, targetLimb, useTarget });
if (should != null && should.Value) { return; }
bool remove = false;
@@ -3400,11 +3394,6 @@ namespace Barotrauma
{
if (condition <= 0.0f) { return; }
var should = GameMain.LuaCs.Hook.Call<bool?>("item.secondaryUse", this, character);
if (should != null && should.Value)
return;
bool remove = false;
foreach (ItemComponent ic in components)
@@ -4621,8 +4610,6 @@ namespace Barotrauma
body.Remove();
body = null;
}
GameMain.LuaCs.Hook.Call<Item>("item.removed", this);
}
public override void Remove()
@@ -4707,8 +4694,6 @@ namespace Barotrauma
}
RemoveProjSpecific();
GameMain.LuaCs.Hook.Call<Item>("item.removed", this);
}
private void RemoveFromLists()

View File

@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Barotrauma.Items.Components;
using Barotrauma.Items.Components;
using Barotrauma.LuaCs.Data;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Steamworks.Ugc;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Barotrauma.LuaCs.Events;
@@ -351,6 +353,186 @@ interface IEventSignalReceived : IEvent<IEventSignalReceived>
}
}
interface IEventItemCreated : IEvent<IEventItemCreated>
{
void OnItemCreated(Item item);
static IEventItemCreated IEvent<IEventItemCreated>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventItemCreated
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public void OnItemCreated(Item item)
{
LuaFuncs[nameof(OnItemCreated)](item);
}
}
}
interface IEventItemRemoved : IEvent<IEventItemRemoved>
{
void OnItemRemoved(Item item);
static IEventItemRemoved IEvent<IEventItemRemoved>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventItemRemoved
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public void OnItemRemoved(Item item)
{
LuaFuncs[nameof(OnItemRemoved)](item);
}
}
}
interface IEventItemUse : IEvent<IEventItemUse>
{
bool? OnItemUsed(Item item, Character user, Limb targetLimb, Entity useTarget);
static IEventItemUse IEvent<IEventItemUse>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventItemUse
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public bool? OnItemUsed(Item item, Character user, Limb targetLimb, Entity useTarget)
{
var result = LuaFuncs[nameof(OnItemUsed)](item, user, targetLimb, useTarget);
if (result is bool b)
{
return b;
}
else
{
return null;
}
}
}
}
interface IEventItemSecondaryUse : IEvent<IEventItemSecondaryUse>
{
bool? OnItemSecondaryUsed(Item item, Character user);
static IEventItemSecondaryUse IEvent<IEventItemSecondaryUse>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventItemSecondaryUse
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public bool? OnItemSecondaryUsed(Item item, Character user)
{
var result = LuaFuncs[nameof(OnItemSecondaryUsed)](item, user);
if (result is bool b)
{
return b;
}
else
{
return null;
}
}
}
}
interface IEventCharacterDamageLimb : IEvent<IEventCharacterDamageLimb>
{
AttackResult? OnCharacterDamageLimb(Character character, Vector2 worldPosition, Limb hitLimb, IEnumerable<Affliction> afflictions, float stun, bool playSound, Vector2 attackImpulse, Character attacker = null, float damageMultiplier = 1, bool allowStacking = true, float penetration = 0f, bool shouldImplode = false);
static IEventCharacterDamageLimb IEvent<IEventCharacterDamageLimb>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventCharacterDamageLimb
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public AttackResult? OnCharacterDamageLimb(Character character, Vector2 worldPosition, Limb hitLimb, IEnumerable<Affliction> afflictions, float stun, bool playSound, Vector2 attackImpulse, Character attacker = null, float damageMultiplier = 1, bool allowStacking = true, float penetration = 0f, bool shouldImplode = false)
{
var result = LuaFuncs[nameof(OnCharacterDamageLimb)](character, worldPosition, hitLimb, afflictions, stun, playSound, attackImpulse, attacker, damageMultiplier, allowStacking, penetration, shouldImplode);
if (result is AttackResult attackResult)
{
return attackResult;
}
else
{
return null;
}
}
}
}
interface IEventInventoryPutItem : IEvent<IEventInventoryPutItem>
{
bool? OnInventoryPutItem(Inventory inventory, Item item, Character user, int i, bool removeItem);
static IEventInventoryPutItem IEvent<IEventInventoryPutItem>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventInventoryPutItem
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public bool? OnInventoryPutItem(Inventory inventory, Item item, Character user, int i, bool removeItem)
{
var result = LuaFuncs[nameof(OnInventoryPutItem)](inventory, item, user, i, removeItem);
if (result is bool b)
{
return b;
}
else
{
return null;
}
}
}
}
interface IEventInventoryItemSwap : IEvent<IEventInventoryItemSwap>
{
bool? OnInventoryItemSwap(Inventory inventory, Item item, Character user, int i, bool swapWholeStack);
static IEventInventoryItemSwap IEvent<IEventInventoryItemSwap>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc)
=> new LuaWrapper(luaFunc);
public sealed class LuaWrapper : LuaWrapperBase, IEventInventoryItemSwap
{
public LuaWrapper(IDictionary<string, LuaCsFunc> luaFuncs) : base(luaFuncs)
{
}
public bool? OnInventoryItemSwap(Inventory inventory, Item item, Character user, int i, bool swapWholeStack)
{
var result = LuaFuncs[nameof(OnInventoryItemSwap)](inventory, item, user, i, swapWholeStack);
if (result is bool b)
{
return b;
}
else
{
return null;
}
}
}
}
#endregion
#region Networking

View File

@@ -180,6 +180,20 @@ internal class HarmonyEventPatchesService : IService
_eventService.PublishEvent<IEventGiveCharacterJobItems>(x => x.OnGiveCharacterJobItems(__instance, spawnPoint, isPvPMode));
}
[HarmonyPatch(typeof(Character), nameof(Character.DamageLimb)), HarmonyPrefix]
public static bool Character_DamageLimb_Pre(AttackResult __result, Character __instance, Vector2 worldPosition, Limb hitLimb, IEnumerable<Affliction> afflictions, float stun, bool playSound, Vector2 attackImpulse, Character attacker, float damageMultiplier, bool allowStacking, float penetration, bool shouldImplode, bool ignoreDamageOverlay, bool recalculateVitality)
{
AttackResult? result = null;
_eventService.PublishEvent<IEventCharacterDamageLimb>(x => result = x.OnCharacterDamageLimb(__instance, worldPosition, hitLimb, afflictions, stun, playSound, attackImpulse, attacker, damageMultiplier, allowStacking, penetration, shouldImplode));
if (result != null)
{
__result = (AttackResult)result;
return false; // skip
}
return true;
}
[HarmonyPatch(typeof(Affliction), nameof(Affliction.Update)), HarmonyPostfix]
public static void Affliction_Update_Post(Affliction __instance, CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
{
@@ -206,6 +220,91 @@ internal class HarmonyEventPatchesService : IService
}
}
[HarmonyPatch(typeof(Item), MethodType.Constructor, new Type[] { typeof(Rectangle), typeof(ItemPrefab), typeof(Submarine), typeof(bool), typeof(ushort) }), HarmonyPostfix]
public static void Item_Ctor_Post(Item __instance)
{
_eventService.PublishEvent<IEventItemCreated>(x => x.OnItemCreated(__instance));
}
[HarmonyPatch(typeof(Item), nameof(Item.Remove)), HarmonyPostfix]
public static void Item_Remove_Post(Item __instance)
{
_eventService.PublishEvent<IEventItemRemoved>(x => x.OnItemRemoved(__instance));
}
[HarmonyPatch(typeof(Item), nameof(Item.Remove)), HarmonyPostfix]
public static void Item_ShallowRemove_Post(Item __instance)
{
_eventService.PublishEvent<IEventItemRemoved>(x => x.OnItemRemoved(__instance));
}
[HarmonyPatch(typeof(Item), nameof(Item.Use)), HarmonyPrefix]
public static bool Item_Use_Pre(Item __instance, Character user, Limb targetLimb, Entity useTarget)
{
if (__instance.RequireAimToUse && (user == null || !user.IsKeyDown(InputType.Aim)))
{
return true;
}
if (__instance.Condition <= 0.0f) { return true; }
bool? result = null;
_eventService.PublishEvent<IEventItemUse>(x => result = x.OnItemUsed(__instance, user, targetLimb, useTarget));
if (result == true)
{
return false; // skip
}
return true;
}
[HarmonyPatch(typeof(Item), nameof(Item.SecondaryUse)), HarmonyPrefix]
public static bool Item_SecondaryUse_Pre(Item __instance, Character character)
{
if (__instance.Condition <= 0.0f) { return true; }
bool? result = null;
_eventService.PublishEvent<IEventItemSecondaryUse>(x => result = x.OnItemSecondaryUsed(__instance, character));
if (result == true)
{
return false; // skip
}
return true;
}
[HarmonyPatch(typeof(Inventory), "PutItem"), HarmonyPrefix]
public static bool Inventory_PutItem_Prefix(Inventory __instance, Item item, int i, Character user, bool removeItem)
{
bool? result = null;
_eventService.PublishEvent<IEventInventoryPutItem>(x => result = x.OnInventoryPutItem(__instance, item, user, i, removeItem));
if (result == true)
{
return false; // skip
}
return true;
}
[HarmonyPatch(typeof(Inventory), "TrySwapping"), HarmonyPrefix]
public static bool Inventory_TrySwapping_Prefix(Inventory __instance, Item item, int index, Character user, bool swapWholeStack, ref bool __result)
{
// uncomment when we are plugin
// if (item?.ParentInventory == null || !__instance.slots[index].Any()) { return false; }
// if (__instance.slots[index].Items.Any(it => !it.IsInteractable(user))) { return false; }
if (!__instance.AllowSwappingContainedItems) { return false; }
bool? result = null;
_eventService.PublishEvent<IEventInventoryItemSwap>(x => result = x.OnInventoryItemSwap(__instance, item, user, index, swapWholeStack));
if (result != null)
{
__result = (bool)result;
return false; // skip
}
return true;
}
public void Dispose()
{
IsDisposed = true;

View File

@@ -177,6 +177,7 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
_eventService.RegisterLuaEventAlias<IEventCharacterCreated>("character.created", nameof(IEventCharacterCreated.OnCharacterCreated));
_eventService.RegisterLuaEventAlias<IEventCharacterDeath>("character.death", nameof(IEventCharacterDeath.OnCharacterDeath));
_eventService.RegisterLuaEventAlias<IEventCharacterDamageLimb>("character.damageLimb", nameof(IEventCharacterDamageLimb.OnCharacterDamageLimb));
_eventService.RegisterLuaEventAlias<IEventGiveCharacterJobItems>("character.giveJobItems", nameof(IEventGiveCharacterJobItems.OnGiveCharacterJobItems));
_eventService.RegisterLuaEventAlias<IEventRoundStarted>("roundStart", nameof(IEventRoundStarted.OnRoundStart));
@@ -185,6 +186,14 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
_eventService.RegisterLuaEventAlias<IEventSignalReceived>("signalReceived", nameof(IEventSignalReceived.OnSignalReceived));
_eventService.RegisterLuaEventAlias<IEventItemCreated>("item.created", nameof(IEventItemCreated.OnItemCreated));
_eventService.RegisterLuaEventAlias<IEventItemRemoved>("item.removed", nameof(IEventItemRemoved.OnItemRemoved));
_eventService.RegisterLuaEventAlias<IEventItemUse>("item.use", nameof(IEventItemUse.OnItemUsed));
_eventService.RegisterLuaEventAlias<IEventItemSecondaryUse>("item.secondaryUse", nameof(IEventItemSecondaryUse.OnItemSecondaryUsed));
_eventService.RegisterLuaEventAlias<IEventInventoryPutItem>("inventoryPutItem", nameof(IEventInventoryPutItem.OnInventoryPutItem));
_eventService.RegisterLuaEventAlias<IEventInventoryItemSwap>("inventoryItemSwap", nameof(IEventInventoryItemSwap.OnInventoryItemSwap));
#if SERVER
_eventService.RegisterLuaEventAlias<IEventClientConnected>("client.connected", nameof(IEventClientConnected.OnClientConnected));
_eventService.RegisterLuaEventAlias<IEventClientDisconnected>("client.disconnected", nameof(IEventClientDisconnected.OnClientDisconnected));