[MOD EXT] Empyrion Scripting - Scripts

Discussion in 'The Hangar Bay' started by Ephoie, Mar 22, 2020.

  1. ASTIC

    ASTIC Captain

    Joined:
    Dec 11, 2016
    Messages:
    993
    Likes Received:
    707
    Cargo Teleporter:


    EmpyrionScriptingMod Version >= 5.3.0

    Code:
    using System;
    using System.Collections.Generic;
    using System.IO;
    using Newtonsoft.Json;
    
    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).Where(C => C.Device is ContainerData).FirstOrDefault ();
                    if (container == null) return;
                    if (!int.TryParse (cargoOutContainerName.Substring ("CargoOut@".Length), out var targetEntityId))
                    {
                        WriteTo (infoOutLcds, $"CargoOut@[ID] id is not a number");
                        return;
                    }
    
                    var cargoTargetFileName = Path.Combine (root.MainScriptPath, "..", "CargoTeleport", root.E.Faction.Id.ToString (), $"Cargo-{targetEntityId}.json");
    
                    if (!File.Exists (cargoTargetFileName))
                    {
                        WriteTo (infoOutLcds, $"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");
                                WriteTo (infoOutLcds, $"Transfer: Item:[{i.id}] {i.count} {root.CsRoot.I18n(i.id)}");
                            }
                            catch {
                                failedItems.Add (i);
                                WriteTo (infoOutLcds, $"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).Where(C => C.Device is ContainerData).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");
                    Directory.CreateDirectory(Path.GetDirectoryName(cargoTargetFileName));
    
                    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))
                        {
                            using (var file = new StreamReader (lockFile))
                            {
                                var remainLines = new List<string> ();
    
                                while (true)
                                {
                                    var itemLine = file.ReadLine ();
                                    if(string.IsNullOrEmpty(itemLine)) break;
                                    else if (items.Count < 64)
                                    {
                                        var item = JsonConvert.DeserializeObject<ItemStack> (itemLine);
                                        items.Add (item);
                                        itemsAdded = true;
                                        WriteTo (infoInLcds, $"Transfer: Item:[{item.id}] {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());
                        }
                    });
                });
    
        }
    
        private static void WriteTo (ILcd[] lcds, string text)
        {
            lcds.ForEach (L => L.SetText ($"{text}\n{L.GetText()}"));
        }
    }
     
    #21
    Ephoie likes this.
  2. ASTIC

    ASTIC Captain

    Joined:
    Dec 11, 2016
    Messages:
    993
    Likes Received:
    707
    And now (with a EcfParser included ;-) ) you have access to the config...
    Version >= 5.4.0

    Code:
    {{i18n 2248 'English'}}
    StackSize: {{itemconfig 2248 'StackSize'}}
    Volume: {{itemconfig 2248 'Volume'}}
    Mass: {{itemconfig 2248 'Mass'}}
     
    Stack/2: {{calc (itemconfig 2248 'StackSize') '/' 2}}
    Stack*2: {{calc (itemconfig 2248 'StackSize') '*' 2}}
    upload_2020-5-9_18-19-28.png
     
    #22
    Sephrajin, shadowiviper and Ephoie like this.
  3. Myrmidon

    Myrmidon Rear Admiral

    Joined:
    Mar 26, 2016
    Messages:
    1,729
    Likes Received:
    2,058
    Can i use this on SP games?
     
    #23
    Ephoie likes this.
  4. ASTIC

    ASTIC Captain

    Joined:
    Dec 11, 2016
    Messages:
    993
    Likes Received:
    707
    Yes, you can use the Empyrion Scripting Mod also in SP.
    Note: in SP the EAC must be turn off to load MODs
     
    #24
    Ephoie likes this.
  5. Myrmidon

    Myrmidon Rear Admiral

    Joined:
    Mar 26, 2016
    Messages:
    1,729
    Likes Received:
    2,058
    Thank you. Well I play always with EAC off. I play SP all the time you see. I wonder why we do not see WS creations using them.
     
    #25
    Ephoie likes this.
  6. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    144
    @Myrmidon - ASTIC may well correct me on this, but from my testing this works fine in SP when entering code dirctly into a LCD e.g. having "Script:Display1" + "Display1", but if you're using the .hbs files like the ActiveRadar script they only execute when running as a 'server' so you need to start a local coop game for 1 person. The only difference in functionality is when entering code via the screens you're limited to about 2,000 characters so some more complex scripts need to be broken up or compressed down to fit.
     
    #26
    Ephoie likes this.
  7. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    144
    Name: Fuel Log
    Description: Graph of fuel consumption over the last ~2 hours with axis lines

    Picture:
    upload_2020-5-10_20-3-58.png
    upload_2020-5-10_20-14-24.png
    LCD Input Name: Script:[+120]FuelLog, Script:FuelLogAxis
    LCD Output Name/Setup: FuelLog + FuelLogAxis, both as projector blocks with width/height 1. Offset both projectors so they are on the same blockspace, with 'FuelLog' being rotated 90 degress clockwise - so the first letter of "Enter text" appears in the top right corner pointing down. As the script is a [+N] new data is added to the "top" and pushes previous bars "down", but being rotated 90deg the "top" is now the far right. The 2nd projector is then used for the axis and numbering as a single screen cannot rotate only some of its text, so the numbers are the right way up.

    Paint the block behind black and/or texture as desired. To give a glassy/screen type look the screenshot above has the projection 0.25 in front of the block and placing the full glass heavy window over the top to give a 'thick screen' effect.

    The modulus in FuelLog causes the script to run once per hour, with a text size that fits in 120 columns across the screen - increasing the length of the log should just be a case of increasing the modulus on line 2 e.g. changing 60 to 120 would mean it only runs once every 2 minutes, so 120 lines covers 4 hours instead of 2.
    LCD Input Script:
    Script:[+120]FuelLog
    Code:
    {{fontsize 2}}
    {{#test (calc @root.CycleCounter '%' 60) eq 0}}
    <indent=28><line-height=0><color=#FF111150>
    {{#use @root.E.S.FuelTank}}
    {{~bar (calc Capacity '-' Content) 0 Capacity 60 '<color=#000>█</color>' '█'~}}
    {{/use}}
    </color></line-height>
    {{/test}}
    
    Script:FuelLogAxis
    Code:
    <size=6><indent=5%>{{E.Name}} - {{datetime 'HH:mm'}}</indent><indent=50%>{{#use E.S.FuelTank~}}
    <color=#F11>☢ {{bar Content 0 Capacity 15 '▒' '<color=#300>░</color>'}}<indent=50%><size=4><b><color=#FFF>{{~math Content '/' Capacity}}{{~format . '{0,8:P2}'}}{{~/math}}</color></b></size></indent></color>
    {{/use~}}
    </indent><indent=0>{{bar 1 0 1 65 '─'}}</indent></size>
    <line-height=4>{{fontsize 8}}
    <size=4>100%</size>
    <indent=8%>{{bar 1 0 1 7 '║
    '}}</indent>
    <size=4>75%</size>
    <indent=8%>╟<color=#CCCCCC40>{{bar 1 0 1 33 '─'}}</color>
    {{bar 1 0 1 7 '║
    '}}</indent>
    <size=4>50%</size>
    <indent=8%>╟<color=#CCCCCC40>{{bar 1 0 1 33 '─'}}</color>
    {{bar 1 0 1 9 '║
    '}}</indent>
    <size=4>25%</size>
    <indent=8%>╟<color=#CCCCCC40>{{bar 1 0 1 33 '─'}}</color>
    {{bar 1 0 1 9 '║
    '}}</indent>
    <indent=8%>╚{{bar 1 0 1 33 '═'}}
    <size=4><indent=5%>-2h</indent><indent=50%>-1h</indent><indent=95%>-0s</indent></size>
    
     
    #27
  8. Myrmidon

    Myrmidon Rear Admiral

    Joined:
    Mar 26, 2016
    Messages:
    1,729
    Likes Received:
    2,058
    Nice.
     
    #28
    shadowiviper and Ephoie like this.
  9. ASTIC

    ASTIC Captain

    Joined:
    Dec 11, 2016
    Messages:
    993
    Likes Received:
    707
  10. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    144
    Amazing as always! Can't wait for A12 so I can start implementing some of these and cleaning up my old scripts so they don't have 12000 lines of hard-coded data from the config in them. These updates ruin my motivation to finish the A11 scripts I've got in progress knowing it will be so much simpler to do when A12 drops
     
    #30
    Ephoie likes this.
  11. ASTIC

    ASTIC Captain

    Joined:
    Dec 11, 2016
    Messages:
    993
    Likes Received:
    707
    Sorry for ruin your motivation ;-)
    You can run the EmpyrionScriptingMod in your A12 Exp in Single Player ... or you can join my server if you want.
     
    #31
    Ephoie likes this.
  12. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    144
    Always happy for new toys to play with even if it means having to wait a few days :) I've not tried A12 at all yet as I've been busying building on @Ephoie 's server which also has scripting enabled, so everything I've written currently has been to use there. I need to install experimental soon and start work on a new batch of scripts for when the update drops, so can work on them in SP ready for the big update.

    My current project is a hbs script for Ephoie that does a complete universal listing for any container just by naming the screen, and adapts to fit the size of the screen properly so can be used with a 1x1, 1x2, 0.5x0.5 and changes it contents to show more/less, then show total volume vs capacity and the number of free inventory slots (I believe all containers are 128 apart from the fridge which is 64), so 'ItemCount/Stacksize then round up for the number of slots taken per item and total up all items to give the number of slots taken/free as well as volume - but im currently writting for A11 so calculating volume/stacksize from a csv file in a very long winded way.

    Very excited to update all of it to A12 version, should be very simple as all that code can just be replaced with the new itemconfig call and done automatically so then becomes a very short/simple script.

    Think I've finally got the hang of the basics at least (finding you can use @Key in an each to find the property names for an entity was a big step forwards) so guess I'll have to start learning C# next in preperation for the new version.

    Looking forwards to what comes next :)
     
    #32
    Ephoie likes this.
  13. Thodin O Gondrafn

    Thodin O Gondrafn Lieutenant

    Joined:
    Mar 14, 2019
    Messages:
    55
    Likes Received:
    14
    Hi,
    soweit ich verstehe, laufen die Scripte ja ständig, unabhängig, ob das LCD aktiviert ist oder nicht. Ich suche nach einer Möglichkeit, insbesondere die Intervall-Scipte ein und aus zu schalten, am liebsten mit Schalter/Sensor. Was kann ich tun (bitte nicht C-Sharp lernen empfehlen, ich bin ALT)?
    Hi,
    as far as I understand, the scripts are always running, regardless of whether the LCD is activated or not. I am looking for a way to switch the interval scipts on and off, preferably with a switch / sensor. What can I do (please do not recommend learning C-Sharp, I am OLD)?
     
    #33
    Ephoie likes this.
  14. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    144
    You can get the state of a custom signal - the far right column in the 'P' menu with
    Code:
    {{getsignal @root.E.S 'NameOfSignal'}}
    {{#if .}}
    ...do stuff here...
    {{/if}}
    {{/getsignal}}
    
    I believe this also works for a tx signal on a switch or sensor if you use "getswitch" instead of "getsignal" but haven't tried it personally
     
    #34
    Sephrajin and Ephoie like this.
  15. Thodin O Gondrafn

    Thodin O Gondrafn Lieutenant

    Joined:
    Mar 14, 2019
    Messages:
    55
    Likes Received:
    14
    Hi and thx,
    scheint zu gehen :).
    Jedoch behält die Ausgabe, in diesem Fall kein LCD sondern ein Projektor, die Hintergrundfarbe im Ausschaltmoment.
    Daher schon die nächste Frage: Wie bekomme ich den Projektor ganz aus oder auf den eingestellten Grundwert (default setting)?
    --
    Hi and thx,
    seems to be going :).
    However, the output, in this case not an LCD but a projector, retains the background color at the moment of switching off.
    Therefore, the next question: How do I get the projector out of its entirety or to the default value?

    Code:
    {{getsignal @root.E.S 'TxLicht'}}
    {{#if .}}
    
    {{#intervall 2}}
    Hallo
    {{else}}
    Welt
    {{/intervall}}
    {{#intervall 2}}
    {{bgcolor 'ffff00'}}
    {{else}}
    {{bgcolor ''}}
    {{/intervall}}
    
    {{/if}}
    {{/getsignal}}
    
     
    #35
  16. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    144
    I wasn't actually aware you could use background colour with a projector... that's very interesting to know :)

    My first guess would be bgcolor doesn't accept a null/blank value, but I believe it does support an alpha (transparency) value like the text color does. So where you have {{bgcolor ''}} try {{bgcolor 'FFFFFF00'}}, so effectively white (FFFFFF) with full transparency (00) which would put the projector background back to its normal invisible state.
     
    #36
    Ephoie likes this.
  17. Thodin O Gondrafn

    Thodin O Gondrafn Lieutenant

    Joined:
    Mar 14, 2019
    Messages:
    55
    Likes Received:
    14
    Hi, war auch mein erster Gedanke für einen Workaround. Nur ist das mit Standart-HTML bisher misslungen. Bestenfalls erhalte ich ein halb transparentes Schwarz oder beliebige andere Farbe. Würde aber auch nicht die endgültige Lösung sein, da ich ja bei Abschaltung nichts mehr sehen möchte. Das geht leider nur bisher mit Verzicht auf Background. FYI: ich benutze EGS 12.3 ;)
    Hi, was also my first thought for a workaround. Only that has so far failed with standard HTML. At best, I get a semi-transparent black or any other color. Wouldn't be the final solution either, since I don't want to see anything anymore when I turn it off. Unfortunately, this has only been possible so far with no background. FYI: i use EGS 12.3 ;)
     
    #37
  18. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    144
    Just tried this in-game and I think background colours on projectors must be a new Alpha 12 feature. If the aim is to turn off the screen entirely when your switch is off could you do this through signal logic - so in the devices list of the P menu setting the output screen to 'Follow' on txLicht, which would turn it off entirely when its turned off (so displays nothing).

    If you wanted to keep it all within the script but just turning off the output screen as part of the toggle, you can add it as an {{else}}

    Code:
    {{getsignal @root.E.S 'txLicht'}}
    {{#if .}}
    
    {{devices @root.E.S 'HalloWelt'}}
    {{setactive .0 true}}
    {{/devices}}
    
    {{#intervall 2}}
    Hallo
    {{else}}
    Welt
    {{/intervall}}
    {{#intervall 2}}
    {{bgcolor 'ffff00'}}
    {{else}}
    {{bgcolor ''}}
    {{/intervall}}
    
    {{else}}
    
    {{devices @root.E.S 'HalloWelt'}}
    {{setactive .0 false}}
    {{/devices}}
    
    {{/if}}
    {{/getsignal}}
    
    This is for an output screen called HalloWelt - so when the txLicht signal is on the output screen turns on and alternates the text / background color when it's on.

    If you're trying to get the background to alternate between yellow and transparent while the switch is on - I'm not currently sure. For a standard LCD screen {{bgcolor ''}} does work and sets the screen to its default (black) but this apparently doesn't work with a projector. I'm planning to try Alpha 12 over the weekend so will have a look at projector backgrounds then to see if theres any other way to do it
     
    #38
  19. Thodin O Gondrafn

    Thodin O Gondrafn Lieutenant

    Joined:
    Mar 14, 2019
    Messages:
    55
    Likes Received:
    14
    ... und DAS geht wirklich nur mit den ASTIC-LCD-Scripten... XD
    ... and THAT really only works with the ASTIC LCD scripts ... XD
     

    Attached Files:

    #39
  20. Thodin O Gondrafn

    Thodin O Gondrafn Lieutenant

    Joined:
    Mar 14, 2019
    Messages:
    55
    Likes Received:
    14
    Hi, mit der Signallogik war mein erster Versuch, hatte ebenso den Hintergrund nicht ausgeschaltet.
    Den HalloWorld-Code habe ich gerade versucht, Ergebnis anbei.
    Scheine da wohl ein sehr spezielles "Problem" zu haben :)
    Hi, with the signal logic was my first try, also hadn't switched off the background.
    I just tried the HalloWorld code, result attached.
    Seems to have a very special "problem" :)
     

    Attached Files:

    #40

Share This Page