Difference between revisions of "Ambient behaviour"

From Dragon Age Toolset Wiki
Jump to: navigation, search
(ambient_anim_patterns 2da)
m (ambient_anim_patterns 2da: Restoring final sentence)
 
(4 intermediate revisions by 2 users not shown)
Line 41: Line 41:
  
 
The actions used in an animation phase are listed in the [[ambient_anim_patterns 2da]]. Each row defines an animation pattern, consisting of up to thirteen actions. Each action is composed of an animation (left of the decimal) and the number of loops it is played (right of decimal). For example, 619.02 will play a sleeping loop animation twice and 619.99 will play an infinitely looping sleeping animation. Non-looping animations require no loop-count (i.e. decimal) component. The list of all available animations is located in [[ANIM_ 2da]].
 
The actions used in an animation phase are listed in the [[ambient_anim_patterns 2da]]. Each row defines an animation pattern, consisting of up to thirteen actions. Each action is composed of an animation (left of the decimal) and the number of loops it is played (right of decimal). For example, 619.02 will play a sleeping loop animation twice and 619.99 will play an infinitely looping sleeping animation. Non-looping animations require no loop-count (i.e. decimal) component. The list of all available animations is located in [[ANIM_ 2da]].
ID Label
 
0 nothing
 
1 ambient_twitches
 
2 ambient_relaxed
 
3 wardog_eating
 
4 wardog_lazy
 
5 guard_patrolling_1
 
6 guard_patrolling_2
 
7 dead_1
 
8 priest_blessing
 
9 crouching_praying_1
 
10 speaker_lecturer
 
11 listener_passive_1
 
12 speaker_inciter
 
13 idle_chatter
 
14 listener_passive_2
 
15 shopper
 
16 nurse
 
17 wounded
 
18 interact_map_table
 
19 arms_crossed
 
20 merchant_beckon
 
21 merchant_wander
 
22 servant_clean_floor
 
23 sit_on_ground
 
24 guard_wander_left_right
 
25 hands_behind_back
 
26 guard_attention
 
27 pre_loghain_meeting
 
28 guard_wander_right
 
29 guard_wander_left
 
30 darkspawn_wander
 
31 crouch
 
32 praying
 
33 crouching_praying_2
 
34 hands_behind_back
 
35 rummaging_1
 
36 sitting_ground_begging
 
37 wizard_conjuring
 
38 sitting_chair
 
39 wall_lean_left
 
40 wall_lean_right
 
41 dead_2
 
42 dead_3
 
43 dead_4
 
44 chair_hand_table
 
45 dying_soldier
 
46 fainted
 
47 lying_wounded_loop
 
48 lying_knee_up
 
49 lying_ground
 
50 sitting_throne
 
51 sitting_desk_sleeping
 
52 servant_pose
 
53 door_push_v3
 
54 door_push_v4
 
55 dead
 
56 relaxed
 
57 werewolf_kneel
 
58 laying_sleep_bed
 
59 ambient_deer_grazing_1
 
60 ambient_deer_grazing_2
 
61 distressed_1
 
62 interact_sit_chair
 
63 servant_loop
 
64 ambient_bear_grazing_1
 
65 ambient_wolf_eating_1
 
66 torture_rack
 
67 bored_loitering_1
 
68 bored_loitering_2
 
69 browse_books_1
 
70 warm_by_fire
 
71 chat_by_fire_1
 
72 chat_by_fire_2
 
73 bored_wander_1
 
74 listen_talk_1
 
75 listen_talk_2
 
76 talk_listen_1
 
77 talk_listen_2
 
78 warm_fire_squat
 
79 female_sit_ground
 
80 lying_wounded
 
81 browse_books_2
 
82 sit_beg
 
83 sit_beg_post
 
84 sit_desk_doze
 
85 listener_passive_3
 
86 servant_clean_wall
 
87 throat slit dead
 
88 merchant_stationary
 
89 crazy_hermit
 
90 guard_stand_aside_l
 
91 guard_stand_aside_r
 
92 prisoner_1
 
93 prisoner_2
 
94 prisoner_3
 
95 scared
 
96 weeping
 
97 wandering_slob
 
98 soldier_after_battle_1
 
99 cowering
 
100 squat_by_fire
 
101 unconscious
 
102 bartender_seedy
 
103 bored_stationary
 
104 interact_sit_chair
 
105 chat_side_left
 
106 chat_side_right
 
107 soldier_after_battle_2
 
108 bored soldier
 
109 wounded_werewolf
 
110 oghren_faints
 
111 prisoner_4
 
112 prisoner_5
 
113 bored_stationary_2
 
114 merchant_wander_2
 
115 shopper_2
 
116 Cowering Loop
 
117 Praying Loop
 
118 Pleading
 
119 Crate Interaction
 
120 AngryCrowd1
 
121 AngryCrowd2
 
122 AngryCrowd3
 
123 AngryCrowd4
 
124 Cheer1
 
125 Cheer2
 
126 Cheer3
 
127 Cheer4
 
128 Hespith Eat Body
 
129 FemaleSitGroundLoop
 
130 dog_sleep
 
131 rummaging_2
 
1000 ambient_test
 
1001 ambient_test_long
 
  
 
== sys_ambient_h ==
 
== sys_ambient_h ==

Latest revision as of 00:16, 10 December 2013

Creature topics:

Ambient behaviour begins when the player moves within 50m of a creature and ceases when the player remains more than 50m away for at least 40s. Ambient behaviour alternates between a movement phase and an animation phase, simulating a bubble of activity around the player. In a movement phase, the creature (optionally) moves to a new destination (typically a waypoint but it could be any object) and turns to face the same direction as the destination object. In an animation phase, the creature (optionally) performs one or more animations either in sequence or at random. Exact behaviour is controlled by local variables set on either the creature instance or template (see table below). All other local variables with the prefix AMBIENT_* are used internally by the ambient behaviour system (see script sys_ambient_h.nss) and should not be manually modified. Never directly modify AMBIENT_* local variables at run time using SetLocalInt - always use the functions Ambient_Start, Ambient_Stop, Ambient_OverrideBehaviour, and Ambient_RestoreBehaviour instead. Ambient behaviour is persisted when a game is saved and automatically resumes when a game is loaded.

Local Variables (var_creature)

Variable name Type Default Description
AMBIENT_SYSTEM_STATE int 0 Bitmask controlling ambient system operation. (ergo, values below are in hexadecimal).
  • 0x01 (AMBIENT_SYSTEM_ENABLED): Ambient behaviour enabled. For non-looping animations this is the only bit that need be set.
  • 0x02 (AMBIENT_SYSTEM_SPAWNSTART): Begin ambient behaviour immediately after spawning. Generally, only infinitely looping animations require this.
  • 0x04 (AMBIENT_SYSTEM_NOPLAYNEXT): Sets bPlayNext parameter to CommandPlayAnimation to false. Only infinitely looping animations require this.
  • 0x08 (AMBIENT_SYSTEM_NOBLEND): Sets bBlendIn parameter to CommandPlayAnimation to false. Set this to force a creature to resume an infinitely looping animation after a conversation.
  • 0x10 (AMBIENT_SYSTEM_ALWAYSON): Ambient behaviour never stops, regardless of distance to player. This should rarely, if ever, be used but at least the functionality exists if needed.
AMBIENT_MOVE_PATTERN int 0 Dictates how the creature moves. Add 100 to the values below make creature run instead of walk. Add 10-90 for a random mix of running and walking (a higher value means more running).
  • 0 (AMBIENT_MOVE_NONE): No ambient movement
  • 1 (AMBIENT_MOVE_PATROL): Patrol waypoints (1, 2, 3, 2, 1, ...)
  • 2 (AMBIENT_MOVE_LOOP): Loop through waypoints (1, 2, 3, 1, 2, 3, ...)
  • 3 (AMBIENT_MOVE_WARP): Jump creature from the last waypoint to the first (1, 2, 3, jump to 1, 2, 3, ...)
  • 4 (AMBIENT_MOVE_RANDOM): Move to a random waypoint other than the one the creature is currently at
  • 5 (AMBIENT_MOVE_WANDER): Move to random location within 10m of home location
  • 6 (AMBIENT_MOVE_WANDER_FAR): Move to random location within 30m of home location
  • 7 (AMBIENT_MOVE_PATH_PATROL): Patrol all waypoints using CommandMoveToMultiLocations (1,2,3,2,1,...)
  • 8 (AMBIENT_MOVE_PATH_LOOP): Loop through all waypoints using CommandMoveToMultiLocations (1,2,3. 1,2,3)
  • 9 (AMBIENT_MOVE_ONCE): Walk through the waypoint set once (1-2-3)
AMBIENT_MOVE_PREFIX string ap_<tag> The prefix is used to determine the waypoints the creature can travel to. Note that <tag> is a placeholder filled in at run-time with the tag of the creature. Hence, for example, if AMBIENT_MOVE_PREFIX is ap_<tag> and the creature's tag is cr_dog then the system will look for waypoints with tags ap_cr_dog_01, ap_cr_dog_02, etc. If no waypoint is found with the _01 extension, the system will search instead for all waypoints with tags matching the AMBIENT_MOVE_PREFIX value exactly (i.e. ap_cr_dog). This is useful in cases where you just want to add N waypoints all with the same tag.
AMBIENT_ANIM_PATTERN int 0 A row ID in ambient_anim_patterns 2da. Specifies the list of possible actions the creature can/will perform during an animation phase.
  • 0: No ambient animation pattern (ergo, no ambient animations).
AMBIENT_ANIM_FREQ float -1.0 Animation frequency. The part left of the decimal specifies the minimum and the part right of the decimal specifies the maximum number of random animations to play during an animation phase. So, for example, a value of 1.3 will play between 1 and 3 random animations from the animation pattern listed in ambient_ai.xls. A value of -1.0 plays all animations in the animation pattern in the order they are listed in ambient_ai.xls. Animation pattens that are highlighted in green on the worksheeet should always be played in order (i.e. AMBIENT_ANIM_FREQ is -1.0).
AMBIENT_COMMAND int 0 If non-zero, this value forces the creature to perform a specific command (instead of moving and animating).
  • 0: Use standard ambient ambient behaviour system to perform movement and animations.
  • 1: Forces creature to attack the nearest object with tag <tag>_target. There's an interval of 1-5 seconds between attack commands.
  • 2: Forces creature to attack the nearest object with tag <tag>_target. There's an interval of 0-0.5 seconds between attack commands.
AMBIENT_ANIM_PATTERN_OVERRIDE int 0 Overrides AMBIENT_ANIM_PATTERN if non-zero.
AMBIENT_ANIM_FREQ_OVERRIDE int 0 Overrides AMBIENT_ANIM_FREQ if non-zero.
AMBIENT_ANIM_STATE int 0 Internal use by ambient behaviour system. Tracks number of animations left to play.
AMBIENT_MOVE_COUNT int -1 Internal use by ambient behaviour system. Tracks total number of destination points for a creature.
AMBIENT_MOVE_STATE int 0 Internal use by ambient behaviour system. Tracks the last waypoint creature moved to and direction of travel.
AMBIENT_TICK_COUNT int 0 Used internally, do not modify
AMBIENT_ANIM_OVERRIDE_COUNT int 0

ambient_anim_patterns 2da

The actions used in an animation phase are listed in the ambient_anim_patterns 2da. Each row defines an animation pattern, consisting of up to thirteen actions. Each action is composed of an animation (left of the decimal) and the number of loops it is played (right of decimal). For example, 619.02 will play a sleeping loop animation twice and 619.99 will play an infinitely looping sleeping animation. Non-looping animations require no loop-count (i.e. decimal) component. The list of all available animations is located in ANIM_ 2da.

sys_ambient_h

The script sys_ambient_h contains the implementation of the ambient behaviour system. The AMBIENT_* local variables should never be directly modified at run-time. Instead, use the following functions to customize a creature's ambient behaviour through script.

// Normally this function is called automatically to begin or resume  ambient behaviour when a 
// creature perceives the player. However, it can be called explicitly to force a creature to begin 
// performing ambient behaviour or, if nAmbientEnable is 1, to enable ambient behaviour on a creature. 
void Ambient_Start(object oCreature = OBJECT_SELF, int nAmbientEnable = 0, int nMovePattern = 0, string sMovePrefix = "");
 
// Normally this function is called automatically to pause ambient behaviour after the party has 
// been out of the creature's sight for a while. However, this function can be used to force a 
// creature to temporarily cease ambient behaviour. Note that the creature will automatically  
// resume ambient behaviour when it perceives the player again. 
void Ambient_Pause(object oCreature = OBJECT_SELF, int bCheckVisibility = TRUE);
 
// Turns off ambient behaviour on a creature. The creature will resume ambient behaviour only 
// after Ambient_Start() is called.
void Ambient_Stop(object oCreature = OBJECT_SELF);
 
// Overrides the ambient animation pattern and animation frequency defined by the creature's template. 
void Ambient_OverrideBehaviour(object oCreature, int nAnimPattern, float fAnimFreq);
 
// Restores a creature's ambient animation behaviour to that defined in the creature's template.
void Ambient_RestoreBehaviour(object oCreature);

Overriding Ambient Behaviour

Variable name Type Default Description
AMBIENT_ANIM_PATTERN_OVERRIDE int 0 A row ID in ambient_anim_patterns 2da. Specifies the list of possible actions the creature can/will perform during an animation phase.
  • 0: no animations.
AMBIENT_ANIM_FREQ_OVERRIDE float -1.0 Animation frequency. The portion left of decimal specifies the minimum and the portion right of the decimal specifies the maximum number of animations to play during an animation phase. A value of -1.0 plays all animations in the animation pattern in the order listed in ambient_anim_patterns 2da.
AMBIENT_ANIM_OVERRIDE_COUNT int Used internally, do not modify

Customising Ambient Behaviour

Animations

New ambient_anim_patterns can be added as an M2DA.

Provisionally, it seems that some animations are cutscene-only. They don't work when scripted. This requires further investigation and documentation, as there is a bug which may account for some or all of this.

Movement

The system doesn't provide an explicit hook for a user-defined movement pattern.

However, it does support walking once through a set of waypoints.

We can implement any custom movement pattern as several sets of waypoints (each with its own prefix).

For example, if we want to walk from A to B, then C or D and E depending on some condition, we might define the sets as ap1 (A, B), ap2 (C) and ap3 (D, E).

We tell Ambient AI to walk waypoints prefixed ap1. On completion, we tell it to walk ap2 or ap3, depending on the condition.

Intercepting the Ambient AI is tricky. By default, EVENT_TYPE_COMMAND_COMPLETE is handled directly by the rules_core script, which kicks off the next Ambient AI action before we can stop it. Presumably, this is for performance reasons.

Set the AI_CUSTOM_AI_ACTIVE variable (see Custom AI) on the creature template to generate a new event (EVENT_TYPE_CUSTOM_COMMAND_COMPLETE) which can be handled in the creature script. If the creature is a non-combatant, CAI_INACTIVE (1) works fine.

Using AMBIENT_MOVE_ONCE, when the final waypoint is reached, Ambient AI will reset the move pattern to AMBIENT_MOVE_NONE before this new event fires.

We can then trigger the next set of waypoints by including a snippet like this in our creature script:

        case EVENT_TYPE_CUSTOM_COMMAND_COMPLETE:
        {
         object oCreature = OBJECT_SELF;
 
         // Do nothing unless we have arrived at our destination 
 
         if (GetLocalInt(oCreature, AMBIENT_MOVE_PATTERN) == AMBIENT_MOVE_NONE)
            {     
              int    nLastCommandType = GetEventInteger(ev, 0);
              int    nCommandStatus   = GetEventInteger(ev, 1);
              int    nLastSubCommand  = GetEventInteger(ev, 2);
              object oLastTarget      = OBJECT_INVALID;
              object oBlockingObject  = GetEventObject(ev, 2);  
 
              // Check which path just finished
 
              if (GetLocalString(oCreature, AMBIENT_MOVE_PREFIX) != "ap1_<tag>") break;
 
              // Stop Ambient AI for good order
 
              Ambient_Stop(oCreature);
 
              // Fix bug in Ambient_Start
 
              SetLocalInt(oCreature, AMBIENT_MOVE_COUNT, AMBIENT_MOVE_COUNT_INVALID); 
              SetLocalInt(oCreature, AMBIENT_MOVE_STATE,  AMBIENT_MOVE_NEXT);   
 
              // Restart on new path           
 
              Ambient_Start(oCreature, AMBIENT_SYSTEM_ENABLED, AMBIENT_MOVE_ONCE, "ap2_<tag>");                
            }
 
          bEventHandled = TRUE;
          break;
        }

Note that when using any movement pattern other than AMBIENT_MOVE_ONCE, Ambient AI will issue the next movement command before EVENT_TYPE_CUSTOM_COMMAND_COMPLETE fires.

Bugs

Changing the movement path for a creature is bugged.