From 6e134bb7dc0b5650946318a28cbe72a2e5743e24 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Fri, 17 Feb 2023 12:52:43 -0300 Subject: [PATCH 01/30] Removed pointless IsBattlerHpLow function --- src/battle_message.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/battle_message.c b/src/battle_message.c index 2b8005f64b..9c8a1b7020 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3899,14 +3899,6 @@ static u32 GetEnemyMonCount(bool32 onlyAlive) return count; } -static bool32 IsBattlerHpLow(u32 battler) -{ - if ((gBattleMons[battler].hp * 100) / gBattleMons[battler].maxHP < 25) - return TRUE; - else - return FALSE; -} - bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which) { s32 i; @@ -3931,7 +3923,7 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which) case TRAINER_SLIDE_LAST_LOW_HP: if (sTrainerSlides[i].msgLastLowHp != NULL && GetEnemyMonCount(TRUE) == 1 - && IsBattlerHpLow(battlerId) + && gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 4) && !gBattleStruct->trainerSlideLowHpMsgDone) { gBattleStruct->trainerSlideLowHpMsgDone = TRUE; From 3a91a5c930d8c06de95882b5ca0ce90d017cbbc9 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Fri, 17 Feb 2023 12:53:24 -0300 Subject: [PATCH 02/30] =?UTF-8?q?Added=20new=20trainer=20slide-in=20msg=20?= =?UTF-8?q?conditions=20Now=20they=20can=20say=20something:=20-When=20thei?= =?UTF-8?q?r=20last=20Pok=C3=A9mon's=20HP=20is=20between=2025%=20and=2050%?= =?UTF-8?q?.=20-When=20a=20critical=20hit=20is=20dealt=20to=20their=20firs?= =?UTF-8?q?t=20Pok=C3=A9mon=20for=20the=20first=20time.=20-When=20a=20supe?= =?UTF-8?q?r=20effective=20hit=20is=20dealt=20to=20their=20first=20Pok?= =?UTF-8?q?=C3=A9mon=20for=20the=20first=20time.=20-When=20a=20STAB=20move?= =?UTF-8?q?=20is=20used=20against=20(but=20doesn't=20faint)=20the=20oppone?= =?UTF-8?q?nt's=20Pok=C3=A9mon.=20-When=20the=20Player's=20Pok=C3=A9mon's?= =?UTF-8?q?=20move=20doesn't=20affect=20the=20opponent's=20Pok=C3=A9mon.?= =?UTF-8?q?=20-When=20they're=20about=20to=20trigger=20a=20Mega=20Evolutio?= =?UTF-8?q?n.=20-When=20they're=20about=20to=20trigger=20a=20Z-Move.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Misc. changes: -Split GetEnemyMonCount for readability's sake. -Optimized the size allocated to trainerSlideLowHpMsgDone. --- asm/macros/battle_script.inc | 8 + data/battle_scripts_1.s | 8 + include/battle.h | 9 +- include/battle_message.h | 7 + include/constants/battle_script_commands.h | 338 +++++++++++---------- src/battle_main.c | 10 + src/battle_message.c | 109 ++++++- src/battle_script_commands.c | 35 +++ src/battle_util.c | 10 + 9 files changed, 356 insertions(+), 178 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 4f11fc78b8..e24e20e6e9 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -2049,6 +2049,14 @@ .4byte \jumpInstr .endm + .macro trytrainerslidezmovemsg battler:req + various \battler, VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE + .endm + + .macro trytrainerslidemegaevolutionmsg battler:req + various \battler, VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index ae92aba7cf..c6c9626384 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7763,6 +7763,8 @@ BattleScript_FocusPunchSetUp:: end2 BattleScript_MegaEvolution:: + printstring STRINGID_EMPTYSTRING3 + trytrainerslidemegaevolutionmsg BS_ATTACKER printstring STRINGID_MEGAEVOREACTING waitmessage B_WAIT_TIME_LONG setbyte gIsCriticalHit, 0 @@ -7777,6 +7779,8 @@ BattleScript_MegaEvolution:: end2 BattleScript_WishMegaEvolution:: + printstring STRINGID_EMPTYSTRING3 + trytrainerslidemegaevolutionmsg BS_ATTACKER printstring STRINGID_FERVENTWISHREACHED waitmessage B_WAIT_TIME_LONG setbyte gIsCriticalHit, 0 @@ -9989,6 +9993,8 @@ BattleScript_JabocaRowapBerryActivate_Dmg: @ z moves / effects BattleScript_ZMoveActivateDamaging:: + printstring STRINGID_EMPTYSTRING3 + trytrainerslidezmovemsg BS_ATTACKER printstring STRINGID_ZPOWERSURROUNDS playanimation BS_ATTACKER, B_ANIM_ZMOVE_ACTIVATE, NULL printstring STRINGID_ZMOVEUNLEASHED @@ -9996,6 +10002,8 @@ BattleScript_ZMoveActivateDamaging:: return BattleScript_ZMoveActivateStatus:: + printstring STRINGID_EMPTYSTRING3 + trytrainerslidezmovemsg BS_ATTACKER savetarget printstring STRINGID_ZPOWERSURROUNDS playanimation BS_ATTACKER, B_ANIM_ZMOVE_ACTIVATE, NULL diff --git a/include/battle.h b/include/battle.h index 8be922384f..f4b10c813c 100644 --- a/include/battle.h +++ b/include/battle.h @@ -620,7 +620,7 @@ struct BattleStruct struct MegaEvolutionData mega; struct ZMoveData zmove; const u8 *trainerSlideMsg; - bool8 trainerSlideLowHpMsgDone; + bool8 trainerSlideLowHpMsgDone:1; u8 introState; u8 ateBerry[2]; // array id determined by side, each party pokemon as bit u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages @@ -655,6 +655,13 @@ struct BattleStruct u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching) bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face. u8 battleBondTransformed[NUM_BATTLE_SIDES]; // Bitfield for each party. + bool8 trainerSlideHalfHpMsgDone:1; + u8 trainerSlideFirstCriticalHitMsgState:2; + u8 trainerSlideFirstSuperEffectiveHitMsgState:2; + u8 trainerSlideFirstSTABMoveMsgState:2; + u8 trainerSlidePlayerMonUnaffectedMsgState:2; + bool8 trainerSlideMegaEvolutionMsgDone:1; + bool8 trainerSlideZMoveMsgDone:1; }; #define F_DYNAMIC_TYPE_1 (1 << 6) diff --git a/include/battle_message.h b/include/battle_message.h index 9f6905abd3..57c6c21c24 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -229,6 +229,13 @@ enum TRAINER_SLIDE_LAST_SWITCHIN, TRAINER_SLIDE_LAST_LOW_HP, TRAINER_SLIDE_FIRST_DOWN, + TRAINER_SLIDE_LAST_HALF_HP, + TRAINER_SLIDE_FIRST_CRITICAL_HIT, + TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT, + TRAINER_SLIDE_FIRST_STAB_MOVE, + TRAINER_SLIDE_PLAYER_MON_UNAFFECTED, + TRAINER_SLIDE_MEGA_EVOLUTION, + TRAINER_SLIDE_Z_MOVE, }; void BufferStringBattle(u16 stringID); diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 68e927d75f..f55628315c 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -89,174 +89,176 @@ #define CMP_NO_COMMON_BITS 5 // Cmd_various -#define VARIOUS_CANCEL_MULTI_TURN_MOVES 0 -#define VARIOUS_SET_MAGIC_COAT_TARGET 1 -#define VARIOUS_IS_RUNNING_IMPOSSIBLE 2 -#define VARIOUS_GET_MOVE_TARGET 3 -#define VARIOUS_GET_BATTLER_FAINTED 4 -#define VARIOUS_RESET_SWITCH_IN_ABILITY_BITS 5 -#define VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP 6 -#define VARIOUS_RESET_PLAYER_FAINTED 7 -#define VARIOUS_PALACE_FLAVOR_TEXT 8 -#define VARIOUS_ARENA_JUDGMENT_WINDOW 9 -#define VARIOUS_ARENA_OPPONENT_MON_LOST 10 -#define VARIOUS_ARENA_PLAYER_MON_LOST 11 -#define VARIOUS_ARENA_BOTH_MONS_LOST 12 -#define VARIOUS_EMIT_YESNOBOX 13 -#define VARIOUS_DRAW_ARENA_REF_TEXT_BOX 14 -#define VARIOUS_ERASE_ARENA_REF_TEXT_BOX 15 -#define VARIOUS_ARENA_JUDGMENT_STRING 16 -#define VARIOUS_ARENA_WAIT_STRING 17 -#define VARIOUS_WAIT_CRY 18 -#define VARIOUS_RETURN_OPPONENT_MON1 19 -#define VARIOUS_RETURN_OPPONENT_MON2 20 -#define VARIOUS_VOLUME_DOWN 21 -#define VARIOUS_VOLUME_UP 22 -#define VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT 23 -#define VARIOUS_PALACE_TRY_ESCAPE_STATUS 24 -#define VARIOUS_SET_TELEPORT_OUTCOME 25 -#define VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC 26 -#define VARIOUS_STAT_TEXT_BUFFER 27 -#define VARIOUS_SWITCHIN_ABILITIES 28 -#define VARIOUS_SAVE_TARGET 29 -#define VARIOUS_RESTORE_TARGET 30 -#define VARIOUS_INSTANT_HP_DROP 31 -#define VARIOUS_CLEAR_STATUS 32 -#define VARIOUS_RESTORE_PP 33 -#define VARIOUS_TRY_ACTIVATE_MOXIE 34 -#define VARIOUS_TRY_ACTIVATE_FELL_STINGER 35 -#define VARIOUS_PLAY_MOVE_ANIMATION 36 -#define VARIOUS_SET_LUCKY_CHANT 37 -#define VARIOUS_SUCKER_PUNCH_CHECK 38 -#define VARIOUS_SET_SIMPLE_BEAM 39 -#define VARIOUS_TRY_ENTRAINMENT 40 -#define VARIOUS_SET_LAST_USED_ABILITY 41 -#define VARIOUS_TRY_HEAL_PULSE 42 -#define VARIOUS_TRY_QUASH 43 -#define VARIOUS_INVERT_STAT_STAGES 44 -#define VARIOUS_SET_TERRAIN 45 -#define VARIOUS_TRY_ME_FIRST 46 -#define VARIOUS_JUMP_IF_BATTLE_END 47 -#define VARIOUS_TRY_ELECTRIFY 48 -#define VARIOUS_TRY_REFLECT_TYPE 49 -#define VARIOUS_TRY_SOAK 50 -#define VARIOUS_HANDLE_MEGA_EVO 51 -#define VARIOUS_TRY_LAST_RESORT 52 -#define VARIOUS_ARGUMENT_STATUS_EFFECT 53 -#define VARIOUS_TRY_HIT_SWITCH_TARGET 54 -#define VARIOUS_TRY_AUTOTOMIZE 55 -#define VARIOUS_TRY_COPYCAT 56 -#define VARIOUS_ABILITY_POPUP 57 -#define VARIOUS_DEFOG 58 -#define VARIOUS_JUMP_IF_TARGET_ALLY 59 -#define VARIOUS_TRY_SYNCHRONOISE 60 -#define VARIOUS_PSYCHO_SHIFT 61 -#define VARIOUS_CURE_STATUS 62 -#define VARIOUS_POWER_TRICK 63 -#define VARIOUS_AFTER_YOU 64 -#define VARIOUS_BESTOW 65 -#define VARIOUS_ARGUMENT_TO_MOVE_EFFECT 66 -#define VARIOUS_JUMP_IF_NOT_GROUNDED 67 -#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 68 -#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 69 -#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 70 -#define VARIOUS_SET_AURORA_VEIL 71 -#define VARIOUS_TRY_THIRD_TYPE 72 -#define VARIOUS_ACUPRESSURE 73 -#define VARIOUS_SET_POWDER 74 -#define VARIOUS_SPECTRAL_THIEF 75 -#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76 -#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77 -#define VARIOUS_JUMP_IF_ROAR_FAILS 78 -#define VARIOUS_TRY_INSTRUCT 79 -#define VARIOUS_JUMP_IF_NOT_BERRY 80 -#define VARIOUS_TRACE_ABILITY 81 -#define VARIOUS_UPDATE_NICK 82 -#define VARIOUS_TRY_ILLUSION_OFF 83 -#define VARIOUS_SET_SPRITEIGNORE0HP 84 -#define VARIOUS_HANDLE_FORM_CHANGE 85 -#define VARIOUS_GET_STAT_VALUE 86 -#define VARIOUS_JUMP_IF_FULL_HP 87 -#define VARIOUS_LOSE_TYPE 88 -#define VARIOUS_TRY_ACTIVATE_SOULHEART 89 -#define VARIOUS_TRY_ACTIVATE_RECEIVER 90 -#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 91 -#define VARIOUS_TRY_FRISK 92 -#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 93 -#define VARIOUS_TRY_FAIRY_LOCK 94 -#define VARIOUS_JUMP_IF_NO_ALLY 95 -#define VARIOUS_POISON_TYPE_IMMUNITY 96 -#define VARIOUS_JUMP_IF_NO_HOLD_EFFECT 97 -#define VARIOUS_INFATUATE_WITH_BATTLER 98 -#define VARIOUS_SET_LAST_USED_ITEM 99 -#define VARIOUS_PARALYZE_TYPE_IMMUNITY 100 -#define VARIOUS_JUMP_IF_ABSENT 101 -#define VARIOUS_DESTROY_ABILITY_POPUP 102 -#define VARIOUS_TOTEM_BOOST 103 -#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 104 -#define VARIOUS_MOVEEND_ITEM_EFFECTS 105 -#define VARIOUS_TERRAIN_SEED 106 -#define VARIOUS_MAKE_INVISIBLE 107 -#define VARIOUS_ROOM_SERVICE 108 -#define VARIOUS_JUMP_IF_TERRAIN_AFFECTED 109 -#define VARIOUS_EERIE_SPELL_PP_REDUCE 110 -#define VARIOUS_JUMP_IF_TEAM_HEALTHY 111 -#define VARIOUS_TRY_HEAL_QUARTER_HP 112 -#define VARIOUS_REMOVE_TERRAIN 113 -#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114 -#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115 -#define VARIOUS_GET_ROTOTILLER_TARGETS 116 -#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 117 -#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 118 -#define VARIOUS_CONSUME_BERRY 119 -#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 120 -#define VARIOUS_HANDLE_PRIMAL_REVERSION 121 -#define VARIOUS_APPLY_PLASMA_FISTS 122 -#define VARIOUS_JUMP_IF_SPECIES 123 -#define VARIOUS_UPDATE_ABILITY_POPUP 124 -#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125 -#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126 -#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 -#define VARIOUS_PHOTON_GEYSER_CHECK 128 -#define VARIOUS_SHELL_SIDE_ARM_CHECK 129 -#define VARIOUS_TRY_NO_RETREAT 130 -#define VARIOUS_TRY_TAR_SHOT 131 -#define VARIOUS_CAN_TAR_SHOT_WORK 132 -#define VARIOUS_CHECK_POLTERGEIST 133 -#define VARIOUS_SET_OCTOLOCK 134 -#define VARIOUS_CUT_1_3_HP_RAISE_STATS 135 -#define VARIOUS_TRY_END_NEUTRALIZING_GAS 136 -#define VARIOUS_JUMP_IF_UNDER_200 137 -#define VARIOUS_SET_SKY_DROP 138 -#define VARIOUS_CLEAR_SKY_DROP 139 -#define VARIOUS_SKY_DROP_YAWN 140 -#define VARIOUS_JUMP_IF_CANT_FLING 141 -#define VARIOUS_JUMP_IF_HOLD_EFFECT 142 -#define VARIOUS_CURE_CERTAIN_STATUSES 143 -#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 145 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 146 -#define VARIOUS_SAVE_BATTLER_ITEM 147 -#define VARIOUS_RESTORE_BATTLER_ITEM 148 -#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 149 -#define VARIOUS_SET_BEAK_BLAST 150 -#define VARIOUS_SWAP_SIDE_STATUSES 151 -#define VARIOUS_SET_Z_EFFECT 152 -#define VARIOUS_TRY_SYMBIOSIS 153 -#define VARIOUS_CAN_TELEPORT 154 -#define VARIOUS_GET_BATTLER_SIDE 155 -#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 156 -#define VARIOUS_SWAP_STATS 157 -#define VARIOUS_JUMP_IF_ROD 158 -#define VARIOUS_JUMP_IF_ABSORB 159 -#define VARIOUS_JUMP_IF_MOTOR 160 -#define VARIOUS_TEATIME_INVUL 161 -#define VARIOUS_TEATIME_TARGETS 162 -#define VARIOUS_TRY_WIND_RIDER_POWER 163 -#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 164 -#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 165 -#define VARIOUS_JUMP_IF_NO_VALID_TARGETS 166 -#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 167 +#define VARIOUS_CANCEL_MULTI_TURN_MOVES 0 +#define VARIOUS_SET_MAGIC_COAT_TARGET 1 +#define VARIOUS_IS_RUNNING_IMPOSSIBLE 2 +#define VARIOUS_GET_MOVE_TARGET 3 +#define VARIOUS_GET_BATTLER_FAINTED 4 +#define VARIOUS_RESET_SWITCH_IN_ABILITY_BITS 5 +#define VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP 6 +#define VARIOUS_RESET_PLAYER_FAINTED 7 +#define VARIOUS_PALACE_FLAVOR_TEXT 8 +#define VARIOUS_ARENA_JUDGMENT_WINDOW 9 +#define VARIOUS_ARENA_OPPONENT_MON_LOST 10 +#define VARIOUS_ARENA_PLAYER_MON_LOST 11 +#define VARIOUS_ARENA_BOTH_MONS_LOST 12 +#define VARIOUS_EMIT_YESNOBOX 13 +#define VARIOUS_DRAW_ARENA_REF_TEXT_BOX 14 +#define VARIOUS_ERASE_ARENA_REF_TEXT_BOX 15 +#define VARIOUS_ARENA_JUDGMENT_STRING 16 +#define VARIOUS_ARENA_WAIT_STRING 17 +#define VARIOUS_WAIT_CRY 18 +#define VARIOUS_RETURN_OPPONENT_MON1 19 +#define VARIOUS_RETURN_OPPONENT_MON2 20 +#define VARIOUS_VOLUME_DOWN 21 +#define VARIOUS_VOLUME_UP 22 +#define VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT 23 +#define VARIOUS_PALACE_TRY_ESCAPE_STATUS 24 +#define VARIOUS_SET_TELEPORT_OUTCOME 25 +#define VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC 26 +#define VARIOUS_STAT_TEXT_BUFFER 27 +#define VARIOUS_SWITCHIN_ABILITIES 28 +#define VARIOUS_SAVE_TARGET 29 +#define VARIOUS_RESTORE_TARGET 30 +#define VARIOUS_INSTANT_HP_DROP 31 +#define VARIOUS_CLEAR_STATUS 32 +#define VARIOUS_RESTORE_PP 33 +#define VARIOUS_TRY_ACTIVATE_MOXIE 34 +#define VARIOUS_TRY_ACTIVATE_FELL_STINGER 35 +#define VARIOUS_PLAY_MOVE_ANIMATION 36 +#define VARIOUS_SET_LUCKY_CHANT 37 +#define VARIOUS_SUCKER_PUNCH_CHECK 38 +#define VARIOUS_SET_SIMPLE_BEAM 39 +#define VARIOUS_TRY_ENTRAINMENT 40 +#define VARIOUS_SET_LAST_USED_ABILITY 41 +#define VARIOUS_TRY_HEAL_PULSE 42 +#define VARIOUS_TRY_QUASH 43 +#define VARIOUS_INVERT_STAT_STAGES 44 +#define VARIOUS_SET_TERRAIN 45 +#define VARIOUS_TRY_ME_FIRST 46 +#define VARIOUS_JUMP_IF_BATTLE_END 47 +#define VARIOUS_TRY_ELECTRIFY 48 +#define VARIOUS_TRY_REFLECT_TYPE 49 +#define VARIOUS_TRY_SOAK 50 +#define VARIOUS_HANDLE_MEGA_EVO 51 +#define VARIOUS_TRY_LAST_RESORT 52 +#define VARIOUS_ARGUMENT_STATUS_EFFECT 53 +#define VARIOUS_TRY_HIT_SWITCH_TARGET 54 +#define VARIOUS_TRY_AUTOTOMIZE 55 +#define VARIOUS_TRY_COPYCAT 56 +#define VARIOUS_ABILITY_POPUP 57 +#define VARIOUS_DEFOG 58 +#define VARIOUS_JUMP_IF_TARGET_ALLY 59 +#define VARIOUS_TRY_SYNCHRONOISE 60 +#define VARIOUS_PSYCHO_SHIFT 61 +#define VARIOUS_CURE_STATUS 62 +#define VARIOUS_POWER_TRICK 63 +#define VARIOUS_AFTER_YOU 64 +#define VARIOUS_BESTOW 65 +#define VARIOUS_ARGUMENT_TO_MOVE_EFFECT 66 +#define VARIOUS_JUMP_IF_NOT_GROUNDED 67 +#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 68 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 69 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 70 +#define VARIOUS_SET_AURORA_VEIL 71 +#define VARIOUS_TRY_THIRD_TYPE 72 +#define VARIOUS_ACUPRESSURE 73 +#define VARIOUS_SET_POWDER 74 +#define VARIOUS_SPECTRAL_THIEF 75 +#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76 +#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77 +#define VARIOUS_JUMP_IF_ROAR_FAILS 78 +#define VARIOUS_TRY_INSTRUCT 79 +#define VARIOUS_JUMP_IF_NOT_BERRY 80 +#define VARIOUS_TRACE_ABILITY 81 +#define VARIOUS_UPDATE_NICK 82 +#define VARIOUS_TRY_ILLUSION_OFF 83 +#define VARIOUS_SET_SPRITEIGNORE0HP 84 +#define VARIOUS_HANDLE_FORM_CHANGE 85 +#define VARIOUS_GET_STAT_VALUE 86 +#define VARIOUS_JUMP_IF_FULL_HP 87 +#define VARIOUS_LOSE_TYPE 88 +#define VARIOUS_TRY_ACTIVATE_SOULHEART 89 +#define VARIOUS_TRY_ACTIVATE_RECEIVER 90 +#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 91 +#define VARIOUS_TRY_FRISK 92 +#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 93 +#define VARIOUS_TRY_FAIRY_LOCK 94 +#define VARIOUS_JUMP_IF_NO_ALLY 95 +#define VARIOUS_POISON_TYPE_IMMUNITY 96 +#define VARIOUS_JUMP_IF_NO_HOLD_EFFECT 97 +#define VARIOUS_INFATUATE_WITH_BATTLER 98 +#define VARIOUS_SET_LAST_USED_ITEM 99 +#define VARIOUS_PARALYZE_TYPE_IMMUNITY 100 +#define VARIOUS_JUMP_IF_ABSENT 101 +#define VARIOUS_DESTROY_ABILITY_POPUP 102 +#define VARIOUS_TOTEM_BOOST 103 +#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 104 +#define VARIOUS_MOVEEND_ITEM_EFFECTS 105 +#define VARIOUS_TERRAIN_SEED 106 +#define VARIOUS_MAKE_INVISIBLE 107 +#define VARIOUS_ROOM_SERVICE 108 +#define VARIOUS_JUMP_IF_TERRAIN_AFFECTED 109 +#define VARIOUS_EERIE_SPELL_PP_REDUCE 110 +#define VARIOUS_JUMP_IF_TEAM_HEALTHY 111 +#define VARIOUS_TRY_HEAL_QUARTER_HP 112 +#define VARIOUS_REMOVE_TERRAIN 113 +#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114 +#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115 +#define VARIOUS_GET_ROTOTILLER_TARGETS 116 +#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 117 +#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 118 +#define VARIOUS_CONSUME_BERRY 119 +#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 120 +#define VARIOUS_HANDLE_PRIMAL_REVERSION 121 +#define VARIOUS_APPLY_PLASMA_FISTS 122 +#define VARIOUS_JUMP_IF_SPECIES 123 +#define VARIOUS_UPDATE_ABILITY_POPUP 124 +#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125 +#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126 +#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 +#define VARIOUS_PHOTON_GEYSER_CHECK 128 +#define VARIOUS_SHELL_SIDE_ARM_CHECK 129 +#define VARIOUS_TRY_NO_RETREAT 130 +#define VARIOUS_TRY_TAR_SHOT 131 +#define VARIOUS_CAN_TAR_SHOT_WORK 132 +#define VARIOUS_CHECK_POLTERGEIST 133 +#define VARIOUS_SET_OCTOLOCK 134 +#define VARIOUS_CUT_1_3_HP_RAISE_STATS 135 +#define VARIOUS_TRY_END_NEUTRALIZING_GAS 136 +#define VARIOUS_JUMP_IF_UNDER_200 137 +#define VARIOUS_SET_SKY_DROP 138 +#define VARIOUS_CLEAR_SKY_DROP 139 +#define VARIOUS_SKY_DROP_YAWN 140 +#define VARIOUS_JUMP_IF_CANT_FLING 141 +#define VARIOUS_JUMP_IF_HOLD_EFFECT 142 +#define VARIOUS_CURE_CERTAIN_STATUSES 143 +#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 145 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 146 +#define VARIOUS_SAVE_BATTLER_ITEM 147 +#define VARIOUS_RESTORE_BATTLER_ITEM 148 +#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 149 +#define VARIOUS_SET_BEAK_BLAST 150 +#define VARIOUS_SWAP_SIDE_STATUSES 151 +#define VARIOUS_SET_Z_EFFECT 152 +#define VARIOUS_TRY_SYMBIOSIS 153 +#define VARIOUS_CAN_TELEPORT 154 +#define VARIOUS_GET_BATTLER_SIDE 155 +#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 156 +#define VARIOUS_SWAP_STATS 157 +#define VARIOUS_JUMP_IF_ROD 158 +#define VARIOUS_JUMP_IF_ABSORB 159 +#define VARIOUS_JUMP_IF_MOTOR 160 +#define VARIOUS_TEATIME_INVUL 161 +#define VARIOUS_TEATIME_TARGETS 162 +#define VARIOUS_TRY_WIND_RIDER_POWER 163 +#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 164 +#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 165 +#define VARIOUS_JUMP_IF_NO_VALID_TARGETS 166 +#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 167 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 168 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 169 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_main.c b/src/battle_main.c index b23d8af553..5ec0937f09 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3868,6 +3868,16 @@ void BattleTurnPassed(void) BattleScriptExecute(BattleScript_ArenaTurnBeginning); else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_LOW_HP)) BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2); + else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_HALF_HP)) + BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2); + else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_CRITICAL_HIT)) + BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2); + else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT)) + BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2); + else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_STAB_MOVE)) + BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2); + else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_PLAYER_MON_UNAFFECTED)) + BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2); } u8 IsRunningFromBattleImpossible(void) diff --git a/src/battle_message.c b/src/battle_message.c index 9c8a1b7020..6a301d9ee7 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3868,6 +3868,13 @@ struct TrainerSlide const u8 *msgLastSwitchIn; const u8 *msgLastLowHp; const u8 *msgFirstDown; + const u8 *msgLastHalfHp; + const u8 *msgFirstCriticalHit; + const u8 *msgFirstSuperEffectiveHit; + const u8 *msgFirstSTABMove; + const u8 *msgPlayerMonUnaffected; + const u8 *msgMegaEvolution; + const u8 *msgZMove; }; static const struct TrainerSlide sTrainerSlides[] = @@ -3879,20 +3886,39 @@ static const struct TrainerSlide sTrainerSlides[] = .msgLastSwitchIn = sText_AarghAlmostHadIt, .msgLastLowHp = sText_BoxIsFull, .msgFirstDown = sText_123Poof, + .msgLastHalfHp = sText_ShootSoClose, + .msgFirstCriticalHit = sText_CriticalHit, + .msgFirstSuperEffectiveHit = sText_SuperEffective, + .msgFirstSTABMove = sText_ABoosted, + .msgPlayerMonUnaffected = sText_ButNoEffect, + .msgMegaEvolution = sText_PowderExplodes, + .msgZMove = sText_Electromagnetism, }, */ }; -static u32 GetEnemyMonCount(bool32 onlyAlive) +static u32 GetAliveEnemyMonCount(void) { u32 i, count = 0; for (i = 0; i < PARTY_SIZE; i++) { u32 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2, NULL); - if (species != SPECIES_NONE - && species != SPECIES_EGG - && (!onlyAlive || GetMonData(&gEnemyParty[i], MON_DATA_HP, NULL))) + if (species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(&gEnemyParty[i], MON_DATA_HP, NULL)) + count++; + } + + return count; +} + +static u32 GetTotalEnemyMonCount(void) +{ + u32 i, count = 0; + + for (i = 0; i < PARTY_SIZE; i++) + { + u32 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2, NULL); + if (species != SPECIES_NONE && species != SPECIES_EGG) count++; } @@ -3914,7 +3940,7 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which) switch (which) { case TRAINER_SLIDE_LAST_SWITCHIN: - if (sTrainerSlides[i].msgLastSwitchIn != NULL && GetEnemyMonCount(TRUE) == 1) + if (sTrainerSlides[i].msgLastSwitchIn != NULL && GetAliveEnemyMonCount() == 1) { gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastSwitchIn; return TRUE; @@ -3922,9 +3948,9 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which) break; case TRAINER_SLIDE_LAST_LOW_HP: if (sTrainerSlides[i].msgLastLowHp != NULL - && GetEnemyMonCount(TRUE) == 1 - && gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 4) - && !gBattleStruct->trainerSlideLowHpMsgDone) + && GetAliveEnemyMonCount() == 1 + && gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 4) + && !gBattleStruct->trainerSlideLowHpMsgDone) { gBattleStruct->trainerSlideLowHpMsgDone = TRUE; gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastLowHp; @@ -3932,12 +3958,77 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which) } break; case TRAINER_SLIDE_FIRST_DOWN: - if (sTrainerSlides[i].msgFirstDown != NULL && GetEnemyMonCount(TRUE) == GetEnemyMonCount(FALSE) - 1) + if (sTrainerSlides[i].msgFirstDown != NULL && GetAliveEnemyMonCount() == GetTotalEnemyMonCount() - 1) { gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstDown; return TRUE; } break; + case TRAINER_SLIDE_LAST_HALF_HP: + if (sTrainerSlides[i].msgLastHalfHp != NULL + && GetAliveEnemyMonCount() == 1 + && (gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 2) && gBattleMons[battlerId].hp > (gBattleMons[battlerId].maxHP / 4)) + && !gBattleStruct->trainerSlideHalfHpMsgDone) + { + gBattleStruct->trainerSlideHalfHpMsgDone = TRUE; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastHalfHp; + return TRUE; + } + break; + case TRAINER_SLIDE_FIRST_CRITICAL_HIT: + if (sTrainerSlides[i].msgFirstCriticalHit != NULL && gBattleStruct->trainerSlideFirstCriticalHitMsgState == 1) + { + gBattleStruct->trainerSlideFirstCriticalHitMsgState = 2; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstCriticalHit; + return TRUE; + } + break; + case TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT: + if (sTrainerSlides[i].msgFirstSuperEffectiveHit != NULL + && gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState == 1 + && gBattleMons[battlerId].hp) + { + gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState = 2; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstSuperEffectiveHit; + return TRUE; + } + break; + case TRAINER_SLIDE_FIRST_STAB_MOVE: + if (sTrainerSlides[i].msgFirstSTABMove != NULL + && gBattleStruct->trainerSlideFirstSTABMoveMsgState == 1 + && GetAliveEnemyMonCount() == GetTotalEnemyMonCount()) + { + gBattleStruct->trainerSlideFirstSTABMoveMsgState = 2; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstSTABMove; + return TRUE; + } + break; + case TRAINER_SLIDE_PLAYER_MON_UNAFFECTED: + if (sTrainerSlides[i].msgPlayerMonUnaffected != NULL + && gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState == 1 + && GetAliveEnemyMonCount() == GetTotalEnemyMonCount()) + { + gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState = 2; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgPlayerMonUnaffected; + return TRUE; + } + break; + case TRAINER_SLIDE_MEGA_EVOLUTION: + if (sTrainerSlides[i].msgMegaEvolution != NULL && !gBattleStruct->trainerSlideMegaEvolutionMsgDone) + { + gBattleStruct->trainerSlideMegaEvolutionMsgDone = TRUE; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgMegaEvolution; + return TRUE; + } + break; + case TRAINER_SLIDE_Z_MOVE: + if (sTrainerSlides[i].msgZMove != NULL && !gBattleStruct->trainerSlideZMoveMsgDone) + { + gBattleStruct->trainerSlideZMoveMsgDone = TRUE; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgZMove; + return TRUE; + } + break; } break; } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 87feb56271..683a979bdd 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2540,6 +2540,11 @@ static void Cmd_critmessage(void) if (gIsCriticalHit == TRUE && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) { PrepareStringBattle(STRINGID_CRITICALHIT, gBattlerAttacker); + + // Signal for the trainer slide-in system. + if (GetBattlerSide(gBattlerTarget) != B_SIDE_PLAYER && gBattleStruct->trainerSlideFirstCriticalHitMsgState != 2) + gBattleStruct->trainerSlideFirstCriticalHitMsgState = 1; + gBattleCommunication[MSG_DISPLAY] = 1; } gBattlescriptCurrInstr = cmd->nextInstr; @@ -2619,7 +2624,13 @@ static void Cmd_resultmessage(void) { case MOVE_RESULT_SUPER_EFFECTIVE: if (!gMultiHitCounter) // Don't print effectiveness on each hit in a multi hit attack + { + // Signal for the trainer slide-in system. + if (GetBattlerSide(gBattlerTarget) != B_SIDE_PLAYER && gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState != 2) + gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState = 1; + stringId = STRINGID_SUPEREFFECTIVE; + } break; case MOVE_RESULT_NOT_VERY_EFFECTIVE: if (!gMultiHitCounter) @@ -11040,6 +11051,30 @@ static void Cmd_various(void) gBattlescriptCurrInstr = cmd->nextInstr; return; } + case VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE: + { + VARIOUS_ARGS(); + if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_Z_MOVE)) + { + gBattleScripting.battler = gActiveBattler; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet; + return; + } + break; + } + case VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION: + { + VARIOUS_ARGS(); + if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_MEGA_EVOLUTION)) + { + gBattleScripting.battler = gActiveBattler; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet; + return; + } + break; + } } // End of switch (cmd->id) gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/battle_util.c b/src/battle_util.c index 46f8d3a3d3..18ac8fa543 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1607,6 +1607,12 @@ void PrepareStringBattle(u16 stringId, u8 battler) } #endif + // Signal for the trainer slide-in system. + if ((stringId == STRINGID_ITDOESNTAFFECT || stringId == STRINGID_PKMNWASNTAFFECTED || stringId == STRINGID_PKMNUNAFFECTED) + && GetBattlerSide(gBattlerTarget) == B_SIDE_OPPONENT + && gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState != 2) + gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState = 1; + gActiveBattler = battler; BtlController_EmitPrintString(BUFFER_A, stringId); MarkBattlerForControllerExec(gActiveBattler); @@ -9884,6 +9890,10 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat } } + // Signal for the trainer slide-in system. + if (GetBattlerSide(battlerDef) != B_SIDE_PLAYER && modifier && gBattleStruct->trainerSlideFirstSTABMoveMsgState != 2) + gBattleStruct->trainerSlideFirstSTABMoveMsgState = 1; + return modifier; } From 8a036e6007cdc8152a89b3ef211cb51fb759091e Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 27 Feb 2023 07:45:01 -0300 Subject: [PATCH 03/30] Made this build again --- src/battle_main.c | 10 +++++----- src/battle_message.c | 2 +- src/battle_script_commands.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 0f841a89be..d144590d59 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3868,15 +3868,15 @@ void BattleTurnPassed(void) BattleScriptExecute(BattleScript_ArenaTurnBeginning); else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_LAST_LOW_HP))) BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2); - else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_LAST_HALF_HP)) + else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_LAST_HALF_HP))) BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2); - else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_CRITICAL_HIT)) + else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_CRITICAL_HIT))) BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2); - else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT)) + else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT))) BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2); - else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_STAB_MOVE)) + else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_STAB_MOVE))) BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2); - else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_PLAYER_MON_UNAFFECTED)) + else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_PLAYER_MON_UNAFFECTED))) BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2); } diff --git a/src/battle_message.c b/src/battle_message.c index a9536d5a13..f321da46c0 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3964,7 +3964,7 @@ u32 ShouldDoTrainerSlide(u32 battlerId, u32 which) case TRAINER_SLIDE_LAST_LOW_HP: if (sTrainerSlides[i].msgLastLowHp != NULL && GetEnemyMonCount(firstId, lastId, TRUE) == 1 - && IsBattlerHpLow(battlerId) + && gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 4) && !gBattleStruct->trainerSlideLowHpMsgDone) { gBattleStruct->trainerSlideLowHpMsgDone = TRUE; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e50aed2429..21e1d4d9c5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11170,11 +11170,11 @@ static void Cmd_various(void) case VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE: { VARIOUS_ARGS(); - if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_Z_MOVE)) + if ((i = ShouldDoTrainerSlide(gActiveBattler, TRAINER_SLIDE_Z_MOVE))) { gBattleScripting.battler = gActiveBattler; BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet; + gBattlescriptCurrInstr = (i == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet); return; } break; @@ -11182,11 +11182,11 @@ static void Cmd_various(void) case VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION: { VARIOUS_ARGS(); - if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_MEGA_EVOLUTION)) + if ((i = ShouldDoTrainerSlide(gActiveBattler, TRAINER_SLIDE_MEGA_EVOLUTION))) { gBattleScripting.battler = gActiveBattler; BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet; + gBattlescriptCurrInstr = (i == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet); return; } break; From ff15856820bd30e9820e8fb5a46b093e39f47a0d Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Thu, 2 Mar 2023 06:14:42 -0300 Subject: [PATCH 04/30] Added yet another trainer slide condition Now a trainer NPC can also say something before the first turn of a battle starts for good. --- include/battle.h | 1 + include/battle_message.h | 1 + src/battle_main.c | 3 +++ src/battle_message.c | 10 ++++++++++ 4 files changed, 15 insertions(+) diff --git a/include/battle.h b/include/battle.h index 3c2b6ed197..f3b788037e 100644 --- a/include/battle.h +++ b/include/battle.h @@ -669,6 +669,7 @@ struct BattleStruct u8 trainerSlidePlayerMonUnaffectedMsgState:2; bool8 trainerSlideMegaEvolutionMsgDone:1; bool8 trainerSlideZMoveMsgDone:1; + bool8 trainerSlideBeforeFirstTurnMsgDone:1; }; #define F_DYNAMIC_TYPE_1 (1 << 6) diff --git a/include/battle_message.h b/include/battle_message.h index de60d6d026..93bb63022b 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -236,6 +236,7 @@ enum TRAINER_SLIDE_PLAYER_MON_UNAFFECTED, TRAINER_SLIDE_MEGA_EVOLUTION, TRAINER_SLIDE_Z_MOVE, + TRAINER_SLIDE_BEFORE_FIRST_TURN, }; void BufferStringBattle(u16 stringID); diff --git a/src/battle_main.c b/src/battle_main.c index d144590d59..a93bef7ac6 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3776,6 +3776,9 @@ static void TryDoEventsBeforeFirstTurn(void) StopCryAndClearCrySongs(); BattleScriptExecute(BattleScript_ArenaTurnBeginning); } + + if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_BEFORE_FIRST_TURN))) + BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2); } static void HandleEndTurn_ContinueBattle(void) diff --git a/src/battle_message.c b/src/battle_message.c index f321da46c0..ed430e9f8c 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3881,6 +3881,7 @@ struct TrainerSlide const u8 *msgPlayerMonUnaffected; const u8 *msgMegaEvolution; const u8 *msgZMove; + const u8 *msgBeforeFirstTurn; }; static const struct TrainerSlide sTrainerSlides[] = @@ -3899,6 +3900,7 @@ static const struct TrainerSlide sTrainerSlides[] = .msgPlayerMonUnaffected = sText_ButNoEffect, .msgMegaEvolution = sText_PowderExplodes, .msgZMove = sText_Electromagnetism, + .msgBeforeFirstTurn = sText_GravityIntensified, }, */ }; @@ -4044,6 +4046,14 @@ u32 ShouldDoTrainerSlide(u32 battlerId, u32 which) return TRUE; } break; + case TRAINER_SLIDE_BEFORE_FIRST_TURN: + if (sTrainerSlides[i].msgBeforeFirstTurn != NULL && !gBattleStruct->trainerSlideBeforeFirstTurnMsgDone) + { + gBattleStruct->trainerSlideBeforeFirstTurnMsgDone = TRUE; + gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgBeforeFirstTurn; + return TRUE; + } + break; } break; } From 686d42709a6281c5baed0e5a6d8aad34b6b642a5 Mon Sep 17 00:00:00 2001 From: PSF Date: Tue, 28 Mar 2023 15:50:58 -0700 Subject: [PATCH 05/30] Added documentation on resetting battle flags and vars Added Overworld_ResetBattleFlagsAndVars to Overworld_ResetStateAfterWhiteOut --- include/config/battle.h | 2 ++ src/overworld.c | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/config/battle.h b/include/config/battle.h index 4a3d6382fb..c6bca6de89 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -143,6 +143,7 @@ // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. // Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag to toggle the feature. +// Once these features are turned on within the game, they will remain on until they are explcitily turned off or until the player whites out. This can be turned off by disabling Overworld_ResetBattleFlagsAndVars. #define B_FLAG_INVERSE_BATTLE 0 // If this flag is set, the battle's type effectiveness are inversed. For example, fire is super effective against water. #define B_FLAG_FORCE_DOUBLE_WILD 0 // If this flag is set, all land and surfing wild battles will be double battles. #define B_SMART_WILD_AI_FLAG 0 // If not 0, you can set this flag in a script to enable smart wild pokemon @@ -152,6 +153,7 @@ // Var Settings // To use the following features in scripting, replace the 0s with the var ID you're assigning it to. // Eg: Replace with VAR_UNUSED_0x40F7 so you can use VAR_TERRAIN for that feature. +// Once these features are turned on within the game, they will remain on until they are explcitily turned off or until the player whites out. This can be turned off by disabling Overworld_ResetBattleFlagsAndVars. #define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active #define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) diff --git a/src/overworld.c b/src/overworld.c index 6b63a60d5b..9fabe3ed90 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -401,6 +401,23 @@ void Overworld_ResetStateAfterDigEscRope(void) FlagClear(FLAG_SYS_USE_FLASH); } +void Overworld_ResetBattleFlagsAndVars(void) +{ +#if VAR_TERRAIN != 0 + VarSet(VAR_TERRAIN, 0); +#endif + +#if B_VAR_WILD_AI_FLAGS != 0 + VarSet(B_VAR_WILD_AI_FLAGS,0); +#endif + + FlagClear(B_FLAG_INVERSE_BATTLE); + FlagClear(B_FLAG_FORCE_DOUBLE_WILD); + FlagClear(B_SMART_WILD_AI_FLAG); + FlagClear(B_FLAG_NO_BAG_USE); + FlagClear(B_FLAG_NO_CATCHING); +} + static void Overworld_ResetStateAfterWhiteOut(void) { ResetInitialPlayerAvatarState(); @@ -409,9 +426,7 @@ static void Overworld_ResetStateAfterWhiteOut(void) FlagClear(FLAG_SYS_SAFARI_MODE); FlagClear(FLAG_SYS_USE_STRENGTH); FlagClear(FLAG_SYS_USE_FLASH); -#if VAR_TERRAIN != 0 - VarSet(VAR_TERRAIN, 0); -#endif + Overworld_ResetBattleFlagsAndVars(); // If you were defeated by Kyogre/Groudon and the step counter has // maxed out, end the abnormal weather. if (VarGet(VAR_SHOULD_END_ABNORMAL_WEATHER) == 1) From 24df9823e8f1c20e723b2b9b8b2ab01ee84db379 Mon Sep 17 00:00:00 2001 From: PSF Date: Thu, 30 Mar 2023 06:35:38 -0700 Subject: [PATCH 06/30] In response to PR discussion, added new preproc config for developers to toggle Overworld_ResetBattleFlagsAndVars --- include/config/battle.h | 5 +++-- src/overworld.c | 18 +++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/config/battle.h b/include/config/battle.h index c6bca6de89..77e0e0f4d9 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -143,7 +143,6 @@ // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. // Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag to toggle the feature. -// Once these features are turned on within the game, they will remain on until they are explcitily turned off or until the player whites out. This can be turned off by disabling Overworld_ResetBattleFlagsAndVars. #define B_FLAG_INVERSE_BATTLE 0 // If this flag is set, the battle's type effectiveness are inversed. For example, fire is super effective against water. #define B_FLAG_FORCE_DOUBLE_WILD 0 // If this flag is set, all land and surfing wild battles will be double battles. #define B_SMART_WILD_AI_FLAG 0 // If not 0, you can set this flag in a script to enable smart wild pokemon @@ -153,10 +152,12 @@ // Var Settings // To use the following features in scripting, replace the 0s with the var ID you're assigning it to. // Eg: Replace with VAR_UNUSED_0x40F7 so you can use VAR_TERRAIN for that feature. -// Once these features are turned on within the game, they will remain on until they are explcitily turned off or until the player whites out. This can be turned off by disabling Overworld_ResetBattleFlagsAndVars. #define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active #define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) +//Flag and Var settings +#define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If set to TRUE, Flag and Var settings (B_FLAG_INVERSE_BATTLE,B_FLAG_FORCE_DOUBLE_WILD,B_SMART_WILD_AI_FLAG,B_FLAG_NO_BAG_USE,B_FLAG_NO_CATCHING,B_VAR_WILD_AI_FLAGS, and VAR_TERRAIN) will be reset when the player whites out. + // Terrain settings #define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. #define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. diff --git a/src/overworld.c b/src/overworld.c index 9fabe3ed90..3af1cfd6d8 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -401,15 +401,16 @@ void Overworld_ResetStateAfterDigEscRope(void) FlagClear(FLAG_SYS_USE_FLASH); } -void Overworld_ResetBattleFlagsAndVars(void) +#if B_RESET_FLAGS_VARS_AFTER_WHITEOUT == TRUE + void Overworld_ResetBattleFlagsAndVars(void) { -#if VAR_TERRAIN != 0 - VarSet(VAR_TERRAIN, 0); -#endif + #if VAR_TERRAIN != 0 + VarSet(VAR_TERRAIN, 0); + #endif -#if B_VAR_WILD_AI_FLAGS != 0 - VarSet(B_VAR_WILD_AI_FLAGS,0); -#endif + #if B_VAR_WILD_AI_FLAGS != 0 + VarSet(B_VAR_WILD_AI_FLAGS,0); + #endif FlagClear(B_FLAG_INVERSE_BATTLE); FlagClear(B_FLAG_FORCE_DOUBLE_WILD); @@ -417,6 +418,7 @@ void Overworld_ResetBattleFlagsAndVars(void) FlagClear(B_FLAG_NO_BAG_USE); FlagClear(B_FLAG_NO_CATCHING); } +#endif static void Overworld_ResetStateAfterWhiteOut(void) { @@ -426,7 +428,9 @@ static void Overworld_ResetStateAfterWhiteOut(void) FlagClear(FLAG_SYS_SAFARI_MODE); FlagClear(FLAG_SYS_USE_STRENGTH); FlagClear(FLAG_SYS_USE_FLASH); +#if B_RESET_FLAGS_VARS_AFTER_WHITEOUT == TRUE Overworld_ResetBattleFlagsAndVars(); +#endif // If you were defeated by Kyogre/Groudon and the step counter has // maxed out, end the abnormal weather. if (VarGet(VAR_SHOULD_END_ABNORMAL_WEATHER) == 1) From 59dfc7c3ad513ee2bc05b43e80eedf7dfccb43ee Mon Sep 17 00:00:00 2001 From: psf <77138753+pkmnsnfrn@users.noreply.github.com> Date: Fri, 7 Apr 2023 06:07:12 -0700 Subject: [PATCH 07/30] Update include/config/battle.h Took suggestions from https://github.com/rh-hideout/pokeemerald-expansion/pull/2875#discussion_r1160574308 Co-authored-by: LOuroboros --- include/config/battle.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/config/battle.h b/include/config/battle.h index 77e0e0f4d9..790ad78cca 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -155,8 +155,8 @@ #define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active #define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) -//Flag and Var settings -#define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If set to TRUE, Flag and Var settings (B_FLAG_INVERSE_BATTLE,B_FLAG_FORCE_DOUBLE_WILD,B_SMART_WILD_AI_FLAG,B_FLAG_NO_BAG_USE,B_FLAG_NO_CATCHING,B_VAR_WILD_AI_FLAGS, and VAR_TERRAIN) will be reset when the player whites out. +// Flag and Var settings +#define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If TRUE, Overworld_ResetBattleFlagsAndVars will reset battle-related Flags and Vars when the player whites out. // Terrain settings #define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. From 82dc1e3e93810f74f7abd377f76c2f4ceab70976 Mon Sep 17 00:00:00 2001 From: AgustinGDLV Date: Sat, 15 Apr 2023 09:27:28 -0700 Subject: [PATCH 08/30] fixed dupe strings in battle item use --- data/battle_scripts_2.s | 12 ++++++------ src/item_use.c | 5 +++-- src/party_menu.c | 8 +------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index dee482d1d3..71d88ae84b 100644 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -49,14 +49,13 @@ BattleScript_UseItemMessage: BattleScript_ItemRestoreHP:: call BattleScript_UseItemMessage itemrestorehp - printstring STRINGID_ITEMRESTOREDSPECIESHEALTH - waitmessage B_WAIT_TIME_LONG jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_ItemRestoreHP_SendOutRevivedBattler bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER - updatestatusicon BS_ATTACKER + printstring STRINGID_ITEMRESTOREDSPECIESHEALTH + waitmessage B_WAIT_TIME_LONG end BattleScript_ItemRestoreHP_SendOutRevivedBattler: @@ -68,22 +67,22 @@ BattleScript_ItemRestoreHP_SendOutRevivedBattler: BattleScript_ItemCureStatus:: call BattleScript_UseItemMessage itemcurestatus + updatestatusicon BS_ATTACKER printstring STRINGID_ITEMCUREDSPECIESSTATUS waitmessage B_WAIT_TIME_LONG - updatestatusicon BS_ATTACKER end BattleScript_ItemHealAndCureStatus:: call BattleScript_UseItemMessage itemrestorehp curestatus BS_ATTACKER - printstring STRINGID_ITEMRESTOREDSPECIESHEALTH - waitmessage B_WAIT_TIME_LONG bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER updatestatusicon BS_ATTACKER + printstring STRINGID_ITEMRESTOREDSPECIESHEALTH + waitmessage B_WAIT_TIME_LONG end BattleScript_ItemIncreaseStat:: @@ -256,3 +255,4 @@ BattleScript_TrainerBSlideMsgRet:: BattleScript_TrainerBSlideMsgEnd2:: call BattleScript_TrainerBSlideMsgRet end2 + end2 diff --git a/src/item_use.c b/src/item_use.c index 8bcadfb2eb..26b48ac80b 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -1229,10 +1229,11 @@ void ItemUseInBattle_BagMenu(u8 taskId) { PlaySE(SE_SELECT); RemoveUsedItem(); + ScheduleBgCopyTilemapToVram(2); if (!InBattlePyramid()) - DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, Task_FadeAndCloseBagMenu); + gTasks[taskId].func = Task_FadeAndCloseBagMenu; else - DisplayItemMessageInBattlePyramid(taskId, gStringVar4, CloseBattlePyramidBag); + gTasks[taskId].func = CloseBattlePyramidBag; } } diff --git a/src/party_menu.c b/src/party_menu.c index dd46b10634..95d64e5463 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -4470,11 +4470,8 @@ void ItemUseCB_BattleScript(u8 taskId, TaskFunc task) gBattleStruct->itemPartyIndex[gBattlerInMenuId] = GetPartyIdFromBattleSlot(gPartyMenu.slotId); gPartyMenuUseExitCallback = TRUE; PlaySE(SE_SELECT); - CopyItemName(gSpecialVar_ItemId, gStringVar2); - StringExpandPlaceholders(gStringVar4, gText_PlayerUsedVar2); - DisplayPartyMenuMessage(gStringVar4, TRUE); - ScheduleBgCopyTilemapToVram(2); RemoveBagItem(gSpecialVar_ItemId, 1); + ScheduleBgCopyTilemapToVram(2); gTasks[taskId].func = task; } } @@ -4943,9 +4940,6 @@ static void TryUseItemOnMove(u8 taskId) gChosenMovePos = ptr->data1; gPartyMenuUseExitCallback = TRUE; RemoveBagItem(gSpecialVar_ItemId, 1); - CopyItemName(gSpecialVar_ItemId, gStringVar2); - StringExpandPlaceholders(gStringVar4, gText_PlayerUsedVar2); - DisplayPartyMenuMessage(gStringVar4, TRUE); ScheduleBgCopyTilemapToVram(2); gTasks[taskId].func = Task_ClosePartyMenuAfterText; } From d3a090020bb062d88c0c162bc62292e4debfcd95 Mon Sep 17 00:00:00 2001 From: AgustinGDLV Date: Sat, 15 Apr 2023 15:30:07 -0700 Subject: [PATCH 09/30] added code review --- data/battle_scripts_2.s | 1 - src/battle_message.c | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index 71d88ae84b..9ffad7d843 100644 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -255,4 +255,3 @@ BattleScript_TrainerBSlideMsgRet:: BattleScript_TrainerBSlideMsgEnd2:: call BattleScript_TrainerBSlideMsgRet end2 - end2 diff --git a/src/battle_message.c b/src/battle_message.c index 7d10b19f11..640e7900da 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -465,7 +465,7 @@ const u8 *const gPokeblockWasTooXStringTable[FLAVOR_COUNT] = [FLAVOR_SOUR] = sText_PokeblockWasTooSour }; -static const u8 sText_PlayerUsedItem[] = _("{B_PLAYER_NAME} used\n{B_LAST_ITEM}!"); +static const u8 sText_PlayerUsedItem[] = _("You used\n{B_LAST_ITEM}!"); static const u8 sText_WallyUsedItem[] = _("WALLY used\n{B_LAST_ITEM}!"); static const u8 sText_Trainer1UsedItem[] = _("{B_ATK_TRAINER_CLASS} {B_ATK_TRAINER_NAME}\nused {B_LAST_ITEM}!"); static const u8 sText_TrainerBlockedBall[] = _("The TRAINER blocked the BALL!"); @@ -783,9 +783,9 @@ static const u8 sText_ShellTrapDidntWork[] = _("{B_ATK_NAME_WITH_PREFIX}'s shell static const u8 sText_CouldntFullyProtect[] = _("{B_DEF_NAME_WITH_PREFIX} couldn't fully protect\nitself and got hurt!"); static const u8 sText_StockpiledEffectWoreOff[] = _("{B_ATK_NAME_WITH_PREFIX}'s stockpiled\neffect wore off!"); static const u8 sText_PkmnRevivedReadyToFight[] = _("{B_BUFF1} was revived and\nis ready to fight again!"); -static const u8 sText_ItemRestoredSpeciesHealth[] = _("{B_LAST_ITEM} restored\n{B_BUFF1}'s health!"); -static const u8 sText_ItemCuredSpeciesStatus[] = _("{B_LAST_ITEM} cured\n{B_BUFF1}'s status!"); -static const u8 sText_ItemRestoredSpeciesPP[] = _("{B_LAST_ITEM} restored\n{B_BUFF1}'s PP!"); +static const u8 sText_ItemRestoredSpeciesHealth[] = _("{B_BUFF1} had its\nHP restored!"); +static const u8 sText_ItemCuredSpeciesStatus[] = _("{B_BUFF1} had\nits status healed!"); +static const u8 sText_ItemRestoredSpeciesPP[] = _("{B_BUFF1} had its\nPP restored!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { From 7d4807d956c391e480c2be39afbeb4117ba431da Mon Sep 17 00:00:00 2001 From: CallmeEchoo <65783283+CallmeEchoo@users.noreply.github.com> Date: Sun, 16 Apr 2023 13:11:49 +0200 Subject: [PATCH 10/30] fix nightmare status only being healed in doubles this came up in a conversation on discord. its not tested. --- src/battle_script_commands.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d313697b0a..dcfaf0da4d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -16506,10 +16506,11 @@ void BS_ItemCureStatus(void) { { gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem); gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker); - if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP) - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; } + if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP) + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; + PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES)); gBattlescriptCurrInstr = cmd->nextInstr; } From 73ba8264e0f6d9a4e98f9ef3ded2c527c3f6ab5d Mon Sep 17 00:00:00 2001 From: Jaizu Date: Sun, 16 Apr 2023 21:34:07 +0200 Subject: [PATCH 11/30] Fix Rare Candies --- src/party_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/party_menu.c b/src/party_menu.c index dd46b10634..a7ab305450 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -4948,7 +4948,7 @@ static void TryUseItemOnMove(u8 taskId) DisplayPartyMenuMessage(gStringVar4, TRUE); ScheduleBgCopyTilemapToVram(2); gTasks[taskId].func = Task_ClosePartyMenuAfterText; - } + } } // Outside of battle, only PP items are used on moves. else @@ -5290,7 +5290,7 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task) if (sInitialLevel != MAX_LEVEL) { BufferMonStatsToTaskData(mon, arrayPtr); - cannotUseEffect = ExecuteTableBasedItemEffect(mon, gPartyMenu.slotId, *itemPtr, 0); + cannotUseEffect = ExecuteTableBasedItemEffect(mon, *itemPtr, gPartyMenu.slotId, 0); BufferMonStatsToTaskData(mon, &ptr->data[NUM_STATS]); } else From efd7465c12a2ab52335bb0a90f1c6325f5af1aba Mon Sep 17 00:00:00 2001 From: CallmeEchoo Date: Mon, 17 Apr 2023 13:34:11 +0200 Subject: [PATCH 12/30] fix gBattleMons using party indices instead of battle indices --- src/battle_script_commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index dcfaf0da4d..4e1494ce38 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -16500,7 +16500,9 @@ void BS_ItemCureStatus(void) { // Heal Status2 conditions if battler is active. if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker]) - gBattleMons[gBattleStruct->itemPartyIndex[gBattlerAttacker]].status2 &= ~GetItemStatus2Mask(gLastUsedItem); + { + gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem); + } else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)]) { From 0531ab5d87ecdc959a331535719fabe180cddd81 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 17 Apr 2023 18:47:54 +0200 Subject: [PATCH 13/30] Fix Ability PopUp freeze --- data/battle_scripts_1.s | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 4848b73227..91bc37f76f 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5612,7 +5612,7 @@ BattleScript_EffectStockpileSpDef:: BattleScript_EffectStockpileEnd: stockpile 1 goto BattleScript_MoveEnd - + BattleScript_MoveEffectStockpileWoreOff:: .if B_STOCKPILE_RAISES_DEFS >= GEN_4 dostockpilestatchangeswearoff BS_ATTACKER, BattleScript_StockpileStatChangeDown @@ -5620,7 +5620,7 @@ BattleScript_MoveEffectStockpileWoreOff:: waitmessage B_WAIT_TIME_SHORT .endif return - + BattleScript_StockpileStatChangeDown: statbuffchange MOVE_EFFECT_AFFECTS_USER, BattleScript_StockpileStatChangeDown_Ret setgraphicalstatchangevalues @@ -6943,7 +6943,7 @@ BattleScript_MagicRoomEnds:: printstring STRINGID_MAGICROOMENDS waitmessage B_WAIT_TIME_LONG end2 - + BattleScript_GrassyTerrainEnds: setbyte cMULTISTRING_CHOOSER, B_MSG_TERRAINENDS_GRASS BattleScript_TerrainEnds_Ret:: @@ -6951,7 +6951,7 @@ BattleScript_TerrainEnds_Ret:: waitmessage B_WAIT_TIME_LONG playanimation BS_ATTACKER, B_ANIM_RESTORE_BG return - + BattleScript_TerrainEnds:: call BattleScript_TerrainEnds_Ret end2 @@ -7496,7 +7496,7 @@ BattleScript_StealthRockFree:: printstring STRINGID_PKMNBLEWAWAYSTEALTHROCK waitmessage B_WAIT_TIME_LONG return - + BattleScript_SpikesDefog:: printstring STRINGID_SPIKESDISAPPEAREDFROMTEAM waitmessage B_WAIT_TIME_LONG @@ -9181,6 +9181,7 @@ BattleScript_WanderingSpiritActivates:: destroyabilitypopup pause 40 + copybyte gBattlerAbility, gBattlerAttacker setbyte sFIXED_ABILITY_POPUP, TRUE copyhword sABILITY_OVERWRITE, gLastUsedAbility showabilitypopup BS_ATTACKER From 60c88d8fccb0c0fa3b1a44273b7210f228412a26 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Mon, 17 Apr 2023 19:12:39 +0200 Subject: [PATCH 14/30] Update data/battle_scripts_1.s Co-authored-by: Eduardo Quezada D'Ottone --- data/battle_scripts_1.s | 1 - 1 file changed, 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 91bc37f76f..0be8934127 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -9180,7 +9180,6 @@ BattleScript_WanderingSpiritActivates:: pause 20 destroyabilitypopup pause 40 - copybyte gBattlerAbility, gBattlerAttacker setbyte sFIXED_ABILITY_POPUP, TRUE copyhword sABILITY_OVERWRITE, gLastUsedAbility From 9d93af2261101aee307ca6cc82c4c04dec36ab74 Mon Sep 17 00:00:00 2001 From: Frank DeBlasio <35279583+fdeblasio@users.noreply.github.com> Date: Tue, 18 Apr 2023 16:28:02 -0400 Subject: [PATCH 15/30] Fixed Budew evolution method (#2928) --- src/data/pokemon/evolution.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/pokemon/evolution.h b/src/data/pokemon/evolution.h index 6ec3c0a14c..f222148178 100644 --- a/src/data/pokemon/evolution.h +++ b/src/data/pokemon/evolution.h @@ -316,7 +316,7 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] = [SPECIES_KRICKETOT] = {{EVO_LEVEL, 10, SPECIES_KRICKETUNE}}, [SPECIES_SHINX] = {{EVO_LEVEL, 15, SPECIES_LUXIO}}, [SPECIES_LUXIO] = {{EVO_LEVEL, 30, SPECIES_LUXRAY}}, - [SPECIES_BUDEW] = {{EVO_FRIENDSHIP, 0, SPECIES_ROSELIA}}, + [SPECIES_BUDEW] = {{EVO_FRIENDSHIP_DAY, 0, SPECIES_ROSELIA}}, [SPECIES_CRANIDOS] = {{EVO_LEVEL, 30, SPECIES_RAMPARDOS}}, [SPECIES_SHIELDON] = {{EVO_LEVEL, 30, SPECIES_BASTIODON}}, [SPECIES_BURMY] = {{EVO_LEVEL_FEMALE, 20, SPECIES_WORMADAM}, From 76d0d8a94eeab0aa2e0943ab5581c31cb893462a Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Tue, 18 Apr 2023 23:02:51 +0200 Subject: [PATCH 16/30] Fix battle message strings for stats (#2927) * Fix battle message strings for stats --- include/config/battle.h | 4 ++-- src/battle_message.c | 12 ++++++------ src/pokemon.c | 4 ++-- test/ability_contrary.c | 18 +++++++++--------- test/ability_download.c | 12 ++++++------ test/ability_intimidate.c | 2 +- test/ability_magic_bounce.c | 6 +++--- test/ability_oblivious.c | 2 +- test/ability_speed_boost.c | 2 +- test/ability_volt_absorb.c | 2 +- test/item_effect_increase_stat.c | 2 +- test/move.c | 4 ++-- test/move_effect_attack_down.c | 2 +- test/move_effect_attack_up.c | 2 +- test/move_effect_attack_up_user_ally.c | 6 +++--- test/move_effect_defense_down.c | 2 +- test/move_effect_defense_up.c | 2 +- test/move_effect_defog.c | 4 ++-- test/move_effect_special_attack_down.c | 2 +- test/move_effect_special_attack_up_3.c | 2 +- test/move_effect_stockpile.c | 20 ++++++++++---------- test/status1.c | 4 ++-- test/terrain_electric.c | 2 +- test/terrain_grassy.c | 2 +- test/terrain_misty.c | 2 +- test/terrain_psychic.c | 2 +- 26 files changed, 62 insertions(+), 62 deletions(-) diff --git a/include/config/battle.h b/include/config/battle.h index 24f4ad4f15..ad31621623 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -98,7 +98,7 @@ #define B_HEALING_WISH_SWITCH GEN_LATEST // In Gen5+, the mon receiving Healing Wish is sent out at the end of the turn. // Additionally, in gen8+ the Healing Wish's effect will be stored until the user switches into a statused or hurt mon. #define B_DEFOG_CLEARS_TERRAIN GEN_LATEST // In Gen8+, Defog also clears active Terrain. -#define B_STOCKPILE_RAISES_DEFS GEN_LATEST // In Gen4+, Stockpile also raises Defense and Sp.Defense stats. Once Spit Up / Swallow is used, these stat changes are lost. +#define B_STOCKPILE_RAISES_DEFS GEN_LATEST // In Gen4+, Stockpile also raises Defense and Sp. Defense stats. Once Spit Up / Swallow is used, these stat changes are lost. // Ability settings #define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters. @@ -183,7 +183,7 @@ // Other settings #define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. -#define B_DOUBLE_WILD_REQUIRE_2_MONS FALSE // If set to TRUE, Wild Double Battles will default to Single Battles when the player only has 1 usuable Pokémon, ignoring B_DOUBLE_WILD_CHANCE and B_FLAG_FORCE_DOUBLE_WILD. +#define B_DOUBLE_WILD_REQUIRE_2_MONS FALSE // If set to TRUE, Wild Double Battles will default to Single Battles when the player only has 1 usuable Pokémon, ignoring B_DOUBLE_WILD_CHANCE and B_FLAG_FORCE_DOUBLE_WILD. #define B_MULTI_BATTLE_WHITEOUT GEN_LATEST // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight. #define B_EVOLUTION_AFTER_WHITEOUT GEN_LATEST // In Gen6+, Pokemon that qualify for evolution after battle will evolve even if the player loses. #define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper) diff --git a/src/battle_message.c b/src/battle_message.c index 7d10b19f11..7df30cb296 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -435,11 +435,11 @@ static const u8 sText_ExclamationMark3[] = _("!"); static const u8 sText_ExclamationMark4[] = _("!"); static const u8 sText_ExclamationMark5[] = _("!"); static const u8 sText_HP[] = _("HP"); -static const u8 sText_Attack[] = _("attack"); -static const u8 sText_Defense[] = _("defense"); -static const u8 sText_Speed[] = _("speed"); -static const u8 sText_SpAttack[] = _("sp. attack"); -static const u8 sText_SpDefense[] = _("sp. defense"); +static const u8 sText_Attack[] = _("Attack"); +static const u8 sText_Defense[] = _("Defense"); +static const u8 sText_Speed[] = _("Speed"); +static const u8 sText_SpAttack[] = _("Sp. Atk"); +static const u8 sText_SpDefense[] = _("Sp. Def"); static const u8 sText_Accuracy[] = _("accuracy"); static const u8 sText_Evasiveness[] = _("evasiveness"); @@ -555,7 +555,7 @@ static const u8 sText_VanishedInstantly[] =_("{B_ATK_NAME_WITH_PREFIX} vanished\ static const u8 sText_ProtectedTeam[] =_("{B_CURRENT_MOVE} protected\n{B_ATK_TEAM2} team!"); static const u8 sText_SharedItsGuard[] =_("{B_ATK_NAME_WITH_PREFIX} shared its\nguard with the target!"); static const u8 sText_SharedItsPower[] =_("{B_ATK_NAME_WITH_PREFIX} shared its\npower with the target!"); -static const u8 sText_SwapsDefAndSpDefOfAllPkmn[] =_("It created a bizarre area in which the\nDefense and Sp.Def stats are swapped!"); +static const u8 sText_SwapsDefAndSpDefOfAllPkmn[] =_("It created a bizarre area in which the\nDefense and Sp. Def stats are swapped!"); static const u8 sText_BecameNimble[] =_("{B_ATK_NAME_WITH_PREFIX} became nimble!"); static const u8 sText_HurledIntoTheAir[] =_("{B_DEF_NAME_WITH_PREFIX} was hurled\ninto the air!"); static const u8 sText_HeldItemsLoseEffects[] =_("It created a bizarre area in which\nPokémon's held items lose their effects!"); diff --git a/src/pokemon.c b/src/pokemon.c index d985ef95d3..46eca90b29 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -1919,7 +1919,7 @@ const struct SpindaSpot gSpindaSpotGraphics[] = #include "data/pokemon/item_effects.h" const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] = -{ // Attack Defense Speed Sp.Atk Sp.Def +{ // Attack Defense Speed Sp.Atk Sp. Def [NATURE_HARDY] = { 0, 0, 0, 0, 0 }, [NATURE_LONELY] = { +1, -1, 0, 0, 0 }, [NATURE_BRAVE] = { +1, 0, -1, 0, 0 }, @@ -6626,7 +6626,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s RtcCalcLocalTime(); if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && gEvolutionTable[species][i].param == evolutionItem) targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; + break; } } break; diff --git a/test/ability_contrary.c b/test/ability_contrary.c index 7fd902280b..33cfa7ce87 100644 --- a/test/ability_contrary.c +++ b/test/ability_contrary.c @@ -21,7 +21,7 @@ SINGLE_BATTLE_TEST("Contrary raises Attack when Intimidated", s16 damage) if (ability == ABILITY_CONTRARY) { ABILITY_POPUP(opponent, ABILITY_CONTRARY); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's attack rose!"); + MESSAGE("Foe Spinda's Attack rose!"); } HP_BAR(player, captureDamage: &results[i].damage); } @@ -49,11 +49,11 @@ SINGLE_BATTLE_TEST("Contrary raises stats after using a move which would normall if (ability == ABILITY_CONTRARY) { // ABILITY_POPUP(opponent, ABILITY_CONTRARY); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's sp. attack sharply rose!"); + MESSAGE("Foe Spinda's Sp. Atk sharply rose!"); } else { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's sp. attack harshly fell!"); + MESSAGE("Foe Spinda's Sp. Atk harshly fell!"); } // MESSAGE("Foe Spinda used Overheat!"); @@ -61,11 +61,11 @@ SINGLE_BATTLE_TEST("Contrary raises stats after using a move which would normall if (ability == ABILITY_CONTRARY) { // ABILITY_POPUP(opponent, ABILITY_CONTRARY); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's sp. attack sharply rose!"); + MESSAGE("Foe Spinda's Sp. Atk sharply rose!"); } else { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's sp. attack harshly fell!"); + MESSAGE("Foe Spinda's Sp. Atk harshly fell!"); } } FINALLY { @@ -95,11 +95,11 @@ SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normal if (ability == ABILITY_CONTRARY) { // ABILITY_POPUP(opponent, ABILITY_CONTRARY); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's attack harshly fell!"); + MESSAGE("Foe Spinda's Attack harshly fell!"); } else { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's attack sharply rose!"); + MESSAGE("Foe Spinda's Attack sharply rose!"); } // MESSAGE("Foe Spinda used Tackle!"); @@ -127,11 +127,11 @@ SINGLE_BATTLE_TEST("Contrary raises a stat after using a move which would normal if (ability == ABILITY_CONTRARY) { // ABILITY_POPUP(opponent, ABILITY_CONTRARY); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's attack rose!"); + MESSAGE("Foe Spinda's Attack rose!"); } else { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Spinda's attack fell!"); + MESSAGE("Foe Spinda's Attack fell!"); } MESSAGE("Foe Spinda used Tackle!"); diff --git a/test/ability_download.c b/test/ability_download.c index 132c0eb5ba..d83d90196e 100644 --- a/test/ability_download.c +++ b/test/ability_download.c @@ -7,7 +7,7 @@ ASSUMPTIONS ASSUME(gBattleMoves[MOVE_TRI_ATTACK].split == SPLIT_SPECIAL); } -SINGLE_BATTLE_TEST("Download raises Attack if player has lower Def than Sp.Def", s16 damage) +SINGLE_BATTLE_TEST("Download raises Attack if player has lower Def than Sp. Def", s16 damage) { u32 ability; PARAMETRIZE { ability = ABILITY_TRACE; } @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Download raises Attack if player has lower Def than Sp.Def", { ABILITY_POPUP(opponent, ABILITY_DOWNLOAD); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Porygon's Download raised its attack!"); + MESSAGE("Foe Porygon's Download raised its Attack!"); } HP_BAR(player, captureDamage: &results[i].damage); } FINALLY { @@ -30,7 +30,7 @@ SINGLE_BATTLE_TEST("Download raises Attack if player has lower Def than Sp.Def", } } -SINGLE_BATTLE_TEST("Download raises Sp.Attack if enemy has lower Sp.Def than Def", s16 damage) +SINGLE_BATTLE_TEST("Download raises Sp.Attack if enemy has lower Sp. Def than Def", s16 damage) { u32 ability; PARAMETRIZE { ability = ABILITY_TRACE; } @@ -45,7 +45,7 @@ SINGLE_BATTLE_TEST("Download raises Sp.Attack if enemy has lower Sp.Def than Def { ABILITY_POPUP(player, ABILITY_DOWNLOAD); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Porygon's Download raised its sp. attack!"); + MESSAGE("Porygon's Download raised its Sp. Atk!"); } HP_BAR(opponent, captureDamage: &results[i].damage); } FINALLY { @@ -79,10 +79,10 @@ SINGLE_BATTLE_TEST("Download doesn't activate if target hasn't been sent out yet { ABILITY_POPUP(player, ABILITY_DOWNLOAD); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Porygon's Download raised its attack!"); + MESSAGE("Porygon's Download raised its Attack!"); ABILITY_POPUP(opponent, ABILITY_DOWNLOAD); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Porygon2's Download raised its sp. attack!"); + MESSAGE("Foe Porygon2's Download raised its Sp. Atk!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); HP_BAR(opponent, captureDamage: &results[i].damagePhysical); diff --git a/test/ability_intimidate.c b/test/ability_intimidate.c index a891f9af87..40804cbb19 100644 --- a/test/ability_intimidate.c +++ b/test/ability_intimidate.c @@ -104,7 +104,7 @@ SINGLE_BATTLE_TEST("Intimidate and Eject Button force the opponent to Attack") OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_BUTTON); }; OPPONENT(SPECIES_HITMONTOP) { Moves(MOVE_TACKLE); }; } WHEN { - TURN { + TURN { MOVE(player, MOVE_QUICK_ATTACK); MOVE(opponent, MOVE_TACKLE); SEND_OUT(opponent, 1); diff --git a/test/ability_magic_bounce.c b/test/ability_magic_bounce.c index d52b93c4a5..848f632ab5 100644 --- a/test/ability_magic_bounce.c +++ b/test/ability_magic_bounce.c @@ -74,11 +74,11 @@ DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting both foes at two foe MESSAGE("Abra's Leer was bounced back by Foe Espeon's Magic Bounce!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_LEER, opponentLeft); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); - MESSAGE("Abra's defense fell!"); + MESSAGE("Abra's Defense fell!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); - MESSAGE("Kadabra's defense fell!"); + MESSAGE("Kadabra's Defense fell!"); // Also check if second original target gets hit by Leer as this was once bugged ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); - MESSAGE("Foe Wynaut's defense fell!"); + MESSAGE("Foe Wynaut's Defense fell!"); } } diff --git a/test/ability_oblivious.c b/test/ability_oblivious.c index 0708845ed1..efe2901eca 100644 --- a/test/ability_oblivious.c +++ b/test/ability_oblivious.c @@ -63,6 +63,6 @@ SINGLE_BATTLE_TEST("Oblivious prevents Intimidate") ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); ABILITY_POPUP(player, ABILITY_OBLIVIOUS); NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } - MESSAGE("Slowpoke's attack was not lowered!"); + MESSAGE("Slowpoke's Attack was not lowered!"); } } diff --git a/test/ability_speed_boost.c b/test/ability_speed_boost.c index b3e128931a..39219a5cc7 100644 --- a/test/ability_speed_boost.c +++ b/test/ability_speed_boost.c @@ -1,7 +1,7 @@ #include "global.h" #include "test_battle.h" -SINGLE_BATTLE_TEST("Speed Boost gradually boosts speed") +SINGLE_BATTLE_TEST("Speed Boost gradually boosts Speed") { GIVEN { PLAYER(SPECIES_TORCHIC) { Ability(ABILITY_SPEED_BOOST); Speed(99); }; diff --git a/test/ability_volt_absorb.c b/test/ability_volt_absorb.c index bef35e2b4b..18902eaa20 100644 --- a/test/ability_volt_absorb.c +++ b/test/ability_volt_absorb.c @@ -102,7 +102,7 @@ SINGLE_BATTLE_TEST("Volt Absorb prevents Cell Battery from activating") NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Cell Battery, the attack of Jolteon rose!"); + MESSAGE("Using Cell Battery, the Attack of Jolteon rose!"); } } diff --git a/test/item_effect_increase_stat.c b/test/item_effect_increase_stat.c index 70c89bdd4e..b459e3ac88 100644 --- a/test/item_effect_increase_stat.c +++ b/test/item_effect_increase_stat.c @@ -1,7 +1,7 @@ #include "global.h" #include "test_battle.h" -SINGLE_BATTLE_TEST("X-Attack sharply raises battler's attack stat", s16 damage) +SINGLE_BATTLE_TEST("X-Attack sharply raises battler's Attack stat", s16 damage) { u16 useItem; PARAMETRIZE { useItem = FALSE; } diff --git a/test/move.c b/test/move.c index 9ad336330f..9e23c2bd00 100644 --- a/test/move.c +++ b/test/move.c @@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Turn order is determined by priority") } } -SINGLE_BATTLE_TEST("Turn order is determined by speed if priority ties") +SINGLE_BATTLE_TEST("Turn order is determined by Speed if priority ties") { GIVEN { PLAYER(SPECIES_WOBBUFFET) { Speed(2); } @@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Turn order is determined by speed if priority ties") } } -SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and speed tie") +SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie") { KNOWN_FAILING; // The algorithm is significantly biased. PASSES_RANDOMLY(1, 2); diff --git a/test/move_effect_attack_down.c b/test/move_effect_attack_down.c index 6333bbea1f..0df14f701a 100644 --- a/test/move_effect_attack_down.c +++ b/test/move_effect_attack_down.c @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Growl lowers Attack", s16 damage) if (lowerAttack) { ANIMATION(ANIM_TYPE_MOVE, MOVE_GROWL, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Wobbuffet's attack fell!"); + MESSAGE("Foe Wobbuffet's Attack fell!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); HP_BAR(player, captureDamage: &results[i].damage); diff --git a/test/move_effect_attack_up.c b/test/move_effect_attack_up.c index 7b57fa0d26..4978d03f96 100644 --- a/test/move_effect_attack_up.c +++ b/test/move_effect_attack_up.c @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Meditate raises Attack", s16 damage) if (raiseAttack) { ANIMATION(ANIM_TYPE_MOVE, MOVE_MEDITATE, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's attack rose!"); + MESSAGE("Wobbuffet's Attack rose!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); HP_BAR(opponent, captureDamage: &results[i].damage); diff --git a/test/move_effect_attack_up_user_ally.c b/test/move_effect_attack_up_user_ally.c index e98df30d8e..e920752dec 100644 --- a/test/move_effect_attack_up_user_ally.c +++ b/test/move_effect_attack_up_user_ally.c @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Howl raises user's Attack", s16 damage) if (raiseAttack) { ANIMATION(ANIM_TYPE_MOVE, MOVE_HOWL, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's attack rose!"); + MESSAGE("Wobbuffet's Attack rose!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); HP_BAR(opponent, captureDamage: &results[i].damage); @@ -50,9 +50,9 @@ DOUBLE_BATTLE_TEST("Howl raises user's and partner's Attack", s16 damageLeft, s1 if (raiseAttack) { ANIMATION(ANIM_TYPE_MOVE, MOVE_HOWL, playerLeft); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); - MESSAGE("Wobbuffet's attack rose!"); + MESSAGE("Wobbuffet's Attack rose!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); - MESSAGE("Wynaut's attack rose!"); + MESSAGE("Wynaut's Attack rose!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft); HP_BAR(opponentLeft, captureDamage: &results[i].damageLeft); diff --git a/test/move_effect_defense_down.c b/test/move_effect_defense_down.c index 6e5a45e848..9ecd1c25f2 100644 --- a/test/move_effect_defense_down.c +++ b/test/move_effect_defense_down.c @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Tail Whip lowers Defense", s16 damage) if (lowerDefense) { ANIMATION(ANIM_TYPE_MOVE, MOVE_TAIL_WHIP, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Wobbuffet's defense fell!"); + MESSAGE("Foe Wobbuffet's Defense fell!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); HP_BAR(opponent, captureDamage: &results[i].damage); diff --git a/test/move_effect_defense_up.c b/test/move_effect_defense_up.c index 8db9a7f7e4..492ce7bc93 100644 --- a/test/move_effect_defense_up.c +++ b/test/move_effect_defense_up.c @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Harden raises Defense", s16 damage) if (raiseDefense) { ANIMATION(ANIM_TYPE_MOVE, MOVE_HARDEN, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's defense rose!"); + MESSAGE("Wobbuffet's Defense rose!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); HP_BAR(player, captureDamage: &results[i].damage); diff --git a/test/move_effect_defog.c b/test/move_effect_defog.c index e9e55d57fe..751ddf60f6 100644 --- a/test/move_effect_defog.c +++ b/test/move_effect_defog.c @@ -165,7 +165,7 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S MESSAGE("Pointed stones dug into Wobbuffet!"); MESSAGE("Wobbuffet was caught in a Sticky Web!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); - MESSAGE("Wobbuffet's speed fell!"); + MESSAGE("Wobbuffet's Speed fell!"); } else { NONE_OF { @@ -173,7 +173,7 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S MESSAGE("Pointed stones dug into Wobbuffet!"); MESSAGE("Wobbuffet was caught in a Sticky Web!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); - MESSAGE("Wobbuffet's speed fell!"); + MESSAGE("Wobbuffet's Speed fell!"); } } } diff --git a/test/move_effect_special_attack_down.c b/test/move_effect_special_attack_down.c index a20b8558e7..0511692d46 100644 --- a/test/move_effect_special_attack_down.c +++ b/test/move_effect_special_attack_down.c @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Confide lowers Special Attack", s16 damage) if (lowerSpecialAttack) { ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFIDE, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("Foe Wobbuffet's sp. attack fell!"); + MESSAGE("Foe Wobbuffet's Sp. Atk fell!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_GUST, opponent); HP_BAR(player, captureDamage: &results[i].damage); diff --git a/test/move_effect_special_attack_up_3.c b/test/move_effect_special_attack_up_3.c index f7e7e11d14..ad53bedb9e 100644 --- a/test/move_effect_special_attack_up_3.c +++ b/test/move_effect_special_attack_up_3.c @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Tail Glow drastically raises Special Attack", s16 damage) if (raiseSpecialAttack) { ANIMATION(ANIM_TYPE_MOVE, MOVE_TAIL_GLOW, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's sp. attack drastically rose!"); + MESSAGE("Wobbuffet's Sp. Atk drastically rose!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_GUST, player); HP_BAR(opponent, captureDamage: &results[i].damage); diff --git a/test/move_effect_stockpile.c b/test/move_effect_stockpile.c index 0530355efb..bd0d3a113d 100644 --- a/test/move_effect_stockpile.c +++ b/test/move_effect_stockpile.c @@ -142,7 +142,7 @@ SINGLE_BATTLE_TEST("Swallow heals HP depending on Stockpile's count", s16 hpHeal } } -SINGLE_BATTLE_TEST("Stockpile temporarily raises Def and Sp.Def", s16 dmgPyhsical, s16 dmgSpecial) +SINGLE_BATTLE_TEST("Stockpile temporarily raises Def and Sp. Def", s16 dmgPyhsical, s16 dmgSpecial) { u16 move; PARAMETRIZE {move = MOVE_STOCKPILE;} @@ -161,8 +161,8 @@ SINGLE_BATTLE_TEST("Stockpile temporarily raises Def and Sp.Def", s16 dmgPyhsica if (move == MOVE_STOCKPILE) { MESSAGE("Wobbuffet stockpiled 1!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's defense rose!"); - MESSAGE("Wobbuffet's sp. defense rose!"); + MESSAGE("Wobbuffet's Defense rose!"); + MESSAGE("Wobbuffet's Sp. Def rose!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); @@ -176,7 +176,7 @@ SINGLE_BATTLE_TEST("Stockpile temporarily raises Def and Sp.Def", s16 dmgPyhsica } } -DOUBLE_BATTLE_TEST("Stockpile's Def and Sp.Def boost is lost after using Spit Up or Swallow", s16 dmgPyhsicalBefore, s16 dmgPhysicalAfter, s16 dmgSpecialBefore, s16 dmgSpecialAfter) +DOUBLE_BATTLE_TEST("Stockpile's Def and Sp. Def boost is lost after using Spit Up or Swallow", s16 dmgPyhsicalBefore, s16 dmgPhysicalAfter, s16 dmgSpecialBefore, s16 dmgSpecialAfter) { u8 count; u16 move; @@ -217,24 +217,24 @@ DOUBLE_BATTLE_TEST("Stockpile's Def and Sp.Def boost is lost after using Spit Up ANIMATION(ANIM_TYPE_MOVE, move, playerLeft); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); if (count == 1) { - MESSAGE("Wobbuffet's defense fell!"); + MESSAGE("Wobbuffet's Defense fell!"); } else if (count == 2) { - MESSAGE("Wobbuffet's defense harshly fell!"); + MESSAGE("Wobbuffet's Defense harshly fell!"); } else { - MESSAGE("Wobbuffet's defense severely fell!"); + MESSAGE("Wobbuffet's Defense severely fell!"); } ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); if (count == 1) { - MESSAGE("Wobbuffet's sp. defense fell!"); + MESSAGE("Wobbuffet's Sp. Def fell!"); } else if (count == 2) { - MESSAGE("Wobbuffet's sp. defense harshly fell!"); + MESSAGE("Wobbuffet's Sp. Def harshly fell!"); } else { - MESSAGE("Wobbuffet's sp. defense severely fell!"); + MESSAGE("Wobbuffet's Sp. Def severely fell!"); } MESSAGE("Wobbuffet's stockpiled effect wore off!"); diff --git a/test/status1.c b/test/status1.c index f4d3c7d944..c244b9a604 100644 --- a/test/status1.c +++ b/test/status1.c @@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Burn deals 1/16th damage per turn") } } -SINGLE_BATTLE_TEST("Burn reduces attack by 50%", s16 damage) +SINGLE_BATTLE_TEST("Burn reduces Attack by 50%", s16 damage) { bool32 burned; PARAMETRIZE { burned = FALSE; } @@ -113,7 +113,7 @@ SINGLE_BATTLE_TEST("Freeze is thawed by user's Flame Wheel") } } -SINGLE_BATTLE_TEST("Paralysis reduces speed by 50%") +SINGLE_BATTLE_TEST("Paralysis reduces Speed by 50%") { u16 playerSpeed; bool32 playerFirst; diff --git a/test/terrain_electric.c b/test/terrain_electric.c index b5608e661b..bb397fdf9b 100644 --- a/test/terrain_electric.c +++ b/test/terrain_electric.c @@ -31,7 +31,7 @@ SINGLE_BATTLE_TEST("Electric Terrain activates Electric Seed and Mimicry") TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); } } SCENE { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Electric Seed, the defense of Wobbuffet rose!"); + MESSAGE("Using Electric Seed, the Defense of Wobbuffet rose!"); ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Electr!"); } FINALLY { diff --git a/test/terrain_grassy.c b/test/terrain_grassy.c index cf83048750..ae6e6d9e92 100644 --- a/test/terrain_grassy.c +++ b/test/terrain_grassy.c @@ -27,7 +27,7 @@ SINGLE_BATTLE_TEST("Grassy Terrain activates Grassy Seed and Mimicry") TURN { MOVE(player, MOVE_GRASSY_TERRAIN); } } SCENE { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Grassy Seed, the defense of Wobbuffet rose!"); + MESSAGE("Using Grassy Seed, the Defense of Wobbuffet rose!"); ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Grass!"); } FINALLY { diff --git a/test/terrain_misty.c b/test/terrain_misty.c index dda5253f23..668b036992 100644 --- a/test/terrain_misty.c +++ b/test/terrain_misty.c @@ -31,7 +31,7 @@ SINGLE_BATTLE_TEST("Misty Terrain activates Misty Seed and Mimicry") TURN { MOVE(player, MOVE_MISTY_TERRAIN); } } SCENE { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Misty Seed, the sp. defense of Wobbuffet rose!"); + MESSAGE("Using Misty Seed, the Sp. Def of Wobbuffet rose!"); ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Fairy!"); } FINALLY { diff --git a/test/terrain_psychic.c b/test/terrain_psychic.c index eb5103f314..2cddef070f 100644 --- a/test/terrain_psychic.c +++ b/test/terrain_psychic.c @@ -30,7 +30,7 @@ SINGLE_BATTLE_TEST("Psychic Terrain activates Psychic Seed and Mimicry") TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); } } SCENE { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Psychic Seed, the sp. defense of Wobbuffet rose!"); + MESSAGE("Using Psychic Seed, the Sp. Def of Wobbuffet rose!"); ABILITY_POPUP(opponent); MESSAGE("Foe Stunfisk's type changed to Psychc!"); } FINALLY { From e6505bda4bc9ebb23573ac9703ab09261742c110 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Wed, 19 Apr 2023 01:49:42 +0200 Subject: [PATCH 17/30] Fix some sprites (#2926) * Fix hisuian typlosion * Fix mega metagross backsprite * Fix shiny Reuniclus * Fix Duosion mouth * Fix front mega metagross * Fix front Yanmega * Fix Electivire front sprite * Fix shiny duskull * Fix Hariyama sprite * Fix Shiny masquerain --- graphics/pokemon/duosion/anim_front.png | Bin 802 -> 738 bytes graphics/pokemon/duosion/normal.pal | 2 +- graphics/pokemon/duskull/anim_front.png | Bin 725 -> 737 bytes graphics/pokemon/duskull/back.png | Bin 562 -> 524 bytes graphics/pokemon/duskull/shiny.pal | 2 +- graphics/pokemon/electivire/anim_front.png | Bin 1898 -> 1908 bytes graphics/pokemon/electivire/normal.pal | 2 +- graphics/pokemon/hariyama/anim_front.png | Bin 1405 -> 1405 bytes graphics/pokemon/hariyama/normal.pal | 2 +- graphics/pokemon/masquerain/anim_front.png | Bin 1282 -> 1284 bytes graphics/pokemon/masquerain/normal.pal | 2 +- graphics/pokemon/metagross/mega/back.png | Bin 966 -> 897 bytes graphics/pokemon/metagross/mega/front.png | Bin 1366 -> 1311 bytes graphics/pokemon/reuniclus/anim_front.png | Bin 1176 -> 1210 bytes .../pokemon/typhlosion/hisuian/normal.pal | 2 +- graphics/pokemon/typhlosion/hisuian/pal.pal | 19 ------------------ graphics/pokemon/yanmega/anim_front.png | Bin 1210 -> 1103 bytes 17 files changed, 6 insertions(+), 25 deletions(-) delete mode 100755 graphics/pokemon/typhlosion/hisuian/pal.pal diff --git a/graphics/pokemon/duosion/anim_front.png b/graphics/pokemon/duosion/anim_front.png index e8c48d6c05fa3b8fd5dfcce88789aae67968b2a4..c265b42524e803d4fe8096c459643f42f4aa2114 100644 GIT binary patch delta 692 zcmV;l0!#g(2I2*f7#0Wv0001tU!Pb20004VQb$4nuFf3kks&63us}d?I5>dVpa1{> z00000005ZOL^l8c0$@o*K~!jg?U>n;gCGz^MUc)U|Np;3vtvMSH6>(N}lIW#2*oX0XzYYALMtTLfjM5 z^7##ndHxF~L_mlZz@b6HC|?L5z>;;D9^i&x;sA*BVc#F|5b_Mjjo|ZsyJ7gT)a!@> zIL|{Mq84yT$N=l+&jgzRRssmS5Y`|9tPG(2yg%W}HlGN8IKUBXT74S|ydes~?L%GY zJ(&SyHStjt<5m9Vo0J|VoVNbQDSrP=ECfsXGdYyZaq&Fe|=e;6>*e}VreeQ)g__kW-7*uO;o z`}U9P|H%GP{U6&uX73mF4+1XiA2E(g`$x3#(*99@z}Wr)cfPiNtbcG}{|MmH{=xpi z*#5!(!AbvNd++PN;GQ-e{U?dO1Nsk6;jI54V5tB20Q&l0^&g-abo3v!*Q(Rd>i>>) zFoyb{+6Qn;G_GTAAE5n*t*if%{zE{V)Lqnn_?`#60pIg@05~IN`VR#$-GA6t|6$dC as$Vt}u^^N#nQ>$Q0000I!7zqRe0000=*q&4Ew`VenmEfg*hAf@C4+b2!Zrt=G2Vb^Z_ zbeY+On1dO*=%mO~SeEDW%$@I|zRz zzy(N@DrF#rK&iami9H6Om4FOa5UW~CQ&Jv4W1a_|;MaE;V$0+=@a6Oy;#eDkDdEHE zgcE3G2xg%^c8FD>lqD7=aF1w>9RjN5N)XTuz=11~0z}Gmz}N{uQyuQWyaxiEPQG2$ z*kcBm5p;EXQ%!}PB;a_yDBW3LHiUlxN_9I|1T;K=tH2o$$ORy%)Diz((ScwAc*gng zywn^(%Y;DJCK~R65)hSr(__Bn0D5Jjy6>AYzu3tw{@B;A!vO47`O90b8y?6%%5cU@*3TN=>OyP4%C16XBqoon>`+k28xOQ>c zw&IR`W;0+a%}2CEmaYTXW*{>01~EjKIT>Goh%A$nk9fp?8ynC2w3heq1>LR?o~VjL zebQd>-F3_@5v!QJ9&A{3Uoj9V`G>j`dt}C7&{fF;B>zE@(`C&9)*eK<6_(*n>;Z6F z<)b|a;;+0IIJ8HnQ;-y0(aL}J;73B@UT}(KZ`#C)d%>1)C+fcw?7?UsME}tDD!Bto z&5DZG{37}X8lmWq=PK`c6JvnxcD@#R0A@oFkSE9U8v(f>?&u3HiU3LdpOv~QoPia0 z*QzFlp#DbF;=vxU>OZju)(_5sm%sL4$S*3)?E%+fvm9?za9)v)^yuidBg!J*W$df&|y91_xGwhXJ4S#`*_CW+jB24)X mBa!XhOvqbpsd7#0Wv0001tU!Pb20004VQb$4nuFf3kks&{SUr9tkRA_Ds;JOjc^&*QW(J8^^0`mcY?J#&{SrAxD{bs=h3#MB^h;q;D z%YBR%EGFQSUe40Nf(tC>3W0!CWb8!`Uyd^V;0l4_x}N>lH^NV_Y#~!JqIdl6Xj3xI z{^#clsRt#vU0(qZytDuTBnQ$%CItEI-68_b0r0K*2;fM6;Og>PSXP~)E|fOWgNv$O zZ5iS$7JSer15JQ%lvf=?Tt68=#N79v^~FKn8wif7a?!7TDF8r|eZ5N3y#RbXPHp=a z2~Zchb2x1v^azv9MOgX-(4Ry$8$jCm;{+S}P)4CayMDJ($jLOv6QgtWg0XjD8o(O@ zf}1XV?4whEI%?FYQKSC78u`J<58CpB!?UtIKhP%;XGC*;kX}^Vd#p7-*dAp0MR&>% zYF|lEWqy%K8>jpL)%PlN*!%Y+9rJ_D$1S0dE1=8|_MNyPNRP5?23+%px(BU9DDwlj zd=?GU*Z^gIfUtk&ai)*@GCzpl>x~x9`GNgTQTnuaKjjAvw=#_4k{<*M@d01Il|+>7@w^#@&k%`TMO^<1EYbzKR>WB zZt??TCV7(|SfAi;^8@>T$&nuvgpnVN8fB|ru;LwU7|-Y200000NkvXXu0mjflw~=5 delta 653 zcmV;80&@M~1=R(R7zqRe0000c#H5ELlz0jGlyxHHMv zJ-KG#*3bh&UDkp=KmjUc5C^vYf?=qMTMPL^+PorpO!n?f%i`@(O@I{PwmY1ey(76Z znT++1N?Z>2r*~%vZq5NdFV09ri@P(3uVOaXj}tL8#}slQ#Ft`8?7~+Wb$dpaKyC( zkcPb22_F%^8U?L)W)R}>RHFM@x3IS+#6A%-53%0pCqQe0dw4QF(wHg$i0iF>B7#;ysXPZ%_wJ;v0!exOc)PcNM)3lZ z_&e4u8Ua(@2vitv8(6(rRF@IMad_?kB@`L+ZX@|e=!$#!WB0fUxgZ3-^$ULteLaW+ z&pQ%oBV2_66LLBU3OFA_-Lb~{KWoen1Nk9xTQZm*qC^@*Fh4}(%dEIielUFj#e063 z_kU8A%*~EVyZlh~mu|ci_UD|s{4ghyp3Tbry;GMTtc_C&T&4!#@`LUBr=8L7+2)5v z=7O8V09<~kM9Pjz8^Gm<29c0004VQb$4nuFf3kkv=bf_;^?V000000H#zU zHUIztib+I4R9J=Wmd&<aiz#R_^$u9N)MelJ7@K%4k)!zV5S=d{LW+gW=S+C<} zCKJMyg2ma$OHByzns)qzxH(CEE6r`r@qv+4SFtyI-h@vOJoPgY@ z27oyL_$1Qwv4;r(<4hTVnFTZra1Rp#ng-?;=rBfq#tKP6pE|&40Qlv2mI^+>x*iNd zt1tD~0yppuz`tL;2U#C`&^81cfNE?Q<;j8y=p*nN(63>C?m?RaY&+=Rd|ObXWM;4s ztPNEI2KyP$X;uh`p`>`6zA)-w_xA>82U~{oJD^Ky^*l^Rfa+h~@z(fRX|`Tm4NXjW!R+VL2s$ zamJ5nkOmtv03k^$7Q{G;7PPBc(90WICTROfCJax<1^DW#;|HNU7!Dx>jer0E002ov JPDHLkV1hoL$4CGG delta 505 zcmV7$yV*00013M{Ml?0004VQb$4nuFf3k00004XF*Lt006O%3;baP zkuEQPXjo7H000000H#D0gFjQK~zY`<&;5c z!!Qs(GeYB9KL{Ta9c*GqEl2Tdj=e@&D+Lq~fow zRrQ{&?{~V{X6mYjgI;Hd4uFVx0MR2_+l&c+l12tlWMXVy05IdQBoF{-ss#(J=i^jJ zLFi1Jo*+Q4ZN|gb;V=`Yg3!c#T45LcDksX-KGi4UT2-0}n9J=IXm!a1jQbw>ACLjf z2w2s?8~{#Vx7QsS30%eiufyA`hXNG9sLR$IoxA#qI}gBB3UtQNx_fNchPz3JlZ$JA z=u!f$SpYgi{tv33<2Lv}Ro#ZaAJ4k)QUEc=Md0YtG0=5t<(GM4>+YHH|9N_Jaia zV?(zOcNp*P{fP6M780_6Zm#UPJvx?w3v37{28#t_p`Y%v1F={IQ>Pi4^r v3%i^2uv7D968z0nOd@`o+@t&NR#E%{b%xFx8N_#800000NkvXXu0mjfv=ZOe diff --git a/graphics/pokemon/duskull/shiny.pal b/graphics/pokemon/duskull/shiny.pal index 2c59d3ae14..16dc97f5a8 100644 --- a/graphics/pokemon/duskull/shiny.pal +++ b/graphics/pokemon/duskull/shiny.pal @@ -14,6 +14,6 @@ JASC-PAL 248 232 176 248 120 88 152 40 72 -104 88 80 +248 120 88 0 0 0 0 0 0 diff --git a/graphics/pokemon/electivire/anim_front.png b/graphics/pokemon/electivire/anim_front.png index a5f05a7e8b9552604a2c1903e92628e449dac87e..9aae7e5b5c7ef8497b1c49c6a0b2321a0309b3ed 100644 GIT binary patch delta 1865 zcmV-P2e$a?4)hL?7#0Wv0001tU!Pb20004VQb$4nuFf3kks&O9SV%xyfXKkib1MiZ0Vb9a92S?A72r==_qiPS91 z-y5&jzcQ!S`}1Rj$y&s(&-i9iRBLWX_7sxoqtf9GhJ^F@yUOX8fwJaBM`CFRk6 zpm6X&5nvf)P9>4SV>uvP10*#Qd-o#daNLymhK+KtX0GPa2^Is6&Z^bwu>_KED(D@LAdiaQakYCJyD}Ua`gAV{y*B8d%;0Voc zB@ohk3LxeNz_K<7RDdwpw;1XwvP`pwnUYrei7Nmy&Y~_Uob!m1u{mAT6_2?Tm{Z1H zrW|b7zuShN5WXEqPzYVrXk$$-hz7|w@{A*=s1V<6{jU16b-9p|ZiQP{fTHFCU^6ud zlR5x51S5BU>q{t@S*G(Kupah^Z>HO7A;LoG63E;((F-- z6d;+;bvpH~_GlrJexlR&;tEG`AP}&3**v*VjxWuC2J&7ksdfjeDE!KX(3LpG5lUVxdw?N|Rs{ExI@C!0=_pJ9YSraz z$MW>5X#haj0jfFY2EdAO0l-K-F-toDVt``M-ej1SuI=^EB_LRJ(*XM}@AEF~msW~^ zP&2gU>GR+gW3f-^7xv9a1J?swaqdR4Q&?Sp;IXtmQ%H7rYfV2PYnq(TrOgrdlP2`VeuhkTP+QCG=Kv6eDLm6wq9Dvabm3Gk$y%%_Ya2o@A zSk&~T4375w&0_`-{DxKd{ozqJkY|G3-Lhu(-V!SNwciNu*~)(R(W}!5KwBBJdpmnL zBS*(C9k`;f7S{PK#`a&MApT446#TvNM*)gnnyqKNc+D3WY0~xE{~-uC_E1}5??)%g z7qzt?~PGetBAi8qHX;-&PBs@7(a+?sp~} z;675U;ncX|-dE~vSJyA&$@0$5C3-$To zEid|&mXA_t5Gax#>|_B*%SQs8D#tC2LM2{fLl7@;7{Ol#w?LA)gL}F@aRI^scpp|p zytfZsTS3*Xmh~nd9Q6x-ol;`sc2Q=jRn>gZFN`X|0ceOvg#Fc70n&b~^`nYB2!LWt z+p`^^mk-RGT_rMmg#M}n(>SSokPV>IAGD&8Z9}=ZwX)U~MSu^x{vZI757<$Lk_%Vn z=H9=W4_)g`dhQ6VneM5OnDnT(`T=EAaLH@?3E)XTfb*WS7K+(_e{0<72flr|k)YH1 zGyTBDSTx2|?65Zy2Y}uCW!DdanwWy1|0Q7RF}^+6pXGzaMMov#3POFnoZ1h*ln<7l zDG2?EnF5%Ca1C&+9vFOIwyxH&uuoI`NkO<%4;-L+I0d*<51ikvgm9-G=y;M4Zq)-r zc#;rq)B|_nK|;7FQ4jq4X9?j_J#ZiXmk^A^L_+unt&nm=yg7=+00000NkvXXu0mjf D)t`z) delta 1855 zcmV-F2f+CB4(bk&7zqRe0000wHcbNQTpjV>kT)}uR@!x(G?`|lnUCJQdGlu8cM17V?d^Ym z8UNt3w{Gcut?ASret8@4-X})&WWqc0*ZZ~uy!(Y!1L~p2W>rVelZM|1WkRcd{Zlqn zfX|N9fYk*~_)*XEJkoo5QdV=z5v`i4$IG72SeW#Ruxx)?10*i}gAo!(DL*2uIm{Z^ z^4SC!VB4#mV5K;8u)Nu)1Z@YRSN0D#YjZ9q>f1ps`G z9!$Qv52MP2auS?`3ZOUf9@xGQ7hj^0;cA(B5<6BT!zbFo&@sj%1a!GhJOd*H9Gn~5XeV$=Dw^0;yHEh&m?Luz5-WdzVus_f%vH2t zRDdlF09eA&S=1M~x0Rp^qy~Z-&? zCoK>n_f`Qq8Hx<{SAZk3nWwxtK{CZh3J~M20CKl%13CxhNMHhKDh|p}FNZAvcd&?K z4B<4-F)Zp_kS@SW#}0pGQe|YL>B8wePE^(zn}8#Ra&Qzd+!#+;jB}JwCjBKAC+Av zi1u;or5`2ny=(H%t^ecoH`gyVb7p1k-sLwJmv;a}du9Gi?*a%l=v~AAQ~NIxWKBJE znvftX^`P2oZBc)sp#)i}2c<7o0);4@;GZZ}K}3Q4wk=SIs=zIQ^7LfZ5-6muz)3_r zp+691`(!0hNFy}dUqwM&lC6Rn^~4=u`SkSkgfZ`BM%&%Z)0mx}o}!6EX0&H+0Nt)C zcae3}LxYa7T8<v+YpU=QRl9?Y?j7lc9s=uqGq@1q0o@ZAS^mGHtcXzR|w z7zATBu@{TU-q#P%A6^8R*}4MWuorBhG|<-{-X9Ao=5o3^tz>*CD!Eu9z^5{xc&oOq zF?|uvb9aA{Uqh{v7D4BV&=>stC$R13Hxp25YK{P#HivKglAn*cO^ffJUy2EWLzIOF zMX+)K??nuaX`(0)v78(V9W!t0k)C6b0Dfk=yI5429lB$oF9PyLwTvAsl>8jUg@^jW z3;^fH@k7g4C_sBDB!~5o(z8c&douE*{5TAFR%L(IuFKC6&`gVGO2J4+>G|}@ToSt| zq0Yh3Fd6pgKvX5%)t!BgDeg-^yHa&fNCUbff@$qDD;TgRzcLxj-MRQq2#isH*3o0j z+5xJaEthlY=B`CFHMo$bIA+hd>+($7Hz{0=mqu$`h*78nhM_T-6bnA t=&OrYdlz>A`~A!Js9*`yOD7=$#Al5CekuM{*gq32ICFXAkhN zd0J`i4UM1m&vm_j4lsG`B)~I7clQ*aCeCmH#{mDD0QAHg=TZV4VFK`?j|m_i0k+Z1 zgh#3bY$-uo#*n~Z7ClwmP5^ZZqYD zmS&+@r67@i>K6gLaT@{`Y<`Ht{?Y`lidAbRNU@rOHazTL-Wd?aCIpApX3&BD;dgNF z&-?TFyx-fN5qao*0OG-WECAp`@dns{=OGYK)(Xm!>k3!{-fspN1mFy)z{qnHvqw03 ziTQnF!rO!lB7hJ)AIzD_eSD2k3Nf}l?}mo~$TK~ER)?Dz5%O00{V3a7%|Qqnd6Hky zD|JM8$bTGGO9J*T0)d%6RMB%B6QE+ypPP!5)gdG^KpwsOA}`fBuS8BI>t$xH5kem6 z2;ej%d)O7?gaBm&KGH~1P7!fZ%yb6CrOQh$4eI6dDml}?>ZQYkaP_}?gE%EdVouWqY%UmKt$Xk5aM(xpCWDo{-yZq zef(V){=00vnci~^Fs+lh=;9{;WAK`bpVY}<`~o}!OokagNKrnZeg-h|F^OXj-|BmS z=;cfN7%-``;ZIocO||oD4l=XYVFHN7`|1CGw(i|mey!-!CvfLI2LL7*(*xWEfXCW5 zw}6rL)OW7QFf{~TLNo6Ql|B-ddbLy~Yyhf%uolnOe6AadWA|M34_0ORTt^t!pc;V& zw2o&s3mTBDFOC7xJl6ni|Fd<*i&Ue?_QiQjsT$yXl?3n zRs91~oA*!w92!?KsDu82vD$j`?-S!H2m^Khz$oi&Q>|wwFMp#q{ey*@BiVT4`N`e& z54gGFig#X)^@IL_h0o1F|3EcZF2tyR z@Kuca2j3Bf{evq?c@h4ge;{I?T=tj!gGbv!__BZS7_<;{|KL*oRSThMAb5YF2T>Sp z1EKT}E~KKGCw|aBI8P$_!`L}=zsJ6KMvy;!njWp7q3jH00000NkvXXu0mjf(Gf^w delta 1231 zcmV;=1Tg!A3W5rd7zqRe0000 zzl-BW6vri82wdH2*XeIg-X@LMNn)0`i89t7V4qZ^+>?ea7fe<-=kB;5(q3_ha}fvu zbJdY8Lbz)Z6~^5BQF(7>^xL+I%!0vws zdTR6mCg}le!e%F%7%>(e1<`AgD_LveE!asHzC#d_6j4*;9_{Pw4x4*{l} z5CUoH9s+EFzy%9yz^Vr5{eKqm+cbUA1uRqu&|O;DU73J$uLkHQ ztgL8exD5d~Qvg2zY||e(lRfy61XO<$s{(kNmOv2sRhI=YOiKWsm5(WYb!7zw47U>S z0|YLx2_6Ru*tn_z4J>e8jL$d^@w>HBzz-NtL(V)2_?*q+7_+UiOaNfrN`M0(kJ>0= z%yD39$v)c)7}R~NDn!gXLtrpxvm1|)$sbv^+2qEV&x165$$7**wI}NMFm`_%3P6V3 zbS}ACjNj;~(D9r+nLs?-h(B$Qsd&WvpqMMA)U^~~6UXsY0>&1#(_>5#$i!cSFgY0( z=uH%BncE2DSHxj4Lnvy#v+J)Mhmj9RTtfPog>mzRTT{k7`XKTF2_iOw=>^T#X$`f% zSxiN4&|pq{?v1I@1b%baV+wyIU{f|32c#ai;DxiGe*!&V-gDS@J)W#ZVhjYtKNq6= z9$Sfkl^9cj@w^j2+CP{~YCG&~UXv#v&b5EArMAOI*ic?d3;*CS2c;B=$s`-b*tL`7VE4e%2A0V8F zU2=EKKWKv?c1QdJDy3RG=^xsvZD@M{24O1w!|&iQIuLk_e4_k;^bZ|(0BvBM=cRvW zyA-LFU>%P82bBL!!#^|$IPTdiD*Z!Y51MVPvNxr?qdhxVPFh8lwZ|*%fko+oc~rn@ t>85>vL9hGl!QlF60|n9ZAMF2c{S9y!fv3C#-A@1j002ovPDHLkV1gfqJcs}Q diff --git a/graphics/pokemon/masquerain/normal.pal b/graphics/pokemon/masquerain/normal.pal index bd8d9c4c7c..3d0291badc 100644 --- a/graphics/pokemon/masquerain/normal.pal +++ b/graphics/pokemon/masquerain/normal.pal @@ -14,6 +14,6 @@ JASC-PAL 136 32 72 136 160 200 192 200 224 -16 16 16 224 104 40 248 144 96 +16 16 16 diff --git a/graphics/pokemon/metagross/mega/back.png b/graphics/pokemon/metagross/mega/back.png index 00bfdd18181e129eb963e142b922ecec66bcb9bb..86c2b6e145655c2717d7ad305e9625253be03337 100644 GIT binary patch delta 828 zcmV-C1H=5r2Z0BW7#0Wv0001;w}I>c0004VQb$4nuFf3kkv=|u0{=-wK~z|U?U&tB z>o5$2W2siAA-wRjMqU?}-kYyH?^S^n0~Rg?i_n5==kEmxY

siT0sTOUYnhTZ)g zuFrD^YhSJr0zB&Q{pOK*2q+pqMDS@BtpvjJ1>X_L!O%$s?F%o&_qcV>G?2V0Fx>Dx zFB1#{;)_$@x(mskDh9*@b6DV8UM4StH#2U5Z+JH_@sWdn?gD%}MWh2H=kTGR0@u7I zY6%=Rya%fQU-4+RLGZ|a5xC^XLelfejbLE56pzP7_@G!uK&?q_GTCWDUI@gB2^*wL` z$`dEt2>ok+33dAtKBp~qPUA*o+V|tryPa1@1?q*@*hEq;B>Jcd`~HdRqAC#QabdW9 z%L~nWa-Rx{e}0h7obbs2c;Lz>&elGf%TNHm>lW<7sRH5$9-g(zcgLZ{h-On9_>P44 zs(=&7_?b?eZ}PUCsi=>tE-{g@9RT_z%Pc@D6Dfq;8=5QPuEnhC`N*3NT;-t;JYDfQtc( z=`V*ZkLpo!6VGd00SRML_t(Y$K8}qYZE~j#y2T=^58UdOM-{E zA@yo@m<{$U^qej;hn(CF`+_~0SQz>-ltS5~gyb-vp$GA*egeOY&pQ(<*|eU;Hzb5S zzkUBbGfDp4=m_!tFLGBLH_hU4r2F!^;aEI>s$acvZXr0HJ)jd^ojJ!v5TEw-6Tg_x~z2-4?2k>5LZM4>8y*JZax7;0n zLHQK`3&7B+*Hh>XeH?C5@Lxqby?V2Pg@C+6D^Uv z)`U+>N>AHHjJZOM7osFpW-UD#$r>}70O&%Uw-V4>=;#1zj6mMf{f5Gfm>>XhH^Bkh zL%OU@%uw2k-2_h<(5Ao+Ljq}AEe=?J*OlH@utmOGp#y){p?l&IBrjSC1kE==M+M$< z*4{z79gd8c}Cw{Z-fX@dBs#IL(w=Y5ed2+dbiS>@) z0d(rIE=5n?1^xTj_z2*rQ6?untXoqhFE=u0{i`zbRRBhkE{5ExUJ+HeQ=3vu?!JH3 z`Z6{#qI`HDah@bvg{|wl^ktSY5NmX^Veiy?Au(!o%ID_P8)ZlLK$6JlH7r90*gEiJ z>oLsnv5Af^Cj!8Xfi-L$tf`8BKpeCa_88qBz}C{>TLAzyBm)Y~v7e}6Q$DfAN|BEE zi8v_Nu4sZKQpL}ev-w)j4r59_n<>`VPb-Bcs&MZH-1ID5^O^y%psEpc1Yp8|@GBvd z7W_}6altw_FzRMO?8y-W%BNLIy%`Rf)#m^{3hLjwG{yf)1U}QT3;qF6D2GXZ0l+QN z%ESsYg^Fh%$QEI?Jn0KTFqr_z(Bq8WHMfgOMBqF*7V$a&2o-uIGTas-O}D^*5J~b2 XR@sk%RP-X-00000NkvXXu0mjfiYlXX diff --git a/graphics/pokemon/metagross/mega/front.png b/graphics/pokemon/metagross/mega/front.png index 6ed2cfbebc30f33e2e42d8de98a8817ab2324de0..1ebb0470aad180f323818652db2c8c4356ba1cb2 100644 GIT binary patch delta 1245 zcmV<31S0#^3ZDv)7#0Wv0001;w}I>c0004VQb$4nuFf3kkv=|u1f5AlK~z|UomY#N zqdE*DHc2S7JOBT;SCSo|vxV8Y+0*S5kRm^0rm2`s)8tl)xlg}eHqV4seK-3(1%Pue zrP@+J(cFG`zLesAmTGhFgj!kfZ9g!S@_0b$x*iCN612e2>4?$@#I5Ue3Li0ljbPpcc6C)Vxh$Z#~ z0X^t%cr!^rPHO))vfGHK1SDMq(m+54SO<9GQPPr-0-7k3AQ=ED5r;t#0o?H}37!Iu z0@eL+q>2K6abPl=1=@GK7+9C>4L{jnU@|axc`qqkRxIr#X~9tXVk6vBUf$ti zFkA*lU1QaTjZO@OuC`Hk;HLBaSa=i!JDiJFk|P-8=u_b`q2-5!`-TYn+73LE@|ioO zUgptTy~iDr+qQv)+wK#YcQZg#_F1K^u5qafzv-P43z^vT)m8n~wm5eiAVDBiS!kkr!UC zS4$rT{OKfsaAo@~-k78ycu7Lr@eI5&Pm`D47I@<#LMrIOm}Dq=v}F7E)AO& z_6LD~5pQ?a4}wZt|A-+72t+K<#(Mt;2_$g)vO(bfWg@WoL580Qpi~mRJP7O$$k>FT z0FwY1uE8!JvkQ25f&1GR@p0mGGF%ckoo>oRKJLQ;<_<&9Ab|{*_%*6AD$f0IVN?$} zt>a9%!dIm!N=U`>WFD9)h|$=XfQkRhk5M0gsy|wa{gFCwAFeBn_O@xn!%J^NgzmCy zj6U8hl2;AJGLO?dIk}xDp}^8@aW;~`?YXy~!6uO`l58mZ5so9RxDIC7DTomiMQ8DY z3~H%Xvn$qdVy?)J65GrC?3hnE#Wh&kz)wo2?7n$~SHRc3Ar#01P!&7JfYL00000NkvXX Hu0mjfgeXUa delta 1300 zcmV+v1?&2s3f2mc7$yV*00013M{Ml?0004VQb$4nuFf3k00004XF*Lt006O%3;baP zkuE-e010qNS#tmY4#NNd4#NS*Z>VGd00gf|L_t(Y$90u4Z`(!`$Im3t*_4<_$s`_S zTCLN@y#o)1!Pt zJM`YU0lOE^hmRL^;(h(jZE4*S4GHT}el zX`zyBiNS2-bn`1`u>t07o+!BmSb9Erl;h{|ArYR|T1cs6`UzlK4`z8DMc*8fkRlL& zegazNOB^9^9z~-)AYqCXN(0nI?EJQah){EFfYWS281+zKDMby~oIN_-B?7qC{V19u z(2wT+csx#c29yvk6`LZEr~v{aUoOag=S5g7moW&yA_NbU!7d3iIMV$K$9WLrO}5X9 zVyr+x+Ow0rI7H4)l2q?Id43raPhS>)#qwGJ3!n#am?#9S43zf1&ZEc+wxS+Z?q>Z@{9$fC$(QdRVLK~baOXHhSG^T(?-~4RuINmM7etUuOG_veAoc& z>sEEc8Ko$3>-%YfrZhQ!!uM`_EW^YM!V~Iqr;S4B?@$5`4CV-3=Q6_#IGsRymN%Mm z%4yHe5*UwTH1+pGZB|r}g4qwm9ZhMEnuBM!HJ13u?dlmWISw0xxuebD?XzMz9s@q} z^sMD)NeaORxa+`I1zr|40HxHM2^=$CTiCt3y))EQ0yhF~0%xLs+WJ4?fkpVklGECYC;Cg|6R|icXOSpFP z=pmT5mPm(s4vkl1t0mQZ_A-yA_3hehI1ieWZearY@@ljJh>cn9%^BC7N$Y$RsLc{X z*B&+jHapKpltOdGZ0G2_yt?q=vlsSOj{c|x>dUWuB+v&wA>@BlE<$)GQ2?$P#e^fphs( z>$1QGpX%p-4MJ810ny765jD0Y;PG$<+;1#IBLRkR4!m`UUavoYh(GE#rRNkmM-_Xv zF-dwFa+0M=N#GLXcv1fp{M%7x2bFAz9>foj{*EdOjsw z�j#+!)A@7W6Y}tOcrA7tbCdSK(9DPb2O7mf%NdWxyZh-co!7zvGTO?)Vk)sr!bD z=iokn@bXD|z(+X`f6SofyJHcD{D0TwmUrPx1gm@BUdO*ZEA0(QUMnj1?rwJ2{}-RT zzMi=e?fCx_3F+wGQ`f$C7+Uwf+V`Q?1?;%@G$vpw&A4;#7w}sBgL^+tcDnd*?%s!A zm(Jb$_{&-);M~2B5cJLWKOk`Yse2z{5Q4scdmkn^ckh=J9Nqf`g1&nnCOCKR;{<2! zeRv(QFtqM{kU*`v8P~?We~U*XjbKv{9fP=gue@)6J5?9S1Viku_JF!~wvbT#?>Pn9 zfJ3$G3`J9j#l2@ANpvX`KhHDhkY>Gfb?+2|F}RNX2m{%q0$(=II)`#4VRi4hXwxZw zO374)NY2Cg6D_P@Ml3^`g4V;N*ms+vm4 zFq(GJbMHErM1-0hPw-RUy&E;v<8eB}zX_uz8ayrUxZ^*FzbM@@PabE3pO_JEN->{UI$d3wwWN2YnmJ<@DA1Rsr}OYcdDSn{XBVV%NjqVVx=A zBYnBZ0XYER@};LvSe^uh4|jKb9|#;Syjv9_NDgeWO^;M0#|5yUz$KC0^*FZKCLLUC z?$3QCW-9|+1E3DQU9aDpx2`#{4SReF#o{^#W*R`q>EhwfdlFaXj05I>|KxuQEKLvv zK*$5{Vzc>MT|H>Ddbe?ydOoD`jZ=xjE;d}R#C8_8Fx{*>u-mEs5=pLwUZd*_Z; z!JLcqQ zw$Q`LXn8tiJY>#+Az4o(G97=*rSuNGm!(G}aFCOM=iB#P13W@CEL2{&K?8ush-a~c ze`@GV3rufhG8+3w05nFrlJf-B&=?_iarr};&^cejLG6%A z%QHl&99=i}6x9#;05}rg8hasrL40QY)n4sOn%CH|J8K>5$kObP>K>ZtlJ#qilkd+Of^RMh{7hpm75Hv@a>-w0IHzZux6f8$A^R!a460@|7azfk|0^16MEr|fh} z8tSi2RduU?c@)gQ^`PzPc&0pmpXd{wcyDCS7neB5F(!>YAFc|r+u+eW&DCEI0_o!? zVJS~so$2hmk3D#aa`m6$gD2nRVYQQ2juyXW8GA;SNsOAD58;0*98Uuub7|K}9# z(`6Js_ttkyGfyh&a5H@y_5Ue0>I;c~`;fgy`McUEwn@p%H_Uu??bd96a8W3BRsAtg zVqPp}cCr13u)9E6TuibXZoaws2CY@qpAqIo(}QmD_rN@@s6S|Jn^f1Ur=)fF$l9y@ a5B4vEDudj3#^-_n0000c>cDC*N5CWoahT(}n62_P>_2c*zg7o7T2+IE} zf~Z%-M}R!K`IMjl7IzbjuAV&*Y==6JSO7|Jjq671+5K$crD0!StyCjk2k>#_oTs?hgS0z2}5QoY1_ zYa0mGfTdx7aY52X+VcjudMKl}q`-iYs=%9I^l>Dd1q3gAo{d>&iEi`D^{L$El-ja z`_CN+`mGa6Qz}13R_(u21jPk_4Wcx{{Du90XRR*K86kbioQL;U_Fu>6Zca6ebsqlO z{wpDBH|;_``tZ*FGa~np4~VV1M$f=+>^~D^x8$mw^wQzFvj6J-o$8N$Y;$bRUD$s% z^|ZJ16pnptv+wO)*?+aZ6D5?jd%~_gcV++A_5q^J8DF%q<(c|y|F!#}?Sr*_YizA* zi>-hc`>&k?E`(UujZo<;<_5yv{_DYnyY9i-L$3DW*G5mV|7!lzv6m)@dSCNwEb8X} zx-VJ?*`xC5+GpN#Yw=I@eBAsJp9Fzzs~>w002ovPDHLk FV1gu;{`vp_ delta 1143 zcmV--1c>|32)YT77zqRe0000yDJS*qr3ALvX)l%6p}dF*x?(TWV34sRBe{yfq$0i-Q!k%Jws0D$snL%2L|9Rtwfs%SjKZ`|gDitw1&OXONf zl2$me@jhV0X5#;#b}(s4z$>t0hf?A9wDynO$@}R5Z}@b z{)_4^|M(CpO%`lpjC((lTjT<$HjjVfyfWJo5X~cqO%A-*?Cmb(F>wKSJjWQ;Pvk%x z9FZg4^!lCydE={v7)mkqBc1i5?lp{S?eqsLxh=Rq=>Ji7jzzJgJZ;^fr~R`TvbXJVgEmpRE|KWe-Y5&js zckH8IT$%=Qk6!elhG^?d4P2e3*4S=P$e(r4R&?2;^x}~vMnL6JFx=ij1v_$S#UzVB z`9c1}!8cbn${l+|bt(eT3-)yL(Sw5JDnO(Fxmbh^BDGVLP4dhn)*?VVb`(V&wQNYT zX`5tmpE8ke5AB~j#X|f;8Zdti>A-R^-Qn9aiEev~0F~}qZX?c#ZkhIC2TwQFWcQfo zv_*!*OV7ZgeSX!}Eze3nPScoPkx0Fq2IL7Kx9l@j@VMhzYquqtdSR3rVO;ldqrI;% z&l7#4cpbnWV9jTYEd$o>V|)|xaLEdMh_C(doIP(t?TZm5jI6K?uM>YhP^Zw|<>$=}tx`d@4BHStUj zgf*uJ%kIwvR%d!3E_td4OKPeI*}&p^ep;966Fm^e)!t8IJzyfD+QZI74tv1E=bIG1r3o(#P=Loawo>~fWa@J|nsIXkG7=788R;JB4rmLH9R Date: Wed, 19 Apr 2023 01:52:20 +0200 Subject: [PATCH 18/30] Reusable TMs (#2903) * Reusable TMs * Forgot about Gen9 making TMs expendable again * Change importance check based on Alex's suggestion * Prevent items with importance from being bought more than once * Change importance check to ghoul's suggestion * Update include/config/item.h Co-authored-by: Eduardo Quezada D'Ottone --------- Co-authored-by: Eduardo Quezada D'Ottone --- include/config/item.h | 3 ++ include/strings.h | 2 + src/data/items.h | 100 ++++++++++++++++++++++++++++++++++++++++++ src/party_menu.c | 2 +- src/shop.c | 22 ++++++++-- src/strings.c | 2 + 6 files changed, 126 insertions(+), 5 deletions(-) diff --git a/include/config/item.h b/include/config/item.h index 031af37241..f707b7a540 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -9,6 +9,9 @@ #define I_SITRUS_BERRY_HEAL GEN_LATEST // In Gen4+, Sitrus Berry was changed from healing 30 HP to healing 25% of Max HP. #define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8, the Vitamins no longer have a cap of 100 EV per stat. +// TM config +#define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1. + // Repel/Lure config // These two settings are both independent and complementary. #define VAR_LAST_REPEL_LURE_USED 0 // If this var has been assigned, last Repel/Lure used will be saved and the player will get prompted with the vanilla repel YES/NO option, unless I_REPEL_LURE_MENU is set to TRUE. diff --git a/include/strings.h b/include/strings.h index 959bb8c22d..f17d509e85 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1025,6 +1025,8 @@ extern const u8 gText_ThrowInPremierBall[]; extern const u8 gText_ShopBuy[]; extern const u8 gText_ShopSell[]; extern const u8 gText_ShopQuit[]; +extern const u8 gText_SoldOut[]; +extern const u8 gText_SoldOut2[]; extern const u8 gText_OhABite[]; extern const u8 gText_PokemonOnHook[]; diff --git a/src/data/items.h b/src/data/items.h index fc99e10373..84436be55b 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -7728,6 +7728,7 @@ const struct Item gItems[] = .itemId = ITEM_TM01_FOCUS_PUNCH, .price = 3000, .description = sTM01Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7739,6 +7740,7 @@ const struct Item gItems[] = .itemId = ITEM_TM02_DRAGON_CLAW, .price = 3000, .description = sTM02Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7750,6 +7752,7 @@ const struct Item gItems[] = .itemId = ITEM_TM03_WATER_PULSE, .price = 3000, .description = sTM03Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7761,6 +7764,7 @@ const struct Item gItems[] = .itemId = ITEM_TM04_CALM_MIND, .price = 3000, .description = sTM04Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7772,6 +7776,7 @@ const struct Item gItems[] = .itemId = ITEM_TM05_ROAR, .price = 1000, .description = sTM05Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7783,6 +7788,7 @@ const struct Item gItems[] = .itemId = ITEM_TM06_TOXIC, .price = 3000, .description = sTM06Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7794,6 +7800,7 @@ const struct Item gItems[] = .itemId = ITEM_TM07_HAIL, .price = 3000, .description = sTM07Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7805,6 +7812,7 @@ const struct Item gItems[] = .itemId = ITEM_TM08_BULK_UP, .price = 3000, .description = sTM08Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7816,6 +7824,7 @@ const struct Item gItems[] = .itemId = ITEM_TM09_BULLET_SEED, .price = 3000, .description = sTM09Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7827,6 +7836,7 @@ const struct Item gItems[] = .itemId = ITEM_TM10_HIDDEN_POWER, .price = 3000, .description = sTM10Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7838,6 +7848,7 @@ const struct Item gItems[] = .itemId = ITEM_TM11_SUNNY_DAY, .price = 2000, .description = sTM11Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7849,6 +7860,7 @@ const struct Item gItems[] = .itemId = ITEM_TM12_TAUNT, .price = 3000, .description = sTM12Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7860,6 +7872,7 @@ const struct Item gItems[] = .itemId = ITEM_TM13_ICE_BEAM, .price = 3000, .description = sTM13Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7871,6 +7884,7 @@ const struct Item gItems[] = .itemId = ITEM_TM14_BLIZZARD, .price = 5500, .description = sTM14Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7882,6 +7896,7 @@ const struct Item gItems[] = .itemId = ITEM_TM15_HYPER_BEAM, .price = 7500, .description = sTM15Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7893,6 +7908,7 @@ const struct Item gItems[] = .itemId = ITEM_TM16_LIGHT_SCREEN, .price = 3000, .description = sTM16Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7904,6 +7920,7 @@ const struct Item gItems[] = .itemId = ITEM_TM17_PROTECT, .price = 3000, .description = sTM17Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7915,6 +7932,7 @@ const struct Item gItems[] = .itemId = ITEM_TM18_RAIN_DANCE, .price = 2000, .description = sTM18Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7926,6 +7944,7 @@ const struct Item gItems[] = .itemId = ITEM_TM19_GIGA_DRAIN, .price = 3000, .description = sTM19Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7937,6 +7956,7 @@ const struct Item gItems[] = .itemId = ITEM_TM20_SAFEGUARD, .price = 3000, .description = sTM20Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7948,6 +7968,7 @@ const struct Item gItems[] = .itemId = ITEM_TM21_FRUSTRATION, .price = 1000, .description = sTM21Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7959,6 +7980,7 @@ const struct Item gItems[] = .itemId = ITEM_TM22_SOLAR_BEAM, .price = 3000, .description = sTM22Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7970,6 +7992,7 @@ const struct Item gItems[] = .itemId = ITEM_TM23_IRON_TAIL, .price = 3000, .description = sTM23Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7981,6 +8004,7 @@ const struct Item gItems[] = .itemId = ITEM_TM24_THUNDERBOLT, .price = 3000, .description = sTM24Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -7992,6 +8016,7 @@ const struct Item gItems[] = .itemId = ITEM_TM25_THUNDER, .price = 5500, .description = sTM25Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8003,6 +8028,7 @@ const struct Item gItems[] = .itemId = ITEM_TM26_EARTHQUAKE, .price = 3000, .description = sTM26Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8014,6 +8040,7 @@ const struct Item gItems[] = .itemId = ITEM_TM27_RETURN, .price = 1000, .description = sTM27Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8025,6 +8052,7 @@ const struct Item gItems[] = .itemId = ITEM_TM28_DIG, .price = 2000, .description = sTM28Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8036,6 +8064,7 @@ const struct Item gItems[] = .itemId = ITEM_TM29_PSYCHIC, .price = 2000, .description = sTM29Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8047,6 +8076,7 @@ const struct Item gItems[] = .itemId = ITEM_TM30_SHADOW_BALL, .price = 3000, .description = sTM30Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8058,6 +8088,7 @@ const struct Item gItems[] = .itemId = ITEM_TM31_BRICK_BREAK, .price = 3000, .description = sTM31Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8069,6 +8100,7 @@ const struct Item gItems[] = .itemId = ITEM_TM32_DOUBLE_TEAM, .price = 2000, .description = sTM32Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8080,6 +8112,7 @@ const struct Item gItems[] = .itemId = ITEM_TM33_REFLECT, .price = 3000, .description = sTM33Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8091,6 +8124,7 @@ const struct Item gItems[] = .itemId = ITEM_TM34_SHOCK_WAVE, .price = 3000, .description = sTM34Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8102,6 +8136,7 @@ const struct Item gItems[] = .itemId = ITEM_TM35_FLAMETHROWER, .price = 3000, .description = sTM35Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8113,6 +8148,7 @@ const struct Item gItems[] = .itemId = ITEM_TM36_SLUDGE_BOMB, .price = 1000, .description = sTM36Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8124,6 +8160,7 @@ const struct Item gItems[] = .itemId = ITEM_TM37_SANDSTORM, .price = 2000, .description = sTM37Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8135,6 +8172,7 @@ const struct Item gItems[] = .itemId = ITEM_TM38_FIRE_BLAST, .price = 5500, .description = sTM38Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8146,6 +8184,7 @@ const struct Item gItems[] = .itemId = ITEM_TM39_ROCK_TOMB, .price = 3000, .description = sTM39Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8157,6 +8196,7 @@ const struct Item gItems[] = .itemId = ITEM_TM40_AERIAL_ACE, .price = 3000, .description = sTM40Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8168,6 +8208,7 @@ const struct Item gItems[] = .itemId = ITEM_TM41_TORMENT, .price = 3000, .description = sTM41Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8179,6 +8220,7 @@ const struct Item gItems[] = .itemId = ITEM_TM42_FACADE, .price = 3000, .description = sTM42Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8190,6 +8232,7 @@ const struct Item gItems[] = .itemId = ITEM_TM43_SECRET_POWER, .price = 3000, .description = sTM43Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8201,6 +8244,7 @@ const struct Item gItems[] = .itemId = ITEM_TM44_REST, .price = 3000, .description = sTM44Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8212,6 +8256,7 @@ const struct Item gItems[] = .itemId = ITEM_TM45_ATTRACT, .price = 3000, .description = sTM45Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8223,6 +8268,7 @@ const struct Item gItems[] = .itemId = ITEM_TM46_THIEF, .price = 3000, .description = sTM46Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8234,6 +8280,7 @@ const struct Item gItems[] = .itemId = ITEM_TM47_STEEL_WING, .price = 3000, .description = sTM47Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8245,6 +8292,7 @@ const struct Item gItems[] = .itemId = ITEM_TM48_SKILL_SWAP, .price = 3000, .description = sTM48Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8256,6 +8304,7 @@ const struct Item gItems[] = .itemId = ITEM_TM49_SNATCH, .price = 3000, .description = sTM49Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8267,6 +8316,7 @@ const struct Item gItems[] = .itemId = ITEM_TM50_OVERHEAT, .price = 3000, .description = sTM50Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8278,6 +8328,7 @@ const struct Item gItems[] = .itemId = ITEM_TM51, .price = 3000, .description = sTM51Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8289,6 +8340,7 @@ const struct Item gItems[] = .itemId = ITEM_TM52, .price = 3000, .description = sTM52Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8300,6 +8352,7 @@ const struct Item gItems[] = .itemId = ITEM_TM53, .price = 3000, .description = sTM53Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8311,6 +8364,7 @@ const struct Item gItems[] = .itemId = ITEM_TM54, .price = 3000, .description = sTM54Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8322,6 +8376,7 @@ const struct Item gItems[] = .itemId = ITEM_TM55, .price = 3000, .description = sTM55Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8333,6 +8388,7 @@ const struct Item gItems[] = .itemId = ITEM_TM56, .price = 3000, .description = sTM56Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8344,6 +8400,7 @@ const struct Item gItems[] = .itemId = ITEM_TM57, .price = 3000, .description = sTM57Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8355,6 +8412,7 @@ const struct Item gItems[] = .itemId = ITEM_TM58, .price = 3000, .description = sTM58Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8366,6 +8424,7 @@ const struct Item gItems[] = .itemId = ITEM_TM59, .price = 3000, .description = sTM59Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8377,6 +8436,7 @@ const struct Item gItems[] = .itemId = ITEM_TM60, .price = 3000, .description = sTM60Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8388,6 +8448,7 @@ const struct Item gItems[] = .itemId = ITEM_TM61, .price = 3000, .description = sTM61Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8399,6 +8460,7 @@ const struct Item gItems[] = .itemId = ITEM_TM62, .price = 3000, .description = sTM62Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8410,6 +8472,7 @@ const struct Item gItems[] = .itemId = ITEM_TM63, .price = 3000, .description = sTM63Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8421,6 +8484,7 @@ const struct Item gItems[] = .itemId = ITEM_TM64, .price = 3000, .description = sTM64Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8432,6 +8496,7 @@ const struct Item gItems[] = .itemId = ITEM_TM65, .price = 3000, .description = sTM65Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8443,6 +8508,7 @@ const struct Item gItems[] = .itemId = ITEM_TM66, .price = 3000, .description = sTM66Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8454,6 +8520,7 @@ const struct Item gItems[] = .itemId = ITEM_TM67, .price = 3000, .description = sTM67Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8465,6 +8532,7 @@ const struct Item gItems[] = .itemId = ITEM_TM68, .price = 3000, .description = sTM68Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8476,6 +8544,7 @@ const struct Item gItems[] = .itemId = ITEM_TM69, .price = 3000, .description = sTM69Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8487,6 +8556,7 @@ const struct Item gItems[] = .itemId = ITEM_TM70, .price = 3000, .description = sTM70Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8498,6 +8568,7 @@ const struct Item gItems[] = .itemId = ITEM_TM71, .price = 3000, .description = sTM71Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8509,6 +8580,7 @@ const struct Item gItems[] = .itemId = ITEM_TM72, .price = 3000, .description = sTM72Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8520,6 +8592,7 @@ const struct Item gItems[] = .itemId = ITEM_TM73, .price = 3000, .description = sTM73Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8531,6 +8604,7 @@ const struct Item gItems[] = .itemId = ITEM_TM74, .price = 3000, .description = sTM74Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8542,6 +8616,7 @@ const struct Item gItems[] = .itemId = ITEM_TM75, .price = 3000, .description = sTM75Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8553,6 +8628,7 @@ const struct Item gItems[] = .itemId = ITEM_TM76, .price = 3000, .description = sTM76Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8564,6 +8640,7 @@ const struct Item gItems[] = .itemId = ITEM_TM77, .price = 3000, .description = sTM77Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8575,6 +8652,7 @@ const struct Item gItems[] = .itemId = ITEM_TM78, .price = 3000, .description = sTM78Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8586,6 +8664,7 @@ const struct Item gItems[] = .itemId = ITEM_TM79, .price = 3000, .description = sTM79Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8597,6 +8676,7 @@ const struct Item gItems[] = .itemId = ITEM_TM80, .price = 3000, .description = sTM80Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8608,6 +8688,7 @@ const struct Item gItems[] = .itemId = ITEM_TM81, .price = 3000, .description = sTM81Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8619,6 +8700,7 @@ const struct Item gItems[] = .itemId = ITEM_TM82, .price = 3000, .description = sTM82Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8630,6 +8712,7 @@ const struct Item gItems[] = .itemId = ITEM_TM83, .price = 3000, .description = sTM83Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8641,6 +8724,7 @@ const struct Item gItems[] = .itemId = ITEM_TM84, .price = 3000, .description = sTM84Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8652,6 +8736,7 @@ const struct Item gItems[] = .itemId = ITEM_TM85, .price = 3000, .description = sTM85Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8663,6 +8748,7 @@ const struct Item gItems[] = .itemId = ITEM_TM86, .price = 3000, .description = sTM86Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8674,6 +8760,7 @@ const struct Item gItems[] = .itemId = ITEM_TM87, .price = 3000, .description = sTM87Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8685,6 +8772,7 @@ const struct Item gItems[] = .itemId = ITEM_TM88, .price = 3000, .description = sTM88Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8696,6 +8784,7 @@ const struct Item gItems[] = .itemId = ITEM_TM89, .price = 3000, .description = sTM89Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8707,6 +8796,7 @@ const struct Item gItems[] = .itemId = ITEM_TM90, .price = 3000, .description = sTM90Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8718,6 +8808,7 @@ const struct Item gItems[] = .itemId = ITEM_TM91, .price = 3000, .description = sTM91Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8729,6 +8820,7 @@ const struct Item gItems[] = .itemId = ITEM_TM92, .price = 3000, .description = sTM92Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8740,6 +8832,7 @@ const struct Item gItems[] = .itemId = ITEM_TM93, .price = 3000, .description = sTM93Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8751,6 +8844,7 @@ const struct Item gItems[] = .itemId = ITEM_TM94, .price = 3000, .description = sTM94Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8762,6 +8856,7 @@ const struct Item gItems[] = .itemId = ITEM_TM95, .price = 3000, .description = sTM95Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8773,6 +8868,7 @@ const struct Item gItems[] = .itemId = ITEM_TM96, .price = 3000, .description = sTM96Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8784,6 +8880,7 @@ const struct Item gItems[] = .itemId = ITEM_TM97, .price = 3000, .description = sTM97Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8795,6 +8892,7 @@ const struct Item gItems[] = .itemId = ITEM_TM98, .price = 3000, .description = sTM98Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8806,6 +8904,7 @@ const struct Item gItems[] = .itemId = ITEM_TM99, .price = 3000, .description = sTM99Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, @@ -8817,6 +8916,7 @@ const struct Item gItems[] = .itemId = ITEM_TM100, .price = 3000, .description = sTM100Desc, + .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, .fieldUseFunc = ItemUseOutOfBattle_TMHM, diff --git a/src/party_menu.c b/src/party_menu.c index a7ab305450..3cc3efdcdd 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -5090,7 +5090,7 @@ static void Task_LearnedMove(u8 taskId) if (move[1] == 0) { AdjustFriendship(mon, FRIENDSHIP_EVENT_LEARN_TMHM); - if (item < ITEM_HM01_CUT) + if (!ItemId_GetImportance(item)) RemoveBagItem(item, 1); } GetMonNickname(mon, gStringVar1); diff --git a/src/shop.c b/src/shop.c index 8fea1e1178..6f4e093562 100644 --- a/src/shop.c +++ b/src/shop.c @@ -639,7 +639,10 @@ static void BuyMenuPrintPriceInList(u8 windowId, u32 itemId, u8 y) 5); } - StringExpandPlaceholders(gStringVar4, gText_PokedollarVar1); + if (ItemId_GetImportance(itemId) && (CheckBagHasItem(itemId, 1) || CheckPCHasItem(itemId, 1))) + StringCopy(gStringVar4, gText_SoldOut2); + else + StringExpandPlaceholders(gStringVar4, gText_PokedollarVar1); x = GetStringRightAlignXOffset(FONT_NARROW, gStringVar4, 120); AddTextPrinterParameterized4(windowId, FONT_NARROW, x, y, 0, 0, sShopBuyMenuTextColors[COLORID_ITEM_LIST], TEXT_SKIP_DRAW, gStringVar4); } @@ -989,7 +992,9 @@ static void Task_BuyMenu(u8 taskId) else sShopData->totalCost = gDecorations[itemId].price; - if (!IsEnoughMoney(&gSaveBlock1Ptr->money, sShopData->totalCost)) + if (ItemId_GetImportance(itemId) && (CheckBagHasItem(itemId, 1) || CheckPCHasItem(itemId, 1))) + BuyMenuDisplayMessage(taskId, gText_SoldOut, BuyMenuReturnToItemList); + else if (!IsEnoughMoney(&gSaveBlock1Ptr->money, sShopData->totalCost)) { BuyMenuDisplayMessage(taskId, gText_YouDontHaveMoney, BuyMenuReturnToItemList); } @@ -998,7 +1003,15 @@ static void Task_BuyMenu(u8 taskId) if (sMartInfo.martType == MART_TYPE_NORMAL) { CopyItemName(itemId, gStringVar1); - if (ItemId_GetPocket(itemId) == POCKET_TM_HM) + if (ItemId_GetImportance(itemId)) + { + ConvertIntToDecimalStringN(gStringVar2, sShopData->totalCost, STR_CONV_MODE_LEFT_ALIGN, 6); + StringExpandPlaceholders(gStringVar4, gText_YouWantedVar1ThatllBeVar2); + tItemCount = 1; + sShopData->totalCost = (ItemId_GetPrice(tItemId) >> IsPokeNewsActive(POKENEWS_SLATEPORT)) * tItemCount; + BuyMenuDisplayMessage(taskId, gStringVar4, BuyMenuConfirmPurchase); + } + else if (ItemId_GetPocket(itemId) == POCKET_TM_HM) { StringCopy(gStringVar2, gMoveNames[ItemIdToBattleMoveId(itemId)]); BuyMenuDisplayMessage(taskId, gText_Var1CertainlyHowMany2, Task_BuyHowManyDialogueInit); @@ -1103,8 +1116,8 @@ static void BuyMenuTryMakePurchase(u8 taskId) { if (AddBagItem(tItemId, tItemCount) == TRUE) { - BuyMenuDisplayMessage(taskId, gText_HereYouGoThankYou, BuyMenuSubtractMoney); RecordItemPurchase(taskId); + BuyMenuDisplayMessage(taskId, gText_HereYouGoThankYou, BuyMenuSubtractMoney); } else { @@ -1170,6 +1183,7 @@ static void BuyMenuReturnToItemList(u8 taskId) s16 *data = gTasks[taskId].data; ClearDialogWindowAndFrameToTransparent(WIN_MESSAGE, FALSE); + RedrawListMenu(tListTaskId); BuyMenuPrintCursor(tListTaskId, COLORID_ITEM_LIST); PutWindowTilemap(WIN_ITEM_LIST); PutWindowTilemap(WIN_ITEM_DESCRIPTION); diff --git a/src/strings.c b/src/strings.c index 847b2849a6..dd632a32bd 100644 --- a/src/strings.c +++ b/src/strings.c @@ -341,6 +341,8 @@ const u8 gText_Var1DisdainfullyAteVar2[] = _("{STR_VAR_1} disdainfully ate the\n const u8 gText_ShopBuy[] = _("BUY"); const u8 gText_ShopSell[] = _("SELL"); const u8 gText_ShopQuit[] = _("QUIT"); +const u8 gText_SoldOut[] = _("I'm sorry, but that item is sold out.\p"); +const u8 gText_SoldOut2[] = _("SOLD OUT"); const u8 gText_InBagVar1[] = _("IN BAG: {STR_VAR_1}"); const u8 gText_QuitShopping[] = _("Quit shopping."); const u8 gText_Var1CertainlyHowMany[] = _("{STR_VAR_1}? Certainly.\nHow many would you like?"); From 52ce39924051c3a94f96eabb4ac9fb5b7edebf81 Mon Sep 17 00:00:00 2001 From: Bassoonian Date: Wed, 19 Apr 2023 17:01:00 +0200 Subject: [PATCH 19/30] Fix TM reusability shortcomings (#2930) --- include/strings.h | 2 +- src/shop.c | 4 ++-- src/strings.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/strings.h b/include/strings.h index f17d509e85..72109ed945 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1025,8 +1025,8 @@ extern const u8 gText_ThrowInPremierBall[]; extern const u8 gText_ShopBuy[]; extern const u8 gText_ShopSell[]; extern const u8 gText_ShopQuit[]; +extern const u8 gText_ThatItemIsSoldOut[]; extern const u8 gText_SoldOut[]; -extern const u8 gText_SoldOut2[]; extern const u8 gText_OhABite[]; extern const u8 gText_PokemonOnHook[]; diff --git a/src/shop.c b/src/shop.c index 6f4e093562..b4978f063e 100644 --- a/src/shop.c +++ b/src/shop.c @@ -640,7 +640,7 @@ static void BuyMenuPrintPriceInList(u8 windowId, u32 itemId, u8 y) } if (ItemId_GetImportance(itemId) && (CheckBagHasItem(itemId, 1) || CheckPCHasItem(itemId, 1))) - StringCopy(gStringVar4, gText_SoldOut2); + StringCopy(gStringVar4, gText_SoldOut); else StringExpandPlaceholders(gStringVar4, gText_PokedollarVar1); x = GetStringRightAlignXOffset(FONT_NARROW, gStringVar4, 120); @@ -993,7 +993,7 @@ static void Task_BuyMenu(u8 taskId) sShopData->totalCost = gDecorations[itemId].price; if (ItemId_GetImportance(itemId) && (CheckBagHasItem(itemId, 1) || CheckPCHasItem(itemId, 1))) - BuyMenuDisplayMessage(taskId, gText_SoldOut, BuyMenuReturnToItemList); + BuyMenuDisplayMessage(taskId, gText_ThatItemIsSoldOut, BuyMenuReturnToItemList); else if (!IsEnoughMoney(&gSaveBlock1Ptr->money, sShopData->totalCost)) { BuyMenuDisplayMessage(taskId, gText_YouDontHaveMoney, BuyMenuReturnToItemList); diff --git a/src/strings.c b/src/strings.c index dd632a32bd..75ff2ef994 100644 --- a/src/strings.c +++ b/src/strings.c @@ -341,8 +341,8 @@ const u8 gText_Var1DisdainfullyAteVar2[] = _("{STR_VAR_1} disdainfully ate the\n const u8 gText_ShopBuy[] = _("BUY"); const u8 gText_ShopSell[] = _("SELL"); const u8 gText_ShopQuit[] = _("QUIT"); -const u8 gText_SoldOut[] = _("I'm sorry, but that item is sold out.\p"); -const u8 gText_SoldOut2[] = _("SOLD OUT"); +const u8 gText_ThatItemIsSoldOut[] = _("I'm sorry, but that item is sold out.{PAUSE_UNTIL_PRESS}"); +const u8 gText_SoldOut[] = _("SOLD OUT"); const u8 gText_InBagVar1[] = _("IN BAG: {STR_VAR_1}"); const u8 gText_QuitShopping[] = _("Quit shopping."); const u8 gText_Var1CertainlyHowMany[] = _("{STR_VAR_1}? Certainly.\nHow many would you like?"); From d3fed5639b4b56836221ccf6232387e2d63a3eed Mon Sep 17 00:00:00 2001 From: psf <77138753+pkmnsnfrn@users.noreply.github.com> Date: Wed, 19 Apr 2023 15:54:57 -0700 Subject: [PATCH 20/30] Added config to enable NEW_ROCKS_PARTICLE (#2929) Co-authored-by: LOuroboros --- include/config/battle.h | 1 + src/data/battle_anim.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/config/battle.h b/include/config/battle.h index ad31621623..3e9ec9b9a5 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -195,6 +195,7 @@ #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. #define B_NEW_LEECH_SEED_PARTICLE FALSE // If set to TRUE, it updates Leech Seed's animation particle. #define B_NEW_HORN_ATTACK_PARTICLE FALSE // If set to TRUE, it updates Horn Attack's horn particle. +#define B_NEW_ROCKS_PARTICLE TRUE // If set to TRUE, it updates rock particles. #define B_NEW_LEAF_PARTICLE FALSE // If set to TRUE, it updates leaf particle. #define B_NEW_EMBER_PARTICLES FALSE // If set to TRUE, it updates Ember's fire particle. #define B_NEW_MEAN_LOOK_PARTICLE FALSE // If set to TRUE, it updates Mean Look's eye particle. diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h index b1f158310a..46293e3a0a 100644 --- a/src/data/battle_anim.h +++ b/src/data/battle_anim.h @@ -1079,7 +1079,7 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] = {gBattleAnimSpriteGfx_RedFist, 0x0200, ANIM_TAG_RED_FIST}, {gBattleAnimSpriteGfx_SlamHit, 0x1000, ANIM_TAG_SLAM_HIT}, {gBattleAnimSpriteGfx_Ring, 0x0180, ANIM_TAG_RING}, -#if NEW_ROCKS_PARTICLE +#if B_NEW_ROCKS_PARTICLE == TRUE {gBattleAnimSpriteGfx_NewRocks, 0x0C00, ANIM_TAG_ROCKS}, #else {gBattleAnimSpriteGfx_Rocks, 0x0C00, ANIM_TAG_ROCKS}, @@ -1529,7 +1529,7 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] = {gBattleAnimSpritePal_HumanoidFoot, ANIM_TAG_RED_FIST}, {gBattleAnimSpritePal_SlamHit, ANIM_TAG_SLAM_HIT}, {gBattleAnimSpritePal_Ring, ANIM_TAG_RING}, -#if NEW_ROCKS_PARTICLE +#if B_NEW_ROCKS_PARTICLE == TRUE {gBattleAnimSpritePal_NewRocks, ANIM_TAG_ROCKS}, #else {gBattleAnimSpritePal_Rocks, ANIM_TAG_ROCKS}, From 216b7a4dfd4521104ca4f1a2a07bf58fd56539a7 Mon Sep 17 00:00:00 2001 From: CallmeEchoo Date: Thu, 20 Apr 2023 09:44:18 +0200 Subject: [PATCH 21/30] fix dire hit and paralyze heal --- src/item.c | 2 ++ src/item_use.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/item.c b/src/item.c index da57c40766..b2b19480a3 100644 --- a/src/item.c +++ b/src/item.c @@ -973,6 +973,8 @@ u32 GetItemStatus1Mask(u16 itemId) const u8 *effect = GetItemEffect(itemId); switch (effect[3]) { + case ITEM3_PARALYSIS: + return STATUS1_PARALYSIS; case ITEM3_FREEZE: return STATUS1_FREEZE; case ITEM3_BURN: diff --git a/src/item_use.c b/src/item_use.c index 8bcadfb2eb..3a838288b1 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -1154,7 +1154,7 @@ static bool32 CannotUseBagBattleItem(u16 itemId) } // Dire Hit if (battleUsage == EFFECT_ITEM_SET_FOCUS_ENERGY - && !(gBattleMons[gBattlerInMenuId].status2 & STATUS2_FOCUS_ENERGY)) + && (gBattleMons[gBattlerInMenuId].status2 & STATUS2_FOCUS_ENERGY)) { cannotUse++; } From 3aec63b8cfb23b0983b92ba03e89c31db84b20a1 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 20 Apr 2023 15:08:42 +0200 Subject: [PATCH 22/30] new define to restore items after battle --- include/battle.h | 4 ++-- include/battle_util.h | 2 +- include/config/battle.h | 1 + src/battle_main.c | 6 +++--- src/battle_script_commands.c | 14 +++++++------- src/battle_util.c | 18 ++++++++++-------- 6 files changed, 24 insertions(+), 21 deletions(-) diff --git a/include/battle.h b/include/battle.h index 46975bec3c..f86a5c975c 100644 --- a/include/battle.h +++ b/include/battle.h @@ -517,7 +517,7 @@ struct ZMoveData u8 splits[MAX_BATTLERS_COUNT]; }; -struct StolenItem +struct LostItem { u16 originalItem:15; u16 stolen:1; @@ -640,7 +640,7 @@ struct BattleStruct u16 moveEffect2; // For Knock Off u16 changedSpecies[PARTY_SIZE]; // For Zygarde or future forms when multiple mons can change into the same pokemon. u8 quickClawBattlerId; - struct StolenItem itemStolen[PARTY_SIZE]; // Player's team that had items stolen (two bytes per party member) + struct LostItem itemLost[PARTY_SIZE]; // Player's team that had items consumed or stolen (two bytes per party member) u8 blunderPolicy:1; // should blunder policy activate u8 swapDamageCategory:1; // Photon Geyser, Shell Side Arm, Light That Burns the Sky u8 forcedSwitch:4; // For each battler diff --git a/include/battle_util.h b/include/battle_util.h index 0661081e43..b83209a697 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -197,7 +197,7 @@ bool32 IsPartnerMonFromSameTrainer(u8 battlerId); u8 GetSplitBasedOnStats(u8 battlerId); void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast); bool32 TestSheerForceFlag(u8 battler, u16 move); -void TryRestoreStolenItems(void); +void TryRestoreHeldItems(void); bool32 CanStealItem(u8 battlerStealing, u8 battlerItem, u16 item); void TrySaveExchangedItem(u8 battlerId, u16 stolenItem); bool32 IsPartnerMonFromSameTrainer(u8 battlerId); diff --git a/include/config/battle.h b/include/config/battle.h index 3e9ec9b9a5..4bead3ae83 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -126,6 +126,7 @@ #define B_X_ITEMS_BUFF GEN_LATEST // In Gen7+, the X Items raise a stat by 2 stages instead of 1. #define B_MENTAL_HERB GEN_LATEST // In Gen5+, the Mental Herb cures Taunt, Encore, Torment, Heal Block, and Disable in addition to Infatuation from before. #define B_TRAINERS_KNOCK_OFF_ITEMS TRUE // If TRUE, trainers can steal/swap your items (non-berries are restored after battle). In vanilla games trainers cannot steal items. +#define B_RESTORE_HELD_BATTLE_ITEMS TRUE // In Gen9 all non berry items are restored after battle. #define B_SOUL_DEW_BOOST GEN_LATEST // In Gens3-6, Soul Dew boosts Lati@s' Sp. Atk and Sp. Def. In Gen7+ it boosts the power of their Psychic and Dragon type moves instead. #define B_NET_BALL_MODIFIER GEN_LATEST // In Gen7+, Net Ball's catch multiplier is x5 instead of x3. #define B_DIVE_BALL_MODIFIER GEN_LATEST // In Gen4+, Dive Ball's effectiveness increases by when Surfing or Fishing. diff --git a/src/battle_main.c b/src/battle_main.c index a5a9b5bbf6..01d79db3eb 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3189,7 +3189,7 @@ static void BattleStartClearSetData(void) { gBattleStruct->usedHeldItems[i][B_SIDE_PLAYER] = 0; gBattleStruct->usedHeldItems[i][B_SIDE_OPPONENT] = 0; - gBattleStruct->itemStolen[i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + gBattleStruct->itemLost[i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); gPartyCriticalHits[i] = 0; gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_PLAYER] = FALSE; gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_OPPONENT] = FALSE; @@ -5387,9 +5387,9 @@ static void HandleEndTurn_FinishBattle(void) TestRunner_Battle_AfterLastTurn(); BeginFastPaletteFade(3); FadeOutMapMusic(5); - #if B_TRAINERS_KNOCK_OFF_ITEMS == TRUE + #if B_TRAINERS_KNOCK_OFF_ITEMS == TRUE || B_RESTORE_HELD_BATTLE_ITEMS == TRUE if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - TryRestoreStolenItems(); + TryRestoreHeldItems(); #endif for (i = 0; i < PARTY_SIZE; i++) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 4e1494ce38..228cbb8120 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7892,7 +7892,7 @@ static void BestowItem(u32 battlerAtk, u32 battlerDef) // Called by Cmd_removeitem. itemId represents the item that was removed, not being given. static bool32 TrySymbiosis(u32 battler, u32 itemId) { - if (!gBattleStruct->itemStolen[gBattlerPartyIndexes[battler]].stolen + if (!gBattleStruct->itemLost[gBattlerPartyIndexes[battler]].stolen && gBattleStruct->changedItems[battler] == ITEM_NONE && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_EJECT_BUTTON && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_EJECT_PACK @@ -11264,7 +11264,7 @@ static void Cmd_various(void) // Open party menu, wait to go to next instruction. else - { + { BtlController_EmitChoosePokemon(BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gBattlerAttacker]); MarkBattlerForControllerExec(gBattlerAttacker); } @@ -16469,7 +16469,7 @@ void BS_ItemRestoreHP(void) { } if (hp + healAmount > maxHP) healAmount = maxHP - hp; - + // Heal is applied as move damage if battler is active. if (battlerId != MAX_BATTLERS_COUNT && hp != 0) { @@ -16494,10 +16494,10 @@ void BS_ItemRestoreHP(void) { void BS_ItemCureStatus(void) { NATIVE_ARGS(); struct Pokemon *party = (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty; - + // Heal Status1 conditions. HealStatusConditions(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], gBattleStruct->itemPartyIndex[gBattlerAttacker], GetItemStatus1Mask(gLastUsedItem), gBattlerAttacker); - + // Heal Status2 conditions if battler is active. if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker]) { @@ -16506,10 +16506,10 @@ void BS_ItemCureStatus(void) { else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)]) { - gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem); + gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem); gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker); } - + if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; diff --git a/src/battle_util.c b/src/battle_util.c index ac274bf0f8..e057b78dc3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10536,18 +10536,20 @@ void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast) } } -void TryRestoreStolenItems(void) +void TryRestoreHeldItems(void) { u32 i; - u16 stolenItem = ITEM_NONE; + u16 lostItem = ITEM_NONE; for (i = 0; i < PARTY_SIZE; i++) { - if (gBattleStruct->itemStolen[i].stolen) + #if B_RESTORE_HELD_BATTLE_ITEMS == FALSE + if (gBattleStruct->itemLost[i].stolen) + #endif { - stolenItem = gBattleStruct->itemStolen[i].originalItem; - if (stolenItem != ITEM_NONE && ItemId_GetPocket(stolenItem) != POCKET_BERRIES) - SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &stolenItem); // Restore stolen non-berry items + lostItem = gBattleStruct->itemLost[i].originalItem; + if (lostItem != ITEM_NONE && ItemId_GetPocket(lostItem) != POCKET_BERRIES) + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &lostItem); // Restore stolen non-berry items } } } @@ -10601,8 +10603,8 @@ void TrySaveExchangedItem(u8 battlerId, u16 stolenItem) if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && GetBattlerSide(battlerId) == B_SIDE_PLAYER - && stolenItem == gBattleStruct->itemStolen[gBattlerPartyIndexes[battlerId]].originalItem) - gBattleStruct->itemStolen[gBattlerPartyIndexes[battlerId]].stolen = TRUE; + && stolenItem == gBattleStruct->itemLost[gBattlerPartyIndexes[battlerId]].originalItem) + gBattleStruct->itemLost[gBattlerPartyIndexes[battlerId]].stolen = TRUE; #endif } From 6c7f5881e453631a1f336618b7e0120c33b7f140 Mon Sep 17 00:00:00 2001 From: citrusbolt <32605812+citrusbolt@users.noreply.github.com> Date: Thu, 20 Apr 2023 08:05:32 -0600 Subject: [PATCH 23/30] Add two EV-related configs (#2825) --- include/config/item.h | 13 +++++++------ include/config/pokemon.h | 1 + include/constants/pokemon.h | 4 ++++ src/pokemon.c | 12 ++++++++++-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/config/item.h b/include/config/item.h index f707b7a540..09008d0f24 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -2,12 +2,13 @@ #define GUARD_CONFIG_ITEM_H // Item config -#define I_SHINY_CHARM_REROLLS 3 // Amount of re-rolls if the player has the Shiny Charm. Set to 0 to disable Shiny Charm's effects. -#define I_KEY_FOSSILS GEN_LATEST // In Gen4+, all Gen 3 fossils became regular items. -#define I_KEY_ESCAPE_ROPE GEN_LATEST // In Gen8, Escape Rope became a Key Item. Keep in mind, this will make it free to buy in marts. -#define I_HEALTH_RECOVERY GEN_LATEST // In Gen7+, certain healing items recover a different amount of HP than they used to. -#define I_SITRUS_BERRY_HEAL GEN_LATEST // In Gen4+, Sitrus Berry was changed from healing 30 HP to healing 25% of Max HP. -#define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8, the Vitamins no longer have a cap of 100 EV per stat. +#define I_SHINY_CHARM_REROLLS 3 // Amount of re-rolls if the player has the Shiny Charm. Set to 0 to disable Shiny Charm's effects. +#define I_KEY_FOSSILS GEN_LATEST // In Gen4+, all Gen 3 fossils became regular items. +#define I_KEY_ESCAPE_ROPE GEN_LATEST // In Gen8, Escape Rope became a Key Item. Keep in mind, this will make it free to buy in marts. +#define I_HEALTH_RECOVERY GEN_LATEST // In Gen7+, certain healing items recover a different amount of HP than they used to. +#define I_SITRUS_BERRY_HEAL GEN_LATEST // In Gen4+, Sitrus Berry was changed from healing 30 HP to healing 25% of Max HP. +#define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8+, the Vitamins no longer have a cap of 100 EV per stat. +#define I_BERRY_EV_JUMP GEN_LATEST // In Gen4 only, EV-lowering Berries lower a stat's EV to 100 if it is above 100. // TM config #define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1. diff --git a/include/config/pokemon.h b/include/config/pokemon.h index ce5faf2a6e..1cde573c96 100644 --- a/include/config/pokemon.h +++ b/include/config/pokemon.h @@ -21,6 +21,7 @@ // Other settings #define P_LEGENDARY_PERFECT_IVS GEN_LATEST // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs. +#define P_EV_CAP GEN_LATEST // Since Gen 6, the max EVs per stat is 252 instead of 255. // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index cf6cc8751b..ddf879854e 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -201,7 +201,11 @@ #define MAX_PER_STAT_IVS 31 #define MAX_IV_MASK 31 #define USE_RANDOM_IVS (MAX_PER_STAT_IVS + 1) +#if P_EV_CAP >= GEN_6 +#define MAX_PER_STAT_EVS 252 +#else #define MAX_PER_STAT_EVS 255 +#endif #define MAX_TOTAL_EVS 510 #if I_VITAMIN_EV_CAP >= GEN_8 #define EV_ITEM_RAISE_LIMIT MAX_PER_STAT_EVS diff --git a/src/pokemon.c b/src/pokemon.c index 46eca90b29..e82cb98c30 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -5854,7 +5854,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if (itemEffect[10] & ITEM10_IS_VITAMIN) evCap = EV_ITEM_RAISE_LIMIT; else - evCap = 252; + evCap = MAX_PER_STAT_EVS; if (dataSigned >= evCap) break; @@ -5880,6 +5880,10 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov break; } dataSigned += evChange; + #if I_EV_LOWERING_BERRY_JUMP == GEN_4 + if (dataSigned > 100) + dataSigned = 100; + #endif if (dataSigned < 0) dataSigned = 0; } @@ -6030,7 +6034,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if (itemEffect[10] & ITEM10_IS_VITAMIN) evCap = EV_ITEM_RAISE_LIMIT; else - evCap = 252; + evCap = MAX_PER_STAT_EVS; if (dataSigned >= evCap) break; @@ -6056,6 +6060,10 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov break; } dataSigned += evChange; + #if I_BERRY_EV_JUMP == GEN_4 + if (dataSigned > 100) + dataSigned = 100; + #endif if (dataSigned < 0) dataSigned = 0; } From ae80d545c5b4f2f86baf702d4527d88c11b935b0 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 20 Apr 2023 16:12:11 +0200 Subject: [PATCH 24/30] Support for multi battles where Trainer has only one mon (#2670) --- src/battle_controller_opponent.c | 12 +++++++----- src/battle_interface.c | 5 +++++ src/battle_main.c | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index cb0499ac8f..4eda81b094 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -228,9 +228,11 @@ static void Intro_DelayAndEnd(void) } } -static bool32 TwoIntroMons(u32 battlerId) // Double battle with both player pokemon active. +static bool32 TwoIntroMons(u32 battlerId) // Double battle with both opponent pokemon active. { - return (IsDoubleBattle() && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]])); + return (IsDoubleBattle() + && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[battlerId]]) + && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]])); } static void Intro_WaitForShinyAnimAndHealthbox(void) @@ -1969,7 +1971,7 @@ static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite) static void Task_StartSendOutAnim(u8 taskId) { - u8 savedActiveBank = gActiveBattler; + u8 savedActiveBattler = gActiveBattler; gActiveBattler = gTasks[taskId].data[0]; if ((!TwoIntroMons(gActiveBattler) || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) && !BATTLE_TWO_VS_ONE_OPPONENT) @@ -1977,7 +1979,7 @@ static void Task_StartSendOutAnim(u8 taskId) gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; StartSendOutAnim(gActiveBattler, FALSE); } - else if ((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)) + else if ((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) || (BATTLE_TWO_VS_ONE_OPPONENT && !TwoIntroMons(gActiveBattler))) { gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; StartSendOutAnim(gActiveBattler, FALSE); @@ -1992,7 +1994,7 @@ static void Task_StartSendOutAnim(u8 taskId) gActiveBattler ^= BIT_FLANK; } gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; - gActiveBattler = savedActiveBank; + gActiveBattler = savedActiveBattler; DestroyTask(taskId); } diff --git a/src/battle_interface.c b/src/battle_interface.c index 7f7e1d20f0..bbe61a3727 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -690,12 +690,17 @@ static void InitLastUsedBallAssets(void) } // This function is here to cover a specific case - one player's mon in a 2 vs 1 double battle. In this scenario - display singles layout. +// The same goes for a 2 vs 1 where opponent has only one pokemon. u32 WhichBattleCoords(u32 battlerId) // 0 - singles, 1 - doubles { if (GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT && gPlayerPartyCount == 1 && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) return 0; + else if (GetBattlerPosition(battlerId) == B_POSITION_OPPONENT_LEFT + && gEnemyPartyCount == 1 + && !(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)) + return 0; else return IsDoubleBattle(); } diff --git a/src/battle_main.c b/src/battle_main.c index a5a9b5bbf6..2eecda65b2 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -594,6 +594,7 @@ static void CB2_InitBattleInternal(void) if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT) CreateNPCTrainerParty(&gEnemyParty[PARTY_SIZE / 2], gTrainerBattleOpponent_B, FALSE); SetWildMonHeldItem(); + CalculateEnemyPartyCount(); } gMain.inBattle = TRUE; From 4a08ede2c49ba55ac9d358d95ee240b238325192 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 21 Apr 2023 20:13:30 +0200 Subject: [PATCH 25/30] Add GetMovesArray in GetMovesArray --- src/battle_ai_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 05e7aec58f..53b5ebed6c 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -477,7 +477,7 @@ bool32 IsAiBattlerAware(u32 battlerId) { if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_OMNISCIENT) return TRUE; - + return BattlerHasAi(battlerId); } @@ -1129,7 +1129,7 @@ bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk) { s32 i, dmg; u32 unusable = AI_DATA->moveLimitations[battlerDef]; - u16 *moves = gBattleResources->battleHistory->usedMoves[battlerDef]; + u16 *moves = GetMovesArray(battlerDef); for (i = 0; i < MAX_MON_MOVES; i++) { From 30204e99533bf826486c3cd535a04a2c97dc5e09 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 21 Apr 2023 20:59:54 +0200 Subject: [PATCH 26/30] fix wrong z-move ususage --- src/battle_z_move.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 104a44daa5..f435253c7b 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -215,11 +215,7 @@ bool32 IsViableZMove(u8 battlerId, u16 move) if (move != MOVE_NONE && zMove != MOVE_Z_STATUS && gBattleMoves[move].type == ItemId_GetSecondaryId(item)) { - if (IS_MOVE_STATUS(move)) - gBattleStruct->zmove.chosenZMove = move; - else - gBattleStruct->zmove.chosenZMove = GetTypeBasedZMove(move, battlerId); - + gBattleStruct->zmove.chosenZMove = GetTypeBasedZMove(move, battlerId); return TRUE; } } From 330e85ba64b1b23d602a83ad3bef16f93a05b73c Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 24 Apr 2023 09:34:11 -0300 Subject: [PATCH 27/30] Updates -Undeclared size for certain trainer slide-in variables at struct BattleStruct for reasons. -Added a BattlerHPPercentage function to make HP threshold checks in ShouldDoTrainerSlide a bit more readable. --- include/battle.h | 10 +++++----- src/battle_message.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/include/battle.h b/include/battle.h index 44aa063c9c..2b72d48365 100644 --- a/include/battle.h +++ b/include/battle.h @@ -622,7 +622,7 @@ struct BattleStruct struct MegaEvolutionData mega; struct ZMoveData zmove; const u8 *trainerSlideMsg; - bool8 trainerSlideLowHpMsgDone:1; + bool8 trainerSlideLowHpMsgDone; u8 introState; u8 ateBerry[2]; // array id determined by side, each party pokemon as bit u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages @@ -663,14 +663,14 @@ struct BattleStruct u8 storedHealingWish:4; // Each battler as a bit. u8 storedLunarDance:4; // Each battler as a bit. u16 supremeOverlordModifier[MAX_BATTLERS_COUNT]; - bool8 trainerSlideHalfHpMsgDone:1; + bool8 trainerSlideHalfHpMsgDone; u8 trainerSlideFirstCriticalHitMsgState:2; u8 trainerSlideFirstSuperEffectiveHitMsgState:2; u8 trainerSlideFirstSTABMoveMsgState:2; u8 trainerSlidePlayerMonUnaffectedMsgState:2; - bool8 trainerSlideMegaEvolutionMsgDone:1; - bool8 trainerSlideZMoveMsgDone:1; - bool8 trainerSlideBeforeFirstTurnMsgDone:1; + bool8 trainerSlideMegaEvolutionMsgDone; + bool8 trainerSlideZMoveMsgDone; + bool8 trainerSlideBeforeFirstTurnMsgDone; }; #define F_DYNAMIC_TYPE_1 (1 << 6) diff --git a/src/battle_message.c b/src/battle_message.c index fab65a46b4..dd6390d282 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3934,6 +3934,37 @@ static u32 GetEnemyMonCount(u32 firstId, u32 lastId, bool32 onlyAlive) return count; } +enum +{ + LESS_THAN, + EQUAL, + GREATER_THAN, + LESS_THAN_OR_EQUAL, + GREATER_THAN_OR_EQUAL, + NOT_EQUAL, +}; + +u32 BattlerHPPercentage(u32 battlerId, u32 operation, u32 threshold) +{ + switch (operation) + { + case LESS_THAN: + return gBattleMons[battlerId].hp < (gBattleMons[battlerId].maxHP / threshold); + case EQUAL: + return gBattleMons[battlerId].hp == (gBattleMons[battlerId].maxHP / threshold); + case GREATER_THAN: + return gBattleMons[battlerId].hp > (gBattleMons[battlerId].maxHP / threshold); + case LESS_THAN_OR_EQUAL: + return gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / threshold); + case GREATER_THAN_OR_EQUAL: + return gBattleMons[battlerId].hp >= (gBattleMons[battlerId].maxHP / threshold); + case NOT_EQUAL: + return gBattleMons[battlerId].hp != (gBattleMons[battlerId].maxHP / threshold); + default: + break; + } +} + u32 ShouldDoTrainerSlide(u32 battlerId, u32 which) { u32 i, firstId, lastId, trainerId, retValue = 1; @@ -3979,7 +4010,7 @@ u32 ShouldDoTrainerSlide(u32 battlerId, u32 which) case TRAINER_SLIDE_LAST_LOW_HP: if (sTrainerSlides[i].msgLastLowHp != NULL && GetEnemyMonCount(firstId, lastId, TRUE) == 1 - && gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 4) + && BattlerHPPercentage(battlerId, GREATER_THAN_OR_EQUAL, 4) && !gBattleStruct->trainerSlideLowHpMsgDone) { gBattleStruct->trainerSlideLowHpMsgDone = TRUE; @@ -3997,7 +4028,7 @@ u32 ShouldDoTrainerSlide(u32 battlerId, u32 which) case TRAINER_SLIDE_LAST_HALF_HP: if (sTrainerSlides[i].msgLastHalfHp != NULL && GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE) - 1 - && (gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 2) && gBattleMons[battlerId].hp > (gBattleMons[battlerId].maxHP / 4)) + && BattlerHPPercentage(battlerId, LESS_THAN_OR_EQUAL, 2) && BattlerHPPercentage(battlerId, GREATER_THAN, 4) && !gBattleStruct->trainerSlideHalfHpMsgDone) { gBattleStruct->trainerSlideHalfHpMsgDone = TRUE; From 868838a87d8af109ee90835d6c33bd7d8928328c Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Mon, 24 Apr 2023 14:35:42 -0400 Subject: [PATCH 28/30] Add thunder cage case to trap anim IDs (#2941) --- data/battle_anim_scripts.s | 5 +++++ include/constants/battle_anim.h | 1 + include/constants/battle_string_ids.h | 24 +++++++++++--------- src/battle_anim_throw.c | 32 +++++++++++++++++++-------- src/battle_message.c | 3 +++ 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index cca8706cbc..adcb88c881 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -24463,6 +24463,7 @@ General_TurnTrap: jumpargeq 0, TRAP_ANIM_MAGMA_STORM, Status_MagmaStorm jumpargeq 0, TRAP_ANIM_INFESTATION, Status_Infestation jumpargeq 0, TRAP_ANIM_SNAP_TRAP, Status_Snap_Trap + jumpargeq 0, TRAP_ANIM_THUNDER_CAGE, Status_Thunder_Cage goto Status_BindWrap Status_BindWrap: loadspritegfx ANIM_TAG_TENDRILS @@ -24549,6 +24550,10 @@ Status_Clamp: waitforvisualfinish end +Status_Thunder_Cage: + @ TODO + goto Move_THUNDER_CAGE + Status_Snap_Trap: @ placeholder goto Move_BITE diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 4316191a2e..46e229a319 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -583,6 +583,7 @@ #define TRAP_ANIM_MAGMA_STORM 5 #define TRAP_ANIM_INFESTATION 6 #define TRAP_ANIM_SNAP_TRAP 7 +#define TRAP_ANIM_THUNDER_CAGE 8 // Weather defines for battle animation scripts. #define ANIM_WEATHER_NONE 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index e552077534..f4fd589db1 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -651,8 +651,9 @@ #define STRINGID_ITEMRESTOREDSPECIESHEALTH 649 #define STRINGID_ITEMCUREDSPECIESSTATUS 650 #define STRINGID_ITEMRESTOREDSPECIESPP 651 +#define STRINGID_THUNDERCAGETRAPPED 652 -#define BATTLESTRINGS_COUNT 652 +#define BATTLESTRINGS_COUNT 653 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, @@ -917,16 +918,17 @@ #define B_MSG_TERRAINENDS_COUNT 4 // gWrappedStringIds -#define B_MSG_WRAPPED_BIND 0 -#define B_MSG_WRAPPED_WRAP 1 -#define B_MSG_WRAPPED_FIRE_SPIN 2 -#define B_MSG_WRAPPED_CLAMP 3 -#define B_MSG_WRAPPED_WHIRLPOOL 4 -#define B_MSG_WRAPPED_SAND_TOMB 5 -#define B_MSG_WRAPPED_MAGMA_STORM 6 -#define B_MSG_WRAPPED_INFESTATION 7 -#define B_MSG_WRAPPED_SNAP_TRAP 8 -#define NUM_TRAPPING_MOVES 9 +#define B_MSG_WRAPPED_BIND 0 +#define B_MSG_WRAPPED_WRAP 1 +#define B_MSG_WRAPPED_FIRE_SPIN 2 +#define B_MSG_WRAPPED_CLAMP 3 +#define B_MSG_WRAPPED_WHIRLPOOL 4 +#define B_MSG_WRAPPED_SAND_TOMB 5 +#define B_MSG_WRAPPED_MAGMA_STORM 6 +#define B_MSG_WRAPPED_INFESTATION 7 +#define B_MSG_WRAPPED_SNAP_TRAP 8 +#define B_MSG_WRAPPED_THUNDER_CAGE 9 +#define NUM_TRAPPING_MOVES 10 // z effects #define B_MSG_Z_RESET_STATS 0 diff --git a/src/battle_anim_throw.c b/src/battle_anim_throw.c index a3197d4477..3fc2000e4a 100755 --- a/src/battle_anim_throw.c +++ b/src/battle_anim_throw.c @@ -2736,23 +2736,37 @@ void AnimTask_SetAttackerTargetLeftPos(u8 taskId) void AnimTask_GetTrappedMoveAnimId(u8 taskId) { - if (gBattleSpritesDataPtr->animationData->animArg == MOVE_FIRE_SPIN) + switch (gBattleSpritesDataPtr->animationData->animArg) + { + case MOVE_FIRE_SPIN: gBattleAnimArgs[0] = TRAP_ANIM_FIRE_SPIN; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_WHIRLPOOL) + break; + case MOVE_WHIRLPOOL: gBattleAnimArgs[0] = TRAP_ANIM_WHIRLPOOL; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_CLAMP) + break; + case MOVE_CLAMP: gBattleAnimArgs[0] = TRAP_ANIM_CLAMP; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_SAND_TOMB) + break; + case MOVE_SAND_TOMB: gBattleAnimArgs[0] = TRAP_ANIM_SAND_TOMB; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_MAGMA_STORM) + break; + case MOVE_MAGMA_STORM: gBattleAnimArgs[0] = TRAP_ANIM_MAGMA_STORM; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_INFESTATION) + break; + case MOVE_INFESTATION: gBattleAnimArgs[0] = TRAP_ANIM_INFESTATION; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_SNAP_TRAP) + break; + case MOVE_SNAP_TRAP: gBattleAnimArgs[0] = TRAP_ANIM_SNAP_TRAP; - else + break; + case MOVE_THUNDER_CAGE: + gBattleAnimArgs[0] = TRAP_ANIM_THUNDER_CAGE; + break; + default: gBattleAnimArgs[0] = TRAP_ANIM_BIND; - + break; + } + DestroyAnimVisualTask(taskId); } diff --git a/src/battle_message.c b/src/battle_message.c index e1122c7aac..21f7098f81 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -786,9 +786,11 @@ static const u8 sText_PkmnRevivedReadyToFight[] = _("{B_BUFF1} was revived and\n static const u8 sText_ItemRestoredSpeciesHealth[] = _("{B_BUFF1} had its\nHP restored!"); static const u8 sText_ItemCuredSpeciesStatus[] = _("{B_BUFF1} had\nits status healed!"); static const u8 sText_ItemRestoredSpeciesPP[] = _("{B_BUFF1} had its\nPP restored!"); +static const u8 sText_AtkTrappedDef[] = _("{B_ATK_NAME_WITH_PREFIX} trapped\nthe {B_DEF_NAME_WITH_PREFIX}!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_THUNDERCAGETRAPPED - BATTLESTRINGS_TABLE_START] = sText_AtkTrappedDef, [STRINGID_ITEMRESTOREDSPECIESHEALTH - BATTLESTRINGS_TABLE_START] = sText_ItemRestoredSpeciesHealth, [STRINGID_ITEMCUREDSPECIESSTATUS - BATTLESTRINGS_TABLE_START] = sText_ItemCuredSpeciesStatus, [STRINGID_ITEMRESTOREDSPECIESPP - BATTLESTRINGS_TABLE_START] = sText_ItemRestoredSpeciesPP, @@ -1679,6 +1681,7 @@ const u16 gWrappedStringIds[NUM_TRAPPING_MOVES] = [B_MSG_WRAPPED_MAGMA_STORM] = STRINGID_TRAPPEDBYSWIRLINGMAGMA, // MOVE_MAGMA_STORM [B_MSG_WRAPPED_INFESTATION] = STRINGID_INFESTATION, // MOVE_INFESTATION [B_MSG_WRAPPED_SNAP_TRAP] = STRINGID_PKMNINSNAPTRAP, // MOVE_SNAP_TRAP + [B_MSG_WRAPPED_THUNDER_CAGE]= STRINGID_THUNDERCAGETRAPPED, // MOVE_THUNDER_CAGE }; const u16 gMistUsedStringIds[] = From 9562c7a37a000b4cfa34650ad717e300f7234c9e Mon Sep 17 00:00:00 2001 From: Frank DeBlasio <35279583+fdeblasio@users.noreply.github.com> Date: Mon, 24 Apr 2023 18:49:53 -0400 Subject: [PATCH 29/30] Added forbidden Metronome moves from PLA and SV (#2949) --- src/battle_script_commands.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 07669635e3..3632095963 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -979,6 +979,7 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_STRUGGLE] = 0xFF, // Neither Struggle [MOVE_AFTER_YOU] = FORBIDDEN_METRONOME, [MOVE_APPLE_ACID] = FORBIDDEN_METRONOME, + [MOVE_ARMOR_CANNON] = FORBIDDEN_METRONOME, [MOVE_ARM_THRUST] = FORBIDDEN_PARENTAL_BOND, [MOVE_ASSIST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_ASTRAL_BARRAGE] = FORBIDDEN_METRONOME, @@ -994,6 +995,7 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_BESTOW] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BIDE] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, // Note: Bide should work with Parental Bond. This will be addressed in future. [MOVE_BLAST_BURN] = FORBIDDEN_INSTRUCT, + [MOVE_BLAZING_TORQUE] = FORBIDDEN_MIMIC | FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_BODY_PRESS] = FORBIDDEN_METRONOME, [MOVE_BONE_RUSH] = FORBIDDEN_PARENTAL_BOND, [MOVE_BONEMERANG] = FORBIDDEN_PARENTAL_BOND, @@ -1005,9 +1007,14 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_BUZZY_BUZZ] = FORBIDDEN_METRONOME, [MOVE_CELEBRATE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_CHATTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, + [MOVE_CHILLING_WATER] = FORBIDDEN_METRONOME, + [MOVE_CHILLY_RECEPTION] = FORBIDDEN_METRONOME, [MOVE_CIRCLE_THROW] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_CLANGOROUS_SOUL] = FORBIDDEN_METRONOME, + [MOVE_COLLISION_COURSE] = FORBIDDEN_METRONOME, + [MOVE_COMBAT_TORQUE] = FORBIDDEN_MIMIC | FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_COMET_PUNCH] = FORBIDDEN_PARENTAL_BOND, + [MOVE_COMEUPPANCE] = FORBIDDEN_METRONOME, [MOVE_COPYCAT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_COUNTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_COVET] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, @@ -1018,9 +1025,11 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_DIAMOND_STORM] = FORBIDDEN_METRONOME, [MOVE_DIG] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_DIVE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, + [MOVE_DOODLE] = FORBIDDEN_METRONOME, [MOVE_DOUBLE_IRON_BASH] = FORBIDDEN_METRONOME | FORBIDDEN_PARENTAL_BOND, [MOVE_DOUBLE_HIT] = FORBIDDEN_PARENTAL_BOND, [MOVE_DOUBLE_KICK] = FORBIDDEN_PARENTAL_BOND, + [MOVE_DOUBLE_SHOCK] = FORBIDDEN_METRONOME, [MOVE_DOUBLE_SLAP] = FORBIDDEN_PARENTAL_BOND, [MOVE_DRAGON_ASCENT] = FORBIDDEN_METRONOME, [MOVE_DRAGON_ENERGY] = FORBIDDEN_METRONOME, @@ -1030,6 +1039,7 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_DUAL_CHOP] = FORBIDDEN_PARENTAL_BOND, [MOVE_DUAL_WINGBEAT] = FORBIDDEN_PARENTAL_BOND, [MOVE_DYNAMAX_CANNON] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, + [MOVE_ELECTRO_DRIFT] = FORBIDDEN_METRONOME, [MOVE_ENDEAVOR] = FORBIDDEN_PARENTAL_BOND, [MOVE_ENDURE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ETERNABEAM] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT, @@ -1037,6 +1047,7 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_FALSE_SURRENDER] = FORBIDDEN_METRONOME, [MOVE_FEINT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_FIERY_WRATH] = FORBIDDEN_METRONOME, + [MOVE_FILLET_AWAY] = FORBIDDEN_METRONOME, [MOVE_FINAL_GAMBIT] = FORBIDDEN_PARENTAL_BOND, [MOVE_FISSURE] = FORBIDDEN_PARENTAL_BOND, [MOVE_FLEUR_CANNON] = FORBIDDEN_METRONOME, @@ -1062,16 +1073,20 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_HORN_DRILL] = FORBIDDEN_PARENTAL_BOND, [MOVE_HYDRO_CANNON] = FORBIDDEN_INSTRUCT, [MOVE_HYPER_BEAM] = FORBIDDEN_INSTRUCT, + [MOVE_HYPER_DRILL] = FORBIDDEN_METRONOME, [MOVE_HYPERSPACE_FURY] = FORBIDDEN_METRONOME, [MOVE_HYPERSPACE_HOLE] = FORBIDDEN_METRONOME, [MOVE_ICE_BALL] = FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_ICE_BURN] = FORBIDDEN_METRONOME | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_ICICLE_SPEAR] = FORBIDDEN_PARENTAL_BOND, [MOVE_INSTRUCT] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT, + [MOVE_JET_PUNCH] = FORBIDDEN_METRONOME, [MOVE_JUNGLE_HEALING] = FORBIDDEN_METRONOME, [MOVE_KINGS_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_INSTRUCT, [MOVE_LIFE_DEW] = FORBIDDEN_METRONOME, [MOVE_LIGHT_OF_RUIN] = FORBIDDEN_METRONOME, + [MOVE_MAKE_IT_RAIN] = FORBIDDEN_METRONOME, + [MOVE_MAGICAL_TORQUE] = FORBIDDEN_MIMIC | FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_MAT_BLOCK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ME_FIRST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_METEOR_ASSAULT] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT, @@ -1085,32 +1100,47 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_MOONGEIST_BEAM] = FORBIDDEN_METRONOME, [MOVE_NATURE_POWER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_NATURES_MADNESS] = FORBIDDEN_METRONOME, + [MOVE_NOXIOUS_TORQUE] = FORBIDDEN_MIMIC | FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_OBSTRUCT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_INSTRUCT, + [MOVE_ORDER_UP] = FORBIDDEN_METRONOME, [MOVE_ORIGIN_PULSE] = FORBIDDEN_METRONOME, [MOVE_OUTRAGE] = FORBIDDEN_INSTRUCT, [MOVE_OVERDRIVE] = FORBIDDEN_METRONOME, [MOVE_PHANTOM_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_PHOTON_GEYSER] = FORBIDDEN_METRONOME, + [MOVE_PLASMA_FISTS] = FORBIDDEN_METRONOME, + [MOVE_POPULATION_BOMB] = FORBIDDEN_METRONOME, + [MOVE_POUNCE] = FORBIDDEN_METRONOME, + [MOVE_POWER_SHIFT] = FORBIDDEN_METRONOME, + [MOVE_PRECIPICE_BLADES] = FORBIDDEN_METRONOME, [MOVE_PRISMATIC_LASER] = FORBIDDEN_INSTRUCT, [MOVE_PROTECT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_PYRO_BALL] = FORBIDDEN_METRONOME, [MOVE_QUASH] = FORBIDDEN_METRONOME, [MOVE_QUICK_GUARD] = FORBIDDEN_METRONOME, + [MOVE_RAGE_FIST] = FORBIDDEN_METRONOME, [MOVE_RAGE_POWDER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_RAGING_BULL] = FORBIDDEN_METRONOME, + [MOVE_RAGING_FURY] = FORBIDDEN_METRONOME, [MOVE_RAZOR_WIND] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_RELIC_SONG] = FORBIDDEN_METRONOME, + [MOVE_REVIVAL_BLESSING] = FORBIDDEN_METRONOME, [MOVE_ROAR] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ROAR_OF_TIME] = FORBIDDEN_INSTRUCT, [MOVE_ROCK_BLAST] = FORBIDDEN_PARENTAL_BOND, [MOVE_ROCK_WRECKER] = FORBIDDEN_INSTRUCT, [MOVE_ROLLOUT] = FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, + [MOVE_RUINATION] = FORBIDDEN_METRONOME, [MOVE_SAPPY_SEED] = FORBIDDEN_METRONOME, + [MOVE_SALT_CURE] = FORBIDDEN_METRONOME, [MOVE_SCALE_SHOT] = FORBIDDEN_PARENTAL_BOND, [MOVE_SECRET_SWORD] = FORBIDDEN_METRONOME, [MOVE_SELF_DESTRUCT] = FORBIDDEN_PARENTAL_BOND, [MOVE_SHADOW_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, + [MOVE_SHED_TAIL] = FORBIDDEN_METRONOME, [MOVE_SHEER_COLD] = FORBIDDEN_PARENTAL_BOND, [MOVE_SHELL_TRAP] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, + [MOVE_SILK_TRAP] = FORBIDDEN_METRONOME, [MOVE_SIZZLY_SLIDE] = FORBIDDEN_METRONOME, [MOVE_SKETCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SKULL_BASH] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, @@ -1121,10 +1151,12 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_SNARL] = FORBIDDEN_METRONOME, [MOVE_SNATCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_INSTRUCT, [MOVE_SNORE] = FORBIDDEN_METRONOME, + [MOVE_SNOWSCAPE] = FORBIDDEN_METRONOME, [MOVE_SOLAR_BEAM] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_SOLAR_BLADE] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_SPARKLY_SWIRL] = FORBIDDEN_METRONOME, [MOVE_SPECTRAL_THIEF] = FORBIDDEN_METRONOME, + [MOVE_SPICY_EXTRACT] = FORBIDDEN_METRONOME, [MOVE_SPIKE_CANNON] = FORBIDDEN_PARENTAL_BOND, [MOVE_SPIKY_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_SPIRIT_BREAK] = FORBIDDEN_METRONOME, @@ -1144,17 +1176,21 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_THRASH] = FORBIDDEN_INSTRUCT, [MOVE_THUNDER_CAGE] = FORBIDDEN_METRONOME, [MOVE_THUNDEROUS_KICK] = FORBIDDEN_METRONOME, + [MOVE_TIDY_UP] = FORBIDDEN_METRONOME, + [MOVE_TRAILBLAZE] = FORBIDDEN_METRONOME, [MOVE_TRANSFORM] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_INSTRUCT, [MOVE_TRICK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_TRIPLE_AXEL] = FORBIDDEN_PARENTAL_BOND, [MOVE_TRIPLE_KICK] = FORBIDDEN_PARENTAL_BOND, [MOVE_TWINEEDLE] = FORBIDDEN_PARENTAL_BOND, + [MOVE_TWIN_BEAM] = FORBIDDEN_METRONOME, [MOVE_UPROAR] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, [MOVE_V_CREATE] = FORBIDDEN_METRONOME, [MOVE_VEEVEE_VOLLEY] = FORBIDDEN_METRONOME, [MOVE_WATER_SHURIKEN] = FORBIDDEN_PARENTAL_BOND, [MOVE_WHIRLWIND] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_WICKED_BLOW] = FORBIDDEN_METRONOME, + [MOVE_WICKED_TORQUE] = FORBIDDEN_MIMIC | FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_WIDE_GUARD] = FORBIDDEN_METRONOME, [MOVE_ZIPPY_ZAP] = FORBIDDEN_METRONOME, }; From 78c4d07b234c026304898bdc2b2fe8edc77a8402 Mon Sep 17 00:00:00 2001 From: Salem <65783283+CallmeEchoo@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:03:57 +0200 Subject: [PATCH 30/30] Add Berserk Gene Item (#2893) Co-authored-by: Eduardo Quezada D'Ottone --- data/battle_scripts_1.s | 27 +++ graphics/items/icon_palettes/berserk_gene.pal | 19 ++ graphics/items/icons/berserk_gene.png | Bin 0 -> 356 bytes include/battle_scripts.h | 1 + include/battle_util.h | 1 + include/constants/battle.h | 1 + include/constants/hold_effects.h | 3 + include/constants/items.h | 3 +- include/graphics.h | 2 + src/battle_main.c | 2 +- src/battle_script_commands.c | 2 + src/battle_util.c | 79 +++++++- src/data/graphics/items.h | 3 + src/data/item_icon_table.h | 1 + src/data/items.h | 13 ++ src/data/text/item_descriptions.h | 5 + test/hold_effect_berserk_gene.c | 187 ++++++++++++++++++ 17 files changed, 340 insertions(+), 9 deletions(-) create mode 100644 graphics/items/icon_palettes/berserk_gene.pal create mode 100644 graphics/items/icons/berserk_gene.png create mode 100644 test/hold_effect_berserk_gene.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 4a5af83a2d..dcb076c278 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -10395,3 +10395,30 @@ BattleScript_CouldntFullyProtect:: printstring STRINGID_COULDNTFULLYPROTECT waitmessage B_WAIT_TIME_LONG return + +BattleScript_BerserkGeneRet:: +BattleScript_BerserkGeneRet_Anim: + statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_BerserkGeneRet_TryConfuse + setgraphicalstatchangevalues + playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, sB_ANIM_ARG1 + setbyte cMULTISTRING_CHOOSER, B_MSG_STAT_ROSE_ITEM + call BattleScript_StatUp +BattleScript_BerserkGeneRet_TryConfuse: + jumpifability BS_SCRIPTING, ABILITY_OWN_TEMPO, BattleScript_BerserkGeneRet_OwnTempoPrevents + jumpifsafeguard BattleScript_BerserkGeneRet_SafeguardProtected + setmoveeffect MOVE_EFFECT_CONFUSION + seteffectprimary + goto BattleScript_BerserkGeneRet_End +BattleScript_BerserkGeneRet_SafeguardProtected:: + pause B_WAIT_TIME_SHORT + printstring STRINGID_PKMNUSEDSAFEGUARD + waitmessage B_WAIT_TIME_LONG + goto BattleScript_BerserkGeneRet_End +BattleScript_BerserkGeneRet_OwnTempoPrevents: + pause B_WAIT_TIME_SHORT + call BattleScript_AbilityPopUp + printstring STRINGID_PKMNPREVENTSCONFUSIONWITH + waitmessage B_WAIT_TIME_LONG +BattleScript_BerserkGeneRet_End: + removeitem BS_SCRIPTING + end3 diff --git a/graphics/items/icon_palettes/berserk_gene.pal b/graphics/items/icon_palettes/berserk_gene.pal new file mode 100644 index 0000000000..3ac8981aa0 --- /dev/null +++ b/graphics/items/icon_palettes/berserk_gene.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +212 146 75 +49 49 49 +131 123 131 +98 90 98 +74 65 74 +164 90 222 +230 180 255 +255 230 238 +255 230 106 +255 189 74 +255 171 32 +238 148 0 +255 246 189 +123 82 32 +0 0 0 +0 0 0 diff --git a/graphics/items/icons/berserk_gene.png b/graphics/items/icons/berserk_gene.png new file mode 100644 index 0000000000000000000000000000000000000000..faac0f67690b8861aa2794e781924c47b26ada27 GIT binary patch literal 356 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;w_7YEDSN7*DZ2W5c{>}^efI{LW zt`Q}{`DrEPiAAXl?mjL+V-(6#ixiCYObT0QTLv0`TzgfyZ_I!{_pkrzgpql z6o&ub_ErZe0CfOCK(E1XAjO#E?e6k_Df_3RKu(9Ji(^Q|oaBUr1OXOCMm7V15GF=f zgZ_&gX9A5_ienDsh`MvIGbzjoNM6vgDO15kZS9^tdvuNpCP_sc6G+;|azl<&BmLUE zyVYfH8;Z)_S{A2W=Sh*YNdNxwvd0|T-4EwTY8Y|Y_BimJFmW_+7tk>lJX9#Sr~3Ol nS3#zAX(f!OXC!=NQd+^_oM!J?|9kIKkV8FP{an^LB{Ts5%RhFk literal 0 HcmV?d00001 diff --git a/include/battle_scripts.h b/include/battle_scripts.h index c78fcafe48..876e2d343a 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -461,6 +461,7 @@ extern const u8 BattleScript_CouldntFullyProtect[]; extern const u8 BattleScript_MoveEffectStockpileWoreOff[]; extern const u8 BattleScript_StealthRockActivates[]; extern const u8 BattleScript_SpikesActivates[]; +extern const u8 BattleScript_BerserkGeneRet[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; diff --git a/include/battle_util.h b/include/battle_util.h index b83209a697..3a28f9b3d8 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -234,5 +234,6 @@ u32 GetBattlerFriendshipScore(u8 battlerId); u32 CountBattlerStatIncreases(u8 battlerId, bool32 countEvasionAcc); bool32 IsMyceliumMightOnField(void); bool8 ChangeTypeBasedOnTerrain(u8 battlerId); +void RemoveConfusionStatus(u8 battlerId); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/constants/battle.h b/include/constants/battle.h index 61c3776c6c..f0130e58f2 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -185,6 +185,7 @@ #define STATUS4_PLASMA_FISTS (1 << 1) #define STATUS4_MUD_SPORT (1 << 2) // Only used if B_SPORT_TURNS < GEN_6 #define STATUS4_WATER_SPORT (1 << 3) // Only used if B_SPORT_TURNS < GEN_6 +#define STATUS4_INFINITE_CONFUSION (1 << 4) // Used for Berserk Gene #define HITMARKER_WAKE_UP_CLEAR (1 << 4) // Cleared when waking up. Never set or checked. #define HITMARKER_SKIP_DMG_TRACK (1 << 5) diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index 5fc268cb05..9f877cffa8 100644 --- a/include/constants/hold_effects.h +++ b/include/constants/hold_effects.h @@ -161,6 +161,9 @@ #define HOLD_EFFECT_LOADED_DICE 180 #define HOLD_EFFECT_BOOSTER_ENERGY 181 // Not implemented. +// Gen2 hold effect +#define HOLD_EFFECT_BERSERK_GENE 182 + #define HOLD_EFFECT_CHOICE(holdEffect)((holdEffect == HOLD_EFFECT_CHOICE_BAND || holdEffect == HOLD_EFFECT_CHOICE_SCARF || holdEffect == HOLD_EFFECT_CHOICE_SPECS)) // Terrain seed params diff --git a/include/constants/items.h b/include/constants/items.h index 4421181668..57ed63feb4 100644 --- a/include/constants/items.h +++ b/include/constants/items.h @@ -972,8 +972,9 @@ #define ITEM_BLACK_AUGURITE 795 #define ITEM_LINKING_CORD 796 #define ITEM_PEAT_BLOCK 797 +#define ITEM_BERSERK_GENE 798 -#define ITEMS_COUNT 798 +#define ITEMS_COUNT 799 #define ITEM_FIELD_ARROW ITEMS_COUNT // A special item id associated with "Cancel"/"Exit" etc. in a list of items or decorations diff --git a/include/graphics.h b/include/graphics.h index 76f6e5d7cf..ad23dc67c8 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -8878,6 +8878,8 @@ extern const u32 gItemIcon_GriseousCore[]; extern const u32 gItemIconPalette_GriseousCore[]; extern const u32 gItemIcon_LustrousGlobe[]; extern const u32 gItemIconPalette_LustrousGlobe[]; +extern const u32 gItemIcon_BerserkGene[]; +extern const u32 gItemIconPalette_BerserkGene[]; extern const u32 gItemIcon_ReturnToFieldArrow[]; extern const u32 gItemIconPalette_ReturnToFieldArrow[]; diff --git a/src/battle_main.c b/src/battle_main.c index c43a2dc3b9..dec2100961 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3227,7 +3227,7 @@ void SwitchInClearSetData(void) gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_GASTRO_ACID | STATUS3_EMBARGO | STATUS3_TELEKINESIS | STATUS3_MAGNET_RISE | STATUS3_HEAL_BLOCK | STATUS3_AQUA_RING | STATUS3_POWER_TRICK); - gStatuses4[gActiveBattler] &= (STATUS4_MUD_SPORT | STATUS4_WATER_SPORT); + gStatuses4[gActiveBattler] &= (STATUS4_MUD_SPORT | STATUS4_WATER_SPORT | STATUS4_INFINITE_CONFUSION); for (i = 0; i < gBattlersCount; i++) { if (GetBattlerSide(gActiveBattler) != GetBattlerSide(i) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 3632095963..7195892ffc 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -16583,6 +16583,8 @@ void BS_ItemCureStatus(void) { if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; + if (GetItemStatus2Mask(gLastUsedItem) & STATUS2_CONFUSION) + gStatuses4[gBattlerAttacker] &= ~STATUS4_INFINITE_CONFUSION; PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES)); gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/battle_util.c b/src/battle_util.c index cbe7629ee2..f6a9c642bf 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -64,6 +64,7 @@ static void SetRandomMultiHitCounter(); static u32 GetBattlerItemHoldEffectParam(u8 battlerId, u16 item); static u16 GetInverseTypeMultiplier(u16 multiplier); static u16 GetSupremeOverlordModifier(u8 battlerId); +static bool8 CanBeInfinitelyConfused(u8 battlerId); extern const u8 *const gBattleScriptsForMoveEffects[]; extern const u8 *const gBattlescriptsForRunningByItem[]; @@ -3526,7 +3527,8 @@ u8 AtkCanceller_UnableToUseMove(void) case CANCELLER_CONFUSED: // confusion if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) { - gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1); + if (!(gStatuses4[gBattlerAttacker] & STATUS4_INFINITE_CONFUSION)) + gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1); if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) { // confusion dmg @@ -5968,7 +5970,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus; break; case 2: // get rid of confusion - gBattleMons[battler].status2 &= ~STATUS2_CONFUSION; + RemoveConfusionStatus(battler); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus; break; @@ -6906,7 +6908,7 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect) case HOLD_EFFECT_CURE_CONFUSION: if (gBattleMons[battlerId].status2 & STATUS2_CONFUSION && !UnnerveOn(battlerId, gLastUsedItem)) { - gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION; + RemoveConfusionStatus(battlerId); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet; effect = ITEM_EFFECT_OTHER; @@ -6947,7 +6949,7 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect) StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); gBattleMons[battlerId].status1 = 0; - gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION; + RemoveConfusionStatus(battlerId); BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_CURED_PROBLEM; gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; @@ -6985,6 +6987,21 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect) effect = ITEM_EFFECT_OTHER; } break; + case HOLD_EFFECT_BERSERK_GENE: + BufferStatChange(battlerId, STAT_ATK, STRINGID_STATROSE); + gEffectBattler = battlerId; + if (CanBeInfinitelyConfused(gEffectBattler)) + { + gStatuses4[gEffectBattler] |= STATUS4_INFINITE_CONFUSION; + } + SET_STATCHANGER(STAT_ATK, 2, FALSE); + + gBattleScripting.animArg1 = 14 + STAT_ATK; + gBattleScripting.animArg2 = 0; + + BattleScriptPushCursorAndCallback(BattleScript_BerserkGeneRet); + effect = ITEM_STATS_CHANGE; + break; } return effect; @@ -7163,7 +7180,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) else gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_NORMALIZED_STATUS; gBattleMons[battlerId].status1 = 0; - gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION; + RemoveConfusionStatus(battlerId); BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); effect = ITEM_STATUS_CHANGE; } @@ -7224,6 +7241,21 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) } } break; + case HOLD_EFFECT_BERSERK_GENE: + BufferStatChange(battlerId, STAT_ATK, STRINGID_STATROSE); + gEffectBattler = battlerId; + if (CanBeInfinitelyConfused(gEffectBattler)) + { + gStatuses4[gEffectBattler] |= STATUS4_INFINITE_CONFUSION; + } + SET_STATCHANGER(STAT_ATK, 2, FALSE); + + gBattleScripting.animArg1 = 14 + STAT_ATK; + gBattleScripting.animArg2 = 0; + + BattleScriptPushCursorAndCallback(BattleScript_BerserkGeneRet); + effect = ITEM_STATS_CHANGE; + break; } if (effect != 0) { @@ -7444,7 +7476,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) case HOLD_EFFECT_CURE_CONFUSION: if (gBattleMons[battlerId].status2 & STATUS2_CONFUSION && !UnnerveOn(battlerId, gLastUsedItem)) { - gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION; + RemoveConfusionStatus(battlerId); BattleScriptExecute(BattleScript_BerryCureConfusionEnd2); effect = ITEM_EFFECT_OTHER; } @@ -7489,7 +7521,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) else gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_NORMALIZED_STATUS; gBattleMons[battlerId].status1 = 0; - gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION; + RemoveConfusionStatus(battlerId); BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); effect = ITEM_STATUS_CHANGE; } @@ -7507,6 +7539,21 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) if (!moveTurn) effect = TrySetMicleBerry(battlerId, gLastUsedItem, TRUE); break; + case HOLD_EFFECT_BERSERK_GENE: + BufferStatChange(battlerId, STAT_ATK, STRINGID_STATROSE); + gEffectBattler = battlerId; + if (CanBeInfinitelyConfused(gEffectBattler)) + { + gStatuses4[gEffectBattler] |= STATUS4_INFINITE_CONFUSION; + } + SET_STATCHANGER(STAT_ATK, 2, FALSE); + + gBattleScripting.animArg1 = 14 + STAT_ATK; + gBattleScripting.animArg2 = 0; + + BattleScriptPushCursorAndCallback(BattleScript_BerserkGeneRet); + effect = ITEM_STATS_CHANGE; + break; } if (effect != 0) @@ -10870,3 +10917,21 @@ static void SetRandomMultiHitCounter() gMultiHitCounter = 5 - (Random() & 1); } } + +void RemoveConfusionStatus(u8 battlerId) +{ + gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION; + gStatuses4[battlerId] &= ~STATUS4_INFINITE_CONFUSION; +} + +static bool8 CanBeInfinitelyConfused(u8 battlerId) +{ + if (gBattleMons[battlerId].ability == ABILITY_OWN_TEMPO + || IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN) + || gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_SAFEGUARD) + { + return FALSE; + } + return TRUE; +} + diff --git a/src/data/graphics/items.h b/src/data/graphics/items.h index 1e60357b3e..9ef79b2c92 100644 --- a/src/data/graphics/items.h +++ b/src/data/graphics/items.h @@ -1998,3 +1998,6 @@ const u32 gItemIconPalette_GriseousCore[] = INCBIN_U32("graphics/items/icon_pale const u32 gItemIcon_LustrousGlobe[] = INCBIN_U32("graphics/items/icons/lustrous_globe.4bpp.lz"); const u32 gItemIconPalette_LustrousGlobe[] = INCBIN_U32("graphics/items/icon_palettes/lustrous_globe.gbapal.lz"); + +const u32 gItemIcon_BerserkGene[] = INCBIN_U32("graphics/items/icons/berserk_gene.4bpp.lz"); +const u32 gItemIconPalette_BerserkGene[] = INCBIN_U32("graphics/items/icon_palettes/berserk_gene.gbapal.lz"); diff --git a/src/data/item_icon_table.h b/src/data/item_icon_table.h index f220bd819c..05a8782812 100644 --- a/src/data/item_icon_table.h +++ b/src/data/item_icon_table.h @@ -843,6 +843,7 @@ const u32 *const gItemIconTable[ITEMS_COUNT + 1][2] = [ITEM_BLACK_AUGURITE] = {gItemIcon_BlackAugurite, gItemIconPalette_BlackAugurite}, [ITEM_LINKING_CORD] = {gItemIcon_LinkingCord, gItemIconPalette_LinkingCord}, [ITEM_PEAT_BLOCK] = {gItemIcon_PeatBlock, gItemIconPalette_PeatBlock}, + [ITEM_BERSERK_GENE] = {gItemIcon_BerserkGene, gItemIconPalette_BerserkGene}, // Return to field arrow [ITEMS_COUNT] = {gItemIcon_ReturnToFieldArrow, gItemIconPalette_ReturnToFieldArrow}, }; diff --git a/src/data/items.h b/src/data/items.h index 84436be55b..67c5b477f5 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -10340,4 +10340,17 @@ const struct Item gItems[] = .fieldUseFunc = ItemUseOutOfBattle_EvolutionStone, .flingPower = 30, }, + + [ITEM_BERSERK_GENE] = + { + .name = _("Berserk Gene"), + .itemId = ITEM_BERSERK_GENE, + .price = 20, + .holdEffect = HOLD_EFFECT_BERSERK_GENE, + .description = sBerserkGene, + .pocket = POCKET_ITEMS, + .type = ITEM_USE_BAG_MENU, + .fieldUseFunc = ItemUseOutOfBattle_CannotUse, + .flingPower = 10, + }, }; diff --git a/src/data/text/item_descriptions.h b/src/data/text/item_descriptions.h index 5dc870038a..dddf8552f5 100644 --- a/src/data/text/item_descriptions.h +++ b/src/data/text/item_descriptions.h @@ -3907,3 +3907,8 @@ static const u8 sLustrousGlobeDesc[] = _( "A large, glowing gem\n" "that lets Palkia\n" "change form."); + +static const u8 sBerserkGene[] = _( + "Sharply boosts\n" + "Attack, but causes\n" + "lasting confusion."); diff --git a/test/hold_effect_berserk_gene.c b/test/hold_effect_berserk_gene.c new file mode 100644 index 0000000000..361d148611 --- /dev/null +++ b/test/hold_effect_berserk_gene.c @@ -0,0 +1,187 @@ +#include "global.h" +#include "test_battle.h" + +ASSUMPTIONS +{ + ASSUME(gItems[ITEM_BERSERK_GENE].holdEffect == HOLD_EFFECT_BERSERK_GENE); +} + +SINGLE_BATTLE_TEST("Berserk Gene sharply raises attack at the start of battle", s16 damage) +{ + u16 useItem; + PARAMETRIZE { useItem = FALSE; } + PARAMETRIZE { useItem = TRUE; } + if (useItem) PASSES_RANDOMLY(66, 100, RNG_CONFUSION); + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { if (useItem) Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + MOVE(player, MOVE_TACKLE); + } + } SCENE { + if (useItem) + { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Berserk Gene, the Attack of Wobbuffet sharply rose!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, player); + MESSAGE("Wobbuffet became confused!"); + } + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Berserk Gene activates on switch in", s16 damage) +{ + u16 useItem; + PARAMETRIZE { useItem = FALSE; } + PARAMETRIZE { useItem = TRUE; } + if (useItem) PASSES_RANDOMLY(66, 100, RNG_CONFUSION); + GIVEN { + PLAYER(SPECIES_WYNAUT); + PLAYER(SPECIES_WOBBUFFET) { if (useItem) Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + SWITCH(player, 1); + } TURN { + MOVE(player, MOVE_TACKLE); + } + } SCENE { + if (useItem) + { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Berserk Gene, the Attack of Wobbuffet sharply rose!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, player); + MESSAGE("Wobbuffet became confused!"); + } + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Berserk Gene does not confuse a Pokemon with Own Tempo but still raises attack sharply", s16 damage) +{ + u16 useItem; + PARAMETRIZE { useItem = FALSE; } + PARAMETRIZE { useItem = TRUE; } + GIVEN { + PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_OWN_TEMPO); if (useItem) Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + MOVE(player, MOVE_TACKLE); + } + } SCENE { + if (useItem) + { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Berserk Gene, the Attack of Slowbro sharply rose!"); + ABILITY_POPUP(player, ABILITY_OWN_TEMPO); + MESSAGE("Slowbro's Own Tempo prevents confusion!"); + } + HP_BAR(opponent, captureDamage: &results[i].damage); + NONE_OF + { + MESSAGE("Slowbro became confused!"); + } + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Berserk Gene does not confuse on Misty Terrain but still raises attack sharply") +{ + GIVEN { + ASSUME(P_GEN_7_POKEMON == TRUE); + PLAYER(SPECIES_TAPU_FINI) { Ability(ABILITY_MISTY_SURGE); Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + MOVE(player, MOVE_TACKLE); + } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Berserk Gene, the Attack of Tapu Fini sharply rose!"); + NONE_OF + { + MESSAGE("Tapu Fini became confused!"); + } + } +} + +SINGLE_BATTLE_TEST("Berserk Gene does not confuse when Safeguard is active") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SAFEGUARD); } + TURN { SWITCH(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Berserk Gene, the Attack of Wobbuffet sharply rose!"); + MESSAGE("Wobbuffet's party is protected by SAFEGUARD!"); + NONE_OF + { + MESSAGE("Wobbuffet became confused!"); + } + } +} + +SINGLE_BATTLE_TEST("Berserk Gene causes confusion for more than 5 turns") // how else would be check for infinite? +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN {} + TURN {} + TURN {} + TURN {} + TURN {} + TURN {} + } SCENE { + NONE_OF + { + MESSAGE("Wobbuffet snapped out of confusion!"); + } + } +} + +SINGLE_BATTLE_TEST("Berserk Gene causes infinite confusion") // check if bit is set +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN {} + } SCENE { + } THEN { + EXPECT(gStatuses4[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)] & STATUS4_INFINITE_CONFUSION); + } +} + +SINGLE_BATTLE_TEST("Berserk Gene causes confusion timer to not tick down", u32 status2) +{ + u32 turns; + PARAMETRIZE { turns = 1; } + PARAMETRIZE { turns = 2; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BERSERK_GENE); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + u32 count; + for (count = 0; count < turns; count++) { + TURN {} + } + } THEN { + results[i].status2 = player->status2; + } FINALLY { + EXPECT_EQ(results[0].status2, results[1].status2); + } +}