--[fnSpawnTitan]
--Spawns a resinous titan enemy. Exactly the same as a normal doll, with a slightly different transformation and majorly increased stats.
fnSpawnTitan = function(sSpawnLocation, sIdentifier, saPatrolList)
    
    --Argument check.
    gzTextVar.iLastSpawnedEntity = -1
    if(sSpawnLocation == nil) then return end
    if(sIdentifier == nil) then return end
    
    --If the patrol list is nil, then the doll will move randomly. We don't check it.
    
    --Location Resolver. If the first letter of the location is an "_" then we need to resolve the room's name
    -- by its coordinates on the 3D map.
    if(string.sub(sSpawnLocation, 1, 1) == "_") then
        
        --Subroutine does the work. Range-check it.
        local iIndex = fnGetRoomIndexFromString(sSpawnLocation)
        if(iIndex == -1 or iIndex >= gzTextVar.iRoomsTotal) then return end
        
        --Modify the sSpawnLocation to be the name of the room.
        sSpawnLocation = gzTextVar.zRoomList[iIndex].sName
    end
    
    --Go through the patrol list and do this modification to all of its entries, turning coordinates to names.
    if(saPatrolList ~= nil) then
        for i = 1, #saPatrolList, 1 do
            
            if(string.sub(saPatrolList[i], 1, 1) == "_") then
                
                --Subroutine does the work. Range-check it.
                local iIndex = fnGetRoomIndexFromString(saPatrolList[i])
                if(iIndex == -1 or iIndex >= gzTextVar.iRoomsTotal) then return end
                
                --Modify the sSpawnLocation to be the name of the room.
                saPatrolList[i] = gzTextVar.zRoomList[iIndex].sName
            end
        end
    end
    
    --Add space for a new entity.
    gzTextVar.zEntitiesTotal = gzTextVar.zEntitiesTotal + 1

    --Shorthand
    local i = gzTextVar.zEntitiesTotal

    --Possible names.
    if(gzTextVar.saDollNameList == nil) then
        gzTextVar.saDollNameList          = {"Francine", "Priscilla", "Rosemary", "Marilee", "Carolina", "Alice", "Melanie", "Jackqueline", "Florence", "Bonnie", "Tiffany"}
        gzTextVar.saDollLowercaseNameList = {"francine", "priscilla", "rosemary", "marilee", "carolina", "alice", "melanie", "jackqueline", "florence", "bonnie", "tiffany"}
    end

    --Roll a name. Retry until we get a legal one or make 100 attempts.
    local iAttemptsLeft = 100
    local bStop = false
    local iRoll = 1
    while(iAttemptsLeft > 0) do
        
        --Roll.
        bStop = false
        iAttemptsLeft = iAttemptsLeft - 1
        iRoll = LM_GetRandomNumber(1, #gzTextVar.saDollNameList)
        
        --Check if the name is taken. If it is, reroll.
        for p = 1, gzTextVar.zEntitiesTotal - 1, 1 do
            if(gzTextVar.zEntities[p].sQueryName == gzTextVar.saDollLowercaseNameList[iRoll]) then
                bStop = true
                break
            end
        end
        
        --Exit case.
        if(bStop == false) then break end
    end

    --Couldn't generate a legal name.
    if(iAttemptsLeft == 0) then
        gzTextVar.zEntitiesTotal = gzTextVar.zEntitiesTotal - 1
        return
    end

    --Strings
    gzTextVar.iLastSpawnedEntity = i
    gzTextVar.zEntities[i] = {}
    gzTextVar.zEntities[i].sDisplayName = gzTextVar.saDollNameList[iRoll]
    gzTextVar.zEntities[i].sQueryName = gzTextVar.saDollLowercaseNameList[iRoll]
    gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/Doll Dancer E"
    gzTextVar.zEntities[i].sUniqueName = gzTextVar.saDollLowercaseNameList[iRoll]
    gzTextVar.zEntities[i].sLocation = sSpawnLocation
    gzTextVar.zEntities[i].sSpecialIdentifier = sIdentifier
    
    --Skin color.
    local sEndLetter = "E"
    
    --Sets. No differences exist between these except appearances.
    local iTypeRoll = LM_GetRandomNumber(1, 6)
    if(iTypeRoll == 1) then
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/Doll Bride " .. sEndLetter
    elseif(iTypeRoll == 2) then
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/Doll Dancer " .. sEndLetter
    elseif(iTypeRoll == 3) then
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/Doll Geisha " .. sEndLetter
    elseif(iTypeRoll == 4) then
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/Doll Goth " .. sEndLetter
    elseif(iTypeRoll == 5) then
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/Doll Princess " .. sEndLetter
    else
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/Doll Punk " .. sEndLetter
    end
    
    --Debug: Randomly rolls a location.
    if(false) then
        while(gzTextVar.iRoomsTotal > 0) do
            
            --Random location.
            local iRoll = LM_GetRandomNumber(1, gzTextVar.iRoomsTotal)
            
            --Check if the room is the one the player is currently in. If it is, we can't spawn there.
            if(gzTextVar.zRoomList[iRoll].sName == gzTextVar.gzPlayer.sLocation) then
            
            --Check if this room is the Main Hall. We can't spawn there since it's protected.
            elseif(gzTextVar.zRoomList[iRoll].sName == "Main Hall") then
            
            --All checks passed. Spawn.
            else
                gzTextVar.zEntities[i].sLocation = gzTextVar.zRoomList[iRoll].sName
                break
            end
        end
    
    --Debug force position.
    elseif(false) then
        gzTextVar.zEntities[i].sLocation = "Main Hall"
    end

    --[AI Variables and Paths]
    --Command Handler
    gzTextVar.zEntities[i].sCommandHandler = gzTextVar.sEntityHandlers .. "Doll.lua"
    gzTextVar.zEntities[i].sAIHandlerHostility = "Titan"
    gzTextVar.zEntities[i].sAIHandlerPostTurn = "Titan"
    gzTextVar.zEntities[i].sAIHandlerPrimary = "Titan"
    gzTextVar.zEntities[i].iMoveIndex = -1
    gzTextVar.zEntities[i].iPatrolIndex = 1
    if(saPatrolList ~= nil) then
        gzTextVar.zEntities[i].saPatrolList = saPatrolList
        gzTextVar.zEntities[i].bMovesRandomly = false
    else
        gzTextVar.zEntities[i].saPatrolList = {"None"}
        gzTextVar.zEntities[i].bMovesRandomly = true
    end
    gzTextVar.zEntities[i].iStayStillTurns = 0
    gzTextVar.zEntities[i].sLastDoorDir = "P"
    gzTextVar.zEntities[i].sIndicatorName = gzTextVar.zEntities[i].sUniqueName
    gzTextVar.zEntities[i].sFirstSawPlayer = "Nowhere"
    gzTextVar.zEntities[i].sLastSawPlayer = "Nowhere"
    gzTextVar.zEntities[i].iChanceToForget = 20
    gzTextVar.zEntities[i].sInDisguise = "Null"

    --[Combat Properties]
    --Resin Titans maintain their high HP in all difficulties, only DPS goes down.
    gzTextVar.zEntities[i].zCombatTable = {}
    
    --Easy:
    if(gzTextVar.sDifficulty == "Easy") then
        local fTimeFactor = 2.00
        gzTextVar.zEntities[i].zCombatTable.iHealth = 120
        gzTextVar.zEntities[i].zCombatTable.iAttacksTotal = 4
        gzTextVar.zEntities[i].zCombatTable.zAttacks = {}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[1] = { 50,  1,  60 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[2] = {100,  6, 270 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[3] = {100,  8, 360 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[4] = { 20, 12, 630 * fTimeFactor, 0}
    
    --Normal:
    elseif(gzTextVar.sDifficulty == "Normal") then
        local fTimeFactor = 1.50
        gzTextVar.zEntities[i].zCombatTable.iHealth = 120
        gzTextVar.zEntities[i].zCombatTable.iAttacksTotal = 4
        gzTextVar.zEntities[i].zCombatTable.zAttacks = {}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[1] = { 50,  1,  60 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[2] = {100,  6, 270 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[3] = {100,  8, 360 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[4] = { 20, 12, 630 * fTimeFactor, 0}
    
    --Hard:
    else
        local fTimeFactor = 1.00
        gzTextVar.zEntities[i].zCombatTable.iHealth = 120
        gzTextVar.zEntities[i].zCombatTable.iAttacksTotal = 4
        gzTextVar.zEntities[i].zCombatTable.zAttacks = {}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[1] = { 50,  1,  60 * fTimeFactor, 0} --1.00 DPS
        gzTextVar.zEntities[i].zCombatTable.zAttacks[2] = {100,  6, 270 * fTimeFactor, 0} --1.33 DPS
        gzTextVar.zEntities[i].zCombatTable.zAttacks[3] = {100,  8, 360 * fTimeFactor, 0} --1.33 DPS
        gzTextVar.zEntities[i].zCombatTable.zAttacks[4] = { 20, 12, 630 * fTimeFactor, 0} --1.14 DPS
    end
    
    --Weaknesses. Titans are just as weak to fire as dolls.
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses = {}
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Fire] = 1
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Water] = 0
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Wind] = 0
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Earth] = 0
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Life] = 0
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Death] = 0
    
    --[Indicator]
    --Resolve indicator position based on doll type.
    local fX, fY, fZ = fnGetRoomPosition(gzTextVar.zEntities[i].sLocation)
    local iIndicatorX = 0
    if(iTypeRoll == 1) then
        iIndicatorX = 1
    elseif(iTypeRoll == 2) then
        iIndicatorX = 2
    elseif(iTypeRoll == 3) then
        iIndicatorX = 3
    elseif(iTypeRoll == 4) then
        iIndicatorX = 0
    elseif(iTypeRoll == 5) then
        iIndicatorX = 4
    else
        iIndicatorX = 5
    end
    
    --Offset gains +11 since the resinous indicators are on the same row but offset.
    gzTextVar.zEntities[i].bIndicatorRed = true
    gzTextVar.zEntities[i].iIndicatorX = iIndicatorX + 11
    gzTextVar.zEntities[i].iIndicatorY = 4
    gzTextVar.zEntities[i].iIndicatorC = ciCodeUnfriendly
    gzTextVar.zEntities[i].iIndicatorH = 0
    TL_SetProperty("Register Entity Indicator", fX, fY, fZ, gzTextVar.zEntities[i].sIndicatorName, gzTextVar.zEntities[i].iIndicatorX, gzTextVar.zEntities[i].iIndicatorY, gzTextVar.zEntities[i].iIndicatorC)
    
    --Determine Hostility
    if(gzTextVar.gzPlayer.sFormState == "Human") then
        gzTextVar.zEntities[i].iIndicatorH = 2
        TL_SetProperty("Modify Entity Indicator Hosility", fX, fY, fZ, gzTextVar.zEntities[i].sIndicatorName, ciHostilityX_Boss, ciHostilityY_Boss)
    end
end