From 59ff4aec9b792acacbdf6978ba4e9f63543af41f Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 27 Feb 2018 20:40:09 +0100 Subject: [PATCH] decompile and document battle tv --- asm/battle_link_817C95C.s | 246 ---- data/battle_link_817C95C.s | 174 --- include/battle.h | 37 +- include/battle_link_817C95C.h | 11 - include/battle_tv.h | 11 + include/global.tv.h | 4 +- include/tv.h | 1 + ld_script.txt | 5 +- src/battle_controller_link_opponent.c | 8 +- src/battle_controller_link_partner.c | 8 +- src/battle_controller_opponent.c | 2 +- src/battle_controller_player.c | 14 +- src/battle_controller_recorded_opponent.c | 2 +- src/battle_controller_wally.c | 2 +- src/battle_link_817C95C.c | 1306 ----------------- src/battle_tv.c | 1585 +++++++++++++++++++++ src/tv.c | 26 +- 17 files changed, 1649 insertions(+), 1793 deletions(-) delete mode 100644 asm/battle_link_817C95C.s delete mode 100644 data/battle_link_817C95C.s delete mode 100644 include/battle_link_817C95C.h create mode 100644 include/battle_tv.h delete mode 100644 src/battle_link_817C95C.c create mode 100644 src/battle_tv.c diff --git a/asm/battle_link_817C95C.s b/asm/battle_link_817C95C.s deleted file mode 100644 index 91406075df..0000000000 --- a/asm/battle_link_817C95C.s +++ /dev/null @@ -1,246 +0,0 @@ - .include "asm/macros.inc" - .include "constants/constants.inc" - - .syntax unified - - .text - - thumb_func_start sub_817F21C -sub_817F21C: @ 817F21C - push {r4-r7,lr} - adds r6, r1, 0 - mov r12, r2 - lsls r0, 16 - lsrs r2, r0, 16 - ldr r1, =gBattleMoves - lsls r0, r2, 1 - adds r0, r2 - lsls r0, 2 - adds r0, r1 - ldrb r0, [r0, 0x1] - cmp r0, 0 - beq _0817F286 - movs r4, 0 - ldr r5, =gUnknown_0860A4AC - ldr r7, =0x0000ffff - adds r3, r5, 0 - adds r1, r5, 0 -_0817F240: - ldrh r0, [r1] - cmp r2, r0 - beq _0817F252 - adds r3, 0x2 - adds r1, 0x2 - adds r4, 0x1 - ldrh r0, [r3] - cmp r0, r7 - bne _0817F240 -_0817F252: - lsls r0, r4, 1 - adds r0, r5 - ldrh r1, [r0] - ldr r0, =0x0000ffff - cmp r1, r0 - beq _0817F270 - movs r0, 0 - str r0, [r6] - b _0817F2A0 - .pool -_0817F270: - cmp r2, 0x95 - bne _0817F294 - ldr r2, =gBattleMons - ldr r0, =gBattlerAttacker - ldrb r1, [r0] - movs r0, 0x58 - muls r0, r1 - adds r0, r2 - adds r0, 0x2A - ldrb r0, [r0] - asrs r0, 1 -_0817F286: - str r0, [r6] - movs r0, 0 - b _0817F2A0 - .pool -_0817F294: - cmp r2, 0xDE - bne _0817F29E - movs r0, 0xA - mov r1, r12 - strh r0, [r1] -_0817F29E: - movs r0, 0x1 -_0817F2A0: - pop {r4-r7} - pop {r1} - bx r1 - thumb_func_end sub_817F21C - - thumb_func_start sub_817F2A8 -sub_817F2A8: @ 817F2A8 - push {r4,r5,lr} - ldr r0, =gBattleTypeFlags - ldr r0, [r0] - movs r1, 0x2 - ands r0, r1 - cmp r0, 0 - beq _0817F324 - ldr r0, =gBattleStruct - ldr r3, [r0] - ldr r0, =0x0000025b - adds r4, r3, r0 - ldrb r2, [r4] - subs r1, 0x21 - adds r0, r1, 0 - ands r0, r2 - strb r0, [r4] - ldr r0, =0x00000267 - adds r2, r3, r0 - ldrb r0, [r2] - ands r1, r0 - strb r1, [r2] - ldrb r5, [r4] - movs r1, 0x1F - adds r0, r1, 0 - ands r0, r5 - strb r0, [r4] - ldrb r0, [r2] - ands r1, r0 - strb r1, [r2] - movs r0, 0x97 - lsls r0, 2 - adds r4, r3, r0 - ldrb r2, [r4] - movs r1, 0x39 - negs r1, r1 - adds r0, r1, 0 - ands r0, r2 - strb r0, [r4] - movs r0, 0x9A - lsls r0, 2 - adds r3, r0 - ldrb r0, [r3] - ands r1, r0 - strb r1, [r3] - ldrb r2, [r4] - movs r1, 0x7 - negs r1, r1 - adds r0, r1, 0 - ands r0, r2 - strb r0, [r4] - ldrb r0, [r3] - ands r1, r0 - strb r1, [r3] - ldrb r2, [r4] - movs r1, 0x2 - negs r1, r1 - adds r0, r1, 0 - ands r0, r2 - strb r0, [r4] - ldrb r0, [r3] - ands r1, r0 - strb r1, [r3] -_0817F324: - pop {r4,r5} - pop {r0} - bx r0 - .pool - thumb_func_end sub_817F2A8 - - thumb_func_start GetBattlerMoveSlotId -GetBattlerMoveSlotId: @ 817F33C - push {r4-r7,lr} - lsls r0, 24 - lsrs r5, r0, 24 - lsls r1, 16 - lsrs r7, r1, 16 - adds r0, r5, 0 - bl GetBattlerSide - lsls r0, 24 - ldr r6, =gEnemyParty - cmp r0, 0 - bne _0817F356 - ldr r6, =gPlayerParty -_0817F356: - movs r4, 0 - ldr r1, =gBattlerPartyIndexes - lsls r0, r5, 1 - adds r5, r0, r1 - b _0817F36E - .pool -_0817F36C: - adds r4, 0x1 -_0817F36E: - cmp r4, 0x3 - bgt _0817F388 - ldrh r1, [r5] - movs r0, 0x64 - muls r0, r1 - adds r0, r6, r0 - adds r1, r4, 0 - adds r1, 0xD - movs r2, 0 - bl GetMonData - cmp r0, r7 - bne _0817F36C -_0817F388: - lsls r0, r4, 24 - lsrs r0, 24 - pop {r4-r7} - pop {r1} - bx r1 - thumb_func_end GetBattlerMoveSlotId - - thumb_func_start sub_817F394 -sub_817F394: @ 817F394 - push {r4-r6,lr} - lsls r0, 16 - lsrs r3, r0, 16 - adds r4, r3, 0 - lsls r1, 16 - lsrs r1, 16 - adds r6, r1, 0 - lsls r2, 24 - lsrs r2, 24 - adds r5, r2, 0 - movs r0, 0x7 - ands r0, r3 - cmp r0, 0 - beq _0817F3B4 - movs r0, 0x3 - b _0817F3CA -_0817F3B4: - movs r0, 0x60 - ands r0, r3 - cmp r0, 0 - beq _0817F3C0 - movs r0, 0x4 - b _0817F3CA -_0817F3C0: - movs r0, 0x18 - ands r0, r3 - cmp r0, 0 - beq _0817F3D2 - movs r0, 0x5 -_0817F3CA: - movs r3, 0 - bl sub_817E684 - b _0817F3E6 -_0817F3D2: - movs r0, 0x80 - ands r4, r0 - cmp r4, 0 - beq _0817F3E6 - movs r0, 0x6 - adds r1, r6, 0 - adds r2, r5, 0 - movs r3, 0 - bl sub_817E684 -_0817F3E6: - pop {r4-r6} - pop {r0} - bx r0 - thumb_func_end sub_817F394 - - .align 2, 0 @ Don't pad with nop. diff --git a/data/battle_link_817C95C.s b/data/battle_link_817C95C.s deleted file mode 100644 index 24f70c79c4..0000000000 --- a/data/battle_link_817C95C.s +++ /dev/null @@ -1,174 +0,0 @@ - .include "asm/macros.inc" - .include "constants/constants.inc" - - .section .rodata - - .align 1 -gUnknown_0860A4AC:: @ 860A4AC - .2byte 0x0044, 0x005a, 0x0075, 0x00f3, 0x0020, 0x00af, 0x00b3, 0x00ed, 0x0149, 0x0108, 0x011c, 0x0143, 0x008a, 0x0137, 0x00ad, 0x00dc - .2byte 0x000c, 0x00da, 0x00d8, 0x011b, 0x00d9, 0x0117, 0xffff, 0x00de, 0x0095, 0xffff - - .align 1 -gUnknown_0860A4E0:: @ 860A4E0 - .2byte 0x0001, 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0001, 0x0000, 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 - .2byte 0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0005, 0x0005, 0x0004, 0x0005, 0x0001, 0x0003, 0x0001 - .2byte 0x0003, 0x0005, 0x0001, 0x0007, 0x0001, 0x0007, 0x0007, 0x0001, 0x0005, 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0005, 0x0001 - .2byte 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 - .2byte 0x0001, 0x0007, 0x0004, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0001, 0x0004 - .2byte 0x0005, 0x0002, 0x0004, 0x0001, 0x0004, 0x0001, 0x0007, 0x0002, 0x0001, 0x0005, 0x0007, 0x0003, 0x0003, 0x0004, 0x0003, 0x0003 - .2byte 0x0003, 0x0003, 0x0003, 0x0002, 0x0004, 0x0001, 0x0005, 0x0001, 0x0001, 0x0004, 0x0005, 0x0003, 0x0001, 0x0002, 0x0001, 0x0005 - .2byte 0x0004, 0x0003, 0x0006, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0005, 0x0001, 0x0001, 0x0007 - .2byte 0x0002, 0x0002, 0x0001, 0x0001, 0x0004, 0x0004, 0x0004, 0x0001, 0x0004, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0007, 0x0007 - .2byte 0x0006, 0x0003, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003, 0x0001, 0x0001, 0x0004, 0x0004 - .2byte 0x0003, 0x0003, 0x0003, 0x0001, 0x0004, 0x0007, 0x0007, 0x0005, 0x0007, 0x0001, 0x0007, 0x0001, 0x0005, 0x0000, 0x0004, 0x0004 - .2byte 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0006, 0x0003, 0x0006, 0x0004, 0x0004, 0x0002, 0x0005, 0x0002, 0x0001, 0x0001, 0x0006 - .2byte 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0006, 0x0001, 0x0004, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001, 0x0001 - .2byte 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0003 - - .align 1 -gUnknown_0860A68C:: @ 860A68C - .2byte 0x0004, 0xfffd, 0xfffa - - .align 1 -gUnknown_0860A692:: @ 860A692 - .2byte 0x0004, 0x0004, 0x0006, 0x0006, 0x0007, 0x0006, 0x0002 - - .align 1 -gUnknown_0860A6A0:: @ 860A6A0 - .2byte 0x0091, 0x0003, 0x00fa, 0x0003, 0x00be, 0x0003, 0x0080, 0x0003, 0x006e, 0x0003, 0x0098, 0x0003, 0x0143, 0x0003, 0x0123, 0x0003 - .2byte 0x007f, 0x0003, 0x014a, 0x0003, 0x0039, 0x0003, 0x0134, 0x0003, 0x0038, 0x0003, 0x003d, 0x0003, 0x015a, 0x0000, 0x0037, 0x0003 - .2byte 0x0160, 0x0003, 0x0137, 0x0003, 0x0057, 0x0003, 0x004c, 0xfffc, 0x013b, 0xfffc, 0x00ac, 0xfffc, 0x0035, 0xfffc, 0x00dd, 0xfffc - .2byte 0x007e, 0xfffc, 0x0101, 0xfffc, 0x0034, 0xfffc, 0x0133, 0xfffc, 0x012b, 0xfffc, 0x011c, 0xfffc, 0x0053, 0xfffc, 0x0007, 0xfffc - .2byte 0x004c, 0xfffc, 0xffff, 0x0000 - - .align 1 -gUnknown_0860A728:: @ 860A728 - .2byte 0x013b, 0x0003, 0x00ac, 0x0003, 0x0035, 0x0003, 0x00dd, 0x0003, 0x007e, 0x0003, 0x0101, 0x0003, 0x0034, 0x0003, 0x0133, 0x0003 - .2byte 0x012b, 0x0003, 0x011c, 0x0003, 0x0053, 0x0003, 0x0007, 0x0003, 0x004c, 0x0005, 0x00eb, 0x0003, 0x00ea, 0x0003, 0x00ec, 0x0003 - .2byte 0x0137, 0x0003, 0xffff, 0x0000 - - .align 1 -gUnknown_0860A770:: @ 860A770 - .2byte 0x0137, 0x0003, 0x004c, 0xfffd, 0xffff, 0x0000 - - .align 1 -gUnknown_0860A77C:: @ 860A77C - .2byte 0x0137, 0x0003, 0x004c, 0xfffd, 0xffff, 0x0000 - - .align 1 -gUnknown_0860A788:: @ 860A788 - .2byte 0x0055, 0x0003, 0x0009, 0x0003, 0x00d1, 0x0003, 0x0054, 0x0003, 0x00c0, 0x0003, 0x015f, 0x0003, 0x0056, 0x0000, 0x0057, 0x0003 - .2byte 0x0158, 0x0003, 0xffff, 0x0000 - - .align 1 -gUnknown_0860A7B0:: @ 860A7B0 - .2byte 0x0005, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003 - - .align 1 -gUnknown_0860A7BE:: @ 860A7BE - .2byte 0x0005, 0x0005, 0x0005, 0x0005, 0x0005 - - .align 1 -gUnknown_0860A7C8:: @ 860A7C8 - .2byte 0x0004 - - .align 1 -gUnknown_0860A7CA:: @ 860A7CA - .2byte 0x0005 - - .align 1 -gUnknown_0860A7CC:: @ 860A7CC - .2byte 0x0005 - - .align 1 -gUnknown_0860A7CE:: @ 860A7CE - .2byte 0x0003 - - .align 1 -gUnknown_0860A7D0:: @ 860A7D0 - .2byte 0x0003 - - .align 1 -gUnknown_0860A7D2:: @ 860A7D2 - .2byte 0x0004 - - .align 1 -gUnknown_0860A7D4:: @ 860A7D4 - .2byte 0x0003 - - .align 1 -gUnknown_0860A7D6:: @ 860A7D6 - .2byte 0x0006 - - .align 1 -gUnknown_0860A7D8:: @ 860A7D8 - .2byte 0x0006 - - .align 1 -gUnknown_0860A7DA:: @ 860A7DA - .2byte 0x0006 - - .align 1 -gUnknown_0860A7DC:: @ 860A7DC - .2byte 0x0004 - - .align 1 -gUnknown_0860A7DE:: @ 860A7DE - .2byte 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002 - - .align 1 -gUnknown_0860A7EC:: @ 860A7EC - .2byte 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004 - - .align 1 -gUnknown_0860A7FA:: @ 860A7FA - .2byte 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff - - .align 1 -gUnknown_0860A808:: @ 860A808 - .2byte 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002 - - .align 1 -gUnknown_0860A816:: @ 860A816 - .2byte 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004 - - .align 1 -gUnknown_0860A824:: @ 860A824 - .2byte 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe - - .align 2 -gUnknown_0860A834:: @ 860A834 - .4byte gUnknown_0860A4E0 - .4byte gUnknown_0860A68C - .4byte gUnknown_0860A692 - .4byte gUnknown_0860A6A0 - .4byte gUnknown_0860A728 - .4byte gUnknown_0860A770 - .4byte gUnknown_0860A77C - .4byte gUnknown_0860A788 - .4byte gUnknown_0860A7B0 - .4byte gUnknown_0860A7BE - .4byte gUnknown_0860A7C8 - .4byte gUnknown_0860A7CA - .4byte gUnknown_0860A7CC - .4byte gUnknown_0860A7CE - .4byte gUnknown_0860A7D0 - .4byte gUnknown_0860A7D2 - .4byte gUnknown_0860A7D4 - .4byte gUnknown_0860A7D6 - .4byte gUnknown_0860A7D8 - .4byte gUnknown_0860A7DA - .4byte gUnknown_0860A7DA - .4byte gUnknown_0860A7DC - .4byte gUnknown_0860A7DE - .4byte gUnknown_0860A7EC - .4byte gUnknown_0860A7FA - .4byte gUnknown_0860A808 - .4byte gUnknown_0860A816 - .4byte gUnknown_0860A824 - - .align 1 -gUnknown_0860A8A4:: @ 860A8A4 - .2byte 0x0097, 0x00b2, 0x00bc, 0x008c, 0x00b4, 0x00b5, 0x0093, 0x006a, 0x0091, 0x005e, 0x0030, 0x002a, 0x0095, 0x001c, 0x001d, 0x0064 - .2byte 0x0060, 0xffff - diff --git a/include/battle.h b/include/battle.h index 8c819f0478..731b5692ef 100644 --- a/include/battle.h +++ b/include/battle.h @@ -368,7 +368,7 @@ struct BattleResults u8 catchAttempts[11]; // 0x36 }; -struct BattleLinkStringSide +struct BattleTv_Side { u32 spikesMonId:3; u32 reflectMonId:3; @@ -380,7 +380,7 @@ struct BattleLinkStringSide u32 perishSongMonId:3; u32 wishMonId:3; u32 grudgeMonId:3; - u32 field_8_6:2; + u32 usedMoveSlot:2; u32 spikesMoveSlot:2; u32 reflectMoveSlot:2; u32 lightScreenMoveSlot:2; @@ -393,18 +393,15 @@ struct BattleLinkStringSide u32 grudgeMoveSlot:2; u32 destinyBondMonId:3; u32 destinyBondMoveSlot:2; - u32 field_3_0:4; - u32 field_3_1:3; + u32 faintCause:4; + u32 faintCauseMonId:3; u32 explosion:1; u32 explosionMoveSlot:2; u32 explosionMonId:3; u32 perishSong:1; - u32 field_4_2:1; - u32 field_5_0:3; - u32 field_5_1:2; }; -struct BattleLinkStringPosition +struct BattleTv_Position { u32 curseMonId:3; u32 leechSeedMonId:3; @@ -424,11 +421,11 @@ struct BattleLinkStringPosition u32 mudSportMoveSlot:2; u32 ingrainMonId:3; u32 ingrainMoveSlot:2; - u32 field_5_5:3; - u32 field_6_0:2; + u32 attackedByMonId:3; + u32 attackedByMoveSlot:2; }; -struct BattleLinkStringMon +struct BattleTv_Mon { u32 psnMonId:3; u32 badPsnMonId:3; @@ -444,16 +441,16 @@ struct BattleLinkStringMon u32 frzMoveSlot:2; }; -struct UnknownBattleLinkStruct +struct BattleTv { - struct BattleLinkStringMon mon[2][6]; // [side][partyId] - struct BattleLinkStringPosition pos[2][2]; // [side][flank] - struct BattleLinkStringSide side[2]; // [side] + struct BattleTv_Mon mon[2][6]; // [side][partyId] + struct BattleTv_Position pos[2][2]; // [side][flank] + struct BattleTv_Side side[2]; // [side] }; -struct UnknownBattleLinkArrayStruct +struct BattleTvMovePoints { - s16 unk0[2][6*4]; + s16 points[2][PARTY_SIZE * 4]; }; struct BattleStruct @@ -535,7 +532,7 @@ struct BattleStruct u8 field_B0; u8 hpScale; u8 synchronizeMoveEffect; - u8 field_B3; + bool8 anyMonHasTransformed; void (*savedCallback)(void); u16 usedHeldItems[MAX_BATTLERS_COUNT]; u8 chosenItem[4]; // why is this an u8? @@ -560,8 +557,8 @@ struct BattleStruct u8 wishPerishSongBattlerId; bool8 overworldWeatherDone; u8 atkCancellerTracker; - struct UnknownBattleLinkArrayStruct field_1A4; - struct UnknownBattleLinkStruct field_204; + struct BattleTvMovePoints tvMovePoints; + struct BattleTv tv; u8 notSureWhatFieldLol[0x28]; u8 AI_monToSwitchIntoId[MAX_BATTLERS_COUNT]; u8 field_298[8]; diff --git a/include/battle_link_817C95C.h b/include/battle_link_817C95C.h deleted file mode 100644 index cb2cb0b273..0000000000 --- a/include/battle_link_817C95C.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef GUARD_BATTLE_LINK_817C95C_H -#define GUARD_BATTLE_LINK_817C95C_H - -void sub_817C95C(u16 stringId); -void sub_817E0FC(u16 move, u16 weatherFlags, struct DisableStruct *disableStructPtr); -void sub_817E32C(u8 animationId); -void sub_817E3F4(void); -void sub_817F2A8(void); -u8 GetBattlerMoveSlotId(u8 bank, u16 move); - -#endif // GUARD_BATTLE_LINK_817C95C_H diff --git a/include/battle_tv.h b/include/battle_tv.h new file mode 100644 index 0000000000..72466d73b8 --- /dev/null +++ b/include/battle_tv.h @@ -0,0 +1,11 @@ +#ifndef GUARD_BATTLE_TV_H +#define GUARD_BATTLE_TV_H + +void BattleTv_SetDataBasedOnString(u16 stringId); +void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruct *disableStructPtr); +void BattleTv_SetDataBasedOnAnimation(u8 animationId); +void TryPutLinkBattleTvShowOnAir(void); +void BattleTv_ClearExplosionFaintCause(void); +u8 GetBattlerMoveSlotId(u8 battlerId, u16 moveId); + +#endif // GUARD_BATTLE_TV_H diff --git a/include/global.tv.h b/include/global.tv.h index 5f65aa8e0a..81f181cf32 100644 --- a/include/global.tv.h +++ b/include/global.tv.h @@ -188,11 +188,11 @@ typedef union // size = 0x24 struct { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u16 species; + /*0x02*/ u16 speciesOpponent; /*0x04*/ u8 playerName[8]; /*0x0C*/ u8 linkOpponentName[8]; /*0x14*/ u16 move; - /*0x16*/ u16 species2; + /*0x16*/ u16 speciesPlayer; /*0x18*/ u8 battleType; /*0x19*/ u8 language; /*0x1A*/ u8 linkOpponentLanguage; diff --git a/include/tv.h b/include/tv.h index 93854be56b..8c7c4701e3 100644 --- a/include/tv.h +++ b/include/tv.h @@ -38,5 +38,6 @@ void sub_80EECC8(void); void sub_80EECEC(void); void sub_80F1208(TVShow *shows); void sub_80EE44C(u8 nMonsCaught, u8 nPkblkUsed); +void PutBattleUpdateOnTheAir(u8 opponentLinkPlayerId, u16 move, u16 speciesPlayer, u16 speciesOpponent); #endif //GUARD_TV_H diff --git a/ld_script.txt b/ld_script.txt index 4ae3f183af..ede1c7ad16 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -236,8 +236,7 @@ SECTIONS { src/evolution_graphics.o(.text); src/bard_music.o(.text); src/fldeff_teleport.o(.text); - src/battle_link_817C95C.o(.text); - asm/battle_link_817C95C.o(.text); + src/battle_tv.o(.text); src/pokemon_animation.o(.text); src/recorded_battle.o(.text); src/battle_controller_recorded_opponent.o(.text); @@ -512,7 +511,7 @@ SECTIONS { src/intro_credits_graphics.o(.rodata); src/evolution_graphics.o(.rodata); src/bard_music.o(.rodata); - data/battle_link_817C95C.o(.rodata); + src/battle_tv.o(.rodata); src/pokemon_animation.o(.rodata); src/battle_controller_recorded_opponent.o(.rodata); src/battle_controller_recorded_player.o(.rodata); diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index a399adf25e..6e6968786e 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -6,7 +6,7 @@ #include "battle_anim.h" #include "constants/battle_anim.h" #include "battle_ai_script_commands.h" -#include "battle_link_817C95C.h" +#include "battle_tv.h" #include "pokemon.h" #include "link.h" #include "util.h" @@ -1414,7 +1414,7 @@ static void LinkOpponentHandleMoveAnimation(void) { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; gBattlerControllerFuncs[gActiveBattler] = LinkOpponentDoMoveAnimation; - sub_817E0FC(move, gWeatherMoveAnim, gAnimDisableStructPtr); + BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr); } } } @@ -1478,7 +1478,7 @@ static void LinkOpponentHandlePrintString(void) BufferStringBattle(*stringId); BattleHandleAddTextPrinter(gDisplayedStringBattle, 0); gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; - sub_817C95C(*stringId); + BattleTv_SetDataBasedOnString(*stringId); } static void LinkOpponentHandlePrintSelectionString(void) @@ -1831,7 +1831,7 @@ static void LinkOpponentHandleBattleAnimation(void) else gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - sub_817E32C(animationId); + BattleTv_SetDataBasedOnAnimation(animationId); } } diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c index 1734abe622..476a95ad1a 100644 --- a/src/battle_controller_link_partner.c +++ b/src/battle_controller_link_partner.c @@ -6,7 +6,7 @@ #include "battle_anim.h" #include "constants/battle_anim.h" #include "battle_ai_script_commands.h" -#include "battle_link_817C95C.h" +#include "battle_tv.h" #include "pokemon.h" #include "link.h" #include "util.h" @@ -1238,7 +1238,7 @@ static void LinkPartnerHandleMoveAnimation(void) { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; gBattlerControllerFuncs[gActiveBattler] = LinkPartnerDoMoveAnimation; - sub_817E0FC(move, gWeatherMoveAnim, gAnimDisableStructPtr); + BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr); } } } @@ -1302,7 +1302,7 @@ static void LinkPartnerHandlePrintString(void) BufferStringBattle(*stringId); BattleHandleAddTextPrinter(gDisplayedStringBattle, 0); gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; - sub_817C95C(*stringId); + BattleTv_SetDataBasedOnString(*stringId); } static void LinkPartnerHandlePrintSelectionString(void) @@ -1666,7 +1666,7 @@ static void LinkPartnerHandleBattleAnimation(void) else gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - sub_817E32C(animationId); + BattleTv_SetDataBasedOnAnimation(animationId); } } diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 26e0191cbf..54d6434a36 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -5,7 +5,7 @@ #include "battle_interface.h" #include "battle_anim.h" #include "constants/battle_anim.h" -#include "battle_link_817C95C.h" +#include "battle_tv.h" #include "battle_ai_script_commands.h" #include "pokemon.h" #include "link.h" diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 8847715f68..f25566dd51 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -5,7 +5,7 @@ #include "battle_interface.h" #include "battle_anim.h" #include "constants/battle_anim.h" -#include "battle_link_817C95C.h" +#include "battle_tv.h" #include "pokemon.h" #include "link.h" #include "util.h" @@ -881,7 +881,7 @@ static void sub_80586F8(void) gMain.callback1 = gPreBattleCallback1; SetMainCallback2(sub_8038D64); if (gBattleOutcome == B_OUTCOME_WON) - sub_817E3F4(); + TryPutLinkBattleTvShowOnAir(); FreeAllWindowBuffers(); } } @@ -894,7 +894,7 @@ static void sub_80586F8(void) gMain.callback1 = gPreBattleCallback1; SetMainCallback2(sub_8038D64); if (gBattleOutcome == B_OUTCOME_WON) - sub_817E3F4(); + TryPutLinkBattleTvShowOnAir(); FreeAllWindowBuffers(); } } @@ -2484,7 +2484,7 @@ static void PlayerHandleMoveAnimation(void) { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; gBattlerControllerFuncs[gActiveBattler] = PlayerDoMoveAnimation; - sub_817E0FC(move, gWeatherMoveAnim, gAnimDisableStructPtr); + BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr); } } } @@ -2548,7 +2548,7 @@ static void PlayerHandlePrintString(void) BufferStringBattle(*stringId); BattleHandleAddTextPrinter(gDisplayedStringBattle, 0); gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter2; - sub_817C95C(*stringId); + BattleTv_SetDataBasedOnString(*stringId); sub_81A57E4(gActiveBattler, *stringId); } @@ -2575,7 +2575,7 @@ static void PlayerHandleChooseAction(void) s32 i; gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3; - sub_817F2A8(); + BattleTv_ClearExplosionFaintCause(); BattleHandleAddTextPrinter(gText_BattleMenu, 2); for (i = 0; i < 4; i++) @@ -3069,7 +3069,7 @@ static void PlayerHandleBattleAnimation(void) else gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - sub_817E32C(animationId); + BattleTv_SetDataBasedOnAnimation(animationId); } } diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index 2295c4a75c..ded65828bf 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -6,7 +6,7 @@ #include "battle_anim.h" #include "constants/battle_anim.h" #include "battle_ai_script_commands.h" -#include "battle_link_817C95C.h" +#include "battle_tv.h" #include "recorded_battle.h" #include "pokemon.h" #include "link.h" diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c index 445feaf7a9..0d18de0e4b 100644 --- a/src/battle_controller_wally.c +++ b/src/battle_controller_wally.c @@ -5,7 +5,7 @@ #include "battle_interface.h" #include "battle_anim.h" #include "constants/battle_anim.h" -#include "battle_link_817C95C.h" +#include "battle_tv.h" #include "pokemon.h" #include "link.h" #include "util.h" diff --git a/src/battle_link_817C95C.c b/src/battle_link_817C95C.c deleted file mode 100644 index 1a8a201aad..0000000000 --- a/src/battle_link_817C95C.c +++ /dev/null @@ -1,1306 +0,0 @@ -#include "global.h" -#include "pokemon.h" -#include "battle.h" -#include "battle_link_817C95C.h" -#include "constants/battle_string_ids.h" -#include "constants/battle_anim.h" -#include "constants/moves.h" -#include "constants/species.h" -#include "battle_message.h" -#include "tv.h" - -extern struct StringInfoBattle *gStringInfo; - -extern const struct BattleMove gBattleMoves[]; - -// this file's functions -bool8 sub_817E0B8(u16 stringId); -void sub_817E684(u8 arg0, u16 arg1, u8 arg2, u8 arg3); -void sub_817EECC(void); -void sub_817EA80(u8 arg0); -void sub_817F394(u16 weatherFlags, u16 moveId, u8 moveSlot); -bool8 sub_817F21C(u16 moveId, s32 *dmg, u16 *powerOverride); - -// const rom data -extern const u16 *const gUnknown_0860A834[]; -extern const u16 gUnknown_0860A8A4[]; -extern const u16 gUnknown_0860A4AC[]; - -// code -void sub_817C95C(u16 stringId) -{ - struct UnknownBattleLinkStruct *structPtr; - u32 atkSide, defSide, effSide, scriptingSide; - struct Pokemon *atkMon, *defMon; - u8 moveSlot; - u32 atkFlank, defFlank, effFlank; - u8 *perishCount; - u16 *statStringId, *finishedMoveId; - - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && stringId != STRINGID_ITDOESNTAFFECT && stringId != STRINGID_NOTVERYEFFECTIVE) - return; - - structPtr = &gBattleStruct->field_204; - - atkSide = GetBattlerSide(gBattlerAttacker); - defSide = GetBattlerSide(gBattlerTarget); - effSide = GetBattlerSide(gEffectBattler); - scriptingSide = GetBattlerSide(gStringInfo->scrActive); - - if (atkSide == B_SIDE_PLAYER) - atkMon = &gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]]; - else - atkMon = &gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]]; - - if (defSide == B_SIDE_PLAYER) - defMon = &gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]]; - else - defMon = &gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]]; - - moveSlot = GetBattlerMoveSlotId(gBattlerAttacker, gStringInfo->currentMove); - - if (moveSlot >= 4 && sub_817E0B8(stringId) && stringId > BATTLESTRINGS_ID_ADDER) - { - structPtr->side[atkSide].field_3_0 = 15; - return; - } - - perishCount = (u8 *)(gBattleTextBuff1 + 4); - statStringId = (u16 *)(gBattleTextBuff2 + 2); - finishedMoveId = (u16 *)(gBattleTextBuff1 + 2); - - atkFlank = GetBattlerPosition(gBattlerAttacker) / 2; - defFlank = GetBattlerPosition(gBattlerTarget) / 2; - effFlank = GetBattlerPosition(gEffectBattler) / 2; - - switch (stringId) - { - case STRINGID_ITDOESNTAFFECT: - sub_817E684(1, moveSlot, 2, 0); - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) - sub_817EECC(); - break; - case STRINGID_NOTVERYEFFECTIVE: - sub_817E684(1, moveSlot, 1, 0); - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && GetMonData(defMon, MON_DATA_HP, NULL) != 0) - sub_817EECC(); - break; - case STRINGID_SUPEREFFECTIVE: - sub_817E684(1, moveSlot, 0, 0); - break; - case STRINGID_PKMNFORESAWATTACK: - structPtr->side[atkSide].futureSightMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].futureSightMoveSlot = moveSlot; - break; - case STRINGID_PKMNCHOSEXASDESTINY: - structPtr->side[atkSide].doomDesireMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].doomDesireMoveSlot = moveSlot; - break; - case STRINGID_FAINTINTHREE: - structPtr->side[atkSide].perishSongMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].perishSongMoveSlot = moveSlot; - structPtr->side[atkSide].perishSong = 1; - break; - case STRINGID_PKMNPERISHCOUNTFELL: - if (*perishCount == 0) - structPtr->side[atkSide].field_3_0 = 10; - break; - case STRINGID_PKMNWISHCAMETRUE: - if (structPtr->side[defSide].wishMonId != 0) - { - sub_817E684(2, 3, defSide, - (structPtr->side[defSide].wishMonId - 1) * 4 + structPtr->side[defSide].wishMoveSlot); - } - break; - case STRINGID_PKMNWANTSGRUDGE: - structPtr->side[atkSide].grudgeMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].grudgeMoveSlot = moveSlot; - break; - case STRINGID_PKMNLOSTPPGRUDGE: - if (structPtr->side[defSide].grudgeMonId != 0) - { - sub_817E684(2, 4, defSide, - (structPtr->side[defSide].grudgeMonId - 1) * 4 + structPtr->side[defSide].grudgeMoveSlot); - } - break; - case STRINGID_PKMNTRYINGTOTAKEFOE: - structPtr->side[atkSide].destinyBondMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].destinyBondMoveSlot = moveSlot; - break; - case STRINGID_PKMNTOOKFOE: - if (structPtr->side[defSide].destinyBondMonId != 0) - structPtr->side[atkSide].field_3_0 = 11; - break; - case STRINGID_PKMNPLANTEDROOTS: - structPtr->pos[atkSide][atkFlank].ingrainMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[atkSide][atkFlank].ingrainMoveSlot = moveSlot; - break; - case STRINGID_PKMNABSORBEDNUTRIENTS: - if (structPtr->pos[atkSide][atkFlank].ingrainMonId != 0) - { - sub_817E684(2, 6, atkSide, - (structPtr->pos[atkSide][atkFlank].ingrainMonId - 1) * 4 + structPtr->pos[atkSide][atkFlank].ingrainMoveSlot); - } - break; - case STRINGID_PKMNANCHOREDITSELF: - if (structPtr->pos[defSide][defFlank].ingrainMonId != 0) - { - sub_817E684(2, 6, defSide, - (structPtr->pos[defSide][defFlank].ingrainMonId - 1) * 4 + structPtr->pos[defSide][defFlank].ingrainMoveSlot); - } - break; - case STRINGID_PKMNTRANSFORMEDINTO: - gBattleStruct->field_B3 = 1; - break; - case STRINGID_CRITICALHIT: - sub_817E684(0x12, moveSlot, 0, 0); - break; - case STRINGID_PKMNSSTATCHANGED: - if (gBattleTextBuff1[2] != 0) - { - if (*statStringId == STRINGID_STATSHARPLY) - sub_817E684(0x17, moveSlot, gBattleTextBuff1[2] - 1, 0); - else - sub_817E684(0x16, moveSlot, gBattleTextBuff1[2] - 1, 0); - } - break; - case STRINGID_PKMNSSTATCHANGED2: - if (gBattleTextBuff1[2] != 0) - { - if (gBattlerAttacker == gBattlerTarget) - { - if (*statStringId == STRINGID_STATSHARPLY) - sub_817E684(0x17, moveSlot, gBattleTextBuff1[2] - 1, 0); - else - sub_817E684(0x16, moveSlot, gBattleTextBuff1[2] - 1, 0); - } - else - { - sub_817E684(0x1B, moveSlot, gBattleTextBuff1[2] - 1, 0); - } - } - break; - case STRINGID_PKMNSSTATCHANGED3: - if (gBattleTextBuff1[2] != 0) - sub_817E684(0x18, moveSlot, gBattleTextBuff1[2] - 1, 0); - break; - case STRINGID_PKMNSSTATCHANGED4: - if (gBattleTextBuff1[2] != 0) - { - if (*statStringId == STRINGID_STATHARSHLY) - sub_817E684(0x1A, moveSlot, gBattleTextBuff1[2] - 1, 0); - else - sub_817E684(0x19, moveSlot, gBattleTextBuff1[2] - 1, 0); - } - break; - case STRINGID_PKMNLAIDCURSE: - structPtr->pos[defSide][defFlank].curseMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[defSide][defFlank].curseMoveSlot = moveSlot; - break; - case STRINGID_PKMNAFFLICTEDBYCURSE: - if (GetMonData(atkMon, MON_DATA_HP, NULL) - && structPtr->pos[atkSide][atkFlank].curseMonId != 0) - { - sub_817E684(8, 0, structPtr->pos[atkSide][atkFlank].curseMonId - 1, structPtr->pos[atkSide][atkFlank].curseMoveSlot); - structPtr->side[atkSide].field_3_0 = 1; - structPtr->side[atkSide].field_3_1 = atkFlank; - } - break; - case STRINGID_PKMNSEEDED: - structPtr->pos[defSide][defFlank].leechSeedMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[defSide][defFlank].leechSeedMoveSlot = moveSlot; - break; - case STRINGID_PKMNSAPPEDBYLEECHSEED: - if (structPtr->pos[atkSide][atkFlank].leechSeedMonId != 0) - { - sub_817E684(8, 1, structPtr->pos[atkSide][atkFlank].leechSeedMonId - 1, structPtr->pos[atkSide][atkFlank].leechSeedMoveSlot); - structPtr->side[atkSide].field_3_0 = 2; - structPtr->side[atkSide].field_3_1 = atkFlank; - } - break; - case STRINGID_PKMNFELLINTONIGHTMARE: - structPtr->pos[defSide][defFlank].nightmareMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[defSide][defFlank].nightmareMoveSlot = moveSlot; - break; - case STRINGID_PKMNLOCKEDINNIGHTMARE: - if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0 - && structPtr->pos[atkSide][atkFlank].nightmareMonId != 0) - { - sub_817E684(8, 5, structPtr->pos[atkSide][atkFlank].nightmareMonId - 1, structPtr->pos[atkSide][atkFlank].nightmareMoveSlot); - structPtr->side[atkSide].field_3_0 = 5; - structPtr->side[atkSide].field_3_1 = atkFlank; - } - break; - case STRINGID_PKMNSQUEEZEDBYBIND: - case STRINGID_PKMNTRAPPEDINVORTEX: - case STRINGID_PKMNWRAPPEDBY: - case STRINGID_PKMNCLAMPED: - case STRINGID_PKMNTRAPPEDBYSANDTOMB: - structPtr->pos[defSide][defFlank].wrapMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[defSide][defFlank].wrapMoveSlot = moveSlot; - break; - case STRINGID_PKMNHURTBY: - if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0 - && structPtr->pos[atkSide][atkFlank].wrapMonId != 0) - { - sub_817E684(8, 6, structPtr->pos[atkSide][atkFlank].wrapMonId - 1, structPtr->pos[atkSide][atkFlank].wrapMoveSlot); - structPtr->side[atkSide].field_3_0 = 6; - structPtr->side[atkSide].field_3_1 = atkFlank; - } - break; - case STRINGID_PKMNWASBURNED: - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].brnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].brnMoveSlot = moveSlot; - break; - case STRINGID_PKMNHURTBYBURN: - if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0) - { - if (structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMonId != 0) - sub_817E684(8, 4, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMonId - 1, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMoveSlot); - structPtr->side[atkSide].field_3_0 = 4; - structPtr->side[atkSide].field_3_1 = gBattlerPartyIndexes[gBattlerAttacker]; - } - break; - case STRINGID_PKMNWASPOISONED: - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].psnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].psnMoveSlot = moveSlot; - break; - case STRINGID_PKMNBADLYPOISONED: - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].badPsnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].badPsnMoveSlot = moveSlot; - break; - case STRINGID_PKMNHURTBYPOISON: - if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0) - { - if (structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMonId != 0) - sub_817E684(8, 2, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMonId - 1, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMoveSlot); - if (structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMonId != 0) - sub_817E684(8, 3, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMonId - 1, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMoveSlot); - structPtr->side[atkSide].field_3_0 = 3; - structPtr->side[atkSide].field_3_1 = gBattlerPartyIndexes[gBattlerAttacker]; - } - break; - case STRINGID_PKMNFELLINLOVE: - structPtr->pos[defSide][defFlank].attractMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[defSide][defFlank].attractMoveSlot = moveSlot; - break; - case STRINGID_PKMNIMMOBILIZEDBYLOVE: - if (structPtr->pos[atkSide][atkFlank].attractMonId != 0) - sub_817E684(9, 0, structPtr->pos[atkSide][atkFlank].attractMonId - 1, structPtr->pos[atkSide][atkFlank].attractMoveSlot); - break; - case STRINGID_PKMNWASPARALYZED: - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].prlzMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].prlzMoveSlot = moveSlot; - break; - case STRINGID_PKMNISPARALYZED: - if (structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMonId != 0) - sub_817E684(9, 2, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMonId - 1, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMoveSlot); - break; - case STRINGID_PKMNFELLASLEEP: - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].slpMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].slpMoveSlot = moveSlot; - break; - case STRINGID_PKMNFASTASLEEP: - if (structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMonId != 0 - && gStringInfo->currentMove != MOVE_SNORE - && gStringInfo->currentMove != MOVE_SLEEP_TALK) - sub_817E684(9, 3, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMonId - 1, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMoveSlot); - break; - case STRINGID_PKMNWASFROZEN: - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].frzMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].frzMoveSlot = moveSlot; - break; - case STRINGID_PKMNISFROZEN: - if (structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMonId != 0) - sub_817E684(9, 4, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMonId - 1, structPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMoveSlot); - break; - case STRINGID_PKMNWASCONFUSED: - structPtr->pos[effSide][effFlank].confusionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[effSide][effFlank].confusionMoveSlot = moveSlot; - break; - case STRINGID_ITHURTCONFUSION: - if (structPtr->pos[atkSide][atkFlank].confusionMonId != 0) - sub_817E684(9, 1, structPtr->pos[atkSide][atkFlank].confusionMonId - 1, structPtr->pos[atkSide][atkFlank].confusionMoveSlot); - structPtr->side[atkSide].field_3_0 = 12; - break; - case STRINGID_SPIKESSCATTERED: - structPtr->side[defSide].spikesMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[defSide].spikesMoveSlot = moveSlot; - break; - case STRINGID_PKMNHURTBYSPIKES: - if (structPtr->side[scriptingSide].spikesMonId != 0) - { - sub_817E684(10, scriptingSide ^ BIT_SIDE, structPtr->side[scriptingSide].spikesMonId - 1, structPtr->side[scriptingSide].spikesMoveSlot); - structPtr->side[scriptingSide].field_3_0 = 7; - } - break; - case STRINGID_PKMNBLEWAWAYSPIKES: - structPtr->side[atkSide].spikesMonId = 0; - structPtr->side[atkSide].spikesMoveSlot = 0; - break; - case STRINGID_FIREWEAKENED: - structPtr->pos[atkSide][atkFlank].waterSportMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[atkSide][atkFlank].waterSportMoveSlot = moveSlot; - break; - case STRINGID_ELECTRICITYWEAKENED: - structPtr->pos[atkSide][atkFlank].mudSportMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[atkSide][atkFlank].mudSportMoveSlot = moveSlot; - break; - case STRINGID_ATTACKERFAINTED: - sub_817EA80(0); - case STRINGID_RETURNMON: - if (structPtr->pos[atkSide][atkFlank].waterSportMonId != 0) - { - structPtr->pos[atkSide][atkFlank].waterSportMonId = 0; - structPtr->pos[atkSide][atkFlank].waterSportMoveSlot = 0; - } - if (structPtr->pos[atkSide][atkFlank].mudSportMonId != 0) - { - structPtr->pos[atkSide][atkFlank].mudSportMonId = 0; - structPtr->pos[atkSide][atkFlank].mudSportMoveSlot = 0; - } - break; - case STRINGID_TARGETFAINTED: - sub_817EA80(1); - if (structPtr->pos[atkSide][defFlank].waterSportMonId != 0) - { - structPtr->pos[atkSide][defFlank].waterSportMonId = 0; - structPtr->pos[atkSide][defFlank].waterSportMoveSlot = 0; - } - if (structPtr->pos[atkSide][defFlank].mudSportMonId != 0) - { - structPtr->pos[atkSide][defFlank].mudSportMonId = 0; - structPtr->pos[atkSide][defFlank].mudSportMoveSlot = 0; - } - break; - case STRINGID_PKMNRAISEDDEF: - case STRINGID_PKMNRAISEDDEFALITTLE: - structPtr->side[atkSide].reflectMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].reflectMoveSlot = moveSlot; - break; - case STRINGID_PKMNRAISEDSPDEF: - case STRINGID_PKMNRAISEDSPDEFALITTLE: - structPtr->side[atkSide].lightScreenMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].lightScreenMoveSlot = moveSlot; - break; - case STRINGID_PKMNSXWOREOFF: - if (*finishedMoveId == MOVE_REFLECT) - { - structPtr->side[atkSide].reflectMonId = 0; - structPtr->side[atkSide].reflectMoveSlot = 0; - } - if (*finishedMoveId == MOVE_LIGHT_SCREEN) - { - structPtr->side[atkSide].lightScreenMonId = 0; - structPtr->side[atkSide].lightScreenMoveSlot = 0; - } - if (*finishedMoveId == MOVE_MIST) - { - structPtr->side[atkSide].mistMonId = 0; - structPtr->side[atkSide].mistMoveSlot = 0; - } - break; - case STRINGID_PKMNCOVEREDBYVEIL: - structPtr->side[atkSide].safeguardMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].safeguardMoveSlot = moveSlot; - break; - case STRINGID_PKMNUSEDSAFEGUARD: - if (structPtr->side[defSide].safeguardMonId != 0) - sub_817E684(15, 0, structPtr->side[defSide].safeguardMonId - 1, structPtr->side[defSide].safeguardMoveSlot); - break; - case STRINGID_PKMNSAFEGUARDEXPIRED: - structPtr->side[atkSide].safeguardMonId = 0; - structPtr->side[atkSide].safeguardMoveSlot = 0; - break; - case STRINGID_PKMNSHROUDEDINMIST: - structPtr->side[atkSide].mistMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].mistMoveSlot = moveSlot; - break; - case STRINGID_PKMNPROTECTEDBYMIST: - if (structPtr->side[defSide].mistMonId != 0) - sub_817E684(16, 0, structPtr->side[defSide].mistMonId - 1, structPtr->side[defSide].mistMoveSlot); - break; - case STRINGID_THEWALLSHATTERED: - structPtr->side[defSide].reflectMonId = 0; - structPtr->side[defSide].reflectMoveSlot = 0; - structPtr->side[defSide].lightScreenMonId = 0; - structPtr->side[defSide].lightScreenMoveSlot = 0; - sub_817E684(17, 0, gBattlerPartyIndexes[gBattlerAttacker], moveSlot); - break; - case STRINGID_PKMNFLINCHED: - if (structPtr->pos[atkSide][0].field_5_5 != 0) - sub_817E684(21, 0, structPtr->pos[atkSide][0].field_5_5 - 1, structPtr->pos[atkSide][0].field_6_0); - if (structPtr->pos[atkSide][1].field_5_5 != 0) - sub_817E684(21, 0, structPtr->pos[atkSide][1].field_5_5 - 1, structPtr->pos[atkSide][1].field_6_0); - break; - case STRINGID_PKMNCRASHED: - case STRINGID_PKMNHITWITHRECOIL: - structPtr->side[atkSide].field_3_0 = 14; - break; - } -} - -bool8 sub_817E0B8(u16 stringId) -{ - s32 i = 0; - - while (1) - { - if (gUnknown_0860A8A4[i] == stringId) - break; - i++; - if (gUnknown_0860A8A4[i] == 0xFFFF) - break; - } - - if (gUnknown_0860A8A4[i] == 0xFFFF) - return TRUE; - else - return FALSE; -} - -void sub_817E0FC(u16 move, u16 weatherFlags, struct DisableStruct *disableStructPtr) -{ - struct UnknownBattleLinkStruct *structPtr; - u32 atkSide, defSide; - u8 moveSlot; - - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) - return; - - structPtr = &gBattleStruct->field_204; - - atkSide = GetBattlerSide(gBattlerAttacker); - defSide = GetBattlerSide(gBattlerTarget); - moveSlot = GetBattlerMoveSlotId(gBattlerAttacker, move); - - if (moveSlot >= 4) - { - structPtr->side[atkSide].field_3_0 = 15; - return; - } - - structPtr->pos[defSide][GetBattlerPosition(gBattlerAttacker) / 2].field_5_5 = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->pos[defSide][GetBattlerPosition(gBattlerAttacker) / 2].field_6_0 = moveSlot; - structPtr->side[atkSide].field_8_6 = moveSlot; - sub_817E684(0, moveSlot, gBattleMoves[move].effect, 0); - sub_817F394(weatherFlags, move, moveSlot); - if (disableStructPtr->chargeTimer1 != 0) - sub_817E684(7, move, moveSlot, 0); - - if (move == MOVE_WISH) - { - structPtr->side[atkSide].wishMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide].wishMoveSlot = moveSlot; - } - if (move == MOVE_SELF_DESTRUCT || move == MOVE_EXPLOSION) - { - structPtr->side[atkSide ^ BIT_SIDE].explosionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; - structPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot = moveSlot; - structPtr->side[atkSide ^ BIT_SIDE].field_3_0 = 13; - structPtr->side[atkSide ^ BIT_SIDE].explosion = 1; - } - - sub_817E684(13, gBattleMoves[move].type, gBattleMoves[move].power, 0); - sub_817E684(14, gBattleMoves[move].type, gBattleMoves[move].power, 0); - sub_817E684(11, gBattleMoves[move].type, 0, 0); - sub_817E684(12, gBattleMoves[move].type, 0, 0); -} - -void sub_817E32C(u8 animationId) -{ - struct UnknownBattleLinkStruct *structPtr; - u32 atkSide; - - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) - return; - - structPtr = &gBattleStruct->field_204; - atkSide = GetBattlerSide(gBattlerAttacker); - switch (animationId) - { - case B_ANIM_FUTURE_SIGHT_HIT: - if (structPtr->side[atkSide].futureSightMonId != 0) - { - sub_817E684(2, 0, atkSide, - (structPtr->side[atkSide].futureSightMonId - 1) * 4 + structPtr->side[atkSide].futureSightMoveSlot); - structPtr->side[atkSide].field_3_0 = 8; - } - break; - case B_ANIM_DOOM_DESIRE_HIT: - if (structPtr->side[atkSide].doomDesireMonId != 0) - { - sub_817E684(2, 1, atkSide, - (structPtr->side[atkSide].doomDesireMonId - 1) * 4 + structPtr->side[atkSide].doomDesireMoveSlot); - structPtr->side[atkSide].field_3_0 = 9; - } - break; - } -} - -#ifdef NONMATCHING -// for loop has an unused stack variable -void sub_817E3F4(void) -{ - u16 playerBestSpecies = 0, opponentBestSpecies = 0; - s16 playerBestSum = 0, opponentBestSum = SHRT_MAX; - u8 playerBestMonId = 0, opponentBestMonId = 0; - struct UnknownBattleLinkArrayStruct *array = NULL; - u8 countPlayer = 0, countOpponent = 0; - s16 sum = 0; - u16 species = 0; - u16 moveId = 0; - s32 i, j; - - if (gBattleStruct->field_B3) - return; - - array = &gBattleStruct->field_1A4; - for (i = 0; i < PARTY_SIZE; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE) - countPlayer++; - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE) - countOpponent++; - } - - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) || countPlayer != countOpponent) - return; - - for (i = 0; i < PARTY_SIZE; i++) - { - species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL); - if (species != SPECIES_NONE && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG, NULL)) - { - for (sum = 0, j = 0; j < 4; j++) - sum += array->unk0[0][i * 4 + j]; - - if (playerBestSum < sum) - { - playerBestMonId = i; - playerBestSum = sum; - playerBestSpecies = species; - } - } - - species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, NULL); - if (species != SPECIES_NONE && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG, NULL)) - { - s32 id = 1; - for (sum = 0, j = 0; j < 4; j++) - sum += array->unk0[id][i * 4 + j]; - - if (opponentBestSum == sum) - { - if (GetMonData(&gEnemyParty[i], MON_DATA_EXP, NULL) > GetMonData(&gEnemyParty[opponentBestMonId], MON_DATA_EXP, NULL)) - { - opponentBestMonId = i; - opponentBestSum = sum; - opponentBestSpecies = species; - } - } - else if (opponentBestSum > sum) - { - opponentBestMonId = i; - opponentBestSum = sum; - opponentBestSpecies = species; - } - } - } - - for (sum = 0, i = 0, j = 0; j < 4; j++) - { - if (sum < array->unk0[0][playerBestMonId * 4 + j]) - { - sum = array->unk0[0][playerBestMonId * 4 + j]; - i = j; - } - } - - moveId = GetMonData(&gPlayerParty[playerBestMonId], MON_DATA_MOVE1 + i, NULL); - if (playerBestSum == 0 || moveId == 0) - return; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if ((playerBestMonId < 3 && !sub_806D82C(gBattleScripting.multiplayerId)) - || (playerBestMonId >= 3 && sub_806D82C(gBattleScripting.multiplayerId))) - { - j = (opponentBestMonId < 3) ? 0 : 1; - PutBattleUpdateOnTheAir(sub_806EF84(j, gBattleScripting.multiplayerId), moveId, playerBestSpecies, opponentBestSpecies); - } - } - else - { - PutBattleUpdateOnTheAir(gBattleScripting.multiplayerId ^ 1, moveId, playerBestSpecies, opponentBestSpecies); - } -} - -#else -ASM_DIRECT -void sub_817E3F4(void) -{ - asm_unified( - "push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x20\n\ - movs r0, 0\n\ - str r0, [sp]\n\ - movs r1, 0\n\ - str r1, [sp, 0x4]\n\ - movs r2, 0\n\ - str r2, [sp, 0x8]\n\ - ldr r3, =0x00007fff\n\ - str r3, [sp, 0xC]\n\ - movs r4, 0\n\ - str r4, [sp, 0x10]\n\ - movs r7, 0\n\ - str r7, [sp, 0x14]\n\ - mov r8, r0\n\ - ldr r0, =gBattleStruct\n\ - ldr r1, [r0]\n\ - adds r0, r1, 0\n\ - adds r0, 0xB3\n\ - ldrb r0, [r0]\n\ - cmp r0, 0\n\ - beq _0817E42A\n\ - b _0817E670\n\ -_0817E42A:\n\ - movs r2, 0xD2\n\ - lsls r2, 1\n\ - adds r2, r1\n\ - mov r10, r2\n\ - movs r6, 0\n\ -_0817E434:\n\ - movs r0, 0x64\n\ - adds r4, r6, 0\n\ - muls r4, r0\n\ - ldr r0, =gPlayerParty\n\ - adds r0, r4, r0\n\ - movs r1, 0xB\n\ - movs r2, 0\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _0817E454\n\ - mov r0, r8\n\ - adds r0, 0x1\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - mov r8, r0\n\ -_0817E454:\n\ - ldr r5, =gEnemyParty\n\ - adds r0, r4, r5\n\ - movs r1, 0xB\n\ - movs r2, 0\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _0817E46A\n\ - adds r0, r7, 0x1\n\ - lsls r0, 24\n\ - lsrs r7, r0, 24\n\ -_0817E46A:\n\ - adds r6, 0x1\n\ - cmp r6, 0x5\n\ - ble _0817E434\n\ - ldr r0, =gBattleTypeFlags\n\ - ldr r0, [r0]\n\ - movs r1, 0x2\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0817E47E\n\ - b _0817E670\n\ -_0817E47E:\n\ - cmp r8, r7\n\ - beq _0817E484\n\ - b _0817E670\n\ -_0817E484:\n\ - movs r6, 0\n\ - lsls r3, r6, 1\n\ - str r3, [sp, 0x18]\n\ - movs r4, 0x64\n\ - mov r8, r4\n\ -_0817E48E:\n\ - mov r1, r8\n\ - muls r1, r6\n\ - ldr r0, =gPlayerParty\n\ - adds r4, r1, r0\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - movs r2, 0\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r7, r0, 16\n\ - adds r0, r6, 0x1\n\ - mov r9, r0\n\ - cmp r7, 0\n\ - beq _0817E4EE\n\ - adds r0, r4, 0\n\ - movs r1, 0x2D\n\ - movs r2, 0\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _0817E4EE\n\ - movs r4, 0\n\ - lsls r0, r6, 3\n\ - mov r2, r10\n\ - adds r1, r0, r2\n\ - movs r3, 0x3\n\ -_0817E4C4:\n\ - lsls r0, r4, 16\n\ - asrs r0, 16\n\ - ldrh r4, [r1]\n\ - adds r0, r4\n\ - lsls r0, 16\n\ - lsrs r4, r0, 16\n\ - adds r1, 0x2\n\ - subs r3, 0x1\n\ - cmp r3, 0\n\ - bge _0817E4C4\n\ - ldr r1, [sp, 0x8]\n\ - lsls r0, r1, 16\n\ - lsls r1, r4, 16\n\ - cmp r0, r1\n\ - bge _0817E4EE\n\ - lsls r0, r6, 24\n\ - lsrs r0, 24\n\ - str r0, [sp, 0x10]\n\ - lsrs r1, 16\n\ - str r1, [sp, 0x8]\n\ - str r7, [sp]\n\ -_0817E4EE:\n\ - mov r0, r8\n\ - muls r0, r6\n\ - ldr r2, =gEnemyParty\n\ - adds r4, r0, r2\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - movs r2, 0\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r7, r0, 16\n\ - ldr r3, [sp, 0x8]\n\ - lsls r3, 16\n\ - str r3, [sp, 0x1C]\n\ - cmp r7, 0\n\ - beq _0817E5A0\n\ - adds r0, r4, 0\n\ - movs r1, 0x2D\n\ - movs r2, 0\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _0817E5A0\n\ - movs r4, 0\n\ - ldr r0, [sp, 0xC]\n\ - lsls r2, r0, 16\n\ - movs r3, 0x1\n\ - lsls r1, r3, 1\n\ - adds r1, 0x1\n\ - lsls r1, 4\n\ - lsls r0, r6, 3\n\ - adds r0, r1\n\ - mov r3, r10\n\ - adds r1, r0, r3\n\ - movs r3, 0x3\n\ -_0817E534:\n\ - lsls r0, r4, 16\n\ - asrs r0, 16\n\ - ldrh r4, [r1]\n\ - adds r0, r4\n\ - lsls r0, 16\n\ - lsrs r4, r0, 16\n\ - adds r1, 0x2\n\ - subs r3, 0x1\n\ - cmp r3, 0\n\ - bge _0817E534\n\ - asrs r1, r2, 16\n\ - lsls r5, r4, 16\n\ - asrs r0, r5, 16\n\ - cmp r1, r0\n\ - bne _0817E590\n\ - mov r0, r8\n\ - muls r0, r6\n\ - ldr r1, =gEnemyParty\n\ - adds r0, r1\n\ - movs r1, 0x19\n\ - movs r2, 0\n\ - bl GetMonData\n\ - adds r4, r0, 0\n\ - ldr r2, [sp, 0x14]\n\ - mov r0, r8\n\ - muls r0, r2\n\ - ldr r3, =gEnemyParty\n\ - adds r0, r3\n\ - movs r1, 0x19\n\ - movs r2, 0\n\ - bl GetMonData\n\ - cmp r4, r0\n\ - bls _0817E5A0\n\ - b _0817E594\n\ - .pool\n\ -_0817E590:\n\ - cmp r1, r0\n\ - ble _0817E5A0\n\ -_0817E594:\n\ - lsls r0, r6, 24\n\ - lsrs r0, 24\n\ - str r0, [sp, 0x14]\n\ - lsrs r5, 16\n\ - str r5, [sp, 0xC]\n\ - str r7, [sp, 0x4]\n\ -_0817E5A0:\n\ - mov r6, r9\n\ - cmp r6, 0x5\n\ - bgt _0817E5A8\n\ - b _0817E48E\n\ -_0817E5A8:\n\ - movs r4, 0\n\ - movs r6, 0\n\ - movs r3, 0\n\ - ldr r5, =gPlayerParty\n\ - ldr r7, [sp, 0x10]\n\ - lsls r0, r7, 3\n\ - mov r1, r10\n\ - adds r2, r0, r1\n\ -_0817E5B8:\n\ - lsls r0, r4, 16\n\ - asrs r0, 16\n\ - movs r7, 0\n\ - ldrsh r1, [r2, r7]\n\ - cmp r0, r1\n\ - bge _0817E5C8\n\ - ldrh r4, [r2]\n\ - adds r6, r3, 0\n\ -_0817E5C8:\n\ - adds r2, 0x2\n\ - adds r3, 0x1\n\ - cmp r3, 0x3\n\ - ble _0817E5B8\n\ - movs r0, 0x64\n\ - ldr r1, [sp, 0x10]\n\ - muls r0, r1\n\ - adds r0, r5\n\ - adds r1, r6, 0\n\ - adds r1, 0xD\n\ - movs r2, 0\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r4, r0, 16\n\ - ldr r2, [sp, 0x1C]\n\ - cmp r2, 0\n\ - beq _0817E670\n\ - cmp r4, 0\n\ - beq _0817E670\n\ - ldr r0, =gBattleTypeFlags\n\ - ldr r0, [r0]\n\ - movs r1, 0x40\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0817E65C\n\ - ldr r3, [sp, 0x10]\n\ - cmp r3, 0x2\n\ - bhi _0817E620\n\ - ldr r0, =gBattleScripting\n\ - adds r0, 0x25\n\ - ldrb r0, [r0]\n\ - bl sub_806D82C\n\ - lsls r0, 16\n\ - cmp r0, 0\n\ - beq _0817E630\n\ - b _0817E670\n\ - .pool\n\ -_0817E620:\n\ - ldr r0, =gBattleScripting\n\ - adds r0, 0x25\n\ - ldrb r0, [r0]\n\ - bl sub_806D82C\n\ - lsls r0, 16\n\ - cmp r0, 0\n\ - beq _0817E670\n\ -_0817E630:\n\ - movs r3, 0\n\ - ldr r7, [sp, 0x14]\n\ - cmp r7, 0x2\n\ - bls _0817E63A\n\ - movs r3, 0x1\n\ -_0817E63A:\n\ - lsls r0, r3, 24\n\ - lsrs r0, 24\n\ - ldr r1, =gBattleScripting\n\ - adds r1, 0x25\n\ - ldrb r1, [r1]\n\ - bl sub_806EF84\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - adds r1, r4, 0\n\ - ldr r2, [sp]\n\ - ldr r3, [sp, 0x4]\n\ - bl PutBattleUpdateOnTheAir\n\ - b _0817E670\n\ - .pool\n\ -_0817E65C:\n\ - ldr r0, =gBattleScripting\n\ - adds r0, 0x25\n\ - ldrb r1, [r0]\n\ - movs r0, 0x1\n\ - eors r0, r1\n\ - adds r1, r4, 0\n\ - ldr r2, [sp]\n\ - ldr r3, [sp, 0x4]\n\ - bl PutBattleUpdateOnTheAir\n\ -_0817E670:\n\ - add sp, 0x20\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .pool"); -} -#endif - -void sub_817E684(u8 caseId, u16 arg1, u8 arg2, u8 arg3) -{ - struct UnknownBattleLinkArrayStruct *array = &gBattleStruct->field_1A4; - struct UnknownBattleLinkStruct *structPtr = &gBattleStruct->field_204; - u32 atkSide = GetBattlerSide(gBattlerAttacker); - u32 defSide = GetBattlerSide(gBattlerTarget); - const u16 *ptr; - s32 i; - - switch (caseId) - { - case 0: - case 1: - case 18: - case 22 ... 27: - array->unk0[atkSide][gBattlerPartyIndexes[gBattlerAttacker] * 4 + arg1] += gUnknown_0860A834[caseId][arg2]; - break; - case 3 ... 7: - i = 0; - ptr = gUnknown_0860A834[caseId]; - do - { - if (arg1 == ptr[i]) - { - array->unk0[atkSide][gBattlerPartyIndexes[gBattlerAttacker] * 4 + arg2] += ptr[i+1]; - break; - } - i += 2; - } while (ptr[i] != 0xFFFF); - break; - case 19: - structPtr->side[arg2 ^ 1].field_3_0 = 0; - array->unk0[arg2][0 * 4 + arg3] += gUnknown_0860A834[caseId][arg1]; - break; - case 20: - structPtr->side[arg2].field_3_0 = 0; - case 2: - array->unk0[arg2][0 * 4 + arg3] += gUnknown_0860A834[caseId][arg1]; - break; - case 17: - array->unk0[atkSide][arg2 * 4 + arg3] += gUnknown_0860A834[caseId][arg1]; - break; - case 8: - case 9: - case 15: - case 16: - case 21: - array->unk0[atkSide ^ BIT_SIDE][arg2 * 4 + arg3] += gUnknown_0860A834[caseId][arg1]; - break; - case 10: - array->unk0[arg1][arg2 * 4 + arg3] += gUnknown_0860A834[caseId][0]; - break; - case 11: - if (structPtr->pos[defSide][0].waterSportMonId != -(structPtr->pos[defSide][1].waterSportMonId) && arg1 == 10) - { - if (structPtr->pos[defSide][0].waterSportMonId != 0) - { - u32 id = (structPtr->pos[defSide][0].waterSportMonId - 1) * 4; - array->unk0[defSide][id + structPtr->pos[defSide][0].waterSportMoveSlot] += gUnknown_0860A834[caseId][0]; - } - if (structPtr->pos[defSide][1].waterSportMonId != 0) - { - u32 id = (structPtr->pos[defSide][1].waterSportMonId - 1) * 4; - array->unk0[defSide][id + structPtr->pos[defSide][1].waterSportMoveSlot] += gUnknown_0860A834[caseId][0]; - } - } - break; - case 12: - if (structPtr->pos[defSide][0].mudSportMonId != -(structPtr->pos[defSide][1].mudSportMonId) && arg1 == 13) - { - if (structPtr->pos[defSide][0].mudSportMonId != 0) - { - u32 id = (structPtr->pos[defSide][0].mudSportMonId - 1) * 4; - array->unk0[defSide][id + structPtr->pos[defSide][0].mudSportMoveSlot] += gUnknown_0860A834[caseId][0]; - } - if (structPtr->pos[defSide][1].mudSportMonId != 0) - { - u32 id = (structPtr->pos[defSide][1].mudSportMonId - 1) * 4; - array->unk0[defSide][id + structPtr->pos[defSide][1].mudSportMoveSlot] += gUnknown_0860A834[caseId][0]; - } - } - break; - case 13: - if (arg1 <= 8 && arg2 != 0 && structPtr->side[defSide].reflectMonId != 0) - { - u32 id = (structPtr->side[defSide].reflectMonId - 1) * 4; - array->unk0[defSide][id + structPtr->side[defSide].reflectMoveSlot] += gUnknown_0860A834[caseId][0]; - } - break; - case 14: - if (arg1 > 8 && arg2 != 0 && structPtr->side[defSide].lightScreenMonId != 0) - { - u32 id = (structPtr->side[defSide].lightScreenMonId - 1) * 4; - array->unk0[defSide][id + structPtr->side[defSide].lightScreenMoveSlot] += gUnknown_0860A834[caseId][0]; - } - break; - break; - } -} - -void sub_817EA80(u8 arg0) -{ - struct UnknownBattleLinkStruct *structPtr = &gBattleStruct->field_204; - u32 atkSide = GetBattlerSide(gBattlerAttacker); - u32 defSide = GetBattlerSide(gBattlerTarget); - u32 atkArrId = structPtr->side[atkSide].field_3_1; - s32 i; - - if (structPtr->side[atkSide].field_3_0 != 0) - { - switch (structPtr->side[atkSide].field_3_0) - { - case 1: - if (structPtr->pos[atkSide][atkArrId].curseMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->pos[atkSide][atkArrId].curseMonId - 1) * 4 + structPtr->pos[atkSide][atkArrId].curseMoveSlot); - } - break; - case 2: - if (structPtr->pos[atkSide][atkArrId].leechSeedMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->pos[atkSide][atkArrId].leechSeedMonId - 1) * 4 + structPtr->pos[atkSide][atkArrId].leechSeedMoveSlot); - } - break; - case 3: - if (structPtr->mon[atkSide][atkArrId].psnMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->mon[atkSide][atkArrId].psnMonId - 1) * 4 + structPtr->mon[atkSide][atkArrId].psnMoveSlot); - } - if (structPtr->mon[atkSide][atkArrId].badPsnMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->mon[atkSide][atkArrId].badPsnMonId - 1) * 4 + structPtr->mon[atkSide][atkArrId].badPsnMoveSlot); - } - break; - case 4: - if (structPtr->mon[atkSide][atkArrId].brnMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->mon[atkSide][atkArrId].brnMonId - 1) * 4 + structPtr->mon[atkSide][atkArrId].brnMoveSlot); - } - break; - case 5: - if (structPtr->pos[atkSide][atkArrId].nightmareMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->pos[atkSide][atkArrId].nightmareMonId - 1) * 4 + structPtr->pos[atkSide][atkArrId].nightmareMoveSlot); - } - break; - case 6: - if (structPtr->pos[atkSide][atkArrId].wrapMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->pos[atkSide][atkArrId].wrapMonId - 1) * 4 + structPtr->pos[atkSide][atkArrId].wrapMoveSlot); - } - break; - case 7: - if (structPtr->side[atkSide].spikesMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->side[atkSide].spikesMonId - 1) * 4 + structPtr->side[atkSide].spikesMoveSlot); - } - break; - case 8: - if (structPtr->side[atkSide].futureSightMonId != 0) - { - sub_817E684(20, 0, atkSide, - (structPtr->side[atkSide].futureSightMonId - 1) * 4 + structPtr->side[atkSide].futureSightMoveSlot); - } - break; - case 9: - if (structPtr->side[atkSide].doomDesireMonId != 0) - { - sub_817E684(20, 0, atkSide, - (structPtr->side[atkSide].doomDesireMonId - 1) * 4 + structPtr->side[atkSide].doomDesireMoveSlot); - } - break; - case 10: - if (structPtr->side[atkSide].perishSong - && structPtr->side[atkSide].perishSongMonId - 1 != gBattlerPartyIndexes[gBattlerAttacker]) - { - sub_817E684(19, 0, atkSide, - (structPtr->side[atkSide].perishSongMonId - 1) * 4 + structPtr->side[atkSide].perishSongMoveSlot); - } - if (structPtr->side[atkSide ^ BIT_SIDE].perishSong) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->side[atkSide ^ BIT_SIDE].perishSongMonId - 1) * 4 + structPtr->side[atkSide ^ BIT_SIDE].perishSongMoveSlot); - } - break; - case 11: - if (structPtr->side[atkSide ^ BIT_SIDE].destinyBondMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->side[atkSide ^ BIT_SIDE].destinyBondMonId - 1) * 4 + structPtr->side[atkSide ^ BIT_SIDE].destinyBondMoveSlot); - } - break; - case 12: - for (i = 0; i < 2; i++) - { - if (structPtr->pos[atkSide][i].confusionMonId != 0) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->pos[atkSide][i].confusionMonId - 1) * 4 + structPtr->pos[atkSide][i].confusionMoveSlot); - } - } - break; - case 13: - if (structPtr->side[atkSide].explosion) - { - sub_817E684(19, 0, atkSide, - (structPtr->side[atkSide].explosionMonId - 1) * 4 + structPtr->side[atkSide].explosionMoveSlot); - } - if (structPtr->side[atkSide ^ BIT_SIDE].explosion) - { - sub_817E684(19, 0, atkSide ^ BIT_SIDE, - (structPtr->side[atkSide ^ BIT_SIDE].explosionMonId - 1) * 4 + structPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot); - } - break; - case 14: - if (arg0 == 1) - { - sub_817E684(20, 0, atkSide, - (gBattlerPartyIndexes[gBattlerAttacker]) * 4 + structPtr->side[atkSide].field_8_6); - } - break; - case 15: - break; - } - } - else - { - if (structPtr->side[defSide].field_3_0 == 7) - { - if (structPtr->side[defSide].spikesMonId != 0) - { - sub_817E684(19, 0, defSide ^ BIT_SIDE, - (structPtr->side[defSide].spikesMonId - 1) * 4 + structPtr->side[defSide].spikesMoveSlot); - } - } - else - { - sub_817E684(20, 0, atkSide, - (gBattlerPartyIndexes[gBattlerAttacker]) * 4 + structPtr->side[atkSide].field_8_6); - } - } -} - -void sub_817EECC(void) -{ - s32 i; - s32 dmgByMove[4]; - u16 powerOverride; - u16 currMoveSaved; - - if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) - return; - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT) - return; - if (gBattleMons[gBattlerAttacker].statStages[STAT_ACC] <= 5) - return; - if (gBattleMons[gBattlerTarget].statStages[STAT_EVASION] > 6) - return; - if (gCurrentMove == MOVE_HIDDEN_POWER || gCurrentMove == MOVE_WEATHER_BALL) - return; - if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID)) - return; - if (gBattleMoves[gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]].power == 0) - return; - - i = 0; - currMoveSaved = gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]; - while (1) - { - if (currMoveSaved == gUnknown_0860A4AC[i]) - break; - i++; - if (gUnknown_0860A4AC[i] == 0xFFFF) - break; - } - - if (gUnknown_0860A4AC[i] != 0xFFFF) - return; - - dmgByMove[gMoveSelectionCursor[gBattlerAttacker]] = gBattleMoveDamage; - currMoveSaved = gCurrentMove; - for (i = 0; i < 4; i++) - { - gCurrentMove = gBattleMons[gBattlerAttacker].moves[i]; - powerOverride = 0; - if (sub_817F21C(gCurrentMove, &dmgByMove[i], &powerOverride)) - { - u8 moveResultFlags; - u16 sideStatus = gSideStatuses[GET_BATTLER_SIDE(gBattlerTarget)]; - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBattlerAttacker], &gBattleMons[gBattlerTarget], gCurrentMove, - sideStatus, powerOverride, - 0, gBattlerAttacker, gBattlerTarget); - - if (gStatuses3[gBattlerAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) - gBattleMoveDamage *= 2; - if (gProtectStructs[gBattlerAttacker].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; - - moveResultFlags = TypeCalc(gCurrentMove, gBattlerAttacker, gBattlerTarget); - dmgByMove[i] = gBattleMoveDamage; - if (dmgByMove[i] == 0 && !(moveResultFlags & MOVE_RESULT_NO_EFFECT)) - dmgByMove[i] = 1; - } - } - - for (i = 0; i < 4; i++) - { - if (i != gMoveSelectionCursor[gBattlerAttacker] && dmgByMove[i] > dmgByMove[gMoveSelectionCursor[gBattlerAttacker]]) - { - u16 opponentSpecies, playerSpecies; - s32 bestMoveId; - - if (gMoveSelectionCursor[gBattlerAttacker] != 0) - bestMoveId = 0; - else - bestMoveId = 1; - - for (i = 0; i < 4; i++) - { - if (i != gMoveSelectionCursor[gBattlerAttacker] && dmgByMove[i] > dmgByMove[bestMoveId]) - bestMoveId = i; - } - - opponentSpecies = GetMonData(&gEnemyParty [gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_SPECIES, NULL); - playerSpecies = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_SPECIES, NULL); - sub_80EE35C(opponentSpecies, playerSpecies, gMoveSelectionCursor[gBattlerAttacker], gBattleMons[gBattlerAttacker].moves, gBattleMons[gBattlerAttacker].moves[bestMoveId]); - break; - } - } - - gBattleMoveDamage = dmgByMove[gMoveSelectionCursor[gBattlerAttacker]]; - gCurrentMove = currMoveSaved; -} diff --git a/src/battle_tv.c b/src/battle_tv.c new file mode 100644 index 0000000000..bd3de548bc --- /dev/null +++ b/src/battle_tv.c @@ -0,0 +1,1585 @@ +#include "global.h" +#include "pokemon.h" +#include "battle.h" +#include "battle_tv.h" +#include "constants/battle_string_ids.h" +#include "constants/battle_anim.h" +#include "constants/moves.h" +#include "constants/species.h" +#include "battle_message.h" +#include "tv.h" + +extern struct StringInfoBattle *gStringInfo; + +extern const struct BattleMove gBattleMoves[]; + +// this file's functions +static bool8 sub_817E0B8(u16 stringId); +static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3); +static void TrySetBattleSeminarShow(void); +static void AddPointsOnFainting(bool8 targetFainted); +static void AddPointsBasedOnWeather(u16 weatherFlags, u16 moveId, u8 moveSlot); +static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride); + +// const rom data +static const u16 sVariableDmgMoves[] = +{ + MOVE_COUNTER, MOVE_FISSURE, MOVE_BIDE, MOVE_MIRROR_COAT, + MOVE_HORN_DRILL, MOVE_FLAIL, MOVE_REVERSAL, MOVE_HIDDEN_POWER, + MOVE_SHEER_COLD, MOVE_FOCUS_PUNCH, MOVE_ERUPTION, + MOVE_WATER_SPOUT, MOVE_DREAM_EATER, MOVE_WEATHER_BALL, + MOVE_SNORE, MOVE_PAIN_SPLIT, MOVE_GUILLOTINE, + MOVE_FRUSTRATION, MOVE_RETURN, MOVE_ENDEAVOR, + MOVE_PRESENT, MOVE_REVENGE, 0xFFFF, + // those are handled by the function itself + MOVE_MAGNITUDE, MOVE_PSYWAVE, 0xFFFF +}; + +static const u16 sUnknown_0860A4E0[] = +{ + 0x0001, 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0001, 0x0000, 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0005, 0x0005, 0x0004, 0x0005, 0x0001, 0x0003, 0x0001, + 0x0003, 0x0005, 0x0001, 0x0007, 0x0001, 0x0007, 0x0007, 0x0001, 0x0005, 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0005, 0x0001, + 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0007, 0x0004, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0001, 0x0004, + 0x0005, 0x0002, 0x0004, 0x0001, 0x0004, 0x0001, 0x0007, 0x0002, 0x0001, 0x0005, 0x0007, 0x0003, 0x0003, 0x0004, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0002, 0x0004, 0x0001, 0x0005, 0x0001, 0x0001, 0x0004, 0x0005, 0x0003, 0x0001, 0x0002, 0x0001, 0x0005, + 0x0004, 0x0003, 0x0006, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0005, 0x0001, 0x0001, 0x0007, + 0x0002, 0x0002, 0x0001, 0x0001, 0x0004, 0x0004, 0x0004, 0x0001, 0x0004, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0007, 0x0007, + 0x0006, 0x0003, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003, 0x0001, 0x0001, 0x0004, 0x0004, + 0x0003, 0x0003, 0x0003, 0x0001, 0x0004, 0x0007, 0x0007, 0x0005, 0x0007, 0x0001, 0x0007, 0x0001, 0x0005, 0x0000, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0006, 0x0003, 0x0006, 0x0004, 0x0004, 0x0002, 0x0005, 0x0002, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0006, 0x0001, 0x0004, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0003 +}; +static const u16 sUnknown_0860A68C[] = +{ + 0x0004, 0xfffd, 0xfffa +}; +static const u16 sUnknown_0860A692[] = +{ + 0x0004, 0x0004, 0x0006, 0x0006, 0x0007, 0x0006, 0x0002 +}; +static const u16 sUnknown_0860A6A0[] = +{ + 0x0091, 0x0003, 0x00fa, 0x0003, 0x00be, 0x0003, 0x0080, 0x0003, 0x006e, 0x0003, 0x0098, 0x0003, 0x0143, 0x0003, 0x0123, 0x0003, + 0x007f, 0x0003, 0x014a, 0x0003, 0x0039, 0x0003, 0x0134, 0x0003, 0x0038, 0x0003, 0x003d, 0x0003, 0x015a, 0x0000, 0x0037, 0x0003, + 0x0160, 0x0003, 0x0137, 0x0003, 0x0057, 0x0003, 0x004c, 0xfffc, 0x013b, 0xfffc, 0x00ac, 0xfffc, 0x0035, 0xfffc, 0x00dd, 0xfffc, + 0x007e, 0xfffc, 0x0101, 0xfffc, 0x0034, 0xfffc, 0x0133, 0xfffc, 0x012b, 0xfffc, 0x011c, 0xfffc, 0x0053, 0xfffc, 0x0007, 0xfffc, + 0x004c, 0xfffc, 0xffff, 0x0000 +}; +static const u16 sUnknown_0860A728[] = +{ + 0x013b, 0x0003, 0x00ac, 0x0003, 0x0035, 0x0003, 0x00dd, 0x0003, 0x007e, 0x0003, 0x0101, 0x0003, 0x0034, 0x0003, 0x0133, 0x0003, + 0x012b, 0x0003, 0x011c, 0x0003, 0x0053, 0x0003, 0x0007, 0x0003, 0x004c, 0x0005, 0x00eb, 0x0003, 0x00ea, 0x0003, 0x00ec, 0x0003, + 0x0137, 0x0003, 0xffff, 0x0000 +}; +static const u16 sUnknown_0860A770[] = +{ + 0x0137, 0x0003, 0x004c, 0xfffd, 0xffff, 0x0000 +}; +static const u16 sUnknown_0860A77C[] = +{ + 0x0137, 0x0003, 0x004c, 0xfffd, 0xffff, 0x0000 +}; +static const u16 sUnknown_0860A788[] = +{ + 0x0055, 0x0003, 0x0009, 0x0003, 0x00d1, 0x0003, 0x0054, 0x0003, 0x00c0, 0x0003, 0x015f, 0x0003, 0x0056, 0x0000, 0x0057, 0x0003, + 0x0158, 0x0003, 0xffff, 0x0000 +}; +static const u16 sUnknown_0860A7B0[] = +{ + 0x0005, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003 +}; +static const u16 sUnknown_0860A7BE[] = +{ + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005 +}; +static const u16 sUnknown_0860A7C8[] = +{ + 0x0004 +}; +static const u16 sUnknown_0860A7CA[] = +{ + 0x0005 +}; +static const u16 sUnknown_0860A7CC[] = +{ + 0x0005 +}; +static const u16 sUnknown_0860A7CE[] = +{ + 0x0003 +}; +static const u16 sUnknown_0860A7D0[] = +{ + 0x0003 +}; +static const u16 sUnknown_0860A7D2[] = +{ + 0x0004 +}; +static const u16 sUnknown_0860A7D4[] = +{ + 0x0003 +}; +static const u16 sUnknown_0860A7D6[] = +{ + 0x0006 +}; +static const u16 sUnknown_0860A7D8[] = +{ + 0x0006 +}; +static const u16 sUnknown_0860A7DA[] = +{ + 0x0006 +}; +static const u16 sUnknown_0860A7DC[] = +{ + 0x0004 +}; +static const u16 sUnknown_0860A7DE[] = +{ + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002 +}; +static const u16 sUnknown_0860A7EC[] = +{ + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004 +}; +static const u16 sUnknown_0860A7FA[] = +{ + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff +}; +static const u16 sUnknown_0860A808[] = +{ + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002 +}; +static const u16 sUnknown_0860A816[] = +{ + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004 +}; +static const u16 sUnknown_0860A824[] = +{ + 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe +}; + +static const u16 *const sPointsArray[] = +{ + sUnknown_0860A4E0, + sUnknown_0860A68C, + sUnknown_0860A692, + sUnknown_0860A6A0, + sUnknown_0860A728, + sUnknown_0860A770, + sUnknown_0860A77C, + sUnknown_0860A788, + sUnknown_0860A7B0, + sUnknown_0860A7BE, + sUnknown_0860A7C8, + sUnknown_0860A7CA, + sUnknown_0860A7CC, + sUnknown_0860A7CE, + sUnknown_0860A7D0, + sUnknown_0860A7D2, + sUnknown_0860A7D4, + sUnknown_0860A7D6, + sUnknown_0860A7D8, + sUnknown_0860A7DA, + sUnknown_0860A7DA, + sUnknown_0860A7DC, + sUnknown_0860A7DE, + sUnknown_0860A7EC, + sUnknown_0860A7FA, + sUnknown_0860A808, + sUnknown_0860A816, + sUnknown_0860A824 +}; + +static const u16 sUnknown_0860A8A4[] = +{ + STRINGID_PKMNPERISHCOUNTFELL, STRINGID_PKMNWISHCAMETRUE, STRINGID_PKMNLOSTPPGRUDGE, + STRINGID_PKMNTOOKFOE, STRINGID_PKMNABSORBEDNUTRIENTS, STRINGID_PKMNANCHOREDITSELF, + STRINGID_PKMNAFFLICTEDBYCURSE, STRINGID_PKMNSAPPEDBYLEECHSEED, STRINGID_PKMNLOCKEDINNIGHTMARE, + STRINGID_PKMNHURTBY, STRINGID_PKMNHURTBYBURN, STRINGID_PKMNHURTBYPOISON, + STRINGID_PKMNHURTBYSPIKES, STRINGID_ATTACKERFAINTED, STRINGID_TARGETFAINTED, + STRINGID_PKMNHITWITHRECOIL, STRINGID_PKMNCRASHED, 0xFFFF +}; + +// code +void BattleTv_SetDataBasedOnString(u16 stringId) +{ + struct BattleTv *tvPtr; + u32 atkSide, defSide, effSide, scriptingSide; + struct Pokemon *atkMon, *defMon; + u8 moveSlot; + u32 atkFlank, defFlank, effFlank; + u8 *perishCount; + u16 *statStringId, *finishedMoveId; + + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && stringId != STRINGID_ITDOESNTAFFECT && stringId != STRINGID_NOTVERYEFFECTIVE) + return; + + tvPtr = &gBattleStruct->tv; + + atkSide = GetBattlerSide(gBattlerAttacker); + defSide = GetBattlerSide(gBattlerTarget); + effSide = GetBattlerSide(gEffectBattler); + scriptingSide = GetBattlerSide(gStringInfo->scrActive); + + if (atkSide == B_SIDE_PLAYER) + atkMon = &gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]]; + else + atkMon = &gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]]; + + if (defSide == B_SIDE_PLAYER) + defMon = &gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]]; + else + defMon = &gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]]; + + moveSlot = GetBattlerMoveSlotId(gBattlerAttacker, gStringInfo->currentMove); + + if (moveSlot >= 4 && sub_817E0B8(stringId) && stringId > BATTLESTRINGS_ID_ADDER) + { + tvPtr->side[atkSide].faintCause = 15; + return; + } + + perishCount = (u8 *)(gBattleTextBuff1 + 4); + statStringId = (u16 *)(gBattleTextBuff2 + 2); + finishedMoveId = (u16 *)(gBattleTextBuff1 + 2); + + atkFlank = GetBattlerPosition(gBattlerAttacker) / 2; + defFlank = GetBattlerPosition(gBattlerTarget) / 2; + effFlank = GetBattlerPosition(gEffectBattler) / 2; + + switch (stringId) + { + case STRINGID_ITDOESNTAFFECT: + AddMovePoints(1, moveSlot, 2, 0); + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) + TrySetBattleSeminarShow(); + break; + case STRINGID_NOTVERYEFFECTIVE: + AddMovePoints(1, moveSlot, 1, 0); + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && GetMonData(defMon, MON_DATA_HP, NULL) != 0) + TrySetBattleSeminarShow(); + break; + case STRINGID_SUPEREFFECTIVE: + AddMovePoints(1, moveSlot, 0, 0); + break; + case STRINGID_PKMNFORESAWATTACK: + tvPtr->side[atkSide].futureSightMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].futureSightMoveSlot = moveSlot; + break; + case STRINGID_PKMNCHOSEXASDESTINY: + tvPtr->side[atkSide].doomDesireMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].doomDesireMoveSlot = moveSlot; + break; + case STRINGID_FAINTINTHREE: + tvPtr->side[atkSide].perishSongMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].perishSongMoveSlot = moveSlot; + tvPtr->side[atkSide].perishSong = 1; + break; + case STRINGID_PKMNPERISHCOUNTFELL: + if (*perishCount == 0) + tvPtr->side[atkSide].faintCause = 10; + break; + case STRINGID_PKMNWISHCAMETRUE: + if (tvPtr->side[defSide].wishMonId != 0) + { + AddMovePoints(2, 3, defSide, + (tvPtr->side[defSide].wishMonId - 1) * 4 + tvPtr->side[defSide].wishMoveSlot); + } + break; + case STRINGID_PKMNWANTSGRUDGE: + tvPtr->side[atkSide].grudgeMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].grudgeMoveSlot = moveSlot; + break; + case STRINGID_PKMNLOSTPPGRUDGE: + if (tvPtr->side[defSide].grudgeMonId != 0) + { + AddMovePoints(2, 4, defSide, + (tvPtr->side[defSide].grudgeMonId - 1) * 4 + tvPtr->side[defSide].grudgeMoveSlot); + } + break; + case STRINGID_PKMNTRYINGTOTAKEFOE: + tvPtr->side[atkSide].destinyBondMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].destinyBondMoveSlot = moveSlot; + break; + case STRINGID_PKMNTOOKFOE: + if (tvPtr->side[defSide].destinyBondMonId != 0) + tvPtr->side[atkSide].faintCause = 11; + break; + case STRINGID_PKMNPLANTEDROOTS: + tvPtr->pos[atkSide][atkFlank].ingrainMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[atkSide][atkFlank].ingrainMoveSlot = moveSlot; + break; + case STRINGID_PKMNABSORBEDNUTRIENTS: + if (tvPtr->pos[atkSide][atkFlank].ingrainMonId != 0) + { + AddMovePoints(2, 6, atkSide, + (tvPtr->pos[atkSide][atkFlank].ingrainMonId - 1) * 4 + tvPtr->pos[atkSide][atkFlank].ingrainMoveSlot); + } + break; + case STRINGID_PKMNANCHOREDITSELF: + if (tvPtr->pos[defSide][defFlank].ingrainMonId != 0) + { + AddMovePoints(2, 6, defSide, + (tvPtr->pos[defSide][defFlank].ingrainMonId - 1) * 4 + tvPtr->pos[defSide][defFlank].ingrainMoveSlot); + } + break; + case STRINGID_PKMNTRANSFORMEDINTO: + gBattleStruct->anyMonHasTransformed = TRUE; + break; + case STRINGID_CRITICALHIT: + AddMovePoints(0x12, moveSlot, 0, 0); + break; + case STRINGID_PKMNSSTATCHANGED: + if (gBattleTextBuff1[2] != 0) + { + if (*statStringId == STRINGID_STATSHARPLY) + AddMovePoints(0x17, moveSlot, gBattleTextBuff1[2] - 1, 0); + else + AddMovePoints(0x16, moveSlot, gBattleTextBuff1[2] - 1, 0); + } + break; + case STRINGID_PKMNSSTATCHANGED2: + if (gBattleTextBuff1[2] != 0) + { + if (gBattlerAttacker == gBattlerTarget) + { + if (*statStringId == STRINGID_STATSHARPLY) + AddMovePoints(0x17, moveSlot, gBattleTextBuff1[2] - 1, 0); + else + AddMovePoints(0x16, moveSlot, gBattleTextBuff1[2] - 1, 0); + } + else + { + AddMovePoints(0x1B, moveSlot, gBattleTextBuff1[2] - 1, 0); + } + } + break; + case STRINGID_PKMNSSTATCHANGED3: + if (gBattleTextBuff1[2] != 0) + AddMovePoints(0x18, moveSlot, gBattleTextBuff1[2] - 1, 0); + break; + case STRINGID_PKMNSSTATCHANGED4: + if (gBattleTextBuff1[2] != 0) + { + if (*statStringId == STRINGID_STATHARSHLY) + AddMovePoints(0x1A, moveSlot, gBattleTextBuff1[2] - 1, 0); + else + AddMovePoints(0x19, moveSlot, gBattleTextBuff1[2] - 1, 0); + } + break; + case STRINGID_PKMNLAIDCURSE: + tvPtr->pos[defSide][defFlank].curseMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[defSide][defFlank].curseMoveSlot = moveSlot; + break; + case STRINGID_PKMNAFFLICTEDBYCURSE: + if (GetMonData(atkMon, MON_DATA_HP, NULL) + && tvPtr->pos[atkSide][atkFlank].curseMonId != 0) + { + AddMovePoints(8, 0, tvPtr->pos[atkSide][atkFlank].curseMonId - 1, tvPtr->pos[atkSide][atkFlank].curseMoveSlot); + tvPtr->side[atkSide].faintCause = 1; + tvPtr->side[atkSide].faintCauseMonId = atkFlank; + } + break; + case STRINGID_PKMNSEEDED: + tvPtr->pos[defSide][defFlank].leechSeedMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[defSide][defFlank].leechSeedMoveSlot = moveSlot; + break; + case STRINGID_PKMNSAPPEDBYLEECHSEED: + if (tvPtr->pos[atkSide][atkFlank].leechSeedMonId != 0) + { + AddMovePoints(8, 1, tvPtr->pos[atkSide][atkFlank].leechSeedMonId - 1, tvPtr->pos[atkSide][atkFlank].leechSeedMoveSlot); + tvPtr->side[atkSide].faintCause = 2; + tvPtr->side[atkSide].faintCauseMonId = atkFlank; + } + break; + case STRINGID_PKMNFELLINTONIGHTMARE: + tvPtr->pos[defSide][defFlank].nightmareMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[defSide][defFlank].nightmareMoveSlot = moveSlot; + break; + case STRINGID_PKMNLOCKEDINNIGHTMARE: + if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0 + && tvPtr->pos[atkSide][atkFlank].nightmareMonId != 0) + { + AddMovePoints(8, 5, tvPtr->pos[atkSide][atkFlank].nightmareMonId - 1, tvPtr->pos[atkSide][atkFlank].nightmareMoveSlot); + tvPtr->side[atkSide].faintCause = 5; + tvPtr->side[atkSide].faintCauseMonId = atkFlank; + } + break; + case STRINGID_PKMNSQUEEZEDBYBIND: + case STRINGID_PKMNTRAPPEDINVORTEX: + case STRINGID_PKMNWRAPPEDBY: + case STRINGID_PKMNCLAMPED: + case STRINGID_PKMNTRAPPEDBYSANDTOMB: + tvPtr->pos[defSide][defFlank].wrapMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[defSide][defFlank].wrapMoveSlot = moveSlot; + break; + case STRINGID_PKMNHURTBY: + if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0 + && tvPtr->pos[atkSide][atkFlank].wrapMonId != 0) + { + AddMovePoints(8, 6, tvPtr->pos[atkSide][atkFlank].wrapMonId - 1, tvPtr->pos[atkSide][atkFlank].wrapMoveSlot); + tvPtr->side[atkSide].faintCause = 6; + tvPtr->side[atkSide].faintCauseMonId = atkFlank; + } + break; + case STRINGID_PKMNWASBURNED: + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].brnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].brnMoveSlot = moveSlot; + break; + case STRINGID_PKMNHURTBYBURN: + if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0) + { + if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMonId != 0) + AddMovePoints(8, 4, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMoveSlot); + tvPtr->side[atkSide].faintCause = 4; + tvPtr->side[atkSide].faintCauseMonId = gBattlerPartyIndexes[gBattlerAttacker]; + } + break; + case STRINGID_PKMNWASPOISONED: + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].psnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].psnMoveSlot = moveSlot; + break; + case STRINGID_PKMNBADLYPOISONED: + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].badPsnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].badPsnMoveSlot = moveSlot; + break; + case STRINGID_PKMNHURTBYPOISON: + if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0) + { + if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMonId != 0) + AddMovePoints(8, 2, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMoveSlot); + if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMonId != 0) + AddMovePoints(8, 3, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMoveSlot); + tvPtr->side[atkSide].faintCause = 3; + tvPtr->side[atkSide].faintCauseMonId = gBattlerPartyIndexes[gBattlerAttacker]; + } + break; + case STRINGID_PKMNFELLINLOVE: + tvPtr->pos[defSide][defFlank].attractMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[defSide][defFlank].attractMoveSlot = moveSlot; + break; + case STRINGID_PKMNIMMOBILIZEDBYLOVE: + if (tvPtr->pos[atkSide][atkFlank].attractMonId != 0) + AddMovePoints(9, 0, tvPtr->pos[atkSide][atkFlank].attractMonId - 1, tvPtr->pos[atkSide][atkFlank].attractMoveSlot); + break; + case STRINGID_PKMNWASPARALYZED: + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].prlzMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].prlzMoveSlot = moveSlot; + break; + case STRINGID_PKMNISPARALYZED: + if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMonId != 0) + AddMovePoints(9, 2, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMoveSlot); + break; + case STRINGID_PKMNFELLASLEEP: + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].slpMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].slpMoveSlot = moveSlot; + break; + case STRINGID_PKMNFASTASLEEP: + if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMonId != 0 + && gStringInfo->currentMove != MOVE_SNORE + && gStringInfo->currentMove != MOVE_SLEEP_TALK) + AddMovePoints(9, 3, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMoveSlot); + break; + case STRINGID_PKMNWASFROZEN: + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].frzMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].frzMoveSlot = moveSlot; + break; + case STRINGID_PKMNISFROZEN: + if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMonId != 0) + AddMovePoints(9, 4, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMoveSlot); + break; + case STRINGID_PKMNWASCONFUSED: + tvPtr->pos[effSide][effFlank].confusionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[effSide][effFlank].confusionMoveSlot = moveSlot; + break; + case STRINGID_ITHURTCONFUSION: + if (tvPtr->pos[atkSide][atkFlank].confusionMonId != 0) + AddMovePoints(9, 1, tvPtr->pos[atkSide][atkFlank].confusionMonId - 1, tvPtr->pos[atkSide][atkFlank].confusionMoveSlot); + tvPtr->side[atkSide].faintCause = 12; + break; + case STRINGID_SPIKESSCATTERED: + tvPtr->side[defSide].spikesMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[defSide].spikesMoveSlot = moveSlot; + break; + case STRINGID_PKMNHURTBYSPIKES: + if (tvPtr->side[scriptingSide].spikesMonId != 0) + { + AddMovePoints(10, scriptingSide ^ BIT_SIDE, tvPtr->side[scriptingSide].spikesMonId - 1, tvPtr->side[scriptingSide].spikesMoveSlot); + tvPtr->side[scriptingSide].faintCause = 7; + } + break; + case STRINGID_PKMNBLEWAWAYSPIKES: + tvPtr->side[atkSide].spikesMonId = 0; + tvPtr->side[atkSide].spikesMoveSlot = 0; + break; + case STRINGID_FIREWEAKENED: + tvPtr->pos[atkSide][atkFlank].waterSportMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[atkSide][atkFlank].waterSportMoveSlot = moveSlot; + break; + case STRINGID_ELECTRICITYWEAKENED: + tvPtr->pos[atkSide][atkFlank].mudSportMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[atkSide][atkFlank].mudSportMoveSlot = moveSlot; + break; + case STRINGID_ATTACKERFAINTED: + AddPointsOnFainting(FALSE); + case STRINGID_RETURNMON: + if (tvPtr->pos[atkSide][atkFlank].waterSportMonId != 0) + { + tvPtr->pos[atkSide][atkFlank].waterSportMonId = 0; + tvPtr->pos[atkSide][atkFlank].waterSportMoveSlot = 0; + } + if (tvPtr->pos[atkSide][atkFlank].mudSportMonId != 0) + { + tvPtr->pos[atkSide][atkFlank].mudSportMonId = 0; + tvPtr->pos[atkSide][atkFlank].mudSportMoveSlot = 0; + } + break; + case STRINGID_TARGETFAINTED: + AddPointsOnFainting(TRUE); + if (tvPtr->pos[atkSide][defFlank].waterSportMonId != 0) + { + tvPtr->pos[atkSide][defFlank].waterSportMonId = 0; + tvPtr->pos[atkSide][defFlank].waterSportMoveSlot = 0; + } + if (tvPtr->pos[atkSide][defFlank].mudSportMonId != 0) + { + tvPtr->pos[atkSide][defFlank].mudSportMonId = 0; + tvPtr->pos[atkSide][defFlank].mudSportMoveSlot = 0; + } + break; + case STRINGID_PKMNRAISEDDEF: + case STRINGID_PKMNRAISEDDEFALITTLE: + tvPtr->side[atkSide].reflectMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].reflectMoveSlot = moveSlot; + break; + case STRINGID_PKMNRAISEDSPDEF: + case STRINGID_PKMNRAISEDSPDEFALITTLE: + tvPtr->side[atkSide].lightScreenMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].lightScreenMoveSlot = moveSlot; + break; + case STRINGID_PKMNSXWOREOFF: + if (*finishedMoveId == MOVE_REFLECT) + { + tvPtr->side[atkSide].reflectMonId = 0; + tvPtr->side[atkSide].reflectMoveSlot = 0; + } + if (*finishedMoveId == MOVE_LIGHT_SCREEN) + { + tvPtr->side[atkSide].lightScreenMonId = 0; + tvPtr->side[atkSide].lightScreenMoveSlot = 0; + } + if (*finishedMoveId == MOVE_MIST) + { + tvPtr->side[atkSide].mistMonId = 0; + tvPtr->side[atkSide].mistMoveSlot = 0; + } + break; + case STRINGID_PKMNCOVEREDBYVEIL: + tvPtr->side[atkSide].safeguardMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].safeguardMoveSlot = moveSlot; + break; + case STRINGID_PKMNUSEDSAFEGUARD: + if (tvPtr->side[defSide].safeguardMonId != 0) + AddMovePoints(15, 0, tvPtr->side[defSide].safeguardMonId - 1, tvPtr->side[defSide].safeguardMoveSlot); + break; + case STRINGID_PKMNSAFEGUARDEXPIRED: + tvPtr->side[atkSide].safeguardMonId = 0; + tvPtr->side[atkSide].safeguardMoveSlot = 0; + break; + case STRINGID_PKMNSHROUDEDINMIST: + tvPtr->side[atkSide].mistMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].mistMoveSlot = moveSlot; + break; + case STRINGID_PKMNPROTECTEDBYMIST: + if (tvPtr->side[defSide].mistMonId != 0) + AddMovePoints(16, 0, tvPtr->side[defSide].mistMonId - 1, tvPtr->side[defSide].mistMoveSlot); + break; + case STRINGID_THEWALLSHATTERED: + tvPtr->side[defSide].reflectMonId = 0; + tvPtr->side[defSide].reflectMoveSlot = 0; + tvPtr->side[defSide].lightScreenMonId = 0; + tvPtr->side[defSide].lightScreenMoveSlot = 0; + AddMovePoints(17, 0, gBattlerPartyIndexes[gBattlerAttacker], moveSlot); + break; + case STRINGID_PKMNFLINCHED: + if (tvPtr->pos[atkSide][0].attackedByMonId != 0) + AddMovePoints(21, 0, tvPtr->pos[atkSide][0].attackedByMonId - 1, tvPtr->pos[atkSide][0].attackedByMoveSlot); + if (tvPtr->pos[atkSide][1].attackedByMonId != 0) + AddMovePoints(21, 0, tvPtr->pos[atkSide][1].attackedByMonId - 1, tvPtr->pos[atkSide][1].attackedByMoveSlot); + break; + case STRINGID_PKMNCRASHED: + case STRINGID_PKMNHITWITHRECOIL: + tvPtr->side[atkSide].faintCause = 14; + break; + } +} + +static bool8 sub_817E0B8(u16 stringId) +{ + s32 i = 0; + + while (1) + { + if (sUnknown_0860A8A4[i] == stringId) + break; + i++; + if (sUnknown_0860A8A4[i] == 0xFFFF) + break; + } + + if (sUnknown_0860A8A4[i] == 0xFFFF) + return TRUE; + else + return FALSE; +} + +void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruct *disableStructPtr) +{ + struct BattleTv *tvPtr; + u32 atkSide, defSide; + u8 moveSlot; + + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) + return; + + tvPtr = &gBattleStruct->tv; + + atkSide = GetBattlerSide(gBattlerAttacker); + defSide = GetBattlerSide(gBattlerTarget); + moveSlot = GetBattlerMoveSlotId(gBattlerAttacker, move); + + if (moveSlot >= 4) + { + tvPtr->side[atkSide].faintCause = 15; + return; + } + + tvPtr->pos[defSide][GetBattlerPosition(gBattlerAttacker) / 2].attackedByMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->pos[defSide][GetBattlerPosition(gBattlerAttacker) / 2].attackedByMoveSlot = moveSlot; + tvPtr->side[atkSide].usedMoveSlot = moveSlot; + AddMovePoints(0, moveSlot, gBattleMoves[move].effect, 0); + AddPointsBasedOnWeather(weatherFlags, move, moveSlot); + if (disableStructPtr->chargeTimer1 != 0) + AddMovePoints(7, move, moveSlot, 0); + + if (move == MOVE_WISH) + { + tvPtr->side[atkSide].wishMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide].wishMoveSlot = moveSlot; + } + if (move == MOVE_SELF_DESTRUCT || move == MOVE_EXPLOSION) + { + tvPtr->side[atkSide ^ BIT_SIDE].explosionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; + tvPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot = moveSlot; + tvPtr->side[atkSide ^ BIT_SIDE].faintCause = 13; + tvPtr->side[atkSide ^ BIT_SIDE].explosion = 1; + } + + AddMovePoints(13, gBattleMoves[move].type, gBattleMoves[move].power, 0); + AddMovePoints(14, gBattleMoves[move].type, gBattleMoves[move].power, 0); + AddMovePoints(11, gBattleMoves[move].type, 0, 0); + AddMovePoints(12, gBattleMoves[move].type, 0, 0); +} + +void BattleTv_SetDataBasedOnAnimation(u8 animationId) +{ + struct BattleTv *tvPtr; + u32 atkSide; + + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) + return; + + tvPtr = &gBattleStruct->tv; + atkSide = GetBattlerSide(gBattlerAttacker); + switch (animationId) + { + case B_ANIM_FUTURE_SIGHT_HIT: + if (tvPtr->side[atkSide].futureSightMonId != 0) + { + AddMovePoints(2, 0, atkSide, + (tvPtr->side[atkSide].futureSightMonId - 1) * 4 + tvPtr->side[atkSide].futureSightMoveSlot); + tvPtr->side[atkSide].faintCause = 8; + } + break; + case B_ANIM_DOOM_DESIRE_HIT: + if (tvPtr->side[atkSide].doomDesireMonId != 0) + { + AddMovePoints(2, 1, atkSide, + (tvPtr->side[atkSide].doomDesireMonId - 1) * 4 + tvPtr->side[atkSide].doomDesireMoveSlot); + tvPtr->side[atkSide].faintCause = 9; + } + break; + } +} + +#ifdef NONMATCHING +// for loop has an unused stack variable +void TryPutLinkBattleTvShowOnAir(void) +{ + u16 playerBestSpecies = 0, opponentBestSpecies = 0; + s16 playerBestSum = 0, opponentBestSum = SHRT_MAX; + u8 playerBestMonId = 0, opponentBestMonId = 0; + struct BattleTvMovePoints *movePoints = NULL; + u8 countPlayer = 0, countOpponent = 0; + s16 sum = 0; + u16 species = 0; + u16 moveId = 0; + s32 i, j; + + if (gBattleStruct->anyMonHasTransformed) + return; + + movePoints = &gBattleStruct->tvMovePoints; + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE) + countPlayer++; + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE) + countOpponent++; + } + + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) || countPlayer != countOpponent) + return; + + for (i = 0; i < PARTY_SIZE; i++) + { + species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL); + if (species != SPECIES_NONE && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG, NULL)) + { + for (sum = 0, j = 0; j < 4; j++) + sum += movePoints->points[0][i * 4 + j]; + + if (playerBestSum < sum) + { + playerBestMonId = i; + playerBestSum = sum; + playerBestSpecies = species; + } + } + + species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, NULL); + if (species != SPECIES_NONE && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG, NULL)) + { + s32 id = 1; + for (sum = 0, j = 0; j < 4; j++) + sum += movePoints->points[id][i * 4 + j]; + + if (opponentBestSum == sum) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_EXP, NULL) > GetMonData(&gEnemyParty[opponentBestMonId], MON_DATA_EXP, NULL)) + { + opponentBestMonId = i; + opponentBestSum = sum; + opponentBestSpecies = species; + } + } + else if (opponentBestSum > sum) + { + opponentBestMonId = i; + opponentBestSum = sum; + opponentBestSpecies = species; + } + } + } + + for (sum = 0, i = 0, j = 0; j < 4; j++) + { + if (sum < movePoints->points[0][playerBestMonId * 4 + j]) + { + sum = movePoints->points[0][playerBestMonId * 4 + j]; + i = j; + } + } + + moveId = GetMonData(&gPlayerParty[playerBestMonId], MON_DATA_MOVE1 + i, NULL); + if (playerBestSum == 0 || moveId == 0) + return; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if ((playerBestMonId < 3 && !sub_806D82C(gBattleScripting.multiplayerId)) + || (playerBestMonId >= 3 && sub_806D82C(gBattleScripting.multiplayerId))) + { + j = (opponentBestMonId < 3) ? 0 : 1; + PutBattleUpdateOnTheAir(sub_806EF84(j, gBattleScripting.multiplayerId), moveId, playerBestSpecies, opponentBestSpecies); + } + } + else + { + PutBattleUpdateOnTheAir(gBattleScripting.multiplayerId ^ 1, moveId, playerBestSpecies, opponentBestSpecies); + } +} + +#else +ASM_DIRECT +void TryPutLinkBattleTvShowOnAir(void) +{ + asm_unified( + "push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x20\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r1, 0\n\ + str r1, [sp, 0x4]\n\ + movs r2, 0\n\ + str r2, [sp, 0x8]\n\ + ldr r3, =0x00007fff\n\ + str r3, [sp, 0xC]\n\ + movs r4, 0\n\ + str r4, [sp, 0x10]\n\ + movs r7, 0\n\ + str r7, [sp, 0x14]\n\ + mov r8, r0\n\ + ldr r0, =gBattleStruct\n\ + ldr r1, [r0]\n\ + adds r0, r1, 0\n\ + adds r0, 0xB3\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _0817E42A\n\ + b _0817E670\n\ +_0817E42A:\n\ + movs r2, 0xD2\n\ + lsls r2, 1\n\ + adds r2, r1\n\ + mov r10, r2\n\ + movs r6, 0\n\ +_0817E434:\n\ + movs r0, 0x64\n\ + adds r4, r6, 0\n\ + muls r4, r0\n\ + ldr r0, =gPlayerParty\n\ + adds r0, r4, r0\n\ + movs r1, 0xB\n\ + movs r2, 0\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0817E454\n\ + mov r0, r8\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r8, r0\n\ +_0817E454:\n\ + ldr r5, =gEnemyParty\n\ + adds r0, r4, r5\n\ + movs r1, 0xB\n\ + movs r2, 0\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0817E46A\n\ + adds r0, r7, 0x1\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ +_0817E46A:\n\ + adds r6, 0x1\n\ + cmp r6, 0x5\n\ + ble _0817E434\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x2\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0817E47E\n\ + b _0817E670\n\ +_0817E47E:\n\ + cmp r8, r7\n\ + beq _0817E484\n\ + b _0817E670\n\ +_0817E484:\n\ + movs r6, 0\n\ + lsls r3, r6, 1\n\ + str r3, [sp, 0x18]\n\ + movs r4, 0x64\n\ + mov r8, r4\n\ +_0817E48E:\n\ + mov r1, r8\n\ + muls r1, r6\n\ + ldr r0, =gPlayerParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + movs r2, 0\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r7, r0, 16\n\ + adds r0, r6, 0x1\n\ + mov r9, r0\n\ + cmp r7, 0\n\ + beq _0817E4EE\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + movs r2, 0\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0817E4EE\n\ + movs r4, 0\n\ + lsls r0, r6, 3\n\ + mov r2, r10\n\ + adds r1, r0, r2\n\ + movs r3, 0x3\n\ +_0817E4C4:\n\ + lsls r0, r4, 16\n\ + asrs r0, 16\n\ + ldrh r4, [r1]\n\ + adds r0, r4\n\ + lsls r0, 16\n\ + lsrs r4, r0, 16\n\ + adds r1, 0x2\n\ + subs r3, 0x1\n\ + cmp r3, 0\n\ + bge _0817E4C4\n\ + ldr r1, [sp, 0x8]\n\ + lsls r0, r1, 16\n\ + lsls r1, r4, 16\n\ + cmp r0, r1\n\ + bge _0817E4EE\n\ + lsls r0, r6, 24\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x10]\n\ + lsrs r1, 16\n\ + str r1, [sp, 0x8]\n\ + str r7, [sp]\n\ +_0817E4EE:\n\ + mov r0, r8\n\ + muls r0, r6\n\ + ldr r2, =gEnemyParty\n\ + adds r4, r0, r2\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + movs r2, 0\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r7, r0, 16\n\ + ldr r3, [sp, 0x8]\n\ + lsls r3, 16\n\ + str r3, [sp, 0x1C]\n\ + cmp r7, 0\n\ + beq _0817E5A0\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + movs r2, 0\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0817E5A0\n\ + movs r4, 0\n\ + ldr r0, [sp, 0xC]\n\ + lsls r2, r0, 16\n\ + movs r3, 0x1\n\ + lsls r1, r3, 1\n\ + adds r1, 0x1\n\ + lsls r1, 4\n\ + lsls r0, r6, 3\n\ + adds r0, r1\n\ + mov r3, r10\n\ + adds r1, r0, r3\n\ + movs r3, 0x3\n\ +_0817E534:\n\ + lsls r0, r4, 16\n\ + asrs r0, 16\n\ + ldrh r4, [r1]\n\ + adds r0, r4\n\ + lsls r0, 16\n\ + lsrs r4, r0, 16\n\ + adds r1, 0x2\n\ + subs r3, 0x1\n\ + cmp r3, 0\n\ + bge _0817E534\n\ + asrs r1, r2, 16\n\ + lsls r5, r4, 16\n\ + asrs r0, r5, 16\n\ + cmp r1, r0\n\ + bne _0817E590\n\ + mov r0, r8\n\ + muls r0, r6\n\ + ldr r1, =gEnemyParty\n\ + adds r0, r1\n\ + movs r1, 0x19\n\ + movs r2, 0\n\ + bl GetMonData\n\ + adds r4, r0, 0\n\ + ldr r2, [sp, 0x14]\n\ + mov r0, r8\n\ + muls r0, r2\n\ + ldr r3, =gEnemyParty\n\ + adds r0, r3\n\ + movs r1, 0x19\n\ + movs r2, 0\n\ + bl GetMonData\n\ + cmp r4, r0\n\ + bls _0817E5A0\n\ + b _0817E594\n\ + .pool\n\ +_0817E590:\n\ + cmp r1, r0\n\ + ble _0817E5A0\n\ +_0817E594:\n\ + lsls r0, r6, 24\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x14]\n\ + lsrs r5, 16\n\ + str r5, [sp, 0xC]\n\ + str r7, [sp, 0x4]\n\ +_0817E5A0:\n\ + mov r6, r9\n\ + cmp r6, 0x5\n\ + bgt _0817E5A8\n\ + b _0817E48E\n\ +_0817E5A8:\n\ + movs r4, 0\n\ + movs r6, 0\n\ + movs r3, 0\n\ + ldr r5, =gPlayerParty\n\ + ldr r7, [sp, 0x10]\n\ + lsls r0, r7, 3\n\ + mov r1, r10\n\ + adds r2, r0, r1\n\ +_0817E5B8:\n\ + lsls r0, r4, 16\n\ + asrs r0, 16\n\ + movs r7, 0\n\ + ldrsh r1, [r2, r7]\n\ + cmp r0, r1\n\ + bge _0817E5C8\n\ + ldrh r4, [r2]\n\ + adds r6, r3, 0\n\ +_0817E5C8:\n\ + adds r2, 0x2\n\ + adds r3, 0x1\n\ + cmp r3, 0x3\n\ + ble _0817E5B8\n\ + movs r0, 0x64\n\ + ldr r1, [sp, 0x10]\n\ + muls r0, r1\n\ + adds r0, r5\n\ + adds r1, r6, 0\n\ + adds r1, 0xD\n\ + movs r2, 0\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r4, r0, 16\n\ + ldr r2, [sp, 0x1C]\n\ + cmp r2, 0\n\ + beq _0817E670\n\ + cmp r4, 0\n\ + beq _0817E670\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0817E65C\n\ + ldr r3, [sp, 0x10]\n\ + cmp r3, 0x2\n\ + bhi _0817E620\n\ + ldr r0, =gBattleScripting\n\ + adds r0, 0x25\n\ + ldrb r0, [r0]\n\ + bl sub_806D82C\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + beq _0817E630\n\ + b _0817E670\n\ + .pool\n\ +_0817E620:\n\ + ldr r0, =gBattleScripting\n\ + adds r0, 0x25\n\ + ldrb r0, [r0]\n\ + bl sub_806D82C\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + beq _0817E670\n\ +_0817E630:\n\ + movs r3, 0\n\ + ldr r7, [sp, 0x14]\n\ + cmp r7, 0x2\n\ + bls _0817E63A\n\ + movs r3, 0x1\n\ +_0817E63A:\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + ldr r1, =gBattleScripting\n\ + adds r1, 0x25\n\ + ldrb r1, [r1]\n\ + bl sub_806EF84\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + adds r1, r4, 0\n\ + ldr r2, [sp]\n\ + ldr r3, [sp, 0x4]\n\ + bl PutBattleUpdateOnTheAir\n\ + b _0817E670\n\ + .pool\n\ +_0817E65C:\n\ + ldr r0, =gBattleScripting\n\ + adds r0, 0x25\n\ + ldrb r1, [r0]\n\ + movs r0, 0x1\n\ + eors r0, r1\n\ + adds r1, r4, 0\n\ + ldr r2, [sp]\n\ + ldr r3, [sp, 0x4]\n\ + bl PutBattleUpdateOnTheAir\n\ +_0817E670:\n\ + add sp, 0x20\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool"); +} +#endif + +static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3) +{ + struct BattleTvMovePoints *movePoints = &gBattleStruct->tvMovePoints; + struct BattleTv *tvPtr = &gBattleStruct->tv; + u32 atkSide = GetBattlerSide(gBattlerAttacker); + u32 defSide = GetBattlerSide(gBattlerTarget); + const u16 *ptr; + s32 i; + + switch (caseId) + { + case 0: + case 1: + case 18: + case 22 ... 27: + movePoints->points[atkSide][gBattlerPartyIndexes[gBattlerAttacker] * 4 + arg1] += sPointsArray[caseId][arg2]; + break; + case 3 ... 7: + i = 0; + ptr = sPointsArray[caseId]; + do + { + if (arg1 == ptr[i]) + { + movePoints->points[atkSide][gBattlerPartyIndexes[gBattlerAttacker] * 4 + arg2] += ptr[i+1]; + break; + } + i += 2; + } while (ptr[i] != 0xFFFF); + break; + case 19: + tvPtr->side[arg2 ^ 1].faintCause = 0; + movePoints->points[arg2][0 * 4 + arg3] += sPointsArray[caseId][arg1]; + break; + case 20: + tvPtr->side[arg2].faintCause = 0; + case 2: + movePoints->points[arg2][0 * 4 + arg3] += sPointsArray[caseId][arg1]; + break; + case 17: + movePoints->points[atkSide][arg2 * 4 + arg3] += sPointsArray[caseId][arg1]; + break; + case 8: + case 9: + case 15: + case 16: + case 21: + movePoints->points[atkSide ^ BIT_SIDE][arg2 * 4 + arg3] += sPointsArray[caseId][arg1]; + break; + case 10: + movePoints->points[arg1][arg2 * 4 + arg3] += sPointsArray[caseId][0]; + break; + case 11: + if (tvPtr->pos[defSide][0].waterSportMonId != -(tvPtr->pos[defSide][1].waterSportMonId) && arg1 == 10) + { + if (tvPtr->pos[defSide][0].waterSportMonId != 0) + { + u32 id = (tvPtr->pos[defSide][0].waterSportMonId - 1) * 4; + movePoints->points[defSide][id + tvPtr->pos[defSide][0].waterSportMoveSlot] += sPointsArray[caseId][0]; + } + if (tvPtr->pos[defSide][1].waterSportMonId != 0) + { + u32 id = (tvPtr->pos[defSide][1].waterSportMonId - 1) * 4; + movePoints->points[defSide][id + tvPtr->pos[defSide][1].waterSportMoveSlot] += sPointsArray[caseId][0]; + } + } + break; + case 12: + if (tvPtr->pos[defSide][0].mudSportMonId != -(tvPtr->pos[defSide][1].mudSportMonId) && arg1 == 13) + { + if (tvPtr->pos[defSide][0].mudSportMonId != 0) + { + u32 id = (tvPtr->pos[defSide][0].mudSportMonId - 1) * 4; + movePoints->points[defSide][id + tvPtr->pos[defSide][0].mudSportMoveSlot] += sPointsArray[caseId][0]; + } + if (tvPtr->pos[defSide][1].mudSportMonId != 0) + { + u32 id = (tvPtr->pos[defSide][1].mudSportMonId - 1) * 4; + movePoints->points[defSide][id + tvPtr->pos[defSide][1].mudSportMoveSlot] += sPointsArray[caseId][0]; + } + } + break; + case 13: + if (arg1 <= 8 && arg2 != 0 && tvPtr->side[defSide].reflectMonId != 0) + { + u32 id = (tvPtr->side[defSide].reflectMonId - 1) * 4; + movePoints->points[defSide][id + tvPtr->side[defSide].reflectMoveSlot] += sPointsArray[caseId][0]; + } + break; + case 14: + if (arg1 > 8 && arg2 != 0 && tvPtr->side[defSide].lightScreenMonId != 0) + { + u32 id = (tvPtr->side[defSide].lightScreenMonId - 1) * 4; + movePoints->points[defSide][id + tvPtr->side[defSide].lightScreenMoveSlot] += sPointsArray[caseId][0]; + } + break; + } +} + +static void AddPointsOnFainting(bool8 targetFainted) +{ + struct BattleTv *tvPtr = &gBattleStruct->tv; + u32 atkSide = GetBattlerSide(gBattlerAttacker); + u32 defSide = GetBattlerSide(gBattlerTarget); + u32 atkArrId = tvPtr->side[atkSide].faintCauseMonId; + s32 i; + + if (tvPtr->side[atkSide].faintCause != 0) + { + switch (tvPtr->side[atkSide].faintCause) + { + case 1: + if (tvPtr->pos[atkSide][atkArrId].curseMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->pos[atkSide][atkArrId].curseMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].curseMoveSlot); + } + break; + case 2: + if (tvPtr->pos[atkSide][atkArrId].leechSeedMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->pos[atkSide][atkArrId].leechSeedMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].leechSeedMoveSlot); + } + break; + case 3: + if (tvPtr->mon[atkSide][atkArrId].psnMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->mon[atkSide][atkArrId].psnMonId - 1) * 4 + tvPtr->mon[atkSide][atkArrId].psnMoveSlot); + } + if (tvPtr->mon[atkSide][atkArrId].badPsnMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->mon[atkSide][atkArrId].badPsnMonId - 1) * 4 + tvPtr->mon[atkSide][atkArrId].badPsnMoveSlot); + } + break; + case 4: + if (tvPtr->mon[atkSide][atkArrId].brnMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->mon[atkSide][atkArrId].brnMonId - 1) * 4 + tvPtr->mon[atkSide][atkArrId].brnMoveSlot); + } + break; + case 5: + if (tvPtr->pos[atkSide][atkArrId].nightmareMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->pos[atkSide][atkArrId].nightmareMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].nightmareMoveSlot); + } + break; + case 6: + if (tvPtr->pos[atkSide][atkArrId].wrapMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->pos[atkSide][atkArrId].wrapMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].wrapMoveSlot); + } + break; + case 7: + if (tvPtr->side[atkSide].spikesMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->side[atkSide].spikesMonId - 1) * 4 + tvPtr->side[atkSide].spikesMoveSlot); + } + break; + case 8: + if (tvPtr->side[atkSide].futureSightMonId != 0) + { + AddMovePoints(20, 0, atkSide, + (tvPtr->side[atkSide].futureSightMonId - 1) * 4 + tvPtr->side[atkSide].futureSightMoveSlot); + } + break; + case 9: + if (tvPtr->side[atkSide].doomDesireMonId != 0) + { + AddMovePoints(20, 0, atkSide, + (tvPtr->side[atkSide].doomDesireMonId - 1) * 4 + tvPtr->side[atkSide].doomDesireMoveSlot); + } + break; + case 10: + if (tvPtr->side[atkSide].perishSong + && tvPtr->side[atkSide].perishSongMonId - 1 != gBattlerPartyIndexes[gBattlerAttacker]) + { + AddMovePoints(19, 0, atkSide, + (tvPtr->side[atkSide].perishSongMonId - 1) * 4 + tvPtr->side[atkSide].perishSongMoveSlot); + } + if (tvPtr->side[atkSide ^ BIT_SIDE].perishSong) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->side[atkSide ^ BIT_SIDE].perishSongMonId - 1) * 4 + tvPtr->side[atkSide ^ BIT_SIDE].perishSongMoveSlot); + } + break; + case 11: + if (tvPtr->side[atkSide ^ BIT_SIDE].destinyBondMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->side[atkSide ^ BIT_SIDE].destinyBondMonId - 1) * 4 + tvPtr->side[atkSide ^ BIT_SIDE].destinyBondMoveSlot); + } + break; + case 12: + for (i = 0; i < 2; i++) + { + if (tvPtr->pos[atkSide][i].confusionMonId != 0) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->pos[atkSide][i].confusionMonId - 1) * 4 + tvPtr->pos[atkSide][i].confusionMoveSlot); + } + } + break; + case 13: + if (tvPtr->side[atkSide].explosion) + { + AddMovePoints(19, 0, atkSide, + (tvPtr->side[atkSide].explosionMonId - 1) * 4 + tvPtr->side[atkSide].explosionMoveSlot); + } + if (tvPtr->side[atkSide ^ BIT_SIDE].explosion) + { + AddMovePoints(19, 0, atkSide ^ BIT_SIDE, + (tvPtr->side[atkSide ^ BIT_SIDE].explosionMonId - 1) * 4 + tvPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot); + } + break; + case 14: + if (targetFainted == TRUE) + { + AddMovePoints(20, 0, atkSide, + (gBattlerPartyIndexes[gBattlerAttacker]) * 4 + tvPtr->side[atkSide].usedMoveSlot); + } + break; + case 15: + break; + } + } + else + { + if (tvPtr->side[defSide].faintCause == 7) + { + if (tvPtr->side[defSide].spikesMonId != 0) + { + AddMovePoints(19, 0, defSide ^ BIT_SIDE, + (tvPtr->side[defSide].spikesMonId - 1) * 4 + tvPtr->side[defSide].spikesMoveSlot); + } + } + else + { + AddMovePoints(20, 0, atkSide, + (gBattlerPartyIndexes[gBattlerAttacker]) * 4 + tvPtr->side[atkSide].usedMoveSlot); + } + } +} + +static void TrySetBattleSeminarShow(void) +{ + s32 i; + s32 dmgByMove[4]; + u16 powerOverride; + u16 currMoveSaved; + + if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) + return; + if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT) + return; + if (gBattleMons[gBattlerAttacker].statStages[STAT_ACC] <= 5) + return; + if (gBattleMons[gBattlerTarget].statStages[STAT_EVASION] > 6) + return; + if (gCurrentMove == MOVE_HIDDEN_POWER || gCurrentMove == MOVE_WEATHER_BALL) + return; + if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID)) + return; + if (gBattleMoves[gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]].power == 0) + return; + + i = 0; + currMoveSaved = gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]; + while (1) + { + if (currMoveSaved == sVariableDmgMoves[i]) + break; + i++; + if (sVariableDmgMoves[i] == 0xFFFF) + break; + } + + if (sVariableDmgMoves[i] != 0xFFFF) + return; + + dmgByMove[gMoveSelectionCursor[gBattlerAttacker]] = gBattleMoveDamage; + currMoveSaved = gCurrentMove; + for (i = 0; i < 4; i++) + { + gCurrentMove = gBattleMons[gBattlerAttacker].moves[i]; + powerOverride = 0; + if (ShouldCalculateDamage(gCurrentMove, &dmgByMove[i], &powerOverride)) + { + u8 moveResultFlags; + u16 sideStatus = gSideStatuses[GET_BATTLER_SIDE(gBattlerTarget)]; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBattlerAttacker], &gBattleMons[gBattlerTarget], gCurrentMove, + sideStatus, powerOverride, + 0, gBattlerAttacker, gBattlerTarget); + + if (gStatuses3[gBattlerAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + gBattleMoveDamage *= 2; + if (gProtectStructs[gBattlerAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + + moveResultFlags = TypeCalc(gCurrentMove, gBattlerAttacker, gBattlerTarget); + dmgByMove[i] = gBattleMoveDamage; + if (dmgByMove[i] == 0 && !(moveResultFlags & MOVE_RESULT_NO_EFFECT)) + dmgByMove[i] = 1; + } + } + + for (i = 0; i < 4; i++) + { + if (i != gMoveSelectionCursor[gBattlerAttacker] && dmgByMove[i] > dmgByMove[gMoveSelectionCursor[gBattlerAttacker]]) + { + u16 opponentSpecies, playerSpecies; + s32 bestMoveId; + + if (gMoveSelectionCursor[gBattlerAttacker] != 0) + bestMoveId = 0; + else + bestMoveId = 1; + + for (i = 0; i < 4; i++) + { + if (i != gMoveSelectionCursor[gBattlerAttacker] && dmgByMove[i] > dmgByMove[bestMoveId]) + bestMoveId = i; + } + + opponentSpecies = GetMonData(&gEnemyParty [gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_SPECIES, NULL); + playerSpecies = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_SPECIES, NULL); + sub_80EE35C(opponentSpecies, playerSpecies, gMoveSelectionCursor[gBattlerAttacker], gBattleMons[gBattlerAttacker].moves, gBattleMons[gBattlerAttacker].moves[bestMoveId]); + break; + } + } + + gBattleMoveDamage = dmgByMove[gMoveSelectionCursor[gBattlerAttacker]]; + gCurrentMove = currMoveSaved; +} + +static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride) +{ + if (gBattleMoves[moveId].power == 0) + { + *dmg = 0; + return FALSE; + } + else + { + s32 i = 0; + while (1) + { + if (moveId == sVariableDmgMoves[i]) + break; + i++; + if (sVariableDmgMoves[i] == 0xFFFF) + break; + } + + if (sVariableDmgMoves[i] != 0xFFFF) + { + *dmg = 0; + return FALSE; + } + else if (moveId == MOVE_PSYWAVE) + { + *dmg = gBattleMons[gBattlerAttacker].level; + *dmg /= 2; + return FALSE; + } + else if (moveId == MOVE_MAGNITUDE) + { + *powerOverride = 10; + return TRUE; + } + else + { + return TRUE; + } + } +} + +void BattleTv_ClearExplosionFaintCause(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + struct BattleTv *tvPtr = &gBattleStruct->tv; + + tvPtr->side[B_SIDE_PLAYER].faintCause = 0; + tvPtr->side[B_SIDE_OPPONENT].faintCause = 0; + + tvPtr->side[B_SIDE_PLAYER].faintCauseMonId = 0; + tvPtr->side[B_SIDE_OPPONENT].faintCauseMonId = 0; + + tvPtr->side[B_SIDE_PLAYER].explosionMonId = 0; + tvPtr->side[B_SIDE_OPPONENT].explosionMonId = 0; + + tvPtr->side[B_SIDE_PLAYER].explosionMoveSlot = 0; + tvPtr->side[B_SIDE_OPPONENT].explosionMoveSlot = 0; + + tvPtr->side[B_SIDE_PLAYER].explosion = 0; + tvPtr->side[B_SIDE_OPPONENT].explosion = 0; + } +} + +u8 GetBattlerMoveSlotId(u8 battlerId, u16 moveId) +{ + s32 i; + struct Pokemon *party; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + i = 0; + while (1) + { + if (i >= 4) + break; + if (GetMonData(&party[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + i, NULL) == moveId) + break; + i++; + } + + return i; +} + +static void AddPointsBasedOnWeather(u16 weatherFlags, u16 moveId, u8 moveSlot) +{ + if (weatherFlags & WEATHER_RAIN_ANY) + AddMovePoints(3, moveId, moveSlot, 0); + else if (weatherFlags & WEATHER_SUN_ANY) + AddMovePoints(4, moveId, moveSlot, 0); + else if (weatherFlags & WEATHER_SANDSTORM_ANY) + AddMovePoints(5, moveId, moveSlot, 0); + else if (weatherFlags & WEATHER_HAIL_ANY) + AddMovePoints(6, moveId, moveSlot, 0); +} diff --git a/src/tv.c b/src/tv.c index 03d564828e..fbbc108018 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1276,7 +1276,7 @@ static void InterviewAfter_ContestLiveUpdates(void) } } -void PutBattleUpdateOnTheAir(u8 a0, u16 a1, u16 a2, u16 a3) +void PutBattleUpdateOnTheAir(u8 opponentLinkPlayerId, u16 move, u16 speciesPlayer, u16 speciesOpponent) { TVShow *show; u8 name[32]; @@ -1303,21 +1303,21 @@ void PutBattleUpdateOnTheAir(u8 a0, u16 a1, u16 a2, u16 a3) { show->battleUpdate.battleType = 0; } - show->battleUpdate.move = a1; - show->battleUpdate.species2 = a2; - show->battleUpdate.species = a3; - StringCopy(name, gLinkPlayers[a0].name); + show->battleUpdate.move = move; + show->battleUpdate.speciesPlayer = speciesPlayer; + show->battleUpdate.speciesOpponent = speciesOpponent; + StringCopy(name, gLinkPlayers[opponentLinkPlayerId].name); StripExtCtrlCodes(name); StringCopy(show->battleUpdate.linkOpponentName, name); tv_store_id_2x(show); show->battleUpdate.language = gGameLanguage; - if (show->battleUpdate.language == LANGUAGE_JAPANESE || gLinkPlayers[a0].language == LANGUAGE_JAPANESE) + if (show->battleUpdate.language == LANGUAGE_JAPANESE || gLinkPlayers[opponentLinkPlayerId].language == LANGUAGE_JAPANESE) { show->battleUpdate.linkOpponentLanguage = LANGUAGE_JAPANESE; } else { - show->battleUpdate.linkOpponentLanguage = gLinkPlayers[a0].language; + show->battleUpdate.linkOpponentLanguage = gLinkPlayers[opponentLinkPlayerId].language; } } } @@ -3822,8 +3822,8 @@ static void sub_80F0708(void) // FIXME: register allocation shenanigans case TVSHOW_3_CHEERS_FOR_POKEBLOCKS: break; case TVSHOW_BATTLE_UPDATE: - sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.species2, i); - sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.species, i); + sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.speciesPlayer, i); + sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.speciesOpponent, i); break; case TVSHOW_FAN_CLUB_SPECIAL: break; @@ -5972,13 +5972,13 @@ static void DoTVShowPokemonBattleUpdate(void) break; case 2: TVShowConvertInternationalString(gStringVar1, show->battleUpdate.playerName, show->battleUpdate.language); - StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.species2]); + StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.speciesPlayer]); StringCopy(gStringVar3, gMoveNames[show->battleUpdate.move]); sTVShowState = 3; break; case 3: TVShowConvertInternationalString(gStringVar1, show->battleUpdate.linkOpponentName, show->battleUpdate.linkOpponentLanguage); - StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.species]); + StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.speciesOpponent]); sTVShowState = 4; break; case 4: @@ -5993,14 +5993,14 @@ static void DoTVShowPokemonBattleUpdate(void) break; case 6: TVShowConvertInternationalString(gStringVar1, show->battleUpdate.playerName, show->battleUpdate.language); - StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.species2]); + StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.speciesPlayer]); StringCopy(gStringVar3, gMoveNames[show->battleUpdate.move]); sTVShowState = 7; break; case 7: TVShowConvertInternationalString(gStringVar1, show->battleUpdate.playerName, show->battleUpdate.language); TVShowConvertInternationalString(gStringVar2, show->battleUpdate.linkOpponentName, show->battleUpdate.linkOpponentLanguage); - StringCopy(gStringVar3, gSpeciesNames[show->battleUpdate.species]); + StringCopy(gStringVar3, gSpeciesNames[show->battleUpdate.speciesOpponent]); TVShowDone(); break; }