diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c3d0055d8a..70e56f9f55 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -480,24 +480,22 @@ BattleScript_AxeKickHitFromAtkString: BattleScript_EffectTakeHeart:: attackcanceler - accuracycheck BattleScript_AxeKickMissedDoDamage, ACC_CURR_MOVE attackstring ppreduce + cureifburnedparalysedorpoisoned BattleScript_EffectTakeHeart_TryToRaiseStats attackanimation waitanimation - jumpifstatus BS_ATTACKER, STATUS1_ANY, BattleScript_TakeHeart_HealStatusConditions - goto BattleScript_TakeHeart_TryToRaiseSpecialStats -BattleScript_TakeHeart_HealStatusConditions: - curestatus BS_ATTACKER updatestatusicon BS_ATTACKER printstring STRINGID_PKMNSTATUSNORMAL waitmessage B_WAIT_TIME_LONG -BattleScript_TakeHeart_TryToRaiseSpecialStats: - modifybattlerstatstage BS_ATTACKER, STAT_SPATK, INCREASE, 1, BattleScript_TakeHeartTrySpDef, ANIM_ON -BattleScript_TakeHeartTrySpDef: - modifybattlerstatstage BS_ATTACKER, STAT_SPDEF, INCREASE, 1, BattleScript_TakeHeart_MoveEnd, ANIM_ON -BattleScript_TakeHeart_MoveEnd: - goto BattleScript_MoveEnd + jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_CalmMindStatRaise + jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPDEF, MAX_STAT_STAGE, BattleScript_CalmMindStatRaise + goto BattleScript_CantRaiseMultipleStats + +BattleScript_EffectTakeHeart_TryToRaiseStats: + jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_CalmMindDoMoveAnim + jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPDEF, MAX_STAT_STAGE, BattleScript_CalmMindDoMoveAnim + goto BattleScript_CantRaiseMultipleStats BattleScript_EffectTripleArrows:: setmoveeffect MOVE_EFFECT_TRIPLE_ARROWS @@ -1535,6 +1533,13 @@ BattleScript_DefDown:: BattleScript_DefDown_Ret: return +BattleScript_ReduceDefenseAndFlinch:: + modifybattlerstatstage BS_TARGET, STAT_DEF, DECREASE, 1, BattleScript_DefDown_Ret, ANIM_ON + jumpifability BS_TARGET, ABILITY_INNER_FOCUS, BattleScript_FlinchPrevention + setmoveeffect MOVE_EFFECT_FLINCH + seteffectprimary + goto BattleScript_MoveEnd + BattleScript_EffectPurify: attackcanceler attackstring @@ -6387,6 +6392,7 @@ BattleScript_EffectCalmMind:: BattleScript_CalmMindDoMoveAnim:: attackanimation waitanimation +BattleScript_CalmMindStatRaise:: setbyte sSTAT_ANIM_PLAYED, FALSE playstatchangeanimation BS_ATTACKER, BIT_SPATK | BIT_SPDEF, 0 setstatchanger STAT_SPATK, 1, FALSE diff --git a/include/battle_scripts.h b/include/battle_scripts.h index aac118d036..c58f0afc23 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -462,6 +462,7 @@ extern const u8 BattleScript_MoveEffectStockpileWoreOff[]; extern const u8 BattleScript_StealthRockActivates[]; extern const u8 BattleScript_SpikesActivates[]; extern const u8 BattleScript_DefDown[]; +extern const u8 BattleScript_ReduceDefenseAndFlinch[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; diff --git a/include/random.h b/include/random.h index 14b6a253e3..e5f8c05ece 100644 --- a/include/random.h +++ b/include/random.h @@ -60,7 +60,8 @@ enum RandomTag RNG_SPEED_TIE, RNG_STATIC, RNG_STENCH, - RNG_TRIPLE_ARROWS, + RNG_TRIPLE_ARROWS_DEFENSE_DOWN, + RNG_TRIPLE_ARROWS_FLINCH, }; #define RandomWeighted(tag, ...) \ diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index c52f9bc032..c51517d371 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1788,7 +1788,6 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_RESTORE_HP: case EFFECT_SOFTBOILED: case EFFECT_ROOST: - case EFFECT_JUNGLE_HEALING: if (AtMaxHp(battlerAtk)) score -= 10; else if (AI_DATA->hpPercents[battlerAtk] >= 90) @@ -2611,9 +2610,20 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (gBattleMons[battlerAtk].hp <= gBattleMons[battlerAtk].maxHP / 3) score -= 10; break;*/ + case EFFECT_JUNGLE_HEALING: + if (AtMaxHp(battlerAtk) + && AtMaxHp(BATTLE_PARTNER(battlerAtk)) + && !(gBattleMons[battlerAtk].status1 & STATUS1_ANY) + && !(gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY)) + score -= 10; + else if (AI_DATA->hpPercents[battlerAtk] >= 90 || AI_DATA->hpPercents[BATTLE_PARTNER(battlerAtk)] >= 90) + score -= 9; //No point in healing, but should at least do it if nothing better + break; case EFFECT_TAKE_HEART: if ((!(gBattleMons[battlerAtk].status1 & STATUS1_ANY) - || PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove)) + || PartnerMoveIs(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove, MOVE_JUNGLE_HEALING) + || PartnerMoveIs(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove, MOVE_HEAL_BELL) + || PartnerMoveIs(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove, MOVE_AROMATHERAPY)) && !BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPATK) && !BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPDEF)) score -= 10; @@ -3483,11 +3493,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_BIG_ROOT) score++; break; - case EFFECT_JUNGLE_HEALING: - if (ShouldRecover(battlerAtk, battlerDef, move, 25) - || (ShouldRecover(BATTLE_PARTNER(battlerAtk), battlerDef, move, 25) && ShouldRecover(BATTLE_PARTNER(battlerAtk), BATTLE_PARTNER(battlerDef), move, 25))) - score += 3; - break; case EFFECT_TOXIC: case EFFECT_POISON: case EFFECT_BARB_BARRAGE: @@ -4371,7 +4376,9 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) break; case EFFECT_REFRESH: case EFFECT_TAKE_HEART: - if (gBattleMons[battlerAtk].status1 & STATUS1_ANY) + if (gBattleMons[battlerAtk].status1 & STATUS1_ANY + || BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPATK) + || BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPDEF)) score += 2; break; case EFFECT_PSYCHO_SHIFT: @@ -4817,6 +4824,15 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) //break; //case EFFECT_SKY_DROP //break; + case EFFECT_JUNGLE_HEALING: + if (ShouldRecover(battlerAtk, battlerDef, move, 25) + || ShouldRecover(battlerAtk, BATTLE_PARTNER(battlerDef), move, 25) + || ShouldRecover(BATTLE_PARTNER(battlerAtk), battlerDef, move, 25) + || ShouldRecover(BATTLE_PARTNER(battlerAtk), BATTLE_PARTNER(battlerDef), move, 25) + || gBattleMons[battlerAtk].status1 & STATUS1_ANY + || gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY) + score += 3; + break; } // move effect checks return score; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 775f8c456a..f5f8ccf31a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3801,26 +3801,47 @@ void SetMoveEffect(bool32 primary, u32 certain) break; case MOVE_EFFECT_TRIPLE_ARROWS: { - u8 randomChance = RandomUniform(RNG_TRIPLE_ARROWS, 1, 10); - if (randomChance <= 5) // Chance to reduce a foe's Defense by 1 stat stage. + u8 randomLowerDefenseChance; + u8 randomFlinchChance; + + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) + { + randomLowerDefenseChance = RandomPercentage(RNG_TRIPLE_ARROWS_DEFENSE_DOWN, 100); + randomFlinchChance = RandomPercentage(RNG_TRIPLE_ARROWS_FLINCH, 60); + } + else + { + randomLowerDefenseChance = RandomPercentage(RNG_TRIPLE_ARROWS_DEFENSE_DOWN, 50); + randomFlinchChance = RandomPercentage(RNG_TRIPLE_ARROWS_FLINCH, 30); + } + + if (randomLowerDefenseChance && randomFlinchChance) { BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_DefDown; + gBattlescriptCurrInstr = BattleScript_ReduceDefenseAndFlinch; } - if (randomChance > 5 && randomChance <= 8) // Chance to cause a foe to flinch. + else { - if (battlerAbility == ABILITY_INNER_FOCUS && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + if (randomLowerDefenseChance) { - gLastUsedAbility = ABILITY_INNER_FOCUS; - gBattlerAbility = gEffectBattler; - RecordAbilityBattle(gEffectBattler, ABILITY_INNER_FOCUS); - gBattlescriptCurrInstr = BattleScript_FlinchPrevention; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_DefDown; } - else + else if (randomFlinchChance) { - if (GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber) - gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[MOVE_EFFECT_FLINCH]; - gBattlescriptCurrInstr++; + if (battlerAbility == ABILITY_INNER_FOCUS) + { + gLastUsedAbility = ABILITY_INNER_FOCUS; + gBattlerAbility = gEffectBattler; + RecordAbilityBattle(gEffectBattler, ABILITY_INNER_FOCUS); + gBattlescriptCurrInstr = BattleScript_FlinchPrevention; + } + else + { + if (GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber) + gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[MOVE_EFFECT_FLINCH]; + gBattlescriptCurrInstr++; + } } } } diff --git a/test/move_effect_triple_arrows.c b/test/move_effect_triple_arrows.c index 020e46c6bb..5fdf30737f 100644 --- a/test/move_effect_triple_arrows.c +++ b/test/move_effect_triple_arrows.c @@ -8,7 +8,7 @@ ASSUMPTIONS SINGLE_BATTLE_TEST("Triple Arrows lower's defense by one stage") { - PASSES_RANDOMLY(50, 100, RNG_TRIPLE_ARROWS); + PASSES_RANDOMLY(50, 100, RNG_TRIPLE_ARROWS_DEFENSE_DOWN); GIVEN { PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Triple Arrows lower's defense by one stage") SINGLE_BATTLE_TEST("Triple Arrows flinch 30% of the time") { - PASSES_RANDOMLY(30, 100, RNG_TRIPLE_ARROWS); + PASSES_RANDOMLY(30, 100, RNG_TRIPLE_ARROWS_FLINCH); GIVEN { PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);