summaryrefslogtreecommitdiff
path: root/include/battle.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/battle.h')
-rw-r--r--include/battle.h695
1 files changed, 503 insertions, 192 deletions
diff --git a/include/battle.h b/include/battle.h
index 4093f55d1..3328c691f 100644
--- a/include/battle.h
+++ b/include/battle.h
@@ -1,8 +1,36 @@
#ifndef GUARD_BATTLE_H
#define GUARD_BATTLE_H
+// should they be included here or included individually by every file?
+#include "battle_util.h"
+#include "battle_script_commands.h"
+#include "battle_2.h"
+#include "battle_ai_switch_items.h"
+
+/*
+ Banks are a name given to what could be called a 'battlerId' or 'monControllerId'.
+ Each bank has a value consisting of two bits.
+ 0x1 bit is responsible for the side, 0 = player's side, 1 = opponent's side.
+ 0x2 bit is responsible for the id of sent out pokemon. 0 means it's the first sent out pokemon, 1 it's the second one. (Triple battle didn't exist at the time yet.)
+*/
+
#define BATTLE_BANKS_COUNT 4
+#define IDENTITY_PLAYER_MON1 0
+#define IDENTITY_OPPONENT_MON1 1
+#define IDENTITY_PLAYER_MON2 2
+#define IDENTITY_OPPONENT_MON2 3
+
+#define SIDE_PLAYER 0x0
+#define SIDE_OPPONENT 0x1
+
+#define BIT_SIDE 0x1
+#define BIT_MON 0x2
+
+#define GET_BANK_IDENTITY(bank)((gBanksByIdentity[bank]))
+#define GET_BANK_SIDE(bank)((GetBankIdentity(bank) & BIT_SIDE))
+#define GET_BANK_SIDE2(bank)((GET_BANK_IDENTITY(bank) & BIT_SIDE))
+
#define BATTLE_TYPE_DOUBLE 0x0001
#define BATTLE_TYPE_LINK 0x0002
#define BATTLE_TYPE_WILD 0x0004
@@ -34,14 +62,16 @@
#define BATTLE_TYPE_GROUDON 0x10000000
#define BATTLE_TYPE_KYORGE 0x20000000
#define BATTLE_TYPE_RAYQUAZA 0x40000000
+#define BATTLE_TYPE_x80000000 0x80000000
+#define TRAINER_OPPONENT_3FE 0x3FE
+#define TRAINER_OPPONENT_C00 0xC00
+#define TRAINER_OPPONENT_800 0x800
#define STEVEN_PARTNER_ID 0xC03
#define SECRET_BASE_OPPONENT 0x400
-#define BATTLE_TYPE_FRONTIER (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_x100000 | BATTLE_TYPE_PYRAMID)
-
-#define SIDE_PLAYER 0x0
-#define SIDE_OPPONENT 0x1
+#define BATTLE_TYPE_FRONTIER (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_x100000 | BATTLE_TYPE_PYRAMID)
+#define BATTLE_TYPE_FRONTIER_NO_PYRAMID (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_x100000)
#define BATTLE_WON 0x1
#define BATTLE_LOST 0x2
@@ -50,8 +80,12 @@
#define BATTLE_PLAYER_TELEPORTED 0x5
#define BATTLE_POKE_FLED 0x6
#define BATTLE_CAUGHT 0x7
+#define BATTLE_SAFARI_OUT_OF_BALLS 0x8
+#define BATTLE_FORFEITED 0x9
#define BATTLE_OPPONENT_TELEPORTED 0xA
+#define BATTLE_OUTCOME_BIT_x80 0x80
+
#define STATUS_SLEEP 0x7
#define STATUS_POISON 0x8
#define STATUS_BURN 0x10
@@ -66,11 +100,12 @@
#define STATUS2_CONFUSION 0x00000007
#define STATUS2_FLINCHED 0x00000008
#define STATUS2_UPROAR 0x00000070
-#define STATUS2_BIDE 0x00000300 //two bits 0x100 0x200
+#define STATUS2_BIDE 0x00000300 // two bits 0x100, 0x200
#define STATUS2_LOCK_CONFUSE 0x00000C00
#define STATUS2_MULTIPLETURNS 0x00001000
#define STATUS2_WRAPPED 0x0000E000
-#define STATUS2_INFATUATION 0x000F0000
+#define STATUS2_INFATUATION 0x000F0000 // 4 bits, one for every bank
+#define STATUS2_INFATUATED_WITH(bank)((gBitTable[bank] << 16))
#define STATUS2_FOCUS_ENERGY 0x00100000
#define STATUS2_TRANSFORMED 0x00200000
#define STATUS2_RECHARGE 0x00400000
@@ -86,15 +121,15 @@
#define STATUS3_LEECHSEED_BANK 0x3
#define STATUS3_LEECHSEED 0x4
-#define STATUS3_ALWAYS_HITS 0x18 //two bits
+#define STATUS3_ALWAYS_HITS 0x18 // two bits
#define STATUS3_PERISH_SONG 0x20
#define STATUS3_ON_AIR 0x40
#define STATUS3_UNDERGROUND 0x80
#define STATUS3_MINIMIZED 0x100
#define STATUS3_ROOTED 0x400
#define STATUS3_CHARGED_UP 0x200
-#define STATUS3_YAWN 0x1800 //two bits
-#define STATUS3_IMPRISIONED 0x2000
+#define STATUS3_YAWN 0x1800 // two bits
+#define STATUS3_IMPRISONED_OTHERS 0x2000
#define STATUS3_GRUDGE 0x4000
#define STATUS3_CANT_SCORE_A_CRIT 0x8000
#define STATUS3_MUDSPORT 0x10000
@@ -105,6 +140,7 @@
#define STATUS3_SEMI_INVULNERABLE ((STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER))
+#define HITMARKER_x10 0x00000010
#define HITMARKER_x20 0x00000020
#define HITMARKER_DESTINYBOND 0x00000040
#define HITMARKER_NO_ANIMATIONS 0x00000080
@@ -115,6 +151,7 @@
#define HITMARKER_PURSUIT_TRAP 0x00001000
#define HITMARKER_IGNORE_SAFEGUARD 0x00002000
#define HITMARKER_SYNCHRONISE_EFFECT 0x00004000
+#define HITMARKER_RUN 0x00008000
#define HITMARKER_IGNORE_ON_AIR 0x00010000
#define HITMARKER_IGNORE_UNDERGROUND 0x00020000
#define HITMARKER_IGNORE_UNDERWATER 0x00040000
@@ -125,6 +162,7 @@
#define HITMARKER_x800000 0x00800000
#define HITMARKER_GRUDGE 0x01000000
#define HITMARKER_OBEYS 0x02000000
+#define HITMARKER_x4000000 0x04000000
#define HITMARKER_x8000000 0x08000000
#define HITMARKER_FAINTED(bank) ((gBitTable[bank] << 0x1C))
#define HITMARKER_UNK(bank) ((0x10000000 << bank))
@@ -138,28 +176,21 @@
#define SIDE_STATUS_MIST (1 << 8)
#define SIDE_STATUS_SPIKES_DAMAGED (1 << 9)
-#define ABILITYEFFECT_ON_SWITCHIN 0x0
-#define ABILITYEFFECT_ENDTURN 0x1
-#define ABILITYEFFECT_MOVES_BLOCK 0x2
-#define ABILITYEFFECT_ABSORBING 0x3
-#define ABILITYEFFECT_CONTACT 0x4
-#define ABILITYEFFECT_IMMUNITY 0x5
-#define ABILITYEFFECT_FORECAST 0x6
-#define ABILITYEFFECT_SYNCHRONIZE 0x7
-#define ABILITYEFFECT_ATK_SYNCHRONIZE 0x8
-#define ABILITYEFFECT_INTIMIDATE1 0x9
-#define ABILITYEFFECT_INTIMIDATE2 0xA
-#define ABILITYEFFECT_TRACE 0xB
-#define ABILITYEFFECT_CHECK_OTHER_SIDE 0xC
-#define ABILITYEFFECT_CHECK_BANK_SIDE 0xD
-#define ABILITYEFFECT_FIELD_SPORT 0xE
-#define ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK 0xF
-#define ABILITYEFFECT_COUNT_OTHER_SIZE 0x10
-#define ABILITYEFFECT_COUNT_BANK_SIDE 0x11
-#define ABILITYEFFECT_COUNT_ON_FIELD 0x12
-#define ABILITYEFFECT_CHECK_ON_FIELD 0x13
-
-#define WEATHER_HAS_EFFECT ((!AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, ABILITY_CLOUD_NINE, 0, 0) && !AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, ABILITY_AIR_LOCK, 0, 0)))
+#define ACTION_USE_MOVE 0
+#define ACTION_USE_ITEM 1
+#define ACTION_SWITCH 2
+#define ACTION_RUN 3
+#define ACTION_WATCHES_CAREFULLY 4
+#define ACTION_SAFARI_ZONE_BALL 5
+#define ACTION_POKEBLOCK_CASE 6
+#define ACTION_GO_NEAR 7
+#define ACTION_SAFARI_ZONE_RUN 8
+#define ACTION_9 9
+#define ACTION_RUN_BATTLESCRIPT 10 // when executing an action
+#define ACTION_CANCEL_PARTNER 12 // when choosing an action
+#define ACTION_FINISHED 12 // when executing an action
+#define ACTION_NOTHING_FAINTED 13 // when choosing an action
+#define ACTION_INIT_VALUE 0xFF
#define MOVESTATUS_MISSED (1 << 0)
#define MOVESTATUS_SUPEREFFECTIVE (1 << 1)
@@ -187,27 +218,105 @@
#define WEATHER_SUN_ANY ((WEATHER_SUN_TEMPORARY | WEATHER_SUN_PERMANENT))
#define WEATHER_HAIL (1 << 7)
#define WEATHER_HAIL_ANY ((WEATHER_HAIL))
-
-#define REQUEST_ALL_BATTLE 0x0
-#define REQUEST_SPECIES_BATTLE 0x1
-#define REQUEST_HELDITEM_BATTLE 0x2
-#define REQUEST_MOVES_PP_BATTLE 0x3
-#define REQUEST_PPMOVE1_BATTLE 0x9
-#define REQUEST_PPMOVE2_BATTLE 0xA
-#define REQUEST_PPMOVE3_BATTLE 0xB
-#define REQUEST_PPMOVE4_BATTLE 0xC
-#define REQUEST_STATUS_BATTLE 0x28
-#define REQUEST_HP_BATTLE 0x2A
+#define WEATHER_ANY ((WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY))
+
+#define BATTLE_TERRAIN_GRASS 0
+#define BATTLE_TERRAIN_LONG_GRASS 1
+#define BATTLE_TERRAIN_SAND 2
+#define BATTLE_TERRAIN_UNDERWATER 3
+#define BATTLE_TERRAIN_WATER 4
+#define BATTLE_TERRAIN_POND 5
+#define BATTLE_TERRAIN_ROCK 6
+#define BATTLE_TERRAIN_CAVE 7
+#define BATTLE_TERRAIN_INSIDE 8
// array entries for battle communication
-#define MOVE_EFFECT_BYTE 0x3
-#define MULTISTRING_CHOOSER 0x5
-#define MSG_DISPLAY 0x7
+#define MULTIUSE_STATE 0x0
+#define CURSOR_POSITION 0x1
+#define TASK_ID 0x1 // task Id and cursor position share the same field
+#define SPRITES_INIT_STATE1 0x1 // shares the Id as well
+#define SPRITES_INIT_STATE2 0x2
+#define MOVE_EFFECT_BYTE 0x3
+#define ACTIONS_CONFIRMED_COUNT 0x4
+#define MULTISTRING_CHOOSER 0x5
+#define MSG_DISPLAY 0x7
+#define BATTLE_COMMUNICATION_ENTRIES_COUNT 0x8
+
+#define MOVE_TARGET_SELECTED 0x0
+#define MOVE_TARGET_DEPENDS 0x1
+#define MOVE_TARGET_USER 0x2
+#define MOVE_TARGET_RANDOM 0x4
+#define MOVE_TARGET_x10 0x10
+#define MOVE_TARGET_BOTH 0x8
+#define MOVE_TARGET_FOES_AND_ALLY 0x20
+#define MOVE_TARGET_OPPONENTS_FIELD 0x40
+
+#define TYPE_MUL_NO_EFFECT 0
+#define TYPE_MUL_NOT_EFFECTIVE 5
+#define TYPE_MUL_NORMAL 10
+#define TYPE_MUL_SUPER_EFFECTIVE 20
+
+#define BS_GET_TARGET 0
+#define BS_GET_ATTACKER 1
+#define BS_GET_EFFECT_BANK 2
+#define BS_ATTACKER_WITH_PARTNER 4 // for atk98_status_icon_update
+#define BS_GET_ATTACKER_SIDE 8 // for atk1E_jumpifability
+#define BS_GET_NOT_ATTACKER_SIDE 9 // for atk1E_jumpifability
+#define BS_GET_SCRIPTING_BANK 10
+#define BS_GET_OPPONENT1 12
+#define BS_GET_PLAYER2 13
+#define BS_GET_OPPONENT2 14
+
+// for battle script commands
+#define CMP_EQUAL 0x0
+#define CMP_NOT_EQUAL 0x1
+#define CMP_GREATER_THAN 0x2
+#define CMP_LESS_THAN 0x3
+#define CMP_COMMON_BITS 0x4
+#define CMP_NO_COMMON_BITS 0x5
+
+struct TrainerMonNoItemDefaultMoves
+{
+ u16 iv;
+ u8 lvl;
+ u16 species;
+};
-// functions
+u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg);
+u8 GetBankSide(u8 bank);
+
+struct TrainerMonItemDefaultMoves
+{
+ u16 iv;
+ u8 lvl;
+ u16 species;
+ u16 heldItem;
+};
+
+struct TrainerMonNoItemCustomMoves
+{
+ u16 iv;
+ u8 lvl;
+ u16 species;
+ u16 moves[4];
+};
-extern u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg);
-extern u8 GetBankSide(u8 bank);
+struct TrainerMonItemCustomMoves
+{
+ u16 iv;
+ u8 lvl;
+ u16 species;
+ u16 heldItem;
+ u16 moves[4];
+};
+
+union TrainerMonPtr
+{
+ struct TrainerMonNoItemDefaultMoves* NoItemDefaultMoves;
+ struct TrainerMonNoItemCustomMoves* NoItemCustomMoves;
+ struct TrainerMonItemDefaultMoves* ItemDefaultMoves;
+ struct TrainerMonItemCustomMoves* ItemCustomMoves;
+};
struct Trainer
{
@@ -220,9 +329,12 @@ struct Trainer
/*0x18*/ bool8 doubleBattle;
/*0x1C*/ u32 aiFlags;
/*0x20*/ u8 partySize;
- /*0x24*/ void *party;
+ /*0x24*/ union TrainerMonPtr party;
};
+#define PARTY_FLAG_CUSTOM_MOVES 0x1
+#define PARTY_FLAG_HAS_ITEM 0x2
+
extern const struct Trainer gTrainers[];
#define TRAINER_ENCOUNTER_MUSIC(trainer)((gTrainers[trainer].encounterMusic_gender & 0x7F))
@@ -251,8 +363,8 @@ struct DisableStruct
/*0x0F*/ u8 perishSong1 : 4;
/*0x0F*/ u8 perishSong2 : 4;
/*0x10*/ u8 furyCutterCounter;
- /*0x11*/ u8 rolloutTimer1 : 4;
- /*0x11*/ u8 rolloutTimer2 : 4;
+ /*0x11*/ u8 rolloutCounter1 : 4;
+ /*0x11*/ u8 rolloutCounter2 : 4;
/*0x12*/ u8 chargeTimer1 : 4;
/*0x12*/ u8 chargeTimer2 : 4;
/*0x13*/ u8 tauntTimer1:4;
@@ -262,7 +374,8 @@ struct DisableStruct
/*0x16*/ u8 isFirstTurn;
/*0x17*/ u8 unk17;
/*0x18*/ u8 truantCounter : 1;
- /*0x18*/ u8 unk18_a : 3;
+ /*0x18*/ u8 truantUnknownBit : 1;
+ /*0x18*/ u8 unk18_a_2 : 2;
/*0x18*/ u8 unk18_b : 4;
/*0x19*/ u8 rechargeCounter;
/*0x1A*/ u8 unk1A[2];
@@ -283,7 +396,7 @@ struct ProtectStruct
u32 prlzImmobility:1;
/* field_1 */
u32 confusionSelfDmg:1;
- u32 notEffective:1;
+ u32 targetNotAffected:1;
u32 chargingTurn:1;
u32 fleeFlag:2; // for RunAway and Smoke Ball
u32 usedImprisionedMove:1;
@@ -312,11 +425,11 @@ extern struct ProtectStruct gProtectStructs[BATTLE_BANKS_COUNT];
struct SpecialStatus
{
- u8 statLowered : 1;
- u8 lightningRodRedirected : 1;
- u8 restoredBankSprite: 1;
- u8 intimidatedPoke : 1;
- u8 traced : 1;
+ u8 statLowered : 1; // 0x1
+ u8 lightningRodRedirected : 1; // 0x2
+ u8 restoredBankSprite: 1; // 0x4
+ u8 intimidatedPoke : 1; // 0x8
+ u8 traced : 1; // 0x10
u8 flag20 : 1;
u8 flag40 : 1;
u8 focusBanded : 1;
@@ -359,7 +472,7 @@ struct WishFutureKnock
u8 wishCounter[BATTLE_BANKS_COUNT];
u8 wishUserID[BATTLE_BANKS_COUNT];
u8 weatherDuration;
- u16 knockedOffPokes;
+ u8 knockedOffPokes[2];
};
extern struct WishFutureKnock gWishFutureKnock;
@@ -389,7 +502,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;
};
@@ -405,13 +518,23 @@ struct BattleCallbacksStack
u8 size;
};
+struct StatsArray
+{
+ u16 hp;
+ u16 atk;
+ u16 def;
+ u16 spd;
+ u16 spAtk;
+ u16 spDef;
+};
+
struct BattleResources
{
struct SecretBaseRecord* secretBase;
struct UnknownFlags *flags;
struct BattleScriptsStack* battleScriptsStack;
struct BattleCallbacksStack* battleCallbackStack;
- void* statsBeforeLvlUp;
+ struct StatsArray* statsBeforeLvlUp;
struct AI_ThinkingStruct *ai;
struct BattleHistory *battleHistory;
struct BattleScriptsStack *AI_ScriptsStack;
@@ -421,31 +544,33 @@ extern struct BattleResources* gBattleResources;
#define BATTLESCRIPTS_STACK (gBattleResources->battleScriptsStack)
#define BATTLE_CALLBACKS_STACK (gBattleResources->battleCallbackStack)
+#define BATTLE_LVLUP_STATS (gBattleResources->statsBeforeLvlUp)
struct BattleResults
{
u8 playerFaintCounter; // 0x0
u8 opponentFaintCounter; // 0x1
- u8 unk2; // 0x2
+ u8 playerSwitchesCounter; // 0x2
u8 unk3; // 0x3
u8 unk4; // 0x4
u8 unk5_0:1; // 0x5
- u8 unk5_1:1; // 0x5
- u16 poke1Species; // 0x6
- u8 pokeString1[10]; // 0x8
- u8 unk12;
+ u8 usedMasterBall:1; // 0x5
+ u8 caughtMonBall:4; // 0x5
+ u8 unk5_6:1; // 0x5
+ u8 unk5_7:1; // 0x5
+ u16 playerMon1Species; // 0x6
+ u8 playerMon1Name[11]; // 0x8
u8 battleTurnCounter; // 0x13
- u8 pokeString2[10]; // 0x14
- u8 field_1E; // 0x1E
+ u8 playerMon2Name[11]; // 0x14
u8 field_1F; // 0x1F
u16 lastOpponentSpecies; // 0x20
- u16 lastUsedMove; // 0x22
- u16 opponentMove; // 0x24
- u16 opponentSpecies; // 0x26
- u16 caughtPoke; // 0x28
- u8 caughtNick[10]; // 0x2A
+ u16 lastUsedMovePlayer; // 0x22
+ u16 lastUsedMoveOpponent; // 0x24
+ u16 playerMon2Species; // 0x26
+ u16 caughtMonSpecies; // 0x28
+ u8 caughtMonNick[10]; // 0x2A
u8 filler34[2];
- u8 unk36[10]; // usedBalls?
+ u8 catchAttempts[11]; // 0x36
};
extern struct BattleResults gBattleResults;
@@ -463,46 +588,7 @@ struct BattleStruct
u8 wildVictorySong;
u8 dynamicMoveType;
u8 wrappedBy[4];
- u8 field_18;
- u8 field_19;
- u8 field_1A;
- u8 field_1B;
- u8 field_1C;
- u8 field_1D;
- u8 field_1E;
- u8 field_1F;
- u8 field_20;
- u8 field_21;
- u8 field_22;
- u8 field_23;
- u8 field_24;
- u8 field_25;
- u8 field_26;
- u8 field_27;
- u8 field_28;
- u8 field_29;
- u8 field_2A;
- u8 field_2B;
- u8 field_2C;
- u8 field_2D;
- u8 field_2E;
- u8 field_2F;
- u8 field_30;
- u8 field_31;
- u8 field_32;
- u8 field_33;
- u8 field_34;
- u8 field_35;
- u8 field_36;
- u8 field_37;
- u8 field_38;
- u8 field_39;
- u8 field_3A;
- u8 field_3B;
- u8 field_3C;
- u8 field_3D;
- u8 field_3E;
- u8 field_3F;
+ u16 assistPossibleMoves[5 * 4]; // 5 mons, each of them knowing 4 moves
u8 field_40;
u8 field_41;
u8 field_42;
@@ -511,51 +597,23 @@ struct BattleStruct
u8 field_45;
u8 field_46;
u8 field_47;
- u8 field_48;
+ u8 focusPunchBank;
u8 field_49;
u8 moneyMultiplier;
u8 field_4B;
- u8 field_4C;
+ u8 switchInAbilitiesCounter;
u8 field_4D;
u8 field_4E;
u8 field_4F;
- u8 field_50;
- u8 field_51;
+ u16 expValue;
u8 field_52;
- u8 field_53;
- u8 field_54;
- u8 field_55;
- u8 field_56;
- u8 field_57;
- u8 field_58;
- u8 field_59;
- u8 field_5A;
- u8 field_5B;
+ u8 sentInPokes;
+ bool8 selectionScriptFinished[BATTLE_BANKS_COUNT];
+ u8 field_58[4];
u8 field_5C[4];
- u8 field_60;
- u8 field_61;
- u8 field_62;
- u8 field_63;
- u8 field_64;
- u8 field_65;
- u8 field_66;
- u8 field_67;
- u8 field_68;
- u8 field_69;
- u8 field_6A;
- u8 field_6B;
- u8 field_6C;
- u8 field_6D;
- u8 field_6E;
- u8 field_6F;
- u8 field_70;
- u8 field_71;
- u8 field_72;
- u8 field_73;
- u8 field_74;
- u8 field_75;
- u8 field_76;
- u8 field_77;
+ u8 field_60[4][3];
+ u8 runTries;
+ u8 caughtMonNick[11];
u8 field_78;
u8 field_79;
u8 field_7A;
@@ -564,18 +622,15 @@ struct BattleStruct
u8 field_7D;
u8 field_7E;
u8 formToChangeInto;
- u8 chosenMovesIds[4];
- u8 field_84;
- u8 field_85;
- u8 field_86;
- u8 field_87;
+ u8 chosenMovePositions[BATTLE_BANKS_COUNT];
+ u8 stateIdAfterSelScript[BATTLE_BANKS_COUNT];
u8 field_88;
u8 field_89;
u8 field_8A;
u8 field_8B;
u8 field_8C;
u8 field_8D;
- u8 field_8E;
+ u8 stringMoveType;
u8 expGetterBank;
u8 field_90;
u8 field_91;
@@ -585,14 +640,7 @@ struct BattleStruct
u8 field_95;
u8 field_96;
u8 field_97;
- u8 field_98;
- u8 field_99;
- u8 field_9A;
- u8 field_9B;
- u8 field_9C;
- u8 field_9D;
- u8 field_9E;
- u8 field_9F;
+ u8 mirrorMoves[8]; // ask gamefreak why they declared it that way
u8 field_A0;
u8 field_A1;
u8 field_A2;
@@ -601,30 +649,44 @@ struct BattleStruct
u8 field_A5;
u8 field_A6;
u8 field_A7;
- u16 hpOnSwitchout[4];
+ u16 hpOnSwitchout[2];
+ u32 savedBattleTypeFlags;
u8 field_B0;
u8 hpScale;
u8 synchronizeMoveEffect;
u8 field_B3;
- u8 field_B4;
- u8 field_B5;
- u8 field_B6;
- u8 field_B7;
- u16 usedHeldItems[4];
- u8 field_C0[8];
- u16 choicedMove[4];
- u8 field_D0[8];
+ void (*savedCallback)(void);
+ u16 usedHeldItems[BATTLE_BANKS_COUNT];
+ u8 field_C0[4];
+ u8 AI_itemType[2];
+ u8 AI_itemFlags[2];
+ u16 choicedMove[BATTLE_BANKS_COUNT];
+ u16 changedItems[BATTLE_BANKS_COUNT];
u8 intimidateBank;
- u8 fillerD9[0xDA-0xD9];
+ u8 switchInItemsCounter;
u8 field_DA;
u8 turnSideTracker;
u8 fillerDC[0xDF-0xDC];
u8 field_DF;
- u8 fillerE0[0x1A0-0xE0];
+ u8 mirrorMoveArrays[32];
+ u16 castformPalette[4][16];
+ u8 field_180;
+ u8 field_181;
+ u8 field_182;
+ u8 field_183;
+ struct BattleEnigmaBerry battleEnigmaBerry;
u8 field_1A0;
u8 field_1A1;
- u8 filler1A2;
+ bool8 overworldWeatherDone;
u8 atkCancellerTracker;
+ u8 field_1A4[96];
+ u8 field_204[104];
+ u8 field_26C[40];
+ u8 field_294[4];
+ u8 field_298[8];
+ u8 field_2A0;
+ u8 field_2A1;
+ u8 field_2A2;
};
extern struct BattleStruct* gBattleStruct;
@@ -636,19 +698,125 @@ extern struct BattleStruct* gBattleStruct;
var2[offsetof(struct structName, offsetField)] = value; \
}
+#define GET_MOVE_TYPE(move, typeArg) \
+{ \
+ if (gBattleStruct->dynamicMoveType) \
+ typeArg = gBattleStruct->dynamicMoveType & 0x3F; \
+ else \
+ typeArg = gBattleMoves[move].type; \
+}
+
+#define MOVE_EFFECT_SLEEP 0x1
+#define MOVE_EFFECT_POISON 0x2
+#define MOVE_EFFECT_BURN 0x3
+#define MOVE_EFFECT_FREEZE 0x4
+#define MOVE_EFFECT_PARALYSIS 0x5
+#define MOVE_EFFECT_TOXIC 0x6
+#define MOVE_EFFECT_CONFUSION 0x7
+#define MOVE_EFFECT_FLINCH 0x8
+#define MOVE_EFFECT_TRI_ATTACK 0x9
+#define MOVE_EFFECT_UPROAR 0xA
+#define MOVE_EFFECT_PAYDAY 0xB
+#define MOVE_EFFECT_CHARGING 0xC
+#define MOVE_EFFECT_WRAP 0xD
+#define MOVE_EFFECT_RECOIL_25 0xE
+#define MOVE_EFFECT_ATK_PLUS_1 0xF
+#define MOVE_EFFECT_DEF_PLUS_1 0x10
+#define MOVE_EFFECT_SPD_PLUS_1 0x11
+#define MOVE_EFFECT_SP_ATK_PLUS_1 0x12
+#define MOVE_EFFECT_SP_DEF_PLUS_1 0x13
+#define MOVE_EFFECT_ACC_PLUS_1 0x14
+#define MOVE_EFFECT_EVS_PLUS_1 0x15
+#define MOVE_EFFECT_ATK_MINUS_1 0x16
+#define MOVE_EFFECT_DEF_MINUS_1 0x17
+#define MOVE_EFFECT_SPD_MINUS_1 0x18
+#define MOVE_EFFECT_SP_ATK_MINUS_1 0x19
+#define MOVE_EFFECT_SP_DEF_MINUS_1 0x1A
+#define MOVE_EFFECT_ACC_MINUS_1 0x1B
+#define MOVE_EFFECT_EVS_MINUS_1 0x1C
+#define MOVE_EFFECT_RECHARGE 0x1D
+#define MOVE_EFFECT_RAGE 0x1E
+#define MOVE_EFFECT_STEAL_ITEM 0x1F
+#define MOVE_EFFECT_PREVENT_ESCAPE 0x20
+#define MOVE_EFFECT_NIGHTMARE 0x21
+#define MOVE_EFFECT_ALL_STATS_UP 0x22
+#define MOVE_EFFECT_RAPIDSPIN 0x23
+#define MOVE_EFFECT_REMOVE_PARALYSIS 0x24
+#define MOVE_EFFECT_ATK_DEF_DOWN 0x25
+#define MOVE_EFFECT_RECOIL_33_PARALYSIS 0x26
+#define MOVE_EFFECT_ATK_PLUS_2 0x27
+#define MOVE_EFFECT_DEF_PLUS_2 0x28
+#define MOVE_EFFECT_SPD_PLUS_2 0x29
+#define MOVE_EFFECT_SP_ATK_PLUS_2 0x2A
+#define MOVE_EFFECT_SP_DEF_PLUS_2 0x2B
+#define MOVE_EFFECT_ACC_PLUS_2 0x2C
+#define MOVE_EFFECT_EVS_PLUS_2 0x2D
+#define MOVE_EFFECT_ATK_MINUS_2 0x2E
+#define MOVE_EFFECT_DEF_MINUS_2 0x2F
+#define MOVE_EFFECT_SPD_MINUS_2 0x30
+#define MOVE_EFFECT_SP_ATK_MINUS_2 0x31
+#define MOVE_EFFECT_SP_DEF_MINUS_2 0x32
+#define MOVE_EFFECT_ACC_MINUS_2 0x33
+#define MOVE_EFFECT_EVS_MINUS_2 0x34
+#define MOVE_EFFECT_THRASH 0x35
+#define MOVE_EFFECT_KNOCK_OFF 0x36
+#define MOVE_EFFECT_NOTHING_37 0x37
+#define MOVE_EFFECT_NOTHING_38 0x38
+#define MOVE_EFFECT_NOTHING_39 0x39
+#define MOVE_EFFECT_NOTHING_3A 0x3A
+#define MOVE_EFFECT_SP_ATK_TWO_DOWN 0x3B
+#define MOVE_EFFECT_NOTHING_3C 0x3C
+#define MOVE_EFFECT_NOTHING_3D 0x3D
+#define MOVE_EFFECT_NOTHING_3E 0x3E
+#define MOVE_EFFECT_NOTHING_3F 0x3F
+#define MOVE_EFFECT_AFFECTS_USER 0x40
+#define MOVE_EFFECT_CERTAIN 0x80
+
+// battle animations ids
+
+#define B_ANIM_CASTFORM_CHANGE 0x0
+#define B_ANIM_STATS_CHANGE 0x1
+#define B_ANIM_SUBSTITUTE_FADE 0x2
+#define B_ANIM_SUBSTITUTE_APPEAR 0x3
+#define B_ANIM_x4 0x4
+#define B_ANIM_ITEM_KNOCKOFF 0x5
+#define B_ANIM_TURN_TRAP 0x6
+#define B_ANIM_ITEM_EFFECT 0x7
+#define B_ANIM_SMOKEBALL_ESCAPE 0x8
+#define B_ANIM_HANGED_ON 0x9
+#define B_ANIM_RAIN_CONTINUES 0xA
+#define B_ANIM_SUN_CONTINUES 0xB
+#define B_ANIM_SANDSTORM_CONTINUES 0xC
+#define B_ANIM_HAIL_CONTINUES 0xD
+#define B_ANIM_LEECH_SEED_DRAIN 0xE
+#define B_ANIM_MON_HIT 0xF
+#define B_ANIM_ITEM_STEAL 0x10
+#define B_ANIM_SNATCH_MOVE 0x11
+#define B_ANIM_FUTURE_SIGHT_HIT 0x12
+#define B_ANIM_x13 0x13
+#define B_ANIM_x14 0x14
+#define B_ANIM_INGRAIN_HEAL 0x15
+#define B_ANIM_WISH_HEAL 0x16
+#define B_ANIM_x17 0x17
+#define B_ANIM_x18 0x18
+#define B_ANIM_x19 0x19
+#define B_ANIM_x1A 0x1A
+#define B_ANIM_x1B 0x1B
+#define B_ANIM_x1C 0x1C
+#define B_ANIM_x1D 0x1D
+
+#define GET_STAT_BUFF_ID(n)((n & 0xF)) // first four bits 0x1, 0x2, 0x4, 0x8
+#define GET_STAT_BUFF_VALUE(n)(((n >> 4) & 7)) // 0x10, 0x20, 0x40
+#define STAT_BUFF_NEGATIVE 0x80 // 0x80, the sign bit
+
+#define SET_STAT_BUFF_ID(n)((n & 0xF))
+#define SET_STAT_BUFF_VALUE(n)(((s8)(((s8)(n) << 4)) & 0xF0))
+
struct BattleScripting
{
- u8 field_0;
- u8 field_1;
- u8 field_2;
- u8 field_3;
- u32 bideDmg;
- u8 field_8;
- u8 field_9;
- u8 field_A;
- u8 field_B;
- u8 field_C;
- u8 field_D;
+ s32 painSplitHp;
+ s32 bideDmg;
+ u8 multihitString[6];
u8 dmgMultiplier;
u8 field_F;
u8 animArg1;
@@ -659,22 +827,165 @@ struct BattleScripting
u8 field_15;
u8 field_16;
u8 bank;
- u8 field_18;
- u8 field_19;
+ u8 animTurn;
+ u8 animTargetsHit;
u8 statChanger;
+ u8 field_1B;
+ u8 atk23_state;
+ u8 battleStyle;
+ u8 atk6C_state;
+ u8 learnMoveState;
+ u8 field_20;
+ u8 reshowMainState;
+ u8 reshowHelperState;
+ u8 field_23;
+ u8 field_24;
+ u8 multiplayerId;
};
extern struct BattleScripting gBattleScripting;
+// functions
+
+// battle_1
+void LoadBattleTextboxAndBackground(void);
+void LoadBattleEntryBackground(void);
+void ApplyPlayerChosenFrameToBattleMenu(void);
+bool8 LoadChosenBattleElement(u8 caseId);
+void DrawMainBattleBackground(void);
+void task00_0800F6FC(u8 taskId);
+
+// battle_5
+void AllocateBattleResrouces(void);
+void FreeBattleResources(void);
+void AdjustFriendshipOnBattleFaint(u8 bank);
+void sub_80571DC(u8 bank, u8 arg1);
+u32 sub_805725C(u8 bank);
+
+// battle 7
+void AllocateBattleSpritesData(void);
+void FreeBattleSpritesData(void);
+void AllocateMonSpritesGfx(void);
+void FreeMonSpritesGfx(void);
+void BattleMusicStop(void);
+void sub_805E990(struct Pokemon *mon, u8 bank);
+void sub_805EF14(void);
+bool8 BattleInitAllSprites(u8 *state1, u8 *state2);
+void sub_805E350(void);
+bool8 BattleLoadAllHealthBoxesGfx(u8 state);
+void LoadAndCreateEnemyShadowSprites(void);
+void SetBankEnemyShadowSpriteCallback(u8 bank, u16 species);
+void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 bank);
+void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 bank);
+void BattleLoadSubstituteSpriteGfx(u8 bank, bool8 arg1);
+
+enum
+{
+ BACK_PIC_BRENDAN,
+ BACK_PIC_MAY,
+ BACK_PIC_RED,
+ BACK_PIC_LEAF,
+ BACK_PIC_RS_BRENDAN,
+ BACK_PIC_RS_MAY,
+ BACK_PIC_WALLY,
+ BACK_PIC_STEVEN
+};
+void LoadBackTrainerBankSpriteGfx(u8 backPicId, u8 bank);
+
+// rom_80A5C6C
+u8 GetBankSide(u8 bank);
+u8 GetBankIdentity(u8 bank);
+u8 GetBankByIdentity(u8 bank);
+
+struct BattleSpriteInfo
+{
+ u16 invisible : 1; // 0x1
+ u16 flag_x2 : 1; // 0x2
+ u16 behindSubstitute : 1; // 0x4
+ u16 flag_x8 : 1; // 0x8
+ u16 hpNumbersNoBars : 1; // 0x10
+ u16 transformSpecies;
+};
+
+struct BattleAnimationInfo
+{
+ u16 field; // to fill up later
+ u8 field_2;
+ u8 field_3;
+ u8 field_4;
+ u8 field_5;
+ u8 field_6;
+ u8 field_7;
+ u8 field_8;
+ u8 field_9_x1 : 1;
+ u8 field_9_x2 : 1;
+ u8 field_9_x1C : 3;
+ u8 field_9_x20 : 1;
+ u8 field_9_x40 : 1;
+ u8 field_9_x80 : 1;
+};
+
+struct BattleHealthboxInfo
+{
+ u8 flag_x1 : 1;
+ u8 flag_x2 : 1;
+ u8 flag_x4 : 1;
+ u8 flag_x8 : 1;
+ u8 flag_x10 : 1;
+ u8 field_1;
+ u8 field_2;
+ u8 field_3;
+ u8 field_4;
+ u8 field_5;
+ u8 field_6;
+ u8 field_7;
+ u8 field_8;
+ u8 field_9;
+ u8 field_A;
+ u8 field_B;
+};
+
+struct BattleBarInfo
+{
+ u8 healthboxSpriteId;
+ s32 maxValue;
+ s32 currentValue;
+ s32 field_C;
+ s32 field_10;
+};
+
+struct BattleSpriteData
+{
+ struct BattleSpriteInfo *bankData;
+ struct BattleHealthboxInfo *healthBoxesData;
+ struct BattleAnimationInfo *animationData;
+ struct BattleBarInfo *battleBars;
+};
+
+extern struct BattleSpriteData *gBattleSpritesDataPtr;
+
+#define BATTLE_BUFFER_LINK_SIZE 0x1000
+
+extern u8 *gLinkBattleSendBuffer;
+extern u8 *gLinkBattleRecvBuffer;
+
+// Move this somewhere else
+
#include "sprite.h"
-struct BattleSpritesGfx
+struct MonSpritesGfx
{
void* firstDecompressed; // ptr to the decompressed sprite of the first pokemon
void* sprites[4];
struct SpriteTemplate templates[4];
+ u8 field_74[0x100];
+ u8 *fontPixels;
};
-extern struct BattleSpritesGfx* gBattleSpritesGfx;
+extern struct BattleSpritesGfx* gMonSpritesGfx;
+extern u8 gBattleOutcome;
+extern u16 gLastUsedItem;
+extern u32 gBattleTypeFlags;
+extern struct MonSpritesGfx* gMonSpritesGfxPtr;
#endif // GUARD_BATTLE_H