diff options
author | jiangzhengwenjz <jiangzhengwenjzw@qq.com> | 2019-10-21 03:07:59 +0800 |
---|---|---|
committer | jiangzhengwenjz <jiangzhengwenjzw@qq.com> | 2019-10-21 03:08:10 +0800 |
commit | b0400ef6ba6e6cf49ad2bdc19a29eb2abef26701 (patch) | |
tree | 60276257dd8cccfa1278bb0302cf948ae8ab79fa /src | |
parent | e48725d9b54ed9f71f65c3ba5577cffa8f4887d1 (diff) |
battle_setup funcs
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_anim_mons.c | 2 | ||||
-rw-r--r-- | src/battle_script_commands.c | 2 | ||||
-rw-r--r-- | src/battle_setup.c | 974 | ||||
-rw-r--r-- | src/fame_checker.c | 2 | ||||
-rw-r--r-- | src/fldeff_rocksmash.c | 1 | ||||
-rw-r--r-- | src/item_use.c | 3 | ||||
-rw-r--r-- | src/metatile_behavior.c | 12 | ||||
-rw-r--r-- | src/psychic.c | 4 | ||||
-rw-r--r-- | src/quest_log_8150454.c | 4 | ||||
-rw-r--r-- | src/scrcmd.c | 2 | ||||
-rw-r--r-- | src/unk_8159F40.c | 2 | ||||
-rw-r--r-- | src/vs_seeker.c | 16 |
12 files changed, 1000 insertions, 24 deletions
diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c index e871937e7..7bb62af69 100644 --- a/src/battle_anim_mons.c +++ b/src/battle_anim_mons.c @@ -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; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 46120085a..aec6eec8e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -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) diff --git a/src/battle_setup.c b/src/battle_setup.c new file mode 100644 index 000000000..3e06437da --- /dev/null +++ b/src/battle_setup.c @@ -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); +} diff --git a/src/fame_checker.c b/src/fame_checker.c index e803a9700..945b5ffe6 100644 --- a/src/fame_checker.c +++ b/src/fame_checker.c @@ -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; diff --git a/src/fldeff_rocksmash.c b/src/fldeff_rocksmash.c index 56a607fff..90abda81f 100644 --- a/src/fldeff_rocksmash.c +++ b/src/fldeff_rocksmash.c @@ -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); diff --git a/src/item_use.c b/src/item_use.c index 8602d6f72..416edfe88 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -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; diff --git a/src/metatile_behavior.c b/src/metatile_behavior.c index 62a102a09..bca99d38f 100644 --- a/src/metatile_behavior.c +++ b/src/metatile_behavior.c @@ -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; diff --git a/src/psychic.c b/src/psychic.c index 662320a2b..b37820d02 100644 --- a/src/psychic.c +++ b/src/psychic.c @@ -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[] = diff --git a/src/quest_log_8150454.c b/src/quest_log_8150454.c index 3d61dee72..fbd3b4487 100644 --- a/src/quest_log_8150454.c +++ b/src/quest_log_8150454.c @@ -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; diff --git a/src/scrcmd.c b/src/scrcmd.c index ae994fceb..540474a7e 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -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; } diff --git a/src/unk_8159F40.c b/src/unk_8159F40.c index ab27cea63..a9a567c51 100644 --- a/src/unk_8159F40.c +++ b/src/unk_8159F40.c @@ -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; diff --git a/src/vs_seeker.c b/src/vs_seeker.c index 2c339cceb..15dc30234 100644 --- a/src/vs_seeker.c +++ b/src/vs_seeker.c @@ -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; } } |