diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 20071fc36..8c2f95a17 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -143,7 +143,7 @@ .macro jumpifability param0:req, ability:req, ptr:req .byte 0x1e .byte \param0 - .byte \ability + .2byte \ability .4byte \ptr .endm @@ -371,7 +371,7 @@ .macro jumpifabilitypresent ability:req, ptr:req .byte 0x43 - .byte \ability + .2byte \ability .4byte \ptr .endm diff --git a/include/battle.h b/include/battle.h index 6a9ecd89c..8c4b4ac9a 100644 --- a/include/battle.h +++ b/include/battle.h @@ -237,7 +237,7 @@ struct WishFutureKnock struct AI_SavedBattleMon { - u8 ability; + u16 ability; u16 moves[4]; u16 heldItem; u16 species; @@ -267,7 +267,7 @@ struct UsedMoves struct BattleHistory { struct UsedMoves usedMoves[MAX_BATTLERS_COUNT]; - u8 abilities[MAX_BATTLERS_COUNT]; + u16 abilities[MAX_BATTLERS_COUNT]; u8 itemEffects[MAX_BATTLERS_COUNT]; u16 trainerItems[MAX_BATTLERS_COUNT]; u8 itemsNo; @@ -486,7 +486,7 @@ struct BattleStruct u16 lastTakenMove[MAX_BATTLERS_COUNT]; // Last move that a battler was hit with. u16 hpOnSwitchout[2]; u32 savedBattleTypeFlags; - u8 abilityPreventingSwitchout; + u16 abilityPreventingSwitchout; u8 hpScale; u16 synchronizeMoveEffect; bool8 anyMonHasTransformed; @@ -539,7 +539,7 @@ struct BattleStruct u8 lastMoveFailed; // as bits for each battler, for the sake of Stomping Tantrum u8 lastMoveTarget[MAX_BATTLERS_COUNT]; // The last target on which each mon used a move, for the sake of Instruct u8 debugHoldEffects[MAX_BATTLERS_COUNT]; // These override actual items' hold effects. - u8 tracedAbility[MAX_BATTLERS_COUNT]; + u16 tracedAbility[MAX_BATTLERS_COUNT]; u16 hpBefore[MAX_BATTLERS_COUNT]; // Hp of battlers before using a move. For Berserk bool8 spriteIgnore0Hp; struct Illusion illusion[MAX_BATTLERS_COUNT]; @@ -754,7 +754,7 @@ extern s32 gBattleMoveDamage; extern s32 gHpDealt; extern s32 gTakenDmg[MAX_BATTLERS_COUNT]; extern u16 gLastUsedItem; -extern u8 gLastUsedAbility; +extern u16 gLastUsedAbility; extern u8 gBattlerAttacker; extern u8 gBattlerTarget; extern u8 gBattlerFainted; @@ -818,7 +818,7 @@ extern u16 gMoveToLearn; extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; extern u32 gFieldStatuses; extern struct FieldTimer gFieldTimers; -extern u8 gBattlerAbility; +extern u16 gBattlerAbility; extern u16 gPartnerSpriteId; extern void (*gPreBattleCallback1)(void); diff --git a/include/battle_ai_script_commands.h b/include/battle_ai_script_commands.h index 04d580a84..6bca16639 100644 --- a/include/battle_ai_script_commands.h +++ b/include/battle_ai_script_commands.h @@ -18,7 +18,7 @@ bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler); bool32 IsBattlerAIControlled(u32 battlerId); void ClearBattlerMoveHistory(u8 battlerId); void RecordMoveBattle(u8 battlerId, u32 move); -void RecordAbilityBattle(u8 battlerId, u8 abilityId); +void RecordAbilityBattle(u8 battlerId, u16 abilityId); void ClearBattlerAbilityHistory(u8 battlerId); void RecordItemEffectBattle(u8 battlerId, u8 itemEffect); void ClearBattlerItemEffectHistory(u8 battlerId); diff --git a/include/battle_controllers.h b/include/battle_controllers.h index bbaa40ca8..0cf7f6b5a 100644 --- a/include/battle_controllers.h +++ b/include/battle_controllers.h @@ -211,7 +211,7 @@ void BtlController_EmitChooseAction(u8 bufferId, u8 arg1, u16 arg2); void BtlController_EmitUnknownYesNoBox(u8 bufferId); void BtlController_EmitChooseMove(u8 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData); void BtlController_EmitChooseItem(u8 bufferId, u8* arg1); -void BtlController_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 arg2, u8 abilityId, u8* arg4); +void BtlController_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 arg2, u16 abilityId, u8* arg4); void BtlController_EmitCmd23(u8 bufferId); // unused void BtlController_EmitHealthBarUpdate(u8 bufferId, u16 hpValue); void BtlController_EmitExpUpdate(u8 bufferId, u8 partyId, u16 expPoints); diff --git a/include/battle_message.h b/include/battle_message.h index 0236cc793..df9265288 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -103,7 +103,8 @@ textVar[0] = B_BUFF_PLACEHOLDER_BEGIN; \ textVar[1] = B_BUFF_ABILITY; \ textVar[2] = abilityId; \ - textVar[3] = B_BUFF_EOS; \ + textVar[3] = (abilityId & 0xFF00) >> 8; \ + textVar[4] = B_BUFF_EOS; \ } #define PREPARE_TYPE_BUFFER(textVar, typeId) \ @@ -207,13 +208,13 @@ struct BattleMsgData u16 currentMove; u16 originallyUsedMove; u16 lastItem; - u8 lastAbility; + u16 lastAbility; u8 scrActive; u8 unk1605E; u8 hpScale; u8 itemEffectBattler; u8 moveType; - u8 abilities[MAX_BATTLERS_COUNT]; + u16 abilities[MAX_BATTLERS_COUNT]; u8 textBuffs[3][TEXT_BUFF_ARRAY_COUNT]; }; diff --git a/include/battle_util.h b/include/battle_util.h index 71a485d35..54f86b3af 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -77,7 +77,7 @@ u8 AtkCanceller_UnableToUseMove2(void); bool8 HasNoMonsToSwitch(u8 battlerId, u8 r1, u8 r2); u8 TryWeatherFormChange(u8 battlerId); bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility); -u8 AbilityBattleEffects(u8 caseID, u8 battlerId, u8 ability, u8 special, u16 moveArg); +u8 AbilityBattleEffects(u8 caseID, u8 battlerId, u16 ability, u8 special, u16 moveArg); u32 GetBattlerAbility(u8 battlerId); u32 IsAbilityOnSide(u32 battlerId, u32 ability); u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability); @@ -102,7 +102,7 @@ u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move); u32 GetBattlerWeight(u8 battlerId); s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags); u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities); -u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 abilityDef); +u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef); u16 GetTypeModifier(u8 atkType, u8 defType); s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId); u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId); diff --git a/include/constants/abilities.h b/include/constants/abilities.h index fdb5233f0..321446153 100644 --- a/include/constants/abilities.h +++ b/include/constants/abilities.h @@ -255,6 +255,35 @@ #define ABILITIES_COUNT_GEN7 235 -#define ABILITIES_COUNT ABILITIES_COUNT_GEN7 +// Gen 8 +#define ABILITY_INTREPID_SWORD 235 +#define ABILITY_DAUNTLESS_SHIELD 236 +#define ABILITY_LIBERO 237 +#define ABILITY_BALL_FETCH 238 +#define ABILITY_COTTON_DOWN 239 +#define ABILITY_PROPELLER_TAIL 240 +#define ABILITY_MIRROR_ARMOR 241 +#define ABILITY_GULP_MISSILE 242 +#define ABILITY_STALWART 243 +#define ABILITY_STEAM_ENGINE 244 +#define ABILITY_PUNK_ROCK 245 +#define ABILITY_SAND_SPIT 246 +#define ABILITY_ICE_SCALES 247 +#define ABILITY_RIPEN 248 +#define ABILITY_ICE_FACE 249 +#define ABILITY_POWER_SPOT 250 +#define ABILITY_MIMICRY 251 +#define ABILITY_SCREEN_CLEANER 252 +#define ABILITY_STEELY_SPIRIT 253 +#define ABILITY_PERISH_BODY 254 +#define ABILITY_WANDERING_SPIRIT 255 +#define ABILITY_GORILLA_TACTICS 256 +#define ABILITY_NEUTRALIZING_GAS 257 +#define ABILITY_PASTEL_VEIL 258 +#define ABILITY_HUNGER_SWITCH 259 + +#define ABILITIES_COUNT_GEN8 260 + +#define ABILITIES_COUNT ABILITIES_COUNT_GEN8 #endif // GUARD_CONSTANTS_ABILITIES_H diff --git a/include/pokemon.h b/include/pokemon.h index 61647eff8..46ccf50d6 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -152,24 +152,24 @@ struct BattlePokemon /*0x17*/ u32 spDefenseIV:5; /*0x17*/ u32 abilityNum:2; /*0x18*/ s8 statStages[NUM_BATTLE_STATS]; - /*0x20*/ u8 ability; - /*0x21*/ u8 type1; - /*0x22*/ u8 type2; - /*0x23*/ u8 type3; - /*0x24*/ u8 pp[MAX_MON_MOVES]; - /*0x28*/ u16 hp; - /*0x2A*/ u8 level; - /*0x2B*/ u8 friendship; - /*0x2C*/ u16 maxHP; - /*0x2E*/ u16 item; - /*0x30*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; - /*0x3B*/ u8 ppBonuses; - /*0x3C*/ u8 otName[PLAYER_NAME_LENGTH + 1]; - /*0x44*/ u32 experience; - /*0x48*/ u32 personality; - /*0x4C*/ u32 status1; - /*0x50*/ u32 status2; - /*0x54*/ u32 otId; + /*0x20*/ u16 ability; + /*0x22*/ u8 type1; + /*0x23*/ u8 type2; + /*0x24*/ u8 type3; + /*0x25*/ u8 pp[MAX_MON_MOVES]; + /*0x29*/ u16 hp; + /*0x2B*/ u8 level; + /*0x2C*/ u8 friendship; + /*0x2D*/ u16 maxHP; + /*0x2F*/ u16 item; + /*0x31*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; + /*0x3C*/ u8 ppBonuses; + /*0x3D*/ u8 otName[PLAYER_NAME_LENGTH + 1]; + /*0x45*/ u32 experience; + /*0x49*/ u32 personality; + /*0x4D*/ u32 status1; + /*0x51*/ u32 status2; + /*0x55*/ u32 otId; }; struct BaseStats @@ -198,9 +198,9 @@ struct BaseStats /* 0x13 */ u8 growthRate; /* 0x14 */ u8 eggGroup1; /* 0x15 */ u8 eggGroup2; - /* 0x16 */ u8 abilities[2]; - /* 0x18 */ u8 safariZoneFleeRate; - /* 0x19 */ u8 bodyColor : 7; + /* 0x16 */ u16 abilities[2]; + /* 0x1A */ u8 safariZoneFleeRate; + /* 0x1B */ u8 bodyColor : 7; u8 noFlip : 1; }; @@ -326,8 +326,8 @@ u8 CalculatePlayerPartyCount(void); u8 CalculateEnemyPartyCount(void); u8 GetMonsStateToDoubles(void); u8 GetMonsStateToDoubles_2(void); -u8 GetAbilityBySpecies(u16 species, u8 abilityNum); -u8 GetMonAbility(struct Pokemon *mon); +u16 GetAbilityBySpecies(u16 species, u8 abilityNum); +u16 GetMonAbility(struct Pokemon *mon); void CreateSecretBaseEnemyParty(struct SecretBase *secretBaseRecord); u8 GetSecretBaseTrainerPicIndex(void); u8 GetSecretBaseTrainerClass(void); diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c index 6247df4bc..30740c47e 100644 --- a/src/battle_ai_script_commands.c +++ b/src/battle_ai_script_commands.c @@ -774,7 +774,7 @@ void RecordMoveBattle(u8 battlerId, u32 move) } } -void RecordAbilityBattle(u8 battlerId, u8 abilityId) +void RecordAbilityBattle(u8 battlerId, u16 abilityId) { BATTLE_HISTORY->abilities[battlerId] = abilityId; } diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 2eaf0e2e3..1ed5d03c7 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -138,7 +138,7 @@ static bool8 ShouldSwitchIfWonderGuard(void) static bool8 FindMonThatAbsorbsOpponentsMove(void) { u8 battlerIn1, battlerIn2; - u8 absorbingTypeAbility; + u16 absorbingTypeAbility; s32 firstId; s32 lastId; // + 1 struct Pokemon *party; @@ -189,7 +189,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void) for (i = firstId; i < lastId; i++) { u16 species; - u8 monAbility; + u16 monAbility; if (GetMonData(&party[i], MON_DATA_HP) == 0) continue; @@ -370,7 +370,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent) for (i = firstId; i < lastId; i++) { u16 species; - u8 monAbility; + u16 monAbility; if (GetMonData(&party[i], MON_DATA_HP) == 0) continue; diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 3bf255776..0d93a574a 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -2703,7 +2703,7 @@ static void PlayerHandleChoosePokemon(void) gTasks[gUnknown_03005D7C[gActiveBattler]].data[0] = gBattleResources->bufferA[gActiveBattler][1] & 0xF; *(&gBattleStruct->battlerPreventingSwitchout) = gBattleResources->bufferA[gActiveBattler][1] >> 4; *(&gBattleStruct->field_8B) = gBattleResources->bufferA[gActiveBattler][2]; - *(&gBattleStruct->abilityPreventingSwitchout) = gBattleResources->bufferA[gActiveBattler][3]; + *(&gBattleStruct->abilityPreventingSwitchout) = (gBattleResources->bufferA[gActiveBattler][3] & 0xFF) | (gBattleResources->bufferA[gActiveBattler][7] << 8); BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK); gBattlerControllerFuncs[gActiveBattler] = OpenPartyMenuToChooseMon; gBattlerInMenuId = gActiveBattler; diff --git a/src/battle_controllers.c b/src/battle_controllers.c index fdcd98aed..4c3b55e4c 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -1186,14 +1186,15 @@ void BtlController_EmitChooseItem(u8 bufferId, u8 *arg1) PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } -void BtlController_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 slotId, u8 abilityId, u8 *arg4) +void BtlController_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 slotId, u16 abilityId, u8 *arg4) { s32 i; sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEPOKEMON; sBattleBuffersTransferData[1] = caseId; sBattleBuffersTransferData[2] = slotId; - sBattleBuffersTransferData[3] = abilityId; + sBattleBuffersTransferData[3] = abilityId & 0xFF; + sBattleBuffersTransferData[7] = (abilityId >> 8) & 0xFF; for (i = 0; i < 3; i++) sBattleBuffersTransferData[4 + i] = arg4[i]; PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 8); // Only 7 bytes were written. diff --git a/src/battle_debug.c b/src/battle_debug.c index 4b86b9963..1568c333c 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -1436,10 +1436,10 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) { case LIST_ITEM_ABILITY: data->modifyArrows.minValue = 0; - data->modifyArrows.maxValue = ABILITIES_COUNT_GEN7 - 1; + data->modifyArrows.maxValue = ABILITIES_COUNT_GEN8 - 1; data->modifyArrows.maxDigits = 3; data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].ability; - data->modifyArrows.typeOfVal = VAL_U8; + data->modifyArrows.typeOfVal = VAL_U16; data->modifyArrows.currValue = gBattleMons[data->battlerId].ability; break; case LIST_ITEM_MOVES: diff --git a/src/battle_main.c b/src/battle_main.c index 29194b889..645e6cd56 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -181,7 +181,7 @@ EWRAM_DATA s32 gBattleMoveDamage = 0; EWRAM_DATA s32 gHpDealt = 0; EWRAM_DATA s32 gTakenDmg[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gLastUsedItem = 0; -EWRAM_DATA u8 gLastUsedAbility = 0; +EWRAM_DATA u16 gLastUsedAbility = 0; EWRAM_DATA u8 gBattlerAttacker = 0; EWRAM_DATA u8 gBattlerTarget = 0; EWRAM_DATA u8 gBattlerFainted = 0; @@ -245,7 +245,7 @@ EWRAM_DATA u16 gMoveToLearn = 0; EWRAM_DATA u8 gBattleMonForms[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u32 gFieldStatuses = 0; EWRAM_DATA struct FieldTimer gFieldTimers = {0}; -EWRAM_DATA u8 gBattlerAbility = 0; +EWRAM_DATA u16 gBattlerAbility = 0; EWRAM_DATA u16 gPartnerSpriteId = 0; // IWRAM common vars diff --git a/src/battle_message.c b/src/battle_message.c index 29eaf12ec..dd99c2c5c 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -49,7 +49,7 @@ static void ChooseTypeOfMoveUsedString(u8 *dst); static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst); // EWRAM vars -static EWRAM_DATA u8 sBattlerAbilities[MAX_BATTLERS_COUNT] = {0}; +static EWRAM_DATA u16 sBattlerAbilities[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA struct BattleMsgData *gBattleMsgDataPtr = NULL; // const rom data @@ -3320,7 +3320,7 @@ static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst) break; case B_BUFF_ABILITY: // ability names StringAppend(dst, gAbilityNames[src[srcID + 1]]); - srcID += 2; + srcID += 3; break; case B_BUFF_ITEM: // item name hword = T1_READ_16(&src[srcID + 1]); diff --git a/src/battle_pike.c b/src/battle_pike.c index 6b31419a5..edcbc4e40 100644 --- a/src/battle_pike.c +++ b/src/battle_pike.c @@ -811,7 +811,7 @@ static void HealMon(struct Pokemon *mon) static bool8 DoesAbilityPreventStatus(struct Pokemon *mon, u32 status) { - u8 ability = GetMonAbility(mon); + u16 ability = GetMonAbility(mon); bool8 ret = FALSE; switch (status) @@ -1626,7 +1626,7 @@ static bool8 CanEncounterWildMon(u8 enemyMonLevel) { if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) { - u8 monAbility = GetMonAbility(&gPlayerParty[0]); + u16 monAbility = GetMonAbility(&gPlayerParty[0]); if (monAbility == ABILITY_KEEN_EYE || monAbility == ABILITY_INTIMIDATE) { u8 playerMonLevel = GetMonData(&gPlayerParty[0], MON_DATA_LEVEL); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 5faadb24e..a8464532a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3248,7 +3248,7 @@ static void Cmd_jumpifability(void) { u32 battlerId; bool32 hasAbility = FALSE; - u32 ability = gBattlescriptCurrInstr[2]; + u32 ability = T2_READ_16(gBattlescriptCurrInstr + 2); switch (gBattlescriptCurrInstr[1]) { @@ -3278,13 +3278,13 @@ static void Cmd_jumpifability(void) if (hasAbility) { gLastUsedAbility = ability; - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 4); RecordAbilityBattle(battlerId, gLastUsedAbility); gBattlerAbility = battlerId; } else { - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr += 8; } } @@ -4187,10 +4187,10 @@ static void Cmd_setroost(void) static void Cmd_jumpifabilitypresent(void) { - if (IsAbilityOnField(gBattlescriptCurrInstr[1])) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + if (IsAbilityOnField(T1_READ_16(gBattlescriptCurrInstr + 1))) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); else - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr += 7; } static void Cmd_endselectionscript(void) @@ -9939,7 +9939,7 @@ static void Cmd_healpartystatus(void) if (species != SPECIES_NONE && species != SPECIES_EGG) { - u8 ability; + u16 ability; if (gBattlerPartyIndexes[gBattlerAttacker] == i) ability = gBattleMons[gBattlerAttacker].ability; @@ -10942,7 +10942,7 @@ static void Cmd_tryswapabilities(void) // skill swap } else { - u8 abilityAtk = gBattleMons[gBattlerAttacker].ability; + u16 abilityAtk = gBattleMons[gBattlerAttacker].ability; gBattleMons[gBattlerAttacker].ability = gBattleMons[gBattlerTarget].ability; gBattleMons[gBattlerTarget].ability = abilityAtk; @@ -11197,7 +11197,7 @@ static void Cmd_pickup(void) { s32 i; u16 species, heldItem; - u8 ability; + u16 ability; u8 lvlDivBy10; if (InBattlePike()) diff --git a/src/battle_util.c b/src/battle_util.c index 86de71de3..34e4d9bbd 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2845,7 +2845,7 @@ static u8 ForewarnChooseMove(u32 battler) free(data); } -u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveArg) +u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 moveArg) { u8 effect = 0; u32 speciesAtk, speciesDef; @@ -6510,7 +6510,7 @@ u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 bat return modifier; } -u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 abilityDef) +u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef) { u16 modifier = UQ_4_12(1.0); u8 moveType = gBattleMoves[move].type; diff --git a/src/data/text/abilities.h b/src/data/text/abilities.h index 11b6ffaf7..182a33536 100644 --- a/src/data/text/abilities.h +++ b/src/data/text/abilities.h @@ -221,8 +221,33 @@ static const u8 sMistySurgeDescription[] = _("Field becomes misty."); static const u8 sGrassySurgeDescription[] = _("Field becomes grassy."); static const u8 sFullMetalBodyDescription[] = _("Prevents stat reduction."); static const u8 sNeuroforceDescription[] = _("Ups “super effective.“."); +static const u8 sIntrepidSwordDescription[] = _("Ups Attack on entry."); +static const u8 sDauntlessShieldDescription[] = _("Ups Defense on entry."); +static const u8 sLiberoDescription[] = _("Changes type to match move."); +static const u8 sBallFetchDescription[] = _("Fetches first failed Poké Ball."); +static const u8 sCottonDownDescription[] = _("Lowers everyone's Speed when hit."); +static const u8 sPropellerTailDescription[] = _("Moves ignore redirection."); +static const u8 sMirrorArmorDescription[] = _("Bounces back stat decreases."); +static const u8 sGulpMissileDescription[] = _("Spits prey if damaged after a swim."); +static const u8 sStalwartDescription[] = _("Moves ignore redirection."); +static const u8 sSteamEngineDescription[] = _("Fire and Water hits boost Speed."); +static const u8 sPunkRockDescription[] = _("Ups and resists sound moves."); +static const u8 sSandSpitDescription[] = _("Creates a sandstorm when hit."); +static const u8 sIceScalesDescription[] = _("Halves special damage."); +static const u8 sRipenDescription[] = _("Doubles Berry effects."); +static const u8 sIceFaceDescription[] = _("Takes one free physical hit."); +static const u8 sPowerSpotDescription[] = _("Powers up ally moves."); +static const u8 sMimicryDescription[] = _("Changes type with terrain."); +static const u8 sScreenCleanerDescription[] = _("Screens are removed on entry."); +static const u8 sSteelySpiritDescription[] = _("Boosts ally Steel moves."); +static const u8 sPerishBodyDescription[] = _("Gives a perish count on contact."); +static const u8 sWanderingSpiritDescription[] = _("Trades Abilities on contact."); +static const u8 sGorillaTacticsDescription[] = _("Ups Attack, but allows one move."); +static const u8 sNeutralizingGasDescription[] = _("All Abilities are nullified."); +static const u8 sPastelVeilDescription[] = _("Protects team from poison."); +static const u8 sHungerSwitchDescription[] = _("Changes form each turn."); -const u8 gAbilityNames[ABILITIES_COUNT_GEN7][ABILITY_NAME_LENGTH + 1] = +const u8 gAbilityNames[ABILITIES_COUNT_GEN8][ABILITY_NAME_LENGTH + 1] = { [ABILITY_NONE] = _("-------"), [ABILITY_STENCH] = _("Stench"), @@ -459,9 +484,34 @@ const u8 gAbilityNames[ABILITIES_COUNT_GEN7][ABILITY_NAME_LENGTH + 1] = [ABILITY_SHADOW_SHIELD] = _("ShadowShield"), [ABILITY_PRISM_ARMOR] = _("Prism Armor"), [ABILITY_NEUROFORCE] = _("Neuroforce"), + [ABILITY_INTREPID_SWORD] = _("IntrepidSwor"), + [ABILITY_DAUNTLESS_SHIELD] = _("DauntlessShi"), + [ABILITY_LIBERO] = _("Libero"), + [ABILITY_BALL_FETCH] = _("Ball Fetch"), + [ABILITY_COTTON_DOWN] = _("Cotton Down"), + [ABILITY_PROPELLER_TAIL] = _("PropellerTai"), + [ABILITY_MIRROR_ARMOR] = _("Mirror Armor"), + [ABILITY_GULP_MISSILE] = _("Gulp Missile"), + [ABILITY_STALWART] = _("Stalwart"), + [ABILITY_STEAM_ENGINE] = _("Steam Engine"), + [ABILITY_PUNK_ROCK] = _("Punk Rock"), + [ABILITY_SAND_SPIT] = _("Sand Spit"), + [ABILITY_ICE_SCALES] = _("Ice Scales"), + [ABILITY_RIPEN] = _("Ripen"), + [ABILITY_ICE_FACE] = _("Ice Face"), + [ABILITY_POWER_SPOT] = _("Power Spot"), + [ABILITY_MIMICRY] = _("Mimicry"), + [ABILITY_SCREEN_CLEANER] = _("ScreenCleane"), + [ABILITY_STEELY_SPIRIT] = _("SteelySpirit"), + [ABILITY_PERISH_BODY] = _("Perish Body"), + [ABILITY_WANDERING_SPIRIT] = _("WanderingSpi"), + [ABILITY_GORILLA_TACTICS] = _("GorillaTacti"), + [ABILITY_NEUTRALIZING_GAS] = _("Neutralizing"), + [ABILITY_PASTEL_VEIL] = _("Pastel Veil"), + [ABILITY_HUNGER_SWITCH] = _("HungerSwitch"), }; -const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT_GEN7] = +const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT_GEN8] = { [ABILITY_NONE] = sNoneDescription, [ABILITY_STENCH] = sStenchDescription, @@ -698,4 +748,29 @@ const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT_GEN7] = [ABILITY_SHADOW_SHIELD] = sMultiscaleDescription, [ABILITY_PRISM_ARMOR] = sFilterDescription, [ABILITY_NEUROFORCE] = sNeuroforceDescription, + [ABILITY_INTREPID_SWORD] = sIntrepidSwordDescription, + [ABILITY_DAUNTLESS_SHIELD] = sDauntlessShieldDescription, + [ABILITY_LIBERO] = sLiberoDescription, + [ABILITY_BALL_FETCH] = sBallFetchDescription, + [ABILITY_COTTON_DOWN] = sCottonDownDescription, + [ABILITY_PROPELLER_TAIL] = sPropellerTailDescription, + [ABILITY_MIRROR_ARMOR] = sMirrorArmorDescription, + [ABILITY_GULP_MISSILE] = sGulpMissileDescription, + [ABILITY_STALWART] = sStalwartDescription, + [ABILITY_STEAM_ENGINE] = sSteamEngineDescription, + [ABILITY_PUNK_ROCK] = sPunkRockDescription, + [ABILITY_SAND_SPIT] = sSandSpitDescription, + [ABILITY_ICE_SCALES] = sIceScalesDescription, + [ABILITY_RIPEN] = sRipenDescription, + [ABILITY_ICE_FACE] = sIceFaceDescription, + [ABILITY_POWER_SPOT] = sPowerSpotDescription, + [ABILITY_MIMICRY] = sMimicryDescription, + [ABILITY_SCREEN_CLEANER] = sScreenCleanerDescription, + [ABILITY_STEELY_SPIRIT] = sSteelySpiritDescription, + [ABILITY_PERISH_BODY] = sPerishBodyDescription, + [ABILITY_WANDERING_SPIRIT] = sWanderingSpiritDescription, + [ABILITY_GORILLA_TACTICS] = sGorillaTacticsDescription, + [ABILITY_NEUTRALIZING_GAS] = sNeutralizingGasDescription, + [ABILITY_PASTEL_VEIL] = sPastelVeilDescription, + [ABILITY_HUNGER_SWITCH] = sHungerSwitchDescription, }; diff --git a/src/egg_hatch.c b/src/egg_hatch.c index 032ae6733..a7da3234a 100644 --- a/src/egg_hatch.c +++ b/src/egg_hatch.c @@ -872,7 +872,7 @@ u8 GetEggStepsToSubtract(void) { if (!GetMonData(&gPlayerParty[i], MON_DATA_SANITY_IS_EGG)) { - u8 ability = GetMonAbility(&gPlayerParty[i]); + u16 ability = GetMonAbility(&gPlayerParty[i]); if (ability == ABILITY_MAGMA_ARMOR || ability == ABILITY_FLAME_BODY) return 2; } diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index b0918a78d..9928d6a4f 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -1827,7 +1827,7 @@ static bool8 Fishing6(struct Task *task) { if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) { - u8 ability = GetMonAbility(&gPlayerParty[0]); + u16 ability = GetMonAbility(&gPlayerParty[0]); if (ability == ABILITY_SUCTION_CUPS || ability == ABILITY_STICKY_HOLD) { if (Random() % 100 > 14) diff --git a/src/fldeff_cut.c b/src/fldeff_cut.c index 88927959e..8e216da4c 100644 --- a/src/fldeff_cut.c +++ b/src/fldeff_cut.c @@ -141,7 +141,7 @@ bool8 SetUpFieldMove_Cut(void) s16 x, y; u8 i, j; u8 tileBehavior; - u8 userAbility; + u16 userAbility; bool8 cutTiles[CUT_NORMAL_AREA]; bool8 ret; diff --git a/src/pokemon.c b/src/pokemon.c index a417fffec..62fe01704 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4170,7 +4170,7 @@ u8 GetMonsStateToDoubles_2(void) return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON; } -u8 GetAbilityBySpecies(u16 species, u8 abilityNum) +u16 GetAbilityBySpecies(u16 species, u8 abilityNum) { if (abilityNum) gLastUsedAbility = gBaseStats[species].abilities[1]; @@ -4180,7 +4180,7 @@ u8 GetAbilityBySpecies(u16 species, u8 abilityNum) return gLastUsedAbility; } -u8 GetMonAbility(struct Pokemon *mon) +u16 GetMonAbility(struct Pokemon *mon) { u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); u8 abilityNum = GetMonData(mon, MON_DATA_ABILITY_NUM, NULL); diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index db6da1495..4751e052a 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -3173,13 +3173,13 @@ static void PrintMonOTID(void) static void PrintMonAbilityName(void) { - u8 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum); + u16 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum); SummaryScreen_PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilityNames[ability], 0, 1, 0, 1); } static void PrintMonAbilityDescription(void) { - u8 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum); + u16 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum); SummaryScreen_PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilityDescriptionPointers[ability], 0, 17, 0, 0); } diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 9f2197cee..f218d0f2d 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -36,7 +36,7 @@ static void FeebasSeedRng(u16 seed); static bool8 IsWildLevelAllowedByRepel(u8 level); static void ApplyFluteEncounterRateMod(u32 *encRate); static void ApplyCleanseTagEncounterRateMod(u32 *encRate); -static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex); +static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u16 ability, u8 *monIndex); static bool8 IsAbilityAllowingEncounter(u8 level); // EWRAM vars @@ -256,7 +256,7 @@ static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon) // check ability for max level mon if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) { - u8 ability = GetMonAbility(&gPlayerParty[0]); + u16 ability = GetMonAbility(&gPlayerParty[0]); if (ability == ABILITY_HUSTLE || ability == ABILITY_VITAL_SPIRIT || ability == ABILITY_PRESSURE) { if (Random() % 2 == 0) @@ -905,7 +905,7 @@ static bool8 IsWildLevelAllowedByRepel(u8 wildLevel) static bool8 IsAbilityAllowingEncounter(u8 level) { - u8 ability; + u16 ability; if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) return TRUE; @@ -942,7 +942,7 @@ static bool8 TryGetRandomWildMonIndexByType(const struct WildPokemon *wildMon, u return TRUE; } -static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex) +static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u16 ability, u8 *monIndex) { if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) return FALSE;