--------------------------------------------------------------

-- L_QB_SPAWNER.lua

-- Works in tandem with objects requesting mob spawns where the 
-- requesting object is set to be the immediate target of the
-- resulting group of enemies
-- Created abeechler... 1/31/11

-------------------------------------------------------------

local defaultMobNum = 3				-- The maximum size of the enemy mob to maintain
local defaultSpawnDist = 25			-- How far away should we spawn the enemy mob?
local defaultMobTemplate = 4712		-- What object template comprises the mob?
local defaultSpawnTime = 2			-- How long to delay (if at all) until the mob is spawned

function onStartup(self)
	-- Establish initial object state
	local mobNum = self:GetVar("mobNum") or defaultMobNum
	local spawnDist = self:GetVar("spawnDist") or defaultSpawnDist
	local mobTemplate = self:GetVar("mobTemplate") or defaultMobTemplate
	local spawnTime = self:GetVar("spawnTime") or defaultSpawnTime
	
	self:SetVar("mobNum", mobNum)
	self:SetVar("spawnDist", spawnDist)
	self:SetVar("mobTemplate", mobTemplate)
	self:SetVar("spawnTime", spawnTime)
end

----------------------------------------------
-- Received an event call to process
----------------------------------------------
function onFireEvent(self, msg)

	-- Have we been sent a valid event type to process?
	local eventType = msg.args
	if not eventType then return end

	-- A call has been made to update the enemy mob
	if eventType == "spawnMobs" then
		if not msg.senderID then return end
		-- Set the object ID that requested the mob update
		local gateObj = msg.senderID
		self:SetVar("gateObj", gateObj)
		
		local spawnTime = self:GetVar("spawnTime")
		GAMEOBJ:GetTimer():AddTimerWithCancel(spawnTime, "SpawnMobEnemies", self )
	end

end

function onTimerDone(self, msg)
    if msg.name == "SpawnMobEnemies" then
		-- Grab the current mobTable, or build a new one if it doesn't exist
		local mobTable = self:GetVar("mobTable") or {}
		-- Grab mob stats
		local mobNum = self:GetVar("mobNum")
		local mobTemplate = self:GetVar("mobTemplate")
		local spawnDist = self:GetVar("spawnDist")
		-- Grab the object ID that requested the mob update
		local gateObj = self:GetVar("gateObj")
		
		-- Calculate the mob base destination and orientation based 
		-- on the valid senderID object
		local oPos = {pos = gateObj:GetPosition().pos}
		local oDir = gateObj:GetObjectDirectionVectors()
		local newPos = {x = oPos.pos.x + (oDir.forward.x * spawnDist), y = oPos.pos.y, z = oPos.pos.z + (oDir.forward.z * spawnDist)} --+ (oDir.forward.y * posOffset)
        
		oPos.rot = gateObj:GetRotation()
        
        -- Build the base mob creature config data table
		local config = { {"no_timed_spawn", true}, {"aggroRadius", 70}, {"softtetherRadius", 80}, {"tetherRadius", 90}, {"wanderRadius", 5} }
         
		-- Iterate through the mobTable (scaled to the desired mob size)
		-- and load a new AI for every available open mob slot
		for i=1, mobNum do
			local posOffset = -10
			if(not mobTable[i]) then
				-- We have found an open mob slot
				-- Identify his mob slot in the config data
				table.insert(config, {"mobTableLoc", i})
				-- Created a new mob entity at the desired offset loc
				posOffset = posOffset + 5 * i 
				local newOffset = {x = newPos.x, y = newPos.y, z = newPos.z + posOffset}
				RESMGR:LoadObject{ objectTemplate = mobTemplate, x= newPos.x, y= newPos.y , z= newPos.z + posOffset, rw = oPos.rot.w, rx = -oPos.rot.x, ry = -oPos.rot.y, rz = -oPos.rot.z, owner = self, configData = config}
			else
				-- There is an existing mob object - set it to aggro
				-- the requesting spawn object
				aggroTargetObj(self, mobTable[i])
			end
		end  
    end
end

----------------------------------------------
-- Called on successful load of a spawned entity
----------------------------------------------
function onChildLoaded(self, msg)
	-- Identify the spawned mob creature
    local spawnedMob = msg.childID
    
    -- Add the spawned entity to the mobTable at the appropriate slot
    local mobTable = self:GetVar("mobTable") or {}
    local tableLoc = spawnedMob:GetVar("mobTableLoc")
    mobTable[tableLoc] = spawnedMob
    self:SetVar("mobTable", mobTable)
    
    -- Set mob object to aggro the spawning object
    aggroTargetObj(self, spawnedMob)
end

----------------------------------------------
-- Notifcation of child death for processing
----------------------------------------------
function onChildRemoved(self, msg)
	-- Remove the dead mob object from the mobTable
	local mobTable = self:GetVar("mobTable") or {}
	local tableLoc = msg.childID:GetVar("mobTableLoc")
	mobTable[tableLoc] = nil
	self:SetVar("mobTable", mobTable)
end

----------------------------------------------
-- Sets aggro on a target child to a specified target
----------------------------------------------
function aggroTargetObj(self, enemy)
	-- Identify the obj that called for mob spawn
	local gateObj = self:GetVar("gateObj")
	
	-- Set the enemy to follow and aggro the target
	if(gateObj:Exists()) then
		enemy:FollowTarget{targetID = gateObj}    
		enemy:AddThreatRating{newThreatObjID = gateObj, ThreatToAdd = 1000}
    end
    
    -- Place secondary focus on the player that caused the mob spawn call
    local player = self:GetVar("player")
    if(player:Exists()) then
		enemy:AddThreatRating{newThreatObjID = player, ThreatToAdd = 100}
    end
end
