DO/CTL/OpCodes

From Dark Omen Wiki

< DO | CTL(Difference between revisions)
Jump to: navigation, search
(Updated opcode table to match up with ctldis)
m (spawn_regiment (BF))
 
(11 intermediate revisions not shown)
Line 1: Line 1:
-
{|class="wikitable" style="border-collapse: separate; "
+
<div style="float:right; margin-left: 2em; padding: 1em;">
-
! Op !! Mnemonic !! Parameter !! Explanation
+
__TOC__
 +
</div>
 +
 
 +
== init_unit (00) ==
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 00
+
|unk
-
| {{a-likely|init_unit}}
+
|unknown purpose
-
| -
+
|}
-
| At the start of every regiment script.
+
This command initializes some data structures of the unit to it's default values. It should be used as the first command called by a unit script.
 +
 
 +
== wait_for_deploy (01) ==
 +
 
 +
Blocks the execution of the units script until the deployment phase is finished.
 +
 
 +
In the deployment phase it sets bit 31 of unit flag 1. At the end of the phase it clears the bit.
 +
 
 +
== reset_call_stack (02) ==
 +
 
 +
Resets the units stack. Don't call this when you have to return from a function or are in a loop.
 +
 
 +
== restore_ip (03) ==
 +
 
 +
Restores the state saved with save_ip (execution continues after the save_ip call). All events get marked as handled so unhandled events are lost.
 +
 
 +
== save_ip (04) ==
 +
 
 +
Stores the current state of the instruction pointer (current function, position in function, number of free stack slots). Note that the stack itself is not saved!
 +
 
 +
== do (05) ==
 +
 
 +
Begins a do-loop (pushes position of next opcode on the stack). This loop is always executed at least once.
 +
 
 +
== always (06) ==
 +
 
 +
Usually used at the end of a do-loop. Pops from the stack and continues script execution at this position (this is usually the command following the do-statement).
 +
 
 +
== while (07) ==
 +
 
 +
Usually used at the end of a do-loop. Pops from the stack and checks the conditional flag:
 +
 
 +
{|class="wikitable"
 +
! Condition !! Result
|-
|-
-
| 01
+
|true
-
| {{a-certain|wait_for_deploy}}
+
|Continue execution at stack position
-
| -
+
-
| Pause script until deployment is finished
+
|-
|-
-
| 02
+
|false
-
| {{a-guess|reset_call_stack}}
+
|Continue execution with command after while
-
| -
+
|}
-
| ?
+
 
 +
== whilenot (08) ==
 +
 
 +
Usually used at the end of a do-loop. Pops from the stack and checks the conditional flag:
 +
 
 +
{|class="wikitable"
 +
! Condition !! Result
|-
|-
-
| 03
+
|true
-
| {{a-guess|restoreip}}
+
|Continue execution with command after while_not
-
| -
+
-
| Jumps to last saveip-call
+
|-
|-
-
| 04
+
|false
-
| {{a-guess|saveip}}
+
|Continue execution at stack position
-
| -
+
|}
-
| Saves Instruction Pointer
+
 
 +
== for (09) ==
 +
 
 +
Begins a for-loop.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 05
+
|num_loops
-
| {{a-certain|do}}
+
|How often the loop shall be executed.
-
| -
+
|}
-
|  
+
 
 +
Pushes two elements on the stack: The position of the next opcode and how often loop shall be executed.
 +
 
 +
== next (0A) ==
 +
 
 +
Usually used at the end of a for-loop.
 +
 
 +
Pops the loop counter from the stack and decrements it by one. If it is higher then 0 it's pushed again and the execution continues after the for-command (2nd stack element). Otherwise the 2nd element is popped too and execution continues after the next-command.
 +
 
 +
== goto (0B) ==
 +
 
 +
Continues execution at the beginning of a function.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 06
+
|func
-
| {{a-likely|always}}
+
|Number of the function to execute
-
| -
+
|}
-
| Jump to last do statement
+
 
 +
Note that the call stack is not altered. So you shouldn't call this while you are in a loop because it leaves garbage on the stack (call reset_call_stack to clear the stack).
 +
 
 +
== set_return_func (0C) ==
 +
 
 +
Overwrites the function [[DO/CTL/OpCodes#return_from_event_handler_.2813.29|return_from_event_handler]] returns to by setting the "overwrite return"-flag in the control flag but only when the "restart funtion"-bit was not set.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 07
+
|func
-
| {{a-likely|while}}
+
|Number of the function to execute
-
| -
+
|}
-
| Jump to do if previous statement is true
+
 
 +
== set_return_func_iftrue (0D) ==
 +
 
 +
Overwrites the function [[DO/CTL/OpCodes#return_from_event_handler_.2813.29|return_from_event_handler]] returns to by setting the "overwrite return"-flag in the control flag but only when the "restart funtion"-flag was not set and the conditional flag indicated true.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 08
+
|func
-
| {{a-likely|whilenot}}
+
|Number of the function to execute
-
| -
+
|}
-
| Jump to do if previous statement is false
+
 
 +
== set_return_func_with_restart (0E) ==
 +
 
 +
Overwrites the function [[DO/CTL/OpCodes#return_from_event_handler_.2813.29|return_from_event_handler]] returns to by setting the "overwrite return"-flag and the "restart function"-flag.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 09
+
|func
-
| {{a-likely|for}}
+
|Number of the function to execute
-
| -
+
|}
-
|  
+
 
 +
== set_return_func_with_restart_iftrue (0F) ==
 +
 
 +
Overwrites the function [[DO/CTL/OpCodes#return_from_event_handler_.2813.29|return_from_event_handler]] returns to by setting the "overwrite return"-flag and the "restart function"-flag if the conditional flag was true.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 0A
+
|func
-
| {{a-likely|next}}
+
|Number of the function to execute
-
| -
+
|}
-
|  
+
 
 +
== set_return_func_iffalse (10) ==
 +
 
 +
Overwrites the function [[DO/CTL/OpCodes#return_from_event_handler_.2813.29|return_from_event_handler]] returns to by setting the "overwrite return"-flag in the control flag but only when the "restart funtion"-flag was not set and the conditional flag indicated false.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 0B
+
|func
-
| {{a-certain|goto}}
+
|Number of the function to execute
-
| func_id
+
|}
-
| Jump to func_id
+
 
 +
== call (11) ==
 +
 
 +
Calls a function (use with return).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 0C
+
|func
-
| {{a-certain|branch1}}
+
|Number of the function to execute
-
| func_id
+
|}
-
| Used in eventhandler, Jump to func_id
+
 
 +
Pushes the position of the next opcode and the current function on the stack.
 +
 
 +
== return (12) ==
 +
 
 +
Continues execution directly after the call-command (Pops two elements from the stack (function and position)).
 +
 
 +
Don't call return while you are in a loop because the stack top contains the wrong element!
 +
 
 +
This function can also be used to return from an event handler (this command ignores the "overwrite return"-flag)
 +
 
 +
== return_from_event_handler (13) ==
 +
 
 +
Like return but checks the "overwrite return" and "restart function"-flag of the CTL control flag:
 +
 
 +
{|class="wikitable"
 +
! Condition !! Result
|-
|-
-
| 0D
+
|"overwrite return" not set
-
| {{a-certain|branch2}}
+
|Behaves like a normal return.
-
| func_id
+
-
| Used in eventhandler, Jump to func_id
+
|-
|-
-
| 0E
+
|"overwrite return" set
-
| {{a-certain|branch3}}
+
|Returns to the function specified with one of the set_return_function-commands. If the return function is the same as the one on the stack it will behave like a normal return instead.
-
| func_id
+
-
| Used in eventhandler, Jump to func_id
+
|-
|-
-
| 0F
+
|"overwrite return" and "restart function" set
-
| {{a-certain|branch4}}
+
|Always returns to the function specified with one of the set_return_function-commands (the stack gets cleaned but the content is ignored).
-
| func_id
+
|}
-
| Used in eventhandler, Jump to func_id
+
 
 +
Don't call return_from_event_handler while you are in a loop because the stack top contains the wrong element!
 +
 
 +
== sleep (15) ==
 +
 
 +
Pauses the script execution (script of next unit gets executed). Next time the execution continues with the command after sleep.
 +
 
 +
== sleep_iftrue (16) ==
 +
 
 +
Pauses the script execution based on the conditional flag:
 +
{|class="wikitable"
 +
! Condition !! Result
|-
|-
-
| 10
+
|true
-
| {{a-certain|branch5}}
+
|Script of next unit is executed. Next time the execution continues with the command after sleep.
-
| func_id
+
-
| Used in eventhandler, Jump to func_id
+
|-
|-
-
| 11
+
|false
-
| {{a-certain|call}}
+
|No sleep. Execution continues with the command after sleep_if_true
-
| func_id
+
|}
-
| Jump to func_id (return pos saved)
+
 
 +
== skip_iftrue (17) ==
 +
 
 +
Skips instructions based on the state of the conditional flag.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 12
+
|num_skip
-
| {{a-likely|return}}
+
|How many commands to skip. This value must be 1 + number of arguments. E.g. if you want to skip a function that takes two arguments num_skip must be 3.
-
| -
+
|}
-
| Continue from last call statement
+
 
 +
{|class="wikitable"
 +
! Condition !! Result
|-
|-
-
| 13
+
|true
-
| {{a-guess|return_from_event_handler}}
+
|num_skip commands are skipped
-
| -
+
-
| Continue from last event call?
+
|-
|-
-
| 15
+
|false
-
| {{a-guess|sleep1}}
+
|Execution continues with the next command
-
| -
+
|}
-
|  
+
 
 +
== set_timer (18) ==
 +
 
 +
Sets a timer for the unit (or overwrites the old). The timer decrements by 1 when the regiments script starts execution again.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 16
+
|timer
-
| {{a-guess|sleep2}}
+
|New value for the timer
-
| -
+
|}
-
| Call event handler if last statement was true
+
 
 +
== test_waiting_for_timer (19) ==
 +
 
 +
Sets the conditional flag to true if the timer is not 0.
 +
 
 +
== wait_for_timer (1A) ==
 +
 
 +
Pauses script execution until the timer is not 0.
 +
 
 +
== set_x_i (1B) ==
 +
 
 +
Sets the value of the unknown local register x (= purpose is unknown).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 17
+
|value
-
| {{a-likely|cond_skip}}
+
|Sets x to value.
-
| value
+
|}
-
| Skip value number of opcodes followed by this command
+
 
 +
== add_x_i (1C) ==
 +
 
 +
Adds a value to the unknown local register x (= purpose is unknown).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 18
+
|value
-
| {{a-likely|set_timer}}
+
|Adds value to x.
-
| time
+
|}
-
| set timer to time
+
 
 +
== test_x_eq_0 (1D) ==
 +
 
 +
Sets the conditional flag to true if the unknown local register x is 0.
 +
 
 +
== set_unit_r_i (1E) ==
 +
 
 +
Sets a local register to a value.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 19
+
|register
-
| {{a-likely|test_waiting_for_timer}}
+
|Local register to write
-
| -
+
-
| true if timer is set and is not 0
+
|-
|-
-
| 1A
+
|value
-
| {{a-likely|wait_for_timer"}}
+
|Sets register to value
-
| -
+
|}
-
| Waits for the amount of time set by set_timer
+
 
 +
Every unit has 8 registers, so the register parameter should be from 1 to 8. Other values will overwrite other memory!
 +
 
 +
== add_unit_r_i (1F) ==
 +
 
 +
Adds a value to a local registers value.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 1B
+
|register
-
| {{a-guess|set_x_i}}
+
|Local register to write
-
| value
+
-
| ?
+
|-
|-
-
| 1C
+
|value
-
| {{a-guess|add_x_i}}
+
|value added to value in register
-
| value
+
|}
-
| ?
+
 
 +
Every unit has 8 registers, so the register parameter should be from 1 to 8. Other values will overwrite other memory!
 +
 
 +
== test_unit_r_eq_i (20) ==
 +
 
 +
Sets the conditional flag to true if the value in a units register equals a value.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 1D
+
|register
-
| {{a-guess|test_x_eq_0}}
+
|Register to check
-
| -
+
-
| true if value == 0
+
|-
|-
-
| 1E
+
|value
-
| {{a-certain|set_unit_r_i}}
+
|Value the registers value is compared against
-
| register, value
+
|}
-
| Set register to value
+
 
 +
Use register -278 to check against the unit Id.
 +
 
 +
== test_unit_r_eq_r (21) ==
 +
 
 +
Sets the conditional flag to true if two local registers contain the same value.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 1F
+
|register1
-
| {{a-certain|add_unit_r_i}}
+
|First register
-
| register, value
+
-
| reg_value = reg_value + value
+
|-
|-
-
| 20
+
|register2
-
| {{a-certain|test_unit_r_eq_i}}
+
|Second register
-
| register, value
+
|}
-
| true if register == value
+
 
 +
Use register -278 to check against the unit Id.
 +
 
 +
== set_unit_r_random1to10 (22) ==
 +
 
 +
Assigns a "random" value (the value changes every second) in a range form 1 to 10 to a local register.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 21
+
|register
-
| {{a-certain|test_unit_r_eq_r}}
+
|Register to write
-
| register1, register2
+
|}
-
| true if register1 == register2
+
 
 +
Every unit has 8 registers, so the register parameter should range from 1 to 8. Other values will overwrite other memory!
 +
 
 +
== set_global_r_i (23) ==
 +
 
 +
Assigns a value to a global register.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 22
+
|register
-
| {{a-certain|set_unit_r_random1to10}}
+
|Global register to write
-
| register
+
-
| loads a value from 1-10 in a register<br />The value changes every ~2seconds
+
|-
|-
-
| 23
+
|value
-
| {{a-guess|set_global_r_i}}
+
|Value to assign to the register
-
| register, value
+
|}
-
| Set global register to value
+
 
 +
There are 8 registers, so the register parameter should range from 1 to 8. Other values will overwrite other memory!
 +
 
 +
== add_global_r_i (24) ==
 +
 
 +
Adds a value to the value in a global register.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 24
+
|register
-
| {{a-guess|add_global_r_i}}
+
|Global register to write
-
| register, value
+
-
| global_reg_value = global_reg_value + value
+
|-
|-
-
| 25
+
|value
-
| {{a-guess|test_global_r_eq_i}}
+
|Value to add to the registers value
-
| register, value
+
|}
-
| true if global register == value
+
 
 +
There are 8 registers, so the register parameter should range from 1 to 8. Other values will overwrite other memory!
 +
 
 +
== test_global_r_eq_i (25) ==
 +
 
 +
Sets the conditional flag to true if the value in a global register equals a value.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 28
+
|register
-
| {{a-certain|move_to_node}}
+
|Global register to test
-
| node_id
+
-
| Unit moves to node with id node_id
+
|-
|-
-
| 29
+
|value
-
| {{a-certain|retreat_to_node}}
+
|Value to test against
-
| node_id
+
|}
-
| Caller tries to reach node_id when retreating.<br /> If it's near the boundaries the unit will escape.
+
 
 +
== move_to_node (28) ==
 +
 
 +
{{a-guess|The side effects of this function are unknown.}}
 +
 
 +
The regiment will move to the node specified.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 2A
+
|node
-
| {{a-certain|patrol_to_waypoint}}
+
|Node the unit will move to
-
| waypoint_id (<11>)
+
|}
-
| Unit patrols between all circles that have the correct waypoint_id
+
 
 +
The node can be retrieved by looking at the "Game Objects"-Chunk of the BTB file by counting the entries downwards (starting from 0).
 +
 
 +
== retreat_to_node (29) ==
 +
 
 +
{{a-guess|The side effects of this function are unknown.}}
 +
 
 +
When the unit is retreating it will move the the node specified.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 2B
+
|node
-
| {{a-guess|block_movement}}
+
|Node the unit will move to
-
| -
+
|}
-
| Unit can't move anymore
+
 
 +
The node can be retrieved by looking at the "Game Objects"-Chunk of the BTB file by counting the entries downwards (starting from 0).
 +
 
 +
== patrol_to_waypoint (2A) ==
 +
 
 +
ToDo.
 +
 
 +
== block_movement (2B) ==
 +
 
 +
ToDo. Pauses script execution if some unknown condition is true.
 +
 
 +
== wait_unit_flag1_clear (2C) ==
 +
 
 +
Pauses the script execution until all of the bits specified in the bitmask are not set in unit flag 1.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 2C
+
|bitmask
-
| {{a-likely|wait_unit_flag1_clear}}
+
|The bitmask unit flag 1 is checked against.
-
| bitmask
+
|}
-
| Wait until flag 1 bits of caller are cleared
+
 
 +
== wait_unit_flag1_set (2D) ==
 +
 
 +
Pauses the script execution if none of the bits specified in the bitmask is set in unit flag 1.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 2D
+
|bitmask
-
| {{a-likely|wait_unit_flag1_set}}
+
|The bitmask unit flag 1 is checked against.
-
| bitmask
+
|}
-
| Wait until flag 1 bits of caller are set
+
 
 +
== test_unit_flag1 (2E) ==
 +
 
 +
Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in unit flag 1.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 2E
+
|bitmask
-
| {{a-likely|test_unit_flag1}}
+
|The bitmask unit flag 1 is checked against.
-
| bitmask
+
|}
-
| true if flag 1 bits of caller are set
+
 
 +
== set_unit_flag1 (2F) ==
 +
 
 +
Sets the bits specified in the bitmask in unit flag 1 (other bits are not changed).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 2F
+
|bitmask
-
| {{a-likely|set_unit_flag1}}
+
|The bitmask that will be used to set bits in unit flag 1.
-
| bitmask
+
|}
-
| Set flag 1 bits of caller
+
 
 +
== clear_unit_flag1 (30) ==
 +
 
 +
Clears the bits specified in the bitmask in unit flag 1 (other bits are not changed).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 30
+
|bitmask
-
| {{a-likely|clear_unit_flag1}}
+
|The bitmask that will be used to clear bits in unit flag 1.
-
| bitmask
+
|}
-
| Clear flag 1 bits of caller
+
 
 +
== wait_unit_flag2_clear (31) ==
 +
 
 +
Pauses the script execution until all of the bits specified in the bitmask are not set in unit flag 2.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 31
+
|bitmask
-
| {{a-likely|wait_unit_flag2_clear}}
+
|The bitmask unit flag 2 is checked against.
-
| bitmask
+
|}
-
| Wait until flag 2 bits of caller are cleared
+
 
 +
== wait_unit_flag1_set (32) ==
 +
 
 +
Pauses the script execution if none of the bits specified in the bitmask is set in unit flag 2.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 32
+
|bitmask
-
| {{a-likely|wait_unit_flag2_set}}
+
|The bitmask unit flag 2 is checked against.
-
| bitmask
+
|}
-
| Wait until flag 2 bits of caller are set
+
 
 +
== test_unit_flag2 (33) ==
 +
 
 +
Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in unit flag 2.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 33
+
|bitmask
-
| {{a-likely|test_unit_flag2}}
+
|The bitmask unit flag 2 is checked against.
-
| bitmask
+
|}
-
| true if flag 2 bits of caller are set
+
 
 +
== set_unit_flag2 (34) ==
 +
 
 +
Sets the bits specified in the bitmask in unit flag 2 (other bits are not changed).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 34
+
|bitmask
-
| {{a-likely|set_unit_flag2}}
+
|The bitmask that will be used to set bits in unit flag 2.
-
| bitmask
+
|}
-
| Set flag 2 bits of caller
+
 
 +
== clear_unit_flag2 (35) ==
 +
 
 +
Clears the bits specified in the bitmask in unit flag 2 (other bits are not changed).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 35
+
|bitmask
-
| {{a-likely|clear_unit_flag2}}
+
|The bitmask that will be used to clear bits in unit flag 2.
-
| bitmask
+
|}
-
| Clear flag 2 bits of caller
+
 
 +
== wait_unit_flag3_clear (36) ==
 +
 
 +
Pauses the script execution until all of the bits specified in the bitmask are not set in unit flag 3.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 36
+
|bitmask
-
| {{a-likely|wait_unit_flag3_clear}}
+
|The bitmask unit flag 3 is checked against.
-
| bitmask
+
|}
-
| Wait until flag 3 bits of caller are cleared
+
 
 +
== wait_unit_flag3_set (37) ==
 +
 
 +
Pauses the script execution if none of the bits specified in the bitmask is set in unit flag 3.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 37
+
|bitmask
-
| {{a-likely|wait_unit_flag3_set}}
+
|The bitmask unit flag 3 is checked against.
-
| bitmask
+
|}
-
| Wait until flag 3 bits of caller are set
+
 
 +
== test_unit_flag3 (38) ==
 +
 
 +
Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in unit flag 3.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 38
+
|bitmask
-
| {{a-likely|test_unit_flag3}}
+
|The bitmask unit flag 3 is checked against.
-
| bitmask
+
|}
-
| true if flag 3 bits of caller are set
+
 
 +
== set_ctrl_flag (39) ==
 +
 
 +
Sets the bits specified in the bitmask in the CTL control flag (other bits are not changed).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 39
+
|bitmask
-
| {{a-guess|set_ctrl_flag}}
+
|The bitmask that will be used to set bits in the CTL control flag.
-
| bitmask
+
|}
-
| Set flag bits of CTL-Engine
+
 
 +
== clear_ctrl_flag (3A) ==
 +
 
 +
Clears the bits specified in the bitmask in the CTL control flag (other bits are not changed).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 3A
+
|bitmask
-
| {{a-guess|clear_ctrl_flag}}
+
|The bitmask that will be used to clear bits in the CTL control flag.
-
| bitmask
+
|}
-
| Clear flag bits of CTL-Engine
+
 
 +
== test_ctrl_flag (3B) ==
 +
 
 +
Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in the CTL control flag
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 3B
+
|bitmask
-
| {{a-guess|test_ctrl_flag}}
+
|The bitmask the CTL control flag is checked against.
-
| bitmask
+
|}
-
| true if CTL-Engine-Flag flag bits are set
+
 
 +
== set_event_handler (3D) ==
 +
 
 +
Assigns a new event handler to the unit. An old event handler will be overwritten. If the game is in deployment phase all events will be marked as handled.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 3D
+
|func
-
| {{a-certain|set_event_handler}}
+
|The id of the function that will become the event handler.
-
| func
+
|}
-
| Registers func as an event handler
+
 
 +
== set_label (3F) ==
 +
 
 +
Assigns a label (identifier) to the unit which can be used by other commands to reference the unit (an old label will be overwritten).
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 3F
+
|label
-
| {{a-certain|set_label}}
+
|Unique label assigned to the unit.
-
| label
+
|}
-
| Sets label of a unit to label
+
 
 +
If another unit already has the same label this call will silently fail!
 +
 
 +
== store_unit_by_label (40) ==
 +
 
 +
Saves a reference to a unit. The reference can be used with [[DO/CTL/OpCodes#send_event_to_stored_unit_.2870.29|send_event_to_stored_unit]].
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 41
+
|label
-
| {{a-guess|test_label_exists}}
+
|Label of the regiment whose reference will be stored for later use.
-
| label
+
|}
-
| true if unit with thread_id is alive
+
 
 +
Only active units are checked. If no unit has the label this call will remove the stored reference.
 +
 
 +
== test_label_exists (41) ==
 +
 
 +
Sets the conditional flag to true if any unit has the label.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 52
+
|label
-
| {{a-certain|move_rand_in_radius}}
+
|Label to check.
-
| waypoint_id (<11>)
+
|}
-
| Move to a random position in the radius of the waypoint<br />Used for Peasants
+
 
 +
Only active units are checked.
 +
 
 +
== send_event_to_self_if_label_exists (42) ==
 +
 
 +
Sets the conditional flag to true if any unit has the label.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 53
+
|event
-
| {{a-likely|init_teleport}}
+
|Event to generate.
-
| node_id
+
-
| Sets the target of the next teleport call
+
|-
|-
-
| 55
+
|label
-
| {{a-likely|teleport_to}}
+
|Label to check.
-
| -
+
|}
-
| Moves the unit to the node_it set by init_teleport
+
 
 +
Additionally it adds a message if the label was found:
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 5C
+
|target
-
| {{a-certain|retreat}}
+
|Caller of the command
-
| -
+
-
| Caller retreats (yellow arrow) but without white flag
+
|-
|-
-
| 69
+
|event
-
| {{a-guess|send_event_to_this}}
+
|Passed as an argument
-
| event_id
+
-
| executes event of caller
+
|-
|-
-
| 6b
+
|source (arg1)
-
| {{a-guess|raise_event2}}
+
|Id of the unit with the label
-
| event_id
+
|}
-
| executes event of caller
+
 
 +
Only active units are checked.
 +
 
 +
== nop_4c (4C) ==
 +
 
 +
Does nothing. It's possible that some other function skips to this instruction.
 +
 
 +
== goto_iftrue (4E) ==
 +
 
 +
Continues execution at the beginning of a function if the conditional flag is true.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 6d
+
|func
-
| {{a-guess|raise_event3}}
+
|Number of the function to execute
-
| event_id
+
|}
-
| executes event of caller
+
 
 +
{|class="wikitable"
 +
! Condition !! Result
|-
|-
-
| 6e
+
|true
-
| {{a-guess|raise_event4}}
+
|Script execution continues at the start of the function passed as an argument.
-
| event_id
+
-
| executes event of caller
+
|-
|-
-
| 70
+
|false
-
| {{a-guess|raise_event5}}
+
|Script execution continues with the command following goto.
-
| event_id
+
|}
-
| executes event of caller
+
 
-
|-
+
Note that the call stack is not altered. So you shouldn't call this while you are in a loop because it leaves garbage on the stack (call reset_call_stack to clear the stack).
-
| 71
+
 
-
| {{a-likely|teleport_to2}}
+
== move_rand_in_radius (52) ==
-
| -
+
 
-
| Moves the unit to the node_it set by init_teleport
+
{{a-guess|The side effects of this function are unknown.}}
 +
 
 +
The regiments units will randomly move around at a node.
 +
 
 +
{|class="wikitable"
 +
! Argument !! Explanation
|-
|-
-
| 72
+
|node
-
| {{a-certain|get_event}}
+
|Node referenced by value in <11>
-
| -
+
|}
-
| Get the next event from the unit's event queue
+
 
-
|-
+
== init_teleport (53) ==
-
| 73
+
 
-
| {{a-certain|test_more_events}}
+
{{a-guess|The side effects of this function are unknown.}}
-
| -
+
 
-
| True if there are more events in the unit's event queue
+
The unit will pass through wall to the node.
-
|-
+
 
-
| 74
+
{|class="wikitable"
-
| {{a-certain|on_event}}
+
! Argument !! Explanation
-
| event_id
+
-
| If the current event matches event_id then continue, otherwise skip this event handler.
+
-
|-
+
-
| 75
+
-
| {{a-likely|end_event}}
+
-
| value
+
-
| leave the event-statement. Value is 0x1abc to skip to the next 0xabc label, or 0xdef to fall through to next event handler.
+
-
|-
+
-
| 76
+
-
| {{a-certain|iftrue}}
+
-
| -
+
-
|
+
-
|-
+
-
| 77
+
-
| {{a-certain|iffalse}}
+
-
| -
+
-
|
+
-
|-
+
-
| 78
+
-
| {{a-certain|else}}
+
-
| -
+
-
|
+
|-
|-
-
| 79
+
|node
-
| {{a-certain|endif}}
+
|Node the unit will move to
-
| -
+
-
|
+
-
|-
+
-
| 97
+
-
| {{a-guess|init_teleport_spell}}
+
-
| node_id
+
-
| Used by B1_04 Necromancer. Caller teleports to node_id
+
-
|-
+
-
| A2
+
-
| {{a-guess|search_and_attack_enemy}}
+
-
| unk, unk, unk
+
-
| Searches for an enemy in a specific radius and attacks it.<br/>True if enemy was found.
+
-
|-
+
-
| AC
+
-
| {{a-guess|search_and_shoot_enemy}}
+
-
| unk, unk, unk
+
-
| Searches for an enemy in a specific radius and shoots at him.<br/>True if enemy was found.
+
-
|-
+
-
| AE
+
-
| {{a-certain|play}}
+
-
| voice_id
+
-
| display portrait of caller and say text voice_id
+
-
|-
+
-
| AF
+
-
| {{a-certain|play_other_unit}}
+
-
| unit_id, voice_id
+
-
| display portrait of unit_id and say text voice_id
+
-
|-
+
-
| B2
+
-
| {{a-likely|test_unit_afraid}}
+
-
| -
+
-
| true if unit has fear
+
-
|-
+
-
| B3
+
-
| {{a-certain|test_unit_at_node}}
+
-
| node_id
+
-
| true if unit reached node_id
+
-
|-
+
-
| B3
+
-
| {{a-likely|test_unit_at_node2}}
+
-
| node_id
+
-
| true if unit reached node_id
+
-
|-
+
-
| B6
+
-
| {{a-guess|send_event_to_labelled}}
+
-
| label_id, event
+
-
| Calls event in unit with label_id
+
-
|-
+
-
| B8
+
-
| {{a-likely|test_event_from_enemy}}
+
-
| -
+
-
| true if event was caused by an enemy
+
-
|-
+
-
| BA
+
-
| {{a-certain|test_unit_class}}
+
-
| unit_class
+
-
| true if unit has unit type unit_class (ignores first 3 bits)
+
-
|-
+
-
| C1
+
-
| {{a-certain|test_unit_label}}
+
-
| label_id
+
-
| true if unit with label_id is on the map (= deployed) and alive
+
-
|-
+
-
| D8
+
-
| {{a-guess|test_other_unit_alive}}
+
-
| unit_id
+
-
| true if unit_id is still alive?
+
-
|-
+
-
| D9
+
-
| {{a-likely|test_user_action}}
+
-
| action_id
+
-
| Used in the tutorial map to check for player events.<br />True if the specific action was done.
+
-
|- 
+
-
| DA
+
-
| {{a-certain|ui_indicate}}
+
-
| x, y, size
+
-
| display 4 arrows that are placed around a rectangle<br />If x and y are -1, size is the unit_id
+
-
|-
+
-
| DE
+
-
| {{a-likely|test_other_unit_at_node}}
+
-
| node_id
+
-
| True if unit_id reached node
+
-
|-
+
-
| DF
+
-
| {{a-likely|test_other_unit_attacking}}
+
-
| unit_id
+
-
| True if unit_id is fighting
+
-
|-
+
-
| E0
+
-
| {{a-likely|test_other_unit_flags}}
+
-
| unit_id, flag
+
-
| true if flag of unit_id is set
+
-
|-
+
-
| E2
+
-
| {{a-likely|test_other_unit_selected}}
+
-
| unit_id
+
-
| true if unit with unit_id is selected
+
-
|-
+
-
| E6
+
-
| {{a-certain|test_mapmode}}
+
-
| -
+
-
| true if worldmap (spacebar) has been displayed
+
-
|-
+
-
| E7
+
-
| {{a-guess|test_other_unit_status}}
+
-
| unit_id
+
-
| true if ?
+
-
|-
+
-
| EA
+
-
| {{a-likely|test_sound_playing}}
+
-
| -
+
-
| true if last "play" is still playing
+
-
|-
+
-
| ED
+
-
| {{a-likely|end_mission}}
+
-
| -
+
-
| Display "End Mission" message
+
-
|-
+
-
| EE
+
-
| {{a-guess|test_other_unit_dead}}
+
-
| unit_id
+
-
| true if unit_id is dead
+
-
|-
+
-
|colspan="4"|<div style="color:green;">likely and tested</div>
+
-
<div style="color:brown;">Highly likely but not tested</div>
+
-
<!--<div style="color:orange;">Function basically undeterminable... :(</div>-->
+
-
<div style="color:red;">Guess and/or untested</div>
+
|}
|}
-
Note: node_id can be calculated by counting the subsections (starting from 0)
+
The node can be retrieved by looking at the "Game Objects"-Chunk of the BTB file by counting the entries downwards (starting from 0).
 +
 
 +
All teleport stuff is unknown, they somehow teleport the regiment to a new location... (often a game object). This function is often used combined with teleport_to, #54 and teleport_to2.
 +
 
 +
== teleport_to (54) ==
 +
 
 +
== teleport_to2 (55) ==
 +
 
 +
== charge (5A) ==
 +
 
 +
== retreat (5C) ==
 +
 
 +
== hold (65) ==
 +
 
 +
== send_event_to_self (69) ==
 +
 
 +
Send event with id arg to self.
 +
 
 +
== send_event_to_self_iftrue (6A) ==
 +
 
 +
== send_event_to_self_iffalse (6B) ==
 +
 
 +
== set_event_id (6D) ==
 +
 
 +
Changes id of last retrieved event (with get_event) to arg.
 +
 
 +
== broadcast_event_to_friends (6E) ==
 +
 
 +
All friends (same alignment) get a message. Source is the caller.
 +
 
 +
== broadcast_event_to_enemies (6F) ==
 +
 
 +
All enemies (different alignment) get a message. Source is the caller.
 +
 
 +
== send_event_to_stored_unit (70) ==
 +
 
 +
See [[DO/CTL/OpCodes#store_unit_by_label_.2840.29|store_unit_by_label]]
 +
 
 +
== teleport_to3 (71) ==
 +
 
 +
== get_event (72) ==
 +
 
 +
== test_more_events (73) ==
 +
 
 +
== on_event (74) ==
 +
 
 +
== end_event (75) ==
 +
 
 +
Checks for next event when arg is 3567, skips to marker otherwise (usually 6844, thats 1ABC. The 1 gets cleared, makes ABC (2748)).
 +
 
 +
== iftrue (76) ==
 +
 
 +
== iffalse (77) ==
 +
 
 +
== else (78) ==
 +
 
 +
== endif (79) ==
 +
 
 +
== (80) ==
 +
 
 +
Generates an enemy sighted event and sends it to the sender of the last event if some unknown condition is met.
 +
 
 +
== test_unit_flag1_and_close_combat (82) ==
 +
 
 +
Close combat is already set when the order is given by clicking the enemy unit not when the close combat is really entered.
 +
arg: unit flag 1
 +
 
 +
== test_missile_weapon (8D) ==
 +
 
 +
If arg1 is -1 return true if there is any leader missile weapon.
 +
If arg1 is not -1 return true if leader missile is same as arg1 (use 0 to check for "no leader missile weapon")
 +
 
 +
== nop_90 (90) ==
 +
 
 +
== nop_91 (91) ==
 +
 
 +
== nop_92 (92) ==
 +
 
 +
== test_magic_points_leq_i (93) ==
 +
 
 +
Checks if the AI controlled units have: magic points <= i.
 +
 
 +
== add_magic_points (94) ==
 +
 
 +
Adds arg magic points to the ai controlled global magic pool.
 +
 
 +
== init_teleport_spell (97) ==
 +
 
 +
== cast_spell (98) ==
 +
 
 +
<nowiki>#</nowiki>98 66, 16384, 1
 +
 
 +
Necromancer in B4_05 uses this to cast doombolt on the stone.
 +
 
 +
== cast_spell2 (99) ==
 +
 
 +
<nowiki>#</nowiki>99 66, 32768, 1: Casts dispell on the caller. Arguments are unknown. Must be called from an event handler
 +
 
 +
<nowiki>#</nowiki>94 n Adds n magic points to the enemies global magic pool
 +
 
 +
<nowiki>#</nowiki>93 n Checks if the enemy has at least n magic points
 +
 
 +
== add_spell (9D) ==
 +
 
 +
Add spell or magic item.
 +
 
 +
== search_and_attack_enemy (A2) ==
 +
 
 +
arg3 is the attribute that should not be set (usually, 4096, thats the steam tank).
 +
 
 +
== search_and_shoot_enemy (AC) ==
 +
 
 +
A2 up to AC are all doing similiar stuff.
 +
if arg1 != -1 then arg1 is the event (with id arg1) the caller will receive when something was found. About the source I have no idea yet but it could be the id of the unit found.
 +
 
 +
== play_self (AE) ==
 +
 
 +
Plays the speech file specified by arg.
 +
 
 +
== play_other (AF) ==
 +
 
 +
== test_self_afraid (B2) ==
 +
 
 +
Units with "Will never rout" or "Never retreats" attribute always fail this test.
 +
 
 +
== test_self_at_node (B3) ==
 +
 
 +
True if caller is at the game object specified.
 +
 
 +
== test_any_at_node (B4) ==
 +
 
 +
True if any unit is at the game object specified.
 +
 
 +
== test_any_at_node2 (B5) ==
 +
 
 +
arg1: Alignment
 +
arg2: game object node
 +
arg3: these flags must not be set in unit flag 1
 +
 
 +
== send_event_to_unit_with_label (B6) ==
 +
 
 +
arg1: label
 +
arg2: eventId (sender will be caller)
 +
 
 +
== send_event_to_source (B7) ==
 +
 
 +
Sends an event with id arg to the source of the last event (retrieved with get_event).
 +
Sender will be caller.
 +
 
 +
== test_event_from_enemy (B8) ==
 +
 
 +
== test_event_from_close_combat (B9) ==
 +
 
 +
True if sender is the one you are currently fighting (or want to fight by selecting it as a target with the mouse)
 +
 
 +
== test_unit_class (BA) ==
 +
 
 +
See [[Talk:DO/ARM#Unit_Type_Bitfield|Unit Type Bitfield]]
 +
 
 +
== change_unit_class (BD) ==
 +
 
 +
See [[Talk:DO/ARM#Unit_Type_Bitfield|Unit Type Bitfield]]
 +
 
 +
== spawn_unit (BF) ==
 +
 
 +
arg1: 1: Fanatics, 2: Zombie (same as spell)
 +
 
 +
arg2: CTL Function to execute
 +
 
 +
arg3: unknown
 +
 
 +
arg4: looks like some offset
 +
 
 +
== test_members_alive_geq_i (C0) ==
 +
 
 +
Members means the single units that are part of a regiment.
 +
 
 +
Returns true if alive members in the regiment >= arg.
 +
 
 +
== test_label_eq_i (C1) ==
 +
 
 +
True if caller has arg1 as label
 +
 
 +
== test_event_source_eq_i (C2) ==
 +
 
 +
Source is usually the unit that generated the event... but not always :)
 +
The id needed for arg1 can be calculated by counting all allied regiments allowed on the current map (starting with 0) continueing with the enemy regiments.
 +
If dead units get an id is not tested yet, if not this command is garbage because the ids would change...
 +
 
 +
Better command: [[DO/CTL/OpCodes#test_event_from_unit_.28EE.29|test_event_from_unit]]
 +
 
 +
== test_game_status (C3) ==
 +
 
 +
1: Deployment
 +
2: Battle
 +
 
 +
== test_objective (C4) ==
 +
 
 +
Somehow related to the objectives specified in the BTB.
 +
Valid arguments are 1 to 12 and 25.
 +
 
 +
== clear_event_queue (C7) ==
 +
 
 +
Marks all events of the unit as handled
 +
 
 +
== clear_last_event (C9) ==
 +
 
 +
Clears the last event (retrieved with get_event)
 +
 
 +
== test_attribute_set (CD) ==
 +
 
 +
Tests if any of the attributes in the bitmask is set.
 +
 
 +
== set_attribute (CE) ==
 +
 
 +
Sets the bitmask.
 +
 
 +
== clear_attribute (CF) ==
 +
 
 +
Clears the bitmask.
 +
 
 +
== test_event_arg3 (D3) ==
 +
 
 +
No idea what arg3 usually is, often just 0.
 +
 
 +
== test_units_alive_le_i (D5) ==
 +
 
 +
arg1: alignment
 +
arg2: compared against the counted units.
 +
if (counted >= arg2) false flag is set, true otherwise.
 +
 
 +
It counts the unit if it is active (unitflag1 & 1), the alignment matches and unitFlag2 & 2048 is not set and it has at least one alive unit. If the unit was counted unitflag2 & 0x100 is set.
 +
 
 +
== test_boss_defeated (D7) ==
 +
 
 +
Checks your game if you defeated Carstein (n = 1), Hand of Nagash (n = 2) or Black Grail (n = 3).
 +
 
 +
== test_unit_alive (D8) ==
 +
 
 +
True if a unit with unitId arg is active.
 +
 
 +
== test_user_action (D9) ==
 +
 
 +
Used to detect input in the tutorial
 +
 
 +
== ui_indicate (DA) ==
 +
 
 +
arg1: x pos
 +
arg2: y pos
 +
arg3: size
 +
 
 +
Display 4 arrows that are placed around a rectangle
 +
If x and y are -1, size is the unit_id
 +
 
 +
== (DB) and (DC) ==
 +
 
 +
Also something for use in tutorial...
 +
 
 +
== set_unit_r_direction (DD) ==
 +
 
 +
arg1: unit id
 +
arg2: register where direction of arg1 is written to.
 +
 
 +
Useful in the tutorial only.
 +
 
 +
== test_unit_at_node (DE) ==
 +
 
 +
Tests if unit with unitId arg1 is at arg2 (game object).
 +
 
 +
Some unknown value is checked too, so this description could be partly wrong.
 +
 
 +
[[DO/CTL/OpCodes#test_unit_at_node2_.28E7.29|test_unit_at_node2]] takes the same arguments but does not check this unknown value.
 +
 
 +
== test_unit_attacking (DF) ==
 +
 
 +
True if unit with unitId arg1 attacks unit with unitId arg2.
 +
 
 +
== test_other_unit_flag2 (E0) ==
 +
 
 +
arg1: unitId
 +
arg2: bitmask for unit flag 2
 +
 
 +
True if at least one bit is set.
 +
 
 +
== test_other_unit_flag3 (E1) ==
 +
 
 +
arg1: unitId
 +
arg2: bitmask for unit flag 3
 +
 
 +
True if at least one bit is set.
 +
 
 +
== test_unit_selected (E2) ==
 +
 
 +
True if unit with unitId arg is selected.
 +
 
 +
== test_any_spell_selected (E3) ==
 +
 
 +
True if any spell / magic item is selected.
 +
 
 +
== test_mapmode (E6) ==
 +
 
 +
True if overworld map (spacebar) was activated.
 +
 
 +
== test_unit_at_node2 (E7) ==
 +
 
 +
Tests if unit with unitId arg1 is at arg2 (game object).
 +
 
 +
See: [[DO/CTL/OpCodes#test_unit_at_node_.28DE.29|test_unit_at_node]]
 +
 
 +
== test_sound_playing (EA) ==
 +
 
 +
Tutorial stuff...
 +
 
 +
== test_other_unit_flag1 (EB) ==
 +
 
 +
arg1: unitId
 +
arg2: bitmask for unit flag 1
 +
 
 +
== test_other_unit_r_eq_i (EC) ==
 +
 
 +
arg1: unitId where to read from
 +
arg2: register to read
 +
arg3: value register is checked against
 +
 
 +
== end_mission (ED) ==
 +
 
 +
Displays the mission ended message
 +
 
 +
== test_event_from_unit (EE) ==
 +
 
 +
True if the events source is a unit with unitId arg.
 +
Will crash if event arg1 was no valid source.

Current revision as of 13:15, 5 May 2012

Contents

init_unit (00)

Argument Explanation
unk unknown purpose

This command initializes some data structures of the unit to it's default values. It should be used as the first command called by a unit script.

wait_for_deploy (01)

Blocks the execution of the units script until the deployment phase is finished.

In the deployment phase it sets bit 31 of unit flag 1. At the end of the phase it clears the bit.

reset_call_stack (02)

Resets the units stack. Don't call this when you have to return from a function or are in a loop.

restore_ip (03)

Restores the state saved with save_ip (execution continues after the save_ip call). All events get marked as handled so unhandled events are lost.

save_ip (04)

Stores the current state of the instruction pointer (current function, position in function, number of free stack slots). Note that the stack itself is not saved!

do (05)

Begins a do-loop (pushes position of next opcode on the stack). This loop is always executed at least once.

always (06)

Usually used at the end of a do-loop. Pops from the stack and continues script execution at this position (this is usually the command following the do-statement).

while (07)

Usually used at the end of a do-loop. Pops from the stack and checks the conditional flag:

Condition Result
true Continue execution at stack position
false Continue execution with command after while

whilenot (08)

Usually used at the end of a do-loop. Pops from the stack and checks the conditional flag:

Condition Result
true Continue execution with command after while_not
false Continue execution at stack position

for (09)

Begins a for-loop.

Argument Explanation
num_loops How often the loop shall be executed.

Pushes two elements on the stack: The position of the next opcode and how often loop shall be executed.

next (0A)

Usually used at the end of a for-loop.

Pops the loop counter from the stack and decrements it by one. If it is higher then 0 it's pushed again and the execution continues after the for-command (2nd stack element). Otherwise the 2nd element is popped too and execution continues after the next-command.

goto (0B)

Continues execution at the beginning of a function.

Argument Explanation
func Number of the function to execute

Note that the call stack is not altered. So you shouldn't call this while you are in a loop because it leaves garbage on the stack (call reset_call_stack to clear the stack).

set_return_func (0C)

Overwrites the function return_from_event_handler returns to by setting the "overwrite return"-flag in the control flag but only when the "restart funtion"-bit was not set.

Argument Explanation
func Number of the function to execute

set_return_func_iftrue (0D)

Overwrites the function return_from_event_handler returns to by setting the "overwrite return"-flag in the control flag but only when the "restart funtion"-flag was not set and the conditional flag indicated true.

Argument Explanation
func Number of the function to execute

set_return_func_with_restart (0E)

Overwrites the function return_from_event_handler returns to by setting the "overwrite return"-flag and the "restart function"-flag.

Argument Explanation
func Number of the function to execute

set_return_func_with_restart_iftrue (0F)

Overwrites the function return_from_event_handler returns to by setting the "overwrite return"-flag and the "restart function"-flag if the conditional flag was true.

Argument Explanation
func Number of the function to execute

set_return_func_iffalse (10)

Overwrites the function return_from_event_handler returns to by setting the "overwrite return"-flag in the control flag but only when the "restart funtion"-flag was not set and the conditional flag indicated false.

Argument Explanation
func Number of the function to execute

call (11)

Calls a function (use with return).

Argument Explanation
func Number of the function to execute

Pushes the position of the next opcode and the current function on the stack.

return (12)

Continues execution directly after the call-command (Pops two elements from the stack (function and position)).

Don't call return while you are in a loop because the stack top contains the wrong element!

This function can also be used to return from an event handler (this command ignores the "overwrite return"-flag)

return_from_event_handler (13)

Like return but checks the "overwrite return" and "restart function"-flag of the CTL control flag:

Condition Result
"overwrite return" not set Behaves like a normal return.
"overwrite return" set Returns to the function specified with one of the set_return_function-commands. If the return function is the same as the one on the stack it will behave like a normal return instead.
"overwrite return" and "restart function" set Always returns to the function specified with one of the set_return_function-commands (the stack gets cleaned but the content is ignored).

Don't call return_from_event_handler while you are in a loop because the stack top contains the wrong element!

sleep (15)

Pauses the script execution (script of next unit gets executed). Next time the execution continues with the command after sleep.

sleep_iftrue (16)

Pauses the script execution based on the conditional flag:

Condition Result
true Script of next unit is executed. Next time the execution continues with the command after sleep.
false No sleep. Execution continues with the command after sleep_if_true

skip_iftrue (17)

Skips instructions based on the state of the conditional flag.

Argument Explanation
num_skip How many commands to skip. This value must be 1 + number of arguments. E.g. if you want to skip a function that takes two arguments num_skip must be 3.
Condition Result
true num_skip commands are skipped
false Execution continues with the next command

set_timer (18)

Sets a timer for the unit (or overwrites the old). The timer decrements by 1 when the regiments script starts execution again.

Argument Explanation
timer New value for the timer

test_waiting_for_timer (19)

Sets the conditional flag to true if the timer is not 0.

wait_for_timer (1A)

Pauses script execution until the timer is not 0.

set_x_i (1B)

Sets the value of the unknown local register x (= purpose is unknown).

Argument Explanation
value Sets x to value.

add_x_i (1C)

Adds a value to the unknown local register x (= purpose is unknown).

Argument Explanation
value Adds value to x.

test_x_eq_0 (1D)

Sets the conditional flag to true if the unknown local register x is 0.

set_unit_r_i (1E)

Sets a local register to a value.

Argument Explanation
register Local register to write
value Sets register to value

Every unit has 8 registers, so the register parameter should be from 1 to 8. Other values will overwrite other memory!

add_unit_r_i (1F)

Adds a value to a local registers value.

Argument Explanation
register Local register to write
value value added to value in register

Every unit has 8 registers, so the register parameter should be from 1 to 8. Other values will overwrite other memory!

test_unit_r_eq_i (20)

Sets the conditional flag to true if the value in a units register equals a value.

Argument Explanation
register Register to check
value Value the registers value is compared against

Use register -278 to check against the unit Id.

test_unit_r_eq_r (21)

Sets the conditional flag to true if two local registers contain the same value.

Argument Explanation
register1 First register
register2 Second register

Use register -278 to check against the unit Id.

set_unit_r_random1to10 (22)

Assigns a "random" value (the value changes every second) in a range form 1 to 10 to a local register.

Argument Explanation
register Register to write

Every unit has 8 registers, so the register parameter should range from 1 to 8. Other values will overwrite other memory!

set_global_r_i (23)

Assigns a value to a global register.

Argument Explanation
register Global register to write
value Value to assign to the register

There are 8 registers, so the register parameter should range from 1 to 8. Other values will overwrite other memory!

add_global_r_i (24)

Adds a value to the value in a global register.

Argument Explanation
register Global register to write
value Value to add to the registers value

There are 8 registers, so the register parameter should range from 1 to 8. Other values will overwrite other memory!

test_global_r_eq_i (25)

Sets the conditional flag to true if the value in a global register equals a value.

Argument Explanation
register Global register to test
value Value to test against

move_to_node (28)

The side effects of this function are unknown.

The regiment will move to the node specified.

Argument Explanation
node Node the unit will move to

The node can be retrieved by looking at the "Game Objects"-Chunk of the BTB file by counting the entries downwards (starting from 0).

retreat_to_node (29)

The side effects of this function are unknown.

When the unit is retreating it will move the the node specified.

Argument Explanation
node Node the unit will move to

The node can be retrieved by looking at the "Game Objects"-Chunk of the BTB file by counting the entries downwards (starting from 0).

patrol_to_waypoint (2A)

ToDo.

block_movement (2B)

ToDo. Pauses script execution if some unknown condition is true.

wait_unit_flag1_clear (2C)

Pauses the script execution until all of the bits specified in the bitmask are not set in unit flag 1.

Argument Explanation
bitmask The bitmask unit flag 1 is checked against.

wait_unit_flag1_set (2D)

Pauses the script execution if none of the bits specified in the bitmask is set in unit flag 1.

Argument Explanation
bitmask The bitmask unit flag 1 is checked against.

test_unit_flag1 (2E)

Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in unit flag 1.

Argument Explanation
bitmask The bitmask unit flag 1 is checked against.

set_unit_flag1 (2F)

Sets the bits specified in the bitmask in unit flag 1 (other bits are not changed).

Argument Explanation
bitmask The bitmask that will be used to set bits in unit flag 1.

clear_unit_flag1 (30)

Clears the bits specified in the bitmask in unit flag 1 (other bits are not changed).

Argument Explanation
bitmask The bitmask that will be used to clear bits in unit flag 1.

wait_unit_flag2_clear (31)

Pauses the script execution until all of the bits specified in the bitmask are not set in unit flag 2.

Argument Explanation
bitmask The bitmask unit flag 2 is checked against.

wait_unit_flag1_set (32)

Pauses the script execution if none of the bits specified in the bitmask is set in unit flag 2.

Argument Explanation
bitmask The bitmask unit flag 2 is checked against.

test_unit_flag2 (33)

Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in unit flag 2.

Argument Explanation
bitmask The bitmask unit flag 2 is checked against.

set_unit_flag2 (34)

Sets the bits specified in the bitmask in unit flag 2 (other bits are not changed).

Argument Explanation
bitmask The bitmask that will be used to set bits in unit flag 2.

clear_unit_flag2 (35)

Clears the bits specified in the bitmask in unit flag 2 (other bits are not changed).

Argument Explanation
bitmask The bitmask that will be used to clear bits in unit flag 2.

wait_unit_flag3_clear (36)

Pauses the script execution until all of the bits specified in the bitmask are not set in unit flag 3.

Argument Explanation
bitmask The bitmask unit flag 3 is checked against.

wait_unit_flag3_set (37)

Pauses the script execution if none of the bits specified in the bitmask is set in unit flag 3.

Argument Explanation
bitmask The bitmask unit flag 3 is checked against.

test_unit_flag3 (38)

Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in unit flag 3.

Argument Explanation
bitmask The bitmask unit flag 3 is checked against.

set_ctrl_flag (39)

Sets the bits specified in the bitmask in the CTL control flag (other bits are not changed).

Argument Explanation
bitmask The bitmask that will be used to set bits in the CTL control flag.

clear_ctrl_flag (3A)

Clears the bits specified in the bitmask in the CTL control flag (other bits are not changed).

Argument Explanation
bitmask The bitmask that will be used to clear bits in the CTL control flag.

test_ctrl_flag (3B)

Sets the conditional flag to "true" if any of the bits specified in the bitmask is set in the CTL control flag

Argument Explanation
bitmask The bitmask the CTL control flag is checked against.

set_event_handler (3D)

Assigns a new event handler to the unit. An old event handler will be overwritten. If the game is in deployment phase all events will be marked as handled.

Argument Explanation
func The id of the function that will become the event handler.

set_label (3F)

Assigns a label (identifier) to the unit which can be used by other commands to reference the unit (an old label will be overwritten).

Argument Explanation
label Unique label assigned to the unit.

If another unit already has the same label this call will silently fail!

store_unit_by_label (40)

Saves a reference to a unit. The reference can be used with send_event_to_stored_unit.

Argument Explanation
label Label of the regiment whose reference will be stored for later use.

Only active units are checked. If no unit has the label this call will remove the stored reference.

test_label_exists (41)

Sets the conditional flag to true if any unit has the label.

Argument Explanation
label Label to check.

Only active units are checked.

send_event_to_self_if_label_exists (42)

Sets the conditional flag to true if any unit has the label.

Argument Explanation
event Event to generate.
label Label to check.

Additionally it adds a message if the label was found:

Argument Explanation
target Caller of the command
event Passed as an argument
source (arg1) Id of the unit with the label

Only active units are checked.

nop_4c (4C)

Does nothing. It's possible that some other function skips to this instruction.

goto_iftrue (4E)

Continues execution at the beginning of a function if the conditional flag is true.

Argument Explanation
func Number of the function to execute
Condition Result
true Script execution continues at the start of the function passed as an argument.
false Script execution continues with the command following goto.

Note that the call stack is not altered. So you shouldn't call this while you are in a loop because it leaves garbage on the stack (call reset_call_stack to clear the stack).

move_rand_in_radius (52)

The side effects of this function are unknown.

The regiments units will randomly move around at a node.

Argument Explanation
node Node referenced by value in <11>

init_teleport (53)

The side effects of this function are unknown.

The unit will pass through wall to the node.

Argument Explanation
node Node the unit will move to

The node can be retrieved by looking at the "Game Objects"-Chunk of the BTB file by counting the entries downwards (starting from 0).

All teleport stuff is unknown, they somehow teleport the regiment to a new location... (often a game object). This function is often used combined with teleport_to, #54 and teleport_to2.

teleport_to (54)

teleport_to2 (55)

charge (5A)

retreat (5C)

hold (65)

send_event_to_self (69)

Send event with id arg to self.

send_event_to_self_iftrue (6A)

send_event_to_self_iffalse (6B)

set_event_id (6D)

Changes id of last retrieved event (with get_event) to arg.

broadcast_event_to_friends (6E)

All friends (same alignment) get a message. Source is the caller.

broadcast_event_to_enemies (6F)

All enemies (different alignment) get a message. Source is the caller.

send_event_to_stored_unit (70)

See store_unit_by_label

teleport_to3 (71)

get_event (72)

test_more_events (73)

on_event (74)

end_event (75)

Checks for next event when arg is 3567, skips to marker otherwise (usually 6844, thats 1ABC. The 1 gets cleared, makes ABC (2748)).

iftrue (76)

iffalse (77)

else (78)

endif (79)

(80)

Generates an enemy sighted event and sends it to the sender of the last event if some unknown condition is met.

test_unit_flag1_and_close_combat (82)

Close combat is already set when the order is given by clicking the enemy unit not when the close combat is really entered. arg: unit flag 1

test_missile_weapon (8D)

If arg1 is -1 return true if there is any leader missile weapon. If arg1 is not -1 return true if leader missile is same as arg1 (use 0 to check for "no leader missile weapon")

nop_90 (90)

nop_91 (91)

nop_92 (92)

test_magic_points_leq_i (93)

Checks if the AI controlled units have: magic points <= i.

add_magic_points (94)

Adds arg magic points to the ai controlled global magic pool.

init_teleport_spell (97)

cast_spell (98)

#98 66, 16384, 1

Necromancer in B4_05 uses this to cast doombolt on the stone.

cast_spell2 (99)

#99 66, 32768, 1: Casts dispell on the caller. Arguments are unknown. Must be called from an event handler

#94 n Adds n magic points to the enemies global magic pool

#93 n Checks if the enemy has at least n magic points

add_spell (9D)

Add spell or magic item.

search_and_attack_enemy (A2)

arg3 is the attribute that should not be set (usually, 4096, thats the steam tank).

search_and_shoot_enemy (AC)

A2 up to AC are all doing similiar stuff. if arg1 != -1 then arg1 is the event (with id arg1) the caller will receive when something was found. About the source I have no idea yet but it could be the id of the unit found.

play_self (AE)

Plays the speech file specified by arg.

play_other (AF)

test_self_afraid (B2)

Units with "Will never rout" or "Never retreats" attribute always fail this test.

test_self_at_node (B3)

True if caller is at the game object specified.

test_any_at_node (B4)

True if any unit is at the game object specified.

test_any_at_node2 (B5)

arg1: Alignment arg2: game object node arg3: these flags must not be set in unit flag 1

send_event_to_unit_with_label (B6)

arg1: label arg2: eventId (sender will be caller)

send_event_to_source (B7)

Sends an event with id arg to the source of the last event (retrieved with get_event). Sender will be caller.

test_event_from_enemy (B8)

test_event_from_close_combat (B9)

True if sender is the one you are currently fighting (or want to fight by selecting it as a target with the mouse)

test_unit_class (BA)

See Unit Type Bitfield

change_unit_class (BD)

See Unit Type Bitfield

spawn_unit (BF)

arg1: 1: Fanatics, 2: Zombie (same as spell)

arg2: CTL Function to execute

arg3: unknown

arg4: looks like some offset

test_members_alive_geq_i (C0)

Members means the single units that are part of a regiment.

Returns true if alive members in the regiment >= arg.

test_label_eq_i (C1)

True if caller has arg1 as label

test_event_source_eq_i (C2)

Source is usually the unit that generated the event... but not always :) The id needed for arg1 can be calculated by counting all allied regiments allowed on the current map (starting with 0) continueing with the enemy regiments. If dead units get an id is not tested yet, if not this command is garbage because the ids would change...

Better command: test_event_from_unit

test_game_status (C3)

1: Deployment 2: Battle

test_objective (C4)

Somehow related to the objectives specified in the BTB. Valid arguments are 1 to 12 and 25.

clear_event_queue (C7)

Marks all events of the unit as handled

clear_last_event (C9)

Clears the last event (retrieved with get_event)

test_attribute_set (CD)

Tests if any of the attributes in the bitmask is set.

set_attribute (CE)

Sets the bitmask.

clear_attribute (CF)

Clears the bitmask.

test_event_arg3 (D3)

No idea what arg3 usually is, often just 0.

test_units_alive_le_i (D5)

arg1: alignment arg2: compared against the counted units. if (counted >= arg2) false flag is set, true otherwise.

It counts the unit if it is active (unitflag1 & 1), the alignment matches and unitFlag2 & 2048 is not set and it has at least one alive unit. If the unit was counted unitflag2 & 0x100 is set.

test_boss_defeated (D7)

Checks your game if you defeated Carstein (n = 1), Hand of Nagash (n = 2) or Black Grail (n = 3).

test_unit_alive (D8)

True if a unit with unitId arg is active.

test_user_action (D9)

Used to detect input in the tutorial

ui_indicate (DA)

arg1: x pos arg2: y pos arg3: size

Display 4 arrows that are placed around a rectangle If x and y are -1, size is the unit_id

(DB) and (DC)

Also something for use in tutorial...

set_unit_r_direction (DD)

arg1: unit id arg2: register where direction of arg1 is written to.

Useful in the tutorial only.

test_unit_at_node (DE)

Tests if unit with unitId arg1 is at arg2 (game object).

Some unknown value is checked too, so this description could be partly wrong.

test_unit_at_node2 takes the same arguments but does not check this unknown value.

test_unit_attacking (DF)

True if unit with unitId arg1 attacks unit with unitId arg2.

test_other_unit_flag2 (E0)

arg1: unitId arg2: bitmask for unit flag 2

True if at least one bit is set.

test_other_unit_flag3 (E1)

arg1: unitId arg2: bitmask for unit flag 3

True if at least one bit is set.

test_unit_selected (E2)

True if unit with unitId arg is selected.

test_any_spell_selected (E3)

True if any spell / magic item is selected.

test_mapmode (E6)

True if overworld map (spacebar) was activated.

test_unit_at_node2 (E7)

Tests if unit with unitId arg1 is at arg2 (game object).

See: test_unit_at_node

test_sound_playing (EA)

Tutorial stuff...

test_other_unit_flag1 (EB)

arg1: unitId arg2: bitmask for unit flag 1

test_other_unit_r_eq_i (EC)

arg1: unitId where to read from arg2: register to read arg3: value register is checked against

end_mission (ED)

Displays the mission ended message

test_event_from_unit (EE)

True if the events source is a unit with unitId arg. Will crash if event arg1 was no valid source.

Personal tools
communication