behavior
Function
AI command. Puts the actor in a predetermined behavior pattern. A behavior is often (but not always) associated with the name of an animation. The descriptions for the game's predefined behaviors are listed in global/baseai.scr. Custom behaviors can also be defined with this command.
Syntax
|
$<actor_name> behavior <behavior_name> <arg1> <arg2> ...
|
Notes & examples
|
Unfortunately, I can only provide sketchy explanations on how behaviors work and how to use them since I don't fully understand them myself. From the examples I have seen in baseai.scr, behaviors are usually set within an actor's AI state.
However, behaviors are not likely to be used often compared to the other actor commands. A few of them (like Idle and Repel) are simple and can be very useful. What follows is a list of the game's configurable behaviors (as can be found in global/baseai.scr). I grouped them in several tables according to their usefulness and what I know or don't know about them.
Behaviors most likely to be useful:
The following 3 behaviors are simple to grasp and can be used in several situations.
|
Idle [animname]
|
Sets the name of the animation associated to an actor's Idle behavior.
|
Repel [animname] ["slide down" node] [max speed]
|
Sets the name of the animation, the name of the pathnode to "slide down" to and the maximum speed to at which to repel associated to this behavior. Repel is the behavior given to thugs when they repel from the ceiling windows in the Bank level.
|
PickupAndThrow [throwobject name]
|
Sets the name of the throwobject to use with this behavior. PickupAndThrow is the behavior given to the Manumit when it throws barrels at the player in the Subway level.
|
Jump [animname] [name of node to jump to]
|
Sets the name of the animation and the name of the pathnode associated to this behavior. Jump is the behavior that fighting actors (such as monsters and HC officers) are given when placed in the "jump" state. This can be used to change an actor's default jump animation when making him jump to a pathnode.
|
|
Repel behavior mini-tutorial:
|
Here's how you make thugs repel from a ledge with the Repel behavior. First, make a small rectangular room about 512 units high and add a ledge about 384 units above the floor.
Place a Monster_Thug_Magnum somewhere on that ledge and give him a targetname of "thug1" (any Monster_Thug_* and Monster_Guerilla_* type actor can be used for this because they all have a repel animation named "repel1").
Then, insert 2 info_pathnode entities. Place one on the ledge so the middle of its bounding box is lined up with the edge of the ledge brush. Place the other one on the floor and line up the side of it's bounding box so it's a bit farther ahead of the first one. Observe the green dashed line in Figure 1 and Figure 2 below to see how the pathnodes should line up.
|
|
|
Figure 1: Side View
|
Figure 2: Front View
|
Note: The placement of the top pathnode is critical in order for this to work properly. If it's placed too far back on the ledge, the actor will be blocked by the ledge and won't be able to repel to the bottom node. If it's placed too far out, the actor won't be able to walk or run to it because he figures it's sitting in "mid-air".
The placement of the bottom pathnode is also important. Just make sure it's completely clear of the ledge when seen from above. If it's placed underneath the ledge, the actor will be blocked by the ledge when trying to repel down to it.
Now give the info_pathnode on the ledge a targetname of "node1" and give the one on the floor a targetname of "node2". Don't forget to add an info_player_start and a couple of light entities. Save your map and compile it.
Next, you will need to write the following script.
$thug1 thread thug1_repel_thread
waitForPlayer
end
thug1_repel_thread:
local.self ignoreall
local.self respondto weaponsound
local.self definestate weaponsound thug1_repel
pause
thug1_repel:
local.self runto $node1
waitFor local.self
local.self behavior Repel repel1 $node2 48
waitFor local.self
end
Here, I chose to define the custom "thug1_repel" state to be activated by a weaponsound event because this is convenient. Since the map is small and only has one room, no matter where you stand, just firing a shot in the air will activate the "thug1_repel" state and execute the commands under that label. The ignoreall command is to make sure the monster doesn't attack the player on sight.
|
|
PickupAndThrow behavior mini-tutorial:
|
Here's how you make a Manumit throw objects at you with the PickupAndThrow behavior. First, make a small rectangular room about 512 units wide by 512 units long and about 256 units high.
Place a Monster_Manumit close to the west wall and give him a targetname of "manu1".
Then, insert a func_throwobject entity in one of the corners of the room. Give it a model key and set the value to "can.def". Click on the Scale + and - buttons once in the entity dialog so the model shows up in the views. Place the bottom of the barrel flush with the floor and give it a targetname of "barrel1".
While in the editor's XY view (top) and with the barrel still selected, use the X key to make 3 eXact copies of it and place them in the remaining 3 corners. Name them "barrel2", "barrel3" and "barrel4" in clockwise order around the room. Take a look at Figure 1 below to see how the entities should be placed.
|
|
Figure 1: Top View
|
Now add an info_player_start in the middle of the room and a couple of light entities. Save your map and compile it.
Next, you will need to write the following script.
$manu1 thread manu1_initstate
waitForPlayer
stuffcmd "god"
end
manu1_initstate:
local.self definestate sightenemy manu1_findbarrel
end
manu1_findbarrel:
local.self ifnear ThrowObject 8192 goto manu1_shootbarrel
print "I'm out of barrels so gotta whoop your ass!\n"
local.self copystate sightenemy default_sightenemy
local.self state sightenemy
end
manu1_shootbarrel:
local.barrel string local.other
local.self runto local.barrel
waitFor local.self
local.self behavior PickupAndThrow local.barrel
waitFor local.self
goto manu1_findbarrel
end
Here, I inserted the godmode cheat with the stuffcmd command to give the player a chance to observe what's going on in the game without being killed.
In the manu1_initstate thread, the definestate command is used to define a custom state thread (manu1_findbarrel) for the when the Manumit witnesses a sightenemy event (IOW, when he sees the player). So now, when the Manumit sees the player, the manu1_findbarrel thread is called instead of the default state thread defined for that event (global/baseai.scr::sightenemy).
The manu1_findbarrel thread uses the ifnear command to make the Manumit locate all the barrels (ThrowObject server class) within a distance of 8192 units (across the entire map IOW). So the condition will test true as long as there is a barrel left in the map and each time, the commands in the manu1_shootbarrel thread will be executed.
The manu1_shootbarrel thread is the part that handles the Manumit running up to the barrels, picking them up and throwing them at the player. The part to note is the use of the local.other variable. This is an implicit variable which contains the name of the activator of the current state. In this case, it's the targetname of the barrel found by the Manumit through the ifnear command. The value is passed to the variable local.barrel which is then used to tell the Manumit which barrel to run to, pick up and throw.
Once there are no barrels left (because they have all been thrown), the Manumit reverts to his default sightenemy state (copystate and state commands) and attacks the player.
Note: The use of the copystate command is essential in this example because you cannot use a definestate command to define a state from within that state thread itself.
When you spawn in the map, the Manumit will be facing the wall and you will be sitting in the middle of the room. Stay right where you are so you don't get in his way when he runs for barrels from one corner of the room to the next. Just fire a shot in the air to make him turn around and see you. This will set things in motion. If you like, you can download the example map and script of this tutorial here.
|
|
Jump behavior mini-tutorial:
|
Here's how you can make an actor jump while using a different animation than its default jump animation with the Jump behavior. For this example, I'll use the hero_Blade actor because he has a cool "frontflip" animation especialy suitable for this.
First, make a small rectangular room about 512 units in all directions (width, length and height). Place a Hero_Blade entity at one end of the room and give him a targetname of "blade1".
Then, insert 2 info_pathnode entities. Place one at the opposite end of the room from where the actor is. Place the other one between the actor and the pathnode that's at the end of the room. Make sure the 3 entities line up with one another as can be seen in Figure 1 and Figure 2 below.
|
|
|
Figure 1: Side View
|
Figure 2: Top View
|
Now give the info_pathnode closest to the actor a targetname of "node1" and give the one farthest from him a targetname of "node2". Don't forget to add an info_player_start and a light entity. Save your map and compile it.
Next, you will need to write the following script.
$blade1 thread blade1_flip_thread
waitForPlayer
end
blade1_flip_thread:
local.self ignoreall
local.self respondto weaponsound
local.self definestate weaponsound blade1_flip
pause
blade1_flip:
local.self walkto $node1
waitFor local.self
local.self behavior Jump frontflip $node2
waitFor local.self
end
Here, I chose to define the custom "blade1_flip" state to be activated by a weaponsound event because this is convenient. Since the map is small and only has one room, no matter where you stand, just firing a shot in the air will activate the "blade1_flip" state and execute the commands under that label. The ignoreall command is to make sure the actor doesn't continuously run around like mad.
What will happen here is that when you fire a shot in the air, the Blade actor will walk to node1 and then jump from node1 to node2 while using a frontflip animation instead of his regular jump animation.
|
|
Behaviors less likely to be useful:
The following behaviors are harder grasp and less useful because most would not benefit much from being modified unless you really know what you're doing. These apply mostly to human type enemies like thugs.
|
Investigate [animname] [position]
|
Sets the name of the animation and default coordinates location associated to this behavior. Investigate is the behavior that make fighting actors (such as monsters and HC officers) walk or run to the location of a suspicious sound (weapon sounds for example) when they hear it.
|
FindCover [animname]
|
Sets the name of the animation associated to this behavior. FindCover is one of the behaviors that fighting actors (such as monsters and HC officers) are given when placed in the "duckandcover" state. It makes them search and go to pathnodes which have the COVER spawnflag set.
|
FindEnemy [animname]
|
Sets the name of the animation associated to this behavior. FindEnemy is one of the behaviors that fighting actors (such as monsters and HC officers) are given when placed in the "duckandcover" state. It makes them search for enemies.
|
AimAndShoot [number of shots to take]
|
Sets the number of weapon shots to take when given this behavior. AimAndShoot is one of the behaviors that fighting actors (such as monsters and HC officers) are given when placed in the "duckandcover" state. It controls how many shots they fire at an enemy when they stop moving and shoot.
|
AimAndMelee [number of shots to take]
|
Sets the number of punch or kick shots to take when given this behavior. AimAndMelee is one of the behaviors that fighting actors (such as thugs) are given when placed in the "duckandcover" state. It becomes active when an actor is close enough to an enemy for melee attack.
|
StrafeAttack [animname]
|
Sets the name of the animation associated to this behavior. StrafeAttack is one of the behaviors that fighting actors (such as thugs) are given when placed in the "duckandcover" state. It determines what animation to use during strafing attacks.
|
StrafeTo [animname] [position/node name]
|
Sets the name of the animation and default coordinates/pathnode location associated to this behavior. StrafeTo is one of the behaviors that fighting actors (such as thugs) are given when placed in the "duckandcover" state. It determines what animation to use and where to go during strafing attacks.
|
|
Behaviors specific to a certain type of actor:
The following behaviors would not benefit much from being modified either unless you really know what you're doing. These are used for specific actors like nautics, bats, rats and civilians (neutrals).
|
SwimCloseAttack [animname]
|
Sets the name of the animation associated to this behavior. SwimCloseAttack is one of the behaviors that Nautics are given when placed in the "swimmeleeattack" state. It determines what animation to use when the Nautic rushes an enemy before melee attack.
|
FlyCloseAttack [animname]
|
Sets the name of the animation associated to this behavior. FlyCloseAttack is one of the behaviors that Bats are given when placed in the "flymeleeattack" state. It determines what animation to use when the Bat rushes an enemy before melee attack.
|
Wander [animname] [maxdistance]
|
Sets the name of the animation and maximum distance to wander from a Rat's initial spawn location associated to this behavior. Wander is the behavior given to rats in their "idle" state.
|
WanderCloseAttack [animname]
|
Sets the name of the animation associated to this behavior. WanderCloseAttack is one of the behaviors that Rats are given when placed in the "wandermeleeattack" state. It determines what animation to use when the Rat rushes an enemy before melee attack.
|
Melee
|
Melee is one of the behaviors that Nautics, Bats and Rats are given when placed in the "swimmeleeattack", "flymeleeattack" and "wandermeleeattack" states respectively. It simply makes the actor melee attack.
|
Hide [animname]
|
Sets the name of the animation associated to this behavior. Hide is the behavior that non-fighting actors (civilians) are given when placed in the "hide" or "flee" state. It makes them cower when they hear certain sounds (weapon shots, pain, etc.) or get hurt.
|
FleeAndRemove [animname]
|
Sets the name of the animation associated to this behavior. FleeAndRemove is the behavior that non-fighting actors (civilians) are given when placed in the "flee" state. It makes them cower when they hear certain sounds (weapon shots, pain, etc.) or get hurt.
|
|
Behaviors not likely to be useful:
Since I haven't been able to find any examples for these, I can't figure out what they do and how they work. In fact, I can't even figure whether they work at all (except for the last 2). I have included them here for the sake of completeness but their use is definitely not recommended.
|
Flee [animname]
|
Sets the name of the animation associated to this behavior. I can't find any examples of this so experiment at your own risk.
|
GotoPathNode [animname] [position/node name]
|
Sets the name of the animation and default coordinates/pathnode location associated to this behavior. I can't find any examples of this so experiment at your own risk.
|
FireFromCover [animname]
|
Sets the name of the animation associated to this behavior. I can't find any examples of this so experiment at your own risk.
|
FireOnSight [animname]
|
Sets the name of the animation associated to this behavior. I can't find any examples of this so experiment at your own risk.
|
PlayAnim [animname]
|
Sets the name of the animation associated to this behavior. I can't find any examples of this so experiment at your own risk.
|
OpenDoor [direction of door]
|
Sets the direction a rotating door will open when the actor walks up to it. Not much reason to change this since the default works properly (door opens away from him).
|
ObstacleAvoidance
|
Probably sets an actor's obstacle avoidance AI. Pretty much default so I can't see any reason to use this.
|
|
|