// Creates an Irregular Dungeon.
// Worthless Bums 2012.


// Test function for map generation.
function tmap ()
{//echo("tmap()");
	gap();
	zoomCamera(0.4);
	$fogofwar.clear();
}
// Test function to kill squad.
function killSquad ()
{//echo("killSquad()");
	executeSquadMemberDeath(0, true, "[Debug]");
	executeSquadMemberDeath(1, true, "[Debug]");
	executeSquadMemberDeath(2, true, "[Debug]");
	executeSquadMemberDeath(3, true, "[Debug]");
}


// Marks checks the specified tile for connectivity.
function exploreTile (%i, %j)
{//echo("exploreTile()");
	if (%i >= 0	&&
		%i < $mazeDimension	&&
		%j >= 0	&&
		%j < $mazeDimension)
	{
		if (!isObject($mazeRoom[%i, %j])	||		// Not an object means the tile is a floor - space tiles are actual $mazeRoom sprite objects!
			$mazeRoom[%i, %j].status == -3)			// Closed door.
		{
			if ($dummyMaze[%i + 1, %j] == 1	||
				$dummyMaze[%i - 1, %j] == 1	||
				$dummyMaze[%i, %j + 1] == 1	||
				$dummyMaze[%i, %j - 1] == 1)
			{
				$dummyMaze[%i, %j] = 1;
			}
			
			if  ($dummyMaze[%i + 1, %j] != 1)
			{
				exploreTile(%i + 1, %j);
			}
			if  ($dummyMaze[%i - 1, %j] != 1)
			{
				exploreTile(%i - 1, %j);
			}
			if  ($dummyMaze[%i, %j + 1] != 1)
			{
				exploreTile(%i, %j + 1);
			}
			if  ($dummyMaze[%i, %j - 1] != 1)
			{
				exploreTile(%i, %j - 1);
			}
		}
	}
}
// Returns the number of islands.
function getIslandCount ()
{//echo("getIslandCount()");
	%initialMark = false;
	%islandCount = 1;
	$dummyMaze[$mazeDimension, $mazeDimension] = 0;
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			$dummyMaze[%i, %j] = 0;
		}
	}
	
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			if (!isObject($mazeRoom[%i, %j])	||		// Not an object means the tile is a floor - space tiles are actual $mazeRoom sprite objects!
				$mazeRoom[%i, %j].status == -3)			// Closed door.
			{
				if (!%initialMark)
				{
					$dummyMaze[%i, %j] = 1;
					%initialMark = true;
				}
				else
				{
					exploreTile(%i, %j);
				}
			}
		}
	}
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		%rowString = "";
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			%rowString = %rowString @ convertTileToSymbol($dummyMaze[%i, %j]);
		}
		echo(%rowString);
	}
	echo(%islandCount);
	return %islandCount;
}

// Returns the number of disjointed islands.
function getDisjointedIslandCount ()//tmap();echo(getDisjointedIslandCount());
{//echo("getDisjointedIslandCount()");
	%initialMark = false;
	%islandCount = 1;
	$dummyMaze[$mazeDimension, $mazeDimension] = 0;
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			$dummyMaze[%i, %j] = 0;
		}
	}
	
	do {
		%cleanPass = true;
		//echo("===========================================================");
		for (%i = 0; %i < $mazeDimension; %i++)
		{
			for (%j = 0; %j < $mazeDimension; %j++)
			{
				if (!isObject($mazeRoom[%i, %j]))		// Not an object means the tile is a floor - space tiles are actual $mazeRoom sprite objects!
				{
					if (!%initialMark)
					{
						$dummyMaze[%i, %j] = 1;
						%initialMark = true;
					}
					else
					{
						if ($dummyMaze[%i + 1, %j] == 1	||
							$dummyMaze[%i - 1, %j] == 1	||
							$dummyMaze[%i, %j + 1] == 1	||
							$dummyMaze[%i, %j - 1] == 1)
						{
							if ($dummyMaze[%i, %j] != 1)
							{
								%cleanPass = false;
							}
							$dummyMaze[%i, %j] = 1;
							//echo("1" SPC %i SPC %j);
						}
						else
						{
							if ($dummyMaze[%i, %j] != -1)
							{
								%cleanPass = false;
							}
							// Not accurate - just testing for now!
							%islandCount++;
							$dummyMaze[%i, %j] = -1;
							//echo("-1" SPC %i SPC %j);
						}
					}
				}
				else if ($mazeRoom[%i, %j].status == -3	||		// Closed door.
						$mazeRoom[%i, %j].status == -4)			// Opened door.
				{
					if ($dummyMaze[%i, %j] != 1)
					{
						%cleanPass = false;
					}
					$dummyMaze[%i, %j] = 1;
				}
				else if ($mazeRoom[%i, %j].status != -1)			// Not a space tile.
				{
					$dummyMaze[%i, %j] = -1;
				}
				else
				{
					$dummyMaze[%i, %j] = 0;						// Space tile by elimination!
				}
			}
		}
	} while (!%cleanPass)
	/*for (%i = 0; %i < $mazeDimension; %i++)
	{
		%rowString = "";
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			%rowString = %rowString @ convertTileToSymbol(%i, %j);
		}
		echo(%rowString);
	}*/
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		%rowString = "";
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			%rowString = %rowString @ convertTileToSymbol(%j, %i);
		}
		echo(%rowString);
	}
	//echo(%islandCount);
	return %islandCount;
}
function convertTileToSymbol (%i, %j)
{//echo("convertTileToSymbol()");
	%symbol = $dummyMaze[%i, %j];
	
	if ($playerSquad[0].xIndex == %i	&&
		$playerSquad[0].yIndex == %j)
	{
		return "1";
	}
	if ($playerSquad[1].xIndex == %i	&&
		$playerSquad[1].yIndex == %j)
	{
		return "2";
	}
	if ($playerSquad[2].xIndex == %i	&&
		$playerSquad[2].yIndex == %j)
	{
		return "3";
	}
	if ($playerSquad[3].xIndex == %i	&&
		$playerSquad[3].yIndex == %j)
	{
		return "4";
	}
	
	if (%symbol == 0)
	{
		return " ";
	}
	else if (%symbol == 1)
	{
		return ".";
	}
	else if (%symbol == -1)
	{
		return "_";
	}
}

// Displays a randomly generated dungeon layout.
function showRandomDungeonLayout (%failThreshold, %featureProbability, %numberOfRooms, %iterations)
{//echo("showRandomDungeonLayout()");
	// Ranges.
	%startx = 32;
	%starty = 32;
	
	// Null maze room.
	destroyMazeRoom();
	
	// Create a dungeon.
	createIrregularDungeon(%startx, %starty, %failThreshold, %featureProbability, %numberOfRooms, %iterations);
	// Create geomorph dungeon layout.
	//generateGeomorphDatabase();
	
	// Loop through and echo dungeon map.
	for (%y = 0; %y < %starty; %y++)//y in range(starty):
	{
        %line = "";
		
        for (%x = 0; %x < %startx; %x++)//x in range(startx):
		{
            if ($mapArr[%y, %x] == 0)		// Walkable.
			{
                %line = %line @ ".";
			}
            if ($mapArr[%y, %x] == 1)		// Blank.
			{
                %line = %line @ "_";
			}
            if ($mapArr[%y, %x] == 2)		// Wall.
			{
                %line = %line @ "#";
			}
            if ($mapArr[%y, %x] == 3)
			{
				%line = %line @ "^";		// Torch.
			}
			if ($mapArr[%y, %x] == 4	||	// Closed Door.
				$mapArr[%y, %x] == 5)		// Secret Door.
			{
                %line = %line @ "=";
			}
		}
		
        echo(%line);
	}
}

// Displays a randomly generated deck layout.
function showDeckGenerationLayout ()
{//echo("showDeckGenerationLayout()");
	// Ranges.
	%startx = 32;
	%starty = 32;
	
	// Null maze room.
	destroyMazeRoom();
	
	// Create a dungeon.
	//createIrregularDungeon(%startx, %starty, %failThreshold, %featureProbability, %numberOfRooms, %iterations);
	generateShipDeckLevel();
	
	// Loop through and echo dungeon map.
	for (%y = 0; %y < %starty; %y++)//y in range(starty):
	{
        %line = "";
		
        for (%x = 0; %x < %startx; %x++)//x in range(startx):
		{
            if ($mapArr[%y, %x] == 0)		// Walkable.
			{
                %line = %line @ ".";
			}
            if ($mapArr[%y, %x] == 1)		// Blank.
			{
                %line = %line @ "_";
			}
            if ($mapArr[%y, %x] == 2)		// Wall.
			{
                %line = %line @ "#";
			}
            if ($mapArr[%y, %x] == 3)
			{
				%line = %line @ "^";		// Torch.
			}
			if ($mapArr[%y, %x] == 4	||	// Closed Door.
				$mapArr[%y, %x] == 5)		// Secret Door.
			{
                %line = %line @ "=";
			}
		}
		
        echo(%line);
	}
}

function echoCurrentLevel ()
{//echo("echoCurrentLevel()");
	// Ranges.
	%startx = 32;
	%starty = 32;
	
	// Loop through and echo dungeon map.
	for (%y = 0; %y < %starty; %y++)//y in range(starty):
	{
        %line = "";
		
        for (%x = 0; %x < %startx; %x++)//x in range(startx):
		{
            if ($mapArr[%y, %x] == 0)		// Walkable.
			{
                %line = %line @ ".";
			}
            if ($mapArr[%y, %x] == 1)		// Blank.
			{
                %line = %line @ "_";
			}
            if ($mapArr[%y, %x] == 2)		// Wall.
			{
                %line = %line @ "#";
			}
            if ($mapArr[%y, %x] == 3)
			{
				%line = %line @ "^";		// Torch.
			}
			if ($mapArr[%y, %x] == 4	||	// Closed Door.
				$mapArr[%y, %x] == 5)		// Secret Door.
			{
                %line = %line @ "=";
			}
		}
		
        echo(%line);
	}
}

// Helper function to return the proper tileset imagemap from the overworld location.
function getImageFromOverworldLocation ()
{//echo("getImageFromOverworldLocation()");
	switch$ ($overworldLocation)
	{
		case "Command Deck":		return "Sprites:CommandDeckAtlas";
		case "Engineering Deck":	return "Sprites:EngineeringDeckAtlas";
		case "Medical Deck":		return "Sprites:MedicalDeckAtlas";
		case "Armory Deck":			return "Sprites:ArmoryDeckAtlas";
		case "Bridge Deck":			return "Sprites:BridgeDeckAtlas";
		case "Alien Deck":			return "Sprites:AlienDeckAtlas";
	}
}

// Helper function: Returns true iff the tile status is not "blocked".
function tileNotBlocked (%x, %y)
{//echo("tileNotBlocked()");
	// Out of bounds (edge of map) is considered blocked.
	if (%x < 0	||
		%x > 63	||
		%y < 0	||
		%y > 63)
	{//echo(%x SPC %y SPC "Out of range!");
		return false;
	}
	
	// Get the tile status.
	%tileStatus = $mapArr[%y, %x];
	//echo(%x SPC %y SPC "status =" SPC %tileStatus);
	if (%tileStatus != 1	&&	// Outer Space.
		%tileStatus != 2	&&	// Wall.
		%tileStatus != 4)		// Closed Door.
	{
		return false;
	}
	
	return true;
}

// Cleanup level generation.
function levelGenerationCleanup ()
{//echo("levelGenerationCleanup())";
	destroyMazeRoom();
	destroyMapArr();
	destroyMazeRoom();
}

function setPreloadedTilemap ()
{//echo("setPreloadedTilemap()");
	// Load Preloaded.
	$PreloadedTilemap = new Sprite();
	$PreloadedTilemap.SceneLayer = $PreloadedTilemapLayer;
	$PreloadedTilemap.setImage("Sprites:Preloaded" @ strreplace($overworldLocation, " ", ""));
	$PreloadedTilemap.size = "128 128";
	$PreloadedTilemap.setPosition(64 SPC (64 + $GlobalVerticalShift));
	addObjectToScene($PreloadedTilemap);
}

// Fully generates the specified irregular dungeon map.
function generateSpecifiedIrregularDungeon (%dungeonDimension, %PreloadedImagemap, %WallTile1Imagemap, %failThreshold, %featureProbability, %numberOfRooms, %iterations,
											%generateTutorialLevel)
{//echo("generateSpecifiedIrregularDungeon()");echo("%PreloadedImagemap =" SPC %PreloadedImagemap);//echo(%failThreshold SPC %featureProbability SPC %numberOfRooms SPC %iterations);
	// Null maze room.
	destroyMazeRoom();
	// Clear $mazeLiftedTiles.
	destroyMazeLiftedTiles();
	// Handle preloaded background image.
	setPreloadedTilemap();
	
	// Create a dungeon.
	// Clear $mapArr[] and $mapArrGeo[].
    $mapArr[%dungeonDimension, %dungeonDimension] = 1;
    $mapArrGeo[%dungeonDimension, %dungeonDimension] = 1;
	for (%i = 0; %i < %dungeonDimension; %i++)
	{
		for (%j = 0; %j < %dungeonDimension; %j++)
		{
			$mapArr[%i, %j] = 1;
			$mapArrGeo[%i, %j] = 1;
		}
	}
	
	// Check to see if we should generate a tutorial level!
	if ($generateTutorialLevel)
	{
		createTutorialLevel();
	}
	else
	{
		// Generate geomorph level!
		//generateGeomorphDatabase();			// Need this if using both generateGeomorphDatabase() and createIrregularDungeon()!	<------------|
		//createIrregularDungeon(%dungeonDimension, %dungeonDimension, %failThreshold, %featureProbability, %numberOfRooms, %iterations);	   //|
		createIrregularDungeon(32, 32, %failThreshold, 120, 60, 80);																		   //|	FUCKING THESE.
		/*if (getRandom(1, 100) <= $treasureRoomChance)																						   //|
		{																																	   //|
			// Generate geomorph treasure room!																								   //|
			%treasureRoomGenerated = generateGeomorphTreasureRoom();			//													<------------|
			// Compile the two generated levels.																							   //|
			compileMapArrs(%treasureRoomGenerated);	// Need this if using both geomorphs and createIrregularDungeon()!			    <------------|
		}*/
	}
	
	// Loop through and echo dungeon map.
	for (%y = 0; %y < %dungeonDimension; %y++)
	{
        %line = "";
		
        for (%x = 0; %x < %dungeonDimension; %x++)
		{
            if ($mapArr[%y, %x] == 0)		// Walkable.
			{
				// Grating chance roll.
				%gratingChance = getRandom(1, 100);
				if (%gratingChance <= $gratingChance)
				{
					// Spawn grating tile.
					spawnGrating(%x, %y, false);
				}
				else
				{
					%liftedTileChance = getRandom(1, 100);
					if (%liftedTileChance <= $liftedTileChance)
					{
						// If no grating, have a chance to spawn a lifted tile on the floor!
						spawnLiftedFloorTile(%x, %y);
					}
				}
				
				// Place barrels.
				// NOTE: Should probably place these differently to cluster them up!
				if ($overworldLocation $= "Alien Deck")
				{
				}
				else
				{
					%placeBarrel = getRandom(1, 100);
					if (%placeBarrel <= $barrelPlacementChance)
					{
						%barrelSprite = new Sprite("Barrel")
						{
							SceneLayer = $BarrelLayer;
							graph = $BarrelGroup;
							position = getTilePositionFromIndices(%x, %y);
							scenegraph = levelSceneGraph;
							imagemap = "ContainerCrateImageMap";
							visible = true;
							size = "4 4";
							xIndex = %x;
							yIndex = %y;
						};
						%barrelSprite.setImage("Sprites:ContainerCrate");
						addObjectToScene(%barrelSprite);
						
						// Add barrel to list of barrels.
						$barrelList.add(%barrelSprite);
					}
				}
			}
            if ($mapArr[%y, %x] == 1)		// Space.
			{
				$mazeRoom[%x, %y] = -12;
				// Only place a space tile if it's next to a wall tile!
				if ($mapArr[%y - 1, %x]		== 2	||	// North.
					$mapArr[%y + 1, %x]	 	== 2	||	// South.
					$mapArr[%y, %x + 1]	 	== 2	||	// East.
					$mapArr[%y, %x - 1]		== 2	||	// West.
					$mapArr[%y - 1, %x - 1] == 2	||	// NW.
					$mapArr[%y - 1, %x + 1] == 2	||	// NE.
					$mapArr[%y + 1, %x - 1] == 2	||	// SW.
					$mapArr[%y + 1, %x + 1] == 2)		// SE.
				{
					%randomSpaceTile = getRandom(1, 6);
					%spaceImagemap = "Sprites:SpaceBackground" @ %randomSpaceTile;
					// Create space tile.
					$mazeRoom[%x, %y] = new Sprite("Space Tile")
					{
						status = -1;
						SceneLayer = $SpaceTileLayer;
						graph = $SpaceTileGraph;
						position = getTileShiftedPositionFromIndices(%x, %y);
						scenegraph = levelSceneGraph;
						imagemap = %spaceImagemap;
						visible = true;
						size = "4 4";
						xIndex = %x;
						yIndex = %y;
					};
					$mazeRoom[%x, %y].setImage(%spaceImagemap);
					addObjectToScene($mazeRoom[%x, %y]);
				}
			}
            if ($mapArr[%y, %x] == 2)		// Wall.
			{//echo("wall at (" @ %x @ ", " @ %y @ ")");
				// Command Deck!
				%imageMap = %WallTile1Imagemap;//"";	// "Default" wall imagemap. Don't pick the second one since it could be nothing!
				
				// Check adjacent tile statuses!
				// Bounds checking.
				
				// North.
				%north = 1;
				if (%y + 1 < %dungeonDimension)
				{
					%north = tileNotBlocked(%x, %y + 1);
				}
				// South.
				%south = 1;
				if (%y - 1 >= 0)
				{
					%south = tileNotBlocked(%x, %y - 1);
				}
				// East.
				%east = 1;
				if (%x + 1 <= %dungeonDimension)
				{
					%east = tileNotBlocked(%x + 1, %y);
				}
				// West.
				%west = 1;
				if (%x - 1 >= 0)
				{
					%west = tileNotBlocked(%x - 1, %y);
				}
				
				// North-West.
				%nw = 1;
				if (%y + 1 < %dungeonDimension	&&
					%x - 1 < %dungeonDimension)
				{
					%nw = tileNotBlocked(%x - 1, %y + 1);
				}
				// North-East.
				%ne = 1;
				if (%y + 1 < %dungeonDimension	&&
					%x + 1 >= 0)
				{
					%ne = tileNotBlocked(%x + 1, %y + 1);
				}
				// South-West.
				%sw = 1;
				if (%y - 1 >= 0	&&
					%x - 1 >= 0)
				{
					%sw = tileNotBlocked(%x - 1, %y - 1);
				}
				// South-East.
				%se = 1;
				if (%y - 1 >= 0	&&
					%x + 1 >= 0)
				{
					%se = tileNotBlocked(%x + 1, %y - 1);
				}
				
				// Special case for protruding south wall!
				// South-South.
				%ss = 1;
				if (%y - 2 >= 0)
				{
					%ss = tileNotBlocked(%x, %y - 2);
				}
				// South-South-West.
				%ssw = 1;
				if (%y - 2 >= 0	&&
					%x - 1 >= 0)
				{
					%ssw = tileNotBlocked(%x - 1, %y - 2);
				}
				// South-South-East.
				%sse = 1;
				if (%y - 2 >= 0	&&
					%x + 1 < %dungeonDimension)
				{
					%sse = tileNotBlocked(%x + 1, %y - 2);
				}
				
				// Get wall status code.
				%frame = getAtlasFrame(%north, %south, %east, %west,
									   %nw, %ne, %sw, %se,
									   %ss, %ssw, %sse);
				
				
				// HACK for map edges!!
				// South edge.
				if (%frame == 17	&&
					%x <= 0)
				{
					%frame = 72;
				}
				// South edge.
				else if (%frame == 18	&&
						 %y >= 63)
				{
					%frame = 70;
				}
				// END OF HACK.
				
				
				// Use tileset atlases!
				%imagemap = getImageFromOverworldLocation();
				
				// Create wall sprite.
				$mazeRoom[%x, %y] = new Sprite("Wall")
				{
					status = -2;
					SceneLayer = $BaseTileLayer;
					position = getTileShiftedPositionFromIndices(%x, %y);
					scenegraph = levelSceneGraph;
					image = %imagemap;
					frame = %frame;
					visible = true;
					size = "4 4";
					xIndex = %x;
					yIndex = %y;
					door = null;
					light = null;
					painting = null;
					pipes = null;
				};
				addObjectToScene($mazeRoom[%x, %y]);
				
				// Flags for lights and paintings.
				%placedLight = false;
				%placedPainting = false;
				%placedWallPipeObject = false;
				%placedSideWallPipeObject = false;
				%placedPorthole = false;
				%placedPumpObject = false;
				// Determine if this wall should hold a light.
				%lightChance = $lightPlacementChance;
				%lightRoll = getRandom(1, 100);
				// Get random light imagemap.
				%lightImageMap = getLightImageFromAtlasFrame(%frame);
				// Chance for painting if light placement fails.
				%paintingChance = $paintingPlacementChance;
				%paintingRoll = getRandom(1, 100);
				// Get random painting imagemap.
				%paintingImageMap = getPaintingImageFromAtlasFrame(%frame);
				// Light.
				if ($overworldLocation $= "Alien Deck")
				{
					%placedLight = false;
				}
				else
				{
					if (%lightImageMap !$= ""	&&
						%lightRoll <= %lightChance)
					{
						// Handle offsets here.
						%xOffset = 0;
						%yOffset = 0;
						switch$ (%lightImageMap)
						{
							case "Sprites:LightFloorLeft":		%xOffset = -5.6;
							case "Sprites:LightFloorRight":		%xOffset =  5.6;
						}
						
						// Create light sprite.
						%light = new Sprite("Light")
						{
							SceneLayer = $WallLightLayer;
							position = getTileShiftedPositionFromIndices(%x, %y);
							scenegraph = levelSceneGraph;
							image = %lightImageMap;
							visible = true;
							size = "4 4";
							lightSource = null;
							xIndex = %x;
							yIndex = %y;
						};
						addObjectToScene(%light);
						%lightSource = createWallLightSource(%x, %y);
						$LightSourceList.add(%lightSource);
						%lightSource.position = getWord(getTileShiftedPositionFromIndices(%x, %y), 0) + %xOffset SPC getWord(getTileShiftedPositionFromIndices(%x, %y), 1) + %yOffset;
						if (%xOffset > 0)
						{
							%lightSource.setFlipX(1);
						}
						$mazeRoom[%x, %y].light = %light;
						%light.lightSource = %lightSource;
						$lightList.add(%light);
						
						
						// Wall lights - ignore for now!
						/*
						// Find proper light to mount to this light.
						switch$ (%lightImageMap)
						{
							case "LightFloorLeftImageMap":
								%lightMountLight = LightWallLeftImageMap;
								%xOffset = 0;
							case "LightFloorRightImageMap":
								%lightMountLight = LightWallRightImageMap;
								%xOffset = 0;
						}
						// Attach "wall" light next to this light.
						%lightMount = new Sprite("Light Mount")
						{
							SceneLayer = $WallLightLayer;
							position = getTileShiftedPositionFromIndices(%x, %y);
							scenegraph = levelSceneGraph;
							imagemap = %lightMountLight;
							visible = true;
							size = "4 4";
						};
						addObjectToScene(%lightMount);
						// Mount light to light mount.
						// NOTE: Offset mount depending on type of light fixture!
						%lightMount.mount($mazeRoom[%x, %y], %xOffset, %yOffset, 50.0, true, true, true, true);
						*/
						
						
						%placedLight = true;
					}
				}
				// Painting.
				if (%paintingImageMap !$= ""			&&
					%paintingRoll <= %paintingChance	&&
					%lightImageMap $= "")		// Only place painting if no light fixture is placed.
				{
					if ($overworldLocation $= "Alien Deck")
					{
						%placedPainting = false;
					}
					else
					{
						// Create painting sprite.
						%painting = new Sprite("Painting")
						{
							SceneLayer = $PaintingLayer;
							graph = $PaintingGraph;
							position = getTileShiftedPositionFromIndices(%x, %y);
							scenegraph = levelSceneGraph;
							image = %paintingImageMap;
							visible = true;
							size = "4 4";
						};
						addObjectToScene(%painting);
						// Assign painting to wall.
						$mazeRoom[%x, %y].painting = %painting;
						// Mount painting to wall.
						//%painting.mount($mazeRoom[%x, %y], 0.0, 0.0, 50.0, true, true, true, true);
						// Attach wall pipes if required.
						if (%paintingImageMap $= "Painting2ImageMap"	&&
							!isObject($mazeRoom[%x - 1, %y]))
						{
							// Create painting sprite.
							%wallPipes = new Sprite("Wall Pipes")
							{
								SceneLayer = $WallPipesLayer;
								graph = $WallPipesGraph;
								position = getTileShiftedPositionFromIndices(%x, %y);
								scenegraph = levelSceneGraph;
								image = "PaintingFloorLeftImageMap";
								visible = true;
								size = "4 4";
							};
							addObjectToScene(%wallPipes);
							// Set pipe offsets.
							%xOffset = -1.8;
							%yOffset = 0;
							// Assign pipes to wall.
							$mazeRoom[%x, %y].pipes = %wallPipes;
							// Mount pipes to wall.
							%wallPipes.mount($mazeRoom[%x, %y], %xOffset, %yOffset, 50.0, true, true, true, true);
						}
						%placedPainting = true;
					}
				}
				// Porthole.
				%placePorthole = getRandom(1, 100);
				if (%placePorthole <= $portholeChance	&&
					!%placedLight						&&
					!%placedPainting					&&
					(%frame == 54	||
					 %frame == 55	||
					 %frame == 56	||
					 %frame == 57	||
					 %frame == 58	||
					 %frame == 59	||
					 %frame == 73))
					 // Make sure the second tile above is space?
				{
					createPorthole(%x, %y);
					%placedPorthole = true;
				}
				// Place wall pipe object.
				%wallPipeObjectRoll = getRandom(1, 100);
				if (%wallPipeObjectRoll <= $WallPipeObjectChance	&&
					!%placedLight		&&
					!%placedPainting	&&
					!%placedPorthole	&&
					(%frame == 27		||
					 %frame == 28		||
					 %frame == 29		||
					 %frame == 42))
				{
					createWallPipes(%x, %y);
					%placedWallPipeObject = true;
				}
				// Place side wall pipe objects.
				%sideWallPipeObjectRoll = getRandom(1, 100);
				if (%sideWallPipeObjectRoll <= $SideWallPipeObjectChance	&&
					!%placedLight			&&
					!%placedPainting		&&
					!%placedPorthole		&&
					!%placedWallPipeObject	&&
					(%frame == 17		||
					 %frame == 20		||
					 %frame == 34		||
					 %frame == 43		||
					 %frame == 46		||
					 %frame == 47		||
					 %frame == 67		||
					 %frame == 72		||
					 %frame == 75		||
					 %frame == 76))
				{
					createRightSideWallPipes(%x, %y);
					%placedSideWallPipeObject = true;
				}
				%sideWallPipeObjectRoll = getRandom(1, 100);
				if (%sideWallPipeObjectRoll <= $SideWallPipeObjectChance	&&
					!%placedLight			&&
					!%placedPainting		&&
					!%placedPorthole		&&
					!%placedWallPipeObject	&&
					(%frame == 16		||
					 %frame == 10		||
					 %frame == 35		||
					 %frame == 44		||
					 %frame == 45		||
					 %frame == 47		||
					 %frame == 68		||
					 %frame == 71		||
					 %frame == 75		||
					 %frame == 76))
				{
					createLeftSideWallPipes(%x, %y);
					%placedSideWallPipeObject = true;
				}
				%pumpRoll = getRandom(1, 100);
				if (%pumpRoll <= $PumpPlacementChance	&&
					!%placedLight				&&
					!%placedPainting			&&
					!%placedPorthole			&&
					!%placedWallPipeObject		&&
					!%placedSideWallPipeObject	&&
					(%frame == 16	||
					 %frame == 17	||
					 %frame == 18	||
					 %frame == 19	||
					 %frame == 20	||
					 %frame == 21	||
					 %frame == 26	||
					 %frame == 33	||
					 %frame == 34	||
					 %frame == 35	||
					 %frame == 40	||
					 %frame == 41	||
					 %frame == 43	||
					 %frame == 44	||
					 %frame == 47	||
					 %frame == 48	||
					 %frame == 53	||
					 %frame == 62	||
					 %frame == 63	||
					 %frame == 64	||
					 %frame == 65	||
					 %frame == 66	||
					 %frame == 67	||
					 %frame == 68	||
					 %frame == 69	||
					 %frame == 70	||
					 %frame == 71	||
					 %frame == 72	||
					 %frame == 75	||
					 %frame == 76))
				{
					createPumpAnimation(%x, %y);
					%placedPumpObject = true;	// Unused?
				}
			}
            if ($mapArr[%y, %x] == 3	||
				$mapArr[%y, %x] == 4	||
				$mapArr[%y, %x] == 5)		// Door/Special.
			{
				// Determine proper door imagemap.
				if ($mapArr[%y, %x - 1] == 2	||	// Wall.
					$mapArr[%y, %x - 1] == 3	||	// Door.
					$mapArr[%y, %x - 1] == 4	||	// Door.
					$mapArr[%y, %x - 1] == 5	||	// Door.
					$mapArr[%y, %x + 1] == 2	||	// Wall.
					$mapArr[%y, %x + 1] == 3	||	// Door.
					$mapArr[%y, %x + 1] == 4	||	// Door.
					$mapArr[%y, %x + 1] == 5)		// Door.)
				{//echo("horizontal door!");
					%positionFlag = 0;
					%doorFrame = 22;
				}
				else
				{//echo("vertical door!");
					%positionFlag = 1;
					%doorFrame = 24;
				}
				
				// Create closed door sprite.
				$mazeRoom[%x, %y] = new Sprite("Door Closed")
				{
					status = -3;			// Flag as door! Door closed is -3, opened is -4.
					SceneLayer = $DoorClosedLayer;
					position = getTileShiftedPositionFromIndices(%x, %y);
					scenegraph = levelSceneGraph;
					image = %imageMap;
					//frame = %doorFrame;
					visible = true;
					size = "4 4";
					xIndex = %x;
					yIndex = %y;
					positionFlag = %positionFlag;		// Flags as horizontal (0) or vertical (1) door tile.
					doorFrame = %doorFrame;
					plasticExplosive = null;
				};
				$mazeRoom[%x, %y].setImage(%imagemap);
				$mazeRoom[%x, %y].frame = %doorFrame;
				addObjectToScene($mazeRoom[%x, %y]);
				
				// Chance to set plastic explosives on the door tile!
				if ($overworldLocation $= "Alien Deck")
				{
				}
				else
				{
					if (getRandom(1, 100) <= $plasticExplosiveSpawnChance)
					{
						if (!$generateTutorialLevel)
						{
							createPlasticExplosiveAnimation(%x, %y);
						}
					}
				}
			}
		}
	}
	
	
	// TESTER
	//echoCurrentLevel();
	// END OF TESTER
	
	
	// Adds stairs to the dungeon.
	addStairsToDungeon();
	
	// Spawn consoles.
	spawnConsoles();
	// Spawn dispensers.
	spawnDispensers();
	// Spawn switches.
	spawnSwitches();
	// Spawn lockers.
	spawnLockers();
	// Spawn traps.
	//spawnTraps();		// These need to stop spawning under squad members! Call this after squad is placed instead!
	// Spawn crew corpses.
	spawnCrewCorpses();
	// Span floor markings.
	spawnFloorMarkings();
	// Don't spawn CryoTubes on the Command Deck!
	if ($overworldLocation !$= "Command Deck")
	{
		spawnCryoTubes();
	}
	
	// Add grating steam venting animations.
	addSteamVentingAnimations();
	
	// Turn off physics!
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			if (isObject($mazeRoom[%i, %j]))
			{
				$mazeRoom[%i, %j].CollisionPhysicsReceieve = "0";
				$mazeRoom[%i, %j].CollisionPhysicsSend = "0";
			}
		}
	}
}

// Test function that finds doors not being properly flagged as doors!
// NOTE: Being used as a hack workaround to fix misflagged doors!
function getMisflaggedDoorsCount ()
{//echo("getMisflaggedDoorsCount()");
	%doorCount = 0;
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			if ($mazeRoom[%i, %j].frame == 22	||
				$mazeRoom[%i, %j].frame == 23	||
				$mazeRoom[%i, %j].frame == 24	||
				$mazeRoom[%i, %j].frame == 25)
			{
				if ($mazeRoom[%i, %j].status != -3	&&
					$mazeRoom[%i, %j].status != -4)
				{
					%doorCount++;
					
					if ($mazeRoom[%i, %j].frame == 22	||
						$mazeRoom[%i, %j].frame == 24)
					{
						$mazeRoom[%i, %j].status = -3;		// Closed door.
					}
					else
					{
						$mazeRoom[%i, %j].status = -4;		// Opened door.
					}
				}
			}
		}
	}
	return %doorCount;
}
// Test function that finds walls not being properly flagged as walls!
// NOTE: Being used as a hack workaround to fix misflagged walls!
function getMisflaggedWallsCount ()
{//echo("getMisflaggedWallsCount()");
return;
	%doorCount = 0;
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			if ($mazeRoom[%i, %j].frame == 22	||
				$mazeRoom[%i, %j].frame == 23	||
				$mazeRoom[%i, %j].frame == 24	||
				$mazeRoom[%i, %j].frame == 25)
			{
				if ($mazeRoom[%i, %j].status != -3	&&
					$mazeRoom[%i, %j].status != -4)
				{
					%doorCount++;
					
					if ($mazeRoom[%i, %j].frame == 22	||
						$mazeRoom[%i, %j].frame == 24)
					{
						$mazeRoom[%i, %j].status = -3;		// Closed door.
					}
					else
					{
						$mazeRoom[%i, %j].status = -4;		// Opened door.
					}
				}
			}
		}
	}
	return %doorCount;
}
function createIrregularDungeon (%xsize, %ysize, %fail, %b1, %mrooms, %iterations)
{//echo("createIrregularDungeon()");
//createIrregularDungeonNEW();return;	// HACK ALERT!
	// Destroy any remnants of the last generated dungeon of this type!
	if (isObject($mazeRoom))
	{
		$mazeRoom.safeDelete();
	}
	if (isObject($roomList))
	{
		$roomList.safeDelete();
	}
	if (isObject($cList))
	{
		$cList.safeDelete();
	}
	if (isObject($checkExit))
	{
		$checkExit.safeDelete();
	}
	
	// Variable initialization.
	$mazeDimension = %xsize;
	$mazeRoom[%xsize, %ysize] = 0;
	$roomList[%xsize * %ysize] = 0;
	$roomListLength = 0;
    $cList[%xsize * %ysize] = 0;
	$cListLength = 0;
	$checkExit[$mazeDimension] = 0;
	$checkExitLength = 0;
	%roomResult = makeRoom();
	%w = getWord(%roomResult, 0);		// Wide.
	%l = getWord(%roomResult, 1);		// Long.
	%t = getWord(%roomResult, 2);		// Type.
	
	// Run placeRoom until we create an initial room.
    while ($roomListLength == 0)
	{
		%x = getRandom(14, 17);
		%y = getRandom(14, 17);
		%p = placeInitialRoom(%l, %w, %x, %y, %xsize, %ysize, 6, 0);
	}
	%failed = 0;
	// Absolute end condition!
	%totalIterations = 0;
	
    while (%failed < %fail	&&			// The lower the value that failed the smaller the dungeon.
		   %totalIterations < %iterations)
	{//echo("$roomListLength =" SPC $roomListLength);
		%totalIterations++;
        %chooseRoom = getRandom(0, $roomListLength - 1);
		
        %exitCode = makeExit(%chooseRoom);
		%ex  = getWord(%exitCode, 0);
		%ey  = getWord(%exitCode, 1);
		%ex2 = getWord(%exitCode, 2);
		%ey2 = getWord(%exitCode, 3);
		%et  = getWord(%exitCode, 4);
		
        %feature = getRandom(0, 100);
		
        //if (%feature < -1)//%b1)				// Begin feature choosing (more features to be added here).
        if (%feature < %b1)				// Begin feature choosing (more features to be added here).
		{
			%corridorCode = makeCorridor();
			%w = getWord(%corridorCode, 0);
			%l = getWord(%corridorCode, 1);
			%t = getWord(%corridorCode, 2);
		}
        else
		{
			%roomCode = makeRoom();
			%w = getWord(%roomCode, 0);
			%l = getWord(%roomCode, 1);
			%t = getWord(%roomCode, 2);
		}
		
		// This function call is the key for placing properly joined rooms!
		%roomDone = placeRoom(%l, %w, %ex2, %ey2, %xsize, %ysize, %t, %et);
		
		if (%roomDone == 0)			// If placement failed increase possibility map is full.
		{
			%failed += 1;
		}
		else if (%roomDone == 2)	// Possibility of linking rooms.
		{
			/*makePortal(%ex, %ey);	// Can crash game!
			if ($mapArr[%ey2, %ex2] == 0)
			{
				%failed += 1;
			}*/
			if ($mapArr[%ey2, %ex2] == 0)
			{
				makePortal(%ex, %ey);
				%failed += 1;
			}
		}
		else						// Otherwise link up the two rooms.
		{
			makePortal(%ex, %ey);
			%failed = 0;
			if (%t < 5)
			{
				%tc = $roomListLength - 1 SPC %ex2 SPC %ey2 SPC %t;	
				$cList[$cListLength] = %tc;
				$cListLength++;
				joinCorridor($roomListLength - 1, %ex2, %ey2, %t, 50);
			}
		}
		if ($roomListLength == %mrooms)
		{
			%failed = %fail;
		}
	}
	correctDoors();
	getMisflaggedDoorsCount();					// ...
	schedule(50, 0, "getMisflaggedDoorsCount");	// ... oh God this is terrible.
}
function makeRoom ()
{//echo("makeRoom()");
    %rtype = 5;
	// Room dimension parameters.
	%roomUpper = 2;
	%roomExtender = 2;
    %rwide = getRandom(0, %roomUpper) + %roomExtender;
    %rlong = getRandom(0, %roomUpper) + %roomExtender;
    return %rwide SPC %rlong SPC %rtype;
}
function makeCorridor ()
{//echo("makeCorridor()");
	%clength = getRandom(1, 3) + 3;		// Still too long?
	%heading = getRandom(0, 3);			// Really should use direction enums...
	%corridorBreadth = 2;
	switch$ ($overworldLocation)
	{
		case "Command Deck":		%corridorBreadth = 2;
		case "Engineering Deck":	%corridorBreadth = getRandom(2, 3);
		case "Medical Deck":		%corridorBreadth = getRandom(1, 3);
		case "Armory Deck":			%corridorBreadth = 2;
		case "Bridge Deck":			%corridorBreadth = 2;
		case "Alien Deck":			%corridorBreadth = getRandom(1, 3);
	}
    if (%heading == 0)		// North.
	{
        %wd = %corridorBreadth;
        %lg = %clength * -1;
	}
    else if (%heading == 1)	// East.
	{
        %wd = %clength;
        %lg = %corridorBreadth;
	}
    else if (%heading == 2)	// South.
	{
		%wd = %corridorBreadth;
        %lg = %clength;
	}
    else if (%heading == 3)	// West.
	{
        %wd = %clength * -1;
        %lg = %corridorBreadth;
	}
    return %wd SPC %lg SPC %heading;
}
function placeInitialRoom (%ll,
						   %ww,
						   %xposs,
						   %yposs,
						   %xsize,
						   %ysize,
						   %rty,
						   %ext)
{//echo("initial()");
	// Place feature if enough space and return canPlace as true or false.
	
	// Arrange for heading
	%xpos = %xposs;
	%ypos = %yposs;
	
	if (%ll < 0)
	{
		%ypos += %ll + 1;
		%ll = mAbs(%ll);
	}
	if (%ww < 0)
	{
		%xpos += %ww + 1;
		%ww = mAbs(%ww);
	}
	// Make offset if type is room.
	if (%rty == 5)
	{
		if (%ext == 0 ||
			%ext == 2)
		{
		   %offset = getRandom(0, %ww);
		   %xpos -= %offset;
		}
		else
		{
		   %offset = getRandom(0, %ll);
		   %ypos -= %offset;
		}
	}
	%canPlace = 1;
    // If there is space, add to list of rooms.
    if (%canPlace == 1)
    {
		// Ignore the first generated room!
		if ($roomListLength > 0)
		{
			// Pad the sides of the maze space!
			%mazeBuffer = 2;
			if (%xPos - %ww / 2 < %mazeBuffer		||
				%yPos - %ll / 2 < %mazeBuffer		||
				%xPos + %ww / 2 > 64 - %mazeBuffer	||
				%yPos + %ll / 2 > 64 - %mazeBuffer)
			{
				// Short-circuit %canPlace! Probably bad! Oh well!
				return 0;
			}
		}
		// Append (%ll, %ww, %xpos, %ypos) to roomList.
		$roomList[$roomListLength] = %ll SPC %ww SPC %xpos SPC %ypos;
		$roomListLength++;
		
		for (%j = 0; %j < %ll + 2; %j++)
		{
			for (%k = 0; %k < %ww + 2; %k++)
			{
				$mapArr[(%ypos - 1) + %j, (%xpos - 1) + %k] = 2;			// Wall.
			}
		}
		for (%j = 0; %j < %ll; %j++)
		{
			for (%k = 0; %k < %ww; %k++)
			{
				$mapArr[%ypos + %j, %xpos + %k] = 0;						// Floor.
			}
		}
	}
	
	return %canPlace;
}


// Place a room.
function placeRoom (%ll,
					%ww,
					%xposs,
					%yposs,
					%xsize,
					%ysize,
					%rty,
					%ext)
{//echo("placeRoom()");
	// Place feature if enough space and return canPlace as true or false.
	
	// Arrange for heading
	%xpos = %xposs;
	%ypos = %yposs;
	
	if (%ll < 0)
	{
		%ypos += %ll + 1;
		%ll = mAbs(%ll);
	}
	if (%ww < 0)
	{
		%xpos += %ww + 1;
		%ww = mAbs(%ww);
	}
	// Make offset if type is room.
	if (%rty == 5)
	{
		%buffer = 2;//1;//0;
		if (%ext == 0 ||
			%ext == 2)
		{
			//%offset = getRandom(0, %ww);
			%offset = getRandom(%buffer, %ww - %buffer);
			%xpos -= %offset;
		}
		else
		{
			//%offset = getRandom(0, %ll);
			%offset = getRandom(%buffer, %ll - %buffer);
			%ypos -= %offset;
		}
	}
	
	// Then check if there is space.
	%canPlace = 1;
	if (%ww + %xpos + 1 > %xsize - 3	||
		%ll + %ypos + 1 > %ysize - 3)
	{//echo("1) CAN'T PLACE ROOM!--------------------------------------------------------------------------------------");
		%canPlace = 0;
		return %canPlace;
	}
	else if (%xpos < 0 ||
			 %ypos < 0)
	{//echo("2) CAN'T PLACE ROOM!--------------------------------------------------------------------------------------");
		%canPlace = 0;
		return %canPlace;
	}
	else
	{
		for (%j = 0; %j < %ll; %j++)
		{
			for (%k = 0; %k < %ww; %k++)
			{
				if ($mapArr[(%ypos) + %j, (%xpos) + %k] != 1)
				{
					%canPlace = 2;
				}
			}
		}
	}
	 
    // If there is space, add to list of rooms.
    if (%canPlace == 1)	// Only 1? Not 2?
    {//echo("3) CAN PLACE ROOM!--------------------------------------------------------------------------------------");
		// Ignore the first generated room!
		if ($roomListLength > 0)
		{
			/*echo("------------------------------------------");
			echo("%xPos - %ww / 2 =" SPC %xPos - %ww / 2);
			echo("%yPos - %ll / 2 =" SPC %yPos - %ll / 2);
			echo("%xPos + %ww / 2 =" SPC %xPos + %ww / 2);
			echo("%yPos + %ll / 2 =" SPC %yPos + %ll / 2);*/
			// Think we can place? Okay, but pad the sides of the maze space!
			%mazeBuffer = 2;
			if (%xPos - %ww / 2 < %mazeBuffer		||
				%yPos - %ll / 2 < %mazeBuffer		||
				%xPos + %ww / 2 > 64 - %mazeBuffer	||
				%yPos + %ll / 2 > 64 - %mazeBuffer)
			{
				// Short-circuit %canPlace! Probably bad! Oh well!
				return 0;//showRandomDungeonLayout(64, 64, 110, 50, 60);
			}
		}
		
		// Append (%ll, %ww, %xpos, %ypos) to roomList.
		$roomList[$roomListLength] = %ll SPC %ww SPC %xpos SPC %ypos;
		$roomListLength++;
		
		for (%j = 0; %j < %ll + 2; %j++)
		{
			for (%k = 0; %k < %ww + 2; %k++)
			{
				$mapArr[(%ypos - 1) + %j, (%xpos - 1) + %k] = 2;			// Wall.
			}
		}
		for (%j = 0; %j < %ll; %j++)
		{
			for (%k = 0; %k < %ww; %k++)
			{
				$mapArr[%ypos + %j, %xpos + %k] = 0;						// Floor.
			}
		}
	}
	return %canPlace;
}

// Make an exit.
function makeExit (%rn)	 
{//echo("makeExit()");
	//Pick random wall and random point along that wall"""
    %room = $roomList[%rn];
	
	%ll = getWord(%room, 0);
	%ww = getWord(%room, 1);
	%xpos = getWord(%room, 2);
	%ypos = getWord(%room, 3);
	
	// Don't pick corners!
	// NOTE: Setting %boundedPad to 1 can cause infinite loops... WHY?!?
	%boundPad = 0;
	
	// Loop while the tile isn't a wall!
	while ($mapArr[%ry, %rx] != 2)
	{//echo("exit loop!");
		%rw = getRandom(0, 3);
		if (%rw == 0)		// North wall.
		{
			%rx  = getRandom(%boundPad, %ww - %boundPad) + %xpos;
			%ry  = %ypos - 1;
			%rx2 = %rx;
			%ry2 = %ry - 1;
		}
		else if (%rw == 1)	// East wall.
		{
			%ry  = getRandom(%boundPad, %ll - %boundPad) + %ypos;
			%rx  = %xpos + %ww;
			%rx2 = %rx + 1;
			%ry2 = %ry;
		}
		else if (%rw == 2)	// South wall.
		{
			%rx  = getRandom(%boundPad, %ww - %boundPad) + %xpos;
			%ry  = %ypos + %ll;
			%rx2 = %rx;
			%ry2 = %ry + 1;
		}
		else if (%rw == 3)	// West wall.
		{
			%ry  = getRandom(%boundPad, %ll - %boundPad) + %ypos;
			%rx  = %xpos - 1;
			%rx2 = %rx - 1;
			%ry2 = %ry;
		}
	}
	
	return %rx SPC %ry SPC %rx2 SPC %ry2 SPC %rw;
}

function makePortal (%px, %py)
{//echo("makePortal()");
	// Make Closed Door.
	$mapArr[%py, %px] = 4;
}

function joinCorridor (%cno, %xp, %yp, %ed, %psb)
{echo("joinCorridor()");
echo("%cno =" SPC %cno);
//echo("%xp =" SPC %xp);
//echo("%yp =" SPC %yp);
//echo("%ed =" SPC %ed);
//echo("%psb =" SPC %psb);
		//"""Check corridor endpoint and make an exit if it links to another room"""
		//%cArea = $roomList[%cno];
		/*%cArea0 = $roomList[getWord(%cno, 0)];
		%cArea1 = $roomList[getWord(%cno, 1)];
		%cArea2 = $roomList[getWord(%cno, 2)];
		%cArea3 = $roomList[getWord(%cno, 3)];*/
		%cArea0 = getWord($roomList[%cno], 0);
		%cArea1 = getWord($roomList[%cno], 1);
		%cArea2 = getWord($roomList[%cno], 2);
		%cArea3 = getWord($roomList[%cno], 3);

echo("\"" + getWord(%cno, 0) + "\"\n");
echo("\"" + getWord(%cno, 1) + "\"\n");
echo("\"" + getWord(%cno, 2) + "\"\n");
echo("\"" + getWord(%cno, 3) + "\"\n");

echo(%cArea0);
echo(%cArea1);
echo(%cArea2);
echo(%cArea3);
		
		if (%xp != %cArea2 ||
			%yp != %cArea3)		// Find the corridor endpoint
		{
			%endx = %xp - (%cArea1 - 1);
			%endy = %yp - (%cArea0 - 1);
		}
		else
		{
			%endx = %xp + (%cArea1 - 1);
			%endy = %yp + (%cArea0 - 1);
		}
		
		if (%ed == 0)			// North corridor
		{
			if (%endx > 1)
			{
				%coords = %endx - 2 SPC %endy SPC %endx - 1 SPC %endy;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endy > 1)
			{
				%coords = %endx SPC %endy - 2 SPC %endx SPC %endy - 1;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endx < 78)
			{
				%coords = %endx + 2 SPC %endy SPC %endx + 1 SPC %endy;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
		}
		else if (%ed == 1)		// East corridor
		{
			if (%endy > 1)
			{
				%coords = %endx SPC %endy - 2 SPC %endx SPC %endy - 1;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endx < 78)
			{
				%coords = %endx + 2 SPC %endy SPC %endx + 1 SPC %endy - 1;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endy < 38)
			{
				%coords = %endx SPC %endy + 2 SPC %endx SPC %endy + 1;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
		}
		else if (%ed == 2)		// South corridor
		{
			if (%endx < 78)
			{
				%coords = %endx + 2 SPC %endy SPC %endx + 1 SPC %endy;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endy < 38)
			{
				%coords = %endx SPC %endy + 2 SPC %endx SPC %endy + 1;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endx > 1)
			{
				%coords = %endx - 2 SPC %endy SPC %endx - 1 SPC %endy;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
		}
		else if (%ed == 3)		// West corridor
		{
			if (%endx > 1)
			{
				%coords = %endx - 2 SPC %endy SPC %endx - 1 SPC %endy;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endy > 1)
			{
				%coords = %endx SPC %endy - 2 SPC %endx SPC %endy - 1;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
			if (%endy < 38)
			{
				%coords = %endx SPC %endy + 2 SPC %endx SPC %endy + 1;
				$checkExit[$checkExitLength] = %coords;
				$checkExitLength++;
			}
		}
		
		for (%i = 0; %i < $checkExitLength; %i++)
		{
			%exit = $checkExit[%i];
			%x1 = getWord(%exit, 0);
			%y1 = getWord(%exit, 1);
			%x2 = getWord(%exit, 2);
			%y2 = getWord(%exit, 3);
			
			if ($mapArr[%y1, %x1] == 0)			// If joins to a room.
			{
				if (getRandom(1, 100) < %psb)	// Possibility of linking rooms.
				{//echo("final join portal!" SPC %x2 SPC %y2);
					makePortal(%x2, %y2);
				}
			}
		}
}

// Joins corridors together.
// Also corrects stair placement.
function finalJoins ()
{//echo("finalJoins()");
//echo("$cListLength =" SPC $cListLength);
	// NOTE: Doesn't work!
    // Final stage - loops through all the corridors to see if any can be joined to other rooms.
	/*for (%i = 0; %i < $cListLength; %i++)//x in self.cList:
	{
		joinCorridor($cList[0], $cList[1], $cList[2], $cList[3], 101);
	}*/
	
	// Look through the entire room list and connect to adjacent rooms at a depth of 1 only (i.e. do not stack doors to get through multiple wall layers).
	for (%r = 0; %r < $roomListLength; %r++)
	{
		// Grab the room data.
		%room = $roomList[%r];
		%ll = getWord(%room, 0);
		%ww = getWord(%room, 1);
		%xpos = getWord(%room, 2);
		%ypos = getWord(%room, 3);
		
		// Check entire room border for doors.
		%hasDoor = false;
		for (%j = 0; %j < %ll + 2; %j++)
		{
			for (%k = 0; %k < %ww + 2; %k++)
			{
				if ($mapArr[(%ypos - 1) + %j, (%xpos - 1) + %k] == 5)			// Door.
				{
					// Door found, break out!
					%j = %ll + 2;
					%k = %ww + 2;
					%hasDoor = true;
				}
			}
		}
		
		// If the room has no doors, make one!
		if (!%hasDoor)
		{
			for (%j = 0; %j < %ll + 2; %j++)
			{
				for (%k = 0; %k < %ww + 2; %k++)
				{
					if ($mapArr[(%ypos - 1) + %j, (%xpos - 1) + %k] == 2)		// Wall.
					{
						// Found a wall. Check if it can be turned into a door (floor tiles North & South or East & West).
						if ((($mapArr[(%ypos - 1) + %j + 1, (%xpos - 1) + %k] == 0) && ($mapArr[(%ypos - 1) + %j - 1, (%xpos - 1) + %k] == 0))	||
							(($mapArr[(%ypos - 1) + %j, (%xpos - 1) + %k + 1] == 0) && ($mapArr[(%ypos - 1) + %j, (%xpos - 1) + %k - 1] == 0)))
						{
							$mapArr[(%ypos - 1) + %j, (%xpos - 1) + %k] = 5;	// Door.
							// Break out.
							%j = %ll + 2;
							%k = %ww + 2;
						}
					}
				}
			}
		}
	}
}

// Corrects any misplaced doors!
function correctDoors ()
{//echo("correctDoors()");
	// Ranges.
	%startx = 32;
	%starty = 32;
	// Loop through the dungeon map.
	for (%y = 0; %y < %starty; %y++)
	{
        for (%x = 0; %x < %startx; %x++)
		{//echo($mapArr[%y, %x]);
			// Check if this tile is a door.
            if ($mapArr[%y, %x] == 3	||
				$mapArr[%y, %x] == 4	||
				$mapArr[%y, %x] == 5)		// Door/Special.
			{//echo("Door found at: " @ %x @ ", " @ %y);
				// Flag for door is okay.
				//%doorOkay = false;
				//$mapArr[%y, %x] = 0;
				
				// Make sure this door placement is good!
				// Doors should have a NS free/wall and WE free/wall opposite combination to have any meaning!
				// Check North and South tiles as walls.
				//echo("NSEW =" SPC $mapArr[%y - 1, %x] SPC $mapArr[%y + 1, %x] SPC $mapArr[%y, %x + 1] SPC $mapArr[%y, %x - 1]);
				%northTile = $mapArr[%y - 1, %x];
				%southTile = $mapArr[%y + 1, %x];
				%eastTile = $mapArr[%y, %x + 1];
				%westTile = $mapArr[%y, %x - 1];
				// Translate closed door tiles (4) into wall tiles (2).
				if (%northTile == 4)
				{
					%northTile = 2;
				}
				if (%southTile == 4)
				{
					%southTile = 2;
				}
				if (%eastTile == 4)
				{
					%eastTile = 2;
				}
				if (%westTile == 4)
				{
					%westTile = 2;
				}
				
				if (%northTile == 2	&&		// North.
					%southTile == 2	&&		// South
					%eastTile == 0	&&		// East.
					%westTile == 0)			// West.
				{//echo("GOOD DOOR!");
					// Good to go!
					//%doorOkay = true;
				}
				// Check West and East tiles as walls.
				else if (%northTile == 0	&&		// North.
						 %southTile == 0	&&		// South
						 %eastTile  == 2	&&		// East.
						 %westTile  == 2)			// West. 
				{//echo("GOOD DOOR!");
					// Good to go - return door placement!.
					//%doorOkay = true;
				}
				// Door placement is bad! Change the door!
				else
				{//echo("BAD DOOR!" SPC %x SPC %y);
					// Make tile walkable.
					$mapArr[%y, %x] = 2;
				}
			}
		}
	}
}

// Corrects any misplaced wall statuses!
function correctWallStatuses ()
{//echo("correctWallStatuses()");
//return;	// Cut off for now!
	// Ranges.
	%startx = 32;
	%starty = 32;
	// Loop through the dungeon map.
	for (%y = 0; %y < %starty; %y++)
	{
        for (%x = 0; %x < %startx; %x++)
		{//echo($mapArr[%y, %x]);
			// Check if this tile is a wall.
            if (isObject($mazeRoom[%x, %y])		&&
				$mazeRoom[%x, %y].frame >= 14 	&&
				$mazeRoom[%x, %y].frame <= 77	&&
				$mazeRoom[%x, %y].status == 0)
			{//echo("Incorrect door found at: " @ %x @ ", " @ %y);
				$mazeRoom[%x, %y].status = -2;
			}
		}
	}
}


// Checks for any misplaced wall statuses!
function checksWallStatuses ()
{//echo("checksWallStatuses()");
	// Ranges.
	%startx = 32;
	%starty = 32;
	// Loop through the dungeon map.
	for (%y = 0; %y < %starty; %y++)
	{
        for (%x = 0; %x < %startx; %x++)
		{//echo($mapArr[%y, %x]);
			// Check if this tile is a wall.
            if (isObject($mazeRoom[%x, %y])		&&
				$mazeRoom[%x, %y].frame >= 14 	&&
				$mazeRoom[%x, %y].frame <= 77	&&
				$mazeRoom[%x, %y].status == 0)
			{
				echo("Incorrect door found at: " @ %x @ ", " @ %y);
				//$mazeRoom[%x, %y].status = -2;
			}
		}
	}
}


//----------------------------------//
// New level generation code below! //
//----------------------------------//
function echoTestLevel ()
{//echo("echoTestLevel()");
	createIrregularDungeonNEW();
	echoMapArr();
}
function echoMapArr ()
{//echo("echoMapArr()");
	for (%y = 0; %y < $mazeDimension; %y++)
	{
        %line = "";
		
        for (%x = 0; %x < $mazeDimension; %x++)
		{
            if ($mapArr[%y, %x] == 0)		// Walkable.
			{
                %line = %line @ "_";
			}
            if ($mapArr[%y, %x] == 1)		// Blank.
			{
                %line = %line @ "_";
			}
            if ($mapArr[%y, %x] == 2)		// Wall.
			{
                %line = %line @ "#";
			}
            if ($mapArr[%y, %x] == 3)
			{
				%line = %line @ "^";		// Torch.
			}
			if ($mapArr[%y, %x] == 4	||	// Closed Door.
				$mapArr[%y, %x] == 5)		// Secret Door.
			{
                %line = %line @ "=";
			}
		}
        echo(%line);
	}
}
function clearMapArr ()
{//echo("clearMapArr()");
	for (%y = 0; %y < $mazeDimension; %y++)
	{
        for (%x = 0; %x < $mazeDimension; %x++)
		{
            $mapArr[%y, %x] = 1;
		}
	}
	//echoMapArr();
}
function createIrregularDungeonNEW ()
{//echo("createIrregularDungeonNEW()");
	// Create and clear data structures.
	clearMapArr();
	if (isObject($RoomList))
	{
		for (%i = 0; %i < $RoomList.getCount(); %i++)
		{
			$RoomList.getObject(%i).safeDelete();
		}
		$RoomList.safeDelete();
	}
	$RoomList = new SimSet();
	
	// Place large-ish room in the center of the map - spawn marines here!
	%xStart = 13;//9;
	%yStart = 13;//$mazeDimension - 9;
	%width = getRandom(4, 5);
	%height = getRandom(4, 5);
	createRoom(%xStart, %yStart, %width, %height);
	
	// Spawn rooms in all four directions, NSEW!
	%maxRooms = 2;
	%lastRoomPosition = %xStart SPC %yStart SPC %width SPC %height;
	for (%i = 0; %i < %maxRooms; %i++)
	{//echo(%xStart SPC %yStart);
		%lastRoomPosition = pickRoomSizeAndPosition(%xStart, %yStart, %width, %height);
		%xStart = getWord(%lastRoomPosition, 0);
		%yStart = getWord(%lastRoomPosition, 1);
		%width = getWord(%lastRoomPosition, 2);
		%height = getWord(%lastRoomPosition, 3);
	//echo("%lastRoomPosition =" SPC %lastRoomPosition);
	}
	
	// Keep randomly spawning till some failure limit count!
	// Nothing here yet!
}
function pickRoomSizeAndPosition (%xStart, %yStart, %width, %height)
{//echo("pickRoomSizeAndPosition()");echoTestLevel();
//echo("room indices:" SPC %xStart SPC %yStart);
//echo("last room size:" SPC %width SPC %height);
	%mapBuffer = 2;
	%originalX = %xStart;
	%originalY = %yStart;
	%originalWidth = %width;
	%originalHeight = %height;
	%minWidth = 4;
	%maxWidth = 6;
	%minHeight = 4;
	%maxHeight = 6;
	%direction = getRandom(1, 4);
echo("%direction =" SPC getDirectionName(%direction));
	//%direction = $northDirection;	// For testing purposes only!
	//%direction = $southDirection;	// For testing purposes only!
	//%direction = $eastDirection;	// For testing purposes only!
	//%direction = $westDirection;	// For testing purposes only!
	switch (%direction)
	{
		case $northDirection:
			%yStart += %originalHeight - 1;	// So walls overlap in this direction.
			%width = getRandom(%minWidth, %maxWidth);
			%height = getRandom(%minHeight, %maxHeight);
		//echo(%width SPC %height);
			if (%xStart + %width  > $mazeDimension - %mapBuffer	||
				%yStart + %height > $mazeDimension - %mapBuffer)
			{//echo("no room created!");
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
			%roomPlaced = createRoom(%xStart, %yStart, %width, %height);
			if (%roomPlaced)
			{
				// Create door(s).
				%doorX = %xStart + getRandom(1, 2);
				%doorY = %originalY + %originalHeight - 1;
				$mapArr[%doorY, %doorX] = 4;
				return %xStart SPC %yStart SPC %width SPC %height;
			}
			else
			{
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
			
		case $southDirection:
			%yStart -= -2;	// So walls overlap in this direction.
			%width = getRandom(%minWidth, %maxWidth);
			%height = getRandom(%minHeight, %maxHeight);
			%yStart -= %height;
		//echo(%width SPC %height);
			if (%xStart + %width  > $mazeDimension - %mapBuffer	||
				%yStart + %height > $mazeDimension - %mapBuffer)
			{//echo("no room created!");
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
			%roomPlaced = createRoom(%xStart, %yStart, %width, %height);
			if (%roomPlaced)
			{
				// Create door(s).
				%doorX = %xStart + getRandom(1, 2);
				%doorY = %originalY + %height;
				$mapArr[%doorY, %doorX] = 4;
				return %xStart SPC %yStart SPC %width SPC %height;
			}
			else
			{
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
		
		case $eastDirection:
			%xStart += %originalWidth - 1;	// So walls overlap in this direction.
			%width = getRandom(%minWidth, %maxWidth);
			%height = getRandom(%minHeight, %maxHeight);
		//echo(%width SPC %height);
			if (%xStart + %width  > $mazeDimension - %mapBuffer	||
				%yStart + %height > $mazeDimension - %mapBuffer)
			{//echo("no room created!");
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
			%roomPlaced = createRoom(%xStart, %yStart, %width, %height);
			if (%roomPlaced)
			{
				// Create door(s).
				%doorX = %xStart;
				%doorY = %yStart + getRandom(1, 2);
				$mapArr[%doorY, %doorX] = 4;
				return %xStart SPC %yStart SPC %width SPC %height;
			}
			else
			{
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
			
		case $westDirection:
			%width = getRandom(%minWidth, %maxWidth);
			%height = getRandom(%minHeight, %maxHeight);
			%xStart -= %width - 1;	// So walls overlap in this direction.
		//echo(%width SPC %height);
			if (%xStart + %width  > $mazeDimension - %mapBuffer	||
				%yStart + %height > $mazeDimension - %mapBuffer)
			{//echo("no room created!");
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
			%roomPlaced = createRoom(%xStart, %yStart, %width, %height);
			if (%roomPlaced)
			{
				// Create door(s).
				%doorX = %originalX;
				%doorY = %yStart + getRandom(1, 2);
				$mapArr[%doorY, %doorX] = 4;
				return %xStart SPC %yStart SPC %width SPC %height;
			}
			else
			{
				return %originalX SPC %originalY SPC %originalWidth SPC %originalHeight;
			}
	}
}
function createRoom (%xStart, %yStart, %width, %height)
{//echo("createRoom()");
	/*for (%i = %xStart; %i < %xStart + %width; %i++)
	{
		for (%j = %yStart; %j < %yStart + %height; %j++)
		{
			if (%i < 0					||
				%i > $mazeDimension - 1	||
				%j < 0					||
				%j > $mazeDimension - 1)
			{
				return false;
			}
			if ($mapArr[%j, %i] != 1)	// Space.
			{
				return false;
			}
		}
	}*/
	for (%i = %xStart; %i < %xStart + %width; %i++)
	{
		for (%j = %yStart; %j < %yStart + %height; %j++)
		{
			if (%i == %xStart				||
				%i == %xStart +  %width - 1	||
				%j == %yStart				||
				%j == %yStart + %height - 1)
			{
				switch ($mapArr[%j, %i])
				{
					case 0:	// Floor.
						
					case 1:	// Space.
						$mapArr[%j, %i] = 2;	// Wall.
						
					case 4:	// Door.
				}
			}
			else
			{
				switch ($mapArr[%j, %i])
				{
					case 1:	// Space.
						$mapArr[%j, %i] = 0;	// Floor.
						
					case 4:	// Door.
				}
			}
		}
	}
	%room = new ScriptObject()
	{
		xStart = %xStart;
		yStart = %yStart;
		width = %width;
		height = %height;
	};
	$RoomList.add(%room);
	return true;
}