--------------------------------------------------------------------------------
Build 1
--------------------------------------------------------------------------------
[+] Lua scripts support
[+] Moving monsters in combat (should it be optional?)
[+] Now there are no delays caused by waiting for sound to finish playing (tell me if you'd like to have it back in some cases)
[+] CA:M3 command to set up monsters in Portal of Summoning
[+] UN:A#/11/$ command to set pick up message for artifact
[+] UN:G1 additional indexes to set def name & sound prefix
[+] VR:R/$ command set/check/get random seed
[!] y-1..y-100 and f-1..f-100 are still set to 0 when a trigger is started. This is done for backward compatibility. y1..y100 and f1..f100 are still set to 0 when function is first called (only on first DO iteration).
[+] FU:E$ goto support
[+] Now UN:A#/9-11/$, UN:G0, UN:G1, UN:G2, SS:W,N,D, HT:, OB:H, HO:H, UN:K2, QW:A, may take constant strings as parameters and store them
[+] Now right mouse click in battle doesn't open a dialog with a button. Instead, Ctrl+Right click/Alt+Right click/Shift+Right click do that (should it be optional?)
[+] IF:M now can take a z-string as parameter (!!IF:Mz1, !!IF:Mz-1)
[+] TR:G - additional syntax lets you get terrain layout type and subtype. Type 40 subtypes 10000+ are for WoG terrain layouts.
[+] HD trigger and reciever lets you change hint text (also lets you track mouse moves on map, but not over Uncharted Territory)
[+] Work windowed in 32 bit colors mode
[+] FU:X#/?$ get type of argument x#
[+] !?TM#/#/#/# new syntax - automatic constant timer. The parameters are similar to TM:S.
[+] if-el-en changes
[+] z-1 - z-10 are now local variables for both functions and triggers
[+] UX:K#/?$ - check if key is pressed right now
[+] UX:M$1/$2 - get/check/set mouse coordinates
[+] UX:T - get current time or show dialog with time delta
[+] UX:S command to set/check/get various string constants
[+] BM:V - extended syntax
[+] BM:G - if you set duration to 0, now it removes the spell
[+] New experimental parameters syntax to get memory address
[+] MP new trigger and commands
[+] SN trigger works with more sounds
[+] New BG:X command - set/check/get second target of spell, changed BG:N
[+] New TR:E command syntax - get/check object entrance position
[+] Number of monsters extended to 255
[+] Number of artifacts extended to 255
[+] A bit improved errors reporting
[+] New kind of macros - macros for numbers (and flags). For example, !!MC3410:S@GetFirstStack@; [no need for a v-variable anymore]
[+] Macros length extended to 16 characters
[+] UN:C now accepts any integer variable - v,y,x and even f..t
[+] IF:M now can be used to display strings this way: IF:Mz1
[+] MP reciever only accepted z1-z1000 strings, now it accepts any strings
[+] MM:S and DL:H now accept constant and local strings
[-] TR:T road subtype wasn't handled correctly
[-] DO:P didn't restore z-1..z-10
[-] FU:P and DO:P didn't set unspecified parameters to zero
[-] DO:P ?y1 bug fixed
[-] FUy1:P didn't work
[-] Shortened delay on map start
[-] HE:B not only deleted hint, but also deleted all object setup made by OB reciever, except OB:C,T,U
[-] Check syntax didn't work properly (e.g. <> was taken for >)
[-] In case of wrong OB trigger syntax it was still added to triggers list.
[-] In case of !!FU:P?$macro$ call x1 didn't contain index of the macro variable
[-] MR:N didn't work
[-] SoD bug: monsters right-click dialog border color wasn't adjusted to fit current player color
[-] SoD bug: garrison right-click dialog border color wasn't adjusted to fit it's owner
[-] !?TL was called even after the game was finished and the player was in the main menu
[-] After setting hint for some artifact it was used instead of artifact description
[-] After an error in a script, the script was truncated. Script continued working, but after saving and loading game it didn't work.
[-] Comparsion in & and | part worked with e-vars incorrectly
[-] String !#VRv1:S$macro_1$ +$macro_2$; didn't work
[-] Macros didn't work with w-vars. Now each w-var may have a macro associated with it. The macro is common for all heroes. That is, the macro translates to, say, "w10", not to "w10 of the hero for which it was defined".
[*] Help additions (some information about already existing triggers)
Savegames of previous versions are incompatible.
Detailed Descriptions:
CA:M3/$1/$2; - set up type and count of creatures in Portal of Summoning
$1 - Type. -1 for no monster.
$2 - Count. It may be anything if Type is -1.
Note that the monster isn't defined on game start until you enter the town screen or the new week starts. This is a bug of SoD.
For example, start a game with a couple of dwellings and a Portal of Summoning in one of your castles. Save game. Enter the castle to see which type of creature is summoned. Then load the game and do the same. You may see a different creature there.
UN:G1/#1/#2/$; - additional indexes to set def name & sound prefix
#2 can now be 3 and 4.
#1 - Number of Monster (see Creature Format)
#2 - Type of text
0 - Singular name
1 - Plural name
2 - Specialty text
3 - Def file name (in battle, e.g. 'CGTITA.DEF')
4 - Sound prefix (4 first letters in sounds, e.g. 'gtit')
$ - string constant, z variable or index of z variable that keep the new text
0 means restore original
UN:A#/9-11/$, UN:G0, UN:G1, UN:G2, SS:W,N,D, HT:, OB:H, HO:H, UN:K2, MP:S, QW:A - new strings management syntax
New syntax:
If you pass a string constant (^hi!^) or a z-string (global or local), the value is copied into internal buffer (you don't need to use up a z variable for each object which hint you change).
If you use get syntax for a string (?z1), it's set to the current value (even if the value wasn't customized).
Usual syntax works the same:
If you pass 0, the original value is restored.
If you pass number, corresponding z-var is used and all changes made to z-var are reflected to the value. ERT strings are also supported.
If you use get/check syntax with a number (?v1), z variable index is returned. 0 is returned if the value wasn't customized. Negative values are returned if the custom string is stored in internal buffer.
Exceptions:
1) UN:K2 doesn't retrieve a standard new week message.
2) for QW:A you can pass -1 to restore original value, as before
VR:R/$ - set/check/get random seed
$ is random seed value.
Examples:
!!VR:R/?v1; will store current random seed in v1
!!VR:R/v1; will set random seed to v1
For a new chest you can set the seed to (X + (Y + L*256)*256) where X,Y,L are coordinates of the chest square:
!!VRv1:Sv999 *256 +v998 *256 +v997 R/v1;
This way you'll get good random numbers that depend on object position and don't change when you reload map.
You can also generate a random number on map start and add it to such random seed, so you will get different numbers when map is restarted.
Another example:
(this problem was discussed somewhere in erm_help. Now this solution)
On start of a battle random seed is set to some value that don't change if you load savegame and attack the same monsters again. So, if you need some real randomness in battle, use
!!VRv1:S0 T2147483647 R/v1; randomize - use random seed based on current time
It is also a good idea to restore the original random seed after all calculations are done:
!!VR:R/?v10; store original random seed in v10
!!VRv1:S0 T2147483647 R/v1; randomize - use random seed based on current time
........... some calculations
!!VR:Rv10; restore original random seed
FU:E$ - GoTo
Go $ triggers of same kind up or down. Triggers of same kind are those with the same 2 letters and the same parameters.
!?OB5/5/0 and !?OB0/0/0 are different. !?OB5/5/0 and !$OB5/5/0 are different too. But !?OB5/5/0; and !?OB5/5/0&v1=0; are of the same kind.
Examples:
1)
!?FU255; [1]
....
!?FU255; [2]
(...)
!!FU&1:E-1; [go to 2]
!!FU&2:E-2; [go to 1]
!!FU&3:E0; [usual FU:E - exit function]
2)
A single loop:
!?FU255;
!!VRy1:S0;
!?FU255&y1<100;
(...)
!!VRy1:+1;
!!FU:E-1;
This is equivalent to while y1<100 do { (...) y1 = y1 + 1; }
You can also make one loop inside another and anything you could do with regular DO, but much faster and without a need for a free function number.
You can place FU:G99999; at the end of a function and you would be able to insert it into multiple scripts - it would be executed only once anyway.
TR:G$1/$2 - get type & subtype of topmost terrain overlay.
$1 - type,
$2 - subtype
Type 40 subtypes starting with 10000 are recognized as new WoG terrain overlays. You can give them any effect with a script.
HD trigger - Hint Display.
!?HD triggers when the game needs to display a hint for an object. v998-v1000 keep coordinates of the square that was clicked by mouse.
Use HD:M$ to get or set hint text
Use HD:T$ to check if it's a right-click hint
($ is 1 if it's a right-click hint, 0 if it's a mouseover hint to be displayed in status bar)
Use HD:P$1/$2/$3/$4/$5/$6 to set pictures for the message (you can use less than 6 parameters if you don't need all 3 pictures)
$1 - picture 1 type,
$2 - picture 1 subtype,
$3 - picture 2 type,
$4 - picture 2 subtype,
$5 - picture 3 type,
$6 - picture 3 subtype
(if you use it in mouse over hint, it will be just ignored)
Use HD:C to check if hint of the object was customized with HT reciever or with HO:H command. In many cases you shouldn't process hints for such objects.
Example:
!?HD;
!!OB998:T?v1 U?v2; [get type and subtype of object to which the square belongs]
!!HD&v1=5:P8/v2;
!!HD&v1=93:P8/1;
[Displays artifact picture in right-click message]
FU:X#/?$ - get type of argument x# (stores it in $)
Types are: -2 'd?', -1 'd', 0 (normal), 1?, 2=, 3<>, 4>, 5<, 6>=, 7<=
Example:
!?FU1;
!!FU:X1/?y1 X2/?y2 X3/?y3 X4/?y4 X5/?y5;
!!IF:M^%X1:%Y1 %X2:%Y2 %X3:%Y3 %X4:%Y4 %X5:%Y5^;
!#FU1:P11/d22/?33/>=44; [show "11:0 22:-1 33:1 44:6 0:0"]
Note 1: Type 'd' and checks are only hints for the function. They are handled like there was no such sign unless the function handles them differently based on FU:X value.
Note 2: Type '=' have a special meaning in DO reciever.
!?TM#/#/#/# new syntax - automatic constant timer. The parameters are similar to TM:S.
You don't need to set up this kind of timers with TM reciever and their numbers are managed automatically. Once set up such timers cannot be changed with TM reciever.
Example:
!?TM1/-1/7/1; [timer every week for the first player]
Note: the best way to set up an infinite timer (in TM:S as well) is to use -1 as ending day.
if-el-en changes.
Now ef, el, en work as instructions too. (They worked only in triggers before)
You can use conditions in !!el now. You can use 'el' multiple times. This works like 'elseif' in Lua. The first one whose condition is true gets executed.
Example:
!#VRv5:S2;
!#if&v5=0:;
!#IF:M^v5 = 0^;
!#el&v5=1:;
!#IF:M^v5 = 1^;
!#el&v5=2:;
!#IF:M^v5 = 2^;
!#el&v5=3:;
!#IF:M^v5 = 3^;
!#el&v5=4:;
!#IF:M^v5 = 4^;
!#el:;
!#IF:M^other^;
!#en:;
[You will see the message "v5 = 2"]
UX reciever - Universal Extended
UX:S#/$ - reciever to get/check/set a big brunch of global strings
# is string index
$ is string or z variable or z variable index. 0 restores default. The new syntax explained above is used.
The list of all strings is in UX_S.txt file.
UX:K#/?$ - check if key is pressed right now
# is key code. $ is a variable to store the key state (1 = pressed, 0 = released)
Here are codes of some keys:
Shift 16
Control 17
Alt 18
Left Mouse Button 1
Right Mouse Button 2
Mouse Wheel 4
(you can use other keys codes, you can find them under name VK_* in programming languages)
UX:M$1/$2 - get/check/set mouse coordinates
$1 is X coordinate, $2 is Y coordinate.
The coordinates may be negative or more than 800,600 if the mouse is outside the Heroes window.
UX:T - get current time or show dialog with time delta
Returns time that ellapsed after the Windows was started in milliseconds when used with get (or check) syntax.
When used with set syntax it subtracts the valuse passed as parameter from the current time and shows the differance in a message.
Example:
!!UN:T?y10;
[some calculations that take much time...]
!!UN:Ty10;
BM:V - extended syntax
V#/$1 - Play animation #. $1 = bad effect.
$1 = Bad effect
$1 = 0 - just show the animation (same as V#)
$1 = 1 - show monster getting hit at the time of animation
V$1/$2/$3 - Play custom animation.
$1 = Type
0 - The bottom of animation is at the bottom of the creature (e.g. Prayer)
1 - Animation center is in the center of the creature (e.g. Air Shield)
2 - Animation is over the creature (e.g. Lightning)
4 - Animation is near the attacking hero (e.g Land Mine)
15 - Animation is in the center of battlefield (flying Desrupting Ray, Death Cloud)
Flag 256 - semi-transparent animation (add it to the type)
$2 = Bad effect (0 - just show the animation, 1 - show monster getting hit)
$3 = Name of def file with animation (this can be any existing def file) (any z-variable or a constant string)
Moving monsters in combat (should it be optional?)
Now monsters aren't just standing still in the combat, they always breath.
However, some monsters have bad animation in the standing phase and need updating. For instance, Phoenixes don't have a selection on some cadres. Most WoG monsters have terrible standing animation.
I've adjusted animation of some standard monsters. It's in h3wog.lod.
New experimental parameters syntax to get memory address
Now you can use d? to get address of an integer value. This is useful when working with UN:C command. If a command doen't support this, the value returned is 0. In Lua use ?ptr for this.
Example:
!#MA:P13/d?v1; [get Archangels hit points address in v1]
!#IF:M^%V1^;
MP new trigger and commands
MP:N$1 - play MP3 file ($1 - index of file or filename in z-variable or ^^)
!?MP - triggered when music starts to play
MP:C$1 - set/check/get index of upcoming music ($1 - index) (0 is returned if the mp3 isn't in the list)
MP:P$1 - set/check/get upcoming music ($1 - z-var or ^const string^)
SN trigger works with more sounds
Now it works when any sound is loaded (one of few exceptions is the buttons clicking sound that is loaded once before the map is started). Note that it works when sound is loaded, which doesn't always happen at the same time it is played.
SN:S, SN:P now take both ^^ constants and Z-vars
New BG:X command - set/check/get second target of spell
BG:X gets/sets/checks additional parameter of a spell being cast. It's the second target of Teleport and Sacrifice spells. For teleport, BG:D is the position of monster to be teleported and BG:X is the place where it will move. For sacrifice, BG:D is position of the corpse and BG:X is the victim position.
You can also use set syntax with BG:N command now.
Here are additions to other commands descriptions:
BG:A is 11 when Healing Tent heals
BG:S depands on the action:
Action 1 Hero cast spell: BG:S keeps spell number
Action 10 monster cast spell: BG:S keeps spell number
Action 6 Walk and Attack: BG:S keeps the position to which the monster will move. (BG:P keeps the enemy to attack)
Action 5 Surrender: BG:S keeps the cost of surrender.
For other actions it's -1 or the value from the last action.
Here is an example. You'll need a hero with a Pikeman in the first slot and Angels in the others (for example).
ZVSE
!#VRv100:S0;
!?CM4&v100<3;
!!CM:R0;
!!BG&v100=0:N3 A6 S2 D1;
!!BG&v100=1:A1 S40 D1 X2;
!!BG&v100=2:A1 S63 D1 X93;
!!VRv100:+1;
New TR:E$1/$2/$3 command syntax - get/check object entrance position
This command lets you get position of entrance of an object.
$1 - x
$2 - y
$3 - Level
If there is no object at the position, the coordinates passed to TR reciever are returned. If you pass coordinates of a red square of an object to it, it would return croordinates of its entrance.
Try this example:
!?CM;
!!CM:I?v5 P?v1/?v2/?v3;
!!FU&v5<>37:E;
!!TR1:E?v1/?v2/?v3;
!!IF:Q1/-1/0/4^%V1 %V2 %V3^;
!!CM:R0;
Help additions:
UN:G2 description in erm_help is wrong
#2 = 0: Speciality name. It's "Griffins" for Edric
#2 = 1: Long speciality name. It's "Creature Bonus: Griffins" for Edric
However, I have no idea where these strings are used in the the game.
(only know that speciality name is used in Advanced Options on map start, but maybe somewhere else too)
Small speciality picture is always the same as the normal one.
IF:M-1 doesn't exist anymore
In addition to HE-1 for current hero, there are HE-10 for attacker and HE-20 for defender in battles.
Help desn't mention that TR reciever and all recievers listed in "Other Objects" can take variable index as paramerer (like LE)
PM reciever as well can take x/y/l or variable index, and its parameters arent mentioned at all
OB reciever mentions the indirect syntax, but as a small note
--------------------------------------------------------------------------------
Build 2
--------------------------------------------------------------------------------
[+] Reworked Lua.
[+] New Lua-based custom dialogs engine.
[+] dialogs.CheckBoxesDialog. IF:G implementation swithed to dialogs.CheckBoxesDialog.
[+] Lua memory-management functions, hooks, Default metatable for numbers, bit.ToTable, bit.FromTable, Color functions, os.writelog, events support.
[-] _PlaceObject didn't preserve ebx register.
[+] !?OB - trigger for any object.
[-] BM:G was insecure (could be used to change any value in memory).
[+-] MR:N didn't work when a copy of monster was passed to !?MR. Now it returns -1 in this case and BM-1 changes current (from !?MR or currently active) monseter's properties.
[+] CA:B3/$/1 - check if the structure is built - works for non-upgraded buildings if upgrade is built.
[+] !?BA54 - called on both sides(?) after showing battlefield (after showing tactics dialog in case tactics is enabled).
[*] Hard-coded support for hex numbers (it was there before, I just didn't know about it
). 0x instead of $. $ isn't supported anymore.
[*] ?ptr instead of ?address.
[-] fixed SOD bug: def compression type 1 didn't work when used for map objects.
[+] now WoG supports locale in edits.
[+] CA:S# returns town income.
[+] !?CI0 trigger - change town income, !?CI1 trigger - change monster growth in town, !!CI reciever.
[+] CA:M4/level/# returns monster growth per week.
[+] Lua scripts path is configured in WoG.ini: [Common] LuaScriptsPath.
[+] UX:Gtown/$ - get/check/set town-specific grail effect state (0 - disabled, 1 - enabled) (for example, UX:G8/0 will disable the Conflux grail effect of learning all spells).
[+] !#FU:E can be used in instructions.
[-] Local functions weren't handled correctly in map scripts.
[-] Local functions weren't callable from instructions.
[+] CA:B3 - 2 more checks: CA:B3/#/1, CA:B3/#/2.
[-] SC:L was wrong
[-] For some unknown reason artifact hints were locked in IF:Q dialogs. Now they are unlocked.
[+] MessageEx - highly customazable message in Lua
[+] OB:T$/1, OB:C$/1 - type and control word of object, ignoring hero on top of it (works as usual if there's no hero standing on the object)
[+] !?FC trigger - change flag color, !!FC reciever
[+] !?DG trigger - digging for Grail, !!DG reciever
[+] flawed support for new Bink format
[+] !$HL post-trigger, getting skills in !?HL trigger
[-] Using UN:L inside !?OB trigger with enabled standard reaction caused a trade dialog of the hero with himself to occur.
[+] New HE:Y syntax: HE:Y$1/$2/$3, HE:Y0/0/0/3.
[-] HE:Y2 was totally broken.
[+] SoD campaigns are playable again. WoG campaigns have their separate button.
[+] Allow multiple copies if [Common]AllowMultipleCopies is set to 1 in WoG.ini
[+] HE:A5/$1/$2/?3/?4 - control artifact locks.
[+] !?AI - triggered when AI gets weight of a map square
[-] SoD bug: damage to be inflicted wasn't shown if Creature Info was disabled
[-] HE:F was redrawing adventure screen ONLY when check syntax is used (now it doesn't redraw screen at all)
[-] OW:R and some other commands were redrawing parts of adventure screen even if it's not active
[-] SoD bug: wrong check for free disk space
[+] New better GOTO. !!la, !!go in trigger.
[+] Number of if-el-en levels is now unlimited.
[+] File and line number information for ERM errors.
[-] SoD bug: rare crash on game start.
[!] Need to update help: BU:O may return values 0 - 3. 0 means no obstacle, 1 is an obstacle that can be passed through, but can be removed, 2 and 3 are unpassable (thanks to pHOMM).
[!] For help: IF:Q type 8 (artifact) subtype = <artifact number> + 0x10000*<spell number> (for scrolls)
[!] For help: change HE:A4 into HE:A4/#
[!] For help: BM:G description is inaccurate: $2 - Set/check/get level in school of the spell
[!] For help: OW:H has 2 kinds of syntax - with 2 parameters and with 3. They are mixed together in help. (description of $2 applies to 2-param syntax)
[!] For help: Additions to "List of all buildings" in CA.
[!] For help: HE:X: $1=5 means "+2 Speed to all units". No subtype of the speciality exists.
!?CI0 trigger - change town income, !?CI1 - change monster growth in town, !!CI reciever.
!?CI0 is triggered when the game calculates castle income.
!?CI1 is triggered when the game calculates monster growth in a castle.
!!CI:I$ set/check/get resulting income (or growth)
!!CI:I$/1 set/check/get base income (or growth) before ERM scripts changed it. ERM scripts shouldn't change this normally.
!!CI:L$ set/check/get monster level for CI1 (returns -1 for CI0)
Example:
!?CI;
!!CA-1:T?v1; [get town type]
!!CI&v1=1:Id500; [increase income of all Ramparts by 500]
CA:B3 - 2 more checks: CA:B3/#/1, CA:B3/#/2.
CA:B3/#/1 checks if the building is built with respect to upgrades,
CA:B3/#/2 checks if the building is enabled
Example:
!!CA-1:B3/30/1;
!!IF&1:M^Dwelling 1 is built^;
This will work even if you build the upgraded dwelling, or horde dwelling.
!?FC trigger - change flag color, !!FC reciever.
!?FC is triggered when the game needs flag color. Now any object can have a flag.
Use !!FC:T$ to get the type of object.
Use !!FC:U$ to get the subtype of object.
!!FC:C$ is the color of the flag.
v998, v999 and v1000 keep coordinates of the object entrance.
!?DG trigger - digging for Grail, !!DG reciever
!?DG is triggered when a hero is digging for Grail and the hole has already been placed
!!DG:P$/$/$ returns coordinates.
!!DG:G$ is 1 if the hero finds Grail, 0 otherwise.
!!DG:R$ is 1 to enable standard reaction, 0 to disable (the reaction is giving Grail to hero or showing failure message)
v998, v999 and v1000 keep coordinates.
Flag 1000 shows you that the hero belongs to the player sitting at the monitor.
HE-1 gives you the digging hero.
Example:
!?DG;
!!DG:G?y-1; [found Grail?]
!!FU&y-1=0:E; [exit if not found]
!!DG:R0; [no standard reaction]
!!VRz1:S^UltimateArtifact.wav^;
!!SN&1000:Pz1; [play Grail sound, if it's the player's hero]
!!IF&1000:M^Congratulations! After spending many hours digging here, your hero has uncovered A SKELETON!^; [show message]
!!HE-1:C2/56/1/1; [give 1 skeleton]
!$HL post-trigger, getting skills in !?HL trigger
Now you can get actual numbers of secondary skills in HL:S. You can still use value -2, but it will cause a skill to be generated again.
!$HL triggers after the dialog is closed and skills are enhanced.
!!HL:R gives you the number of secondary skill player chose in the dialog.
Example:
ZVSE
* this script lets heroes learn all 28 skills
!#VRv100:S0;
!?HL-1;
!!HE-1:S=8;
!!VRv100&1:S1;
!!HE-1&1:S7; [set number of shown skills to 7 to allow new skills]
!!HL&1:Sd/-2/-2; [generate skills again]
!$HL-1&v100<>0; [if we altered the number of shown skills]
!!VRv100:S0;
!!HE-1:S8; [restore the number of shown skills]
New HE:Y syntax: HE:Y$1/$2/$3, HE:Y0/0/0/3.
HE:Y now supports all syntax variations, so 4th parameter is usually unneeded.
Examples:
!!HE-1:Yv1/v2/v3 - set curse.
!!HE-1:Yv1/dv2/dv3 - add/sub curse.
!!HE-1:Yv1/0/0 - delete curse.
!!HE-1:Yv1/?v2/?v3 - get curse.
The only case when it's needed is unmentioned in Help:
HE:Y0/0/0/3 - remove all curses/blessings from the hero.
HE:Y2 was totally broken.
Here's how it works now. The syntax in ERM Help is wrong. Slot number is passed as second parameter ("power"). If it's -1, the slot is chosen randomly.
Here's the list of slot lock indexes (it's not the same as format AP):
0 head
1 shoulders
2 neck
3 right hand
4 left hand
5 torso
6 rings
7 feet
8 misc. slots
9 ballista (war machine 1)
10 ammo cart (war machine 2)
11 first aid tent (war machine 3)
12 catapult
13 spell book
HE:A5/$1/$2/?3/?4 - control artifact locks.
$1 is the lock slot (see "HE:Y2 was totally broken" for list of slots).
$2 is the number of locks in the locks slot.
(?3 and ?4 are optional)
?3 returnes the number of free artifact slots for the lock slot ($2 sholdn't exceed ?3).
?4 returnes the total number of artifact slots for the lock slot.
!?AI - triggered when AI gets weight of a map square
!!AI:W$ is the weight.
!!AI:W$/1 is the base weight, that was before ERM triggers changed it
!!AI:M$ is the number of movement points needed to reach the square (modified by in-game function and triggers).
!!AI:M$/1 is the number of movement points needed to reach the square, not modified by the in-game function.
v998, v999, v1000 keep coordinates of the square.
HE-1 is the hero for which the value is calculated.
Example:
!?AI&v998=42/v999=2/v1000=0; [object at 42/2/0]
!!AI:M?v1; [get distance to object in movement points]
!!AI&v1>500:W1000000; [this is the ultimate goal of every AI hero that stands further than 5 squares from it]
[however, note that the object will be ignored if it's beyond AI thinking radius]
Here are examples of standard weights:
Stables:
If it gives more movement points than the hero spends to get to it, the weight is 10000.
Otherwise, the weight is 50 + (importance of cavaliers upgrade).
Keymaster's Tent:
5000, if it's needed.
Objects that give moral or luck:
Weight is 0 if the hero can't reach the square at this turn.
Weight is usually proportional to army strength (total AI value of army).
For morale - if all stacks are undead, the weight is 0.
Objects that give a resource:
(resource count)*(resource importance for the owner)
Fountain of Youth (it gives +200 movement and +1 morale):
If it's closer than 200 movement points, the weight is 10000.
Otherwise, the weight is the usual weight of moral enhancement, AI:M$ is decreased by 200 (so, it doesn't match AI:M$/1 even without any triggers).
Shipyard:
1000, if it's needed.
Weight of guarded objects depends on bonus and comparsion of hero's army and defending army.
Mine:
(2 or 3)*(resource count per day)*(resource importance for the owner) - (guards penalty to weight)
"2 or 3" is 2 if it's a neutral mine and 3 if the mine belongs to other player (even an ally! This is probably a bug).
[+] New better GOTO. !!la, !!go in trigger.
This GOTO is preferrable. There may be 50 labels (0...49).
Use !!la0:; to !!la49:; to set a label.
Use !!go0:; to !!go49:; to go to a label.
Examples:
1)
!?FU255;
!!la0:; [label 0]
(...)
!!la1:; [label 1]
(...)
!!go0&1:; [go to label 0]
!!go1&2:; [go to label 1]
2)
A single 'for' loop:
!?FU255;
!!VRy1:S0;
!!la0:; [label 0]
!!if&y1<100:;
(...)
!!VRy1:+1;
!!go0:; [goto label 0]
!!en:;
This is equivalent to while y1<100 do { (...) y1 = y1 + 1; }
You can also make one loop inside another and anything you could do with regular DO, but much faster and without a need for a free function number.
[!] For help: Additions to "List of all buildings" in CA.
20 Shipyard with a ship in it
22 Also: Decorations, always present (8).
23 Also: Decorations. For Village hall (1, 4, 8) or always present (0, 7).
27 Decorations. For Town Hall (1, 4, 8) or always present (6).
28 Decorations for City Hall (1, 4, 8)
29 Decorations for Capitol (1, 4, 8)