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.

Need help with airlock script

Discussion in 'Programming Questions and Suggestions' started by Oztopher, Apr 24, 2020.

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

    Messages:
    2
    Hi All,

    2 weeks ago i didn't know what a string was, so a complete beginner here. I read general C# tutorials and some of the tutorials on here, so i have a basic grasp now.

    I started writing my own airlock script being annoyed at using timer blocks to get what i wanted.

    It's an airlock for an asteroid space station so the outer door will always be leading to space. Although in the future would be nice to create an adaptable script for large ships which enter atmospheres. I made it on creative mode lone survivor to get it working before i apply it to my survival game's asteroid space station.

    It's a simple script that consists of 2 doors, an outer and inner, sensors for each door, a block space between the doors for a vent above which connects to a isolated oxygen tank (to prevent it from becoming full).

    Code:
    		public Program()
    		{
    			Runtime.UpdateFrequency = UpdateFrequency.Update100;
    // i've read this can replace the need for a timer block
    		}
    
    		public void Main()
    		{
    			IMyAirtightSlideDoor insideDoor;
    
    			insideDoor = GridTerminalSystem.GetBlockWithName("Sliding Door Inside") as IMyAirtightSlideDoor;
    			if (insideDoor == null)
    			{
    				Echo("Couldn't find block 'Sliding Door Inside'");
    				return;
    			}
    
    			IMyAirtightSlideDoor outsideDoor;
    
    			outsideDoor = GridTerminalSystem.GetBlockWithName("Sliding Door Outside") as IMyAirtightSlideDoor;
    			if (outsideDoor == null)
    			{
    				Echo("Couldn't find block 'Sliding Door Outside'");
    				return;
    			}
    
    			IMySensorBlock sensorInside;
    
    			sensorInside = GridTerminalSystem.GetBlockWithName("Sensor Inside") as IMySensorBlock;
    			if (sensorInside == null)
    			{
    				Echo("Couldn't find block 'Sensor Inside'");
    				return;
    			}
    
    			IMySensorBlock sensorOutside;
    
    			sensorOutside = GridTerminalSystem.GetBlockWithName("Sensor Outside") as IMySensorBlock;
    			if (sensorOutside == null)
    			{
    				Echo("Couldn't find block 'Sensor Outside'");
    				return;
    			}
    
    			IMyAirVent airlockVent;
    
    			airlockVent = GridTerminalSystem.GetBlockWithName("Air Vent Airlock") as IMyAirVent;
    			if (airlockVent == null)
    			{
    				Echo("Couldn't find block 'Air Vent Air Lock'");
    				return;
    			}
    
    			float oxygen = airlockVent.GetOxygenLevel();
    			
    			if (sensorInside.IsActive == true && outsideDoor.Status == DoorStatus.Open)
    			{
    				outsideDoor.CloseDoor();
    			}
    			else if (sensorInside.IsActive == true && !(oxygen == 1) && outsideDoor.Status == DoorStatus.Closed)
    			{
    				airlockVent.Depressurize = false;
    				outsideDoor.Enabled = false;
    			}
    			else if (sensorInside.IsActive == true && (oxygen == 1))
    			{
    				insideDoor.Enabled = true;
    				insideDoor.OpenDoor();
    			}
    
    			if (sensorOutside.IsActive == true && insideDoor.Status == DoorStatus.Open)
    			{
    				insideDoor.CloseDoor();
    			}
    			else if (sensorOutside.IsActive == true && !(oxygen == 0) && insideDoor.Status == DoorStatus.Closed)
    			{
    				airlockVent.Depressurize = true;
    				insideDoor.Enabled = false;
    			}
    			else if (sensorOutside.IsActive == true && (oxygen == 0))
    			{
    				outsideDoor.Enabled = true;
    				outsideDoor.OpenDoor();
    			}
    		}

    Now, it's working perfectly but took me like a days worth of trial and error. I'm aware i probably don't need all the code inside the main method, or i could use a different format such as switch's instead if's, but at the moment - it works.

    I would now like to apply this to my space station, but it has 3 different airlocks, all of the same type. I don't want to have to create 3 or more duplicates of this code just named differently to be able to work in different airlocks.

    My question is - Is it possible to have a single template of code but it applies/references to different 'groups' depending on which airlock i am using?

    For example, if i am trying to open the inner door to 'Airlock 3', the code knows which airlock i am using and applies it accordingly.

    My main idea was that the code would search for groups containing substring 'Airlock' and add them to a list, therefore creating a list of all airlock groups on the grid. The code would then use this list to apply the if statements depending on which airlock i was using. But... i can't quite manage.

    I've tried reading the scripts of other peoples airlock scripts from the workshop but it just seems overly complicated for what i'm looking for and to be honest i don't really follow along with the basic amount of information i'm aware of.

    I've tried messing around with groups and lists but i'm not really getting anywhere hence this post.

    Any help is much appreciated.
     
    Last edited: Apr 24, 2020
  2. Oztopher Trainee Engineer

    Messages:
    2
    Ok... so after playing about and failing again and again, i finally made what i initially imagined. A script which grabs any group with 'Airlock' in it, applies a prefix to the blocks in the group automatically, and then as long as they are named right as per the script requirements... voila.

    Code:
    public Program()
    		{
    			Runtime.UpdateFrequency = UpdateFrequency.Update100;
    		}		 
    		
    		void Airlocks()
    		{			
    			List<IMyBlockGroup> airlockGroups = new List<IMyBlockGroup>();
    			List<IMyBlockGroup> groups = new List<IMyBlockGroup>();
    			GridTerminalSystem.GetBlockGroups(groups);
    			foreach (var group in groups)
    			{
    				if (group.Name.Contains("Airlock"))
    				{
    					airlockGroups.Add(group);
    				}			 
    			}
    			List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
    			foreach (var airlockGroup in airlockGroups)
    			{
    				airlockGroup.GetBlocks(blocks);
    				foreach (var block in blocks)
    				{
    					string prefix = block.CustomName.Insert(0, $"[{airlockGroup.Name}] ");
    					if (!(block.CustomName.Contains(airlockGroup.Name)))
    					{
    						block.CustomName = prefix;
    					}
    				}
    
    				var doorInside = GridTerminalSystem.GetBlockWithName($"[{airlockGroup.Name}] Sliding Door Inside") as IMyAirtightSlideDoor;
    				if (doorInside == null)
    				{
    					Echo("Could not find block 'doorInside'");
    					return;
    				}
    				var doorOutside = GridTerminalSystem.GetBlockWithName($"[{airlockGroup.Name}] Sliding Door Outside") as IMyAirtightSlideDoor;
    				if (doorOutside == null)
    				{
    					Echo("Could not find block 'doorOutside'");
    					return;
    				}
    				var sensorInside = GridTerminalSystem.GetBlockWithName($"[{airlockGroup.Name}] Sensor Inside") as IMySensorBlock;
    				if (sensorInside == null)
    				{
    					Echo("Could not find block 'Sensor Inside'");
    					return;
    				}
    				
    				var sensorOutside = GridTerminalSystem.GetBlockWithName($"[{airlockGroup.Name}] Sensor Outside") as IMySensorBlock;
    				if (sensorOutside == null)
    				{
    					Echo("Could not find block 'sensorOutside'");
    					return;
    				}
    
    				var airlockVent = GridTerminalSystem.GetBlockWithName($"[{airlockGroup.Name}] Air Vent Airlock") as IMyAirVent;
    				if (airlockVent == null)
    				{
    					Echo("Could not find block 'airlockVent'");
    					return;
    				}
    				var oxygen = airlockVent.GetOxygenLevel();
    
    				if (sensorInside.IsActive == true && doorOutside.Status == DoorStatus.Open)
    				{
    					doorOutside.CloseDoor();
    				}
    				else if (sensorInside.IsActive == true && !(oxygen == 1))
    				{
    					airlockVent.Depressurize = false;
    					doorOutside.Enabled = false;
    				}
    				else if (sensorInside.IsActive == true && oxygen == 1)
    				{
    					doorInside.Enabled = true;
    					doorInside.OpenDoor();
    				}
    
    				if (sensorOutside.IsActive == true && doorInside.Status == DoorStatus.Open)
    				{
    					doorInside.CloseDoor();
    				}
    				else if (sensorOutside.IsActive == true && !(oxygen == 0))
    				{
    					airlockVent.Depressurize = true;
    					doorInside.Enabled = false;
    				}
    				else if (sensorOutside.IsActive == true && oxygen == 0)
    				{
    					doorOutside.Enabled = true;
    					doorOutside.OpenDoor();
    				}
    			}
    		}
    
    		public void Main()
    		{
    			Airlocks();
    		}
    Any tips that anyone can give to improve the code, like anywhere i can make it more efficient or better in anyway, will be much appreciated.

    All that needs to be done for this to work:
    - Copy the script into a programmable block.
    - Have an airlock built which has, an inside door, outside door (both sliding doors), a sensor above each door (fields tweaked to your liking, as long as it can be activated outside and inside the door) and an air vent connected to an empty oxygen tank (it can be filled manually from the pressurized connected room to 'jump start' it)
    Naming is as follows (case sensitive):
    - Sliding Door Inside
    - Sliding Door Outside
    - Sensor Inside
    - Sensor Outside
    - Air Vent Airlock

    - Put them in a group, and as long as the group name has 'Airlock' in it, it will automatically prefix the group name with [ ], for example if the group name was 'Airlock Hanger' or even 'Hanger 4 Airlock' it will prefix to each block within the group like - [Hanger 4 Airlock] Sensor Inside.

    and that's it ! I know there are other much more adaptable and better scripts but i really wanted to write my own, hate the feeling of someone spoon feeding me then wiping my mouth at the same time.

    Again, any tips or comments much appreciated.

    What would be cool is to have it automatically detect which block is what and name them accordingly automatically, but not sure how to tell it how to detect which door and sensors are inside or outside... literately just whack the blocks into a group with airlock in the name, and it sorts it out.
     
Thread Status:
This last post in this thread was made more than 31 days old.