summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/battle_9.s726
-rw-r--r--asm/battle_controller_opponent.s4
-rw-r--r--asm/battle_controller_player_partner.s4
-rw-r--r--include/battle.h1
-rw-r--r--include/battle_ai_switch_items.h7
-rw-r--r--src/battle_9.c299
6 files changed, 299 insertions, 742 deletions
diff --git a/asm/battle_9.s b/asm/battle_9.s
index 6d77d1593..0cf529bcc 100644
--- a/asm/battle_9.s
+++ b/asm/battle_9.s
@@ -5,726 +5,6 @@
.text
- thumb_func_start sub_8063880
-sub_8063880: @ 8063880
- push {r4-r7,lr}
- mov r7, r8
- push {r7}
- ldr r4, =gActiveBank
- ldrb r0, [r4]
- bl GetBankIdentity
- lsls r0, 24
- lsrs r6, r0, 24
- adds r5, r6, 0
- ldrb r0, [r4]
- bl GetBankSide
- lsls r0, 24
- ldr r1, =gEnemyParty
- mov r8, r1
- cmp r0, 0
- bne _080638A8
- ldr r2, =gPlayerParty
- mov r8, r2
-_080638A8:
- ldr r7, =gBattleTypeFlags
- ldr r0, [r7]
- movs r1, 0x8
- ands r0, r1
- cmp r0, 0
- bne _080638B6
- b _080639E6
-_080638B6:
- bl ShouldSwitch
- lsls r0, 24
- cmp r0, 0
- bne _080638C2
- b _080639DC
-_080638C2:
- ldrb r0, [r4]
- ldr r2, =gBattleStruct
- ldr r1, [r2]
- adds r0, r1
- movs r1, 0xA5
- lsls r1, 2
- adds r0, r1
- ldrb r0, [r0]
- cmp r0, 0x6
- bne _080639B8
- bl sub_8063A90
- lsls r0, 24
- lsrs r4, r0, 24
- cmp r4, 0x6
- bne _080639A6
- ldr r0, [r7]
- movs r1, 0x1
- ands r0, r1
- cmp r0, 0
- bne _08063910
- adds r0, r6, 0
- bl GetBankByIdentity
- lsls r0, 24
- lsrs r5, r0, 24
- adds r6, r5, 0
- b _08063928
- .pool
-_08063910:
- adds r0, r5, 0
- bl GetBankByIdentity
- lsls r0, 24
- lsrs r6, r0, 24
- movs r0, 0x2
- eors r5, r0
- adds r0, r5, 0
- bl GetBankByIdentity
- lsls r0, 24
- lsrs r5, r0, 24
-_08063928:
- ldr r0, =gBattleTypeFlags
- ldr r0, [r0]
- ldr r1, =0x00808000
- ands r0, r1
- cmp r0, 0
- beq _08063958
- ldr r0, =gActiveBank
- ldrb r1, [r0]
- movs r0, 0x2
- ands r0, r1
- cmp r0, 0
- bne _08063954
- movs r0, 0
- movs r7, 0x3
- b _0806395C
- .pool
-_08063954:
- movs r0, 0x3
- b _0806395A
-_08063958:
- movs r0, 0
-_0806395A:
- movs r7, 0x6
-_0806395C:
- adds r4, r0, 0
- cmp r4, r7
- bge _080639A6
-_08063962:
- movs r0, 0x64
- muls r0, r4
- add r0, r8
- movs r1, 0x39
- bl GetMonData
- cmp r0, 0
- beq _080639A0
- ldr r1, =gBattlePartyID
- lsls r0, r6, 1
- adds r0, r1
- ldrh r0, [r0]
- cmp r4, r0
- beq _080639A0
- lsls r0, r5, 1
- adds r0, r1
- ldrh r0, [r0]
- cmp r4, r0
- beq _080639A0
- ldr r0, =gBattleStruct
- ldr r1, [r0]
- adds r0, r6, r1
- adds r0, 0x5C
- ldrb r0, [r0]
- cmp r4, r0
- beq _080639A0
- adds r0, r5, r1
- adds r0, 0x5C
- ldrb r0, [r0]
- cmp r4, r0
- bne _080639A6
-_080639A0:
- adds r4, 0x1
- cmp r4, r7
- blt _08063962
-_080639A6:
- ldr r0, =gActiveBank
- ldrb r0, [r0]
- ldr r2, =gBattleStruct
- ldr r1, [r2]
- adds r0, r1
- movs r1, 0xA5
- lsls r1, 2
- adds r0, r1
- strb r4, [r0]
-_080639B8:
- ldr r0, =gActiveBank
- ldrb r1, [r0]
- ldr r0, [r2]
- adds r0, r1, r0
- adds r1, r0, 0
- adds r1, 0x5C
- movs r2, 0xA5
- lsls r2, 2
- adds r0, r2
- ldrb r0, [r0]
- strb r0, [r1]
- b _080639F8
- .pool
-_080639DC:
- bl sub_8063EE0
- lsls r0, 24
- cmp r0, 0
- bne _080639F8
-_080639E6:
- ldr r0, =gActiveBank
- ldrb r0, [r0]
- movs r2, 0x1
- eors r2, r0
- lsls r2, 8
- movs r0, 0x1
- movs r1, 0
- bl EmitCmd_x21
-_080639F8:
- pop {r3}
- mov r8, r3
- pop {r4-r7}
- pop {r0}
- bx r0
- .pool
- thumb_func_end sub_8063880
-
- thumb_func_start sub_8063A08
-sub_8063A08: @ 8063A08
- push {r4-r7,lr}
- mov r7, r10
- mov r6, r9
- mov r5, r8
- push {r5-r7}
- sub sp, 0x4
- adds r6, r3, 0
- lsls r0, 24
- lsrs r0, 24
- str r0, [sp]
- lsls r1, 24
- lsrs r1, 24
- mov r9, r1
- lsls r2, 24
- lsrs r2, 24
- mov r8, r2
- movs r7, 0
- ldr r0, =gTypeEffectiveness
- mov r10, r0
- ldrb r0, [r0]
- cmp r0, 0xFF
- beq _08063A7A
- mov r5, r10
-_08063A36:
- ldrb r0, [r5]
- cmp r0, 0xFE
- beq _08063A6C
- ldr r1, [sp]
- cmp r0, r1
- bne _08063A6C
- ldrb r4, [r5, 0x1]
- cmp r4, r9
- bne _08063A56
- ldrb r1, [r6]
- ldrb r0, [r5, 0x2]
- muls r0, r1
- movs r1, 0xA
- bl __divsi3
- strb r0, [r6]
-_08063A56:
- cmp r4, r8
- bne _08063A6C
- cmp r9, r8
- beq _08063A6C
- ldrb r1, [r6]
- ldrb r0, [r5, 0x2]
- muls r0, r1
- movs r1, 0xA
- bl __divsi3
- strb r0, [r6]
-_08063A6C:
- adds r5, 0x3
- adds r7, 0x3
- mov r1, r10
- adds r0, r7, r1
- ldrb r0, [r0]
- cmp r0, 0xFF
- bne _08063A36
-_08063A7A:
- add sp, 0x4
- pop {r3-r5}
- mov r8, r3
- mov r9, r4
- mov r10, r5
- pop {r4-r7}
- pop {r0}
- bx r0
- .pool
- thumb_func_end sub_8063A08
-
- thumb_func_start sub_8063A90
-sub_8063A90: @ 8063A90
- push {r4-r7,lr}
- mov r7, r10
- mov r6, r9
- mov r5, r8
- push {r5-r7}
- sub sp, 0x24
- ldr r4, =gActiveBank
- ldrb r2, [r4]
- ldr r0, =gBattleStruct
- ldr r0, [r0]
- adds r0, r2, r0
- adds r1, r0, 0
- adds r1, 0x5C
- ldrb r0, [r1]
- cmp r0, 0x6
- beq _08063AB2
- b _08063E50
-_08063AB2:
- ldr r0, =gBattleTypeFlags
- ldr r1, [r0]
- movs r0, 0x80
- lsls r0, 11
- ands r0, r1
- cmp r0, 0
- beq _08063AE0
- ldr r1, =gBattlePartyID
- lsls r0, r2, 1
- adds r0, r1
- ldrb r0, [r0]
- adds r0, 0x1
- lsls r0, 24
- lsrs r0, 24
- b _08063E50
- .pool
-_08063AE0:
- movs r0, 0x1
- ands r1, r0
- cmp r1, 0
- beq _08063B6C
- str r2, [sp, 0x10]
- adds r0, r2, 0
- bl GetBankIdentity
- movs r5, 0x2
- eors r0, r5
- lsls r0, 24
- lsrs r0, 24
- bl GetBankByIdentity
- ldr r1, =gAbsentBankFlags
- ldrb r1, [r1]
- ldr r2, =gBitTable
- lsls r0, 24
- lsrs r0, 22
- adds r0, r2
- ldr r0, [r0]
- ands r1, r0
- cmp r1, 0
- beq _08063B20
- ldrb r4, [r4]
- str r4, [sp, 0x14]
- b _08063B36
- .pool
-_08063B20:
- ldrb r0, [r4]
- bl GetBankIdentity
- eors r0, r5
- lsls r0, 24
- lsrs r0, 24
- bl GetBankByIdentity
- lsls r0, 24
- lsrs r0, 24
- str r0, [sp, 0x14]
-_08063B36:
- bl Random
- movs r3, 0x2
- ands r0, r3
- lsls r0, 24
- lsrs r0, 24
- str r0, [sp, 0x4]
- ldr r0, =gAbsentBankFlags
- ldrb r1, [r0]
- ldr r2, =gBitTable
- ldr r4, [sp, 0x4]
- lsls r0, r4, 2
- adds r0, r2
- ldr r0, [r0]
- ands r1, r0
- cmp r1, 0
- beq _08063B8A
- eors r4, r3
- lsls r0, r4, 24
- lsrs r0, 24
- str r0, [sp, 0x4]
- b _08063B8A
- .pool
-_08063B6C:
- adds r0, r2, 0
- bl GetBankIdentity
- movs r1, 0x1
- eors r0, r1
- lsls r0, 24
- lsrs r0, 24
- bl GetBankByIdentity
- lsls r0, 24
- lsrs r0, 24
- str r0, [sp, 0x4]
- ldrb r4, [r4]
- str r4, [sp, 0x14]
- str r4, [sp, 0x10]
-_08063B8A:
- ldr r0, =gBattleTypeFlags
- ldr r0, [r0]
- ldr r1, =0x00808000
- ands r0, r1
- cmp r0, 0
- beq _08063BC2
- ldr r2, =gActiveBank
- ldrb r1, [r2]
- movs r0, 0x2
- ands r0, r1
- cmp r0, 0
- bne _08063BB8
- movs r0, 0
- str r0, [sp, 0x18]
- movs r1, 0x3
- str r1, [sp, 0x1C]
- b _08063BCC
- .pool
-_08063BB8:
- movs r4, 0x3
- str r4, [sp, 0x18]
- movs r0, 0x6
- str r0, [sp, 0x1C]
- b _08063BCC
-_08063BC2:
- movs r1, 0
- str r1, [sp, 0x18]
- movs r2, 0x6
- str r2, [sp, 0x1C]
- ldr r2, =gActiveBank
-_08063BCC:
- ldrb r0, [r2]
- bl GetBankSide
- lsls r0, 24
- ldr r4, =gEnemyParty
- str r4, [sp, 0x20]
- cmp r0, 0
- bne _08063BE0
- ldr r0, =gPlayerParty
- str r0, [sp, 0x20]
-_08063BE0:
- movs r1, 0
- mov r9, r1
-_08063BE4:
- movs r2, 0
- str r2, [sp, 0x8]
- movs r4, 0x6
- str r4, [sp, 0xC]
- ldr r7, [sp, 0x18]
- ldr r0, [sp, 0x1C]
- cmp r7, r0
- blt _08063BF6
- b _08063CF2
-_08063BF6:
- lsls r0, r7, 2
- ldr r1, =gBitTable
- adds r0, r1
- mov r8, r0
- mov r10, sp
-_08063C00:
- movs r0, 0x64
- muls r0, r7
- ldr r2, [sp, 0x20]
- adds r4, r2, r0
- adds r0, r4, 0
- movs r1, 0xB
- bl GetMonData
- lsls r0, 16
- lsrs r5, r0, 16
- cmp r5, 0
- beq _08063CD8
- adds r0, r4, 0
- movs r1, 0x39
- bl GetMonData
- cmp r0, 0
- beq _08063CD8
- mov r4, r8
- ldr r0, [r4]
- mov r1, r9
- ands r0, r1
- cmp r0, 0
- bne _08063CD8
- ldr r1, =gBattlePartyID
- ldr r2, [sp, 0x10]
- lsls r0, r2, 1
- adds r0, r1
- ldrh r0, [r0]
- cmp r0, r7
- beq _08063CD8
- ldr r4, [sp, 0x14]
- lsls r0, r4, 1
- adds r0, r1
- ldrh r0, [r0]
- cmp r0, r7
- beq _08063CD8
- ldr r0, =gBattleStruct
- ldr r1, [r0]
- adds r0, r2, r1
- adds r0, 0x5C
- ldrb r0, [r0]
- cmp r7, r0
- beq _08063CD8
- adds r0, r4, r1
- adds r0, 0x5C
- ldrb r0, [r0]
- cmp r7, r0
- beq _08063CD8
- ldr r1, =gBaseStats
- lsls r0, r5, 3
- subs r0, r5
- lsls r0, 2
- adds r0, r1
- ldrb r5, [r0, 0x6]
- ldrb r6, [r0, 0x7]
- movs r0, 0xA
- mov r1, r10
- strb r0, [r1]
- movs r0, 0x58
- ldr r2, [sp, 0x4]
- adds r4, r2, 0
- muls r4, r0
- ldr r0, =gBattleMons
- adds r4, r0
- adds r0, r4, 0
- adds r0, 0x21
- ldrb r0, [r0]
- adds r1, r5, 0
- adds r2, r6, 0
- mov r3, sp
- bl sub_8063A08
- adds r4, 0x22
- ldrb r0, [r4]
- adds r1, r5, 0
- adds r2, r6, 0
- mov r3, sp
- bl sub_8063A08
- ldr r2, [sp, 0x8]
- mov r1, r10
- ldrb r1, [r1]
- cmp r2, r1
- bcs _08063CE6
- mov r2, r10
- ldrb r2, [r2]
- str r2, [sp, 0x8]
- lsls r0, r7, 24
- lsrs r0, 24
- str r0, [sp, 0xC]
- b _08063CE6
- .pool
-_08063CD8:
- mov r4, r8
- ldr r0, [r4]
- mov r1, r9
- orrs r1, r0
- lsls r0, r1, 24
- lsrs r0, 24
- mov r9, r0
-_08063CE6:
- movs r2, 0x4
- add r8, r2
- adds r7, 0x1
- ldr r4, [sp, 0x1C]
- cmp r7, r4
- blt _08063C00
-_08063CF2:
- ldr r0, [sp, 0xC]
- cmp r0, 0x6
- beq _08063D54
- movs r7, 0
- movs r0, 0x64
- ldr r1, [sp, 0xC]
- adds r5, r1, 0
- muls r5, r0
-_08063D02:
- adds r1, r7, 0
- adds r1, 0xD
- ldr r2, [sp, 0x20]
- adds r0, r2, r5
- bl GetMonData
- lsls r0, 16
- lsrs r4, r0, 16
- cmp r4, 0
- beq _08063D2A
- ldr r0, =gActiveBank
- ldrb r1, [r0]
- adds r0, r4, 0
- ldr r2, [sp, 0x4]
- bl TypeCalc
- movs r1, 0x2
- ands r1, r0
- cmp r1, 0
- bne _08063D30
-_08063D2A:
- adds r7, 0x1
- cmp r7, 0x3
- ble _08063D02
-_08063D30:
- cmp r7, 0x4
- beq _08063D36
- b _08063E4E
-_08063D36:
- ldr r4, [sp, 0xC]
- lsls r0, r4, 2
- ldr r1, =gBitTable
- adds r0, r1
- ldr r0, [r0]
- mov r2, r9
- orrs r2, r0
- lsls r0, r2, 24
- lsrs r0, 24
- mov r9, r0
- b _08063D58
- .pool
-_08063D54:
- movs r4, 0x3F
- mov r9, r4
-_08063D58:
- mov r0, r9
- cmp r0, 0x3F
- beq _08063D60
- b _08063BE4
-_08063D60:
- ldr r0, =gDynamicBasePower
- movs r1, 0
- strh r1, [r0]
- ldr r0, =gBattleStruct
- ldr r0, [r0]
- strb r1, [r0, 0x13]
- ldr r0, =gBattleScripting
- movs r2, 0x1
- strb r2, [r0, 0xE]
- ldr r0, =gBattleMoveFlags
- strb r1, [r0]
- ldr r0, =gCritMultiplier
- strb r2, [r0]
- movs r1, 0
- str r1, [sp, 0x8]
- movs r2, 0x6
- str r2, [sp, 0xC]
- ldr r7, [sp, 0x18]
- ldr r4, [sp, 0x1C]
- cmp r7, r4
- bge _08063E4E
-_08063D8A:
- movs r0, 0x64
- adds r6, r7, 0
- muls r6, r0
- ldr r0, [sp, 0x20]
- adds r4, r0, r6
- adds r0, r4, 0
- movs r1, 0xB
- bl GetMonData
- lsls r0, 16
- adds r1, r7, 0x1
- mov r10, r1
- cmp r0, 0
- beq _08063E46
- adds r0, r4, 0
- movs r1, 0x39
- bl GetMonData
- cmp r0, 0
- beq _08063E46
- ldr r1, =gBattlePartyID
- ldr r2, [sp, 0x10]
- lsls r0, r2, 1
- adds r0, r1
- ldrh r0, [r0]
- cmp r0, r7
- beq _08063E46
- ldr r4, [sp, 0x14]
- lsls r0, r4, 1
- adds r0, r1
- ldrh r0, [r0]
- cmp r0, r7
- beq _08063E46
- ldr r0, =gBattleStruct
- ldr r1, [r0]
- adds r0, r2, r1
- adds r0, 0x5C
- ldrb r0, [r0]
- cmp r7, r0
- beq _08063E46
- adds r0, r4, r1
- adds r0, 0x5C
- ldrb r0, [r0]
- cmp r7, r0
- beq _08063E46
- movs r5, 0
- mov r9, r6
- ldr r0, =gBattleMoveDamage
- mov r8, r0
- ldr r6, =gActiveBank
-_08063DEE:
- adds r1, r5, 0
- adds r1, 0xD
- ldr r0, [sp, 0x20]
- add r0, r9
- bl GetMonData
- lsls r0, 16
- lsrs r4, r0, 16
- movs r0, 0
- mov r1, r8
- str r0, [r1]
- cmp r4, 0
- beq _08063E2A
- ldr r0, =gBattleMoves
- lsls r1, r4, 1
- adds r1, r4
- lsls r1, 2
- adds r1, r0
- ldrb r0, [r1, 0x1]
- cmp r0, 0x1
- beq _08063E2A
- ldrb r0, [r6]
- ldr r1, [sp, 0x4]
- bl AI_CalcDmg
- ldrb r1, [r6]
- adds r0, r4, 0
- ldr r2, [sp, 0x4]
- bl TypeCalc
-_08063E2A:
- mov r2, r8
- ldr r0, [r2]
- ldr r4, [sp, 0x8]
- cmp r4, r0
- bge _08063E40
- lsls r0, 24
- lsrs r0, 24
- str r0, [sp, 0x8]
- lsls r0, r7, 24
- lsrs r0, 24
- str r0, [sp, 0xC]
-_08063E40:
- adds r5, 0x1
- cmp r5, 0x3
- ble _08063DEE
-_08063E46:
- mov r7, r10
- ldr r0, [sp, 0x1C]
- cmp r7, r0
- blt _08063D8A
-_08063E4E:
- ldr r0, [sp, 0xC]
-_08063E50:
- add sp, 0x24
- pop {r3-r5}
- mov r8, r3
- mov r9, r4
- mov r10, r5
- pop {r4-r7}
- pop {r1}
- bx r1
- .pool
- thumb_func_end sub_8063A90
thumb_func_start ai_identify_item_effect
ai_identify_item_effect: @ 8063E84
@@ -783,8 +63,8 @@ _08063EDA:
bx r1
thumb_func_end ai_identify_item_effect
- thumb_func_start sub_8063EE0
-sub_8063EE0: @ 8063EE0
+ thumb_func_start ShouldUseItem
+ShouldUseItem: @ 8063EE0
push {r4-r7,lr}
mov r7, r10
mov r6, r9
@@ -1361,6 +641,6 @@ _0806437E:
pop {r4-r7}
pop {r1}
bx r1
- thumb_func_end sub_8063EE0
+ thumb_func_end ShouldUseItem
.align 2, 0 @ Don't pad with nop.
diff --git a/asm/battle_controller_opponent.s b/asm/battle_controller_opponent.s
index 3fbeac5c1..896d86d3a 100644
--- a/asm/battle_controller_opponent.s
+++ b/asm/battle_controller_opponent.s
@@ -5212,7 +5212,7 @@ sub_8061F90: @ 8061F90
thumb_func_start sub_8061F9C
sub_8061F9C: @ 8061F9C
push {lr}
- bl sub_8063880
+ bl AI_TrySwitchOrUseItem
bl OpponentBufferExecCompleted
pop {r0}
bx r0
@@ -5456,7 +5456,7 @@ sub_8062188: @ 8062188
ldrb r0, [r1]
cmp r0, 0x6
bne _08062254
- bl sub_8063A90
+ bl GetMostSuitableMonToSwitchInto
lsls r0, 24
lsrs r4, r0, 24
cmp r4, 0x6
diff --git a/asm/battle_controller_player_partner.s b/asm/battle_controller_player_partner.s
index 269e5347b..8c080500e 100644
--- a/asm/battle_controller_player_partner.s
+++ b/asm/battle_controller_player_partner.s
@@ -4990,7 +4990,7 @@ sub_81BDAA0: @ 81BDAA0
thumb_func_start sub_81BDAAC
sub_81BDAAC: @ 81BDAAC
push {lr}
- bl sub_8063880
+ bl AI_TrySwitchOrUseItem
bl PlayerPartnerBufferExecCompleted
pop {r0}
bx r0
@@ -5087,7 +5087,7 @@ sub_81BDB70: @ 81BDB70
thumb_func_start sub_81BDB7C
sub_81BDB7C: @ 81BDB7C
push {r4-r6,lr}
- bl sub_8063A90
+ bl GetMostSuitableMonToSwitchInto
lsls r0, 24
lsrs r4, r0, 24
cmp r4, 0x6
diff --git a/include/battle.h b/include/battle.h
index bb61c7043..0aa778fe2 100644
--- a/include/battle.h
+++ b/include/battle.h
@@ -5,6 +5,7 @@
#include "battle_util.h"
#include "battle_script_commands.h"
#include "battle_2.h"
+#include "battle_ai_switch_items.h"
/*
Banks are a name given to what could be called a 'battlerId' or 'monControllerId'.
diff --git a/include/battle_ai_switch_items.h b/include/battle_ai_switch_items.h
new file mode 100644
index 000000000..5c78a5386
--- /dev/null
+++ b/include/battle_ai_switch_items.h
@@ -0,0 +1,7 @@
+#ifndef GUARD_BATTLE_AI_SWITCH_ITEMS_H
+#define GUARD_BATTLE_AI_SWITCH_ITEMS_H
+
+void AI_TrySwitchOrUseItem(void);
+u8 GetMostSuitableMonToSwitchInto(void);
+
+#endif // GUARD_BATTLE_AI_SWITCH_ITEMS_H
diff --git a/src/battle_9.c b/src/battle_9.c
index 1b1a4ab7c..291bfc9e3 100644
--- a/src/battle_9.c
+++ b/src/battle_9.c
@@ -16,13 +16,19 @@ extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
extern u16 gUnknown_02024250[BATTLE_BANKS_COUNT];
extern u8 gUnknown_02024270[BATTLE_BANKS_COUNT];
+extern u16 gDynamicBasePower;
+extern u8 gBattleMoveFlags;
+extern u8 gCritMultiplier;
+extern s32 gBattleMoveDamage;
extern const struct BattleMove gBattleMoves[];
extern const struct BaseStats gBaseStats[];
+extern const u8 gTypeEffectiveness[];
// this file's functions
bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent);
+bool8 ShouldUseItem(void);
bool8 ShouldSwitchIfPerishSong(void)
{
@@ -121,7 +127,7 @@ bool8 ShouldSwitchIfWonderGuard(void)
return FALSE; // at this point there is not a single pokemon in the party that has a super effective move against a pokemon with wonder guard
}
-bool8 sub_8062E54(void)
+bool8 FindMonThatAbsorbsOpponentsMove(void)
{
u8 bankIn1, bankIn2;
u8 absorbingTypeAbility;
@@ -430,13 +436,14 @@ bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
bool8 ShouldSwitch(void)
{
u8 bankIn1, bankIn2;
+ u8 *activeBankPtr; // needed to match
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
s32 i;
s32 availableToSwitch;
- if (gBattleMons[gActiveBank].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
+ if (gBattleMons[*(activeBankPtr = &gActiveBank)].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
return FALSE;
if (gStatuses3[gActiveBank] & STATUS3_ROOTED)
return FALSE;
@@ -444,25 +451,29 @@ bool8 ShouldSwitch(void)
return FALSE;
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBank, ABILITY_ARENA_TRAP, 0, 0))
return FALSE; // misses the flying or levitate check
- if (AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, gActiveBank, ABILITY_MAGNET_PULL, 0, 0)
- && (gBattleMons[gActiveBank].type1 == TYPE_STEEL || gBattleMons[gActiveBank].type2 == TYPE_STEEL))
- return FALSE;
+ if (AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MAGNET_PULL, 0, 0))
+ {
+ if (gBattleMons[gActiveBank].type1 == TYPE_STEEL)
+ return FALSE;
+ if (gBattleMons[gActiveBank].type2 == TYPE_STEEL)
+ return FALSE;
+ }
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
return FALSE;
availableToSwitch = 0;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
- bankIn1 = gActiveBank;
- if (gAbsentBankFlags & gBitTable[GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON)])
- bankIn2 = gActiveBank;
+ bankIn1 = *activeBankPtr;
+ if (gAbsentBankFlags & gBitTable[GetBankByIdentity(GetBankIdentity(*activeBankPtr) ^ BIT_MON)])
+ bankIn2 = *activeBankPtr;
else
- bankIn2 = GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON);
+ bankIn2 = GetBankByIdentity(GetBankIdentity(*activeBankPtr) ^ BIT_MON);
}
else
{
- bankIn1 = gActiveBank;
- bankIn2 = gActiveBank;
+ bankIn1 = *activeBankPtr;
+ bankIn2 = *activeBankPtr;
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
@@ -508,7 +519,7 @@ bool8 ShouldSwitch(void)
return TRUE;
if (ShouldSwitchIfWonderGuard())
return TRUE;
- if (sub_8062E54())
+ if (FindMonThatAbsorbsOpponentsMove())
return TRUE;
if (ShouldSwitchIfNaturalCure())
return TRUE;
@@ -516,10 +527,268 @@ bool8 ShouldSwitch(void)
return FALSE;
if (AreStatsRaised())
return FALSE;
- if (FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTAFFECTED, 2))
- return TRUE;
- if (FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTVERYEFFECTIVE, 3))
+ if (FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTAFFECTED, 2)
+ || FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTVERYEFFECTIVE, 3))
return TRUE;
return FALSE;
}
+
+void AI_TrySwitchOrUseItem(void)
+{
+ struct Pokemon *party;
+ u8 bankIn1, bankIn2;
+ s32 firstId;
+ s32 lastId; // + 1
+ u8 bankIdentity = GetBankIdentity(gActiveBank);
+
+ if (GetBankSide(gActiveBank) == SIDE_PLAYER)
+ party = gPlayerParty;
+ else
+ party = gEnemyParty;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ if (ShouldSwitch())
+ {
+ if (*(gBattleStruct->field_294 + gActiveBank) == 6)
+ {
+ s32 monToSwitchId = GetMostSuitableMonToSwitchInto();
+ if (monToSwitchId == 6)
+ {
+ if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
+ {
+ bankIn1 = GetBankByIdentity(bankIdentity);
+ bankIn2 = bankIn1;
+ }
+ else
+ {
+ bankIn1 = GetBankByIdentity(bankIdentity);
+ bankIn2 = GetBankByIdentity(bankIdentity ^ BIT_MON);
+ }
+
+ if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
+ {
+ if ((gActiveBank & BIT_MON) == 0)
+ firstId = 0, lastId = 3;
+ else
+ firstId = 3, lastId = 6;
+ }
+ else
+ {
+ firstId = 0, lastId = 6;
+ }
+
+ for (monToSwitchId = firstId; monToSwitchId < lastId; monToSwitchId++)
+ {
+ if (GetMonData(&party[monToSwitchId], MON_DATA_HP) == 0)
+ continue;
+ if (monToSwitchId == gBattlePartyID[bankIn1])
+ continue;
+ if (monToSwitchId == gBattlePartyID[bankIn2])
+ continue;
+ if (monToSwitchId == *(gBattleStruct->field_5C + bankIn1))
+ continue;
+ if (monToSwitchId == *(gBattleStruct->field_5C + bankIn2))
+ continue;
+
+ break;
+ }
+ }
+
+ *(gBattleStruct->field_294 + gActiveBank) = monToSwitchId;
+ }
+
+ *(gBattleStruct->field_5C + gActiveBank) = *(gBattleStruct->field_294 + gActiveBank);
+ return;
+ }
+ else if (ShouldUseItem())
+ {
+ return;
+ }
+ }
+
+ EmitCmd_x21(1, 0, (gActiveBank ^ BIT_SIDE) << 8);
+}
+
+#define TYPE_FORESIGHT 0xFE
+#define TYPE_ENDTABLE 0xFF
+
+static void ModulateByTypeEffectiveness(u8 atkType, u8 defType1, u8 defType2, u8 *var)
+{
+ s32 i = 0;
+
+ while (gTypeEffectiveness[i] != TYPE_ENDTABLE)
+ {
+ if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
+ {
+ i += 3;
+ continue;
+ }
+ else if (gTypeEffectiveness[i] == atkType)
+ {
+ // check type1
+ if (gTypeEffectiveness[i + 1] == defType1)
+ *var = (*var * gTypeEffectiveness[i + 2]) / 10;
+ // check type2
+ if (gTypeEffectiveness[i + 1] == defType2 && defType1 != defType2)
+ *var = (*var * gTypeEffectiveness[i + 2]) / 10;
+ }
+ i += 3;
+ }
+}
+
+u8 GetMostSuitableMonToSwitchInto(void)
+{
+ u8 opposingBank;
+ u8 bestDmg; // note : should be changed to u32 for obvious reasons
+ u8 bestMonId;
+ u8 bankIn1, bankIn2;
+ s32 firstId;
+ s32 lastId; // + 1
+ struct Pokemon *party;
+ s32 i, j;
+ u8 invalidMons;
+ u16 move;
+
+ if (*(gBattleStruct->field_5C + gActiveBank) != 6)
+ return *(gBattleStruct->field_5C + gActiveBank);
+ if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
+ return gBattlePartyID[gActiveBank] + 1;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+ {
+ bankIn1 = gActiveBank;
+ if (gAbsentBankFlags & gBitTable[GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON)])
+ bankIn2 = gActiveBank;
+ else
+ bankIn2 = GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON);
+
+ // UB: It considers the opponent only player's side even though it can battle alongside player;
+ opposingBank = Random() & BIT_MON;
+ if (gAbsentBankFlags & gBitTable[opposingBank])
+ opposingBank ^= BIT_MON;
+ }
+ else
+ {
+ opposingBank = GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_SIDE);
+ bankIn1 = gActiveBank;
+ bankIn2 = gActiveBank;
+ }
+
+ if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
+ {
+ if ((gActiveBank & BIT_MON) == 0)
+ firstId = 0, lastId = 3;
+ else
+ firstId = 3, lastId = 6;
+ }
+ else
+ {
+ firstId = 0, lastId = 6;
+ }
+
+ if (GetBankSide(gActiveBank) == SIDE_PLAYER)
+ party = gPlayerParty;
+ else
+ party = gEnemyParty;
+
+ invalidMons = 0;
+
+ while (invalidMons != 0x3F) // all mons are invalid
+ {
+ bestDmg = 0;
+ bestMonId = 6;
+ // find the mon which type is the most suitable offensively
+ for (i = firstId; i < lastId; i++)
+ {
+ u16 species = GetMonData(&party[i], MON_DATA_SPECIES);
+ if (species != SPECIES_NONE
+ && GetMonData(&party[i], MON_DATA_HP) != 0
+ && !(gBitTable[i] & invalidMons)
+ && gBattlePartyID[bankIn1] != i
+ && gBattlePartyID[bankIn2] != i
+ && i != *(gBattleStruct->field_5C + bankIn1)
+ && i != *(gBattleStruct->field_5C + bankIn2))
+ {
+ u8 type1 = gBaseStats[species].type1;
+ u8 type2 = gBaseStats[species].type2;
+ u8 typeDmg = 10;
+ ModulateByTypeEffectiveness(gBattleMons[opposingBank].type1, type1, type2, &typeDmg);
+ ModulateByTypeEffectiveness(gBattleMons[opposingBank].type2, type1, type2, &typeDmg);
+ if (bestDmg < typeDmg)
+ {
+ bestDmg = typeDmg;
+ bestMonId = i;
+ }
+ }
+ else
+ {
+ invalidMons |= gBitTable[i];
+ }
+ }
+
+ // ok, we know the mon has the right typing but does it have at least one super effective move?
+ if (bestMonId != 6)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ move = GetMonData(&party[bestMonId], MON_DATA_MOVE1 + i);
+ if (move != MOVE_NONE && TypeCalc(move, gActiveBank, opposingBank) & MOVESTATUS_SUPEREFFECTIVE)
+ break;
+ }
+
+ if (i != 4)
+ return bestMonId; // has both the typing and at least one super effective move
+
+ invalidMons |= gBitTable[bestMonId]; // sorry buddy, we want something better
+ }
+ else
+ {
+ invalidMons = 0x3F; // no viable mon to switch
+ }
+ }
+
+ gDynamicBasePower = 0;
+ gBattleStruct->dynamicMoveType = 0;
+ gBattleScripting.dmgMultiplier = 1;
+ gBattleMoveFlags = 0;
+ gCritMultiplier = 1;
+ bestDmg = 0;
+ bestMonId = 6;
+
+ // if we couldn't find the best mon in terms of typing, find the one that deals most damage
+ for (i = firstId; i < lastId; i++)
+ {
+ if ((u16)(GetMonData(&party[i], MON_DATA_SPECIES)) == SPECIES_NONE)
+ continue;
+ if (GetMonData(&party[i], MON_DATA_HP) == 0)
+ continue;
+ if (gBattlePartyID[bankIn1] == i)
+ continue;
+ if (gBattlePartyID[bankIn2] == i)
+ continue;
+ if (i == *(gBattleStruct->field_5C + bankIn1))
+ continue;
+ if (i == *(gBattleStruct->field_5C + bankIn2))
+ continue;
+
+ for (j = 0; j < 4; j++)
+ {
+ move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
+ gBattleMoveDamage = 0;
+ if (move != MOVE_NONE && gBattleMoves[move].power != 1)
+ {
+ AI_CalcDmg(gActiveBank, opposingBank);
+ TypeCalc(move, gActiveBank, opposingBank);
+ }
+ if (bestDmg < gBattleMoveDamage)
+ {
+ bestDmg = gBattleMoveDamage;
+ bestMonId = i;
+ }
+ }
+ }
+
+ return bestMonId;
+}