-- COMBATCORE Common Module -- anim0 : Idle -- anim1 : Move -- anim2 : Punch/Kick/Bite -- anim3 : Hurt -- anim4 : Reload -- anim5 : Punch/Kick/Bite Damage Frames -- anim6 : Dying -- anim7 : Stood to Duck -- anim8 : Duck Idle -- anim9 : Duck to Stood -- anim10 : Run/Dash -- anim11 : Roll to Duck -- anim12 : Fast Crouch Dash -- anim13 : idle sentry -- anim14 : relaxed move -- anim15 : strafe left -- anim16 : strafe right -- sound0 : Start moving A -- sound1 : Start strike -- sound2 : Start moving B -- sound3 : Get hurt A -- sound4 : Get hurt B module_core = require "scriptbank\\ai\\module_core" module_agro = require "scriptbank\\ai\\module_agro" module_cameraoverride = require "scriptbank\\ai\\module_cameraoverride" module_combateffects = require "scriptbank\\ai\\module_combateffects" ai_bot_newroty = {} local module_combatcore = {} function module_combatcore.init(e,startstate,coverstate) CharacterControlManual(e) AIObjNo = g_Entity[e]['obj'] AISetEntityControl(AIObjNo,AI_MANUAL) ai_bot_oldhealth[e] = g_Entity[e]['health'] ai_bot_coverindex[e] = coverstate ai_bot_state[e] = startstate ai_bot_substate[e] = 0 ai_bot_targetx[e] = nil ai_bot_pointtime[e] = -1 ai_bot_patroltime[e] = 0 ai_bot_targetx[e] = g_Entity[e]['x'] ai_bot_targety[e] = g_Entity[e]['y'] ai_bot_targetz[e] = g_Entity[e]['z'] ai_bot_closeenoughx[e] = 0 ai_bot_closeenoughy[e] = 0 ai_bot_closeenoughz[e] = 0 ai_bot_gofast[e] = 0 ai_bot_sighting[e] = 0 -- populate animation data if entity file does not provide it (except 5 and 6 which are melee) if GetEntityAnimationFound(e,0) == 0 then SetEntityAnimation(e,0,100,205) end if GetEntityAnimationFound(e,1) == 0 then SetEntityAnimation(e,1,685,707) end if GetEntityAnimationFound(e,2) == 0 then SetEntityAnimation(e,2,5511,5553) end if GetEntityAnimationFound(e,3) == 0 then SetEntityAnimation(e,3,4812,4850) end if GetEntityAnimationFound(e,4) == 0 then SetEntityAnimation(e,4,515,605) end if GetEntityAnimationFound(e,7) == 0 then SetEntityAnimation(e,7,1630,1646) end if GetEntityAnimationFound(e,8) == 0 then SetEntityAnimation(e,8,1670,1819) end if GetEntityAnimationFound(e,9) == 0 then SetEntityAnimation(e,9,1646,1663) end if GetEntityAnimationFound(e,10) == 0 then SetEntityAnimation(e,10,795,811) end if GetEntityAnimationFound(e,11) == 0 then SetEntityAnimation(e,11,2160,2218) end if GetEntityAnimationFound(e,12) == 0 then SetEntityAnimation(e,12,2135,2153) end if GetEntityAnimationFound(e,13) == 0 then SetEntityAnimation(e,13,900,999) end if GetEntityAnimationFound(e,14) == 0 then SetEntityAnimation(e,14,1290,1320) end if GetEntityAnimationFound(e,15) == 0 then SetEntityAnimation(e,15,610,640) end if GetEntityAnimationFound(e,16) == 0 then SetEntityAnimation(e,16,645,676) end end function module_combatcore.findcover(e,x,y,z) CoverIndex = -1 tdx = x - g_PlayerPosX tdy = 0 tdz = z - g_PlayerPosZ tDistToPlayer = math.sqrt ( math.abs(tdx*tdx) + math.abs(tdz*tdz) ) for prefer = 1, 2, 1 do pClosest = 99999 for ca = 1, AIGetTotalCover(), 1 do pDX = x - AICoverGetPointX(ca) pDZ = z - AICoverGetPointZ(ca) pDistToCover = math.sqrt(math.abs(pDX*pDX)+math.abs(pDZ*pDZ)); if pDistToCover < pClosest and pDistToCover < tDistToPlayer and pDistToCover < 3000 then -- also reject cover that is 'further away' from player than the enemy tdx = AICoverGetPointX(ca) - g_PlayerPosX tdz = AICoverGetPointZ(ca) - g_PlayerPosZ tPlayerCoverDist = math.sqrt ( math.abs(tdx*tdx) + math.abs(tdz*tdz) ) if tPlayerCoverDist <= tDistToPlayer then -- reject cover if facing away from player direction tdx = g_PlayerPosX - AICoverGetPointX(ca) tdz = g_PlayerPosZ - AICoverGetPointZ(ca) tPlayerCoverAngle = (math.atan2(tdx,tdz)/6.28)*360.0 tanglediff = tPlayerCoverAngle - AICoverGetAngle(ca) if tanglediff < -180 then tanglediff=tanglediff+360 end if tanglediff > 180 then tanglediff=tanglediff-360 end if math.abs(tanglediff) < 90 then tchoosethis = 0 if prefer == 1 and ai_cover_slot[ca] == nil then tchoosethis = 1 end if prefer == 2 and ai_cover_slot[ca] ~= nil then tchoosethis = 1 end if tchoosethis == 1 then pClosest = pDistToCover CoverIndex = ca end end end end end if prefer == 1 and CoverIndex ~= -1 then return CoverIndex end end return CoverIndex end function module_combatcore.atcover(e) atcoverpos = 0 CoverIndex = ai_bot_coverindex[e] if CoverIndex ~= -1 then tdx = AICoverGetPointX(CoverIndex) - g_Entity[e]['x'] tdy = 0 tdz = AICoverGetPointZ(CoverIndex) - g_Entity[e]['z'] tcoverdd = math.sqrt ( math.abs(tdx*tdx) + math.abs(tdz*tdz) ) if tcoverdd < 125 then atcoverpos = 1 end end return atcoverpos end function module_combatcore.claimcover(e,slot) ai_cover_slot[slot] = e ai_bot_coverindex[e] = slot end function module_combatcore.releasecover(e) slot = ai_bot_coverindex[e] if slot > 0 then ai_cover_slot[slot] = nil end ai_bot_coverindex[e] = -2 end function module_combatcore.findandassigncover(e,AIObjNo,PlayerDist) tcoverassigned = 0 if ai_bot_coverindex[e] == -1 then coverslot = module_combatcore.findcover(e,g_Entity[e]['x'],g_Entity[e]['y'],g_Entity[e]['z']) if coverslot > 0 then module_combatcore.claimcover(e,coverslot) ai_bot_targetx[e] = AICoverGetPointX(ai_bot_coverindex[e]) ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = AICoverGetPointZ(ai_bot_coverindex[e]) tcoverassigned = 1 end end if ai_bot_coverindex[e] < 0 then module_combatcore.releasecover(e) end if ai_bot_coverindex[e] == -2 and PlayerDist < AIGetEntityViewRange(AIObjNo) then ai_bot_targetx[e] = g_PlayerPosX ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = g_PlayerPosZ end return tcoverassigned end function module_combatcore.detectplayer(e,AIObjNo,PlayerDist,CanFire,detectstate,combattype) if (PlayerDist < AIGetEntityViewRange(AIObjNo) and (g_Entity[e]['plrvisible'] == 1 or ai_bot_coverindex[e] == -2)) or g_Entity[e]['activated'] == 2 then if g_Entity[e]['activated'] == 2 then ai_bot_targetx[e] = g_PlayerPosX ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = g_PlayerPosZ ai_bot_substate[e] = 0 SetActivated(e,0) else if module_combatcore.findandassigncover(e,AIObjNo,PlayerDist) == 1 then AIEntityGoToPosition(AIObjNo,ai_bot_targetx[e],ai_bot_targety[e],ai_bot_targetz[e]) ai_bot_state[e] = ai_state_startmove ai_bot_substate[e] = 0 end end if ai_bot_targetx[e] ~= nil then if ai_bot_substate[e] == 0 then if module_combatcore.getcomfortdistance(e) < 25 then RotateToPlayerSlowly(e,1.0) else AIEntityGoToPosition(AIObjNo,ai_bot_targetx[e],ai_bot_targety[e],ai_bot_targetz[e]) if AIGetEntityIsMoving(AIObjNo) == 1 then ai_bot_state[e] = detectstate PlaySound(e,0+(math.random(0,1)*2)) else if g_Entity[e]['plrvisible'] == 1 then if CanFire == 1 and ai_bot_state[e] == ai_state_idle and combattype ~= ai_combattype_bashmelee then -- if not moving and can see, fire on spot! ai_bot_state[e] = ai_state_startfireonspot end RotateToPlayer(e) if CanFire == 1 then module_combatcore.fireweapon(e) end ai_bot_targetx[e] = g_PlayerPosX ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = g_PlayerPosZ AIEntityGoToPosition(AIObjNo,ai_bot_targetx[e],ai_bot_targety[e],ai_bot_targetz[e]) end end end end end end end function module_combatcore.getcomfortdistance(e) dx = ai_bot_closeenoughx[e] - g_PlayerPosX dy = ai_bot_closeenoughy[e] - g_PlayerPosY dz = ai_bot_closeenoughz[e] - g_PlayerPosZ checkdistancefromcomfort = math.sqrt(math.abs(dx*dx)+math.abs(dy*dy)+math.abs(dz*dz)) return checkdistancefromcomfort end function module_combatcore.idle(e,AIObjNo,PlayerDist,CanFire,detectstate,combattype) CharacterControlManual(e) AISetEntityControl(AIObjNo,AI_MANUAL) if ai_bot_state[e] == ai_state_startidle then ai_bot_state[e] = ai_state_idle if combattype == ai_combattype_regular then SetAnimation(13) else SetAnimation(0) end LoopAnimation(e) SetAnimationSpeedModulation(e,1.0) end if ai_bot_state[e] == ai_state_idle then module_combatcore.detectplayer(e,AIObjNo,PlayerDist,CanFire,detectstate,combattype) module_combatcore.donotmove(e) end --if g_Entity[e]['plrvisible'] == 0 and PlayerDist < 200 then Another Duff Logic - dont stop a chase, even if enemy cannot see the player! -- ai_bot_state[e] = ai_state_idle -- SetAnimation(0) -- CanFire = 0 -- module_combatcore.donotmove(e) --end end function module_combatcore.patrol(e,AIObjNo,PlayerDist,MoveType,CanFire,detectstate,stopstate,combattype) if ai_bot_pointtime[e] == -1 then ai_bot_pointtime[e] = 0 StartTimer(e) end if ai_bot_state[e] == ai_state_findpatrolpath and ai_bot_pointtime[e] == 0 then PathIndex = -1 PointIndex = 2 pClosest = 99999 for pa = 1, AIGetTotalPaths(), 1 do for po = 1 , AIGetPathCountPoints(pa), 1 do pDX = g_Entity[e]['x'] - AIPathGetPointX(pa,po) pDY = g_Entity[e]['y'] - AIPathGetPointY(pa,po) pDZ = g_Entity[e]['z'] - AIPathGetPointZ(pa,po) pDist = math.sqrt(math.abs(pDX*pDX)+math.abs(pDY*pDY)+math.abs(pDZ*pDZ)); if pDist < pClosest and pDist < 200 then pClosest = pDist PathIndex = pa PointIndex = po end end -- po end -- pa ai_bot_pathindex[e] = PathIndex if PathIndex > -1 then ai_bot_state[e] = ai_state_startpatrol ai_bot_pointdirection[e] = 1 ai_bot_pointindex[e] = PointIndex ai_bot_pointmax[e] = AIGetPathCountPoints(PathIndex) else ai_bot_state[e] = ai_state_startidle end end if ai_bot_state[e] == ai_state_startpatrol then if ai_bot_pathindex[e] ~= -1 then ai_bot_state[e] = ai_state_patrol ai_bot_pointtime[e] = g_Time + 100 AISetEntityMoveBoostPriority(AIObjNo) SetAnimationSpeedModulation(e,0.0) if combattype == ai_combattype_regular then SetAnimation(14) else SetAnimation(1) end LoopAnimation(e) StartTimer(e) else ai_bot_state[e] = ai_state_idle if combattype == ai_combattype_regular then SetAnimation(13) else SetAnimation(0) end LoopAnimation(e) SetAnimationSpeedModulation(e,1.0) end end if ai_bot_state[e] == ai_state_patrol then patrolx = AIPathGetPointX(ai_bot_pathindex[e],ai_bot_pointindex[e]) patroly = AIPathGetPointY(ai_bot_pathindex[e],ai_bot_pointindex[e]) patrolz = AIPathGetPointZ(ai_bot_pathindex[e],ai_bot_pointindex[e]) module_combatcore.moveandavoid(e,AIObjNo,PlayerDist,MoveType,patrolx,patroly,patrolz,stopstate) if AIGetEntityIsMoving(AIObjNo) == 1 then if GetAnimationSpeedModulation(e) == 0.0 then SetAnimationSpeedModulation(e,0.1) else tWalkDelta = GetMovementDelta(e) * 2.0 if tWalkDelta > 0.9 then tWalkDelta = 0.9 end SetAnimationSpeedModulation(e,0.1+tWalkDelta) end end tDistX = g_Entity[e]['x'] - patrolx tDistZ = g_Entity[e]['z'] - patrolz VertDist = math.abs(g_Entity[e]['y'] - patroly) DistFromPath = math.sqrt(math.abs(tDistX*tDistX)+math.abs(tDistZ*tDistZ)) if DistFromPath < 50 and VertDist < 95 and g_Time > ai_bot_pointtime[e] then ai_bot_pointtime[e] = g_Time + 100 AISetEntityMoveBoostPriority(AIObjNo) StartTimer(e) 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 end module_combatcore.detectplayer(e,AIObjNo,PlayerDist,CanFire,detectstate,combattype) end end function module_combatcore.hunt(e,AIObjNo,PlayerDist,MoveType,CanFire,stopstate,duckstrafe) if ai_bot_state[e] == ai_state_startmove then ai_bot_state[e] = ai_state_move if ai_bot_targetx[e] ~= nil then tdX = g_Entity[e]['x'] - ai_bot_targetx[e] tdZ = g_Entity[e]['z'] - ai_bot_targetz[e] tdist = math.sqrt(math.abs(tdX*tdX)+math.abs(tdZ*tdZ)) else tdist = 0 end if tdist > 200 then ai_bot_gofast[e] = Timer() else ai_bot_gofast[e] = 0 end if ai_bot_gofast[e] > 0 then ModulateSpeed(e,1.5) SetAnimation(10) else ModulateSpeed(e,1.0) SetAnimation(1) end LoopAnimation(e) SetAnimationSpeedModulation(e,1.0) StartTimer(e) end if ai_bot_state[e] == ai_state_move then if GetTimer(e) > 500 then if ai_bot_coverindex[e] > 0 then if module_combatcore.atcover(e) == 1 then if g_Entity[e]['plrdist'] > 400 then if duckstrafe == ai_duckstrafe_on then local rays = module_combatcore.checkentityrays(e,130,0,g_Entity[e]['obj'],57) if rays == 0 then if ai_bot_state[e] ~= ai_state_duck then ai_bot_state[e] = ai_state_duckstart end else --can't see over cover so try roll sideways? if ai_bot_state[e] ~= ai_state_rollstart and ai_bot_state[e] ~= ai_state_roll then ai_bot_state[e] = ai_state_rollstart module_combatcore.handleducking(e,AIObjNo,PlayerDist) return end end end else -- break from cover, player too close module_combatcore.releasecover(e) end end end if ai_bot_coverindex[e] == -2 then if g_Entity[e]['plrvisible'] == 1 and CanFire == 1 then ai_bot_state[e] = ai_state_startfireonspot end end if ai_bot_substate[e] == 0 then StartTimer(e) end end if ai_bot_state[e] ~= ai_state_startfireonspot then if ai_bot_coverindex[e] == -2 then if g_Entity[e]['plrvisible'] == 1 then ai_bot_targetx[e] = g_PlayerPosX ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = g_PlayerPosZ end end if ai_bot_coverindex[e] > 0 then ai_bot_targetx[e] = AICoverGetPointX(ai_bot_coverindex[e]) ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = AICoverGetPointZ(ai_bot_coverindex[e]) end if ai_bot_targetx[e] ~= nil then module_combatcore.moveandavoid(e,AIObjNo,PlayerDist,MoveType,ai_bot_targetx[e],ai_bot_targety[e],ai_bot_targetz[e],stopstate) if CanFire == 1 then module_combatcore.fireweapon(e) end end if ai_bot_gofast[e] > 0 and Timer() > ai_bot_gofast[e]+500 then tWalkDelta = GetMovementDeltaManually(e,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) if tWalkDelta < 1.0 then StopAnimation(e) SetAnimationFrame(e,GetEntityAnimationStart(e,1)) SetAnimation(1) LoopAnimation(e) ModulateSpeed(e,1.0) ai_bot_gofast[e] = 0 end end end end if g_Entity[e]['plrvisible'] == 1 then ai_bot_hunttime[e] = Timer() else if ai_bot_hunttime[e] ~= nil then if ai_bot_hunttime[e] > 0 and Timer() > ai_bot_hunttime[e]+10000 then if ai_bot_state[e] ~= ai_state_duck and ai_bot_state[e] ~= ai_state_patrol then ai_bot_state[e] = ai_state_startmove ai_bot_hunttime[e] = 0 SetActivated(e,0) end end end --if g_Entity[e]['plrvisible'] == 0 and PlayerDist < 200 then Duff Logic - enemy could be chasing player around a maze and getting VERY close without seeing them, do not interfere! -- ai_bot_state[e] = ai_state_idle -- SetAnimation(0) -- CanFire = 0 -- module_combatcore.donotmove(e) --end end end function module_combatcore.handleducking(e,AIObjNo,PlayerDist) if ai_bot_state[e] == ai_state_crouchdashstart then ai_bot_state[e] = ai_state_crouchdash ai_bot_substate[e] = 0 StopAnimation(e) SetAnimationFrame(e,GetEntityAnimationStart(e,12)) SetAnimation(12) LoopAnimation(e) ModulateSpeed(e,1.25) SetAnimationSpeedModulation(e,1.25) randomevade = math.random(45,70) if math.random(1,2) == 1 then randomevade=randomevade*-1 end SetRotation(e,0,AIGetEntityAngleY(AIObjNo)+randomevade,0) StartTimer(e) else if ai_bot_state[e] == ai_state_crouchdash then tWalkDelta = GetMovementDeltaManually(e,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) if GetTimer(e) < 250 or (GetTimer(e) < 2000 and PlayerDist > 200 and tWalkDelta > 1.0) then if GetTimer(e) < 1750 then MoveForward(e,AIGetEntitySpeed(AIObjNo)) AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) end if GetTimer(e) > 1250 then RotateToPlayerSlowly(e,10.0) ModulateSpeed(e,1.0) SetAnimationSpeedModulation(e,1.0) end else ai_bot_state[e] = ai_state_checkforcover end end end module_combatcore.evasiveactions(e,AIObjNo,PlayerDist) module_combatcore.strafeleft(e,0.5) module_combatcore.straferight(e,0.5) module_combatcore.fireweapon(e) if ai_bot_state[e] == ai_state_rollstart then randomevade = math.random(65,90) if math.random(1,2) == 1 then randomevade=randomevade*-1 end local roty = AIGetEntityAngleY(AIObjNo)+randomevade local dist = 130 local rays = module_combatcore.checkentityrays(e,e,dist,roty,g_Entity[e]['obj'],20) if rays == 0 then SetRotation(e,0,roty,0) ai_bot_state[e] = ai_state_roll ai_bot_substate[e] = 0 SetAnimation(11) PlayAnimation(e) ModulateSpeed(e,1.25) SetAnimationSpeedModulation(e,1.25) else ai_bot_state[e] = ai_state_checkforcover end else if ai_bot_state[e] == ai_state_roll then tFrame = GetAnimationFrame(e) tStart = GetEntityAnimationStart(e,11) tFinish = GetEntityAnimationFinish(e,11) if tFrame > tStart + 1 and tFrame < tFinish - 20 then MoveForward(e,AIGetEntitySpeed(AIObjNo)) AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) else if tFrame >= tFinish - 20 then RotateToPlayerSlowly(e,30.0) end MoveForward(e,0.0) end if tFrame >= tFinish then ai_bot_state[e] = ai_state_checkforcover end end end if ai_bot_state[e] == ai_state_checkforcover then SetAnimationSpeedModulation(e,1.0) ModulateSpeed(e,1.0) StopAnimation(e) if module_combatcore.findandassigncover(e,AIObjNo,PlayerDist) == 1 then AIEntityGoToPosition(AIObjNo,ai_bot_targetx[e],ai_bot_targety[e],ai_bot_targetz[e]) ai_bot_state[e] = ai_state_startmove ai_bot_substate[e] = 0 else ai_bot_state[e] = ai_state_duckstart end end if ai_bot_state[e] == ai_state_duckstart then ai_bot_state[e] = ai_state_duck ai_bot_substate[e] = 0 RotateToPlayer(e) SetAnimation(7) PlayAnimation(e) SetAnimationSpeedModulation(e,1.0) else if ai_bot_state[e] == ai_state_duck then if ai_bot_substate[e] == 0 then tFrame = GetAnimationFrame(e) tFinish = GetEntityAnimationFinish(e,7) if tFrame >= tFinish then ai_bot_substate[e] = 1 StartTimer(e) SetAnimation(8) PlayAnimation(e) end end -- while ducking if ai_bot_substate[e] == 1 then -- stay put MoveForward(e,0.0) -- if see player, rotate slowly to shoot if g_Entity[e]['plrvisible'] == 1 then RotateToPlayerSlowly(e,30.0) module_combatcore.fireweapon(e) end -- if player gets too close, end duck and cover if g_Entity[e]['plrdist'] < 400 then ai_bot_state[e] = ai_state_unduckstart end -- if player at distance and in cover, pop head up and shoot at random if ai_bot_coverindex[e] > 0 and math.random(1,30) == 1 then ai_bot_state[e] = ai_state_unduckstart end -- if ducked for a while, and nothing happening, unduck if GetTimer(e) > 3000 and g_Entity[e]['plrvisible'] == 0 then ai_bot_state[e] = ai_state_unduckstart end end -- while ducking-popupshoot if ai_bot_substate[e] == 2 then StopAnimation(e) SetAnimationFrame(e,GetEntityAnimationStart(e,9)) SetAnimation(9) PlayAnimation(e) ai_bot_substate[e] = 3 else if ai_bot_substate[e] == 3 then RotateToPlayerSlowly(e,20.0) module_combatcore.fireweapon(e) tFrame = GetAnimationFrame(e) tFinish = GetEntityAnimationFinish(e,9) if tFrame >= tFinish then StopAnimation(e) SetAnimationFrame(e,GetEntityAnimationStart(e,7)) SetAnimation(7) PlayAnimation(e) ai_bot_substate[e] = 4 end else if ai_bot_substate[e] == 4 then RotateToPlayerSlowly(e,20.0) module_combatcore.fireweapon(e) tFrame = GetAnimationFrame(e) tFinish = GetEntityAnimationFinish(e,7) if tFrame >= tFinish then ai_bot_substate[e] = 1 StopAnimation(e) SetAnimationFrame(e,GetEntityAnimationStart(e,8)) SetAnimation(8) PlayAnimation(e) end end end end end if ai_bot_state[e] == ai_state_unduckstart then ai_bot_state[e] = ai_state_unduck SetAnimation(9) PlayAnimation(e) else if ai_bot_state[e] == ai_state_unduck then tFrame = GetAnimationFrame(e) tFinish = GetEntityAnimationFinish(e,9) if tFrame >= tFinish-1 and tFrame <= tFinish then ai_bot_state[e] = ai_state_startidle module_combatcore.releasecover(e) ai_bot_substate[e] = 0 end end end end end function module_combatcore.homein(e,AIObjNo,PlayerDist,MoveType,CanFire,stopstate) if ai_bot_state[e] == ai_state_startmove then if module_combatcore.getcomfortdistance(e) < 25 then -- no need to go to target, happy with close location determined by player position ai_bot_state[e] = stopstate else ai_bot_state[e] = ai_state_move SetAnimation(1) LoopAnimation(e) SetAnimationSpeedModulation(e,1.0) end end if ai_bot_state[e] == ai_state_move then -- scan if another bot is crowding player tbeingcrowded=0 for ee = 1 , g_EntityElementMax, 1 do if g_Entity[ee] ~= nil then pDX = g_Entity[ee]['x'] - g_PlayerPosX pDY = g_Entity[ee]['y'] - g_PlayerPosY pDZ = g_Entity[ee]['z'] - g_PlayerPosZ pDist = math.sqrt(math.abs(pDX*pDX)+math.abs(pDY*pDY)+math.abs(pDZ*pDZ)); if e ~= ee and pDist < 100 then tbeingcrowded=1 end end end if tbeingcrowded == 0 then ai_bot_targetx[e] = g_PlayerPosX ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = g_PlayerPosZ else ai_bot_targetx[e] = g_PlayerPosX + (math.sin(e)*50.0) ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = g_PlayerPosZ + (math.cos(e)*50.0) end module_combatcore.moveandavoid(e,AIObjNo,PlayerDist,MoveType,ai_bot_targetx[e],ai_bot_targety[e],ai_bot_targetz[e],stopstate) end end function module_combatcore.moveandavoid(e,AIObjNo,PlayerDist,MoveType,x,y,z,stopstate) movementfrozen = module_combateffects.ismovementfrozen(e) if ai_bot_substate[e] == 0 then if PlayerDist < 100 then if module_core.countaiaroundplayer() > 1 then tDistX = x - g_Entity[e]['x'] tDistZ = z - g_Entity[e]['z'] tDA = math.atan2(tDistX,tDistZ) x = x + (math.sin(tDA) * 50) z = z + (math.cos(tDA) * 50) end end AIEntityGoToPosition(AIObjNo,x,y,z) SetRotationYSlowly(e,AIGetEntityAngleY(AIObjNo),25.0) --10.0) when rotate too slowly, miss target node position! if movementfrozen == 0 then dy = g_PlayerPosY - (g_Entity[e]['y']+50) local stopifclosetofinaldest = 0 if ai_bot_state[e] ~= ai_state_patrol then stopifclosetofinaldest = math.sqrt(math.abs(dy*dy)) if stopifclosetofinaldest < 75 then dx = g_PlayerPosX - g_Entity[e]['x'] dz = g_PlayerPosZ - g_Entity[e]['z'] stopifclosetofinaldest = math.sqrt(math.abs(dx*dx)+math.abs(dz*dz)) if stopifclosetofinaldest < 35 then ai_bot_closeenoughx[e] = g_PlayerPosX ai_bot_closeenoughy[e] = g_PlayerPosY ai_bot_closeenoughz[e] = g_PlayerPosZ AIEntityGoToPosition(AIObjNo,ai_bot_closeenoughx[e],ai_bot_closeenoughy[e],ai_bot_closeenoughz[e]) RotateToPlayer(e) stopifclosetofinaldest = 1 else stopifclosetofinaldest = 0 end else stopifclosetofinaldest = 0 end end if stopifclosetofinaldest == 0 then tDistX = x - g_Entity[e]['x'] tDistY = y - g_Entity[e]['y'] tDistZ = z - g_Entity[e]['z'] stopifclosetofinaldest = math.sqrt(math.abs(tDistX*tDistX)+math.abs(tDistY*tDistY)+math.abs(tDistZ*tDistZ)) if stopifclosetofinaldest < 50 then stopifclosetofinaldest = 1 else stopifclosetofinaldest = 0 end end if AIGetEntityIsMoving(AIObjNo) == 1 and stopifclosetofinaldest == 0 then ai_bot_closeenoughx[e] = 0 ai_bot_closeenoughy[e] = 0 ai_bot_closeenoughz[e] = 0 if MoveType == ai_movetype_useanim then MoveWithAnimation(e,1) else local speedmod = 1.0 if ai_bot_state[e] == ai_state_patrol then speedmod = 0.5 end MoveForward(e,AIGetEntitySpeed(AIObjNo)*speedmod) end else MoveForward(e,0.0) if GetTimer(e) > 250 then ai_bot_state[e] = stopstate end end AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) end if g_Entity[e]['avoid'] == 2 or (g_Entity[e]['avoid'] == 1 and stopstate ~= ai_state_startpatrol) then ai_bot_substate[e] = math.random(1,2) if ai_bot_substate[e] == 1 then tAvoidAngle = AIGetEntityAngleY(AIObjNo)-95 else tAvoidAngle = AIGetEntityAngleY(AIObjNo)+95 end tAvoidAngle = (tAvoidAngle / 360.0) * 6.28 tAvoidX = GetEntityPositionX(e) + (math.sin(tAvoidAngle) * 30) tAvoidZ = GetEntityPositionZ(e) + (math.cos(tAvoidAngle) * 30) AIEntityGoToPosition(AIObjNo,tAvoidX,GetEntityPositionY(e),tAvoidZ) StartTimer(e) end end if ai_bot_substate[e] > 0 and ai_bot_state[e] ~= ai_state_duck then SetRotation(e,0,AIGetEntityAngleY(AIObjNo),0) if movementfrozen == 0 then if AIGetEntityIsMoving(AIObjNo) == 1 then if MoveType == ai_movetype_useanim then MoveWithAnimation(e,1) else MoveForward(e,AIGetEntitySpeed(AIObjNo)) end else MoveForward(e,0.0) end AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) end if GetTimer(e) > 1000 then ai_bot_substate[e] = 0 end end end function module_combatcore.donotmove(e) MoveForward(e,0) ai_bot_substate[e] = 0 end function module_combatcore.sensepunch(e,AIObjNo,PlayerDist,combattype) if PlayerDist < 150 and combattype == ai_combattype_freezermelee and ai_bot_state[e] ~= ai_state_move then RotateToPlayer(e) end if ai_bot_state[e] == ai_state_move or ai_bot_state[e] == ai_state_fireonspot then if PlayerDist < 75 and g_PlayerPosY > g_Entity[e]['y'] and g_PlayerPosY < g_Entity[e]['y']+70 then -- must also check for line of sight (i.e not through walls) (first and third person) thaslineofsight = 0 tthitvalue = IntersectAll(g_Entity[e]['x'],g_Entity[e]['y']+50,g_Entity[e]['z'],g_PlayerPosX,g_PlayerPosY+50,g_PlayerPosZ,AIObjNo) ttpersonobj = 0 if GetGamePlayerControlThirdpersonEnabled() == 1 then ttpersone = GetGamePlayerControlThirdpersonCharactere() if ttpersone > 0 then ttpersonobj = GetEntityElementObj(ttpersone) if GetObjectExist(ttpersonobj) == 0 then ttpersonobj = 0 end end end if tthitvalue == 0 or tthitvalue == playerobj then thaslineofsight = 1 end if thaslineofsight == 1 then ai_bot_state[e] = ai_state_punch SetAnimation(2) PlayAnimation(e) SetAnimationSpeedModulation(e,1.0) PlaySound(e,1) RotateToPlayer(e) if combattype == ai_combattype_freezermelee then module_cameraoverride.beingattackedby(e,60.0) end end end end end function module_combatcore.hurt(e,PlayerDist,responsestate) if ai_bot_state[e] == ai_state_idle or ai_bot_state[e] == ai_state_patrol or ai_bot_state[e] == ai_state_move or ai_bot_state[e] == ai_state_fireonspot or ai_bot_state[e] == ai_state_recover or ai_bot_state[e] == ai_state_punch or ai_bot_state[e] == ai_state_duck then if g_Entity[e]['health'] < ai_bot_oldhealth[e] then if ai_bot_state[e] == ai_state_duck then ai_bot_state[e] = ai_state_unduckstart else if (ai_bot_state[e] == ai_state_move or ai_bot_state[e] == ai_state_idle or ai_bot_state[e] == ai_state_fireonspot) and PlayerDist > 300 then if math.random(1,3) == 1 then ai_bot_state[e] = ai_state_rollstart else ai_bot_state[e] = ai_state_crouchdashstart end else if ai_bot_state[e] == ai_state_roll then -- AI is immune to damage when rolling SetEntityHealth(e,ai_bot_oldhealth[e]) else local flinch = math.random(1,3) if flinch == 1 then ai_bot_state[e] = ai_state_hurt SetAnimationSpeed(e,3.0) SetAnimation(3) PlayAnimation(e) SetAnimationSpeedModulation(e,1.0) end end end end ai_bot_oldhealth[e] = g_Entity[e]['health'] ai_bot_angryhurt[e] = 1 PlaySound(e,math.random(3,4)) module_agro.alertallwithinradius(g_Entity[e]['x'],g_Entity[e]['y'],g_Entity[e]['z'],250.0) end end if ai_bot_state[e] == ai_state_hurt then MoveForward(e,0.0) RotateToPlayerSlowly(e,10.0) tFrame = GetAnimationFrame(e) tStart = GetEntityAnimationFinish(e,3) if tFrame >= tStart then SetAnimationSpeed(e,1.0) ai_bot_state[e] = responsestate end end end function module_combatcore.headshot(e) if string.find(string.lower(g_Entity[e]['limbhit']), "head") ~= nil then SetEntityHealth(e,0) ResetLimbHit(e) end end function module_combatcore.soundawareness(e,AIObjNo) if AIGetEntityHeardSound(AIObjNo) == 1 then local botState = ai_bot_state[e] if botState == ai_state_idle or botState == ai_state_hurt then ai_bot_sighting[e] = Timer()+500 elseif botState == ai_state_patrol then ai_bot_state[e] = ai_state_startidle ai_bot_sighting[e] = Timer()+500 else ai_bot_sighting[e] = 0 end end if ai_bot_sighting[e] > 0 and Timer() < ai_bot_sighting[e] then RotateToPlayerSlowly( e, 10.0 ) end end function module_combatcore.punch(e,AIObjNo,PlayerDist,combattype,afterstate) if ai_bot_state[e] == ai_state_punch then wemoved = 0 if combattype == ai_combattype_freezermelee then if module_cameraoverride.manageattackcycle(e) == 1 then MoveWithAnimation(e,1) wemoved = 1 end end tFrame = GetAnimationFrame(e) tStart = GetEntityAnimationStart(e,2) tFinish = GetEntityAnimationFinish(e,2) tDamageFramesStart = GetEntityAnimationStart(e,5) tDamageFramesFinish = GetEntityAnimationFinish(e,5) if tDamageFramesStart > 0 and tDamageFramesFinish > 0 then -- override defaults if anim5 specifies specific damage frame range tStart = tDamageFramesStart tFinish = tDamageFramesFinish if combattype == ai_combattype_freezermelee then tStart = tStart - 10 tFinish = tFinish + 30 else if combattype == ai_combattype_bashmelee then tStart = tStart - 25 else tStart = tStart - 10 end end end if PlayerDist < 90 then if combattype == ai_combattype_freezermelee then if tFrame >= tStart+10 and tFrame <= tFinish-30 then if math.random(1,7) == 1 then HurtPlayer(e,math.random(1,2)) end end else if combattype == ai_combattype_bashmelee then if tFrame >= tStart+25 and tFrame <= tStart+35 then HurtPlayer(e,math.random(2,3)) ForcePlayer ( g_Entity[e]['angley'], 2.0 ) end else if tFrame >= tStart+10 and tFrame <= tStart+15 then HurtPlayer(e,math.random(2,3)) ForcePlayer ( g_Entity[e]['angley'], 3.0 ) end end end end if combattype == ai_combattype_freezermelee then if tFrame >= tFinish-30 then if module_cameraoverride.finishbeingattacked(e) == 1 then ForcePlayer ( g_Entity[e]['angley'], 3.0 ) end else if module_cameraoverride.hasowner() == 0 then ai_bot_state[e] = ai_state_recoverstart end end end if tFrame >= tFinish then if combattype == ai_combattype_freezermelee or combattype == ai_combattype_bashmelee then ai_bot_state[e] = ai_state_recoverstart else ai_bot_state[e] = afterstate end end if wemoved == 0 then module_combatcore.donotmove(e) end end end function module_combatcore.recover(e,resumestate) if ai_bot_state[e] == ai_state_recoverstart then ai_bot_state[e] = ai_state_recover StopAnimation(e) SetAnimation(0) SetAnimationFrame(e,GetEntityAnimationStart(e,0)) PlayAnimation(e) SetAnimationSpeedModulation(e,1.0) StartTimer(e) end if ai_bot_state[e] == ai_state_recover then module_combatcore.donotmove(e) if GetTimer(e) > 100 then ai_bot_state[e] = resumestate end end end function module_combatcore.fireonspot(e,AIObjNo) if ai_bot_state[e] == ai_state_startfireonspot then ai_bot_state[e] = ai_state_fireonspot StopAnimation(e) SetAnimation(0) LoopAnimation(e) SetAnimationSpeedModulation(e,1.0) StartTimer(e) end if ai_bot_state[e] == ai_state_fireonspot then if g_Entity[e]['plrvisible'] == 0 and GetTimer(e) > 500 then if ai_bot_state[e] ~= ai_state_startidle then ai_bot_state[e] = ai_state_startidle end else RotateToPlayer(e) module_combatcore.fireweapon(e) ai_bot_targetx[e] = g_PlayerPosX ai_bot_targety[e] = g_PlayerPosY ai_bot_targetz[e] = g_PlayerPosZ AIEntityGoToPosition(AIObjNo,ai_bot_targetx[e],ai_bot_targety[e],ai_bot_targetz[e]) end module_combatcore.donotmove(e) end end function module_combatcore.fireweapon(e) if ai_bot_state[e] ~= ai_state_startreload and ai_bot_state[e] ~= ai_state_reload and ai_bot_state[e] ~= ai_state_reloadsettle then if GetAmmoClip(e) > 0 then FireWeapon(e) else tReloadFinishFrame = GetEntityAnimationFinish(e,4) if tReloadFinishFrame > 0 then ai_bot_state[e] = ai_state_startreload end end end end function module_combatcore.reloadweapon(e) if ai_bot_state[e] == ai_state_startreload then ai_bot_state[e] = ai_state_reload SetAnimation(4) PlayAnimation(e) SetAnimationSpeedModulation(e,1.0) tStart = GetEntityAnimationStart(e,4) SetAnimationFrame(e,tStart) StartTimer(e) else if ai_bot_state[e] == ai_state_reload then if GetTimer(e) > 500 then tFrame = GetAnimationFrame(e) tStart = GetEntityAnimationStart(e,4) tFinish = GetEntityAnimationFinish(e,4) tDiffHalf = (tFinish - tStart) / 3 if (tFrame >= tFinish - tDiffHalf and tFrame <= tFinish ) or tFinish == 0 then ai_bot_state[e] = ai_state_reloadsettle StartTimer(e) end end module_combatcore.donotmove(e) else if ai_bot_state[e] == ai_state_reloadsettle then if GetTimer(e) > 750 then SetAmmoClip(e,GetAmmoClipMax(e)) ai_bot_state[e] = ai_state_startidle end module_combatcore.donotmove(e) end end end end function module_combatcore.preexit(e,MoveType) tFrame = GetAnimationFrame(e) tDyingAnimStart = GetEntityAnimationStart(e,6) tDyingAnimFinish = GetEntityAnimationFinish(e,6) if tDyingAnimStart > 0 and tDyingAnimFinish > 0 then if ai_bot_state[e] ~= ai_state_preexit then ai_bot_state[e] = ai_state_preexit CharacterControlLimbo(e) StopAnimation(e) SetAnimation(6) PlayAnimation(e) SetAnimationFrame(e,tDyingAnimStart) SetAnimationSpeedModulation(e,1.0) end else return 1 end if tFrame >= tDyingAnimFinish-2 then return 1 else return 0 end end function module_combatcore.exit(e) StopSound(e,0) StopSound(e,1) CollisionOff(e) end function module_combatcore.evasiveactions(e,AIObjNo,PlayerDist) if ai_bot_state[e] ~= ai_state_idle and ai_bot_state[e] ~= ai_state_move and ai_bot_state[e] ~= ai_state_startmove and ai_bot_state[e] ~= ai_state_roll and ai_bot_state[e] ~= ai_state_strafeleft and ai_bot_state[e] ~= ai_state_strafeleftstart and ai_bot_state[e] ~= ai_state_straferightstart and ai_bot_state[e] ~= ai_state_straferight and ai_bot_state[e] ~= ai_state_duckstart and ai_bot_state[e] ~= ai_state_duck and ai_bot_state[e] ~= ai_state_unduckstart then if math.random(1,2) == 1 then local pdist = GetPlayerDistance(e) if pdist > 200 then if module_combatcore.playerlooking(e,pdist,10) == 1 then local rays = module_combatcore.checkplayertoentityrays(pdist+5,0,0,60) if rays == g_Entity[e]['obj'] or rays == 0 then local temp = math.random(1,6) --set max to 7 or higher to add a chance to roll if temp < 7 then if module_combatcore.entitylookingatplayer(e,PlayerDist,10) ~= 1 then temp = 99 end end if ai_bot_last_sidestep[e] == nil then ai_bot_last_sidestep[e] = 0 end if temp < 4 then if ai_bot_last_sidestep[e] == 0 then ai_bot_last_sidestep[e] = -15 ai_bot_state[e] = ai_state_strafeleftstart else if ai_bot_last_sidestep[e] < 0 then ai_bot_last_sidestep[e] = ai_bot_last_sidestep[e] + 1 else ai_bot_last_sidestep[e] = ai_bot_last_sidestep[e] - 1 end end elseif temp < 7 then if ai_bot_last_sidestep[e] == 0 then ai_bot_last_sidestep[e] = 15 ai_bot_state[e] = ai_state_straferightstart else if ai_bot_last_sidestep[e] < 0 then ai_bot_last_sidestep[e] = ai_bot_last_sidestep[e] + 1 else ai_bot_last_sidestep[e] = ai_bot_last_sidestep[e] - 1 end end elseif temp < 8 then ai_bot_state[e] = ai_state_rollstart end end end end end end end function module_combatcore.strafeleft(e,speedmod) if ai_bot_state[e] == ai_state_strafeleftstart then ai_bot_state[e] = ai_state_checkforcover randomevade = math.random(45,90)*-1 local dist = 120 local rays = module_combatcore.checkentityrays(e,dist,randomevade,g_Entity[e]['obj'],20) if rays == 0 then ai_bot_state[e] = ai_state_strafeleft ai_bot_substate[e] = 0 SetAnimationFrame(e,GetEntityAnimationStart(e,15)) SetAnimation(15) PlayAnimation(e) g_Entity[e]['animating'] = 15 ModulateSpeed(e,1) SetAnimationSpeedModulation(e,1.5) ai_bot_roty[e] = AIGetEntityAngleY(AIObjNo) local temprot = AIGetEntityAngleY(AIObjNo)+randomevade SetRotation(e,0,temprot,0) ai_bot_newroty[e] = temprot end end if ai_bot_state[e] == ai_state_strafeleft then tFrame = GetAnimationFrame(e) tStart = GetEntityAnimationStart(e,15) tFinish = GetEntityAnimationFinish(e,15) if tFrame >= tStart+5 and tFrame < tFinish-8 and g_Entity[e]['animating'] == 15 then SetRotation(e,0,ai_bot_newroty[e],0) MoveForward(e,AIGetEntitySpeed(AIObjNo)*speedmod) end SetRotation(e,0,ai_bot_roty[e],0) AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) if tFrame >= tFinish-2 and tFrame <= tFinish then ai_bot_state[e] = ai_state_startfireonspot SetAnimationSpeedModulation(e,1) end end end function module_combatcore.straferight(e,speedmod) if ai_bot_state[e] == ai_state_straferightstart then ai_bot_state[e] = ai_state_checkforcover randomevade = math.random(45,90) local dist = 120 local rays = module_combatcore.checkentityrays(e,dist,randomevade,g_Entity[e]['obj'],20) if rays == 0 then ai_bot_state[e] = ai_state_straferight ai_bot_substate[e] = 0 SetAnimationFrame(e,GetEntityAnimationStart(e,16)) SetAnimation(16) PlayAnimation(e) g_Entity[e]['animating'] = 16 ModulateSpeed(e,1) SetAnimationSpeedModulation(e,1.5) ai_bot_roty[e] = AIGetEntityAngleY(AIObjNo) local temprot = AIGetEntityAngleY(AIObjNo)+randomevade SetRotation(e,0,temprot,0) ai_bot_newroty[e] = temprot end end if ai_bot_state[e] == ai_state_straferight then tFrame = GetAnimationFrame(e) tStart = GetEntityAnimationStart(e,16) tFinish = GetEntityAnimationFinish(e,16) if tFrame >= tStart+5 and tFrame < tFinish-8 then SetRotation(e,0,ai_bot_newroty[e],0) MoveForward(e,AIGetEntitySpeed(AIObjNo)*speedmod) end SetRotation(e,0,ai_bot_roty[e],0) AISetEntityPosition(AIObjNo,GetEntityPositionX(e),GetEntityPositionY(e),GetEntityPositionZ(e)) if tFrame >= tFinish-2 and tFrame <= tFinish and g_Entity[e]['animating'] == 16 then ai_bot_state[e] = ai_state_startfireonspot SetAnimationSpeedModulation(e,1) end end end function module_combatcore.getangletopoint(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 return angle end end function module_combatcore.checkfiredrecently(e,window) if last_fired[e] == nil then last_fired[e] = g_Time end local tfired = 0 if g_Time > last_fired[e]+window then tfired = 0 else tfired = 1 end return tfired end function module_combatcore.checkentityrays(e,dist,ang,obj,yoff) if g_Entity[e]['obj'] ~= nil then if dist == nil then dist = 10 end if ang == nil then ang = 0 end if obj == nil then ang = 0 end new_y = math.rad(GetEntityAngleY(e)+ang) x1 = GetEntityPositionX(e) y1 = GetEntityPositionY(e)+yoff z1 = GetEntityPositionZ(e) x2 = x1 + (math.sin(new_y) * dist) y2 = y1 z2 = z1 + (math.cos(new_y) * dist) local hit = 0 hit = RayTerrain(x1,y1,z1,x2,y2,z2) if hit == nil then hit = 0 end if hit ~= 1 then hit = IntersectAll(x1,y1,z1,x2,y2,z2,obj) end if hit == nil then hit = 0 end return hit end end function module_combatcore.checkplayertoentityrays(dist,ang,obj,yoff) if dist == nil then dist = 10 end if ang == nil then ang = 0 end if obj == nil then ang = 0 end new_y = math.rad(g_PlayerAngY)+ang x1 = g_PlayerPosX y1 = g_PlayerPosY+yoff z1 = g_PlayerPosZ x2 = x1 + (math.sin(new_y) * dist) y2 = y1 z2 = z1 + (math.cos(new_y) * dist) local hit = 0 hit = RayTerrain(x1,y1,z1,x2,y2,z2) if hit == nil then hit = 0 end if hit ~= 1 then hit = IntersectAll(x1,y1,z1,x2,y2,z2,obj) end if hit == nil then hit = 0 end return hit end function module_combatcore.playerlooking(e,dis,v) if g_Entity[e] ~= nil then if dis == nil then dis = 3000 end if v == nil then v = 0.5 end if GetPlayerDistance(e) <= dis then local destx = g_Entity[e]['x'] - g_PlayerPosX local destz = g_Entity[e]['z'] - g_PlayerPosZ 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 while g_PlayerAngY < 0 or g_PlayerAngY > 360 do if g_PlayerAngY <= 0 then g_PlayerAngY = 360 + g_PlayerAngY elseif g_PlayerAngY > 360 then g_PlayerAngY = g_PlayerAngY - 360 end end local L = angle - v local R = angle + 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 (L < R and math.abs(g_PlayerAngY) > L and math.abs(g_PlayerAngY) < R) then return 1 elseif (L > R and (math.abs(g_PlayerAngY) > L or math.abs(g_PlayerAngY) < R)) then return 1 else return 0 end else return 0 end end end function module_combatcore.entitylookingatplayer(e,dis,v) if g_Entity[e] ~= nil then if dis == nil then dis = 3000 end if v == nil then v = 0.5 end local distx = g_PlayerPosX - g_Entity[e]['x'] local disty = g_PlayerPosY - g_Entity[e]['y'] local distz = g_PlayerPosZ - g_Entity[e]['z'] local tdist = math.sqrt((distx^2)+(disty^2)+(distz^2)) if tdist <= dis then local destx = distx local destz = distz 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 while g_Entity[e]['angley'] < 0 or g_Entity[e]['angley'] > 360 do if g_Entity[e]['angley'] <= 0 then g_Entity[e]['angley'] = 360 + g_Entity[e]['angley'] elseif g_Entity[e]['angley'] > 360 then g_Entity[e]['angley'] = g_Entity[e]['angley'] - 360 end end local L = angle - v local R = angle + 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 (L < R and math.abs(g_Entity[e]['angley']) > L and math.abs(g_Entity[e]['angley']) < R) then return 1 elseif (L > R and (math.abs(g_Entity[e]['angley']) > L or math.abs(g_Entity[e]['angley']) < R)) then return 1 else return 0 end else return 0 end end end return module_combatcore