Hey, just wanted to provide some technical info and usage tips for these codes. First off for independent subroutines, the currently available specials (last byte of the basic) are set to the max available specials whenever the fighter becomes grounded (grabs a ledge or physically makes contact with the ground and are decremented each time the corresponding special is used. When a given group of bits becomes 0 and it has a max number of specials set that special cannot be activated. This has a couple of important things to note: 1) if you have a special that changes to itself (specifically to the first 11X action) for some reason it will consume multiple uses of the special and potentially fail to work properly, 2) if the user becomes grounded during the special they will recover all uses (many DO NOT become grounded even when they touch the ground), and 3) if the user uses the special and remains grounded for the entire move the special's uses will be consumed and will not refresh until the user jumps or lands. The specials also do not refresh on taking damage, as this is not always intended behavior and refreshing on taking damage is fairly easy to implement. Create a subroutine setting LA-Basic[71] to the value of your choice and copy past that subroutine call to wait1, squat, swim, and if you want refresh on damage all of the damage and captureDamage subactions.
For the independent subroutines code threads 5-8 are generally safe to use (I think, 7 and 8 are safe on every fighter as far as I can tell). Thread 0 is the action thread, threads 1-4 are the subaction threads (main, gfx, sfx, and other tabs in PSA), thread 9 is the default concurrent infinite loop thread, thread A is the default independent subroutine thread. Articles and other non-fighter entities that run PSA commands do not necessarily have the same number of threads as fighters, and may not have any free threads. Also, the specific thread number does matter for some commands, flash overlay effects for instance behave differently when called from thread A. In terms of how to use independent subroutines, there are a couple of very nice general purpose uses. The first is for generating flashing effects for fully charged moves. The way that you'd implement one of these is something like:
if flashing condition
if thread is null: A
independent subroutine: (Thread A): @flashing subroutine
end if
end if
With the flashing subroutine of the form (this is actually how flashing effects are implemented in Brawl)
Flash Overlay Effect: Color 1
Sync Wait: 1 frame
Change Flash Overlay Color: Transition Time=4 Color 2
Sync Wait: 4 frames
Terminate Flash Effect
Synch Wait: 1 frame
goto: @flashing subroutine
The second general purpose method for independent subroutines is in conjunction with limited specials to create cooldowns for specials. This is implemented using two different threads, one of which runs once per character frame and one which runs once per actual frame. So if you wanted to give neutral special a 3 second cooldown starting from when it's activated you could put the following code in neutral special:
Float variable set: LA-Float[255] = 180
Then in an independent subroutine in thread 8 you can run this code:
if compare: LA-Float[255] > 0
Float variable subtract: LA-Float[255] - 1
End if
Sync wait: 1 frame
Goto start
And in thread 7 run this code:
If compare: LA-Float[255] > 0
Basic variable set: LA-Basic[71] = 27180100
else
Basic variable set: LA-Basic[71] = 0
end if
sync wait: .1 frames
goto start
This code turns on limited specials and sets neutral special to be limited and have no remaining uses whenever LA-Float[255] is non-zero. Because of how action changes are checked this very easily prevents neutral special from ever being activated when you don't want it to be.
The final comment I'd like to make is to mention that attribute modification makes no attempts to limit the user to sane inputs. If you run Attribute Range Set: IC-Basic[10,000,000] = 0 the code will gladly attempt to 0 out the 5 kilobytes of memory you told it to zero out, probably crashing your game. At the same time, if you happen to know where some relevant piece of information occurs relative to the fighter's attribute table you may be able to use attribute modification to write to that value. Also, I suspect that the way attribute modification is written may remove certain safeguards on bad PSA commands, specifically 12 type commands with a subtype of 14-1F (commands which do not exist) may attempt to branch into random memory crashing the game. This is very easily avoidable though, since you shouldn't be using non-existent commands in the first place.
For the independent subroutines code threads 5-8 are generally safe to use (I think, 7 and 8 are safe on every fighter as far as I can tell). Thread 0 is the action thread, threads 1-4 are the subaction threads (main, gfx, sfx, and other tabs in PSA), thread 9 is the default concurrent infinite loop thread, thread A is the default independent subroutine thread. Articles and other non-fighter entities that run PSA commands do not necessarily have the same number of threads as fighters, and may not have any free threads. Also, the specific thread number does matter for some commands, flash overlay effects for instance behave differently when called from thread A. In terms of how to use independent subroutines, there are a couple of very nice general purpose uses. The first is for generating flashing effects for fully charged moves. The way that you'd implement one of these is something like:
if flashing condition
if thread is null: A
independent subroutine: (Thread A): @flashing subroutine
end if
end if
With the flashing subroutine of the form (this is actually how flashing effects are implemented in Brawl)
Flash Overlay Effect: Color 1
Sync Wait: 1 frame
Change Flash Overlay Color: Transition Time=4 Color 2
Sync Wait: 4 frames
Terminate Flash Effect
Synch Wait: 1 frame
goto: @flashing subroutine
The second general purpose method for independent subroutines is in conjunction with limited specials to create cooldowns for specials. This is implemented using two different threads, one of which runs once per character frame and one which runs once per actual frame. So if you wanted to give neutral special a 3 second cooldown starting from when it's activated you could put the following code in neutral special:
Float variable set: LA-Float[255] = 180
Then in an independent subroutine in thread 8 you can run this code:
if compare: LA-Float[255] > 0
Float variable subtract: LA-Float[255] - 1
End if
Sync wait: 1 frame
Goto start
And in thread 7 run this code:
If compare: LA-Float[255] > 0
Basic variable set: LA-Basic[71] = 27180100
else
Basic variable set: LA-Basic[71] = 0
end if
sync wait: .1 frames
goto start
This code turns on limited specials and sets neutral special to be limited and have no remaining uses whenever LA-Float[255] is non-zero. Because of how action changes are checked this very easily prevents neutral special from ever being activated when you don't want it to be.
The final comment I'd like to make is to mention that attribute modification makes no attempts to limit the user to sane inputs. If you run Attribute Range Set: IC-Basic[10,000,000] = 0 the code will gladly attempt to 0 out the 5 kilobytes of memory you told it to zero out, probably crashing your game. At the same time, if you happen to know where some relevant piece of information occurs relative to the fighter's attribute table you may be able to use attribute modification to write to that value. Also, I suspect that the way attribute modification is written may remove certain safeguards on bad PSA commands, specifically 12 type commands with a subtype of 14-1F (commands which do not exist) may attempt to branch into random memory crashing the game. This is very easily avoidable though, since you shouldn't be using non-existent commands in the first place.
