Starcraft - AO iscript mechanics at a glance, part 1

Post Reply
User avatar
IskatuMesk
Xel'naga World Shaper
Xel'naga World Shaper
Posts: 8332
Joined: Sat Feb 07, 2009 1:40 pm
Location: M͈̙̞͍͞ͅE̹H̨͇̰͈͕͇̫Ì̩̳CO̼̩̤͖͘ జ్ఞ‌ా
Contact:

Starcraft - AO iscript mechanics at a glance, part 1

Post by IskatuMesk »

This is part 1 of a series of documents that will cover some of the things I did in AO. I will provide scripts and descriptions of what the scripts do. This is a part of my effort to get some advanced iscripting knowledge out there before it retires along with me.

1.1 - The Heretic Wizard

What it does -

The Heretic Wizard is a unit that teleports to move. Since actual teleportation is not possible, he fakes it by vanishing from sight, and then moving a distance, and then reappearing. This has some limitations, such as the unit still being selectable through teleportation, and the fact it can't teleport over obstacles like rivers. However, it still requires quite a unique effect.

How it works -

Forcing the unit to use the correct animation when re-appearing was a bit of a pain because of how starcraft handles to-idle on walking. When the unit went to attack, it would either become locked in a specific state and never attack, or become permanently invisible until moved again. To correct this, I initially forced most of the code through nobreak sequences, but in some instances starcraft will still actually break these, especially if they have to do with movement (never nobreak a full walking sequence). nobreak on these walk sequences caused a lot of bugs so I screwed them altogether and came up with a more simpler method, taking advantage of the walk-to-idle and sprinkled rmgraphicend commands everywhere.

It seems simple but it's easy to go wrong with.

The Code -

Code: Select all

# ----------------------------------------------------------------------------- #
# This is a decompile of the iscript.bin file 'data\scripts\iscript.bin'
# created on: Fri Nov 16 13:35:47 2007
# ----------------------------------------------------------------------------- #

# ----------------------------------------------------------------------------- #
# This header is used by images.dat entries:
# 013 MatureChrysalis (zerg\MatureChrysalis.grp)
.headerstart
IsId           	47
Type           	26
Init           	MatureChrysalisInit
Death          	MatureChrysalisDeath
GndAttkInit    	MatureChrysalisGndAttkInit
AirAttkInit    	MatureChrysalisGndAttkInit
SpAbility1     	[NONE]
GndAttkRpt     	MatureChrysalisGndAttkInit
AirAttkRpt     	MatureChrysalisGndAttkInit
SpAbility2     	MatureChrysalisSpAbility2
GndAttkToIdle  	MatureChrysalisGndAttkToIdle
AirAttkToIdle  	MatureChrysalisGndAttkToIdle
SpAbility3     	[NONE]
Walking        	MatureChrysalisWalking
Other          	MatureChrysalisWalkToIdle
BurrowInit     	[NONE]
ConstrctHarvst 	MatureChrysalisConstrctHarvst
IsWorking      	[NONE]
Landing        	[NONE]
LiftOff        	[NONE]
Unknown18      	[NONE]
Unknown19      	[NONE]
Unknown20      	[NONE]
Unknown21      	[NONE]
Unknown22      	[NONE]
Unknown23      	[NONE]
Unknown24      	[NONE]
Burrow         	MatureChrysalisBurrow
UnBurrow       	MatureChrysalisUnBurrow
Unknown27      	[NONE]
.headerend
# ----------------------------------------------------------------------------- #

MatureChrysalisInit:
	#imgul09        	14 0 3	# MatureChrysalisShad (zerg\MatureChrysalis.grp)
	playfram       	0x00	# frame set 0
	waitrand       	1 4
MatureChrysalisGndAttkToIdle:
	playfram       	0xaa	# frame set 0
	wait           	1
	playfram       	0xbb	# frame set 1
	wait           	1
	playfram       	0xcc	# frame set 2
	wait           	1
	playfram       	0xdd	# frame set 1
	wait           	1
	playfram       	0xee	# frame set 0
	wait           	1
	playfram       	0xff	# frame set 1
	wait           	1
	playfram       	0x110	# frame set 2
	wait           	1
	playfram       	0x121	# frame set 1
	wait           	1
	playfram       	0x132	# frame set 2
	wait           	1
	playfram       	0x143	# frame set 1
	wait           	1
	goto           	MatureChrysalisGndAttkToIdle

MatureChrysalisWalkToIdle:
	#nobrkcodestart
	tmprmgraphicend
	playfram       	0x1dc	# frame set 0
	wait           	1
	playfram       	0x1cb	# frame set 1
	wait           	1
	playfram       	0x1ba	# frame set 2
	wait           	1
	playfram       	0x1a9	# frame set 3
	wait           	1
	playfram       	0x198	# frame set 4
	wait           	1
	playfram       	0x187	# frame set 5
	wait           	1
	playfram       	0x176	# frame set 6
	wait           	1
	playfram       	0x165	# frame set 7
	wait		1
	playfram       	0x154	# frame set 4
	wait		1
	#nobrkcodeend
	ignorerest
	goto           	MatureChrysalisGndAttkToIdle

MatureChrysalisDeath:
	playsnd        	815	# Zerg\MatureChrysalis\ZDeDth00.WAV
	imgol08        	214 0 0
	playframno     	0
	wait           	1
	end            	

MatureChrysalisGndAttkInit:
	#playframno	0
	tmprmgraphicend
	playfram       	0x00	# frame set 0
	wait           	1
	playfram       	0x11	# frame set 1
	wait           	1
	playfram       	0x22	# frame set 2
	wait		1
	playfram       	0x33	# frame set 0
	wait           	1
	playfram       	0x44	# frame set 1
	playsnd        	110	# Bullet\zdeAtt00.wav
	attack25       	1
	wait           	4
	playfram       	0x55	# frame set 2
	wait           	1
	playfram       	0x66	# frame set 0
	wait           	1
	playfram       	0x77	# frame set 1
	wait           	1
	playfram       	0x88	# frame set 2
	wait		1
	playfram       	0x99	# frame set 0
	wait           	1
	gotorepeatattk 	
	goto           	MatureChrysalisGndAttkToIdle

MatureChrysalisSpAbility2:
	playfram       	0x00	# frame set 0
	nobrkcodestart 	
	wait           	1
	playfram       	0x11	# frame set 1
	wait           	1
	playfram       	0x22	# frame set 2
	wait		1
	playfram       	0x33	# frame set 0
	wait           	1
	playfram       	0x44	# frame set 1
	playsnd        	110	# Bullet\zdeAtt00.wav
	castspell
	wait           	4
	playfram       	0x55	# frame set 2
	wait           	1
	playfram       	0x66	# frame set 0
	wait           	1
	playfram       	0x77	# frame set 1
	wait           	1
	playfram       	0x88	# frame set 2
	wait		1
	playfram       	0x99	# frame set 0
	wait           	1
	nobrkcodeend   	
	gotorepeatattk 	
	sigorder       	2
	goto           	MatureChrysalisGndAttkToIdle

MatureChrysalisWalking:
	#nobrkcodestart
	playfram       	0x154	# frame set 0
	wait           	1
	playfram       	0x165	# frame set 1
	wait           	1
	playfram       	0x176	# frame set 2
	wait           	1
	playfram       	0x187	# frame set 3
	wait           	1
	playfram       	0x198	# frame set 4
	wait           	1
	playfram       	0x1a9	# frame set 5
	wait           	1
	playfram       	0x1ba	# frame set 6
	wait           	1
	playfram       	0x1cb	# frame set 7
	wait		1
	playfram       	0x1dc	# frame set 4
	wait		1
	tmprmgraphicstart
	move		60
	wait		1
	move		60
	wait		1
	move		60
	wait		1
	move		60
	wait		1
	move		60
	wait		1
	move		60
	wait		1
	move		60
	wait		1
	move		60
	wait		1
	move		60
	tmprmgraphicend
	playfram       	0x1dc	# frame set 0
	wait           	1
	playfram       	0x1cb	# frame set 1
	wait           	1
	playfram       	0x1ba	# frame set 2
	wait           	1
	playfram       	0x1a9	# frame set 3
	wait           	1
	playfram       	0x198	# frame set 4
	wait           	1
	playfram       	0x187	# frame set 5
	wait           	1
	playfram       	0x176	# frame set 6
	wait           	1
	playfram       	0x165	# frame set 7
	wait		1
	playfram       	0x154	# frame set 4
	wait		1
	#nobrkcodeend
	goto           	MatureChrysalisWalking

MatureChrysalisConstrctHarvst:
	playfram       	0x110	# frame set 16
	goto           	local00

local00:
	wait           	125
	goto           	local00

MatureChrysalisBurrow:
	imgol08        	423 0 0	# BurrowingDust (thingy\bDust.grp)
	playfram       	0xcc	# frame set 12
	wait           	1
	playfram       	0xdd	# frame set 13
	wait           	1
	playfram       	0xee	# frame set 14
	wait           	1
	playfram       	0xff	# frame set 15
	wait           	1
	playfram       	0x110	# frame set 16
	wait           	1
	sigorder       	4
	goto           	local00

MatureChrysalisUnBurrow:
	waitrand       	1 5
	imgul09        	423 0 0	# BurrowingDust (thingy\bDust.grp)
	playfram       	0xff	# frame set 15
	wait           	1
	playfram       	0xee	# frame set 14
	wait           	1
	playfram       	0xdd	# frame set 13
	wait           	1
	playfram       	0xcc	# frame set 12
	wait           	1
	sigorder       	4
	goto           	MatureChrysalisGndAttkToIdle


1.2 - The Madness Titan

What it does -

The Madness Titan is a tier6 unit with 4 different attacks. This script is not complete, however; he needs to use attack type 2 for his air attack.

This unit randomizes between 4 types of attacks; his standard attack, a berserk which "increases his attack speed" (but actually fakes it), and two variants of the pit lord fire nova. One waves back and forth, the other will come from behind and focus on the front and molest units in front of the unit.

How it works -

This is a simple randomized sequence taken to the next level of functionality with custom sequencing and pretty explosions. However, if the target dies while the unit is channeling the fire novas, it will discontinue firing the weapon but continue animating until the sequence is over. This is a limitation of starcraft. Sometimes if the unit re-acquires a target it will resume firing but not reset the sequence. This is most noticeable with the Lord of Terror.

The Code -

http://www.staff.samods.org/iskatumesk/ ... seeker.txt

1.3 - The Touch of Anguish

What it does -

This is a unit that casts a projectile that will create a perpetual explosion for roughly half a minute, dealing damage to any enemy who steps in it. But what's most important about this unit is that its grp is not centered correctly. Because of how the source images are arranged, the attack animations for this unit will move off-center from the other frames. These are off center from a relative viewpoint, so to compensate for this, I needed to use the arc jump command used by the Sunken Colony to determine the tentacle's position. The result is the lack of a shadow because I am too lazy to fix it, and a correct attack animation that doesn't move around.

How it works -

With DoA's help, he provided this diagram and explanation of how the arc command works.
Image

Ok. trgtarccondjmp works like this

trgtarccondjmp %arccenter %arclen %label

the arc center is the angle that corresponds to the middle of the arc, and the arc length is the angle both positive and negative to check. As an example, I've illustrated the sunken colony's arcs -

trgtarccondjmp 74 42 SunkenColonyLocal01
trgtarccondjmp 159 42 SunkenColonyLocal02

The 74 is the center of the blue arc, and the endpoints are both 42 away from it. Same goes for the 159.

Remember, angles go from 0x00 to 0xff, or 0-255, not to 360.
I used this command to syncronize the unit. So, if you have a unit that is off-center at some points, you can fix it without dicking with the grp. It just takes some patience and lots of testing.

The Code

Code: Select all

# ----------------------------------------------------------------------------- #
# This is a decompile of the iscript.bin file 'data\scripts\iscript.bin'
# created on: Sun Dec 02 23:16:11 2007
# ----------------------------------------------------------------------------- #

# ----------------------------------------------------------------------------- #
# This header is used by images.dat entries:
# 095 HydraliskDen (zerg\Snakey.grp)
.headerstart
IsId           	57
Type           	26
Init           	HydraliskDenInit
Death          	HydraliskDenDeath
GndAttkInit    	HydraliskDenGndAttkInit
AirAttkInit    	HydraliskDenGndAttkInit
SpAbility1     	[NONE]
GndAttkRpt     	HydraliskDenGndAttkInit
AirAttkRpt     	HydraliskDenGndAttkInit
SpAbility2     	[NONE]
GndAttkToIdle  	HydraliskDenGndAttkToIdle
AirAttkToIdle  	HydraliskDenGndAttkToIdle
SpAbility3     	[NONE]
Walking        	HydraliskDenWalking
Other          	HydraliskDenGndAttkToIdle
BurrowInit     	[NONE]
ConstrctHarvst 	HydraliskDenConstrctHarvst
IsWorking      	[NONE]
Landing        	[NONE]
LiftOff        	[NONE]
Unknown18      	[NONE]
Unknown19      	[NONE]
Unknown20      	[NONE]
Unknown21      	[NONE]
Unknown22      	[NONE]
Unknown23      	[NONE]
Unknown24      	[NONE]
Burrow         	HydraliskDenBurrow
UnBurrow       	HydraliskDenUnBurrow
Unknown27      	[NONE]
.headerend
# ----------------------------------------------------------------------------- #
HydraliskDenInit:
	#imgul09          	96 254 254	# HydraliskDenShad (zerg\zzeShad.grp)
HydraliskDenGndAttkToIdle:
	__02	0
	playfram       	0x00	# frame set 8
	wait           	2
	playfram       	0x11	# frame set 9
	wait           	2
	playfram       	0x22	# frame set 10
	wait           	2
	playfram       	0x33	# frame set 11
	wait           	2
	playfram       	0x44	# frame set 12
	wait           	2
	playfram       	0x55	# frame set 13
	wait           	2
	playfram       	0x77	# frame set 14
	wait           	2
	playfram       	0x88	# frame set 15
	wait           	2
	playfram       	0x99	# frame set 15
	wait           	2
	playfram       	0xaa	# frame set 15
	wait           	2
	playfram       	0xbb	# frame set 15
	wait           	2
	goto           	HydraliskDenGndAttkToIdle

HydraliskDenDeath:
	playsnd        	194	# Zerg\HydraliskDen\ZZeDth00.WAV
	playframno    	0
	imgol08        	333 0 0	# TerranBuildingExplosionmedium (thingy\tBangL.grp)
	#lowsprul       	160 0 0	# HydraliskDenDeath (zerg\zzeDeath.grp)
	wait           	1
	end            	

HydraliskDenGndAttkInit:
	__02		0
	trgtarccondjmp 0x60 18 pewpewsoutheast
	trgtarccondjmp 0xa0 18 pewpewsouthwest
attackreturn:
	nobrkcodestart 	
	playsnd        	664	# Bullet\ZGuFir00.wav
	playfram       	0x198	# frame set 20
	wait           	1
	playfram       	0x1a9	# frame set 20
	wait           	1
	playfram       	0x1ba	# frame set 20
	wait           	1
	playfram       	0x1cb	# frame set 20
	wait           	1
	playfram       	0x1dc	# frame set 16
	wait           	1
	playfram       	0x1ed	# frame set 17
	wait           	1
	playfram       	0x1fe	# frame set 18
	wait           	1
	playfram       	0x20f	# frame set 19
	wait           	1
	playfram       	0x220	# frame set 20
	wait           	1
	playfram       	0x231	# frame set 20
	wait           	1
	playfram       	0x243	# frame set 20
	wait           	1
	playfram       	0x253	# frame set 20
	wait           	1
	attack25	1
	playfram       	0x264	# frame set 20
	wait           	1
	playfram       	0x275	# frame set 20
	wait           	1
	playfram       	0x286	# frame set 20
	wait           	1
	playfram       	0x297	# frame set 20
	wait           	1
	#playfram       	0x2a8	# frame set 20
	#wait           	1
	#playfram       	0x2b9	# frame set 20
	#wait           	1
	nobrkcodeend   		
	gotorepeatattk 	
	goto           	HydraliskDenGndAttkToIdle

pewpewsoutheast:
__02		16
goto attackreturn

pewpewsouthwest:
__02		-16
goto attackreturn


HydraliskDenWalking:
	__02		0
	move           	5
	wait           	1
	playfram       	0xcc	# frame set 16
	move           	5
	wait           	1
	playfram       	0xdd	# frame set 17
	move           	5
	wait           	1
	playfram       	0xee	# frame set 18
	move            5
	wait           	1
	playfram       	0xff	# frame set 19
	move            5
	wait           	1
	playfram       	0x110	# frame set 20
	move           	5
	wait           	1
	playfram       	0x121	# frame set 20
	move           	5
	wait           	1
	playfram       	0x132	# frame set 20
	move           	5
	wait           	1
	playfram       	0x143	# frame set 20
	move           	5
	wait           	1
	playfram       	0x154	# frame set 20
	move           	5
	wait           	1
	playfram       	0x165	# frame set 20
	move           	5
	wait           	1
	playfram       	0x176	# frame set 20
	move           	5
	wait           	1
	playfram       	0x187	# frame set 20
	move           	5
	wait           	1
	goto           	HydraliskDenWalking

HydraliskDenConstrctHarvst:
	playfram       	0x110	# frame set 16
	goto           	HydraliskDenGndAttkToIdle

HydraliskDenBurrow:
	imgol08          	423 0 0	# BurrowingDust (thingy\bDust.grp)
	playfram       	0xcc	# frame set 12
	wait           	1
	playfram       	0xdd	# frame set 13
	wait           	1
	playfram       	0xee	# frame set 14
	wait           	1
	playfram       	0xff	# frame set 15
	wait           	1
	playfram       	0x110	# frame set 16
	wait           	1
	sigorder       	4
	goto           	HydraliskDenGndAttkToIdle

HydraliskDenUnBurrow:
	waitrand       	1 5
	imgul09          	423 0 0	# BurrowingDust (thingy\bDust.grp)
	playfram       	0xff	# frame set 15
	wait           	1
	playfram       	0xee	# frame set 14
	wait           	1
	playfram       	0xdd	# frame set 13
	wait           	1
	playfram       	0xcc	# frame set 12
	wait           	1
	sigorder       	4
	goto           	HydraliskDenGndAttkToIdle

Last edited by Anonymous on Fri Dec 07, 2007 12:14 am, edited 1 time in total.
Gameproc
Though we stand alone, stand we shall.
User avatar
ShadowFlare
Terran Science Facility Guinea Pig
Terran Science Facility Guinea Pig
Posts: 213
Joined: Thu Jul 19, 2007 11:12 pm
Contact:

Re: Starcraft - AO iscript mechanics at a glance, part 1

Post by ShadowFlare »

Doctor Doack wrote:I used this command to syncronize the unit. So, if you have a unit that is off-center at some points, you can fix it without dicking with the grp. It just takes some patience and lots of testing.
For those who do want to fix the centering in the grp, I'd suggest modifying it with GRPEdit.  With that program you can modify the overall size of the grp and the positions of individual frames in the grp.  I haven't tried out that feature myself, though.


btw,
Image
You do not have the required permissions to view the files attached to this post.
Don't point that camera at me!
Image
User avatar
IskatuMesk
Xel'naga World Shaper
Xel'naga World Shaper
Posts: 8332
Joined: Sat Feb 07, 2009 1:40 pm
Location: M͈̙̞͍͞ͅE̹H̨͇̰͈͕͇̫Ì̩̳CO̼̩̤͖͘ జ్ఞ‌ా
Contact:

Re: Starcraft - AO iscript mechanics at a glance, part 1

Post by IskatuMesk »

ShadowFlare wrote: btw,
Image
You're catching on pretty quick!

Also I have 42 pie.
Gameproc
Though we stand alone, stand we shall.
Post Reply