i also made a ai_pedestrian.lua script a while ago witch i gave away as a freebie, ( all credit to Lee)
-- LUA Script - precede every function and global member with lowercase name of script
local ps1 = {}
local nn1 = {}
-- init when level first runs
function ai_pedestrian_init(e)
ps1[e] = 0
nn1[e] = 0
ai_soldier_state[e] = "patrol";
ai_soldier_pathindex[e] = -1;
ai_start_x[e] = nil
ai_starting_heath[e] = nil
ai_ran_to_cover[e] = 0
ModulateSpeed(e,1.0)
ai_old_health[e] = 0
CharacterControlStand(e)
ai_returning_home[e] = 0
ai_newdest_time[e] = -1
ai_cover_on[e] = 0
ai_alerted_spoken[e] = 0
SetCharacterSoundSet(e)
end
function ai_pedestrian_main(e)
CharacterControlUnarmed(e)
-- Death Animation
if ai_soldier_state[e] ~= "deathanim" then
-- Detect player distance (note: possible optimization here)
PlayerDX = g_Entity[e]['x'] - g_PlayerPosX;
PlayerDY = g_Entity[e]['y'] - g_PlayerPosY;
PlayerDZ = g_Entity[e]['z'] - g_PlayerPosZ;
PlayerDist = math.sqrt(math.abs(PlayerDX*PlayerDX)+math.abs(PlayerDY*PlayerDY)+math.abs(PlayerDZ*PlayerDZ));
-- Entity Object Number
EntObjNo = g_Entity[e]['obj'];
-- Handle health
if ai_starting_heath[e] == nil then
ai_starting_heath[e] = g_Entity[e]['health']
end
-- Store starting point so we can return there if player moves far away
if ai_start_x[e] == nil then
ai_start_x[e] = g_Entity[e]['x']
ai_start_z[e] = g_Entity[e]['z']
AISetEntityControl(EntObjNo,AI_MANUAL);
end
-- Patrol Mode
if ai_soldier_state[e] == "patrol" then
-- Try and find a close path to patrol, just check once for it
if ai_soldier_pathindex[e] == -1 then
ai_soldier_pathindex[e] = -2
CharacterControlArmed(e)
-- find initial waypoint path to follow
PathIndex = -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;
end
end -- po
end -- pa
-- follow found path
if PathIndex > -1 then
ai_soldier_pathindex[e] = PathIndex;
ai_path_point_index[e] = 2
ModulateSpeed(e,0.7)
SetCharacterToWalk(e)
ai_path_point_direction[e] = 1
ai_path_point_max[e] = AIGetPathCountPoints(ai_soldier_pathindex[e])
end
end
-- Force character as unarmed
CharacterControlUnarmed(e)
-- If set to head home, lets go there
if ai_returning_home[e] == 1 then
tDistX = g_Entity[e]['x'] - ai_start_x[e];
tDistZ = g_Entity[e]['z'] - ai_start_z[e];
DistToStart = math.sqrt(math.abs(tDistX*tDistX)+math.abs(tDistZ*tDistZ))
if DistToStart < 200 or GetTimer(e) > ai_combat_state_delay[e] then
ai_soldier_pathindex[e] = -1
SetCharacterToWalk(e)
CharacterControlUnarmed(e)
AIEntityStop(EntObjNo);
ModulateSpeed(e,1.0)
ai_returning_home[e] = 0
ai_soldier_state[e] = "alerted"
ai_alerted_mode[e] = 0
else
AIEntityGoToPosition(EntObjNo,ai_start_x[e],ai_start_z[e])
end
-- If we have a path then lets patrol it
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])
AIEntityGoToPosition(EntObjNo,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 < 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
--wander code
if PlayerDist < 70 and ps1[e] == 0 then
AIEntityStop(EntObjNo);
RotateToPlayer(e)
LookAtPlayer(e)
CharacterControlFidget(e)
Prompt("What do you want?")
PlaySound(e,1)
ps1[e] = 1
if GetTimer(e) >4000 then
tempangle = math.random(6.28)
tempx = g_Entity[e]['x']+(math.cos(tempangle)*400);
tempz = g_Entity[e]['z']+(math.sin(tempangle)*400);
AIEntityGoToPosition(EntObjNo,tempx,tempz)
StartTimer(e)
end
else
if PlayerDist > 80 then
ps1[e] = 0
end
if GetTimer(e)>5500 and nn1[e] == 0 then --timer value to tel ai when to change to next x and z pos.
tempangle = math.random(6.28)
tempx = g_Entity[e]['x']+(math.cos(tempangle)*400);
tempz = g_Entity[e]['z']+(math.sin(tempangle)*400);
AIEntityGoToPosition(EntObjNo,tempx,tempz)
StartTimer(e)
end
end
tDistX = g_Entity[e]['x'] - ai_start_x[e];
tDistZ = g_Entity[e]['z'] - ai_start_z[e];
DistToStart = math.sqrt(math.abs(tDistX*tDistX)+math.abs(tDistZ*tDistZ))
if PlayerDist > 2000 then ------------------------------------------- increase this value to roam far away
CharacterControlFidget(e)
Prompt("I'm to Far away ")
AIEntityGoToPosition(g_Entity[e]['obj'],g_PlayerPosX,g_PlayerPosZ) -----use this line for going to player
--AIEntityGoToPosition (EntObjNo,ai_start_x[e],ai_start_z[e])----------- use this line to go to start point
CharacterControlFidget(e)
nn1[e] = 1
end
if PlayerDist < 600 and GetTimer(e)>5500 then -- this line tels ai not to walk not to close to player when they return.
Prompt("I'm to close")
nn1[e] = 0
end
end
end
if string.find(string.lower(g_Entity[e]['limbhit']), "head") ~= nil then
ai_soldier_state[e] = "deathanim"
PlayCharacterSound(e,"onDeath")
StartTimer(e)
CharacterControlLimbo(e)
BulletRayDX = g_Entity[e]['x'] - g_PlayerPosX;
BulletRayDY = g_Entity[e]['y'] - g_PlayerPosY;
BulletRayDZ = g_Entity[e]['z'] - g_PlayerPosZ;
BulletAngle = (math.atan2(BulletRayDX,BulletRayDZ)/6.28)*360
BulletAngle = BulletAngle + g_Entity[e]['angley']
if BulletAngle < 0 then
BulletAngle = BulletAngle + 360
end
if BulletAngle >= 360 then
BulletAngle = BulletAngle - 360
end
if BulletAngle >= 360 then
BulletAngle = BulletAngle - 360
end
--Prompt ( BulletAngle )
if BulletAngle >= 360-45 or BulletAngle <= 0+45 then
SetAnimationFrames(5031,5050)
SetAnimationFrame(e,5031)
end
if BulletAngle >= 180-45 and BulletAngle <= 180+45 then
SetAnimationFrames(4972,5002)
SetAnimationFrame(e,4972)
end
if BulletAngle >= 90-45 and BulletAngle <= 90+45 then
-- side hit animations not aligned for this technique (yet)
SetAnimationFrames(4972,5002)
SetAnimationFrame(e,4972)
end
if BulletAngle >= 270-45 and BulletAngle <= 270+45 then
-- side hit animations not aligned for this technique (yet)
SetAnimationFrames(4972,5002)
SetAnimationFrame(e,4972)
end
PlayAnimation(e)
ModulateSpeed(e,1.0)
SetAnimationSpeed(e,1.5)
end
else --DeathAnim Else
-- wait until death anim mostly over, then switch to ragdoll
if GetTimer(e)>200 then
SetEntityHealth(e,0)
BulletRayDX = g_Entity[e]['x'] - g_PlayerPosX;
BulletRayDY = g_Entity[e]['y'] - g_PlayerPosY;
BulletRayDZ = g_Entity[e]['z'] - g_PlayerPosZ;
SetEntityRagdollForce(e,g_Entity[e]['limbhitindex'],BulletRayDX,BulletRayDY,BulletRayDZ,750)
ResetLimbHit(e)
end
end --DeathAnim Endif
-- Debug prompt
--if ai_soldier_state[e] ~= nil and ai_combat_mode[e] ~= nil and g_Entity[e]['angley'] ~= nil then
-- Prompt( ai_soldier_state[e] .. " mode=" .. ai_combat_mode[e] .. " angley=" .. g_Entity[e]['angley'] )
--else
-- Prompt( "angley=" .. g_Entity[e]['angley'] )
--end
end
function ai_loopnet_exit(e)
if ai_soldier_state[e] ~= "deathanim" then
PlayCharacterSound(e,"onDeath")
end
end
in this one you can control how far it must wonder before it turns back and when it turns back does it go to the player's direction or there own starting point.
Windows 7 Professional 64-bit
Intel(R) Pentium(R) CPU G3260 @ 3.30GHz (2 CPUs), ~3.3GHz RAM 16GB NVIDIA GeForce GT 730
DirectX Version: DirectX 11