<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.wesnoth.org/index.php?action=history&amp;feed=atom&amp;title=CutsceneWML</id>
	<title>CutsceneWML - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.wesnoth.org/index.php?action=history&amp;feed=atom&amp;title=CutsceneWML"/>
	<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=CutsceneWML&amp;action=history"/>
	<updated>2026-05-05T21:15:53Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=CutsceneWML&amp;diff=32510&amp;oldid=prev</id>
		<title>Solsword at 06:50, 29 September 2009</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=CutsceneWML&amp;diff=32510&amp;oldid=prev"/>
		<updated>2009-09-29T06:50:15Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Revision as of 06:50, 29 September 2009&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l659&quot; &gt;Line 659:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 659:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160;  [/clear_variable]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; &amp;#160;  [/clear_variable]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160; #enddef&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160; #enddef&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;== See Also ==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[UsefulWMLFragments]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[ReferenceWML]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category: UsefulWMLFragments]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Solsword</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=CutsceneWML&amp;diff=32505&amp;oldid=prev</id>
		<title>Solsword: Initial copy of the page macros</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=CutsceneWML&amp;diff=32505&amp;oldid=prev"/>
		<updated>2009-09-29T06:39:02Z</updated>

		<summary type="html">&lt;p&gt;Initial copy of the page macros&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;WML for cutscenes, including a fixed fake movement macro (for cases where the destination contains a unit) and macros for defining dialogue for units that activates when a &amp;quot;main character&amp;quot; stops south of them.&lt;br /&gt;
&lt;br /&gt;
==== Fake Movement ====&lt;br /&gt;
&lt;br /&gt;
 #define MOVE_TO FILTER X Y CONDITION&lt;br /&gt;
     # Moves a unit to an empty space near (X, Y) (or to (X, Y) if possible).&lt;br /&gt;
     # Ignores zones of control. Just like MOVE_UNIT, except doesn't glitch the&lt;br /&gt;
     # movement animation when X,Y is occupied. The destination will satisfy&lt;br /&gt;
     # CONDITION (a standard location filter), even if (X, Y) doesn't.&lt;br /&gt;
     [store_unit]&lt;br /&gt;
         variable=move_to_units&lt;br /&gt;
         [filter]&lt;br /&gt;
             {FILTER}&lt;br /&gt;
             [and]&lt;br /&gt;
                 [not]&lt;br /&gt;
                     x=recall&lt;br /&gt;
                 [/not]&lt;br /&gt;
             [/and]&lt;br /&gt;
         [/filter]&lt;br /&gt;
     [/store_unit]&lt;br /&gt;
     {FOREACH move_to_units move_to_units_index}&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=move_to_id&lt;br /&gt;
             to_variable=move_to_units[$move_to_units_index].id&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         [store_unit]&lt;br /&gt;
             variable=move_to_unit&lt;br /&gt;
             [filter]&lt;br /&gt;
                 id=$move_to_id&lt;br /&gt;
             [/filter]&lt;br /&gt;
         [/store_unit]&lt;br /&gt;
         # Get the starting x and y values:&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=start_x&lt;br /&gt;
             to_variable=move_to_unit.x&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=start_y&lt;br /&gt;
             to_variable=move_to_unit.y&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         # Find an open space near the destination:&lt;br /&gt;
         {FIND_NEARBY ([not]&lt;br /&gt;
                           [filter]&lt;br /&gt;
                           [/filter]&lt;br /&gt;
                       [/not]&lt;br /&gt;
                       [and]&lt;br /&gt;
                           {CONDITION}&lt;br /&gt;
                       [/and]) {X} {Y} 30}&lt;br /&gt;
         # Set real coordinates and end position:&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=move_to_unit.x&lt;br /&gt;
             to_variable=nearby_locations[0].x&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=move_to_unit.y&lt;br /&gt;
             to_variable=nearby_locations[0].y&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         [clear_variable]&lt;br /&gt;
             name=nearby_locations&lt;br /&gt;
         [/clear_variable]&lt;br /&gt;
         [hide_unit]&lt;br /&gt;
             x,y=move_to_unit.x,move_to_unit.y&lt;br /&gt;
         [/hide_unit]&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=end_x&lt;br /&gt;
             to_variable=move_to_unit.x&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=end_y&lt;br /&gt;
             to_variable=move_to_unit.y&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         # Determine new facing for the unit:&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=move_to_unit.facing&lt;br /&gt;
             format=$(if(start_x &amp;lt; end_x, se, sw))&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         # Scroll to the old location:&lt;br /&gt;
         [scroll_to]&lt;br /&gt;
             x=$start_x&lt;br /&gt;
             y=$start_y&lt;br /&gt;
         [/scroll_to]&lt;br /&gt;
         # Erase the old unit:&lt;br /&gt;
         [kill]&lt;br /&gt;
             id=$move_to_id&lt;br /&gt;
             animate=no&lt;br /&gt;
             fire_event=no&lt;br /&gt;
         [/kill]&lt;br /&gt;
         # Move the fake unit:&lt;br /&gt;
         [move_unit_fake]&lt;br /&gt;
             type=$move_to_unit.type&lt;br /&gt;
             gender=$move_to_unit.gender&lt;br /&gt;
             variation=$move_to_unit.variation&lt;br /&gt;
             side=$move_to_unit.side&lt;br /&gt;
             x=$start_x,$end_x&lt;br /&gt;
             y=$start_y,$end_y&lt;br /&gt;
         [/move_unit_fake]&lt;br /&gt;
         # Place the real unit:&lt;br /&gt;
         [unstore_unit]&lt;br /&gt;
             variable=move_to_unit&lt;br /&gt;
             find_vacant=yes&lt;br /&gt;
         [/unstore_unit]&lt;br /&gt;
         [redraw]&lt;br /&gt;
         [/redraw]&lt;br /&gt;
     {NEXT move_to_units_index}&lt;br /&gt;
     [clear_variable]&lt;br /&gt;
         name=move_to_units, move_to_unit, move_to_id, start_x, start_y, end_x, end_y&lt;br /&gt;
     [/clear_variable]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Move to a point and then go to the recall list ====&lt;br /&gt;
&lt;br /&gt;
 #define EXIT_STAGE_RECALL FILTER X Y&lt;br /&gt;
     # Moves a unit matching the filter to X,Y, at which point it takes them&lt;br /&gt;
     # off of the map and puts them on the recall list. Doesn't work for more&lt;br /&gt;
     # than one unit at once.&lt;br /&gt;
     {MOVE_TO {FILTER} {X} {Y} ()}&lt;br /&gt;
     [store_unit]&lt;br /&gt;
         variable=exit_stage_recall_unit&lt;br /&gt;
         kill=yes&lt;br /&gt;
         [filter]&lt;br /&gt;
             {FILTER}&lt;br /&gt;
         [/filter]&lt;br /&gt;
     [/store_unit]&lt;br /&gt;
     [unstore_unit]&lt;br /&gt;
         variable=exit_stage_recall_unit&lt;br /&gt;
         x,y=recall,recall&lt;br /&gt;
     [/unstore_unit]&lt;br /&gt;
     [clear_variable]&lt;br /&gt;
         name=exit_stage_recall_unit&lt;br /&gt;
     [/clear_variable]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Give a unit unlimited movement ====&lt;br /&gt;
&lt;br /&gt;
 #define SET_UNLIMITED_MOVEMENT FILTER&lt;br /&gt;
     # Useful for story-only situations, this macro defines an event that&lt;br /&gt;
     # replenishes a unit's movement whenever that unit moves.&lt;br /&gt;
     [event]&lt;br /&gt;
         name=moveto&lt;br /&gt;
         first_time_only=no&lt;br /&gt;
         [filter]&lt;br /&gt;
             {FILTER}&lt;br /&gt;
         [/filter]&lt;br /&gt;
         [store_unit]&lt;br /&gt;
             kill=no&lt;br /&gt;
             variable=temp&lt;br /&gt;
             [filter]&lt;br /&gt;
                 {FILTER}&lt;br /&gt;
             [/filter]&lt;br /&gt;
         [/store_unit]&lt;br /&gt;
         [set_variable]&lt;br /&gt;
             name=temp.moves&lt;br /&gt;
             to_variable=temp.max_moves&lt;br /&gt;
         [/set_variable]&lt;br /&gt;
         [unstore_unit]&lt;br /&gt;
             find_vacant=no&lt;br /&gt;
             variable=temp&lt;br /&gt;
         [/unstore_unit]&lt;br /&gt;
         [clear_variable]&lt;br /&gt;
             name=temp&lt;br /&gt;
         [/clear_variable]&lt;br /&gt;
     [/event]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Set up dialogue-based interaction ====&lt;br /&gt;
&lt;br /&gt;
 #define ENABLE_INTERACTION&lt;br /&gt;
     # Sets up events to handle unit interaction. See the SET_MAIN_CHARACTER and&lt;br /&gt;
     # UNIT_MESSAGE macros...&lt;br /&gt;
     [event]&lt;br /&gt;
         name=trigger_dialogue&lt;br /&gt;
         first_time_only=no&lt;br /&gt;
         [switch]&lt;br /&gt;
             variable=second_unit.variables.dialogue.type&lt;br /&gt;
             [case]&lt;br /&gt;
                 value=message&lt;br /&gt;
                 {M id=$second_unit.id $second_unit.variables.dialogue.message}&lt;br /&gt;
                 [if]&lt;br /&gt;
                     [variable]&lt;br /&gt;
                         name=second_unit.variables.dialogue.response&lt;br /&gt;
                         not_equals=$null&lt;br /&gt;
                     [/variable]&lt;br /&gt;
                     [then]&lt;br /&gt;
                         {M id=$unit.id $second_unit.variables.dialogue.response}&lt;br /&gt;
                     [/then]&lt;br /&gt;
                 [/if]&lt;br /&gt;
                 [if]&lt;br /&gt;
                     [variable]&lt;br /&gt;
                         name=second_unit.variables.dialogue.event&lt;br /&gt;
                         not_equals=$null&lt;br /&gt;
                     [/variable]&lt;br /&gt;
                     [then]&lt;br /&gt;
                         [fire_event]&lt;br /&gt;
                             name=$second_unit.variables.dialogue.event&lt;br /&gt;
                             [primary_unit]&lt;br /&gt;
                                 id=$unit.id&lt;br /&gt;
                             [/primary_unit]&lt;br /&gt;
                             [secondary_unit]&lt;br /&gt;
                                 id=$second_unit.id&lt;br /&gt;
                             [/secondary_unit]&lt;br /&gt;
                         [/fire_event]&lt;br /&gt;
                     [/then]&lt;br /&gt;
                 [/if]&lt;br /&gt;
             [/case]&lt;br /&gt;
             [case]&lt;br /&gt;
                 value=option&lt;br /&gt;
                 [message]&lt;br /&gt;
                     id=$second_unit.id&lt;br /&gt;
                     message=$second_unit.variables.dialogue.message&lt;br /&gt;
                     [option]&lt;br /&gt;
                         message=$second_unit.variables.dialogue.option1&lt;br /&gt;
                         [command]&lt;br /&gt;
                             [if]&lt;br /&gt;
                                 [variable]&lt;br /&gt;
                                     name=second_unit.variables.dialogue.event1&lt;br /&gt;
                                     not_equals=$null&lt;br /&gt;
                                 [/variable]&lt;br /&gt;
                                 [then]&lt;br /&gt;
                                     [fire_event]&lt;br /&gt;
                                         name=$second_unit.variables.dialogue.event1&lt;br /&gt;
                                         [primary_unit]&lt;br /&gt;
                                             id=$unit.id&lt;br /&gt;
                                         [/primary_unit]&lt;br /&gt;
                                         [secondary_unit]&lt;br /&gt;
                                             id=$second_unit.id&lt;br /&gt;
                                         [/secondary_unit]&lt;br /&gt;
                                     [/fire_event]&lt;br /&gt;
                                 [/then]&lt;br /&gt;
                             [/if]&lt;br /&gt;
                         [/command]&lt;br /&gt;
                     [/option]&lt;br /&gt;
                     [option]&lt;br /&gt;
                         message=$second_unit.variables.dialogue.option2&lt;br /&gt;
                         [command]&lt;br /&gt;
                             [if]&lt;br /&gt;
                                 [variable]&lt;br /&gt;
                                     name=second_unit.variables.dialogue.event2&lt;br /&gt;
                                     not_equals=$null&lt;br /&gt;
                                 [/variable]&lt;br /&gt;
                                 [then]&lt;br /&gt;
                                     [fire_event]&lt;br /&gt;
                                         name=$second_unit.variables.dialogue.event2&lt;br /&gt;
                                         [primary_unit]&lt;br /&gt;
                                             id=$unit.id&lt;br /&gt;
                                         [/primary_unit]&lt;br /&gt;
                                         [secondary_unit]&lt;br /&gt;
                                             id=$second_unit.id&lt;br /&gt;
                                         [/secondary_unit]&lt;br /&gt;
                                     [/fire_event]&lt;br /&gt;
                                 [/then]&lt;br /&gt;
                             [/if]&lt;br /&gt;
                         [/command]&lt;br /&gt;
                     [/option]&lt;br /&gt;
                 [/message]&lt;br /&gt;
             [/case]&lt;br /&gt;
             # Note: silent failure on unknown type is intentional.&lt;br /&gt;
         [/switch]&lt;br /&gt;
     [/event]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Set the main character ====&lt;br /&gt;
&lt;br /&gt;
 #define SET_MAIN_CHARACTER FILTER&lt;br /&gt;
     # Sets the filtered unit as the &amp;quot;main character&amp;quot; allowing them to talk to&lt;br /&gt;
     # units that have an appropriate 'dialogue' variable. Interaction is&lt;br /&gt;
     # triggered when the filtered unit moves to a space drectly south of a unit&lt;br /&gt;
     # with dialogue. Note that the ENABLE_INTERACTION macro must be present in&lt;br /&gt;
     # order for this macro to work. See also the UNIT_MESSAGE and UNIT_OPTION&lt;br /&gt;
     # macros.&lt;br /&gt;
     [event]&lt;br /&gt;
         name=moveto&lt;br /&gt;
         first_time_only=no&lt;br /&gt;
         [filter]&lt;br /&gt;
             {FILTER}&lt;br /&gt;
             [and]&lt;br /&gt;
                 [filter_adjacent]&lt;br /&gt;
                     count=1&lt;br /&gt;
                     adjacent=n&lt;br /&gt;
                     [variable]&lt;br /&gt;
                         name=this_unit.variables.dialogue.type&lt;br /&gt;
                         not_equals=$null&lt;br /&gt;
                     [/variable]&lt;br /&gt;
                 [/filter_adjacent]&lt;br /&gt;
             [/and]&lt;br /&gt;
         [/filter]&lt;br /&gt;
         [fire_event]&lt;br /&gt;
             name=trigger_dialogue&lt;br /&gt;
             [primary_unit]&lt;br /&gt;
                 {FILTER}&lt;br /&gt;
             [/primary_unit]&lt;br /&gt;
             [secondary_unit]&lt;br /&gt;
                 [filter_adjacent]&lt;br /&gt;
                     count=1&lt;br /&gt;
                     adjacent=s&lt;br /&gt;
                     {FILTER}&lt;br /&gt;
                 [/filter_adjacent]&lt;br /&gt;
             [/secondary_unit]&lt;br /&gt;
         [/fire_event]&lt;br /&gt;
     [/event]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Set dialogue for a unit ====&lt;br /&gt;
&lt;br /&gt;
 #define UNIT_MESSAGE MESSAGE RESPONSE EVENT&lt;br /&gt;
     # Defines dialogue for a unit. When the main character (see the&lt;br /&gt;
     # SET_MAIN_CHARACTER macro) triggers interaction with this unit, the&lt;br /&gt;
     # message MESSAGE will be displayed, and the triggering unit will respond&lt;br /&gt;
     # with RESPONSE, after which EVENT will be fired with the triggering unit&lt;br /&gt;
     # as the primary unit and this unit as the secondary unit. Note that this&lt;br /&gt;
     # macro should be placed within a [variables] tag inside of a [unit] tag.&lt;br /&gt;
     [dialogue]&lt;br /&gt;
         type=message&lt;br /&gt;
         message={MESSAGE}&lt;br /&gt;
         response={RESPONSE}&lt;br /&gt;
         event={EVENT}&lt;br /&gt;
     [/dialogue]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #define SET_UNIT_MESSAGE FILTER MESSAGE RESPONSE EVENT&lt;br /&gt;
     # Works just like the UNIT_MESSAGE macro, except that it takes a FILTER&lt;br /&gt;
     # argument and applies the message to the all units matching the filter.&lt;br /&gt;
     # UNIT_MESSAGE can only be used during unit creation, and must be placed&lt;br /&gt;
     # within a [variables] tag. SET_UNIT_MESSAGE, on the other hand, can be&lt;br /&gt;
     # used anywhere.&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.type) (&amp;quot;message&amp;quot;)}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.message) ({MESSAGE})}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.response) ({RESPONSE})}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.event) ({EVENT})}&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Set dialogue for a unit, including a two-option question ====&lt;br /&gt;
&lt;br /&gt;
 #define UNIT_OPTION MESSAGE OPTION1 OPTION2 EVENT1 EVENT2&lt;br /&gt;
     # Defines dialogue for a unit that includes a choice to present to the&lt;br /&gt;
     # player. When the main character (see the SET_MAIN_CHARACTER macro)&lt;br /&gt;
     # triggers interaction with this unit, the message MESSAGE will be&lt;br /&gt;
     # displayed, along with the options OPTION1 and OPTION2. Depending on which&lt;br /&gt;
     # option the player chooses, either EVENT1 or EVENT2 will then be fired&lt;br /&gt;
     # with the triggering unit as the primary unit and this unit as the&lt;br /&gt;
     # secondary unit. Note that this macro should be placed within a&lt;br /&gt;
     # [variables] tag inside of a [unit] tag.&lt;br /&gt;
     [dialogue]&lt;br /&gt;
         type=option&lt;br /&gt;
         message={MESSAGE}&lt;br /&gt;
         option1={OPTION1}&lt;br /&gt;
         option2={OPTION2}&lt;br /&gt;
         event1={EVENT1}&lt;br /&gt;
         event2={EVENT2}&lt;br /&gt;
     [/dialogue]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #define SET_UNIT_OPTION FILTER MESSAGE OPTION1 OPTION2 EVENT1 EVENT2&lt;br /&gt;
     # Works just like the UNIT_OPTION macro, except that it takes a FILTER&lt;br /&gt;
     # argument and applies the message to all units matching the filter.&lt;br /&gt;
     # UNIT_OPTION can only be used during unit creation, and must be placed&lt;br /&gt;
     # within a [variables] tag. SET_UNIT_OPTION, on the other hand, can be&lt;br /&gt;
     # used anywhere.&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.type) (&amp;quot;option&amp;quot;)}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.message) ({MESSAGE})}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.option1) ({OPTION1})}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.option2) ({OPTION2})}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.event1) ({EVENT1})}&lt;br /&gt;
     {SET_PROPERTY ({FILTER}) (variables.dialogue.event2) ({EVENT2})}&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Clear unit dialogue ====&lt;br /&gt;
&lt;br /&gt;
 #define CLEAR_UNIT_DIALOGUE FILTER&lt;br /&gt;
     # Removes any dialogue that is assigned to units matching the given filter,&lt;br /&gt;
     # including both messages and options.&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.type)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.message)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.response)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.option1)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.option2)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.event)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.event1)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue.event2)}&lt;br /&gt;
     {CLEAR_PROPERTY ({FILTER}) (variables.dialogue)}&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Assign a role to a recalled unit with various back-ups ====&lt;br /&gt;
&lt;br /&gt;
 #define FILL_ROLE_RECALL SIDE ROLE FILTER BACKUP_FILTER TYPE X Y&lt;br /&gt;
     # Recalls the first unit on side SIDE matching FILTER and assigns it the&lt;br /&gt;
     # role ROLE. If no such unit exists, it tries to find a unit that matches&lt;br /&gt;
     # the given BACKUP_FILTER on SIDE's recall list, and if it can't, it tries&lt;br /&gt;
     # to find any unit on side SIDE's recall list. If SIDE has no units on its&lt;br /&gt;
     # recall list, a unit is spawned of type TYPE to fill the role. If the role&lt;br /&gt;
     # is already filled, this does nothing. If the given location is&lt;br /&gt;
     # unavailable, the nearest empty location will be used.&lt;br /&gt;
     [if]&lt;br /&gt;
         [have_unit]&lt;br /&gt;
             side={SIDE}&lt;br /&gt;
             x,y={X},{Y}&lt;br /&gt;
         [/have_unit]&lt;br /&gt;
         [then]&lt;br /&gt;
             {FIND_NEARBY ([not]&lt;br /&gt;
                               [filter]&lt;br /&gt;
                               [/filter]&lt;br /&gt;
                           [/not]) {X} {Y} 30}&lt;br /&gt;
             [set_variable]&lt;br /&gt;
                 name=fill_role_recall_target_x&lt;br /&gt;
                 to_variable=nearby_locations[0].x&lt;br /&gt;
             [/set_variable]&lt;br /&gt;
             [set_variable]&lt;br /&gt;
                 name=fill_role_recall_target_y&lt;br /&gt;
                 to_variable=nearby_locations[0].y&lt;br /&gt;
             [/set_variable]&lt;br /&gt;
             [clear_variable]&lt;br /&gt;
                 name=nearby_locations&lt;br /&gt;
             [/clear_variable]&lt;br /&gt;
         [/then]&lt;br /&gt;
         [else]&lt;br /&gt;
             [set_variable]&lt;br /&gt;
                 name=fill_role_recall_target_x&lt;br /&gt;
                 value={X}&lt;br /&gt;
             [/set_variable]&lt;br /&gt;
             [set_variable]&lt;br /&gt;
                 name=fill_role_recall_target_y&lt;br /&gt;
                 value={Y}&lt;br /&gt;
             [/set_variable]&lt;br /&gt;
         [/else]&lt;br /&gt;
     [/if]&lt;br /&gt;
     [if]&lt;br /&gt;
         [not]&lt;br /&gt;
             [have_unit]&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
             [/have_unit]&lt;br /&gt;
         [/not]&lt;br /&gt;
         [then]&lt;br /&gt;
             [recall]&lt;br /&gt;
                 show=no&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 x,y=$fill_role_recall_target_x,$fill_role_recall_target_y&lt;br /&gt;
                 {FILTER}&lt;br /&gt;
             [/recall]&lt;br /&gt;
             [role]&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 x,y=$fill_role_recall_target_x,$fill_role_recall_target_y&lt;br /&gt;
                 {FILTER}&lt;br /&gt;
             [/role]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
     [if]&lt;br /&gt;
         [not]&lt;br /&gt;
             [have_unit]&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
             [/have_unit]&lt;br /&gt;
         [/not]&lt;br /&gt;
         [then]&lt;br /&gt;
             [recall]&lt;br /&gt;
                 show=no&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 x,y=$fill_role_recall_target_x,$fill_role_recall_target_y&lt;br /&gt;
                 {BACKUP_FILTER}&lt;br /&gt;
             [/recall]&lt;br /&gt;
             [role]&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 {BACKUP_FILTER}&lt;br /&gt;
                 x,y=$fill_role_recall_target_x,$fill_role_recall_target_y&lt;br /&gt;
             [/role]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
     [if]&lt;br /&gt;
         [not]&lt;br /&gt;
             [have_unit]&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
             [/have_unit]&lt;br /&gt;
         [/not]&lt;br /&gt;
         [then]&lt;br /&gt;
             [recall]&lt;br /&gt;
                 show=no&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 x,y=$fill_role_recall_target_x,$fill_role_recall_target_y&lt;br /&gt;
             [/recall]&lt;br /&gt;
             [role]&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 x,y=$fill_role_recall_target_x,$fill_role_recall_target_y&lt;br /&gt;
             [/role]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
     [if]&lt;br /&gt;
         [not]&lt;br /&gt;
             [have_unit]&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
             [/have_unit]&lt;br /&gt;
         [/not]&lt;br /&gt;
         [then]&lt;br /&gt;
             [unit]&lt;br /&gt;
                 side={SIDE}&lt;br /&gt;
                 type={TYPE}&lt;br /&gt;
                 x,y=$fill_role_recall_target_x,$fill_role_recall_target_y&lt;br /&gt;
                 generate_name=yes&lt;br /&gt;
                 random_gender=yes&lt;br /&gt;
                 random_traits=yes&lt;br /&gt;
                 role={ROLE}&lt;br /&gt;
             [/unit]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
     [clear_variable]&lt;br /&gt;
         name=fill_role_recall_target_x,fill_role_recall_target_y&lt;br /&gt;
     [/clear_variable]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
==== Assign a group of roles to several units with backups ====&lt;br /&gt;
&lt;br /&gt;
 #define ASSIGN_ROLES ROLES DESIRED_ROLE_FILTER BACKUP_ROLE_FILTER&lt;br /&gt;
     # Fills several roles at once from the pool of units specified by&lt;br /&gt;
     # DESIRED_ROLE_FILTER, using units that match BACKUP_ROLE_FILTER if&lt;br /&gt;
     # necessary. ROLES should be an ordered, comma-separated list of roles to&lt;br /&gt;
     # fill. If not enough units match among both the DESIRED and BACKUP&lt;br /&gt;
     # filters, not all of the roles will be assigned. The main advantage of&lt;br /&gt;
     # ASSIGN_ROLES over [role] tags is that you don't have to use a bunch of&lt;br /&gt;
     # [not] role= [/not] statements to ensure that each unit gets one role.&lt;br /&gt;
     [set_variables]&lt;br /&gt;
         name=roles_to_assign&lt;br /&gt;
         [split]&lt;br /&gt;
             list={ROLES}&lt;br /&gt;
             key=value&lt;br /&gt;
             separator=,&lt;br /&gt;
             remove_empty=yes&lt;br /&gt;
         [/split]&lt;br /&gt;
     [/set_variables]&lt;br /&gt;
     [set_variable]&lt;br /&gt;
         name=role_assignment_index&lt;br /&gt;
         value=0&lt;br /&gt;
     [/set_variable]&lt;br /&gt;
     [set_variable]&lt;br /&gt;
         name=done_assigning_roles&lt;br /&gt;
         value=no&lt;br /&gt;
     [/set_variable]&lt;br /&gt;
     [store_unit]&lt;br /&gt;
         variable=primary_role_candidates&lt;br /&gt;
         [filter]&lt;br /&gt;
             {DESIRED_ROLE_FILTER}&lt;br /&gt;
         [/filter]&lt;br /&gt;
     [/store_unit]&lt;br /&gt;
     [set_variable]&lt;br /&gt;
         name=role_candidate_index&lt;br /&gt;
         value=0&lt;br /&gt;
     [/set_variable]&lt;br /&gt;
     [while]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=done_assigning_roles&lt;br /&gt;
             boolean_equals=no&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [and]&lt;br /&gt;
             [variable]&lt;br /&gt;
                 name=role_candidate_index&lt;br /&gt;
                 less_than=$primary_role_candidates.length&lt;br /&gt;
             [/variable]&lt;br /&gt;
         [/and]&lt;br /&gt;
         [do]&lt;br /&gt;
             # Assign a role:&lt;br /&gt;
             [role]&lt;br /&gt;
                 role=$roles_to_assign[$($role_assignment_index)].value&lt;br /&gt;
                 id=$primary_role_candidates[$($role_candidate_index)].id&lt;br /&gt;
             [/role]&lt;br /&gt;
             # Increment loop variables:&lt;br /&gt;
             [set_variable]&lt;br /&gt;
                 name=role_assignment_index&lt;br /&gt;
                 add=1&lt;br /&gt;
             [/set_variable]&lt;br /&gt;
             [set_variable]&lt;br /&gt;
                 name=role_candidate_index&lt;br /&gt;
                 add=1&lt;br /&gt;
             [/set_variable]&lt;br /&gt;
             # Check the break condition:&lt;br /&gt;
             [if]&lt;br /&gt;
                 [not]&lt;br /&gt;
                     [variable]&lt;br /&gt;
                         name=role_assignment_index&lt;br /&gt;
                         less_than=$roles_to_assign.length&lt;br /&gt;
                     [/variable]&lt;br /&gt;
                 [/not]&lt;br /&gt;
                 [then]&lt;br /&gt;
                     [set_variable]&lt;br /&gt;
                         name=done_assigning_roles&lt;br /&gt;
                         value=yes&lt;br /&gt;
                     [/set_variable]&lt;br /&gt;
                 [/then]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/do]&lt;br /&gt;
     [/while]&lt;br /&gt;
     # Use backups if necessary:&lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=done_assigning_roles&lt;br /&gt;
             boolean_equals=no&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [store_unit]&lt;br /&gt;
                 variable=secondary_role_candidates&lt;br /&gt;
                 [filter]&lt;br /&gt;
                     {BACKUP_ROLE_FILTER}&lt;br /&gt;
                 [/filter]&lt;br /&gt;
             [/store_unit]&lt;br /&gt;
             [set_variable]&lt;br /&gt;
                 name=role_candidate_index&lt;br /&gt;
                 value=0&lt;br /&gt;
             [/set_variable]&lt;br /&gt;
             [while]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=done_assigning_roles&lt;br /&gt;
                     boolean_equals=no&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [and]&lt;br /&gt;
                     [variable]&lt;br /&gt;
                         name=role_candidate_index&lt;br /&gt;
                         less_than=$secondary_role_candidates.length&lt;br /&gt;
                     [/variable]&lt;br /&gt;
                 [/and]&lt;br /&gt;
                 [do]&lt;br /&gt;
                     # Assign a role:&lt;br /&gt;
                     [role]&lt;br /&gt;
                         role=$roles_to_assign[$($role_assignment_index)].value&lt;br /&gt;
                         id=$secondary_role_candidates[$($role_candidate_index)].id&lt;br /&gt;
                     [/role]&lt;br /&gt;
                     # Increment loop variables:&lt;br /&gt;
                     [set_variable]&lt;br /&gt;
                         name=role_assignment_index&lt;br /&gt;
                         add=1&lt;br /&gt;
                     [/set_variable]&lt;br /&gt;
                     [set_variable]&lt;br /&gt;
                         name=role_candidate_index&lt;br /&gt;
                         add=1&lt;br /&gt;
                     [/set_variable]&lt;br /&gt;
                     # Check the break condition:&lt;br /&gt;
                     [if]&lt;br /&gt;
                         [not]&lt;br /&gt;
                             [variable]&lt;br /&gt;
                                 name=role_assignment_index&lt;br /&gt;
                                 less_than=$roles_to_assign.length&lt;br /&gt;
                             [/variable]&lt;br /&gt;
                         [/not]&lt;br /&gt;
                         [then]&lt;br /&gt;
                             [set_variable]&lt;br /&gt;
                                 name=done_assigning_roles&lt;br /&gt;
                                 value=yes&lt;br /&gt;
                             [/set_variable]&lt;br /&gt;
                         [/then]&lt;br /&gt;
                     [/if]&lt;br /&gt;
                 [/do]&lt;br /&gt;
             [/while]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
     [clear_variable]&lt;br /&gt;
         name=roles_to_assign, role_assignment_index, primary_role_candidates, secondary_role_candidates, role_candidate_index, done_assigning_roles&lt;br /&gt;
     [/clear_variable]&lt;br /&gt;
 #enddef&lt;/div&gt;</summary>
		<author><name>Solsword</name></author>
		
	</entry>
</feed>