Ace_Gambit

[WIP] NPC Animation Classes 0.2

Recommended Posts

NPC Animation Classes 0.2

The NPC Animation Classes is my latest attempt at making NPC animation available to a wider audience without having to deal with the complexity of scripting it yourself. These classes are just a small portion of a much bigger animation class that I use in my game mode (as you can see here
). But I am cleaning up my entire script and thought it was a good time to make some parts publicly available. The parts included in these classes only provide support for pedestrian animation (maybe I'll add more later on).

The folder structure may look a bit messy. But that's because I literally copied script files from my game mode folder. I tried to keep it as clean as possible. But once you've included the files in your script you're good to go.

Getting Started

  • Extract npcac.zip to the root folder of your resource. The most recent version is attached at the bottom of this post.
  • Now add the following lines to meta.xml. This is required.

<script src="npcac/shared/include/const.inc" type="server" /> 
<script src="npcac/shared/include/type.inc" type="server" /> 
<script src="npcac/shared/include/util.inc" type="server" /> 
<script src="npcac/shared/objects/CPath.obj" type="server" /> 
<script src="npcac/shared/objects/CAnim.obj" type="server" /> 
<script src="npcac/shared/objects/CPause.obj" type="server" /> 
<script src="npcac/shared/anim/npc/CStaticPed.npc" type="server" /> 
<script src="npcac/shared/include/const.inc" type="client" /> 
<script src="npcac/shared/include/type.inc" type="client" /> 
<script src="npcac/shared/include/util.inc" type="client" /> 
<script src="npcac/shared/objects/CPath.obj" type="client" /> 
<script src="npcac/shared/objects/CAnim.obj" type="client" /> 
<script src="npcac/shared/objects/CPause.obj" type="client" /> 
<script src="npcac/shared/anim/npc/CStaticPed.npc" type="client" /> 
<script src="npcac/server/include/const.inc" type="server" /> 
<script src="npcac/server/debug/CDebug.lua" type="server" /> 
<script src="npcac/server/CNPC.lua" type="server" /> 
<script src="npcac/client/include/const.inc" type="client" /> 
<script src="npcac/client/objects/CLook.obj" type="client" /> 
<script src="npcac/client/debug/CDebug.lua" type="client" /> 
<script src="npcac/client/CStaticAnimator.lua" type="client" /> 
<script src="npcac/client/CNPC.lua" type="client" /> 
<file src="npcac/client/anim/npc.xml" /> 
<script src="npcac/server/npcac.lua" type="server" /> 
<script src="npcac/client/npcac.lua" type="client" /> 

You are now ready to add NPC's!

Adding NPC's

Adding NPC's is easy. There are two XML files to add NPC's.

  • npcac/client/anim/npc.xml
  • npcac/server/anim/npc.xml

The only main difference at the moment is that the former (client NPC XML) does not support weapon elements.

Every NPC XML must have a root node.

  
<npc> 
</npc> 
  

You can add a NPC block but this is optional. NPC blocks are used to group NPC's in case of a large population.

  
<npc> 
  <BOMBER> 
  </BOMBER> 
</npc> 
  

Adding NPC's is just like you are used to with MTA map elements. This version only supports ped elements at the moment.

  
<npc> 
  <BOMBER> 
    <npc-ped> 
      <ped id="Herbert" model="259" posX="-15" posY="-15" posZ="3" pose="crouch"> 
        <!-- This is where you can add task elements --> 
      </ped> 
    </npc-ped> 
  </BOMBER> 
</npc> 
  

Notice the npc-ped element. This is required as well and tells the script what type of NPC it should expect.

In the future I will add other NPC types like npc-object, npc-camera and npc-vehicle (even though these aren't really considered "real" NPC's).

It is important to notice that ped elements must have a ID. The only (non-standard) optional attribute is pose. The pose attribute determines the initial pose.

Weapons

As mentioned before you can give weapons to ped NPC's. Weapons are a special type of task elements as they are not really tasks. Weapon elements can only be added to the server-side NPC XML.

The XML syntax for weapon elements is.

  
<weapon weapon="" ammo="" setAsCurrent="" /> 
  

  • weapon: The weapon ID.
  • ammo: Ammo amount for the given weapon.
  • setAsCurrent: Determines whether or not the weapon will be set as current (true or false).

You are now ready to add tasks.

Tasks

Tasks are ordinary elements as well. The task list goes from top to bottom. The XML syntax for supported tasks is as follows.

Path

Make a ped walk to a specified target position.

  
<path targetX="" targetY="" block="" name="" stepRotZ="" interruptible="" targetMinAngle="" targetMinDist="" /> 
  

  • targetX: The x coordinate of the world position to target at.
  • targetY: The y coordinate of the world position to target at.
  • block: The animation block's name.
  • name: The name of the animation within the block.
  • stepRotZ: Steps to turn every frame (high number means fast rotation).
  • interruptible: Determines whether or not the NPC is allowed to be interrupted while performing this task (true or false).
  • targetMinAngle: Minimum angle between facing direction and target before the NPC stops rotating towards its destination.
  • targetMinDist: Minimum distance to destination before the NPC completes this task.

Anim

Set ped animation.

  
<anim time="" block="" name="" loop="" updatePosition="" interruptible="" /> 
  

  • time: The duration for the animation.
  • block: The animation block's name.
  • name: The name of the animation within the block.
  • loop: Indicates whether or not the animation will loop (true or false).
  • updatePosition: Will change the actual coordinates of the ped according to the animation (true or false).
  • interruptible: Defines whether the animation can be interrupted by normal movements (true or false).

Look

Make a ped look at a specified target position or ped.

  
<look targetX="" targetY="" targetZ="" time="" target="" blocking="" /> 
  

  • targetX: The x coordinate of the world position to look at.
  • targetY: The y coordinate of the world position to look at.
  • targetZ: The z coordinate of the world position to look at.
  • time: The time, in milliseconds, during which the ped will look at the target.
  • target: The target ID. If this argument is specified, the position arguments will be ignored and the ped's gaze will follow the specified element instead. Can be a player, a vehicle, another ped etc.
  • blocking: Determines whether or not the ped should interrupt all other tasks and complete looking at the target before proceeding (true or false).

Pause

Suspend the task list for a specified number of milliseconds.

  
<pause time="" resume="" /> 
  

  • time: The duration to suspend all tasks.
  • resume: Determines whether or not the task list will go into play state again or remain paused until the script explicitly tells it to resume (true or false).

Putting It Together

Example NPC XML (client).

  
<npc> 
  <BOMBER> 
    <npc-ped> 
      <ped id="Herbert" model="259" posX="-15" posY="-15" posZ="3" pose="crouch"> 
        <path targetX="30" targetY="30" block="ped" name="WALK_civi" stepRotZ="1.0" interruptible="true" targetMinAngle="2.0" targetMinDist="2.5" /> 
        <look targetX="0" targetY="0" targetZ="0" time="2500" target="Herald" blocking="false" /> 
        <path targetX="30" targetY="10" block="ped" name="WALK_civi" stepRotZ="1.0" interruptible="true" targetMinAngle="2.0" targetMinDist="2.5" /> 
        <anim time="0" block="ped" name="idle_stance" loop="false" updatePosition="false" interruptible="false" /> 
        <look targetX="0" targetY="0" targetZ="0" time="2500" target="Herald" blocking="true" /> 
        <look targetX="30" targetY="30" targetZ="5" targetID="" time="2500" blocking="true" /> 
        <path targetX="10" targetY="30" block="ped" name="WALK_civi" stepRotZ="1.0" interruptible="true" targetMinAngle="2.0" targetMinDist="2.5" /> 
        <look targetX="0" targetY="0" targetZ="0" time="2500" target="Herald" blocking="false" /> 
        <pause time="5000" resume="true" /> 
        <look targetX="30" targetY="30" targetZ="5" targetID="" time="2500" blocking="true" /> 
        <anim time="3000" block="BOMBER" name="BOM_Plant" loop="false" updatePosition="false" interruptible="false" /> 
      </ped> 
    </npc-ped> 
  </BOMBER> 
</npc> 
  

Example NPC XML (server).

  
<npc> 
  <SWAT> 
    <npc-ped> 
      <ped id="Herald" model="285" posX="-15" posY="-5" posZ="3" pose="armed"> 
        <weapon weapon="29" ammo="30" setAsCurrent="true" /> 
        <anim time="3000" block="UZI" name="UZI_crouchreload" loop="false" updatePosition="false" interruptible="false" /> 
      </ped> 
    </npc-ped> 
  </SWAT> 
</npc> 
  

Task List States

Now that we have created our NPC's we want to see some action. We can do so by putting the task list into play state by invoking the play method of our NPC instance.

Every NPC is member of the global NPC table instance created by the NPC Animation Classes. You can access each NPC by NPC block ID (optional) and NPC ID (required). For example NPC.SWAT.Herald points to our server-side created NPC (see NPC XML example).

Available task list states are:

  • start: start ( [ bool loop=false ] ).
  • stop: stop ( void ).
  • pause: pause ( [ float time=0, bool resume=false ] ).
  • resume: resume ( void ).

Events

The following events are available.

  • onNPCTask ( string taskName, int taskPosition )
  • onNPCTaskStart ( void )
  • onNPCTaskStop ( void )
  • onNPCTaskPause ( int taskPosition, float timeInterval, boolean resume )
  • onNPCTaskResume ( int taskPosition )

Lua Example

  
function onNPCTask ( szTaskName, iTaskPos ) 
  outputChatBox ( "* NPC Task: " .. ( tonumber ( iTaskPos ) or -1 ) .. " is of type " .. szTaskName ); 
  if ( iTaskPos == 2 ) then 
    NPC.SWAT.Herald:start (); 
  end; 
end; 
  
function onClientResourceStart ( pStartedResource ) 
  if ( pStartedResource == getThisResource () ) then 
    addEvent ( "onNPCTask", false ); 
    addEventHandler ( "onNPCTask", NPC.BOMBER.Herbert:getPed (), onNPCTask ); 
    NPC.BOMBER.Herbert:start (); 
  end; 
end; 
  
addEventHandler ( "onClientResourceStart", getRootElement (), onClientResourceStart, true ); 
  

Important Notes:

  • If the attribute "interruptible" is enabled for path tasks causing damage to the NPC will clear all tasks currently waiting.
  • The "NPC" variable is the global NPC table instance.
  • If you want the actual MTA element you must invoke the getPed() method on a NPC member.
  • NPC tasks are MTA elements. In theory this allows you to make editor definitions and place path nodes.
  • In practice path tasks are almost the same as anim tasks. This means that in theory you can use any animation. The animator however only keeps track of the NPC's position causing it to go into infinite play state if the NPC does not move.

Changes

0.2 - 09/04/2009

- Changed onNPCTask ( int taskPosition ) event syntax to onNPCTask ( string taskName, int taskPosition ).

- Added onNPCTaskStart ( void ) event.

- Added onNPCTaskStop ( void ) event.

- Added onNPCTaskPause ( int taskPosition, float timeInterval, boolean resume ) event.

- Added onNPCTaskResume ( int taskPosition ) event.

- Added look task.

- Made some tweaks.

You'll probably find mistakes in the script but that's because I am cleaning my entire game mode script and may forgot to change things properly.

Edited by Guest

Share this post


Link to post

This is very very nice. I'm impressed.

One thing i would suggest, maybe implement a Lua table structure as well? XML files are nice but working within Lua is often much more practical, and Lua tables can formulate a mirrored structure to XML

Share this post


Link to post

That's exactly my thought. Ideally you can add/remove tasks at runtime (something like setNPCTasks ( table tasks )) and have a less obvious way with xml files. The latter is primarily meant for NPC's that perform a fixed list of tasks (like shop owners).

Share this post


Link to post

for some reason when i try to start this it reads couldn't find file and keeps doing that even though the path in the meta is correct it is not finding the files....

has any1 else had this problem?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.