I think I've finally worked the bugs out of Protean, and I'm 96% sure it'll work with no problem now. As promised here's the (Emerald BPEE) ASM for it, so hold on to your butts:
Code:
.align 2
.thumb
GetPokeTypes:
push {r0-r5}
ldr r1, .BattleData
ldr r0, .CurPokeIndex
ldrb r0, [r0]
mov r2, #0x58
mul r2, r0
add r1, #0x21
add r1, r2
ldrh r0, [r1]
mov r2, r0
lsr r0, #2
lsl r2, #24
lsr r2, #24
GetMoveType:
ldr r3, .CurMoveIndex
ldrh r3, [r3]
ldr r4, .MoveData
mov r5, #0xC
mul r5, r3
add r4, r5
add r4, #0x2
ldrb r4, [r4]
ChangePokeType:
cmp r0, r4
beq End
cmp r2, r4
beq End
lsl r4, #2
ldr r5, .TypeList1
add r5, r4
mov r0, r5
mov r2, #0x2
sub r1, #0x1
swi #0x0B
ldr r0, .TypeList1
ldr r1, .CheckForChange
mov r2, #0x1
swi #0x0B
ldr r0, .TypeList2
add r0, r4
ldr r1, .TypeBuffer
mov r2, #0x2
swi #0x0B
End:
pop {r0-r5}
bx lr
.align 2
.BattleData: .word 0x02024084
.CurPokeIndex: .word 0x0202420B
.CurMoveIndex: .word 0x020241EA
.MoveData: [B].word 0x[addressmovedata][/B]
.CheckForChange: .word 0x02024200
.TypeBuffer: .word 0x02022F58
.TypeList1: [B].word 0x[address1][/B]
.TypeList2: [B].word 0x[address2][/B]
For TypeList1, copy this hex somewhere and use its start as address1
In bold your ability number:
Code:
[B]6A[/B] 00 00 00 [B]6A[/B] 01 01 00 [B]6A[/B] 02 02 00 [B]6A[/B] 03 03 00 [B]6A[/B] 04 04 00 [B]6A[/B] 05 05 00 [B]6A[/B] 06 06 00 [B]6A[/B] 07 07 00 [B]6A[/B] 08 08 00 [B]6A[/B] 09 09 00 [B]6A[/B] 0A 0A 00 [B]6A[/B] 0B 0B 00 [B]6A[/B] 0C 0C 00 [B]6A[/B] 0D 0D 00 [B]6A[/B] 0E 0E 00 [B]6A[/B] 0F 0F 00 [B]6A[/B] 10 10 00 [B]6A[/B] 11 11 00
For TypeList2, copy this hex somewhere and use its start as address2
Code:
FD 03 00 FF FD 03 01 FF FD 03 02 FF FD 03 03 FF FD 03 04 FF FD 03 05 FF FD 03 06 FF FD 03 07 FF FD 03 08 FF FD 03 09 FF FD 03 0A FF FD 03 0B FF FD 03 0C FF FD 03 0D FF FD 03 0E FF FD 03 0F FF FD 03 10 FF FD 03 11 FF
Now actually implementing it is the tricky part, it won't be a simple copy/paste job; you'll need some insight on what the battle scripts for different moves are actually doing to decide the appropriate place(s) to put ability checks. For any move you want to be affected by Protean you'll need to add a check for it somewhere in the battle script before calculatedamage. In order for a notification string to print out correctly callasm must be before printstring 0x49, and the printstring must be before attackcanceller. You should add a check to see if the user's ability is Protean, if so execute the ASM and optionally print a message if the type is changed, then jump back to the right point in the script. A potential script segment would look something like:
Code:
... (move script stuff is here) ...
jumpifability BANK_USER ABILITY_PROTEAN @Protean /Note 1
goto 0x082D8A26 /Note 2
#org @Protean
callasm [address of Protean asm, plus 0x1]
jumpifbyte B_!= 0x02024200 0x0 @Change /Note 3
jumpifbyte B_= 0x02024200 0x0 @AttackCanceller
#org @Change
setbyte 0x02024200 0x0
printstring 0x49 /Note 4
waitmessage 0x40
goto @AttackCanceller
#org @AttackCanceller
attackcanceler
accuracycheck 0x82D8A5E 0x0
attackstring
ppreduce
calculatedamage
goto 0x82D8A34
Note 1: You'll either need to define ABILITY_PROTEAN in BSP's abilities.bsh, or just use the hex for the ability here instead.
Note 2: A goto jump to an address somewhere in the area of 0x082D8A26 usually signifies the end of a moves' unique scripting, as that jumps to a segment of script shared by nearly all damaging moves. In damaging moves I'd suggest putting the check for Protean before that jump. In status moves the jump may be different.
Note 3: The ASM for Protean does the following: gets the type of the move being used, checks it against the user's type(s), and if necessary changes type to match the move. If there is a type change it will always result in a monotype, if one is not needed though the Poke can retain a dual typing. If a type change is done the byte at 0x02024200 is set to a non-zero garbage byte (in this case 0x6A). This can be used to decide whether or not to display a message, and should be reset to 0x0 somewhere in the battle script.
Note 4: String 0x49 is "[User] transformed into the [Type] type!". This is the string used in Gen 6 games.
As a demo, here's the script I used while testing it. It changes Psybeam, Feint Attack, and Slash (all moves known by the Kecleon I was testing with). After compiling the test script change Psybeam's move effect (effect 76) pointer to match @Psybeam, and change Slash and Feint Attack (effects 43 and 17) to both match @Slash. You'll also need
Jambo's callasm for BSP and to define Protean in abilities.bsh.
Even though it seems complicated and may not be the most concise or elegant way to add Protean, it does indeed work. The only known issue is that when using Hidden Power it will change to Normal instead of the hidden type, but honestly it seems like a small issue and writing more asm to fix that is fairly low on my priority list.