Hello, I am currently working on a gamemode and I need a custom NPC. I have looked around, but could not find the folder that you put the .lua in for gamemodes.
Thank you, Endus322
You would put them in ~/gamemode_name/entities/entities/; Lua NPCs, or Nextbots, are just SENTs of a special type
[QUOTE=code_gs;52404607]You would put them in ~/gamemode_name/entities/entities/; Lua NPCs, or Nextbots, are just SENTs of a special type[/QUOTE]
I moved it there using the Exact Nextbot code, and I still don't see it in my menu
Post the code.
[QUOTE=code_gs;52404829]Post the code.[/QUOTE]
[CODE]AddCSLuaFile()
ENT.Base = "base_nextbot"
ENT.Spawnable = true
function ENT:Initialize()
self:SetModel( "models/hunter.mdl" )
self.SetHealth(1000)
self.LoseTargetDist = 2000 -- How far the enemy has to be before we lose them
self.SearchRadius = 1000 -- How far to search for enemies
end
----------------------------------------------------
-- ENT:Get/SetEnemy()
-- Simple functions used in keeping our enemy saved
----------------------------------------------------
function ENT:SetEnemy( ent )
self.Enemy = ent
end
function ENT:GetEnemy()
return self.Enemy
end
----------------------------------------------------
-- ENT:HaveEnemy()
-- Returns true if we have a enemy
----------------------------------------------------
function ENT:HaveEnemy()
-- If our current enemy is valid
if ( self:GetEnemy() and IsValid( self:GetEnemy() ) ) then
-- If the enemy is too far
if ( self:GetRangeTo( self:GetEnemy():GetPos() ) > self.LoseTargetDist ) then
-- If the enemy is lost then call FindEnemy() to look for a new one
-- FindEnemy() will return true if an enemy is found, making this function return true
return self:FindEnemy()
-- If the enemy is dead( we have to check if its a player before we use Alive() )
elseif ( self:GetEnemy():IsPlayer() and !self:GetEnemy():Alive() ) then
return self:FindEnemy() -- Return false if the search finds nothing
end
-- The enemy is neither too far nor too dead so we can return true
return true
else
-- The enemy isn't valid so lets look for a new one
return self:FindEnemy()
end
end
----------------------------------------------------
-- ENT:FindEnemy()
-- Returns true and sets our enemy if we find one
----------------------------------------------------
function ENT:FindEnemy()
-- Search around us for entities
-- This can be done any way you want eg. ents.FindInCone() to replicate eyesight
local _ents = ents.FindInSphere( self:GetPos(), self.SearchRadius )
-- Here we loop through every entity the above search finds and see if it's the one we want
for k, v in pairs( _ents ) do
if ( v:IsPlayer() ) then
-- We found one so lets set it as our enemy and return true
self:SetEnemy( v )
return true
end
end
-- We found nothing so we will set our enemy as nil ( nothing ) and return false
self:SetEnemy( nil )
return false
end
----------------------------------------------------
-- ENT:RunBehaviour()
-- This is where the meat of our AI is
----------------------------------------------------
function ENT:RunBehaviour()
-- This function is called when the entity is first spawned. It acts as a giant loop that will run as long as the NPC exists
while ( true ) do
-- Lets use the above mentioned functions to see if we have/can find a enemy
if ( self:HaveEnemy() ) then
-- Now that we have an enemy, the code in this block will run
self.loco:FaceTowards( self:GetEnemy():GetPos() ) -- Face our enemy
self:PlaySequenceAndWait( "plant" ) -- Lets make a pose to show we found a enemy
self:PlaySequenceAndWait( "hunter_angry" )-- Play an animation to show the enemy we are angry
self:PlaySequenceAndWait( "unplant" ) -- Get out of the pose
self:StartActivity( ACT_RUN ) -- Set the animation
self.loco:SetDesiredSpeed( 450 ) -- Set the speed that we will be moving at. Don't worry, the animation will speed up/slow down to match
self.loco:SetAcceleration( 900 ) -- We are going to run at the enemy quickly, so we want to accelerate really fast
self:ChaseEnemy() -- The new function like MoveToPos.
self.loco:SetAcceleration( 400 ) -- Set this back to its default since we are done chasing the enemy
self:PlaySequenceAndWait( "charge_miss_slide" ) -- Lets play a fancy animation when we stop moving
self:StartActivity( ACT_IDLE ) --We are done so go back to idle
-- Now once the above function is finished doing what it needs to do, the code will loop back to the start
-- unless you put stuff after the if statement. Then that will be run before it loops
else
-- Since we can't find an enemy, lets wander
-- Its the same code used in Garry's test bot
self:StartActivity( ACT_WALK ) -- Walk anmimation
self.loco:SetDesiredSpeed( 200 ) -- Walk speed
self:MoveToPos( self:GetPos() + Vector( math.Rand( -1, 1 ), math.Rand( -1, 1 ), 0 ) * 400 ) -- Walk to a random place within about 400 units ( yielding )
self:StartActivity( ACT_IDLE )
end
-- At this point in the code the bot has stopped chasing the player or finished walking to a random spot
-- Using this next function we are going to wait 2 seconds until we go ahead and repeat it
coroutine.wait( 2 )
end
end
----------------------------------------------------
-- ENT:ChaseEnemy()
-- Works similarly to Garry's MoveToPos function
-- except it will constantly follow the
-- position of the enemy until there no longer
-- is one.
----------------------------------------------------
function ENT:ChaseEnemy( options )
local options = options or {}
local path = Path( "Follow" )
path:SetMinLookAheadDistance( options.lookahead or 300 )
path:SetGoalTolerance( options.tolerance or 20 )
path:Compute( self, self:GetEnemy():GetPos() ) -- Compute the path towards the enemies position
if ( !path:IsValid() ) then return "failed" end
while ( path:IsValid() and self:HaveEnemy() ) do
if ( path:GetAge() > 0.1 ) then -- Since we are following the player we have to constantly remake the path
path:Compute( self, self:GetEnemy():GetPos() )-- Compute the path towards the enemy's position again
end
path:Update( self ) -- This function moves the bot along the path
if ( options.draw ) then path:Draw() end
-- If we're stuck, then call the HandleStuck function and abandon
if ( self.loco:IsStuck() ) then
self:HandleStuck()
return "stuck"
end
coroutine.yield()
end
return "ok"
end
list.Set( "NPC", "simple_nextbot", {
Name = "Zombboo bot",
Class = "simple_nextbot",
Category = "Zomb"
} )[/CODE]
Exact Nextbot Code Except for Name
It is inside the \gamemodes\*mygamemode*\entities\entities\zombie_test\simple_nextbot.lua
Thank you, Endus322
[QUOTE]
It is inside the \gamemodes\*mygamemode*\entities\entities\zombie_test\simple_nextbot.lua
[/QUOTE]
If simple_nextbot.lua is the only file that this nextbot consists of (which Im assuming it is), it this should actually be gamemodes\*yourgamemode*\entities\entities\simple_nextbot.lua
You would only need to create a folder (which would have to be called simple_nextbot) if you had a shared as well as init or other class files, and then put those in the folder and name them something else (usually shared, init, cl_init, etc depending on whether they're server or client)
Sorry, you need to Log In to post a reply to this thread.