--[[
anim1 = 1,60 ; walk
anim2 = 65,130 ; run
anim3 = 135,200 ; run and shoot
anim4 = 205,235 ; stand and shoot
anim5 = 240,300 ; die sideways
anim6 = 305,350 ; die back
anim7 = 235,240 ; idle
--]]
local U = require "scriptbank\\utillib"
local state,hasHit, attack_range = {},{},{}
local startX,startY,startZ,startAX,startAY,startAZ = {},{},{},{},{},{}
local health,startHealth,damageFrame = {},{},{}
local destx,desty,destz = {},{},{}

local damage = 50
local lose_interest_timer = 3000 
local dodge_delay = 125

local idle_anim = 7
local walk_anim = 1
local run_anim = 2
local run_attack_anim = 3
local attack_anim = 4
local die_anim = {}
die_anim[1] = 5
die_anim[2] = 6

--[[
sounds;
slot 0 = empty
slot 1 = attack / fire weapon
slot 2 = engine noise (moving)
slot 3 = aggro
slot 4 = die
--]]
function robot_init(e)
	Include( "utillib.lua" )
	state[e] = "check route"
	startX[e],startY[e],startZ[e],startAX[e],startAY[e],startAZ[e] = GetEntityPosAng(e)
	health[e] = g_Entity[e]['health']
	startHealth[e] = health[e]
	SetActivated(e,1)
	SetPreExitValue(e,0)
	CharacterControlManual(e)
	attack_range[e] = AIGetEntityViewRange(g_Entity[e]['obj'])
	damageFrame[e] = GetEntityAnimationStart(e,attack_anim)+((GetEntityAnimationFinish(e,attack_anim)-GetEntityAnimationStart(e,attack_anim))/2)
end 

function robot_main(e)
	if GetMovementDelta(e) == 0 then 
		StopSound(e,2)
	else 
		LoopSound(e,2)
	end
		
	local obj = g_Entity[e]['obj']
	local pDist = GetPlayerDistance(e)
	if state[e] == "check route" then 
		local PathIndex = -1
		local PointIndex = 2
		local pClosest = 99999
		for pa = 1, AIGetTotalPaths(), 1 do
			for po = 1 , AIGetPathCountPoints(pa), 1 do
				local pDX = g_Entity[e]['x'] - AIPathGetPointX(pa,po)
				local pDY = g_Entity[e]['y'] - AIPathGetPointY(pa,po)
				local pDZ = g_Entity[e]['z'] - AIPathGetPointZ(pa,po)
				local pDist2 = math.sqrt(math.abs(pDX*pDX)+math.abs(pDY*pDY)+math.abs(pDZ*pDZ));
				if pDist2 < pClosest and pDist2 < 200 then
					pClosest = pDist2
					PathIndex = pa
					PointIndex = po
				end
			end -- po
		end -- pa
		ai_bot_pathindex[e] = PathIndex
		if PathIndex > -1 then
			state[e] = "patrol"
			ai_bot_pointdirection[e] = 1
			ai_bot_pointindex[e] = PointIndex
			ai_bot_pointmax[e] = AIGetPathCountPoints(PathIndex)
		else
			state[e] = "idle"
		end   
	elseif state[e] == "idle" then 
		ModulateSpeed(e,GetAnimationSpeed(e)*0.1)
		LoopAnim(e,idle_anim)
		if CheckAggro(e,obj,pDist) == 1 then 
			state[e] = "alert"
			ModulateSpeed(e,GetAnimationSpeed(e))
			StartTimer(e)
			PlaySound(e,3)
			return
		end 
	elseif state[e] == "patrol" then
		if CheckAggro(e,obj,pDist) == 1 then 
			state[e] = "alert"
			StartTimer(e)
			PlaySound(e,3)
			ModulateSpeed(e,GetAnimationSpeed(e))
			return 
		end 
		ModulateSpeed(e,GetAnimationSpeed(e)*0.5)
		destx[e] = AIPathGetPointX(ai_bot_pathindex[e],ai_bot_pointindex[e])
		desty[e] = AIPathGetPointY(ai_bot_pathindex[e],ai_bot_pointindex[e])
		destz[e] = AIPathGetPointZ(ai_bot_pathindex[e],ai_bot_pointindex[e])
		if GetDistanceToPoint(e,destx[e],desty[e],destz[e]) < 10000 then 
			if ai_bot_pointdirection[e] == 1 then
				ai_bot_pointindex[e] = ai_bot_pointindex[e] + 1
				if ai_bot_pointindex[e] > ai_bot_pointmax[e] then
					ai_bot_pointindex[e] = ai_bot_pointmax[e] -1
					ai_bot_pointdirection[e] = 0
				end
			else
				ai_bot_pointindex[e] = ai_bot_pointindex[e] - 1
				if ai_bot_pointindex[e] < 1 then
					ai_bot_pointindex[e] = 2
					ai_bot_pointdirection[e] = 1
				end		
			end
		else 
			LoopAnim(e,walk_anim)
			AIEntityGoToPosition(obj,destx[e],destz[e])
			MoveForward(e,AIGetEntitySpeed(obj))
			SetRotation(e,0,AIGetEntityAngleY(obj),0)
		end 
	elseif state[e] == "alert" then 
		if g_PlayerHealth < 1 then 
			health[e] = g_Entity[e]['health']
			state[e] = "return to idle pos"
			return
		end
		if pDist < attack_range[e] and g_Entity[e]['plrvisible'] == 1 then
			AIEntityStop(obj)
			state[e] = "stand and fire"
		else
			LoopAnim(e,run_anim)
			destx[e] = g_PlayerPosX
			destz[e] = g_PlayerPosZ
			AIEntityGoToPosition(obj,destx[e],destz[e])
			MoveForward(e,AIGetEntitySpeed(obj))
			SetRotation(e,0,AIGetEntityAngleY(obj),0)
		end 
	elseif state[e] == "stand and fire" then 
		hasHit[e] = 0
		RotateToPlayer(e)
		if U.PlayerLookingAt(e,attack_range[e]) == true then 
			--PromptDuration("looking at me!",2000)
			if GetTimer(e) > dodge_delay then 
				state[e] = "dodge incoming fire"
				return 
			end 
		else 
			StartTimer(e)
			--PromptDuration("not looking at me",2000)
		end 
		PlaySound(e,1)
		LoopAnim(e,attack_anim,0)
		state[e] = "firing"
	elseif state[e] == "firing" then 
		local tframe = GetAnimationFrame(e)
		if hasHit[e] == 0 then 
			if tframe >= damageFrame[e] -1 and tframe <= damageFrame[e] +1 then 
				HurtPlayer(e,damage)
				hasHit[e] = 1
			end 
		end 
		if g_Entity[e]['animating'] == 0 then 
			state[e] = "alert"
		end 
	elseif state[e] == "dodge incoming fire" then 
		--get a random point in attack range of player 
		local tx,ty,tz = 0,0,0
		tx = g_PlayerPosX+math.random(-attack_range[e],attack_range[e])
		tz = g_PlayerPosZ+math.random(-attack_range[e],attack_range[e])
		ty = GetTerrainHeight(tx,tz)
		local tray = IntersectAll(tx,ty,tz)
		if tray == nil then tray = 0 end 
		if tray == 0 then 
			destx[e] = tx 
			desty[e] = ty 
			destz[e] = tz 
			state[e] = "dodging"
		end 
	elseif state[e] == "dodging" then 
		if GetDistanceToPoint(e,destx[e],desty[e],destz[e]) < 12000 then 
			state[e] = "alert"
			StartTimer(e)
			return 
		else 
			LoopAnim(e,run_anim)
			AIEntityGoToPosition(obj,destx[e],destz[e])
			MoveForward(e,AIGetEntitySpeed(obj))
			SetRotation(e,0,AIGetEntityAngleY(obj),0)
		end 
	elseif state[e] == "return to idle pos" then 
		if GetDistanceToPoint(e,startX[e],startY[e],startZ[e]) > 15000 then 
			LoopAnim(e,walk_anim)
			AIEntityGoToPosition(obj,startX[e],startZ[e])
			MoveForward(e,AIGetEntitySpeed(obj))
			SetRotation(e,0,AIGetEntityAngleY(obj),0)
		else 
			SetPosition(e,startX[e],startY[e],startZ[e])
			ResetPosition(e,startX[e],startY[e],startZ[e])
			SetRotation(e,startAX[e],startAY[e],startAZ[e])
			ResetRotation(e,startAX[e],startAY[e],startAZ[e])
			state[e] = "check route"
			return
		end 			
	end	
	
	--PromptLocal(e,state[e])

end 

function robot_preexit(e)
	SetPreExitValue(e,1)
	if state[e] ~= "dead" then 
		StopSound(e,2)
		AIEntityStop(g_Entity[e]['obj'])
		ModulateSpeed(e,GetAnimationSpeed(e))
		PlaySound(e,4)
		if GetPlayerDistance(e) < 120 then 
			LoopAnim(e,die_anim[2],0)
		else 
			LoopAnim(e,die_anim[1],0)
		end 
		state[e] = "dead"
	else 
		if g_Entity[e]['animating'] == 0 then 
			SetPreExitValue(e,2)
		end 
	end 
end 

function robot_exit(e)
	Destroy(e)
end 


function CheckAggro(e,obj,dist)
	if (dist < AIGetEntityViewRange(obj) or g_Entity[e]['health'] < health[e] or AIGetEntityHeardSound(obj) > 0) and g_PlayerHealth > 0 then 
		return 1
	else 
		return 0
	end 
end

function GetDistanceToPoint(e,x,y,z)
	local dx, dy, dz = g_Entity[e]['x'] - x, g_Entity[e]['y'] - y, g_Entity[e]['z'] - z
	return dx*dx+dy*dy+dz*dz
end

function LoopAnim(e,v,l)
	if g_Entity[e]['animating'] ~= v then 
		SetAnimation(v)
		if l == 0 then 
			PlayAnimation(e)
		else 
			LoopAnimation(e)
		end 
		g_Entity[e]['animating'] = v
	end 
end 