ported battle_ai_switch_items from pokeem
This commit is contained in:
+14
-14
@@ -4847,7 +4847,7 @@ sub_8012434: @ 8012434
|
||||
mov r10, r0
|
||||
ldr r1, _080126D0 @ =gUnknown_2023DA8
|
||||
mov r12, r1
|
||||
ldr r0, _080126D4 @ =gUnknown_2023DA0
|
||||
ldr r0, _080126D4 @ =gLastLandedMoves
|
||||
mov r9, r0
|
||||
ldr r1, _080126D8 @ =gLastMoves
|
||||
mov r8, r1
|
||||
@@ -4879,7 +4879,7 @@ _0801246C:
|
||||
strh r3, [r0]
|
||||
mov r1, r10
|
||||
strh r3, [r1]
|
||||
ldr r0, _080126F0 @ =gUnknown_2023DC0
|
||||
ldr r0, _080126F0 @ =gLastHitBy
|
||||
adds r1, r2, r0
|
||||
movs r0, 0xFF
|
||||
strb r0, [r1]
|
||||
@@ -5173,14 +5173,14 @@ _080126AE:
|
||||
.align 2, 0
|
||||
_080126CC: .4byte gUnknown_2023DB0
|
||||
_080126D0: .4byte gUnknown_2023DA8
|
||||
_080126D4: .4byte gUnknown_2023DA0
|
||||
_080126D4: .4byte gLastLandedMoves
|
||||
_080126D8: .4byte gLastMoves
|
||||
_080126DC: .4byte gDisableStructs
|
||||
_080126E0: .4byte gUnknown_2023D90
|
||||
_080126E4: .4byte gUnknown_2023DB8
|
||||
_080126E8: .4byte gStatuses3
|
||||
_080126EC: .4byte gUnknown_2023DD4
|
||||
_080126F0: .4byte gUnknown_2023DC0
|
||||
_080126F0: .4byte gLastHitBy
|
||||
_080126F4: .4byte gBattleResources
|
||||
_080126F8: .4byte gSideTimers
|
||||
_080126FC: .4byte gSideStatuses
|
||||
@@ -5585,7 +5585,7 @@ _08012A1A:
|
||||
strh r2, [r0]
|
||||
ldrb r0, [r1]
|
||||
lsls r0, 1
|
||||
ldr r6, _08012BB0 @ =gUnknown_2023DA0
|
||||
ldr r6, _08012BB0 @ =gLastLandedMoves
|
||||
adds r0, r6
|
||||
strh r2, [r0]
|
||||
ldrb r0, [r1]
|
||||
@@ -5606,7 +5606,7 @@ _08012A1A:
|
||||
strh r2, [r0]
|
||||
mov r1, r12
|
||||
ldrb r0, [r1]
|
||||
ldr r2, _08012BC0 @ =gUnknown_2023DC0
|
||||
ldr r2, _08012BC0 @ =gLastHitBy
|
||||
adds r0, r2
|
||||
movs r1, 0xFF
|
||||
strb r1, [r0]
|
||||
@@ -5758,11 +5758,11 @@ _08012BA0: .4byte gCurrentMove
|
||||
_08012BA4: .4byte gBattleMoves
|
||||
_08012BA8: .4byte gMoveResultFlags
|
||||
_08012BAC: .4byte gLastMoves
|
||||
_08012BB0: .4byte gUnknown_2023DA0
|
||||
_08012BB0: .4byte gLastLandedMoves
|
||||
_08012BB4: .4byte gUnknown_2023DA8
|
||||
_08012BB8: .4byte gUnknown_2023DB0
|
||||
_08012BBC: .4byte gUnknown_2023D90
|
||||
_08012BC0: .4byte gUnknown_2023DC0
|
||||
_08012BC0: .4byte gLastHitBy
|
||||
_08012BC4: .4byte gBattleResources
|
||||
thumb_func_end sub_8012760
|
||||
|
||||
@@ -6053,7 +6053,7 @@ _08012CA8:
|
||||
strh r2, [r0]
|
||||
ldrb r0, [r7]
|
||||
lsls r0, 1
|
||||
ldr r1, _08012F90 @ =gUnknown_2023DA0
|
||||
ldr r1, _08012F90 @ =gLastLandedMoves
|
||||
adds r0, r1
|
||||
strh r2, [r0]
|
||||
ldrb r0, [r7]
|
||||
@@ -6072,7 +6072,7 @@ _08012CA8:
|
||||
adds r0, r1
|
||||
strh r2, [r0]
|
||||
ldrb r0, [r7]
|
||||
ldr r2, _08012FA0 @ =gUnknown_2023DC0
|
||||
ldr r2, _08012FA0 @ =gLastHitBy
|
||||
adds r0, r2
|
||||
movs r1, 0xFF
|
||||
strb r1, [r0]
|
||||
@@ -6250,11 +6250,11 @@ _08012F80: .4byte 0xfbffffff
|
||||
_08012F84: .4byte gBattleStruct
|
||||
_08012F88: .4byte 0xffff1fff
|
||||
_08012F8C: .4byte gLastMoves
|
||||
_08012F90: .4byte gUnknown_2023DA0
|
||||
_08012F90: .4byte gLastLandedMoves
|
||||
_08012F94: .4byte gUnknown_2023DA8
|
||||
_08012F98: .4byte gUnknown_2023DB0
|
||||
_08012F9C: .4byte gUnknown_2023D90
|
||||
_08012FA0: .4byte gUnknown_2023DC0
|
||||
_08012FA0: .4byte gLastHitBy
|
||||
_08012FA4: .4byte gBattleResources
|
||||
_08012FA8: .4byte gBaseStats
|
||||
thumb_func_end sub_8012BC8
|
||||
@@ -13836,7 +13836,7 @@ HandleAction_ActionFinished: @ 8016D70
|
||||
ldr r5, _08016E04 @ =gBattleScripting
|
||||
strb r1, [r5, 0x18]
|
||||
strb r1, [r5, 0x19]
|
||||
ldr r2, _08016E08 @ =gUnknown_2023DA0
|
||||
ldr r2, _08016E08 @ =gLastLandedMoves
|
||||
ldr r3, _08016E0C @ =gBattlerAttacker
|
||||
ldrb r0, [r3]
|
||||
lsls r0, 1
|
||||
@@ -13875,7 +13875,7 @@ _08016DF8: .4byte gCurrentMove
|
||||
_08016DFC: .4byte gBattleMoveDamage
|
||||
_08016E00: .4byte gMoveResultFlags
|
||||
_08016E04: .4byte gBattleScripting
|
||||
_08016E08: .4byte gUnknown_2023DA0
|
||||
_08016E08: .4byte gLastLandedMoves
|
||||
_08016E0C: .4byte gBattlerAttacker
|
||||
_08016E10: .4byte gUnknown_2023DA8
|
||||
_08016E14: .4byte gBattleStruct
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -370,7 +370,7 @@ _0801DA5E:
|
||||
movs r1, 0x1
|
||||
orrs r0, r1
|
||||
strb r0, [r2]
|
||||
ldr r1, _0801DAA4 @ =gUnknown_2023DA0
|
||||
ldr r1, _0801DAA4 @ =gLastLandedMoves
|
||||
ldr r3, _0801DAA8 @ =gBattlerTarget
|
||||
ldrb r0, [r3]
|
||||
lsls r0, 1
|
||||
@@ -392,7 +392,7 @@ _0801DA94: .4byte gCurrentMove
|
||||
_0801DA98: .4byte gBattleMons
|
||||
_0801DA9C: .4byte gBattlerAttacker
|
||||
_0801DAA0: .4byte gMoveResultFlags
|
||||
_0801DAA4: .4byte gUnknown_2023DA0
|
||||
_0801DAA4: .4byte gLastLandedMoves
|
||||
_0801DAA8: .4byte gBattlerTarget
|
||||
_0801DAAC: .4byte gUnknown_2023DA8
|
||||
_0801DAB0: .4byte gBattleCommunication
|
||||
@@ -458,7 +458,7 @@ JumpIfMoveFailed: @ 801DB10
|
||||
ands r0, r1
|
||||
cmp r0, 0
|
||||
beq _0801DB70
|
||||
ldr r1, _0801DB64 @ =gUnknown_2023DA0
|
||||
ldr r1, _0801DB64 @ =gLastLandedMoves
|
||||
ldr r3, _0801DB68 @ =gBattlerTarget
|
||||
ldrb r0, [r3]
|
||||
lsls r0, 1
|
||||
@@ -484,7 +484,7 @@ JumpIfMoveFailed: @ 801DB10
|
||||
.align 2, 0
|
||||
_0801DB5C: .4byte gBattlescriptCurrInstr
|
||||
_0801DB60: .4byte gMoveResultFlags
|
||||
_0801DB64: .4byte gUnknown_2023DA0
|
||||
_0801DB64: .4byte gLastLandedMoves
|
||||
_0801DB68: .4byte gBattlerTarget
|
||||
_0801DB6C: .4byte gUnknown_2023DA8
|
||||
_0801DB70:
|
||||
@@ -2182,7 +2182,7 @@ _0801E8C0:
|
||||
movs r1, 0x9
|
||||
orrs r0, r1
|
||||
strb r0, [r2]
|
||||
ldr r1, _0801E92C @ =gUnknown_2023DA0
|
||||
ldr r1, _0801E92C @ =gLastLandedMoves
|
||||
ldrb r0, [r4]
|
||||
lsls r0, 1
|
||||
adds r0, r1
|
||||
@@ -2208,22 +2208,22 @@ _0801E91C: .4byte gBattleMoveDamage
|
||||
_0801E920: .4byte gBattlerTarget
|
||||
_0801E924: .4byte gLastUsedAbility
|
||||
_0801E928: .4byte gMoveResultFlags
|
||||
_0801E92C: .4byte gUnknown_2023DA0
|
||||
_0801E92C: .4byte gLastLandedMoves
|
||||
_0801E930: .4byte gUnknown_2023DA8
|
||||
_0801E934: .4byte gBattleCommunication
|
||||
_0801E938:
|
||||
ldr r1, _0801E944 @ =gUnknown_824F050
|
||||
ldr r1, _0801E944 @ =gTypeEffectiveness
|
||||
adds r0, r3, r1
|
||||
ldrb r0, [r0]
|
||||
adds r2, r1, 0
|
||||
b _0801E9B4
|
||||
.align 2, 0
|
||||
_0801E944: .4byte gUnknown_824F050
|
||||
_0801E944: .4byte gTypeEffectiveness
|
||||
_0801E948:
|
||||
adds r3, 0x3
|
||||
b _0801E9B0
|
||||
_0801E94C:
|
||||
ldr r5, _0801EA84 @ =gUnknown_824F050
|
||||
ldr r5, _0801EA84 @ =gTypeEffectiveness
|
||||
adds r0, r3, r5
|
||||
ldrb r0, [r0]
|
||||
cmp r0, r8
|
||||
@@ -2272,7 +2272,7 @@ _0801E9A8:
|
||||
adds r3, 0x3
|
||||
ldr r5, _0801EA88 @ =gBattleMons
|
||||
ldr r4, _0801EA8C @ =gBattlerTarget
|
||||
ldr r2, _0801EA84 @ =gUnknown_824F050
|
||||
ldr r2, _0801EA84 @ =gTypeEffectiveness
|
||||
_0801E9B0:
|
||||
adds r0, r3, r2
|
||||
ldrb r0, [r0]
|
||||
@@ -2339,7 +2339,7 @@ _0801EA10:
|
||||
orrs r0, r4
|
||||
mov r1, r8
|
||||
strb r0, [r1]
|
||||
ldr r1, _0801EAA4 @ =gUnknown_2023DA0
|
||||
ldr r1, _0801EAA4 @ =gLastLandedMoves
|
||||
ldrb r0, [r5]
|
||||
lsls r0, 1
|
||||
adds r0, r1
|
||||
@@ -2384,7 +2384,7 @@ _0801EA70:
|
||||
pop {r0}
|
||||
bx r0
|
||||
.align 2, 0
|
||||
_0801EA84: .4byte gUnknown_824F050
|
||||
_0801EA84: .4byte gTypeEffectiveness
|
||||
_0801EA88: .4byte gBattleMons
|
||||
_0801EA8C: .4byte gBattlerTarget
|
||||
_0801EA90: .4byte gBattlerAttacker
|
||||
@@ -2392,7 +2392,7 @@ _0801EA94: .4byte gCurrentMove
|
||||
_0801EA98: .4byte gMoveResultFlags
|
||||
_0801EA9C: .4byte gBattleMoves
|
||||
_0801EAA0: .4byte gLastUsedAbility
|
||||
_0801EAA4: .4byte gUnknown_2023DA0
|
||||
_0801EAA4: .4byte gLastLandedMoves
|
||||
_0801EAA8: .4byte gUnknown_2023DA8
|
||||
_0801EAAC: .4byte gBattleCommunication
|
||||
_0801EAB0: .4byte gProtectStructs
|
||||
@@ -2473,13 +2473,13 @@ _0801EB40: .4byte gBattlerTarget
|
||||
_0801EB44: .4byte gLastUsedAbility
|
||||
_0801EB48: .4byte gBattleCommunication
|
||||
_0801EB4C:
|
||||
ldr r1, _0801EB58 @ =gUnknown_824F050
|
||||
ldr r1, _0801EB58 @ =gTypeEffectiveness
|
||||
adds r0, r5, r1
|
||||
ldrb r0, [r0]
|
||||
adds r4, r1, 0
|
||||
b _0801EC9E
|
||||
.align 2, 0
|
||||
_0801EB58: .4byte gUnknown_824F050
|
||||
_0801EB58: .4byte gTypeEffectiveness
|
||||
_0801EB5C:
|
||||
adds r0, r5, r4
|
||||
ldrb r0, [r0]
|
||||
@@ -2919,7 +2919,7 @@ _0801EE94: .4byte gBattleMoves
|
||||
_0801EE98: .4byte gBattleMons
|
||||
_0801EE9C: .4byte gBattleMoveDamage
|
||||
_0801EEA0:
|
||||
ldr r1, _0801EEBC @ =gUnknown_824F050
|
||||
ldr r1, _0801EEBC @ =gTypeEffectiveness
|
||||
mov r2, r8
|
||||
adds r0, r2, r1
|
||||
ldrb r0, [r0]
|
||||
@@ -2934,13 +2934,13 @@ _0801EEA0:
|
||||
adds r0, r3, 0
|
||||
b _0801EF3E
|
||||
.align 2, 0
|
||||
_0801EEBC: .4byte gUnknown_824F050
|
||||
_0801EEBC: .4byte gTypeEffectiveness
|
||||
_0801EEC0:
|
||||
movs r0, 0x3
|
||||
add r8, r0
|
||||
b _0801EF28
|
||||
_0801EEC6:
|
||||
ldr r7, _0801EFC0 @ =gUnknown_824F050
|
||||
ldr r7, _0801EFC0 @ =gTypeEffectiveness
|
||||
mov r1, r8
|
||||
adds r0, r1, r7
|
||||
ldrb r0, [r0]
|
||||
@@ -2988,7 +2988,7 @@ _0801EF20:
|
||||
movs r1, 0x3
|
||||
add r8, r1
|
||||
ldr r5, _0801EFC4 @ =gBattleMons
|
||||
ldr r2, _0801EFC0 @ =gUnknown_824F050
|
||||
ldr r2, _0801EFC0 @ =gTypeEffectiveness
|
||||
_0801EF28:
|
||||
mov r3, r8
|
||||
adds r0, r3, r2
|
||||
@@ -3070,7 +3070,7 @@ _0801EFAE:
|
||||
pop {r1}
|
||||
bx r1
|
||||
.align 2, 0
|
||||
_0801EFC0: .4byte gUnknown_824F050
|
||||
_0801EFC0: .4byte gTypeEffectiveness
|
||||
_0801EFC4: .4byte gBattleMons
|
||||
_0801EFC8: .4byte gBattleMoves
|
||||
thumb_func_end TypeCalc
|
||||
@@ -3129,7 +3129,7 @@ _0801F00C:
|
||||
.align 2, 0
|
||||
_0801F030: .4byte gBattleMoves
|
||||
_0801F034:
|
||||
ldr r0, _0801F0C0 @ =gUnknown_824F050
|
||||
ldr r0, _0801F0C0 @ =gTypeEffectiveness
|
||||
adds r1, r7, r0
|
||||
ldrb r0, [r1]
|
||||
cmp r0, 0xFF
|
||||
@@ -3160,7 +3160,7 @@ _0801F05A:
|
||||
_0801F06C:
|
||||
adds r4, 0x3
|
||||
adds r7, 0x3
|
||||
ldr r1, _0801F0C0 @ =gUnknown_824F050
|
||||
ldr r1, _0801F0C0 @ =gTypeEffectiveness
|
||||
adds r0, r7, r1
|
||||
ldrb r0, [r0]
|
||||
cmp r0, 0xFF
|
||||
@@ -3205,7 +3205,7 @@ _0801F0B0:
|
||||
pop {r1}
|
||||
bx r1
|
||||
.align 2, 0
|
||||
_0801F0C0: .4byte gUnknown_824F050
|
||||
_0801F0C0: .4byte gTypeEffectiveness
|
||||
_0801F0C4: .4byte gBattleMoves
|
||||
thumb_func_end AI_TypeCalc
|
||||
|
||||
@@ -12325,7 +12325,7 @@ _08023966:
|
||||
ands r1, r0
|
||||
cmp r1, 0
|
||||
bne _08023984
|
||||
ldr r0, _080239C4 @ =gUnknown_2023DC0
|
||||
ldr r0, _080239C4 @ =gLastHitBy
|
||||
adds r0, r3, r0
|
||||
mov r3, r9
|
||||
ldrb r1, [r3]
|
||||
@@ -12348,7 +12348,7 @@ _08023984:
|
||||
ldr r0, _080239B8 @ =0x0000ffff
|
||||
cmp r3, r0
|
||||
bne _080239D4
|
||||
ldr r1, _080239D0 @ =gUnknown_2023DA0
|
||||
ldr r1, _080239D0 @ =gLastLandedMoves
|
||||
ldrb r0, [r2]
|
||||
lsls r0, 1
|
||||
adds r0, r1
|
||||
@@ -12359,12 +12359,12 @@ _080239B4: .4byte gLastMoves
|
||||
_080239B8: .4byte 0x0000ffff
|
||||
_080239BC: .4byte gUnknown_2023DB0
|
||||
_080239C0: .4byte gBattlerTarget
|
||||
_080239C4: .4byte gUnknown_2023DC0
|
||||
_080239C4: .4byte gLastHitBy
|
||||
_080239C8: .4byte gMoveResultFlags
|
||||
_080239CC: .4byte gChosenMove
|
||||
_080239D0: .4byte gUnknown_2023DA0
|
||||
_080239D0: .4byte gLastLandedMoves
|
||||
_080239D4:
|
||||
ldr r0, _080239F8 @ =gUnknown_2023DA0
|
||||
ldr r0, _080239F8 @ =gLastLandedMoves
|
||||
ldrb r1, [r2]
|
||||
lsls r1, 1
|
||||
adds r1, r0
|
||||
@@ -12383,7 +12383,7 @@ _080239D4:
|
||||
ands r0, r3
|
||||
b _08023A2A
|
||||
.align 2, 0
|
||||
_080239F8: .4byte gUnknown_2023DA0
|
||||
_080239F8: .4byte gLastLandedMoves
|
||||
_080239FC: .4byte gCurrentMove
|
||||
_08023A00: .4byte gUnknown_2023DA8
|
||||
_08023A04:
|
||||
@@ -12402,7 +12402,7 @@ _08023A04:
|
||||
.align 2, 0
|
||||
_08023A1C: .4byte gUnknown_2023DA8
|
||||
_08023A20:
|
||||
ldr r0, _08023A38 @ =gUnknown_2023DA0
|
||||
ldr r0, _08023A38 @ =gLastLandedMoves
|
||||
ldrb r1, [r2]
|
||||
lsls r1, 1
|
||||
adds r1, r0
|
||||
@@ -12416,7 +12416,7 @@ _08023A2C:
|
||||
strb r0, [r4, 0x14]
|
||||
b _08023BB4
|
||||
.align 2, 0
|
||||
_08023A38: .4byte gUnknown_2023DA0
|
||||
_08023A38: .4byte gLastLandedMoves
|
||||
_08023A3C: .4byte 0x0000ffff
|
||||
_08023A40:
|
||||
ldr r0, _08023B04 @ =gAbsentBattlerFlags
|
||||
@@ -12699,7 +12699,7 @@ atk4A_typecalc2: @ 8023C38
|
||||
movs r1, 0x9
|
||||
orrs r0, r1
|
||||
strb r0, [r2]
|
||||
ldr r1, _08023CB4 @ =gUnknown_2023DA0
|
||||
ldr r1, _08023CB4 @ =gLastLandedMoves
|
||||
ldrb r0, [r7]
|
||||
lsls r0, 1
|
||||
adds r0, r1
|
||||
@@ -12718,7 +12718,7 @@ _08023CA4: .4byte gBattleMons
|
||||
_08023CA8: .4byte gBattlerTarget
|
||||
_08023CAC: .4byte gLastUsedAbility
|
||||
_08023CB0: .4byte gMoveResultFlags
|
||||
_08023CB4: .4byte gUnknown_2023DA0
|
||||
_08023CB4: .4byte gLastLandedMoves
|
||||
_08023CB8: .4byte gBattleCommunication
|
||||
_08023CBC:
|
||||
ldr r0, _08023CC8 @ =gMoveResultFlags
|
||||
@@ -12730,13 +12730,13 @@ _08023CBC:
|
||||
.align 2, 0
|
||||
_08023CC8: .4byte gMoveResultFlags
|
||||
_08023CCC:
|
||||
ldr r1, _08023CD8 @ =gUnknown_824F050
|
||||
ldr r1, _08023CD8 @ =gTypeEffectiveness
|
||||
adds r0, r5, r1
|
||||
ldrb r0, [r0]
|
||||
adds r6, r1, 0
|
||||
b _08023D8E
|
||||
.align 2, 0
|
||||
_08023CD8: .4byte gUnknown_824F050
|
||||
_08023CD8: .4byte gTypeEffectiveness
|
||||
_08023CDC:
|
||||
adds r0, r5, r6
|
||||
ldrb r0, [r0]
|
||||
@@ -12899,7 +12899,7 @@ _08023DF0:
|
||||
movs r1, 0x1
|
||||
orrs r0, r1
|
||||
strb r0, [r2]
|
||||
ldr r1, _08023E78 @ =gUnknown_2023DA0
|
||||
ldr r1, _08023E78 @ =gLastLandedMoves
|
||||
mov r2, r8
|
||||
ldrb r0, [r2]
|
||||
lsls r0, 1
|
||||
@@ -12945,7 +12945,7 @@ _08023E68: .4byte gCurrentMove
|
||||
_08023E6C: .4byte gBattleMoves
|
||||
_08023E70: .4byte gLastUsedAbility
|
||||
_08023E74: .4byte gMoveResultFlags
|
||||
_08023E78: .4byte gUnknown_2023DA0
|
||||
_08023E78: .4byte gLastLandedMoves
|
||||
_08023E7C: .4byte gBattleCommunication
|
||||
_08023E80: .4byte gProtectStructs
|
||||
_08023E84: .4byte gBattlescriptCurrInstr
|
||||
@@ -24813,7 +24813,7 @@ atkA6_settypetorandomresistance: @ 8029DAC
|
||||
mov r6, r9
|
||||
mov r5, r8
|
||||
push {r5-r7}
|
||||
ldr r1, _08029E14 @ =gUnknown_2023DA0
|
||||
ldr r1, _08029E14 @ =gLastLandedMoves
|
||||
ldr r4, _08029E18 @ =gBattlerAttacker
|
||||
ldrb r0, [r4]
|
||||
lsls r0, 1
|
||||
@@ -24830,7 +24830,7 @@ atkA6_settypetorandomresistance: @ 8029DAC
|
||||
cmp r0, 0
|
||||
beq _08029E94
|
||||
ldr r1, _08029E20 @ =gBattleMons
|
||||
ldr r2, _08029E24 @ =gUnknown_2023DC0
|
||||
ldr r2, _08029E24 @ =gLastHitBy
|
||||
ldrb r0, [r4]
|
||||
adds r0, r2
|
||||
ldrb r2, [r0]
|
||||
@@ -24860,11 +24860,11 @@ _08029DF6:
|
||||
str r1, [r3]
|
||||
b _08029F80
|
||||
.align 2, 0
|
||||
_08029E14: .4byte gUnknown_2023DA0
|
||||
_08029E14: .4byte gLastLandedMoves
|
||||
_08029E18: .4byte gBattlerAttacker
|
||||
_08029E1C: .4byte 0x0000ffff
|
||||
_08029E20: .4byte gBattleMons
|
||||
_08029E24: .4byte gUnknown_2023DC0
|
||||
_08029E24: .4byte gLastHitBy
|
||||
_08029E28: .4byte gBattlescriptCurrInstr
|
||||
_08029E2C:
|
||||
mov r0, r12
|
||||
@@ -24931,7 +24931,7 @@ _08029E9C:
|
||||
bhi _08029E9C
|
||||
lsls r0, r4, 1
|
||||
adds r4, r0, r4
|
||||
ldr r6, _08029F90 @ =gUnknown_824F050
|
||||
ldr r6, _08029F90 @ =gTypeEffectiveness
|
||||
adds r3, r4, r6
|
||||
ldr r1, _08029F94 @ =gUnknown_2023DA8
|
||||
ldr r2, _08029F98 @ =gBattlerAttacker
|
||||
@@ -24979,7 +24979,7 @@ _08029EF8:
|
||||
mov r8, r0
|
||||
ldr r1, _08029FA4 @ =gBattlescriptCurrInstr
|
||||
mov r12, r1
|
||||
ldr r3, _08029F90 @ =gUnknown_824F050
|
||||
ldr r3, _08029F90 @ =gTypeEffectiveness
|
||||
adds r0, r4, 0x1
|
||||
adds r0, r3
|
||||
mov r9, r0
|
||||
@@ -25050,7 +25050,7 @@ _08029F80:
|
||||
pop {r0}
|
||||
bx r0
|
||||
.align 2, 0
|
||||
_08029F90: .4byte gUnknown_824F050
|
||||
_08029F90: .4byte gTypeEffectiveness
|
||||
_08029F94: .4byte gUnknown_2023DA8
|
||||
_08029F98: .4byte gBattlerAttacker
|
||||
_08029F9C: .4byte gBattleMons
|
||||
|
||||
+1
-1
@@ -233,7 +233,7 @@ gUnknown_824F020:: @ 824F020
|
||||
gUnknown_824F048:: @ 824F048
|
||||
.incbin "baserom.gba", 0x24F048, 0x8
|
||||
|
||||
gUnknown_824F050:: @ 824F050
|
||||
gTypeEffectiveness:: @ 824F050
|
||||
.incbin "baserom.gba", 0x24F050, 0x150
|
||||
|
||||
gUnknown_824F1A0:: @ 824F1A0
|
||||
|
||||
+2
-3
@@ -175,9 +175,6 @@ struct TrainerMonNoItemDefaultMoves
|
||||
u16 species;
|
||||
};
|
||||
|
||||
u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg);
|
||||
u8 GetBattlerSide(u8 bank);
|
||||
|
||||
struct TrainerMonItemDefaultMoves
|
||||
{
|
||||
u16 iv;
|
||||
@@ -985,5 +982,7 @@ extern u8 gChosenMovePos;
|
||||
extern u8 gUnknown_3004FFC[MAX_BATTLERS_COUNT];
|
||||
extern u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT];
|
||||
extern u16 gDynamicBasePower;
|
||||
extern u16 gLastLandedMoves[MAX_BATTLERS_COUNT];
|
||||
extern u8 gLastHitBy[MAX_BATTLERS_COUNT];
|
||||
|
||||
#endif // GUARD_BATTLE_H
|
||||
|
||||
@@ -59,4 +59,6 @@ extern const u8 gStatusConditionString_LoveJpn[8];
|
||||
|
||||
extern const u8 * const gStatusConditionStringsTable[7][2];
|
||||
|
||||
extern const u8 gTypeEffectiveness[336];
|
||||
|
||||
#endif // GUARD_BATTLE_2_H
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ SECTIONS {
|
||||
asm/battle_controller_player.o(.text);
|
||||
src/battle_gfx_sfx_util.o(.text);
|
||||
src/battle_controller_opponent.o(.text);
|
||||
asm/battle_ai_switch_items.o(.text);
|
||||
src/battle_ai_switch_items.o(.text);
|
||||
asm/battle_controller_link_opponent.o(.text);
|
||||
src/pokemon.o(.text);
|
||||
src/trig.o(.text);
|
||||
|
||||
@@ -0,0 +1,734 @@
|
||||
#include "global.h"
|
||||
#include "battle.h"
|
||||
#include "battle_anim.h"
|
||||
#include "battle_controllers.h"
|
||||
#include "pokemon.h"
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "constants/item_effects.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/species.h"
|
||||
#include "constants/pokemon.h"
|
||||
|
||||
static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
|
||||
static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent);
|
||||
static bool8 ShouldUseItem(void);
|
||||
|
||||
static bool8 ShouldSwitchIfPerishSong(void)
|
||||
{
|
||||
if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG
|
||||
&& gDisableStructs[gActiveBattler].perishSongTimer == 0)
|
||||
{
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = PARTY_SIZE;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool8 ShouldSwitchIfWonderGuard(void)
|
||||
{
|
||||
u8 opposingBattler;
|
||||
u8 moveFlags;
|
||||
s32 i, j;
|
||||
u16 move;
|
||||
|
||||
if(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
return FALSE;
|
||||
if (gBattleMons[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)].ability == ABILITY_WONDER_GUARD)
|
||||
{
|
||||
// Check if Pokemon has a super effective move.
|
||||
for (opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT), i = 0; i < MAX_MON_MOVES; ++i)
|
||||
{
|
||||
move = gBattleMons[gActiveBattler].moves[i];
|
||||
if (move == MOVE_NONE)
|
||||
continue;
|
||||
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability);
|
||||
if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE)
|
||||
return FALSE;
|
||||
}
|
||||
// Find a Pokemon in the party that has a super effective move.
|
||||
for (i = 0; i < PARTY_SIZE; ++i)
|
||||
{
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG)
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[gActiveBattler])
|
||||
continue;
|
||||
GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); // Unused return value.
|
||||
GetMonData(&gEnemyParty[i], MON_DATA_ABILITY_NUM); // Unused return value.
|
||||
|
||||
for (opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT), j = 0; j < MAX_MON_MOVES; ++j)
|
||||
{
|
||||
move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j);
|
||||
if (move == MOVE_NONE)
|
||||
continue;
|
||||
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability);
|
||||
if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE && Random() % 3 < 2)
|
||||
{
|
||||
// We found a mon.
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = i;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE; // There is not a single Pokemon in the party that has a super effective move against a mon with Wonder Guard.
|
||||
}
|
||||
|
||||
static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
||||
{
|
||||
u8 battlerIn1, battlerIn2;
|
||||
u8 absorbingTypeAbility;
|
||||
s32 i;
|
||||
|
||||
if (HasSuperEffectiveMoveAgainstOpponents(TRUE) && Random() % 3)
|
||||
return FALSE;
|
||||
if (gLastLandedMoves[gActiveBattler] == MOVE_NONE)
|
||||
return FALSE;
|
||||
if (gLastLandedMoves[gActiveBattler] == 0xFFFF)
|
||||
return FALSE;
|
||||
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0)
|
||||
return FALSE;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
battlerIn1 = gActiveBattler;
|
||||
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))])
|
||||
battlerIn2 = gActiveBattler;
|
||||
else
|
||||
battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)));
|
||||
}
|
||||
else
|
||||
{
|
||||
battlerIn1 = gActiveBattler;
|
||||
battlerIn2 = gActiveBattler;
|
||||
}
|
||||
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_FIRE)
|
||||
absorbingTypeAbility = ABILITY_FLASH_FIRE;
|
||||
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_WATER)
|
||||
absorbingTypeAbility = ABILITY_WATER_ABSORB;
|
||||
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_ELECTRIC)
|
||||
absorbingTypeAbility = ABILITY_VOLT_ABSORB;
|
||||
else
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility)
|
||||
return FALSE;
|
||||
for (i = 0; i < PARTY_SIZE; ++i)
|
||||
{
|
||||
u16 species;
|
||||
u8 monAbility;
|
||||
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG)
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battlerIn1])
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battlerIn2])
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn1))
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn2))
|
||||
continue;
|
||||
species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES);
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_ABILITY_NUM) != ABILITY_NONE)
|
||||
monAbility = gBaseStats[species].abilities[1];
|
||||
else
|
||||
monAbility = gBaseStats[species].abilities[0];
|
||||
if (absorbingTypeAbility == monAbility && Random() & 1)
|
||||
{
|
||||
// we found a mon
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = i;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool8 ShouldSwitchIfNaturalCure(void)
|
||||
{
|
||||
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].ability != ABILITY_NATURAL_CURE)
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2)
|
||||
return FALSE;
|
||||
if ((gLastLandedMoves[gActiveBattler] == MOVE_NONE || gLastLandedMoves[gActiveBattler] == 0xFFFF) && Random() & 1)
|
||||
{
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = PARTY_SIZE;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0 && Random() & 1)
|
||||
{
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = PARTY_SIZE;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_DOESNT_AFFECT_FOE, 1))
|
||||
return TRUE;
|
||||
if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_NOT_VERY_EFFECTIVE, 1))
|
||||
return TRUE;
|
||||
if (Random() & 1)
|
||||
{
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = PARTY_SIZE;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng)
|
||||
{
|
||||
u8 opposingBattler;
|
||||
s32 i;
|
||||
u8 moveFlags;
|
||||
u16 move;
|
||||
|
||||
opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
||||
if (!(gAbsentBattlerFlags & gBitTable[opposingBattler]))
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; ++i)
|
||||
{
|
||||
move = gBattleMons[gActiveBattler].moves[i];
|
||||
if (move == MOVE_NONE)
|
||||
continue;
|
||||
|
||||
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability);
|
||||
if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE)
|
||||
{
|
||||
if (noRng)
|
||||
return TRUE;
|
||||
if (Random() % 10 != 0)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
||||
return FALSE;
|
||||
opposingBattler = GetBattlerAtPosition(BATTLE_PARTNER(B_POSITION_PLAYER_LEFT));
|
||||
if (!(gAbsentBattlerFlags & gBitTable[opposingBattler]))
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; ++i)
|
||||
{
|
||||
move = gBattleMons[gActiveBattler].moves[i];
|
||||
if (move == MOVE_NONE)
|
||||
continue;
|
||||
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability);
|
||||
if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE)
|
||||
{
|
||||
if (noRng)
|
||||
return TRUE;
|
||||
if (Random() % 10 != 0)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool8 AreStatsRaised(void)
|
||||
{
|
||||
u8 buffedStatsValue = 0;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < NUM_BATTLE_STATS; ++i)
|
||||
{
|
||||
if (gBattleMons[gActiveBattler].statStages[i] > 6)
|
||||
buffedStatsValue += gBattleMons[gActiveBattler].statStages[i] - 6;
|
||||
}
|
||||
return (buffedStatsValue > 3);
|
||||
}
|
||||
|
||||
static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
|
||||
{
|
||||
u8 battlerIn1, battlerIn2;
|
||||
s32 i, j;
|
||||
u16 move;
|
||||
u8 moveFlags;
|
||||
|
||||
if (gLastLandedMoves[gActiveBattler] == 0)
|
||||
return FALSE;
|
||||
if (gLastLandedMoves[gActiveBattler] == 0xFFFF)
|
||||
return FALSE;
|
||||
if (gLastHitBy[gActiveBattler] == 0xFF)
|
||||
return FALSE;
|
||||
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0)
|
||||
return FALSE;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
battlerIn1 = gActiveBattler;
|
||||
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))])
|
||||
battlerIn2 = gActiveBattler;
|
||||
else
|
||||
battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)));
|
||||
}
|
||||
else
|
||||
{
|
||||
battlerIn1 = gActiveBattler;
|
||||
battlerIn2 = gActiveBattler;
|
||||
}
|
||||
|
||||
for (i = 0; i < PARTY_SIZE; ++i)
|
||||
{
|
||||
u16 species;
|
||||
u8 monAbility;
|
||||
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG)
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battlerIn1])
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battlerIn2])
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn1))
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn2))
|
||||
continue;
|
||||
species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES);
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_ABILITY_NUM) != ABILITY_NONE)
|
||||
monAbility = gBaseStats[species].abilities[1];
|
||||
else
|
||||
monAbility = gBaseStats[species].abilities[0];
|
||||
moveFlags = AI_TypeCalc(gLastLandedMoves[gActiveBattler], species, monAbility);
|
||||
if (moveFlags & flags)
|
||||
{
|
||||
battlerIn1 = gLastHitBy[gActiveBattler];
|
||||
for (j = 0; j < MAX_MON_MOVES; ++j)
|
||||
{
|
||||
move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j);
|
||||
if (move == MOVE_NONE)
|
||||
continue;
|
||||
moveFlags = AI_TypeCalc(move, gBattleMons[battlerIn1].species, gBattleMons[battlerIn1].ability);
|
||||
if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE && Random() % moduloPercent == 0)
|
||||
{
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = i;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool8 ShouldSwitch(void)
|
||||
{
|
||||
u8 battlerIn1, battlerIn2;
|
||||
s32 i;
|
||||
s32 availableToSwitch;
|
||||
|
||||
if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
|
||||
return FALSE;
|
||||
if (gStatuses3[gActiveBattler] & STATUS3_ROOTED)
|
||||
return FALSE;
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_SHADOW_TAG, 0, 0))
|
||||
return FALSE;
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_ARENA_TRAP, 0, 0))
|
||||
return FALSE; // misses the flying or levitate check
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MAGNET_PULL, 0, 0))
|
||||
{
|
||||
if (gBattleMons[gActiveBattler].type1 == TYPE_STEEL)
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].type2 == TYPE_STEEL)
|
||||
return FALSE;
|
||||
}
|
||||
availableToSwitch = 0;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
battlerIn1 = gActiveBattler;
|
||||
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK)])
|
||||
battlerIn2 = gActiveBattler;
|
||||
else
|
||||
battlerIn2 = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK);
|
||||
}
|
||||
else
|
||||
{
|
||||
battlerIn2 = gActiveBattler;
|
||||
battlerIn1 = gActiveBattler;
|
||||
}
|
||||
for (i = 0; i < PARTY_SIZE; ++i)
|
||||
{
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG)
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battlerIn1])
|
||||
continue;
|
||||
if (i == gBattlerPartyIndexes[battlerIn2])
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn1))
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn2))
|
||||
continue;
|
||||
++availableToSwitch;
|
||||
}
|
||||
if (!availableToSwitch)
|
||||
return FALSE;
|
||||
if (ShouldSwitchIfPerishSong())
|
||||
return TRUE;
|
||||
if (ShouldSwitchIfWonderGuard())
|
||||
return TRUE;
|
||||
if (FindMonThatAbsorbsOpponentsMove())
|
||||
return TRUE;
|
||||
if (ShouldSwitchIfNaturalCure())
|
||||
return TRUE;
|
||||
if (HasSuperEffectiveMoveAgainstOpponents(FALSE))
|
||||
return FALSE;
|
||||
if (AreStatsRaised())
|
||||
return FALSE;
|
||||
if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_DOESNT_AFFECT_FOE, 2)
|
||||
|| FindMonWithFlagsAndSuperEffective(MOVE_RESULT_NOT_VERY_EFFECTIVE, 3))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void AI_TrySwitchOrUseItem(void)
|
||||
{
|
||||
u8 battlerIn1, battlerIn2;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
||||
{
|
||||
if (ShouldSwitch())
|
||||
{
|
||||
if (*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) == 6)
|
||||
{
|
||||
s32 monToSwitchId = GetMostSuitableMonToSwitchInto();
|
||||
if (monToSwitchId == 6)
|
||||
{
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
||||
{
|
||||
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
||||
battlerIn2 = battlerIn1;
|
||||
}
|
||||
else
|
||||
{
|
||||
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
||||
battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
||||
}
|
||||
|
||||
for (monToSwitchId = 0; monToSwitchId < PARTY_SIZE; ++monToSwitchId)
|
||||
{
|
||||
if (GetMonData(&gEnemyParty[monToSwitchId], MON_DATA_HP) == 0)
|
||||
continue;
|
||||
if (monToSwitchId == gBattlerPartyIndexes[battlerIn1])
|
||||
continue;
|
||||
if (monToSwitchId == gBattlerPartyIndexes[battlerIn2])
|
||||
continue;
|
||||
if (monToSwitchId == *(gBattleStruct->monToSwitchIntoId + battlerIn1))
|
||||
continue;
|
||||
if (monToSwitchId == *(gBattleStruct->monToSwitchIntoId + battlerIn2))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1)) = monToSwitchId;
|
||||
}
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = *(gBattleStruct->AI_monToSwitchIntoId + (GetBattlerPosition(gActiveBattler) >> 1));
|
||||
return;
|
||||
}
|
||||
else if (ShouldUseItem())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_USE_MOVE, (gActiveBattler ^ BIT_SIDE) << 8);
|
||||
}
|
||||
|
||||
static void ModulateByTypeEffectiveness(u8 atkType, u8 defType1, u8 defType2, u8 *var)
|
||||
{
|
||||
s32 i = 0;
|
||||
|
||||
while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE)
|
||||
{
|
||||
if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
|
||||
{
|
||||
i += 3;
|
||||
continue;
|
||||
}
|
||||
else if (TYPE_EFFECT_ATK_TYPE(i) == atkType)
|
||||
{
|
||||
// Check type1.
|
||||
if (TYPE_EFFECT_DEF_TYPE(i) == defType1)
|
||||
*var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10;
|
||||
// Check type2.
|
||||
if (TYPE_EFFECT_DEF_TYPE(i) == defType2 && defType1 != defType2)
|
||||
*var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10;
|
||||
}
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
u8 GetMostSuitableMonToSwitchInto(void)
|
||||
{
|
||||
u8 opposingBattler;
|
||||
u8 bestDmg; // Note : should be changed to u32 for obvious reasons.
|
||||
u8 bestMonId;
|
||||
u8 battlerIn1, battlerIn2;
|
||||
s32 i, j;
|
||||
u8 invalidMons;
|
||||
u16 move;
|
||||
|
||||
if (*(gBattleStruct->monToSwitchIntoId + gActiveBattler) != PARTY_SIZE)
|
||||
return *(gBattleStruct->monToSwitchIntoId + gActiveBattler);
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
battlerIn1 = gActiveBattler;
|
||||
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK)])
|
||||
battlerIn2 = gActiveBattler;
|
||||
else
|
||||
battlerIn2 = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK);
|
||||
// UB: It considers the opponent only player's side even though it can battle alongside player.
|
||||
opposingBattler = Random() & BIT_FLANK;
|
||||
if (gAbsentBattlerFlags & gBitTable[opposingBattler])
|
||||
opposingBattler ^= BIT_FLANK;
|
||||
}
|
||||
else
|
||||
{
|
||||
opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
||||
battlerIn1 = gActiveBattler;
|
||||
battlerIn2 = gActiveBattler;
|
||||
}
|
||||
invalidMons = 0;
|
||||
while (invalidMons != 0x3F) // All mons are invalid.
|
||||
{
|
||||
bestDmg = 0;
|
||||
bestMonId = 6;
|
||||
// Find the mon whose type is the most suitable offensively.
|
||||
for (i = 0; i < PARTY_SIZE; ++i)
|
||||
{
|
||||
u16 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES);
|
||||
if (species != SPECIES_NONE
|
||||
&& GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0
|
||||
&& !(gBitTable[i] & invalidMons)
|
||||
&& gBattlerPartyIndexes[battlerIn1] != i
|
||||
&& gBattlerPartyIndexes[battlerIn2] != i
|
||||
&& i != *(gBattleStruct->monToSwitchIntoId + battlerIn1)
|
||||
&& i != *(gBattleStruct->monToSwitchIntoId + battlerIn2))
|
||||
{
|
||||
u8 type1 = gBaseStats[species].type1;
|
||||
u8 type2 = gBaseStats[species].type2;
|
||||
u8 typeDmg = 10;
|
||||
ModulateByTypeEffectiveness(gBattleMons[opposingBattler].type1, type1, type2, &typeDmg);
|
||||
ModulateByTypeEffectiveness(gBattleMons[opposingBattler].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 != PARTY_SIZE)
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; ++i)
|
||||
{
|
||||
move = GetMonData(&gEnemyParty[bestMonId], MON_DATA_MOVE1 + i);
|
||||
if (move != MOVE_NONE && TypeCalc(move, gActiveBattler, opposingBattler) & MOVE_RESULT_SUPER_EFFECTIVE)
|
||||
break;
|
||||
}
|
||||
if (i != MAX_MON_MOVES)
|
||||
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;
|
||||
gMoveResultFlags = 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 = 0; i < PARTY_SIZE; ++i)
|
||||
{
|
||||
if ((u16)(GetMonData(&gEnemyParty[i], MON_DATA_SPECIES)) == SPECIES_NONE)
|
||||
continue;
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0)
|
||||
continue;
|
||||
if (gBattlerPartyIndexes[battlerIn1] == i)
|
||||
continue;
|
||||
if (gBattlerPartyIndexes[battlerIn2] == i)
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn1))
|
||||
continue;
|
||||
if (i == *(gBattleStruct->monToSwitchIntoId + battlerIn2))
|
||||
continue;
|
||||
for (j = 0; j < MAX_MON_MOVES; ++j)
|
||||
{
|
||||
move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j);
|
||||
gBattleMoveDamage = 0;
|
||||
if (move != MOVE_NONE && gBattleMoves[move].power != 1)
|
||||
{
|
||||
AI_CalcDmg(gActiveBattler, opposingBattler);
|
||||
TypeCalc(move, gActiveBattler, opposingBattler);
|
||||
}
|
||||
if (bestDmg < gBattleMoveDamage)
|
||||
{
|
||||
bestDmg = gBattleMoveDamage;
|
||||
bestMonId = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestMonId;
|
||||
}
|
||||
|
||||
static u8 GetAI_ItemType(u8 itemId, const u8 *itemEffect) // NOTE: should take u16 as item Id argument
|
||||
{
|
||||
if (itemId == ITEM_FULL_RESTORE)
|
||||
return AI_ITEM_FULL_RESTORE;
|
||||
else if (itemEffect[4] & ITEM4_HEAL_HP)
|
||||
return AI_ITEM_HEAL_HP;
|
||||
else if (itemEffect[3] & ITEM3_STATUS_ALL)
|
||||
return AI_ITEM_CURE_CONDITION;
|
||||
else if (itemEffect[0] & (ITEM0_HIGH_CRIT | ITEM0_X_ATTACK) || itemEffect[1] != 0 || itemEffect[2] != 0)
|
||||
return AI_ITEM_X_STAT;
|
||||
else if (itemEffect[3] & ITEM3_MIST)
|
||||
return AI_ITEM_GUARD_SPECS;
|
||||
else
|
||||
return AI_ITEM_NOT_RECOGNIZABLE;
|
||||
}
|
||||
|
||||
static bool8 ShouldUseItem(void)
|
||||
{
|
||||
s32 i;
|
||||
u8 validMons = 0;
|
||||
bool8 shouldUse = FALSE;
|
||||
|
||||
for (i = 0; i < PARTY_SIZE; ++i)
|
||||
if (GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0
|
||||
&& GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) != SPECIES_NONE
|
||||
&& GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) != SPECIES_EGG)
|
||||
++validMons;
|
||||
for (i = 0; i < MAX_MON_MOVES; ++i)
|
||||
{
|
||||
u16 item;
|
||||
const u8 *itemEffects;
|
||||
u8 paramOffset;
|
||||
u8 battlerSide;
|
||||
|
||||
if (i && validMons > (gBattleResources->battleHistory->itemsNo - i) + 1)
|
||||
continue;
|
||||
item = gBattleResources->battleHistory->trainerItems[i];
|
||||
if (item == ITEM_NONE)
|
||||
continue;
|
||||
if (gItemEffectTable[item - ITEM_POTION] == NULL)
|
||||
continue;
|
||||
if (item == ITEM_ENIGMA_BERRY)
|
||||
itemEffects = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
||||
else
|
||||
itemEffects = gItemEffectTable[item - ITEM_POTION];
|
||||
*(gBattleStruct->AI_itemType + gActiveBattler / 2) = GetAI_ItemType(item, itemEffects);
|
||||
switch (*(gBattleStruct->AI_itemType + gActiveBattler / 2))
|
||||
{
|
||||
case AI_ITEM_FULL_RESTORE:
|
||||
if (gBattleMons[gActiveBattler].hp >= gBattleMons[gActiveBattler].maxHP / 4)
|
||||
break;
|
||||
if (gBattleMons[gActiveBattler].hp == 0)
|
||||
break;
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case AI_ITEM_HEAL_HP:
|
||||
paramOffset = GetItemEffectParamOffset(item, 4, 4);
|
||||
if (paramOffset == 0)
|
||||
break;
|
||||
if (gBattleMons[gActiveBattler].hp == 0)
|
||||
break;
|
||||
if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 4 || gBattleMons[gActiveBattler].maxHP - gBattleMons[gActiveBattler].hp > itemEffects[paramOffset])
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case AI_ITEM_CURE_CONDITION:
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) = 0;
|
||||
if (itemEffects[3] & ITEM3_SLEEP && gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x20;
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_POISON && (gBattleMons[gActiveBattler].status1 & STATUS1_POISON || gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_POISON))
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x10;
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_BURN && gBattleMons[gActiveBattler].status1 & STATUS1_BURN)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x8;
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_FREEZE && gBattleMons[gActiveBattler].status1 & STATUS1_FREEZE)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x4;
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_PARALYSIS && gBattleMons[gActiveBattler].status1 & STATUS1_PARALYSIS)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x2;
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_CONFUSION && gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x1;
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
break;
|
||||
case AI_ITEM_X_STAT:
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) = 0;
|
||||
if (!gDisableStructs[gActiveBattler].isFirstTurn)
|
||||
break;
|
||||
if (itemEffects[0] & ITEM0_X_ATTACK)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x1;
|
||||
if (itemEffects[1] & ITEM1_X_DEFEND)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x2;
|
||||
if (itemEffects[1] & ITEM1_X_SPEED)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x4;
|
||||
if (itemEffects[2] & ITEM2_X_SPATK)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x8;
|
||||
if (itemEffects[2] & ITEM2_X_ACCURACY)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x20;
|
||||
if (itemEffects[0] & ITEM0_HIGH_CRIT)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x80;
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case AI_ITEM_GUARD_SPECS:
|
||||
battlerSide = GetBattlerSide(gActiveBattler);
|
||||
if (gDisableStructs[gActiveBattler].isFirstTurn && gSideTimers[battlerSide].mistTimer == 0)
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case AI_ITEM_NOT_RECOGNIZABLE:
|
||||
return FALSE;
|
||||
}
|
||||
if (shouldUse)
|
||||
{
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_USE_ITEM, 0);
|
||||
*(gBattleStruct->chosenItem + (gActiveBattler / 2) * 2) = item;
|
||||
gBattleResources->battleHistory->trainerItems[i] = 0;
|
||||
return shouldUse;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1439,7 +1439,7 @@ static void OpponentHandleChoosePokemon(void)
|
||||
battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
||||
battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
||||
}
|
||||
for (chosenMonId = 0; chosenMonId < 6; ++chosenMonId)
|
||||
for (chosenMonId = 0; chosenMonId < PARTY_SIZE; ++chosenMonId)
|
||||
if (GetMonData(&gEnemyParty[chosenMonId], MON_DATA_HP) != 0
|
||||
&& chosenMonId != gBattlerPartyIndexes[battler1]
|
||||
&& chosenMonId != gBattlerPartyIndexes[battler2])
|
||||
|
||||
+2
-2
@@ -291,7 +291,7 @@ gUnknown_2023D90: @ 2023D90
|
||||
gLastMoves: @ 2023D98
|
||||
.space 0x8
|
||||
|
||||
gUnknown_2023DA0: @ 2023DA0
|
||||
gLastLandedMoves: @ 2023DA0
|
||||
.space 0x8
|
||||
|
||||
gUnknown_2023DA8: @ 2023DA8
|
||||
@@ -303,7 +303,7 @@ gUnknown_2023DB0: @ 2023DB0
|
||||
gUnknown_2023DB8: @ 2023DB8
|
||||
.space 0x8
|
||||
|
||||
gUnknown_2023DC0: @ 2023DC0
|
||||
gLastHitBy: @ 2023DC0
|
||||
.space 0x4
|
||||
|
||||
gChosenMoveByBattler: @ 2023DC4
|
||||
|
||||
Reference in New Issue
Block a user