From d38e0d8ae574fbca7db09eaa112dcb2b63f64909 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 20 Apr 2020 11:27:09 +0200 Subject: [PATCH] AI dont rely on power if bad effects --- data/battle_scripts_1.s | 18 ++--- include/constants/battle_move_effects.h | 4 +- src/battle_ai_script_commands.c | 87 ++++++++++++++++++------- src/battle_script_commands.c | 20 +++--- src/data/battle_moves.h | 16 ++--- src/data/trainer_parties.h | 2 +- 6 files changed, 94 insertions(+), 53 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index b4cfbcd3ac..e87b550c57 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -63,7 +63,7 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectRecoilIfMiss .4byte BattleScript_EffectMist .4byte BattleScript_EffectFocusEnergy - .4byte BattleScript_EffectRecoil + .4byte BattleScript_EffectRecoil25 .4byte BattleScript_EffectConfuse .4byte BattleScript_EffectAttackUp2 .4byte BattleScript_EffectDefenseUp2 @@ -213,7 +213,7 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectSnatch .4byte BattleScript_EffectLowKick .4byte BattleScript_EffectSecretPower - .4byte BattleScript_EffectDoubleEdge + .4byte BattleScript_EffectRecoil33 .4byte BattleScript_EffectTeeterDance .4byte BattleScript_EffectHitEscape .4byte BattleScript_EffectMudSport @@ -2821,12 +2821,6 @@ BattleScript_EffectFocusEnergy: waitmessage 0x40 goto BattleScript_MoveEnd -BattleScript_EffectRecoil: - setmoveeffect MOVE_EFFECT_RECOIL_25 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN - jumpifnotmove MOVE_STRUGGLE, BattleScript_EffectHit - incrementgamestat GAME_STAT_USED_STRUGGLE - goto BattleScript_EffectHit - BattleScript_EffectConfuse: attackcanceler attackstring @@ -4533,7 +4527,13 @@ BattleScript_EffectSecretPower:: getsecretpowereffect goto BattleScript_EffectHit -BattleScript_EffectDoubleEdge:: +BattleScript_EffectRecoil25: + setmoveeffect MOVE_EFFECT_RECOIL_25 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN + jumpifnotmove MOVE_STRUGGLE, BattleScript_EffectHit + incrementgamestat GAME_STAT_USED_STRUGGLE + goto BattleScript_EffectHit + +BattleScript_EffectRecoil33:: setmoveeffect MOVE_EFFECT_RECOIL_33 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN goto BattleScript_EffectHit diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 5b3c3bd64c..1cae783237 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -49,7 +49,7 @@ #define EFFECT_RECOIL_IF_MISS 45 #define EFFECT_MIST 46 #define EFFECT_FOCUS_ENERGY 47 -#define EFFECT_RECOIL 48 +#define EFFECT_RECOIL_25 48 #define EFFECT_CONFUSE 49 #define EFFECT_ATTACK_UP_2 50 #define EFFECT_DEFENSE_UP_2 51 @@ -199,7 +199,7 @@ #define EFFECT_SNATCH 195 #define EFFECT_LOW_KICK 196 #define EFFECT_SECRET_POWER 197 -#define EFFECT_DOUBLE_EDGE 198 +#define EFFECT_RECOIL_33 198 #define EFFECT_TEETER_DANCE 199 #define EFFECT_HIT_ESCAPE 200 #define EFFECT_MUD_SPORT 201 diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c index 1c8fb6b0dc..ebf9788e91 100644 --- a/src/battle_ai_script_commands.c +++ b/src/battle_ai_script_commands.c @@ -1378,8 +1378,8 @@ static void Cmd_get_considered_move_power(void) gAIScriptPtr += 1; } -// Checks if the move dealing less damage does not have worse effects. -static bool32 CompareTwoMoves(u32 bestMove, u32 goodMove) +// Checks if one of the moves has side effects or perks +static u32 WhichMoveBetter(u32 move1, u32 move2) { s32 defAbility = AI_GetAbility(gBattlerTarget, FALSE); @@ -1388,31 +1388,52 @@ static bool32 CompareTwoMoves(u32 bestMove, u32 goodMove) && (BATTLE_HISTORY->itemEffects[gBattlerTarget] == HOLD_EFFECT_ROCKY_HELMET || defAbility == ABILITY_IRON_BARBS || defAbility == ABILITY_ROUGH_SKIN)) { - if (IS_MOVE_PHYSICAL(goodMove) && !IS_MOVE_PHYSICAL(bestMove)) - return FALSE; + if (IS_MOVE_PHYSICAL(move1) && !IS_MOVE_PHYSICAL(move2)) + return 1; + if (IS_MOVE_PHYSICAL(move2) && !IS_MOVE_PHYSICAL(move1)) + return 0; } // Check recoil if (GetBattlerAbility(sBattler_AI) != ABILITY_ROCK_HEAD) { - if (((gBattleMoves[goodMove].effect == EFFECT_RECOIL - || gBattleMoves[goodMove].effect == EFFECT_RECOIL_IF_MISS - || gBattleMoves[goodMove].effect == EFFECT_RECOIL_50 - || gBattleMoves[goodMove].effect == EFFECT_RECOIL_33_STATUS) - && (gBattleMoves[bestMove].effect != EFFECT_RECOIL - && gBattleMoves[bestMove].effect != EFFECT_RECOIL_IF_MISS - && gBattleMoves[bestMove].effect != EFFECT_RECOIL_50 - && gBattleMoves[bestMove].effect != EFFECT_RECOIL_33_STATUS - && gBattleMoves[bestMove].effect != EFFECT_RECHARGE))) - return FALSE; + if (((gBattleMoves[move1].effect == EFFECT_RECOIL_25 + || gBattleMoves[move1].effect == EFFECT_RECOIL_IF_MISS + || gBattleMoves[move1].effect == EFFECT_RECOIL_50 + || gBattleMoves[move1].effect == EFFECT_RECOIL_33 + || gBattleMoves[move1].effect == EFFECT_RECOIL_33_STATUS) + && (gBattleMoves[move2].effect != EFFECT_RECOIL_25 + && gBattleMoves[move2].effect != EFFECT_RECOIL_IF_MISS + && gBattleMoves[move2].effect != EFFECT_RECOIL_50 + && gBattleMoves[move2].effect != EFFECT_RECOIL_33 + && gBattleMoves[move2].effect != EFFECT_RECOIL_33_STATUS + && gBattleMoves[move2].effect != EFFECT_RECHARGE))) + return 1; + + if (((gBattleMoves[move2].effect == EFFECT_RECOIL_25 + || gBattleMoves[move2].effect == EFFECT_RECOIL_IF_MISS + || gBattleMoves[move2].effect == EFFECT_RECOIL_50 + || gBattleMoves[move2].effect == EFFECT_RECOIL_33 + || gBattleMoves[move2].effect == EFFECT_RECOIL_33_STATUS) + && (gBattleMoves[move1].effect != EFFECT_RECOIL_25 + && gBattleMoves[move1].effect != EFFECT_RECOIL_IF_MISS + && gBattleMoves[move1].effect != EFFECT_RECOIL_50 + && gBattleMoves[move1].effect != EFFECT_RECOIL_33 + && gBattleMoves[move1].effect != EFFECT_RECOIL_33_STATUS + && gBattleMoves[move1].effect != EFFECT_RECHARGE))) + return 0; } // Check recharge - if (gBattleMoves[goodMove].effect == EFFECT_RECHARGE && gBattleMoves[bestMove].effect != EFFECT_RECHARGE) - return FALSE; + if (gBattleMoves[move1].effect == EFFECT_RECHARGE && gBattleMoves[move2].effect != EFFECT_RECHARGE) + return 1; + if (gBattleMoves[move2].effect == EFFECT_RECHARGE && gBattleMoves[move1].effect != EFFECT_RECHARGE) + return 0; // Check additional effect. - if (gBattleMoves[bestMove].effect != 0 && gBattleMoves[goodMove].effect == 0) - return FALSE; + if (gBattleMoves[move1].effect == 0 && gBattleMoves[move2].effect != 0) + return 1; + if (gBattleMoves[move2].effect == 0 && gBattleMoves[move1].effect != 0) + return 0; - return TRUE; + return 2; } static void Cmd_get_how_powerful_move_is(void) @@ -1449,19 +1470,39 @@ static void Cmd_get_how_powerful_move_is(void) } } - for (bestId = 0, i = 0; i < MAX_MON_MOVES; i++) + hp = gBattleMons[gBattlerTarget].hp + (20 * gBattleMons[gBattlerTarget].hp / 100); // 20 % add to make sure the battler is always fainted + // If a move can faint battler, it doesn't matter how much damage it does + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moveDmgs[i] > hp) + moveDmgs[i] = hp; + } + + for (bestId = 0, i = 1; i < MAX_MON_MOVES; i++) { if (moveDmgs[i] > moveDmgs[bestId]) bestId = i; + if (moveDmgs[i] == moveDmgs[bestId]) + { + switch (WhichMoveBetter(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[i])) + { + case 2: + if (Random() & 1) + break; + case 1: + bestId = i; + break; + } + } } currId = AI_THINKING_STRUCT->movesetIndex; - hp = gBattleMons[gBattlerTarget].hp; if (currId == bestId) AI_THINKING_STRUCT->funcResult = MOVE_POWER_BEST; // Compare percentage difference. - else if ((moveDmgs[bestId] * 100 / hp) - (moveDmgs[currId] * 100 / hp) <= 10 - && CompareTwoMoves(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[currId])) + else if ((moveDmgs[currId] >= hp || moveDmgs[bestId] < hp) // If current move can faint as well, or if neither can + && (moveDmgs[bestId] * 100 / hp) - (moveDmgs[currId] * 100 / hp) <= 30 + && WhichMoveBetter(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[currId]) != 0) AI_THINKING_STRUCT->funcResult = MOVE_POWER_GOOD; else AI_THINKING_STRUCT->funcResult = MOVE_POWER_WEAK; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 44468ba3ab..a1dfe79489 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2599,14 +2599,6 @@ void SetMoveEffect(bool32 primary, u32 certain) } } break; - case MOVE_EFFECT_RECOIL_25: // 25% recoil - gBattleMoveDamage = (gHpDealt) / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect]; - break; case MOVE_EFFECT_ATK_PLUS_1: case MOVE_EFFECT_DEF_PLUS_1: case MOVE_EFFECT_SPD_PLUS_1: @@ -2812,7 +2804,15 @@ void SetMoveEffect(bool32 primary, u32 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_DefSpDefDown; break; - case MOVE_EFFECT_RECOIL_33: // Double Edge + case MOVE_EFFECT_RECOIL_25: // Take Down, 25% recoil + gBattleMoveDamage = (gHpDealt) / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect]; + break; + case MOVE_EFFECT_RECOIL_33: // Double Edge, 33 % recoil gBattleMoveDamage = gHpDealt / 3; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -2820,7 +2820,7 @@ void SetMoveEffect(bool32 primary, u32 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect]; break; - case MOVE_EFFECT_RECOIL_50: // Head Smash + case MOVE_EFFECT_RECOIL_50: // Head Smash, 50 % recoil gBattleMoveDamage = gHpDealt / 2; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 462cabeab0..7f310e2a47 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -506,7 +506,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_TAKE_DOWN] = { - .effect = EFFECT_RECOIL, + .effect = EFFECT_RECOIL_25, .power = 90, .type = TYPE_NORMAL, .accuracy = 85, @@ -534,7 +534,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_DOUBLE_EDGE] = { - .effect = EFFECT_DOUBLE_EDGE, + .effect = EFFECT_RECOIL_33, .power = 120, .type = TYPE_NORMAL, .accuracy = 100, @@ -926,7 +926,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_SUBMISSION] = { - .effect = EFFECT_RECOIL, + .effect = EFFECT_RECOIL_25, .power = 80, .type = TYPE_FIGHTING, .accuracy = 80, @@ -2313,7 +2313,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_STRUGGLE] = { - .effect = EFFECT_RECOIL, + .effect = EFFECT_RECOIL_25, .power = 50, .type = TYPE_NORMAL, .accuracy = 0, @@ -5790,7 +5790,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_BRAVE_BIRD] = { - .effect = EFFECT_DOUBLE_EDGE, + .effect = EFFECT_RECOIL_33, .power = 120, .type = TYPE_FLYING, .accuracy = 100, @@ -6339,7 +6339,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_WOOD_HAMMER] = { - .effect = EFFECT_RECOIL, + .effect = EFFECT_RECOIL_25, .power = 120, .type = TYPE_GRASS, .accuracy = 100, @@ -7405,7 +7405,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_WILD_CHARGE] = { - .effect = EFFECT_RECOIL, + .effect = EFFECT_RECOIL_25, .power = 90, .type = TYPE_ELECTRIC, .accuracy = 100, @@ -7615,7 +7615,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_HEAD_CHARGE] = { - .effect = EFFECT_RECOIL, + .effect = EFFECT_RECOIL_25, .power = 120, .type = TYPE_NORMAL, .accuracy = 100, diff --git a/src/data/trainer_parties.h b/src/data/trainer_parties.h index 824a49dc3e..e2a509e092 100644 --- a/src/data/trainer_parties.h +++ b/src/data/trainer_parties.h @@ -3218,7 +3218,7 @@ static const struct TrainerMonItemCustomMoves sParty_Sidney[] = { .lvl = 46, .species = SPECIES_MIGHTYENA, .heldItem = ITEM_NONE, - .moves = {MOVE_ROAR, MOVE_DOUBLE_EDGE, MOVE_SAND_ATTACK, MOVE_CRUNCH} + .moves = {MOVE_TAKE_DOWN, MOVE_DOUBLE_EDGE, MOVE_BITE, MOVE_CRUNCH} }, { .iv = 250,