121 lines
2.6 KiB
Lua
121 lines
2.6 KiB
Lua
if SERVER then AddCSLuaFile() end
|
|
|
|
ENT.Base = "base_nextbot"
|
|
ENT.Type = "nextbot"
|
|
|
|
function ENT:Initialize()
|
|
if CLIENT then return end
|
|
|
|
self:SetModel("models/player.mdl")
|
|
self:SetNoDraw(!GetConVar("developer"):GetBool())
|
|
self:SetSolid(SOLID_NONE)
|
|
|
|
local fov_convar = GetConVar("refoselbots_fov")
|
|
|
|
self:SetFOV((fov_convar:GetBool() and math.Clamp(fov_convar:GetInt(), 75, 100)) or 90)
|
|
self.PosGen = nil
|
|
self.NextJump = -1
|
|
self.NextDuck = 0
|
|
self.cur_segment = 2
|
|
self.Target = nil
|
|
self.LastSegmented = 0
|
|
self.ForgetTarget = 0
|
|
self.NextCenter = 0
|
|
self.LookAt = Angle(0, 0, 0)
|
|
self.LookAtTime = 0
|
|
self.goalPos = Vector(0, 0, 0)
|
|
self.strafeAngle = 0
|
|
self.nextStuckJump = 0
|
|
|
|
if RefoselBots.AddControllerOverride then
|
|
RefoselBots.AddControllerOverride(self)
|
|
end
|
|
end
|
|
|
|
function ENT:ChasePos()
|
|
self.P = Path("Follow")
|
|
self.P:SetMinLookAheadDistance(10)
|
|
self.P:SetGoalTolerance(20)
|
|
self.P:Compute(self, self.PosGen)
|
|
|
|
if !self.P:IsValid() then return end
|
|
|
|
while self.P:IsValid() do
|
|
if self.PosGen then
|
|
self.P:Compute(self, self.PosGen)
|
|
self.cur_segment = 2
|
|
end
|
|
|
|
coroutine.wait(1)
|
|
coroutine.yield()
|
|
end
|
|
end
|
|
|
|
function ENT:OnInjured()
|
|
return false
|
|
end
|
|
|
|
function ENT:OnKilled()
|
|
return false
|
|
end
|
|
|
|
function ENT:IsNPC()
|
|
return false
|
|
end
|
|
|
|
function ENT:Health()
|
|
return nil
|
|
end
|
|
|
|
-- remade this in lua so we can finally ignore the controller's bot
|
|
-- for some reason it's not really possible to overwrite IsAbleToSee
|
|
local function PointWithinViewAngle(pos, targetpos, lookdir, fov)
|
|
pos = targetpos - pos
|
|
local diff = lookdir:Dot(pos)
|
|
if diff < 0 then return false end
|
|
local len = pos:LengthSqr()
|
|
return diff * diff > len * fov * fov
|
|
end
|
|
|
|
function ENT:InFOV(pos, fov)
|
|
local owner = self:GetOwner()
|
|
|
|
if not IsValid(owner) then return false end
|
|
|
|
if IsEntity(pos) then
|
|
if PointWithinViewAngle(owner:EyePos(), pos:WorldSpaceCenter(), owner:GetAimVector(), fov) then
|
|
return true
|
|
end
|
|
|
|
return PointWithinViewAngle(owner:EyePos(), pos:EyePos(), owner:GetAimVector(), fov)
|
|
else
|
|
return PointWithinViewAngle(owner:EyePos(), pos, owner:GetAimVector(), fov)
|
|
end
|
|
end
|
|
|
|
function ENT:CanSee(ply, fov)
|
|
local owner = self:GetOwner()
|
|
if not IsValid(owner) then return false end
|
|
|
|
if ply:GetPos():DistToSqr(self:GetPos()) > self:GetMaxVisionRange() * self:GetMaxVisionRange() then
|
|
return false
|
|
end
|
|
|
|
fov = fov or true
|
|
|
|
if fov and !self:InFOV(ply, math.cos(0.5 * (self:GetFOV() or 90) * math.pi / 180)) then
|
|
return false
|
|
end
|
|
|
|
return util.QuickTrace(owner:EyePos(), ply:EyePos() - owner:EyePos(), {owner, self}).Entity == ply
|
|
end
|
|
|
|
function ENT:RunBehaviour()
|
|
while (true) do
|
|
if self.PosGen then
|
|
self:ChasePos({})
|
|
end
|
|
|
|
coroutine.yield()
|
|
end
|
|
end |