Basic Scripted NPC

From GMod Wiki

Jump to: navigation, search
Warning 64.pngThis page needs to be edited as it contains information that is unclear or incorrect. Improvement can be discussed on the talk page. Find more pages that need work here.
Details: None given.
Lua: Example SNPC
Page white text.png Description:Information about scripted npcs
link=User:elspin Original Author:elspin
Calendar.png Created:18th July 2007

Contents

What are SNPCs?

Scripted npcs are NPCs that the user has total control of, in this example I've taken garry's fighter npc and made it fight the player instead of just shooting props, and it dies properly.

What program do I use for these, and where do I put them?

First of all, all these files (as of the beta) go into: garrysmod/lua/entities or the respective equal gamemode folder. Second of all, you can use notepad for editing/writing lua, though it's suggested that you google notepad++ and get that.


Actual files

I'll try to fit information on how it works into the comments.

cl_init.lua:

 
include('shared.lua')
 
ENT.RenderGroup = RENDERGROUP_BOTH
 
/*---------------------------------------------------------
   Name: Draw
   Desc: Draw it!
---------------------------------------------------------*/
function ENT:Draw()
	self:DrawModel()
end
 
/*---------------------------------------------------------
   Name: DrawTranslucent
   Desc: Draw translucent
---------------------------------------------------------*/
function ENT:DrawTranslucent()
 
	// This is here just to make it backwards compatible.
	// You shouldn't really be drawing your model here unless it's translucent
 
	self:Draw()
 
end
 
/*---------------------------------------------------------
   Name: BuildBonePositions
   Desc: 
---------------------------------------------------------*/
function ENT:BuildBonePositions( NumBones, NumPhysBones )
 
	// You can use this section to position the bones of
	// any animated model using self:SetBonePosition( BoneNum, Pos, Angle )
 
	// This will override any animation data and isn't meant as a 
	// replacement for animations. We're using this to position the limbs
	// of ragdolls.
 
end
 
 
 
/*---------------------------------------------------------
   Name: SetRagdollBones
   Desc: 
---------------------------------------------------------*/
function ENT:SetRagdollBones( bIn )
 
	// If this is set to true then the engine will call 
	// DoRagdollBone (below) for each ragdoll bone.
	// It will then automatically fill in the rest of the bones
 
	self.m_bRagdollSetup = bIn
 
end
 
 
/*---------------------------------------------------------
   Name: DoRagdollBone
   Desc: 
---------------------------------------------------------*/
function ENT:DoRagdollBone( PhysBoneNum, BoneNum )
 
	// self:SetBonePosition( BoneNum, Pos, Angle )
 
end
 


init.lua:

 
AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
 
include('shared.lua')
 
local schdChase = ai_schedule.New( "AIFighter Chase" ) //creates the schedule used for this npc
 
 
	// Run away randomly (first objective in task)
	schdChase:EngTask( "TASK_GET_PATH_TO_RANDOM_NODE", 	128 )
	schdChase:EngTask( "TASK_RUN_PATH", 				0 )
	schdChase:EngTask( "TASK_WAIT_FOR_MOVEMENT", 	0 )
	schdChase:AddTask( "PlaySequence", 				{ Name = "cheer1", Speed = 1 } )
 
	// Find an enemy and run to it (second objectives in task)
	schdChase:AddTask( "FindEnemy", 		{ Class = "player", Radius = 2000 } )
	schdChase:EngTask( "TASK_GET_PATH_TO_RANGE_ENEMY_LKP_LOS", 	0 )
	schdChase:EngTask( "TASK_RUN_PATH", 				0 )
	schdChase:EngTask( "TASK_WAIT_FOR_MOVEMENT", 	0 )
 
	// Shoot it (third objective in task)
	schdChase:EngTask( "TASK_STOP_MOVING", 			0 )
	schdChase:EngTask( "TASK_FACE_ENEMY", 			0 )
	schdChase:EngTask( "TASK_ANNOUNCE_ATTACK", 		0 )
	schdChase:EngTask( "TASK_RANGE_ATTACK1", 		0 )
	schdChase:EngTask( "TASK_RELOAD", 				0 )
	//schedule is looped till you give it a different schedule
 
 
function ENT:Initialize()
 
	self:SetModel( "models/Humans/Group01/Female_01.mdl" )
 
	self:SetHullType( HULL_HUMAN );
	self:SetHullSizeNormal();
 
	self:SetSolid( SOLID_BBOX ) 
	self:SetMoveType( MOVETYPE_STEP )
 
	self:CapabilitiesAdd( CAP_MOVE_GROUND | CAP_OPEN_DOORS | CAP_ANIMATEDFACE | CAP_TURN_HEAD | CAP_USE_SHOT_REGULATOR | CAP_AIM_GUN )
 
	self:SetMaxYawSpeed( 5000 )
 
	//don't touch stuff above here
	self:SetHealth(100)
	self:Give( "weapon_ak47" ) //Can be given sweps.
 
end
 
 function ENT:OnTakeDamage(dmg)
  self:SetHealth(self:Health() - dmg:GetDamage())
  if self:Health() <= 0 then //run on death
  self:SetSchedule( SCHED_FALL_TO_GROUND ) //because it's given a new schedule, the old one will end.
  end
 end 
 
 
/*---------------------------------------------------------
   Name: SelectSchedule
---------------------------------------------------------*/
function ENT:SelectSchedule()
 
	self:StartSchedule( schdChase ) //run the schedule we created earlier
 
end
 
 

shared.lua:

 
ENT.Base = "base_ai" 
ENT.Type = "ai"
 
ENT.PrintName		= ""
ENT.Author			= ""
ENT.Contact			= ""  //fill in these if you want it to be in the spawn menu
ENT.Purpose			= ""
ENT.Instructions	= ""
 
ENT.AutomaticFrameAdvance = true
 
 
/*---------------------------------------------------------
   Name: OnRemove
   Desc: Called just before entity is deleted
---------------------------------------------------------*/
function ENT:OnRemove()
end
 
 
/*---------------------------------------------------------
   Name: PhysicsCollide
   Desc: Called when physics collides. The table contains 
			data on the collision
---------------------------------------------------------*/
function ENT:PhysicsCollide( data, physobj )
end
 
 
/*---------------------------------------------------------
   Name: PhysicsUpdate
   Desc: Called to update the physics .. or something.
---------------------------------------------------------*/
function ENT:PhysicsUpdate( physobj )
end
 
/*---------------------------------------------------------
   Name: SetAutomaticFrameAdvance
   Desc: If you're not using animation you should turn this 
	off - it will save lots of bandwidth.
---------------------------------------------------------*/
function ENT:SetAutomaticFrameAdvance( bUsingAnim )
 
	self.AutomaticFrameAdvance = bUsingAnim
 
end
 

Unless you got it in the spawn menu, you can use this command to create it (without the quotes):

"ent_create folder_name" please note:Do not use capitals in your folder name, and do not use spaces.

Where can I find a list of schedules for my SNPC?

The full list of schedules can be found here: http://developer.valvesoftware.com/wiki/Shared_schedules

But as garrysmod has it's own enumeration file for schedules, you can probably only use these

Where can I find a list of tasks for my SNPC?

A full list can be found here: http://developer.valvesoftware.com/wiki/Shared_tasks

See Also

Personal tools
Namespaces
Variants
Actions
Navigation
Lua Scripting
Functions
Hooks
Toolbox