-- LUA Script - precede every function and global member with lowercase name of script + '_main'
-- Default script - does nothing.
local state = {}
local walking = {}
local curious = {}
local attacking = {}
local aggressive = {}
local approaching = {}
local animationcomplete = {}
local hitting = {}
local attacktype = {}
local xpos = {}
local zpos = {}
local ypos = {}
local setpos = {}
local timer = {}
local timed = {}
local timed2 = {}
local started = {}
local health = {}
local healthset = {}
local idle = {}
local idleState = {}
local goalx = {}
local goalz = {}
local goaly = {}
local tooClose = {}
local range = {}
local setState = {}
local soundPlayed = {}
local pushed = {}
local attackDistance = {}
local alertDistance = {}

function headman_init(e)
state[e] = "relaxed"
walking[e] = 1
curious[e] = 0
attacking[e] = 0
aggressive[e] = 0
approaching[e] = 0
animationcomplete[e] = 1
hitting[e] = 0
attacktype[e] = 0
xpos[e] = 0
zpos[e] = 0
ypos[e] = 0
setpos[e] = 0
timer[e] = 0
timed[e] = 0
timed2[e] = 0
started[e] = 0
health[e] = 1000
healthset[e] = 0
ai_soldier_pathindex[e] = -1
idle[e] = 0
idleState[e] = 0
goalx[e] = 0
goalz[e] = 0
goaly[e] = 0
tooClose[e] = 0
range[e] = 500
setState[e] = 0
soundPlayed[e] = 0
pushed[e] = 0
attackDistance[e] = 150
alertDistance[e] = 800
end

function headman_main(e)

AIObjNo = g_Entity[e]['obj']

if g_PlayerHealth < 1 then 
	headman_init(e)
end


if healthset[e] == 0 then
	health[e] = g_Entity[e]['health']
	healthset[e] = 1
end


if setpos[e] == 0 then
	xpos[e] = g_Entity[e]['x']
	zpos[e] = g_Entity[e]['z']
	ypos[e] = g_Entity[e]['y']
	setpos[e] = 1
end

if GoalheadmanDistance(e) < 100 then
	tooClose[e] = 1
	else
	tooClose[e] = 0
end

if g_Entity[e]['health'] < health[e] then	
	aggressive[e] = 1
end

if GetAnimationFrame(e) == 31 or GetAnimationFrame(e) == 45 or GetAnimationFrame(e) == 61 or GetAnimationFrame(e) == 75 then
	PlaySound(e,0)
end
	
if aggressive[e] == 0 and animationcomplete[e] == 1 then

	if GetPlayerDistance(e) > alertDistance[e] then
		if GetTimer(e) - timed2[e] > (10000 + math.random(0,5000)) then
			
			if setState[e] == 0 and idleState[e] == 1 then
				idleState[e] = 0
				setState[e] = 1
			elseif setState[e] == 0 and idleState[e]  == 0 then
				idleState[e] = 1
				setState[e] = 1
			end	
			setState[e] = 0
			timed2[e] = GetTimer(e)			
			
			if idleState[e] == 0 then
				if state[e] ~= "walking" then
					g_Entity[e]['animating'] = 0
					state[e] = "walking"
				end
				walking[e] = 1
				curious[e] = 0
				attacking[e] = 0
				approaching[e] = 0
				idle[e] = 0
			end
			if idleState[e] == 1 then
				if state[e] ~= "idle" then
					g_Entity[e]['animating'] = 0
					state[e] = "idle"
				end
				walking[e] = 0
				curious[e] = 0
				attacking[e] = 0
				approaching[e] = 0
				idle[e] = 1
			end
		end	
	

	elseif GetPlayerDistance(e) < alertDistance[e] and GetPlayerDistance(e) > alertDistance[e] - 200 then
		if state[e] ~= "curious" then
			g_Entity[e]['animating'] = 0
				state[e] = "curious"
				end
		walking[e] = 0
		curious[e] = 1
		attacking[e] = 0
		approaching[e] = 0
		idle[e] = 0
		
			
	elseif GetPlayerDistance(e) < 500 and GetPlayerDistance(e) > attackDistance[e] then
		if state[e] ~= "approaching" then
			g_Entity[e]['animating'] = 0
				state[e] = "approaching"
				end
		walking[e] = 0
		curious[e] = 0
		attacking[e] = 0
		approaching[e] = 1
		idle[e] = 0
		
	elseif GetPlayerDistance(e) < attackDistance[e] then
		if state[e] ~= "attacking" then
			g_Entity[e]['animating'] = 0
				state[e] = "attacking"
		end
		walking[e] = 0
		approaching[e] = 0
		curious[e] = 0
		attacking[e] = 1
		idle[e] = 0
	end
elseif aggressive[e] == 1 and animationcomplete[e] == 1 then
	if GetPlayerDistance(e) < attackDistance[e] then
		if state[e] ~= "attacking" then
			g_Entity[e]['animating'] = 0
			state[e] = "attacking"
			end
		walking[e] = 0
		curious[e] = 0
		attacking[e] = 1
		approaching[e] = 0
		idle[e] = 0
	end
	if GetPlayerDistance(e) > attackDistance[e] and GetPlayerDistance(e) < 2000 then
		if state[e] ~= "approaching" then
			g_Entity[e]['animating'] = 0
			state[e] = "approaching"
			end
		walking[e] = 0
		curious[e] = 0
		attacking[e] = 0
		approaching[e] = 1
		idle[e] = 0
	end
	if GetPlayerDistance(e) > 2000  then
		if state[e] ~= "walking" then
			g_Entity[e]['animating'] = 0
			state[e] = "walking"
			end
		walking[e] = 0
		curious[e] = 0
		attacking[e] = 0
		approaching[e] = 1
		aggressive[e] = 0
		idle[e] = 0
	end
	
end

if idle[e] == 1 then
	SetAnimationSpeed(e,1)
	CharacterControlLimbo(e)
	ModulateSpeed(e,1)
	if g_Entity[e]['animating'] == 0 then
		SetAnimationFrames(91,300)
		LoopAnimation(e)
		g_Entity[e]['animating'] = 1
	end
end

if walking[e] == 1 then
ModulateSpeed(e,1)
	SetAnimationSpeed(e,1)
	if 	GetAnimationFrame(e) > 1 or GetAnimationFrame(e) < 30 then
		SetAnimationFrames(1,30)
	end
--Prompt(ai_soldier_pathindex[e])
	
 if ai_soldier_pathindex[e] == -1 then
   ai_soldier_pathindex[e] = -2
   PathIndex = -1
   PathPointIndex = -1
   pClosest = 99999
   for pa = 1, AIGetTotalPaths(), 1 do
    for po = 1 , AIGetPathCountPoints(pa), 1 do
     pDX = g_Entity[e]['x'] - AIPathGetPointX(pa,po)
     pDZ = g_Entity[e]['z'] - AIPathGetPointZ(pa,po)
     pDist = math.sqrt(math.abs(pDX*pDX)+math.abs(pDZ*pDZ))
     if pDist < pClosest and pDist < 800 then
      pClosest = pDist
      PathIndex = pa
	  PathPointIndex = po
     end
    end -- po
   end -- pa
   if PathIndex > -1 then
    ai_soldier_pathindex[e] = PathIndex
	ai_path_point_index[e] = PathPointIndex
	ai_path_point_direction[e] = 1
	ai_path_point_max[e] = AIGetPathCountPoints(ai_soldier_pathindex[e])
   end   
  end
  if ai_soldier_pathindex[e] > -1 then 
  SetCharacterToWalk(e)
  CharacterControlUnarmed(e)
  if 	GetAnimationFrame(e) > 87 or GetAnimationFrame(e) < 37 then
	SetAnimationFrames(37,37)
end
  --ModulateSpeed(e,walk_speed / 100)
   ai_patrol_x[e] = AIPathGetPointX(ai_soldier_pathindex[e],ai_path_point_index[e])
   ai_patrol_z[e] = AIPathGetPointZ(ai_soldier_pathindex[e],ai_path_point_index[e])
   AIEntityGoToPosition(g_Entity[e]['obj'],ai_patrol_x[e],ai_patrol_z[e])
   tDistX = g_Entity[e]['x'] - ai_patrol_x[e]
   tDistZ = g_Entity[e]['z'] - ai_patrol_z[e]
   DistFromPath = math.sqrt(math.abs(tDistX*tDistX)+math.abs(tDistZ*tDistZ))	
   if DistFromPath < 75 then
	if ai_path_point_direction[e] == 1 then
	 ai_path_point_index[e] = ai_path_point_index[e] + 1
	 if ( ai_path_point_index[e] > ai_path_point_max[e] ) then
	  ai_path_point_index[e] = ai_path_point_max[e] - 1
	  ai_path_point_direction[e] = 0
	 end
	else
	 ai_path_point_index[e] = ai_path_point_index[e] - 1
	 if ( ai_path_point_index[e] < 1 ) then
	  ai_path_point_index[e] = 2
	  ai_path_point_direction[e] = 1
	 end		
	end
	end
	
   else
	CharacterControlManual(e)
	ModulateSpeed(e,1)
	if g_Entity[e]['animating'] == 0 then
		SetAnimationFrames(1,30)
		LoopAnimation(e)
		g_Entity[e]['animating'] = 1
	end
	if 	GetAnimationFrame(e) > 30 or GetAnimationFrame(e) < 1 then
		SetAnimationFrames(1,1)
	end
	AISetEntityControl(AIObjNo,AI_MANUAL)
	AIEntityGoToPosition(g_Entity[e]['obj'],goalx[e],goalz[e])
	MoveForward(e,80)
	RotateToPointSlowly(e,goalx[e],goalz[e],1)
 if (GetTimer(e) - timer[e] > (10000 + math.random(-2000,2000))) or tooClose[e] == 1 then 
	goalx[e] = xpos[e] + math.random(-range[e],range[e])
	goalz[e] = zpos[e] + math.random(-range[e],range[e])
	timer[e] = GetTimer(e)
end
	
 end
if GetPlayerDistance(e) < 1200 then	
	RotateToPlayerSlowly(e,5)
end
end

if approaching[e] == 1 then
	SetAnimationSpeed(e,1.5)
	StopSound(e,2)
	if g_Entity[e]['animating'] == 0 then
		SetAnimationFrames(31,60)
		LoopAnimation(e)
		g_Entity[e]['animating'] = 1
	end
		RotateToPlayerSlowly(e,10)
		CharacterControlManual(e)
		AISetEntityControl(AIObjNo,AI_MANUAL)
		AIEntityGoToPosition(AIObjNo,g_PlayerPosX,g_PlayerPosZ)
		MoveForward(e,220)
		--SetRotation(e,0,AIGetEntityAngleY(AIObjNo),0)
		AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e))
 end

if curious[e] == 1 then
	CharacterControlLimbo(e)
	SetAnimationSpeed(e,1)
	RotateToPlayerSlowly(e,7)
	if g_Entity[e]['animating'] == 0 then
		SetAnimationFrames(1,30)
		LoopAnimation(e)
		g_Entity[e]['animating'] = 1
	end
	MoveForward(e,80)
	if GetTimer(e) - timed[e] > 5000 and started[e] == 0 then
		started[e] = 1
		timed[e] = GetTimer(e)
	end
	if GetTimer(e) - timed[e] > 5000 and started[e] == 1 then
		aggressive[e] = 1
		timed[e] = GetTimer(e)
	end
end
 
if attacking[e] == 1 then
	StopSound(e,1)
	CharacterControlLimbo(e)
	SetAnimationSpeed(e,1.5)
	RotateToPlayerSlowly(e,10)
	MoveForward(e,220)
	
	if GetPlayerDistance(e) > 80 then
		pushed[e] = 0
	end
		if g_Entity[e]['animating'] == 0 then
			SetAnimationFrames(61,90)
			PlayAnimation(e)
			g_Entity[e]['animating'] = 1
		end
			
		if GetAnimationFrame(e) == 61 then
			animationcomplete[e] = 0
		end
		if GetAnimationFrame(e) == 90 then
			animationcomplete[e] = 1
		end
		
		if (GetPlayerDistance(e)) < 80 then 
			if pushed[e] == 0 then
				HurtPlayer(e,50)
				ForcePlayer (180, 10 )
				PlaySound(e,1)
				pushed[e] = 1
			end
		end
end

	

if g_PlayerHealth < 1 then
	headman_init(e)
end
end



function headman_exit(e)
SetAnimationSpeed(e,1)
CharacterControlLimbo(e)
SetAnimationFrames(551,620)
PlayAnimation(e)
StopSound(e)
 end
 
 function headmanDistance(e)
  headmanDX = (g_Entity[e]['x'] - xpos[e])
  headmanDY = (g_Entity[e]['y'] - ypos[e])
  headmanDZ = (g_Entity[e]['z'] - zpos[e])
  if math.abs(headmanDY) > 100 then 
   headmanDY = headmanDY * 4
  end
  return math.sqrt(math.abs(headmanDX*headmanDX)+math.abs(headmanDY*headmanDY)+math.abs(headmanDZ*headmanDZ));
end  

function GoalheadmanDistance(e)
if g_Entity[e] ~= nil and g_Entity[e] ~= 0 then
local disx = g_Entity[e]['x'] - goalx[e]
local disz = g_Entity[e]['z'] - goalz[e]
return math.sqrt(disx^2 + disz^2)
end
end
function RotateToPointSlowly(e,x,z,v)
if g_Entity[e] ~= nil and x > 0 and z > 0 then
if v == nil then
v = 1 
end
local destx = x - g_Entity[e]['x']
local destz = z - g_Entity[e]['z']
local angleneeded = math.atan2(destx,destz)
angleneeded = angleneeded * (180.0 / math.pi)
if angleneeded < 0 then
angleneeded = 360 + angleneeded
elseif angleneeded > 360 then
angleneeded = angleneeded - 360
end
local current_angy = g_Entity[e]['angley']
while current_angy < 0 or current_angy > 360 do
if current_angy <= 0 then
current_angy = 360 + current_angy
elseif current_angy > 360 then
current_angy = current_angy - 360
end
end
local L = angleneeded - v
local R = angleneeded + v
if L <= 0 then
L = 360 + L 
elseif L > 360 then
L = L - 360
end
if R <= 0 then
R = 360 + R
elseif R > 360 then
R = R - 360
end
 
--if not already facing the target direction (+/- the rotation speed)
if current_angy < L or current_angy > R then
--do it in 2 halfs so we can account for 0/360 wrap
if current_angy > 180 then
if angleneeded > current_angy - 180 and angleneeded < current_angy then
current_angy = current_angy - v
else
current_angy = current_angy + v
end
else
if angleneeded < current_angy + 180 and angleneeded > current_angy then
current_angy = current_angy + v
else
current_angy = current_angy - v
end
end
SetRotation(e,0,current_angy,0)
return current_angy
end
end
end

