How to make an SNPC follow you?

I need some way of making an SNPC toggle between Following the player who invokes ENT:Use(), or randomly wandering. I have tried self.Entity:NavSetGoalTarget(ply, Vector(0,0,0)) but that does not seem to work by itself.

Any help with this one?

Try
[lua]

self.Entity:SetTarget(ply)
self.Enitty:SetSchedule(SCHED_TARGET_CHASE)

[/lua]

That should make it run to the player. Will need to be called every time the schedule finishes for it to be following.

Yeah, Ive thought about that, but doesn’t that cause the NPC to target the actual player as the “enemy”? Im trying to mimic the HL2 Rebels how they join your squad. They need to still be able target enemies, fire at them, etc.

[editline]8th March 2011[/editline]

Ok. So I figured out why this is not working. ENT:Use() apparently does not work on SNPCs?
I put a debug message as the first line of the Use function and I am not seeing it.

[lua]
function ENT:Use(activator, caller)
Msg(“Use was called”)
//0 - never found
//1 - following
//2 - holding position
if (self.State == 0) then
self.State = 1
self.Entity:SetTarget(activator)
//self.Entity:SetSchedule( sched )
//self.Entity:SetCurrentSchedule( sched )
Msg(“Following!!!”)
elseif (self.state == 1) then
self.State = 2
else
self.State = 1
end
end
[/lua]

NOTE: I am setting the schedule elsewhere.

Did you set the use type on the npc in Initialize? Because i’ve made a shop npc before and use worked

**[Entity.SetUseType

http://wiki.garrysmod.com/favicon.ico](http://wiki.garrysmod.com/?title=Entity.SetUseType)**

As far as them being enemies, no it’s just a target, **[NPC.SetEnemy

http://wiki.garrysmod.com/favicon.ico](http://wiki.garrysmod.com/?title=NPC.SetEnemy)** would set the player as the enemy target. If the relationship is Neutral or Like, it shouldn’t be an enemy anyway.
Here’s the set target page also **[NPC.SetTarget

http://wiki.garrysmod.com/favicon.ico](http://wiki.garrysmod.com/?title=NPC.SetTarget)**

Yep, Ive had that in from the beginning. And I know what you mean because I’ve done similar things before.

Here’s my entire init.lua for the NPC. Theres not much else in cl_init or shared other than the few required things like “Draw”
[lua]
AddCSLuaFile( “cl_init.lua” )
AddCSLuaFile( “shared.lua” )

include(‘shared.lua’)

ENT.RemoveTime = 0
ENT.RemovePos = Vector(0,0,0)

function ENT:Initialize()

self.Entity:InitializeCharacter()

self.Entity:SetHullSizeNormal()
self.Entity:SetHullType( HULL_HUMAN )

self.Entity:SetSolid( SOLID_BBOX ) 
self.Entity:SetMoveType( MOVETYPE_STEP )

self.Entity:SetMaxYawSpeed( 5000 )
self.Entity:SetHealth( 100 )

self.Entity:CapabilitiesAdd( CAP_MOVE_GROUND | CAP_TURN_HEAD | CAP_USE_WEAPONS | CAP_AIM_GUN | CAP_WEAPON_RANGE_ATTACK1 | CAP_MOVE_SHOOT ) 

self.Entity:DropToFloor()
self.Entity:Give( "weapon_glock" )
self.Entity:SetUseType(SIMPLE_USE)

end

function ENT:InitializeCharacter()

self.Entity:SetModel( "models/Humans/Group03/Male_0" .. math.random( 1, 9 ) .. ".mdl" )
//0 - never found
//1 - following
//2 - holding position
self.State = 0
self.Items = {}

end

function ENT:Think()

if self.Entity:GetCurrentSchedule() == SCHED_RANGE_ATTACK1 then
    local wep = self.Entity:GetActiveWeapon()
    
    if ValidEntity( wep ) then
    
        wep:PrimaryAttack()
        
    end

end

end

function ENT:SpawnRagdoll( att, model )

local ang = self.Entity:GetAngles()

local shooter = ents.Create("env_shooter")
shooter:SetPos( self.Entity:GetPos() )
shooter:SetKeyValue( "m_iGibs", "1" )
shooter:SetKeyValue( "shootsounds", "3" )
shooter:SetKeyValue( "gibangles", ang.p.." "..ang.y.." "..ang.r )
shooter:SetKeyValue( "angles", ang.p.." "..ang.y.." "..ang.r )
shooter:SetKeyValue( "shootmodel", ( model or self.Entity:GetModel() ) ) 
shooter:SetKeyValue( "simulation", "2" )
shooter:SetKeyValue( "gibanglevelocity", math.random(-50,50).." "..math.random(-250,250).." "..math.random(-250,250) )

if ValidEntity( att ) then

    shooter:SetKeyValue( "m_flVelocity", tostring( math.Rand( -40, 0 ) ) )
    shooter:SetKeyValue( "m_flVariance", tostring( math.Rand( -2, 0 ) ) )
    
end

shooter:Spawn()

shooter:Fire( "shoot", 0, 0 )
shooter:Fire( "kill", 0.1, 0.1 )

if not att:IsPlayer() then return end

//local ent = ents.Create( "sent_lootbag" )

//for k,v in pairs( self.Items ) do

//    ent:AddItem( v )

//end

//ent:SetPos( self.Entity:GetPos() + Vector(0,0,25) )
//ent:SetRemoval( 60 * 3 )
//ent:Spawn()

end

function ENT:DoDeath( dmginfo )

if self.Dying then return end
self.Dying = true

self.Entity:SpawnRagdoll( dmginfo:GetAttacker() )

self.Entity:SetSchedule( SCHED_FALL_TO_GROUND )
self.Entity:Remove()

end

function ENT:VoiceSound( tbl )

if ( self.VoiceTime or 0 ) > CurTime() then return end

self.VoiceTime = CurTime() + 2

self.Entity:EmitSound( Sound( table.Random( tbl ) ) )

end

function ENT:OnTakeDamage( dmginfo )

self.Entity:SetHealth( math.Clamp( self.Entity:Health() - dmginfo:GetDamage(), 0, 1000 ) )

if self.Entity:Health() < 1 then

    self.Entity:DoDeath( dmginfo )
    
end

end

function ENT:GetRelationship( entity )

if string.find( entity:GetClass(), "npc_headcrab" ) or string.find( entity:GetClass(), "zombie" ) then

    return D_HT

end

return D_LI

end

function ENT:UpdateEnemy( enemy )

if ValidEntity( enemy ) and ( string.find( enemy:GetClass(), "npc_headcrab" ) or string.find( enemy:GetClass(), "zombie" ) ) then
    
    self.Entity:SetEnemy( enemy, true ) 
    self.Entity:UpdateEnemyMemory( enemy, enemy:GetPos() ) 
    
else
    
    self.Entity:SetEnemy( NULL )
    
end

end

function ENT:FindEnemy()

local tbl = ents.FindByClass( "npc_zombie*" )
tbl = table.Add( tbl, ents.FindByClass( "npc_headcrab*" ) )

if #tbl < 1 then
    
    return NULL
    
else

    local enemy = NULL
    local dist = 99999
    
    for k,v in pairs( tbl ) do
    
        local compare = v:GetPos():Distance( self.Entity:GetPos() )
        
        if (compare < dist and string.find( v:GetClass(), "npc" ) ) then
        
            enemy = v
            dist = compare
            
        end
        
    end
    
    return enemy
    
end

end

function ENT:SelectSchedule()

local enemy = self.Entity:GetEnemy()
local sched = SCHED_IDLE_WANDER 

if (self.State == 1) then
    Msg("We choose to follow")
    sched = SCHED_TARGET_CHASE
    if self.Entity:HasCondition( 21 ) then // COND_CAN_RANGE_ATTACK1
        sched = SCHED_RANGE_ATTACK1    
    end    

elseif (self.State == 2) then
    sched = SCHED_ALERT_STAND
elseif ValidEntity( enemy ) and enemy:GetPos():Distance( self.Entity:GetPos() ) < 2000 then

    if self.Entity:HasCondition( 21 ) then // COND_CAN_RANGE_ATTACK1
    
        sched = SCHED_RANGE_ATTACK1
        
    else
    
        sched = SCHED_CHASE_ENEMY
        
    end
    
else

    self.Entity:UpdateEnemy( self.Entity:FindEnemy() )
    
end

self.Entity:SetSchedule( sched ) 
self.Entity:SetCurrentSchedule( sched )

end

function ENT:SetCurrentSchedule( sched )

self.CurrSched = sched

end

function ENT:GetCurrentSchedule()

return self.CurrSched or SCHED_IDLE_WANDER 

end

function ENT:Use(activator, caller)
Msg(“Use was called”)
//0 - never found
//1 - following
//2 - holding position
if (self.State == 0) then
self.State = 1
self.Entity:SetTarget(activator)
//self.Entity:SetSchedule( sched )
//self.Entity:SetCurrentSchedule( sched )
Msg(“Following!!!”)
elseif (self.state == 1) then
self.State = 2
else
self.State = 1
end
end
//NavSetGoalTarget

[/lua]

Just looked up my old code, i’m not using ENT:Use() i’m using
[lua]
function ENT:AcceptInput( Name, Activator, Caller)
if( Name == “Use”) and CurTime() >= (Activator.LastUse or 0) + 3 then
Activator.LastUse = CurTime()
– Insert Shop or whatever code here
end
end
[/lua]

Works great. Thanks mate!