I am working on having a single script that both refuels vessels tanks that dock to my carrier but also refills predefined reserve container on the docked vessels as well. I keep getting Reached end of template before the expression was closed. Can someone help? EDIT: I think I solved my problem, I believe it wasn't recalling the RST-FillRes amounts. I am no longer getting any kind of a error but the script only fills tanks. It wont transfer any items to the docked ships, any suggestions? Code updated. Code: <align=center><color=yellow><size=4>{{!Auto Fuel}}</size></color> <size=60%><color=#444444>{{!Docked}}</size></align> <size=30%><color=white> {{#getswitch @root.E.S 'RST-AutoFuelDocked'}} {{#if SwitchState}} {{!Tanks}} {{~set 'IDs' '4421,4342,4176,4177,4314,4335'}} {{~#each @root.E.S.DockedE}} {{#if S.IsPowerd}} {{else}} {{#items @root.E.S 'RSTCE1*'}} {{~#math (configattr Id 'StackSize') '/' 500}} {{~set 'Stacks' (int (max 100 .))}} {{~/math}} {{~#test Count ge @root.Data.Stacks}} {{~#test Id in @root.Data.IDs}} {{~#fill ../this ../../../S 'Oxygen' 100}}{{/fill}} {{~#fill ../this ../../../S 'Fuel' 100}}{{/fill}} {{~#fill ../this ../../../S 'Pentaxid' 100}}{{/fill}} {{~/test}} {{/test}} {{/items}} {{!Reserves}} {{~set 'RST-FillRes-Fuel' 25}} {{~set 'RST-FillRes-Oxygen' 25}} {{~set 'RST-FillRes-Pentaxid' 125}} {{~set 'LimitToType' 'CV'}} {{~#test EntityType in @root.Data.LimitToType}} {{~set 'RST-FillRes-Fuel' 200}} {{~set 'RST-FillRes-Oxygen' 200}} {{~set 'RST-FillRes-Pentaxid' 1000}} {{/test}} {{~#items @root.E.S 'RSTCE1*'}} {{~#test Id in '4421'}} {{~#test Count ge @root.Data.RST-FillRes-Fuel}} {{~#move ../this ../../../S '*CE11-[1AA5DD][c]Fuel' @root.Data.RST-FillRes-Fuel}} {{/move}} {{/test}} {{/test}} {{~#test Id in '4176'}} {{~#test Count ge @root.Data.RST-FillRes-Oxygen}} {{~#move ../this ../../../S '*CE12-[2EE8DE][c]Oxygen' @root.Data.RST-FillRes-Oxygen}} {{/move}} {{/test}} {{/test}} {{~#test Id in '4342'}} {{~#test Count ge @root.Data.RST-FillRes-Pentaxid}} {{~#move ../this ../../../S '*CE13-[FF33C2][c]Pentaxid' @root.Data.RST-FillRes-Pentaxid}} {{/move}} {{/test}} {{/test}} {{/items}} {{/if}} {{/each}} {{/if}} {{/getswitch}} </size>
I was able to finally figure out how to transfer items from my carrier to docked vessels. My new issue is that because my reserve containers are different sizes depending on the ship some of them will fill while others wont. I have figured out that if the container doesnt have enough room for the amount set it wont transfer any items. Is it possible to have it transfer as many items as it can fit up to a maximum amount? Code: <align=center><color=yellow><size=4>{{!Auto Fuel}}</size></color> <size=60%><color=#444444>{{!Docked}}</size></align> <size=30%><color=white> {{#getswitch @root.E.S 'RST-AutoFuelDocked'}} {{#if SwitchState}} {{!Tanks}} {{~set 'IDs' '4421,4342,4176,4177,4314,4335'}} {{~#each @root.E.S.DockedE}} {{#if S.IsPowerd}} {{else}} {{#items @root.E.S 'RSTCE1*'}} {{~#math (configattr Id 'StackSize') '/' 500}} {{~set 'Stacks' (int (max 100 .))}} {{~/math}} {{~#test Count ge @root.Data.Stacks}} {{~#test Id in @root.Data.IDs}} {{~#fill ../this ../../../S 'Oxygen' 100}}{{/fill}} {{~#fill ../this ../../../S 'Fuel' 100}}{{/fill}} {{~#fill ../this ../../../S 'Pentaxid' 100}}{{/fill}} {{~/test}} {{/test}} {{/items}} {{!Reserves}} {{~set 'RST-FillRes-Fuel' 200}} {{~set 'RST-FillRes-Oxygen' 200}} {{~set 'RST-FillRes-Pentaxid' 1000}} {{~#items @root.E.S 'RSTCE1*'}} {{~#test Id in '4421'}} {{~#test Count ge 400}} {{~#move . ../../../S '*CE11-[1AA5DD][c]Fuel' @root.Data.RST-FillRes-Fuel}} {{/move}} {{/test}} {{/test}} {{~#test Id in '4176'}} {{~#test Count ge 500}} {{~#move . ../../../S '*CE12-[2EE8DE][c]Oxygen' @root.Data.RST-FillRes-Oxygen}} {{/move}} {{/test}} {{/test}} {{~#test Id in '4342'}} {{~#test Count ge 500}} {{~#move . ../../../S '*CE13-[FF33C2][c]Pentaxid' @root.Data.RST-FillRes-Pentaxid}} {{/move}} {{/test}} {{/test}} {{/items}} {{/if}} {{/each}} {{/if}} {{/getswitch}} </size>
So we have a server using the scripts. I was wondering if there is a way to use the scripts without it requiring credits to work. Specifically the recycle script. Unless you put credits in the container it doesn't do anything.
I have a good bit of credits to give you for the scripts. I also created a Faction Bank with a few Mil in there.
If you are the admin, just edit the Mods\EmpyrionScripting\Configuration.json within the save folder. Change DeconstructSalary and RecycleSalary Amounts to 0, and it's back to the way it was.
Release added ToId & ToName · GitHub-TC/EmpyrionScripting 13.3.1 https://github.com/GitHub-TC/EmpyrionScripting/releases/download/13.3.1/EmpyrionScripting.zip Added "toid" and "toname" functions. (C# CsRoot.ToId(string) & CsRoot.ToName(string))
@ASTIC I am using a modified version of the ore/ingot/components display. Is there a way to get the script to sort the items in the order they are given instead of always changing to ascending? For example in this code I have Graphite (4292) at the end of the IDs but it always shows it first. Note: I do realize the section sortedeach is set to ids, but even when I take that section of the code out I noticed that the script always seems to sort by id number ascending by default. Left it in because if there is a chance of sorting the way I am asking I figured I would need it left in. Code: {{~set 'H' 'Ores'}} {{~set 'T' '4000'}} {{~#split '#15FC05,#8FF904,#F4DC04,#F99C04,#FC6305,#CE1818' ','}}{{set 'C' .}}{{/split}} {{~set 'IDs' '4296-4302,4317-4318,4328,4332,4338,4345,4359,4362,4365,7300,7342,7344,4358,4292,'}} {{~#split @root.ScriptId ':'}} {{~#devices @root.E.S .1}} {{~#split (substring (i18n .0/Id 'English') 4) ' '}}{{set 'SS' .0}}{{/split}} {{~/devices}} {{~/split}} {{~concat '<color=#FFF><align=center><size=200%>' @root.Data.H '</size></align>'}} <align=center>{{bar 1 0 1 45 '═'}}</align> {{#sortedeach @root.E.S.Items 'Id' false}}{{~#test Id in @root.Data.IDs}}{{set 'X' (concat @root.Data.X Id ',')}}{{setblock 'D' ~}} {{@root.Data.D}}{{i18n Id}}:{{format Count '{0,6:N0}'}}: {{~#test Count geq @root.Data.T}}{{@root.Data.C.0}}{{else}} {{~#test Count ge (calc @root.Data.T '*' '0.75')}}{{@root.Data.C.1}}{{else}} {{~#test Count ge (calc @root.Data.T '*' '0.50')}}{{@root.Data.C.2}}{{else}} {{~#test Count ge (calc @root.Data.T '*' '0.25')}}{{@root.Data.C.3}}{{else}}{{@root.Data.C.4}}{{/test}}{{/test}}{{/test}}{{/test}};{{~/setblock}} {{~/test}}{{~/sortedeach}} {{~#itemlist @root.E.S.Items @root.Data.IDs}}{{#test Id in @root.Data.X}}{{else}}{{set 'D' (concat @root.Data.D (i18n Id) ':' (format 0 '{0,6:N0}') ':' @root.Data.C.5 ';')}}{{/test}}{{/itemlist}} {{~#split @root.Data.D ';' true}}{{#each .}}{{#split . ':'}} {{~#test @root.Data.SS eq '1x2'}}{{~fontsize 6}}{{~#test (calc @Index '%' 3) eq 2}}{{set 'P' '67,90'}}1x2A{{else}}{{~#test (calc @Index '%' 3) eq 1}}{{set 'P' '32,56'}}1x2B{{else}} {{set 'P' '0,20'}}1x2C{{/test}}{{/test}}{{else}} {{~#test @root.Data.SS eq '1x1'}}{{~fontsize 4}}{{~#test (calc @Index '%' 2) eq 1}}{{set 'P' '52,85'}}1x1A{{else}} {{set 'P' '0,34'}}1x1B{{/test}}{{else}}{{fontsize 3}} {{set 'P' '8,74'}}{{/test}}{{/test}} {{~#split @root.Data.P ','}}{{~concat '<color=' ../.2 '><indent=' .0 '%>◉ ' ../.0 '</indent> <indent=' .1 '%>' ../.1 '</indent></color>' ~}}{{/split}} {{~/split}}{{~/each}}{{~/split}}
13.3.2 https://github.com/GitHub-TC/EmpyrionScripting/releases/download/13.3.2/EmpyrionScripting.zip @BloodAngel099 added 'orderbylist'
Hello everyone, I can't find the information I'm interested in. Please help me, the task is so that on the screen I can track the activity of the constructor and deconstructor (It is idle or some work is being done).
Unfortunately, Eleon has not yet created an API for accessing the constructor/deconstructor. Therefore, they are not yet accessible via scripting.
Need some help. Im trying to get a script to display O/I status display on my CV to display SV levels. The script I'm using now is this. {{entitybyid 10709370}} (Target Entity) {{~set 'limitLow' 1000}} {{~set 'limitMedium' 1000}} {{~set 'limitGood' 100000}} <align=left><size=5>Ingots {{Name}} - {{Id}}</size> {{bar 1 0 1 50 '═'}}</align> {{scroll 14 1}} {{#sortedeach E.S.Items 'Count' true}} ( This line I believe does not work when trying to target a different Entity) {{~#test Id 'in' (concat @Ids.Ingot '7301,7343')}} <color={{~#test Count geq @root.Data.limitGood}}green>{{~else}}{{~#test Count le @root.Data.limitMedium}}{{~#test Count le @root.Data.limitLow}}red>{{else}}orange>{{/test}}{{~else}}yellow>{{/test}}{{/test}}◉ {{i18n Key}} <pos=150>{{format Count '{0,6:N0}'}}</pos></color> {{/test}} {{/sortedeach}} {{#itemlist E.S.Items (concat @Ids.Ingot '7301,7343')}}{{~#test Count geq 1}}{{~else}}<color=red>○ {{i18n Key}} <pos=150><size=5> ⚠</size></pos></color> {{/test}} {{/itemlist}} {{/scroll}} {{/entitybyid}} How do I get it to target another Entity? The above code obviously does not work just give wrong parameters error! I not a code writer just a code copier. But I'm learning along the way.
Anyone got a mailbox script ? I'm looking for a script where players can send items or credits to each other but not in the same faction
with the new update on 14.10.2024 the cargo teleport script i hacked, originally for reforged eden, stopped working... after a lot of hacking and debug prints I found the reason: the target container had > 64 items (re allows 128 in cargo controllers) the hack in the script was Code: else if (items.Count < (root.CsRoot.ConfigFindAttribute(container.Id, "LootList").ToString() == "76" ? 128 : 64)) I can not recall that I made this (definitive not my style, so I might have borrowed it) Also where "LootList" and "76" come from no idea ;P all I know for now is the value changed to "66". It would be great if someone with more knowledge can give a comment to why the value might have changed and if changing it to 66 is the right fix. and for context the whole mess of a script: Code: using Eleon.Modding; using EmpyrionScripting; using EmpyrionScripting.CustomHelpers; using EmpyrionScripting.DataWrapper; using EmpyrionScripting.Interface; using Newtonsoft.Json; using System.Collections.Generic; using System.IO; using System.Linq; using System; public class ModMain { public static void Main(IScriptModData rootObject) { if (!(rootObject is IScriptSaveGameRootData root)) return; if (root.E.Faction.Id == 0) return; var infoOutLcds = root.CsRoot.GetDevices<ILcd>(root.CsRoot.Devices(root.E.S, "CargoOutInfo*")); root.E.S .AllCustomDeviceNames .GetUniqueNames("CargoOut@*") .ForEach(cargoOutContainerName => { var container = root.CsRoot.Devices(root.E.S, cargoOutContainerName).FirstOrDefault(); if (container == null) return; //WriteTo(infoOutLcds, $"\n\n{container.CustomName} vor gettype"); try { if (!(container.Device.GetType().ToString()).Contains("EmpyrionScripting.DataWrapper.ContainerData")) return; } catch { return; } var z = cargoOutContainerName.Substring("CargoOut@".Length); if (z.Equals("lcd")) { var colcds = root.CsRoot.GetDevices<ILcd>(root.CsRoot.Devices(root.E.S, "CargoOut@lcd")); z = colcds.FirstOrDefault().GetText(); } if (!int.TryParse(z, out var targetEntityId)) { WriteTo3(infoOutLcds, $"CargoOut@[ID] id is not a number"); return; } var fp = string.Concat("CargoTeleport", root.E.Faction.Id.ToString(), $"Cargo-{targetEntityId}.Name"); string zname; try { if (root.CacheData.TryGetValue(fp, out var zn)) zname = zn.ToString(); else zname = "false"; //WriteTo2(infoOutLcds, $"{cargoOutContainerName}", $"data {zname} {fp}"); } catch { zname = "Unbekannt"; WriteTo2(infoOutLcds, $"{cargoOutContainerName}", $"data catch"); } if (zname == "Unbekannt" || zname == "false") { try { var cargoAdresse = Path.Combine(root.MainScriptPath, "..", "CargoTeleport", root.E.Faction.Id.ToString(), $"Cargo-{targetEntityId}.Name"); zname = File.ReadAllText(cargoAdresse); //root.CacheData[fp] = zname; //WriteTo2(infoOutLcds, $"{zname}", $"file {fp} {zname}"); } catch { zname = "Unbekannt"; } } WriteTo3(infoOutLcds, zname); var cargoTargetFileName = Path.Combine(root.MainScriptPath, "..", "CargoTeleport", root.E.Faction.Id.ToString(), $"Cargo-{targetEntityId}.json"); if (!File.Exists(cargoTargetFileName)) { WriteTo2(infoOutLcds, $"{cargoOutContainerName}", $"CargoIn in [ID] not ready"); return; } root.CsRoot.WithLockedDevice(root.E.S, container, () => { var nativeContainer = ((ContainerData)container.Device).GetContainer() as IContainer; var items = nativeContainer.GetContent(); var failedItems = new List<ItemStack>(); items.ForEach(i => { try { File.AppendAllText(cargoTargetFileName, JsonConvert.SerializeObject(i) + "\n"); WriteTo2(infoOutLcds, zname, $"{i.count} {root.CsRoot.I18n(i.id)} nach {zname}"); } catch { failedItems.Add(i); WriteTo2(infoOutLcds, zname, $"Transfer failed: Item:[{i.id}] {i.count} {root.CsRoot.I18n(i.id)}"); } }); nativeContainer.SetContent(failedItems); }); }); var infoInLcds = root.CsRoot.GetDevices<ILcd>(root.CsRoot.Devices(root.E.S, "CargoInInfo*")); root.E.S .AllCustomDeviceNames .GetUniqueNames("CargoIn") .ForEach(cargoInContainerName => { var container = root.CsRoot.Devices(root.E.S, cargoInContainerName).FirstOrDefault(); if (container == null) return; var nativeContainer = ((ContainerData)container.Device).GetContainer() as IContainer; if (nativeContainer == null) return; var cargoTargetFileName = Path.Combine(root.MainScriptPath, "..", "CargoTeleport", root.E.Faction.Id.ToString(), $"Cargo-{root.E.Id}.json"); //WriteTo(infoInLcds, $"DEBUG {cargoTargetFileName}"); Directory.CreateDirectory(Path.GetDirectoryName(cargoTargetFileName)); //Block zum löschen von alten Dateien var dir = Directory.GetFiles(Path.Combine(root.MainScriptPath, "..", "CargoTeleport"), $"Cargo-{root.E.Id}.json", SearchOption.AllDirectories); foreach (var f in dir) { if (f.Equals(cargoTargetFileName)) continue; FileInfo fi = new FileInfo(f); if (fi.Length == 0) fi.Delete(); } var cargoAdresse = Path.Combine(root.MainScriptPath, "..", "CargoTeleport", root.E.Faction.Id.ToString(), $"Cargo-{root.E.Id}.Name"); File.WriteAllText(cargoAdresse, $"{root.E.GetCurrentPlayfield().Name} - {root.E.Name}"); root.CsRoot.WithLockedDevice(root.E.S, container, () => { var items = nativeContainer.GetContent() ?? new List<ItemStack>(); bool itemsAdded = false; using (var lockFile = File.Open(cargoTargetFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) { //WriteTo(infoInLcds, $"DEBUG lf {lockFile}"); using (var file = new StreamReader(lockFile)) { var remainLines = new List<string>(); //WriteTo(infoInLcds, $"DEBUG rl {remainLines}"); while (true) { var itemLine = file.ReadLine(); //WriteTo(infoInLcds, $"DEBUG itemline {itemLine} {root.CsRoot.ConfigFindAttribute(container.Id, "LootList").ToString()} 76"); if (string.IsNullOrEmpty(itemLine)) break; else if (items.Count < (root.CsRoot.ConfigFindAttribute(container.Id, "LootList").ToString() == "66" ? 128 : 64)) { var item = JsonConvert.DeserializeObject<ItemStack>(itemLine); items.Add(item); itemsAdded = true; WriteTo(infoInLcds, $"{item.count} {root.CsRoot.I18n(item.id)}"); } else remainLines.Add(itemLine); } lockFile.Seek(0, SeekOrigin.Begin); lockFile.SetLength(0); using (var fileWrite = new StreamWriter(lockFile)) { remainLines.ForEach(l => fileWrite.WriteLine(l)); } } } if (items.Count > 0 && itemsAdded) { byte index = 0; nativeContainer.SetContent(items .Select(i => new ItemStack(i.id, i.count) { slotIdx = index++, decay = i.decay, ammo = i.ammo }).ToList()); } }); }); //var s = DateTime.Now; var AdressLCD = root.CsRoot.GetDevices<ILcd>(root.CsRoot.Devices(root.E.S, "directory*")); string tempoutput = "<size=3>"; int count1 = 11; var get = root.CacheData.TryGetValue("count1", out var count1t); if (get) { int.TryParse(count1t.ToString(), out count1); if (count1 < 11) { //tempoutput = string.Concat(tempoutput, $"dir {count1.ToString()}\n"); { root.CacheData.Where(i => i.Key.StartsWith(string.Concat("CargoTeleport", root.E.Faction.Id.ToString()))).ForEach(n => { var D1 = n.Key.ToString(); var D2 = D1.Substring(0, D1.Length - 5).Substring(D1.LastIndexOf("Cargo-") + 6); tempoutput = string.Concat(tempoutput, $"{D2}:<indent=20>{n.Value}</indent>\n"); }); }; int c = count1 + 1; root.CacheData["count1"] = c.ToString(); }; } if (count1 >=11) { var cargoAdresse1 = Path.Combine(root.MainScriptPath, "..", "CargoTeleport", root.E.Faction.Id.ToString()); var dir1 = Directory.GetFiles(cargoAdresse1, "Cargo-*.Name", SearchOption.TopDirectoryOnly); dir1.ForEach(D1 => { var name = File.ReadAllText(D1); var D2 = D1.Substring(0, D1.Length - 5).Substring(D1.LastIndexOf("Cargo-") + 6); tempoutput = string.Concat(tempoutput, $"{D2}:<indent=20>{name}</indent>\n"); var fp = string.Concat("CargoTeleport", root.E.Faction.Id.ToString(), $"Cargo-{D2}.Name"); root.CacheData[fp] = name; }); root.CacheData["count1"] ="1"; //var s2 = DateTime.Now; //var dif = s2.Subtract(s).TotalMilliseconds.ToString(); } AdressLCD.ForEach(A => { A.SetText(tempoutput); }); }//ende main private static void WriteTo(ILcd[] lcds, string text) { lcds.ForEach(L => L.SetText($"{text}\n{L.GetText()}")); } private static void WriteTo2(ILcd[] lcds, string z1, string text) { lcds.ForEach(L => { L.SetText($"<align=center><b><color=green>{z1}</color></b></align><size=5>\n{text}\n{L.GetText().Substring(L.GetText().IndexOf("\n") + 1)}"); }); } private static void WriteTo3(ILcd[] lcds, string z1) { lcds.ForEach(L => { L.SetText($"<align=center><color=green>{z1}</color></align><size=5>\n{L.GetText().Substring(L.GetText().IndexOf("\n") + 1)}"); }); } }
Unfortunately, I have not found any information on which “LootList” has how many slots. There is also no API function that returns the number of slots for a container. I don't know what happens if you fill a container with too many slots :-(
This is going to sound odd, please bear with me. This is a script I wrote and shared last year, me and a mate have just come back to empyrion and I can not for the life of me remember how to use "savegame"scripts Can some one refresh my memory? the mod is installed on our dedicated server. all updated. I Dont think i ever got an answer about a salvage script in c# either... if anyone knows of one that would be very handy. (thanks in advance)