--[ ===================================== fnSpawnClayGirl() ===================================== ]
--Spawns a claygirl enemy. These spawn in any room that the player cannot currently see and that has an item in it that
-- the claygirl can disguise as. If there are no items to disguise as, the claygirl spawns and instead paths randomly
-- to rooms within 4 movements of its location.
--Providing a location causes the clay girl to spawn at that location and not take a disguise. If not provided, the
-- default disguise behavior executes. The location can use numeric notation "_XxYxZ".
fnSpawnClayGirl = function(sUniqueIdentifier, sLocation, saPatrolList)
    
    --[Setup]
    --Argument check.
    gzTextVar.iLastSpawnedEntity = -1
    if(sUniqueIdentifier == nil) then return end
    
    --Setup.
    local sSelectedRoom = "Null"
    local bSpawnInDisguise = true
    local sDisguiseObject = "Null"
        
    --[No Location, Spawn In Disguise]
    if(sLocation == nil) then
        
        --Iterate across all rooms. Make a list of rooms that have an item in them. The list of legal items
        -- that can be disguised as is set up in the Scenario Builder file.
        --This does not execute if sLocation is not nil.
        if(gzTextVar.iClaygirlDisguisesTotal >= 1 and sLocation == nil) then
            
            --Build a list of all the rooms we can use.
            local iEntries = 0
            local iaRoomList = {}
            
            --Iterate.
            for i = 1, gzTextVar.iRoomsTotal, 1 do
            
                --Scan the items. Any one match is enough.
                for p = 1, gzTextVar.zRoomList[i].iObjectsTotal, 1 do
                    
                    --Now cross reference with the disguise list. Holy moly!
                    for u = 1, gzTextVar.iClaygirlDisguisesTotal, 1 do
                        
                        --Match.
                        if(gzTextVar.saClaygirlDisguises[u] == gzTextVar.zRoomList[i].zObjects[p].sUniqueName) then
                            
                            --Record.
                            iEntries = iEntries + 1
                            iaRoomList[iEntries] = i
     
                            --Break out of the two inner loops.
                            u = gzTextVar.iClaygirlDisguisesTotal
                            p = gzTextVar.zRoomList[i].iObjectsTotal
                        end
                    end
                end
            end
            
            --Debug.
            --io.write("Found " .. iEntries .. " legal locations for a claygirl to spawn.\n")
            
            --If there was at least one entry, roll!
            if(iEntries > 0) then
            
                --Roll!
                local iRoll = LM_GetRandomNumber(1, iEntries)
            
                --Store the name of the rolled room.
                local iIndex = iaRoomList[iRoll]
                sSelectedRoom = gzTextVar.zRoomList[iIndex].sName
                
                --Next, pick a random disguisable object in the room and disguise as that. It's rare that
                -- there will be more than one but hey, screw you.
                local iDisguiseCandidatesTotal = 0
                local saDisguiseCandidates = {}
            
                --Scan the items.
                for p = 1, gzTextVar.zRoomList[iIndex].iObjectsTotal, 1 do
                    
                    --Now cross reference with the disguise list.
                    for u = 1, gzTextVar.iClaygirlDisguisesTotal, 1 do
                        
                        --Match.
                        if(gzTextVar.saClaygirlDisguises[u] == gzTextVar.zRoomList[iIndex].zObjects[p].sUniqueName) then
                            
                            --Record.
                            iDisguiseCandidatesTotal = iDisguiseCandidatesTotal + 1
                            saDisguiseCandidates[iDisguiseCandidatesTotal] = gzTextVar.zRoomList[iIndex].zObjects[p].sUniqueName
                        end
                    end
                end
                
                --Pick a disguise candidate.
                local iDisguiseRoll = LM_GetRandomNumber(1, iDisguiseCandidatesTotal)
                sDisguiseObject = saDisguiseCandidates[iDisguiseRoll]
            
                --Debug.
                --io.write("Roll: " .. iRoll .. " max was " .. iEntries .. "\n")
                --io.write("Room index: " .. iIndex .. "\n")
                --io.write("Room name: " .. sSelectedRoom .. "\n")
                --io.write("Disguise candidates: " .. iDisguiseCandidatesTotal .. "\n")
                --io.write("Disguise roll: " .. iDisguiseRoll .. "\n")
                --io.write("Disguise object: " .. sDisguiseObject .. "\n")
            
            end
        end
        
        --If we have no selected room, it can be because there are no legal disguises, or because there
        -- are no rooms that contain a legally disguisable item. In any case, don't spawn.
        if(sSelectedRoom == "Null") then return end
    
    --[Has Location, Spawn as Patroller]
    else
    
        --Don't spawn in disguise.
        bSpawnInDisguise = false
    
        --If location is not nil, and is a numeric notation, switch it to a room name.
        if(string.sub(sLocation, 1, 1) == "_") then
            
            --Subroutine does the work. Range-check it.
            local iIndex = fnGetRoomIndexFromString(sLocation)
            if(iIndex == -1 or iIndex >= gzTextVar.iRoomsTotal) then return end
            
            --Modify the sSpawnLocation to be the name of the room.
            sLocation = gzTextVar.zRoomList[iIndex].sName
        end
        
        --Set.
        sSelectedRoom = sLocation
        
        --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
    end
    
    --[Entity Creation]
    --Add space for a new entity.
    gzTextVar.zEntitiesTotal = gzTextVar.zEntitiesTotal + 1

    --Shorthand
    local i = gzTextVar.zEntitiesTotal

    --Strings
    gzTextVar.iLastSpawnedEntity = i
    gzTextVar.zEntities[i] = {}
    gzTextVar.zEntities[i].sDisplayName = "Clay Girl"
    gzTextVar.zEntities[i].sQueryName = "clay girl"
    gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/ClayGirlBlue"
    gzTextVar.zEntities[i].sUniqueName = sUniqueIdentifier
    gzTextVar.zEntities[i].sLocation = sSelectedRoom
    gzTextVar.zEntities[i].sSpecialIdentifier = sUniqueIdentifier
    
    --Sets. No differences exist between these except appearances.
    local iTypeRoll = LM_GetRandomNumber(1, 3)
    if(iTypeRoll == 1) then
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/ClayGirlBlue"
    elseif(iTypeRoll == 2) then
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/ClayGirlRed"
    else
        gzTextVar.zEntities[i].sQueryPicture = "Root/Images/DollManor/Characters/ClayGirlYellow"
    end

    --[AI Paths and Variables]
    --Command Handler
    gzTextVar.zEntities[i].sCommandHandler = gzTextVar.sEntityHandlers .. "Claygirl.lua"
    gzTextVar.zEntities[i].sAIHandlerHostility = "Claygirl"
    gzTextVar.zEntities[i].sAIHandlerPostTurn = "Claygirl"
    gzTextVar.zEntities[i].sAIHandlerPrimary = "Claygirl"
    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 = 30
    gzTextVar.zEntities[i].sInDisguise = sDisguiseObject

    --[Combat]
    --Combat Properties. Claygirls have less HP as difficulty goes down, but not as severely as dolls. Also, the 
    -- odds of their rolling their high-DPS attack decreases in addition to slowing the attacks down.
    gzTextVar.zEntities[i].zCombatTable = {}
    gzTextVar.zEntities[i].zCombatTable.bScalesWithPhase = true
    
    --Easy:
    if(gzTextVar.sDifficulty == "Easy") then
        local fTimeFactor = 2.00
        gzTextVar.zEntities[i].zCombatTable.iHealth = 35
        gzTextVar.zEntities[i].zCombatTable.iAttacksTotal = 2
        gzTextVar.zEntities[i].zCombatTable.zAttacks = {}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[1] = {100,  5, 360 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[2] = {  5,  5,  90 * fTimeFactor, 0}
    
    --Normal:
    elseif(gzTextVar.sDifficulty == "Normal") then
        local fTimeFactor = 1.50
        gzTextVar.zEntities[i].zCombatTable.iHealth = 40
        gzTextVar.zEntities[i].zCombatTable.iAttacksTotal = 2
        gzTextVar.zEntities[i].zCombatTable.zAttacks = {}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[1] = {100,  5, 360 * fTimeFactor, 0}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[2] = { 10,  5,  90 * fTimeFactor, 0}
    
    --Hard:
    else
        local fTimeFactor = 1.00
        gzTextVar.zEntities[i].zCombatTable.iHealth = 45
        gzTextVar.zEntities[i].zCombatTable.iAttacksTotal = 2
        gzTextVar.zEntities[i].zCombatTable.zAttacks = {}
        gzTextVar.zEntities[i].zCombatTable.zAttacks[1] = {100,  5, 360 * fTimeFactor, 0} --0.83 DPS
        gzTextVar.zEntities[i].zCombatTable.zAttacks[2] = { 30,  5,  90 * fTimeFactor, 0} --3.33 DPS (!)
    end
    
    --Weaknesses. Claygirls are weak to fire and water.
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses = {}
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Fire] = 1
    gzTextVar.zEntities[i].zCombatTable.iaWeaknesses[gciElementSlot_Water] = 1
    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]
    --Determine position on the tileset by color.
    local fX, fY, fZ = fnGetRoomPosition(gzTextVar.zEntities[i].sLocation)
    local iIndicatorX = 0
    if(iTypeRoll == 1) then
        iIndicatorX = 6
    elseif(iTypeRoll == 2) then
        iIndicatorX = 7
    else
        iIndicatorX = 8
    end
    
    --Spawn the indicator. Don't do this if disguised!
    if(bSpawnInDisguise == false) then
        gzTextVar.zEntities[i].iIndicatorX = iIndicatorX
        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 = 1
            TL_SetProperty("Modify Entity Indicator Hosility", fX, fY, fZ, gzTextVar.zEntities[i].sIndicatorName, ciHostilityX_Enemy, ciHostilityY_Enemy)
        end
    
    --A disguised claygirl marks the item they spawned on.
    else
    
        --Mark for no indicator.
        gzTextVar.zEntities[i].iIndicatorX = "No Indicator"
        gzTextVar.zEntities[i].iIndicatorY = "No Indicator"
        gzTextVar.zEntities[i].iIndicatorC = "No Indicator"
        gzTextVar.zEntities[i].iIndicatorH = 0
        
        --Room index.
        local iRoomIndex = fnGetRoomIndex(gzTextVar.zEntities[i].sLocation)
    
        --Find the matching item.
        for p = 1, gzTextVar.zRoomList[iRoomIndex].iObjectsTotal, 1 do
            if(gzTextVar.zRoomList[iRoomIndex].zObjects[p].sUniqueName == sDisguiseObject) then
                
                --Order the item in question to build a list of actions that will trigger the trap. This is usually
                -- taking or equipping the item. Some objects will trigger it on 'read' or other special actions.
                gzTextVar.bIsClaygirlTrapCheck = true
                gzTextVar.saClaygirlTrapList = {}
                LM_ExecuteScript(gzTextVar.zRoomList[iRoomIndex].zObjects[p].sHandlerScript, "Null", -1, -1, -1)
                gzTextVar.bIsClaygirlTrapCheck = false
                
                --Store the values.
                gzTextVar.zRoomList[iRoomIndex].zObjects[p].bIsClaygirlTrapped = true
                gzTextVar.zRoomList[iRoomIndex].zObjects[p].sClaygirlName = gzTextVar.zEntities[i].sUniqueName
                gzTextVar.zRoomList[iRoomIndex].zObjects[p].saClaygirlList = gzTextVar.saClaygirlTrapList
                break
            end
        end

    end
end