battle 9 is decompiled

This commit is contained in:
DizzyEggg 2017-10-11 12:49:42 +02:00
parent 6dfe8ced2c
commit a3b62f43ee
9 changed files with 252 additions and 677 deletions

View File

@ -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.

View File

@ -477,7 +477,7 @@ struct BattleHistory
struct UsedMoves usedMoves[BATTLE_BANKS_COUNT]; struct UsedMoves usedMoves[BATTLE_BANKS_COUNT];
u8 abilities[BATTLE_BANKS_COUNT]; u8 abilities[BATTLE_BANKS_COUNT];
u8 itemEffects[BATTLE_BANKS_COUNT]; u8 itemEffects[BATTLE_BANKS_COUNT];
u16 TrainerItems[BATTLE_BANKS_COUNT]; u16 trainerItems[BATTLE_BANKS_COUNT];
u8 itemsNo; u8 itemsNo;
}; };
@ -633,8 +633,8 @@ struct BattleStruct
void (*savedCallback)(void); void (*savedCallback)(void);
u16 usedHeldItems[BATTLE_BANKS_COUNT]; u16 usedHeldItems[BATTLE_BANKS_COUNT];
u8 field_C0[4]; u8 field_C0[4];
u8 field_C4[2]; u8 AI_itemType[2];
u8 field_C6[2]; u8 AI_itemFlags[2];
u16 choicedMove[BATTLE_BANKS_COUNT]; u16 choicedMove[BATTLE_BANKS_COUNT];
u16 changedItems[BATTLE_BANKS_COUNT]; u16 changedItems[BATTLE_BANKS_COUNT];
u8 intimidateBank; u8 intimidateBank;

View File

@ -1,6 +1,16 @@
#ifndef GUARD_BATTLE_AI_SWITCH_ITEMS_H #ifndef GUARD_BATTLE_AI_SWITCH_ITEMS_H
#define 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); void AI_TrySwitchOrUseItem(void);
u8 GetMostSuitableMonToSwitchInto(void); u8 GetMostSuitableMonToSwitchInto(void);

View File

@ -642,6 +642,7 @@ void UpdatePartyPokerusTime(u16 days);
void PartySpreadPokerus(struct Pokemon *party); void PartySpreadPokerus(struct Pokemon *party);
s8 GetMonFlavourRelation(struct Pokemon *mon, u8 a2); s8 GetMonFlavourRelation(struct Pokemon *mon, u8 a2);
s8 GetFlavourRelationByPersonality(u32 personality, u8 a2); s8 GetFlavourRelationByPersonality(u32 personality, u8 a2);
u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit);
#include "sprite.h" #include "sprite.h"

View File

@ -3,6 +3,60 @@
#include "pokemon.h" #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); bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 itemId, u8 partyId, u8 monMoveIndex, u8 a5);
#endif // GUARD_POKEMON_ITEM_EFFECTS #endif // GUARD_POKEMON_ITEM_EFFECTS

View File

@ -64,8 +64,7 @@ SECTIONS {
asm/battle_controller_player.o(.text); asm/battle_controller_player.o(.text);
asm/battle_7.o(.text); asm/battle_7.o(.text);
asm/battle_controller_opponent.o(.text); asm/battle_controller_opponent.o(.text);
src/battle_9.o(.text); src/battle_ai_switch_items.o(.text);
asm/battle_9.o(.text);
asm/battle_controller_linkopponent.o(.text); asm/battle_controller_linkopponent.o(.text);
src/pokemon_1.o(.text); src/pokemon_1.o(.text);
asm/pokemon_1.o(.text); asm/pokemon_1.o(.text);

View File

@ -5324,30 +5324,30 @@ static void HandleAction_UseItem(void)
{ {
gBattleScripting.bank = gBankAttacker; gBattleScripting.bank = gBankAttacker;
switch (*(gBattleStruct->field_C4 + (gBankAttacker >> 1))) switch (*(gBattleStruct->AI_itemType + (gBankAttacker >> 1)))
{ {
case 1: case AI_ITEM_FULL_RESTORE:
case 2: case AI_ITEM_HEAL_HP:
break; break;
case 3: case AI_ITEM_CURE_CONDITION:
gBattleCommunication[MULTISTRING_CHOOSER] = 0; 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; gBattleCommunication[MULTISTRING_CHOOSER] = 5;
} }
else 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]++; gBattleCommunication[MULTISTRING_CHOOSER]++;
} }
} }
break; break;
case 4: case AI_ITEM_X_STAT:
gBattleCommunication[MULTISTRING_CHOOSER] = 4; gBattleCommunication[MULTISTRING_CHOOSER] = 4;
if (*(gBattleStruct->field_C6 + (gBankAttacker >> 1)) & 0x80) if (*(gBattleStruct->AI_itemFlags + (gBankAttacker >> 1)) & 0x80)
{ {
gBattleCommunication[MULTISTRING_CHOOSER] = 5; gBattleCommunication[MULTISTRING_CHOOSER] = 5;
} }
@ -5356,9 +5356,9 @@ static void HandleAction_UseItem(void)
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK) PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK)
PREPARE_STRING_BUFFER(gBattleTextBuff2, 0xD2) 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]++; gBattleTextBuff1[2]++;
} }
@ -5366,7 +5366,7 @@ static void HandleAction_UseItem(void)
gBattleScripting.animArg2 = 0; gBattleScripting.animArg2 = 0;
} }
break; break;
case 5: case AI_ITEM_GUARD_SPECS:
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
gBattleCommunication[MULTISTRING_CHOOSER] = 2; gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else else
@ -5374,7 +5374,7 @@ static void HandleAction_UseItem(void)
break; break;
} }
gBattlescriptCurrInstr = gUnknown_082DBD3C[*(gBattleStruct->field_C4 + gBankAttacker / 2)]; gBattlescriptCurrInstr = gUnknown_082DBD3C[*(gBattleStruct->AI_itemType + gBankAttacker / 2)];
} }
gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT;
} }

View File

@ -331,7 +331,7 @@ void BattleAI_HandleItemUseBeforeAISetup(u8 defaultScoreMoves)
{ {
if (gTrainers[gTrainerBattleOpponent_A].items[i] != 0) 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++; gBattleResources->battleHistory->itemsNo++;
} }
} }

View File

@ -7,6 +7,8 @@
#include "species.h" #include "species.h"
#include "rng.h" #include "rng.h"
#include "util.h" #include "util.h"
#include "items.h"
#include "pokemon_item_effects.h"
extern u8 gActiveBank; extern u8 gActiveBank;
extern u8 gAbsentBankFlags; extern u8 gAbsentBankFlags;
@ -24,13 +26,14 @@ extern s32 gBattleMoveDamage;
extern const struct BattleMove gBattleMoves[]; extern const struct BattleMove gBattleMoves[];
extern const struct BaseStats gBaseStats[]; extern const struct BaseStats gBaseStats[];
extern const u8 gTypeEffectiveness[]; extern const u8 gTypeEffectiveness[];
extern const u8 * const gItemEffectTable[]; // todo: fix once struct is declared
// this file's functions // this file's functions
bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng); static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent); static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent);
bool8 ShouldUseItem(void); static bool8 ShouldUseItem(void);
bool8 ShouldSwitchIfPerishSong(void) static bool8 ShouldSwitchIfPerishSong(void)
{ {
if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG
&& gDisableStructs[gActiveBank].perishSong1 == 0) && gDisableStructs[gActiveBank].perishSong1 == 0)
@ -43,7 +46,7 @@ bool8 ShouldSwitchIfPerishSong(void)
return FALSE; return FALSE;
} }
bool8 ShouldSwitchIfWonderGuard(void) static bool8 ShouldSwitchIfWonderGuard(void)
{ {
u8 opposingIdentity; u8 opposingIdentity;
u8 opposingBank; 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 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 bankIn1, bankIn2;
u8 absorbingTypeAbility; u8 absorbingTypeAbility;
@ -226,7 +229,7 @@ bool8 FindMonThatAbsorbsOpponentsMove(void)
return FALSE; return FALSE;
} }
bool8 ShouldSwitchIfNaturalCure(void) static bool8 ShouldSwitchIfNaturalCure(void)
{ {
if (!(gBattleMons[gActiveBank].status1 & STATUS_SLEEP)) if (!(gBattleMons[gActiveBank].status1 & STATUS_SLEEP))
return FALSE; return FALSE;
@ -262,7 +265,7 @@ bool8 ShouldSwitchIfNaturalCure(void)
return FALSE; return FALSE;
} }
bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng) static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng)
{ {
u8 opposingIdentity; u8 opposingIdentity;
u8 opposingBank; u8 opposingBank;
@ -318,7 +321,7 @@ bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng)
return FALSE; return FALSE;
} }
bool8 AreStatsRaised(void) static bool8 AreStatsRaised(void)
{ {
u8 buffedStatsValue = 0; u8 buffedStatsValue = 0;
s32 i; s32 i;
@ -332,7 +335,7 @@ bool8 AreStatsRaised(void)
return (buffedStatsValue > 3); return (buffedStatsValue > 3);
} }
bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent) static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
{ {
u8 bankIn1, bankIn2; u8 bankIn1, bankIn2;
s32 firstId; s32 firstId;
@ -433,7 +436,7 @@ bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
return FALSE; return FALSE;
} }
bool8 ShouldSwitch(void) static bool8 ShouldSwitch(void)
{ {
u8 bankIn1, bankIn2; u8 bankIn1, bankIn2;
u8 *activeBankPtr; // needed to match u8 *activeBankPtr; // needed to match
@ -792,3 +795,157 @@ u8 GetMostSuitableMonToSwitchInto(void)
return bestMonId; 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;
}