From 98b2e88e56bf5831e97b340b870291c7d0e35d84 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 28 Apr 2020 15:36:13 +0200 Subject: [PATCH] Forewarn --- include/battle_ai_script_commands.h | 1 + src/battle_ai_script_commands.c | 30 +++++++------ src/battle_message.c | 3 +- src/battle_util.c | 69 +++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 14 deletions(-) diff --git a/include/battle_ai_script_commands.h b/include/battle_ai_script_commands.h index ef927f88bc..04d580a84c 100644 --- a/include/battle_ai_script_commands.h +++ b/include/battle_ai_script_commands.h @@ -17,6 +17,7 @@ u8 BattleAI_ChooseMoveOrAction(void); 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 ClearBattlerAbilityHistory(u8 battlerId); void RecordItemEffectBattle(u8 battlerId, u8 itemEffect); diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c index 200bcb914a..6247df4bcd 100644 --- a/src/battle_ai_script_commands.c +++ b/src/battle_ai_script_commands.c @@ -731,19 +731,7 @@ static void BattleAI_DoAIProcessing(void) static void RecordLastUsedMoveByTarget(void) { - s32 i; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (BATTLE_HISTORY->usedMoves[gBattlerTarget].moves[i] == gLastMoves[gBattlerTarget]) - break; - if (BATTLE_HISTORY->usedMoves[gBattlerTarget].moves[i] != gLastMoves[gBattlerTarget] // HACK: This redundant condition is a hack to make the asm match. - && BATTLE_HISTORY->usedMoves[gBattlerTarget].moves[i] == MOVE_NONE) - { - BATTLE_HISTORY->usedMoves[gBattlerTarget].moves[i] = gLastMoves[gBattlerTarget]; - break; - } - } + RecordMoveBattle(gBattlerTarget, gLastMoves[gBattlerTarget]); } bool32 IsBattlerAIControlled(u32 battlerId) @@ -770,6 +758,22 @@ void ClearBattlerMoveHistory(u8 battlerId) BATTLE_HISTORY->usedMoves[battlerId].moves[i] = MOVE_NONE; } +void RecordMoveBattle(u8 battlerId, u32 move) +{ + s32 i; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (BATTLE_HISTORY->usedMoves[battlerId].moves[i] == move) + break; + if (BATTLE_HISTORY->usedMoves[battlerId].moves[i] == MOVE_NONE) + { + BATTLE_HISTORY->usedMoves[battlerId].moves[i] = move; + break; + } + } +} + void RecordAbilityBattle(u8 battlerId, u8 abilityId) { BATTLE_HISTORY->abilities[battlerId] = abilityId; diff --git a/src/battle_message.c b/src/battle_message.c index ab15db98c5..0e04baad3b 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -589,7 +589,7 @@ static const u8 sText_SlowStartEnd[] = _("{B_ATK_NAME_WITH_PREFIX} finally got\n static const u8 sText_SolarPowerHpDrop[] = _("The {B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\ntakes its toll!"); static const u8 sText_AftermathDmg[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt!"); static const u8 sText_AnticipationActivates[] = _("{B_ATK_NAME_WITH_PREFIX} shuddered\nin anticipation!"); -static const u8 sText_ForewarnActivates[] = _("{B_ATK_ABILITY} alerted the {B_ATK_NAME_WITH_PREFIX} to the\n{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}!"); +static const u8 sText_ForewarnActivates[] = _("{B_ATK_ABILITY} alerted {B_ATK_NAME_WITH_PREFIX}\nto the{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}!"); static const u8 sText_IceBodyHpGain[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nhealed it a little bit!"); static const u8 sText_SnowWarningHail[] = _("It started to hail!"); static const u8 sText_FriskActivates[] = _("{B_ATK_NAME_WITH_PREFIX} frisked {B_DEF_NAME_WITH_PREFIX} and\nfound its {B_LAST_ITEM}!"); @@ -1238,6 +1238,7 @@ const u16 gSwitchInAbilityStringIds[] = { STRINGID_MOLDBREAKERENTERS, STRINGID_TERAVOLTENTERS, STRINGID_TURBOBLAZEENTERS, STRINGID_SLOWSTARTENTERS, STRINGID_UNNERVEENTERS, STRINGID_ANTICIPATIONACTIVATES, + STRINGID_FOREWARNACTIVATES }; const u16 gMissStringIds[] = diff --git a/src/battle_util.c b/src/battle_util.c index 1d17249bbe..86de71de34 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -16,6 +16,7 @@ #include "battle_ai_script_commands.h" #include "event_data.h" #include "link.h" +#include "malloc.h" #include "berry.h" #include "pokedex.h" #include "mail.h" @@ -2786,6 +2787,64 @@ static bool32 ShouldChangeFormHpBased(u32 battler) return FALSE; } +static u8 ForewarnChooseMove(u32 battler) +{ + struct Forewarn { + u8 battlerId; + u8 power; + u16 moveId; + }; + u32 i, j, bestId, count; + struct Forewarn *data = malloc(sizeof(struct Forewarn) * MAX_BATTLERS_COUNT * MAX_MON_MOVES); + + // Put all moves + for (count = 0, i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (IsBattlerAlive(i) && GetBattlerSide(i) != GetBattlerSide(battler)) + { + for (j = 0; j < MAX_MON_MOVES; j++) + { + if (gBattleMons[i].moves[j] == MOVE_NONE) + continue; + data[count].moveId = gBattleMons[i].moves[j]; + data[count].battlerId = i; + switch (gBattleMoves[data[count].moveId].effect) + { + case EFFECT_OHKO: + data[count].power = 150; + break; + case EFFECT_COUNTER: + case EFFECT_MIRROR_COAT: + case EFFECT_METAL_BURST: + data[count].power = 120; + break; + default: + if (gBattleMoves[data[count].moveId].power == 1) + data[count].power = 80; + else + data[count].power = gBattleMoves[data[count].moveId].power; + break; + } + count++; + } + } + } + + for (bestId = 0, i = 1; i < count; i++) + { + if (data[i].power > data[bestId].power) + bestId = i; + else if (data[i].power == data[bestId].power && Random() & 1) + bestId = i; + } + + gBattlerTarget = data[bestId].battlerId; + PREPARE_MOVE_BUFFER(gBattleTextBuff1, data[bestId].moveId) + RecordMoveBattle(gBattlerTarget, data[bestId].moveId); + + free(data); +} + u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveArg) { u8 effect = 0; @@ -2960,6 +3019,16 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA effect++; } return effect; // Note: It returns effect as to not record the ability if Frisk does not activate. + case ABILITY_FOREWARN: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + ForewarnChooseMove(battler); + gBattleCommunication[MULTISTRING_CHOOSER] = 6; + gSpecialStatuses[battler].switchInAbilityDone = 1; + BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg); + effect++; + } + break; case ABILITY_DOWNLOAD: if (!gSpecialStatuses[battler].switchInAbilityDone) {