diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs
index 184dd852b..ee8071ecb 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs
@@ -223,5 +223,37 @@ namespace Barotrauma
var descriptor = (StandardUserDataDescriptor)IUUD;
descriptor.RemoveMember(memberName);
}
+
+ ///
+ /// See .
+ ///
+ /// Lua value to convert and wrap in a userdata.
+ /// Descriptor of the type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters.
+ /// A userdata that wraps the Lua value converted to an object of the desired type as described by .
+ public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
+ {
+ return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor);
+ }
+
+ ///
+ /// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata.
+ /// If the type is not registered, then a new will be created and used.
+ /// The goal of this method is to allow Lua scripts to create userdata to wrap certain data without having to register types.
+ /// Wrapping the value in a userdata preserves the original type during script-to-CLR conversions.
+ /// A Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets
+ /// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything.
+ /// Registering the List`1 type can break other scripts relying on default converters, so instead
+ /// it is better to manually wrap the List`1 object into a userdata.
+ ///
+ ///
+ /// Lua value to convert and wrap in a userdata.
+ /// Type describing the CLR type of the object to convert the Lua value to.
+ /// A userdata that wraps the Lua value converted to an object of the desired type.
+ public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
+ {
+ IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true);
+ descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
+ return CreateUserDataFromDescriptor(scriptObject, descriptor);
+ }
}
}
\ No newline at end of file