--[ ======================================= Door Handler ======================================== ]
--Script to handle the opening and closing of doors. Handles locks and keys as well.
--Sets the handler variable if it handled the input.

--Argument Listing:
-- 0: sString - The string to be handled. Should be in all lowercase.

--Arg check.
local iRequiredArgs = 1
local iArgs = LM_GetNumOfArgs()
if(iArgs < iRequiredArgs) then
	Debug_ForcePrint(fnResolvePath() .. ": Error, incorrect argument count. Got " .. iArgs .. " expected " .. iRequiredArgs .. ".\n")
	return
end

--Arg resolve.
local sString = LM_GetScriptArgument(0)

--[Setup]
--Get current room.
local iRoomIndex = fnGetRoomIndex(gzTextVar.gzPlayer.sLocation)
if(iRoomIndex == -1) then return end

--[OpenClose]
--Does both open and close, whichever is needed based on the direction provided. First, handle if no direction is provided.
if(sString == "openclose" or sString == "openclose ") then

    --Check the directions. If there is exactly one door, operate on that door.
    local iDoorCount = 0
    local sDoorInDirection = "Null"
    if(gzTextVar.zRoomList[iRoomIndex].sDoorN ~= nil) then
        iDoorCount = iDoorCount + 1
        sDoorInDirection = "n"
    end
    if(gzTextVar.zRoomList[iRoomIndex].sDoorE ~= nil) then
        iDoorCount = iDoorCount + 1
        sDoorInDirection = "e"
    end
    if(gzTextVar.zRoomList[iRoomIndex].sDoorS ~= nil) then
        iDoorCount = iDoorCount + 1
        sDoorInDirection = "s"
    end
    if(gzTextVar.zRoomList[iRoomIndex].sDoorW ~= nil) then
        iDoorCount = iDoorCount + 1
        sDoorInDirection = "w"
    end
    
    --More than one direction, print a message:
    if(iDoorCount > 1) then
        gbHandledInput = true
        TL_SetProperty("Append", "Please specify a direction, [n, s, e, w]. " .. iDoorCount .. " " .. gsDE)
        return

    --No doors.
    elseif(iDoorCount == 0) then
        gbHandledInput = true
        TL_SetProperty("Append", "There are no doors here." .. gsDE)
        return
        
    --Exactly one door. Modify the base string, proceed.
    else
        sString = "openclose " .. sDoorInDirection
    end
end

--OpenClose operation with a direction specified.
if(string.sub(sString, 1, 10)  == "openclose ") then

    --Direction will be the first letter after the command.
    local sDirection = string.sub(sString, 11, 11)

    --Check the door in that direction.
    local sDoorString = "Null"
    if(sDirection == "n") then
        sDoorString = gzTextVar.zRoomList[iRoomIndex].sDoorN
    elseif(sDirection == "e") then
        sDoorString = gzTextVar.zRoomList[iRoomIndex].sDoorE
    elseif(sDirection == "s") then
        sDoorString = gzTextVar.zRoomList[iRoomIndex].sDoorS
    elseif(sDirection == "w") then
        sDoorString = gzTextVar.zRoomList[iRoomIndex].sDoorW
    end
    
    --Now get the door's state. First, if no door exists:
    if(sDoorString== nil) then
        gbHandledInput = true
        TL_SetProperty("Append", "There is no door in that direction." .. gsDE)
        return
        
    --Door is closed:
    elseif(string.sub(sDoorString, 1, 1) == "C") then
        sString = "open " .. sDirection
        
    --Door is open:
    elseif(string.sub(sDoorString, 1, 1) == "O") then
        sString = "close " .. sDirection
    end
end

--[Open Handler]
if(string.sub(sString, 1, 4) == "open") then
    
    --Flag
    gbHandledInput = true
    
    --Check if there is only one door in the room. If so, "open" is modified to open that door.
    if(sString == "open" or sString == "open ") then
        
        --Scan the room directions.
        local iDoorsTotal = 0
        local sDoorDir = "null"
        if(gzTextVar.zRoomList[iRoomIndex].sDoorN ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorN, 1, 1) == "C") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "n"
        end
        if(gzTextVar.zRoomList[iRoomIndex].sDoorE ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorE, 1, 1) == "C") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "e"
        end
        if(gzTextVar.zRoomList[iRoomIndex].sDoorS ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorS, 1, 1) == "C") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "s"
        end
        if(gzTextVar.zRoomList[iRoomIndex].sDoorW ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorW, 1, 1) == "C") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "w"
        end
        
        --If there is exactly one door:
        if(iDoorsTotal == 1) then
            sString = "open " .. sDoorDir
        end
    end
    
    --Direction.
    local sDirection = string.sub(sString, 6, 6)

    --[Hypnotized Mary]
    --If Mary is hypnotized and a human, she cannot open any doors.
    if(gzTextVar.gzPlayer.sFormState == "Human" and gzTextVar.iHypnoticCheck >= 10) then
        
        --Player is at the Stone Gallery, fail all moves.
        if(gzTextVar.gzPlayer.sLocation == "Stone Gallery") then
            TL_SetProperty("Append", "You WILL NOT OPEN THAT DOOR. You will GAZE INTO THE LIGHT. You will OBEY THE LIGHT." .. gsDE)
            return
        end

    --Human, not hypnotised, but in the Stone Gallery and the light hasn't been dealt with. Western opens are illegal.
    elseif(gzTextVar.gzPlayer.sFormState == "Human" and gzTextVar.iHypnoticCheck < 10 and gzTextVar.gzPlayer.sLocation == "Stone Gallery") then
        if(sDirection == "w") then
            
            --Have not disabled the light.
            if(gzTextVar.bDisabledLight == false) then
                TL_SetProperty("Append", "You try to open the door to the west, but your hands fail to grasp the knob. Something tells you to OBEY THE LIGHT and GAZE INTO THE LIGHT." .. gsDE)
            --Have disabled the light, but haven't told Jessie and Lauren.
            elseif(gzTextVar.bDisabledLightCutscene == false) then
                TL_SetProperty("Append", "Now that the light has been taken care of, you should go let Lauren and Jessie know it's safe here." .. gsDE)
            else
                TL_SetProperty("Append", "You try to open the door to the west, but your hands fail to grasp the knob. Something tells you to OBEY THE LIGHT and GAZE INTO THE LIGHT." .. gsDE)
            end
            return
        end
    
    --Statue, Claygirl, Doll. Cannot open the door unless Jessie or Lauren are there.
    elseif(gzTextVar.gzPlayer.sFormState ~= "Human" and gzTextVar.gzPlayer.sLocation == "Stone Gallery") then
        if(sDirection == "w") then
            
            --If Jessie or Lauren is in the room, you can open it.
            if(gzTextVar.zEntities[gzTextVar.iJessieIndex].sLocation == "Pygmalie's Study" or gzTextVar.zEntities[gzTextVar.iLaurenIndex].sLocation == "Pygmalie's Study") then
            
            --Otherwise, error.
            else
                if(gzTextVar.gzPlayer.sFormState == "Statue") then
                    TL_SetProperty("Append", "THE INTRUDERS ARE NOT WITHIN THAT ROOM. FIND THE INTRUDERS. OBEY." .. gsDE)
                    return
                elseif(gzTextVar.gzPlayer.sFormState == "Claygirl") then
                    TL_SetProperty("Append", "Something tells you not to go in that room. It tells you that you have no reason to be there. You ignore the door." .. gsDE)
                    return
                else
                    
                    --In phase 6 the player can open the door.
                    if(gzTextVar.iGameStage ~= 6) then
                        TL_SetProperty("Append", "You feel odd. The room beyond suddenly seems so boring. You really should go play somewhere else." .. gsDE)
                        return
                    end
                end
            end
        end
    end
    
    --North.
    if(sDirection == "n") then
        
        --Flags.
        local sPrintString = "You open the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveN
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorN == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your north." .. gsDE)
            
        --Door is already open.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorN, 1, 1) == "O") then
            TL_SetProperty("Append", "The door is already open." .. gsDE)
            
        --Door can be opened. Check key states.
        else
        
            --Get the string past the first letter. This is the key state.
            local sDoorState = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorN, 1, 1)
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorN, 2)
            local bOpenedDoor = true
            local sPrintString = "You open the door." .. gsDE
            local sOpenSound = "Doll|OpenDoor"
            
            --Clay lock, triggers the special sequence if the clay house is not disarmed. Is otherwise
            -- the same as a normal lock.
            if(sLockType == " Clay") then
                if(gzTextVar.bClayDisarmed == false) then
                    gzTextVar.bClayDoorThisTurn = true
                end
            
            --Unopenable.
            elseif(sLockType == " ClayUnopenable") then
                bOpenedDoor = false
                sPrintString = "The door has merged with the wall, completely cutting access from this room!" .. gsDE
                
            --Check if the lock can't be opened.
            elseif(sLockType ~= " Normal" and sLockType ~= " None") then
                bOpenedDoor, sPrintString = fnCheckKeyStates(sLockType)
                sOpenSound = "Doll|OpenDoorLocked"
            end
            
            --Check if we failed to open the door.
            if(bOpenedDoor == false) then
                TL_SetProperty("Append", sPrintString)
                fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirNorth)
                return
            end
            
            --Small keys destroy one of the small keys in our inventory.
            if(sLockType == " Small") then
                for i = 1, gzTextVar.gzPlayer.iItemsTotal, 1 do
                    if(gzTextVar.gzPlayer.zaItems[i].sDisplayName == "small key") then
                        fnRemoveItemFromInventory(i)
                        break
                    end
                end
            end
            
            --We need the positions of the destination room, since its south door is being displayed.
            local fX, fY, fZ = fnGetRoomPosition(sDestination)
            
            --Once opened, special doors lose their lock type.
            sLockType = " Normal"
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "O Normal", "N", ciModifyVisibility, 1)
            fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirNorth)
            
            --SFX.
            AudioManager_PlaySound(sOpenSound)
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end
        
    --East.
    elseif(sDirection == "e") then
        
        --Flags.
        local sPrintString = "You open the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveE
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorE == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your east." .. gsDE)
            
        --Door is already open.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorE, 1, 1) == "O") then
            TL_SetProperty("Append", "The door is already open." .. gsDE)
            
        --Door can be opened. Check key states.
        else
        
            --Get the string past the first letter. This is the key state.
            local sDoorState = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorE, 1, 1)
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorE, 2)
            local bOpenedDoor = true
            local sPrintString = "You open the door." .. gsDE
            local sOpenSound = "Doll|OpenDoor"
            
            --Clay lock, triggers the special sequence if the clay house is not disarmed. Is otherwise
            -- the same as a normal lock.
            if(sLockType == " Clay") then
                if(gzTextVar.bClayDisarmed == false) then
                    gzTextVar.bClayDoorThisTurn = true
                end
            
            --Unopenable.
            elseif(sLockType == " ClayUnopenable") then
                bOpenedDoor = false
                sPrintString = "The door has merged with the wall, completely cutting access from this room!" .. gsDE
            
            --Check if the lock can't be opened.
            elseif(sLockType ~= " Normal" and sLockType ~= " None") then
                bOpenedDoor, sPrintString = fnCheckKeyStates(sLockType)
                sOpenSound = "Doll|OpenDoorLocked"
            end
            
            --Check if we failed to open the door.
            if(bOpenedDoor == false) then
                TL_SetProperty("Append", sPrintString)
                fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirEast)
                return
            end
            
            --Small keys destroy one of the small keys in our inventory.
            if(sLockType == " Small") then
                for i = 1, gzTextVar.gzPlayer.iItemsTotal, 1 do
                    if(gzTextVar.gzPlayer.zaItems[i].sDisplayName == "small key") then
                        fnRemoveItemFromInventory(i)
                        break
                    end
                end
            end
            
            --We need the positions of the destination room, since its south door is being displayed.
            local fX, fY, fZ = fnGetRoomPosition(gzTextVar.gzPlayer.sLocation)
            
            --Once opened, special doors lose their lock type.
            sLockType = " Normal"
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "O Normal", "E", ciModifyVisibility, 1)
            fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirEast)
            
            --SFX.
            AudioManager_PlaySound(sOpenSound)
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end
    
    --South.
    elseif(sDirection == "s") then
        
        --Flags.
        local sPrintString = "You open the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveS
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorS == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your south." .. gsDE)
            
        --Door is already open.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorS, 1, 1) == "O") then
            TL_SetProperty("Append", "The door is already open." .. gsDE)
            
        --Door can be opened. Check key states.
        else
        
            --Get the string past the first letter. This is the key state.
            local sDoorState = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorS, 1, 1)
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorS, 2)
            local bOpenedDoor = true
            local sPrintString = "You open the door." .. gsDE
            local sOpenSound = "Doll|OpenDoor"
            
            --Clay lock, triggers the special sequence if the clay house is not disarmed. Is otherwise
            -- the same as a normal lock.
            if(sLockType == " Clay") then
                if(gzTextVar.bClayDisarmed == false) then
                    gzTextVar.bClayDoorThisTurn = true
                end
            
            --Unopenable.
            elseif(sLockType == " ClayUnopenable") then
                bOpenedDoor = false
                sPrintString = "The door has merged with the wall, completely cutting access from this room!" .. gsDE
            
            --Check if the lock can't be opened.
            elseif(sLockType ~= " Normal" and sLockType ~= " None") then
                bOpenedDoor, sPrintString = fnCheckKeyStates(sLockType)
                sOpenSound = "Doll|OpenDoorLocked"
            end
            
            --Check if we failed to open the door.
            if(bOpenedDoor == false) then
                TL_SetProperty("Append", sPrintString)
                fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirSouth)
                return
            end
            
            --Small keys destroy one of the small keys in our inventory.
            if(sLockType == " Small") then
                for i = 1, gzTextVar.gzPlayer.iItemsTotal, 1 do
                    if(gzTextVar.gzPlayer.zaItems[i].sDisplayName == "small key") then
                        fnRemoveItemFromInventory(i)
                        break
                    end
                end
            end
            
            --We need the positions of the destination room, since its south door is being displayed.
            local fX, fY, fZ = fnGetRoomPosition(gzTextVar.gzPlayer.sLocation)
            
            --Once opened, special doors lose their lock type.
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "O Normal", "S", ciModifyVisibility, 1)
            fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirSouth)
            
            --SFX.
            AudioManager_PlaySound(sOpenSound)
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end
    
    --West.
    elseif(sDirection == "w") then
        
        --Flags.
        local sPrintString = "You open the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveW
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorW == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your west." .. gsDE)
            
        --Door is already open.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorW, 1, 1) == "O") then
            TL_SetProperty("Append", "The door is already open." .. gsDE)
            
        --Door can be opened. Check key states.
        else
        
            --Get the string past the first letter. This is the key state.
            local sDoorState = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorW, 1, 1)
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorW, 2)
            local bOpenedDoor = true
            local sPrintString = "You open the door." .. gsDE
            local sOpenSound = "Doll|OpenDoor"
            
            --Clay lock, triggers the special sequence if the clay house is not disarmed. Is otherwise
            -- the same as a normal lock.
            if(sLockType == " Clay") then
                if(gzTextVar.bClayDisarmed == false) then
                    gzTextVar.bClayDoorThisTurn = true
                end
            
            --Unopenable.
            elseif(sLockType == " ClayUnopenable") then
                bOpenedDoor = false
                sPrintString = "The door has merged with the wall, completely cutting access from this room!" .. gsDE
            
            --Check if the lock can't be opened.
            elseif(sLockType ~= " Normal" and sLockType ~= " None") then
                bOpenedDoor, sPrintString = fnCheckKeyStates(sLockType)
                sOpenSound = "Doll|OpenDoorLocked"
            end
            
            --Check if we failed to open the door.
            if(bOpenedDoor == false) then
                TL_SetProperty("Append", sPrintString)
                fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirWest)
                return
            end
            
            --Small keys destroy one of the small keys in our inventory.
            if(sLockType == " Small") then
                for i = 1, gzTextVar.gzPlayer.iItemsTotal, 1 do
                    if(gzTextVar.gzPlayer.zaItems[i].sDisplayName == "small key") then
                        fnRemoveItemFromInventory(i)
                        break
                    end
                end
            end
            
            --We need the positions of the destination room, since its south door is being displayed.
            local fX, fY, fZ = fnGetRoomPosition(sDestination)
            
            --Once opened, special doors lose their lock type.
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "O Normal", "W", ciModifyVisibility, 1)
            fnMarkLockAsKnown(iRoomIndex, gzTextCon.iDirWest)
            
            --SFX.
            AudioManager_PlaySound(sOpenSound)
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end

    --Error.
    else
        TL_SetProperty("Append", "Please specify a direction (N, E, S, or W)." .. gsDE)
    end

    --Rebuild sound.
    LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Rebuild Sound.lua")

    return
end

--[Close Handler]
if(string.sub(sString, 1, 5) == "close") then
    
    --Flag
    gbHandledInput = true
    
    --Check if there is only one door in the room. If so, "open" is modified to open that door.
    if(sString == "close" or sString == "close ") then
        
        --Scan the room directions.
        local iDoorsTotal = 0
        local sDoorDir = "null"
        if(gzTextVar.zRoomList[iRoomIndex].sDoorN ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorN, 1, 1) == "O") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "n"
        end
        if(gzTextVar.zRoomList[iRoomIndex].sDoorE ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorE, 1, 1) == "O") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "e"
        end
        if(gzTextVar.zRoomList[iRoomIndex].sDoorS ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorS, 1, 1) == "O") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "s"
        end
        if(gzTextVar.zRoomList[iRoomIndex].sDoorW ~= nil and string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorW, 1, 1) == "O") then
            iDoorsTotal = iDoorsTotal + 1
            sDoorDir = "w"
        end
        
        --If there is exactly one door:
        if(iDoorsTotal == 1) then
            sString = "close " .. sDoorDir
        end
    end
    
    --Direction.
    local sDirection = string.sub(sString, 7, 7)
    
    --North.
    if(sDirection == "n") then
        
        --Flags.
        local sPrintString = "You close the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveN
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorN == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your north." .. gsDE)
            
        --Door is already closed.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorN, 1, 1) == "C") then
            TL_SetProperty("Append", "The door is already closed." .. gsDE)
            
        --Door can be closed.
        else
        
            --Get the string past the first letter. This is the key state.
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorN, 2)
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "C" .. sLockType, "N", ciModifyVisibility, 1)
            
            --SFX.
            AudioManager_PlaySound("Doll|CloseDoor")
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end
        
    --East.
    elseif(sDirection == "e") then
        
        --Flags.
        local sPrintString = "You close the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveE
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorE == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your east." .. gsDE)
            
        --Door is already closed.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorE, 1, 1) == "C") then
            TL_SetProperty("Append", "The door is already closed." .. gsDE)
            
        --Door can be opened. Check key states.
        else
        
            --Get the string past the first letter. This is the key state.
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorE, 2)
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "C" .. sLockType, "E", ciModifyVisibility, 1)
            
            --SFX.
            AudioManager_PlaySound("Doll|CloseDoor")
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end
    
    --South.
    elseif(sDirection == "s") then
        
        --Flags.
        local sPrintString = "You close the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveS
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorS == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your south." .. gsDE)
            
        --Door is already closed.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorS, 1, 1) == "C") then
            TL_SetProperty("Append", "The door is already closed." .. gsDE)
            
        --Door can be closed. Check key states.
        else
        
            --Get the string past the first letter. This is the key state.
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorS, 2)
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "C" .. sLockType, "S", ciModifyVisibility, 1)
            
            --SFX.
            AudioManager_PlaySound("Doll|CloseDoor")
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end
    
    --West.
    elseif(sDirection == "w") then
        
        --Flags.
        local sPrintString = "You close the door." .. gsDE
        local sDestination = gzTextVar.zRoomList[iRoomIndex].sMoveW
        local iDestIndex = fnGetRoomIndex(sDestination)
        
        --No door or no connection.
        if(gzTextVar.zRoomList[iRoomIndex].sDoorW == nil or iDestIndex == -1) then
            TL_SetProperty("Append", "There is no door to your west." .. gsDE)
            
        --Door is already open.
        elseif(string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorW, 1, 1) == "C") then
            TL_SetProperty("Append", "The door is already closed." .. gsDE)
            
        --Door can be opened. Check key states.
        else
        
            --Get the string past the first letter. This is the key state.
            local sLockType = string.sub(gzTextVar.zRoomList[iRoomIndex].sDoorW, 2)
            LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Modify Door State.lua", gzTextVar.gzPlayer.sLocation, "C" .. sLockType, "W", ciModifyVisibility, 1)
            
            --SFX.
            AudioManager_PlaySound("Doll|CloseDoor")
            
            --Printout.
            TL_SetProperty("Append", sPrintString)

            --End the turn.
            LM_ExecuteScript(gzTextVar.sTurnEndScript)
        end

    --Error.
    else
        TL_SetProperty("Append", "Please specify a direction (N, E, S, or W)." .. gsDE)
    end

    --Rebuild sound.
    LM_ExecuteScript(gzTextVar.sRootPath .. "Functions/Rebuild Sound.lua")

    return
end