diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 351146b1e6..b80a7e6c84 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -478,12 +478,20 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData) aiData->weatherHasEffect = WEATHER_HAS_EFFECT; // get/assume all battler data and simulate AI damage battlersCount = gBattlersCount; + for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++) { if (!IsBattlerAlive(battlerAtk)) continue; SetBattlerAiData(battlerAtk, aiData); + } + + for (battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++) + { + if (!IsBattlerAlive(battlerAtk)) + continue; + SetBattlerAiMovesData(aiData, battlerAtk, battlersCount); } } diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 4c894dd238..5f29529d14 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -33,7 +33,6 @@ return FALSE static u32 AI_GetEffectiveness(uq4_12_t multiplier); -u32 AI_GetBattlerAbility(u32); // Functions bool32 AI_IsFaster(u32 battlerAi, u32 battlerDef, u32 move) @@ -411,10 +410,8 @@ bool32 IsDamageMoveUnusable(u32 move, u32 battlerAtk, u32 battlerDef) else battlerDefAbility = aiData->abilities[battlerDef]; - // Battler doesn't see partners Ability for some reason. - // This is a small hack to avoid the issue but should be investigated if (battlerDef == BATTLE_PARTNER(battlerAtk)) - battlerDefAbility = AI_GetBattlerAbility(battlerDef); + battlerDefAbility = aiData->abilities[battlerDef]; switch (battlerDefAbility) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 62b2ac0cdb..62bee8a477 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -13029,7 +13029,7 @@ static void Cmd_trychoosesleeptalkmove(void) } } - unusableMovesBits = CheckMoveLimitations(gBattlerAttacker, unusableMovesBits, ~MOVE_LIMITATION_PP); + unusableMovesBits = CheckMoveLimitations(gBattlerAttacker, unusableMovesBits, ~(MOVE_LIMITATION_PP | MOVE_LIMITATION_CHOICE_ITEM)); if (unusableMovesBits == ALL_MOVES_MASK) // all 4 moves cannot be chosen { gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/battle_util.c b/src/battle_util.c index aa89326d7a..b1ba41ad80 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5894,7 +5894,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && IS_MOVE_PHYSICAL(gCurrentMove) && TARGET_TURN_DAMAGED - && (gSideTimers[gBattlerAttacker].toxicSpikesAmount != 2)) + && (gSideTimers[GetBattlerSide(gBattlerAttacker)].toxicSpikesAmount != 2)) { SWAP(gBattlerAttacker, gBattlerTarget, i); BattleScriptPushCursor(); @@ -8090,7 +8090,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_JabocaRowapBerryActivates; PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem); - RecordItemEffectBattle(battler, HOLD_EFFECT_ROCKY_HELMET); + RecordItemEffectBattle(battler, HOLD_EFFECT_JABOCA_BERRY); } break; case HOLD_EFFECT_ROWAP_BERRY: // consume and damage attacker if used special move @@ -8110,7 +8110,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_JabocaRowapBerryActivates; PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem); - RecordItemEffectBattle(battler, HOLD_EFFECT_ROCKY_HELMET); + RecordItemEffectBattle(battler, HOLD_EFFECT_ROWAP_BERRY); } break; case HOLD_EFFECT_KEE_BERRY: // consume and boost defense if used physical move diff --git a/src/data/abilities.h b/src/data/abilities.h index 8fc7d699e1..ccb27ffe35 100644 --- a/src/data/abilities.h +++ b/src/data/abilities.h @@ -881,7 +881,11 @@ const struct Ability gAbilitiesInfo[ABILITIES_COUNT] = [ABILITY_SNOW_WARNING] = { .name = _("Snow Warning"), - .description = COMPOUND_STRING("Summons a Hailstorm."), + #if B_SNOW_WARNING >= GEN_9 + .description = COMPOUND_STRING("Summons snow in battle."), + #else + .description = COMPOUND_STRING("Summons hail in battle."), + #endif .aiRating = 8, }, diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index dba872543a..810b329aa1 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -487,12 +487,12 @@ void ScrCmd_createmon(struct ScriptContext *ctx) u8 speedEv = PARSE_FLAG(8, 0); u8 spAtkEv = PARSE_FLAG(9, 0); u8 spDefEv = PARSE_FLAG(10, 0); - u8 hpIv = PARSE_FLAG(11, Random() % MAX_PER_STAT_IVS + 1); - u8 atkIv = PARSE_FLAG(12, Random() % MAX_PER_STAT_IVS + 1); - u8 defIv = PARSE_FLAG(13, Random() % MAX_PER_STAT_IVS + 1); - u8 speedIv = PARSE_FLAG(14, Random() % MAX_PER_STAT_IVS + 1); - u8 spAtkIv = PARSE_FLAG(15, Random() % MAX_PER_STAT_IVS + 1); - u8 spDefIv = PARSE_FLAG(16, Random() % MAX_PER_STAT_IVS + 1); + u8 hpIv = PARSE_FLAG(11, Random() % (MAX_PER_STAT_IVS + 1)); + u8 atkIv = PARSE_FLAG(12, Random() % (MAX_PER_STAT_IVS + 1)); + u8 defIv = PARSE_FLAG(13, Random() % (MAX_PER_STAT_IVS + 1)); + u8 speedIv = PARSE_FLAG(14, Random() % (MAX_PER_STAT_IVS + 1)); + u8 spAtkIv = PARSE_FLAG(15, Random() % (MAX_PER_STAT_IVS + 1)); + u8 spDefIv = PARSE_FLAG(16, Random() % (MAX_PER_STAT_IVS + 1)); u16 move1 = PARSE_FLAG(17, MOVE_NONE); u16 move2 = PARSE_FLAG(18, MOVE_NONE); u16 move3 = PARSE_FLAG(19, MOVE_NONE); diff --git a/test/battle/move_effect/sleep_talk.c b/test/battle/move_effect/sleep_talk.c new file mode 100644 index 0000000000..0a42eb90e9 --- /dev/null +++ b/test/battle/move_effect/sleep_talk.c @@ -0,0 +1,93 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(gMovesInfo[MOVE_RAZOR_WIND].sleepTalkBanned == TRUE); + ASSUME(gMovesInfo[MOVE_FLY].sleepTalkBanned == TRUE); + ASSUME(gMovesInfo[MOVE_DIG].sleepTalkBanned == TRUE); +} + +SINGLE_BATTLE_TEST("Sleep Talk fails if not asleep") +{ + u32 status; + PARAMETRIZE { status = STATUS1_SLEEP; } + PARAMETRIZE { status = STATUS1_NONE; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(status); Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + if (status == STATUS1_SLEEP) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + } + else { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + MESSAGE("But it failed!"); + } + } +} + + +SINGLE_BATTLE_TEST("Sleep Talk works if user has Comatose") +{ + + GIVEN { + PLAYER(SPECIES_KOMALA) { Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Talk fails if no moves work") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_RAZOR_WIND, MOVE_FLY, MOVE_DIG); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Sleep Talk can still use moves with no PP") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); MovesWithPP({MOVE_SLEEP_TALK, 10}, {MOVE_TACKLE, 0}, {MOVE_FLY, 10}, {MOVE_DIG, 10}); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE); + } +} + +SINGLE_BATTLE_TEST("Sleep Talk can use moves while choiced into Sleep Talk") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_CHOICE_BAND); Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_FLY, MOVE_DIG); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SLEEP_TALK); } + TURN { MOVE(player, MOVE_SLEEP_TALK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player); + NOT MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE); + } +}