The good news is that even though the waypoints are laid out in a linear line of connecting nodes, the actual logic of following them is written in LUA script, so you can basically do anything you want with the waypoint data. At the moment the default AI just walks the character backwards and forwards between first and last, but there is nothing to stop you creating your own script copy, and modifying the pathfinding logic to create a loop. Here is the code responsible, found in "GameGuru\Files\scriptbank\ai\module_combatcore.lua":
function module_combatcore.patrol(e,AIObjNo,PlayerDist,MoveType,CanFire,detectstate,stopstate)
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
SetAnimationSpeedModulation(e,0.0)
StartTimer(e)
else
ai_bot_state[e] = ai_state_idle
SetAnimation(0)
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
SetAnimation(1)
LoopAnimation(e)
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 < 25 and VertDist < 95 and g_Time > ai_bot_pointtime[e] then
ai_bot_pointtime[e] = g_Time + 100
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)
else
SetAnimationSpeedModulation(e,1.0)
end
end
The magic bit is this section:
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
As you can see, if you left the 'ai_bot_pointdirection' variable alone and simply reset the 'ai_bot_pointindex' to zero, it would simply loop around. Just make sure your first node and last node are close together for a good looping motion.
PC SPECS: Windows 8.1 Pro 64-bit, Intel Core i7-5930K (PASSMARK:13645), NVIDIA Geforce GTX 980 GPU (PASSMARK:9762) , 32GB RAM