battle_setup funcs

This commit is contained in:
jiangzhengwenjz
2019-10-21 03:07:59 +08:00
parent e48725d9b5
commit b0400ef6ba
41 changed files with 1105 additions and 2346 deletions
+4 -4
View File
@@ -3902,7 +3902,7 @@ _080A8C60:
subs r0, r4
strh r0, [r1]
_080A8C6A:
ldr r1, _080A8C80 @ =sub_8075D9C
ldr r1, _080A8C80 @ =AnimSparklingParticle
str r1, [r6, 0x1C]
adds r0, r6, 0
bl _call_via_r1
@@ -3912,7 +3912,7 @@ _080A8C6A:
bx r0
.align 2, 0
_080A8C7C: .4byte gBattleAnimArgs
_080A8C80: .4byte sub_8075D9C
_080A8C80: .4byte AnimSparklingParticle
thumb_func_end sub_80A8BC4
thumb_func_start sub_80A8C84
@@ -4233,7 +4233,7 @@ _080A8F0E:
adds r0, r4, 0
movs r1, 0x1
bl StartSpriteAffineAnim
ldr r1, _080A8F34 @ =sub_8075D9C
ldr r1, _080A8F34 @ =AnimSparklingParticle
str r1, [r4, 0x1C]
adds r0, r4, 0
bl _call_via_r1
@@ -4244,7 +4244,7 @@ _080A8F0E:
_080A8F28: .4byte 0x000027db
_080A8F2C: .4byte 0x01010000
_080A8F30: .4byte gBattleAnimArgs
_080A8F34: .4byte sub_8075D9C
_080A8F34: .4byte AnimSparklingParticle
thumb_func_end sub_80A8EE8
thumb_func_start sub_80A8F38
-2180
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -134,13 +134,13 @@ npc_pal_op: @ 80DAE54
cmp r0, 0
bne _080DAEB0
ldrb r0, [r5, 0x1F]
bl MetatileBehavior_ReturnFalse_7
bl MetatileBehavior_GetBridgeType
lsls r0, 24
lsrs r0, 24
cmp r0, 0
bne _080DAE96
ldrb r0, [r5, 0x1E]
bl MetatileBehavior_ReturnFalse_7
bl MetatileBehavior_GetBridgeType
lsls r0, 24
lsrs r0, 24
cmp r0, 0
@@ -1251,7 +1251,7 @@ _080DB6E8:
cmp r0, 0
bne _080DB73C
adds r0, r4, 0
bl MetatileBehavior_ReturnFalse_3
bl MetatileBehavior_IsLongGrass
lsls r0, 24
cmp r0, 0
beq _080DB73C
+4 -4
View File
@@ -224,7 +224,7 @@ GetGroundEffectFlags_LongGrassOnSpawn: @ 8067CE8
push {r4,lr}
adds r4, r1, 0
ldrb r0, [r0, 0x1E]
bl MetatileBehavior_ReturnFalse_3
bl MetatileBehavior_IsLongGrass
lsls r0, 24
cmp r0, 0
beq _08067D00
@@ -243,7 +243,7 @@ GetGroundEffectFlags_LongGrassOnBeginStep: @ 8067D08
push {r4,lr}
adds r4, r1, 0
ldrb r0, [r0, 0x1E]
bl MetatileBehavior_ReturnFalse_3
bl MetatileBehavior_IsLongGrass
lsls r0, 24
cmp r0, 0
beq _08067D20
@@ -838,12 +838,12 @@ FieldObjectSetSpriteOamTableForLongGrass: @ 8068154
cmp r0, 0
blt _080681A8
ldrb r0, [r5, 0x1E]
bl MetatileBehavior_ReturnFalse_3
bl MetatileBehavior_IsLongGrass
lsls r0, 24
cmp r0, 0
beq _080681A8
ldrb r0, [r5, 0x1F]
bl MetatileBehavior_ReturnFalse_3
bl MetatileBehavior_IsLongGrass
lsls r0, 24
cmp r0, 0
beq _080681A8
+3 -3
View File
@@ -3522,8 +3522,8 @@ _0805669C: .4byte sub_8056534
_080566A0: .4byte sub_80565B4
thumb_func_end CB2_NewGame
thumb_func_start c2_whiteout
c2_whiteout: @ 80566A4
thumb_func_start CB2_WhiteOut
CB2_WhiteOut: @ 80566A4
push {lr}
sub sp, 0x4
ldr r1, _08056708 @ =gMain
@@ -3569,7 +3569,7 @@ _0805670C: .4byte gFieldCallback
_08056710: .4byte sub_807F5F0
_08056714: .4byte sub_8056534
_08056718: .4byte sub_80565B4
thumb_func_end c2_whiteout
thumb_func_end CB2_WhiteOut
thumb_func_start CB2_LoadMap
CB2_LoadMap: @ 805671C
+2 -2
View File
@@ -109,13 +109,13 @@ _080CA3C0: .4byte CB2_DoHallOfFameScreen
thumb_func_start sub_80CA3C4
sub_80CA3C4: @ 80CA3C4
push {lr}
ldr r0, _080CA3D4 @ =c2_whiteout
ldr r0, _080CA3D4 @ =CB2_WhiteOut
bl SetMainCallback2
movs r0, 0
pop {r1}
bx r1
.align 2, 0
_080CA3D4: .4byte c2_whiteout
_080CA3D4: .4byte CB2_WhiteOut
thumb_func_end sub_80CA3C4
.align 2, 0 @ Don't pad with nop.
+1 -1
View File
@@ -878,7 +878,7 @@ _08082D78:
bl sub_8058F1C
lsls r0, 24
lsrs r0, 24
bl MetatileBehavior_ReturnFalse_6
bl MetatileBehavior_IsBridge
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
+2 -2
View File
@@ -790,7 +790,7 @@ EventScript_TryDoNormalTrainerBattle:: @ 81A4EC1
faceplayer
applymovement VAR_LAST_TALKED, Movement_1A4FC5
waitmovement 0
specialvar VAR_RESULT, ScrSpecial_HasTrainerBeenFought
specialvar VAR_RESULT, GetTrainerFlag
compare_var_to_value VAR_RESULT, 0
goto_if 5, EventScript_1A4EE8
special SetUpTrainerEncounterMusic
@@ -804,7 +804,7 @@ EventScript_TryDoDoubleTrainerBattle:: @ 81A4EE9
lock
faceplayer
call EventScript_1A4FBA
specialvar VAR_RESULT, ScrSpecial_HasTrainerBeenFought
specialvar VAR_RESULT, GetTrainerFlag
compare_var_to_value VAR_RESULT, 0
goto_if 5, EventScript_1A4F20
special CheckForAlivePartyMons
+1 -1
View File
@@ -63,7 +63,7 @@ gSpecials:: @ 815FD60
def_special GetTrainerBattleMode
def_special ShowTrainerIntroSpeech
def_special ShowTrainerCantBattleSpeech
def_special ScrSpecial_HasTrainerBeenFought
def_special GetTrainerFlag
def_special ScrSpecial_EndTrainerApproach
def_special SetUpTrainerEncounterMusic
def_special sub_810CD4C
-11
View File
@@ -101,17 +101,6 @@
#define MAX_TRAINER_ITEMS 4
#define MAX_MON_MOVES 4
#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
#define BATTLE_TERRAIN_PLAIN 9
// array entries for battle communication
#define MULTIUSE_STATE 0x0
#define CURSOR_POSITION 0x1
+1 -1
View File
@@ -240,7 +240,7 @@ void SetGreyscaleOrOriginalPalette(u16 paletteNum, bool8 restoreOriginalColor);
u32 sub_8075BE8(u8 battleBackground, u8 attacker, u8 target, u8 attackerPartner, u8 targetPartner, u8 a6, u8 a7);
u32 sub_8075CB8(u8 a1, u8 a2, u8 a3, u8 a4);
u8 sub_8075D80(u8 a1);
void sub_8075D9C(struct Sprite *sprite);
void AnimSparklingParticle(struct Sprite *sprite);
void TranslateAnimSpriteToTargetMonLocation(struct Sprite *sprite);
void sub_8075E80(struct Sprite *sprite);
void sub_8075F0C(struct Sprite *sprite);
+4 -4
View File
@@ -5,17 +5,17 @@
void BattleSetup_StartScriptedWildBattle(void);
u8 BattleSetup_GetTerrainId(void);
u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data);
const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data);
void BattleSetup_StartBattlePikeWildBattle(void);
void BattleSetup_StartWildBattle(void);
void BattleSetup_StartRoamerBattle(void);
u8 HasTrainerAlreadyBeenFought(u16);
u8 HasTrainerBeenFought(u16);
void SetTrainerFlag(u16);
void ClearTrainerFlag(u16);
void BattleSetup_StartTrainerBattle(void);
u8 *BattleSetup_GetScriptAddrAfterBattle(void);
u8 *BattleSetup_GetTrainerPostBattleScript(void);
const u8 *BattleSetup_GetScriptAddrAfterBattle(void);
const u8 *BattleSetup_GetTrainerPostBattleScript(void);
void SetBattledTrainerFlag(void);
u8 sub_8080060(void);
u8 GetTrainerBattleMode(void);
+4 -4
View File
@@ -56,13 +56,13 @@
#define BATTLE_TYPE_OLDMAN_TUTORIAL 0x0200
#define BATTLE_TYPE_ROAMER 0x0400
#define BATTLE_TYPE_EREADER_TRAINER 0x0800
#define BATTLE_TYPE_KYOGRE_GROUDON 0x1000
#define BATTLE_TYPE_KYOGRE_GROUDON 0x1000 // TODO: used, rename later
#define BATTLE_TYPE_LEGENDARY 0x2000
#define BATTLE_TYPE_REGI 0x4000
#define BATTLE_TYPE_REGI 0x4000 // TODO: used, rename later
#define BATTLE_TYPE_GHOST 0x8000
#define BATTLE_TYPE_POKEDUDE 0x10000
#define BATTLE_TYPE_PALACE 0x20000
#define BATTLE_TYPE_ARENA 0x40000
#define BATTLE_TYPE_PALACE 0x20000 // TODO: used, rename later
#define BATTLE_TYPE_ARENA 0x40000 // TODO: used rename later
#define BATTLE_TYPE_TRAINER_TOWER 0x80000
#define BATTLE_TYPE_PIKE 0x100000
#define BATTLE_TYPE_PYRAMID 0x200000
+15
View File
@@ -0,0 +1,15 @@
#ifndef GUARD_CONSTANTS_BATTLE_SETUP_H
#define GUARD_CONSTANTS_BATTLE_SETUP_H
#define TRAINER_BATTLE_SINGLE 0
#define TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC 1
#define TRAINER_BATTLE_CONTINUE_SCRIPT 2
#define TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT 3
#define TRAINER_BATTLE_DOUBLE 4
#define TRAINER_BATTLE_REMATCH 5
#define TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE 6
#define TRAINER_BATTLE_REMATCH_DOUBLE 7
#define TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC 8
#define TRAINER_BATTLE_TUTORIAL 9
#endif // GUARD_CONSTANTS_BATTLE_SETUP_H
+28
View File
@@ -0,0 +1,28 @@
#ifndef GUARD_CONSTANTS_MAP_TYPES_H
#define GUARD_CONSTANTS_MAP_TYPES_H
#define MAP_TYPE_0 0
#define MAP_TYPE_TOWN 1
#define MAP_TYPE_CITY 2
#define MAP_TYPE_ROUTE 3
#define MAP_TYPE_UNDERGROUND 4
#define MAP_TYPE_UNDERWATER 5
#define MAP_TYPE_OCEAN_ROUTE 6
#define MAP_TYPE_7 7
#define MAP_TYPE_INDOOR 8
#define MAP_TYPE_SECRET_BASE 9
enum
{
MAP_BATTLE_SCENE_NORMAL, // 0
MAP_BATTLE_SCENE_GYM, // 1
MAP_BATTLE_SCENE_MAGMA, // 2
MAP_BATTLE_SCENE_AQUA, // 3
MAP_BATTLE_SCENE_SIDNEY, // 4
MAP_BATTLE_SCENE_PHOEBE, // 5
MAP_BATTLE_SCENE_GLACIA, // 6
MAP_BATTLE_SCENE_DRAKE, // 7
MAP_BATTLE_SCENE_BATTLE_TOWER, // 8
};
#endif // GUARD_CONSTANTS_MAP_TYPES_H
-3
View File
@@ -57,9 +57,6 @@ extern u16 gSpecialVar_MonBoxId;
extern u16 gSpecialVar_MonBoxPos;
extern u16 gSpecialVar_0x8014;
extern u16 gSpecialVar_Result;
extern u16 gSpecialVar_0x8004;
extern u16 gUnknown_20370DA;
extern u16 gUnknown_20370DC;
+9
View File
@@ -1155,6 +1155,15 @@ extern const u8 EventScript_SafariOutOfBalls[];
extern const u8 EventScript_ItemfinderDigUpUnderfootItem[];
// battle_setup
extern const u8 EventScript_DoTrainerBattle[];
extern const u8 EventScript_TryDoDoubleTrainerBattle[];
extern const u8 EventScript_TryDoNormalTrainerBattle[];
extern const u8 EventScript_TryDoDoubleRematchBattle[];
extern const u8 EventScript_TryDoRematchBattle[];
extern const u8 gUnknown_81A4EB4[];
extern const u8 gUnknown_81C555B[];
// new_game
extern const u8 EventScript_ResetAllMapFlags[];
+3
View File
@@ -5,4 +5,7 @@
extern u32 gUnknown_3005078;
void RestartWildEncounterImmunitySteps(void);
void ClearPoisonStepCounter(void);
#endif //GUARD_FIELD_CONTROL_AVATAR_H
+2
View File
@@ -94,6 +94,8 @@ void npc_paltag_set_load(u8 mode);
bool8 FieldObjectIsMovementOverridden(struct MapObject *mapObject);
u8 FieldObjectCheckHeldMovementStatus(struct MapObject *mapObject);
u8 sub_8063F84(u8 direction);
u8 GetTrainerFacingDirectionMovementType(u8 direction);
// Exported data declarations
+2 -2
View File
@@ -13,8 +13,8 @@ u8 player_get_direction_upper_nybble(void);
u8 player_get_x22(void);
void sub_808D074(u8);
void sub_805C270();
void sub_805C780();
void sub_805C270(void);
void sub_805C780(void);
void GetXYCoordsOneStepInFrontOfPlayer(s16 *xPtr, s16 *yPtr);
u8 sub_805C808(u8);
void SetPlayerAvatarStateMask(u8 mask);
+1 -30
View File
@@ -13,35 +13,6 @@ enum
CONNECTION_EMERGE
};
// map types
enum
{
MAP_TYPE_0,
MAP_TYPE_TOWN,
MAP_TYPE_CITY,
MAP_TYPE_ROUTE,
MAP_TYPE_UNDERGROUND,
MAP_TYPE_UNDERWATER,
MAP_TYPE_6,
MAP_TYPE_7,
MAP_TYPE_INDOOR,
MAP_TYPE_SECRET_BASE
};
// map battle scenes
enum
{
MAP_BATTLE_SCENE_NORMAL, // 0
MAP_BATTLE_SCENE_GYM, // 1
MAP_BATTLE_SCENE_MAGMA, // 2
MAP_BATTLE_SCENE_AQUA, // 3
MAP_BATTLE_SCENE_SIDNEY, // 4
MAP_BATTLE_SCENE_PHOEBE, // 5
MAP_BATTLE_SCENE_GLACIA, // 6
MAP_BATTLE_SCENE_DRAKE, // 7
MAP_BATTLE_SCENE_BATTLE_TOWER, // 8
};
typedef void (*TilesetCB)(void);
struct Tileset
@@ -241,7 +212,7 @@ struct MapObject
/*0x0C*/ struct Coords16 coords1;
/*0x10*/ struct Coords16 coords2;
/*0x14*/ struct Coords16 coords3;
/*0x18*/ u8 mapobj_unk_18:4; //current direction?
/*0x18*/ u8 facingDirection:4; //current direction?
/*0x18*/ u8 placeholder18:4;
/*0x19*/ union MapObjectRange range;
/*0x1A*/ u8 mapobj_unk_1A;
+6 -6
View File
@@ -10,7 +10,7 @@ bool8 MetatileBehavior_IsJumpNorth(u8 metatileBehavior);
bool8 MetatileBehavior_IsJumpSouth(u8 metatileBehavior);
bool8 MetatileBehavior_IsTallGrass(u8 metatileBehavior);
bool8 MetatileBehavior_IsMB21OrSand(u8 metatileBehavior);
bool8 MetatileBehavior_IsMB21OrWaterfallBottom(u8 metatileBehavior);
bool8 MetatileBehavior_IsSandOrDeepSand(u8 metatileBehavior);
bool8 MetatileBehavior_ReturnFalse(u8 metatileBehavior);
bool8 MetatileBehavior_IsReflective(u8 metatileBehavior);
bool8 MetatileBehavior_IsIce(u8 metatileBehavior);
@@ -53,15 +53,15 @@ bool8 MetatileBehavior_IsPC(u8 metatileBehavior);
bool8 MetatileBehavior_IsPondWaterOrPuddle(u8 metatileBehavior);
bool8 MetatileBehavior_IsPuddle(u8 metatileBehavior);
bool8 MetatileBehavior_IsTallGrass_2(u8 metatileBehavior);
bool8 MetatileBehavior_ReturnFalse_3(u8 metatileBehavior);
bool8 MetatileBehavior_IsLongGrass(u8 metatileBehavior);
bool8 MetatileBehavior_ReturnFalse_4(u8 metatileBehavior);
bool8 MetatileBehavior_ReturnFalse_5(u8 metatileBehavior);
bool8 MetatileBehavior_ReturnFalse_6(u8 metatileBehavior);
bool8 MetatileBehavior_ReturnFalse_7(u8 metatileBehavior);
bool8 MetatileBehavior_IsBridge(u8 metatileBehavior);
bool8 MetatileBehavior_GetBridgeType(u8 metatileBehavior);
bool8 MetatileBehavior_UnusedIsMB_01(u8 metatileBehavior);
bool8 MetatileBehavior_UnusedIsTallGrass(u8 metatileBehavior);
bool8 MetatileBehavior_IsMB0B(u8 metatileBehavior);
bool8 MetatileBehavior_IsMB0C(u8 metatileBehavior);
bool8 MetatileBehavior_IsIndoorEncounter(u8 metatileBehavior);
bool8 MetatileBehavior_IsMountain(u8 metatileBehavior);
bool8 MetatileBehavior_IsDeepOrSemiDeepWater(u8 metatileBehavior);
bool8 MetatileBehavior_IsMB19(u8 metatileBehavior);
bool8 MetatileBehavior_IsWaterfallBottom(u8 metatileBehavior);
+2 -1
View File
@@ -61,7 +61,7 @@ void sub_8084EBC(s16, s16);
void player_avatar_init_params_reset(void);
void Overworld_SetFlashLevel(s32 a1);
//u8 Overworld_GetFlashLevel(void);
u8 Overworld_GetFlashLevel(void);
void sub_8085524(u16);
void Overworld_SetSavedMusic(u16);
@@ -140,5 +140,6 @@ bool32 Overworld_DoScrollSceneForCredits(u8 *, const struct CreditsOverworldCmd
bool32 sub_8058318(void);
void CB2_ReturnToStartMenu(void);
void CB2_WhiteOut(void);
#endif //GUARD_OVERWORLD_H
-29
View File
@@ -169,35 +169,6 @@ enum
EGG_GROUP_UNDISCOVERED
};
enum
{
NATURE_HARDY,
NATURE_LONELY,
NATURE_BRAVE,
NATURE_ADAMANT,
NATURE_NAUGHTY,
NATURE_BOLD,
NATURE_DOCILE,
NATURE_RELAXED,
NATURE_IMPISH,
NATURE_LAX,
NATURE_TIMID,
NATURE_HASTY,
NATURE_SERIOUS,
NATURE_JOLLY,
NATURE_NAIVE,
NATURE_MODEST,
NATURE_MILD,
NATURE_QUIET,
NATURE_BASHFUL,
NATURE_RASH,
NATURE_CALM,
NATURE_GENTLE,
NATURE_SASSY,
NATURE_CAREFUL,
NATURE_QUIRKY,
};
struct PokemonSubstruct0
{
u16 species;
+2
View File
@@ -43,5 +43,7 @@ u8 sub_8112CAC(void);
void sub_81138F8(void);
void sub_812C224(void);
void sub_812BFDC(void);
void sub_811231C(void);
void sub_81139BC(void);
#endif //GUARD_QUEST_LOG_H
+1
View File
@@ -4,5 +4,6 @@
bool8 ScriptGiveMon(u16 species, u8 level, u16 item, u32 unk1, u32 unk2, u8 unk3);
bool8 ScriptGiveEgg(u16 species);
void ScriptSetMonMoveSlot(u8 partyIdx, u16 move, u8 slot);
void sp000_heal_pokemon(void);
#endif //GUARD_SCRIPT_POKEMON_UTIL_80A0058_H
+1 -1
View File
@@ -6,7 +6,7 @@
void Task_VsSeeker_0(u8 taskId);
void sub_810CB90(void);
void sub_810CDE8(void);
int sub_810CE64(u16 a0);
int GetRematchTrainerId(u16 a0);
bool8 sub_810CF04(u8 a0);
u8 sub_810CF54();
void sub_810D0D0(void);
+2 -1
View File
@@ -119,8 +119,9 @@ SECTIONS {
src/reset_save_heap.o(.text);
asm/field_weather.o(.text);
asm/field_weather_effects.o(.text);
src/field_fadetransition.o(.text);;
src/field_fadetransition.o(.text);
asm/field_screen_effect.o(.text);
src/battle_setup.o(.text);
asm/battle_setup.o(.text);
asm/cable_club.o(.text);
asm/trainer_see.o(.text);
+1 -1
View File
@@ -1336,7 +1336,7 @@ static u8 GetBattlerAtPosition_(u8 position)
return GetBattlerAtPosition(position);
}
void sub_8075D9C(struct Sprite *sprite)
void AnimSparklingParticle(struct Sprite *sprite)
{
bool8 var;
+1 -1
View File
@@ -48,6 +48,7 @@
#include "constants/abilities.h"
#include "constants/pokemon.h"
#include "constants/trainers.h"
#include "constants/map_types.h"
#define DEFENDER_IS_PROTECTED ((gProtectStructs[gBattlerTarget].protected) && (gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED))
@@ -9451,7 +9452,6 @@ static void atkEF_handleballthrow(void)
catchRate = gBattleStruct->safariCatchFactor * 1275 / 100;
else
catchRate = gBaseStats[gBattleMons[gBattlerTarget].species].catchRate;
if (gLastUsedItem > ITEM_SAFARI_BALL)
{
switch (gLastUsedItem)
+974
View File
@@ -0,0 +1,974 @@
#include "global.h"
#include "task.h"
#include "help_system.h"
#include "overworld.h"
#include "item.h"
#include "sound.h"
#include "pokemon.h"
#include "load_save.h"
#include "safari_zone.h"
#include "quest_log.h"
#include "script.h"
#include "script_pokemon_util_80A0058.h"
#include "strings.h"
#include "string_util.h"
#include "event_data.h"
#include "unk_8159F40.h"
#include "map_obj_80688E4.h"
#include "metatile_behavior.h"
#include "event_scripts.h"
#include "fldeff.h"
#include "fieldmap.h"
#include "field_control_avatar.h"
#include "field_player_avatar.h"
#include "field_screen_effect.h"
#include "field_message_box.h"
#include "field_map_obj.h"
#include "vs_seeker.h"
#include "battle.h"
#include "battle_setup.h"
#include "battle_transition.h"
#include "constants/battle_setup.h"
#include "constants/flags.h"
#include "constants/items.h"
#include "constants/maps.h"
#include "constants/songs.h"
#include "constants/species.h"
#include "constants/pokemon.h"
#include "constants/trainers.h"
#include "constants/trainer_classes.h"
#include "constants/map_types.h"
enum
{
TRAINER_PARAM_LOAD_VAL_8BIT,
TRAINER_PARAM_LOAD_VAL_16BIT,
TRAINER_PARAM_LOAD_VAL_32BIT,
TRAINER_PARAM_CLEAR_VAL_8BIT,
TRAINER_PARAM_CLEAR_VAL_16BIT,
TRAINER_PARAM_CLEAR_VAL_32BIT,
TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR,
};
struct TrainerBattleParameter
{
void *varPtr;
u8 ptrType;
};
void BattleSetup_StartSafariBattle(void);
void BattleSetup_StartGhostBattle(void);
void BattleSetup_StandardWildBattle(void);
void CB2_EndWildBattle(void);
u8 GetWildBattleTransition(void);
void CB2_EndSafariBattle(void);
u8 GetTrainerBattleTransition(void);
void CB2_EndScriptedWildBattle(void);
void CB2_EndMarowakBattle(void);
bool32 IsPlayerDefeated(u32 battleOutcome);
void CB2_EndTrainerBattle(void);
const u8 *GetIntroSpeechOfApproachingTrainer(void);
const u8 *GetTrainerCantBattleSpeech(void);
EWRAM_DATA u16 sTrainerBattleMode = 0;
EWRAM_DATA u16 gTrainerBattleOpponent_A = 0;
EWRAM_DATA u16 sTrainerEventObjectLocalId = 0;
EWRAM_DATA u8 *sTrainerAIntroSpeech = NULL;
EWRAM_DATA u8 *sTrainerADefeatSpeech = NULL;
EWRAM_DATA u8 *sTrainerBDefeatSpeech = NULL;
EWRAM_DATA u8 *sTrainerCannotBattleSpeech = NULL;
EWRAM_DATA u8 *sTrainerBattleEndScript = NULL;
EWRAM_DATA u8 *sTrainerABattleScriptRetAddr = NULL;
EWRAM_DATA u16 gUnknown_20386CC = 0;
extern const u8 sBattleTransitionTable_Wild[][2];
extern const u8 sBattleTransitionTable_Trainer[][2];
extern const struct TrainerBattleParameter sOrdinaryBattleParams[];
extern const struct TrainerBattleParameter sOrdinaryNoIntroBattleParams[];
extern const struct TrainerBattleParameter sDoubleBattleParams[];
extern const struct TrainerBattleParameter sContinueScriptBattleParams[];
extern const struct TrainerBattleParameter sContinueScriptDoubleBattleParams[];
extern const struct TrainerBattleParameter gUnknown_83C6A20[];
#define tState data[0]
#define tTransition data[1]
void Task_BattleStart(u8 taskId)
{
s16 *data = gTasks[taskId].data;
switch (tState)
{
case 0:
if (!FldEffPoison_IsActive())
{
HelpSystem_Disable();
BT_StartOnField(tTransition);
++tState;
}
break;
case 1:
if (BT_IsDone() == TRUE)
{
HelpSystem_Enable();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_InitBattle);
RestartWildEncounterImmunitySteps();
ClearPoisonStepCounter();
DestroyTask(taskId);
}
break;
}
}
void CreateBattleStartTask(u8 transition, u16 song) // song == 0 means default music for current map
{
u8 taskId = CreateTask(Task_BattleStart, 1);
gTasks[taskId].tTransition = transition;
PlayMapChosenOrBattleBGM(song);
}
bool8 CheckSilphScopeInPokemonTower(u16 mapGroup, u16 mapNum)
{
if (mapGroup == MAP_GROUP(POKEMON_TOWER_1F)
&& ((u16)(mapNum - MAP_NUM(POKEMON_TOWER_1F)) <= 6)
&& !(CheckBagHasItem(ITEM_SILPH_SCOPE, 1)))
return TRUE;
else
return FALSE;
}
void BattleSetup_StartWildBattle(void)
{
if (GetSafariZoneFlag())
BattleSetup_StartSafariBattle();
else if (CheckSilphScopeInPokemonTower(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum))
BattleSetup_StartGhostBattle();
else
BattleSetup_StandardWildBattle();
}
void BattleSetup_StandardWildBattle(void)
{
ScriptContext2_Enable();
FreezeEventObjects();
sub_805C780();
gMain.savedCallback = CB2_EndWildBattle;
gBattleTypeFlags = 0;
CreateBattleStartTask(GetWildBattleTransition(), 0);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void BattleSetup_StartRoamerBattle(void)
{
ScriptContext2_Enable();
FreezeEventObjects();
sub_805C780();
gMain.savedCallback = CB2_EndWildBattle;
gBattleTypeFlags = BATTLE_TYPE_ROAMER;
CreateBattleStartTask(GetWildBattleTransition(), MUS_VS_DEN);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void BattleSetup_StartSafariBattle(void)
{
ScriptContext2_Enable();
FreezeEventObjects();
sub_805C780();
gMain.savedCallback = CB2_EndSafariBattle;
gBattleTypeFlags = BATTLE_TYPE_SAFARI;
CreateBattleStartTask(GetWildBattleTransition(), 0);
}
void BattleSetup_StartGhostBattle(void)
{
ScriptContext2_Enable();
FreezeEventObjects();
sub_805C780();
gMain.savedCallback = CB2_EndWildBattle;
gBattleTypeFlags = BATTLE_TYPE_GHOST;
CreateBattleStartTask(GetWildBattleTransition(), 0);
SetMonData(&gEnemyParty[0], MON_DATA_NICKNAME, gUnknown_841D148);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void DoTrainerBattle(void)
{
CreateBattleStartTask(GetTrainerBattleTransition(), 0);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_TRAINER_BATTLES);
}
void BattleSetup_StartOldManTutorialBattle(void)
{
CreateMaleMon(&gEnemyParty[0], SPECIES_WEEDLE, 5);
ScriptContext2_Enable();
gMain.savedCallback = CB2_ReturnToFieldContinueScriptPlayMapMusic;
gBattleTypeFlags = BATTLE_TYPE_OLDMAN_TUTORIAL;
CreateBattleStartTask(B_TRANSITION_SLICED_SCREEN, 0);
}
void BattleSetup_StartScriptedWildBattle(void)
{
ScriptContext2_Enable();
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_PALACE;
CreateBattleStartTask(GetWildBattleTransition(), 0);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void BattleSetup_StartMarowakBattle(void)
{
ScriptContext2_Enable();
gMain.savedCallback = CB2_EndMarowakBattle;
if (CheckBagHasItem(ITEM_SILPH_SCOPE, 1))
{
gBattleTypeFlags = BATTLE_TYPE_GHOST | BATTLE_TYPE_LEGENDARY;
CreateMonWithGenderNatureLetter(gEnemyParty, SPECIES_MAROWAK, 30, 31, MON_FEMALE, NATURE_SERIOUS, 0);
}
else
{
gBattleTypeFlags = BATTLE_TYPE_GHOST;
}
CreateBattleStartTask(GetWildBattleTransition(), 0);
SetMonData(&gEnemyParty[0], MON_DATA_NICKNAME, gUnknown_841D148);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void sub_807F998(void)
{
ScriptContext2_Enable();
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_LEGENDARY;
CreateBattleStartTask(GetWildBattleTransition(), 0);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void BattleSetup_StartLegendaryBattle(void)
{
u16 species;
ScriptContext2_Enable();
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_ARENA;
species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES);
switch (species)
{
case SPECIES_MEWTWO:
CreateBattleStartTask(B_TRANSITION_BLUR, MUS_VS_MYU2);
break;
case SPECIES_DEOXYS:
CreateBattleStartTask(B_TRANSITION_BLUR, MUS_VS_DEO);
break;
case SPECIES_MOLTRES:
case SPECIES_ARTICUNO:
case SPECIES_ZAPDOS:
case SPECIES_HO_OH:
case SPECIES_LUGIA:
CreateBattleStartTask(B_TRANSITION_BLUR, MUS_VS_DEN);
break;
default:
CreateBattleStartTask(B_TRANSITION_BLUR, MUS_BATTLE20);
break;
}
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void BattleSetup_StartIceCaveBattle(void)
{
ScriptContext2_Enable();
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_KYOGRE_GROUDON;
if (gGameVersion == VERSION_FIRE_RED)
CreateBattleStartTask(B_TRANSITION_BLACK_DOODLES, MUS_BATTLE20);
else // pointless, exactly the same
CreateBattleStartTask(B_TRANSITION_BLACK_DOODLES, MUS_BATTLE20);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
void sub_807FABC(void)
{
ScriptContext2_Enable();
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI;
CreateBattleStartTask(B_TRANSITION_BLUR, MUS_BATTLE20);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
}
// not used
void sub_807FAF8(void)
{
LoadPlayerParty();
CB2_EndWildBattle();
}
//not used
void sub_807FB08(void)
{
ScriptContext2_Enable();
FreezeEventObjects();
sub_805C780();
gMain.savedCallback = sub_807FAF8;
SavePlayerParty();
sub_8159F40();
CreateBattleStartTask(GetWildBattleTransition(), 0);
}
void CB2_EndWildBattle(void)
{
CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE);
ResetOamRange(0, 128);
if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
SetMainCallback2(CB2_WhiteOut);
}
else
{
SetMainCallback2(CB2_ReturnToField);
gFieldCallback = sub_807E3EC;
}
}
void CB2_EndScriptedWildBattle(void)
{
CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE);
ResetOamRange(0, 128);
if (IsPlayerDefeated(gBattleOutcome) == TRUE)
SetMainCallback2(CB2_WhiteOut);
else
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
void CB2_EndMarowakBattle(void)
{
CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE);
ResetOamRange(0, 128);
if (IsPlayerDefeated(gBattleOutcome))
{
SetMainCallback2(CB2_WhiteOut);
}
else
{
if (gBattleOutcome == B_OUTCOME_WON)
gSpecialVar_Result = 0;
else
gSpecialVar_Result = 1;
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
}
u8 BattleSetup_GetTerrainId(void)
{
u16 tileBehavior;
s16 x, y;
PlayerGetDestCoords(&x, &y);
tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
if (MetatileBehavior_IsTallGrass_2(tileBehavior))
return BATTLE_TERRAIN_GRASS;
if (MetatileBehavior_IsLongGrass(tileBehavior))
return BATTLE_TERRAIN_LONG_GRASS;
if (MetatileBehavior_IsSandOrDeepSand(tileBehavior))
return BATTLE_TERRAIN_SAND;
switch (gMapHeader.mapType)
{
case MAP_TYPE_TOWN:
case MAP_TYPE_CITY:
case MAP_TYPE_ROUTE:
break;
case MAP_TYPE_UNDERGROUND:
if (MetatileBehavior_IsIndoorEncounter(tileBehavior))
return BATTLE_TERRAIN_BUILDING;
if (MetatileBehavior_IsSurfable(tileBehavior))
return BATTLE_TERRAIN_POND;
return BATTLE_TERRAIN_CAVE;
case MAP_TYPE_INDOOR:
case MAP_TYPE_SECRET_BASE:
return BATTLE_TERRAIN_BUILDING;
case MAP_TYPE_UNDERWATER:
return BATTLE_TERRAIN_UNDERWATER;
case MAP_TYPE_OCEAN_ROUTE:
if (MetatileBehavior_IsSurfable(tileBehavior))
return BATTLE_TERRAIN_WATER;
return BATTLE_TERRAIN_PLAIN;
}
if (MetatileBehavior_IsDeepSemiDeepOrSplashingWater(tileBehavior))
return BATTLE_TERRAIN_WATER;
if (MetatileBehavior_IsSurfable(tileBehavior))
return BATTLE_TERRAIN_POND;
if (MetatileBehavior_IsMountain(tileBehavior))
return BATTLE_TERRAIN_MOUNTAIN;
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
{
if (MetatileBehavior_GetBridgeType(tileBehavior))
return BATTLE_TERRAIN_POND;
if (MetatileBehavior_IsBridge(tileBehavior) == TRUE)
return BATTLE_TERRAIN_WATER;
}
return BATTLE_TERRAIN_PLAIN;
}
u8 GetBattleTransitionTypeByMap(void)
{
u16 tileBehavior;
s16 x, y;
PlayerGetDestCoords(&x, &y);
tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
if (Overworld_GetFlashLevel())
return B_TRANSITION_HORIZONTAL_CORRUGATE;
if (!MetatileBehavior_IsSurfable(tileBehavior))
{
switch (gMapHeader.mapType)
{
case MAP_TYPE_UNDERGROUND:
return B_TRANSITION_DISTORTED_WAVE;
case MAP_TYPE_UNDERWATER:
return B_TRANSITION_BIG_POKEBALL;
default:
return B_TRANSITION_BLUR;
}
}
return B_TRANSITION_BIG_POKEBALL;
}
u16 GetSumOfPlayerPartyLevel(u8 numMons)
{
u8 sum = 0;
s32 i;
for (i = 0; i < PARTY_SIZE; ++i)
{
u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
if (species != SPECIES_EGG && species != SPECIES_NONE && GetMonData(&gPlayerParty[i], MON_DATA_HP) != 0)
{
sum += GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
if (--numMons == 0)
break;
}
}
return sum;
}
u8 GetSumOfEnemyPartyLevel(u16 opponentId, u8 numMons)
{
u8 i;
u8 sum;
u32 count = numMons;
if (gTrainers[opponentId].partySize < count)
count = gTrainers[opponentId].partySize;
sum = 0;
switch (gTrainers[opponentId].partyFlags)
{
case 0:
{
const struct TrainerMonNoItemDefaultMoves *party;
party = gTrainers[opponentId].party.NoItemDefaultMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
case F_TRAINER_PARTY_CUSTOM_MOVESET:
{
const struct TrainerMonNoItemCustomMoves *party;
party = gTrainers[opponentId].party.NoItemCustomMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
case F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemDefaultMoves *party;
party = gTrainers[opponentId].party.ItemDefaultMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemCustomMoves *party;
party = gTrainers[opponentId].party.ItemCustomMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
}
return sum;
}
u8 GetWildBattleTransition(void)
{
u8 transitionType = GetBattleTransitionTypeByMap();
u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
u8 playerLevel = GetSumOfPlayerPartyLevel(1);
if (enemyLevel < playerLevel)
return sBattleTransitionTable_Wild[transitionType][0];
else
return sBattleTransitionTable_Wild[transitionType][1];
}
u8 GetTrainerBattleTransition(void)
{
u8 minPartyCount;
u8 transitionType;
u8 enemyLevel;
u8 playerLevel;
if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE)
return B_TRANSITION_BLUE;
if (gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_ELITE_FOUR_2)
{
if (gTrainerBattleOpponent_A == 410 || gTrainerBattleOpponent_A == 735) // TODO: replace these with enums
return B_TRANSITION_LORELEI;
if (gTrainerBattleOpponent_A == 411 || gTrainerBattleOpponent_A == 736)
return B_TRANSITION_BRUNO;
if (gTrainerBattleOpponent_A == 412 || gTrainerBattleOpponent_A == 737)
return B_TRANSITION_AGATHA;
if (gTrainerBattleOpponent_A == 413 || gTrainerBattleOpponent_A == 738)
return B_TRANSITION_LANCE;
return B_TRANSITION_BLUE;
}
if (gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_CHAMPION_2)
return B_TRANSITION_BLUE;
if (gTrainers[gTrainerBattleOpponent_A].doubleBattle == TRUE)
minPartyCount = 2; // double battles always at least have 2 pokemon.
else
minPartyCount = 1;
transitionType = GetBattleTransitionTypeByMap();
enemyLevel = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent_A, minPartyCount);
playerLevel = GetSumOfPlayerPartyLevel(minPartyCount);
if (enemyLevel < playerLevel)
return sBattleTransitionTable_Trainer[transitionType][0];
else
return sBattleTransitionTable_Trainer[transitionType][1];
}
u8 sub_8080060(void)
{
u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
u8 playerLevel = GetSumOfPlayerPartyLevel(1);
if (enemyLevel < playerLevel)
return 4;
else
return 3;
}
u32 TrainerBattleLoadArg32(const u8 *ptr)
{
return T1_READ_32(ptr);
}
u16 TrainerBattleLoadArg16(const u8 *ptr)
{
return T1_READ_16(ptr);
}
u8 TrainerBattleLoadArg8(const u8 *ptr)
{
return T1_READ_8(ptr);
}
u16 GetTrainerAFlag(void)
{
return FLAG_TRAINER_FLAG_START + gTrainerBattleOpponent_A;
}
bool32 IsPlayerDefeated(u32 battleOutcome)
{
switch (battleOutcome)
{
case B_OUTCOME_LOST:
case B_OUTCOME_DREW:
return TRUE;
case B_OUTCOME_WON:
case B_OUTCOME_RAN:
case B_OUTCOME_PLAYER_TELEPORTED:
case B_OUTCOME_MON_FLED:
case B_OUTCOME_CAUGHT:
return FALSE;
default:
return FALSE;
}
}
void InitTrainerBattleVariables(void)
{
sTrainerBattleMode = 0;
gTrainerBattleOpponent_A = 0;
sTrainerEventObjectLocalId = 0;
sTrainerAIntroSpeech = NULL;
sTrainerADefeatSpeech = NULL;
sTrainerBDefeatSpeech = NULL;
sTrainerCannotBattleSpeech = NULL;
sTrainerBattleEndScript = NULL;
sTrainerABattleScriptRetAddr = NULL;
gUnknown_20386CC = 0;
}
static inline void SetU8(void *ptr, u8 value)
{
*(u8 *)(ptr) = value;
}
static inline void SetU16(void *ptr, u16 value)
{
*(u16 *)(ptr) = value;
}
static inline void SetU32(void *ptr, u32 value)
{
*(u32 *)(ptr) = value;
}
static inline void SetPtr(const void *ptr, const void* value)
{
*(const void **)(ptr) = value;
}
void TrainerBattleLoadArgs(const struct TrainerBattleParameter *specs, const u8 *data)
{
while (1)
{
switch (specs->ptrType)
{
case TRAINER_PARAM_LOAD_VAL_8BIT:
SetU8(specs->varPtr, TrainerBattleLoadArg8(data));
data += 1;
break;
case TRAINER_PARAM_LOAD_VAL_16BIT:
SetU16(specs->varPtr, TrainerBattleLoadArg16(data));
data += 2;
break;
case TRAINER_PARAM_LOAD_VAL_32BIT:
SetU32(specs->varPtr, TrainerBattleLoadArg32(data));
data += 4;
break;
case TRAINER_PARAM_CLEAR_VAL_8BIT:
SetU8(specs->varPtr, 0);
break;
case TRAINER_PARAM_CLEAR_VAL_16BIT:
SetU16(specs->varPtr, 0);
break;
case TRAINER_PARAM_CLEAR_VAL_32BIT:
SetU32(specs->varPtr, 0);
break;
case TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR:
SetPtr(specs->varPtr, data);
return;
}
++specs;
}
}
void SetMapVarsToTrainer(void)
{
if (sTrainerEventObjectLocalId != 0)
{
gSpecialVar_LastTalked = sTrainerEventObjectLocalId;
gSelectedEventObject = GetFieldObjectIdByLocalIdAndMap(sTrainerEventObjectLocalId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
}
}
const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data)
{
InitTrainerBattleVariables();
sTrainerBattleMode = TrainerBattleLoadArg8(data);
switch (sTrainerBattleMode)
{
case TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT:
TrainerBattleLoadArgs(sOrdinaryNoIntroBattleParams, data);
return EventScript_DoTrainerBattle;
case TRAINER_BATTLE_DOUBLE:
TrainerBattleLoadArgs(sDoubleBattleParams, data);
SetMapVarsToTrainer();
return EventScript_TryDoDoubleTrainerBattle;
case TRAINER_BATTLE_CONTINUE_SCRIPT:
case TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC:
TrainerBattleLoadArgs(sContinueScriptBattleParams, data);
SetMapVarsToTrainer();
return EventScript_TryDoNormalTrainerBattle;
case TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE:
case TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC:
TrainerBattleLoadArgs(sContinueScriptDoubleBattleParams, data);
SetMapVarsToTrainer();
return EventScript_TryDoDoubleTrainerBattle;
case TRAINER_BATTLE_REMATCH_DOUBLE:
sub_811231C();
TrainerBattleLoadArgs(sDoubleBattleParams, data);
SetMapVarsToTrainer();
gTrainerBattleOpponent_A = GetRematchTrainerId(gTrainerBattleOpponent_A);
return EventScript_TryDoDoubleRematchBattle;
case TRAINER_BATTLE_REMATCH:
sub_811231C();
TrainerBattleLoadArgs(sOrdinaryBattleParams, data);
SetMapVarsToTrainer();
gTrainerBattleOpponent_A = GetRematchTrainerId(gTrainerBattleOpponent_A);
return EventScript_TryDoRematchBattle;
case TRAINER_BATTLE_TUTORIAL:
TrainerBattleLoadArgs(gUnknown_83C6A20, data);
return EventScript_DoTrainerBattle;
default:
TrainerBattleLoadArgs(sOrdinaryBattleParams, data);
SetMapVarsToTrainer();
return EventScript_TryDoNormalTrainerBattle;
}
}
void ConfigureAndSetUpOneTrainerBattle(u8 trainerEventObjId, const u8 *trainerScript)
{
gSelectedEventObject = trainerEventObjId;
gSpecialVar_LastTalked = gMapObjects[trainerEventObjId].localId;
BattleSetup_ConfigureTrainerBattle(trainerScript + 1);
ScriptContext1_SetupScript(gUnknown_81A4EB4);
ScriptContext2_Enable();
}
bool32 GetTrainerFlagFromScriptPointer(const u8 *data)
{
u32 flag = TrainerBattleLoadArg16(data + 2);
return FlagGet(FLAG_TRAINER_FLAG_START + flag);
}
void SetUpTrainerMovement(void)
{
struct MapObject *eventObject = &gMapObjects[gSelectedEventObject];
SetTrainerMovementType(eventObject, GetTrainerFacingDirectionMovementType(eventObject->facingDirection));
}
u8 GetTrainerBattleMode(void)
{
return sTrainerBattleMode;
}
u16 sub_80803D8(void)
{
return gUnknown_20386CC;
}
u16 GetTrainerFlag(void)
{
return FlagGet(GetTrainerAFlag());
}
void SetBattledTrainerFlag(void)
{
FlagSet(GetTrainerAFlag());
}
// not used
void SetBattledTrainerFlag2(void)
{
FlagSet(GetTrainerAFlag());
}
bool8 HasTrainerBeenFought(u16 trainerId)
{
return FlagGet(FLAG_TRAINER_FLAG_START + trainerId);
}
void SetTrainerFlag(u16 trainerId)
{
FlagSet(FLAG_TRAINER_FLAG_START + trainerId);
}
void ClearTrainerFlag(u16 trainerId)
{
FlagClear(FLAG_TRAINER_FLAG_START + trainerId);
}
void BattleSetup_StartTrainerBattle(void)
{
gBattleTypeFlags = BATTLE_TYPE_TRAINER;
if (GetTrainerBattleMode() == TRAINER_BATTLE_TUTORIAL
&& sub_80803D8() & 3)
gBattleTypeFlags |= BATTLE_TYPE_FIRST_BATTLE;
gMain.savedCallback = CB2_EndTrainerBattle;
DoTrainerBattle();
ScriptContext1_Stop();
}
void CB2_EndTrainerBattle(void)
{
if (sTrainerBattleMode == TRAINER_BATTLE_TUTORIAL)
{
if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
gSpecialVar_Result = 1;
if (gUnknown_20386CC & 1)
{
sp000_heal_pokemon();
}
else
{
SetMainCallback2(CB2_WhiteOut);
return;
}
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
SetBattledTrainerFlag();
sub_81139BC();
}
else
{
gSpecialVar_Result = 0;
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
SetBattledTrainerFlag();
sub_81139BC();
}
}
else
{
if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE)
{
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
SetMainCallback2(CB2_WhiteOut);
}
else
{
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
SetBattledTrainerFlag();
sub_81139BC();
}
}
}
void CB2_EndRematchBattle(void)
{
if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE)
{
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
SetMainCallback2(CB2_WhiteOut);
}
else
{
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
SetBattledTrainerFlag();
sub_810CDE8();
sub_81138F8();
}
}
void BattleSetup_StartRematchBattle(void)
{
gBattleTypeFlags = BATTLE_TYPE_TRAINER;
gMain.savedCallback = CB2_EndRematchBattle;
DoTrainerBattle();
ScriptContext1_Stop();
}
void ShowTrainerIntroSpeech(void)
{
ShowFieldMessage(GetIntroSpeechOfApproachingTrainer());
}
const u8 *BattleSetup_GetScriptAddrAfterBattle(void)
{
if (sTrainerBattleEndScript != NULL)
return sTrainerBattleEndScript;
else
return gUnknown_81C555B;
}
const u8 *BattleSetup_GetTrainerPostBattleScript(void)
{
if (sTrainerABattleScriptRetAddr != NULL)
return sTrainerABattleScriptRetAddr;
else
return gUnknown_81C555B;
}
void ShowTrainerCantBattleSpeech(void)
{
ShowFieldMessage(GetTrainerCantBattleSpeech());
}
void SetUpTrainerEncounterMusic(void)
{
u16 music;
if ((u8)(gUnknown_203ADFA - 2) > 1
&& sTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC
&& sTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC)
{
switch (GetTrainerEncounterMusicId(gTrainerBattleOpponent_A))
{
case 1: // TODO: replace these with enums
case 2:
case 9:
music = MUS_SHOUJO;
break;
case 0:
case 4:
case 5:
case 8:
case 10:
case 11:
case 12:
case 13:
music = MUS_SHOUNEN;
break;
default:
music = MUS_ROCKET;
break;
}
PlayNewMapMusic(music);
}
}
const u8 *ReturnEmptyStringIfNull(const u8 *string)
{
if (string == NULL)
return gString_Dummy;
else
return string;
}
const u8 *GetIntroSpeechOfApproachingTrainer(void)
{
return ReturnEmptyStringIfNull(sTrainerAIntroSpeech);
}
const u8 *GetTrainerALoseText(void)
{
const u8 *string = sTrainerADefeatSpeech;
StringExpandPlaceholders(gStringVar4, ReturnEmptyStringIfNull(string));
return gStringVar4;
}
const u8 *GetTrainerBLoseText(void)
{
StringExpandPlaceholders(gStringVar4, ReturnEmptyStringIfNull(sTrainerBDefeatSpeech));
return gStringVar4;
}
const u8 *GetTrainerCantBattleSpeech(void)
{
return ReturnEmptyStringIfNull(sTrainerCannotBattleSpeech);
}
+1 -1
View File
@@ -878,7 +878,7 @@ static void FC_DestroyWindow(u8 windowId)
static u8 AdjustGiovanniIndexIfBeatenInGym(u8 a0)
{
if (HasTrainerAlreadyBeenFought(0x15e) == TRUE)
if (HasTrainerBeenFought(0x15e) == TRUE)
{
if (a0 == 9)
return FAMECHECKER_GIOVANNI;
+1
View File
@@ -16,6 +16,7 @@
#include "field_map_obj.h"
#include "constants/songs.h"
#include "constants/map_objects.h"
#include "constants/map_types.h"
static void task08_080C9820(u8 taskId);
static void sub_80C98FC(u8 taskId);
+2 -1
View File
@@ -42,6 +42,7 @@
#include "constants/maps.h"
#include "constants/moves.h"
#include "constants/songs.h"
#include "constants/map_types.h"
EWRAM_DATA void (*sItemUseOnFieldCB)(u8 taskId) = NULL;
@@ -259,7 +260,7 @@ bool8 ItemUseCheckFunc_Rod(void)
{
if (MetatileBehavior_IsSurfable(behavior) && !MapGridIsImpassableAt(x, y))
return TRUE;
if (MetatileBehavior_ReturnFalse_6(behavior) == TRUE)
if (MetatileBehavior_IsBridge(behavior) == TRUE)
return TRUE;
}
return FALSE;
+6 -6
View File
@@ -69,7 +69,7 @@ bool8 MetatileBehavior_IsMB21OrSand(u8 metatileBehavior)
return FALSE;
}
bool8 MetatileBehavior_IsMB21OrWaterfallBottom(u8 metatileBehavior)
bool8 MetatileBehavior_IsSandOrDeepSand(u8 metatileBehavior)
{
if(metatileBehavior == MB_21 || metatileBehavior == MB_WATERFALL_BOTTOM)
return TRUE;
@@ -428,11 +428,11 @@ bool8 MetatileBehavior_IsTallGrass_2(u8 metatileBehavior)
return FALSE;
}
bool8 MetatileBehavior_ReturnFalse_3(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_IsLongGrass(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_ReturnFalse_4(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_ReturnFalse_5(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_ReturnFalse_6(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_ReturnFalse_7(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_IsBridge(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_GetBridgeType(u8 metatileBehavior) { return FALSE; }
bool8 MetatileBehavior_UnusedIsMB_01(u8 metatileBehavior)
{
@@ -450,7 +450,7 @@ bool8 MetatileBehavior_UnusedIsTallGrass(u8 metatileBehavior)
return FALSE;
}
bool8 MetatileBehavior_IsMB0B(u8 metatileBehavior)
bool8 MetatileBehavior_IsIndoorEncounter(u8 metatileBehavior)
{
if(metatileBehavior == MB_0B)
return TRUE;
@@ -458,7 +458,7 @@ bool8 MetatileBehavior_IsMB0B(u8 metatileBehavior)
return FALSE;
}
bool8 MetatileBehavior_IsMB0C(u8 metatileBehavior)
bool8 MetatileBehavior_IsMountain(u8 metatileBehavior)
{
if(metatileBehavior == MB_0C)
return TRUE;
+2 -2
View File
@@ -47,7 +47,7 @@ const struct SpriteTemplate gUnknown_83E6DF8 =
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gUnknown_83E6DF4,
.callback = sub_8075D9C,
.callback = AnimSparklingParticle,
};
const struct SpriteTemplate gUnknown_83E6E10 =
@@ -376,7 +376,7 @@ const struct SpriteTemplate gUnknown_83E7148 =
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gUnknown_83E7144,
.callback = sub_8075D9C,
.callback = AnimSparklingParticle,
};
static const union AffineAnimCmd gUnknown_83E7160[] =
+2 -2
View File
@@ -88,7 +88,7 @@ void sub_8150530(void)
else
{
sub_81507BC(mapObject, sub_805C808(4));
StartSpriteAnim(sprite, sub_80634F0(mapObject->mapobj_unk_18));
StartSpriteAnim(sprite, sub_80634F0(mapObject->facingDirection));
}
}
@@ -103,7 +103,7 @@ void sub_81505C4(u8 taskId)
FieldObjectClearAnimIfSpecialAnimActive(mapObject);
mapObject->mapobj_bit_11 = TRUE;
sub_81507BC(mapObject, sub_805C808(4));
StartSpriteAnim(sprite, sub_80634F0(mapObject->mapobj_unk_18));
StartSpriteAnim(sprite, sub_80634F0(mapObject->facingDirection));
gTasks[taskId].data[0]++;
gTasks[taskId].data[1] = 0;
break;
+1 -1
View File
@@ -1916,7 +1916,7 @@ bool8 ScrCmd_checktrainerflag(struct ScriptContext *ctx)
{
u16 index = VarGet(ScriptReadHalfword(ctx));
ctx->comparisonResult = HasTrainerAlreadyBeenFought(index);
ctx->comparisonResult = HasTrainerBeenFought(index);
return FALSE;
}
+1 -1
View File
@@ -78,7 +78,7 @@ void sub_815A008(struct QuestLog * questLog)
questLog->unk_008[i].mapobj_bit_24 = gMapObjects[i].mapobj_bit_24;
questLog->unk_008[i].mapobj_bit_25 = gMapObjects[i].mapobj_bit_25;
questLog->unk_008[i].mapobj_bit_26 = gMapObjects[i].mapobj_bit_26;
questLog->unk_008[i].mapobj_unk_18 = gMapObjects[i].mapobj_unk_18;
questLog->unk_008[i].mapobj_unk_18 = gMapObjects[i].facingDirection;
questLog->unk_008[i].mapobj_unk_0B_0 = gMapObjects[i].mapobj_unk_0B_0;
questLog->unk_008[i].elevation = gMapObjects[i].elevation;
questLog->unk_008[i].graphicsId = gMapObjects[i].graphicsId;
+8 -8
View File
@@ -928,7 +928,7 @@ static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
if (IsTrainerVisibleOnScreen(&sVsSeeker->trainerInfo[vsSeekerIdx]) == 1)
{
r8 = sVsSeeker->trainerInfo[vsSeekerIdx].trainerIdx;
if (!HasTrainerAlreadyBeenFought(r8))
if (!HasTrainerBeenFought(r8))
{
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], gUnknown_8453F60);
sVsSeeker->trainerHasNotYetBeenFought = 1;
@@ -1024,7 +1024,7 @@ static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
"\tadds r0, r5\n"
"\tldrh r0, [r0, 0x4]\n"
"\tmov r8, r0\n"
"\tbl HasTrainerAlreadyBeenFought\n"
"\tbl HasTrainerBeenFought\n"
"\tlsls r0, 24\n"
"\tcmp r0, 0\n"
"\tbne _0810CA20\n"
@@ -1236,10 +1236,10 @@ void sub_810CB90(void)
TryGetFieldObjectIdByLocalIdAndMap(r4[r8].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &sp0);
r4_2 = &gMapObjects[sp0];
sub_810CF54(&r4[r8]); // You are using this function incorrectly. Please consult the manual.
sub_805FE7C(r4_2, gUnknown_8453F67[r4_2->mapobj_unk_18]);
sub_805FE7C(r4_2, gUnknown_8453F67[r4_2->facingDirection]);
gSaveBlock1Ptr->trainerRematches[r4[r8].localId] = 0;
if (gSelectedEventObject == sp0)
r4_2->animPattern = gUnknown_8453F67[r4_2->mapobj_unk_18];
r4_2->animPattern = gUnknown_8453F67[r4_2->facingDirection];
else
r4_2->animPattern = 0x08;
}
@@ -1316,7 +1316,7 @@ static bool8 HasRematchTrainerAlreadyBeenFought(const VsSeekerData *vsSeekerData
if (rematchIdx == -1)
return FALSE;
if (!HasTrainerAlreadyBeenFought(vsSeekerData[rematchIdx].trainerIdxs[0]))
if (!HasTrainerBeenFought(vsSeekerData[rematchIdx].trainerIdxs[0]))
return FALSE;
return TRUE;
}
@@ -1350,7 +1350,7 @@ static s32 sub_810CE10(const VsSeekerData * a0, u16 a1)
return -1;
}
s32 sub_810CE64(u16 a0)
s32 GetRematchTrainerId(u16 a0)
{
u8 i;
u8 j;
@@ -1526,7 +1526,7 @@ static u8 GetNextAvailableRematchTrainer(const VsSeekerData * vsSeekerData, u16
return j - 1;
if (vsSeekerData[i].trainerIdxs[j] == 0xffff)
continue;
if (HasTrainerAlreadyBeenFought(vsSeekerData[i].trainerIdxs[j]))
if (HasTrainerBeenFought(vsSeekerData[i].trainerIdxs[j]))
continue;
return j;
}
@@ -1547,7 +1547,7 @@ static u8 GetRematchableTrainerLocalId(void)
{
if (IsTrainerVisibleOnScreen(&sVsSeeker->trainerInfo[i]) == 1)
{
if (HasTrainerAlreadyBeenFought(sVsSeeker->trainerInfo[i].trainerIdx) != 1 || GetNextAvailableRematchTrainer(sVsSeekerData, sVsSeeker->trainerInfo[i].trainerIdx, &idx))
if (HasTrainerBeenFought(sVsSeeker->trainerInfo[i].trainerIdx) != 1 || GetNextAvailableRematchTrainer(sVsSeekerData, sVsSeeker->trainerInfo[i].trainerIdx, &idx))
return sVsSeeker->trainerInfo[i].localId;
}
}
+2 -29
View File
@@ -327,35 +327,8 @@ gUnknown_20386A4: @ 20386A4
gUnknown_20386A8: @ 20386A8
.space 0x4
sTrainerBattleMode: @ 20386AC
.space 0x2
gTrainerBattleOpponent_A: @ 20386AE
.space 0x2
sTrainerEventObjectLocalId: @ 20386B0
.space 0x4
sTrainerAIntroSpeech: @ 20386B4
.space 0x4
sTrainerADefeatSpeech: @ 20386B8
.space 0x4
sTrainerBDefeatSpeech: @ 20386BC
.space 0x4
sTrainerCannotBattleSpeech: @ 20386C0
.space 0x4
sTrainerBattleEndScript: @ 20386C4
.space 0x4
sTrainerABattleScriptRetAddr: @ 20386C8
.space 0x4
gUnknown_20386CC: @ 20386CC
.space 0x4
.include "src/battle_setup.o"
.align 2
gUnknown_20386D0: @ 20386D0
.space 0xC