local health = {} local maxhealth = {} local hit = {} local delay = 0 --how close player can "sneak" up before being detected local alert_range = 500 --how long before he gets back up from injured (allows you to kill him while he's down) local recover_delay = 2500 --how fast he moves (1/2 for walking) local speed = 100 --how much damage is applied per hit (seems to get doubled) local damage = 50 local recover_delay_init = recover_delay function dante_init(e) ai_soldier_state[e] = "patrol"; ai_soldier_pathindex[e] = -1; end function dante_main(e) if health[e] == nil then health[e] = g_Entity[e]['health'] maxhealth[e] = g_Entity[e]['health'] SetCharacterSound(e,"dante") else EntObjNo = g_Entity[e]['obj'] if g_Entity[e]['health'] < maxhealth[e] / 2 and ai_soldier_state[e] ~= "hurt" and ai_soldier_state[e] ~= "recover" then StopAnimation(e) ai_soldier_state[e] = "hurt" recover_delay = GetTimer(e) + recover_delay_init end if ai_soldier_state[e] == "patrol" then if g_Entity[e]['health'] < health[e] or g_Entity[e]['plrvisible'] == 1 or AIGetEntityHeardSound(EntObjNo) == 1 or GetPlayerDistance(e) < alert_range then ai_soldier_state[e] = "alert" delay = GetTimer(e) + 5000 else 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 < 200 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 PlayCharacterSound(e,"onAlert") if g_Entity[e]['animating'] == 0 then SetAnimation(1) PlayAnimation(e) g_Entity[e]['animating'] = 1 end 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]) RotateToPoint(e,ai_patrol_x[e],ai_patrol_z[e]) MoveForward(e,speed/2) 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 < 50 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 if g_Entity[e]['animating'] == 0 then local anim = math.random(0,1) if anim == 1 then anim = 5 PlayCharacterSound(e,"onDeath") end SetAnimation(anim) PlayAnimation(e) g_Entity[e]['animating'] = 1 end end end elseif ai_soldier_state[e] == "alert" then if GetPlayerDistance(e) < 120 then ai_soldier_state[e] = "attack" else if GetPlayerDistance(e) < AIGetEntityViewRange(EntObjNo) or GetTimer(e) < delay then RotateToPlayer(e) MoveForward(e,speed) if g_Entity[e]['animating'] == 0 then if GetPlayerDistance(e) < AIGetEntityViewRange(EntObjNo) / 2 then SetAnimation(2) PlayCharacterSound(e,"onAggro") else SetAnimation(1) PlayCharacterSound(e,"onAlert") end PlayAnimation(e) g_Entity[e]['animating'] = 1 end else ai_soldier_state[e] = "patrol" end end elseif ai_soldier_state[e] == "attack" then RotateToPlayer(e) health[e] = g_Entity[e]['health'] if g_Entity[e]['animating'] == 0 then hit[e] = 0 PlayCharacterSound(e,"onHurtPlayer") SetAnimation(math.random(6,7)) PlayAnimation(e) g_Entity[e]['animating'] = 1 else if hit[e] == 0 then if GetAnimationFrame(e) == 295 or GetAnimationFrame(e) == 225 then HurtPlayer(e,damage) hit[e] = 1 end end end if GetPlayerDistance(e) > 80 then MoveForward(e,speed/4) if GetPlayerDistance(e) > 120 then ai_soldier_state[e] = "alert" end end elseif ai_soldier_state[e] == "hurt" then if GetAnimationFrame(e) == 400 then ai_soldier_state[e] = "recover" else if g_Entity[e]['animating'] == 0 then SetAnimation(3) PlayAnimation(e) g_Entity[e]['animating'] = 1 end end elseif ai_soldier_state[e] == "recover" then if GetTimer(e) > recover_delay then SetEntityHealth(e,maxhealth[e]) if GetAnimationFrame(e) == 479 then ai_soldier_state[e] = "alert" else if g_Entity[e]['animating'] == 0 then SetAnimation(4) PlayAnimation(e) g_Entity[e]['animating'] = 1 end end end end --state end --health end --main function dante_exit(e) StopAnimation(e) PlayCharacterSound(e,"onDeath") SetAnimation(8) PlayAnimation(e) end function RotateToPoint(e,x,z) if g_Entity[e] ~= nil and x > 0 and z > 0 then local destx = x - g_Entity[e]['x'] local destz = z - g_Entity[e]['z'] local angle = math.atan2(destx,destz) angle = angle * (180.0 / math.pi) if angle < 0 then angle = 360 + angle elseif angle > 360 then angle = angle - 360 end SetRotation(e,0,angle,0) return angle end end