From 0fefb444debebdd09bbbcdeb9b0a134fc74aadc2 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Fri, 10 Jan 2025 19:07:32 -0300 Subject: [PATCH] Multiple removals of hardcoded move IDs (#5964) --- include/battle_ai_util.h | 3 ++- include/battle_util.h | 4 ++-- include/constants/battle.h | 7 ++++++ src/battle_ai_main.c | 43 ++++++++++++++-------------------- src/battle_ai_switch_items.c | 4 ++-- src/battle_ai_util.c | 41 ++++++++++++++++++++++---------- src/battle_controller_player.c | 15 ++++++------ src/battle_script_commands.c | 4 ++-- src/battle_util.c | 8 +++---- 9 files changed, 72 insertions(+), 57 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 7cfc28e5d6..4a47b63503 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -123,7 +123,7 @@ bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception) bool32 HasMoveThatLowersOwnStats(u32 battlerId); bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool32 ignoreStatus, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect); bool32 HasAnyKnownMove(u32 battlerId); -bool32 IsAromaVeilProtectedMove(u32 move); +bool32 IsAromaVeilProtectedEffect(u32 moveEffect); bool32 IsNonVolatileStatusMoveEffect(u32 moveEffect); bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility); bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move); @@ -182,6 +182,7 @@ bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u32 move, u3 bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u32 partnerMove); bool32 IsMoveEffectWeather(u32 move); bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove); +bool32 PartnerMoveEffectIs(u32 battlerAtkPartner, u32 partnerMove, u32 effectCheck); bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck); bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove); bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove); diff --git a/include/battle_util.h b/include/battle_util.h index 5ab3c3495b..5ab72967dc 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -248,8 +248,8 @@ uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef); uq4_12_t GetTypeModifier(u32 atkType, u32 defType); uq4_12_t GetOverworldTypeEffectiveness(struct Pokemon *mon, u8 moveType); -s32 GetStealthHazardDamage(u8 hazardType, u32 battler); -s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp); +s32 GetStealthHazardDamage(enum TypeSideHazard hazardType, u32 battler); +s32 GetStealthHazardDamageByTypesAndHP(enum TypeSideHazard hazardType, u8 type1, u8 type2, u32 maxHp); bool32 CanMegaEvolve(u32 battler); bool32 CanUltraBurst(u32 battler); void ActivateMegaEvolution(u32 battler); diff --git a/include/constants/battle.h b/include/constants/battle.h index eeccd83144..561d4f81e5 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -253,6 +253,13 @@ #define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL) #define SIDE_STATUS_PLEDGE_ANY (SIDE_STATUS_RAINBOW | SIDE_STATUS_SEA_OF_FIRE | SIDE_STATUS_SWAMP) +// Used for damaging entry hazards based on type +enum TypeSideHazard +{ + TYPE_SIDE_HAZARD_POINTED_STONES = TYPE_ROCK, + TYPE_SIDE_HAZARD_SHARP_STEEL = TYPE_STEEL, +}; + // Field affecting statuses. #define STATUS_FIELD_MAGIC_ROOM (1 << 0) #define STATUS_FIELD_TRICK_ROOM (1 << 1) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 61e27ddb5a..d856fae81f 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -809,7 +809,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_MINUS(10); break; case ABILITY_AROMA_VEIL: - if (IsAromaVeilProtectedMove(move)) + if (IsAromaVeilProtectedEffect(moveEffect)) RETURN_SCORE_MINUS(10); break; case ABILITY_SWEET_VEIL: @@ -902,7 +902,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_MINUS(10); break; case ABILITY_AROMA_VEIL: - if (IsAromaVeilProtectedMove(move)) + if (IsAromaVeilProtectedEffect(moveEffect)) RETURN_SCORE_MINUS(10); break; } @@ -947,12 +947,13 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) weather = AI_GetWeather(aiData); if (weather & B_WEATHER_PRIMAL_ANY) { - switch (move) + switch (moveEffect) { - case MOVE_SUNNY_DAY: - case MOVE_RAIN_DANCE: - case MOVE_HAIL: - case MOVE_SANDSTORM: + case EFFECT_SUNNY_DAY: + case EFFECT_RAIN_DANCE: + case EFFECT_HAIL: + case EFFECT_SNOWSCAPE: + case EFFECT_SANDSTORM: RETURN_SCORE_MINUS(30); } @@ -2020,7 +2021,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); // Don't Fly/dig/etc if opponent is going to fly/dig/etc after you if (BattlerWillFaintFromWeather(battlerAtk, aiData->abilities[battlerAtk]) - && (move == MOVE_FLY || move == MOVE_BOUNCE)) + && GetMoveTwoTurnAttackStatus(move) == STATUS3_ON_AIR) ADJUST_SCORE(-10); // Attacker will faint while in the air break; case EFFECT_HEALING_WISH: //healing wish, lunar dance @@ -2258,7 +2259,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case EFFECT_TRICK_ROOM: - if (PartnerMoveIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, MOVE_TRICK_ROOM)) + if (PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_TRICK_ROOM)) { ADJUST_SCORE(-10); } @@ -2367,17 +2368,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; } case EFFECT_THIRD_TYPE: - switch (move) - { - case MOVE_TRICK_OR_TREAT: - if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST) || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove) || GetActiveGimmick(battlerDef) == GIMMICK_TERA) - ADJUST_SCORE(-10); - break; - case MOVE_FORESTS_CURSE: - if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove) || GetActiveGimmick(battlerDef) == GIMMICK_TERA) - ADJUST_SCORE(-10); - break; - } + if (IS_BATTLER_OF_TYPE(battlerDef, GetMoveArgType(move)) || PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove) || GetActiveGimmick(battlerDef) == GIMMICK_TERA) + ADJUST_SCORE(-10); break; case EFFECT_HEAL_PULSE: // and floral healing if (!IS_TARGETING_PARTNER(battlerAtk, battlerDef)) // Don't heal enemies @@ -2489,7 +2481,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_TAILWIND: if (gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer != 0 - || PartnerMoveIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, MOVE_TAILWIND) + || PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_TAILWIND) || (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 1)) // Trick Room active and not ending this turn ADJUST_SCORE(-10); break; @@ -2566,9 +2558,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_TAKE_HEART: if ((!(gBattleMons[battlerAtk].status1 & STATUS1_ANY) - || PartnerMoveIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, MOVE_JUNGLE_HEALING) - || PartnerMoveIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, MOVE_HEAL_BELL) - || PartnerMoveIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, MOVE_AROMATHERAPY)) + || PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_JUNGLE_HEALING) + || PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_HEAL_BELL)) && !BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPATK) && !BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPDEF)) ADJUST_SCORE(-10); @@ -3893,9 +3884,9 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) break; case EFFECT_FOLLOW_ME: if (isDoubleBattle - && move != MOVE_SPOTLIGHT + && GetMoveTarget(move) == MOVE_TARGET_USER && !IsBattlerIncapacitated(battlerDef, aiData->abilities[battlerDef]) - && (move != MOVE_RAGE_POWDER || IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef])) // Rage Powder doesn't affect powder immunities + && (!IsPowderMove(move) || IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef])) // Rage Powder doesn't affect powder immunities && IsBattlerAlive(BATTLE_PARTNER(battlerAtk))) { u32 predictedMoveOnPartner = gLastMoves[BATTLE_PARTNER(battlerAtk)]; diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 7de2e897a5..8a8fe367ac 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -1283,10 +1283,10 @@ static u32 GetSwitchinHazardsDamage(u32 battler, struct BattlePokemon *battleMon { // Stealth Rock if ((hazardFlags & SIDE_STATUS_STEALTH_ROCK) && heldItemEffect != HOLD_EFFECT_HEAVY_DUTY_BOOTS) - hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_STEALTH_ROCK), defType1, defType2, battleMon->maxHP); + hazardDamage += GetStealthHazardDamageByTypesAndHP(TYPE_SIDE_HAZARD_POINTED_STONES, defType1, defType2, battleMon->maxHP); // G-Max Steelsurge if ((hazardFlags & SIDE_STATUS_STEELSURGE) && heldItemEffect != HOLD_EFFECT_HEAVY_DUTY_BOOTS) - hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_G_MAX_STEELSURGE), defType1, defType2, battleMon->maxHP); + hazardDamage += GetStealthHazardDamageByTypesAndHP(TYPE_SIDE_HAZARD_SHARP_STEEL, defType1, defType2, battleMon->maxHP); // Spikes if ((hazardFlags & SIDE_STATUS_SPIKES) && IsMonGrounded(heldItemEffect, ability, defType1, defType2)) { diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 7b7621d312..7306237de4 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1434,16 +1434,16 @@ u32 AI_GetWeather(struct AiLogicData *aiData) return gBattleWeather; } -bool32 IsAromaVeilProtectedMove(u32 move) +bool32 IsAromaVeilProtectedEffect(u32 moveEffect) { - switch (move) + switch (moveEffect) { - case MOVE_DISABLE: - case MOVE_ATTRACT: - case MOVE_ENCORE: - case MOVE_TORMENT: - case MOVE_TAUNT: - case MOVE_HEAL_BLOCK: + case EFFECT_DISABLE: + case EFFECT_ATTRACT: + case EFFECT_ENCORE: + case EFFECT_TORMENT: + case EFFECT_TAUNT: + case EFFECT_HEAL_BLOCK: return TRUE; default: return FALSE; @@ -1498,8 +1498,9 @@ bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility) if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE) return FALSE; - if (move == MOVE_SKY_DROP - || move == MOVE_SNIPE_SHOT + u32 effect = GetMoveEffect(move); + if (effect == EFFECT_SKY_DROP + || effect == EFFECT_SNIPE_SHOT || atkAbility == ABILITY_PROPELLER_TAIL || atkAbility == ABILITY_STALWART) return TRUE; @@ -2725,7 +2726,7 @@ static bool32 PartyBattlerShouldAvoidHazards(u32 currBattler, u32 switchBattler) u32 ability = GetMonAbility(mon); // we know our own party data u32 holdEffect; u32 species = GetMonData(mon, MON_DATA_SPECIES); - u32 flags = gSideStatuses[GetBattlerSide(currBattler)] & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES); + u32 flags = gSideStatuses[GetBattlerSide(currBattler)] & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STEELSURGE | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES); s32 hazardDamage = 0; u32 type1 = gSpeciesInfo[species].types[0]; u32 type2 = gSpeciesInfo[species].types[1]; @@ -2744,7 +2745,9 @@ static bool32 PartyBattlerShouldAvoidHazards(u32 currBattler, u32 switchBattler) return FALSE; if (flags & SIDE_STATUS_STEALTH_ROCK) - hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_STEALTH_ROCK), type1, type2, maxHp); + hazardDamage += GetStealthHazardDamageByTypesAndHP(TYPE_SIDE_HAZARD_POINTED_STONES, type1, type2, maxHp); + if ((flags & SIDE_STATUS_STEELSURGE)) + hazardDamage += GetStealthHazardDamageByTypesAndHP(TYPE_SIDE_HAZARD_SHARP_STEEL, type1, type2, maxHp); if (flags & SIDE_STATUS_SPIKES && ((type1 != TYPE_FLYING && type2 != TYPE_FLYING && ability != ABILITY_LEVITATE && holdEffect != HOLD_EFFECT_AIR_BALLOON) @@ -3171,7 +3174,7 @@ static u32 FindMoveUsedXTurnsAgo(u32 battlerId, u32 x) bool32 IsWakeupTurn(u32 battler) { // Check if rest was used 2 turns ago - if ((gBattleMons[battler].status1 & STATUS1_SLEEP) == 1 && FindMoveUsedXTurnsAgo(battler, 2) == MOVE_REST) + if ((gBattleMons[battler].status1 & STATUS1_SLEEP) == 1 && GetMoveEffect(FindMoveUsedXTurnsAgo(battler, 2)) == EFFECT_REST) return TRUE; else // no way to know return FALSE; @@ -3431,6 +3434,18 @@ bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove) return FALSE; } +//PARTNER_MOVE_EFFECT_IS +bool32 PartnerMoveEffectIs(u32 battlerAtkPartner, u32 partnerMove, u32 effectCheck) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (partnerMove != MOVE_NONE && GetMoveEffect(partnerMove) == effectCheck) + return TRUE; + + return FALSE; +} + //PARTNER_MOVE_IS_TAILWIND_TRICKROOM bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck) { diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 1eac4dbe26..1e154981dd 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1711,18 +1711,19 @@ static void MoveSelectionDisplayPpNumber(u32 battler) static void MoveSelectionDisplayMoveType(u32 battler) { u8 *txtPtr, *end; - u8 type; u32 speciesId; struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfaceType); - type = GetMoveType(moveInfo->moves[gMoveSelectionCursor[battler]]); + u32 move = moveInfo->moves[gMoveSelectionCursor[battler]]; + u32 type = GetMoveType(move); + u32 effect = GetMoveEffect(move); - if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_TERA_BLAST) + if (effect == EFFECT_TERA_BLAST) { if (IsGimmickSelected(battler, GIMMICK_TERA) || GetActiveGimmick(battler) == GIMMICK_TERA) type = GetBattlerTeraType(battler); } - else if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_IVY_CUDGEL) + else if (effect == EFFECT_IVY_CUDGEL) { speciesId = gBattleMons[battler].species; @@ -1731,12 +1732,12 @@ static void MoveSelectionDisplayMoveType(u32 battler) || speciesId == SPECIES_OGERPON_CORNERSTONE || speciesId == SPECIES_OGERPON_CORNERSTONE_TERA) type = gBattleMons[battler].types[1]; } - else if (GetMoveCategory(moveInfo->moves[gMoveSelectionCursor[battler]]) == DAMAGE_CATEGORY_STATUS + else if (GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS && (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX))) { type = TYPE_NORMAL; // Max Guard is always a Normal-type move } - else if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_TERA_STARSTORM) + else if (effect == EFFECT_TERA_STARSTORM) { if (gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR || (IsGimmickSelected(battler, GIMMICK_TERA) && gBattleMons[battler].species == SPECIES_TERAPAGOS_TERASTAL)) @@ -1745,7 +1746,7 @@ static void MoveSelectionDisplayMoveType(u32 battler) else if (P_SHOW_DYNAMIC_TYPES) // Non-vanilla changes to battle UI showing dynamic types { struct Pokemon *mon = &gPlayerParty[gBattlerPartyIndexes[battler]]; - type = CheckDynamicMoveType(mon, moveInfo->moves[gMoveSelectionCursor[battler]], battler); + type = CheckDynamicMoveType(mon, move, battler); } end = StringCopy(txtPtr, gTypesInfo[type].name); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ba606632f7..536291661a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7755,7 +7755,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) && GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD) { gDisableStructs[battler].stealthRockDone = TRUE; - gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(GetMoveType(MOVE_STEALTH_ROCK), battler); + gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(TYPE_ROCK, battler); if (gBattleStruct->moveDamage[battler] != 0) SetDmgHazardsBattlescript(battler, B_MSG_STEALTHROCKDMG); @@ -7814,7 +7814,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) && GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD) { gDisableStructs[battler].steelSurgeDone = TRUE; - gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(GetMoveType(MOVE_G_MAX_STEELSURGE), battler); + gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(TYPE_STEEL, battler); if (gBattleStruct->moveDamage[battler] != 0) SetDmgHazardsBattlescript(battler, B_MSG_SHARPSTEELDMG); diff --git a/src/battle_util.c b/src/battle_util.c index f7ea083c60..59478ba97e 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10829,14 +10829,14 @@ uq4_12_t GetTypeModifier(u32 atkType, u32 defType) return gTypeEffectivenessTable[atkType][defType]; } -s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp) +s32 GetStealthHazardDamageByTypesAndHP(enum TypeSideHazard hazardType, u8 type1, u8 type2, u32 maxHp) { s32 dmg = 0; uq4_12_t modifier = UQ_4_12(1.0); - modifier = uq4_12_multiply(modifier, GetTypeModifier(hazardType, type1)); + modifier = uq4_12_multiply(modifier, GetTypeModifier((u8)hazardType, type1)); if (type2 != type1) - modifier = uq4_12_multiply(modifier, GetTypeModifier(hazardType, type2)); + modifier = uq4_12_multiply(modifier, GetTypeModifier((u8)hazardType, type2)); switch (modifier) { @@ -10873,7 +10873,7 @@ s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 ma return dmg; } -s32 GetStealthHazardDamage(u8 hazardType, u32 battler) +s32 GetStealthHazardDamage(enum TypeSideHazard hazardType, u32 battler) { u8 type1 = gBattleMons[battler].types[0]; u8 type2 = gBattleMons[battler].types[1];