[MOD EXT] Empyrion Scripting - Discussions

Discussion in 'The Hangar Bay' started by Sephrajin, Jun 29, 2020.

  1. Sephrajin

    Sephrajin Rear Admiral

    Joined:
    Dec 22, 2017
    Messages:
    916
    Likes Received:
    2,918
    Heyas

    For final solutions, please check:
    https://empyriononline.com/threads/mod-ext-empyrion-scripting-scripts.92458/

    I would like to keep that thread for solutions only, as I belive this makes it easier for others to find working solutions / scripts.
    This said, lets use this thread for discussions, bugfixes and scripts that are not ready yet for the 'solution' thread.


    -------------------------------------------------

    So I have this script that is supposed to automaticly fill my docked vessels with O2, Fuel and Pentaxid, if a switch is set to 'true'.

    My issue is, it does not work.
    Nor does it print an error.

    Code:
    <align=center><i><size=150%>Autofill Vessels:</size></i></align>
    {{#getswitch E.S 'sw_auto_fuel'}}
    {{#test SwitchState eq true}}
    
    {{~#each E.S.DockedE}}
    Checking: {{Name}}...
    {{#items @root.E.S 'Output Power'}}
    {{#fill this ../S 'Oxygen' 100}}
    - Oxygen
    {{/fill}}
    {{#fill this ../S 'Fuel' 100}}
    - Fuel
    {{/fill}}
    {{#fill this ../S 'Pentaxid' 100}}
    - Pentaxid
    {{/fill}}
    {{/items}}
    {{/each}}
    
    {{else}}
    <color=red>Switch this lever to automaticly fuel up your docked vessels.</color>
    {{/test}}
    {{/getswitch}}
    
    Anyone able to tell me what I'm doing wrong here?
     
    #1
    Last edited: Jun 29, 2020
  2. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    Hi @Sephrajin

    Oddly this is very similar to something I was already working on but never got around to finishing - an auto refuel/rearm where each SV generates a config file of its current loadout and then a CV/BA can unload any extra items, reload a default 'kit' like medpacks, ammo, food etc and refuel all in one go.

    I've had a quick look and I think the problem is on the {{#each}} - as you're now nested inside getswitch/test "E" no longer refers to your base entity, so when your switch is set to true there is no output due to no docked ships being found. If you change it to
    Code:
    {{~#each @root.E.S.DockedE}}
    
    It will always refer to the top level (e.g. the base with the screen on it) and should then check the docked ships.

    A couple of other minor thoughts
    • getswitch only refers to an actual physical switch where txsignal matches that name - I dont think it will match a custom signal in the control panel - if the switch doesnt exist I believe the entire getswitch is skipped including your else/error message
    • Where you're using {{test}} to compare to true, you can also do this as an {{if}} which always evaluates as "equals true" - so would be
      {{#if SwitchState}} and changing the end tag to make it a little shorter
    Finally, I don't think you will get your intended output text, where it shows "- Fuel" or "- Oxygen", as the script is effectively running once every second and the content within the {{fill}} only shows if it was actually used. In other words you activate your switch, the screen shows "Checking: MySV", fills the fuel tank and shows " - Fuel" for a fraction of a second and then starts over again - on the 2nd run you still get the 'Checking' text but the fuel tank is now full, so that "-Fuel" text no longer shows. The actual intended effect works - your ship will get refueled - you just wont have that text shown on screen to say its happened.

    If you want to have that text you need to have a 'top' screen, so it keeps all content on the screen and just adds new lines to the top as they are output. You'd rename your screen with the code to something like Script:[+20]AutoRefuel, where +20 is the number of lines it always shows. It gets tricky where you have things like the title "Autofill Vessels" as you'd essentially get that line repeated 20 times, so you'd need to change your output to only show something when it actually triggers the fill, which would then show like a log file

    Hope that all makes sense - if not let me know and Ill try and throw together an example
     
    #2
    Sephrajin likes this.
  3. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    I've also had a look at your quetion about the ship list script from the other thread - properly in game this time instead of just guessing. I think whats happening is the {{distance}} tag outputs as a string rather than as a number, so normal number formatting codes don't apply and it always uses the default output of {{distance}}

    There doesn't look to be a good way to re-cast that value as an integer so it can be formatted as a number - so the best option I can find from a quick 5 minute hack is to split it as a string and use that instead.

    If you replace the line
    Code:
    ║ {{format (distance Pos @root.E.Pos) '{0,0:N0}m'}} {{@root.data.E}}
    
    with this
    Code:
    ║ {{split (distance Pos @root.E.Pos) "."}}{{.0}}m{{/split}} {{@root.data.E}}
    
    This basically splits the number on the "." character into an array of values, and then only shows the first element of that - so everything up to the ".". I think in your screenshots you had the decimal point as a comma so you might need to replace the "." with "," if that's what you're using
     
    #3
    Sephrajin likes this.
  4. Sephrajin

    Sephrajin Rear Admiral

    Joined:
    Dec 22, 2017
    Messages:
    916
    Likes Received:
    2,918
    Yes, I did have a physical switch there in use.

    I only want/ed the '- O2/fuel/warp' text to be shown for a second... while re-fuelling.
    Otherwise it should be clean.
    But thinking about it again, you're right, it's better to loose those lines alltogether.

    I'll give the split a go within a few, currently trying to hotfix a count check before filling, which just came to mind while posting.
     
    #4
  5. Sephrajin

    Sephrajin Rear Admiral

    Joined:
    Dec 22, 2017
    Messages:
    916
    Likes Received:
    2,918
    We just dont understand why it stops working here:

    Basicly its the same code as the working one in the scripts thread, but with an additional check wether Count is high enough to be used to fill.
    Regardless, allthough it has enough fuel, it does not get filled.

    Code:
    {{~set 'LimitToType' 'SV,HV'}}
    <pos=0>◜</pos><pos=188>◝</pos>
    <align=center><i><size=150%>Autofill docked vessels</size></i>
    </align><pos=0>◟</pos><pos=188>◞</pos>
    {{#getswitch E.S 'sw_autofil'}}
    {{#if SwitchState}}
    {{~#each @root.E.S.DockedE}}
    {{#items @root.E.S 'Output Power'}}
    {{#test Count ge 1000 }}
    {{#fill this ../S 'Oxygen' 100}}
    {{/fill}}
    {{#fill this ../S 'Fuel' 100}}
    {{/fill}}
    {{#fill this ../S 'Pentaxid' 100}}
    {{/fill}}
    {{/test}}
    {{/items}}
    {{/each}}
    
    
    
    {{else}}
    <color=red>Switch this lever to automaticly fuel up your docked vessels.</color>
    
    
    {{/if}}
    {{/getswitch}}
    <size=90%>
    {{#items @root.E.S 'Output Power'}}
    {{#test ID in '2373,2294,2128'}}
    {{#test count le 1000 }}
    <indent=6>◉ <color=red>Not Enough: <color=green>{{Name}}</color> (<color=orange>{{Count}}</color>)</color></indent>
    {{/test}}
    {{/test}}
    {{/items}}
    </size>
     
    #5
  6. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    Code:
    {{~#each @root.E.S.DockedE}}
    {{#items @root.E.S 'Output Power'}}
    {{#test Count ge 1000 }}
    {{#fill this ../S 'Oxygen' 100}}
    {{/fill}}
    
    Check what "this" and "../S" are referencing on the {{fill}} line - now that it's nested inside "test" I think 'this' will be referring to the result of test, rather than an item from the {{items}} loop, and same again for ../S (i.e. its going 1 level up, so now refers to "S" of the item, rather than the docked vessel. So taking both of those values out of the test to get something like
    Code:
    {{#fill ../this ../../S 'Oxygen' 100}}
    
    Not actually in front of my game at the minute so haven't been able to test it directly, but that's my hunch on what's wrong
     
    #6
    Sephrajin likes this.
  7. Sephrajin

    Sephrajin Rear Admiral

    Joined:
    Dec 22, 2017
    Messages:
    916
    Likes Received:
    2,918
    Love you mate!
    It works with the '.' so it might be cross-country compatible :)

    Also your hints in regards of the sublevel were spot on!
    After a few tries I figured it out, as it was one deeper than your suggestion.

    I updated the script in the scripts thread to what it should have been from the start.
    Thank you very much @shadowiviper! :)
     
    #7
    shadowiviper likes this.
  8. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    No worries buddy, nice to have someone else playing with scripts and gets me to think about it a bit more looking at someone else's code than just staring at my own bugs all the time :) Hopefully will also inspire me to go back and finish some of the mountain of scripts I've started on and abandoned when I got fed up with them

    Edit: had a look at your updated version in the script thread - on your first line you've got
    Code:
    {{~set 'LimitToType' 'SV,HV'}}
    which I assume you saw in 1 of my scripts, but you don't actually reference it anywhere else further down. Wouldn't make much of a difference as you're unlikely to have a BA/CV docked, but if you add in
    Code:
    {{#test EntityType in @root.Data.LimitToType}}
    inside your docked ships loop you'd then be able to filter to only refuelling SVs or HVs with different scripts if needed.
     
    #8
    Last edited: Jun 30, 2020
    Sephrajin likes this.
  9. Sephrajin

    Sephrajin Rear Admiral

    Joined:
    Dec 22, 2017
    Messages:
    916
    Likes Received:
    2,918
    Well I run the script on a class 30 CV and since CV-CV docking is now a thing, it might happen.
    And I just want to make sure I dont spend an unexpected amount of 'fuel' (as cathegory) into another CV.

    The BA could be left out, since the BA wont dock to the CV :p
    But I'd like to exclude it anyway just incase someone wants to change it from "Docked" to "Range" ;)
     
    #9
  10. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    All makes sense - in which case the definition of 'LimitToType=SV,HV' is correct, but you'd actually have to test that the current ship being filled is one of those types, so somewhere in your loop of ships checking EntityType is one of the ones you've listed before continuing - that way it wont bother to try and fill up a CV unless you add it to the list.
     
    #10
  11. Sephrajin

    Sephrajin Rear Admiral

    Joined:
    Dec 22, 2017
    Messages:
    916
    Likes Received:
    2,918
    Soooo.... I'm working on that new script, trying to move some reserve o2, fusion cells and petnaxid into a cargo box of docked vessels.

    I'm running the script from a CV, parsing for docked ships and check wether they have a cargo box named 'Reserves'.
    So far, so good, it works.

    Issue arises when I try to move those items into the docked vessel's box.

    Btw, the script works even when written with indentions :D
    Code:
    {{~set 'LimitToType' 'SV,HV,CV'}}
    {{#getswitch @root.E.S 'sw_AutoReserves'}}
     {{#if SwitchState}}
      {{~#each @root.E.S.DockedE}}
       {{~set 'Ship' Name}}
        {{#test EntityType in 'SV,HV'}}
        {{~set 'Reserves_Num' '5'}}
        {{/test}}
        
        {{#test EntityType in 'CV'}}
        {{~set 'Reserves_Num' '10'}}
        {{/test}}
        
    {{~#devicesoftype S 'Container'}}
    {{#each .}}
    Found: i:{{id}} c:{{CustomName}} / n:{{Name}} // t:{{type}} d:{{.}}
    {{#test CustomName eq 'Reserves'}}
    Ship:{{@root.data.Ship}}
    - has container named  :: {{CustomName}} (id: {{id}})
    {{~set 'MoveTarget' CustomName}}
        {{#items @root.E.S 'Output Power'}}
         {{#test id in 2373,2294,2128}}
         {{~set 'Itemname' Name}}
         Trying to move {{@root.data.Itemname}} to {{@root.data.MoveTarget}}
          {{move this S 'Reserves' @root.data.Reserves_Num}}
          <size=7> {{datetime 'hh:mm:ss'}} |Reserves| {{format Count '{0,6}'}} | {{~format @root.data.Itemname '{0,27}'}} | <color=red>❱</color> {{@root.data.Ship}}</size>
          {{/move}}
         {{/test}}
        {{/items}}
    {{/test}}
    {{/each}}
    {{/devicesoftype}}
    
    
        {{/each}}
       {{/test}}
       
      {{/each}}
     {{/if}}
    {{/getswitch}}
    {{/test}}
    
    Outputs as follows:
    Code:
    Found: i:1684 c:Reserves / n: // t: d:EmpyrionScripting.DataWrapper.BlockData
    Ship:DSEV Austerty (A12)
    - has container named  :: Reserves (id: 1684)
    
         Trying to move Pentaxid (refined) to Reserves
          {{move}} error Object reference not set to an instance of an object
    Any and every idea is welcome.
    Thank you

    PS:
    I already tried with ../this and ../../this and ../../../this with no luck.
     
    #11
  12. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    At a glance, it's not "this" that needs the '../this' but "S" instead. You're looping through the docked ships right from the start, so by the time you get to {{move}} 'S' is already nested inside test,items,another test,each & devicesoftype, so the error you're getting (I think) is that "S" isnt a ship, rather than 'this' not being an item.

    If you swapped out "{{~set 'Ship' Name}}" for "{{~set 'Ship' S}}" to keep your reference to the actual ship rather than it's name, then use {{@root.Data.Ship.E.Name}} to get the name when you need it. In the {{move}} use {{@root.Data.Ship}} instead of S so you don't need to work out how nested you are from the initial 'Docked' loop

    I may well be wrong having not tried it in-game and just having a quick look, if that doesn't work let me know and I'll actually try it tonight
     
    #12
  13. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    Code:
     Trying to move {{@root.data.Itemname}} to {{@root.data.MoveTarget}}
    S: {{S}}
    S-2: {{../../../../../S}}
    S-3:: {{@root.Data.S}}
    Ship name: {{@root.Data.Ship}}
    Ship name 2:: {{@root.Data.S.E.Name}}
    
    Output:
    Code:
       
    Found: i:1684 c:Container 1 / n: // t: d:EmpyrionScripting.DataWrapper.BlockData
    Ship:Scout
    - has container named  :: Container 1 (id: 1684)
         Trying to move Fusion Cell to Container 1
    S: 
    S-2: EmpyrionScripting.DataWrapper.StructureData
    S-3: EmpyrionScripting.DataWrapper.StructureData
    Ship name: Scout
    Ship name 2:: Scout
    
    For the last line, I'd set "{{~set 'S' S}}" just after you had "{{~set 'Ship' Name}}", either option should work - naviagate back up (5 times I think to ../../../../../S or store S at the point you currently store name and use that
     
    #13
    Sephrajin likes this.
  14. Sephrajin

    Sephrajin Rear Admiral

    Joined:
    Dec 22, 2017
    Messages:
    916
    Likes Received:
    2,918
    Oh just seen this 'a few minutes' ago and it works now!
    These "../"'s drive me crazy...

    Thanks alot @shadowiviper ! :)


    If I may ask in addition, thats "why I came here today"...
    You have those nice listing scripts, materials, ores ingots...

    I wanted to make a box-specific itemlist, but I cant get it to work.
    Main reason for that script would be to see wether a required item is there or mising, in this specific box.
    However, I only get the heading/ title..

    It would be great if it would be this simple:
    Code:
    {{~set 'H' 'Power Production Input'}}
    {{~set 'C' '03 Input Power / o2'}}
    {{~set 'T' '1000'}}
    {{~set 'L' 'English'}}
    {{~set 'IDs' '2254,2265,2272,2283,2293,2396'}}
    {{~concat '<align=center><size=150%><i>' @root.Data.H '</i></size></align>'}}
    <color=#FFF><align=center>{{bar 1 0 1 15 '═'}}</align>
    </color>
    {{~devices E.S @root.data.C}}
    {{~#itemlist . @root.Data.IDs}}
    - <color={{~test count geq @root.data.T}}green{{else}}red{{/test}}>{{key}} {{count}}</color>
    {{/itemlist}}
    {{/devices}}
    Beeing aware that the above has some flaws... I did hope this below would work better:
    Code:
    {{~set 'H' 'Power Production Input'}}
    {{~set 'C' '03 Input Power / o2'}}
    {{~set 'T' '1000'}}
    {{~set 'L' 'English'}}
    {{~set 'IDs' '2254,2265,2272,2283,2293,2396'}}
    {{~concat '<align=center><size=150%><i>' @root.Data.H '</i></size></align>'}}
    <color=#FFF><align=center>{{bar 1 0 1 15 '═'}}</align>
    </color>
    {{~devicesoftype E.S 'Container'}}
    {{#each .}}
    {{#test CustomName eq @root.data.C }}
    good
    {{~#itemlist . @root.Data.IDs}}
    - <color={{~test count geq @root.data.T}}green{{else}}red{{/test}}>{{key}} {{count}}</color>
    {{/itemlist}}
    {{/test}}
    {{/each}}
    {{/devicesoftype}}
    However, it only returns:
    good{{itemlist}} error Value cannot be null.
    Parameter name: source

    And I'd like to ask @ASTIC : can itemlist be used on a single specific box, rather than just for the whole structure?

    Any advice / hints?
    Thanks in advance
     
    #14
  15. shadowiviper

    shadowiviper Commander

    Joined:
    Apr 13, 2020
    Messages:
    89
    Likes Received:
    145
    Haha, I just figured you'd already solved it and were working on something else - my game time is pretty sporadic currently so I end up with loads of half finished scripts that just need a few tweaks to get finished but never find the motivation to go back to them.

    The navigation with ../ takes a bit of getting used to especially as your scripts get more complicated. The general rule is any open tag that you could reference with "{{.}}", even if it's just True/False you need to go up 1 more level to get back to where you were before. So working backwards and counting every open 'items', 'test', 'if', 'block' etc - once you're down 4-5 layers it's often easier to just store your reference point to a variable (in this case the docked ship). I just wish it didn't take so many characters to get back to that variable as I'm forever hitting the character limit of a screen, even when I cut everything down as much as possible my last script was something like 2,056 characters and I have to go through changing every variable to a single letter or try to do every little bit as efficiently as possible just to sneak in under 2,000 characters, and having to constantly use "{{@root.Data.X}}" instead of something like {{$X}} eats up that character limit when you've got a lot going on.

    So for your next problem - I don't believe there is any equivalent to 'itemlist' for a single container, the 2 main options being 'items' which looks at everything in a single container, but can only be filtered down by testing for IDs, and "itemlist" which is specifically ship-wide but you can feed in the IDs you want from the start.

    It should still be possible to cobble something together using both types of 'item' and piecing the result together afterwards, which is sort of what my old script you're looking at does anyway (because it orders on count, but 'sortedeach' doesn't include zero item results). You can take a bit of a shortcut as you know any item without a value MUST be zero, and then just show them at the end.

    So some very rough pseudo-code based would be something like
    Code:
    {{set 'ItemstoDisplay' '2045,2046,2047,2048,2049,2050'}}
    {{set 'Items' ''}}
    {{items E.S 'MyContainer'}}
        {{name}}: {{count}}
        {{set 'Items' (concat @root.Data.Items Id "," )}}
    {{/items}} //Do all non-zero values first
    
    //We now have an array of all the items that were found, comma separated
    {{@root.Data.Items}} //shows 2045,2046,2047,2048,    - watch for that extra comma on the end. might cause issues with empty ids
    
    {{split @root.Data.ItemstoDisplay ","}}
        {{each .}}
            //In this loop we go through the IDs of all the items we want to show from line 1
            //If the current id is NOT in our array of items from the container we need to show it, there isn't a "Not In" operator so need to reverse an In
            {{test this in @root.Data.Items}}
                //Do nothing
            {{else}}
                //Need to get the name of this item from its ID, use i18n. Remember to go up 1 to get out of the 'test'
                //As this item wasn't in our array we know it must be zero or it would have been set
                {{i18n ../. 'English}} >> 0
            {{/test}}
        {{/each}}
    {{/split}}
    
    So basically, do your list of items from a single container as you would normally, but 'remember' which items you've already found, then loop through your list of "all" the items you want and if any ID hasn't been stored it must be a zero value for that specific container

    You'd probably also want to throw in a 'sortedeach' in the first loop as well so that your initial results are sorted largest first - it was a very late addition to my old script as ASTIC only added it after i'd published my first version so I went back and added it. Im not sure how well it integrates with using {{items}} instead of the full '{{itemlist}} but in theory it should work the same. I'd need to actually try it myself for a single container to have any idea what I'm doing

    Hope that helps :)
     
    #15
  16. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,085
    Likes Received:
    731
    I can expand itemlist then you can also select containers ... but only in two weeks when I am back from vacation
     
    #16
    Sephrajin and shadowiviper like this.
  17. tachyon

    tachyon Commander

    Joined:
    Aug 12, 2015
    Messages:
    92
    Likes Received:
    134
    @ASTIC it there a way to set the update intervall using the C# scripting? I would like to implement the damagemonitoring so that it scans through the layers of a structure and shows the damages in each layer. But this isn't that usafull with 1sec update rate (slower would be nice).
    I found the InGameScriptsIntervallMS property but I don't now how to access it and also think that this should not be accessible from a usual ingame script.
     
    #17
  18. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,085
    Likes Received:
    731
    I will implement an access when I'm back from vacation.
     
    #18
    tachyon likes this.
  19. tachyon

    tachyon Commander

    Joined:
    Aug 12, 2015
    Messages:
    92
    Likes Received:
    134
    Another suggestion for your post-vacation-time:D: Would it be possible to add some kind of dictionary that allows to store cross-script data or to persist data?
     
    #19
    shadowiviper likes this.
  20. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,085
    Likes Received:
    731
    It exists a "PersistedData" but at the moment it's only accessible from C# scripts in an admin structure I will see to change this.
     
    #20
    shadowiviper and tachyon like this.

Share This Page