diff options
Diffstat (limited to 'src/battle_main.c')
-rw-r--r-- | src/battle_main.c | 228 |
1 files changed, 213 insertions, 15 deletions
diff --git a/src/battle_main.c b/src/battle_main.c index 78b69212d..70eebed85 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -81,7 +81,6 @@ extern struct MusicPlayerInfo gMPlayInfo_SE1; extern struct MusicPlayerInfo gMPlayInfo_SE2; extern u8 gUnknown_0203CF00[]; -extern const struct BattleMove gBattleMoves[]; extern const u16 gBattleTextboxPalette[]; // battle textbox palette extern const struct BgTemplate gUnknown_0831AA08[]; extern const struct WindowTemplate * const gUnknown_0831ABA0[]; @@ -95,12 +94,8 @@ extern const struct ScanlineEffectParams gUnknown_0831AC70; // strings extern const u8 gText_LinkStandby3[]; -extern const u8 gText_RecordBattleToPass[]; -extern const u8 gText_BattleYesNoChoice[]; extern const u8 gText_BattleRecordCouldntBeSaved[]; -extern const u8 gText_BattleRecordedOnPass[]; extern const u8 gText_ShedinjaJapaneseName[]; -extern const u8 gText_EmptyString3[]; extern const u8 gText_Poison[]; extern const u8 gText_Sleep[]; extern const u8 gText_Paralysis[]; @@ -301,6 +296,214 @@ u8 gNumberOfMovesToChoose; u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; // rom const data + +// format: attacking type, defending type, damage multiplier +// the multiplier is a (decimal) fixed-point number: +// 20 is ×2.0 TYPE_MUL_SUPER_EFFECTIVE +// 10 is ×1.0 TYPE_MUL_NORMAL +// 05 is ×0.5 TYPE_MUL_NOT_EFFECTIVE +// 00 is ×0.0 TYPE_MUL_NO_EFFECT +const u8 gTypeEffectiveness[336] = +{ + TYPE_NORMAL, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE, + TYPE_NORMAL, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIRE, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIRE, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIRE, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FIRE, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FIRE, TYPE_BUG, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FIRE, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIRE, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIRE, TYPE_STEEL, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_WATER, TYPE_FIRE, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_WATER, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE, + TYPE_WATER, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE, + TYPE_WATER, TYPE_GROUND, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_WATER, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_WATER, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ELECTRIC, TYPE_WATER, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ELECTRIC, TYPE_ELECTRIC, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ELECTRIC, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ELECTRIC, TYPE_GROUND, TYPE_MUL_NO_EFFECT, + TYPE_ELECTRIC, TYPE_FLYING, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ELECTRIC, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GRASS, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GRASS, TYPE_WATER, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GRASS, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GRASS, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GRASS, TYPE_GROUND, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GRASS, TYPE_FLYING, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GRASS, TYPE_BUG, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GRASS, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GRASS, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GRASS, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ICE, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ICE, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ICE, TYPE_ICE, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ICE, TYPE_GROUND, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ICE, TYPE_FLYING, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ICE, TYPE_DRAGON, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ICE, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ICE, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIGHTING, TYPE_NORMAL, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FIGHTING, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FIGHTING, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIGHTING, TYPE_FLYING, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIGHTING, TYPE_PSYCHIC, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIGHTING, TYPE_BUG, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FIGHTING, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FIGHTING, TYPE_DARK, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FIGHTING, TYPE_STEEL, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_POISON, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_POISON, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_POISON, TYPE_GROUND, TYPE_MUL_NOT_EFFECTIVE, + TYPE_POISON, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE, + TYPE_POISON, TYPE_GHOST, TYPE_MUL_NOT_EFFECTIVE, + TYPE_POISON, TYPE_STEEL, TYPE_MUL_NO_EFFECT, + TYPE_GROUND, TYPE_FIRE, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GROUND, TYPE_ELECTRIC, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GROUND, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GROUND, TYPE_POISON, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GROUND, TYPE_FLYING, TYPE_MUL_NO_EFFECT, + TYPE_GROUND, TYPE_BUG, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GROUND, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GROUND, TYPE_STEEL, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FLYING, TYPE_ELECTRIC, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FLYING, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FLYING, TYPE_FIGHTING, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FLYING, TYPE_BUG, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_FLYING, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FLYING, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_PSYCHIC, TYPE_FIGHTING, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_PSYCHIC, TYPE_POISON, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_PSYCHIC, TYPE_PSYCHIC, TYPE_MUL_NOT_EFFECTIVE, + TYPE_PSYCHIC, TYPE_DARK, TYPE_MUL_NO_EFFECT, + TYPE_PSYCHIC, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_BUG, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE, + TYPE_BUG, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_BUG, TYPE_FIGHTING, TYPE_MUL_NOT_EFFECTIVE, + TYPE_BUG, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE, + TYPE_BUG, TYPE_FLYING, TYPE_MUL_NOT_EFFECTIVE, + TYPE_BUG, TYPE_PSYCHIC, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_BUG, TYPE_GHOST, TYPE_MUL_NOT_EFFECTIVE, + TYPE_BUG, TYPE_DARK, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_BUG, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ROCK, TYPE_FIRE, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ROCK, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ROCK, TYPE_FIGHTING, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ROCK, TYPE_GROUND, TYPE_MUL_NOT_EFFECTIVE, + TYPE_ROCK, TYPE_FLYING, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ROCK, TYPE_BUG, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_ROCK, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GHOST, TYPE_NORMAL, TYPE_MUL_NO_EFFECT, + TYPE_GHOST, TYPE_PSYCHIC, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_GHOST, TYPE_DARK, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GHOST, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_GHOST, TYPE_GHOST, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_DRAGON, TYPE_DRAGON, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_DRAGON, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_DARK, TYPE_FIGHTING, TYPE_MUL_NOT_EFFECTIVE, + TYPE_DARK, TYPE_PSYCHIC, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_DARK, TYPE_GHOST, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_DARK, TYPE_DARK, TYPE_MUL_NOT_EFFECTIVE, + TYPE_DARK, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_STEEL, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE, + TYPE_STEEL, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE, + TYPE_STEEL, TYPE_ELECTRIC, TYPE_MUL_NOT_EFFECTIVE, + TYPE_STEEL, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_STEEL, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE, + TYPE_STEEL, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE, + TYPE_FORESIGHT, TYPE_FORESIGHT, TYPE_MUL_NO_EFFECT, + TYPE_NORMAL, TYPE_GHOST, TYPE_MUL_NO_EFFECT, + TYPE_FIGHTING, TYPE_GHOST, TYPE_MUL_NO_EFFECT, + TYPE_ENDTABLE, TYPE_ENDTABLE, TYPE_MUL_NO_EFFECT +}; + +const u8 gTypeNames[][TYPE_NAME_LENGTH + 1] = +{ + _("NORMAL"), + _("FIGHT"), + _("FLYING"), + _("POISON"), + _("GROUND"), + _("ROCK"), + _("BUG"), + _("GHOST"), + _("STEEL"), + _("???"), + _("FIRE"), + _("WATER"), + _("GRASS"), + _("ELECTR"), + _("PSYCHC"), + _("ICE"), + _("DRAGON"), + _("DARK"), +}; + +// This is a factor in how much money you get for beating a trainer. +const struct TrainerMoney gTrainerMoneyTable[] = +{ + {TRAINER_CLASS_TEAM_AQUA, 5}, + {TRAINER_CLASS_AQUA_ADMIN, 10}, + {TRAINER_CLASS_AQUA_LEADER, 20}, + {TRAINER_CLASS_AROMA_LADY, 10}, + {TRAINER_CLASS_RUIN_MANIAC, 15}, + {TRAINER_CLASS_INTERVIEWER, 12}, + {TRAINER_CLASS_TUBER_1, 1}, + {TRAINER_CLASS_TUBER_2, 1}, + {TRAINER_CLASS_SIS_AND_BRO, 3}, + {TRAINER_CLASS_COOLTRAINER_1, 12}, + {TRAINER_CLASS_HEX_MANIAC, 6}, + {TRAINER_CLASS_LADY, 50}, + {TRAINER_CLASS_BEAUTY, 20}, + {TRAINER_CLASS_RICH_BOY, 50}, + {TRAINER_CLASS_POKEMANIAC, 15}, + {TRAINER_CLASS_SWIMMER_M, 2}, + {TRAINER_CLASS_BLACK_BELT, 8}, + {TRAINER_CLASS_GUITARIST, 8}, + {TRAINER_CLASS_KINDLER, 8}, + {TRAINER_CLASS_CAMPER, 4}, + {TRAINER_CLASS_OLD_COUPLE, 10}, + {TRAINER_CLASS_BUG_MANIAC, 15}, + {TRAINER_CLASS_PSYCHIC, 6}, + {TRAINER_CLASS_GENTLEMAN, 20}, + {TRAINER_CLASS_ELITE_FOUR, 25}, + {TRAINER_CLASS_LEADER, 25}, + {TRAINER_CLASS_SCHOOL_KID, 5}, + {TRAINER_CLASS_SR_AND_JR, 4}, + {TRAINER_CLASS_POKEFAN, 20}, + {TRAINER_CLASS_EXPERT, 10}, + {TRAINER_CLASS_YOUNGSTER, 4}, + {TRAINER_CLASS_CHAMPION, 50}, + {TRAINER_CLASS_FISHERMAN, 10}, + {TRAINER_CLASS_TRIATHLETE, 10}, + {TRAINER_CLASS_DRAGON_TAMER, 12}, + {TRAINER_CLASS_BIRD_KEEPER, 8}, + {TRAINER_CLASS_NINJA_BOY, 3}, + {TRAINER_CLASS_BATTLE_GIRL, 6}, + {TRAINER_CLASS_PARASOL_LADY, 10}, + {TRAINER_CLASS_SWIMMER_F, 2}, + {TRAINER_CLASS_PICNICKER, 4}, + {TRAINER_CLASS_TWINS, 3}, + {TRAINER_CLASS_SAILOR, 8}, + {TRAINER_CLASS_COLLECTOR, 15}, + {TRAINER_CLASS_PKMN_TRAINER_3, 15}, + {TRAINER_CLASS_PKMN_BREEDER, 10}, + {TRAINER_CLASS_PKMN_RANGER, 12}, + {TRAINER_CLASS_TEAM_MAGMA, 5}, + {TRAINER_CLASS_MAGMA_ADMIN, 10}, + {TRAINER_CLASS_MAGMA_LEADER, 20}, + {TRAINER_CLASS_LASS, 4}, + {TRAINER_CLASS_BUG_CATCHER, 4}, + {TRAINER_CLASS_HIKER, 10}, + {TRAINER_CLASS_YOUNG_COUPLE, 8}, + {TRAINER_CLASS_WINSTRATE, 10}, + {0xFF, 5}, +}; + +#include "data/text/abilities.h" + static void (* const sTurnActionsFuncsTable[])(void) = { HandleAction_UseMove, // B_ACTION_USE_MOVE @@ -3387,7 +3590,6 @@ static void BattleIntroOpponent1SendsOutMonAnimation(void) gBattleMainFunc = BattleIntroRecordMonsToDex; } - #else ASM_DIRECT static void BattleIntroOpponent1SendsOutMonAnimation(void) @@ -3474,7 +3676,6 @@ _0803B2F2:\n\ .pool\n\ .syntax divided"); } - #endif // NONMATCHING static void BattleIntroRecordMonsToDex(void) @@ -3835,8 +4036,7 @@ u8 IsRunningFromBattleImpossible(void) } if (side != GetBattlerSide(i) && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE - && gBattleMons[gActiveBattler].type1 != TYPE_FLYING - && gBattleMons[gActiveBattler].type2 != TYPE_FLYING + && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING) && gBattleMons[i].ability == ABILITY_ARENA_TRAP) { gBattleScripting.battler = i; @@ -3846,7 +4046,7 @@ u8 IsRunningFromBattleImpossible(void) } } i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0); - if (i != 0 && (gBattleMons[gActiveBattler].type1 == TYPE_STEEL || gBattleMons[gActiveBattler].type2 == TYPE_STEEL)) + if (i != 0 && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)) { gBattleScripting.battler = i - 1; gLastUsedAbility = gBattleMons[i - 1].ability; @@ -4033,12 +4233,10 @@ static void HandleTurnActionSelectionState(void) } else if ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_SHADOW_TAG, 0, 0)) || ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_ARENA_TRAP, 0, 0)) - && gBattleMons[gActiveBattler].type1 != TYPE_FLYING - && gBattleMons[gActiveBattler].type2 != TYPE_FLYING + && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING) && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE) || ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0)) - && (gBattleMons[gActiveBattler].type1 == TYPE_STEEL - || gBattleMons[gActiveBattler].type2 == TYPE_STEEL))) + && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL))) { BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | 4, 6, gLastUsedAbility, gBattleStruct->field_60[gActiveBattler]); } @@ -5133,7 +5331,7 @@ static void HandleAction_UseMove(void) else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gSideTimers[side].followmeTimer == 0 && (gBattleMoves[gCurrentMove].power != 0 - || gBattleMoves[gCurrentMove].target != MOVE_TARGET_x10) + || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER) && gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) { |