From 2d7c79e860e58610c0691da119e1008fdc947510 Mon Sep 17 00:00:00 2001 From: BlueAnthem37510 <137793234+BlueAnthem37510@users.noreply.github.com> Date: Tue, 7 May 2024 11:44:17 +0100 Subject: [PATCH 01/17] Gulp missile not triggering on faint fix and added form change type (#4502) * Cramorant faint fix and add form change type * Fixed formatting, renamed form change type, changed various to callnative * Fix oops broke everything except gulp missile * Improved condition order * remove extra line * whitespace and alignment Co-authored-by: Eduardo Quezada * whitespace and alignment Co-authored-by: Eduardo Quezada * whitespace and alignment Co-authored-by: Eduardo Quezada * whitespace and alignment Co-authored-by: Eduardo Quezada * whitespace and alignment Co-authored-by: Eduardo Quezada * whitespace and alignment Co-authored-by: Eduardo Quezada * Added requested changes --------- Co-authored-by: BlueAnthem37510 Co-authored-by: Eduardo Quezada --- asm/macros/battle_script.inc | 6 +++- data/battle_scripts_1.s | 2 ++ include/constants/form_change_types.h | 3 ++ src/battle_script_commands.c | 33 ++++++++++++++++++++ src/battle_util.c | 45 +++++++++++++-------------- src/data/pokemon/form_change_tables.h | 1 + test/battle/ability/gulp_missile.c | 4 +-- 7 files changed, 66 insertions(+), 28 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 260257fc61..34aea69998 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1635,7 +1635,11 @@ .macro trygulpmissile callnative BS_TryGulpMissile .endm - + + .macro tryactivategulpmissile + callnative BS_TryActivateGulpMissile + .endm + .macro tryquash failInstr:req callnative BS_TryQuash .4byte \failInstr diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 788b5225f0..79ee6b4017 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5458,6 +5458,7 @@ BattleScript_EffectCamouflage:: BattleScript_FaintAttacker:: tryillusionoff BS_ATTACKER + tryactivategulpmissile playfaintcry BS_ATTACKER pause B_WAIT_TIME_LONG dofaintanimation BS_ATTACKER @@ -5470,6 +5471,7 @@ BattleScript_FaintAttacker:: BattleScript_FaintTarget:: tryillusionoff BS_TARGET + tryactivategulpmissile playfaintcry BS_TARGET pause B_WAIT_TIME_LONG dofaintanimation BS_TARGET diff --git a/include/constants/form_change_types.h b/include/constants/form_change_types.h index 51325baf25..30bb54d027 100644 --- a/include/constants/form_change_types.h +++ b/include/constants/form_change_types.h @@ -120,4 +120,7 @@ // param1: status #define FORM_CHANGE_STATUS 20 +// Form change that activates after move is used. Currently only used for activating Gulp Missile. +#define FORM_CHANGE_HIT_BY_MOVE 21 + #endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index f80bebd8a2..6f57f87e31 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -16880,6 +16880,39 @@ void BS_TryGulpMissile(void) gBattlescriptCurrInstr = cmd->nextInstr; } +void BS_TryActivateGulpMissile(void) +{ + NATIVE_ARGS(); + + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && TARGET_TURN_DAMAGED + && gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT + && GetBattlerAbility(gBattlerTarget) == ABILITY_GULP_MISSILE) + { + if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) + { + gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + + switch(gBattleMons[gBattlerTarget].species) + { + case SPECIES_CRAMORANT_GORGING: + BattleScriptPushCursor(); + TryBattleFormChange(gBattlerTarget, FORM_CHANGE_HIT_BY_MOVE); + gBattlescriptCurrInstr = BattleScript_GulpMissileGorging; + return; + case SPECIES_CRAMORANT_GULPING: + BattleScriptPushCursor(); + TryBattleFormChange(gBattlerTarget, FORM_CHANGE_HIT_BY_MOVE); + gBattlescriptCurrInstr = BattleScript_GulpMissileGulping; + return; + } + } + gBattlescriptCurrInstr = cmd->nextInstr; +} void BS_TryQuash(void) { diff --git a/src/battle_util.c b/src/battle_util.c index efa1a3ecf7..c1f0ac89bf 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5583,34 +5583,30 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED - && IsBattlerAlive(battler)) + && IsBattlerAlive(battler) + && gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT) { - // TODO: Convert this to a proper FORM_CHANGE type. - if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GORGING) + if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) { - gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT; - if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) - { - gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_GulpMissileGorging; - effect++; + gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; } - else if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GULPING) + + switch(gBattleMons[gBattlerTarget].species) { - gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT; - if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) - { - gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_GulpMissileGulping; - effect++; + case SPECIES_CRAMORANT_GORGING: + TryBattleFormChange(battler, FORM_CHANGE_HIT_BY_MOVE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_GulpMissileGorging; + effect++; + break; + case SPECIES_CRAMORANT_GULPING: + TryBattleFormChange(battler, FORM_CHANGE_HIT_BY_MOVE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_GulpMissileGulping; + effect++; + break; } } break; @@ -10480,6 +10476,7 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method) } break; case FORM_CHANGE_BATTLE_TURN_END: + case FORM_CHANGE_HIT_BY_MOVE: if (formChanges[i].param1 == GetBattlerAbility(battler)) targetSpecies = formChanges[i].targetSpecies; break; diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h index 5edd6f42b5..8eb96e04b0 100644 --- a/src/data/pokemon/form_change_tables.h +++ b/src/data/pokemon/form_change_tables.h @@ -1098,6 +1098,7 @@ static const struct FormChange sSandacondaFormChangeTable[] = static const struct FormChange sCramorantFormChangeTable[] = { {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_CRAMORANT_GULPING, ABILITY_GULP_MISSILE, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_CRAMORANT_GORGING, ABILITY_GULP_MISSILE, HP_LOWER_EQ_THAN, 50}, + {FORM_CHANGE_HIT_BY_MOVE, SPECIES_CRAMORANT, ABILITY_GULP_MISSILE}, {FORM_CHANGE_BATTLE_SWITCH, SPECIES_CRAMORANT}, {FORM_CHANGE_FAINT, SPECIES_CRAMORANT}, {FORM_CHANGE_END_BATTLE, SPECIES_CRAMORANT}, diff --git a/test/battle/ability/gulp_missile.c b/test/battle/ability/gulp_missile.c index 680208506d..2ec9acc61b 100644 --- a/test/battle/ability/gulp_missile.c +++ b/test/battle/ability/gulp_missile.c @@ -116,9 +116,7 @@ SINGLE_BATTLE_TEST("(Gulp Missile) Cramorant in Gorging paralyzes the target if } SINGLE_BATTLE_TEST("(Gulp Missile) triggers even if the user is fainted by opposing mon") -{ - // See: https://github.com/rh-hideout/pokeemerald-expansion/issues/4143 - KNOWN_FAILING; +{ GIVEN { PLAYER(SPECIES_CRAMORANT) { HP(1); MaxHP(250); Ability(ABILITY_GULP_MISSILE); } PLAYER(SPECIES_WOBBUFFET); From 82b626aef1af4d1bbec3fd9c0fc000234c9bfd3f Mon Sep 17 00:00:00 2001 From: Nopinou <140268269+Nopinou@users.noreply.github.com> Date: Tue, 7 May 2024 15:53:09 +0200 Subject: [PATCH 02/17] fix and tweak level cap code (#4505) Co-authored-by: Baptiste-Lecoutre <59924283+Baptiste-Lecoutre@users.noreply.github.com> --- src/battle_script_commands.c | 16 ++++++++++------ src/level_caps.c | 30 ++++++++++++++++++------------ src/pokemon.c | 2 +- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6f57f87e31..7bb2390143 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4431,15 +4431,19 @@ static void Cmd_getexp(void) gBattleMoveDamage += GetSoftLevelCapExpValue(gPlayerParty[*expMonId].level, gBattleStruct->expShareExpValue);; } - if (EXP_CAP_HARD && gBattleMoveDamage != 0) + ApplyExperienceMultipliers(&gBattleMoveDamage, *expMonId, gBattlerFainted); + + if (B_EXP_CAP_TYPE == EXP_CAP_HARD && gBattleMoveDamage != 0) { u32 growthRate = gSpeciesInfo[GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPECIES)].growthRate; - if (gExperienceTables[growthRate][GetCurrentLevelCap()] < gExperienceTables[growthRate][GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL)] + gBattleMoveDamage) - gBattleMoveDamage = gExperienceTables[growthRate][GetCurrentLevelCap()]; - } + u32 currentExp = GetMonData(&gPlayerParty[*expMonId], MON_DATA_EXP); + u32 levelCap = GetCurrentLevelCap(); - if (!EXP_CAP_HARD || gBattleMoveDamage != 0) // Edge case for hard level caps. Prevents mons from getting 1 exp - ApplyExperienceMultipliers(&gBattleMoveDamage, *expMonId, gBattlerFainted); + if (GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL) >= levelCap) + gBattleMoveDamage = 0; + else if (gExperienceTables[growthRate][levelCap] < currentExp + gBattleMoveDamage) + gBattleMoveDamage = gExperienceTables[growthRate][levelCap] - currentExp; + } if (IsTradedMon(&gPlayerParty[*expMonId])) { diff --git a/src/level_caps.c b/src/level_caps.c index 81ffa7b090..61b4c8dc8f 100644 --- a/src/level_caps.c +++ b/src/level_caps.c @@ -49,15 +49,26 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue) if (B_EXP_CAP_TYPE == EXP_CAP_NONE) return expValue; - if (B_LEVEL_CAP_EXP_UP && level < currentLevelCap) + if (level < currentLevelCap) { - levelDifference = currentLevelCap - level; - if (levelDifference > ARRAY_COUNT(sExpScalingDown)) - return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingDown) - 1]); + if (B_LEVEL_CAP_EXP_UP) + { + levelDifference = currentLevelCap - level; + if (levelDifference > ARRAY_COUNT(sExpScalingUp)) + return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingUp) - 1]); + else + return expValue + (expValue / sExpScalingUp[levelDifference]); + } else - return expValue + (expValue / sExpScalingUp[levelDifference]); + { + return expValue; + } } - else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT && level >= currentLevelCap) + else if (B_EXP_CAP_TYPE == EXP_CAP_HARD) + { + return 0; + } + else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT) { levelDifference = level - currentLevelCap; if (levelDifference > ARRAY_COUNT(sExpScalingDown)) @@ -65,13 +76,8 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue) else return expValue / sExpScalingDown[levelDifference]; } - else if (level < currentLevelCap) + else { return expValue; } - else - { - return 0; - } - } diff --git a/src/pokemon.c b/src/pokemon.c index f1e8207470..9f8c7211f9 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -3531,7 +3531,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); dataUnsigned = sExpCandyExperienceTable[param - 1] + GetMonData(mon, MON_DATA_EXP, NULL); - if (B_RARE_CANDY_CAP && EXP_CAP_HARD) + if (B_RARE_CANDY_CAP && B_EXP_CAP_TYPE == EXP_CAP_HARD) { u32 currentLevelCap = GetCurrentLevelCap(); if (dataUnsigned > gExperienceTables[gSpeciesInfo[species].growthRate][currentLevelCap]) From b04d153a24858c25ad6f8d67e6dd163dac984b0e Mon Sep 17 00:00:00 2001 From: WillKolada <57021938+WillKolada@users.noreply.github.com> Date: Tue, 7 May 2024 15:47:20 -0500 Subject: [PATCH 03/17] Expanded AI awareness of moves that don't work against Dynamax Pokemon (#4521) * Update IsDamageMoveUsable to check for Steel Roller viability * Condense terrain flag checks and renamed IsDamageMoveUsable IsDamageMoveUsable is now named IsDamageMoveUnusable to more accurately reflect the boolean it returns. * Made the AI aware of when more moves will fail against Dynamax Pokemon Turns out Dynamax Pokemon are immune to quite a few moves. The AI is only aware of one of these at present--the Low Kick/Grass Knot effect, which I learned when the AI tried to Heavy Slam my Dynamaxed Pokemon. These additional cases should prevent the AI from selecting moves that have no effect against Dynamax Pokemon, though it may still select moves whose secondary effect won't work on Dynamaxed Pokemon (such as Fake Out or Circle Throw). * Update battle_ai_util.c Now handles damaging moves that Dynamax Pokemon are immune to --- src/battle_ai_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 009cef3bdc..4a83fc6e4e 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -431,6 +431,7 @@ bool32 IsDamageMoveUnusable(u32 move, u32 battlerAtk, u32 battlerDef) return TRUE; break; case EFFECT_LOW_KICK: + case EFFECT_HEAT_CRASH: if (IsDynamaxed(battlerDef)) return TRUE; break; From 432c4f233c7393a2eef16e209dbc3b3a26add508 Mon Sep 17 00:00:00 2001 From: sneed <56992013+Sneed69@users.noreply.github.com> Date: Wed, 8 May 2024 15:03:59 +0300 Subject: [PATCH 04/17] fix ai caring about fixed damage moves' resists (#4524) --- src/battle_ai_main.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index eb942b3712..92b2239cd3 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -819,7 +819,22 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case AI_EFFECTIVENESS_x0_125: case AI_EFFECTIVENESS_x0_25: - RETURN_SCORE_MINUS(10); + switch (moveEffect) + { + case EFFECT_FIXED_DAMAGE_ARG: + case EFFECT_LEVEL_DAMAGE: + case EFFECT_PSYWAVE: + case EFFECT_OHKO: + case EFFECT_BIDE: + case EFFECT_SUPER_FANG: + case EFFECT_ENDEAVOR: + case EFFECT_COUNTER: + case EFFECT_MIRROR_COAT: + case EFFECT_METAL_BURST: + break; + default: + RETURN_SCORE_MINUS(10); + } break; } From b3a4553860bcc6031153c851fa512c59fb97f832 Mon Sep 17 00:00:00 2001 From: sneed <56992013+Sneed69@users.noreply.github.com> Date: Thu, 9 May 2024 09:44:22 +0300 Subject: [PATCH 05/17] Dynamic Multichoice no longer plays sound on init (#4480) --- src/script_menu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/script_menu.c b/src/script_menu.c index 021f23053c..b78f1ef112 100644 --- a/src/script_menu.c +++ b/src/script_menu.c @@ -329,7 +329,8 @@ void MultichoiceDynamic_DestroyStack(void) static void MultichoiceDynamic_MoveCursor(s32 itemIndex, bool8 onInit, struct ListMenu *list) { u8 taskId; - PlaySE(SE_SELECT); + if (!onInit) + PlaySE(SE_SELECT); taskId = FindTaskIdByFunc(Task_HandleScrollingMultichoiceInput); if (taskId != TASK_NONE) { From 63254a8fdc1b71344258236b4a8db8fdc6f746c4 Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Thu, 9 May 2024 08:22:56 +0100 Subject: [PATCH 06/17] Fixes Thief and Covet used by an opponent not stealing items (#4506) * Fixes MOVE_EFFECT_STEAL_ITEM (Thief and Covet) * Fix stealing consumed item * Removed unnecessary instructions * Removes unnecessary check for item to trigger Sticky Hold --- src/battle_script_commands.c | 39 +++++------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 7bb2390143..5f4ed78aa8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3164,7 +3164,6 @@ void SetMoveEffect(bool32 primary, bool32 certain) } else { - u8 side; switch (gBattleScripting.moveEffect) { case MOVE_EFFECT_CONFUSION: @@ -3178,7 +3177,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) // If the confusion is activating due to being released from Sky Drop, go to "confused due to fatigue" script. // Otherwise, do normal confusion script. - if(gCurrentMove == MOVE_SKY_DROP) + if (gCurrentMove == MOVE_SKY_DROP) { gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); gBattlerAttacker = gEffectBattler; @@ -3422,35 +3421,13 @@ void SetMoveEffect(bool32 primary, bool32 certain) break; case MOVE_EFFECT_STEAL_ITEM: { - if (!CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)) - { - gBattlescriptCurrInstr++; - break; - } - - side = GetBattlerSide(gBattlerAttacker); - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT - && !(gBattleTypeFlags & - (BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_LINK - | BATTLE_TYPE_RECORDED_LINK - | BATTLE_TYPE_SECRET_BASE))) + if (!CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item) + || gBattleMons[gBattlerAttacker].item != ITEM_NONE + || gBattleMons[gBattlerTarget].item == ITEM_NONE) { gBattlescriptCurrInstr++; } - else if (!(gBattleTypeFlags & - (BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_LINK - | BATTLE_TYPE_RECORDED_LINK - | BATTLE_TYPE_SECRET_BASE)) - && (gWishFutureKnock.knockedOffMons[side] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]])) - { - gBattlescriptCurrInstr++; - } - else if (gBattleMons[gBattlerTarget].item - && GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD) + else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD) { BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_NoItemSteal; @@ -3458,12 +3435,6 @@ void SetMoveEffect(bool32 primary, bool32 certain) gLastUsedAbility = gBattleMons[gBattlerTarget].ability; RecordAbilityBattle(gBattlerTarget, gLastUsedAbility); } - else if (gBattleMons[gBattlerAttacker].item != ITEM_NONE - || gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY_E_READER - || gBattleMons[gBattlerTarget].item == ITEM_NONE) - { - gBattlescriptCurrInstr++; - } else { StealTargetItem(gBattlerAttacker, gBattlerTarget); // Attacker steals target item From d07d7a0082a84760382700b18a7cf85be844052f Mon Sep 17 00:00:00 2001 From: sneed <56992013+Sneed69@users.noreply.github.com> Date: Thu, 9 May 2024 11:11:55 +0300 Subject: [PATCH 07/17] Transform GFX uses the correct battler index (#4486) --- src/battle_gfx_sfx_util.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 31e4dcae2f..801e2f5fc5 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -900,8 +900,8 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo { if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality) { - personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY); - isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY); + personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_PERSONALITY); + isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_IS_SHINY); } else { @@ -918,8 +918,8 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo { if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality) { - personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY); - isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY); + personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_PERSONALITY); + isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_IS_SHINY); } else { From fcfc6b60f27447f15b052f1e2d0c6270f24c26ca Mon Sep 17 00:00:00 2001 From: cawtds <38510667+cawtds@users.noreply.github.com> Date: Thu, 9 May 2024 15:19:13 +0200 Subject: [PATCH 08/17] fix getboxmondata for evolutiontracker if compiled with agbcc (#4510) --- src/pokemon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pokemon.c b/src/pokemon.c index 9f8c7211f9..e7db64cd9a 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -2537,6 +2537,7 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) case MON_DATA_EVOLUTION_TRACKER: evoTracker.asField.a = substruct1->evolutionTracker1; evoTracker.asField.b = substruct1->evolutionTracker2; + evoTracker.asField.unused = 0; retVal = evoTracker.value; break; default: From dd0c3a9ee5ceda51ad1215fb994d97424c8bbf81 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Thu, 9 May 2024 15:22:48 +0200 Subject: [PATCH 09/17] Fixed moves with HP cost triggering effects where they shouldn't (#4533) Co-authored-by: Hedara --- data/battle_scripts_1.s | 6 ++++-- test/battle/move_effect/belly_drum.c | 14 ++++++++++++++ test/battle/move_effect/fillet_away.c | 16 ++++++++++++++++ test/battle/move_effect/shed_tail.c | 15 +++++++++++++++ test/battle/move_effect/substitute.c | 14 ++++++++++++++ 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 79ee6b4017..6f5cedd9d9 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -52,6 +52,7 @@ BattleScript_EffectShedTail:: jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_ButItFailed setsubstitute jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SUBSTITUTE_FAILED, BattleScript_SubstituteString + orword gHitMarker, HITMARKER_PASSIVE_DAMAGE attackanimation waitanimation healthbarupdate BS_ATTACKER @@ -76,7 +77,7 @@ BattleScript_EffectFilletAway:: jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, MAX_STAT_STAGE, BattleScript_ButItFailed BattleScript_FilletAwayTryAttack:: halvehp BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE attackanimation waitanimation setbyte sSTAT_ANIM_PLAYED, FALSE @@ -3834,6 +3835,7 @@ BattleScript_EffectSubstitute:: jumpifstatus2 BS_ATTACKER, STATUS2_SUBSTITUTE, BattleScript_AlreadyHasSubstitute setsubstitute jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SUBSTITUTE_FAILED, BattleScript_SubstituteString + orword gHitMarker, HITMARKER_PASSIVE_DAMAGE attackanimation waitanimation healthbarupdate BS_ATTACKER @@ -4568,7 +4570,7 @@ BattleScript_EffectBellyDrum:: ppreduce jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed halvehp BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE attackanimation waitanimation healthbarupdate BS_ATTACKER diff --git a/test/battle/move_effect/belly_drum.c b/test/battle/move_effect/belly_drum.c index f45418fe8a..bbaa910d27 100644 --- a/test/battle/move_effect/belly_drum.c +++ b/test/battle/move_effect/belly_drum.c @@ -90,3 +90,17 @@ SINGLE_BATTLE_TEST("Belly Drum fails if the user's Attack is already at +6") } } } + +SINGLE_BATTLE_TEST("Belly Drum's HP cost doesn't trigger effects that trigger on damage taken") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BELLY_DRUM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player); + MESSAGE("Wobbuffet cut its own HP and maximized ATTACK!"); + NOT MESSAGE("Wobbuffet's Air Balloon popped!"); + } +} diff --git a/test/battle/move_effect/fillet_away.c b/test/battle/move_effect/fillet_away.c index 8d770860a8..de203dbc5a 100644 --- a/test/battle/move_effect/fillet_away.c +++ b/test/battle/move_effect/fillet_away.c @@ -56,3 +56,19 @@ SINGLE_BATTLE_TEST("Fillet Away fails if user's current HP is half or less than } } } + +SINGLE_BATTLE_TEST("Fillet Away's HP cost doesn't trigger effects that trigger on damage taken") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FILLET_AWAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FILLET_AWAY, player); + MESSAGE("Wobbuffet's Attack sharply rose!"); + MESSAGE("Wobbuffet's Sp. Atk sharply rose!"); + MESSAGE("Wobbuffet's Speed sharply rose!"); + NOT MESSAGE("Wobbuffet's Air Balloon popped!"); + } +} diff --git a/test/battle/move_effect/shed_tail.c b/test/battle/move_effect/shed_tail.c index 5ff5746977..6f12d22eee 100644 --- a/test/battle/move_effect/shed_tail.c +++ b/test/battle/move_effect/shed_tail.c @@ -70,3 +70,18 @@ SINGLE_BATTLE_TEST("Shed Tail fails if there are no usable pokemon left") MESSAGE("But it failed!"); } } + +SINGLE_BATTLE_TEST("Shed Tail's HP cost doesn't trigger effects that trigger on damage taken") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); } + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SHED_TAIL); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SHED_TAIL, player); + MESSAGE("Wobbuffet shed its tail to create a decoy!"); + NOT MESSAGE("Wobbuffet's Air Balloon popped!"); + } +} diff --git a/test/battle/move_effect/substitute.c b/test/battle/move_effect/substitute.c index c40711f583..a2e4c686ec 100644 --- a/test/battle/move_effect/substitute.c +++ b/test/battle/move_effect/substitute.c @@ -54,3 +54,17 @@ SINGLE_BATTLE_TEST("Substitute's HP cost can trigger a berry") MESSAGE("Wobbuffet's Sitrus Berry restored health!"); } } + +SINGLE_BATTLE_TEST("Substitute's HP cost doesn't trigger effects that trigger on damage taken") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SUBSTITUTE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUBSTITUTE, player); + MESSAGE("Wobbuffet made a SUBSTITUTE!"); + NOT MESSAGE("Wobbuffet's Air Balloon popped!"); + } +} From f12773dbb8456a04edac588f0900b7a55c47d893 Mon Sep 17 00:00:00 2001 From: Bassoonian Date: Thu, 9 May 2024 16:22:17 +0200 Subject: [PATCH 10/17] Fix possible agbcc corruption for tree mutations (#4535) --- src/berry.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/berry.c b/src/berry.c index e66b106ca9..9f187bd1e2 100644 --- a/src/berry.c +++ b/src/berry.c @@ -2383,6 +2383,7 @@ static u8 GetTreeMutationValue(u8 id) return 0; myMutation.asField.a = tree->mutationA; myMutation.asField.b = tree->mutationB; + myMutation.asField.unused = 0; return sBerryMutations[myMutation.value - 1][2]; #else return 0; From e122ba28be6e3f3513afe31f71816368c5de1fcf Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Thu, 9 May 2024 10:22:46 -0400 Subject: [PATCH 11/17] fix battle script clearing specialBattleType (#4536) Co-authored-by: ghoulslash --- src/battle_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle_main.c b/src/battle_main.c index f09c8110a3..46b633d3e8 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3254,11 +3254,13 @@ static void ClearSetBScriptingStruct(void) { // windowsType is set up earlier in BattleInitBgsAndWindows, so we need to save the value u32 temp = gBattleScripting.windowsType; + u32 specialBattleType = gBattleScripting.specialTrainerBattleType; memset(&gBattleScripting, 0, sizeof(gBattleScripting)); gBattleScripting.windowsType = temp; gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle; gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6); + gBattleScripting.specialTrainerBattleType = specialBattleType; } static void BattleStartClearSetData(void) From d247a779278bdc72b3a6b15c95c939b47cd2f7ca Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Fri, 10 May 2024 23:00:32 +0200 Subject: [PATCH 12/17] Fixes Future Sight freeze/weird behavior (#4543) --- src/battle_util.c | 15 +++++++++------ test/battle/move_effect/future_sight.c | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index c1f0ac89bf..57eb560cd5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2973,6 +2973,15 @@ bool32 HandleWishPerishSongOnTurnEnd(void) { struct Pokemon *party; + if (gWishFutureKnock.futureSightCounter[battler] == 0 + && gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] == 0) + { + gSideStatuses[GetBattlerSide(battler)] &= ~SIDE_STATUS_FUTUREATTACK; + } + + if (!IsBattlerAlive(battler)) + continue; + if (gWishFutureKnock.futureSightMove[battler] == MOVE_FUTURE_SIGHT) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FUTURE_SIGHT; else @@ -2991,12 +3000,6 @@ bool32 HandleWishPerishSongOnTurnEnd(void) BattleScriptExecute(BattleScript_MonTookFutureAttack); - if (gWishFutureKnock.futureSightCounter[battler] == 0 - && gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] == 0) - { - gSideStatuses[GetBattlerSide(gBattlerTarget)] &= ~SIDE_STATUS_FUTUREATTACK; - } - return TRUE; } } diff --git a/test/battle/move_effect/future_sight.c b/test/battle/move_effect/future_sight.c index 6a163a736d..7ebac1ac97 100644 --- a/test/battle/move_effect/future_sight.c +++ b/test/battle/move_effect/future_sight.c @@ -132,3 +132,24 @@ SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints before it is NOT MESSAGE("Foe Wynaut took the Future Sight attack!"); } } + +SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints by residual damage") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(10); } + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(player, MOVE_FUTURE_SIGHT); } + TURN { MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_WRAP); SEND_OUT(opponent, 1); } + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_WRAP, player); + MESSAGE("Foe Wobbuffet fainted!"); + MESSAGE("2 sent out Wynaut!"); + NOT MESSAGE("Foe Wynaut took the Future Sight attack!"); + } +} From 4c5260c82ebbec03f990ff9ea2776525e34bc515 Mon Sep 17 00:00:00 2001 From: WillKolada <57021938+WillKolada@users.noreply.github.com> Date: Fri, 10 May 2024 16:01:37 -0500 Subject: [PATCH 13/17] Changed item descriptions to prevent text overflowing into scroll menus (#4540) * Changed Dubious Disc description to prevent overflow The first line of the Dubious Disc description was too long. A few letters would escape the box in the Bag and in Marts. This brings them in line. * Changed Ice Beam and Blizzard Frostbite descriptions These descriptions also overflowed, even more so than the Dubious Disc. --- src/data/items.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/data/items.h b/src/data/items.h index 04e578c3ca..1a5ec7ff65 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -3682,7 +3682,7 @@ const struct Item gItemsInfo[] = .name = _("Dubious Disc"), .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING( - "A transparent device\n" + "A clear device\n" "overflowing with\n" "dubious data."), .pocket = POCKET_ITEMS, @@ -9413,7 +9413,7 @@ const struct Item gItemsInfo[] = "Fires an icy cold\n" "beam that may\n" #if B_USE_FROSTBITE == TRUE - "give the foe frostbite."), + "inflict frostbite."), #else "freeze the foe."), #endif @@ -9429,11 +9429,13 @@ const struct Item gItemsInfo[] = .name = _("TM14"), .price = 5500, .description = COMPOUND_STRING( + #if B_USE_FROSTBITE == TRUE + "A snow-and-wind\n" + "attack that may\n" + "inflict frostbite."), + #else "A brutal snow-and-\n" "wind attack that\n" - #if B_USE_FROSTBITE == TRUE - "may give the foe frostbite."), - #else "may freeze the foe."), #endif .importance = I_REUSABLE_TMS, From 833decb0df5db7437edc526f2d033c465579b3ae Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Fri, 10 May 2024 23:12:09 +0100 Subject: [PATCH 14/17] Fix Mr. Mime's typing (#4547) --- src/data/pokemon/species_info/gen_1_families.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h index e8de1682c5..6e8a4324f2 100644 --- a/src/data/pokemon/species_info/gen_1_families.h +++ b/src/data/pokemon/species_info/gen_1_families.h @@ -12043,7 +12043,11 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .baseSpeed = 90, .baseSpAttack = 100, .baseSpDefense = 120, + #if P_UPDATED_TYPES >= GEN_6 + .types = MON_TYPES(TYPE_PSYCHIC, TYPE_FAIRY), + #else .types = MON_TYPES(TYPE_PSYCHIC), + #endif .catchRate = 45, .expYield = (P_UPDATED_EXP_YIELDS >= GEN_5) ? 161 : 136, .evYield_SpDefense = 2, From 1ef7e11ef22ef37a5edbeb754d0e78037c49e28d Mon Sep 17 00:00:00 2001 From: Cafei <46283144+cafei-uh@users.noreply.github.com> Date: Sat, 11 May 2024 02:20:25 +0400 Subject: [PATCH 15/17] Unown entry animation fix (#4546) - Changed all anim_front.png into front.png - Set PLACEHOLDER_ANIM_SINGLE_FRAME in front_pic_anims.h --- graphics/pokemon/unown/anim_front.png | Bin 345 -> 0 bytes graphics/pokemon/unown/b/anim_front.png | Bin 362 -> 0 bytes graphics/pokemon/unown/b/front.png | Bin 0 -> 385 bytes graphics/pokemon/unown/c/anim_front.png | Bin 403 -> 0 bytes graphics/pokemon/unown/c/front.png | Bin 0 -> 436 bytes graphics/pokemon/unown/d/anim_front.png | Bin 359 -> 0 bytes graphics/pokemon/unown/d/front.png | Bin 0 -> 380 bytes graphics/pokemon/unown/e/anim_front.png | Bin 332 -> 0 bytes graphics/pokemon/unown/e/front.png | Bin 0 -> 357 bytes .../unown/exclamation_mark/anim_front.png | Bin 301 -> 0 bytes .../pokemon/unown/exclamation_mark/front.png | Bin 0 -> 327 bytes graphics/pokemon/unown/f/anim_front.png | Bin 372 -> 0 bytes graphics/pokemon/unown/f/front.png | Bin 0 -> 394 bytes graphics/pokemon/unown/front.png | Bin 0 -> 371 bytes graphics/pokemon/unown/g/anim_front.png | Bin 369 -> 0 bytes graphics/pokemon/unown/g/front.png | Bin 0 -> 393 bytes graphics/pokemon/unown/h/anim_front.png | Bin 433 -> 0 bytes graphics/pokemon/unown/h/front.png | Bin 0 -> 454 bytes graphics/pokemon/unown/i/anim_front.png | Bin 311 -> 0 bytes graphics/pokemon/unown/i/front.png | Bin 0 -> 332 bytes graphics/pokemon/unown/j/anim_front.png | Bin 342 -> 0 bytes graphics/pokemon/unown/j/front.png | Bin 0 -> 362 bytes graphics/pokemon/unown/k/anim_front.png | Bin 354 -> 0 bytes graphics/pokemon/unown/k/front.png | Bin 0 -> 369 bytes graphics/pokemon/unown/l/anim_front.png | Bin 321 -> 0 bytes graphics/pokemon/unown/l/front.png | Bin 0 -> 344 bytes graphics/pokemon/unown/m/anim_front.png | Bin 423 -> 0 bytes graphics/pokemon/unown/m/front.png | Bin 0 -> 437 bytes graphics/pokemon/unown/n/anim_front.png | Bin 385 -> 0 bytes graphics/pokemon/unown/n/front.png | Bin 0 -> 406 bytes graphics/pokemon/unown/o/anim_front.png | Bin 426 -> 0 bytes graphics/pokemon/unown/o/front.png | Bin 0 -> 443 bytes graphics/pokemon/unown/p/anim_front.png | Bin 318 -> 0 bytes graphics/pokemon/unown/p/front.png | Bin 0 -> 345 bytes graphics/pokemon/unown/q/anim_front.png | Bin 327 -> 0 bytes graphics/pokemon/unown/q/front.png | Bin 0 -> 350 bytes .../unown/question_mark/anim_front.png | Bin 339 -> 0 bytes .../pokemon/unown/question_mark/front.png | Bin 0 -> 366 bytes graphics/pokemon/unown/r/anim_front.png | Bin 319 -> 0 bytes graphics/pokemon/unown/r/front.png | Bin 0 -> 342 bytes graphics/pokemon/unown/s/anim_front.png | Bin 373 -> 0 bytes graphics/pokemon/unown/s/front.png | Bin 0 -> 386 bytes graphics/pokemon/unown/t/anim_front.png | Bin 323 -> 0 bytes graphics/pokemon/unown/t/front.png | Bin 0 -> 350 bytes graphics/pokemon/unown/u/anim_front.png | Bin 397 -> 0 bytes graphics/pokemon/unown/u/front.png | Bin 0 -> 424 bytes graphics/pokemon/unown/v/anim_front.png | Bin 358 -> 0 bytes graphics/pokemon/unown/v/front.png | Bin 0 -> 384 bytes graphics/pokemon/unown/w/anim_front.png | Bin 363 -> 0 bytes graphics/pokemon/unown/w/front.png | Bin 0 -> 379 bytes graphics/pokemon/unown/x/anim_front.png | Bin 344 -> 0 bytes graphics/pokemon/unown/x/front.png | Bin 0 -> 369 bytes graphics/pokemon/unown/y/anim_front.png | Bin 355 -> 0 bytes graphics/pokemon/unown/y/front.png | Bin 0 -> 379 bytes graphics/pokemon/unown/z/anim_front.png | Bin 332 -> 0 bytes graphics/pokemon/unown/z/front.png | Bin 0 -> 343 bytes src/data/graphics/pokemon.h | 56 +++++++++--------- src/data/pokemon_graphics/front_pic_anims.h | 8 +-- 58 files changed, 29 insertions(+), 35 deletions(-) delete mode 100644 graphics/pokemon/unown/anim_front.png delete mode 100644 graphics/pokemon/unown/b/anim_front.png create mode 100644 graphics/pokemon/unown/b/front.png delete mode 100644 graphics/pokemon/unown/c/anim_front.png create mode 100644 graphics/pokemon/unown/c/front.png delete mode 100644 graphics/pokemon/unown/d/anim_front.png create mode 100644 graphics/pokemon/unown/d/front.png delete mode 100644 graphics/pokemon/unown/e/anim_front.png create mode 100644 graphics/pokemon/unown/e/front.png delete mode 100644 graphics/pokemon/unown/exclamation_mark/anim_front.png create mode 100644 graphics/pokemon/unown/exclamation_mark/front.png delete mode 100644 graphics/pokemon/unown/f/anim_front.png create mode 100644 graphics/pokemon/unown/f/front.png create mode 100644 graphics/pokemon/unown/front.png delete mode 100644 graphics/pokemon/unown/g/anim_front.png create mode 100644 graphics/pokemon/unown/g/front.png delete mode 100644 graphics/pokemon/unown/h/anim_front.png create mode 100644 graphics/pokemon/unown/h/front.png delete mode 100644 graphics/pokemon/unown/i/anim_front.png create mode 100644 graphics/pokemon/unown/i/front.png delete mode 100644 graphics/pokemon/unown/j/anim_front.png create mode 100644 graphics/pokemon/unown/j/front.png delete mode 100644 graphics/pokemon/unown/k/anim_front.png create mode 100644 graphics/pokemon/unown/k/front.png delete mode 100644 graphics/pokemon/unown/l/anim_front.png create mode 100644 graphics/pokemon/unown/l/front.png delete mode 100644 graphics/pokemon/unown/m/anim_front.png create mode 100644 graphics/pokemon/unown/m/front.png delete mode 100644 graphics/pokemon/unown/n/anim_front.png create mode 100644 graphics/pokemon/unown/n/front.png delete mode 100644 graphics/pokemon/unown/o/anim_front.png create mode 100644 graphics/pokemon/unown/o/front.png delete mode 100644 graphics/pokemon/unown/p/anim_front.png create mode 100644 graphics/pokemon/unown/p/front.png delete mode 100644 graphics/pokemon/unown/q/anim_front.png create mode 100644 graphics/pokemon/unown/q/front.png delete mode 100644 graphics/pokemon/unown/question_mark/anim_front.png create mode 100644 graphics/pokemon/unown/question_mark/front.png delete mode 100644 graphics/pokemon/unown/r/anim_front.png create mode 100644 graphics/pokemon/unown/r/front.png delete mode 100644 graphics/pokemon/unown/s/anim_front.png create mode 100644 graphics/pokemon/unown/s/front.png delete mode 100644 graphics/pokemon/unown/t/anim_front.png create mode 100644 graphics/pokemon/unown/t/front.png delete mode 100644 graphics/pokemon/unown/u/anim_front.png create mode 100644 graphics/pokemon/unown/u/front.png delete mode 100644 graphics/pokemon/unown/v/anim_front.png create mode 100644 graphics/pokemon/unown/v/front.png delete mode 100644 graphics/pokemon/unown/w/anim_front.png create mode 100644 graphics/pokemon/unown/w/front.png delete mode 100644 graphics/pokemon/unown/x/anim_front.png create mode 100644 graphics/pokemon/unown/x/front.png delete mode 100644 graphics/pokemon/unown/y/anim_front.png create mode 100644 graphics/pokemon/unown/y/front.png delete mode 100644 graphics/pokemon/unown/z/anim_front.png create mode 100644 graphics/pokemon/unown/z/front.png diff --git a/graphics/pokemon/unown/anim_front.png b/graphics/pokemon/unown/anim_front.png deleted file mode 100644 index 065d82a47f3984b13056967a594cef08ef19a7c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3BLr z?;7ibk750=0$)bt)AS;TA6wjuC;hDPwQW}5Xab>{&urSC WBWn1sOi=@Rk-^i|&t;ucLK6V?WRi;j diff --git a/graphics/pokemon/unown/b/anim_front.png b/graphics/pokemon/unown/b/anim_front.png deleted file mode 100644 index bedc986348d3b6a510adc3448411d580f144e0da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 362 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3#6F6VsZ+uIXnWFWUrLCuiad#k@;!cjQtngIwJA0c-*u-!~ zq4a{c3`)rpU%#+PPF(jlXSGlCjN&cVs-h;mzPZes^<-dE!EMvyY}4j_`0(&Xg~${q z&IcPx?+8n=)p^c+d@ziA@|5<2KM$m=Wjxl`9kn%rHGJBo`>(=gbv?a?yjkz;8#@&^nn38!G1-M|;XT{s;{O5t%;4$j=d#Wzp$Pz|n4voW diff --git a/graphics/pokemon/unown/b/front.png b/graphics/pokemon/unown/b/front.png new file mode 100644 index 0000000000000000000000000000000000000000..427eae3e068e43ffb53962f0801f4c362af80719 GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC0a_l>-z~dUJ zSh(J8r-N}&xsDZIjDqKPjx&s>4&=TLxw@uc(YwFfZ1&}D2x>ZTiQ&PEJqk&723}G8 zyu#O*9vDWut$6%<-SI=LI;XZIO-)vM72)IB6J{*<-My@FmyS;h=hD`~`AteyO>%2@ z=kRJcU61SiwW0LP;j76Z>(qA~ZFy_yYag;$`;5wyhi37yZF!xRv!*Op_t85)Q_#Rq z!1Kde{fwT&pY#~_8p?A1@b*=Ewp7-)z4h3gr0+35b8M9y9@$O47k)W@t@L)jU2ajV zE_w~K7I57E)|znPx7HW+Km8B#>vwsa4r~YtxZIliF}Wq#@!k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC?GW>H zaSVxQeLK}V?}!19^X3hjpZ|%kbFmgqXkePuye=zmlcZhk+MVkb13`<2$L_Ko%{;|B zd1=2n`qH*(Ef6UEFKjAc+Vtn6YWlYof`{JkS5IeW3RFJuSGny%nslT}1yf6V{@a;N z9FYu*7$?|AZQw{SW92hVXxabuo{8Ji2`oR@?*7wDTsnd628)JW;=JZE!&s&q76;A^ z%w7i_FHYb(@VZR<81IFkr;LH-QQvF-O_@-4U1~>L`|i%LsFXDeU2j;roqj)oA*On9 zdP7HiO}BRI&nYFLUDp-X@FzZ=bw==q`{KvvJdf0}ZtFMN*8j2nz>E9c_O0H>Z$xRE zf8hSerqHsNNo3uH`;42+ACw>R{(te}Mf*$qKbG-X&3K!=1sHk^p00i_>zopr0252d Apa1{> literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/d/anim_front.png b/graphics/pokemon/unown/d/anim_front.png deleted file mode 100644 index 7491a13fbbc6fcf8b1561916969deec4b6761a7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 359 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3Obxw|1u&CPQ%)Fo-xf`uY7~Svw4U4n;?=VHEMNW-T|H;Rb(#wyZkWyF5 z-@~2Kvrd1FXQ=XqCZ;2GN2Z;4bP0l+XkKcyOIg diff --git a/graphics/pokemon/unown/d/front.png b/graphics/pokemon/unown/d/front.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e6521a8ddb10c3d29541f5d6d29131250917db GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC97Kai|mJn|NkF$C0+94y|DJ)l&AC51#;fL0D|2ij3IxV&O|wAY~*<= z=(TBzt46e7iJ}pM&wOPgmLCTlCNbPSSO2{an^LB{Ts5T&1)q literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/e/anim_front.png b/graphics/pokemon/unown/e/anim_front.png deleted file mode 100644 index a761cdd95a0e1e2dd2c94b138cb3acd8c9ef85bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3!p{nB#O_OySu5pmdizwBPbzF z;X?n51Ww+!+;`&|pPg91xHK-+BjqEnB2%|W(!9pjIE|VA?ryu_Y;x?(6@d+(pQqee zyL^viYOaCJ+POLxYghBeP7_hH7I#dJK36HF|5j+#vptK{Rx9)s_?TXP6%cT=so=^f zVLOkjmFG@8Xz2ds{^9W(Z;>rLCzdAv+5GBU0jHw?3kX?E;{TW!Ug36mX&2B}44$rj JF6*2UngApRkj?-A diff --git a/graphics/pokemon/unown/e/front.png b/graphics/pokemon/unown/e/front.png new file mode 100644 index 0000000000000000000000000000000000000000..78bba2777177d1484f859f5dc7590ba205647282 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<&Jy0 zIEF;DzMX0*cEo_gIW}S1@AwJ^>y@&G`k6m$H$~XGT{byeJwsAG!)9Ve!i=WM9l8pP z!TryjxY(lae>lz*XX(0n`o~RC9a?vU8MKbDWcVnqc<|45!ZVd)RWp?>CV%+gp|Jh9 z#{G1$?+dbJ`tP56w3M-|HPzA8@AHk_%2Es0ct5yk_4HN6(;3SYG;^k|kcl`FePG9h zV<8s|`1+Mzv+m+~xK~L2?TKfhdZ(_7zqDuCx_Mu<XfoO7iQ1HHuH>FVdQ&MBb@02=P300000 literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/exclamation_mark/anim_front.png b/graphics/pokemon/unown/exclamation_mark/anim_front.png deleted file mode 100644 index 96c436e8c87966634bb7445ac63063b033d0b0e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3sHU-_t?VgvW9w^aGZJF-r|Qwf3<$B z3a~!x+47-YQB{w_A--p(ZbtuIwuEHHL}9Uww^Ix!b)5hDR`7JwOm+SQjc*30XBnj~ zj9oPOMMuMpz4K}#GuUkA?4GFksU_CFZPSHkz9$a7t75R>JRxX(;JdD7s2#`3E26G} dB0%)?gt(f$Z?Wdk44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC`=f8g3`RsRdG}m`qhouL5lcevkd9U2H q!t$BE$%SBpn;H`T5_C>~QnKU7=8SFbs@wx~G=rzBpUXO@geCx5YK}Mn literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/f/anim_front.png b/graphics/pokemon/unown/f/anim_front.png deleted file mode 100644 index 1c968565924d4f9f8320066c89d6d99cd30046e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3{dAc};M6|x0Y{=Jaz~eeo zsc=2lE#{VWJXd(DwO{ldxT$HeJ=bZqU*|-tl25|Xb^o>}Pfl(6p#3xG^YfNHO>KPQ z=Mppob(0;J#_}Xjk44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<=%L@ zIEF;DzMX0*bl8ByHCAET?|6%xZRtjuEVD}f{IgYd_*CkvHu>az<)(@j}Gq~xt876`NIaW1zUKM{(M?c9%MAz_A1k#-yKU#S2S`Sh~5?1%M`}2O3~|q zc{Ee@+=VAJKRkM?Aj+t-tG^)GV>jgYTuK19d zuxLrZDeX=}YtK_*D|bxTSa<$a;^U;`-+K3%tVA2$$Hy;XT6XKhK9(uvKO71wS`Mp~ z-9Owu{jd0o@He5GZeRGXf5YGP7u&>&-rwyVKV^Ljjb{3+`pIzQ5ck=jQ;VX2{$}uW L^>bP0l+XkKk2ATZ literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/front.png b/graphics/pokemon/unown/front.png new file mode 100644 index 0000000000000000000000000000000000000000..e47b643588b78ec9947aced270b04b905fa5eac6 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<*s_V zIEF;DzMZ;J=&%8YvvES>zyIyrNA{+PIj;}TKD8)a=fKW&ix)4p7qt8``|)mu3LZv7 zW&Aw#Dvq{blR1!g9*|En9h}aFlSb6BBU|pYU9Go+$@QTR3A( zLl~1#Kv)aUiGR0?R)p{1Y!>(~#dGUM%bcXj31*1~r?z$**YhR6W71~4dY^yMwPv9= zc2RY~Tn&Cs>`O#vwum{oPGFoBI?anS*5PytLtwbWKAuaHzpayr;@sQ&JDBUCp?#9_ l$Di{Z{%)0#mHj&@PW=Q|;=!zs(}5mj@O1TaS?83{1OPp^pELjf literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/g/anim_front.png b/graphics/pokemon/unown/g/anim_front.png deleted file mode 100644 index 028bd4caddccba999a3c1d6bb66ad2b1e3613539..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B39h^$H6CME7iZvMCD+P*gP`mc*Sziv0!qyGD-**VF2aV3r4$EJ!c_&#Um z>~}9_c3PQlbx8Dd*qfzVW4X>hgqQigM9h=cj0?sdoyX>UVLG?;Z`HDOyDbds*?&sz z&sR6hxVYTv9Osvcobv*4U*zi6KYnfXy79RzoxJdsyL0tkyZMWR&3Rz= yc>3eV=K|{k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCn8p}iHvMA)wT;_4` zM&Q1#j3X**zAf%O$FhOLLgUy^b4K^xJFSh$ZtIyi97^=6g}ihax=-Bw64Y|V?&3%D zx7Bl{_jfz5oovssSLhx`w(=Wmj(HoFZDc<1f6lc3FJ8P*|Hbe!jl1QC;aq#5w;4QL L{an^LB{Ts51*Nz) literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/h/anim_front.png b/graphics/pokemon/unown/h/anim_front.png deleted file mode 100644 index 686e70d4bc43a98cc0fb7880dc31e361a9fae9ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3Sc9@$&Mlf=)aapdl)ZmO?U$d^X3i94QViGVFRh&_b!rFa z`I;|3-#(sZl`^$q@7J%4*{_!9_I%j2VO_w?1M&5ooc;%_?w=L9Q{hnaTy6Hf6p3&C z+agP5C*E*>kovlL(#KP#Z;wiRJ(1M8am_MWmq{M`o+x}NWtaOX!f>Yf=h^OE4KcOs zm6H_}gqkOwu~(OIE!zCI{Fy5Uk44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC?a=Ua zaSVxQeH(gOh*^>2wPW+2|NP>W8M`ktzmdzMZ-l63jt0otq)J~Z#x7!{)|6(Rixr)dLyTAYtE!g8$aHBWUSB1 z%J)w|eM?)%8;u*@p31#vn*On?Z)c8HeSDr{n$x8w@lBrF?n%cK{ZnJv#`v(Dbz7?o z|C-fHqb~pA5#s-)DcRKTw^*c({Yq26$?JyFze|!@8tS|`A`Z{8jZ&Wy{b5aMMTfvj zfg~Mcbu+hBJ%-=9?C+0SFJ1sssEAiTVwSN^-1@8;@1bRI+Z_IJfz~a?a!D*EtH?{{J{N7@q zbz+BaNQ~_ADVmFqGIl7vnt6{;Yu+P^@LZ*dN&DAai&K0oD);M|uS52VptrAd^iE7# zdwL2(k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<<@z+ zIEF;DzMbkQ8RP=P^1S&)6EZ_PvYTud{`c5BBgJFjUZE zW)QM!4`NpF^fQVsIHzu7%poWd$7s}nSAT{}4DtNr?{)>r%Yx71XI*%N|$tm37QN-dbO`rp>>YT+-nHZjjX wHjBUf6T0nn!|(r0{EUxtxT4lxi+{;_ypnxp`Tw)JK$kOky85}Sb4q9e0Pv!bQ2+n{ literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/j/anim_front.png b/graphics/pokemon/unown/j/anim_front.png deleted file mode 100644 index e2906d253ad55fa381be13024edadf5641de5df0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B32S6Jq;;pbA1E!7RVfE^q;OIv^Tfo?>fy%dGWjJ|9!GwJw@S<^jklc$9E~YPrM-%4uEo7HpQUQPeW7%w-CO1Sf3RtRrsklg|Bh6JlGMpSk44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<<5Az zIEF;DzMWz%bl8EzId((R&i}2-3g?!@TKc91Jas!CRd?M~s@Ltm8pHWNw__DqrtV)> z|GwDah#uol!Q%|O&eTp1|2(_WeL?isbk1#4>>0n@jtUbEV7jp1D?mvg;6J~Gu}1@! z0QU+GriS;+M59@r>`pwr&~D+Z_T3$NUp9K*&z&N+aMyWL2i-{q9{EhyBfivg+)^-S z6#VWg&^jr{ze&dak)*0sY0`>FVdQ&MBb@0H4aC?EnA( literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/k/anim_front.png b/graphics/pokemon/unown/k/anim_front.png deleted file mode 100644 index b83ef195f4fec750160be45199c7588eff6ff820..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 354 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3nc)B=-M6|x0WXN~OfXCI? z_0`@0ZgvkrY3I&M%nFD4Zq47@@?_hRwKpEQF}dx(>VJRQ*Vcp??>k#7OYOy54zF+0 zS*yXlPT|Ok?av#cd7M^Xh&bcD!Z$IUu|l!uEZ5b=h4+?lSUwY8)jl^wcEQ;>lWt$I zSQ;{`$tuxavwrPEXFCU$-!@yPiy1y+b~&)rbh85sNAtTC(?wmH4jRa3)=GS8YIz;< zw~6nkJ*T8WM)KXA@|_)W68SGZifn`r<5 diff --git a/graphics/pokemon/unown/k/front.png b/graphics/pokemon/unown/k/front.png new file mode 100644 index 0000000000000000000000000000000000000000..23e68bc5f60b84da67697a11c18ec9f300ea7e9a GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCq?=5E-pR1l(loh!-o=! zR2|d>jNQ5=G}m5ac;f8vBwzA@Z`16X`xweO&$C`S&hY7}lEYae!RyisCEasa})hwAOJ|_Wt?v8|Xa-Pgg&ebxsLQ0R4WYyZ`_I literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/l/anim_front.png b/graphics/pokemon/unown/l/anim_front.png deleted file mode 100644 index 9d8b23af4de65b49dde198bea77b249b298db86f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3+<8C4A7(A?Q7BVb|G<)C3P z%|GN&MV-gw;BB6QVUorTzJ|iS34xn(k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<#u_x zIEF;DzMZmL=&%6?OXvdTfB)OhCWkEfvhsw=VY794wH`OJc@G=>v3h!%!Z|yNx_`LfB-+ER+`Umw4CQuhQ|rpKT5o=aPmW5=^rVgK>PJ37}}b)1&x zE^d@(`niq4)G6<9tHL^`DRHc?Qy=}yO8vlWd!+FUKhQk_{0|m!gnQ3=8UgeLgQu&X J%Q~loCIIqTpq&5! literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/m/anim_front.png b/graphics/pokemon/unown/m/anim_front.png deleted file mode 100644 index ee9c7c7a83b535582032abf2a6083cf55565e5c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3pQ-g9FJ|eJ5ltI?K6|p4xAgcS`>2i?pT{^x+?FOrxd*6h*Ionhr~8x zjtiHRCU_UR`ic}N%{nCTVa3dFj||Cx$x%+Hxj2s=UcB4BTFhh0e7U;ySLP)>SKO$n zc&lK>>5|(E-cJ#DoBUPNZrW2xIjw~a0n4WU=4G5?^xDzl)Take#haeAeil`n)AI7~ zB_$4yPi+&9i!SWrHceK`Rb0^jljAevvslR~(q9Y1s*n5)aP#Gj&rN<@5D^&NA$Taa zR;Q)z&hrXc<0Iy08$0&T?~6Z@U?9Q6)_gGGhx!ku29k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC?GX2L zaSVxQeLMAF(P0A)m)Z$pKmN<>DHL3}t#v%idZxw4jQN5Je{8~m;J?c>t8I)L+n25R zx1Rf<{Gx*0eTs|z748(5+OFwPAyD@B#G!l@g=?=nzIKTGC|A1Tae&#oK1cFrhyv#t z`<%t!y1A@5<9}S|^W$8<|MZNGGdweod|TZY>XOaGYLNSX`2^nuP6iVrw*Q&fq~>DE zc|fe;_whN(w;T8mGKx0*PG9x;IMWt}pEb=DJgf_5{bWsHFl*#_$ldV%_Sy@<3}y#r zG(FZ0*`Ff3XtG9ogV)aZa7opfZ(LTaTCe!vvTltm!`0I_q|U2es;g4j+nfIDwZ;U- z9QJbGEweb-k5^_#F1hBv`0xAf#vPTVrKMk&e_`&uAaE_~h7T(+_!vB0{an^LB{Ts5 D>V3*_ literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/n/anim_front.png b/graphics/pokemon/unown/n/anim_front.png deleted file mode 100644 index 47cac4516b9620a1958dc272382801ac406cb826..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3Y;jP5c^@%N}pI_<@;ow|igh>xI4#^IxZ2TBiAo+3csRz#;w~!($q!<}c{#zW#pY z>%)fc{2rhG<0|0Qe{jdHwrK^YIo2sK9gmsDq80IsvoM!~-^=8ChsVK)K!#|)oyXpG zv>o`q1Ld4U$u`Gi!y7O3 zR(DBr917BX#2#O?@Pi&_umSVBm^3y&b&fmpTO=MgWoK|st2RybGVnMQW+i`6|E#ZY z%ioVVtNtinx_7bp!2QgTe~DWM4fcG0bL diff --git a/graphics/pokemon/unown/n/front.png b/graphics/pokemon/unown/n/front.png new file mode 100644 index 0000000000000000000000000000000000000000..92ce38f9220024c8466c9b7a75c4a5faeae34a64 GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<$id& zIEF;DzMXQA@2~-fbFl*3|Ns2@4!7QJ@JzAh^Paj&tIndOq$h0k)vQ|8O?y7P_3B#m zZ2EU?%`m15F1pj#X&lMbV!rd9<&u+lQxt1N#C2sUoku(iP9J(qXw@PshVG>M*nd`9@T6`swM%XW(9~bXuZH@ZBn*Bx! W&$ov=Iop9@z~JfX=d#Wzp$PzRPqoPa literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/o/anim_front.png b/graphics/pokemon/unown/o/anim_front.png deleted file mode 100644 index b32cdb325000c1fc57f395df669fbf991402b5c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 426 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B30w#_?iz|(3g zcwukW6Q;t(ytq|f;vJ<7&da{JEy#-wTCK@=_otfjpFck)KTkEB*;aJ+{beh~Yn+N- zB_C=eW(zm*t-0r}#>N&tsa!GXqV9`{)r?Jf56^A+JS&H37pwFa(;IHvf21;7@k?ezE;zyM_MboFyt I=akR{03M#eG5`Po diff --git a/graphics/pokemon/unown/o/front.png b/graphics/pokemon/unown/o/front.png new file mode 100644 index 0000000000000000000000000000000000000000..979e7ca0bfd93660a725de7c991b0168add8b3e1 GIT binary patch literal 443 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC?U40! zaSVxQeLK~f>4*Y{OR$E;_x&F}876IiFiktO>rC<^mYR9d+w<<85@AsKzQxN;~e&({Xne;qdwAM=ROvLaBo+8&Re$`q+ERM zITtnNwR~g?R64R(#PJG;^`kdcOFBOOX!^GLZAk6wYisRS^Xokl7PU)0<^v2w22WQ% Jmvv4FO#reY#`FLH literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/p/anim_front.png b/graphics/pokemon/unown/p/anim_front.png deleted file mode 100644 index 01aa0329c7bd36a01791187803acb28bfa73fc0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3ICy^7`dP%FRCL>D!>y8R_Wf7==hvqsi##pA;<;}3zFBTfPo_CJ zJmPJiCBER3VDSq^5xYbCl9e@;zATkaR|(s3^y+W!`-h)iij_~Ez_NdmIE#wEr+`k- z_bE{~c)!=4IK$0Y8gINQ` diff --git a/graphics/pokemon/unown/p/front.png b/graphics/pokemon/unown/p/front.png new file mode 100644 index 0000000000000000000000000000000000000000..2f0820946f4f3ad43380294f93451aa9f873f7a0 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<#v0z zIEF;DzMX0)cG!T!**Jmm`~CvfZx^-}P5-t~v)hhI`gx_>;)^f-PdzaAzKy3xkx9TV z_OpSL1SG$-3k!c$6>!+UHCAnky}vY5;_qBt=W8-{>{IHuE^s+<yYcC53@F0cih!c>C~}$!dDrA zz)RO|?#emqP!r%2_0YT_o~eNMLfpc9rcXj2V*Z7L93=jgDRe7G6+_g;cAz&HJYD@< J);T3K0RYpwocjO( literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/q/anim_front.png b/graphics/pokemon/unown/q/anim_front.png deleted file mode 100644 index 18c930e696212d3c414d5735c41067434344eb4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3vOJ8N zp0e7obZOK$$P|5aauGkASH%)`Kv6o`#-6!wjlS9r` z(|D!{N1d4b^8FwCEgUC*PVl~L7%bM1+sY-jetxhtsREzt|d*E*id9UXY&+i z^T$>DR=Lz&E}v@J$&~xqH6!qyL+n$&u0k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCm^p2x-V$&Mw zO`8PYdT%+)7v_I)Amu%db&7~wRLB!Qs z>E*th0>+~oh3A(rH+^Qyd%kSi-7fAIM~}?hXZ-X@?SpNx%m3&rIh{YN*dP_kF;SAu zp)cL4**)&3gj^@r*0YDILK@m0>=&0ZHff)uw4eRtf~FP^Yl-ew`}8Nz^BYZnq_}^O z{dMz`(CpqVF80SmBRbEDb$3pwkdtT3jDPXGdd0?j_3!NTmu}LZF=vj7JIj)XWwM@& zZ1m2}Jt0k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC=KaRfo^TS3ewVq+e z|5i4+t_SXU9UJVUIfO6G*L5iN*k3KDIGKSXuV~MC2Hs@R0_6q{Iprt)0uJXEypt7t zCd}mWbd&C}LT(W!!7|R<8Fy`Neyl4{{>tu|t(+Jh_qm6KAAI*}}+wxl?%w*I&%#I?q_jM^#2gi8_}XDJS8YO;^9mmr{XqV_RANZ*9k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<#u?w zIEF;DzMWzzc2t3fS+l3-ef`4<&xuny?*9?@U+*|0wP#u8to{VP0)cqOwI6n@nAUW< zJ7tbZh@G2*RLq0QnZW{!Z-|A|sU>LbP`GZsqI>~Mt_qT5<rtb8GtKO}(67}Og$+Av^A9KP%bfM>{|<(aX&kNPA}7xP{lMVq>gTe~ HDWM4f`Cgf& literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/s/anim_front.png b/graphics/pokemon/unown/s/anim_front.png deleted file mode 100644 index 17016ac1ca23f7fde4a1d1ee2502c433925a6825..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3{d%8G=M6|x0Vw=aJ$kV#q z=~0|y? zYPz#Cp@G{?JLEz1%89BLUQ1bHn0xg(ryi44X|z9X(rq2^m+{Q+69+clZ!q+~_?=fF z?&+7Xa~{DtwR@lZG|1EcE@1b}^v=EO=ihtJ;*R3~F44hYdgK)AYkpnE8qdkOc`k=0 z7@l0*ebdm4=aEQ(cI~|*%B>c)0-HZ;a!)*2y;EYnQE!p#N+0h(##5e7eZBDX>bU7^ zWcKRCSH#o_*fst;YVo!^kd-_Cq5;ogAgWOP$8hmk44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<(_!D zIEF;DzMXcE>97Kav#r96|NkE*zIhkD>Gqk0Z&lZGH1!phmVRwyxGXhs1#d&y7`CKK{mT`hBvjfA`AkCMw3(2_4uzsoVL5`@`=aOC9*HygGRT0}q4oWJQjKxbo;?%Z3?Ke+l_C zGI6DS>XfM8nH|?2C0yE8y!u>1u=Jz5To<+#Go5!4;8fPEi&Xx1bH*|St;Vi%VCOwlq%Fd(S7#{wAiFoWr9&1bPZ+t-iGI+ZBxvXXdb&7KSbTt4XOGPRu|H-4JNIS_sh;&cz3H^>_0pyf=2I+ZayHg}x!2Ah z({f;{u-648uS6v&?$Y1YOutt;>`Z=kPJidNBbuLHy_B1M(2B`pi|adQ!#S>Umklgk ztQ6lw#lP%1J*(}uQDoEx)xFYZIRv(L_Bbf=`Rh3`e*bl%SMSiH70GNxXU;Jm%kc?Z z^=~S_&(*U{f7k5dD}656{QcSH=S>P6AoL+SPWn?&#pZ?rFQ8`_JYD@<);T3K0RV`t BjgtTX diff --git a/graphics/pokemon/unown/t/front.png b/graphics/pokemon/unown/t/front.png new file mode 100644 index 0000000000000000000000000000000000000000..ed02d17e1e3c9f53e98b63f2e66da318075c2d76 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCe1bF9-g$di4tx5+w)DnYPqO1cClS6 zPS|}>ccF*sr9)4Z?@q5jzrgzMa$Y62l7D?SH##k7JzXo_sJrLOzSFBt$ko40W?9fI zy<^@twZ6bDyk7f--Mk8#YwkzvVLPF~z2WQ}RR*?u+r1+ln_tY%zopr0L99o_5c6? literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/u/anim_front.png b/graphics/pokemon/unown/u/anim_front.png deleted file mode 100644 index cea47fd5befd2407d0a9e858284c34a53ad394e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 397 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B30+L(9PfXBs@ z^F#ergI&j2cU7+R`tR`eU7JguoK)+d+W~LGPM@05nlE(V@Z7#h#cdx$cKvO9ASN&2 zF>h9}TaPYlK6g@{L=LmkrJbz%*9b+4*#y+j+!(h+*f(PR;~!y0Pj>Lt&E3`e>-%}` z3G@04?e7Oq&)Czpk)v(Zfn*tH8{s=EIDW0)-?3Hcz)8ls7plP}ri|IO2iBNgkKj8# zOJc7=+k^nMfZhKqR1|7gZxKpgw|4eK)fG)lL8UVrro;+x^6e-(J}Iy%UG`^4eZYYo z)+f$6Uwv?0>D>fdopgJq5JjfbFWW!#XzF@D_MSRz>GPX0qMJSP&X}sU1lI$-4MG)c Z<(nL;i!U9h+YSsP22WQ%mvv4FO#swUu+snl diff --git a/graphics/pokemon/unown/u/front.png b/graphics/pokemon/unown/u/front.png new file mode 100644 index 0000000000000000000000000000000000000000..43631f3354b303dfb9d6e6c12949e850bb33a473 GIT binary patch literal 424 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC?cnls zaSVxQeLLl#&=Ca==jsaz|NkH6?kxKjw$->gvN&_OsXxn;U420C&+VQ5-)kT8>dW5< z-;v(h%~5UW-IOo5XKE5xVz)y5vV_S34IidQaT|$pGo-(Kx?aSM!|t-^!!t)eKKRGi zEy40)|2&4HTV^m;uu3rPe|cR-;jo|fEu#ascr~tmsAZYG(rr!BscH_dMR`Y57A%ih z87_JBNQ(W6R~K9zG`^j03-UStZ(m^5m1A!8HJ@&_JyE=I#4e9%;pM+8o~6qfurWzV zCvRHlc_FI8Jn^7C$2s#|8=k#yaS@pC&Gf&5$y0~ch&ddq8d|SgT)U=zD)va+iBNk% o8^>#f)tj1cmCDP?%KnXz|HsN#UL^1S2^eAwp00i_>zopr0ABXQ`2YX_ literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/v/anim_front.png b/graphics/pokemon/unown/v/anim_front.png deleted file mode 100644 index d073949e54d4051e2762a1c3da554c5530b8d78f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 358 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3gKQUY9Qrzk$@uUOUxSCD2e)`k{d~DI zyHV%Vqy|%kZjJ-z9Cq}~sAS$WLy(o(_~N>qioCLi(OIjCuE`II~17%~m^dv-|pz`Eh%eo&G7n n)5YYlM!Rc~1`wUP|C52QB0glr0>%qK|1x;G`njxgN@xNA=p>$~ diff --git a/graphics/pokemon/unown/v/front.png b/graphics/pokemon/unown/v/front.png new file mode 100644 index 0000000000000000000000000000000000000000..af578b4fa969c54d4666685ea28dd121eaec66d6 GIT binary patch literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCG>L1ux#%^L#OqU$s}d;g0ErZl=4k zHI@Ru4lm^DxHP?4w*174$M4Q;YU#P0&UP|u$=7tlV7|z+7yFkuzr230+veyCw%eRD zIOG(rn|GuuD9uP?xb5Jkz+zC!)?WXxAZp>dz!^>ssRfS`m+dl? z-6QSs_vMA^bL;soUifKS_-jkW-|WK%JoN{K&0ccb`#k!>1N1F}r>mdKI;Vst06%)N Ak^lez literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/w/anim_front.png b/graphics/pokemon/unown/w/anim_front.png deleted file mode 100644 index d34a16f0593b63b64ae8404afef271591bb736f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3qKQ~S~6k&C{$G~Eh`+>l>&wpric+?-=$9zb~ zegS*d6yUogvkCy~yx;7Y@%*(+bHvx<&O>^k7Y r;5x&^zGKtED@k(`CE7sfpKN&F=kUkZ%yzc`JgTe~DWM4fw3DOc diff --git a/graphics/pokemon/unown/w/front.png b/graphics/pokemon/unown/w/front.png new file mode 100644 index 0000000000000000000000000000000000000000..dd9f9d00f7b45f6b2dc31080b9dcaa4fbf5cca2e GIT binary patch literal 379 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCr#vT0zZB)nVLaJ(hpi#fEyOf&#u7WEzW)k{0>Jp3+Ja)@J+azqt(LS0sG66@R#)(d|}uLz$n?Wye%7=LiuLB`3- zvbM(c%u0v8O#W~quk{XNK(dT`1VhEgdq@6o#Bg@i^_uyA-p{nfp1I<0D?_uwneKnh t2BwGQSysf=wTQN4-;C3m>Se!7JmNf;e}`!JJD^7yJYD@<);T3K0RSI^s44&e literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/x/anim_front.png b/graphics/pokemon/unown/x/anim_front.png deleted file mode 100644 index a75ab916c2707df9434e23dff44dbb2230346d11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3fI*2%6sk44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCqzL8_esqbuy>|E|TA8zt*U@LGrEjXIQCqM5Hj@=_>Pejdv0@%JZBJ+1{*HF^-s+kt<+7?eyv? it^aFzK<;F%VR#Y9d1;Bt^0h$kF?hQAxvXndb&79;CVbh;*_afk44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzCx1KS4u?)s z_%ZX~Pw5ZE5z7DP8@yKt`5@fEG{+%KfFE2agS vs>oknAvNRcQU5Hpu#c5*ORVO;f6n+JkIQq}-Ch1bk1}|=`njxgN@xNA$0@G8 literal 0 HcmV?d00001 diff --git a/graphics/pokemon/unown/z/anim_front.png b/graphics/pokemon/unown/z/anim_front.png deleted file mode 100644 index 3080f7347cd41e5c5aec654ece024135fa33d37e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!VDxm*B3M?L558_D2V6+#yM= z8R9vPChsC9Ow2v6^fx21A}J-&U0#UU@m({=jVtFCZt&Rc{w~k44ofy`glX(f`7zFr)xSl<` z=0C%K2)cLg-v9sq1q1|^ELl=qTpSb>1eby{Ci8y%3e+o5666;Q)Q18N1avzC<#u|y zIEF;Dz72KcV=?4-wb1qF|Mu|QZ+ke;rEZ#ZM$l`eMK&*6^Fe-tix1!DKFi=>xf{*J z@kJ!)2_x(C)1pS6$J8%LDn82&3R&=6M^vTpiS^@>z=xl{TS`x9O8Ml^*wtzf@LX6- zj)nV+(E;Wutd0sf?4o*HSN484ToL{wYJ#&4_mNt+$-fHNU#t^d>%TPNCfmmT6M`js zy+fb9DN2_;vi{*y>0H~*H_y)Yym$0Q(1$dk7qN*35`VbuYW{H?yYFXd3iJenr>mdK II;Vst0F#}XG5`Po literal 0 HcmV?d00001 diff --git a/src/data/graphics/pokemon.h b/src/data/graphics/pokemon.h index 54dfc40895..abb2780adf 100644 --- a/src/data/graphics/pokemon.h +++ b/src/data/graphics/pokemon.h @@ -3146,115 +3146,115 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u8 gMonFootprint_Unown[] = INCBIN_U8("graphics/pokemon/unown/footprint.1bpp"); #endif //P_FOOTPRINTS - const u32 gMonFrontPic_UnownA[] = INCBIN_U32("graphics/pokemon/unown/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownA[] = INCBIN_U32("graphics/pokemon/unown/front.4bpp.lz"); const u32 gMonBackPic_UnownA[] = INCBIN_U32("graphics/pokemon/unown/back.4bpp.lz"); const u8 gMonIcon_UnownA[] = INCBIN_U8("graphics/pokemon/unown/icon.4bpp"); - const u32 gMonFrontPic_UnownB[] = INCBIN_U32("graphics/pokemon/unown/b/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownB[] = INCBIN_U32("graphics/pokemon/unown/b/front.4bpp.lz"); const u32 gMonBackPic_UnownB[] = INCBIN_U32("graphics/pokemon/unown/b/back.4bpp.lz"); const u8 gMonIcon_UnownB[] = INCBIN_U8("graphics/pokemon/unown/b/icon.4bpp"); - const u32 gMonFrontPic_UnownC[] = INCBIN_U32("graphics/pokemon/unown/c/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownC[] = INCBIN_U32("graphics/pokemon/unown/c/front.4bpp.lz"); const u32 gMonBackPic_UnownC[] = INCBIN_U32("graphics/pokemon/unown/c/back.4bpp.lz"); const u8 gMonIcon_UnownC[] = INCBIN_U8("graphics/pokemon/unown/c/icon.4bpp"); - const u32 gMonFrontPic_UnownD[] = INCBIN_U32("graphics/pokemon/unown/d/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownD[] = INCBIN_U32("graphics/pokemon/unown/d/front.4bpp.lz"); const u32 gMonBackPic_UnownD[] = INCBIN_U32("graphics/pokemon/unown/d/back.4bpp.lz"); const u8 gMonIcon_UnownD[] = INCBIN_U8("graphics/pokemon/unown/d/icon.4bpp"); - const u32 gMonFrontPic_UnownE[] = INCBIN_U32("graphics/pokemon/unown/e/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownE[] = INCBIN_U32("graphics/pokemon/unown/e/front.4bpp.lz"); const u32 gMonBackPic_UnownE[] = INCBIN_U32("graphics/pokemon/unown/e/back.4bpp.lz"); const u8 gMonIcon_UnownE[] = INCBIN_U8("graphics/pokemon/unown/e/icon.4bpp"); - const u32 gMonFrontPic_UnownF[] = INCBIN_U32("graphics/pokemon/unown/f/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownF[] = INCBIN_U32("graphics/pokemon/unown/f/front.4bpp.lz"); const u32 gMonBackPic_UnownF[] = INCBIN_U32("graphics/pokemon/unown/f/back.4bpp.lz"); const u8 gMonIcon_UnownF[] = INCBIN_U8("graphics/pokemon/unown/f/icon.4bpp"); - const u32 gMonFrontPic_UnownG[] = INCBIN_U32("graphics/pokemon/unown/g/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownG[] = INCBIN_U32("graphics/pokemon/unown/g/front.4bpp.lz"); const u32 gMonBackPic_UnownG[] = INCBIN_U32("graphics/pokemon/unown/g/back.4bpp.lz"); const u8 gMonIcon_UnownG[] = INCBIN_U8("graphics/pokemon/unown/g/icon.4bpp"); - const u32 gMonFrontPic_UnownH[] = INCBIN_U32("graphics/pokemon/unown/h/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownH[] = INCBIN_U32("graphics/pokemon/unown/h/front.4bpp.lz"); const u32 gMonBackPic_UnownH[] = INCBIN_U32("graphics/pokemon/unown/h/back.4bpp.lz"); const u8 gMonIcon_UnownH[] = INCBIN_U8("graphics/pokemon/unown/h/icon.4bpp"); - const u32 gMonFrontPic_UnownI[] = INCBIN_U32("graphics/pokemon/unown/i/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownI[] = INCBIN_U32("graphics/pokemon/unown/i/front.4bpp.lz"); const u32 gMonBackPic_UnownI[] = INCBIN_U32("graphics/pokemon/unown/i/back.4bpp.lz"); const u8 gMonIcon_UnownI[] = INCBIN_U8("graphics/pokemon/unown/i/icon.4bpp"); - const u32 gMonFrontPic_UnownJ[] = INCBIN_U32("graphics/pokemon/unown/j/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownJ[] = INCBIN_U32("graphics/pokemon/unown/j/front.4bpp.lz"); const u32 gMonBackPic_UnownJ[] = INCBIN_U32("graphics/pokemon/unown/j/back.4bpp.lz"); const u8 gMonIcon_UnownJ[] = INCBIN_U8("graphics/pokemon/unown/j/icon.4bpp"); - const u32 gMonFrontPic_UnownK[] = INCBIN_U32("graphics/pokemon/unown/k/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownK[] = INCBIN_U32("graphics/pokemon/unown/k/front.4bpp.lz"); const u32 gMonBackPic_UnownK[] = INCBIN_U32("graphics/pokemon/unown/k/back.4bpp.lz"); const u8 gMonIcon_UnownK[] = INCBIN_U8("graphics/pokemon/unown/k/icon.4bpp"); - const u32 gMonFrontPic_UnownL[] = INCBIN_U32("graphics/pokemon/unown/l/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownL[] = INCBIN_U32("graphics/pokemon/unown/l/front.4bpp.lz"); const u32 gMonBackPic_UnownL[] = INCBIN_U32("graphics/pokemon/unown/l/back.4bpp.lz"); const u8 gMonIcon_UnownL[] = INCBIN_U8("graphics/pokemon/unown/l/icon.4bpp"); - const u32 gMonFrontPic_UnownM[] = INCBIN_U32("graphics/pokemon/unown/m/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownM[] = INCBIN_U32("graphics/pokemon/unown/m/front.4bpp.lz"); const u32 gMonBackPic_UnownM[] = INCBIN_U32("graphics/pokemon/unown/m/back.4bpp.lz"); const u8 gMonIcon_UnownM[] = INCBIN_U8("graphics/pokemon/unown/m/icon.4bpp"); - const u32 gMonFrontPic_UnownN[] = INCBIN_U32("graphics/pokemon/unown/n/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownN[] = INCBIN_U32("graphics/pokemon/unown/n/front.4bpp.lz"); const u32 gMonBackPic_UnownN[] = INCBIN_U32("graphics/pokemon/unown/n/back.4bpp.lz"); const u8 gMonIcon_UnownN[] = INCBIN_U8("graphics/pokemon/unown/n/icon.4bpp"); - const u32 gMonFrontPic_UnownO[] = INCBIN_U32("graphics/pokemon/unown/o/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownO[] = INCBIN_U32("graphics/pokemon/unown/o/front.4bpp.lz"); const u32 gMonBackPic_UnownO[] = INCBIN_U32("graphics/pokemon/unown/o/back.4bpp.lz"); const u8 gMonIcon_UnownO[] = INCBIN_U8("graphics/pokemon/unown/o/icon.4bpp"); - const u32 gMonFrontPic_UnownP[] = INCBIN_U32("graphics/pokemon/unown/p/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownP[] = INCBIN_U32("graphics/pokemon/unown/p/front.4bpp.lz"); const u32 gMonBackPic_UnownP[] = INCBIN_U32("graphics/pokemon/unown/p/back.4bpp.lz"); const u8 gMonIcon_UnownP[] = INCBIN_U8("graphics/pokemon/unown/p/icon.4bpp"); - const u32 gMonFrontPic_UnownQ[] = INCBIN_U32("graphics/pokemon/unown/q/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownQ[] = INCBIN_U32("graphics/pokemon/unown/q/front.4bpp.lz"); const u32 gMonBackPic_UnownQ[] = INCBIN_U32("graphics/pokemon/unown/q/back.4bpp.lz"); const u8 gMonIcon_UnownQ[] = INCBIN_U8("graphics/pokemon/unown/q/icon.4bpp"); - const u32 gMonFrontPic_UnownR[] = INCBIN_U32("graphics/pokemon/unown/r/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownR[] = INCBIN_U32("graphics/pokemon/unown/r/front.4bpp.lz"); const u32 gMonBackPic_UnownR[] = INCBIN_U32("graphics/pokemon/unown/r/back.4bpp.lz"); const u8 gMonIcon_UnownR[] = INCBIN_U8("graphics/pokemon/unown/r/icon.4bpp"); - const u32 gMonFrontPic_UnownS[] = INCBIN_U32("graphics/pokemon/unown/s/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownS[] = INCBIN_U32("graphics/pokemon/unown/s/front.4bpp.lz"); const u32 gMonBackPic_UnownS[] = INCBIN_U32("graphics/pokemon/unown/s/back.4bpp.lz"); const u8 gMonIcon_UnownS[] = INCBIN_U8("graphics/pokemon/unown/s/icon.4bpp"); - const u32 gMonFrontPic_UnownT[] = INCBIN_U32("graphics/pokemon/unown/t/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownT[] = INCBIN_U32("graphics/pokemon/unown/t/front.4bpp.lz"); const u32 gMonBackPic_UnownT[] = INCBIN_U32("graphics/pokemon/unown/t/back.4bpp.lz"); const u8 gMonIcon_UnownT[] = INCBIN_U8("graphics/pokemon/unown/t/icon.4bpp"); - const u32 gMonFrontPic_UnownU[] = INCBIN_U32("graphics/pokemon/unown/u/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownU[] = INCBIN_U32("graphics/pokemon/unown/u/front.4bpp.lz"); const u32 gMonBackPic_UnownU[] = INCBIN_U32("graphics/pokemon/unown/u/back.4bpp.lz"); const u8 gMonIcon_UnownU[] = INCBIN_U8("graphics/pokemon/unown/u/icon.4bpp"); - const u32 gMonFrontPic_UnownV[] = INCBIN_U32("graphics/pokemon/unown/v/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownV[] = INCBIN_U32("graphics/pokemon/unown/v/front.4bpp.lz"); const u32 gMonBackPic_UnownV[] = INCBIN_U32("graphics/pokemon/unown/v/back.4bpp.lz"); const u8 gMonIcon_UnownV[] = INCBIN_U8("graphics/pokemon/unown/v/icon.4bpp"); - const u32 gMonFrontPic_UnownW[] = INCBIN_U32("graphics/pokemon/unown/w/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownW[] = INCBIN_U32("graphics/pokemon/unown/w/front.4bpp.lz"); const u32 gMonBackPic_UnownW[] = INCBIN_U32("graphics/pokemon/unown/w/back.4bpp.lz"); const u8 gMonIcon_UnownW[] = INCBIN_U8("graphics/pokemon/unown/w/icon.4bpp"); - const u32 gMonFrontPic_UnownX[] = INCBIN_U32("graphics/pokemon/unown/x/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownX[] = INCBIN_U32("graphics/pokemon/unown/x/front.4bpp.lz"); const u32 gMonBackPic_UnownX[] = INCBIN_U32("graphics/pokemon/unown/x/back.4bpp.lz"); const u8 gMonIcon_UnownX[] = INCBIN_U8("graphics/pokemon/unown/x/icon.4bpp"); - const u32 gMonFrontPic_UnownY[] = INCBIN_U32("graphics/pokemon/unown/y/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownY[] = INCBIN_U32("graphics/pokemon/unown/y/front.4bpp.lz"); const u32 gMonBackPic_UnownY[] = INCBIN_U32("graphics/pokemon/unown/y/back.4bpp.lz"); const u8 gMonIcon_UnownY[] = INCBIN_U8("graphics/pokemon/unown/y/icon.4bpp"); - const u32 gMonFrontPic_UnownZ[] = INCBIN_U32("graphics/pokemon/unown/z/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownZ[] = INCBIN_U32("graphics/pokemon/unown/z/front.4bpp.lz"); const u32 gMonBackPic_UnownZ[] = INCBIN_U32("graphics/pokemon/unown/z/back.4bpp.lz"); const u8 gMonIcon_UnownZ[] = INCBIN_U8("graphics/pokemon/unown/z/icon.4bpp"); - const u32 gMonFrontPic_UnownExclamationMark[] = INCBIN_U32("graphics/pokemon/unown/exclamation_mark/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownExclamationMark[] = INCBIN_U32("graphics/pokemon/unown/exclamation_mark/front.4bpp.lz"); const u32 gMonBackPic_UnownExclamationMark[] = INCBIN_U32("graphics/pokemon/unown/exclamation_mark/back.4bpp.lz"); const u8 gMonIcon_UnownExclamationMark[] = INCBIN_U8("graphics/pokemon/unown/exclamation_mark/icon.4bpp"); - const u32 gMonFrontPic_UnownQuestionMark[] = INCBIN_U32("graphics/pokemon/unown/question_mark/anim_front.4bpp.lz"); + const u32 gMonFrontPic_UnownQuestionMark[] = INCBIN_U32("graphics/pokemon/unown/question_mark/front.4bpp.lz"); const u32 gMonBackPic_UnownQuestionMark[] = INCBIN_U32("graphics/pokemon/unown/question_mark/back.4bpp.lz"); const u8 gMonIcon_UnownQuestionMark[] = INCBIN_U8("graphics/pokemon/unown/question_mark/icon.4bpp"); #endif //P_FAMILY_UNOWN diff --git a/src/data/pokemon_graphics/front_pic_anims.h b/src/data/pokemon_graphics/front_pic_anims.h index 1817bc19c2..ab8707ac5d 100644 --- a/src/data/pokemon_graphics/front_pic_anims.h +++ b/src/data/pokemon_graphics/front_pic_anims.h @@ -2894,13 +2894,7 @@ static const union AnimCmd sAnim_Mismagius_1[] = #endif //P_FAMILY_MISDREAVUS #if P_FAMILY_UNOWN -static const union AnimCmd sAnim_Unown_1[] = -{ - ANIMCMD_FRAME(0, 30), - ANIMCMD_FRAME(1, 30), - ANIMCMD_FRAME(0, 1), - ANIMCMD_END, -}; +PLACEHOLDER_ANIM_SINGLE_FRAME(Unown); #endif //P_FAMILY_UNOWN #if P_FAMILY_WOBBUFFET From 8de4ed5a7c7b162329569fdcc4ac1bd2cac0cb9d Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Sat, 11 May 2024 13:16:35 +0100 Subject: [PATCH 16/17] Fixes Copycat issues with Z-Moves and 2 turn moves (#4549) * Fixes Copycat 2-turn moves animation * Fixes Copycat being able to call Z-Moves --- data/battle_scripts_1.s | 2 ++ src/battle_script_commands.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 6f5cedd9d9..8a5891f068 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1684,6 +1684,8 @@ BattleScript_EffectCopycat:: trycopycat BattleScript_CopycatFail attackanimation waitanimation + setbyte sB_ANIM_TURN, 0 + setbyte sB_ANIM_TARGETS_HIT, 0 jumptocalledmove TRUE BattleScript_CopycatFail: ppreduce diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 5f4ed78aa8..f723ce6566 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -16650,7 +16650,7 @@ void BS_TryCopycat(void) { NATIVE_ARGS(const u8 *failInstr); - if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || gMovesInfo[gLastUsedMove].copycatBanned) + if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || gMovesInfo[gLastUsedMove].copycatBanned || IsZMove(gLastUsedMove)) { gBattlescriptCurrInstr = cmd->failInstr; } From f502ba2a696bf9f65093492b910983cea681a4e6 Mon Sep 17 00:00:00 2001 From: sneed <56992013+Sneed69@users.noreply.github.com> Date: Sat, 11 May 2024 20:03:19 +0300 Subject: [PATCH 17/17] Stat stage related AI fixes (#4548) * stat stage related AI fixes * add more ai fixes and 2 tests * use legal ability in tests * Fix test and remove mold breaker check * Use DoesBattlerIgnoreAbilityChecks --- include/battle_ai_main.h | 4 +- include/battle_ai_util.h | 1 + src/battle_ai_main.c | 103 +++++++++++++++++++++++++-------------- src/battle_ai_util.c | 64 +++++++++++++++++++++--- test/battle/ai.c | 52 ++++++++++++++++++++ 5 files changed, 179 insertions(+), 45 deletions(-) diff --git a/include/battle_ai_main.h b/include/battle_ai_main.h index 18148a89b0..e2c7804091 100644 --- a/include/battle_ai_main.h +++ b/include/battle_ai_main.h @@ -32,13 +32,13 @@ #define BEST_DAMAGE_MOVE 1 // Move with the most amount of hits with the best accuracy/effect #define POWERFUL_STATUS_MOVE 10 // Moves with this score will be chosen over a move that faints target -// Temporary scores that are added together to determine a final score at the at of AI_CalcMoveScore +// Temporary scores that are added together to determine a final score at the at of AI_CalcMoveEffectScore #define WEAK_EFFECT 1 #define DECENT_EFFECT 2 #define GOOD_EFFECT 4 #define BEST_EFFECT 6 -// AI_CalcMoveScore final score +// AI_CalcMoveEffectScore final score #define NOT_GOOD_ENOUGH 0 // Not worth using over a damaging move #define GOOD_MOVE_EFFECTS 2 // Worth using over a damaging move #define PREFERRED_MOVE_EFFECTS 3 // Worth using over a damagin move and is better then DECENT_EFFECT diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index ac7aea429b..bd2b8fb920 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -179,6 +179,7 @@ bool32 SideHasMoveCategory(u32 battlerId, u32 category); // score increases void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score); +void IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score); void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 92b2239cd3..429ec6642b 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3161,7 +3161,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId) return score; } -static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move) +static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) { // move data u32 moveEffect = gMovesInfo[move].effect; @@ -3592,7 +3592,7 @@ static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move) else ADJUST_SCORE(WEAK_EFFECT); } - else if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY) + else { IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_ATK, &score); IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score); @@ -4407,56 +4407,88 @@ static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move) // Consider move effects that target self if (gMovesInfo[move].additionalEffects[i].self) { - u32 oneStageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1; - u32 twoStageStatId = STAT_CHANGE_ATK_2 + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1; + u32 StageStatId; - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY) { - case MOVE_EFFECT_SPD_PLUS_2: - case MOVE_EFFECT_SPD_PLUS_1: - if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY && !AI_STRIKES_FIRST(battlerAtk, battlerDef, move)) - ADJUST_SCORE(GOOD_EFFECT); - break; + switch (gMovesInfo[move].additionalEffects[i].moveEffect) + { case MOVE_EFFECT_ATK_PLUS_1: case MOVE_EFFECT_DEF_PLUS_1: + case MOVE_EFFECT_SPD_PLUS_1: case MOVE_EFFECT_SP_ATK_PLUS_1: case MOVE_EFFECT_SP_DEF_PLUS_1: - case MOVE_EFFECT_ACC_PLUS_1: - case MOVE_EFFECT_EVS_PLUS_1: - IncreaseStatUpScore(battlerAtk, battlerDef, oneStageStatId, &score); + StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1; + IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId, &score); break; case MOVE_EFFECT_ATK_PLUS_2: case MOVE_EFFECT_DEF_PLUS_2: + case MOVE_EFFECT_SPD_PLUS_2: case MOVE_EFFECT_SP_ATK_PLUS_2: case MOVE_EFFECT_SP_DEF_PLUS_2: - case MOVE_EFFECT_ACC_PLUS_2: - case MOVE_EFFECT_EVS_PLUS_2: - IncreaseStatUpScore(battlerAtk, battlerDef, twoStageStatId, &score); + StageStatId = STAT_CHANGE_ATK_2 + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1; + IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId, &score); break; - // Effects that lower stat(s) - only need to consider Contrary - case MOVE_EFFECT_ATK_MINUS_1: - case MOVE_EFFECT_DEF_MINUS_1: - case MOVE_EFFECT_SPD_MINUS_1: - case MOVE_EFFECT_SP_ATK_MINUS_1: - case MOVE_EFFECT_SP_DEF_MINUS_1: - case MOVE_EFFECT_DEF_SPDEF_DOWN: - case MOVE_EFFECT_ATK_DEF_DOWN: - case MOVE_EFFECT_SP_ATK_TWO_DOWN: - if (aiData->abilities[battlerAtk] == ABILITY_CONTRARY) - IncreaseStatUpScore(battlerAtk, battlerDef, oneStageStatId, &score); - case MOVE_EFFECT_V_CREATE: - if (aiData->abilities[battlerAtk] == ABILITY_CONTRARY) - { - IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score); - IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_SPEED, &score); - IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_SPDEF, &score); - } + case MOVE_EFFECT_ACC_PLUS_1: + case MOVE_EFFECT_ACC_PLUS_2: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_ACC, &score); + break; + case MOVE_EFFECT_EVS_PLUS_1: + case MOVE_EFFECT_EVS_PLUS_2: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_EVASION, &score); break; case MOVE_EFFECT_RAPID_SPIN: if ((gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY && CountUsablePartyMons(battlerAtk) != 0) || (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].status2 & STATUS2_WRAPPED)) ADJUST_SCORE(GOOD_EFFECT); break; + } + } + else + { + switch (gMovesInfo[move].additionalEffects[i].moveEffect) + { + case MOVE_EFFECT_ATK_MINUS_1: + case MOVE_EFFECT_DEF_MINUS_1: + case MOVE_EFFECT_SPD_MINUS_1: + case MOVE_EFFECT_SP_ATK_MINUS_1: + case MOVE_EFFECT_SP_DEF_MINUS_1: + StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1; + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId, &score); + break; + case MOVE_EFFECT_ATK_MINUS_2: + case MOVE_EFFECT_DEF_MINUS_2: + case MOVE_EFFECT_SPD_MINUS_2: + case MOVE_EFFECT_SP_ATK_MINUS_2: + case MOVE_EFFECT_SP_DEF_MINUS_2: + StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2; + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId, &score); + break; + case MOVE_EFFECT_ACC_MINUS_1: + case MOVE_EFFECT_ACC_MINUS_2: + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_ACC, &score); + break; + case MOVE_EFFECT_EVS_MINUS_1: + case MOVE_EFFECT_EVS_MINUS_2: + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_EVASION, &score); + break; + case MOVE_EFFECT_DEF_SPDEF_DOWN: + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score); + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPDEF, &score); + break; + case MOVE_EFFECT_ATK_DEF_DOWN: + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_ATK, &score); + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score); + break; + case MOVE_EFFECT_SP_ATK_TWO_DOWN: + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPATK_2, &score); + break; + case MOVE_EFFECT_V_CREATE: + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score); + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPEED, &score); + IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPDEF, &score); + break; + } } } else // consider move effects that hinder the target @@ -4639,8 +4671,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score score += AI_CompareDamagingMoves(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex); } - // Calculates score based on effects of a move - score += AI_CalcMoveScore(battlerAtk, battlerDef, move); + score += AI_CalcMoveEffectScore(battlerAtk, battlerDef, move); return score; } diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 4a83fc6e4e..0fcb8b1fc2 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -627,22 +627,35 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 switch (gMovesInfo[move].additionalEffects[i].moveEffect) { case MOVE_EFFECT_ATK_PLUS_1: + case MOVE_EFFECT_ATK_PLUS_2: if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK)) return TRUE; break; - case MOVE_EFFECT_DEF_PLUS_2: case MOVE_EFFECT_DEF_PLUS_1: + case MOVE_EFFECT_DEF_PLUS_2: if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_DEF)) return TRUE; break; case MOVE_EFFECT_SPD_PLUS_1: + case MOVE_EFFECT_SPD_PLUS_2: if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_SPEED)) return TRUE; break; case MOVE_EFFECT_SP_ATK_PLUS_1: + case MOVE_EFFECT_SP_ATK_PLUS_2: if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_SPATK)) return TRUE; break; + case MOVE_EFFECT_EVS_PLUS_1: + case MOVE_EFFECT_EVS_PLUS_2: + if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_EVASION)) + return TRUE; + break; + case MOVE_EFFECT_ACC_PLUS_1: + case MOVE_EFFECT_ACC_PLUS_2: + if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ACC)) + return TRUE; + break; case MOVE_EFFECT_ALL_STATS_UP: for (i = STAT_ATK; i <= NUM_STATS; i++) { @@ -737,18 +750,45 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s case MOVE_EFFECT_DEF_MINUS_1: case MOVE_EFFECT_SPD_MINUS_1: case MOVE_EFFECT_SP_ATK_MINUS_1: + case MOVE_EFFECT_SP_DEF_MINUS_1: + case MOVE_EFFECT_EVS_MINUS_1: + case MOVE_EFFECT_ACC_MINUS_1: + case MOVE_EFFECT_ATK_MINUS_2: + case MOVE_EFFECT_DEF_MINUS_2: + case MOVE_EFFECT_SPD_MINUS_2: + case MOVE_EFFECT_SP_ATK_MINUS_2: + case MOVE_EFFECT_SP_DEF_MINUS_2: + case MOVE_EFFECT_EVS_MINUS_2: + case MOVE_EFFECT_ACC_MINUS_2: case MOVE_EFFECT_SP_ATK_TWO_DOWN: case MOVE_EFFECT_V_CREATE: case MOVE_EFFECT_ATK_DEF_DOWN: case MOVE_EFFECT_DEF_SPDEF_DOWN: - case MOVE_EFFECT_SP_DEF_MINUS_1: - case MOVE_EFFECT_SP_DEF_MINUS_2: - if ((gMovesInfo[move].additionalEffects[i].self && GetBattlerAbility(battlerAtk) != ABILITY_CONTRARY) - || (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !IsMoldBreakerTypeAbility(abilityAtk))) + if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk != ABILITY_CONTRARY) + || (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move))) return TRUE; break; case MOVE_EFFECT_RECHARGE: return gMovesInfo[move].additionalEffects[i].self; + case MOVE_EFFECT_ATK_PLUS_1: + case MOVE_EFFECT_DEF_PLUS_1: + case MOVE_EFFECT_SPD_PLUS_1: + case MOVE_EFFECT_SP_ATK_PLUS_1: + case MOVE_EFFECT_SP_DEF_PLUS_1: + case MOVE_EFFECT_EVS_PLUS_1: + case MOVE_EFFECT_ACC_PLUS_1: + case MOVE_EFFECT_ATK_PLUS_2: + case MOVE_EFFECT_DEF_PLUS_2: + case MOVE_EFFECT_SPD_PLUS_2: + case MOVE_EFFECT_SP_ATK_PLUS_2: + case MOVE_EFFECT_SP_DEF_PLUS_2: + case MOVE_EFFECT_EVS_PLUS_2: + case MOVE_EFFECT_ACC_PLUS_2: + case MOVE_EFFECT_ALL_STATS_UP: + if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk == ABILITY_CONTRARY) + || (noOfHitsToKo != 1 && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move)))) + return TRUE; + break; } } break; @@ -3388,13 +3428,13 @@ bool32 IsRecycleEncouragedItem(u32 item) return FALSE; } -void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score) +static void IncreaseStatUpScoreInternal(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score, bool32 considerContrary) { u32 noOfHitsToFaint = NoOfHitsForTargetToFaintAI(battlerDef, battlerAtk); u32 aiIsFaster = GetWhichBattlerFaster(battlerAtk, battlerDef, TRUE) == AI_IS_FASTER; u32 shouldSetUp = ((noOfHitsToFaint >= 2 && aiIsFaster) || (noOfHitsToFaint >= 3 && !aiIsFaster) || noOfHitsToFaint == UNKNOWN_NO_OF_HITS); - if (AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY) + if (considerContrary && AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY) return; // Don't increase stat if AI is at +4 @@ -3488,6 +3528,16 @@ void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score) } } +void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score) +{ + IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statId, score, TRUE); +} + +void IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score) +{ + IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statId, score, FALSE); +} + void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { if (((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) diff --git a/test/battle/ai.c b/test/battle/ai.c index 0d890da466..11702a0c5a 100644 --- a/test/battle/ai.c +++ b/test/battle/ai.c @@ -830,3 +830,55 @@ AI_SINGLE_BATTLE_TEST("AI will choose Surf over Thunderbolt and Ice Beam if the TURN { EXPECT_MOVE(opponent, MOVE_SURF); } } } + +AI_SINGLE_BATTLE_TEST("AI will choose Scratch over Power-up Punch with Contrary") +{ + u32 ability; + + PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; } + PARAMETRIZE {ability = ABILITY_CONTRARY; } + GIVEN { + ASSUME(gMovesInfo[MOVE_SCRATCH].power == 40); + ASSUME(gMovesInfo[MOVE_SCRATCH].type == TYPE_NORMAL); + ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].power == 40); + ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].type == TYPE_FIGHTING); + ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER); + ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_SQUIRTLE) { }; + OPPONENT(SPECIES_MALAMAR) { Ability(ability); Moves(MOVE_SCRATCH, MOVE_POWER_UP_PUNCH); } + } WHEN { + TURN { + if (ability != ABILITY_CONTRARY) + EXPECT_MOVE(opponent, MOVE_POWER_UP_PUNCH); + else + EXPECT_MOVE(opponent, MOVE_SCRATCH); + } + } +} + +AI_SINGLE_BATTLE_TEST("AI will choose Superpower over Outrage with Contrary") +{ + u32 ability; + + PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; } + PARAMETRIZE {ability = ABILITY_CONTRARY; } + GIVEN { + ASSUME(gMovesInfo[MOVE_SUPERPOWER].power == 120); + ASSUME(gMovesInfo[MOVE_SUPERPOWER].type == TYPE_FIGHTING); + ASSUME(gMovesInfo[MOVE_OUTRAGE].power == 120); + ASSUME(gMovesInfo[MOVE_OUTRAGE].type == TYPE_DRAGON); + ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER); + ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_SQUIRTLE) { }; + OPPONENT(SPECIES_MALAMAR) { Ability(ability); Moves(MOVE_OUTRAGE, MOVE_SUPERPOWER); } + } WHEN { + TURN { + if (ability != ABILITY_CONTRARY) + EXPECT_MOVE(opponent, MOVE_OUTRAGE); + else + EXPECT_MOVE(opponent, MOVE_SUPERPOWER); + } + } +}