summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/battle_9.s646
-rw-r--r--include/battle.h6
-rw-r--r--include/battle_ai_switch_items.h10
-rw-r--r--include/pokemon.h1
-rw-r--r--include/pokemon_item_effects.h54
-rw-r--r--ld_script.txt3
-rw-r--r--src/battle_2.c28
-rw-r--r--src/battle_ai_script_commands.c2
-rw-r--r--src/battle_ai_switch_items.c (renamed from src/battle_9.c)179
9 files changed, 252 insertions, 677 deletions
diff --git a/asm/battle_9.s b/asm/battle_9.s
deleted file mode 100644
index 0cf529bcc..000000000
--- a/asm/battle_9.s
+++ /dev/null
@@ -1,646 +0,0 @@
- .include "asm/macros.inc"
- .include "constants/constants.inc"
-
- .syntax unified
-
- .text
-
-
- thumb_func_start ai_identify_item_effect
-ai_identify_item_effect: @ 8063E84
- push {r4,lr}
- adds r2, r1, 0
- lsls r0, 24
- lsrs r0, 24
- cmp r0, 0x13
- bne _08063E94
- movs r0, 0x1
- b _08063EDA
-_08063E94:
- ldrb r1, [r2, 0x4]
- movs r0, 0x4
- ands r0, r1
- cmp r0, 0
- beq _08063EA2
- movs r0, 0x2
- b _08063EDA
-_08063EA2:
- ldrb r4, [r2, 0x3]
- movs r3, 0x3F
- adds r0, r3, 0
- ands r0, r4
- cmp r0, 0
- beq _08063EB2
- movs r0, 0x3
- b _08063EDA
-_08063EB2:
- ldrb r1, [r2]
- adds r0, r3, 0
- ands r0, r1
- cmp r0, 0
- bne _08063EC8
- ldrb r0, [r2, 0x1]
- cmp r0, 0
- bne _08063EC8
- ldrb r0, [r2, 0x2]
- cmp r0, 0
- beq _08063ECC
-_08063EC8:
- movs r0, 0x4
- b _08063EDA
-_08063ECC:
- movs r0, 0x80
- ands r0, r4
- cmp r0, 0
- bne _08063ED8
- movs r0, 0x6
- b _08063EDA
-_08063ED8:
- movs r0, 0x5
-_08063EDA:
- pop {r4}
- pop {r1}
- bx r1
- thumb_func_end ai_identify_item_effect
-
- thumb_func_start ShouldUseItem
-ShouldUseItem: @ 8063EE0
- push {r4-r7,lr}
- mov r7, r10
- mov r6, r9
- mov r5, r8
- push {r5-r7}
- sub sp, 0x4
- movs r0, 0
- mov r10, r0
- movs r7, 0
- ldr r0, =gBattleTypeFlags
- ldr r0, [r0]
- movs r1, 0x80
- lsls r1, 15
- ands r0, r1
- cmp r0, 0
- beq _08063F12
- ldr r0, =gActiveBank
- ldrb r0, [r0]
- bl GetBankIdentity
- lsls r0, 24
- lsrs r0, 24
- cmp r0, 0x2
- bne _08063F12
- b _0806437C
-_08063F12:
- ldr r0, =gActiveBank
- ldrb r0, [r0]
- bl GetBankSide
- lsls r0, 24
- ldr r5, =gEnemyParty
- cmp r0, 0
- bne _08063F24
- ldr r5, =gPlayerParty
-_08063F24:
- movs r1, 0
- mov r8, r1
-_08063F28:
- movs r0, 0x64
- mov r2, r8
- muls r2, r0
- adds r0, r2, 0
- adds r4, r5, r0
- adds r0, r4, 0
- movs r1, 0x39
- bl GetMonData
- cmp r0, 0
- beq _08063F64
- adds r0, r4, 0
- movs r1, 0x41
- bl GetMonData
- cmp r0, 0
- beq _08063F64
- adds r0, r4, 0
- movs r1, 0x41
- bl GetMonData
- movs r1, 0xCE
- lsls r1, 1
- cmp r0, r1
- beq _08063F64
- mov r0, r10
- adds r0, 0x1
- lsls r0, 24
- lsrs r0, 24
- mov r10, r0
-_08063F64:
- movs r0, 0x1
- add r8, r0
- mov r1, r8
- cmp r1, 0x5
- ble _08063F28
- movs r2, 0
- mov r8, r2
-_08063F72:
- ldr r1, =gBattleResources
- mov r0, r8
- cmp r0, 0
- beq _08063F8E
- ldr r0, [r1]
- ldr r0, [r0, 0x18]
- adds r0, 0x50
- ldrb r0, [r0]
- mov r2, r8
- subs r0, r2
- adds r0, 0x1
- cmp r10, r0
- ble _08063F8E
- b _08064370
-_08063F8E:
- ldr r0, [r1]
- ldr r0, [r0, 0x18]
- mov r2, r8
- lsls r1, r2, 1
- adds r0, 0x48
- adds r0, r1
- ldrh r0, [r0]
- mov r9, r0
- str r1, [sp]
- cmp r0, 0
- bne _08063FA6
- b _08064370
-_08063FA6:
- ldr r1, =gItemEffectTable
- subs r0, 0xD
- lsls r0, 2
- adds r0, r1
- ldr r1, [r0]
- cmp r1, 0
- bne _08063FB6
- b _08064370
-_08063FB6:
- mov r0, r9
- cmp r0, 0xAF
- bne _08063FE8
- ldr r0, =gSaveBlock1Ptr
- ldr r0, [r0]
- ldr r1, =0x00003214
- adds r5, r0, r1
- b _08063FEA
- .pool
-_08063FE8:
- adds r5, r1, 0
-_08063FEA:
- mov r2, r9
- lsls r0, r2, 24
- lsrs r0, 24
- adds r1, r5, 0
- bl ai_identify_item_effect
- ldr r4, =gActiveBank
- ldrb r1, [r4]
- lsrs r1, 1
- ldr r3, =gBattleStruct
- ldr r2, [r3]
- adds r1, r2
- adds r1, 0xC4
- strb r0, [r1]
- ldrb r0, [r4]
- lsrs r0, 1
- ldr r1, [r3]
- adds r0, r1
- adds r0, 0xC4
- ldrb r0, [r0]
- subs r0, 0x1
- cmp r0, 0x5
- bls _0806401A
- b _08064324
-_0806401A:
- lsls r0, 2
- ldr r1, =_08064030
- adds r0, r1
- ldr r0, [r0]
- mov pc, r0
- .pool
- .align 2, 0
-_08064030:
- .4byte _08064048
- .4byte _08064074
- .4byte _080640BC
- .4byte _08064214
- .4byte _080642F4
- .4byte _0806437C
-_08064048:
- ldr r2, =gBattleMons
- ldr r0, =gActiveBank
- ldrb r1, [r0]
- movs r0, 0x58
- muls r0, r1
- adds r0, r2
- ldrh r1, [r0, 0x2C]
- ldrh r0, [r0, 0x28]
- lsrs r1, 2
- cmp r0, r1
- bcc _08064060
- b _08064324
-_08064060:
- cmp r0, 0
- bne _08064066
- b _08064324
-_08064066:
- movs r7, 0x1
- b _08064328
- .pool
-_08064074:
- mov r0, r9
- movs r1, 0x4
- movs r2, 0x4
- bl GetItemEffectParamOffset
- lsls r0, 24
- lsrs r4, r0, 24
- cmp r4, 0
- bne _08064088
- b _08064324
-_08064088:
- ldr r2, =gBattleMons
- ldr r0, =gActiveBank
- ldrb r1, [r0]
- movs r0, 0x58
- muls r0, r1
- adds r1, r0, r2
- ldrh r2, [r1, 0x28]
- cmp r2, 0
- bne _0806409C
- b _08064324
-_0806409C:
- ldrh r3, [r1, 0x2C]
- lsrs r0, r3, 2
- cmp r2, r0
- bcc _08064066
- adds r0, r2, 0
- subs r0, r3, r0
- adds r1, r5, r4
- ldrb r1, [r1]
- cmp r0, r1
- bgt _080640B2
- b _08064324
-_080640B2:
- b _08064066
- .pool
-_080640BC:
- ldr r3, =gActiveBank
- ldrb r0, [r3]
- lsrs r0, 1
- ldr r2, =gBattleStruct
- ldr r1, [r2]
- adds r0, r1
- adds r0, 0xC6
- movs r1, 0
- strb r1, [r0]
- ldrb r1, [r5, 0x3]
- movs r6, 0x20
- movs r0, 0x20
- ands r0, r1
- cmp r0, 0
- beq _08064100
- ldr r1, =gBattleMons
- ldrb r4, [r3]
- movs r0, 0x58
- muls r0, r4
- adds r1, 0x4C
- adds r0, r1
- ldr r0, [r0]
- movs r1, 0x7
- ands r0, r1
- cmp r0, 0
- beq _08064100
- lsrs r1, r4, 1
- ldr r0, [r2]
- adds r1, r0
- adds r1, 0xC6
- ldrb r0, [r1]
- orrs r0, r6
- strb r0, [r1]
- movs r7, 0x1
-_08064100:
- ldrb r1, [r5, 0x3]
- movs r6, 0x10
- movs r0, 0x10
- ands r0, r1
- cmp r0, 0
- beq _0806413A
- ldr r1, =gBattleMons
- ldrb r4, [r3]
- movs r0, 0x58
- muls r0, r4
- adds r1, 0x4C
- adds r0, r1
- ldr r1, [r0]
- movs r0, 0x8
- ands r0, r1
- cmp r0, 0
- bne _0806412A
- movs r0, 0x80
- ands r1, r0
- cmp r1, 0
- beq _0806413A
-_0806412A:
- lsrs r1, r4, 1
- ldr r0, [r2]
- adds r1, r0
- adds r1, 0xC6
- ldrb r0, [r1]
- orrs r0, r6
- strb r0, [r1]
- movs r7, 0x1
-_0806413A:
- ldrb r1, [r5, 0x3]
- movs r6, 0x8
- movs r0, 0x8
- ands r0, r1
- cmp r0, 0
- beq _0806416C
- ldr r1, =gBattleMons
- ldrb r4, [r3]
- movs r0, 0x58
- muls r0, r4
- adds r1, 0x4C
- adds r0, r1
- ldr r0, [r0]
- movs r1, 0x10
- ands r0, r1
- cmp r0, 0
- beq _0806416C
- lsrs r1, r4, 1
- ldr r0, [r2]
- adds r1, r0
- adds r1, 0xC6
- ldrb r0, [r1]
- orrs r0, r6
- strb r0, [r1]
- movs r7, 0x1
-_0806416C:
- ldrb r1, [r5, 0x3]
- movs r6, 0x4
- movs r0, 0x4
- ands r0, r1
- cmp r0, 0
- beq _0806419E
- ldr r1, =gBattleMons
- ldrb r4, [r3]
- movs r0, 0x58
- muls r0, r4
- adds r1, 0x4C
- adds r0, r1
- ldr r0, [r0]
- movs r1, 0x20
- ands r0, r1
- cmp r0, 0
- beq _0806419E
- lsrs r1, r4, 1
- ldr r0, [r2]
- adds r1, r0
- adds r1, 0xC6
- ldrb r0, [r1]
- orrs r0, r6
- strb r0, [r1]
- movs r7, 0x1
-_0806419E:
- ldrb r1, [r5, 0x3]
- movs r6, 0x2
- movs r0, 0x2
- ands r0, r1
- cmp r0, 0
- beq _080641D0
- ldr r1, =gBattleMons
- ldrb r4, [r3]
- movs r0, 0x58
- muls r0, r4
- adds r1, 0x4C
- adds r0, r1
- ldr r0, [r0]
- movs r1, 0x40
- ands r0, r1
- cmp r0, 0
- beq _080641D0
- lsrs r1, r4, 1
- ldr r0, [r2]
- adds r1, r0
- adds r1, 0xC6
- ldrb r0, [r1]
- orrs r0, r6
- strb r0, [r1]
- movs r7, 0x1
-_080641D0:
- ldrb r1, [r5, 0x3]
- movs r4, 0x1
- movs r0, 0x1
- ands r0, r1
- cmp r0, 0
- bne _080641DE
- b _08064324
-_080641DE:
- ldr r1, =gBattleMons
- ldrb r3, [r3]
- movs r0, 0x58
- muls r0, r3
- adds r1, 0x50
- adds r0, r1
- ldr r0, [r0]
- movs r1, 0x7
- ands r0, r1
- cmp r0, 0
- bne _080641F6
- b _08064324
-_080641F6:
- lsrs r1, r3, 1
- ldr r0, [r2]
- adds r1, r0
- adds r1, 0xC6
- ldrb r0, [r1]
- orrs r0, r4
- strb r0, [r1]
- b _08064066
- .pool
-_08064214:
- ldr r4, =gActiveBank
- ldrb r0, [r4]
- lsrs r0, 1
- ldr r3, =gBattleStruct
- ldr r1, [r3]
- adds r0, r1
- adds r0, 0xC6
- movs r1, 0
- strb r1, [r0]
- ldr r1, =gDisableStructs
- ldrb r2, [r4]
- lsls r0, r2, 3
- subs r0, r2
- lsls r0, 2
- adds r0, r1
- ldrb r0, [r0, 0x16]
- cmp r0, 0
- beq _08064324
- ldrb r1, [r5]
- movs r6, 0xF
- adds r0, r6, 0
- ands r0, r1
- cmp r0, 0
- beq _08064254
- lsrs r2, 1
- ldr r0, [r3]
- adds r2, r0
- adds r2, 0xC6
- ldrb r0, [r2]
- movs r1, 0x1
- orrs r0, r1
- strb r0, [r2]
-_08064254:
- ldrb r1, [r5, 0x1]
- movs r7, 0xF0
- adds r0, r7, 0
- ands r0, r1
- cmp r0, 0
- beq _08064272
- ldrb r0, [r4]
- lsrs r0, 1
- ldr r1, [r3]
- adds r0, r1
- adds r0, 0xC6
- ldrb r1, [r0]
- movs r2, 0x2
- orrs r1, r2
- strb r1, [r0]
-_08064272:
- ldrb r1, [r5, 0x1]
- adds r0, r6, 0
- ands r0, r1
- cmp r0, 0
- beq _0806428E
- ldrb r0, [r4]
- lsrs r0, 1
- ldr r1, [r3]
- adds r0, r1
- adds r0, 0xC6
- ldrb r1, [r0]
- movs r2, 0x4
- orrs r1, r2
- strb r1, [r0]
-_0806428E:
- ldrb r1, [r5, 0x2]
- adds r0, r6, 0
- ands r0, r1
- cmp r0, 0
- beq _080642AA
- ldrb r0, [r4]
- lsrs r0, 1
- ldr r1, [r3]
- adds r0, r1
- adds r0, 0xC6
- ldrb r1, [r0]
- movs r2, 0x8
- orrs r1, r2
- strb r1, [r0]
-_080642AA:
- ldrb r1, [r5, 0x2]
- adds r0, r7, 0
- ands r0, r1
- cmp r0, 0
- beq _080642C6
- ldrb r0, [r4]
- lsrs r0, 1
- ldr r1, [r3]
- adds r0, r1
- adds r0, 0xC6
- ldrb r1, [r0]
- movs r2, 0x20
- orrs r1, r2
- strb r1, [r0]
-_080642C6:
- ldrb r1, [r5]
- movs r0, 0x30
- ands r0, r1
- cmp r0, 0
- bne _080642D2
- b _08064066
-_080642D2:
- ldrb r0, [r4]
- lsrs r0, 1
- ldr r1, [r3]
- adds r0, r1
- adds r0, 0xC6
- ldrb r1, [r0]
- movs r2, 0x80
- orrs r1, r2
- strb r1, [r0]
- b _08064066
- .pool
-_080642F4:
- ldr r4, =gActiveBank
- ldrb r0, [r4]
- bl GetBankSide
- lsls r0, 24
- lsrs r3, r0, 24
- ldr r2, =gDisableStructs
- ldrb r1, [r4]
- lsls r0, r1, 3
- subs r0, r1
- lsls r0, 2
- adds r0, r2
- ldrb r0, [r0, 0x16]
- cmp r0, 0
- beq _08064324
- ldr r0, =gSideTimers
- lsls r1, r3, 1
- adds r1, r3
- lsls r1, 2
- adds r1, r0
- ldrb r0, [r1, 0x4]
- cmp r0, 0
- bne _08064324
- b _08064066
-_08064324:
- cmp r7, 0
- beq _08064370
-_08064328:
- movs r0, 0x1
- movs r1, 0x1
- movs r2, 0
- bl EmitCmd_x21
- ldr r0, =gActiveBank
- ldrb r0, [r0]
- lsrs r0, 1
- ldr r1, =gBattleStruct
- ldr r1, [r1]
- lsls r0, 1
- adds r0, r1
- adds r0, 0xC0
- mov r1, r9
- strb r1, [r0]
- ldr r0, =gBattleResources
- ldr r0, [r0]
- ldr r0, [r0, 0x18]
- adds r0, 0x48
- ldr r2, [sp]
- adds r0, r2
- movs r1, 0
- strh r1, [r0]
- adds r0, r7, 0
- b _0806437E
- .pool
-_08064370:
- movs r0, 0x1
- add r8, r0
- mov r1, r8
- cmp r1, 0x3
- bgt _0806437C
- b _08063F72
-_0806437C:
- movs r0, 0
-_0806437E:
- add sp, 0x4
- pop {r3-r5}
- mov r8, r3
- mov r9, r4
- mov r10, r5
- pop {r4-r7}
- pop {r1}
- bx r1
- thumb_func_end ShouldUseItem
-
- .align 2, 0 @ Don't pad with nop.
diff --git a/include/battle.h b/include/battle.h
index 0aa778fe2..a60f450ce 100644
--- a/include/battle.h
+++ b/include/battle.h
@@ -477,7 +477,7 @@ struct BattleHistory
struct UsedMoves usedMoves[BATTLE_BANKS_COUNT];
u8 abilities[BATTLE_BANKS_COUNT];
u8 itemEffects[BATTLE_BANKS_COUNT];
- u16 TrainerItems[BATTLE_BANKS_COUNT];
+ u16 trainerItems[BATTLE_BANKS_COUNT];
u8 itemsNo;
};
@@ -633,8 +633,8 @@ struct BattleStruct
void (*savedCallback)(void);
u16 usedHeldItems[BATTLE_BANKS_COUNT];
u8 field_C0[4];
- u8 field_C4[2];
- u8 field_C6[2];
+ u8 AI_itemType[2];
+ u8 AI_itemFlags[2];
u16 choicedMove[BATTLE_BANKS_COUNT];
u16 changedItems[BATTLE_BANKS_COUNT];
u8 intimidateBank;
diff --git a/include/battle_ai_switch_items.h b/include/battle_ai_switch_items.h
index 5c78a5386..0a230e7f6 100644
--- a/include/battle_ai_switch_items.h
+++ b/include/battle_ai_switch_items.h
@@ -1,6 +1,16 @@
#ifndef GUARD_BATTLE_AI_SWITCH_ITEMS_H
#define GUARD_BATTLE_AI_SWITCH_ITEMS_H
+enum
+{
+ AI_ITEM_FULL_RESTORE = 1,
+ AI_ITEM_HEAL_HP,
+ AI_ITEM_CURE_CONDITION,
+ AI_ITEM_X_STAT,
+ AI_ITEM_GUARD_SPECS,
+ AI_ITEM_NOT_RECOGNIZABLE
+};
+
void AI_TrySwitchOrUseItem(void);
u8 GetMostSuitableMonToSwitchInto(void);
diff --git a/include/pokemon.h b/include/pokemon.h
index 263a37426..c26c28afa 100644
--- a/include/pokemon.h
+++ b/include/pokemon.h
@@ -642,6 +642,7 @@ void UpdatePartyPokerusTime(u16 days);
void PartySpreadPokerus(struct Pokemon *party);
s8 GetMonFlavourRelation(struct Pokemon *mon, u8 a2);
s8 GetFlavourRelationByPersonality(u32 personality, u8 a2);
+u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit);
#include "sprite.h"
diff --git a/include/pokemon_item_effects.h b/include/pokemon_item_effects.h
index 88f341317..505cc0f25 100644
--- a/include/pokemon_item_effects.h
+++ b/include/pokemon_item_effects.h
@@ -3,6 +3,60 @@
#include "pokemon.h"
+// TODO once pokemon item effects is decompiled
+/*
+struct PokemonItemEffect
+{
+ //field 0
+ u8 xAtk : 4; // x1, x2, x4, x8 = xF
+ u8 field_0_x10 : 1; // x10
+ u8 critRatioUp : 1; // x20
+ u8 field_0_x40 : 1; // x40
+ u8 cureInfatuation : 1; // x80
+
+ /*field 1
+ u8 xSpeed : 4; // x1, x2, x4, x8 = xF
+ u8 xDefense : 4; // x10, x20, x40, xF0
+
+ /*field 2
+ u8 xSpAtk : 4; // x1, x2, x4, x8 = xF
+ u8 xAccuracy : 4; // x10, x20, x40, xF0
+
+ /*field 3
+ u8 cureConfusion : 1; // x1
+ u8 cureParalysis : 1; // x2
+ u8 cureFreeze : 1; // x4
+ u8 cureBurn : 1; // x8
+ u8 curePoison : 1; // x10
+ u8 cureSleep : 1; // x20
+ u8 field_3_x40 : 1; // x40
+ u8 cantLowerStats : 1; // x80
+
+ /*field 4
+ u8 hpEv : 1; // x1
+ u8 attackEv : 1; // x2
+ u8 healHp : 1; // x4
+ u8 field_4_x8 : 1; // x8
+ u8 field_4_x10 : 1; // x10
+ u8 ppUp : 1; // x20
+ u8 levelUp : 1; // x40
+ u8 evolutionStone : 1; // x80
+
+ /*field 5
+ u8 defEv: 1; // x1
+ u8 speedEv : 1; // x2
+ u8 spDefEv : 1; // x4
+ u8 spAtkEv : 1; // x8
+ u8 ppMax : 1; // x10
+ u8 field_5_x20 : 1; // x20
+ u8 field_5_x40 : 1; // x40
+ u8 field_5_x80 : 1; // x80
+
+ /*field 6
+ u8 value;
+};
+*/
+
bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 itemId, u8 partyId, u8 monMoveIndex, u8 a5);
#endif // GUARD_POKEMON_ITEM_EFFECTS
diff --git a/ld_script.txt b/ld_script.txt
index 1da43ff9d..887f24811 100644
--- a/ld_script.txt
+++ b/ld_script.txt
@@ -64,8 +64,7 @@ SECTIONS {
asm/battle_controller_player.o(.text);
asm/battle_7.o(.text);
asm/battle_controller_opponent.o(.text);
- src/battle_9.o(.text);
- asm/battle_9.o(.text);
+ src/battle_ai_switch_items.o(.text);
asm/battle_controller_linkopponent.o(.text);
src/pokemon_1.o(.text);
asm/pokemon_1.o(.text);
diff --git a/src/battle_2.c b/src/battle_2.c
index 92c48c427..c4da02e36 100644
--- a/src/battle_2.c
+++ b/src/battle_2.c
@@ -5324,30 +5324,30 @@ static void HandleAction_UseItem(void)
{
gBattleScripting.bank = gBankAttacker;
- switch (*(gBattleStruct->field_C4 + (gBankAttacker >> 1)))
+ switch (*(gBattleStruct->AI_itemType + (gBankAttacker >> 1)))
{
- case 1:
- case 2:
+ case AI_ITEM_FULL_RESTORE:
+ case AI_ITEM_HEAL_HP:
break;
- case 3:
+ case AI_ITEM_CURE_CONDITION:
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- if (*(gBattleStruct->field_C6 + gBankAttacker / 2) & 1)
+ if (*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) & 1)
{
- if (*(gBattleStruct->field_C6 + gBankAttacker / 2) & 0x3E)
+ if (*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) & 0x3E)
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
}
else
{
- while (!(*(gBattleStruct->field_C6 + gBankAttacker / 2) & 1))
+ while (!(*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) & 1))
{
- *(gBattleStruct->field_C6 + gBankAttacker / 2) >>= 1;
+ *(gBattleStruct->AI_itemFlags + gBankAttacker / 2) >>= 1;
gBattleCommunication[MULTISTRING_CHOOSER]++;
}
}
break;
- case 4:
+ case AI_ITEM_X_STAT:
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
- if (*(gBattleStruct->field_C6 + (gBankAttacker >> 1)) & 0x80)
+ if (*(gBattleStruct->AI_itemFlags + (gBankAttacker >> 1)) & 0x80)
{
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
}
@@ -5356,9 +5356,9 @@ static void HandleAction_UseItem(void)
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK)
PREPARE_STRING_BUFFER(gBattleTextBuff2, 0xD2)
- while (!((*(gBattleStruct->field_C6 + (gBankAttacker >> 1))) & 1))
+ while (!((*(gBattleStruct->AI_itemFlags + (gBankAttacker >> 1))) & 1))
{
- *(gBattleStruct->field_C6 + gBankAttacker / 2) >>= 1;
+ *(gBattleStruct->AI_itemFlags + gBankAttacker / 2) >>= 1;
gBattleTextBuff1[2]++;
}
@@ -5366,7 +5366,7 @@ static void HandleAction_UseItem(void)
gBattleScripting.animArg2 = 0;
}
break;
- case 5:
+ case AI_ITEM_GUARD_SPECS:
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else
@@ -5374,7 +5374,7 @@ static void HandleAction_UseItem(void)
break;
}
- gBattlescriptCurrInstr = gUnknown_082DBD3C[*(gBattleStruct->field_C4 + gBankAttacker / 2)];
+ gBattlescriptCurrInstr = gUnknown_082DBD3C[*(gBattleStruct->AI_itemType + gBankAttacker / 2)];
}
gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT;
}
diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c
index bba66983b..24377eacc 100644
--- a/src/battle_ai_script_commands.c
+++ b/src/battle_ai_script_commands.c
@@ -331,7 +331,7 @@ void BattleAI_HandleItemUseBeforeAISetup(u8 defaultScoreMoves)
{
if (gTrainers[gTrainerBattleOpponent_A].items[i] != 0)
{
- gBattleResources->battleHistory->TrainerItems[gBattleResources->battleHistory->itemsNo] = gTrainers[gTrainerBattleOpponent_A].items[i];
+ gBattleResources->battleHistory->trainerItems[gBattleResources->battleHistory->itemsNo] = gTrainers[gTrainerBattleOpponent_A].items[i];
gBattleResources->battleHistory->itemsNo++;
}
}
diff --git a/src/battle_9.c b/src/battle_ai_switch_items.c
index 291bfc9e3..661759a98 100644
--- a/src/battle_9.c
+++ b/src/battle_ai_switch_items.c
@@ -7,6 +7,8 @@
#include "species.h"
#include "rng.h"
#include "util.h"
+#include "items.h"
+#include "pokemon_item_effects.h"
extern u8 gActiveBank;
extern u8 gAbsentBankFlags;
@@ -24,13 +26,14 @@ extern s32 gBattleMoveDamage;
extern const struct BattleMove gBattleMoves[];
extern const struct BaseStats gBaseStats[];
extern const u8 gTypeEffectiveness[];
+extern const u8 * const gItemEffectTable[]; // todo: fix once struct is declared
// this file's functions
-bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
-bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent);
-bool8 ShouldUseItem(void);
+static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
+static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent);
+static bool8 ShouldUseItem(void);
-bool8 ShouldSwitchIfPerishSong(void)
+static bool8 ShouldSwitchIfPerishSong(void)
{
if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG
&& gDisableStructs[gActiveBank].perishSong1 == 0)
@@ -43,7 +46,7 @@ bool8 ShouldSwitchIfPerishSong(void)
return FALSE;
}
-bool8 ShouldSwitchIfWonderGuard(void)
+static bool8 ShouldSwitchIfWonderGuard(void)
{
u8 opposingIdentity;
u8 opposingBank;
@@ -127,7 +130,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 FindMonThatAbsorbsOpponentsMove(void)
+static bool8 FindMonThatAbsorbsOpponentsMove(void)
{
u8 bankIn1, bankIn2;
u8 absorbingTypeAbility;
@@ -226,7 +229,7 @@ bool8 FindMonThatAbsorbsOpponentsMove(void)
return FALSE;
}
-bool8 ShouldSwitchIfNaturalCure(void)
+static bool8 ShouldSwitchIfNaturalCure(void)
{
if (!(gBattleMons[gActiveBank].status1 & STATUS_SLEEP))
return FALSE;
@@ -262,7 +265,7 @@ bool8 ShouldSwitchIfNaturalCure(void)
return FALSE;
}
-bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng)
+static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng)
{
u8 opposingIdentity;
u8 opposingBank;
@@ -318,7 +321,7 @@ bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng)
return FALSE;
}
-bool8 AreStatsRaised(void)
+static bool8 AreStatsRaised(void)
{
u8 buffedStatsValue = 0;
s32 i;
@@ -332,7 +335,7 @@ bool8 AreStatsRaised(void)
return (buffedStatsValue > 3);
}
-bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
+static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
{
u8 bankIn1, bankIn2;
s32 firstId;
@@ -433,7 +436,7 @@ bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
return FALSE;
}
-bool8 ShouldSwitch(void)
+static bool8 ShouldSwitch(void)
{
u8 bankIn1, bankIn2;
u8 *activeBankPtr; // needed to match
@@ -792,3 +795,157 @@ u8 GetMostSuitableMonToSwitchInto(void)
return bestMonId;
}
+
+// TODO: use PokemonItemEffect struct instead of u8 once it's documented
+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;
+ if (itemEffect[4] & 4)
+ return AI_ITEM_HEAL_HP;
+ if (itemEffect[3] & 0x3F)
+ return AI_ITEM_CURE_CONDITION;
+ if (itemEffect[0] & 0x3F || itemEffect[1] != 0 || itemEffect[2] != 0)
+ return AI_ITEM_X_STAT;
+ if (itemEffect[3] & 0x80)
+ return AI_ITEM_GUARD_SPECS;
+
+ return AI_ITEM_NOT_RECOGNIZABLE;
+}
+
+static bool8 ShouldUseItem(void)
+{
+ struct Pokemon *party;
+ s32 i;
+ u8 validMons = 0;
+ bool8 shouldUse = FALSE;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBankIdentity(gActiveBank) == IDENTITY_PLAYER_MON2)
+ return FALSE;
+
+ if (GetBankSide(gActiveBank) == SIDE_PLAYER)
+ party = gPlayerParty;
+ else
+ party = gEnemyParty;
+
+ for (i = 0; i < 6; i++)
+ {
+ if (GetMonData(&party[i], MON_DATA_HP) != 0
+ && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE
+ && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG)
+ {
+ validMons++;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ u16 item;
+ const u8 *itemEffects;
+ u8 paramOffset;
+ u8 bankSide;
+
+ if (i != 0 && validMons > (gBattleResources->battleHistory->itemsNo - i) + 1)
+ continue;
+ item = gBattleResources->battleHistory->trainerItems[i];
+ if (item == ITEM_NONE)
+ continue;
+ if (gItemEffectTable[item - 13] == NULL)
+ continue;
+
+ if (item == ITEM_ENIGMA_BERRY)
+ itemEffects = gSaveBlock1Ptr->enigmaBerry.itemEffect;
+ else
+ itemEffects = gItemEffectTable[item - 13];
+
+ *(gBattleStruct->AI_itemType + gActiveBank / 2) = GetAI_ItemType(item, itemEffects);
+
+ switch (*(gBattleStruct->AI_itemType + gActiveBank / 2))
+ {
+ case AI_ITEM_FULL_RESTORE:
+ if (gBattleMons[gActiveBank].hp >= gBattleMons[gActiveBank].maxHP / 4)
+ break;
+ if (gBattleMons[gActiveBank].hp == 0)
+ break;
+ shouldUse = TRUE;
+ break;
+ case AI_ITEM_HEAL_HP:
+ paramOffset = GetItemEffectParamOffset(item, 4, 4);
+ if (paramOffset == 0)
+ break;
+ if (gBattleMons[gActiveBank].hp == 0)
+ break;
+ if (gBattleMons[gActiveBank].hp < gBattleMons[gActiveBank].maxHP / 4 || gBattleMons[gActiveBank].maxHP - gBattleMons[gActiveBank].hp > itemEffects[paramOffset])
+ shouldUse = TRUE;
+ break;
+ case AI_ITEM_CURE_CONDITION:
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) = 0;
+ if (itemEffects[3] & 0x20 && gBattleMons[gActiveBank].status1 & STATUS_SLEEP)
+ {
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x20;
+ shouldUse = TRUE;
+ }
+ if (itemEffects[3] & 0x10 && (gBattleMons[gActiveBank].status1 & STATUS_POISON || gBattleMons[gActiveBank].status1 & STATUS_TOXIC_POISON))
+ {
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x10;
+ shouldUse = TRUE;
+ }
+ if (itemEffects[3] & 0x8 && gBattleMons[gActiveBank].status1 & STATUS_BURN)
+ {
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x8;
+ shouldUse = TRUE;
+ }
+ if (itemEffects[3] & 0x4 && gBattleMons[gActiveBank].status1 & STATUS_FREEZE)
+ {
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x4;
+ shouldUse = TRUE;
+ }
+ if (itemEffects[3] & 0x2 && gBattleMons[gActiveBank].status1 & STATUS_PARALYSIS)
+ {
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x2;
+ shouldUse = TRUE;
+ }
+ if (itemEffects[3] & 0x1 && gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION)
+ {
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x1;
+ shouldUse = TRUE;
+ }
+ break;
+ case AI_ITEM_X_STAT:
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) = 0;
+ if (gDisableStructs[gActiveBank].isFirstTurn == 0)
+ break;
+ if (itemEffects[0] & 0xF)
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x1;
+ if (itemEffects[1] & 0xF0)
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x2;
+ if (itemEffects[1] & 0xF)
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x4;
+ if (itemEffects[2] & 0xF)
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x8;
+ if (itemEffects[2] & 0xF0)
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x20;
+ if (itemEffects[0] & 0x30)
+ *(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x80;
+ shouldUse = TRUE;
+ break;
+ case AI_ITEM_GUARD_SPECS:
+ bankSide = GetBankSide(gActiveBank);
+ if (gDisableStructs[gActiveBank].isFirstTurn != 0 && gSideTimers[bankSide].mistTimer == 0)
+ shouldUse = TRUE;
+ break;
+ case AI_ITEM_NOT_RECOGNIZABLE:
+ return FALSE;
+ }
+
+ if (shouldUse)
+ {
+ EmitCmd_x21(1, 1, 0);
+ *(gBattleStruct->field_C0 + (gActiveBank / 2) * 2) = item;
+ gBattleResources->battleHistory->trainerItems[i] = 0;
+ return shouldUse;
+ }
+ }
+
+ return FALSE;
+}