ai_soldier_pathindex = {} ai_path_point_direction = {} ai_patrol_x = {} ai_patrol_z = {} ai_path_point_index = {} ai_path_point_max = {} ai_soldier_state = {} ai_old_hp = {} local temproty = {} local atk_anim_s = {} local atk_anim_e = {} local last_atk_frame = {} local last_atk_frame = {} local hit_player = {} local melee_anim = {} local max_hp = {} local found_cover = {} local coverx = {} local covery = {} local coverz = {} local startx = {} local starty = {} local startz = {} local fire_range = 1500 local attack_range = 90 local damage_min = 15 --for melee local damage_max = 25 local idle_anim = 5 local walk_unarmed_anim = 29 local run_unarmed_anim = 31 local hurt_anim = 160 --combat roll local stealth_run_anim = 181 local walk_armed_anim = 103 local run_armed_anim = 115 local throw_grenade_anim = 129 local sit_anim = 68 local stand_sit_anim = 72 melee_anim[1] = 97 melee_anim[2] = 100 local kneel_aim_anim = 155 --or 81? local stand_kneel_anim = 203 --also needed from combat roll local stand_aim_anim = 79 local walk_speed = {} local run_speed = {} function ai_classiccharacter_scifi_init(e) AISetEntityTurnSpeed(AIObjNo,2500) ai_soldier_state[e] = "idle" CharacterControlManual(e) StopAnimation(e) SetCharacterSoundSet(e) ai_soldier_pathindex[e] = -1 walk_speed[e] = 80 run_speed[e] = 120 end function ai_classiccharacter_scifi_main(e) if max_hp[e] == nil then ai_old_hp[e] = g_Entity[e]['health'] max_hp[e] = g_Entity[e]['health'] startx[e] = GetEntityPositionX(e) starty[e] = GetEntityPositionY(e) startz[e] = GetEntityPositionZ(e) found_cover[e] = nil return end AIObjNo = g_Entity[e]['obj'] PlayerDist = GetPlayerDistance(e) if PlayerDist < 2500 then if ai_soldier_state[e] == "idle" then 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 elseif ai_soldier_pathindex[e] > -1 then 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]) if g_Entity[e]['animating'] ~= 2 then StopAnimation(e) SetAnimation(walk_unarmed_anim) PlayAnimation(e) g_Entity[e]['animating'] = 2 else AIEntityGoToPosition(AIObjNo,ai_patrol_x[e],ai_patrol_z[e]) MoveForward(e,walk_speed[e]*0.8) end 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 or g_Entity[e]['animating'] ~= 1 then StopAnimation(e) SetAnimation(idle_anim) PlayAnimation(e) g_Entity[e]['animating'] = 1 end end if g_Entity[e]['plrvisible'] == 1 or PlayerDist < AIGetEntityViewRange(AIObjNo)/3 or AIGetEntityHeardSound(AIObjNo) == 1 or g_Entity[e]['health'] < ai_old_hp[e] then ai_soldier_state[e] = "alert" PlaySoundIfSilent(e,1) end elseif ai_soldier_state[e] == "alert" then if PlayerDist > fire_range or g_Entity[e]['plrvisible'] == 0 then if g_Entity[e]['animating'] ~= 4 then StopAnimation(e) SetAnimation(run_armed_anim) PlayAnimation(e) g_Entity[e]['animating'] = 4 else temproty[e] = 15-(PlayerDist/100) if temproty[e] < 6 then temproty[e] = 6 end AISetEntityTurnSpeed(AIObjNo,temproty[e]*20) AIEntityGoToPosition(AIObjNo,g_PlayerPosX,g_PlayerPosY,g_PlayerPosZ) MoveForward(e,run_speed[e]) FireWeapon(e) end elseif PlayerDist > fire_range * 0.5 then if g_Entity[e]['animating'] ~= 5 then StopAnimation(e) SetAnimation(walk_armed_anim) PlayAnimation(e) g_Entity[e]['animating'] = 5 else temproty[e] = 15-(PlayerDist/100) if temproty[e] < 6 then temproty[e] = 6 end AISetEntityTurnSpeed(AIObjNo,temproty[e]*20) AIEntityGoToPosition(AIObjNo,g_PlayerPosX,g_PlayerPosY,g_PlayerPosZ) MoveForward(e,walk_speed[e]) FireWeapon(e) end elseif PlayerDist > attack_range then AIEntityGoToPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) RotateToPlayer(e) if g_Entity[e]['animating'] ~= 6 then StopAnimation(e) SetAnimation(stand_aim_anim) PlayAnimation(e) g_Entity[e]['animating'] = 6 else RotateToPlayer(e) FireWeapon(e) end elseif PlayerDist <= attack_range then RotateToPlayer(e) if g_Entity[e]['animating'] ~= 9 then StopAnimation(e) temp = math.random(1,2) SetAnimation(melee_anim[temp]) PlayAnimation(e) last_atk_frame[e] = GetEntityAnimationFinish(e,melee_anim[temp]) hit_player[e] = 0 g_Entity[e]['animating'] = 9 else if GetAnimationFrame(e) >= last_atk_frame[e]-15 and GetAnimationFrame(e) <= last_atk_frame[e]-1 and hit_player[e] == 0 then HurtPlayer(e,math.random(damage_min,damage_max)) hit_player[e] = 1 end --if GetAnimationFrame(e) >= last_atk_frame[e]-1 and GetAnimationFrame(e) <= last_atk_frame[e] then end end if g_Entity[e]['health'] < ai_old_hp[e] then ai_soldier_state[e] = "roll" ai_old_hp[e] = g_Entity[e]['health'] * 0.5 end if g_Entity[e]['health'] < max_hp[e]*0.5 then if found_cover[e] == nil then CoverIndex = -1 pClosest = 1999 for ca = 1, AIGetTotalCover(), 1 do pDX = GetEntityPositionX(e) - AICoverGetPointX(ca) pDZ = GetEntityPositionZ(e) - AICoverGetPointZ(ca) --pDist = math.sqrt(math.abs(pDX*pDX)+math.abs(pDY*pDY)+math.abs(pDZ*pDZ)); covDist = math.sqrt((pDX*pDX)+(pDZ*pDZ)); if covDist < pClosest and covDist < 1500 then pClosest = covDist CoverIndex = ca coverx[e] = AICoverGetPointX(ca) coverz[e] = AICoverGetPointZ(ca) covery[e] = GetTerrainHeight(coverx[e],coverz[e]) end end if CoverIndex > -1 then tdx = GetEntityPositionX(e) - g_PlayerPosX tdz = GetEntityPositionZ(e) - g_PlayerPosZ tbotdd = math.sqrt ( (tdx*tdx) + (tdz*tdz) ) tdx = AICoverGetPointX(CoverIndex) - g_PlayerPosX tdz = AICoverGetPointZ(CoverIndex) - g_PlayerPosZ tcoverdd = math.sqrt ( (tdx*tdx) + (tdz*tdz) ) if pClosest < PlayerDist or (pClosest > PlayerDist and tcoverdd > pClosest) then else CoverIndex = -1 end end found_cover[e] = CoverIndex if found_cover[e] > 0 then found_cover[e] = 0 ai_soldier_state[e] = "run to cover" StartTimer(e) end end end elseif ai_soldier_state[e] == "run to cover" then coverdist = GetDistanceToPoint(e,coverx[e],coverz[e]) if coverdist > 62 then --and AICouldSee(AIObjNo,coverx[e],covery[e],coverz[e]) == 1 then if g_Entity[e]['animating'] ~= 9 then StopAnimation(e) SetAnimation(stealth_run_anim) PlayAnimation(e) g_Entity[e]['animating'] = 9 else temproty[e] = 15-(coverdist/100) if temproty[e] < 6 then temproty[e] = 6 end AISetEntityTurnSpeed(AIObjNo,temproty[e]*20) AIEntityGoToPosition(AIObjNo,coverx[e],covery[e],coverz[e]) MoveForward(e,run_speed[e]*1.3) FireWeapon(e) end else if found_cover[e] == 0 then StartTimer(e) found_cover[e] = 1 elseif GetTimer(e) > 1100 then found_cover[e] = nil SetEntityHealth(e,max_hp[e]) ai_old_hp[e] = g_Entity[e]['health'] ai_soldier_state[e] = "alert" elseif g_Entity[e]['plrvisible'] == 1 or PlayerDist < attack_range*1.2 then ai_soldier_state[e] = "alert" found_cover[e] = nil end end elseif ai_soldier_state[e] == "roll" then if g_Entity[e]['animating'] ~= 7 then StopAnimation(e) SetAnimation(hurt_anim) PlayAnimation(e) g_Entity[e]['animating'] = 7 ai_soldier_state[e] = "roll2" end elseif ai_soldier_state[e] == "roll2" then if g_Entity[e]['animating'] == 0 then if PlayerDist > attack_range and PlayerDist < fire_range and g_Entity[e]['plrvisible'] == 1 then ai_soldier_state[e] = "fire crouched" else ai_soldier_state[e] = "get up from crouch" end else AIEntityGoToPosition(AIObjNo,g_PlayerPosX,g_PlayerPosY,g_PlayerPosZ) MoveForward(e,walk_speed[e]) end elseif ai_soldier_state[e] == "fire crouched" then RotateToPlayer(e) FireWeapon(e) if PlayerDist < attack_range then ai_soldier_state[e] = "melee" elseif PlayerDist > fire_range or g_Entity[e]['plrvisible'] == 0 then ai_soldier_state[e] = "get up from crouch" end elseif ai_soldier_state[e] == "get up from crouch" then if g_Entity[e]['animating'] ~= 8 then StopAnimation(e) SetAnimation(stand_kneel_anim) PlayAnimation(e) g_Entity[e]['animating'] = 8 ai_soldier_state[e] = "get up from crouch2" end elseif ai_soldier_state[e] == "get up from crouch2" then if g_Entity[e]['animating'] == 0 then ai_soldier_state[e] = "alert" end end if g_PlayerHealth < 1 then ai_classiccharacter_scifi_init(e) AIEntityGoToPosition(AIObjNo,startx[e],starty[e],startz[e]) end if found_cover[e] ~= nil then --PromptLocal(e,found_cover[e]) end SetRotation(e,0,AIGetEntityAngleY(AIObjNo),0) AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) elseif GetTimer(e) > 500 then StartTimer(e) ai_classiccharacter_scifi_init(e) end end function ai_classiccharacter_scifi_exit(e) end function GetDistanceToPoint(e,x,z) if g_Entity[e] ~= nil and g_Entity[e] ~= 0 then local disx = g_Entity[e]['x'] - x local disz = g_Entity[e]['z'] - z return math.sqrt(disx^2 + disz^2) end end