[MOD EXT] Empyrion Scripting - Scripts

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

  1. kkin形影

    kkin形影 Ensign

    Joined:
    Oct 17, 2022
    Messages:
    21
    Likes Received:
    0
    Is your problem solved? My server also has this problem.
     
    #821
  2. meigrafd

    meigrafd Ensign

    Joined:
    Jan 23, 2024
    Messages:
    6
    Likes Received:
    0
    downgrading to EGS v12.0.1 solved it for me.
    downgrading to v12.0.1 solved it for us.
     
    #822
  3. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,015
    Likes Received:
    712
    @meigrafd @kkin形影
    I have just tested it on a fresh installation and everything works with the current version.
    Maybe you should delete the "EGS\Saves\Games\[Savegamenameame]\Mods\EmpyrionScripting\Configuration.json"
    so that it is recreated with the current default settings.
    There may be incompatible entries in your settings
     
    #823
  4. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,015
    Likes Received:
    712
    #824
    Last edited: Feb 24, 2024
    The_Hammander likes this.
  5. Turist[40k]

    Turist[40k] Ensign

    Joined:
    Oct 4, 2020
    Messages:
    12
    Likes Received:
    1
    Hello

    would appreciate some help with scripting syntaxis here. Modified EnemyScan here (nevermind that all entities are listed, that`s for gebug purposes).

    Code:
    {{set 'AntennaIds' '1365,1877,1878,1879,1880,1880,1881,1882,1883,1884,262'}}
     
    {{#devices @root.E.S '40KScn2=*'}}
    {{#each .}}
    {{#split CustomName '='}}
    {{set 'RadarPos' .1}}
    {{#if .2}}
    {{set 'Size' .2}}
    {{else}}
    {{set 'Size' '100%'}}
    {{/if}}
    {{#if .3}}
    {{set 'ScrollLines' .3}}
    {{else}}
    {{set 'ScrollLines' '100'}}
    {{/if}}
    {{/split}}
    {{#settextblock .}}
    <size={{@root.Data.Size}}>--- 20K scan | {{@root.E.Name}} [{{@root.E.Id}}]: {{@root.E.Pos}} ---
    Entity<indent=27%>Faction</indent><indent=40%>X</indent><indent=55%>Y</indent><indent=70%>Z</indent><indent=85%>Distance</indent>
    {{#split @root.Data.RadarPos ','}}
    {{#block @root.E.S .0 .1 .2}}
    {{#test Id in @root.Data.AntennaIds}}
    {{#scroll @root.Data.ScrollLines 1 @root.Data.ScrollLines}}
    {{#entitiesbyname '*' 20000 'BA,CV,SV,HV,EnemyDrone,TroopTransport,Proxy'}}
    {{#sortedeach . 'Distance'}}<color=grey>{{#test Faction.Group in 'Alien,Zirax,Kriel,Pirates,Admin'}}<color=red>{{/test}}{{#test Faction.Group in 'Talon,Polaris,UCH'}}<color=green>{{/test}}{{#test Faction.Group in 'NoFaction'}}<color=yellow>{{/test}}
    {{~format (i18n Name) '{0,-20} '}}<indent=27%>[
    {{~Faction.Group}}]<indent=40%></indent>
    {{~format Pos.X '{0,6:00000} '}}</indent><indent=55%>
    {{~format Pos.Y '{0,6:00000} '}}</indent><indent=70%>
    {{~format Pos.Z '{0,6:00000} '}}</indent><indent=85%>
    {{~format Distance '△={0:00000}'}}</indent></color>
    {{/sortedeach}}
    {{/entitiesbyname}}
    {{/scroll}}
    {{else}}
    No Antenna found at {{@root.Data.RadarPos}}
     
    {{#split @root.Data.AntennaIds ','}}
    {{#each .}}
    ({{.}}) {{i18n . 'English'}}
    {{/each}}
    {{/split}}
    {{/test}}
    {{/block}}
    {{/split}}
    
    <color=#88888840>Time on board: {{datetime}}
    </color>
    </size>
    {{/settextblock}}
    {{/each}}
    {{/devices}}
    questions:
    1) format Pos.X '{0,6:00000} ' - that is just the workaround to solve that i was not able to make all coordinates be formatted like "take all 6 symbol places without leading zeroes, aligned right". How to do it correctly?

    2) tried to add math to {{~format Distance '△={0:00000}'}}</indent></color> to convert from meters to kilometers but have failed miserably. Is it possible to do "inline" at all or should i go like was shown here https://empyriononline.com/threads/mod-ext-empyrion-scripting-scripts.92458/page-39#post-464424 ?
    It seems to be impossible to do with custom formatting, is it correct that format string ishould be composed according to this https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings ?
     
    #825
  6. Turist[40k]

    Turist[40k] Ensign

    Joined:
    Oct 4, 2020
    Messages:
    12
    Likes Received:
    1
    Nice idea, thanks. I tried it and it generally works, tried to modify it a little bit but...

    1) There is very inconstant and significant delay between when i click "F" (i have used access terminal block instead of pressure plate/sensor) and when dialog box appears, it may be required to press button multiple times. I suppose this is because the signal is like on/off and it have to align in time with the script which is being run at the intervals. Probably adding signal logic with latch/and delayed reset could be the way around this?

    2) i`m clearly not getting something here but this {{~Entities.Faction.Group}} does not return anything, but every entity should have those, isn`t it?

    3) after the dialog has fired the result appears with 2 empty rows at the top (above the header), after the script updates and does this part
    {{CacheData.PFQRT}}
    {{CacheData.PFQR}}
    everything is fine and the text begins at 1st row

    is it correct that:
    3.1) #dialog block is carried out only once on each activation of the "ShowDialog" signal
    3.2) the whole script runs always in the background (unless LCD is switched off) and only last part with fetching two cached blocks is executed

    Code:
    {{#dialog 'ShowDialog'
    'Discovered POIs Registry Search'
    'Type part of the name in Search Box below and click "Search" to proceed'
    'Search'
    '0' '2' '200'
    ''
    'true'
    ''
    'Input search item...'
    }}
    {{#ok PlayerInput}}
    {{set 'QT' (concat ' *' PlayerInput '*')}}
    {{set 'Q' (concat 'Entities.name LIKE "%' PlayerInput '%"')}}
    {{setcacheblock 'PFQRT'}}DiscoveredPOIs {{@root.Data.QT}}:{{/setcacheblock}}
    {{#setcacheblock 'PFQR'}}
    {{#db 'DiscoveredPOIs' 99 'Entities.name asc' @root.Data.Q}}
    {{#each .}}
    {{~SolarSystems.name}}:
    {{~Playfields.name}}:
    {{~Entities.name}}
    {{~Entities.Faction.Group}}
    {{/each}}
    {{/db}}
    {{/setcacheblock}}
    {{else}}
    {{setcacheblock 'PFQRT'}}DiscoveredPOIs <no input>:{{/setcacheblock}}
    {{setcacheblock 'PFQR'}}<empty>{{/setcacheblock}}
    {{/ok}}
    {{/dialog}}
    {{CacheData.PFQRT}}
    {{CacheData.PFQR}}
    
     
    #826
  7. The_Hammander

    The_Hammander Ensign

    Joined:
    Feb 20, 2024
    Messages:
    1
    Likes Received:
    0
    Hello! I've spent the last few weeks trying to understand how to write/tweak these scripts, and I just can't do it. I found a base by -=5!nN|05=- that has what I'm looking for, but I believe the IDs are outdated, so it doesn't work, but I can't fully tell what's happening in the code, so I don't know how to update it. Link to the base: https://steamcommunity.com/sharedfiles/filedetails/?id=2213059019

    The following is what I believe to be the main sorting script, but I don't understand how it supposed to work initially, aside from starting in SubStorage? Though the script won't move any items around currently, tried deposting in a few different boxes and nothing happened

    Code:
    {{fontsize 3}}
    {{#items E.S 'SubStorage'}}
    {{#devices @root.E.S 'Box-*'}}
    {{#each .}}
    {{#split CustomName '-'}}
    {{#test Length eq '3'}}
    {{#split .2 '/'}}
    {{set 'Ids' (concat . ',')}}
    {{/split}}
    {{#test ../../../../Id 'in' @root.Data.Ids}}
    {{#move ../../../../../.
    @root.E.S ../../../CustomName}}
    From {{Source}}
    to {{Destination}}
     at {{datetime 'dd. u\m HH:mm:ss'}}:
     - {{format Count '{0,5}'}} :
    {{~Name}}
    {{/move}}
    {{/test}}
    {{/test}}
    {{/split}}
    {{/each}}
    {{/devices}}
    {{/items}}
    [​IMG]
    [​IMG]
    [​IMG]

    And then there's a 2nd script that I think takes X amount of certain material IDs and moves them into a main crafting box, but either these are old IDs or I couldn't find any that matched as far as base crafting components go:

    Code:
    {{set 'first' '1'}}
    {{#items E.S 'Box-*'}}
    {{set 'MaxCount' '1998'}}
    {{#test Id 'eq' 2373}}
    {{set 'MaxCount' '0'}}
    {{/test}}
    {{#test Id 'eq' 2396}}
    {{set 'MaxCount' '600'}}
    {{/test}}
    {{#test Id in '2294,2128'}}
    {{set 'MaxCount' '100'}}
    {{/test}}
    {{#test Id in '2356,2375,2382,2385,2393,2403,2416,2426,2427,2428,2430,2435,2436,2437,2438,2439,2441'}}
    {{set 'MaxCount' '0'}}
    {{/test}}
    {{move this @root.E.S 'MainStorage' @root.Data.MaxCount}}
    {{#if @root.Data.first}}
    {{set 'first' ''}}
    To {{Destination}} at {{datetime 'dd. u\m HH:mm:ss'}}:
    {{/if}}
    {{~set 'moved' '1'}}
    {{format Count '{0,5}'}} : {{Name}}
    {{/move}}
    {{/items}}
    {{#if @root.Data.moved}}
    -------------------------------------------
    {{/if}}
    [​IMG]

    [​IMG]


    Any help would be greatly appreciated!

    Edit: Added photos of the script screens & outputs
     
    #827
    Last edited: Mar 11, 2024
  8. Grandirus

    Grandirus Commander

    Joined:
    Jan 24, 2017
    Messages:
    43
    Likes Received:
    131
    Don't know if it stills valid but, what's the codes for CV Weapons?
    I'm trying to find by myself but with no luck.
     
    #828
  9. Clocked

    Clocked Ensign

    Joined:
    May 13, 2024
    Messages:
    2
    Likes Received:
    1
    Hello
    I have been working on this registry search script it does work however on a MP server I'm not sure what factions discovered POI it is pulling from because it is not mine.
    Any feedback on how I can get it to pull from myself or my factions discovered POIs would be greatly appreciated.

    <size=2><align=center><color=#0de805>
    {{#scroll 500 1}}
    {{#db 'DiscoveredPOIs' 500 'SolarSystems.name asc' 'Entities.name like "%Hydroflux%" ' @root.E.Faction.Id }}
    {{#each .}}
    {{~SolarSystems.name}}->
    {{~Playfields.name}}->
    {{~Entities.name}}
    {{/each}}
    {{/db}}
    {{/scroll}}
     
    #829
  10. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,015
    Likes Received:
    712
    A 100 has accidentally slipped into the SQL instead of the fraction.
    You can easily fix this by replacing the 100 in the "Configuration.json" of the ScriptingMod in the savegame in the SQL of "DiscoveredPOIs" with @FactionId

    https://github.com/GitHub-TC/EmpyrionScripting/releases/tag/13.0.3
     
    #830
  11. Clocked

    Clocked Ensign

    Joined:
    May 13, 2024
    Messages:
    2
    Likes Received:
    1
    Thank you so much! Appreciate your assistance and your mod is the most amazing piece of work ever!
     
    #831
    ASTIC likes this.
  12. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    I recently ran into the issue that my script runs fine with the actual version of Empyrion Scripting at singleplayer, but at multiplayer the server not even boot.

    I activated all debugging and logging options in the Empyrion Scripting settings but I cannot find a log file anywhere. Am I looking at the wrong place or do my script produce such an error, that not even an logfile can be created?
     
    #832
  13. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,015
    Likes Received:
    712
    What about the logs (Dedicated & Playfield) in [EGS]\Logs\NNNN maybe they give hints - maybe you can send them to me via PM
     
    #833
  14. ctthespian

    ctthespian Ensign

    Joined:
    Jul 13, 2022
    Messages:
    6
    Likes Received:
    0
    How do you disable the costs?
     
    #834
  15. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,015
    Likes Received:
    712
    set the "Amount" to 0
    EGS\Saves\Games\[Savegamename]\Mods\EmpyrionScripting\Configuration.json
    Code:
      "DeconstructSalary": {
        "ItemName": "MoneyCard",
        "Amount": 0
      },
      "RecycleSalary": {
        "ItemName": "MoneyCard",
        "Amount": 0
      },
    
     
    #835
  16. ctthespian

    ctthespian Ensign

    Joined:
    Jul 13, 2022
    Messages:
    6
    Likes Received:
    0
    I assumed this would be the case. When I tried that change I got a divide by 0 when the script tried to run the destruct script.
     
    #836
  17. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,015
    Likes Received:
    712
    #837
  18. SuperFlue

    SuperFlue Ensign

    Joined:
    Friday
    Messages:
    1
    Likes Received:
    1
    Taking inspiration from some of the work done by MrGReaper, here should be a fairly robust sorting script.

    https://gist.github.com/SuperFlue/d596c0eaaa40867bfd34c292458e2281

    This script has predefined desitnations in the script. But you can also make overrides using LCDs if wanted.
    Mostly done some basic testing, but stress-testing is probably needed to find the edge cases.
    Add to your save script folder and rename a LCD to "SuperSort-main" and it should "just work".

    Make a LCD with the name "SuperSort-config" (or "SuperSort-config01", "SuperSort-config02" and so on) and it should come with a help text on how to use the LCD override.
    Multiple config screens can be used depending on need.
    You could also name the screens depending on which overrides you are using there like "SuperSort-config ores".

    EDIT 22.06 (to not doublepost):
    Script is updated now to be based on tags.
    Start your container with the prefix "Sort-" and then whatever tags you want for the container to fill with.
    Generally the Github Gist should always contain the latest version of this, and I'll be improving it here and there over time.

    EDIT2:
    Apparently I messed up the tagging at first, didn't realize that the cointainer search did not accept wildcards in the middle of the name (which is entirely resonable).
    So had to rewrite to handle name comparisons in the script itself.

    Code:
    // Automatic sorting script for Empyrion by SuperFlue
    // This script will automaticall sort items to various containers based on tags
    // Needs https://github.com/GitHub-TC/EmpyrionScripting to work
    // Place in "Empyrion - Galactic Survival\Saves\Games\<SaveName>\Mods\EmpyrionScripting\Scripts
    // Updates will generally be available at https://gist.github.com/SuperFlue/d596c0eaaa40867bfd34c292458e2281
    
    using Eleon.Modding;
    using EmpyrionScripting.Interface;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    
    internal class ModMain
    {
        // Adjust these to your preferences
        // The prefix is used to include the storage in the sorting system
        static string validPrefix = "Sort-";
        // This is the name of the input storage where things will be sorted out off
        static string inputStorageName = "Input";
        // This is the box where anything that did not have a more specific sorting ends up, or if other storages are full
        static string unsortedOutput = "Dumpbox";
    
    
        // These lists allows you to define some static tag overrides for items
        // There is one for item names, and one for item-IDs
        // Moving is based on "first hit wins" so items are moved based on which rule they hit first
        // The name list is evaluated before the ID list
        // There is also an override that can be used for specific entities (ie. different bases).
        // Create a LCD with the name "SuperSort-config" to configure that
        // The overrides defined on the LCD wins over any other configuration
        static List<(string name, string storage)> overrideTargetsName = new List<(string name, string storage)>
        {
            ("PromethiumOre", "Crafting" ),
            ("PentaxidOre", "Crafting" ),
        };
        static List<(int id, string storage)> overrideTargetsID = new List<(int id, string storage)>
        {
            (4159, "Fuel"),
        };
    
        // This is the generic mappings of itemgroups to tags, these are based on the item groups that are defined in the Configuration.json for the scripting mod.
        // We duplicate some lines her allowing for more specific storage to be used before less specific ex. Small Devices goes into DevicesS before the general Devices container
        static List<(string type, string storage)> genericTargets = new List<(string type, string storage)>
            {
                ("OreFurnace", "Furnace"),
                ("Ore", "Ore"),
                ("Ingot", "Crafting"),
                ("Medic", "Medical"),
                ("Food", "Food"),
                ("Sprout", "Plant"),
                ("Tools", "Tools"),
                ("Fuel", "Fuel" ),
    
                ("ArmorMod", "Boosts"),
                ("BlockL", "BlocksL"),
                ("BlockS", "BlocksS"),
                ("BlockL", "Blocks"),
                ("BlockS", "Blocks"),
    
                ("DeviceL", "DevicesL"),
                ("DeviceS", "DevicesS"),
                ("DeviceL", "Devices"),
                ("DeviceS", "Devices"),
    
                ("WeaponPlayer", "WeaponsP"),
                ("WeaponPlayerEpic", "WeaponsP"),
                ("WeaponPlayerUpgrades", "WeaponsP"),
                ("WeaponHV", "WeaponsS"),
                ("WeaponSV", "WeaponsS"),
                ("WeaponBA", "WeaponsL"),
                ("WeaponCV", "WeaponsL"),
                ("WeaponPlayer", "Weapons"),
                ("WeaponPlayerEpic", "Weapons"),
                ("WeaponPlayerUpgrades", "Weapons"),
                ("WeaponHV", "Weapons"),
                ("WeaponSV", "Weapons"),
                ("WeaponBA",    "Weapons"),
                ("WeaponCV", "Weapons"),
    
                ("AmmoPlayer", "AmmoP"),
                ("AmmoHV", "AmmoS"),
                ("AmmoSV", "AmmoS"),
                ("AmmoCV", "AmmoL"),
                ("AmmoBA", "AmmoL"),
                ("AmmoAllEnergy", "Ammo"),
                ("AmmoAllProjectile", "Ammo"),
                ("AmmoAllRocket", "Ammo"),
    
                ("Armor", "Armor"),
                ("Deconstruct", "Deconstruct"),
                ("Deco", "Deco"),
                ("DataPads", "Datapads"),
    
                ("Components", "Crafting"),
                ("EdenComponents", "Crafting"),
                ("Ingredient", "Crafting"),
                ("IngredientBasic", "Crafting"),
                ("IngredientExtra", "Crafting"),
                ("IngredientExtraMod", "Crafting")
            };
    
        // The name of the main screen, this is the name of the LCD that activates the script on the entity
        static string mainScreenName = "SuperSort-main";
        // This is the name of the config screens where you define custom targets for items
        // Needs to have a * wildcard at the end of the name to be able to pic up multiple LCDs
        static string configScreensName = "SuperSort-config*";
        static string debugScreenName = "SuperSort-debug";
    
    
        // There should no be a need to modify stuff below here generally
        static StringBuilder lcdInfoStringBuilder = new StringBuilder();
        static StringBuilder lcdConfigStringBuilder = new StringBuilder();
        static List<(int id, string storage)> customOverrideTargets = new List<(int id, string storage)>();
        static bool doneFirstRun = false;
        static string lcdInfo;
        static List<IItemsData> dumpStorageItems = new List<IItemsData>();
        static List<string> allValidDeviceNames = new List<string>();
        // Stopwatch to keep track of runtime
        static Stopwatch stopWatch = new Stopwatch();
        static string helpString = @"<size=50%># Use this screen to set up custom sorting
    # Use the format 'ITEMID = CUSTOMTAG'
    # For example '4159 = BioFuel' to move Bio Fuel to containers tagged with 'BioFuel'
    # Lines starting with # will be ignored by the script
    # This help text can be safely removed, it will be re-added if LCD is empty
    # You can use multiple LCDs if needed";
    
        public static void Main(IScriptModData rootObject)
        {
            // Make sure to exit out early if we dont need to do anything
            if (!(rootObject is IScriptSaveGameRootData root)) return;
            if (root.E.Faction.Id == 0) return;
    
            // Make sure there is an LCD that begins with the SuperSort keyword before we run the rest of the script
            var superSortMainLCD = root.CsRoot.GetDevices<ILcd>(root.E.S, mainScreenName);
            var superSortDebugScreen = root.CsRoot.GetDevices<ILcd>(root.E.S, debugScreenName);
            if (superSortMainLCD.Length == 0)
            {
                return;
            }
            stopWatch.Restart();
            if (!doneFirstRun)
            {
                WriteToDebug(superSortDebugScreen, "--Init " + DateTime.Now.ToString("s"), true);
                // Lowercase all names
                validPrefix = validPrefix.ToLower();
                inputStorageName = inputStorageName.ToLower();
                unsortedOutput = unsortedOutput.ToLower();
    
                // Need to use temp variables and Select to lowercase the storage names
                var temp1 = overrideTargetsID.Select(x => (x.id, x.storage = x.storage.ToLower())).ToList();
                overrideTargetsID.Clear();
                overrideTargetsID.AddRange(temp1);
    
                var temp2 = genericTargets.Select(x => (x.type, x.storage = x.storage.ToLower())).ToList();
                genericTargets.Clear();
                genericTargets.AddRange(temp2);
    
                var temp3 = overrideTargetsName.Select(x => (x.name, x.storage = x.storage.ToLower())).ToList();
                overrideTargetsName.Clear();
                overrideTargetsName.AddRange(temp3);
            }
           
            allValidDeviceNames.Clear();
            allValidDeviceNames.AddRange(root.E.S.AllCustomDeviceNames.Select(s => s.ToLower()).Where(s => s.StartsWith(validPrefix)).ToList());
            // Get the items to move
            dumpStorageItems.Clear();
            foreach (var deviceName in allValidDeviceNames.Where(s => s.Contains(inputStorageName)))
            {
                dumpStorageItems.AddRange(root.CsRoot.Items(root.E.S, deviceName));
            }
    
            // Get the LCDs with the config keyword and proccess these if they exists
            var superSortConfigDevices = root.CsRoot.Devices(root.E.S, configScreensName);
    
            customOverrideTargets.Clear();
            if (superSortConfigDevices.Length != 0)
            {
                lcdConfigStringBuilder.Clear();
                var superSortConfigLCD = root.CsRoot.GetDevices<ILcd>(superSortConfigDevices);
                foreach (var confLCD in superSortConfigLCD)
                {
                    var currentstring = confLCD.GetText();
                    if (currentstring.Length == 0)
                    {
                        confLCD.SetText(helpString);
                    }
                    else if (currentstring == "Enter text here...")
                    {
                        confLCD.SetText(helpString);
                    }
                    else
                    {
                        _ = lcdConfigStringBuilder.AppendLine(currentstring);
                    }
                }
    
                _ = lcdConfigStringBuilder.Replace("<size=50%>", "");
                var lcdStrings = SplitToLines(lcdConfigStringBuilder.ToString()).Where(s => !s.StartsWith("#") && !string.IsNullOrWhiteSpace(s)).ToArray();
                foreach (var configLine in lcdStrings)
                {
                    // Simple way to just make there are somewhat resonable input in the override dictonary
                    try
                    {
                        var splitline = configLine.Split('=');
    
                        if (!string.IsNullOrWhiteSpace(splitline[1]) && int.TryParse(splitline[0], out int itemid))
                        {
                            if (root.ConfigEcfAccess.IdBlockMapping.ContainsKey(itemid))
                            {
                                customOverrideTargets.Add((itemid, splitline[1].Trim().ToLower()));
                            }
                        }
                    }
                    catch (Exception ex)
                    {
    
                    }
                }
            }
    
            //if there is no items to move we exit
            if (dumpStorageItems.Count <= 0)
            {
                stopWatch.Stop();
                return;
            }
    
            foreach (var item in dumpStorageItems)
            {
                bool moved = false;
    
                // Move items on the customOverrideTargets list
                if (!moved)
                {
                    foreach (var overrideTargetID in customOverrideTargets)
                    {
                        if (overrideTargetID.id == item.Id)
                        {
                            moved = TryMoveItem(root, allValidDeviceNames, item, moved, overrideTargetID.storage);
                            if (moved) { break; }
                        }
                    }
                }
                // Move items on the overrideTargetsName list
                if (!moved)
                {
                    foreach (var overrideTargetName in overrideTargetsName)
                    {
                        if (overrideTargetName.name == item.Name)
                        {
                            moved = TryMoveItem(root, allValidDeviceNames, item, moved, overrideTargetName.storage);
                            if (moved) { break; }
                        }
                    }
                }
    
                // Move items on the overrideTargetsID list
                if (!moved)
                {
                    foreach (var overrideTargetID in overrideTargetsID)
                    {
                        if (overrideTargetID.id == item.Id)
                        {
                            moved = TryMoveItem(root, allValidDeviceNames, item, moved, overrideTargetID.storage);
                            if (moved) { break; }
                        }
                    }
                }
                // Move items based on the generic lists
                if (!moved)
                {
                    foreach (var genericTarget in genericTargets)
                    {
                        if (root.CsRoot.Root.PlainIds[genericTarget.type].Contains(item.Key))
                        {
                            moved = TryMoveItem(root, allValidDeviceNames, item, moved, genericTarget.storage);
                            if (moved) { break; }
                        }
                    }
                }
    
                // Catch anything uncategorized/not moved
                if (!moved)
                {
                    moved = TryMoveItem(root, allValidDeviceNames, item, moved, unsortedOutput);
                }
            }
    
            // Create our output data
            _ = lcdInfoStringBuilder.AppendLine("--- Finished sorting at " + DateTime.Now.ToString("s") + " runtime: " + stopWatch.Elapsed.TotalSeconds.ToString("0.0000") + "s ---");
            _ = lcdInfoStringBuilder.Append(superSortMainLCD.First().GetText().Trim());
            _ = lcdInfoStringBuilder.Replace("<size=50%>", "");
            _ = lcdInfoStringBuilder.Insert(0, "<size=50%>");
    
            stopWatch.Stop();
            lcdInfo = lcdInfoStringBuilder.ToString();
            lcdInfoStringBuilder.Clear();
    
            // Print to all main LCDs
            foreach (ILcd lcd in superSortMainLCD)
            {
                lcd.SetText(lcdInfo);
            }
    
            if (!doneFirstRun)
            {
                doneFirstRun = true;
            }
           
        }
    
        private static bool TryMoveItem(IScriptSaveGameRootData root, IEnumerable<string> allValidDeviceNames, IItemsData item, bool moved, string storage, ILcd[] debugScreens = null)
        {
            storage = storage.ToLower();
            if (null != debugScreens)
            {
                WriteToDebug(debugScreens, "Trying to move " + item.Name + " to " + storage);
                WriteToDebug(debugScreens, "Device list: " + string.Join(", ", allValidDeviceNames) + "\n");
                WriteToDebug(debugScreens, "Valid storage: " + string.Join("\n", allValidDeviceNames.Where(s => s.Contains(storage))) + "\n" );
            }
            foreach (var deviceName in allValidDeviceNames.Where(s => s.Contains(storage)))
            {
                var moveResult = root.CsRoot.Move(item, root.E.S, deviceName);
                if (null != debugScreens)
                {
                    WriteToDebug(debugScreens, "Tried to move " + item.Name + " to " + deviceName + "\nMove result is " + moveResult.Count);
                }
                if (moveResult.Count != 0)
                {
                    AppendItemMoveInfoString(lcdInfoStringBuilder, moveResult, item.Name);
                    moved = true;
                    break;
                }
            }
            return moved;
        }
    
        //Debug screen helper
        private static void WriteToDebug(ILcd[] debugLCDs, string debugline, bool clear = false)
        {
            string currentText = string.Empty;
            foreach (ILcd lcd in debugLCDs)
            {
                currentText = lcd.GetText();
                if (currentText == "clear" || clear)
                {
                    lcd.SetText(debugline);
                }
                else
                {
                    lcd.SetText(debugline + "\n" + currentText);
                }
            }
        }
    
        //Helper to split the string from an LCD
        private static IEnumerable<string> SplitToLines(string input)
        {
            if (input == null)
            {
                yield break;
            }
    
            using (System.IO.StringReader reader = new System.IO.StringReader(input))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    yield return line;
                }
            }
        }
    
        // Helper for writing infostrings for moving and to make it consistent
        private static void AppendItemMoveInfoString(StringBuilder lcdStringBuilder, IList<IItemMoveInfo> moveInfo, string ItemName = null)
        {
            string itemInfoTextTemplate = "Moved {2}x '" + ItemName + "' to '{1}' (ID: {0})";
            foreach (var item in moveInfo)
            {
                _ = lcdStringBuilder.AppendLine(string.Format(itemInfoTextTemplate, item.Id, item.Destination, item.Count));
                if (!string.IsNullOrWhiteSpace(item.Error))
                {
                    _ = lcdStringBuilder.AppendLine($"Failed to move {item.Id}, error: {item.Error}");
                }
            }
        }
    }
    
     
    #838
    Last edited: Jun 22, 2024 at 8:40 PM
    ASTIC likes this.
  19. ctthespian

    ctthespian Ensign

    Joined:
    Jul 13, 2022
    Messages:
    6
    Likes Received:
    0
    So I did try this change with the 13.0.5 version, clean install, and still get the following error for the deconstruct script. {{deconstruct}} error Attempted to divide by zero.
    Tried this is multiple scenarios server, single. Noticed in the single player there is a configuration.json under Saves\Games\NewGame_4\Mods\EmpyrionScripting and that despite deleting this EmpyrionScripting folder and making changes below to the configuration.json in the Empyrion - Galactic Survival\Content\Mods\EmpyrionScripting location the one in the save game was created with the Salary values as default, ie 10 etc.

    Code:
      "GardenerSalary": {
        "ItemName": "MoneyCard",
        "Amount": 0
      },
      "DeconstructSalary": {
        "ItemName": "MoneyCard",
        "Amount": 0
      },
      "RecycleSalary": {
        "ItemName": "MoneyCard",
        "Amount": 0
      },
     
    #839
  20. ctthespian

    ctthespian Ensign

    Joined:
    Jul 13, 2022
    Messages:
    6
    Likes Received:
    0
    Looking at Luke's Dynamic Sorting from a couple of years ago. I like it. Noticed that there can be some hitching or lag when running but the switch solution helps with that. Looking for help with this issue where it doesn't seem to work where containers have color label hex codes in the target box names. Is there a way to support that?
    Also another wish is could this be run on one base vs another base's storage. Thinking of this huge container storage made by Don2k7 that has a huge number of 640k storage controllers. It doesn't run power so running on a production base against that storage would be helpful.

    Code:
    {{fontsize 2}}{{~set 'F' '1'}}{{#getswitch @root.E.S 'sw_AS'}}{{#if SwitchState}}
    {{~set 'I' 'Input'}}{{set 'CI' 'CInput'}}{{set 'O' 'Output'}}{{set 'U' 'TOBESORT'}}
    {{~devices @root.E.S 'SorterDB'}}{{set 'DB' .0}}{{gettext .0}}{{split . '\n'}}{{set 'C' .}}{{/split}}{{/gettext}}{{/devices}}
    {{~#devicesoftype @root.E.S 'Container'}}{{#each .}}{{if CustomName}}{{set 'T' ''}}{{set 'M' 0}}
    {{#split CustomName '-'}}{{set 'n' .}}{{/split}}
    {{~#test @root.data.n.0 in (concat @root.Data.I ',' @root.Data.O ',' @root.Data.U)}}
    {{~#items @root.E.S CustomName}}{{set 'G' @root.data.U}}
    {{#each @root.data.C}}{{#split . ':'}}{{~#test ../../Id in .1}}{{~#test @root.data.CI neq .0}}{{set 'G' .0}}{{/test}}{{/test}}{{/split}}{{/each}}
    {{~#test ../CustomName neq @root.Data.G}}
    {{~move this @root.E.S (concat @root.Data.G '*')}}{{set 'M' 1}}
    {{set 'T' (concat @root.data.T '
    ' ../Name ' - '  Count '<indent=55%>❲' Source ' ➤ ' Destination '❳</indent>')}}
    {{/move}}{{/test}}{{/items}}{{else}}{{set 'x' ''}}
    {{~#each @root.Data.C}}{{#split . ':'}}{{#test @root.data.n.0 eq .0}}{{set 'x' .1}}{{/test}}{{/split}}{{/each}}
    {{~items @root.E.S CustomName}}{{#test Id in @root.data.x}}{{else}}{{set 'x' (concat @root.data.x Id ',')}}{{/test}}
    {{~#test Id in @root.data.CID}}
    {{~move this @root.E.S (concat @root.Data.CI '*') 50}}{{set 'M' 1}}
    {{set 'T' (concat @root.data.T '
    ' ../Name ' - '  Count '<indent=55%>❲' Source ' ➤ ' Destination '❳</indent>')}}
    {{/move}}{{/test}}{{/test}}{{/items}}
    {{~#if @root.data.x}}{{#if @root.data.n.1}}{{else}}{{set 'D' (concat @root.data.D @root.data.n.0 ':' @root.data.x "
    ")}}{{/if}}{{/if}}{{#test @root.data.n.0 eq @root.data.CI}}{{set 'CID' @root.data.x}}{{/test}}{{/test}}
    {{#if @root.data.M}}
    <align=center><size=120%>Transfer - {{datetime 'HH:mm'}}</size></align>
    {{@root.data.T}}
    <align=center><size=4>{{bar 1 0 1 10 '╼╾'}}</size></align>
    {{/if}}{{/if}}{{/each}}{{/devicesoftype}}
    {{settext @root.Data.DB @root.Data.D}}{{/if}}{{/getswitch}}
     
    #840

Share This Page