public static void StepsHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length < 2) { throw new HandlebarsException("{{steps start end [step] [delay]}} helper must have at least two argument: (start) (end)"); } var root = rootObject as IScriptRootData; int.TryParse(arguments[0]?.ToString(), out int start); int.TryParse(arguments[1]?.ToString(), out int end); int step = arguments.Length > 2 && int.TryParse(arguments[2]?.ToString(), out int s) ? s : 1; int delay = arguments.Length > 3 && int.TryParse(arguments[3]?.ToString(), out int d) ? d : 1; try { var i = root.CycleCounter % (Math.Abs(delay) * ((Math.Abs(end - start) / Math.Abs(step)) + 1)); var stepI = (int)(start < end ? i * Math.Abs(step) : start - (i * Math.Abs(step))); options.Template(output, (1 + stepI) / Math.Abs(delay)); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{steps}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void DateTimeHelper(TextWriter output, object rootObject, dynamic context, object[] arguments) { var format = arguments.Length > 0 ? arguments[0]?.ToString() : null; var add = arguments.Length > 1 ? arguments[1]?.ToString() : null; var root = rootObject as IScriptRootData; try { var current = string.IsNullOrEmpty(add) ? DateTime.UtcNow.AddHours(root.CultureInfo.UTCplusTimezone) : DateTime.UtcNow.AddHours(int.Parse(add)); if (string.IsNullOrEmpty(format)) { output.Write(current.ToString(root.CultureInfo.CultureInfo)); } else { output.Write(current.ToString(format, root.CultureInfo.CultureInfo)); } } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{datetime}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void RandomHelper(TextWriter output, object root, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2) { throw new HandlebarsException("{{random start end}} helper must have two argument: (start) (end)"); } var format = arguments.Length > 0 ? arguments[0]?.ToString() : null; var add = arguments.Length > 1 ? arguments[1]?.ToString() : null; try { int.TryParse(arguments[0]?.ToString(), out var start); int.TryParse(arguments[1]?.ToString(), out var end); options.Template(output, new Random().Next(start, end)); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{random}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void LightsBlockHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2) { throw new HandlebarsException("{{lights structure names}} helper must have exactly two argument: (structure) (name;name*;*;name)"); } var structure = arguments[0] as IStructureData; var namesSearch = arguments[1]?.ToString(); try { var uniqueNames = structure.AllCustomDeviceNames.GetUniqueNames(namesSearch); var devices = uniqueNames.Select(N => structure.GetCurrent().GetDevice <ILight>(N)).ToArray(); if (devices.Length > 0) { devices.ForEach(L => options.Template(output, L)); } else { options.Inverse(output, context as object); } } catch (Exception error) { output.Write("{{lights}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static FileContent GetFileContent(string filename) { try { if (FileContentCache.TryGetValue(filename, out var filecontent)) { return(filecontent); } if (!File.Exists(filename)) { return(null); } filecontent = new FileContent() { Lines = File.ReadAllLines(filename), Text = File.ReadAllText(filename), Watcher = new FileSystemWatcher(Path.GetDirectoryName(filename), Path.GetFileName(filename)) }; filecontent.Watcher.Renamed += (S, A) => { filecontent.Watcher.EnableRaisingEvents = false; FileContentCache.TryRemove(filename, out var _); }; filecontent.Watcher.Changed += (S, A) => { filecontent.Watcher.EnableRaisingEvents = false; FileContentCache.TryRemove(filename, out var _); }; filecontent.Watcher.Deleted += (S, A) => { filecontent.Watcher.EnableRaisingEvents = false; FileContentCache.TryRemove(filename, out var _); }; filecontent.Watcher.Created += (S, A) => { filecontent.Watcher.EnableRaisingEvents = false; FileContentCache.TryRemove(filename, out var _); }; filecontent.Watcher.EnableRaisingEvents = true; FileContentCache.AddOrUpdate(filename, filecontent, (S, O) => filecontent); return(filecontent); } catch (Exception error) { EmpyrionScripting.Log($"Filename: {filename} => {error}", EmpyrionNetAPIDefinitions.LogLevel.Message); return(null); } }
public static void I18NHelper(TextWriter output, dynamic context, object[] arguments) { if (arguments.Length != 2) { throw new HandlebarsException("{{i18n}} helper must have exactly two argument: (key|id) (language)"); } var data = arguments[0]?.ToString(); var language = arguments[1] as string; try { if (arguments[0] is int && EmpyrionScripting.ItemInfos.ItemInfo.TryGetValue((int)arguments[0], out ItemInfo details1)) { data = details1.Key; } else if (int.TryParse(data, out int itemId) && EmpyrionScripting.ItemInfos.ItemInfo.TryGetValue(itemId, out ItemInfo details2)) { data = details2.Key; } output.Write(EmpyrionScripting.Localization.GetName(data, language)); } catch (Exception error) { output.Write("{{i18n}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void SendMessageToPlayerHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length < 2) { throw new HandlebarsException("{{sendmessagetoplayer @root playerid}} helper must have at least two argument: @root (playerid)"); } if (!(arguments[0] is ScriptSaveGameRootData root)) { throw new HandlebarsException("{{sendmessagetoplayer @root playerid}} only allowed in SaveGame scripts"); } try { int.TryParse(arguments[1].ToString(), out var playerId); using (var text = new StringWriter()) { options.Template(text, context as object); root.ModApi.Application.SendChatMessage(new Eleon.MessageData() { SenderType = Eleon.SenderType.ServerInfo, Channel = Eleon.MsgChannel.Server, RecipientEntityId = playerId, Text = text.ToString() }); } } catch (Exception error) { output.Write("{{sendmessagetoplayer}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void DevicesBlockHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2) { throw new HandlebarsException("{{devices structure names}} helper must have exactly two argument: (structure) (name;name*;*;name)"); } var structure = arguments[0] as IStructureData; var namesSearch = arguments[1].ToString(); try { var uniqueNames = structure.AllCustomDeviceNames.GetUniqueNames(namesSearch); var blocks = uniqueNames .SelectMany(N => structure.GetCurrent().GetDevicePositions(N) .Select(V => new BlockData(structure.GetCurrent(), V))).ToArray(); if (blocks != null && blocks.Length > 0) { options.Template(output, blocks); } else { options.Inverse(output, context as object); } } catch (Exception error) { output.Write("{{devices}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void DevicesOfTypeBlockHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2) { throw new HandlebarsException("{{devicesoftype structure type}} helper must have exactly two argument: (structure) (type)"); } var structure = arguments[0] as IStructureData; var typeSearch = arguments[1].ToString(); try { var blocks = structure?.GetCurrent() .GetDevices(typeSearch)? .Values() .Select(V => new BlockData(structure.GetCurrent(), V)) .ToArray(); if (blocks != null && blocks.Length > 0) { options.Template(output, blocks); } else { options.Inverse(output, context as object); } } catch (Exception error) { output.Write("{{devicesoftype}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void IntervallBlockHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 1) { throw new HandlebarsException("{{intervall seconds}} helper must have exactly one argument: (value)"); } var root = rootObject as IScriptRootData; double.TryParse(arguments[0]?.ToString(), out double intervall); try { if (root.CycleCounter % (2 * intervall) < intervall) { options.Template(output, context as object); } else { options.Inverse(output, context as object); } } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{intervall}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void ScrollBlockHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2 && arguments.Length != 3) { throw new HandlebarsException("{{scroll lines delay [step]}} helper must have at least two argument: (lines) (delay) [step]"); } var root = rootObject as IScriptRootData; int.TryParse(arguments[0]?.ToString(), out int lines); int.TryParse(arguments[1]?.ToString(), out int delay); if (!int.TryParse(arguments.Get(2)?.ToString(), out var step)) { step = 1; } try { var content = new StringWriter(); options.Template(content, context as object); Scroll(root, content.ToString(), lines, delay, step).ForEach(L => output.Write($"{L}\n")); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{scroll}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public void TestMethodTestLEQReal() { var S = Substitute.For <IStructureData>(); S.Items.Returns(new[] { new ItemsData() { Id = 1, Count = 10, Name = "a" }, new ItemsData() { Id = 2, Count = 20, Name = "b" }, new ItemsData() { Id = 3, Count = 30, Name = "c" }, }); var E = Substitute.For <IEntityData>(); E.S.Returns(S); var lcdData = Substitute.For <IScriptRootData>(); lcdData.E.Returns(E); var lcdMod = new EmpyrionScripting(); Assert.AreEqual( "Yes:aYes:bNo:c", lcdMod.ExecuteHandlebarScript(lcdData, "{{#each E.S.Items}}{{test Id leq 2}}Yes:{{Name}}{{else}}No:{{Name}}{{/test}}{{/each}}") ); }
public void TestMethodTestLEQ() { var lcdMod = new EmpyrionScripting(); Assert.AreEqual( "Yes:aYes:bNo:c", lcdMod.ExecuteHandlebarScript(new { S = new { I = new[] { new ItemsData() { Id = 1, Name = "a" }, new ItemsData() { Id = 2, Name = "b" }, new ItemsData() { Id = 3, Name = "c" }, } } }, "{{#each S.I}}{{test Id leq 2}}Yes:{{Name}}{{else}}No:{{Name}}{{/test}}{{/each}}") ); }
public void TestMethodTestINRangeNeg2() { var lcdMod = new EmpyrionScripting(); Assert.AreEqual( "No:aNo:bNo:c", lcdMod.ExecuteHandlebarScript(new { I = new[] { new Item() { Id = 1, Name = "a" }, new Item() { Id = 2, Name = "b" }, new Item() { Id = 3, Name = "c" }, } }, "{{#each I}}{{test Id in '-1--2'}}Yes:{{Name}}{{else}}No:{{Name}}{{/test}}{{/each}}") ); }
public static void I18NHelper(TextWriter output, object rootObject, dynamic context, object[] arguments) { if (arguments.Length != 1 && arguments.Length != 2) { throw new HandlebarsException("{{i18n}} helper must have at least one argument: (key|id) [language]"); } var root = rootObject as IScriptRootData; var data = arguments[0]?.ToString(); var language = arguments.Get(1) as string ?? root.CultureInfo.i18nDefault; try { if (int.TryParse(data, out int itemId)) { if (EmpyrionScripting.ConfigEcfAccess.IdBlockMapping.TryGetValue(itemId, out var name)) { data = name; } else if (EmpyrionScripting.ItemInfos.ItemInfo.TryGetValue(itemId, out ItemInfo details2)) { data = details2.Key; } } output.Write(EmpyrionScripting.Localization.GetName(data, language)); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{i18n}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void ObjectBlockHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 4) { throw new HandlebarsException("{{block structure x y z}} helper must have exactly four argument: (structure) (x) (y) (z)"); } var structure = arguments[0] as IStructureData; int.TryParse(arguments[1].ToString(), out var x); int.TryParse(arguments[2].ToString(), out var y); int.TryParse(arguments[3].ToString(), out var z); try { var block = new BlockData(structure.GetCurrent(), new Eleon.Modding.VectorInt3(x, y, z)); if (block != null) { options.Template(output, block); } else { options.Inverse(output, context as object); } } catch (Exception error) { output.Write("{{block}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void ProcessBarHelper(TextWriter output, object root, dynamic context, object[] arguments) { if (arguments.Length < 4) { throw new HandlebarsException("{{bar data min max length [char] [bgchar] [l|r]}} helper must have at least four argument: (data) (min) (max) (length)"); } try { double.TryParse(arguments[0]?.ToString(), out var value); double.TryParse(arguments[1]?.ToString(), out var min); double.TryParse(arguments[2]?.ToString(), out var max); int.TryParse(arguments[3]?.ToString(), out var barLength); var len = (int)(barLength / Math.Abs(max - min) * value); if (arguments.Get(6)?.ToString() == "r") { output.Write(string.Concat(Enumerable.Repeat(arguments.Length > 5 ? arguments[5].ToString() : EmpyrionScripting.Configuration.Current.BarStandardSpaceSign, Math.Max(0, Math.Min(barLength, barLength + len))))); output.Write(string.Concat(Enumerable.Repeat(arguments.Length > 4 ? arguments[4].ToString() : EmpyrionScripting.Configuration.Current.BarStandardValueSign, Math.Max(0, Math.Min(barLength, -len))))); } else { output.Write(string.Concat(Enumerable.Repeat(arguments.Length > 4 ? arguments[4].ToString() : EmpyrionScripting.Configuration.Current.BarStandardValueSign, Math.Max(0, Math.Min(barLength, len))))); output.Write(string.Concat(Enumerable.Repeat(arguments.Length > 5 ? arguments[5].ToString() : EmpyrionScripting.Configuration.Current.BarStandardSpaceSign, Math.Max(0, Math.Min(barLength, barLength - len))))); } } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{bar}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void FileExistsHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2) { throw new HandlebarsException("{{fileexists dir filename}} helper must have two argument: (dir) (filename)"); } if (!(rootObject is ScriptSaveGameRootData root)) { throw new HandlebarsException("{{readfile dir filename}} only allowed in SaveGame scripts"); } try { if (File.Exists(Path.Combine(root.MainScriptPath, arguments[0].ToString(), arguments[1].ToString()))) { options.Template(output, context as object); } else { options.Inverse(output, context as object); } } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{fileexists}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void ConfigByIdHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 1) { throw new HandlebarsException("{{configbyid id}} helper must have exactly one argument: (id)"); } var root = rootObject as IScriptModData; int.TryParse(arguments[0]?.ToString(), out var id); try { if (root.ConfigEcfAccess.FlatConfigBlockById.TryGetValue(id, out var config)) { options.Template(output, config); } else { options.Inverse(output, (object)context); } } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{configattr}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void BlockSetHelper(TextWriter output, object root, dynamic context, object[] arguments) { if (arguments.Length < 2) { throw new HandlebarsException("{{settype block typeid}} helper must have two argument: block typeid"); } if (!(root is ScriptSaveGameRootData)) { throw new HandlebarsException("{{settype block typeid}} only allowed in SaveGame scripts"); } var block = arguments[0] as BlockData; int.TryParse(arguments[1].ToString(), out var type); try { block.GetBlock().Set(type); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{settype}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void ReadFileHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 3) { throw new HandlebarsException("{{readfile @root dir filename}} helper must have two argument: @root (dir) (filename)"); } if (!(arguments[0] is ScriptSaveGameRootData root)) { throw new HandlebarsException("{{readfile @root dir filename}} only allowed in SaveGame scripts"); } try { var filename = Path.Combine(arguments[1].ToString(), arguments[2].ToString()); var fileContent = HelpersTools.GetFileContent(filename)?.Lines; if (fileContent == null) { options.Inverse(output, context as object); } else { options.Template(output, fileContent); } } catch (Exception error) { output.Write("{{readfile}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void FileListHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2 && arguments.Length != 3) { throw new HandlebarsException("{{filelist dir filename [recursive]}} helper must have at least three arguments: @root (dir) (filename) [recursive]"); } if (!(rootObject is ScriptSaveGameRootData root)) { throw new HandlebarsException("{{filelist}} only allowed in SaveGame scripts"); } try { bool.TryParse(arguments.Length == 3 ? arguments[2].ToString() : "false", out var recursive); options.Template(output, Directory.EnumerateFiles( Path.Combine(root.MainScriptPath, arguments[0].ToString()), arguments[1].ToString(), recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{filelist}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void SetTextBlockHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 1) { throw new HandlebarsException("{{settextblock lcddevice}} helper must have exactly one argument: (structure)"); } var root = rootObject as IScriptRootData; if (!root.Running) { return; // avoid flicker displays with part of informations } try { var block = arguments[0] as BlockData; var lcd = block?.GetStructure()?.GetDevice <ILcd>(block.Position); using var text = new StringWriter(); options.Template(text, context as object); if (!root.Running) { return; // avoid flicker displays with part of informations } lcd?.SetText(text.ToString()); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{settextblock}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void IntervallBlockHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 1) { throw new HandlebarsException("{{intervall seconds}} helper must have exactly one argument: (value)"); } double.TryParse(arguments[0]?.ToString(), out double intervall); try { if (ScriptExecQueue.Iteration % (2 * intervall) < intervall) { options.Template(output, context as object); } else { options.Inverse(output, context as object); } } catch (Exception error) { output.Write("{{intervall}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void GetTextHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 1) { throw new HandlebarsException("{{gettext lcddevice}} helper must have exactly one argument: (structure)"); } var block = arguments[0] as BlockData; var lcd = block?.GetStructure()?.GetDevice <ILcd>(block.Position); try { if (lcd == null) { options.Inverse(output, context as object); } else { options.Template(output, lcd.GetText()); } } catch (Exception error) { output.Write("{{settext}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void ScrollBlockHelper(TextWriter output, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 2) { throw new HandlebarsException("{{scroll lines delay}} helper must have exactly two argument: (lines) (delay)"); } int.TryParse(arguments[0] as string, out int lines); int.TryParse(arguments[1] as string, out int delay); try { var content = new StringWriter(); options.Template(content, context as object); var textlines = content.ToString().Split('\n'); var overlapp = textlines.Length - lines; if (overlapp <= 0) { output.Write(content.ToString()); } else { var skip = (ScriptExecQueue.Iteration % (delay * overlapp)) / delay; output.Write(string.Join("\n", textlines.Skip((int)skip).Take(lines))); output.Write("\n"); } } catch (Exception error) { output.Write("{{scroll}} error " + EmpyrionScripting.ErrorFilter(error)); } }
public static void SplitHelper(TextWriter output, object root, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length < 2) { throw new HandlebarsException("{{split string separator [removeemptyentries] [trimchars]}} helper must have at least two argument: (string) (separator) [true|false] [trimchars]"); } var data = arguments[0].ToString(); var separator = Regex.Unescape(arguments[1].ToString()); var trimchars = arguments.Get(3)?.ToString().ToCharArray(); try { bool.TryParse(arguments.Length > 2 ? arguments[2]?.ToString() : null, out var removeemptyentries); options.Template(output, data.Split(new[] { separator }, removeemptyentries ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None) .Select(item => trimchars == null ? item : item.Trim(trimchars)) .ToArray()); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{split}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void SignalEventsHelper(TextWriter output, object rootObject, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 1) { throw new HandlebarsException("{{signalevents names}} helper must have exactly one argument: (name1;name2...)"); } var root = rootObject as IScriptRootData; var namesSearch = arguments[0].ToString(); try { var uniqueNames = root.SignalEventStore.GetEvents().Keys.GetUniqueNames(namesSearch).ToDictionary(N => N); var signals = root.SignalEventStore.GetEvents().Where(S => uniqueNames.ContainsKey(S.Key)).Select(S => S.Value).ToArray(); if (signals != null && signals.Length > 0) { signals.ForEach(S => options.Template(output, S.OfType <SignalEventBase>().Select(subS => root.IsElevatedScript ? new SignalEventElevated(root.GetCurrentPlayfield(), subS) : (object)new SignalEvent(root.GetCurrentPlayfield(), subS)).Reverse().ToArray())); } else { options.Inverse(output, context as object); } } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{signalevents}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void UseHelper(TextWriter output, object root, HelperOptions options, dynamic context, object[] arguments) { if (arguments.Length != 1) { throw new HandlebarsException("{{use data}} helper must have one argument: (data)"); } try { if (arguments[0] == null) { options.Inverse(output, context as object); } else { options.Template(output, arguments[0]); } } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{use}} error " + EmpyrionScripting.ErrorFilter(error)); } } }
public static void RemoveItemsHelper(TextWriter output, object rootObject, dynamic context, object[] arguments) { if (arguments.Length != 3) { throw new HandlebarsException("{{removeitems container itemid maxcount}} helper must have three arguments: (container) (item) (maxcount)"); } var root = rootObject as IScriptRootData; var block = arguments[0] as BlockData; int.TryParse(arguments[1].ToString(), out var itemid); int.TryParse(arguments[2].ToString(), out var maxcount); if (!root.IsElevatedScript) { throw new HandlebarsException("{{removeitems}} only allowed in elevated scripts"); } try { var container = block.Device as ContainerData; container.GetContainer().RemoveItems(itemid, maxcount); } catch (Exception error) { if (!CsScriptFunctions.FunctionNeedsMainThread(error, root)) { output.Write("{{removeitems}} error " + EmpyrionScripting.ErrorFilter(error)); } } }