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