-
Notifications
You must be signed in to change notification settings - Fork 2
EUD Tutorial: Extended Animations
There is a field called "Animation" in Orders.dat. It controls the animation that runs when a unit uses the order.
It only works for the spell-casting orders such as "Use Ability (Stasis Field)". Normally, it is set to "Cast Spell" (7).
Some spells don't use those orders, e.g. ScannerSweep, DefensiveMatrix and StimPacks. These spells can be given to any unit without worrying about castspell animations.
In fact, this value is not limited to regular animations (0-27). We can set the value to up to 255.
When the value is above the regular limit, its iscript will overflow the regular header and enter the unknown region, and play animation scripts normally impossible to reach.
Check here for decompiled code for those extended animations: https://ar3sgice.github.io/eudtools/Include/IceDC.html
Protip: you can press up and down arrows in the input field to comfortably go through codes.
But if the animation has no castspell command the unit won't cast the spell! What's the point of doing this!?
Incorrect. It still drains mana and enters spell cooldown, so if we detect the changes via CUnit we can let it trigger a spell.
Also sometimes there are animation codes that get lucky enough to run into a 0x27 castspell, albeit really rare.
Masked MemoryAddr(6704592, Set To, 1241513984, -16777216);
This changes Stasis Field order animation to 74.
Whenever an arbiter casts stasis field, the script adds an archon being and an archon swirl to the arbiter.
playfram 0x12 # frame set 1
wait 1
nobrkcodestart
wait 1
playfram 0x13 # frame set 1
wait 2
playfram 0x14 # frame set 1
wait 2
playfram 0x15 # frame set 1
wait 2
playfram 0x16 # frame set 1
wait 2
playfram 0x17 # frame set 1
wait 2
playfram 0x18 # frame set 1
wait 2
playfram 0x19 # frame set 1
wait 2
playfram 0x1a # frame set 1
wait 2
imgol 135 0 0
imgol 136 0 0
sigorder 4
nobrkcodeend
wait 2
playfram 0x00 # frame set 0
wait 1
playfram 0x01 # frame set 0
wait 1
playfram 0x02 # frame set 0
wait 1
playfram 0x03 # frame set 0
wait 1
playfram 0x04 # frame set 0
wait 1
playfram 0x05 # frame set 0
wait 1
playfram 0x06 # frame set 0
wait 1
playfram 0x07 # frame set 0
wait 1
playfram 0x08 # frame set 0
wait 1
playfram 0x09 # frame set 0
wait 1
playfram 0x08 # frame set 0
wait 1
playfram 0x07 # frame set 0
wait 1
playfram 0x06 # frame set 0
wait 1
playfram 0x05 # frame set 0
wait 1
playfram 0x04 # frame set 0
wait 1
playfram 0x03 # frame set 0
wait 1
playfram 0x02 # frame set 0
wait 1
playfram 0x01 # frame set 0
wait 1
goto 9826
The archon beings can use attacks together with the arbiter main image, doubling every attack with an archon beam.
If it casts another stasis field, another pair of archon being and swirl will be added.
SetDoodadState trigger is one of the cases Starcraft will try to play iscripts regardless of their existence.
Disable Doodad State plays Disable animation. Enable Doodad State plays Enable animation but it only works if it's already disabled.
However, this does not always lead to iscript 0, because the iscript headers are of variable length, and Disable (+0x38) often overflows into the actual script area.
For example, the iscript header for Marine is
53 43 50 45 // "SCPE"
0C 00 00 00 // 12 = 14 Animations
F8 70 // MarineInit
7F 71 // MarineDeath
F8 71 // MarineGndAttkInit
F8 71 // MarineGndAttkInit (Air)
00 00
05 72 // MarineGndAttkRpt
05 72 // MarineGndAttkRpt (Air)
00 00
2E 72 // MarineGndAttkToIdle
2E 72 // MarineGndAttkToIdle (Air)
00 00
B6 71 // MarineWalking
FD 70 // MarineWalkingToIdle
00 00
After this is the next header (MarineDeath)
53 43 50 45 // "SCPE"
01 00 00 00 // 1 = 2 Animations
84 71 // MarineDeathInit
20 79 // long01
Then the actual script
09 F0 00 00 00 // imgul 240 0 0
00 44 00 // playfram 0x44
06 3F 4B // waitrand 63 75
1E 19 24 71 // randcondjmp 25 MarineLocal00
1E // randcondjmp 128 MarineLocal01
80 0E // "Disable" animation overflows to here
71
07 00 71 // goto MarineLocal02
The "Disable" animation overflows into the actual script area, and points to 0x0E80. It decompiles like this:
EnsnareOverlayInit:
tmprmgraphicstart
waitrand 1 3
tmprmgraphicend
MarineLocal05:
playfram 0
wait 2
playfram 1
wait 2
playfram 2
wait 2
MarineDisabled:
playfram 3
waitrand 2 3
goto MarineLocal05
It jumps into the Ensnare scripts, which is why a marine turns around when it gets disabled.