diff --git a/.all-contributorsrc b/.all-contributorsrc
index 52810517f1..aa76ec1a65 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -468,6 +468,16 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "leo60228",
+ "name": "leo60228",
+ "avatar_url": "https://avatars.githubusercontent.com/u/8355305?v=4",
+ "profile": "https://vriska.dev",
+ "contributions": [
+ "doc",
+ "data"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/CREDITS.md b/CREDITS.md
index 31f2302313..e9d1e53354 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -77,6 +77,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
 MandL27 💻 |
 cawtds 💻 |
 Frank DeBlasio 💻 |
+  leo60228 📖 🔣 |
diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc
index 0fe80a617e..29e8c451cc 100644
--- a/asm/macros/battle_script.inc
+++ b/asm/macros/battle_script.inc
@@ -1809,7 +1809,6 @@
.macro setmoveeffect effect:req
sethword sMOVE_EFFECT, \effect
- sethword sSAVED_MOVE_EFFECT, \effect
.endm
.macro sethword dst:req, value:req
diff --git a/asm/macros/event.inc b/asm/macros/event.inc
index ca937e0c0d..6abaeff265 100644
--- a/asm/macros/event.inc
+++ b/asm/macros/event.inc
@@ -169,7 +169,10 @@
.endm
@ Copies the value of source into destination.
- .macro copyvar destination:req, source:req
+ .macro copyvar destination:req, source:req, warn=TRUE
+ .if \warn && !((\source >= VARS_START && \source <= VARS_END) || (\source >= SPECIAL_VARS_START && \source <= SPECIAL_VARS_END))
+ .warning "copyvar with a value that is not a VAR_ constant; did you mean setvar instead?"
+ .endif
.byte SCR_OP_COPYVAR
.2byte \destination
.2byte \source
diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s
index 7b43ebbdf6..a853089e63 100644
--- a/data/battle_anim_scripts.s
+++ b/data/battle_anim_scripts.s
@@ -255,23 +255,23 @@ gBattleAnimMove_Tailwind::
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 24, 6, 4, 4
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 7, 10
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 10, 2304, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 10, 2304, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 90, 2048, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 90, 2048, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 50, 2560, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 50, 2560, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 20, 2304, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 20, 2304, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 70, 1984, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 70, 1984, 96, 1
delay 12
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 0, 2816, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 0, 2816, 96, 1
delay 10
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 60, 2560, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 60, 2560, 96, 1
waitforvisualfinish
stopsound
call UnsetHighSpeedBg
@@ -285,23 +285,23 @@ gBattleAnimGeneral_Tailwind::
playsewithpan SE_M_GUST, SOUND_PAN_ATTACKER
call SetHighSpeedBg
setalpha 12, 8
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 10, 2304, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 10, 2304, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 90, 2048, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 90, 2048, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 50, 2560, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 50, 2560, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 20, 2304, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 20, 2304, 96, 1
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 70, 1984, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 70, 1984, 96, 1
delay 12
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 0, 2816, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 0, 2816, 96, 1
delay 10
- createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 60, 2560, 96, 0
+ createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 60, 2560, 96, 1
waitforvisualfinish
stopsound
call UnsetHighSpeedBg
@@ -32027,7 +32027,8 @@ gBattleAnimGeneral_Rainbow::
createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 6, 0, RGB_WHITE
waitforvisualfinish
delay 30
- fadetobg BG_RAINBOW
+ goto SetRainbowBackground
+AnimGeneral_RainbowContinue:
panse_adjustnone SE_M_ABSORB_2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0
delay 90
blendoff
@@ -32035,6 +32036,14 @@ gBattleAnimGeneral_Rainbow::
waitbgfadein
clearmonbg ANIM_ATK_PARTNER
end
+SetRainbowBackground:
+ createvisualtask AnimTask_GetAttackerSide, 2
+ jumprettrue SetRainbowBgOppoentSide
+ fadetobg BG_RAINBOW_PLAYER
+ goto AnimGeneral_RainbowContinue
+SetRainbowBgOppoentSide:
+ fadetobg BG_RAINBOW_OPPONENT
+ goto AnimGeneral_RainbowContinue
gBattleAnimGeneral_SeaOfFire::
loadspritegfx ANIM_TAG_SMALL_EMBER
diff --git a/data/maps/LilycoveCity_ContestLobby/scripts.inc b/data/maps/LilycoveCity_ContestLobby/scripts.inc
index 862a5ef37d..41db53c954 100644
--- a/data/maps/LilycoveCity_ContestLobby/scripts.inc
+++ b/data/maps/LilycoveCity_ContestLobby/scripts.inc
@@ -349,7 +349,11 @@ LilycoveCity_ContestLobby_EventScript_SetMasterContestType::
@ Functionally unused
LilycoveCity_ContestLobby_EventScript_SetDebug::
setflag FLAG_HIDE_LILYCOVE_MUSEUM_CURATOR
- copyvar VAR_LILYCOVE_MUSEUM_2F_STATE, 1
+#ifdef UBFIX
+ setvar VAR_LILYCOVE_MUSEUM_2F_STATE, 1
+#else
+ copyvar VAR_LILYCOVE_MUSEUM_2F_STATE, 1, warn=FALSE
+#endif
additem ITEM_CONTEST_PASS
setvar VAR_0x800B, 8
setvar VAR_CONTEST_RANK, CONTEST_RANK_MASTER
diff --git a/data/maps/LilycoveCity_LilycoveMuseum_2F/scripts.inc b/data/maps/LilycoveCity_LilycoveMuseum_2F/scripts.inc
index e00c7bcb3c..1ac10a4016 100644
--- a/data/maps/LilycoveCity_LilycoveMuseum_2F/scripts.inc
+++ b/data/maps/LilycoveCity_LilycoveMuseum_2F/scripts.inc
@@ -76,7 +76,11 @@ LilycoveCity_LilycoveMuseum_2F_EventScript_ShowExhibitHall::
applymovement LOCALID_PLAYER, LilycoveCity_LilycoveMuseum_2F_Movement_PlayerWalkInPlaceLeft
waitmovement 0
msgbox LilycoveCity_LilycoveMuseum_2F_Text_PleaseObtainPaintingsForExhibit, MSGBOX_SIGN
- copyvar VAR_LILYCOVE_MUSEUM_2F_STATE, 1
+#ifdef UBFIX
+ setvar VAR_LILYCOVE_MUSEUM_2F_STATE, 1
+#else
+ copyvar VAR_LILYCOVE_MUSEUM_2F_STATE, 1, warn=FALSE
+#endif
releaseall
end
diff --git a/data/maps/SkyPillar_2F/scripts.inc b/data/maps/SkyPillar_2F/scripts.inc
index bad2488f0b..a530e01113 100644
--- a/data/maps/SkyPillar_2F/scripts.inc
+++ b/data/maps/SkyPillar_2F/scripts.inc
@@ -6,7 +6,11 @@ SkyPillar_2F_MapScripts::
SkyPillar_2F_OnTransition:
call_if_lt VAR_SKY_PILLAR_STATE, 2, SkyPillar_2F_EventScript_CleanFloor
- copyvar VAR_ICE_STEP_COUNT, 1
+#ifdef UBFIX
+ setvar VAR_ICE_STEP_COUNT, 1
+#else
+ copyvar VAR_ICE_STEP_COUNT, 1, warn=FALSE
+#endif
end
SkyPillar_2F_EventScript_CleanFloor::
diff --git a/data/maps/SkyPillar_4F/scripts.inc b/data/maps/SkyPillar_4F/scripts.inc
index 9e8f1e80ea..603144f04b 100644
--- a/data/maps/SkyPillar_4F/scripts.inc
+++ b/data/maps/SkyPillar_4F/scripts.inc
@@ -6,7 +6,11 @@ SkyPillar_4F_MapScripts::
SkyPillar_4F_OnTransition:
call_if_lt VAR_SKY_PILLAR_STATE, 2, SkyPillar_4F_EventScript_CleanFloor
- copyvar VAR_ICE_STEP_COUNT, 1
+#ifdef UBFIX
+ setvar VAR_ICE_STEP_COUNT, 1
+#else
+ copyvar VAR_ICE_STEP_COUNT, 1, warn=FALSE
+#endif
end
SkyPillar_4F_EventScript_CleanFloor::
diff --git a/data/scripts/cave_hole.inc b/data/scripts/cave_hole.inc
index 36cac1cb98..e6f9084705 100644
--- a/data/scripts/cave_hole.inc
+++ b/data/scripts/cave_hole.inc
@@ -3,7 +3,11 @@ CaveHole_CheckFallDownHole:
.2byte 0
CaveHole_FixCrackedGround:
+#ifdef UBFIX
setvar VAR_ICE_STEP_COUNT, 1
+#else
+ copyvar VAR_ICE_STEP_COUNT, 1, warn=FALSE
+#endif
end
EventScript_FallDownHole::
diff --git a/graphics/battle_anims/backgrounds/rainbow.pal b/graphics/battle_anims/backgrounds/rainbow.pal
deleted file mode 100644
index 9b62b7b25b..0000000000
--- a/graphics/battle_anims/backgrounds/rainbow.pal
+++ /dev/null
@@ -1,19 +0,0 @@
-JASC-PAL
-0100
-16
-109 92 75
-255 255 255
-255 107 122
-255 200 102
-255 255 107
-143 255 160
-107 255 255
-107 129 255
-220 114 255
-199 255 250
-232 240 248
-224 232 240
-208 224 240
-191 202 224
-183 189 202
-157 166 181
diff --git a/graphics/battle_anims/backgrounds/rainbow.png b/graphics/battle_anims/backgrounds/rainbow.png
deleted file mode 100644
index bd41645b35..0000000000
Binary files a/graphics/battle_anims/backgrounds/rainbow.png and /dev/null differ
diff --git a/graphics/battle_anims/backgrounds/rainbow.bin b/graphics/battle_anims/backgrounds/rainbow_opponent_tile.bin
similarity index 53%
rename from graphics/battle_anims/backgrounds/rainbow.bin
rename to graphics/battle_anims/backgrounds/rainbow_opponent_tile.bin
index 770389abf4..3aedd149cb 100644
Binary files a/graphics/battle_anims/backgrounds/rainbow.bin and b/graphics/battle_anims/backgrounds/rainbow_opponent_tile.bin differ
diff --git a/graphics/battle_anims/backgrounds/rainbow_opponent_tile.png b/graphics/battle_anims/backgrounds/rainbow_opponent_tile.png
new file mode 100644
index 0000000000..2737714805
Binary files /dev/null and b/graphics/battle_anims/backgrounds/rainbow_opponent_tile.png differ
diff --git a/graphics/battle_anims/backgrounds/rainbow_player_tile.bin b/graphics/battle_anims/backgrounds/rainbow_player_tile.bin
new file mode 100644
index 0000000000..a4f509ebe9
Binary files /dev/null and b/graphics/battle_anims/backgrounds/rainbow_player_tile.bin differ
diff --git a/graphics/battle_anims/backgrounds/rainbow_player_tile.png b/graphics/battle_anims/backgrounds/rainbow_player_tile.png
new file mode 100644
index 0000000000..5597a2fa92
Binary files /dev/null and b/graphics/battle_anims/backgrounds/rainbow_player_tile.png differ
diff --git a/graphics/pokemon/chesnaught/overworld.png b/graphics/pokemon/chesnaught/overworld.png
index 7902feaf57..99c5d10cba 100644
Binary files a/graphics/pokemon/chesnaught/overworld.png and b/graphics/pokemon/chesnaught/overworld.png differ
diff --git a/graphics/pokemon/chespin/overworld.png b/graphics/pokemon/chespin/overworld.png
index 5056ad774a..92df00e97d 100644
Binary files a/graphics/pokemon/chespin/overworld.png and b/graphics/pokemon/chespin/overworld.png differ
diff --git a/graphics/pokemon/delphox/overworld.png b/graphics/pokemon/delphox/overworld.png
index e490e31cd8..dbf3da76ea 100644
Binary files a/graphics/pokemon/delphox/overworld.png and b/graphics/pokemon/delphox/overworld.png differ
diff --git a/graphics/pokemon/diggersby/overworld.png b/graphics/pokemon/diggersby/overworld.png
index 03d6b59066..39f72f5531 100644
Binary files a/graphics/pokemon/diggersby/overworld.png and b/graphics/pokemon/diggersby/overworld.png differ
diff --git a/graphics/pokemon/espurr/overworld.png b/graphics/pokemon/espurr/overworld.png
index f7ba8e08a0..6df4dddb3e 100644
Binary files a/graphics/pokemon/espurr/overworld.png and b/graphics/pokemon/espurr/overworld.png differ
diff --git a/graphics/pokemon/fletchinder/overworld.png b/graphics/pokemon/fletchinder/overworld.png
index a987365357..949b3e308d 100644
Binary files a/graphics/pokemon/fletchinder/overworld.png and b/graphics/pokemon/fletchinder/overworld.png differ
diff --git a/graphics/pokemon/fletchling/overworld.png b/graphics/pokemon/fletchling/overworld.png
index acfc95f616..4c35d25d17 100644
Binary files a/graphics/pokemon/fletchling/overworld.png and b/graphics/pokemon/fletchling/overworld.png differ
diff --git a/graphics/pokemon/greninja/overworld.png b/graphics/pokemon/greninja/overworld.png
index bb08608ca5..6e14bb60eb 100644
Binary files a/graphics/pokemon/greninja/overworld.png and b/graphics/pokemon/greninja/overworld.png differ
diff --git a/graphics/pokemon/lillipup/overworld.png b/graphics/pokemon/lillipup/overworld.png
index ef88414713..14f876a2c6 100644
Binary files a/graphics/pokemon/lillipup/overworld.png and b/graphics/pokemon/lillipup/overworld.png differ
diff --git a/graphics/pokemon/litleo/overworld.png b/graphics/pokemon/litleo/overworld.png
index 2c128f3184..a419a8327d 100644
Binary files a/graphics/pokemon/litleo/overworld.png and b/graphics/pokemon/litleo/overworld.png differ
diff --git a/graphics/pokemon/pancham/overworld.png b/graphics/pokemon/pancham/overworld.png
index 90d10d9bfa..a54ddda99d 100644
Binary files a/graphics/pokemon/pancham/overworld.png and b/graphics/pokemon/pancham/overworld.png differ
diff --git a/graphics/pokemon/scatterbug/overworld.png b/graphics/pokemon/scatterbug/overworld.png
index 2da700223d..41de917984 100644
Binary files a/graphics/pokemon/scatterbug/overworld.png and b/graphics/pokemon/scatterbug/overworld.png differ
diff --git a/graphics/pokemon/talonflame/overworld.png b/graphics/pokemon/talonflame/overworld.png
index 43760d9e85..67fc802f44 100644
Binary files a/graphics/pokemon/talonflame/overworld.png and b/graphics/pokemon/talonflame/overworld.png differ
diff --git a/graphics/pokemon/watchog/overworld.png b/graphics/pokemon/watchog/overworld.png
index e9184c7375..092d97f508 100644
Binary files a/graphics/pokemon/watchog/overworld.png and b/graphics/pokemon/watchog/overworld.png differ
diff --git a/include/battle.h b/include/battle.h
old mode 100644
new mode 100755
index 74985151bd..92018ea8db
--- a/include/battle.h
+++ b/include/battle.h
@@ -908,7 +908,7 @@ struct BattleScripting
u8 specialTrainerBattleType;
bool8 monCaught;
s32 savedDmg;
- u16 savedMoveEffect; // For moves hitting multiple targets.
+ u16 unused_0x2c;
u16 moveEffect;
u16 unused_0x30;
u8 illusionNickHack; // To properly display nick in STRINGID_ENEMYABOUTTOSWITCHPKMN.
diff --git a/include/battle_util.h b/include/battle_util.h
index 068f138264..e6855af5b5 100644
--- a/include/battle_util.h
+++ b/include/battle_util.h
@@ -163,7 +163,7 @@ struct DamageContext
u32 randomFactor:1;
u32 updateFlags:1;
u32 isAnticipation:1;
- u32 padding1:1;
+ u32 isSelfInflicted:1;
u32 weather:16;
u32 fixedBasePower:8;
u32 padding2:8;
diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h
index 1c1c73cd15..2ac2bc30f2 100644
--- a/include/constants/battle_anim.h
+++ b/include/constants/battle_anim.h
@@ -533,8 +533,9 @@
#define BG_STEEL_BEAM_OPPONENT 78
#define BG_STEEL_BEAM_PLAYER 79
#define BG_CHLOROBLAST 80
-#define BG_RAINBOW 81
-#define BG_SWAMP 82
+#define BG_RAINBOW_PLAYER 81
+#define BG_RAINBOW_OPPONENT 82
+#define BG_SWAMP 83
// table ids for general animations (sBattleAnims_General)
#define B_ANIM_STATS_CHANGE 0
diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h
index 167649c4d7..70f0739210 100644
--- a/include/constants/battle_script_commands.h
+++ b/include/constants/battle_script_commands.h
@@ -31,7 +31,7 @@
#define sSPECIAL_TRAINER_BATTLE_TYPE (gBattleScripting + 0x26) // specialTrainerBattleType
#define sMON_CAUGHT (gBattleScripting + 0x27) // monCaught
#define sSAVED_DMG (gBattleScripting + 0x28) // savedDmg
-#define sSAVED_MOVE_EFFECT (gBattleScripting + 0x2C) // savedMoveEffect
+#define sUNUSED_0x2C (gBattleScripting + 0x2C) // unused_0x2c
#define sMOVE_EFFECT (gBattleScripting + 0x2E) // moveEffect
#define sUNUSED_0x30 (gBattleScripting + 0x30) // unused_0x30
#define sILLUSION_NICK_HACK (gBattleScripting + 0x32) // illusionNickHack
diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h
index 88584e9978..381c77ca13 100644
--- a/include/constants/generational_changes.h
+++ b/include/constants/generational_changes.h
@@ -47,6 +47,7 @@ enum GenConfigTag
GEN_CONFIG_TOXIC_NEVER_MISS,
GEN_CONFIG_PARALYZE_ELECTRIC,
GEN_CONFIG_BADGE_BOOST,
+ GEN_CONFIG_LEAF_GUARD_PREVENTS_REST,
GEN_CONFIG_COUNT
};
diff --git a/include/generational_changes.h b/include/generational_changes.h
index e8b701d096..0068d74428 100644
--- a/include/generational_changes.h
+++ b/include/generational_changes.h
@@ -49,7 +49,8 @@ static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] =
[GEN_CONFIG_OBLIVIOUS_TAUNT] = B_OBLIVIOUS_TAUNT,
[GEN_CONFIG_TOXIC_NEVER_MISS] = B_TOXIC_NEVER_MISS,
[GEN_CONFIG_PARALYZE_ELECTRIC] = B_PARALYZE_ELECTRIC,
- [GEN_CONFIG_BADGE_BOOST] = B_BADGE_BOOST
+ [GEN_CONFIG_BADGE_BOOST] = B_BADGE_BOOST,
+ [GEN_CONFIG_LEAF_GUARD_PREVENTS_REST] = B_LEAF_GUARD_PREVENTS_REST,
};
#if TESTING
diff --git a/include/graphics.h b/include/graphics.h
index 82bf2691eb..bc168e39a1 100644
--- a/include/graphics.h
+++ b/include/graphics.h
@@ -3196,9 +3196,11 @@ extern const u32 gBattleAnimBgTilemap_Sandstorm[];
extern const u32 gBattleAnimBgImage_Sandstorm[];
// Pledge Effect field status - Rainbow
-extern const u32 gBattleAnimBgImage_Rainbow[];
+extern const u32 gBattleAnimBgImage_RainbowPlayer[];
+extern const u32 gBattleAnimBgImage_RainbowOpponent[];
extern const u16 gBattleAnimBGPalette_Rainbow[];
-extern const u32 gBattleAnimBgTilemap_Rainbow[];
+extern const u32 gBattleAnimBgTilemap_RainbowPlayer[];
+extern const u32 gBattleAnimBgTilemap_RainbowOpponent[];
// Pledge Effect field status - Swamp
extern const u32 gBattleAnimBgImage_Swamp[];
diff --git a/sound/song_table.inc b/sound/song_table.inc
index c551a656b9..6e4237b998 100644
--- a/sound/song_table.inc
+++ b/sound/song_table.inc
@@ -1,616 +1,621 @@
+ .equiv MUSIC_PLAYER_BGM,0
+ .equiv MUSIC_PLAYER_SE1,1
+ .equiv MUSIC_PLAYER_SE2,2
+ .equiv MUSIC_PLAYER_SE3,3
+
.align 2
gSongTable::
- song mus_dummy, 0, 0
- song se_use_item, 1, 1
- song se_pc_login, 1, 1
- song se_pc_off, 1, 1
- song se_pc_on, 1, 1
- song se_select, 2, 2
- song se_win_open, 1, 1
- song se_wall_hit, 2, 2
- song se_door, 1, 1
- song se_exit, 1, 1
- song se_ledge, 1, 1
- song se_bike_bell, 1, 1
- song se_not_effective, 1, 1
- song se_effective, 1, 1
- song se_super_effective, 1, 1
- song se_ball_open, 1, 1
- song se_faint, 1, 1
- song se_flee, 1, 1
- song se_sliding_door, 1, 1
- song se_ship, 1, 1
- song se_bang, 1, 1
- song se_pin, 1, 1
- song se_boo, 1, 1
- song se_ball, 1, 1
- song se_contest_place, 2, 2
- song se_a, 1, 1
- song se_i, 1, 1
- song se_u, 1, 1
- song se_e, 1, 1
- song se_o, 1, 1
- song se_n, 1, 1
- song se_success, 1, 1
- song se_failure, 1, 1
- song se_exp, 1, 1
- song se_bike_hop, 1, 1
- song se_switch, 1, 1
- song se_click, 1, 1
- song se_fu_zaku, 1, 1
- song se_contest_condition_lose, 1, 1
- song se_lavaridge_fall_warp, 1, 1
- song se_ice_stairs, 1, 1
- song se_ice_break, 1, 1
- song se_ice_crack, 1, 1
- song se_fall, 1, 1
- song se_unlock, 2, 2
- song se_warp_in, 1, 1
- song se_warp_out, 1, 1
- song se_repel, 1, 1
- song se_rotating_gate, 1, 1
- song se_truck_move, 1, 1
- song se_truck_stop, 1, 1
- song se_truck_unload, 2, 2
- song se_truck_door, 1, 1
- song se_berry_blender, 2, 2
- song se_card, 1, 1
- song se_save, 1, 1
- song se_ball_bounce_1, 1, 1
- song se_ball_bounce_2, 1, 1
- song se_ball_bounce_3, 1, 1
- song se_ball_bounce_4, 1, 1
- song se_ball_trade, 2, 2
- song se_ball_throw, 1, 1
- song se_note_c, 2, 2
- song se_note_d, 2, 2
- song se_note_e, 2, 2
- song se_note_f, 2, 2
- song se_note_g, 2, 2
- song se_note_a, 2, 2
- song se_note_b, 2, 2
- song se_note_c_high, 2, 2
- song se_puddle, 2, 2
- song se_bridge_walk, 2, 2
- song se_itemfinder, 1, 1
- song se_ding_dong, 1, 1
- song se_balloon_red, 2, 2
- song se_balloon_blue, 2, 2
- song se_balloon_yellow, 2, 2
- song se_breakable_door, 2, 2
- song se_mud_ball, 2, 2
- song se_field_poison, 1, 1
- song se_escalator, 1, 1
- song se_thunderstorm, 3, 3
- song se_thunderstorm_stop, 3, 3
- song se_downpour, 3, 3
- song se_downpour_stop, 3, 3
- song se_rain, 3, 3
- song se_rain_stop, 3, 3
- song se_thunder, 1, 1
- song se_thunder2, 1, 1
- song se_elevator, 1, 1
- song se_low_health, 3, 3
- song se_exp_max, 1, 1
- song se_roulette_ball, 2, 2
- song se_roulette_ball2, 2, 2
- song se_taillow_wing_flap, 1, 1
- song se_shop, 1, 1
- song se_contest_heart, 1, 1
- song se_contest_curtain_rise, 1, 1
- song se_contest_curtain_fall, 1, 1
- song se_contest_icon_change, 1, 1
- song se_contest_icon_clear, 1, 1
- song se_contest_mons_turn, 1, 1
- song se_shiny, 1, 1
- song se_intro_blast, 1, 1
- song se_mugshot, 1, 1
- song se_applause, 1, 1
- song se_vend, 1, 1
- song se_orb, 1, 1
- song se_dex_scroll, 1, 1
- song se_dex_page, 1, 1
- song se_pokenav_on, 1, 1
- song se_pokenav_off, 1, 1
- song se_dex_search, 1, 1
- song se_egg_hatch, 1, 1
- song se_ball_tray_enter, 1, 1
- song se_ball_tray_ball, 1, 1
- song se_ball_tray_exit, 2, 2
- song se_glass_flute, 1, 1
- song se_m_thunderbolt, 2, 2
- song se_m_thunderbolt2, 1, 1
- song se_m_harden, 1, 1
- song se_m_nightmare, 1, 1
- song se_m_vital_throw, 1, 1
- song se_m_vital_throw2, 1, 1
- song se_m_bubble, 1, 1
- song se_m_bubble2, 1, 1
- song se_m_bubble3, 1, 1
- song se_m_rain_dance, 1, 1
- song se_m_cut, 1, 1
- song se_m_string_shot, 1, 1
- song se_m_string_shot2, 1, 1
- song se_m_rock_throw, 1, 1
- song se_m_gust, 2, 2
- song se_m_gust2, 2, 2
- song se_m_double_slap, 1, 1
- song se_m_double_team, 1, 1
- song se_m_razor_wind, 1, 1
- song se_m_icy_wind, 1, 1
- song se_m_thunder_wave, 1, 1
- song se_m_comet_punch, 1, 1
- song se_m_mega_kick, 1, 1
- song se_m_mega_kick2, 1, 1
- song se_m_crabhammer, 1, 1
- song se_m_jump_kick, 1, 1
- song se_m_flame_wheel, 1, 1
- song se_m_flame_wheel2, 1, 1
- song se_m_flamethrower, 1, 1
- song se_m_fire_punch, 1, 1
- song se_m_toxic, 1, 1
- song se_m_sacred_fire, 1, 1
- song se_m_sacred_fire2, 2, 2
- song se_m_ember, 1, 1
- song se_m_take_down, 2, 2
- song se_m_blizzard, 1, 1
- song se_m_blizzard2, 1, 1
- song se_m_scratch, 1, 1
- song se_m_vicegrip, 1, 1
- song se_m_wing_attack, 1, 1
- song se_m_fly, 1, 1
- song se_m_sand_attack, 1, 1
- song se_m_razor_wind2, 1, 1
- song se_m_bite, 1, 1
- song se_m_headbutt, 1, 1
- song se_m_surf, 1, 1
- song se_m_hydro_pump, 1, 1
- song se_m_whirlpool, 1, 1
- song se_m_horn_attack, 1, 1
- song se_m_tail_whip, 2, 2
- song se_m_mist, 1, 1
- song se_m_poison_powder, 1, 1
- song se_m_bind, 2, 2
- song se_m_dragon_rage, 1, 1
- song se_m_sing, 1, 1
- song se_m_perish_song, 1, 1
- song se_m_pay_day, 1, 1
- song se_m_dig, 1, 1
- song se_m_dizzy_punch, 1, 1
- song se_m_self_destruct, 1, 1
- song se_m_explosion, 1, 1
- song se_m_absorb_2, 1, 1
- song se_m_absorb, 1, 1
- song se_m_screech, 1, 1
- song se_m_bubble_beam, 1, 1
- song se_m_bubble_beam2, 1, 1
- song se_m_supersonic, 1, 1
- song se_m_belly_drum, 1, 1
- song se_m_metronome, 1, 1
- song se_m_bonemerang, 1, 1
- song se_m_lick, 1, 1
- song se_m_psybeam, 1, 1
- song se_m_faint_attack, 1, 1
- song se_m_swords_dance, 1, 1
- song se_m_leer, 1, 1
- song se_m_swagger, 1, 1
- song se_m_swagger2, 1, 1
- song se_m_heal_bell, 1, 1
- song se_m_confuse_ray, 1, 1
- song se_m_snore, 1, 1
- song se_m_brick_break, 1, 1
- song se_m_giga_drain, 1, 1
- song se_m_psybeam2, 1, 1
- song se_m_solar_beam, 2, 2
- song se_m_petal_dance, 1, 1
- song se_m_teleport, 1, 1
- song se_m_minimize, 1, 1
- song se_m_sketch, 1, 1
- song se_m_swift, 1, 1
- song se_m_reflect, 1, 1
- song se_m_barrier, 1, 1
- song se_m_detect, 2, 2
- song se_m_lock_on, 1, 1
- song se_m_moonlight, 1, 1
- song se_m_charm, 1, 1
- song se_m_charge, 1, 1
- song se_m_strength, 1, 1
- song se_m_hyper_beam, 1, 1
- song se_m_waterfall, 1, 1
- song se_m_reversal, 1, 1
- song se_m_acid_armor, 1, 1
- song se_m_sandstorm, 1, 1
- song se_m_tri_attack, 1, 1
- song se_m_tri_attack2, 1, 1
- song se_m_encore, 1, 1
- song se_m_encore2, 2, 2
- song se_m_baton_pass, 1, 1
- song se_m_milk_drink, 1, 1
- song se_m_attract, 1, 1
- song se_m_attract2, 1, 1
- song se_m_morning_sun, 1, 1
- song se_m_flatter, 1, 1
- song se_m_sand_tomb, 1, 1
- song se_m_grasswhistle, 1, 1
- song se_m_spit_up, 1, 1
- song se_m_dive, 1, 1
- song se_m_earthquake, 2, 2
- song se_m_twister, 2, 2
- song se_m_sweet_scent, 1, 1
- song se_m_yawn, 1, 1
- song se_m_sky_uppercut, 2, 2
- song se_m_stat_increase, 1, 1
- song se_m_heat_wave, 1, 1
- song se_m_uproar, 1, 1
- song se_m_hail, 1, 1
- song se_m_cosmic_power, 2, 2
- song se_m_teeter_dance, 1, 1
- song se_m_stat_decrease, 1, 1
- song se_m_haze, 1, 1
- song se_m_hyper_beam2, 1, 1
- song se_rg_door, 1, 1
- song se_rg_card_flip, 1, 1
- song se_rg_card_flipping, 1, 1
- song se_rg_card_open, 1, 1
- song se_rg_bag_cursor, 1, 1
- song se_rg_bag_pocket, 1, 1
- song se_rg_ball_click, 1, 1
- song se_rg_shop, 1, 1
- song se_rg_ss_anne_horn, 1, 1
- song se_rg_help_open, 1, 1
- song se_rg_help_close, 1, 1
- song se_rg_help_error, 1, 1
- song se_rg_deoxys_move, 1, 1
- song se_rg_poke_jump_success, 1, 1
- song se_rg_poke_jump_failure, 1, 1
- song se_pokenav_call, 1, 1
- song se_pokenav_hang_up, 1, 1
- song se_arena_timeup1, 1, 1
- song se_arena_timeup2, 1, 1
- song se_pike_curtain_close, 1, 1
- song se_pike_curtain_open, 1, 1
- song se_sudowoodo_shake, 1, 1
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song dummy_song_header, 0, 0
- song mus_littleroot_test, 0, 0
- song mus_gsc_route38, 0, 0
- song mus_caught, 0, 0
- song mus_victory_wild, 0, 0
- song mus_victory_gym_leader, 0, 0
- song mus_victory_league, 0, 0
- song mus_c_comm_center, 0, 0
- song mus_gsc_pewter, 0, 0
- song mus_c_vs_legend_beast, 0, 0
- song mus_route101, 0, 0
- song mus_route110, 0, 0
- song mus_route120, 0, 0
- song mus_petalburg, 0, 0
- song mus_oldale, 0, 0
- song mus_gym, 0, 0
- song mus_surf, 0, 0
- song mus_petalburg_woods, 0, 0
- song mus_level_up, 2, 2
- song mus_heal, 2, 2
- song mus_obtain_badge, 2, 2
- song mus_obtain_item, 2, 2
- song mus_evolved, 2, 2
- song mus_obtain_tmhm, 2, 2
- song mus_lilycove_museum, 0, 0
- song mus_route122, 0, 0
- song mus_oceanic_museum, 0, 0
- song mus_evolution_intro, 2, 2
- song mus_evolution, 0, 0
- song mus_move_deleted, 2, 2
- song mus_encounter_girl, 0, 0
- song mus_encounter_male, 0, 0
- song mus_abandoned_ship, 0, 0
- song mus_fortree, 0, 0
- song mus_birch_lab, 0, 0
- song mus_b_tower_rs, 0, 0
- song mus_encounter_swimmer, 0, 0
- song mus_cave_of_origin, 0, 0
- song mus_obtain_berry, 2, 2
- song mus_awaken_legend, 2, 2
- song mus_slots_jackpot, 2, 2
- song mus_slots_win, 2, 2
- song mus_too_bad, 2, 2
- song mus_roulette, 0, 0
- song mus_link_contest_p1, 0, 0
- song mus_link_contest_p2, 0, 0
- song mus_link_contest_p3, 0, 0
- song mus_link_contest_p4, 0, 0
- song mus_encounter_rich, 0, 0
- song mus_verdanturf, 0, 0
- song mus_rustboro, 0, 0
- song mus_poke_center, 0, 0
- song mus_route104, 0, 0
- song mus_route119, 0, 0
- song mus_cycling, 0, 0
- song mus_poke_mart, 0, 0
- song mus_littleroot, 0, 0
- song mus_mt_chimney, 0, 0
- song mus_encounter_female, 0, 0
- song mus_lilycove, 0, 0
- song mus_route111, 0, 0
- song mus_help, 0, 0
- song mus_underwater, 0, 0
- song mus_victory_trainer, 0, 0
- song mus_title, 0, 0
- song mus_intro, 0, 0
- song mus_encounter_may, 0, 0
- song mus_encounter_intense, 0, 0
- song mus_encounter_cool, 0, 0
- song mus_route113, 0, 0
- song mus_encounter_aqua, 0, 0
- song mus_follow_me, 0, 0
- song mus_encounter_brendan, 0, 0
- song mus_ever_grande, 0, 0
- song mus_encounter_suspicious, 0, 0
- song mus_victory_aqua_magma, 0, 0
- song mus_cable_car, 0, 0
- song mus_game_corner, 0, 0
- song mus_dewford, 0, 0
- song mus_safari_zone, 0, 0
- song mus_victory_road, 0, 0
- song mus_aqua_magma_hideout, 0, 0
- song mus_sailing, 0, 0
- song mus_mt_pyre, 0, 0
- song mus_slateport, 0, 0
- song mus_mt_pyre_exterior, 0, 0
- song mus_school, 0, 0
- song mus_hall_of_fame, 0, 0
- song mus_fallarbor, 0, 0
- song mus_sealed_chamber, 0, 0
- song mus_contest_winner, 0, 0
- song mus_contest, 0, 0
- song mus_encounter_magma, 0, 0
- song mus_intro_battle, 0, 0
- song mus_abnormal_weather, 0, 0
- song mus_weather_groudon, 0, 0
- song mus_sootopolis, 0, 0
- song mus_contest_results, 0, 0
- song mus_hall_of_fame_room, 0, 0
- song mus_trick_house, 0, 0
- song mus_encounter_twins, 0, 0
- song mus_encounter_elite_four, 0, 0
- song mus_encounter_hiker, 0, 0
- song mus_contest_lobby, 0, 0
- song mus_encounter_interviewer, 0, 0
- song mus_encounter_champion, 0, 0
- song mus_credits, 0, 0
- song mus_end, 0, 0
- song mus_b_frontier, 0, 0
- song mus_b_arena, 0, 0
- song mus_obtain_b_points, 2, 2
- song mus_register_match_call, 2, 2
- song mus_b_pyramid, 0, 0
- song mus_b_pyramid_top, 0, 0
- song mus_b_palace, 0, 0
- song mus_rayquaza_appears, 0, 0
- song mus_b_tower, 0, 0
- song mus_obtain_symbol, 2, 2
- song mus_b_dome, 0, 0
- song mus_b_pike, 0, 0
- song mus_b_factory, 0, 0
- song mus_vs_rayquaza, 0, 0
- song mus_vs_frontier_brain, 0, 0
- song mus_vs_mew, 0, 0
- song mus_b_dome_lobby, 0, 0
- song mus_vs_wild, 0, 0
- song mus_vs_aqua_magma, 0, 0
- song mus_vs_trainer, 0, 0
- song mus_vs_gym_leader, 0, 0
- song mus_vs_champion, 0, 0
- song mus_vs_regi, 0, 0
- song mus_vs_kyogre_groudon, 0, 0
- song mus_vs_rival, 0, 0
- song mus_vs_elite_four, 0, 0
- song mus_vs_aqua_magma_leader, 0, 0
- song mus_rg_follow_me, 0, 0
- song mus_rg_game_corner, 0, 0
- song mus_rg_rocket_hideout, 0, 0
- song mus_rg_gym, 0, 0
- song mus_rg_jigglypuff, 2, 2
- song mus_rg_intro_fight, 0, 0
- song mus_rg_title, 0, 0
- song mus_rg_cinnabar, 0, 0
- song mus_rg_lavender, 0, 0
- song mus_rg_heal, 0, 0
- song mus_rg_cycling, 0, 0
- song mus_rg_encounter_rocket, 0, 0
- song mus_rg_encounter_girl, 0, 0
- song mus_rg_encounter_boy, 0, 0
- song mus_rg_hall_of_fame, 0, 0
- song mus_rg_viridian_forest, 0, 0
- song mus_rg_mt_moon, 0, 0
- song mus_rg_poke_mansion, 0, 0
- song mus_rg_credits, 0, 0
- song mus_rg_route1, 0, 0
- song mus_rg_route24, 0, 0
- song mus_rg_route3, 0, 0
- song mus_rg_route11, 0, 0
- song mus_rg_victory_road, 0, 0
- song mus_rg_vs_gym_leader, 0, 0
- song mus_rg_vs_trainer, 0, 0
- song mus_rg_vs_wild, 0, 0
- song mus_rg_vs_champion, 0, 0
- song mus_rg_pallet, 0, 0
- song mus_rg_oak_lab, 0, 0
- song mus_rg_oak, 0, 0
- song mus_rg_poke_center, 0, 0
- song mus_rg_ss_anne, 0, 0
- song mus_rg_surf, 0, 0
- song mus_rg_poke_tower, 0, 0
- song mus_rg_silph, 0, 0
- song mus_rg_fuchsia, 0, 0
- song mus_rg_celadon, 0, 0
- song mus_rg_victory_trainer, 0, 0
- song mus_rg_victory_wild, 0, 0
- song mus_rg_victory_gym_leader, 0, 0
- song mus_rg_vermillion, 0, 0
- song mus_rg_pewter, 0, 0
- song mus_rg_encounter_rival, 0, 0
- song mus_rg_rival_exit, 0, 0
- song mus_rg_dex_rating, 2, 2
- song mus_rg_obtain_key_item, 2, 2
- song mus_rg_caught_intro, 2, 2
- song mus_rg_photo, 2, 2
- song mus_rg_game_freak, 0, 0
- song mus_rg_caught, 0, 0
- song mus_rg_new_game_instruct, 0, 0
- song mus_rg_new_game_intro, 0, 0
- song mus_rg_new_game_exit, 0, 0
- song mus_rg_poke_jump, 0, 0
- song mus_rg_union_room, 0, 0
- song mus_rg_net_center, 0, 0
- song mus_rg_mystery_gift, 0, 0
- song mus_rg_berry_pick, 0, 0
- song mus_rg_sevii_cave, 0, 0
- song mus_rg_teachy_tv_show, 0, 0
- song mus_rg_sevii_route, 0, 0
- song mus_rg_sevii_dungeon, 0, 0
- song mus_rg_sevii_123, 0, 0
- song mus_rg_sevii_45, 0, 0
- song mus_rg_sevii_67, 0, 0
- song mus_rg_poke_flute, 2, 2
- song mus_rg_vs_deoxys, 0, 0
- song mus_rg_vs_mewtwo, 0, 0
- song mus_rg_vs_legend, 0, 0
- song mus_rg_encounter_gym_leader, 0, 0
- song mus_rg_encounter_deoxys, 0, 0
- song mus_rg_trainer_tower, 0, 0
- song mus_rg_slow_pallet, 0, 0
- song mus_rg_teachy_tv_menu, 0, 0
- song ph_trap_blend, 2, 2
- song ph_trap_held, 2, 2
- song ph_trap_solo, 2, 2
- song ph_face_blend, 2, 2
- song ph_face_held, 2, 2
- song ph_face_solo, 2, 2
- song ph_cloth_blend, 2, 2
- song ph_cloth_held, 2, 2
- song ph_cloth_solo, 2, 2
- song ph_dress_blend, 2, 2
- song ph_dress_held, 2, 2
- song ph_dress_solo, 2, 2
- song ph_fleece_blend, 2, 2
- song ph_fleece_held, 2, 2
- song ph_fleece_solo, 2, 2
- song ph_kit_blend, 2, 2
- song ph_kit_held, 2, 2
- song ph_kit_solo, 2, 2
- song ph_price_blend, 2, 2
- song ph_price_held, 2, 2
- song ph_price_solo, 2, 2
- song ph_lot_blend, 2, 2
- song ph_lot_held, 2, 2
- song ph_lot_solo, 2, 2
- song ph_goat_blend, 2, 2
- song ph_goat_held, 2, 2
- song ph_goat_solo, 2, 2
- song ph_thought_blend, 2, 2
- song ph_thought_held, 2, 2
- song ph_thought_solo, 2, 2
- song ph_choice_blend, 2, 2
- song ph_choice_held, 2, 2
- song ph_choice_solo, 2, 2
- song ph_mouth_blend, 2, 2
- song ph_mouth_held, 2, 2
- song ph_mouth_solo, 2, 2
- song ph_foot_blend, 2, 2
- song ph_foot_held, 2, 2
- song ph_foot_solo, 2, 2
- song ph_goose_blend, 2, 2
- song ph_goose_held, 2, 2
- song ph_goose_solo, 2, 2
- song ph_strut_blend, 2, 2
- song ph_strut_held, 2, 2
- song ph_strut_solo, 2, 2
- song ph_cure_blend, 2, 2
- song ph_cure_held, 2, 2
- song ph_cure_solo, 2, 2
- song ph_nurse_blend, 2, 2
- song ph_nurse_held, 2, 2
- song ph_nurse_solo, 2, 2
+ song mus_dummy, MUSIC_PLAYER_BGM, 0
+ song se_use_item, MUSIC_PLAYER_SE1, 1
+ song se_pc_login, MUSIC_PLAYER_SE1, 1
+ song se_pc_off, MUSIC_PLAYER_SE1, 1
+ song se_pc_on, MUSIC_PLAYER_SE1, 1
+ song se_select, MUSIC_PLAYER_SE2, 2
+ song se_win_open, MUSIC_PLAYER_SE1, 1
+ song se_wall_hit, MUSIC_PLAYER_SE2, 2
+ song se_door, MUSIC_PLAYER_SE1, 1
+ song se_exit, MUSIC_PLAYER_SE1, 1
+ song se_ledge, MUSIC_PLAYER_SE1, 1
+ song se_bike_bell, MUSIC_PLAYER_SE1, 1
+ song se_not_effective, MUSIC_PLAYER_SE1, 1
+ song se_effective, MUSIC_PLAYER_SE1, 1
+ song se_super_effective, MUSIC_PLAYER_SE1, 1
+ song se_ball_open, MUSIC_PLAYER_SE1, 1
+ song se_faint, MUSIC_PLAYER_SE1, 1
+ song se_flee, MUSIC_PLAYER_SE1, 1
+ song se_sliding_door, MUSIC_PLAYER_SE1, 1
+ song se_ship, MUSIC_PLAYER_SE1, 1
+ song se_bang, MUSIC_PLAYER_SE1, 1
+ song se_pin, MUSIC_PLAYER_SE1, 1
+ song se_boo, MUSIC_PLAYER_SE1, 1
+ song se_ball, MUSIC_PLAYER_SE1, 1
+ song se_contest_place, MUSIC_PLAYER_SE2, 2
+ song se_a, MUSIC_PLAYER_SE1, 1
+ song se_i, MUSIC_PLAYER_SE1, 1
+ song se_u, MUSIC_PLAYER_SE1, 1
+ song se_e, MUSIC_PLAYER_SE1, 1
+ song se_o, MUSIC_PLAYER_SE1, 1
+ song se_n, MUSIC_PLAYER_SE1, 1
+ song se_success, MUSIC_PLAYER_SE1, 1
+ song se_failure, MUSIC_PLAYER_SE1, 1
+ song se_exp, MUSIC_PLAYER_SE1, 1
+ song se_bike_hop, MUSIC_PLAYER_SE1, 1
+ song se_switch, MUSIC_PLAYER_SE1, 1
+ song se_click, MUSIC_PLAYER_SE1, 1
+ song se_fu_zaku, MUSIC_PLAYER_SE1, 1
+ song se_contest_condition_lose, MUSIC_PLAYER_SE1, 1
+ song se_lavaridge_fall_warp, MUSIC_PLAYER_SE1, 1
+ song se_ice_stairs, MUSIC_PLAYER_SE1, 1
+ song se_ice_break, MUSIC_PLAYER_SE1, 1
+ song se_ice_crack, MUSIC_PLAYER_SE1, 1
+ song se_fall, MUSIC_PLAYER_SE1, 1
+ song se_unlock, MUSIC_PLAYER_SE2, 2
+ song se_warp_in, MUSIC_PLAYER_SE1, 1
+ song se_warp_out, MUSIC_PLAYER_SE1, 1
+ song se_repel, MUSIC_PLAYER_SE1, 1
+ song se_rotating_gate, MUSIC_PLAYER_SE1, 1
+ song se_truck_move, MUSIC_PLAYER_SE1, 1
+ song se_truck_stop, MUSIC_PLAYER_SE1, 1
+ song se_truck_unload, MUSIC_PLAYER_SE2, 2
+ song se_truck_door, MUSIC_PLAYER_SE1, 1
+ song se_berry_blender, MUSIC_PLAYER_SE2, 2
+ song se_card, MUSIC_PLAYER_SE1, 1
+ song se_save, MUSIC_PLAYER_SE1, 1
+ song se_ball_bounce_1, MUSIC_PLAYER_SE1, 1
+ song se_ball_bounce_2, MUSIC_PLAYER_SE1, 1
+ song se_ball_bounce_3, MUSIC_PLAYER_SE1, 1
+ song se_ball_bounce_4, MUSIC_PLAYER_SE1, 1
+ song se_ball_trade, MUSIC_PLAYER_SE2, 2
+ song se_ball_throw, MUSIC_PLAYER_SE1, 1
+ song se_note_c, MUSIC_PLAYER_SE2, 2
+ song se_note_d, MUSIC_PLAYER_SE2, 2
+ song se_note_e, MUSIC_PLAYER_SE2, 2
+ song se_note_f, MUSIC_PLAYER_SE2, 2
+ song se_note_g, MUSIC_PLAYER_SE2, 2
+ song se_note_a, MUSIC_PLAYER_SE2, 2
+ song se_note_b, MUSIC_PLAYER_SE2, 2
+ song se_note_c_high, MUSIC_PLAYER_SE2, 2
+ song se_puddle, MUSIC_PLAYER_SE2, 2
+ song se_bridge_walk, MUSIC_PLAYER_SE2, 2
+ song se_itemfinder, MUSIC_PLAYER_SE1, 1
+ song se_ding_dong, MUSIC_PLAYER_SE1, 1
+ song se_balloon_red, MUSIC_PLAYER_SE2, 2
+ song se_balloon_blue, MUSIC_PLAYER_SE2, 2
+ song se_balloon_yellow, MUSIC_PLAYER_SE2, 2
+ song se_breakable_door, MUSIC_PLAYER_SE2, 2
+ song se_mud_ball, MUSIC_PLAYER_SE2, 2
+ song se_field_poison, MUSIC_PLAYER_SE1, 1
+ song se_escalator, MUSIC_PLAYER_SE1, 1
+ song se_thunderstorm, MUSIC_PLAYER_SE3, 3
+ song se_thunderstorm_stop, MUSIC_PLAYER_SE3, 3
+ song se_downpour, MUSIC_PLAYER_SE3, 3
+ song se_downpour_stop, MUSIC_PLAYER_SE3, 3
+ song se_rain, MUSIC_PLAYER_SE3, 3
+ song se_rain_stop, MUSIC_PLAYER_SE3, 3
+ song se_thunder, MUSIC_PLAYER_SE1, 1
+ song se_thunder2, MUSIC_PLAYER_SE1, 1
+ song se_elevator, MUSIC_PLAYER_SE1, 1
+ song se_low_health, MUSIC_PLAYER_SE3, 3
+ song se_exp_max, MUSIC_PLAYER_SE1, 1
+ song se_roulette_ball, MUSIC_PLAYER_SE2, 2
+ song se_roulette_ball2, MUSIC_PLAYER_SE2, 2
+ song se_taillow_wing_flap, MUSIC_PLAYER_SE1, 1
+ song se_shop, MUSIC_PLAYER_SE1, 1
+ song se_contest_heart, MUSIC_PLAYER_SE1, 1
+ song se_contest_curtain_rise, MUSIC_PLAYER_SE1, 1
+ song se_contest_curtain_fall, MUSIC_PLAYER_SE1, 1
+ song se_contest_icon_change, MUSIC_PLAYER_SE1, 1
+ song se_contest_icon_clear, MUSIC_PLAYER_SE1, 1
+ song se_contest_mons_turn, MUSIC_PLAYER_SE1, 1
+ song se_shiny, MUSIC_PLAYER_SE1, 1
+ song se_intro_blast, MUSIC_PLAYER_SE1, 1
+ song se_mugshot, MUSIC_PLAYER_SE1, 1
+ song se_applause, MUSIC_PLAYER_SE1, 1
+ song se_vend, MUSIC_PLAYER_SE1, 1
+ song se_orb, MUSIC_PLAYER_SE1, 1
+ song se_dex_scroll, MUSIC_PLAYER_SE1, 1
+ song se_dex_page, MUSIC_PLAYER_SE1, 1
+ song se_pokenav_on, MUSIC_PLAYER_SE1, 1
+ song se_pokenav_off, MUSIC_PLAYER_SE1, 1
+ song se_dex_search, MUSIC_PLAYER_SE1, 1
+ song se_egg_hatch, MUSIC_PLAYER_SE1, 1
+ song se_ball_tray_enter, MUSIC_PLAYER_SE1, 1
+ song se_ball_tray_ball, MUSIC_PLAYER_SE1, 1
+ song se_ball_tray_exit, MUSIC_PLAYER_SE2, 2
+ song se_glass_flute, MUSIC_PLAYER_SE1, 1
+ song se_m_thunderbolt, MUSIC_PLAYER_SE2, 2
+ song se_m_thunderbolt2, MUSIC_PLAYER_SE1, 1
+ song se_m_harden, MUSIC_PLAYER_SE1, 1
+ song se_m_nightmare, MUSIC_PLAYER_SE1, 1
+ song se_m_vital_throw, MUSIC_PLAYER_SE1, 1
+ song se_m_vital_throw2, MUSIC_PLAYER_SE1, 1
+ song se_m_bubble, MUSIC_PLAYER_SE1, 1
+ song se_m_bubble2, MUSIC_PLAYER_SE1, 1
+ song se_m_bubble3, MUSIC_PLAYER_SE1, 1
+ song se_m_rain_dance, MUSIC_PLAYER_SE1, 1
+ song se_m_cut, MUSIC_PLAYER_SE1, 1
+ song se_m_string_shot, MUSIC_PLAYER_SE1, 1
+ song se_m_string_shot2, MUSIC_PLAYER_SE1, 1
+ song se_m_rock_throw, MUSIC_PLAYER_SE1, 1
+ song se_m_gust, MUSIC_PLAYER_SE2, 2
+ song se_m_gust2, MUSIC_PLAYER_SE2, 2
+ song se_m_double_slap, MUSIC_PLAYER_SE1, 1
+ song se_m_double_team, MUSIC_PLAYER_SE1, 1
+ song se_m_razor_wind, MUSIC_PLAYER_SE1, 1
+ song se_m_icy_wind, MUSIC_PLAYER_SE1, 1
+ song se_m_thunder_wave, MUSIC_PLAYER_SE1, 1
+ song se_m_comet_punch, MUSIC_PLAYER_SE1, 1
+ song se_m_mega_kick, MUSIC_PLAYER_SE1, 1
+ song se_m_mega_kick2, MUSIC_PLAYER_SE1, 1
+ song se_m_crabhammer, MUSIC_PLAYER_SE1, 1
+ song se_m_jump_kick, MUSIC_PLAYER_SE1, 1
+ song se_m_flame_wheel, MUSIC_PLAYER_SE1, 1
+ song se_m_flame_wheel2, MUSIC_PLAYER_SE1, 1
+ song se_m_flamethrower, MUSIC_PLAYER_SE1, 1
+ song se_m_fire_punch, MUSIC_PLAYER_SE1, 1
+ song se_m_toxic, MUSIC_PLAYER_SE1, 1
+ song se_m_sacred_fire, MUSIC_PLAYER_SE1, 1
+ song se_m_sacred_fire2, MUSIC_PLAYER_SE2, 2
+ song se_m_ember, MUSIC_PLAYER_SE1, 1
+ song se_m_take_down, MUSIC_PLAYER_SE2, 2
+ song se_m_blizzard, MUSIC_PLAYER_SE1, 1
+ song se_m_blizzard2, MUSIC_PLAYER_SE1, 1
+ song se_m_scratch, MUSIC_PLAYER_SE1, 1
+ song se_m_vicegrip, MUSIC_PLAYER_SE1, 1
+ song se_m_wing_attack, MUSIC_PLAYER_SE1, 1
+ song se_m_fly, MUSIC_PLAYER_SE1, 1
+ song se_m_sand_attack, MUSIC_PLAYER_SE1, 1
+ song se_m_razor_wind2, MUSIC_PLAYER_SE1, 1
+ song se_m_bite, MUSIC_PLAYER_SE1, 1
+ song se_m_headbutt, MUSIC_PLAYER_SE1, 1
+ song se_m_surf, MUSIC_PLAYER_SE1, 1
+ song se_m_hydro_pump, MUSIC_PLAYER_SE1, 1
+ song se_m_whirlpool, MUSIC_PLAYER_SE1, 1
+ song se_m_horn_attack, MUSIC_PLAYER_SE1, 1
+ song se_m_tail_whip, MUSIC_PLAYER_SE2, 2
+ song se_m_mist, MUSIC_PLAYER_SE1, 1
+ song se_m_poison_powder, MUSIC_PLAYER_SE1, 1
+ song se_m_bind, MUSIC_PLAYER_SE2, 2
+ song se_m_dragon_rage, MUSIC_PLAYER_SE1, 1
+ song se_m_sing, MUSIC_PLAYER_SE1, 1
+ song se_m_perish_song, MUSIC_PLAYER_SE1, 1
+ song se_m_pay_day, MUSIC_PLAYER_SE1, 1
+ song se_m_dig, MUSIC_PLAYER_SE1, 1
+ song se_m_dizzy_punch, MUSIC_PLAYER_SE1, 1
+ song se_m_self_destruct, MUSIC_PLAYER_SE1, 1
+ song se_m_explosion, MUSIC_PLAYER_SE1, 1
+ song se_m_absorb_2, MUSIC_PLAYER_SE1, 1
+ song se_m_absorb, MUSIC_PLAYER_SE1, 1
+ song se_m_screech, MUSIC_PLAYER_SE1, 1
+ song se_m_bubble_beam, MUSIC_PLAYER_SE1, 1
+ song se_m_bubble_beam2, MUSIC_PLAYER_SE1, 1
+ song se_m_supersonic, MUSIC_PLAYER_SE1, 1
+ song se_m_belly_drum, MUSIC_PLAYER_SE1, 1
+ song se_m_metronome, MUSIC_PLAYER_SE1, 1
+ song se_m_bonemerang, MUSIC_PLAYER_SE1, 1
+ song se_m_lick, MUSIC_PLAYER_SE1, 1
+ song se_m_psybeam, MUSIC_PLAYER_SE1, 1
+ song se_m_faint_attack, MUSIC_PLAYER_SE1, 1
+ song se_m_swords_dance, MUSIC_PLAYER_SE1, 1
+ song se_m_leer, MUSIC_PLAYER_SE1, 1
+ song se_m_swagger, MUSIC_PLAYER_SE1, 1
+ song se_m_swagger2, MUSIC_PLAYER_SE1, 1
+ song se_m_heal_bell, MUSIC_PLAYER_SE1, 1
+ song se_m_confuse_ray, MUSIC_PLAYER_SE1, 1
+ song se_m_snore, MUSIC_PLAYER_SE1, 1
+ song se_m_brick_break, MUSIC_PLAYER_SE1, 1
+ song se_m_giga_drain, MUSIC_PLAYER_SE1, 1
+ song se_m_psybeam2, MUSIC_PLAYER_SE1, 1
+ song se_m_solar_beam, MUSIC_PLAYER_SE2, 2
+ song se_m_petal_dance, MUSIC_PLAYER_SE1, 1
+ song se_m_teleport, MUSIC_PLAYER_SE1, 1
+ song se_m_minimize, MUSIC_PLAYER_SE1, 1
+ song se_m_sketch, MUSIC_PLAYER_SE1, 1
+ song se_m_swift, MUSIC_PLAYER_SE1, 1
+ song se_m_reflect, MUSIC_PLAYER_SE1, 1
+ song se_m_barrier, MUSIC_PLAYER_SE1, 1
+ song se_m_detect, MUSIC_PLAYER_SE2, 2
+ song se_m_lock_on, MUSIC_PLAYER_SE1, 1
+ song se_m_moonlight, MUSIC_PLAYER_SE1, 1
+ song se_m_charm, MUSIC_PLAYER_SE1, 1
+ song se_m_charge, MUSIC_PLAYER_SE1, 1
+ song se_m_strength, MUSIC_PLAYER_SE1, 1
+ song se_m_hyper_beam, MUSIC_PLAYER_SE1, 1
+ song se_m_waterfall, MUSIC_PLAYER_SE1, 1
+ song se_m_reversal, MUSIC_PLAYER_SE1, 1
+ song se_m_acid_armor, MUSIC_PLAYER_SE1, 1
+ song se_m_sandstorm, MUSIC_PLAYER_SE1, 1
+ song se_m_tri_attack, MUSIC_PLAYER_SE1, 1
+ song se_m_tri_attack2, MUSIC_PLAYER_SE1, 1
+ song se_m_encore, MUSIC_PLAYER_SE1, 1
+ song se_m_encore2, MUSIC_PLAYER_SE2, 2
+ song se_m_baton_pass, MUSIC_PLAYER_SE1, 1
+ song se_m_milk_drink, MUSIC_PLAYER_SE1, 1
+ song se_m_attract, MUSIC_PLAYER_SE1, 1
+ song se_m_attract2, MUSIC_PLAYER_SE1, 1
+ song se_m_morning_sun, MUSIC_PLAYER_SE1, 1
+ song se_m_flatter, MUSIC_PLAYER_SE1, 1
+ song se_m_sand_tomb, MUSIC_PLAYER_SE1, 1
+ song se_m_grasswhistle, MUSIC_PLAYER_SE1, 1
+ song se_m_spit_up, MUSIC_PLAYER_SE1, 1
+ song se_m_dive, MUSIC_PLAYER_SE1, 1
+ song se_m_earthquake, MUSIC_PLAYER_SE2, 2
+ song se_m_twister, MUSIC_PLAYER_SE2, 2
+ song se_m_sweet_scent, MUSIC_PLAYER_SE1, 1
+ song se_m_yawn, MUSIC_PLAYER_SE1, 1
+ song se_m_sky_uppercut, MUSIC_PLAYER_SE2, 2
+ song se_m_stat_increase, MUSIC_PLAYER_SE1, 1
+ song se_m_heat_wave, MUSIC_PLAYER_SE1, 1
+ song se_m_uproar, MUSIC_PLAYER_SE1, 1
+ song se_m_hail, MUSIC_PLAYER_SE1, 1
+ song se_m_cosmic_power, MUSIC_PLAYER_SE2, 2
+ song se_m_teeter_dance, MUSIC_PLAYER_SE1, 1
+ song se_m_stat_decrease, MUSIC_PLAYER_SE1, 1
+ song se_m_haze, MUSIC_PLAYER_SE1, 1
+ song se_m_hyper_beam2, MUSIC_PLAYER_SE1, 1
+ song se_rg_door, MUSIC_PLAYER_SE1, 1
+ song se_rg_card_flip, MUSIC_PLAYER_SE1, 1
+ song se_rg_card_flipping, MUSIC_PLAYER_SE1, 1
+ song se_rg_card_open, MUSIC_PLAYER_SE1, 1
+ song se_rg_bag_cursor, MUSIC_PLAYER_SE1, 1
+ song se_rg_bag_pocket, MUSIC_PLAYER_SE1, 1
+ song se_rg_ball_click, MUSIC_PLAYER_SE1, 1
+ song se_rg_shop, MUSIC_PLAYER_SE1, 1
+ song se_rg_ss_anne_horn, MUSIC_PLAYER_SE1, 1
+ song se_rg_help_open, MUSIC_PLAYER_SE1, 1
+ song se_rg_help_close, MUSIC_PLAYER_SE1, 1
+ song se_rg_help_error, MUSIC_PLAYER_SE1, 1
+ song se_rg_deoxys_move, MUSIC_PLAYER_SE1, 1
+ song se_rg_poke_jump_success, MUSIC_PLAYER_SE1, 1
+ song se_rg_poke_jump_failure, MUSIC_PLAYER_SE1, 1
+ song se_pokenav_call, MUSIC_PLAYER_SE1, 1
+ song se_pokenav_hang_up, MUSIC_PLAYER_SE1, 1
+ song se_arena_timeup1, MUSIC_PLAYER_SE1, 1
+ song se_arena_timeup2, MUSIC_PLAYER_SE1, 1
+ song se_pike_curtain_close, MUSIC_PLAYER_SE1, 1
+ song se_pike_curtain_open, MUSIC_PLAYER_SE1, 1
+ song se_sudowoodo_shake, MUSIC_PLAYER_SE1, 1
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song dummy_song_header, MUSIC_PLAYER_BGM, 0
+ song mus_littleroot_test, MUSIC_PLAYER_BGM, 0
+ song mus_gsc_route38, MUSIC_PLAYER_BGM, 0
+ song mus_caught, MUSIC_PLAYER_BGM, 0
+ song mus_victory_wild, MUSIC_PLAYER_BGM, 0
+ song mus_victory_gym_leader, MUSIC_PLAYER_BGM, 0
+ song mus_victory_league, MUSIC_PLAYER_BGM, 0
+ song mus_c_comm_center, MUSIC_PLAYER_BGM, 0
+ song mus_gsc_pewter, MUSIC_PLAYER_BGM, 0
+ song mus_c_vs_legend_beast, MUSIC_PLAYER_BGM, 0
+ song mus_route101, MUSIC_PLAYER_BGM, 0
+ song mus_route110, MUSIC_PLAYER_BGM, 0
+ song mus_route120, MUSIC_PLAYER_BGM, 0
+ song mus_petalburg, MUSIC_PLAYER_BGM, 0
+ song mus_oldale, MUSIC_PLAYER_BGM, 0
+ song mus_gym, MUSIC_PLAYER_BGM, 0
+ song mus_surf, MUSIC_PLAYER_BGM, 0
+ song mus_petalburg_woods, MUSIC_PLAYER_BGM, 0
+ song mus_level_up, MUSIC_PLAYER_SE2, 2
+ song mus_heal, MUSIC_PLAYER_SE2, 2
+ song mus_obtain_badge, MUSIC_PLAYER_SE2, 2
+ song mus_obtain_item, MUSIC_PLAYER_SE2, 2
+ song mus_evolved, MUSIC_PLAYER_SE2, 2
+ song mus_obtain_tmhm, MUSIC_PLAYER_SE2, 2
+ song mus_lilycove_museum, MUSIC_PLAYER_BGM, 0
+ song mus_route122, MUSIC_PLAYER_BGM, 0
+ song mus_oceanic_museum, MUSIC_PLAYER_BGM, 0
+ song mus_evolution_intro, MUSIC_PLAYER_SE2, 2
+ song mus_evolution, MUSIC_PLAYER_BGM, 0
+ song mus_move_deleted, MUSIC_PLAYER_SE2, 2
+ song mus_encounter_girl, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_male, MUSIC_PLAYER_BGM, 0
+ song mus_abandoned_ship, MUSIC_PLAYER_BGM, 0
+ song mus_fortree, MUSIC_PLAYER_BGM, 0
+ song mus_birch_lab, MUSIC_PLAYER_BGM, 0
+ song mus_b_tower_rs, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_swimmer, MUSIC_PLAYER_BGM, 0
+ song mus_cave_of_origin, MUSIC_PLAYER_BGM, 0
+ song mus_obtain_berry, MUSIC_PLAYER_SE2, 2
+ song mus_awaken_legend, MUSIC_PLAYER_SE2, 2
+ song mus_slots_jackpot, MUSIC_PLAYER_SE2, 2
+ song mus_slots_win, MUSIC_PLAYER_SE2, 2
+ song mus_too_bad, MUSIC_PLAYER_SE2, 2
+ song mus_roulette, MUSIC_PLAYER_BGM, 0
+ song mus_link_contest_p1, MUSIC_PLAYER_BGM, 0
+ song mus_link_contest_p2, MUSIC_PLAYER_BGM, 0
+ song mus_link_contest_p3, MUSIC_PLAYER_BGM, 0
+ song mus_link_contest_p4, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_rich, MUSIC_PLAYER_BGM, 0
+ song mus_verdanturf, MUSIC_PLAYER_BGM, 0
+ song mus_rustboro, MUSIC_PLAYER_BGM, 0
+ song mus_poke_center, MUSIC_PLAYER_BGM, 0
+ song mus_route104, MUSIC_PLAYER_BGM, 0
+ song mus_route119, MUSIC_PLAYER_BGM, 0
+ song mus_cycling, MUSIC_PLAYER_BGM, 0
+ song mus_poke_mart, MUSIC_PLAYER_BGM, 0
+ song mus_littleroot, MUSIC_PLAYER_BGM, 0
+ song mus_mt_chimney, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_female, MUSIC_PLAYER_BGM, 0
+ song mus_lilycove, MUSIC_PLAYER_BGM, 0
+ song mus_route111, MUSIC_PLAYER_BGM, 0
+ song mus_help, MUSIC_PLAYER_BGM, 0
+ song mus_underwater, MUSIC_PLAYER_BGM, 0
+ song mus_victory_trainer, MUSIC_PLAYER_BGM, 0
+ song mus_title, MUSIC_PLAYER_BGM, 0
+ song mus_intro, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_may, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_intense, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_cool, MUSIC_PLAYER_BGM, 0
+ song mus_route113, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_aqua, MUSIC_PLAYER_BGM, 0
+ song mus_follow_me, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_brendan, MUSIC_PLAYER_BGM, 0
+ song mus_ever_grande, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_suspicious, MUSIC_PLAYER_BGM, 0
+ song mus_victory_aqua_magma, MUSIC_PLAYER_BGM, 0
+ song mus_cable_car, MUSIC_PLAYER_BGM, 0
+ song mus_game_corner, MUSIC_PLAYER_BGM, 0
+ song mus_dewford, MUSIC_PLAYER_BGM, 0
+ song mus_safari_zone, MUSIC_PLAYER_BGM, 0
+ song mus_victory_road, MUSIC_PLAYER_BGM, 0
+ song mus_aqua_magma_hideout, MUSIC_PLAYER_BGM, 0
+ song mus_sailing, MUSIC_PLAYER_BGM, 0
+ song mus_mt_pyre, MUSIC_PLAYER_BGM, 0
+ song mus_slateport, MUSIC_PLAYER_BGM, 0
+ song mus_mt_pyre_exterior, MUSIC_PLAYER_BGM, 0
+ song mus_school, MUSIC_PLAYER_BGM, 0
+ song mus_hall_of_fame, MUSIC_PLAYER_BGM, 0
+ song mus_fallarbor, MUSIC_PLAYER_BGM, 0
+ song mus_sealed_chamber, MUSIC_PLAYER_BGM, 0
+ song mus_contest_winner, MUSIC_PLAYER_BGM, 0
+ song mus_contest, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_magma, MUSIC_PLAYER_BGM, 0
+ song mus_intro_battle, MUSIC_PLAYER_BGM, 0
+ song mus_abnormal_weather, MUSIC_PLAYER_BGM, 0
+ song mus_weather_groudon, MUSIC_PLAYER_BGM, 0
+ song mus_sootopolis, MUSIC_PLAYER_BGM, 0
+ song mus_contest_results, MUSIC_PLAYER_BGM, 0
+ song mus_hall_of_fame_room, MUSIC_PLAYER_BGM, 0
+ song mus_trick_house, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_twins, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_elite_four, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_hiker, MUSIC_PLAYER_BGM, 0
+ song mus_contest_lobby, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_interviewer, MUSIC_PLAYER_BGM, 0
+ song mus_encounter_champion, MUSIC_PLAYER_BGM, 0
+ song mus_credits, MUSIC_PLAYER_BGM, 0
+ song mus_end, MUSIC_PLAYER_BGM, 0
+ song mus_b_frontier, MUSIC_PLAYER_BGM, 0
+ song mus_b_arena, MUSIC_PLAYER_BGM, 0
+ song mus_obtain_b_points, MUSIC_PLAYER_SE2, 2
+ song mus_register_match_call, MUSIC_PLAYER_SE2, 2
+ song mus_b_pyramid, MUSIC_PLAYER_BGM, 0
+ song mus_b_pyramid_top, MUSIC_PLAYER_BGM, 0
+ song mus_b_palace, MUSIC_PLAYER_BGM, 0
+ song mus_rayquaza_appears, MUSIC_PLAYER_BGM, 0
+ song mus_b_tower, MUSIC_PLAYER_BGM, 0
+ song mus_obtain_symbol, MUSIC_PLAYER_SE2, 2
+ song mus_b_dome, MUSIC_PLAYER_BGM, 0
+ song mus_b_pike, MUSIC_PLAYER_BGM, 0
+ song mus_b_factory, MUSIC_PLAYER_BGM, 0
+ song mus_vs_rayquaza, MUSIC_PLAYER_BGM, 0
+ song mus_vs_frontier_brain, MUSIC_PLAYER_BGM, 0
+ song mus_vs_mew, MUSIC_PLAYER_BGM, 0
+ song mus_b_dome_lobby, MUSIC_PLAYER_BGM, 0
+ song mus_vs_wild, MUSIC_PLAYER_BGM, 0
+ song mus_vs_aqua_magma, MUSIC_PLAYER_BGM, 0
+ song mus_vs_trainer, MUSIC_PLAYER_BGM, 0
+ song mus_vs_gym_leader, MUSIC_PLAYER_BGM, 0
+ song mus_vs_champion, MUSIC_PLAYER_BGM, 0
+ song mus_vs_regi, MUSIC_PLAYER_BGM, 0
+ song mus_vs_kyogre_groudon, MUSIC_PLAYER_BGM, 0
+ song mus_vs_rival, MUSIC_PLAYER_BGM, 0
+ song mus_vs_elite_four, MUSIC_PLAYER_BGM, 0
+ song mus_vs_aqua_magma_leader, MUSIC_PLAYER_BGM, 0
+ song mus_rg_follow_me, MUSIC_PLAYER_BGM, 0
+ song mus_rg_game_corner, MUSIC_PLAYER_BGM, 0
+ song mus_rg_rocket_hideout, MUSIC_PLAYER_BGM, 0
+ song mus_rg_gym, MUSIC_PLAYER_BGM, 0
+ song mus_rg_jigglypuff, MUSIC_PLAYER_SE2, 2
+ song mus_rg_intro_fight, MUSIC_PLAYER_BGM, 0
+ song mus_rg_title, MUSIC_PLAYER_BGM, 0
+ song mus_rg_cinnabar, MUSIC_PLAYER_BGM, 0
+ song mus_rg_lavender, MUSIC_PLAYER_BGM, 0
+ song mus_rg_heal, MUSIC_PLAYER_BGM, 0
+ song mus_rg_cycling, MUSIC_PLAYER_BGM, 0
+ song mus_rg_encounter_rocket, MUSIC_PLAYER_BGM, 0
+ song mus_rg_encounter_girl, MUSIC_PLAYER_BGM, 0
+ song mus_rg_encounter_boy, MUSIC_PLAYER_BGM, 0
+ song mus_rg_hall_of_fame, MUSIC_PLAYER_BGM, 0
+ song mus_rg_viridian_forest, MUSIC_PLAYER_BGM, 0
+ song mus_rg_mt_moon, MUSIC_PLAYER_BGM, 0
+ song mus_rg_poke_mansion, MUSIC_PLAYER_BGM, 0
+ song mus_rg_credits, MUSIC_PLAYER_BGM, 0
+ song mus_rg_route1, MUSIC_PLAYER_BGM, 0
+ song mus_rg_route24, MUSIC_PLAYER_BGM, 0
+ song mus_rg_route3, MUSIC_PLAYER_BGM, 0
+ song mus_rg_route11, MUSIC_PLAYER_BGM, 0
+ song mus_rg_victory_road, MUSIC_PLAYER_BGM, 0
+ song mus_rg_vs_gym_leader, MUSIC_PLAYER_BGM, 0
+ song mus_rg_vs_trainer, MUSIC_PLAYER_BGM, 0
+ song mus_rg_vs_wild, MUSIC_PLAYER_BGM, 0
+ song mus_rg_vs_champion, MUSIC_PLAYER_BGM, 0
+ song mus_rg_pallet, MUSIC_PLAYER_BGM, 0
+ song mus_rg_oak_lab, MUSIC_PLAYER_BGM, 0
+ song mus_rg_oak, MUSIC_PLAYER_BGM, 0
+ song mus_rg_poke_center, MUSIC_PLAYER_BGM, 0
+ song mus_rg_ss_anne, MUSIC_PLAYER_BGM, 0
+ song mus_rg_surf, MUSIC_PLAYER_BGM, 0
+ song mus_rg_poke_tower, MUSIC_PLAYER_BGM, 0
+ song mus_rg_silph, MUSIC_PLAYER_BGM, 0
+ song mus_rg_fuchsia, MUSIC_PLAYER_BGM, 0
+ song mus_rg_celadon, MUSIC_PLAYER_BGM, 0
+ song mus_rg_victory_trainer, MUSIC_PLAYER_BGM, 0
+ song mus_rg_victory_wild, MUSIC_PLAYER_BGM, 0
+ song mus_rg_victory_gym_leader, MUSIC_PLAYER_BGM, 0
+ song mus_rg_vermillion, MUSIC_PLAYER_BGM, 0
+ song mus_rg_pewter, MUSIC_PLAYER_BGM, 0
+ song mus_rg_encounter_rival, MUSIC_PLAYER_BGM, 0
+ song mus_rg_rival_exit, MUSIC_PLAYER_BGM, 0
+ song mus_rg_dex_rating, MUSIC_PLAYER_SE2, 2
+ song mus_rg_obtain_key_item, MUSIC_PLAYER_SE2, 2
+ song mus_rg_caught_intro, MUSIC_PLAYER_SE2, 2
+ song mus_rg_photo, MUSIC_PLAYER_SE2, 2
+ song mus_rg_game_freak, MUSIC_PLAYER_BGM, 0
+ song mus_rg_caught, MUSIC_PLAYER_BGM, 0
+ song mus_rg_new_game_instruct, MUSIC_PLAYER_BGM, 0
+ song mus_rg_new_game_intro, MUSIC_PLAYER_BGM, 0
+ song mus_rg_new_game_exit, MUSIC_PLAYER_BGM, 0
+ song mus_rg_poke_jump, MUSIC_PLAYER_BGM, 0
+ song mus_rg_union_room, MUSIC_PLAYER_BGM, 0
+ song mus_rg_net_center, MUSIC_PLAYER_BGM, 0
+ song mus_rg_mystery_gift, MUSIC_PLAYER_BGM, 0
+ song mus_rg_berry_pick, MUSIC_PLAYER_BGM, 0
+ song mus_rg_sevii_cave, MUSIC_PLAYER_BGM, 0
+ song mus_rg_teachy_tv_show, MUSIC_PLAYER_BGM, 0
+ song mus_rg_sevii_route, MUSIC_PLAYER_BGM, 0
+ song mus_rg_sevii_dungeon, MUSIC_PLAYER_BGM, 0
+ song mus_rg_sevii_123, MUSIC_PLAYER_BGM, 0
+ song mus_rg_sevii_45, MUSIC_PLAYER_BGM, 0
+ song mus_rg_sevii_67, MUSIC_PLAYER_BGM, 0
+ song mus_rg_poke_flute, MUSIC_PLAYER_SE2, 2
+ song mus_rg_vs_deoxys, MUSIC_PLAYER_BGM, 0
+ song mus_rg_vs_mewtwo, MUSIC_PLAYER_BGM, 0
+ song mus_rg_vs_legend, MUSIC_PLAYER_BGM, 0
+ song mus_rg_encounter_gym_leader, MUSIC_PLAYER_BGM, 0
+ song mus_rg_encounter_deoxys, MUSIC_PLAYER_BGM, 0
+ song mus_rg_trainer_tower, MUSIC_PLAYER_BGM, 0
+ song mus_rg_slow_pallet, MUSIC_PLAYER_BGM, 0
+ song mus_rg_teachy_tv_menu, MUSIC_PLAYER_BGM, 0
+ song ph_trap_blend, MUSIC_PLAYER_SE2, 2
+ song ph_trap_held, MUSIC_PLAYER_SE2, 2
+ song ph_trap_solo, MUSIC_PLAYER_SE2, 2
+ song ph_face_blend, MUSIC_PLAYER_SE2, 2
+ song ph_face_held, MUSIC_PLAYER_SE2, 2
+ song ph_face_solo, MUSIC_PLAYER_SE2, 2
+ song ph_cloth_blend, MUSIC_PLAYER_SE2, 2
+ song ph_cloth_held, MUSIC_PLAYER_SE2, 2
+ song ph_cloth_solo, MUSIC_PLAYER_SE2, 2
+ song ph_dress_blend, MUSIC_PLAYER_SE2, 2
+ song ph_dress_held, MUSIC_PLAYER_SE2, 2
+ song ph_dress_solo, MUSIC_PLAYER_SE2, 2
+ song ph_fleece_blend, MUSIC_PLAYER_SE2, 2
+ song ph_fleece_held, MUSIC_PLAYER_SE2, 2
+ song ph_fleece_solo, MUSIC_PLAYER_SE2, 2
+ song ph_kit_blend, MUSIC_PLAYER_SE2, 2
+ song ph_kit_held, MUSIC_PLAYER_SE2, 2
+ song ph_kit_solo, MUSIC_PLAYER_SE2, 2
+ song ph_price_blend, MUSIC_PLAYER_SE2, 2
+ song ph_price_held, MUSIC_PLAYER_SE2, 2
+ song ph_price_solo, MUSIC_PLAYER_SE2, 2
+ song ph_lot_blend, MUSIC_PLAYER_SE2, 2
+ song ph_lot_held, MUSIC_PLAYER_SE2, 2
+ song ph_lot_solo, MUSIC_PLAYER_SE2, 2
+ song ph_goat_blend, MUSIC_PLAYER_SE2, 2
+ song ph_goat_held, MUSIC_PLAYER_SE2, 2
+ song ph_goat_solo, MUSIC_PLAYER_SE2, 2
+ song ph_thought_blend, MUSIC_PLAYER_SE2, 2
+ song ph_thought_held, MUSIC_PLAYER_SE2, 2
+ song ph_thought_solo, MUSIC_PLAYER_SE2, 2
+ song ph_choice_blend, MUSIC_PLAYER_SE2, 2
+ song ph_choice_held, MUSIC_PLAYER_SE2, 2
+ song ph_choice_solo, MUSIC_PLAYER_SE2, 2
+ song ph_mouth_blend, MUSIC_PLAYER_SE2, 2
+ song ph_mouth_held, MUSIC_PLAYER_SE2, 2
+ song ph_mouth_solo, MUSIC_PLAYER_SE2, 2
+ song ph_foot_blend, MUSIC_PLAYER_SE2, 2
+ song ph_foot_held, MUSIC_PLAYER_SE2, 2
+ song ph_foot_solo, MUSIC_PLAYER_SE2, 2
+ song ph_goose_blend, MUSIC_PLAYER_SE2, 2
+ song ph_goose_held, MUSIC_PLAYER_SE2, 2
+ song ph_goose_solo, MUSIC_PLAYER_SE2, 2
+ song ph_strut_blend, MUSIC_PLAYER_SE2, 2
+ song ph_strut_held, MUSIC_PLAYER_SE2, 2
+ song ph_strut_solo, MUSIC_PLAYER_SE2, 2
+ song ph_cure_blend, MUSIC_PLAYER_SE2, 2
+ song ph_cure_held, MUSIC_PLAYER_SE2, 2
+ song ph_cure_solo, MUSIC_PLAYER_SE2, 2
+ song ph_nurse_blend, MUSIC_PLAYER_SE2, 2
+ song ph_nurse_held, MUSIC_PLAYER_SE2, 2
+ song ph_nurse_solo, MUSIC_PLAYER_SE2, 2
.align 2
dummy_song_header:
diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c
index 1ab83e2c67..9612d544f6 100644
--- a/src/battle_ai_main.c
+++ b/src/battle_ai_main.c
@@ -4067,7 +4067,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru
bool32 isBattle1v1 = IsBattle1v1();
bool32 hasTwoOpponents = HasTwoOpponents(battlerAtk);
bool32 hasPartner = HasPartner(battlerAtk);
- bool32 moveTargetsBothOpponents = hasTwoOpponents && (gMovesInfo[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_ALL_BATTLERS));
+ bool32 moveTargetsBothOpponents = hasTwoOpponents && (GetMoveTarget(move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_ALL_BATTLERS));
u32 i;
// The AI should understand that while Dynamaxed, status moves function like Protect.
diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c
index ba78ce4679..1a393fc66f 100644
--- a/src/battle_ai_switch_items.c
+++ b/src/battle_ai_switch_items.c
@@ -386,7 +386,7 @@ static u32 FindMonWithMoveOfEffectiveness(u32 battler, u32 opposingBattler, uq4_
for (j = 0; j < MAX_MON_MOVES; j++)
{
move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
- if (move != MOVE_NONE && AI_GetMoveEffectiveness(move, battler, opposingBattler) >= effectiveness && gMovesInfo[move].power != 0)
+ if (move != MOVE_NONE && AI_GetMoveEffectiveness(move, battler, opposingBattler) >= effectiveness && GetMovePower(move) != 0)
return SetSwitchinAndSwitch(battler, i);
}
}
@@ -422,7 +422,7 @@ static bool32 ShouldSwitchIfAllMovesBad(u32 battler)
if (gAiLogicData->effectiveness[battler][opposingBattler][moveIndex] > UQ_4_12(0.0) && aiMove != MOVE_NONE
&& !CanAbilityAbsorbMove(battler, opposingBattler, gAiLogicData->abilities[opposingBattler], aiMove, GetBattleMoveType(aiMove), AI_CHECK)
&& !CanAbilityBlockMove(battler, opposingBattler, gBattleMons[battler].ability, gAiLogicData->abilities[opposingBattler], aiMove, AI_CHECK)
- && (!ALL_MOVES_BAD_STATUS_MOVES_BAD || gMovesInfo[aiMove].power != 0)) // If using ALL_MOVES_BAD_STATUS_MOVES_BAD, then need power to be non-zero
+ && (!ALL_MOVES_BAD_STATUS_MOVES_BAD || GetMovePower(aiMove) != 0)) // If using ALL_MOVES_BAD_STATUS_MOVES_BAD, then need power to be non-zero
return FALSE;
}
}
@@ -2418,6 +2418,9 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, enum SwitchType switchType)
if (bestMonId != PARTY_SIZE)
return bestMonId;
+ if (aceMonId != PARTY_SIZE && aliveCount == 0)
+ return aceMonId;
+
bestMonId = GetBestMonTypeMatchup(party, firstId, lastId, invalidMons, battler, opposingBattler);
if (bestMonId != PARTY_SIZE)
return bestMonId;
diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c
index 2b91741449..8ab0c83a92 100644
--- a/src/battle_ai_util.c
+++ b/src/battle_ai_util.c
@@ -4158,7 +4158,7 @@ bool32 AreMovesEquivalent(u32 battlerAtk, u32 battlerAtkPartner, u32 move, u32 p
// shared bits indicate they're meaningfully the same in some way
if (atkEffect & partnerEffect)
{
- if (gMovesInfo[move].target == MOVE_TARGET_SELECTED && gMovesInfo[partnerMove].target == MOVE_TARGET_SELECTED)
+ if (GetMoveTarget(move) == MOVE_TARGET_SELECTED && GetMoveTarget(partnerMove) == MOVE_TARGET_SELECTED)
{
if (battlerDef == gBattleStruct->moveTarget[battlerAtkPartner])
return TRUE;
@@ -4303,7 +4303,7 @@ bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u32
if (GetMoveEffect(move) == GetMoveEffect(partnerMove)
&& partnerMove != MOVE_NONE)
{
- if (gMovesInfo[move].target == MOVE_TARGET_SELECTED && gMovesInfo[partnerMove].target == MOVE_TARGET_SELECTED)
+ if (GetMoveTarget(move) == MOVE_TARGET_SELECTED && GetMoveTarget(partnerMove) == MOVE_TARGET_SELECTED)
{
return gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef;
}
@@ -4727,7 +4727,7 @@ bool32 IsRecycleEncouragedItem(u32 item)
static bool32 HasMoveThatChangesKOThreshold(u32 battlerId, u32 noOfHitsToFaint, u32 aiIsFaster)
{
- s32 i;
+ s32 i, j;
u16 *moves = GetMovesArray(battlerId);
for (i = 0; i < MAX_MON_MOVES; i++)
@@ -4739,16 +4739,21 @@ static bool32 HasMoveThatChangesKOThreshold(u32 battlerId, u32 noOfHitsToFaint,
if (GetMovePriority(moves[i]) > 0)
return TRUE;
- switch (gMovesInfo[moves[i]].additionalEffects[i].moveEffect)
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(moves[i]);
+ for (j = 0; j < additionalEffectCount; j++)
{
- case MOVE_EFFECT_SPD_MINUS_1:
- case MOVE_EFFECT_SPD_MINUS_2:
- {
- if(aiIsFaster)
- return TRUE;
- }
- default:
- break;
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(moves[i], j);
+ switch (additionalEffect->moveEffect)
+ {
+ case MOVE_EFFECT_SPD_MINUS_1:
+ case MOVE_EFFECT_SPD_MINUS_2:
+ {
+ if(aiIsFaster)
+ return TRUE;
+ }
+ default:
+ break;
+ }
}
}
}
diff --git a/src/battle_anim.c b/src/battle_anim.c
index 5aea35a05d..f08c1eaa8d 100644
--- a/src/battle_anim.c
+++ b/src/battle_anim.c
@@ -13,6 +13,7 @@
#include "graphics.h"
#include "main.h"
#include "malloc.h"
+#include "menu.h"
#include "m4a.h"
#include "palette.h"
#include "pokemon.h"
@@ -1569,10 +1570,7 @@ void LoadMoveBg(u16 bgId)
{
if (IsContest())
{
- void *decompressionBuffer = Alloc(0x800);
- const u32 *tilemap = gBattleAnimBackgroundTable[bgId].tilemap;
-
- DecompressDataWithHeaderWram(tilemap, decompressionBuffer);
+ void *decompressionBuffer = malloc_and_decompress(gBattleAnimBackgroundTable[bgId].tilemap, NULL);
RelocateBattleBgPal(GetBattleBgPaletteNum(), decompressionBuffer, 0x100, FALSE);
DmaCopy32(3, decompressionBuffer, (void *)BG_SCREEN_ADDR(26), 0x800);
DecompressDataWithHeaderVram(gBattleAnimBackgroundTable[bgId].image, (void *)BG_SCREEN_ADDR(4));
diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c
index 35cd31f331..4699f2008a 100644
--- a/src/battle_anim_effects_1.c
+++ b/src/battle_anim_effects_1.c
@@ -5189,7 +5189,7 @@ void AnimNeedleArmSpike(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
- if (gMovesInfo[gAnimMoveIndex].target == MOVE_TARGET_BOTH)
+ if (GetMoveTarget(gAnimMoveIndex) == MOVE_TARGET_BOTH)
{
SetAverageBattlerPositions(gBattleAnimAttacker, TRUE, &a, &b);
}
@@ -5201,7 +5201,7 @@ void AnimNeedleArmSpike(struct Sprite *sprite)
}
else
{
- if (gMovesInfo[gAnimMoveIndex].target == MOVE_TARGET_BOTH)
+ if (GetMoveTarget(gAnimMoveIndex) == MOVE_TARGET_BOTH)
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &a, &b);
}
diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c
index 58e6a17dc8..fff35b4073 100644
--- a/src/battle_anim_new.c
+++ b/src/battle_anim_new.c
@@ -9431,7 +9431,7 @@ static void SpriteCB_MaxFlutterby(struct Sprite* sprite)
{
s16 target_x;
s16 target_y;
- if (gMovesInfo[gAnimMoveIndex].target == MOVE_TARGET_BOTH)
+ if (GetMoveTarget(gAnimMoveIndex) == MOVE_TARGET_BOTH)
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &target_x, &target_y);
}
diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c
index 8c41359b7a..b03dcd958d 100644
--- a/src/battle_controller_opponent.c
+++ b/src/battle_controller_opponent.c
@@ -534,13 +534,57 @@ static inline bool32 IsAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 batt
&& CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle;
}
+static inline bool32 IsDoubleAceSlot(u32 battler, u32 partyId)
+{
+ u32 partyCountEnd;
+
+ if (!(gAiThinkingStruct->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON))
+ return FALSE;
+
+ partyCountEnd = CalculateEnemyPartyCountInSide(battler);
+ if (partyCountEnd == 0)
+ return FALSE;
+
+ if (partyId == partyCountEnd - 1)
+ return TRUE;
+ if (partyCountEnd > 1 && partyId == partyCountEnd - 2)
+ return TRUE;
+
+ return FALSE;
+}
+
static inline bool32 IsDoubleAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler)
{
- return gAiThinkingStruct->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON
- && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1)
- && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 2)
- && CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle
- && CountAIAliveNonEggMonsExcept(PARTY_SIZE-1) != pokemonInBattle;
+ s32 battler1, battler2, firstId, lastId;
+ s32 i;
+
+ if (!IsDoubleAceSlot(battler, chosenMonId))
+ return FALSE;
+
+ if (!IsDoubleBattle())
+ {
+ battler2 = battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+ }
+ else
+ {
+ battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+ battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
+ }
+
+ GetAIPartyIndexes(battler, &firstId, &lastId);
+ for (i = firstId; i < lastId; i++)
+ {
+ if (!IsValidForBattle(&gEnemyParty[i])
+ || i == gBattlerPartyIndexes[battler1]
+ || i == gBattlerPartyIndexes[battler2]
+ || i == chosenMonId)
+ continue;
+
+ if (!IsAcePokemon(i, pokemonInBattle, battler) && !IsDoubleAceSlot(battler, i))
+ return TRUE;
+ }
+
+ return FALSE;
}
static void OpponentHandleChoosePokemon(u32 battler)
diff --git a/src/battle_end_turn.c b/src/battle_end_turn.c
index 991393de91..d6d8601383 100644
--- a/src/battle_end_turn.c
+++ b/src/battle_end_turn.c
@@ -32,25 +32,9 @@ static bool32 HandleEndTurnOrder(u32 battler)
gBattleTurnCounter++;
gBattleStruct->eventState.endTurn++;
- u32 i, j;
- struct BattleContext ctx = {0};
- for (i = 0; i < gBattlersCount; i++)
- {
+ for (u32 i = 0; i < gBattlersCount; i++)
gBattlerByTurnOrder[i] = i;
- ctx.abilities[i] = GetBattlerAbility(i);
- ctx.holdEffects[i] = GetBattlerHoldEffect(i);
- }
- for (i = 0; i < gBattlersCount - 1; i++)
- {
- for (j = i + 1; j < gBattlersCount; j++)
- {
- ctx.battlerAtk = gBattlerByTurnOrder[i];
- ctx.battlerDef = gBattlerByTurnOrder[j];
-
- if (GetWhichBattlerFaster(&ctx, FALSE) == -1)
- SwapTurnOrder(i, j);
- }
- }
+ SortBattlersBySpeed(gBattlerByTurnOrder, FALSE);
return effect;
}
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 2e5a244d29..3b0afaa140 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -1171,7 +1171,26 @@ static void Cmd_attackcanceler(void)
}
u32 isBounceable = MoveCanBeBouncedBack(gCurrentMove);
- if (gProtectStructs[gBattlerTarget].bounceMove
+ bool32 bounceActive = (gProtectStructs[gBattlerTarget].bounceMove && IsBattlerAlive(gBattlerTarget));
+
+ if (!bounceActive
+ && !gBattleStruct->bouncedMoveIsUsed
+ && isBounceable
+ && GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove) == MOVE_TARGET_OPPONENTS_FIELD)
+ {
+ u32 partner = BATTLE_PARTNER(gBattlerTarget);
+
+ if (partner < gBattlersCount
+ && GetBattlerSide(partner) == GetBattlerSide(gBattlerTarget)
+ && gProtectStructs[partner].bounceMove
+ && IsBattlerAlive(partner))
+ {
+ gBattlerTarget = partner;
+ bounceActive = TRUE;
+ }
+ }
+
+ if (bounceActive
&& isBounceable
&& !gBattleStruct->bouncedMoveIsUsed)
{
@@ -6309,9 +6328,10 @@ static void Cmd_moveend(void)
// Set ShellTrap to activate after the attacker's turn if target was hit by a physical move.
if (GetMoveEffect(gChosenMoveByBattler[gBattlerTarget]) == EFFECT_SHELL_TRAP
+ && IsBattleMovePhysical(gCurrentMove)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& gBattlerTarget != gBattlerAttacker
&& !IsBattlerAlly(gBattlerTarget, gBattlerAttacker)
- && gProtectStructs[gBattlerTarget].physicalDmg
&& gProtectStructs[gBattlerTarget].physicalBattlerId == gBattlerAttacker
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
{
@@ -6444,7 +6464,6 @@ static void Cmd_moveend(void)
gBattleStruct->moveTarget[gBattlerAttacker] = gBattlerTarget = nextTarget; // Fix for moxie spread moves
gBattleScripting.moveendState = 0;
MoveValuesCleanUp();
- gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
// Edge cases for moves that shouldn't repeat their own script
if (moveEffect == EFFECT_EXPLOSION
@@ -6497,7 +6516,7 @@ static void Cmd_moveend(void)
if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gMultiHitCounter
- && !(moveEffect == EFFECT_PRESENT && gBattleStruct->presentBasePower == 0)) // Silly edge case
+ && !(moveEffect == EFFECT_PRESENT && gBattleStruct->presentBasePower == 0)) // Parental Bond edge case
{
gMultiHitCounter--;
if (!IsBattlerAlive(gBattlerTarget) && moveEffect != EFFECT_DRAGON_DARTS)
@@ -6506,7 +6525,9 @@ static void Cmd_moveend(void)
gBattleScripting.multihitString[4]++;
if (gMultiHitCounter == 0)
{
- if (GetMoveEffectArg_MoveProperty(gCurrentMove) == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty())
+ if (moveEffect == EFFECT_MULTI_HIT
+ && GetMoveEffectArg_MoveProperty(gCurrentMove) == MOVE_EFFECT_SCALE_SHOT
+ && !NoAliveMonsForEitherParty())
BattleScriptCall(BattleScript_ScaleShot);
else
BattleScriptCall(BattleScript_MultiHitPrintStrings);
@@ -11402,17 +11423,26 @@ static void Cmd_trysetencore(void)
}
if ((IsMoveEncoreBanned(gLastMoves[gBattlerTarget]))
+ || i == MAX_MON_MOVES
|| gLastMoves[gBattlerTarget] == MOVE_NONE
- || gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE)
+ || gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE
+ || gBattleMons[gBattlerTarget].pp[i] == 0
+ || gDisableStructs[gBattlerTarget].encoredMove != MOVE_NONE
+ || GetMoveEffect(gChosenMoveByBattler[gBattlerTarget]) == EFFECT_SHELL_TRAP)
{
- i = MAX_MON_MOVES;
+ gBattlescriptCurrInstr = cmd->failInstr;
}
-
- if (gDisableStructs[gBattlerTarget].encoredMove == MOVE_NONE
- && i != MAX_MON_MOVES && gBattleMons[gBattlerTarget].pp[i] != 0)
+ else
{
gDisableStructs[gBattlerTarget].encoredMove = gBattleMons[gBattlerTarget].moves[i];
gDisableStructs[gBattlerTarget].encoredMovePos = i;
+
+ // If the target's selected move is not the same as the move being Encored into,
+ // the target will select a random opposing target
+ // Redirection such as Follow Me is already covered in HandleAction_UseMove of battle_util.c
+ if (gDisableStructs[gBattlerTarget].encoredMove != GetChosenMoveFromPosition(gBattlerTarget))
+ gBattleStruct->moveTarget[gBattlerTarget] = SetRandomTarget(gBattlerTarget);
+
// Encore always lasts 3 turns, but we need to account for a scenario where Encore changes the move during the same turn.
if (HasBattlerActedThisTurn(gBattlerTarget))
gDisableStructs[gBattlerTarget].encoreTimer = 4;
@@ -11420,10 +11450,6 @@ static void Cmd_trysetencore(void)
gDisableStructs[gBattlerTarget].encoreTimer = 3;
gBattlescriptCurrInstr = cmd->nextInstr;
}
- else
- {
- gBattlescriptCurrInstr = cmd->failInstr;
- }
}
static void Cmd_painsplitdmgcalc(void)
@@ -14024,13 +14050,16 @@ static void Cmd_displaydexinfo(void)
{
CMD_ARGS();
- struct Pokemon *mon = GetBattlerMon(GetCatchingBattler());
+ u32 caughtBattler = GetCatchingBattler();
+ struct Pokemon *mon = GetBattlerMon(caughtBattler);
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
switch (gBattleCommunication[0])
{
case 0:
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ ClearTemporarySpeciesSpriteData(caughtBattler, FALSE, FALSE);
+ BattleLoadMonSpriteGfx(mon, caughtBattler);
gBattleCommunication[0]++;
break;
case 1:
@@ -17903,7 +17932,7 @@ void BS_JumpIfAbilityPreventsRest(void)
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
u32 battler = GetBattlerForBattleScript(cmd->battler);
u32 ability = GetBattlerAbility(battler);
- if (B_LEAF_GUARD_PREVENTS_REST >= GEN_5 && IsLeafGuardProtected(battler, ability))
+ if (GetGenConfig(GEN_CONFIG_LEAF_GUARD_PREVENTS_REST) >= GEN_5 && IsLeafGuardProtected(battler, ability))
gBattlescriptCurrInstr = cmd->jumpInstr;
else if (IsShieldsDownProtected(battler, ability))
gBattlescriptCurrInstr = cmd->jumpInstr;
diff --git a/src/battle_tv.c b/src/battle_tv.c
index 3dc5ee573b..9444e4dea3 100644
--- a/src/battle_tv.c
+++ b/src/battle_tv.c
@@ -1279,6 +1279,7 @@ static void TrySetBattleSeminarShow(void)
ctx.isCrit = FALSE;
ctx.randomFactor = FALSE;
ctx.updateFlags = FALSE;
+ ctx.isSelfInflicted = FALSE;
ctx.fixedBasePower = powerOverride;
gBattleStruct->moveDamage[gBattlerTarget] = CalculateMoveDamage(&ctx);
dmgByMove[i] = gBattleStruct->moveDamage[gBattlerTarget];
diff --git a/src/battle_util.c b/src/battle_util.c
index 19d9bd1345..98af397329 100644
--- a/src/battle_util.c
+++ b/src/battle_util.c
@@ -438,7 +438,6 @@ void HandleAction_UseMove(void)
gMultiHitCounter = 0;
gBattleScripting.savedDmg = 0;
gBattleCommunication[MISS_TYPE] = 0;
- gBattleScripting.savedMoveEffect = 0;
gCurrMovePos = gChosenMovePos = gBattleStruct->chosenMovePositions[gBattlerAttacker];
// choose move
@@ -2076,6 +2075,7 @@ static enum MoveCanceler CancelerObedience(struct BattleContext *ctx)
dmgCtx.isCrit = FALSE;
dmgCtx.randomFactor = FALSE;
dmgCtx.updateFlags = TRUE;
+ dmgCtx.isSelfInflicted = TRUE;
dmgCtx.fixedBasePower = 40;
gBattleStruct->moveDamage[ctx->battlerAtk] = CalculateMoveDamage(&dmgCtx);
gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself;
@@ -2242,6 +2242,7 @@ static enum MoveCanceler CancelerConfused(struct BattleContext *ctx)
dmgCtx.isCrit = FALSE;
dmgCtx.randomFactor = FALSE;
dmgCtx.updateFlags = TRUE;
+ dmgCtx.isSelfInflicted = TRUE;
dmgCtx.fixedBasePower = 40;
gBattleStruct->passiveHpUpdate[ctx->battlerAtk] = CalculateMoveDamage(&dmgCtx);
gProtectStructs[ctx->battlerAtk].confusionSelfDmg = TRUE;
@@ -7401,6 +7402,24 @@ static bool32 IsRuinStatusActive(u32 fieldEffect)
return FALSE;
}
+static inline uq4_12_t ApplyOffensiveBadgeBoost(uq4_12_t modifier, u32 battler, u32 move)
+{
+ if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_ATTACK, battler) && IsBattleMovePhysical(move))
+ modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
+ if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPATK, battler) && IsBattleMoveSpecial(move))
+ modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
+ return modifier;
+}
+
+static inline uq4_12_t ApplyDefensiveBadgeBoost(uq4_12_t modifier, u32 battler, u32 move)
+{
+ if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_DEFENSE, battler) && IsBattleMovePhysical(move))
+ modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
+ if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPDEF, battler) && IsBattleMoveSpecial(move))
+ modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
+ return modifier;
+}
+
static inline u32 CalcAttackStat(struct DamageContext *ctx)
{
u8 atkStage;
@@ -7472,6 +7491,9 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
// apply attack stat modifiers
modifier = UQ_4_12(1.0);
+ if (ctx->isSelfInflicted)
+ return uq4_12_multiply_by_int_half_down(ApplyOffensiveBadgeBoost(modifier, battlerAtk, move), atkStat);
+
// attacker's abilities
switch (ctx->abilityAtk)
{
@@ -7672,11 +7694,7 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
break;
}
- // The offensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges)
- if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_ATTACK, battlerAtk) && IsBattleMovePhysical(move))
- modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
- if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPATK, battlerAtk) && IsBattleMoveSpecial(move))
- modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
+ modifier = ApplyOffensiveBadgeBoost(modifier, battlerAtk, move);
return uq4_12_multiply_by_int_half_down(modifier, atkStat);
}
@@ -7761,6 +7779,9 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
// apply defense stat modifiers
modifier = UQ_4_12(1.0);
+ if (ctx->isSelfInflicted)
+ return uq4_12_multiply_by_int_half_down(ApplyDefensiveBadgeBoost(modifier, battlerDef, move), defStat);
+
// target's abilities
switch (ctx->abilityDef)
{
@@ -7854,11 +7875,7 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SNOW) && usesDefStat)
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
- // The defensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges)
- if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_DEFENSE, battlerDef) && IsBattleMovePhysical(move))
- modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
- if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPDEF, battlerDef) && IsBattleMoveSpecial(move))
- modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
+ modifier = ApplyDefensiveBadgeBoost(modifier, battlerDef, move);
return uq4_12_multiply_by_int_half_down(modifier, defStat);
}
@@ -10310,9 +10327,9 @@ bool32 HasWeatherEffect(void)
void UpdateStallMons(void)
{
- if (IsBattlerTurnDamaged(gBattlerTarget) || IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove) || gMovesInfo[gCurrentMove].category == DAMAGE_CATEGORY_STATUS)
+ if (IsBattlerTurnDamaged(gBattlerTarget) || IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove) || GetMoveCategory(gCurrentMove) == DAMAGE_CATEGORY_STATUS)
return;
- if (!IsDoubleBattle() || gMovesInfo[gCurrentMove].target == MOVE_TARGET_SELECTED)
+ if (!IsDoubleBattle() || GetMoveTarget(gCurrentMove) == MOVE_TARGET_SELECTED)
{
enum Type moveType = GetBattleMoveType(gCurrentMove); // Probably doesn't handle dynamic move types right now
enum Ability abilityAtk = GetBattlerAbility(gBattlerAttacker);
diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h
index 236c7f6dfd..2ee7f4f1b5 100644
--- a/src/data/battle_anim.h
+++ b/src/data/battle_anim.h
@@ -2031,6 +2031,7 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
[BG_STEEL_BEAM_OPPONENT] = {gBattleAnimBgImage_Highspeed, gBattleAnimBgPalette_SteelBeam, gBattleAnimBgTilemap_HighspeedOpponent},
[BG_STEEL_BEAM_PLAYER] = {gBattleAnimBgImage_Highspeed, gBattleAnimBgPalette_SteelBeam, gBattleAnimBgTilemap_HighspeedPlayer},
[BG_CHLOROBLAST] = {gBattleAnimBgImage_HydroCannon, gBattleAnimBgPalette_Chloroblast, gBattleAnimBgTilemap_HydroCannon},
- [BG_RAINBOW] = {gBattleAnimBgImage_Rainbow, gBattleAnimBGPalette_Rainbow, gBattleAnimBgTilemap_Rainbow},
+ [BG_RAINBOW_PLAYER] = {gBattleAnimBgImage_RainbowPlayer, gBattleAnimBGPalette_Rainbow, gBattleAnimBgTilemap_RainbowPlayer},
+ [BG_RAINBOW_OPPONENT] = {gBattleAnimBgImage_RainbowOpponent, gBattleAnimBGPalette_Rainbow, gBattleAnimBgTilemap_RainbowOpponent},
[BG_SWAMP] = {gBattleAnimBgImage_Swamp, gBattleAnimBGPalette_Swamp, gBattleAnimBgTilemap_Swamp},
};
diff --git a/src/event_object_movement.c b/src/event_object_movement.c
index f11a626be1..848289aec7 100644
--- a/src/event_object_movement.c
+++ b/src/event_object_movement.c
@@ -2627,37 +2627,29 @@ void UpdateLightSprite(struct Sprite *sprite)
return;
}
- // Note: Don't set window registers during hardware fade!
- switch (sprite->sLightType)
+ if (sprite->sLightType == LIGHT_TYPE_BALL)
{
- default:
- case LIGHT_TYPE_BALL:
if (gPaletteFade.active) // if palette fade is active, don't flicker since the timer won't be updated
{
- Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY);
sprite->invisible = FALSE;
}
else if (gPlayerAvatar.tileTransitionState)
{
- Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY); // As long as the second coefficient stays 12, shadows will not change
sprite->invisible = FALSE;
if (GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum) == OBJ_EVENT_PAL_TAG_LIGHT_2)
LoadSpritePaletteInSlot(&sObjectEventSpritePalettes[FindObjectEventPaletteIndexByTag(OBJ_EVENT_PAL_TAG_LIGHT)], sprite->oam.paletteNum);
}
else if ((sprite->invisible = gTimeUpdateCounter & 1))
{
- Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY);
sprite->invisible = FALSE;
if (GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum) == OBJ_EVENT_PAL_TAG_LIGHT_2)
LoadSpritePaletteInSlot(&sObjectEventSpritePalettes[FindObjectEventPaletteIndexByTag(OBJ_EVENT_PAL_TAG_LIGHT)], sprite->oam.paletteNum);
}
- break;
- case LIGHT_TYPE_PKMN_CENTER_SIGN:
- case LIGHT_TYPE_POKE_MART_SIGN:
- Weather_SetBlendCoeffs(12, BASE_SHADOW_INTENSITY);
+ } else {
sprite->invisible = FALSE;
- break;
}
+ // Note: Don't set window registers during hardware fade!
+ Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY);
}
// Spawn a light at a map coordinate
diff --git a/src/faraway_island.c b/src/faraway_island.c
index e275bcfa37..67acf5cc6d 100755
--- a/src/faraway_island.c
+++ b/src/faraway_island.c
@@ -393,6 +393,7 @@ void SetMewAboveGrass(void)
LoadSpritePalette(&gSpritePalette_GeneralFieldEffect1);
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(gSpritePalette_GeneralFieldEffect1.tag), FALSE);
+ gSprites[mew->spriteId].subspriteTableNum = 1;
x = mew->currentCoords.x;
y = mew->currentCoords.y;
diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c
index bbc1e16bfe..a46f292517 100644
--- a/src/field_player_avatar.c
+++ b/src/field_player_avatar.c
@@ -2125,7 +2125,6 @@ bool8 ObjectMovingOnRockStairs(struct ObjectEvent *objectEvent, u8 direction)
s16 x = objectEvent->currentCoords.x;
s16 y = objectEvent->currentCoords.y;
- // TODO followers on sideways stairs
if (IsFollowerVisible() && GetFollowerObject() != NULL && (objectEvent->isPlayer || objectEvent->localId == OBJ_EVENT_ID_FOLLOWER))
return FALSE;
diff --git a/src/follower_npc.c b/src/follower_npc.c
index d6af0abad2..2cca3186b3 100644
--- a/src/follower_npc.c
+++ b/src/follower_npc.c
@@ -1087,6 +1087,10 @@ u32 DetermineFollowerNPCState(struct ObjectEvent *follower, u32 state, u32 direc
RETURN_STATE(MOVEMENT_ACTION_WALK_NORMAL_DOWN, direction);
+ // Slow stairs.
+ case MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN ... MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT:
+ RETURN_STATE(MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN, direction);
+
default:
return MOVEMENT_INVALID;
}
diff --git a/src/graphics.c b/src/graphics.c
index 925e232dbe..013c2d2b85 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -1673,9 +1673,11 @@ const u32 gBattleAnimSpriteGfx_WhiteShadow[] = INCBIN_U32("graphics/battle_anims
const u16 gBattleAnimSpritePal_WhiteShadow[] = INCBIN_U16("graphics/battle_anims/sprites/white_shadow.gbapal");
// Pledge Effect field status - Rainbow
-const u32 gBattleAnimBgImage_Rainbow[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow.4bpp.smol");
-const u16 gBattleAnimBGPalette_Rainbow[] = INCBIN_U16("graphics/battle_anims/backgrounds/rainbow.gbapal");
-const u32 gBattleAnimBgTilemap_Rainbow[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow.bin.smolTM");
+const u32 gBattleAnimBgImage_RainbowPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow_player_tile.4bpp.smol");
+const u32 gBattleAnimBgImage_RainbowOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow_opponent_tile.4bpp.smol");
+const u16 gBattleAnimBGPalette_Rainbow[] = INCBIN_U16("graphics/battle_anims/backgrounds/rainbow_player_tile.gbapal");
+const u32 gBattleAnimBgTilemap_RainbowPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow_player_tile.bin.smolTM");
+const u32 gBattleAnimBgTilemap_RainbowOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow_opponent_tile.bin.smolTM");
// Pledge Effect field status - Swamp
const u32 gBattleAnimBgImage_Swamp[] = INCBIN_U32("graphics/battle_anims/backgrounds/swampswizzle.4bpp.smol");
diff --git a/src/item_menu.c b/src/item_menu.c
index 6bb65b5a2e..f19cad0cdc 100755
--- a/src/item_menu.c
+++ b/src/item_menu.c
@@ -2916,8 +2916,8 @@ static s32 CompareItemsAlphabetically(enum Pocket pocketId, struct ItemSlot item
if (pocketId == POCKET_TM_HM)
{
- name1 = gMovesInfo[GetTMHMMoveId(GetItemTMHMIndex(item1.itemId))].name;
- name2 = gMovesInfo[GetTMHMMoveId(GetItemTMHMIndex(item2.itemId))].name;
+ name1 = GetMoveName(GetTMHMMoveId(GetItemTMHMIndex(item1.itemId)));
+ name2 = GetMoveName(GetTMHMMoveId(GetItemTMHMIndex(item2.itemId)));
}
else
{
diff --git a/src/item_use.c b/src/item_use.c
index 88e01777aa..e9c2288224 100644
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -1269,7 +1269,8 @@ bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon)
switch (battleUsage)
{
case EFFECT_ITEM_INCREASE_STAT:
- if (gBattleMons[gBattlerInMenuId].statStages[GetItemEffect(itemId)[1]] == MAX_STAT_STAGE)
+ u32 ability = GetBattlerAbility(gBattlerInMenuId);
+ if (CompareStat(gBattlerInMenuId, GetItemEffect(itemId)[1], MAX_STAT_STAGE, CMP_EQUAL, ability))
cannotUse = TRUE;
break;
case EFFECT_ITEM_SET_FOCUS_ENERGY:
@@ -1308,11 +1309,12 @@ bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon)
case EFFECT_ITEM_INCREASE_ALL_STATS:
{
u32 ability = GetBattlerAbility(gBattlerInMenuId);
+ cannotUse = TRUE;
for (i = STAT_ATK; i < NUM_STATS; i++)
{
- if (CompareStat(gBattlerInMenuId, i, MAX_STAT_STAGE, CMP_EQUAL, ability))
+ if (!CompareStat(gBattlerInMenuId, i, MAX_STAT_STAGE, CMP_EQUAL, ability))
{
- cannotUse = TRUE;
+ cannotUse = FALSE;
break;
}
}
diff --git a/src/mirage_tower.c b/src/mirage_tower.c
index e2ed74a21a..bf73692a36 100644
--- a/src/mirage_tower.c
+++ b/src/mirage_tower.c
@@ -202,7 +202,7 @@ static const struct OamData sOamData_CeilingCrumbleSmall =
static const struct SpriteTemplate sSpriteTemplate_CeilingCrumbleSmall =
{
.tileTag = TAG_CEILING_CRUMBLE,
- .paletteTag = TAG_NONE,
+ .paletteTag = TAG_CEILING_CRUMBLE,
.oam = &sOamData_CeilingCrumbleSmall,
.anims = sAnims_CeilingCrumbleSmall,
.images = NULL,
@@ -241,7 +241,7 @@ static const struct OamData sOamData_CeilingCrumbleLarge =
static const struct SpriteTemplate sSpriteTemplate_CeilingCrumbleLarge =
{
.tileTag = TAG_CEILING_CRUMBLE,
- .paletteTag = TAG_NONE,
+ .paletteTag = TAG_CEILING_CRUMBLE,
.oam = &sOamData_CeilingCrumbleLarge,
.anims = sAnims_CeilingCrumbleLarge,
.images = NULL,
@@ -420,6 +420,7 @@ static void IncrementCeilingCrumbleFinishedCount(void)
void DoMirageTowerCeilingCrumble(void)
{
+ LoadSpritePaletteWithTag(sMirageTowerCrumbles_Palette, TAG_CEILING_CRUMBLE);
LoadSpriteSheets(sCeilingCrumbleSpriteSheets);
CreateCeilingCrumbleSprites();
CreateTask(WaitCeilingCrumble, 8);
@@ -454,17 +455,12 @@ static void CreateCeilingCrumbleSprites(void)
{
spriteId = CreateSprite(&sSpriteTemplate_CeilingCrumbleLarge, sCeilingCrumblePositions[i][0] + 120, sCeilingCrumblePositions[i][1], 8);
gSprites[spriteId].oam.priority = 0;
- // These sprites use color index 11 from the player's sprite palette. This probably wasn't intentional.
- // The palettes for Brendan and May have different shades of green at this index, so the color of these sprites changes
- // depending on the player's gender (and neither shade of green particularly fits a crumbling yellow/brown ceiling).
- gSprites[spriteId].oam.paletteNum = PALSLOT_PLAYER;
gSprites[spriteId].sIndex = i;
}
for (i = 0; i < ARRAY_COUNT(sCeilingCrumblePositions); i++)
{
spriteId = CreateSprite(&sSpriteTemplate_CeilingCrumbleSmall, sCeilingCrumblePositions[i][0] + 115, sCeilingCrumblePositions[i][1] - 3, 8);
gSprites[spriteId].oam.priority = 0;
- gSprites[spriteId].oam.paletteNum = PALSLOT_PLAYER;
gSprites[spriteId].sIndex = i;
}
}
diff --git a/src/party_menu.c b/src/party_menu.c
index ebf6c7e131..2d5a715dc3 100644
--- a/src/party_menu.c
+++ b/src/party_menu.c
@@ -6392,8 +6392,9 @@ static void SwapFusionMonMoves(struct Pokemon *mon, const u16 moveTable[][2], u3
{
if (move == moveTable[j][oldMoveIndex])
{
+ u32 pp = GetMovePP(moveTable[j][newMoveIndex]);
SetMonData(mon, MON_DATA_MOVE1 + i, &moveTable[j][newMoveIndex]);
- SetMonData(mon, MON_DATA_PP1 + i, &gMovesInfo[moveTable[j][newMoveIndex]].pp);
+ SetMonData(mon, MON_DATA_PP1 + i, &pp);
}
}
}
diff --git a/src/pokedex_plus_hgss.c b/src/pokedex_plus_hgss.c
index ea9bd3f042..ea96e764c3 100644
--- a/src/pokedex_plus_hgss.c
+++ b/src/pokedex_plus_hgss.c
@@ -4089,6 +4089,12 @@ static void UNUSED HighlightScreenSelectBarItem(u8 selectedScreen, u16 unused)
#define tPersonalityLo data[14]
#define tPersonalityHi data[15]
+// Types palettes need to be loaded at a different slot than anticipated by gTypesInfo
+// to avoid overlapping with caught mon sprite palette slot
+// Normal type info palette slots: 13, 14 and 15
+// Caught mon palette slot: 15
+#define TYPE_INFO_PALETTE_NUM_OFFSET -1
+
void Task_DisplayCaughtMonDexPageHGSS(u8 taskId)
{
u8 spriteId;
@@ -4343,7 +4349,7 @@ static void SetTypeIconPosAndPal(u8 typeId, u8 x, u8 y, u8 spriteArrayId)
sprite = &gSprites[sPokedexView->typeIconSpriteIds[spriteArrayId]];
StartSpriteAnim(sprite, typeId);
if (typeId < NUMBER_OF_MON_TYPES)
- sprite->oam.paletteNum = gTypesInfo[typeId].palette;
+ sprite->oam.paletteNum = gTypesInfo[typeId].palette + TYPE_INFO_PALETTE_NUM_OFFSET;
else
sprite->oam.paletteNum = gContestCategoryInfo[typeId - NUMBER_OF_MON_TYPES].palette;
sprite->x = x + 16;
@@ -4386,7 +4392,8 @@ static void CreateTypeIconSprites(void)
u8 i;
LoadCompressedSpriteSheet(&gSpriteSheet_MoveTypes);
- LoadPalette(gMoveTypes_Pal, 0x1D0, 0x60);
+ u32 paletteNum = gTypesInfo[TYPE_NORMAL].palette + TYPE_INFO_PALETTE_NUM_OFFSET;
+ LoadPalette(gMoveTypes_Pal, OBJ_PLTT_ID(paletteNum), 3 * PLTT_SIZE_4BPP);
for (i = 0; i < 2; i++)
{
if (sPokedexView->typeIconSpriteIds[i] == 0xFF)
@@ -4566,6 +4573,7 @@ static u16 CreateSizeScreenTrainerPic(u16 species, s16 x, s16 y, s8 paletteSlot)
return CreateTrainerPicSprite(species, TRUE, x, y, paletteSlot, TAG_NONE);
}
+#undef TYPE_INFO_PALETTE_NUM_OFFSET
//************************************
//* *
diff --git a/src/sound.c b/src/sound.c
index 0eec129dde..80676a4920 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -34,6 +34,7 @@ static void Task_Fanfare(u8 taskId);
static void CreateFanfareTask(void);
static void RestoreBGMVolumeAfterPokemonCry(void);
+// The 1st argument in the table is the length of the fanfare, measured in frames. This is calculated by taking the duration of the midi file, multiplying by 59.72750056960583, and rounding up to the next nearest integer.
static const struct Fanfare sFanfares[] = {
[FANFARE_LEVEL_UP] = { MUS_LEVEL_UP, 80 },
[FANFARE_OBTAIN_ITEM] = { MUS_OBTAIN_ITEM, 160 },
diff --git a/src/trainer_see.c b/src/trainer_see.c
index c60f61ae0b..2c184cd8b8 100644
--- a/src/trainer_see.c
+++ b/src/trainer_see.c
@@ -493,7 +493,7 @@ static u8 CheckTrainer(u8 objectEventId)
if (GetTrainerFlagFromScriptPointer(trainerBattlePtr))
{
//If there is a rematch, we want to trigger the approach sequence
- if (GetRematchFromScriptPointer(trainerBattlePtr))
+ if (I_VS_SEEKER_CHARGING && GetRematchFromScriptPointer(trainerBattlePtr))
{
trainerBattlePtr = NULL;
numTrainers = 0xFF;
diff --git a/test/battle/ability/aura_break.c b/test/battle/ability/aura_break.c
index 389ab327b1..10c248c87d 100644
--- a/test/battle/ability/aura_break.c
+++ b/test/battle/ability/aura_break.c
@@ -5,62 +5,62 @@ DOUBLE_BATTLE_TEST("Aura Break inverts Fairy Aura's effect")
{
s16 damage[3];
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_XERNEAS) { Ability(ABILITY_FAIRY_AURA); }
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_ZYGARDE_50) { Ability(ABILITY_AURA_BREAK); }
- } WHEN {
- TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft); }
- TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft); SWITCH(playerRight, 2); }
- TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft); SWITCH(opponentRight, 2); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[0]);
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_XERNEAS) { Ability(ABILITY_FAIRY_AURA); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ZYGARDE_50) { Ability(ABILITY_AURA_BREAK); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft); SWITCH(playerRight, 2); }
+ TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft); SWITCH(opponentRight, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[0]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[1]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[1]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[2]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[2]);
- } THEN {
- EXPECT_MUL_EQ(damage[0], UQ_4_12(1.33), damage[1]);
- EXPECT_MUL_EQ(damage[0], UQ_4_12(0.75), damage[2]);
- }
+ } THEN {
+ EXPECT_MUL_EQ(damage[0], UQ_4_12(1.33), damage[1]);
+ EXPECT_MUL_EQ(damage[0], UQ_4_12(0.75), damage[2]);
+ }
}
DOUBLE_BATTLE_TEST("Aura Break inverts Dark Aura's effect")
{
s16 damage[3];
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_YVELTAL) { Ability(ABILITY_DARK_AURA); }
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_ZYGARDE_50) { Ability(ABILITY_AURA_BREAK); }
- } WHEN {
- TURN { MOVE(playerLeft, MOVE_BITE, target:opponentLeft); }
- TURN { MOVE(playerLeft, MOVE_BITE, target:opponentLeft); SWITCH(playerRight, 2); }
- TURN { MOVE(playerLeft, MOVE_BITE, target:opponentLeft); SWITCH(opponentRight, 2); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[0]);
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_YVELTAL) { Ability(ABILITY_DARK_AURA); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ZYGARDE_50) { Ability(ABILITY_AURA_BREAK); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_BITE, target:opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_BITE, target:opponentLeft); SWITCH(playerRight, 2); }
+ TURN { MOVE(playerLeft, MOVE_BITE, target:opponentLeft); SWITCH(opponentRight, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[0]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[1]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[1]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[2]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[2]);
- } THEN {
- EXPECT_MUL_EQ(damage[0], UQ_4_12(1.33), damage[1]);
- EXPECT_MUL_EQ(damage[0], UQ_4_12(0.75), damage[2]);
- }
+ } THEN {
+ EXPECT_MUL_EQ(damage[0], UQ_4_12(1.33), damage[1]);
+ EXPECT_MUL_EQ(damage[0], UQ_4_12(0.75), damage[2]);
+ }
}
DOUBLE_BATTLE_TEST("Aura Break ignores Mold Breaker abilities")
@@ -73,43 +73,43 @@ DOUBLE_BATTLE_TEST("Aura Break ignores Mold Breaker abilities")
PARAMETRIZE { species = SPECIES_ZEKROM, ability = ABILITY_TERAVOLT; }
PARAMETRIZE { species = SPECIES_RESHIRAM, ability = ABILITY_TURBOBLAZE; }
- GIVEN {
- PLAYER(species) { Ability(ability); Level(50); }
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_YVELTAL) { Ability(ABILITY_DARK_AURA); }
- PLAYER(SPECIES_XERNEAS) { Ability(ABILITY_FAIRY_AURA); }
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_ZYGARDE_50) { Ability(ABILITY_AURA_BREAK); }
- } WHEN {
- TURN { MOVE(playerLeft, MOVE_BITE, target: opponentLeft); }
- TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target: opponentLeft); }
- TURN { MOVE(playerLeft, MOVE_BITE, target: opponentLeft); SWITCH(playerRight, 2); }
- TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target: opponentLeft); SWITCH(playerRight, 3); }
- TURN { MOVE(playerLeft, MOVE_BITE, target: opponentLeft); SWITCH(playerRight, 2); SWITCH(opponentRight, 2); }
- TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target: opponentLeft); SWITCH(playerRight, 3); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[0]);
+ GIVEN {
+ PLAYER(species) { Ability(ability); Level(50); }
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_YVELTAL) { Ability(ABILITY_DARK_AURA); }
+ PLAYER(SPECIES_XERNEAS) { Ability(ABILITY_FAIRY_AURA); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ZYGARDE_50) { Ability(ABILITY_AURA_BREAK); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_BITE, target: opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target: opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_BITE, target: opponentLeft); SWITCH(playerRight, 2); }
+ TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target: opponentLeft); SWITCH(playerRight, 3); }
+ TURN { MOVE(playerLeft, MOVE_BITE, target: opponentLeft); SWITCH(playerRight, 2); SWITCH(opponentRight, 2); }
+ TURN { MOVE(playerLeft, MOVE_PLAY_ROUGH, target: opponentLeft); SWITCH(playerRight, 3); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[0]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[1]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[1]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[2]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[2]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[3]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[3]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[4]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[4]);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
- HP_BAR(opponentLeft, captureDamage: &damage[5]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[5]);
} THEN {
- EXPECT_MUL_EQ(damage[0], UQ_4_12(1.33), damage[2]);
- EXPECT_MUL_EQ(damage[0], UQ_4_12(0.75), damage[4]);
- EXPECT_MUL_EQ(damage[1], UQ_4_12(1.33), damage[3]);
- EXPECT_MUL_EQ(damage[1], UQ_4_12(0.75), damage[5]);
- }
+ EXPECT_MUL_EQ(damage[0], UQ_4_12(1.33), damage[2]);
+ EXPECT_MUL_EQ(damage[0], UQ_4_12(0.75), damage[4]);
+ EXPECT_MUL_EQ(damage[1], UQ_4_12(1.33), damage[3]);
+ EXPECT_MUL_EQ(damage[1], UQ_4_12(0.75), damage[5]);
+ }
}
diff --git a/test/battle/ability/bad_dreams.c b/test/battle/ability/bad_dreams.c
index 491d5a91a2..cb724e2411 100644
--- a/test/battle/ability/bad_dreams.c
+++ b/test/battle/ability/bad_dreams.c
@@ -35,7 +35,21 @@ SINGLE_BATTLE_TEST("Bad Dreams causes the sleeping enemy Pokemon to lose 1/8 of
}
}
-TO_DO_BATTLE_TEST("Bad Dreams affects Pokémon with Comatose")
+SINGLE_BATTLE_TEST("Bad Dreams causes Pokémon with Comatose to lose 1/8 of HP")
+{
+ GIVEN {
+ PLAYER(SPECIES_DARKRAI);
+ OPPONENT(SPECIES_KOMALA) { Ability(ABILITY_COMATOSE); }
+ } WHEN {
+ TURN {;}
+ } SCENE {
+ ABILITY_POPUP(player, ABILITY_BAD_DREAMS);
+ MESSAGE("The opposing Komala is tormented!");
+ HP_BAR(opponent);
+ } THEN {
+ EXPECT_EQ(opponent->hp, opponent->maxHP - opponent->maxHP / 8);
+ }
+}
DOUBLE_BATTLE_TEST("Bad Dreams does not activate if only the partner Pokemon is sleeping")
{
diff --git a/test/battle/ability/dark_aura.c b/test/battle/ability/dark_aura.c
index eb1bf05246..1371975a28 100644
--- a/test/battle/ability/dark_aura.c
+++ b/test/battle/ability/dark_aura.c
@@ -1,4 +1,108 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Dark Aura (Ability) test titles")
+DOUBLE_BATTLE_TEST("Dark Aura increases the power of all Dark-type attacks by 33%")
+{
+ s16 damage[8];
+
+ GIVEN {
+ PLAYER(SPECIES_YVELTAL) { Ability(ABILITY_DARK_AURA); }
+ PLAYER(SPECIES_LINOONE);
+ PLAYER(SPECIES_LINOONE);
+ OPPONENT(SPECIES_LINOONE);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_SKILL_SWAP, target: playerLeft); }
+ TURN { SWITCH(playerLeft, 2); }
+ TURN {
+ MOVE(playerLeft, MOVE_BITE, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(playerRight, MOVE_BITE, target:opponentRight, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_BITE, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_BITE, target:playerRight, secondaryEffect:FALSE);
+ }
+ TURN { MOVE(opponentLeft, MOVE_GASTRO_ACID, target:playerRight); }
+ TURN {
+ MOVE(playerLeft, MOVE_BITE, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(playerRight, MOVE_BITE, target:opponentRight, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_BITE, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_BITE, target:playerRight, secondaryEffect:FALSE);
+ }
+ } SCENE {
+ // Turn 1
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[0]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerRight);
+ HP_BAR(opponentRight, captureDamage: &damage[1]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[2]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentRight);
+ HP_BAR(playerRight, captureDamage: &damage[3]);
+
+ // Turn 2
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_GASTRO_ACID, opponentLeft);
+
+ // Turn 3
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[4]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerRight);
+ HP_BAR(opponentRight, captureDamage: &damage[5]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[6]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentRight);
+ HP_BAR(playerRight, captureDamage: &damage[7]);
+ } THEN {
+ EXPECT_MUL_EQ(damage[4], UQ_4_12(1.33), damage[0]);
+ EXPECT_MUL_EQ(damage[5], UQ_4_12(1.33), damage[1]);
+ EXPECT_MUL_EQ(damage[6], UQ_4_12(1.33), damage[2]);
+ EXPECT_MUL_EQ(damage[7], UQ_4_12(1.33), damage[3]);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Dark Aura's effect doesn't stack multiple times")
+{
+ s16 damage[6];
+
+ GIVEN {
+ PLAYER(SPECIES_YVELTAL) { Ability(ABILITY_DARK_AURA); }
+ PLAYER(SPECIES_WOBBUFFET) { HP(9999); MaxHP(9999); }
+ PLAYER(SPECIES_YVELTAL) { Ability(ABILITY_DARK_AURA); }
+ OPPONENT(SPECIES_WOBBUFFET) { HP(9999); MaxHP(9999); }
+ OPPONENT(SPECIES_WOBBUFFET) { HP(9999); MaxHP(9999); }
+ } WHEN {
+ TURN {
+ MOVE(playerLeft, MOVE_BITE, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_BITE, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_BITE, target:playerLeft, secondaryEffect:FALSE);
+ }
+ TURN { SWITCH(playerRight, 2); }
+ TURN {
+ MOVE(playerLeft, MOVE_BITE, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_BITE, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_BITE, target:playerLeft, secondaryEffect:FALSE);
+ }
+ } SCENE {
+ // Turn 1
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[0]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[1]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentRight);
+ HP_BAR(playerLeft, captureDamage: &damage[2]);
+
+ // Turn 2
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ SEND_IN_MESSAGE("Yveltal");
+
+ // Turn 3
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[3]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[4]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, opponentRight);
+ HP_BAR(playerLeft, captureDamage: &damage[5]);
+ } THEN {
+ EXPECT_EQ(damage[3], damage[0]);
+ EXPECT_EQ(damage[4], damage[1]);
+ EXPECT_EQ(damage[5], damage[2]);
+ }
+}
diff --git a/test/battle/ability/fairy_aura.c b/test/battle/ability/fairy_aura.c
index 3b8d400b02..a51abf1be5 100644
--- a/test/battle/ability/fairy_aura.c
+++ b/test/battle/ability/fairy_aura.c
@@ -1,4 +1,108 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Fairy Aura (Ability) test titles")
+DOUBLE_BATTLE_TEST("Fairy Aura increases the power of all Fairy-type attacks by 33%")
+{
+ s16 damage[8];
+
+ GIVEN {
+ PLAYER(SPECIES_XERNEAS) { Ability(ABILITY_FAIRY_AURA); }
+ PLAYER(SPECIES_LINOONE);
+ PLAYER(SPECIES_LINOONE);
+ OPPONENT(SPECIES_LINOONE);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_SKILL_SWAP, target: playerLeft); }
+ TURN { SWITCH(playerLeft, 2); }
+ TURN {
+ MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(playerRight, MOVE_PLAY_ROUGH, target:opponentRight, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_PLAY_ROUGH, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_PLAY_ROUGH, target:playerRight, secondaryEffect:FALSE);
+ }
+ TURN { MOVE(opponentLeft, MOVE_GASTRO_ACID, target:playerRight); }
+ TURN {
+ MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(playerRight, MOVE_PLAY_ROUGH, target:opponentRight, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_PLAY_ROUGH, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_PLAY_ROUGH, target:playerRight, secondaryEffect:FALSE);
+ }
+ } SCENE {
+ // Turn 1
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[0]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerRight);
+ HP_BAR(opponentRight, captureDamage: &damage[1]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[2]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentRight);
+ HP_BAR(playerRight, captureDamage: &damage[3]);
+
+ // Turn 2
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_GASTRO_ACID, opponentLeft);
+
+ // Turn 3
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[4]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerRight);
+ HP_BAR(opponentRight, captureDamage: &damage[5]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[6]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentRight);
+ HP_BAR(playerRight, captureDamage: &damage[7]);
+ } THEN {
+ EXPECT_MUL_EQ(damage[4], UQ_4_12(1.33), damage[0]);
+ EXPECT_MUL_EQ(damage[5], UQ_4_12(1.33), damage[1]);
+ EXPECT_MUL_EQ(damage[6], UQ_4_12(1.33), damage[2]);
+ EXPECT_MUL_EQ(damage[7], UQ_4_12(1.33), damage[3]);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Fairy Aura's effect doesn't stack multiple times")
+{
+ s16 damage[6];
+
+ GIVEN {
+ PLAYER(SPECIES_XERNEAS) { Ability(ABILITY_FAIRY_AURA); }
+ PLAYER(SPECIES_WOBBUFFET) { HP(9999); MaxHP(9999); }
+ PLAYER(SPECIES_XERNEAS) { Ability(ABILITY_FAIRY_AURA); }
+ OPPONENT(SPECIES_WOBBUFFET) { HP(9999); MaxHP(9999); }
+ OPPONENT(SPECIES_WOBBUFFET) { HP(9999); MaxHP(9999); }
+ } WHEN {
+ TURN {
+ MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_PLAY_ROUGH, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_PLAY_ROUGH, target:playerLeft, secondaryEffect:FALSE);
+ }
+ TURN { SWITCH(playerRight, 2); }
+ TURN {
+ MOVE(playerLeft, MOVE_PLAY_ROUGH, target:opponentLeft, secondaryEffect:FALSE);
+ MOVE(opponentLeft, MOVE_PLAY_ROUGH, target:playerLeft, secondaryEffect:FALSE);
+ MOVE(opponentRight, MOVE_PLAY_ROUGH, target:playerLeft, secondaryEffect:FALSE);
+ }
+ } SCENE {
+ // Turn 1
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[0]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[1]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentRight);
+ HP_BAR(playerLeft, captureDamage: &damage[2]);
+
+ // Turn 2
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ SEND_IN_MESSAGE("Xerneas");
+
+ // Turn 3
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damage[3]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damage[4]);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLAY_ROUGH, opponentRight);
+ HP_BAR(playerLeft, captureDamage: &damage[5]);
+ } THEN {
+ EXPECT_EQ(damage[3], damage[0]);
+ EXPECT_EQ(damage[4], damage[1]);
+ EXPECT_EQ(damage[5], damage[2]);
+ }
+}
diff --git a/test/battle/ability/filter.c b/test/battle/ability/filter.c
index 30662fe031..db3d353b79 100644
--- a/test/battle/ability/filter.c
+++ b/test/battle/ability/filter.c
@@ -9,7 +9,7 @@ SINGLE_BATTLE_TEST("Filter reduces damage to Super Effective moves by 0.75", s16
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_MR_MIME].types[0] == TYPE_PSYCHIC);
ASSUME(gSpeciesInfo[SPECIES_MR_MIME].types[1] == TYPE_FAIRY);
- ASSUME(gMovesInfo[MOVE_POISON_JAB].type == TYPE_POISON);
+ ASSUME(GetMoveType(MOVE_POISON_JAB) == TYPE_POISON);
ASSUME(gTypeEffectivenessTable[TYPE_POISON][TYPE_FAIRY] > UQ_4_12(1.0));
ASSUME(gTypeEffectivenessTable[TYPE_POISON][TYPE_PSYCHIC] == UQ_4_12(1.0));
PLAYER(SPECIES_MR_MIME) { Ability(ability); }
diff --git a/test/battle/ability/flare_boost.c b/test/battle/ability/flare_boost.c
index a4ff14382a..54bd3b9d38 100644
--- a/test/battle/ability/flare_boost.c
+++ b/test/battle/ability/flare_boost.c
@@ -1,4 +1,21 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Flare Boost (Ability) test titles")
+SINGLE_BATTLE_TEST("Flare Boost increases Sp. Attack by 50% when the Pokémon is burned", s16 damage)
+{
+ u32 status1;
+ PARAMETRIZE { status1 = STATUS1_NONE; }
+ PARAMETRIZE { status1 = STATUS1_BURN; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
+ PLAYER(SPECIES_DRIFBLIM) { Ability(ABILITY_FLARE_BOOST); Status1(status1); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SWIFT); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SWIFT, player);
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
+ }
+}
diff --git a/test/battle/ability/fur_coat.c b/test/battle/ability/fur_coat.c
index 56fb197114..2ad6a3d5a2 100644
--- a/test/battle/ability/fur_coat.c
+++ b/test/battle/ability/fur_coat.c
@@ -1,4 +1,44 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Fur Coat (Ability) test titles")
+ASSUMPTIONS
+{
+ ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL);
+}
+
+SINGLE_BATTLE_TEST("Fur Coat doubles Defense", s16 damage)
+{
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_FUR_COAT; }
+ PARAMETRIZE { ability = ABILITY_RATTLED; }
+
+ GIVEN {
+ PLAYER(SPECIES_PERSIAN_ALOLA) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_SCRATCH); }
+ } SCENE {
+ HP_BAR(player, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
+ }
+}
+
+SINGLE_BATTLE_TEST("Fur Coat has no effect on self-inflicted confusion damage", s16 damage)
+{
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_FUR_COAT; }
+ PARAMETRIZE { ability = ABILITY_RATTLED; }
+
+ GIVEN {
+ PLAYER(SPECIES_PERSIAN_ALOLA) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CONFUSE_RAY); MOVE(player, MOVE_POUND, WITH_RNG(RNG_CONFUSION, TRUE)); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFUSE_RAY, opponent);
+ HP_BAR(player, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ }
+}
diff --git a/test/battle/ability/iron_fist.c b/test/battle/ability/iron_fist.c
index ae26f9cdd0..360b3606be 100644
--- a/test/battle/ability/iron_fist.c
+++ b/test/battle/ability/iron_fist.c
@@ -1,4 +1,26 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Iron Fist (Ability) test titles")
+SINGLE_BATTLE_TEST("Iron Fist increases the power of punching moves by 20%", s16 damage)
+{
+ u32 move, ability;
+ PARAMETRIZE { move = MOVE_BULLET_PUNCH; ability = ABILITY_IRON_FIST; }
+ PARAMETRIZE { move = MOVE_BULLET_PUNCH; ability = ABILITY_BLAZE; }
+ PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_IRON_FIST; }
+ PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_BLAZE; }
+
+ GIVEN {
+ ASSUME(IsPunchingMove(MOVE_BULLET_PUNCH));
+ ASSUME(!IsPunchingMove(MOVE_SCRATCH));
+ ASSUME(GetMovePower(MOVE_BULLET_PUNCH) == GetMovePower(MOVE_SCRATCH));
+ PLAYER(SPECIES_CHIMCHAR) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, move); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.2), results[0].damage); // Iron Fist affects punching moves
+ EXPECT_EQ(results[2].damage, results[3].damage); // Iron Fist does not affect non-punching moves
+ }
+}
diff --git a/test/battle/ability/leaf_guard.c b/test/battle/ability/leaf_guard.c
index 94785bd29b..182f07787b 100644
--- a/test/battle/ability/leaf_guard.c
+++ b/test/battle/ability/leaf_guard.c
@@ -31,7 +31,41 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun")
}
}
-TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent non-volatile status conditions if Cloud Nine/Air Lock is on the field");
+SINGLE_BATTLE_TEST("Leaf Guard doesn't prevent non-volatile status conditions if Cloud Nine/Air Lock is on the field")
+{
+ u32 move, species, ability;
+ u16 status;
+ PARAMETRIZE { move = MOVE_WILL_O_WISP; status = STATUS1_BURN; species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { move = MOVE_HYPNOSIS; status = STATUS1_SLEEP; species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { move = MOVE_THUNDER_WAVE; status = STATUS1_PARALYSIS; species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { move = MOVE_WILL_O_WISP; status = STATUS1_BURN; species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ PARAMETRIZE { move = MOVE_HYPNOSIS; status = STATUS1_SLEEP; species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ PARAMETRIZE { move = MOVE_THUNDER_WAVE; status = STATUS1_PARALYSIS; species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ // PARAMETRIZE { move = MOVE_POWDER_SNOW; status = STATUS1_FREEZE; } // Pointless since you can't freeze in sunlight anyway
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_NON_VOLATILE_STATUS);
+ ASSUME(GetMoveNonVolatileStatus(MOVE_WILL_O_WISP) == MOVE_EFFECT_BURN);
+ ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_NON_VOLATILE_STATUS);
+ ASSUME(GetMoveNonVolatileStatus(MOVE_HYPNOSIS) == MOVE_EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_THUNDER_WAVE) == EFFECT_NON_VOLATILE_STATUS);
+ ASSUME(GetMoveNonVolatileStatus(MOVE_THUNDER_WAVE) == MOVE_EFFECT_PARALYSIS);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_NON_VOLATILE_STATUS);
+ ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC);
+ PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); }
+ OPPONENT(species) { Ability(ability); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, move); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, opponent);
+ NONE_OF {
+ ABILITY_POPUP(player, ABILITY_LEAF_GUARD);
+ MESSAGE("It doesn't affect Leafeon…");
+ }
+ STATUS_ICON(player, status);
+ }
+}
SINGLE_BATTLE_TEST("Leaf Guard prevents status conditions from Flame Orb and Toxic Orb")
{
@@ -50,29 +84,82 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents status conditions from Flame Orb and Tox
NONE_OF { MESSAGE("Leafeon was burned!"); STATUS_ICON(player, burn: TRUE); }
}
else {
- NONE_OF { MESSAGE("Leafeon was badly poisoned!"); STATUS_ICON(player, poison: TRUE); }
+ NONE_OF { MESSAGE("Leafeon was badly poisoned!"); STATUS_ICON(player, badPoison: TRUE); }
}
}
}
-TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent status conditions from Flame Orb and Toxic Orb if Cloud Nine/Air Lock is on the field");
-
-SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun")
+SINGLE_BATTLE_TEST("Leaf Guard doesn't prevent status conditions from Flame Orb and Toxic Orb if Cloud Nine/Air Lock is on the field")
{
+ u32 item, species, ability;
+ PARAMETRIZE { item = ITEM_FLAME_ORB; species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { item = ITEM_TOXIC_ORB; species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { item = ITEM_FLAME_ORB; species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ PARAMETRIZE { item = ITEM_TOXIC_ORB; species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
GIVEN {
- ASSUME(B_LEAF_GUARD_PREVENTS_REST >= GEN_5);
+ ASSUME(gItemsInfo[ITEM_FLAME_ORB].holdEffect == HOLD_EFFECT_FLAME_ORB);
+ ASSUME(gItemsInfo[ITEM_TOXIC_ORB].holdEffect == HOLD_EFFECT_TOXIC_ORB);
+ PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); Item(item); }
+ OPPONENT(species) { Ability(ability); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SUNNY_DAY); }
+ } SCENE {
+ if (item == ITEM_FLAME_ORB) {
+ MESSAGE("Leafeon was burned!");
+ STATUS_ICON(player, burn: TRUE);
+ }
+ else {
+ MESSAGE("Leafeon was badly poisoned!");
+ STATUS_ICON(player, badPoison: TRUE);
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun (Gen 5+)")
+{
+ u32 gen;
+ PARAMETRIZE { gen = GEN_4; }
+ PARAMETRIZE { gen = GEN_5; }
+ GIVEN {
+ WITH_CONFIG(GEN_CONFIG_LEAF_GUARD_PREVENTS_REST, gen);
ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); HP(100); MaxHP(200); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SUNNY_DAY); MOVE(player, MOVE_REST); }
} SCENE {
- MESSAGE("But it failed!");
- NONE_OF {
+ if (gen >= GEN_5) {
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player);
+ STATUS_ICON(player, sleep: TRUE);
+ HP_BAR(player);
+ }
+ }
+ else {
STATUS_ICON(player, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player);
HP_BAR(player);
}
}
}
-TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent Rest if Cloud Nine/Air Lock is on the field");
+SINGLE_BATTLE_TEST("Leaf Guard doesn't prevent Rest if Cloud Nine/Air Lock is on the field")
+{
+ u32 species, ability;
+ PARAMETRIZE { species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ GIVEN {
+ WITH_CONFIG(GEN_CONFIG_LEAF_GUARD_PREVENTS_REST, GEN_5);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
+ PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); HP(100); MaxHP(200); }
+ OPPONENT(species) { Ability(ability); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_SUNNY_DAY); MOVE(player, MOVE_REST); }
+ } SCENE {
+ STATUS_ICON(player, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player);
+ HP_BAR(player);
+ }
+}
diff --git a/test/battle/ability/libero.c b/test/battle/ability/libero.c
index 8ea93df3c0..b2ebf5cd5b 100644
--- a/test/battle/ability/libero.c
+++ b/test/battle/ability/libero.c
@@ -1,4 +1,4 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Libero (Ability) test titles")
+// Tests for Libero are handled in test/battle/ability/protean.c
diff --git a/test/battle/ability/magic_bounce.c b/test/battle/ability/magic_bounce.c
index 56c9a32332..9ef36de4af 100644
--- a/test/battle/ability/magic_bounce.c
+++ b/test/battle/ability/magic_bounce.c
@@ -42,6 +42,7 @@ SINGLE_BATTLE_TEST("Magic Bounce bounces back powder moves")
SINGLE_BATTLE_TEST("Magic Bounce cannot bounce back powder moves against Grass Types")
{
GIVEN {
+ WITH_CONFIG(GEN_CONFIG_POWDER_GRASS, GEN_6);
ASSUME(IsPowderMove(MOVE_STUN_SPORE));
ASSUME(GetSpeciesType(SPECIES_ODDISH, 0) == TYPE_GRASS);
PLAYER(SPECIES_ODDISH);
diff --git a/test/battle/ability/mold_breaker.c b/test/battle/ability/mold_breaker.c
index 2c04deeeef..fb6f9d11ab 100644
--- a/test/battle/ability/mold_breaker.c
+++ b/test/battle/ability/mold_breaker.c
@@ -1,4 +1,22 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Mold Breaker (Ability) test titles")
+SINGLE_BATTLE_TEST("Mold Breaker cancels damage reduction from Ice Scales", s16 damage)
+{
+ u16 ability;
+ PARAMETRIZE { ability = ABILITY_SHADOW_TAG; }
+ PARAMETRIZE { ability = ABILITY_MOLD_BREAKER; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_PSYCHIC) == DAMAGE_CATEGORY_SPECIAL);
+ PLAYER(SPECIES_WOBBUFFET) { Ability(ability); }
+ OPPONENT(SPECIES_FROSMOTH) { Ability(ABILITY_ICE_SCALES); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_PSYCHIC); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[1].damage, UQ_4_12(0.5), results[0].damage);
+ }
+}
+
+TO_DO_BATTLE_TEST("TODO: Write more Mold Breaker (Ability) test titles")
diff --git a/test/battle/ability/overcoat.c b/test/battle/ability/overcoat.c
index cfdbad7de3..5edda7c3d5 100644
--- a/test/battle/ability/overcoat.c
+++ b/test/battle/ability/overcoat.c
@@ -71,17 +71,29 @@ DOUBLE_BATTLE_TEST("Overcoat blocks damage from hail")
}
}
-SINGLE_BATTLE_TEST("Overcoat blocks Effect Spore's effect")
+SINGLE_BATTLE_TEST("Overcoat blocks Effect Spore's effect (Gen6+)")
{
+ u32 config;
+ PARAMETRIZE { config = GEN_5; }
+ PARAMETRIZE { config = GEN_6; }
GIVEN {
+ WITH_CONFIG(GEN_CONFIG_POWDER_OVERCOAT, config);
PLAYER(SPECIES_PINECO) {Ability(ABILITY_OVERCOAT);}
OPPONENT(SPECIES_SHROOMISH) {Ability(ABILITY_EFFECT_SPORE);}
} WHEN {
TURN { MOVE(player, MOVE_TACKLE, WITH_RNG(RNG_EFFECT_SPORE, 1)); }
} SCENE {
MESSAGE("Pineco used Tackle!");
- NOT ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
+ if (config == GEN_6) {
+ NOT ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
+ }
+ else {
+ ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
+ }
} THEN {
- EXPECT_EQ(player->status1, 0);
+ if (config == GEN_6)
+ EXPECT_EQ(player->status1, 0);
+ else
+ EXPECT_NE(player->status1, 0);
}
}
diff --git a/test/battle/ability/parental_bond.c b/test/battle/ability/parental_bond.c
index 1909efe281..c4b83d2e3b 100644
--- a/test/battle/ability/parental_bond.c
+++ b/test/battle/ability/parental_bond.c
@@ -354,6 +354,22 @@ SINGLE_BATTLE_TEST("Parental Bond does not trigger on two turn attacks")
}
}
+SINGLE_BATTLE_TEST("Parental Bond does not trigger Scale Shot effect on Drain Punch")
+{
+ GIVEN {
+ PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DRAIN_PUNCH, gimmick: GIMMICK_MEGA); MOVE(opponent, MOVE_CELEBRATE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAIN_PUNCH, player);
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ } THEN {
+ EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
+ EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
+ }
+}
+
TO_DO_BATTLE_TEST("Parental Bond tests");
// Temporary TODO: Convert Bulbapedia description into tests.
diff --git a/test/battle/ability/prism_armor.c b/test/battle/ability/prism_armor.c
index bdd93d127a..36fbc27f99 100644
--- a/test/battle/ability/prism_armor.c
+++ b/test/battle/ability/prism_armor.c
@@ -9,7 +9,7 @@ SINGLE_BATTLE_TEST("Prism Armor reduces damage to Super Effective moves by 0.75"
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_NECROZMA].types[0] == TYPE_PSYCHIC);
ASSUME(gSpeciesInfo[SPECIES_NECROZMA].types[1] == TYPE_PSYCHIC);
- ASSUME(gMovesInfo[MOVE_DARK_PULSE].type == TYPE_DARK);
+ ASSUME(GetMoveType(MOVE_DARK_PULSE) == TYPE_DARK);
ASSUME(gTypeEffectivenessTable[TYPE_POISON][TYPE_FAIRY] > UQ_4_12(1.0));
ASSUME(gTypeEffectivenessTable[TYPE_POISON][TYPE_PSYCHIC] == UQ_4_12(1.0));
PLAYER(SPECIES_NECROZMA);
diff --git a/test/battle/ability/protean.c b/test/battle/ability/protean.c
index fe4ae25e60..c41fa58cca 100644
--- a/test/battle/ability/protean.c
+++ b/test/battle/ability/protean.c
@@ -1,12 +1,15 @@
#include "global.h"
#include "test/battle.h"
-SINGLE_BATTLE_TEST("Protean changes the type of the user to the move used every time (Gen6-8)")
+SINGLE_BATTLE_TEST("Protean/Libero changes the type of the user to the move used every time (Gen6-8)")
{
+ u32 ability, species;
+ PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; }
+ PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
WITH_CONFIG(GEN_PROTEAN_LIBERO, GEN_6);
PLAYER(SPECIES_REGIROCK);
- OPPONENT(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); }
+ OPPONENT(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_WATER_GUN); }
@@ -15,24 +18,36 @@ SINGLE_BATTLE_TEST("Protean changes the type of the user to the move used every
TURN { SWITCH(opponent, 0); }
TURN { MOVE(opponent, MOVE_WATER_GUN); }
} SCENE {
- ABILITY_POPUP(opponent, ABILITY_PROTEAN);
- MESSAGE("The opposing Kecleon transformed into the Water type!");
+ ABILITY_POPUP(opponent, ability);
+ if (species == SPECIES_KECLEON)
+ MESSAGE("The opposing Kecleon transformed into the Water type!");
+ else
+ MESSAGE("The opposing Raboot transformed into the Water type!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
- ABILITY_POPUP(opponent, ABILITY_PROTEAN);
- MESSAGE("The opposing Kecleon transformed into the Normal type!");
+ ABILITY_POPUP(opponent, ability);
+ if (species == SPECIES_KECLEON)
+ MESSAGE("The opposing Kecleon transformed into the Normal type!");
+ else
+ MESSAGE("The opposing Raboot transformed into the Normal type!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
- ABILITY_POPUP(opponent, ABILITY_PROTEAN);
- MESSAGE("The opposing Kecleon transformed into the Water type!");
+ ABILITY_POPUP(opponent, ability);
+ if (species == SPECIES_KECLEON)
+ MESSAGE("The opposing Kecleon transformed into the Water type!");
+ else
+ MESSAGE("The opposing Raboot transformed into the Water type!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
}
}
-SINGLE_BATTLE_TEST("Protean changes the type of the user only once per switch in (Gen9+)")
+SINGLE_BATTLE_TEST("Protean/Libero changes the type of the user only once per switch in (Gen9+)")
{
+ u32 ability, species;
+ PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; }
+ PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
WITH_CONFIG(GEN_PROTEAN_LIBERO, GEN_9);
PLAYER(SPECIES_REGIROCK);
- OPPONENT(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); }
+ OPPONENT(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_WATER_GUN); }
@@ -41,31 +56,42 @@ SINGLE_BATTLE_TEST("Protean changes the type of the user only once per switch in
TURN { SWITCH(opponent, 0); }
TURN { MOVE(opponent, MOVE_WATER_GUN); }
} SCENE {
- ABILITY_POPUP(opponent, ABILITY_PROTEAN);
- MESSAGE("The opposing Kecleon transformed into the Water type!");
+ ABILITY_POPUP(opponent, ability);
+ if (species == SPECIES_KECLEON)
+ MESSAGE("The opposing Kecleon transformed into the Water type!");
+ else
+ MESSAGE("The opposing Raboot transformed into the Water type!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
NONE_OF {
- ABILITY_POPUP(opponent, ABILITY_PROTEAN);
+ ABILITY_POPUP(opponent, ability);
MESSAGE("The opposing Kecleon transformed into the Normal type!");
+ MESSAGE("The opposing Raboot transformed into the Normal type!");
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
- ABILITY_POPUP(opponent, ABILITY_PROTEAN);
- MESSAGE("The opposing Kecleon transformed into the Water type!");
+ ABILITY_POPUP(opponent, ability);
+ if (species == SPECIES_KECLEON)
+ MESSAGE("The opposing Kecleon transformed into the Water type!");
+ else
+ MESSAGE("The opposing Raboot transformed into the Water type!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
}
}
-SINGLE_BATTLE_TEST("Protean does not change the user's type when using Struggle")
+SINGLE_BATTLE_TEST("Protean/Libero does not change the user's type when using Struggle")
{
+ u32 ability, species;
+ PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_GRENINJA; }
+ PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
PLAYER(SPECIES_REGIROCK);
- OPPONENT(SPECIES_GRENINJA) { Ability(ABILITY_PROTEAN); }
+ OPPONENT(species) { Ability(ability); }
} WHEN {
TURN { MOVE(opponent, MOVE_STRUGGLE); }
} SCENE {
NONE_OF {
- ABILITY_POPUP(opponent, ABILITY_PROTEAN);
+ ABILITY_POPUP(opponent, ability);
MESSAGE("The opposing Greninja transformed into the Normal type!");
+ MESSAGE("The opposing Raboot transformed into the Normal type!");
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_STRUGGLE, opponent);
}
diff --git a/test/battle/ability/sharpness.c b/test/battle/ability/sharpness.c
index 10374faf5b..f737bab72a 100644
--- a/test/battle/ability/sharpness.c
+++ b/test/battle/ability/sharpness.c
@@ -1,7 +1,7 @@
#include "global.h"
#include "test/battle.h"
-SINGLE_BATTLE_TEST("Sharpness increases the power of slicing moves", s16 damage)
+SINGLE_BATTLE_TEST("Sharpness increases the power of slicing moves by 50%", s16 damage)
{
u32 move;
enum Ability ability;
diff --git a/test/battle/ability/solid_rock.c b/test/battle/ability/solid_rock.c
index 56c01e255d..d25fca6259 100644
--- a/test/battle/ability/solid_rock.c
+++ b/test/battle/ability/solid_rock.c
@@ -9,7 +9,7 @@ SINGLE_BATTLE_TEST("Solid Rock reduces damage to Super Effective moves by 0.75",
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_CARRACOSTA].types[0] == TYPE_WATER);
ASSUME(gSpeciesInfo[SPECIES_CARRACOSTA].types[1] == TYPE_ROCK);
- ASSUME(gMovesInfo[MOVE_CLOSE_COMBAT].type == TYPE_FIGHTING);
+ ASSUME(GetMoveType(MOVE_CLOSE_COMBAT) == TYPE_FIGHTING);
ASSUME(gTypeEffectivenessTable[TYPE_FIGHTING][TYPE_ROCK] > UQ_4_12(1.0));
ASSUME(gTypeEffectivenessTable[TYPE_FIGHTING][TYPE_WATER] == UQ_4_12(1.0));
PLAYER(SPECIES_CARRACOSTA) { Ability(ability); }
diff --git a/test/battle/ability/toxic_boost.c b/test/battle/ability/toxic_boost.c
index 85960c5b02..35a233ec23 100644
--- a/test/battle/ability/toxic_boost.c
+++ b/test/battle/ability/toxic_boost.c
@@ -1,4 +1,23 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Toxic Boost (Ability) test titles")
+SINGLE_BATTLE_TEST("Toxic Boost increases Attack by 50% when the Pokémon is poisoned", s16 damage)
+{
+ u32 status1;
+ PARAMETRIZE { status1 = STATUS1_NONE; }
+ PARAMETRIZE { status1 = STATUS1_POISON; }
+ PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_ZANGOOSE) { Ability(ABILITY_TOXIC_BOOST); Status1(status1); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SCRATCH); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player);
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[2].damage);
+ }
+}
diff --git a/test/battle/ai/ai.c b/test/battle/ai/ai.c
index 3ee1f28c17..bde40cece5 100644
--- a/test/battle/ai/ai.c
+++ b/test/battle/ai/ai.c
@@ -695,7 +695,7 @@ AI_SINGLE_BATTLE_TEST("AI won't use thawing moves if target is frozen unless it
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_SCALD].thawsUser == TRUE);
+ ASSUME(MoveThawsUser(MOVE_SCALD) == TRUE);
AI_FLAGS(aiFlags | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE); Status1(status); }
OPPONENT(SPECIES_VULPIX) { Moves(MOVE_TACKLE, aiMove); }
diff --git a/test/battle/ai/ai_double_ace.c b/test/battle/ai/ai_double_ace.c
index 3fa9ce77e0..38b7d1dcd8 100644
--- a/test/battle/ai/ai_double_ace.c
+++ b/test/battle/ai/ai_double_ace.c
@@ -94,3 +94,35 @@ AI_DOUBLE_BATTLE_TEST("AI_FLAG_DOUBLE_ACE_POKEMON: Ace mons won't be switched in
TURN { EXPECT_SWITCH(opponentLeft, 2); }
}
}
+
+AI_DOUBLE_BATTLE_TEST("AI_FLAG_DOUBLE_ACE_POKEMON: sends out Ace mons when no other options remain mid-battle")
+{
+ GIVEN {
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_SMART_SWITCHING | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_DOUBLE_ACE_POKEMON);
+
+ PLAYER(SPECIES_WOBBUFFET) { Level(50); Speed(200); Moves(MOVE_THUNDERBOLT, MOVE_CELEBRATE); SpAttack(200); }
+ PLAYER(SPECIES_WOBBUFFET) { Level(50); Speed(150); Moves(MOVE_THUNDERBOLT, MOVE_CELEBRATE); SpAttack(200); }
+
+ OPPONENT(SPECIES_ZIGZAGOON) { Level(5); HP(1); Speed(1); Moves(MOVE_SPLASH); }
+ OPPONENT(SPECIES_POOCHYENA) { Level(5); HP(1); Speed(1); Moves(MOVE_SPLASH); }
+
+ // Aces
+ OPPONENT(SPECIES_MIGHTYENA) { Level(50); Speed(10); Moves(MOVE_CRUNCH); }
+ OPPONENT(SPECIES_GENGAR) { Level(50); Speed(10); Moves(MOVE_SPLASH); }
+ } WHEN {
+ TURN {
+ MOVE(playerLeft, MOVE_THUNDERBOLT, target: opponentLeft);
+ MOVE(playerRight, MOVE_CELEBRATE);
+ EXPECT_MOVE(opponentLeft, MOVE_SPLASH);
+ EXPECT_MOVE(opponentRight, MOVE_SPLASH);
+ EXPECT_SEND_OUT(opponentLeft, 3);
+ }
+ TURN {
+ MOVE(playerLeft, MOVE_CELEBRATE);
+ MOVE(playerRight, MOVE_THUNDERBOLT, target: opponentRight);
+ EXPECT_MOVE(opponentLeft, MOVE_SPLASH);
+ EXPECT_MOVE(opponentRight, MOVE_SPLASH);
+ EXPECT_SEND_OUT(opponentRight, 2);
+ }
+ }
+}
diff --git a/test/battle/end_turn_effects.c b/test/battle/end_turn_effects.c
index 95ae96889f..931f792efe 100644
--- a/test/battle/end_turn_effects.c
+++ b/test/battle/end_turn_effects.c
@@ -29,6 +29,30 @@ DOUBLE_BATTLE_TEST("End Turn Effects: First Event Block is executed correctly (d
}
}
+DOUBLE_BATTLE_TEST("End Turn Effects: Effects are applied by Speed Order")
+{
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT) { MaxHP(200); HP(100); Speed(3); }
+ PLAYER(SPECIES_RILLABOOM) { MaxHP(200); HP(100); Speed(1); Ability(ABILITY_GRASSY_SURGE); }
+ OPPONENT(SPECIES_MEWTWO) { MaxHP(200); HP(100); Speed(2); }
+ OPPONENT(SPECIES_WOBBUFFET) { MaxHP(200); HP(100); Speed(4); }
+ } WHEN {
+ TURN {
+ MOVE(opponentLeft, MOVE_FAKE_OUT, target: playerLeft);
+ MOVE(playerRight, MOVE_FAKE_OUT, target: opponentRight);
+ }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, opponentLeft);
+ HP_BAR(playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, playerRight);
+ HP_BAR(opponentRight);
+
+ HP_BAR(opponentRight);
+ HP_BAR(playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(playerRight);
+ }
+}
MULTI_BATTLE_TEST("End Turn Effects: First Event Block is executed correctly (multibattle)")
{
@@ -115,4 +139,3 @@ ONE_VS_TWO_BATTLE_TEST("End Turn Effects: First Event Block is executed correctl
EXPECT_GT(damage, 0);
}
}
-
diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c
index 56adddee1a..bb9e3ce5bc 100644
--- a/test/battle/gimmick/terastal.c
+++ b/test/battle/gimmick/terastal.c
@@ -639,17 +639,21 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing into the Stellar type boosts all moves
}
}
-SINGLE_BATTLE_TEST("(TERA) Protean cannot change the type of a Terastallized Pokemon")
+SINGLE_BATTLE_TEST("(TERA) Protean/Libero cannot change the type of a Terastallized Pokemon")
{
+ u32 ability, species;
+ PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_GRENINJA; }
+ PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
- PLAYER(SPECIES_GRENINJA) { Ability(ABILITY_PROTEAN); TeraType(TYPE_GRASS); }
+ PLAYER(species) { Ability(ability); TeraType(TYPE_GRASS); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BUBBLE, gimmick: GIMMICK_TERA);
MOVE(opponent, MOVE_EMBER); }
} SCENE {
- MESSAGE("Greninja used Bubble!");
- MESSAGE("The opposing Wobbuffet used Ember!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BUBBLE, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, opponent);
MESSAGE("It's super effective!");
}
}
diff --git a/test/battle/hold_effect/life_orb.c b/test/battle/hold_effect/life_orb.c
index 81ddd614db..e983537b83 100644
--- a/test/battle/hold_effect/life_orb.c
+++ b/test/battle/hold_effect/life_orb.c
@@ -34,6 +34,7 @@ SINGLE_BATTLE_TEST("Life Orb activates if it hits a Substitute")
SINGLE_BATTLE_TEST("Life Orb does not activate if using status move on a Substitute")
{
GIVEN {
+ ASSUME(MoveIgnoresSubstitute(MOVE_GROWL));
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LIFE_ORB); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_animations/all_anims.c b/test/battle/move_animations/all_anims.c
index 11b286084e..01f105f8f3 100644
--- a/test/battle/move_animations/all_anims.c
+++ b/test/battle/move_animations/all_anims.c
@@ -11,67 +11,43 @@
static void ParametrizeMovesAndSpecies(u32 j, u32 *pMove, u32 *pSpecies, u32 variation)
{
- if (gMovesInfo[j].effect == EFFECT_DARK_VOID) // User needs to be Darkrai
+ enum BattleMoveEffects effect = GetMoveEffect(j);
+ if (effect == EFFECT_DARK_VOID) // User needs to be Darkrai
{
*pMove = j;
*pSpecies = SPECIES_DARKRAI;
}
- else if (gMovesInfo[j].effect == EFFECT_HYPERSPACE_FURY) // User needs to be Hoopa Unbound
+ else if (effect == EFFECT_HYPERSPACE_FURY) // User needs to be Hoopa Unbound
{
*pMove = j;
*pSpecies = SPECIES_HOOPA_UNBOUND;
}
- else if (gMovesInfo[j].effect == EFFECT_AURA_WHEEL) // User needs to be Morpeko
+ else if (effect == EFFECT_AURA_WHEEL) // User needs to be Morpeko
{
*pMove = j;
*pSpecies = SPECIES_MORPEKO_FULL_BELLY;
}
- else if (gMovesInfo[j].effect == EFFECT_ROTOTILLER || gMovesInfo[j].effect == EFFECT_FLOWER_SHIELD) // User needs to be Grass-type
+ else if (effect == EFFECT_ROTOTILLER || effect == EFFECT_FLOWER_SHIELD) // User needs to be Grass-type
{
*pMove = j;
*pSpecies = SPECIES_TANGELA;
}
- else if (gMovesInfo[j].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE && gMovesInfo[j].argument.type == TYPE_FIRE) // User needs to be Fire-type
+ else if (effect == EFFECT_FAIL_IF_NOT_ARG_TYPE && GetMoveArgType(j) == TYPE_FIRE) // User needs to be Fire-type
{
*pMove = j;
*pSpecies = SPECIES_FLAREON;
}
- else if (gMovesInfo[j].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE && gMovesInfo[j].argument.type == TYPE_ELECTRIC) // User needs to be Electric-type
+ else if (effect == EFFECT_FAIL_IF_NOT_ARG_TYPE && GetMoveArgType(j) == TYPE_ELECTRIC) // User needs to be Electric-type
{
*pMove = j;
*pSpecies = SPECIES_JOLTEON;
}
- else if (gMovesInfo[j].effect == EFFECT_CURSE && variation == 1) // User needs to be Ghost-type
- {
- *pMove = j;
- *pSpecies = SPECIES_GASTLY;
- }
- else if (gMovesInfo[j].effect == EFFECT_MAGNETIC_FLUX || gMovesInfo[j].effect == EFFECT_GEAR_UP) // User needs to have Plus
+ else if (effect == EFFECT_MAGNETIC_FLUX || effect == EFFECT_GEAR_UP) // User needs to have Plus
{
*pMove = j;
*pSpecies = SPECIES_KLINKLANG;
}
- else if (gMovesInfo[j].effect == EFFECT_IVY_CUDGEL && variation > 0)
- {
- *pMove = j;
- if (variation == 1)
- *pSpecies = SPECIES_OGERPON_WELLSPRING;
- else if (variation == 2)
- *pSpecies = SPECIES_OGERPON_HEARTHFLAME;
- else
- *pSpecies = SPECIES_OGERPON_CORNERSTONE;
- }
- else if (gMovesInfo[j].effect == EFFECT_DRAGON_DARTS && variation > 0)
- {
- *pMove = j;
- *pSpecies = SPECIES_DRAGAPULT;
- }
- else if (gMovesInfo[j].effect == EFFECT_TERA_STARSTORM && variation == 1)
- {
- *pMove = j;
- *pSpecies = SPECIES_TERAPAGOS_STELLAR;
- }
- else if (gMovesInfo[j].effect == EFFECT_PLACEHOLDER) // Ignore placeholder *pMoves
+ else if (effect == EFFECT_PLACEHOLDER) // Ignore placeholder *pMoves
{
*pMove = MOVE_POUND;
*pSpecies = SPECIES_WOBBUFFET;
@@ -154,46 +130,49 @@ static bool32 GetParametrizedShinyness(u32 move, u32 variation)
static bool32 TargetHasToMove(u32 move) // Opponent needs to hit the player first
{
- if (gMovesInfo[move].effect == EFFECT_COUNTER
- || gMovesInfo[move].effect == EFFECT_MIRROR_MOVE
- || gMovesInfo[move].effect == EFFECT_CONVERSION_2
- || gMovesInfo[move].effect == EFFECT_MIRROR_COAT
- || gMovesInfo[move].effect == EFFECT_METAL_BURST
- || gMovesInfo[move].effect == EFFECT_COPYCAT
- || gMovesInfo[move].effect == EFFECT_SUCKER_PUNCH
- || gMovesInfo[move].effect == EFFECT_INSTRUCT)
+ enum BattleMoveEffects effect = GetMoveEffect(move);
+ if (effect == EFFECT_COUNTER
+ || effect == EFFECT_MIRROR_MOVE
+ || effect == EFFECT_CONVERSION_2
+ || effect == EFFECT_MIRROR_COAT
+ || effect == EFFECT_METAL_BURST
+ || effect == EFFECT_COPYCAT
+ || effect == EFFECT_SUCKER_PUNCH
+ || effect == EFFECT_INSTRUCT)
return TRUE;
return FALSE;
}
static bool32 AttackerHasToSwitch(u32 move) // User needs to send out a different team member
{
- if (gMovesInfo[move].effect == EFFECT_TELEPORT
- || gMovesInfo[move].effect == EFFECT_EXPLOSION
- || gMovesInfo[move].effect == EFFECT_MISTY_EXPLOSION
- || gMovesInfo[move].effect == EFFECT_BATON_PASS
- || gMovesInfo[move].effect == EFFECT_MEMENTO
- || gMovesInfo[move].effect == EFFECT_HEALING_WISH
- || gMovesInfo[move].effect == EFFECT_HIT_ESCAPE
- || gMovesInfo[move].effect == EFFECT_FINAL_GAMBIT
- || gMovesInfo[move].effect == EFFECT_PARTING_SHOT
- || gMovesInfo[move].effect == EFFECT_SHED_TAIL
- || gMovesInfo[move].effect == EFFECT_CHILLY_RECEPTION)
+ enum BattleMoveEffects effect = GetMoveEffect(move);
+ if (effect == EFFECT_TELEPORT
+ || effect == EFFECT_EXPLOSION
+ || effect == EFFECT_MISTY_EXPLOSION
+ || effect == EFFECT_BATON_PASS
+ || effect == EFFECT_MEMENTO
+ || effect == EFFECT_HEALING_WISH
+ || effect == EFFECT_HIT_ESCAPE
+ || effect == EFFECT_FINAL_GAMBIT
+ || effect == EFFECT_PARTING_SHOT
+ || effect == EFFECT_SHED_TAIL
+ || effect == EFFECT_CHILLY_RECEPTION)
return TRUE;
return FALSE;
}
static bool32 UserHasToGoFirst(u32 move) // Player needs to go first
{
- if (gMovesInfo[move].effect == EFFECT_PROTECT
- || gMovesInfo[move].effect == EFFECT_ENDURE
- || gMovesInfo[move].effect == EFFECT_FOLLOW_ME
- || gMovesInfo[move].effect == EFFECT_MAGIC_COAT
- || gMovesInfo[move].effect == EFFECT_ME_FIRST
- || gMovesInfo[move].effect == EFFECT_QUASH
- || gMovesInfo[move].effect == EFFECT_MAT_BLOCK
- || gMovesInfo[move].effect == EFFECT_ELECTRIFY
- || gMovesInfo[move].effect == EFFECT_SHELL_TRAP)
+ enum BattleMoveEffects effect = GetMoveEffect(move);
+ if (effect == EFFECT_PROTECT
+ || effect == EFFECT_ENDURE
+ || effect == EFFECT_FOLLOW_ME
+ || effect == EFFECT_MAGIC_COAT
+ || effect == EFFECT_ME_FIRST
+ || effect == EFFECT_QUASH
+ || effect == EFFECT_MAT_BLOCK
+ || effect == EFFECT_ELECTRIFY
+ || effect == EFFECT_SHELL_TRAP)
return TRUE;
return FALSE;
}
@@ -230,57 +209,58 @@ static u32 GetVariationsNumber(u32 move, bool8 isDouble)
}
static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 variation)
{
+ enum BattleMoveEffects effect = GetMoveEffect(move);
// Setup turn
- if (gMovesInfo[move].effect == EFFECT_SNORE
- || gMovesInfo[move].effect == EFFECT_SLEEP_TALK)
+ if (effect == EFFECT_SNORE
+ || effect == EFFECT_SLEEP_TALK)
{ // attacker needs to be asleep
TURN { MOVE(attacker, MOVE_REST); }
}
- else if (gMovesInfo[move].effect == EFFECT_SPIT_UP
- || gMovesInfo[move].effect == EFFECT_SWALLOW)
+ else if (effect == EFFECT_SPIT_UP
+ || effect == EFFECT_SWALLOW)
{ // attacker needs to have used Stockpile
for (u32 i = 0; i <= variation; i++)
{
TURN { MOVE(attacker, MOVE_STOCKPILE); }
}
}
- else if ((gMovesInfo[move].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS && gMovesInfo[move].argument.status == STATUS1_PARALYSIS))
+ else if ((effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS && GetMoveEffectArg_Status(move) == STATUS1_PARALYSIS))
{ // defender needs to be paralyzed
TURN { MOVE(attacker, MOVE_THUNDER_WAVE); }
}
- else if (gMovesInfo[move].effect == EFFECT_RECYCLE
- || gMovesInfo[move].effect == EFFECT_BELCH)
+ else if (effect == EFFECT_RECYCLE
+ || effect == EFFECT_BELCH)
{ // attacker needs to have eaten its Berry
TURN { MOVE(attacker, MOVE_STUFF_CHEEKS); }
}
- else if (gMovesInfo[move].effect == EFFECT_REFRESH
- || gMovesInfo[move].effect == EFFECT_PSYCHO_SHIFT)
+ else if (effect == EFFECT_REFRESH
+ || effect == EFFECT_PSYCHO_SHIFT)
{ // attacker needs to be paralyzed
TURN { MOVE(defender, MOVE_THUNDER_WAVE); }
}
- else if (gMovesInfo[move].effect == EFFECT_LAST_RESORT)
+ else if (effect == EFFECT_LAST_RESORT)
{ // attacker needs to have used all other moves
TURN { MOVE(attacker, MOVE_POUND); }
}
- else if (gMovesInfo[move].effect == EFFECT_DREAM_EATER
- || gMovesInfo[move].effect == EFFECT_NIGHTMARE)
+ else if (effect == EFFECT_DREAM_EATER
+ || effect == EFFECT_NIGHTMARE)
{ // defender needs to be asleep
TURN { MOVE(defender, MOVE_REST); }
}
- else if (gMovesInfo[move].effect == EFFECT_VENOM_DRENCH
- || gMovesInfo[move].effect == EFFECT_PURIFY)
+ else if (effect == EFFECT_VENOM_DRENCH
+ || effect == EFFECT_PURIFY)
{ // defender needs to be poisoned
TURN { MOVE(attacker, MOVE_POISON_POWDER); }
}
- else if (gMovesInfo[move].effect == EFFECT_TOPSY_TURVY)
+ else if (effect == EFFECT_TOPSY_TURVY)
{ // defender needs to have its stats buffed
TURN { MOVE(defender, MOVE_SWORDS_DANCE); }
}
- else if (gMovesInfo[move].effect == EFFECT_AURORA_VEIL)
+ else if (effect == EFFECT_AURORA_VEIL)
{ // Has to be hailing
TURN { MOVE(attacker, MOVE_HAIL); }
}
- else if (gMovesInfo[move].effect == EFFECT_STEEL_ROLLER)
+ else if (effect == EFFECT_STEEL_ROLLER)
{ // Needs a terrain
TURN { MOVE(attacker, MOVE_ELECTRIC_TERRAIN); }
}
@@ -314,15 +294,15 @@ static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattleP
TURN {
if (TargetHasToMove(move))
{
- MOVE(defender, gMovesInfo[move].effect == EFFECT_MIRROR_COAT ? MOVE_SWIFT : MOVE_POUND);
+ MOVE(defender, effect == EFFECT_MIRROR_COAT ? MOVE_SWIFT : MOVE_POUND);
MOVE(attacker, move);
}
- else if (gMovesInfo[move].effect == EFFECT_SNATCH)
+ else if (effect == EFFECT_SNATCH)
{ // defender needs to steal the defender's buffing move
MOVE(attacker, move);
MOVE(defender, MOVE_SWORDS_DANCE);
}
- else if (gMovesInfo[move].effect == EFFECT_OHKO || gMovesInfo[move].effect == EFFECT_SHEER_COLD)
+ else if (effect == EFFECT_OHKO || effect == EFFECT_SHEER_COLD)
{ // defender needs to send out a different team member
MOVE(attacker, move);
SEND_OUT(defender, 1);
@@ -337,17 +317,17 @@ static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattleP
MOVE(attacker, move);
MOVE(defender, MOVE_POUND);
}
- else if (gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING)
+ else if (effect == EFFECT_REVIVAL_BLESSING)
{ // attacker selects party member
MOVE(attacker, move, partyIndex: 1);
MOVE(defender, MOVE_HELPING_HAND);
}
- else if (gMovesInfo[move].effect == EFFECT_UPPER_HAND)
+ else if (effect == EFFECT_UPPER_HAND)
{ // defender needs to choose priority move
MOVE(attacker, move);
MOVE(defender, MOVE_QUICK_ATTACK);
}
- else if (gMovesInfo[move].effect == EFFECT_ACUPRESSURE)
+ else if (effect == EFFECT_ACUPRESSURE)
{
MOVE(attacker, move, target: attacker);
}
@@ -411,22 +391,23 @@ static void WhenSingles(u32 move, struct BattlePokemon *attacker, struct BattleP
static void SceneSingles(u32 move, struct BattlePokemon *mon)
{
- if (gMovesInfo[move].effect == EFFECT_FOLLOW_ME
- || gMovesInfo[move].effect == EFFECT_HELPING_HAND
- || gMovesInfo[move].effect == EFFECT_AFTER_YOU
- || gMovesInfo[move].effect == EFFECT_ALLY_SWITCH
- || gMovesInfo[move].effect == EFFECT_AROMATIC_MIST
+ enum BattleMoveEffects effect = GetMoveEffect(move);
+ if (effect == EFFECT_FOLLOW_ME
+ || effect == EFFECT_HELPING_HAND
+ || effect == EFFECT_AFTER_YOU
+ || effect == EFFECT_ALLY_SWITCH
+ || effect == EFFECT_AROMATIC_MIST
|| move == MOVE_HOLD_HANDS // Hack here because it shares its effect with Splash and Celebrate
- || gMovesInfo[move].effect == EFFECT_COACHING
- || gMovesInfo[move].effect == EFFECT_DRAGON_CHEER)
+ || effect == EFFECT_COACHING
+ || effect == EFFECT_DRAGON_CHEER)
{
// Moves that fail in Single Battles
}
- else if (gMovesInfo[move].effect == EFFECT_MIRROR_MOVE) // Copy the opponent's move
+ else if (effect == EFFECT_MIRROR_MOVE) // Copy the opponent's move
{
ANIMATION(ANIM_TYPE_MOVE, MOVE_POUND, mon);
}
- else if (gMovesInfo[move].effect == EFFECT_NATURE_POWER) // Recorded battles always use BATTLE_ENVIRONMENT_BUILDING
+ else if (effect == EFFECT_NATURE_POWER) // Recorded battles always use BATTLE_ENVIRONMENT_BUILDING
{
ANIMATION(ANIM_TYPE_MOVE, B_NATURE_POWER_MOVES >= GEN_4 ? MOVE_TRI_ATTACK : MOVE_SWIFT, mon);
}
@@ -438,57 +419,58 @@ static void SceneSingles(u32 move, struct BattlePokemon *mon)
static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattlePokemon *target, struct BattlePokemon *ignore1, struct BattlePokemon *ignore2, u32 variation)
{
+ enum BattleMoveEffects effect = GetMoveEffect(move);
// Setup turn
- if (gMovesInfo[move].effect == EFFECT_SNORE
- || gMovesInfo[move].effect == EFFECT_SLEEP_TALK)
+ if (effect == EFFECT_SNORE
+ || effect == EFFECT_SLEEP_TALK)
{ // Player needs to be asleep
TURN { MOVE(attacker, MOVE_REST); }
}
- else if (gMovesInfo[move].effect == EFFECT_SPIT_UP
- || gMovesInfo[move].effect == EFFECT_SWALLOW)
+ else if (effect == EFFECT_SPIT_UP
+ || effect == EFFECT_SWALLOW)
{ // Player needs to have used Stockpile
for (u32 i = 0; i <= variation; i++)
{
TURN { MOVE(attacker, MOVE_STOCKPILE); }
}
}
- else if ((gMovesInfo[move].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS && gMovesInfo[move].argument.status == STATUS1_PARALYSIS))
+ else if ((effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS && GetMoveEffectArg_Status(move) == STATUS1_PARALYSIS))
{ // Opponent needs to be paralyzed
TURN { MOVE(attacker, MOVE_THUNDER_WAVE, target: target); }
}
- else if (gMovesInfo[move].effect == EFFECT_RECYCLE
- || gMovesInfo[move].effect == EFFECT_BELCH)
+ else if (effect == EFFECT_RECYCLE
+ || effect == EFFECT_BELCH)
{ // Player needs to have eaten its Berry
TURN { MOVE(attacker, MOVE_STUFF_CHEEKS); }
}
- else if (gMovesInfo[move].effect == EFFECT_REFRESH
- || gMovesInfo[move].effect == EFFECT_PSYCHO_SHIFT)
+ else if (effect == EFFECT_REFRESH
+ || effect == EFFECT_PSYCHO_SHIFT)
{ // Player needs to be paralyzed
TURN { MOVE(target, MOVE_THUNDER_WAVE, target: attacker); }
}
- else if (gMovesInfo[move].effect == EFFECT_LAST_RESORT)
+ else if (effect == EFFECT_LAST_RESORT)
{ // Player needs to have used all other moves
TURN { MOVE(attacker, MOVE_POUND, target: target); }
}
- else if (gMovesInfo[move].effect == EFFECT_DREAM_EATER
- || gMovesInfo[move].effect == EFFECT_NIGHTMARE)
+ else if (effect == EFFECT_DREAM_EATER
+ || effect == EFFECT_NIGHTMARE)
{ // Opponent needs to be asleep
TURN { MOVE(target, MOVE_REST); }
}
- else if (gMovesInfo[move].effect == EFFECT_VENOM_DRENCH
- || gMovesInfo[move].effect == EFFECT_PURIFY)
+ else if (effect == EFFECT_VENOM_DRENCH
+ || effect == EFFECT_PURIFY)
{ // Opponent needs to be poisoned
TURN { MOVE(attacker, MOVE_POISON_POWDER, target: target); }
}
- else if (gMovesInfo[move].effect == EFFECT_TOPSY_TURVY)
+ else if (effect == EFFECT_TOPSY_TURVY)
{ // Opponent needs to have its stats buffed
TURN { MOVE(target, MOVE_SWORDS_DANCE); }
}
- else if (gMovesInfo[move].effect == EFFECT_AURORA_VEIL)
+ else if (effect == EFFECT_AURORA_VEIL)
{ // Has to be hailing
TURN { MOVE(attacker, MOVE_HAIL); }
}
- else if (gMovesInfo[move].effect == EFFECT_STEEL_ROLLER)
+ else if (effect == EFFECT_STEEL_ROLLER)
{ // Needs a terrain
TURN { MOVE(attacker, MOVE_ELECTRIC_TERRAIN); }
}
@@ -522,15 +504,15 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP
TURN {
if (TargetHasToMove(move))
{ // Opponent needs to hit the player first
- MOVE(target, gMovesInfo[move].effect == EFFECT_MIRROR_COAT ? MOVE_SWIFT : MOVE_POUND, target: attacker);
+ MOVE(target, effect == EFFECT_MIRROR_COAT ? MOVE_SWIFT : MOVE_POUND, target: attacker);
MOVE(attacker, move, target: target);
}
- else if (gMovesInfo[move].effect == EFFECT_SNATCH)
+ else if (effect == EFFECT_SNATCH)
{ // Opponent needs to steal the opponent's buffing move
MOVE(attacker, move, target: target);
MOVE(target, MOVE_SWORDS_DANCE);
}
- else if (gMovesInfo[move].effect == EFFECT_OHKO || gMovesInfo[move].effect == EFFECT_SHEER_COLD)
+ else if (effect == EFFECT_OHKO || effect == EFFECT_SHEER_COLD)
{ // Opponent needs to send out a different team member
MOVE(attacker, move, target: target);
SEND_OUT(target, 2);
@@ -545,19 +527,19 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP
MOVE(attacker, move, target: target);
MOVE(target, MOVE_POUND, target: attacker);
}
- else if (gMovesInfo[move].effect == EFFECT_AFTER_YOU)
+ else if (effect == EFFECT_AFTER_YOU)
{ // Player goes first, opponent third
MOVE(attacker, move, target: target);
MOVE(ignore1, MOVE_CELEBRATE);
MOVE(target, MOVE_POUND, target: attacker);
MOVE(ignore2, MOVE_CELEBRATE);
}
- else if (gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING)
+ else if (effect == EFFECT_REVIVAL_BLESSING)
{ // Player selects party member
MOVE(attacker, move, partyIndex: 2);
MOVE(target, MOVE_LAST_RESORT, target: attacker); // Last Resort, so there's no anim on the opponent's side.
}
- else if (gMovesInfo[move].effect == EFFECT_UPPER_HAND)
+ else if (effect == EFFECT_UPPER_HAND)
{ // Opponent needs to choose priority move
MOVE(attacker, move, target: target);
MOVE(target, MOVE_QUICK_ATTACK, target: attacker);
@@ -600,7 +582,7 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP
MOVE(target, MOVE_LAST_RESORT, target: attacker); // Last Resort, so there's no anim on the opponent's side.
MOVE(attacker, move, target: target);
}
- if (gMovesInfo[move].effect != EFFECT_AFTER_YOU)
+ if (effect != EFFECT_AFTER_YOU)
{
// Actions for the remaining battlers
MOVE(ignore1, MOVE_CELEBRATE);
@@ -628,15 +610,16 @@ static void DoublesWhen(u32 move, struct BattlePokemon *attacker, struct BattleP
static void DoublesScene(u32 move, struct BattlePokemon *attacker)
{
- if (gMovesInfo[move].effect == EFFECT_MAGNETIC_FLUX || gMovesInfo[move].effect == EFFECT_GEAR_UP) // For some reason, Magnetic Flux and Gear Up are failing in Double Battles here
+ enum BattleMoveEffects effect = GetMoveEffect(move);
+ if (effect == EFFECT_MAGNETIC_FLUX || effect == EFFECT_GEAR_UP) // For some reason, Magnetic Flux and Gear Up are failing in Double Battles here
{
// Moves that fail in Double Battles
}
- else if (gMovesInfo[move].effect == EFFECT_MIRROR_MOVE)
+ else if (effect == EFFECT_MIRROR_MOVE)
{ // Copy the opponent's move
ANIMATION(ANIM_TYPE_MOVE, MOVE_POUND, attacker);
}
- else if (gMovesInfo[move].effect == EFFECT_NATURE_POWER)
+ else if (effect == EFFECT_NATURE_POWER)
{ // Recorded battles always use BATTLE_ENVIRONMENT_BUILDING
ANIMATION(ANIM_TYPE_MOVE, B_NATURE_POWER_MOVES >= GEN_4 ? MOVE_TRI_ATTACK : MOVE_SWIFT, attacker);
}
@@ -671,18 +654,18 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (player to op
Level(GetParametrizedLevel(move, variation));
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW)
+ if (GetMoveEffect(move) != EFFECT_BESTOW)
Item(ITEM_ORAN_BERRY);
}
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); }
@@ -693,7 +676,7 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (player to op
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -718,18 +701,18 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (opponent to
Level(GetParametrizedLevel(move, variation));
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW)
+ if (GetMoveEffect(move) != EFFECT_BESTOW)
Item(ITEM_ORAN_BERRY);
}
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); }
@@ -740,7 +723,7 @@ SINGLE_BATTLE_TEST("Move Animations don't leak when used - Singles (opponent to
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -770,7 +753,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == playerLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -782,7 +765,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
if (attacker == playerRight)
{
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -790,16 +773,16 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW)
+ if (GetMoveEffect(move) != EFFECT_BESTOW)
Item(ITEM_ORAN_BERRY);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW)
+ if (GetMoveEffect(move) != EFFECT_BESTOW)
Item(ITEM_ORAN_BERRY);
}
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); }
@@ -810,7 +793,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -840,7 +823,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -851,7 +834,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -859,17 +842,17 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -881,7 +864,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -911,7 +894,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == playerLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -922,7 +905,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == playerRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -930,17 +913,17 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -952,7 +935,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -982,7 +965,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -993,7 +976,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1001,17 +984,17 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1023,7 +1006,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1053,7 +1036,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == playerLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1064,7 +1047,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == playerRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1072,17 +1055,17 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1094,7 +1077,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1124,7 +1107,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1135,7 +1118,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1143,17 +1126,17 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1165,7 +1148,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentLeft
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1195,7 +1178,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == playerLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1206,7 +1189,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == playerRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1214,17 +1197,17 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1236,7 +1219,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1266,7 +1249,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1277,7 +1260,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
@@ -1285,17 +1268,17 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1307,7 +1290,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1331,7 +1314,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
@@ -1339,23 +1322,23 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1367,7 +1350,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerLeft t
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1390,7 +1373,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
@@ -1398,23 +1381,23 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1426,7 +1409,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (playerRight
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1449,7 +1432,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentleft
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
@@ -1457,23 +1440,23 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentleft
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1485,7 +1468,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentleft
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1508,7 +1491,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentLeft) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
@@ -1516,23 +1499,23 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
HP(9997); MaxHP(9999); Item(ITEM_ORAN_BERRY);
if (attacker == opponentRight) {
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
}
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND, MOVE_CELEBRATE);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW) {
+ if (GetMoveEffect(move) != EFFECT_BESTOW) {
Item(ITEM_ORAN_BERRY);
}
}
@@ -1544,7 +1527,7 @@ DOUBLE_BATTLE_TEST("Move Animations don't leak when used - Doubles (opponentRigh
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1570,29 +1553,29 @@ SINGLE_BATTLE_TEST("Move Animations occur before their stat change animations -
Level(GetParametrizedLevel(move, variation));
HP(GetParametrizedHP(move, variation)); MaxHP(9999); Item(GetParametrizedItem(move, variation));
if (species == SPECIES_WOBBUFFET) Gender(MON_FEMALE);
- if (gMovesInfo[move].effect == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
+ if (GetMoveEffect(move) == EFFECT_LAST_RESORT) Moves(move, MOVE_POUND);
if (species == SPECIES_KLINKLANG) Ability(ABILITY_PLUS);
if (friendship) Friendship(friendship);
if (GetParametrizedShinyness(move, variation)) Shiny(TRUE);
}
PLAYER(SPECIES_WOBBUFFET) {
Gender(MON_MALE); MaxHP(9999); Moves(MOVE_POUND);
- HP(gMovesInfo[move].effect == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
+ HP(GetMoveEffect(move) == EFFECT_REVIVAL_BLESSING ? 0 : 9998);
}
OPPONENT(SPECIES_WOBBUFFET) {
Gender(MON_MALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); Ability(ABILITY_TELEPATHY);
- if (gMovesInfo[move].effect != EFFECT_BESTOW)
+ if (GetMoveEffect(move) != EFFECT_BESTOW)
Item(ITEM_ORAN_BERRY);
}
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); HP(9998); MaxHP(9999); SpDefense(9999); Defense(9999); }
} WHEN {
WhenSingles(move, player, opponent, variation);
} SCENE {
- if (!(gMovesInfo[move].effect == EFFECT_RECYCLE
- || gMovesInfo[move].effect == EFFECT_BELCH
- || gMovesInfo[move].effect == EFFECT_SPIT_UP
- || gMovesInfo[move].effect == EFFECT_SWALLOW
- || gMovesInfo[move].effect == EFFECT_TOPSY_TURVY)) // require a move that boosts stats before using this move
+ if (!(GetMoveEffect(move) == EFFECT_RECYCLE
+ || GetMoveEffect(move) == EFFECT_BELCH
+ || GetMoveEffect(move) == EFFECT_SPIT_UP
+ || GetMoveEffect(move) == EFFECT_SWALLOW
+ || GetMoveEffect(move) == EFFECT_TOPSY_TURVY)) // require a move that boosts stats before using this move
{
NONE_OF {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
@@ -1603,7 +1586,7 @@ SINGLE_BATTLE_TEST("Move Animations occur before their stat change animations -
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1671,7 +1654,7 @@ SINGLE_BATTLE_TEST("Z-Moves don't leak when used - Singles (player to opponent)"
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1700,7 +1683,7 @@ SINGLE_BATTLE_TEST("Z-Moves don't leak when used - Singles (opponent to player)"
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1731,7 +1714,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (playerLeft to oppone
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1762,7 +1745,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (playerLeft to oppone
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1793,7 +1776,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (playerRight to oppon
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1824,7 +1807,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (playerRight to oppon
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1855,7 +1838,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (opponentLeft to play
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1886,7 +1869,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (opponentLeft to play
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1917,7 +1900,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (opponentRight to pla
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1948,7 +1931,7 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (opponentRight to pla
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -1993,7 +1976,7 @@ SINGLE_BATTLE_TEST("Tera Blast doesn't leak when used - Singles (player to oppon
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2015,7 +1998,7 @@ SINGLE_BATTLE_TEST("Tera Blast doesn't leak when used - Singles (opponent to pla
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2039,7 +2022,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerLeft to o
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2063,7 +2046,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerLeft to o
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2087,7 +2070,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerRight to
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2111,7 +2094,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerRight to
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2135,7 +2118,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentLeft to
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2159,7 +2142,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentLeft to
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2183,7 +2166,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentRight t
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
@@ -2207,7 +2190,7 @@ DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentRight t
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
- DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
+ DebugPrintf("Move failed: %S (%u)", GetMoveName(move), move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
diff --git a/test/battle/move_effect/ally_switch.c b/test/battle/move_effect/ally_switch.c
index a7fddb247c..8862c49cff 100644
--- a/test/battle/move_effect/ally_switch.c
+++ b/test/battle/move_effect/ally_switch.c
@@ -170,7 +170,7 @@ DOUBLE_BATTLE_TEST("Ally Switch - move fails if the target was ally which change
DOUBLE_BATTLE_TEST("Ally Switch doesn't make self-targeting status moves fail")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_HARDEN].target == MOVE_TARGET_USER);
+ ASSUME(GetMoveTarget(MOVE_HARDEN) == MOVE_TARGET_USER);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/brine.c b/test/battle/move_effect/brine.c
index 9165257859..5f1504437d 100644
--- a/test/battle/move_effect/brine.c
+++ b/test/battle/move_effect/brine.c
@@ -1,4 +1,25 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("Brine's power doubles if the target is at 50% or below max HP");
+SINGLE_BATTLE_TEST("Brine's power doubles if the target is at 50% or below max HP", s16 damage)
+{
+ bool32 halfHP;
+ PARAMETRIZE { halfHP = FALSE; }
+ PARAMETRIZE { halfHP = TRUE; }
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_BRINE) == EFFECT_BRINE);
+ PLAYER(SPECIES_SQUIRTLE);
+ OPPONENT(SPECIES_BLISSEY){
+ if (halfHP) {
+ HP((GetMonData(&OPPONENT_PARTY[0], MON_DATA_MAX_HP) / 2) - 1);
+ }
+ }
+ } WHEN {
+ TURN { MOVE(player, MOVE_BRINE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BRINE, player);
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
+ }
+}
diff --git a/test/battle/move_effect/curse.c b/test/battle/move_effect/curse.c
index bb1de42fba..355972e74e 100644
--- a/test/battle/move_effect/curse.c
+++ b/test/battle/move_effect/curse.c
@@ -37,16 +37,19 @@ SINGLE_BATTLE_TEST("Curse cuts the user's HP in half when used by Ghost-types")
}
}
-SINGLE_BATTLE_TEST("Curse applies to the user if used with Protean")
+SINGLE_BATTLE_TEST("Curse applies to the user if used with Protean/Libero")
{
+ u32 ability, species;
+ PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; }
+ PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
- PLAYER(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); }
+ PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CURSE, target: player); }
} SCENE {
s32 playerMaxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
- ABILITY_POPUP(player, ABILITY_PROTEAN);
+ ABILITY_POPUP(player, ability);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CURSE, player);
HP_BAR(player, damage: playerMaxHP / 2);
HP_BAR(player, damage: playerMaxHP / 4);
diff --git a/test/battle/move_effect/heal_bell.c b/test/battle/move_effect/heal_bell.c
index 5214d38b35..2f3ab93f04 100644
--- a/test/battle/move_effect/heal_bell.c
+++ b/test/battle/move_effect/heal_bell.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL);
- ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL);
ASSUME(MoveHasAdditionalEffect(MOVE_SPARKLY_SWIRL, MOVE_EFFECT_AROMATHERAPY));
}
diff --git a/test/battle/move_effect/magic_coat.c b/test/battle/move_effect/magic_coat.c
index 50ed79e194..ca7b78883e 100644
--- a/test/battle/move_effect/magic_coat.c
+++ b/test/battle/move_effect/magic_coat.c
@@ -32,3 +32,32 @@ SINGLE_BATTLE_TEST("Magic Coat prints the correct message when bouncing back a m
STATUS_ICON(opponent, sleep: TRUE);
}
}
+
+DOUBLE_BATTLE_TEST("Magic Coat reflects hazards regardless of the user's position")
+{
+ struct BattlePokemon *coatUser = NULL;
+ PARAMETRIZE { coatUser = playerLeft; }
+ PARAMETRIZE { coatUser = playerRight; }
+ ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK);
+
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(coatUser, MOVE_MAGIC_COAT); MOVE(opponentRight, MOVE_STEALTH_ROCK); MOVE(opponentLeft, MOVE_SPIKES); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, coatUser);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponentRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, opponentLeft);
+ }
+ } THEN {
+ EXPECT(!IsHazardOnSide(B_SIDE_PLAYER, HAZARDS_STEALTH_ROCK));
+ EXPECT(!IsHazardOnSide(B_SIDE_PLAYER, HAZARDS_SPIKES));
+ EXPECT(IsHazardOnSide(B_SIDE_OPPONENT, HAZARDS_STEALTH_ROCK));
+ EXPECT(IsHazardOnSide(B_SIDE_OPPONENT, HAZARDS_SPIKES));
+ }
+}
diff --git a/test/battle/move_effect/metronome.c b/test/battle/move_effect/metronome.c
index 2419ecb1e4..91865b05cf 100644
--- a/test/battle/move_effect/metronome.c
+++ b/test/battle/move_effect/metronome.c
@@ -25,6 +25,7 @@ SINGLE_BATTLE_TEST("Metronome picks a random move")
SINGLE_BATTLE_TEST("Metronome's called powder move fails against Grass Types")
{
GIVEN {
+ WITH_CONFIG(GEN_CONFIG_POWDER_GRASS, GEN_6);
ASSUME(IsPowderMove(MOVE_POISON_POWDER));
ASSUME(GetSpeciesType(SPECIES_TANGELA, 0) == TYPE_GRASS);
ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_NON_VOLATILE_STATUS);
diff --git a/test/battle/move_effect/mirror_move.c b/test/battle/move_effect/mirror_move.c
index c9e468a5e4..677fc71a1a 100644
--- a/test/battle/move_effect/mirror_move.c
+++ b/test/battle/move_effect/mirror_move.c
@@ -41,6 +41,7 @@ SINGLE_BATTLE_TEST("Mirror Move fails if no move was used before")
SINGLE_BATTLE_TEST("Mirror Move's called powder move fails against Grass Types")
{
GIVEN {
+ WITH_CONFIG(GEN_CONFIG_POWDER_GRASS, GEN_6);
ASSUME(IsPowderMove(MOVE_STUN_SPORE));
ASSUME(GetSpeciesType(SPECIES_ODDISH, 0) == TYPE_GRASS);
ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_NON_VOLATILE_STATUS);
diff --git a/test/battle/move_effect/powder.c b/test/battle/move_effect/powder.c
index da8eba4caf..0cfeeb0a8d 100644
--- a/test/battle/move_effect/powder.c
+++ b/test/battle/move_effect/powder.c
@@ -168,7 +168,7 @@ SINGLE_BATTLE_TEST("Powder fails if the target is Grass type (Gen6+)")
SINGLE_BATTLE_TEST("Powder fails if the target has Overcoat (Gen6+)")
{
GIVEN {
- WITH_CONFIG(GEN_CONFIG_POWDER_GRASS, GEN_6);
+ WITH_CONFIG(GEN_CONFIG_POWDER_OVERCOAT, GEN_6);
PLAYER(SPECIES_FORRETRESS) { Ability(ABILITY_OVERCOAT); }
OPPONENT(SPECIES_VIVILLON);
} WHEN {
@@ -223,17 +223,20 @@ DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it
}
}
-SINGLE_BATTLE_TEST("Powder prevents Protean from changing its user to Fire type")
+SINGLE_BATTLE_TEST("Powder prevents Protean/Libero from changing its user to Fire type")
{
+ u32 ability, species;
+ PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_GRENINJA; }
+ PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
- PLAYER(SPECIES_GRENINJA) { Ability(ABILITY_PROTEAN); }
+ PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_VIVILLON);
} WHEN {
TURN { MOVE(opponent, MOVE_POWDER); MOVE(player, MOVE_EMBER); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_POWDER, opponent);
NONE_OF {
- ABILITY_POPUP(player, ABILITY_PROTEAN);
+ ABILITY_POPUP(player, ability);
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
HP_BAR(opponent);
}
diff --git a/test/battle/move_effect/psychic_terrain.c b/test/battle/move_effect/psychic_terrain.c
index e17964464b..76e7bc7c82 100644
--- a/test/battle/move_effect/psychic_terrain.c
+++ b/test/battle/move_effect/psychic_terrain.c
@@ -120,6 +120,8 @@ SINGLE_BATTLE_TEST("Psychic Terrain doesn't block priority moves against semi-in
PARAMETRIZE { move = MOVE_SOLAR_BEAM; shouldWork = FALSE;}
PARAMETRIZE { move = MOVE_FLY; shouldWork = TRUE;}
GIVEN {
+ WITH_CONFIG(GEN_CONFIG_TOXIC_NEVER_MISS, GEN_6);
+ ASSUME(IsSpeciesOfType(SPECIES_SHROODLE, TYPE_POISON));
PLAYER(SPECIES_SHROODLE) { Ability(ABILITY_PRANKSTER); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/rest.c b/test/battle/move_effect/rest.c
index fcf2b15567..af1fb19c8c 100644
--- a/test/battle/move_effect/rest.c
+++ b/test/battle/move_effect/rest.c
@@ -35,22 +35,6 @@ SINGLE_BATTLE_TEST("Rest fails if the user is at full HP")
}
}
-SINGLE_BATTLE_TEST("Rest fails if the user is protected by Leaf Guard")
-{
- GIVEN {
- ASSUME(GetMoveEffect(MOVE_SUNNY_DAY) == EFFECT_SUNNY_DAY);
- ASSUME(B_LEAF_GUARD_PREVENTS_REST >= GEN_5);
- PLAYER(SPECIES_CHIKORITA) { Ability(ABILITY_LEAF_GUARD); HP(1); }
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(opponent, MOVE_SUNNY_DAY); MOVE(player, MOVE_REST); }
- } SCENE {
- NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player);
- } THEN {
- EXPECT(!(player->status1 & STATUS1_SLEEP));
- }
-}
-
SINGLE_BATTLE_TEST("Rest fails if the user is protected by Shields Down")
{
GIVEN {
diff --git a/test/battle/move_effect/return.c b/test/battle/move_effect/return.c
index 2a2614200d..2727b1b46e 100644
--- a/test/battle/move_effect/return.c
+++ b/test/battle/move_effect/return.c
@@ -1,6 +1,46 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("Return's power increases the higher friendship of the user is")
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_RETURN) == EFFECT_RETURN);
+}
+
+SINGLE_BATTLE_TEST("Return's power increases the higher friendship of the user is", s16 damage)
+{
+ u32 friendship;
+ PARAMETRIZE { friendship = 0; }
+ PARAMETRIZE { friendship = 100; }
+ PARAMETRIZE { friendship = 200; }
+ PARAMETRIZE { friendship = 255; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Friendship(friendship); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_RETURN); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_RETURN, player);
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } THEN {
+ if (i > 0)
+ EXPECT_GT(results[i].damage, results[i-1].damage);
+ }
+}
+
TO_DO_BATTLE_TEST("Return does 0 damage at min Friendship (Gen2)")
-TO_DO_BATTLE_TEST("Return does 1 damage at min Friendship (Gen3+)")
+
+SINGLE_BATTLE_TEST("Return does 1 damage at min Friendship (Gen3+)")
+{
+ s16 damage;
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Friendship(0); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_RETURN); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_RETURN, player);
+ HP_BAR(opponent, captureDamage: &damage);
+ } THEN {
+ EXPECT_EQ(damage, 1);
+ }
+}
diff --git a/test/battle/move_effect/shell_trap.c b/test/battle/move_effect/shell_trap.c
index 435c79a652..f3f0068d6f 100644
--- a/test/battle/move_effect/shell_trap.c
+++ b/test/battle/move_effect/shell_trap.c
@@ -198,3 +198,84 @@ DOUBLE_BATTLE_TEST("Shell Trap targets correctly if one of the opponents has fai
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft);
}
}
+
+SINGLE_BATTLE_TEST("Shell Trap activates if user is hit with a physical move but does no damage")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_FALSE_SWIPE) == EFFECT_FALSE_SWIPE);
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SHELL_TRAP); MOVE(opponent, MOVE_FALSE_SWIPE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SHELL_TRAP_SETUP, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FALSE_SWIPE, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, player);
+ HP_BAR(opponent);
+ }
+}
+
+SINGLE_BATTLE_TEST("Encore fails if target has active Shell Trap waiting")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_CELEBRATE); }
+ TURN { MOVE(player, MOVE_SHELL_TRAP); MOVE(opponent, MOVE_ENCORE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
+ MESSAGE("Wobbuffet set a shell trap!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, player);
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Shell Trap fails if an other -3 or lower priority Move is used")
+{
+ GIVEN {
+ ASSUME(GetMovePriority(MOVE_DRAGON_TAIL) <= -3);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN {
+ MOVE(player, MOVE_SHELL_TRAP);
+ MOVE(opponent, MOVE_DRAGON_TAIL);
+ }
+ } SCENE {
+ MESSAGE("Wobbuffet set a shell trap!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, opponent);
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, player);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Shell Trap does not trigger when hit into Substitute")
+{
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_DOUBLE_EDGE) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_WYNAUT);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_SNORLAX);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SUBSTITUTE); }
+ TURN {
+ MOVE(playerLeft, MOVE_SHELL_TRAP);
+ MOVE(opponentLeft, MOVE_DOUBLE_EDGE, target: playerLeft);
+ MOVE(opponentRight, MOVE_SCRATCH, target: playerLeft);
+ }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SUBSTITUTE, playerLeft);
+ MESSAGE("Wynaut set a shell trap!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_EDGE, opponentLeft);
+ MESSAGE("Wynaut's substitute faded!");
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponentRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerLeft);
+ }
+}
diff --git a/test/battle/move_effect/two_typed_move.c b/test/battle/move_effect/two_typed_move.c
index 43c3515739..7372222e83 100644
--- a/test/battle/move_effect/two_typed_move.c
+++ b/test/battle/move_effect/two_typed_move.c
@@ -1,4 +1,12 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("TODO: Write Flying Press (Move Effect) test titles")
+TO_DO_BATTLE_TEST("Flying Press does both Fighting and Flying-type for type effectiveness")
+TO_DO_BATTLE_TEST("Flying-type Pokémon don't receive STAB on Flying Press")
+TO_DO_BATTLE_TEST("Sky Plate doesn't boost Flying Press' power") // Check Fist Plate for comparison
+TO_DO_BATTLE_TEST("Sharp Beak doesn't boost Flying Press' power") // Check Black Belt for comparison
+TO_DO_BATTLE_TEST("Flying Gem doesn't trigger when using Flying Press") // Check Fighting Gem for comparison
+TO_DO_BATTLE_TEST("Coba Berry doesn't trigger when the user is attacked by Flying Press")
+TO_DO_BATTLE_TEST("Flying Press triggers Chople Berry, even when it wouldn't be super effective with regular Fighting-type moves")
+TO_DO_BATTLE_TEST("Flying Press under Electrify does both Electric and Flying-type for type effectiveness") // Check Electric 1/4 effectiveness
+TO_DO_BATTLE_TEST("Flying Press under Normalize does both Normal and Flying-type for type effectiveness") // Check Rock/Steel 1/4 effectiveness
diff --git a/test/battle/move_effect_secondary/remove_status.c b/test/battle/move_effect_secondary/remove_status.c
index aef7684233..f1219d7ed0 100644
--- a/test/battle/move_effect_secondary/remove_status.c
+++ b/test/battle/move_effect_secondary/remove_status.c
@@ -118,6 +118,7 @@ TO_DO_BATTLE_TEST("Wake-Up Slap gets increased power against Pokémon with Comat
DOUBLE_BATTLE_TEST("Sparkling Aria cures burns from all Pokemon on the field and behind substitutes")
{
GIVEN {
+ ASSUME(MoveIgnoresSubstitute(MOVE_SPARKLING_ARIA));
ASSUME(MoveHasAdditionalEffect(MOVE_SPARKLING_ARIA, MOVE_EFFECT_REMOVE_STATUS) == TRUE);
ASSUME(GetMoveEffectArg_Status(MOVE_SPARKLING_ARIA) == STATUS1_BURN);
PLAYER(SPECIES_PRIMARINA);
diff --git a/tools/preproc/asm_file.cpp b/tools/preproc/asm_file.cpp
index 10330f1774..6cfc4cbdb3 100644
--- a/tools/preproc/asm_file.cpp
+++ b/tools/preproc/asm_file.cpp
@@ -633,7 +633,11 @@ bool AsmFile::ParseEnum()
RaiseError("%s:%ld: empty enum is invalid", headerFilename.c_str(), currentHeaderLine);
}
- if (m_buffer[m_pos] != ',')
+ if (m_buffer[m_pos] == '#')
+ {
+ currentHeaderLine = ParseLineSkipInEnum();
+ }
+ else if (m_buffer[m_pos] != ',')
{
currentHeaderLine += SkipWhitespaceAndEol();
if (m_buffer[m_pos++] == '}' && m_buffer[m_pos++] == ';')
@@ -737,6 +741,50 @@ int AsmFile::SkipWhitespaceAndEol()
return newlines;
}
+int AsmFile::ParseLineSkipInEnum(void)
+{
+ m_pos++;
+ while (m_buffer[m_pos] == ' ' || m_buffer[m_pos] == '\t')
+ m_pos++;
+
+ if (!IsAsciiDigit(m_buffer[m_pos]))
+ RaiseError("malformatted line indicator found inside `enum`, expected line number");
+
+ unsigned n = 0;
+ int digit = 0;
+ while ((digit = ConvertDigit(m_buffer[m_pos++], 10)) != -1)
+ n = 10 * n + digit;
+
+ while (m_buffer[m_pos] == ' ' || m_buffer[m_pos] == '\t')
+ m_pos++;
+
+ if (m_buffer[m_pos++] != '"')
+ RaiseError("malformatted line indicator found before `enum`, expected filename");
+
+ while (m_buffer[m_pos] != '"')
+ {
+ unsigned char c = m_buffer[m_pos++];
+
+ if (c == 0)
+ {
+ if (m_pos >= m_size)
+ RaiseError("unexpected EOF in line indicator");
+ else
+ RaiseError("unexpected null character in line indicator");
+ }
+
+ if (!IsAsciiPrintable(c))
+ RaiseError("unexpected character '\\x%02X' in line indicator", c);
+
+ if (c == '\\')
+ {
+ c = m_buffer[m_pos];
+ RaiseError("unexpected escape '\\%c' in line indicator", c);
+ }
+ }
+ return n - 1;
+}
+
// returns the last line indicator and its corresponding file name without modifying the token index
int AsmFile::FindLastLineNumber(std::string& filename)
{
diff --git a/tools/preproc/asm_file.h b/tools/preproc/asm_file.h
index 33e6ce5c49..9cab32a97f 100644
--- a/tools/preproc/asm_file.h
+++ b/tools/preproc/asm_file.h
@@ -73,6 +73,7 @@ private:
void VerifyStringLength(int length);
int SkipWhitespaceAndEol();
int FindLastLineNumber(std::string& filename);
+ int ParseLineSkipInEnum(void);
std::string ReadIdentifier();
long ReadInteger(std::string filename, long line);
};