From a7642da54444cd9673a980a022790189e87c6192 Mon Sep 17 00:00:00 2001 From: Pawkkie <61265402+Pawkkie@users.noreply.github.com> Date: Fri, 14 Jun 2024 04:18:01 -0400 Subject: [PATCH] Revenge Killer switching factors in Trick Room (#4794) * Revenge Killer switching factors in Trick Room * Comments and float multiplication --- src/battle_ai_switch_items.c | 17 +++++++++++------ test/battle/ai_switching.c | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 38eff26341..154c251118 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -1880,14 +1880,17 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, // If AI mon can one shot if (damageDealt > playerMonHP) { - // If AI mon is faster and doesn't die to hazards - if ((aiMonSpeed > playerMonSpeed || aiMovePriority > 0) && AI_DATA->switchinCandidate.battleMon.hp > GetSwitchinHazardsDamage(battler, &AI_DATA->switchinCandidate.battleMon)) + // If AI mon outspeeds and doesn't die to hazards + if ((((aiMonSpeed > playerMonSpeed && !(gFieldStatuses & STATUS_FIELD_TRICK_ROOM)) || aiMovePriority > 0) // Outspeed if not Trick Room + || ((gFieldStatuses & STATUS_FIELD_TRICK_ROOM) // Trick Room + && (aiMonSpeed < playerMonSpeed || (gItemsInfo[AI_DATA->switchinCandidate.battleMon.item].holdEffect == HOLD_EFFECT_ROOM_SERVICE && aiMonSpeed * 2 / 3 < playerMonSpeed)))) // Trick Room speeds + && AI_DATA->switchinCandidate.battleMon.hp > GetSwitchinHazardsDamage(battler, &AI_DATA->switchinCandidate.battleMon)) // Hazards { // We have a revenge killer revengeKillerId = i; } - // If AI mon is slower + // If AI mon is outsped else { // If AI mon can't be OHKO'd @@ -1902,8 +1905,10 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, // If AI mon can two shot if (damageDealt > playerMonHP / 2) { - // If AI mon is faster - if (aiMonSpeed > playerMonSpeed || aiMovePriority > 0) + // If AI mon outspeeds + if (((aiMonSpeed > playerMonSpeed && !(gFieldStatuses & STATUS_FIELD_TRICK_ROOM)) || aiMovePriority > 0) // Outspeed if not Trick Room + || (((gFieldStatuses & STATUS_FIELD_TRICK_ROOM) && gFieldTimers.trickRoomTimer > 1) // Trick Room has at least 2 turns left + && (aiMonSpeed < playerMonSpeed || (gItemsInfo[AI_DATA->switchinCandidate.battleMon.item].holdEffect == HOLD_EFFECT_ROOM_SERVICE && aiMonSpeed * 2/ 3 < playerMonSpeed)))) // Trick Room speeds { // If AI mon can't be OHKO'd if (hitsToKOAI > hitsToKOAIThreshold) @@ -1912,7 +1917,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, fastThreatenId = i; } } - // If AI mon is slower + // If AI mon is outsped else { // If AI mon can't be 2HKO'd diff --git a/test/battle/ai_switching.c b/test/battle/ai_switching.c index fb5085a791..50b59f66d1 100644 --- a/test/battle/ai_switching.c +++ b/test/battle/ai_switching.c @@ -224,6 +224,21 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Post-KO switches prioritize of } } +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Post-KO switches factor in Trick Room for revenge killing") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TRICK_ROOM].effect == EFFECT_TRICK_ROOM); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES); + PLAYER(SPECIES_SWELLOW) { Level(30); Speed(10); Moves(MOVE_WING_ATTACK, MOVE_GROWL); } + OPPONENT(SPECIES_BALTOY) { Level(1); Speed(10); Moves(MOVE_TRICK_ROOM); } + OPPONENT(SPECIES_ELECTRODE) { Level(30); Speed(5); Moves(MOVE_THUNDERBOLT); } + OPPONENT(SPECIES_ELECTRODE) { Level(30); Speed(15); Moves(MOVE_THUNDERBOLT); } + } WHEN { + TURN { EXPECT_MOVE(opponent, MOVE_TRICK_ROOM); MOVE(player, MOVE_GROWL); } + TURN { MOVE(player, MOVE_WING_ATTACK); EXPECT_SEND_OUT(opponent, 1); } + } +} + // General AI_FLAG_SMART_SWITCHING behaviour AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI switches out after sufficient stat drops") {