Difference between revisions of "Ambient behaviour"

From Dragon Age Toolset Wiki
Jump to: navigation, search
(ambient_anim_patterns 2da)
(ambient_anim_patterns 2da)
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
+
{{Variable table start}}
0 nothing
+
{{Variable table row|ID| Label|
1 ambient_twitches
+
* 0 nothing
2 ambient_relaxed
+
* 1 ambient_twitches
3 wardog_eating
+
* 2 ambient_relaxed
4 wardog_lazy
+
* 3 wardog_eating
5 guard_patrolling_1
+
* 4 wardog_lazy
6 guard_patrolling_2
+
* 5 guard_patrolling_1
7 dead_1
+
* 6 guard_patrolling_2
8 priest_blessing
+
* 7 dead_1
9 crouching_praying_1
+
* 8 priest_blessing
10 speaker_lecturer
+
* 9 crouching_praying_1
11 listener_passive_1
+
* 10 speaker_lecturer
12 speaker_inciter
+
* 11 listener_passive_1
13 idle_chatter
+
* 12 speaker_inciter
14 listener_passive_2
+
* 13 idle_chatter
15 shopper
+
* 14 listener_passive_2
16 nurse
+
* 15 shopper
17 wounded
+
* 16 nurse
18 interact_map_table
+
* 17 wounded
19 arms_crossed
+
* 18 interact_map_table
20 merchant_beckon
+
* 19 arms_crossed
21 merchant_wander
+
* 20 merchant_beckon
22 servant_clean_floor
+
* 21 merchant_wander
23 sit_on_ground
+
* 22 servant_clean_floor
24 guard_wander_left_right
+
* 23 sit_on_ground
25 hands_behind_back
+
* 24 guard_wander_left_right
26 guard_attention
+
* 25 hands_behind_back
27 pre_loghain_meeting
+
* 26 guard_attention
28 guard_wander_right
+
* 27 pre_loghain_meeting
29 guard_wander_left
+
* 28 guard_wander_right
30 darkspawn_wander
+
* 29 guard_wander_left
31 crouch
+
* 30 darkspawn_wander
32 praying
+
* 31 crouch
33 crouching_praying_2
+
* 32 praying
34 hands_behind_back
+
* 33 crouching_praying_2
35 rummaging_1
+
* 34 hands_behind_back
36 sitting_ground_begging
+
* 35 rummaging_1
37 wizard_conjuring
+
* 36 sitting_ground_begging
38 sitting_chair
+
* 37 wizard_conjuring
39 wall_lean_left
+
* 38 sitting_chair
40 wall_lean_right
+
* 39 wall_lean_left
41 dead_2
+
* 40 wall_lean_right
42 dead_3
+
* 41 dead_2
43 dead_4
+
* 42 dead_3
44 chair_hand_table
+
* 43 dead_4
45 dying_soldier
+
* 44 chair_hand_table
46 fainted
+
* 45 dying_soldier
47 lying_wounded_loop
+
* 46 fainted
48 lying_knee_up
+
* 47 lying_wounded_loop
49 lying_ground
+
* 48 lying_knee_up
50 sitting_throne
+
* 49 lying_ground
51 sitting_desk_sleeping
+
* 50 sitting_throne
52 servant_pose
+
* 51 sitting_desk_sleeping
53 door_push_v3
+
* 52 servant_pose
54 door_push_v4
+
* 53 door_push_v3
55 dead
+
* 54 door_push_v4
56 relaxed
+
* 55 dead
57 werewolf_kneel
+
* 56 relaxed
58 laying_sleep_bed
+
* 57 werewolf_kneel
59 ambient_deer_grazing_1
+
* 58 laying_sleep_bed
60 ambient_deer_grazing_2
+
* 59 ambient_deer_grazing_1
61 distressed_1
+
* 60 ambient_deer_grazing_2
62 interact_sit_chair
+
* 61 distressed_1
63 servant_loop
+
* 62 interact_sit_chair
64 ambient_bear_grazing_1
+
* 63 servant_loop
65 ambient_wolf_eating_1
+
* 64 ambient_bear_grazing_1
66 torture_rack
+
* 65 ambient_wolf_eating_1
67 bored_loitering_1
+
* 66 torture_rack
68 bored_loitering_2
+
* 67 bored_loitering_1
69 browse_books_1
+
* 68 bored_loitering_2
70 warm_by_fire
+
* 69 browse_books_1
71 chat_by_fire_1
+
* 70 warm_by_fire
72 chat_by_fire_2
+
* 71 chat_by_fire_1
73 bored_wander_1
+
* 72 chat_by_fire_2
74 listen_talk_1
+
* 73 bored_wander_1
75 listen_talk_2
+
* 74 listen_talk_1
76 talk_listen_1
+
* 75 listen_talk_2
77 talk_listen_2
+
* 76 talk_listen_1
78 warm_fire_squat
+
* 77 talk_listen_2
79 female_sit_ground
+
* 78 warm_fire_squat
80 lying_wounded
+
* 79 female_sit_ground
81 browse_books_2
+
* 80 lying_wounded
82 sit_beg
+
* 81 browse_books_2
83 sit_beg_post
+
* 82 sit_beg
84 sit_desk_doze
+
* 83 sit_beg_post
85 listener_passive_3
+
* 84 sit_desk_doze
86 servant_clean_wall
+
* 85 listener_passive_3
87 throat slit dead
+
* 86 servant_clean_wall
88 merchant_stationary
+
* 87 throat slit dead
89 crazy_hermit
+
* 88 merchant_stationary
90 guard_stand_aside_l
+
* 89 crazy_hermit
91 guard_stand_aside_r
+
* 90 guard_stand_aside_l
92 prisoner_1
+
* 91 guard_stand_aside_r
93 prisoner_2
+
* 92 prisoner_1
94 prisoner_3
+
* 93 prisoner_2
95 scared
+
* 94 prisoner_3
96 weeping
+
* 95 scared
97 wandering_slob
+
* 96 weeping
98 soldier_after_battle_1
+
* 97 wandering_slob
99 cowering
+
* 98 soldier_after_battle_1
100 squat_by_fire
+
* 99 cowering
101 unconscious
+
* 100 squat_by_fire
102 bartender_seedy
+
* 101 unconscious
103 bored_stationary
+
* 102 bartender_seedy
104 interact_sit_chair
+
* 103 bored_stationary
105 chat_side_left
+
* 104 interact_sit_chair
106 chat_side_right
+
* 105 chat_side_left
107 soldier_after_battle_2
+
* 106 chat_side_right
108 bored soldier
+
* 107 soldier_after_battle_2
109 wounded_werewolf
+
* 108 bored soldier
110 oghren_faints
+
* 109 wounded_werewolf
111 prisoner_4
+
* 110 oghren_faints
112 prisoner_5
+
* 111 prisoner_4
113 bored_stationary_2
+
* 112 prisoner_5
114 merchant_wander_2
+
* 113 bored_stationary_2
115 shopper_2
+
* 114 merchant_wander_2
116 Cowering Loop
+
* 115 shopper_2
117 Praying Loop
+
* 116 Cowering Loop
118 Pleading
+
* 117 Praying Loop
119 Crate Interaction
+
* 118 Pleading
120 AngryCrowd1
+
* 119 Crate Interaction
121 AngryCrowd2
+
* 120 AngryCrowd1
122 AngryCrowd3
+
* 121 AngryCrowd2
123 AngryCrowd4
+
* 122 AngryCrowd3
124 Cheer1
+
* 123 AngryCrowd4
125 Cheer2
+
* 124 Cheer1
126 Cheer3
+
* 125 Cheer2
127 Cheer4
+
* 126 Cheer3
128 Hespith Eat Body
+
* 127 Cheer4
129 FemaleSitGroundLoop
+
* 128 Hespith Eat Body
130 dog_sleep
+
* 129 FemaleSitGroundLoop
131 rummaging_2
+
* 130 dog_sleep
1000 ambient_test
+
* 131 rummaging_2
1001 ambient_test_long
+
* 1000 ambient_test
 +
* 1001 ambient_test_long}}
  
 
== sys_ambient_h ==
 
== sys_ambient_h ==

Revision as of 17:28, 8 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.

Variable name Type Default Description
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

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.