-- 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 tooClose = {} local timer = {} local timed = {} local started = {} local mandogattackpos = {} local maxdistance = {} local direction = {} local health = {} local healthset = {} local range = {} local soundPlayed = {} local goalx = {} local goalz = {} function mandogattack_init(e) state[e] = "walking" 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 tooClose[e] = 0 timer[e] = 0 timed[e] = 0 started[e] = 0 mandogattackpos[e] = 0 maxdistance[e] = 0 direction[e] = 0 health[e] = 1000 healthset[e] = 0 ai_soldier_pathindex[e] = -1 range[e] = 2000 soundPlayed[e] = 0 goalx[e] = 0 goalz[e] = 0 end function mandogattack_main(e) if g_PlayerHealth < 1 then mandogattack_init(e) end --Prompt(state[e].." "..curious[e].." "..walking[e]) 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 GoalmandogattackDistance(e) < 100 then tooClose[e] = 1 else tooClose[e] = 0 end if g_Entity[e]['health'] < health[e] then aggressive[e] = 1 end if aggressive[e] == 0 and animationcomplete[e] == 1 then if GetPlayerDistance(e) > 800 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 elseif GetPlayerDistance(e) < 800 and GetPlayerDistance(e) > 500 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 elseif GetPlayerDistance(e) < 500 and GetPlayerDistance(e) > 100 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 elseif GetPlayerDistance(e) < 100 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 end elseif aggressive[e] == 1 and animationcomplete[e] == 1 then if GetPlayerDistance(e) < 100 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 end if GetPlayerDistance(e) > 100 and GetPlayerDistance(e) < 1000 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 end if GetPlayerDistance(e) > 1000 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 aggressive[e] = 0 end end if walking[e] == 1 then ModulateSpeed(e,1) --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) --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 Prompt("No waypoints") --if no waypoints are set --CharacterControlLimbo(e) SetCharacterToWalk(e) CharacterControlUnarmed(e) ModulateSpeed(e,1) if g_Entity[e]['animating'] == 0 then SetAnimationFrames(37,86) LoopAnimation(e) g_Entity[e]['animating'] = 1 end end if GetAnimationFrame(e) > 86 or GetAnimationFrame(e) < 37 then SetAnimationFrames(86,86) end AIEntityGoToPosition(g_Entity[e]['obj'],goalx[e],goalz[e]) -- MoveForward(e,50) --RotateToPointSlowly(e,goalx[e],goalz[e],0.8) 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 approaching[e] == 1 then Prompt("Approaching") CharacterControlLimbo(e) ModulateSpeed(e,1.5) if g_Entity[e]['animating'] == 0 then SetAnimationFrames(5,32) LoopAnimation(e) g_Entity[e]['animating'] = 1 end RotateToPlayerSlowly(e,9) MoveForward(e,150) end if curious[e] == 1 then CharacterControlLimbo(e) ModulateSpeed(e,2) RotateToPlayerSlowly(e,8) if g_Entity[e]['animating'] == 0 then SetAnimationFrames(37,86) LoopAnimation(e) g_Entity[e]['animating'] = 1 end MoveForward(e,50) end if attacking[e] == 1 then StopSound(e,0) CharacterControlLimbo(e) if animationcomplete[e] == 1 then attacktype[e] = math.random(0,1) animationcomplete[e] = 0 end ModulateSpeed(e,2) RotateToPlayer(e) if GetAnimationFrame(e) == 75 or GetAnimationFrame(e) == 1110 or GetAnimationFrame(e) == 150 then PlaySound(e,1) end if attacktype[e] == 0 then if g_Entity[e]['animating'] == 0 then SetAnimationFrames(130,170) PlayAnimation(e) g_Entity[e]['animating'] = 1 end if GetAnimationFrame(e) > 150 and GetAnimationFrame(e) < 152 then hitting[e] = 1 PlaySound(e,1) else hitting[e] = 0 end if GetAnimationFrame(e) == 169 then animationcomplete[e] = 1 else animationcomplete[e] = 0 end if hitting[e] == 1 and GetPlayerDistance(e) < 130 then HurtPlayer(e,10) end end if attacktype[e] == 1 then if g_Entity[e]['animating'] == 0 then SetAnimationFrames(90,130) PlayAnimation(e) g_Entity[e]['animating'] = 1 end if GetAnimationFrame(e) > 110 and GetAnimationFrame(e) < 115 then hitting[e] = 1 PlaySound(e,1) else hitting[e] = 0 end if GetAnimationFrame(e) == 90 then animationcomplete[e] = 0 end if GetAnimationFrame(e) == 130 then animationcomplete[e] = 1 end if hitting[e] == 1 and GetPlayerDistance(e) < 130 then HurtPlayer(e,10) end end end if g_PlayerHealth < 1 then mandogattack_init(e) end end function mandogattack_exit(e) ModulateSpeed(e,1.0) CharacterControlLimbo(e) SetAnimationFrames(500,550) PlayAnimation(e) StopSound(e) end function mandogattackDistance(e) mandogattackDX = (g_Entity[e]['x'] - xpos[e]) mandogattackDY = (g_Entity[e]['y'] - ypos[e]) mandogattackDZ = (g_Entity[e]['z'] - zpos[e]) if math.abs(mandogattackDY) > 100 then mandogattackDY = mandogattackDY * 4 end return math.sqrt(math.abs(mandogattackDX*mandogattackDX)+math.abs(mandogattackDY*mandogattackDY)+math.abs(mandogattackDZ*mandogattackDZ)); end function GoalmandogattackDistance(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