diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 5a3861a295..fbb18e9e42 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1705,6 +1705,10 @@ .byte \type .endm + .macro tryfriskmsg battler:req + various \battler, VARIOUS_TRY_FRISK + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 6371114c67..4623efd9cd 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6887,6 +6887,18 @@ BattleScript_SwitchInAbilityMsg:: printfromtable gSwitchInAbilityStringIds waitmessage 0x40 end3 + +BattleScript_FriskMsgWithPopup:: + copybyte gBattlerAbility, gBattlerAttacker + call BattleScript_AbilityPopUp +BattleScript_FriskMsg:: + printstring STRINGID_FRISKACTIVATES + waitmessage 0x40 + return + +BattleScript_FriskActivates:: + tryfriskmsg BS_ATTACKER + end3 BattleScript_ImposterActivates:: transformdataexecution diff --git a/include/battle.h b/include/battle.h index b6449837f2..6180829a99 100644 --- a/include/battle.h +++ b/include/battle.h @@ -544,6 +544,8 @@ struct BattleStruct struct Illusion illusion[MAX_BATTLERS_COUNT]; s8 aiFinalScore[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // AI, target, moves to make debugging easier u8 soulheartBattlerId; + u8 friskedBattler; // Frisk needs to identify 2 battlers in double battles. + bool8 friskedAbility; // If identifies two mons, show the ability pop-up only once. }; #define GET_MOVE_TYPE(move, typeArg) \ diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 8ba5920d04..7c3b2ef534 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -336,5 +336,8 @@ extern const u8 BattleScript_SlowStartEnds[]; extern const u8 BattleScript_HealerActivates[]; extern const u8 BattleScript_ScriptingAbilityStatRaise[]; extern const u8 BattleScript_ReceiverActivates[]; +extern const u8 BattleScript_FriskActivates[]; +extern const u8 BattleScript_FriskMsg[]; +extern const u8 BattleScript_FriskMsgWithPopup[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index d1f729eeac..d7faed2f4b 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -152,6 +152,7 @@ #define VARIOUS_TRY_ACTIVATE_SOULHEART 89 #define VARIOUS_TRY_ACTIVATE_RECEIVER 90 #define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 91 +#define VARIOUS_TRY_FRISK 92 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_message.c b/src/battle_message.c index f1168fe1bf..4e3752c9f3 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -1231,7 +1231,7 @@ const u16 gDmgHazardsStringIds[] = const u16 gSwitchInAbilityStringIds[] = { STRINGID_MOLDBREAKERENTERS, STRINGID_TERAVOLTENTERS, STRINGID_TURBOBLAZEENTERS, - STRINGID_SLOWSTARTENTERS, STRINGID_UNNERVEENTERS, STRINGID_ANTICIPATIONACTIVATES + STRINGID_SLOWSTARTENTERS, STRINGID_UNNERVEENTERS, STRINGID_ANTICIPATIONACTIVATES, }; const u16 gMissStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 25d011ea7c..c9dfa977d8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6817,6 +6817,33 @@ static void Cmd_various(void) else gBattlescriptCurrInstr += 7; return; + case VARIOUS_TRY_FRISK: + while (gBattleStruct->friskedBattler < gBattlersCount) + { + gBattlerTarget = gBattleStruct->friskedBattler++; + if (GET_BATTLER_SIDE2(gActiveBattler) != GET_BATTLER_SIDE2(gBattlerTarget) + && IsBattlerAlive(gBattlerTarget) + && gBattleMons[gBattlerTarget].item != ITEM_NONE) + { + gLastUsedItem = gBattleMons[gBattlerTarget].item; + RecordItemEffectBattle(gBattlerTarget, GetBattlerHoldEffect(gBattlerTarget, FALSE)); + BattleScriptPushCursor(); + // If Frisk identifies two mons' items, show the pop-up only once. + if (gBattleStruct->friskedAbility) + { + gBattlescriptCurrInstr = BattleScript_FriskMsg; + } + else + { + gBattleStruct->friskedAbility = TRUE; + gBattlescriptCurrInstr = BattleScript_FriskMsgWithPopup; + } + return; + } + } + gBattleStruct->friskedBattler = 0; + gBattleStruct->friskedAbility = FALSE; + break; case VARIOUS_TRACE_ABILITY: gBattleMons[gActiveBattler].ability = gBattleStruct->tracedAbility[gActiveBattler]; RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); diff --git a/src/battle_util.c b/src/battle_util.c index a803a0de24..a6b7029e7e 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2911,6 +2911,14 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA } } break; + case ABILITY_FRISK: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + gSpecialStatuses[battler].switchInAbilityDone = 1; + BattleScriptPushCursorAndCallback(BattleScript_FriskActivates); // Try activate + effect++; + } + return effect; // Note: It returns effect as to not record the ability if Frisk does not activate. case ABILITY_DOWNLOAD: if (!gSpecialStatuses[battler].switchInAbilityDone) { diff --git a/src/data/pokemon/base_stats.h b/src/data/pokemon/base_stats.h index c191da8162..c1861da7dd 100644 --- a/src/data/pokemon/base_stats.h +++ b/src/data/pokemon/base_stats.h @@ -7296,7 +7296,7 @@ const struct BaseStats gBaseStats[] = .growthRate = GROWTH_SLOW, .eggGroup1 = EGG_GROUP_FLYING, .eggGroup2 = EGG_GROUP_FLYING, - .abilities = {ABILITY_KEEN_EYE, ABILITY_STURDY}, + .abilities = {ABILITY_FRISK, ABILITY_FRISK}, .safariZoneFleeRate = 0, .bodyColor = BODY_COLOR_GRAY, .noFlip = FALSE, @@ -8498,7 +8498,7 @@ const struct BaseStats gBaseStats[] = .growthRate = GROWTH_MEDIUM_FAST, .eggGroup1 = EGG_GROUP_FIELD, .eggGroup2 = EGG_GROUP_FIELD, - .abilities = {ABILITY_PICKUP, ABILITY_NONE}, + .abilities = {ABILITY_FRISK, ABILITY_FRISK}, .safariZoneFleeRate = 0, .bodyColor = BODY_COLOR_BROWN, .noFlip = FALSE, @@ -9994,15 +9994,15 @@ const struct BaseStats gBaseStats[] = .evYield_Speed = 0, .evYield_SpAttack = 0, .evYield_SpDefense = 0, - .item1 = ITEM_NONE, - .item2 = ITEM_NONE, + .item1 = ITEM_LEFTOVERS, + .item2 = ITEM_LEFTOVERS, .genderRatio = PERCENT_FEMALE(25), .eggCycles = 20, .friendship = 70, .growthRate = GROWTH_FLUCTUATING, .eggGroup1 = EGG_GROUP_HUMAN_LIKE, .eggGroup2 = EGG_GROUP_HUMAN_LIKE, - .abilities = {ABILITY_THICK_FAT, ABILITY_GUTS}, + .abilities = {ABILITY_FRISK, ABILITY_FRISK}, .safariZoneFleeRate = 0, .bodyColor = BODY_COLOR_YELLOW, .noFlip = FALSE, @@ -10026,15 +10026,15 @@ const struct BaseStats gBaseStats[] = .evYield_Speed = 0, .evYield_SpAttack = 0, .evYield_SpDefense = 0, - .item1 = ITEM_NONE, - .item2 = ITEM_KINGS_ROCK, + .item1 = ITEM_LEFTOVERS, + .item2 = ITEM_LEFTOVERS, .genderRatio = PERCENT_FEMALE(25), .eggCycles = 20, .friendship = 70, .growthRate = GROWTH_FLUCTUATING, .eggGroup1 = EGG_GROUP_HUMAN_LIKE, .eggGroup2 = EGG_GROUP_HUMAN_LIKE, - .abilities = {ABILITY_THICK_FAT, ABILITY_GUTS}, + .abilities = {ABILITY_FRISK, ABILITY_FRISK}, .safariZoneFleeRate = 0, .bodyColor = BODY_COLOR_BROWN, .noFlip = FALSE,