UnclePunch
Smash Ace
- Joined
- Nov 9, 2014
- Messages
- 673
I've always felt Melee's subaction syntax could use an if/else event. It's possible to make some pretty powerful character edits when combined with Achilles' Character Data Modification code and my Enter Action State code.
This code lets you skip parts of the subaction based on player data (which can be found here). Things you can base if statements on are facing direction (0x2C), horizontal or vertical velocity (0x80 and 0x84 respectively), costume ID (0x619), analog stick X/Y (0x620 and 0x624), buttons held (0x65C), percentage (0x1830), etc.
Event Format:
E9ABXXXX YYYYYYYY ZZZZZZZZ 00000000
E9 = Event ID
A = data size
0 = byte [8-bit]
1 = half word [16-bit]
2 = word [32-bit]
3 = float [32-bit]
B = compare operation
0 = if equal
1 = if not equal
2 = if greater
3 = if greater or equal
4 = if less than
5 = if less than or equal
XXXX = character data offset
YYYYYYYY = value to compare data with
ZZZZZZZZ = length of code to skip if the check fails (IN HEX)
00000000 = nothing, just so crazy hand doesn't have a cow, man
________________________________________________________
This code lets you skip parts of the subaction based on player data (which can be found here). Things you can base if statements on are facing direction (0x2C), horizontal or vertical velocity (0x80 and 0x84 respectively), costume ID (0x619), analog stick X/Y (0x620 and 0x624), buttons held (0x65C), percentage (0x1830), etc.
Event Format:
E9ABXXXX YYYYYYYY ZZZZZZZZ 00000000
E9 = Event ID
A = data size
0 = byte [8-bit]
1 = half word [16-bit]
2 = word [32-bit]
3 = float [32-bit]
B = compare operation
0 = if equal
1 = if not equal
2 = if greater
3 = if greater or equal
4 = if less than
5 = if less than or equal
XXXX = character data offset
YYYYYYYY = value to compare data with
ZZZZZZZZ = length of code to skip if the check fails (IN HEX)
00000000 = nothing, just so crazy hand doesn't have a cow, man
________________________________________________________
Code:
$If-Statement Subaction Event v1.0 [UnclePunch]
C2073118 0000003B
80A30008 88A50000
2C0500E8 418201C4
9421FFBC BE810008
7C0802A6 90010040
7C9F2378 83DF0008
7C7C1B78 83A3002C
A09E0002 887E0001
54630636 2C030000
4182001C 2C030001
41820020 2C030002
41820024 2C030003
41820028 7C84E8AE
88BE0007 4800002C
7C84EA2E A0BE0006
48000020 7C84E82E
80BE0004 48000014
7C84EA14 C03E0004
C0440000 48000084
887E0001 5463073E
2C030000 4182002C
2C030001 41820030
2C030002 41820034
2C030003 41820038
2C030004 4182003C
2C030005 41820040
7C042800 418200C4
480000DC 7C042800
408200B8 480000D0
7C042800 418100AC
480000C4 7C042800
408000A0 480000B8
7C042800 41800094
480000AC 7C042800
40810088 480000A0
887E0001 5463073E
2C030000 4182002C
2C030001 41820030
2C030002 41820034
2C030003 41820038
2C030004 4182003C
2C030005 41820040
FC011040 41820044
4800005C FC011040
40820038 48000050
FC011040 4181002C
48000044 FC011040
40800020 48000038
FC011040 41800014
4800002C FC011040
40810008 48000020
387E0010 907F0008
80010040 7C0803A6
BA810008 38210044
4E800020 807E0008
38630010 7C63F214
907F0008 80010040
7C0803A6 BA810008
38210044 4E800020
7C0802A6 00000000
Code:
Inject @ 80073118
#GET SUBACTION
lwz r5,0x8(r3)
#GET OPCODE
lbz r5,0x0(r5)
cmpwi r5,0xE8
beq exit
######################
/*
Event Format:
E9ABXXXX YYYYYYYY ZZZZZZZZ 00000000
A = data size
0 = byte [8-bit]
1 = half word [16-bit]
2 = word [32-bit]
3 = float [32-bit]
B = compare operation
0 = if equal
1 = if not equal
2 = if greater
3 = if greater or equal
4 = if less than
5 = if less than or equal
XXXX = character data offset
YYYYYYYY = value to compare data with
ZZZZZZZZ = length of code to skip if the check fails (IN HEX)
00000000 = nothing, just so crazy hand doesn't have a cow man
*/
#INIT FUNCTION
backup
mr r31,r4
lwz r30,0x8(r31)
mr r28,r3
lwz r29,0x2c(r3)
#GET CHAR DATA OFFSET
lhz r4,0x2(r30)
#GET DATA SIZE
lbz r3,0x1(r30)
rlwinm r3,r3,0,24,27
cmpwi r3,0x0
beq loadByte
cmpwi r3,0x1
beq loadHalf
cmpwi r3,0x2
beq loadWord
cmpwi r3,0x3
beq loadFloat
loadByte:
lbzx r4,r4,r29
lbz r5,0x7(r30)
b compare
loadHalf:
lhzx r4,r4,r29
lhz r5,0x6(r30)
b compare
loadWord:
lwzx r4,r4,r29
lwz r5,0x4(r30)
b compare
loadFloat:
add r4,r4,r29
lfs f1,0x4(r30)
lfs f2,0x0(r4)
b floatCompare
compare:
#GET COMPARE OPERATION
lbz r3,0x1(r30)
rlwinm r3,r3,0,28,31
cmpwi r3,0x0
beq compareEqual
cmpwi r3,0x1
beq compareNotEqual
cmpwi r3,0x2
beq compareGreater
cmpwi r3,0x3
beq compareGreaterEqual
cmpwi r3,0x4
beq compareLessThan
cmpwi r3,0x5
beq compareLessThanEqual
compareEqual:
cmpw r4,r5
beq Success
b Failed
compareNotEqual:
cmpw r4,r5
bne Success
b Failed
compareGreater:
cmpw r4,r5
bgt Success
b Failed
compareGreaterEqual:
cmpw r4,r5
bge Success
b Failed
compareLessThan:
cmpw r4,r5
blt Success
b Failed
compareLessThanEqual:
cmpw r4,r5
ble Success
b Failed
floatCompare:
#GET COMPARE OPERATION
lbz r3,0x1(r30)
rlwinm r3,r3,0,28,31
cmpwi r3,0x0
beq floatCompareEqual
cmpwi r3,0x1
beq floatCompareNotEqual
cmpwi r3,0x2
beq floatCompareGreater
cmpwi r3,0x3
beq floatCompareGreaterEqual
cmpwi r3,0x4
beq floatCompareLessThan
cmpwi r3,0x5
beq floatCompareLessThanEqual
floatCompareEqual:
fcmpo cr0,f1,f2
beq Success
b Failed
floatCompareNotEqual:
fcmpo cr0,f1,f2
bne Success
b Failed
floatCompareGreater:
fcmpo cr0,f1,f2
bgt Success
b Failed
floatCompareGreaterEqual:
fcmpo cr0,f1,f2
bge Success
b Failed
floatCompareLessThan:
fcmpo cr0,f1,f2
blt Success
b Failed
floatCompareLessThanEqual:
fcmpo cr0,f1,f2
ble Success
b Failed
Success:
addi r3,r30,0x10 #if statement length
stw r3,0x8(r31)
restore
blr
Failed:
lwz r3,0x8(r30) #code to run length
addi r3,r3,0x10 #if statement length
add r3,r3,r30 #increment sub pointer
stw r3,0x8(r31)
restore
blr
######################
exit:
mflr r0