Help adding nextbot navigation to a non-nextbot game entity

Hey guys,
I recently coded an NPC available here

The idea of the project is that when real players are not filling up slots on a empty GMOD Murder server, these will, and they will fight the few players online.
Now right now the code is very basic. Less than 100 lines. So that being said, the pathfinding is decent, but not great. They can chase you down an kill you, but if there is a door between you, they are out of luck.
So, basically I re purposed a Source engine bot to play Murder, so it is basically an Aimbot player. A huge bug thought is, when everyone is dead and there are only 2 bots left, they end up having a staring contest indefinitely through the wall.
I looked into nextbot navigation, but nextbots aren’t detailed enough for me, so I use real bots. I like the pathfinding now, because it is unpredictable, but I need help.
I need a timer to run (Believe me, I did some timer stuff, but GMOD hates me), that will check if the position of the bot hasn’t changed in about 2 seconds, it will switch to the nextbot navmesh system, and more intelligently pathfind there, and then switch back.
Sorry for the messy thread. I am really bad at forum posts, but here is what I need.

Pathfinding algorithm to follow (.nav) files.
Timer to switch to better pathfinding when a certain movement threshhold isn’t reached.

Please help! Teach me of wise lua coders.
I crapped this together in 5 hrs, so it is not the best. Plus I had to relearn lua.

Thanks,
-Blue

P.S. Feel free to decompile my addon and look at the code. I am open to teaching and instruction, not just copy-pasta.

Instead of using the built-in bots, you can use player.CreateNextBot. This code is from one of the WAYWO threads, rewrite your code similar to it:

[lua]local BOTS = {}
local botsName = {“Ron”,
“Bret”,
“Johnathan”,
“Max”,
“Kyle”,
“Jack”,
“Marcus”,
“Jay”,
“Andy”,
“Aran”}

concommand.Add(“gm_bot_add”,function(ply)
local b = player.CreateNextBot(botsName[math.random(#botsName)])
table.insert(BOTS,b)
b.Owner = ply
end)

hook.Add(“PlayerSay”,“Bots”,function(ply,text)
if(text == “!follow”) then
ply.State = 1
end
if(text == “!quiet”) then
ply.State = 0
end
if(text == “!attack”) then
ply.State = 2
end
if(text == “!defend”) then
ply.State = 3
end
end)

hook.Add(“EntityTakeDamage”,“Defend!”,function(ent,dmg)

    if(ent:IsPlayer() && !ent:IsBot() && !dmg:GetAttacker():IsWorld()) then
            for k,v in pairs(player.GetBots()) do
                    if(v.Owner == ent) then
                            v.Target = dmg:GetAttacker()
                    end
            end
    end
    if(dmg:GetAttacker():IsPlayer() && !ent:IsWorld()) then
            MsgN(ent)
            for k,v in pairs(player.GetBots()) do
                    if(v.Owner == dmg:GetAttacker()) then
                            v.Target = ent
                    end
            end
    end

end)

hook.Add(“StartCommand”,“MoveBots”,function(ply,cmd)
if(IsValid(ply.Owner)) then

            cmd:ClearMovement()
            cmd:ClearButtons()

            if(ply.Owner.State == nil) then
                    ply.Owner.State = 1
            end

            local ow = ply.Owner
            local ang = ((ply:EyePos() - Vector(0,0,10))-(ow:EyePos() - Vector(0,0,10))):Angle()

            local lClamp = ang + Angle(0,180,0)

            ply:SetEyeAngles(Angle(math.Clamp(lClamp.p,-180,180),lClamp.y,math.Clamp(lClamp.r,-180,180)))
            cmd:SetViewAngles(Angle(math.Clamp(lClamp.p,-180,180),lClamp.y,math.Clamp(lClamp.r,-180,180)))

            if(ow.State == 1 or ow.State == 3) then
                    if(ow:GetPos():Distance(ply:GetPos()) > 128) then
                            cmd:SetForwardMove(750)
                    end
            end

            if(ow.State == 2) then
                    if(ow:GetPos():Distance(ply:GetPos()) < 72 && ow:Alive() or (ply.Ranged or false)) then
                            if(ow:Alive()) then
                                    cmd:SetButtons(IN_ATTACK)
                                    if(ow:GetPos():Distance(ply:GetPos()) < 72) then
                                            ply:SelectWeapon("weapon_crowbar")
                                            ply.Ranged = false
                                    end
                            end
                    end

                    if(ow:GetPos():Distance(ply:GetPos()) > 256) then
                            if(ply:GetActiveWeapon():GetClass() != "weapon_ar2") then
                                    ply:SelectWeapon("weapon_ar2")
                                    ply.Ranged = true
                            end
                    end
					
                    if(ow:GetPos():Distance(ply:GetPos()) > 64) then
                            cmd:SetForwardMove(750)
                    end

                    cmd:SetSideMove(math.cos(RealTime())*400)
            end

            if(ow.State == 3) then
                    if(IsValid(ply.Target)) then
                            local ang = (ply:GetShootPos()-ply.Target:GetPos()):Angle()
                            if(ply.Owner:KeyDown(IN_ATTACK)) then
                                    ang = (ply:GetShootPos()-ply.Owner:GetEyeTrace().HitPos):Angle()
                            end

                            local lClamp = ang + Angle(90,180,0)
                            ply:SetEyeAngles(lClamp)
                            cmd:SetViewAngles(lClamp)

                            if(ply.Target:GetPos():Distance(ply:GetShootPos()) > 256) then
                                    if(ply:GetActiveWeapon():GetClass() != "weapon_ar2") then
                                            ply:SelectWeapon("weapon_ar2")
                                            ply.Ranged = true
                                    end
                            else
                                    ply:SelectWeapon("weapon_crowbar")
                                    if(ply.Target:GetPos():Distance(ply:GetPos()) > 64) then
                                            cmd:SetForwardMove(750)
                                    end
                            end

                            cmd:SetButtons(IN_ATTACK)
                    end
            end

    end

end)[/lua]

I love you in the most non-homosexual way possible! Thank you! I eventually made a clipboard an next bot and the bot follow the clipboard, but this changed everything. +1 rep for you!

[editline]3rd August 2015[/editline]

Also, now that I have probably freaked you out. Sorry. :confused:
I had one more question. I am currently recoding the bot, and I noticed that in cs_office, when I stand on a snowmound, the bot stops chasing me, turns around and glitches out running in a wierd direction. All I can think of is that the NavMesh of the snow, and the bot don’t play nice. Any workarounds for this.
I’m sure I can make one, but you clearly have more lua experience, and probably have a less hacky way of doing it.

[video]https://youtu.be/XxaTHPNTH6o[/video]

Also, crouch-jumping is the bane of my bot’s existence. It couldn’t crouch jump to save it’s life. Literally. Any Pastebins or Git Gists you can recommend?

[editline]3rd August 2015[/editline]

Are you still there?