Client LuaCsForBarotrauma
LuaConverters.cs
1 using System;
2 using MoonSharp.Interpreter;
3 using Microsoft.Xna.Framework;
4 using FarseerPhysics.Dynamics;
5 using LuaCsCompatPatchFunc = Barotrauma.LuaCsPatch;
7 using System.Collections.Immutable;
8 
9 namespace Barotrauma
10 {
11  partial class LuaCsSetup
12  {
13  private void RegisterLuaConverters()
14  {
15  RegisterAction<Item>();
16  RegisterAction<Character>();
17  RegisterAction<Entity>();
18  RegisterAction<float>();
19  RegisterAction();
20 
21  RegisterFunc<Fixture, Vector2, Vector2, float, float>();
22  RegisterFunc<AIObjective, bool>();
23 
24  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsAction), v => (LuaCsAction)(args =>
25  {
26  if (v.Function.OwnerScript == Lua)
27  {
28  CallLuaFunction(v.Function, args);
29  }
30  }));
31 
32  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsFunc), v => (LuaCsFunc)(args =>
33  {
34  if (v.Function.OwnerScript == Lua)
35  {
36  return CallLuaFunction(v.Function, args);
37  }
38  return default;
39  }));
40 
41  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsCompatPatchFunc), v => (LuaCsCompatPatchFunc)((self, args) =>
42  {
43  if (v.Function.OwnerScript == Lua)
44  {
45  return CallLuaFunction(v.Function, self, args);
46  }
47  return default;
48  }));
49 
50  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsPatchFunc), v => (LuaCsPatchFunc)((self, args) =>
51  {
52  if (v.Function.OwnerScript == Lua)
53  {
54  return CallLuaFunction(v.Function, self, args);
55  }
56  return default;
57  }));
58 
59 
60  DynValue Call(object function, params object[] arguments) => CallLuaFunction(function, arguments);
61  void RegisterHandler<T>(Func<Closure, T> converter) => Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(T), v => converter(v.Function));
62 
63  RegisterHandler(f => (Character.OnDeathHandler)((a1, a2) => Call(f, a1, a2)));
64  RegisterHandler(f => (Character.OnAttackedHandler)((a1, a2) => Call(f, a1, a2)));
65 
66 #if CLIENT
67  RegisterAction<Microsoft.Xna.Framework.Graphics.SpriteBatch, GUICustomComponent>();
68  RegisterAction<float, Microsoft.Xna.Framework.Graphics.SpriteBatch>();
69  RegisterAction<Microsoft.Xna.Framework.Graphics.SpriteBatch, float>();
70 
71  {
72  RegisterHandler(f => (GUIComponent.SecondaryButtonDownHandler)(
73  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
74 
75  RegisterHandler(f => (GUIButton.OnClickedHandler)(
76  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
77  RegisterHandler(f => (GUIButton.OnButtonDownHandler)(
78  () => Call(f)?.CastToBool() ?? default));
79  RegisterHandler(f => (GUIButton.OnPressedHandler)(
80  () => Call(f)?.CastToBool() ?? default));
81 
82  RegisterHandler(f => (GUIColorPicker.OnColorSelectedHandler)(
83  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
84 
85  RegisterHandler(f => (GUIDropDown.OnSelectedHandler)(
86  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
87 
88  RegisterHandler(f => (GUIListBox.OnSelectedHandler)(
89  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
90  RegisterHandler(f => (GUIListBox.OnRearrangedHandler)(
91  (a1, a2) => Call(f, a1, a2)));
92  RegisterHandler(f => (GUIListBox.CheckSelectedHandler)(
93  () => Call(f)?.ToObject() ?? default));
94 
95  RegisterHandler(f => (GUINumberInput.OnValueEnteredHandler)(
96  (a1) => Call(f, a1)));
97  RegisterHandler(f => (GUINumberInput.OnValueChangedHandler)(
98  (a1) => Call(f, a1)));
99 
100  RegisterHandler(f => (GUIProgressBar.ProgressGetterHandler)(
101  () => (float)(Call(f)?.CastToNumber() ?? default)));
102 
103  RegisterHandler(f => (GUIRadioButtonGroup.RadioButtonGroupDelegate)(
104  (a1, a2) => Call(f, a1, a2)));
105 
106  RegisterHandler(f => (GUIScrollBar.OnMovedHandler)(
107  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
108  RegisterHandler(f => (GUIScrollBar.ScrollConversion)(
109  (a1, a2) => (float)(Call(f, a1, a2)?.CastToNumber() ?? default)));
110 
111  RegisterHandler(f => (GUITextBlock.TextGetterHandler)(
112  () => Call(f, new object[0])?.CastToString() ?? default));
113 
114  RegisterHandler(f => (GUITextBox.OnEnterHandler)(
115  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
116  RegisterHandler(f => (GUITextBox.OnTextChangedHandler)(
117  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
118  RegisterHandler(f => (TextBoxEvent)(
119  (a1, a2) => Call(f, a1, a2)));
120 
121  RegisterHandler(f => (GUITickBox.OnSelectedHandler)(
122  (a1) => Call(f, a1)?.CastToBool() ?? default));
123 
124  }
125 #endif
126 
127  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Table, typeof(Pair<JobPrefab, int>), v =>
128  {
129  return new Pair<JobPrefab, int>((JobPrefab)v.Table.Get(1).ToObject(), (int)v.Table.Get(2).CastToNumber());
130  });
131 
132  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion<ulong>((Script script, ulong v) =>
133  {
134  return DynValue.NewString(v.ToString());
135  });
136 
137  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.String, typeof(ulong), v =>
138  {
139  return ulong.Parse(v.String);
140  });
141 
142  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
143  scriptDataType: DataType.UserData,
144  clrDataType: typeof(sbyte),
145  canConvert: luaValue => luaValue.UserData?.Object is LuaSByte,
146  converter: luaValue => luaValue.UserData.Object is LuaSByte v
147  ? (sbyte)v
148  : throw new ScriptRuntimeException("use SByte(value) to pass primitive type 'sbyte' to C#"));
149  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
150  scriptDataType: DataType.UserData,
151  clrDataType: typeof(byte),
152  canConvert: luaValue => luaValue.UserData?.Object is LuaByte,
153  converter: luaValue => luaValue.UserData.Object is LuaByte v
154  ? (byte)v
155  : throw new ScriptRuntimeException("use Byte(value) to pass primitive type 'byte' to C#"));
156  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
157  scriptDataType: DataType.UserData,
158  clrDataType: typeof(short),
159  canConvert: luaValue => luaValue.UserData?.Object is LuaInt16,
160  converter: luaValue => luaValue.UserData.Object is LuaInt16 v
161  ? (short)v
162  : throw new ScriptRuntimeException("use Int16(value) to pass primitive type 'short' to C#"));
163  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
164  scriptDataType: DataType.UserData,
165  clrDataType: typeof(ushort),
166  canConvert: luaValue => luaValue.UserData?.Object is LuaUInt16,
167  converter: luaValue => luaValue.UserData.Object is LuaUInt16 v
168  ? (ushort)v
169  : throw new ScriptRuntimeException("use UInt16(value) to pass primitive type 'ushort' to C#"));
170  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
171  scriptDataType: DataType.UserData,
172  clrDataType: typeof(int),
173  canConvert: luaValue => luaValue.UserData?.Object is LuaInt32,
174  converter: luaValue => luaValue.UserData.Object is LuaInt32 v
175  ? (int)v
176  : throw new ScriptRuntimeException("use Int32(value) to pass primitive type 'int' to C#"));
177  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
178  scriptDataType: DataType.UserData,
179  clrDataType: typeof(uint),
180  canConvert: luaValue => luaValue.UserData?.Object is LuaUInt32,
181  converter: luaValue => luaValue.UserData.Object is LuaUInt32 v
182  ? (uint)v
183  : throw new ScriptRuntimeException("use UInt32(value) to pass primitive type 'uint' to C#"));
184  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
185  scriptDataType: DataType.UserData,
186  clrDataType: typeof(long),
187  canConvert: luaValue => luaValue.UserData?.Object is LuaInt64,
188  converter: luaValue => luaValue.UserData.Object is LuaInt64 v
189  ? (long)v
190  : throw new ScriptRuntimeException("use Int64(value) to pass primitive type 'long' to C#"));
191  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
192  scriptDataType: DataType.UserData,
193  clrDataType: typeof(ulong),
194  canConvert: luaValue => luaValue.UserData?.Object is LuaUInt64,
195  converter: luaValue => luaValue.UserData.Object is LuaUInt64 v
196  ? (ulong)v
197  : throw new ScriptRuntimeException("use UInt64(value) to pass primitive type 'ulong' to C#"));
198  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
199  scriptDataType: DataType.UserData,
200  clrDataType: typeof(float),
201  canConvert: luaValue => luaValue.UserData?.Object is LuaSingle,
202  converter: luaValue => luaValue.UserData.Object is LuaSingle v
203  ? (float)v
204  : throw new ScriptRuntimeException("use Single(value) to pass primitive type 'float' to C#"));
205  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
206  scriptDataType: DataType.UserData,
207  clrDataType: typeof(double),
208  canConvert: luaValue => luaValue.UserData?.Object is LuaDouble,
209  converter: luaValue => luaValue.UserData.Object is LuaDouble v
210  ? (double)v
211  : throw new ScriptRuntimeException("use Double(value) to pass primitive type 'double' to C#"));
212 
213  RegisterOption<Character>(DataType.UserData);
214  RegisterOption<AccountId>(DataType.UserData);
215  RegisterOption<ContentPackageId>(DataType.UserData);
216  RegisterOption<SteamId>(DataType.UserData);
217  RegisterOption<DateTime>(DataType.UserData);
218  RegisterOption<BannedPlayer>(DataType.UserData);
219  RegisterOption<Address>(DataType.UserData);
220 
221  RegisterOption<int>(DataType.Number);
222 
223  RegisterEither<Address, AccountId>();
224 
225  RegisterImmutableArray<FactionPrefab.HireableCharacter>();
226  }
227 
228  private void RegisterImmutableArray<T>()
229  {
230  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Table, typeof(ImmutableArray<T>), v =>
231  {
232  return v.ToObject<T[]>().ToImmutableArray();
233  });
234  }
235 
236  private void RegisterEither<T1, T2>()
237  {
238  DynValue convertEitherIntoDynValue(Either<T1, T2> either)
239  {
240  if (either.TryGet(out T1 value1))
241  {
242  return UserData.Create(value1);
243  }
244 
245  if (either.TryGet(out T2 value2))
246  {
247  return UserData.Create(value2);
248  }
249 
250  return null;
251  }
252 
253  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion(typeof(EitherT<T1, T2>), (Script v, object obj) =>
254  {
255  if (obj is EitherT<T1, T2> either)
256  {
257  return convertEitherIntoDynValue(either);
258  }
259 
260  return null;
261  });
262 
263  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion(typeof(EitherU<T1, T2>), (Script v, object obj) =>
264  {
265  if (obj is EitherU<T1, T2> either)
266  {
267  return convertEitherIntoDynValue(either);
268  }
269 
270  return null;
271  });
272  }
273 
274  private void RegisterOption<T>(DataType dataType)
275  {
276  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion(typeof(Option<T>), (Script v, object obj) =>
277  {
278  if (obj is Option<T> option)
279  {
280  if (option.TryUnwrap(out T outValue))
281  {
282  return UserData.Create(outValue);
283  }
284  }
285 
286  return DynValue.Nil;
287  });
288 
289  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(dataType, typeof(Option<T>), v =>
290  {
291  return Option<T>.Some(v.ToObject<T>());
292  });
293 
294  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Nil, typeof(Option<T>), v =>
295  {
296  return Option<T>.None();
297  });
298  }
299 
300  private void RegisterAction<T>()
301  {
302  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action<T>), v =>
303  {
304  var function = v.Function;
305  return (Action<T>)(p => CallLuaFunction(function, p));
306  });
307 
308  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Action<T>), v =>
309  {
310  var function = v.Function;
311  return (Action<T>)(p => CallLuaFunction(function, p));
312  });
313  }
314 
315  private void RegisterAction<T1, T2>()
316  {
317  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action<T1, T2>), v =>
318  {
319  var function = v.Function;
320  return (Action<T1, T2>)((a1, a2) => CallLuaFunction(function, a1, a2));
321  });
322 
323  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Action<T1, T2>), v =>
324  {
325  var function = v.Function;
326  return (Action<T1, T2>)((a1, a2) => CallLuaFunction(function, a1, a2));
327  });
328  }
329 
330  private void RegisterAction()
331  {
332  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action), v =>
333  {
334  var function = v.Function;
335  return (Action)(() => CallLuaFunction(function));
336  });
337 
338  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Action), v =>
339  {
340  var function = v.Function;
341  return (Action)(() => CallLuaFunction(function));
342  });
343  }
344 
345  private void RegisterFunc<T1>()
346  {
347  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1>), v =>
348  {
349  var function = v.Function;
350  return () => function.Call().ToObject<T1>();
351  });
352 
353  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Func<T1>), v =>
354  {
355  var function = v.Function;
356  return () => function.Call().ToObject<T1>();
357  });
358  }
359 
360  private void RegisterFunc<T1, T2>()
361  {
362  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1, T2>), v =>
363  {
364  var function = v.Function;
365  return (T1 a) => function.Call(a).ToObject<T2>();
366  });
367 
368  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Func<T1, T2>), v =>
369  {
370  var function = v.Function;
371  return (T1 a) => function.Call(a).ToObject<T2>();
372  });
373  }
374 
375  private void RegisterFunc<T1, T2, T3, T4, T5>()
376  {
377  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1, T2, T3, T4, T5>), v =>
378  {
379  var function = v.Function;
380  return (T1 a, T2 b, T3 c, T4 d) => function.Call(a, b, c, d).ToObject<T5>();
381  });
382 
383  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1, T2, T3, T4, T5>), v =>
384  {
385  var function = v.Function;
386  return (T1 a, T2 b, T3 c, T4 d) => function.Call(a, b, c, d).ToObject<T5>();
387  });
388  }
389  }
390 }
delegate void OnDeathHandler(Character character, CauseOfDeath causeOfDeath)
delegate void OnAttackedHandler(Character attacker, AttackResult attackResult)
delegate bool OnPressedHandler()
delegate bool OnButtonDownHandler()
delegate bool OnClickedHandler(GUIButton button, object obj)
delegate bool OnColorSelectedHandler(GUIColorPicker component, Color color)
delegate bool SecondaryButtonDownHandler(GUIComponent component, object userData)
GUIComponent that can be used to render custom content on the UI
delegate bool OnSelectedHandler(GUIComponent selected, object obj=null)
delegate bool OnSelectedHandler(GUIComponent component, object obj)
delegate object CheckSelectedHandler()
delegate void OnRearrangedHandler(GUIListBox listBox, object obj)
delegate void OnValueChangedHandler(GUINumberInput numberInput)
delegate void OnValueEnteredHandler(GUINumberInput numberInput)
delegate float ProgressGetterHandler()
delegate void RadioButtonGroupDelegate(GUIRadioButtonGroup rbg, int? val)
delegate float ScrollConversion(GUIScrollBar scrollBar, float f)
delegate bool OnMovedHandler(GUIScrollBar scrollBar, float barScroll)
delegate LocalizedString TextGetterHandler()
delegate bool OnEnterHandler(GUITextBox textBox, string text)
delegate bool OnTextChangedHandler(GUITextBox textBox, string text)
delegate bool OnSelectedHandler(GUITickBox obj)
DynValue CallLuaFunction(object function, params object[] args)
delegate void LuaCsAction(params object[] args)
delegate void TextBoxEvent(GUITextBox sender, Keys key)
delegate DynValue LuaCsPatchFunc(object instance, LuaCsHook.ParameterTable ptable)
delegate object LuaCsFunc(params object[] args)