Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

Closing door then turning it off

Discussion in 'Programming (In-game)' started by Fiddi, Sep 22, 2016.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Fiddi Apprentice Engineer

    Messages:
    101
    Hello,

    I have a script which (eventually) will control airlocks on my ships and stations, but I have come across a problem. As the title suggest, I want to close the doors and then when they are closed, lock them until (de)pressurization have been completed.
    Code:
    void Main(string argument)
    {
        string[] keywords = argument.Split(' ');
        switch (keywords[0])
        {
            case "Depressurize" :
                if (keywords[1] == "Begin")
                {
                    DepressurizationBegin(keywords[2]);
                }
                else
                {
                    DepressurizationDone(keywords[2]);
                }
            break;
            case "Pressurize" :
                if (keywords[1] == "Begin")
                {
                    PressurizationBegin(keywords[2]);
                }
                else
                {
                    PressurizationDone(keywords[2]);
                }
            break;
        }
    }
    public void DepressurizationBegin(string airlockTag)
    {
    	List<IMyTerminalBlock> doors = new List<IMyTerminalBlock>();
    	GridTerminalSystem.GetBlocksOfType<IMyDoor>(doors);
    	GridTerminalSystem.SearchBlocksOfName(airlockTag, doors);
    	for (int i = 0; i < doors.Count; i++)
        {
            doors[i].ApplyAction("Open_Off");
        }
    }
    public void DepressurizationDone(string airlockTag)
    {
    }
    public void PressurizationBegin(string airlockTag)
    {
    }
    public void PressurizationDone(string airlockTag)
    {
    }
    Preferrably as simple as possible, I have some programming experience but not a huge amount in C#. Thanks!
     
  2. Phoera Senior Engineer

    Messages:
    1,713
    try use OpenRatio, but don't forget to cast to IMyDoor interface.
     
  3. Malware Master Engineer

    Messages:
    9,664
    You can't without running your script multiple times via a timer. The sliding door is particularily finicky because you can't enable and open it in the same tick. You have to first enable, then wait a tick, then open.

    Below I have written a tutorial on a simple and powerful way to run scripts over multiple ticks with a minimum of effort. It's what I use for my airlock code, which also lock down doors.
    http://forums.keenswh.com/threads/t...ful-state-machine-using-yield-return.7385411/
     
  4. Fiddi Apprentice Engineer

    Messages:
    101
    Yes, thank you I have managed to create a more or less working script. I do have come across a problem, I can pressurize and depressurize fine but only once. I cant switch between them. I have a boolean which won't change when either of the pressurizations are done, which to my mind it should since I told it to.

    Malware, I read that but I don't understand much of it sadly..

    I have my script here, said boolean is called inProgress, which should change to false in the end of the functions "Depressurize" and "Pressurize":

    Code:
            string runState = "";
            string airlock = "";
            bool inProgress = false;
            public void Main(string argument)
            {
                Echo(inProgress.ToString() + " " + airlock + " " + runState);
                if (argument.Length > 0 && !inProgress)
                {
                    string[] keywords = argument.Split('-');
                    if (keywords.Length > 0) airlock = keywords[0]; else Echo("No airlock");
                    if (keywords.Length > 1) runState = keywords[1]; else Echo("No Run State");
                  
                }
    
                if (runState.Contains("Out"))
                {
                    Depressurize(airlock);
                    inProgress = true;
                }
    
                if (runState.Contains("In"))
                {
                    Pressurize(airlock);
                    inProgress = true;
                }
    
            }
    
            public void Depressurize(string airlockTag)
            {
                switch (runState)
                {
                    case "Out":
                        DoorControl(airlockTag + "(Inner)", true, "Out2");
                        break;
                    case "Out2":
                        LightControl(airlockTag, new Color(1.0f, 0.0f, 0.0f), 1f);
                        SoundAlarm(airlockTag, "PlaySound");
                        runState = "Out3";
                        break;
                    case "Out3":
                        SwitchAirVents(airlockTag, false, "Out4");
                        break;
                    case "Out4":
                        DoorControl(airlockTag + "(Outer)", false, "");
                        LightControl(airlockTag + "(Inner)", new Color(1.0f, 0.0f, 0.0f), 0f);
                        LightControl(airlockTag + "(Outer)", new Color(0.0f, 1.0f, 0.0f), 0f);
                        runState = "";
                        airlock = "";
                        inProgress = false;
                        break;
                }
    
            }
    
            public void Pressurize (string airlockTag)
            {
                switch (runState)
                {
                    case "In":
                        DoorControl(airlockTag + "(Outer)", true, "In2");
                        break;
                    case "In2":
                        LightControl(airlockTag, new Color(1.0f, 0.0f, 0.0f), 1f);
                        SoundAlarm(airlockTag, "PlaySound");
                        runState = "In3";
                        break;
                    case "In3":
                        SwitchAirVents(airlockTag, true, "In4");
                        break;
                    case "In4":
                        DoorControl(airlockTag + "(Inner)", false, "");
                        LightControl(airlockTag + "(Inner)", new Color(0.0f, 1.0f, 0.0f), 0f);
                        LightControl(airlockTag + "(Outer)", new Color(1.0f, 0.0f, 0.0f), 0f);
                        runState = "";
                        airlock = "";
                        inProgress = false;
                        break;
                }
            }
          
    
            public void DoorControl(string airlockTag, bool doorClose, string runStateChange)
            {
                List<IMyTerminalBlock> doors = new List<IMyTerminalBlock>();
                GridTerminalSystem.GetBlocksOfType<IMyDoor>(doors);
                for (int i = 0; i < doors.Count; i++)
                {
                    var door = doors[i] as IMyDoor;
                    if (door.CustomName.Contains(airlockTag))
                    {
                        if (doorClose)
                        {
                            door.ApplyAction("OnOff_On");
                            door.ApplyAction("Open_Off");
                            if (door.OpenRatio <= 0)
                            {
                                door.ApplyAction("OnOff_Off");
                                runState = runStateChange;
                            }
                        }
                        else
                        {
                            door.ApplyAction("OnOff_On");
                            door.ApplyAction("Open_On");
                        }
                    }
                }
            }
            public void LightControl(string airlockTag, Color lightColor, float blinkInterval)
            {
                List<IMyTerminalBlock> lights = new List<IMyTerminalBlock>();
                GridTerminalSystem.GetBlocksOfType<IMyInteriorLight>(lights);
                for (int i = 0; i < lights.Count; i++)
                {
                    if (lights[i].CustomName.Contains(airlockTag))
                    {
                        lights[i].ApplyAction("OnOff_On");
                        lights[i].SetValue("Blink Interval", blinkInterval);
                        lights[i].SetValue("Blink Lenght", 10f);
                        lights[i].SetValue("Blink Offset", 0f);
                        lights[i].SetValue("Color", lightColor);
                    }
                }
            }
            public void SoundAlarm(string airlockTag, string PlayStop)
            {
                List<IMyTerminalBlock> soundBlocks = new List<IMyTerminalBlock>();
                GridTerminalSystem.GetBlocksOfType<IMySoundBlock>(soundBlocks);
                for (int i = 0; i < soundBlocks.Count; i++)
                {
                    if (soundBlocks[i].CustomName.Contains(airlockTag))
                    {
                        soundBlocks[i].ApplyAction(PlayStop);
                    }
                }
            }
            public void SwitchAirVents(string airlockTag, bool oxygenIn, string runStateChange)
            {
                List<IMyTerminalBlock> airVents = new List<IMyTerminalBlock>();
                GridTerminalSystem.GetBlocksOfType<IMyAirVent>(airVents);
                for(int i = 0; i < airVents.Count; i++)
                {
                    var airVent = airVents[i] as IMyAirVent;
                    if (airVent.CustomName.Contains(airlockTag))
                    {
                        if (oxygenIn)
                        {
                            airVent.ApplyAction("Depressurize_Off");
                            if (airVent.GetOxygenLevel() >= 0.95f)
                            {
                                runState = runStateChange;
                                SoundAlarm(airlockTag, "StopSound");
                            }
                        }
                        else
                        {
                            airVent.ApplyAction("Depressurize_On");
                            if (airVent.GetOxygenLevel() <= 0f)
                            {
                                runState = runStateChange;
                                SoundAlarm(airlockTag, "StopSound");
                            }
                        }
                    }
                }
            }
     
    Last edited: Sep 23, 2016
  5. Wicorel Senior Engineer

    Messages:
    1,243
    You are setting inProgress to true in main () after the calls to those functions .
     
  6. Fiddi Apprentice Engineer

    Messages:
    101
    Thanks, I've since fixed the problem. But it's weird because it should have changed to false in stage 4 of the (de)pressurization. Is there something with global variables that they can't be changed other than in Main () or was there something else going on?

     
  7. Burillo Junior Engineer

    Messages:
    648
    you have a lot of things to account for when you're writing a script like that :) for example, you will have to force open/close the doors on a timeout because there might be too much/not enough oxygen to pressurize/depressurize the inbetween space. i've solved all of those in my JAMS script, take a look at the code.
     
  8. Wicorel Senior Engineer

    Messages:
    1,243
    The code you posted still has inProgress set to true in main after the calls to pressurize and depressurize
     
  9. Fiddi Apprentice Engineer

    Messages:
    101
    Yes? ... I may misunderstand you, that's intended, when runState is empty they aren't called any longer and inProgress will be set to false. Anyway, it works as it should now.
     
Thread Status:
This last post in this thread was made more than 31 days old.