Basic Scripted NPC
From GMod Wiki
This 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 |
Description: | Information about scripted npcs |
Original Author: | elspin |
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