21/02/26 Master to upcoming merge (#9292)
Some checks are pending
CI / build (push) Waiting to run
CI / docs_validate (push) Waiting to run
CI / allcontributors (push) Waiting to run

This commit is contained in:
hedara90 2026-02-22 15:10:16 +01:00 committed by GitHub
commit 021a560de0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
213 changed files with 2076 additions and 953 deletions

View File

@ -642,6 +642,15 @@
"contributions": [
"code"
]
},
{
"login": "LogicalLlama",
"name": "LogicalLlama",
"avatar_url": "https://avatars.githubusercontent.com/u/248230900?v=4",
"profile": "https://github.com/LogicalLlama",
"contributions": [
"bug"
]
}
],
"contributorsPerLine": 7,

View File

@ -92,6 +92,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SabataLunar"><img src="https://avatars.githubusercontent.com/u/26584469?v=4?s=100" width="100px;" alt="SabataLunar"/><br /><sub><b>SabataLunar</b></sub></a><br /><a href="#design-SabataLunar" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PacFire"><img src="https://avatars.githubusercontent.com/u/108960850?v=4?s=100" width="100px;" alt="PacFire"/><br /><sub><b>PacFire</b></sub></a><br /><a href="#design-PacFire" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ChrispyChris27"><img src="https://avatars.githubusercontent.com/u/173648816?v=4?s=100" width="100px;" alt="ChrispyChris27"/><br /><sub><b>ChrispyChris27</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=ChrispyChris27" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LogicalLlama"><img src="https://avatars.githubusercontent.com/u/248230900?v=4?s=100" width="100px;" alt="LogicalLlama"/><br /><sub><b>LogicalLlama</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/issues?q=author%3ALogicalLlama" title="Bug reports">🐛</a></td>
</tr>
</tbody>
<tfoot>

View File

@ -2540,32 +2540,39 @@ gBattleAnimMove_DracoMeteor::
call DracoMeteor2
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=32@; For Meteor 1 createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=32@; For Meteor 1
createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
delay 7
call DracoMeteor3
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=32@; For Meteor 2 delay 7
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=32@; For Meteor 2
delay 7
call DracoMeteor4
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=32@; For Meteor 3 delay 7
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=32@; For Meteor 3
delay 7
call DracoMeteor1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=32@; For Meteor 4 createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=32@; For Meteor 4
createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
delay 7
call DracoMeteor2
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=32@; For Meteor 1 delay 7
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=32@; For Meteor 1
delay 7
call DracoMeteor3
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=32@; For Meteor 3 delay 15
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=32@; For Meteor 3
delay 15
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=32@; For Meteor 3 createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 2, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=32@; For Meteor 3
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 2, 1
delay 7
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 1, 12, 0, RGB(1, 2, 11)
waitforvisualfinish
@ -5024,7 +5031,8 @@ gBattleAnimMove_Hex::
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 2, 0, 37, 1
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
delay 32
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=12, color=RGB(10, 2, 19)@;Deep purple createsprite gCurseGhostSpriteTemplate, ANIM_TARGET, 4
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=12, color=RGB(10, 2, 19)@;Deep purple
createsprite gCurseGhostSpriteTemplate, ANIM_TARGET, 4
waitforvisualfinish
clearmonbg ANIM_TARGET
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 16, 0, RGB(10, 2, 19) @;Deep purple
@ -7812,7 +7820,8 @@ gBattleAnimMove_TrickOrTreat::
createvisualtask AnimTask_ScaryFace, 5
delay 13
waitforvisualfinish
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=12, color=RGB(10, 2, 19)@;Deep purple playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=12, color=RGB(10, 2, 19)@;Deep purple
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
createsprite gCurseGhostSpriteTemplate, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 14, 1
waitforvisualfinish
@ -9384,7 +9393,8 @@ gBattleAnimMove_OblivionWing::
call OblivionWingBeam
call OblivionWingBeam
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 40, 1
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=4, initial_blend_y=0, target_blend_y=12, color=RGB(31, 4, 10)@Pinkish Red call OblivionWingBeam
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=4, initial_blend_y=0, target_blend_y=12, color=RGB(31, 4, 10)@Pinkish Red
call OblivionWingBeam
call OblivionWingBeam
call OblivionWingBeam
call OblivionWingBeam
@ -13278,7 +13288,8 @@ gBattleAnimMove_DynamaxCannon::
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 2, 15, 0, 0
fadetobg BG_DYNAMAX_CANNON
waitbgfadein
blend_color_cycle selector=F_PAL_TARGET, delay=4, num_blends=4, initial_blend_y=0, target_blend_y=12, color=RGB(31, 4, 10)@Pinkish Red panse SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER SOUND_PAN_TARGET 2 0
blend_color_cycle selector=F_PAL_TARGET, delay=4, num_blends=4, initial_blend_y=0, target_blend_y=12, color=RGB(31, 4, 10)@Pinkish Red
panse SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER SOUND_PAN_TARGET 2 0
shake_mon_or_platform velocity=4, shake_timer=1, shake_duration=180, type=1
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 4, 87, 1
call DynamaxCannonLaunch
@ -13411,7 +13422,8 @@ gBattleAnimMove_TarShot::
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 15
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 2, 0, 10, 1
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=16, color=RGB_BLACK@;Black createsprite gAppleAcidDripTemplate, ANIM_TARGET, 2, 0xffe6, 0xffe8, 0x0, 0xf, 0x37
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=16, color=RGB_BLACK@;Black
createsprite gAppleAcidDripTemplate, ANIM_TARGET, 2, 0xffe6, 0xffe8, 0x0, 0xf, 0x37
playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET
delay 10
createsprite gAppleAcidDripTemplate, ANIM_TARGET, 2, 0xf, 0xffe5, 0x0, 0xC, 0x32
@ -14383,7 +14395,8 @@ gBattleAnimMove_Eternabeam::
call OblivionWingBeam
call OblivionWingBeam
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 50, 1
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=4, initial_blend_y=0, target_blend_y=12, color=RGB(31, 4, 10)@Pinkish Red call OblivionWingBeam
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=4, initial_blend_y=0, target_blend_y=12, color=RGB(31, 4, 10)@Pinkish Red
call OblivionWingBeam
call OblivionWingBeam
call OblivionWingBeam
call OblivionWingBeam
@ -15134,7 +15147,8 @@ gBattleAnimMove_CorrosiveGas::
monbg ANIM_ATTACKER
loopsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_ATTACKER, 0x8, 0x3
delay 0
blend_color_cycle selector=F_PAL_ATTACKER, delay=1, num_blends=2, initial_blend_y=0, target_blend_y=15, color=RGB(15, 15, 6)@;Garbage green createsprite gSpriteTemplate_CorrosiveGasSmoke, ANIM_ATTACKER, 0x7a, 0x3, 0xfff2, 0x12, 0x2e
blend_color_cycle selector=F_PAL_ATTACKER, delay=1, num_blends=2, initial_blend_y=0, target_blend_y=15, color=RGB(15, 15, 6)@;Garbage green
createsprite gSpriteTemplate_CorrosiveGasSmoke, ANIM_ATTACKER, 0x7a, 0x3, 0xfff2, 0x12, 0x2e
delay 0
createsprite gSpriteTemplate_CorrosiveGasSmoke, ANIM_ATTACKER, 0x79, 0x3, 0xe, 0xfff2, 0x2e
delay 0
@ -15147,7 +15161,8 @@ gBattleAnimMove_CorrosiveGas::
createsprite gSpriteTemplate_CorrosiveGasSmoke, ANIM_ATTACKER, 0x7b, 0x3, 0x4, 0x4, 0x1e
waitforvisualfinish
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
blend_color_cycle selector=(F_PAL_BG | F_PAL_TARGET | F_PAL_ATK_PARTNER | F_PAL_DEF_PARTNER), delay=1, num_blends=2, initial_blend_y=0, target_blend_y=14, color=RGB(15, 15, 6)@;Garbage green waitforvisualfinish
blend_color_cycle selector=(F_PAL_BG | F_PAL_TARGET | F_PAL_ATK_PARTNER | F_PAL_DEF_PARTNER), delay=1, num_blends=2, initial_blend_y=0, target_blend_y=14, color=RGB(15, 15, 6)@;Garbage green
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
@ -15527,7 +15542,8 @@ gBattleAnimMove_DragonEnergy::
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_HYDRO_PUMP, 0, 12, 12, RGB(30, 2, 11) @;Regidrago Reddish Reddish, Purple
monbg ANIM_TARGET
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER
blend_color_cycle selector=F_PAL_ATTACKER, delay=0, num_blends=4, initial_blend_y=0, target_blend_y=11, color=RGB(31, 28, 31)@;Pinkish White waitforvisualfinish
blend_color_cycle selector=F_PAL_ATTACKER, delay=0, num_blends=4, initial_blend_y=0, target_blend_y=11, color=RGB(31, 28, 31)@;Pinkish White
waitforvisualfinish
playsewithpan SE_M_DETECT, SOUND_PAN_TARGET
createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 16, 0, RGB(30, 2, 11) @;Regidrago Reddish Reddish, Purple
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER, -120, 0, 0, 1 @;Slide off off, screen
@ -15589,7 +15605,8 @@ gBattleAnimMove_FreezingGlare::
createvisualtask AnimTask_GlareEyeDots, 0x5, 0x0
playsewithpan SE_M_PSYBEAM2, SOUND_PAN_ATTACKER
waitforvisualfinish
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=12, color=RGB(12, 26, 31)@;Ice blue createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 4, 28, 1
blend_color_cycle selector=F_PAL_TARGET, delay=2, num_blends=2, initial_blend_y=0, target_blend_y=12, color=RGB(12, 26, 31)@;Ice blue
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 4, 28, 1
call IceCrystalEffectShort
waitforvisualfinish
call UnsetPsychicBg
@ -19848,28 +19865,34 @@ TeraBlastRock:
call TeraBlastRock2
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1 createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1
createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
delay 3
call TeraBlastRock3
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 2 delay 3
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 2
delay 3
call TeraBlastRock4
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3 delay 3
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3
delay 3
call TeraBlastRock1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 4 createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 4
createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
delay 3
call TeraBlastRock2
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1 delay 3
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1
delay 3
call TeraBlastRock3
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 50, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 50, 1
call EternabeamGeyser
delay 5
call EternabeamGeyser
@ -20301,28 +20324,34 @@ TeraBlastWater:
call TeraBlastWater2
playsewithpan SE_M_WATERFALL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1 createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1
createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
delay 3
call TeraBlastWater3
playsewithpan SE_M_WATERFALL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 2 delay 3
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 2
delay 3
call TeraBlastWater4
playsewithpan SE_M_WATERFALL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3 delay 3
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3
delay 3
call TeraBlastWater1
playsewithpan SE_M_WATERFALL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 4 createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=-8, y=16@; For Meteor 4
createvisualtask AnimTask_HorizontalShake, 5, 5, 2, 1
delay 3
call TeraBlastWater2
playsewithpan SE_M_WATERFALL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 4, 2
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1 delay 3
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=40, y=16@; For Meteor 1
delay 3
call TeraBlastWater3
playsewithpan SE_M_WATERFALL, SOUND_PAN_TARGET
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 50, 1
create_dragon_rage_fire_plume_sprite ANIM_ATTACKER, 2, relative_to=ANIM_TARGET, x=21, y=16@; For Meteor 3
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 50, 1
call EternabeamGeyser
delay 5
call EternabeamGeyser
@ -25715,7 +25744,7 @@ SnoreEffect:
playsewithpan SE_M_SNORE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaleMonAndRestore, 5, -7, -7, 7, ANIM_ATTACKER, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 7, 1
shake_mon_or_platform velocity=6, shake_timer=1, shake_duration=14, type=0, battler_selector=0
shake_mon_or_platform velocity=6, shake_timer=1, shake_duration=14, type=0
createsprite gSnoreZSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, -42, -38, 24, 0, 0
createsprite gSnoreZSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 0, -42, 24, 0, 0
createsprite gSnoreZSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 42, -38, 24, 0, 0
@ -34888,7 +34917,8 @@ gBattleAnimMove_10000000VoltThunderbolt::
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x14, 0x2c, SOUND_PAN_ATTACKER, 0x28, 0x2, 0x3
delay 16
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
invert_screen_color scenery=0x101@thunder flash createsprite gGrowingChargeOrbSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER @ charge
invert_screen_color scenery=0x101@thunder flash
createsprite gGrowingChargeOrbSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER @ charge
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 64, -36
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 64, -20
@ -34902,7 +34932,8 @@ gBattleAnimMove_10000000VoltThunderbolt::
@ createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x18, 0x2c, SOUND_PAN_ATTACKER, 0x28, 0x2, 0x3
delay 20
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
invert_screen_color scenery=0x101@thunder flash createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -64, -36
invert_screen_color scenery=0x101@thunder flash
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -64, -36
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -64, -20
delay 1
@ -34915,7 +34946,8 @@ gBattleAnimMove_10000000VoltThunderbolt::
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x1c, 0x2c, SOUND_PAN_ATTACKER, 0x28, 0x2, 0x3
delay 20
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
invert_screen_color scenery=0x101@thunder flash createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -112, -36
invert_screen_color scenery=0x101@thunder flash
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -112, -36
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -112, -20
delay 1
@ -34928,7 +34960,8 @@ gBattleAnimMove_10000000VoltThunderbolt::
@ createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x20, 0x2c, SOUND_PAN_ATTACKER, 0x28, 0x2, 0x3
delay 16
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
invert_screen_color scenery=0x101@thunder flash createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -48, -36
invert_screen_color scenery=0x101@thunder flash
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -48, -36
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, -48, -20
delay 1
@ -34949,7 +34982,7 @@ gBattleAnimMove_10000000VoltThunderbolt::
loadspritegfx ANIM_TAG_POISON_BUBBLE @purple
loopsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER, 0x5, 0xA
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 4, 50, 1
flash_anim_tag_with_color tag=ANIM_TAG_ORBS, delay=1, num_blends=12, color1=RGB_RED, blend_y1=16, color2=0, blend_y2=0
@flash_anim_tag_with_color tag=ANIM_TAG_ORBS, delay=1, num_blends=12, color1=RGB_RED, blend_y1=16, color2=0, blend_y2=0
call TenMillionVoltThunderboltBeamRed
call TenMillionVoltThunderboltBeamBlue
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 50, 1
@ -35437,7 +35470,8 @@ PulverizingPancakeFinish:
createsprite gBounceBallLandSpriteTemplate, ANIM_TARGET, 3
delay 7
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
create_basic_hitsplat_sprite ANIM_TARGET, 2, x=0, y=0, relative_to=ANIM_TARGET, animation=0@big hit marker delay 0
create_basic_hitsplat_sprite ANIM_TARGET, 2, x=0, y=0, relative_to=ANIM_TARGET, animation=0@big hit marker
delay 0
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 4, 44
createsprite gPulverizingPancakeYellowRingSpriteTemplate, ANIM_TARGET, 3, 0x0, 0x0, 0x100, 0x0
delay 5

View File

@ -958,7 +958,7 @@ BattleScript_EffectPartingShotTrySpAtk:
statbuffchange BS_TARGET, STAT_CHANGE_ALLOW_PTR, BattleScript_EffectPartingShotMaybeSwitch
call BattleScript_EffectPartingShotMaybePrintStat
BattleScript_EffectPartingShotMaybeSwitch:
jumpifgenconfiglowerthan CONFIG_PARTING_SHOT_SWITCH, GEN_7, BattleScript_EffectPartingShotSwitch
jumpifgenconfiglowerthan CONFIG_B_PARTING_SHOT_SWITCH, GEN_7, BattleScript_EffectPartingShotSwitch
jumpifbyte CMP_NOT_EQUAL, sB_ANIM_TARGETS_HIT, 0, BattleScript_EffectPartingShotSwitch
goto BattleScript_MoveEnd
@ -1304,7 +1304,7 @@ BattleScript_EffectHitEnemyHealAlly::
BattleScript_EffectDefog::
setstatchanger STAT_EVASION, 1, TRUE
attackcanceler
jumpifgenconfiglowerthan CONFIG_DEFOG_EFFECT_CLEARING, GEN_5, BattleScript_DefogAfterSubstituteCheck
jumpifgenconfiglowerthan CONFIG_B_DEFOG_EFFECT_CLEARING, GEN_5, BattleScript_DefogAfterSubstituteCheck
jumpifsubstituteblocks BattleScript_DefogIfCanClearHazards
BattleScript_DefogAfterSubstituteCheck:
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_EVASION, MIN_STAT_STAGE, BattleScript_DefogWorks
@ -1312,7 +1312,7 @@ BattleScript_DefogIfCanClearHazards:
trydefog FALSE, BattleScript_ButItFailed
BattleScript_DefogWorks:
accuracycheck BattleScript_MoveMissedPause
jumpifgenconfiglowerthan CONFIG_DEFOG_EFFECT_CLEARING, GEN_5, BattleScript_DefogWorksAfterSubstituteCheck
jumpifgenconfiglowerthan CONFIG_B_DEFOG_EFFECT_CLEARING, GEN_5, BattleScript_DefogWorksAfterSubstituteCheck
jumpifsubstituteblocks BattleScript_DefogTryHazardsWithAnim
BattleScript_DefogWorksAfterSubstituteCheck:
statbuffchange BS_TARGET, STAT_CHANGE_ALLOW_PTR | STAT_CHANGE_ONLY_CHECKING, BattleScript_DefogTryHazardsWithAnim
@ -1830,7 +1830,7 @@ BattleScript_EffectHealingWish::
setatkhptozero
tryfaintmon BS_ATTACKER
storehealingwish BS_ATTACKER
jumpifgenconfiglowerthan CONFIG_HEALING_WISH_SWITCH, GEN_5, BattleScript_EffectHealingWishGen4
jumpifgenconfiglowerthan CONFIG_B_HEALING_WISH_SWITCH, GEN_5, BattleScript_EffectHealingWishGen4
goto BattleScript_MoveEnd
BattleScript_EffectHealingWishGen4:
@ -2052,6 +2052,7 @@ BattleScript_EffectMagicRoom::
BattleScript_EffectAquaRing::
attackcanceler
jumpifvolatile BS_ATTACKER, VOLATILE_AQUA_RING, BattleScript_ButItFailed
setvolatile BS_ATTACKER, VOLATILE_AQUA_RING
attackanimation
waitanimation
@ -2107,7 +2108,7 @@ BattleScript_TryTailwindAbilitiesLoop_WindPower:
BattleScript_EffectMiracleEye::
attackcanceler
accuracycheck BattleScript_MoveMissedPause
jumpifgenconfiglowerthan CONFIG_MIRACLE_EYE_FAIL, GEN_5, BattleScript_MiracleEyeSet
jumpifgenconfiglowerthan CONFIG_B_MIRACLE_EYE_FAIL, GEN_5, BattleScript_MiracleEyeSet
jumpifvolatile BS_TARGET, VOLATILE_MIRACLE_EYE, BattleScript_ButItFailed
BattleScript_MiracleEyeSet:
setvolatile BS_TARGET, VOLATILE_MIRACLE_EYE
@ -3076,7 +3077,7 @@ BattleScript_EffectMeanLook::
attackcanceler
jumpifvolatile BS_TARGET, VOLATILE_ESCAPE_PREVENTION, BattleScript_ButItFailed
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifgenconfiglowerthan CONFIG_GHOSTS_ESCAPE, GEN_6, BattleScript_EffectMeanLookGen5
jumpifgenconfiglowerthan CONFIG_B_GHOSTS_ESCAPE, GEN_6, BattleScript_EffectMeanLookGen5
jumpiftype BS_TARGET, TYPE_GHOST, BattleScript_ButItFailed
BattleScript_EffectMeanLookGen5:
attackanimation
@ -3105,7 +3106,7 @@ BattleScript_NightmareWorked::
BattleScript_EffectMinimize::
attackcanceler
setvolatile BS_ATTACKER, VOLATILE_MINIMIZE
jumpifgenconfiglowerthan CONFIG_MINIMIZE_EVASION, GEN_5, BattleScript_EffectMinimizeGen4
jumpifgenconfiglowerthan CONFIG_B_MINIMIZE_EVASION, GEN_5, BattleScript_EffectMinimizeGen4
setstatchanger STAT_EVASION, 2, FALSE
goto BattleScript_EffectStatUpAfterAtkCanceler
BattleScript_EffectMinimizeGen4:
@ -3178,8 +3179,8 @@ BattleScript_EffectSpikes::
BattleScript_EffectForesight::
attackcanceler
accuracycheck BattleScript_ButItFailed
jumpifgenconfiglowerthan CONFIG_FORESIGHT_FAIL, GEN_3, BattleScript_ForesightFailCheck
jumpifgenconfiglowerthan CONFIG_FORESIGHT_FAIL, GEN_5, BattleScript_ForesightSet
jumpifgenconfiglowerthan CONFIG_B_FORESIGHT_FAIL, GEN_3, BattleScript_ForesightFailCheck
jumpifgenconfiglowerthan CONFIG_B_FORESIGHT_FAIL, GEN_5, BattleScript_ForesightSet
BattleScript_ForesightFailCheck:
jumpifvolatile BS_TARGET, VOLATILE_FORESIGHT, BattleScript_ButItFailed
BattleScript_ForesightSet:
@ -3399,7 +3400,7 @@ BattleScript_EffectFutureSight::
goto BattleScript_MoveEnd
BattleScript_EffectTeleport::
jumpifgenconfiglowerthan CONFIG_TELEPORT_BEHAVIOR, GEN_8, BattleScript_EffectTeleportGen7
jumpifgenconfiglowerthan CONFIG_B_TELEPORT_BEHAVIOR, GEN_8, BattleScript_EffectTeleportGen7
jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_EffectBatonPass
jumpifside BS_ATTACKER, B_SIDE_PLAYER, BattleScript_EffectBatonPass
goto BattleScript_DoEffectTeleport
@ -4845,9 +4846,7 @@ BattleScript_GulpMissileGorging::
tryfaintmon BS_ATTACKER
jumpiffainted BS_ATTACKER, TRUE, BattleScript_GulpMissileNoSecondEffectGorging
BattleScript_GulpMissileNoDmgGorging:
swapattackerwithtarget
seteffectprimary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_PARALYSIS
swapattackerwithtarget
seteffectprimary BS_TARGET, BS_ATTACKER, MOVE_EFFECT_PARALYSIS
BattleScript_GulpMissileNoSecondEffectGorging:
return
@ -4873,7 +4872,7 @@ BattleScript_GulpMissileNoDmgGulping:
printfromtable gStatDownStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_GulpMissileGulpingEnd:
swapattackerwithtarget @ restore the battlers, just in case
swapattackerwithtarget
BattleScript_GulpMissileNoSecondEffectGulping:
return
@ -5482,7 +5481,7 @@ BattleScript_CudChewActivates::
end2
BattleScript_ApplyDisguiseFormChangeHPLoss::
jumpifgenconfiglowerthan CONFIG_DISGUISE_HP_LOSS, GEN_8, BattleScript_ApplyDisguiseFormChangeHPLossReturn
jumpifgenconfiglowerthan CONFIG_B_DISGUISE_HP_LOSS, GEN_8, BattleScript_ApplyDisguiseFormChangeHPLossReturn
healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE
datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE
BattleScript_ApplyDisguiseFormChangeHPLossReturn:
@ -6727,7 +6726,7 @@ BattleScript_WeakArmorDefPrintString:
printstring STRINGID_TARGETABILITYSTATLOWER
waitmessage B_WAIT_TIME_LONG
BattleScript_WeakArmorActivatesSpeed:
jumpifgenconfiglowerthan CONFIG_WEAK_ARMOR_SPEED, GEN_7, BattleScript_WeakArmorSetSpeedGen6
jumpifgenconfiglowerthan CONFIG_B_WEAK_ARMOR_SPEED, GEN_7, BattleScript_WeakArmorSetSpeedGen6
setstatchanger STAT_SPEED, 2, FALSE
goto BattleScript_WeakArmorDoSpeed
BattleScript_WeakArmorSetSpeedGen6:

View File

@ -67,3 +67,46 @@ A: Shadows can be disabled for certain locations by modifying the `CurrentMapHas
### Q: How do I change the default light-blend color?
A: The default color is handled by the `#define DEFAULT_LIGHT_COLOR` in `src/palette.c`.
### Q. How do I use alternate nighttime palettes?
In addition to palette tinting, the DNS allows tilesets to define alternate nighttime palettes.
These palettes are automatically blended with their corresponding daytime palettes with the passage of time.
Each tileset has `16` total palette slots. `3` of the BG palettes (`13 - 15`) are reserved for the UI leaving `13` (`0-12`) usable for tilesets. Because primary tilesets load `6` (`NUM_PALS_IN_PRIMARY`) palettes (`0-5`) and secondary Tilesets load `7` palettes (6-12), some slots are unused for each. DNS repurposes these unused slots to store alternate nighttime palettes.
To avoid overlap with active palettes, each nighttime palette is stored in a different slot determined by the formula: `night_pal = (day_pal + 9) % 16`
**Day palette index vs. Night palette index**
| Day | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|-----|---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----|
| Night | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
For instance, in a secondary Tileset (slots `6-12`), the nighttime palettes for index `8` would be stored at index `1` (which is unused in a secondary tileset). Slots `0` and `13-15` are not used for blending so the corresponding slots `9` and `6-8` are never used for nighttime palettes.
_Note that palette `0` is not used for blending._
Once the appropriate nighttime `.pal` file has been added, add a `swapPalettes` field to the tileset struct definition in `src/data/tilesets/headers.h`. The macro `SWAP_PAL(x)` is provided for this purpose.
`swapPalettes` is a bitmask so to use nighttime palettes for indices 7 and 9 in the Petalburg Tileset we add a `swapPalettes` with `SWAP_PAL(7) | SWAP_PAL(9)`.
Note that the palette index to specify here is the palette index that you want to swap at night (**NOT** the corresponding nighttime palette).
```diff
const struct Tileset gTileset_Petalburg =
{
.isCompressed = TRUE,
.isSecondary = TRUE,
.tiles = gTilesetTiles_Petalburg,
+ .swapPalettes = SWAP_PAL(7) | SWAP_PAL(9), // Enable nighttime variants for slots 7 and 9
.palettes = gTilesetPalettes_Petalburg,
.metatiles = gMetatiles_Petalburg,
.metatileAttributes = gMetatileAttributes_Petalburg,
.callback = InitTilesetAnim_Petalburg,
};
```

View File

@ -118,11 +118,16 @@
// Additionally, in gen8+ the Healing Wish's effect will be stored until the user switches into a statused or hurt mon.
#define B_DEFOG_EFFECT_CLEARING GEN_LATEST // In Gen5+, Defog does not lower Evasion of target behind Subsitute. In Gen6+, Defog clears Spikes, Toxic Spikes, Stealth Rock and Sticky Web from both sides. In Gen8+, Defog also clears active Terrain.
#define B_STOCKPILE_RAISES_DEFS GEN_LATEST // In Gen4+, Stockpile also raises Defense and Sp. Defense stats. Once Spit Up / Swallow is used, these stat changes are lost.
#define B_TRANSFORM_SEMI_INV_FAIL GEN_LATEST // In Gen2+, Transform fails if the target is semi-invulnerable.
#define B_TRANSFORM_TARGET_FAIL GEN_LATEST // In Gen2+, Transform fails if the target is already transformed.
#define B_TRANSFORM_USER_FAIL GEN_LATEST // In Gen5+, Transform fails if the user is already transformed.
#define B_TRANSFORM_SUBSTITUTE_FAIL GEN_LATEST // In Gen5+, Transform fails if the target is behind a Substitute.
#define B_TRANSFORM_SHINY GEN_LATEST // In Gen4+, Transform will copy the shiny state of the opponent instead of maintaining its own shiny state.
#define B_TRANSFORM_FORM_CHANGES GEN_LATEST // In Gen5+, Transformed Pokemon cannot change forms.
#define B_WIDE_GUARD GEN_LATEST // In Gen5 only, Wide Guard has a chance to fail if used consecutively.
#define B_QUICK_GUARD GEN_LATEST // In Gen5 only, Quick Guard has a chance to fail if used consecutively.
#define B_IMPRISON GEN_LATEST // In Gen5+, Imprison doesn't fail if opposing pokemon don't have any moves the user knows.
#define B_TAUNT_ME_FIRST GEN_LATEST // In Gen5+, Taunt does not block Me First.
#define B_ALLY_SWITCH_FAIL_CHANCE GEN_LATEST // In Gen9+, using Ally Switch consecutively decreases the chance of success for each consecutive use.
#define B_SKETCH_BANS GEN_LATEST // In Gen9+, Sketch is unable to copy more moves than in previous generations.
#define B_KNOCK_OFF_REMOVAL GEN_LATEST // In Gen5+, Knock Off removes the foe's item instead of rendering it unusable.

View File

@ -4,216 +4,221 @@
/* Config definitions */
#define BATTLE_CONFIG_DEFINITIONS(F) \
/* Calculation settings */ \
F(CRIT_CHANCE, critChance, (u32, GEN_COUNT - 1)) \
F(CRIT_MULTIPLIER, critMultiplier, (u32, GEN_COUNT - 1)) \
F(PARALYSIS_SPEED, paralysisSpeed, (u32, GEN_COUNT - 1)) \
F(CONFUSION_SELF_DMG_CHANCE, confusionSelfDmgChance, (u32, GEN_COUNT - 1)) \
F(MULTI_HIT_CHANCE, multiHitChance, (u32, GEN_COUNT - 1)) \
F(WHITEOUT_MONEY, whiteoutMoney, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(LIGHT_BALL_ATTACK_BOOST, lightBallAttackBoost, (u32, GEN_COUNT - 1)) \
F(B_CRIT_CHANCE, critChance, (u32, GEN_COUNT - 1)) \
F(B_CRIT_MULTIPLIER, critMultiplier, (u32, GEN_COUNT - 1)) \
F(B_PARALYSIS_SPEED, paralysisSpeed, (u32, GEN_COUNT - 1)) \
F(B_CONFUSION_SELF_DMG_CHANCE, confusionSelfDmgChance, (u32, GEN_COUNT - 1)) \
F(B_MULTI_HIT_CHANCE, multiHitChance, (u32, GEN_COUNT - 1)) \
F(B_WHITEOUT_MONEY, whiteoutMoney, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_LIGHT_BALL_ATTACK_BOOST, lightBallAttackBoost, (u32, GEN_COUNT - 1)) \
/* Experience settings */ \
F(EXP_CATCH, expCatch, (u32, GEN_COUNT - 1)) \
F(TRAINER_EXP_MULTIPLIER, trainerExpMultiplier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SPLIT_EXP, splitExp, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SCALED_EXP, scaledExp, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(UNEVOLVED_EXP_MULTIPLIER, unevolvedExpMultiplier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(LEVEL_UP_NOTIFICATION, levelUpNotification, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_EXP_CATCH, expCatch, (u32, GEN_COUNT - 1)) \
F(B_TRAINER_EXP_MULTIPLIER, trainerExpMultiplier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SPLIT_EXP, splitExp, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SCALED_EXP, scaledExp, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_UNEVOLVED_EXP_MULTIPLIER, unevolvedExpMultiplier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_LEVEL_UP_NOTIFICATION, levelUpNotification, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
/* Stat settings */ \
F(BADGE_BOOST, badgeBoost, (u32, GEN_COUNT - 1)) \
F(FRIENDSHIP_BOOST, friendshipBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MAX_LEVEL_EV_GAINS, maxLevelEvGains, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(RECALCULATE_STATS, recalculateStats, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_BADGE_BOOST, badgeBoost, (u32, GEN_COUNT - 1)) \
F(B_FRIENDSHIP_BOOST, friendshipBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MAX_LEVEL_EV_GAINS, maxLevelEvGains, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_RECALCULATE_STATS, recalculateStats, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
/* Damage settings */ \
F(BURN_DAMAGE, burnDamage, (u32, GEN_COUNT - 1)) \
F(BURN_FACADE_DMG, burnFacadeDmg, (u32, GEN_COUNT - 1)) \
F(BINDING_DAMAGE, bindingDamage, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PSYWAVE_DMG, psywaveDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PAYBACK_SWITCH_BOOST, paybackSwitchBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(HIDDEN_POWER_DMG, hiddenPowerDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(ROUGH_SKIN_DMG, roughSkinDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(KNOCK_OFF_DMG, knockOffDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SPORT_DMG_REDUCTION, sportDmgReduction, (u32, GEN_COUNT - 1)) \
F(EXPLOSION_DEFENSE, explosionDefense, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PARENTAL_BOND_DMG, parentalBondDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MULTIPLE_TARGETS_DMG, multipleTargetsDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_BURN_DAMAGE, burnDamage, (u32, GEN_COUNT - 1)) \
F(B_BURN_FACADE_DMG, burnFacadeDmg, (u32, GEN_COUNT - 1)) \
F(B_BINDING_DAMAGE, bindingDamage, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_PSYWAVE_DMG, psywaveDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_PAYBACK_SWITCH_BOOST, paybackSwitchBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_HIDDEN_POWER_DMG, hiddenPowerDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_ROUGH_SKIN_DMG, roughSkinDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_KNOCK_OFF_DMG, knockOffDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SPORT_DMG_REDUCTION, sportDmgReduction, (u32, GEN_COUNT - 1)) \
F(B_EXPLOSION_DEFENSE, explosionDefense, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_PARENTAL_BOND_DMG, parentalBondDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MULTIPLE_TARGETS_DMG, multipleTargetsDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
/* Type settings */ \
F(GHOSTS_ESCAPE, ghostsEscape, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PARALYZE_ELECTRIC, paralyzeElectric, (u32, GEN_COUNT - 1)) \
F(POWDER_GRASS, powderGrass, (u32, GEN_COUNT - 1)) \
F(POWDER_OVERCOAT, powderOvercoat, (u32, GEN_COUNT - 1)) \
F(UPDATED_TYPE_MATCHUPS, updatedTypeMatchups, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PRANKSTER_DARK_TYPES, pranksterDarkTypes, (u32, GEN_COUNT - 1)) \
F(SHEER_COLD_IMMUNITY, sheerColdImmunity, (u32, GEN_COUNT - 1)) \
F(ROOST_PURE_FLYING, roostPureFlying, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(STATUS_TYPE_IMMUNITY, statusTypeImmunity, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(HIDDEN_POWER_COUNTER, hiddenPowerCounter, (u32, GEN_COUNT - 1)) \
F(B_GHOSTS_ESCAPE, ghostsEscape, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_PARALYZE_ELECTRIC, paralyzeElectric, (u32, GEN_COUNT - 1)) \
F(B_POWDER_GRASS, powderGrass, (u32, GEN_COUNT - 1)) \
F(B_POWDER_OVERCOAT, powderOvercoat, (u32, GEN_COUNT - 1)) \
F(B_UPDATED_TYPE_MATCHUPS, updatedTypeMatchups, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_PRANKSTER_DARK_TYPES, pranksterDarkTypes, (u32, GEN_COUNT - 1)) \
F(B_SHEER_COLD_IMMUNITY, sheerColdImmunity, (u32, GEN_COUNT - 1)) \
F(B_ROOST_PURE_FLYING, roostPureFlying, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_STATUS_TYPE_IMMUNITY, statusTypeImmunity, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_HIDDEN_POWER_COUNTER, hiddenPowerCounter, (u32, GEN_COUNT - 1)) \
/* Turn settings */ \
F(BINDING_TURNS, bindingTurns, (u32, GEN_COUNT - 1)) \
F(UPROAR_TURNS, uproarTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(UPROAR_IGNORE_SOUNDPROOF, uproarIgnoreSoundproof, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(DISABLE_TURNS, disableTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(TAILWIND_TURNS, tailwindTurns, (u32, GEN_COUNT - 1)) \
F(SLEEP_TURNS, sleepTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(TAUNT_TURNS, tauntTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SPORT_TURNS, sportTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MEGA_EVO_TURN_ORDER, megaEvoTurnOrder, (u32, GEN_COUNT - 1)) \
F(RECALC_TURN_AFTER_ACTIONS, recalcTurnAfterActions, (u32, GEN_COUNT - 1)) \
F(FAINT_SWITCH_IN, faintSwitchIn, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_BINDING_TURNS, bindingTurns, (u32, GEN_COUNT - 1)) \
F(B_UPROAR_TURNS, uproarTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_UPROAR_IGNORE_SOUNDPROOF, uproarIgnoreSoundproof, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_DISABLE_TURNS, disableTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TAILWIND_TURNS, tailwindTurns, (u32, GEN_COUNT - 1)) \
F(B_SLEEP_TURNS, sleepTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TAUNT_TURNS, tauntTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SPORT_TURNS, sportTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MEGA_EVO_TURN_ORDER, megaEvoTurnOrder, (u32, GEN_COUNT - 1)) \
F(B_RECALC_TURN_AFTER_ACTIONS, recalcTurnAfterActions, (u32, GEN_COUNT - 1)) \
F(B_FAINT_SWITCH_IN, faintSwitchIn, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
/* Move data settings */ \
F(UPDATED_MOVE_DATA, updatedMoveData, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(UPDATED_MOVE_TYPES, updatedMoveTypes, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(UPDATED_MOVE_FLAGS, updatedMoveFlags, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PHYSICAL_SPECIAL_SPLIT, physicalSpecialSplit, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(RECOIL_IF_MISS_DMG, recoilIfMissDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(KLUTZ_FLING_INTERACTION, klutzFlingInteraction, (u32, GEN_COUNT - 1)) \
F(UPDATED_CONVERSION, updatedConversion, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(UPDATED_CONVERSION_2, updatedConversion2, (u32, GEN_COUNT - 1)) \
F(PP_REDUCED_BY_SPITE, ppReducedBySpite, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(EXTRAPOLATED_MOVE_FLAGS, extrapolatedMoveFlags, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MODERN_TRICK_CHOICE_LOCK, modernTrickChoiceLock, (u32, GEN_COUNT - 1)) \
F(B_UPDATED_MOVE_DATA, updatedMoveData, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_UPDATED_MOVE_TYPES, updatedMoveTypes, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_UPDATED_MOVE_FLAGS, updatedMoveFlags, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_PHYSICAL_SPECIAL_SPLIT, physicalSpecialSplit, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_RECOIL_IF_MISS_DMG, recoilIfMissDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_KLUTZ_FLING_INTERACTION, klutzFlingInteraction, (u32, GEN_COUNT - 1)) \
F(B_UPDATED_CONVERSION, updatedConversion, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_UPDATED_CONVERSION_2, updatedConversion2, (u32, GEN_COUNT - 1)) \
F(B_PP_REDUCED_BY_SPITE, ppReducedBySpite, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_EXTRAPOLATED_MOVE_FLAGS, extrapolatedMoveFlags, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MODERN_TRICK_CHOICE_LOCK, modernTrickChoiceLock, (u32, GEN_COUNT - 1)) \
/* Ability data settings */ \
F(UPDATED_ABILITY_DATA, updatedAbilityData, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_UPDATED_ABILITY_DATA, updatedAbilityData, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
/* Move accuracy settings */ \
F(TOXIC_NEVER_MISS, toxicNeverMiss, (u32, GEN_COUNT - 1)) \
F(MINIMIZE_DMG_ACC, minimizeDmgAcc, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(BLIZZARD_HAIL, blizzardHail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SHEER_COLD_ACC, sheerColdAcc, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TOXIC_NEVER_MISS, toxicNeverMiss, (u32, GEN_COUNT - 1)) \
F(B_MINIMIZE_DMG_ACC, minimizeDmgAcc, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_BLIZZARD_HAIL, blizzardHail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SHEER_COLD_ACC, sheerColdAcc, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
/* Move stat change settings */ \
F(FELL_STINGER_STAT_RAISE, fellStingerStatRaise, (u32, GEN_COUNT - 1)) \
F(KINGS_SHIELD_LOWER_ATK, kingsShieldLowerAtk, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SPEED_BUFFING_RAPID_SPIN, speedBuffingRapidSpin, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(CHARGE_SPDEF_RAISE, chargeSpDefRaise, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MINIMIZE_EVASION, minimizeEvasion, (u32, GEN_COUNT - 1)) \
F(GROWTH_STAT_RAISE, growthStatRaise, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(FOCUS_ENERGY_CRIT_RATIO, focusEnergyCritRatio, (u32, GEN_COUNT - 1)) \
F(PSYCH_UP_CRIT_RATIO, psychUpCritRatio, (u32, GEN_COUNT - 1)) \
F(B_FELL_STINGER_STAT_RAISE, fellStingerStatRaise, (u32, GEN_COUNT - 1)) \
F(B_KINGS_SHIELD_LOWER_ATK, kingsShieldLowerAtk, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SPEED_BUFFING_RAPID_SPIN, speedBuffingRapidSpin, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_CHARGE_SPDEF_RAISE, chargeSpDefRaise, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MINIMIZE_EVASION, minimizeEvasion, (u32, GEN_COUNT - 1)) \
F(B_GROWTH_STAT_RAISE, growthStatRaise, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_FOCUS_ENERGY_CRIT_RATIO, focusEnergyCritRatio, (u32, GEN_COUNT - 1)) \
F(B_PSYCH_UP_CRIT_RATIO, psychUpCritRatio, (u32, GEN_COUNT - 1)) \
/* Other move settings */ \
F(INCINERATE_GEMS, incinerateGems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(CAN_SPITE_FAIL, canSpiteFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(CRASH_IF_TARGET_IMMUNE, crashIfTargetImmune, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MEMENTO_FAIL, mementoFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PARTING_SHOT_SWITCH, partingShotSwitch, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(GLARE_GHOST, glareGhost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SKILL_SWAP, skillSwap, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(BRICK_BREAK, brickBreak, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(WISH_HP_SOURCE, wishHpSource, (u32, GEN_COUNT - 1)) \
F(RAMPAGE_CANCELLING, rampageCancelling, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(HEAL_BLOCKING, healBlocking, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(ROOTED_GROUNDING, rootedGrounding, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(METRONOME_MOVES, metronomeMoves, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(TELEPORT_BEHAVIOR, teleportBehavior, (u32, GEN_COUNT - 1)) \
F(BEAT_UP, beatUp, (u32, GEN_COUNT - 1)) \
F(DARK_VOID_FAIL, darkVoidFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(BURN_HIT_THAW, burnHitThaw, (u32, GEN_COUNT - 1)) \
F(HEALING_WISH_SWITCH, healingWishSwitch, (u32, GEN_COUNT - 1)) \
F(DEFOG_EFFECT_CLEARING, defogEffectClearing, (u32, GEN_COUNT - 1)) \
F(STOCKPILE_RAISES_DEFS, stockpileRaisesDefs, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(TRANSFORM_SHINY, transformShiny, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(TRANSFORM_FORM_CHANGES, transformFormChanges, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(WIDE_GUARD, wideGuard, (u32, GEN_COUNT - 1)) \
F(QUICK_GUARD, quickGuard, (u32, GEN_COUNT - 1)) \
F(IMPRISON, imprison, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(ALLY_SWITCH_FAIL_CHANCE, allySwitchFailChance, (u32, GEN_COUNT - 1)) \
F(SKETCH_BANS, sketchBans, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(KNOCK_OFF_REMOVAL, knockOffRemoval, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(HEAL_BELL_SOUNDPROOF, healBellSoundproof, (u32, GEN_COUNT - 1)) \
F(CHARGE, charge, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(POWDER_STATUS_HEAVY_RAIN, powderStatusHeavyRain, (u32, GEN_COUNT - 1)) \
F(AFTER_YOU_TURN_ORDER, afterYouTurnOrder, (u32, GEN_COUNT - 1)) \
F(QUASH_TURN_ORDER, quashTurnOrder, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(DESTINY_BOND_FAIL, destinyBondFail, (u32, GEN_COUNT - 1)) \
F(FORESIGHT_FAIL, foresightFail, (u32, GEN_COUNT - 1)) \
F(MIRACLE_EYE_FAIL, miracleEyeFail, (u32, GEN_COUNT - 1)) \
F(PURSUIT_TARGET, pursuitTarget, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SKIP_RECHARGE, skipRecharge, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(ENCORE_TARGET, encoreTarget, (u32, GEN_COUNT - 1)) \
F(TIME_OF_DAY_HEALING_MOVES, timeOfDayHealingMoves, (u32, GEN_COUNT - 1)) \
F(DREAM_EATER_LIQUID_OOZE, dreamEaterLiquidOoze, (u32, GEN_COUNT - 1)) \
F(FOCUS_PUNCH_FAILURE, focusPunchFailure, (u32, GEN_COUNT - 1)) \
F(RAGE_BUILDS, rageBuilds, (u32, GEN_COUNT - 1)) \
F(CHECK_USER_FAILURE, checkUserFailure, (u32, GEN_COUNT - 1)) \
F(ABSORB_MESSAGE, absorbMessge, (u32, GEN_COUNT - 1)) \
F(B_INCINERATE_GEMS, incinerateGems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_CAN_SPITE_FAIL, canSpiteFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_CRASH_IF_TARGET_IMMUNE, crashIfTargetImmune, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MEMENTO_FAIL, mementoFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_PARTING_SHOT_SWITCH, partingShotSwitch, (u32, GEN_COUNT - 1)) \
F(B_GLARE_GHOST, glareGhost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SKILL_SWAP, skillSwap, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_BRICK_BREAK, brickBreak, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_WISH_HP_SOURCE, wishHpSource, (u32, GEN_COUNT - 1)) \
F(B_RAMPAGE_CANCELLING, rampageCancelling, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_HEAL_BLOCKING, healBlocking, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_ROOTED_GROUNDING, rootedGrounding, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_METRONOME_MOVES, metronomeMoves, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TELEPORT_BEHAVIOR, teleportBehavior, (u32, GEN_COUNT - 1)) \
F(B_BEAT_UP, beatUp, (u32, GEN_COUNT - 1)) \
F(B_DARK_VOID_FAIL, darkVoidFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_BURN_HIT_THAW, burnHitThaw, (u32, GEN_COUNT - 1)) \
F(B_HEALING_WISH_SWITCH, healingWishSwitch, (u32, GEN_COUNT - 1)) \
F(B_DEFOG_EFFECT_CLEARING, defogEffectClearing, (u32, GEN_COUNT - 1)) \
F(B_STOCKPILE_RAISES_DEFS, stockpileRaisesDefs, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TRANSFORM_SEMI_INV_FAIL, transformSemiInvFail, (u32, GEN_COUNT - 1)) \
F(B_TRANSFORM_TARGET_FAIL, transformTargetFail, (u32, GEN_COUNT - 1)) \
F(B_TRANSFORM_USER_FAIL, transformUserFail, (u32, GEN_COUNT - 1)) \
F(B_TRANSFORM_SUBSTITUTE_FAIL, transformSubstituteFail, (u32, GEN_COUNT - 1)) \
F(B_TRANSFORM_SHINY, transformShiny, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TRANSFORM_FORM_CHANGES, transformFormChanges, (u32, GEN_COUNT - 1)) \
F(B_WIDE_GUARD, wideGuard, (u32, GEN_COUNT - 1)) \
F(B_QUICK_GUARD, quickGuard, (u32, GEN_COUNT - 1)) \
F(B_IMPRISON, imprison, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TAUNT_ME_FIRST, tauntMeFirst, (u32, GEN_COUNT - 1)) \
F(B_ALLY_SWITCH_FAIL_CHANCE, allySwitchFailChance, (u32, GEN_COUNT - 1)) \
F(B_SKETCH_BANS, sketchBans, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_KNOCK_OFF_REMOVAL, knockOffRemoval, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_HEAL_BELL_SOUNDPROOF, healBellSoundproof, (u32, GEN_COUNT - 1)) \
F(B_CHARGE, charge, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_POWDER_STATUS_HEAVY_RAIN, powderStatusHeavyRain, (u32, GEN_COUNT - 1)) \
F(B_AFTER_YOU_TURN_ORDER, afterYouTurnOrder, (u32, GEN_COUNT - 1)) \
F(B_QUASH_TURN_ORDER, quashTurnOrder, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_DESTINY_BOND_FAIL, destinyBondFail, (u32, GEN_COUNT - 1)) \
F(B_FORESIGHT_FAIL, foresightFail, (u32, GEN_COUNT - 1)) \
F(B_MIRACLE_EYE_FAIL, miracleEyeFail, (u32, GEN_COUNT - 1)) \
F(B_PURSUIT_TARGET, pursuitTarget, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SKIP_RECHARGE, skipRecharge, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_ENCORE_TARGET, encoreTarget, (u32, GEN_COUNT - 1)) \
F(B_TIME_OF_DAY_HEALING_MOVES, timeOfDayHealingMoves, (u32, GEN_COUNT - 1)) \
F(B_DREAM_EATER_LIQUID_OOZE, dreamEaterLiquidOoze, (u32, GEN_COUNT - 1)) \
F(B_FOCUS_PUNCH_FAILURE, focusPunchFailure, (u32, GEN_COUNT - 1)) \
F(B_RAGE_BUILDS, rageBuilds, (u32, GEN_COUNT - 1)) \
F(B_CHECK_USER_FAILURE, checkUserFailure, (u32, GEN_COUNT - 1)) \
F(B_ABSORB_MESSAGE, absorbMessge, (u32, GEN_COUNT - 1)) \
/* Ability settings */ \
F(GALE_WINGS, galeWings, (u32, GEN_COUNT - 1)) \
F(STANCE_CHANGE_FAIL, stanceChangeFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SHADOW_TAG_ESCAPE, shadowTagEscape, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MOODY_ACC_EVASION, moodyAccEvasion, (u32, GEN_COUNT - 1)) \
F(FLASH_FIRE_FROZEN, flashFireFrozen, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SYNCHRONIZE_TOXIC, synchronizeToxic, (u32, GEN_COUNT - 1)) \
F(UPDATED_INTIMIDATE, updatedIntimidate, (u32, GEN_COUNT - 1)) \
F(OBLIVIOUS_TAUNT, obliviousTaunt, (u32, GEN_COUNT - 1)) \
F(STURDY, sturdy, (u32, GEN_COUNT - 1)) \
F(PLUS_MINUS_INTERACTION, plusMinusInteraction, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(WEATHER_FORMS, weatherForms, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SYMBIOSIS_GEMS, symbiosisGems, (u32, GEN_COUNT - 1)) \
F(REDIRECT_ABILITY_IMMUNITY, redirectAbilityImmunity, (u32, GEN_COUNT - 1)) \
F(REDIRECT_ABILITY_ALLIES, redirectAbilityAllies, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(LEAF_GUARD_PREVENTS_REST, leafGuardPreventsRest, (u32, GEN_COUNT - 1)) \
F(TRANSISTOR_BOOST, transistorBoost, (u32, GEN_COUNT - 1)) \
F(ILLUMINATE_EFFECT, illuminateEffect, (u32, GEN_COUNT - 1)) \
F(WEAK_ARMOR_SPEED, weakArmorSpeed, (u32, GEN_COUNT - 1)) \
F(PROTEAN_LIBERO, proteanLibero, (u32, GEN_COUNT - 1)) \
F(INTREPID_SWORD, intrepidSword, (u32, GEN_COUNT - 1)) \
F(DAUNTLESS_SHIELD, dauntlessShield, (u32, GEN_COUNT - 1)) \
F(DISGUISE_HP_LOSS, disguiseHpLoss, (u32, GEN_COUNT - 1)) \
F(ABILITY_TRIGGER_CHANCE, abilityTriggerChance, (u32, GEN_COUNT - 1)) \
F(PICKUP_WILD, pickupWild, (u32, GEN_COUNT - 1)) \
F(MAGIC_GUARD, magicGuard, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(BATTLE_BOND, battleBond, (u32, GEN_COUNT - 1)) \
F(ATE_MULTIPLIER, ateMultiplier, (u32, GEN_COUNT - 1)) \
F(DEFIANT_STICKY_WEB, defiantStickyWeb, (u32, GEN_COUNT - 1)) \
F(INFILTRATOR_SUBSTITUTE, infiltratorSubstitute, (u32, GEN_COUNT - 1)) \
F(B_GALE_WINGS, galeWings, (u32, GEN_COUNT - 1)) \
F(B_STANCE_CHANGE_FAIL, stanceChangeFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SHADOW_TAG_ESCAPE, shadowTagEscape, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MOODY_ACC_EVASION, moodyAccEvasion, (u32, GEN_COUNT - 1)) \
F(B_FLASH_FIRE_FROZEN, flashFireFrozen, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SYNCHRONIZE_TOXIC, synchronizeToxic, (u32, GEN_COUNT - 1)) \
F(B_UPDATED_INTIMIDATE, updatedIntimidate, (u32, GEN_COUNT - 1)) \
F(B_OBLIVIOUS_TAUNT, obliviousTaunt, (u32, GEN_COUNT - 1)) \
F(B_STURDY, sturdy, (u32, GEN_COUNT - 1)) \
F(B_PLUS_MINUS_INTERACTION, plusMinusInteraction, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_WEATHER_FORMS, weatherForms, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SYMBIOSIS_GEMS, symbiosisGems, (u32, GEN_COUNT - 1)) \
F(B_REDIRECT_ABILITY_IMMUNITY, redirectAbilityImmunity, (u32, GEN_COUNT - 1)) \
F(B_REDIRECT_ABILITY_ALLIES, redirectAbilityAllies, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_LEAF_GUARD_PREVENTS_REST, leafGuardPreventsRest, (u32, GEN_COUNT - 1)) \
F(B_TRANSISTOR_BOOST, transistorBoost, (u32, GEN_COUNT - 1)) \
F(B_ILLUMINATE_EFFECT, illuminateEffect, (u32, GEN_COUNT - 1)) \
F(B_WEAK_ARMOR_SPEED, weakArmorSpeed, (u32, GEN_COUNT - 1)) \
F(B_PROTEAN_LIBERO, proteanLibero, (u32, GEN_COUNT - 1)) \
F(B_INTREPID_SWORD, intrepidSword, (u32, GEN_COUNT - 1)) \
F(B_DAUNTLESS_SHIELD, dauntlessShield, (u32, GEN_COUNT - 1)) \
F(B_DISGUISE_HP_LOSS, disguiseHpLoss, (u32, GEN_COUNT - 1)) \
F(B_ABILITY_TRIGGER_CHANCE, abilityTriggerChance, (u32, GEN_COUNT - 1)) \
F(B_PICKUP_WILD, pickupWild, (u32, GEN_COUNT - 1)) \
F(B_MAGIC_GUARD, magicGuard, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_BATTLE_BOND, battleBond, (u32, GEN_COUNT - 1)) \
F(B_ATE_MULTIPLIER, ateMultiplier, (u32, GEN_COUNT - 1)) \
F(B_DEFIANT_STICKY_WEB, defiantStickyWeb, (u32, GEN_COUNT - 1)) \
F(B_INFILTRATOR_SUBSTITUTE, infiltratorSubstitute, (u32, GEN_COUNT - 1)) \
/* Item settings */ \
F(CONFUSE_BERRIES_HEAL, confuseBerriesHeal, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(X_ITEMS_BUFF, xItemsBuff, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MENTAL_HERB, mentalHerb, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(TRAINERS_KNOCK_OFF_ITEMS, trainersKnockOffItems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(RETURN_STOLEN_NPC_ITEMS, returnStolenNpcItems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(STEAL_WILD_ITEMS, stealWildItems, (u32, GEN_COUNT - 1)) \
F(RESTORE_HELD_BATTLE_ITEMS, restoreHeldBattleItems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SOUL_DEW_BOOST, soulDewBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(NET_BALL_MODIFIER, netBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(DIVE_BALL_MODIFIER, diveBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(NEST_BALL_MODIFIER, nestBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(REPEAT_BALL_MODIFIER, repeatBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(TIMER_BALL_MODIFIER, timerBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(DUSK_BALL_MODIFIER, duskBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(QUICK_BALL_MODIFIER, quickBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(LURE_BALL_MODIFIER, lureBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(HEAVY_BALL_MODIFIER, heavyBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(DREAM_BALL_MODIFIER, dreamBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SPORT_BALL_MODIFIER, sportBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SAFARI_BALL_MODIFIER, safariBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(FRIEND_BALL_MODIFIER, friendBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SERENE_GRACE_BOOST, sereneGraceBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(IRON_BALL, ironBall, (u32, GEN_COUNT - 1)) \
F(B_CONFUSE_BERRIES_HEAL, confuseBerriesHeal, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_X_ITEMS_BUFF, xItemsBuff, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_MENTAL_HERB, mentalHerb, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TRAINERS_KNOCK_OFF_ITEMS, trainersKnockOffItems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_RETURN_STOLEN_NPC_ITEMS, returnStolenNpcItems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_STEAL_WILD_ITEMS, stealWildItems, (u32, GEN_COUNT - 1)) \
F(B_RESTORE_HELD_BATTLE_ITEMS, restoreHeldBattleItems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SOUL_DEW_BOOST, soulDewBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_NET_BALL_MODIFIER, netBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_DIVE_BALL_MODIFIER, diveBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_NEST_BALL_MODIFIER, nestBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_REPEAT_BALL_MODIFIER, repeatBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TIMER_BALL_MODIFIER, timerBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_DUSK_BALL_MODIFIER, duskBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_QUICK_BALL_MODIFIER, quickBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_LURE_BALL_MODIFIER, lureBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_HEAVY_BALL_MODIFIER, heavyBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_DREAM_BALL_MODIFIER, dreamBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SPORT_BALL_MODIFIER, sportBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SAFARI_BALL_MODIFIER, safariBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_FRIEND_BALL_MODIFIER, friendBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SERENE_GRACE_BOOST, sereneGraceBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_IRON_BALL, ironBall, (u32, GEN_COUNT - 1)) \
/* Weather settings */ \
F(ABILITY_WEATHER, abilityWeather, (u32, GEN_COUNT - 1)) \
F(SANDSTORM_SPDEF_BOOST, sandstormSpDefBoost, (u32, GEN_COUNT - 1)) \
F(OVERWORLD_FOG, overworldFog, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(OVERWORLD_SNOW, overworldSnow, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SNOW_WARNING, snowWarning, (u32, GEN_COUNT - 1)) \
F(PREFERRED_ICE_WEATHER, preferredIceWeather, (u32, B_ICE_WEATHER_SNOW)) /* TODO: use in tests */ \
F(B_ABILITY_WEATHER, abilityWeather, (u32, GEN_COUNT - 1)) \
F(B_SANDSTORM_SPDEF_BOOST, sandstormSpDefBoost, (u32, GEN_COUNT - 1)) \
F(B_OVERWORLD_FOG, overworldFog, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_OVERWORLD_SNOW, overworldSnow, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SNOW_WARNING, snowWarning, (u32, GEN_COUNT - 1)) \
F(B_PREFERRED_ICE_WEATHER, preferredIceWeather, (u32, B_ICE_WEATHER_SNOW)) /* TODO: use in tests */ \
/* Terrain settings */ \
F(TERRAIN_TYPE_BOOST, terrainTypeBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SECRET_POWER_EFFECT, secretPowerEffect, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SECRET_POWER_ANIMATION, secretPowerAnimation, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(NATURE_POWER_MOVES, naturePowerMoves, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(CAMOUFLAGE_TYPES, camouflageTypes, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_TERRAIN_TYPE_BOOST, terrainTypeBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SECRET_POWER_EFFECT, secretPowerEffect, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SECRET_POWER_ANIMATION, secretPowerAnimation, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_NATURE_POWER_MOVES, naturePowerMoves, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_CAMOUFLAGE_TYPES, camouflageTypes, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
/* Catching settings */ \
F(SEMI_INVULNERABLE_CATCH, semiInvulnerableCatch, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(INCAPACITATED_CATCH_BONUS, incapacitatedCatchBonus, (u32, GEN_COUNT - 1)) \
F(LOW_LEVEL_CATCH_BONUS, lowLevlCatchBonus, (u32, GEN_COUNT - 1)) \
F(MISSING_BADGE_CATCH_MALUS, missingBadgeCatchMalue, (u32, GEN_COUNT - 1)) \
F(CRITICAL_CAPTURE_IF_OWNED, criticalCaptureIfOwned, (u32, GEN_COUNT - 1)) \
F(B_SEMI_INVULNERABLE_CATCH, semiInvulnerableCatch, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_INCAPACITATED_CATCH_BONUS, incapacitatedCatchBonus, (u32, GEN_COUNT - 1)) \
F(B_LOW_LEVEL_CATCH_BONUS, lowLevlCatchBonus, (u32, GEN_COUNT - 1)) \
F(B_MISSING_BADGE_CATCH_MALUS, missingBadgeCatchMalue, (u32, GEN_COUNT - 1)) \
F(B_CRITICAL_CAPTURE_IF_OWNED, criticalCaptureIfOwned, (u32, GEN_COUNT - 1)) \
/* Other settings */ \
F(WILD_NATURAL_ENEMIES, wildNaturalEnemies, (u32, TRUE)) /* TODO: use in tests */ \
F(AFFECTION_MECHANICS, affectionMechanics, (u32, TRUE)) /* TODO: use in tests */ \
F(OBEDIENCE_MECHANICS, obedienceMechanics, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(USE_FROSTBITE, useFrostbite, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SANDSTORM_SOLAR_BEAM, standstormSolarBeam, (u32, GEN_COUNT - 1)) \
F(COUNTER_MIRROR_COAT_ALLY, counterMirrorCoatAlly, (u32, GEN_COUNT - 1)) \
F(COUNTER_TRY_HIT_PARTNER, counterTryHitPartner, (u32, GEN_COUNT - 1)) \
F(B_WILD_NATURAL_ENEMIES, wildNaturalEnemies, (u32, TRUE)) /* TODO: use in tests */ \
F(B_AFFECTION_MECHANICS, affectionMechanics, (u32, TRUE)) /* TODO: use in tests */ \
F(B_OBEDIENCE_MECHANICS, obedienceMechanics, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_USE_FROSTBITE, useFrostbite, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(B_SANDSTORM_SOLAR_BEAM, standstormSolarBeam, (u32, GEN_COUNT - 1)) \
F(B_COUNTER_MIRROR_COAT_ALLY, counterMirrorCoatAlly, (u32, GEN_COUNT - 1)) \
F(B_COUNTER_TRY_HIT_PARTNER, counterTryHitPartner, (u32, GEN_COUNT - 1)) \
#define POKEMON_CONFIG_DEFINITIONS(F) \

View File

@ -43,4 +43,6 @@ void UpdateSparkleFieldEffect(struct Sprite *sprite);
void SetSpriteInvisible(u8 spriteId);
void ShowWarpArrowSprite(u8 spriteId, enum Direction direction, s16 x, s16 y);
u32 FldEff_TallGrass(void);
#endif //GUARD_FIELD_EFFECT_HELPERS_H

View File

@ -18,7 +18,9 @@ struct GenChanges
// ...
};
u32 GetConfig(enum ConfigTag configTag);
#define GetConfig(name) GetConfigInternal(CONFIG_##name)
u32 GetConfigInternal(enum ConfigTag configTag);
void SetConfig(enum ConfigTag configTag, u32 value);
#if TESTING

View File

@ -470,7 +470,7 @@ static inline bool32 MoveAlwaysHitsInHailSnow(enum Move moveId)
static inline bool32 MoveAlwaysHitsOnSameType(enum Move moveId)
{
#if TESTING
if (moveId == MOVE_TOXIC && GetConfig(CONFIG_TOXIC_NEVER_MISS) < GEN_6)
if (moveId == MOVE_TOXIC && GetConfig(B_TOXIC_NEVER_MISS) < GEN_6)
return FALSE;
#endif
return gMovesInfo[SanitizeMoveId(moveId)].alwaysHitsOnSameType;
@ -479,7 +479,7 @@ static inline bool32 MoveAlwaysHitsOnSameType(enum Move moveId)
static inline bool32 MoveHasNoEffectOnSameType(enum Move moveId)
{
#if TESTING
if (moveId == MOVE_SHEER_COLD && GetConfig(CONFIG_SHEER_COLD_IMMUNITY) < GEN_7)
if (moveId == MOVE_SHEER_COLD && GetConfig(B_SHEER_COLD_IMMUNITY) < GEN_7)
return FALSE;
#endif
return gMovesInfo[SanitizeMoveId(moveId)].noAffectOnSameTypeTarget;

View File

@ -309,7 +309,7 @@
* of `enum ConfigTag`
* Example:
* GIVEN {
* WITH_CONFIG(CONFIG_GALE_WINGS, GEN_6);
* WITH_CONFIG(B_GALE_WINGS, GEN_6);
* }
* The `value` may be inferred from a local variable, e.g. set by
* PARAMETRIZE.
@ -1012,7 +1012,7 @@ struct moveWithPP {
#define FLAG_SET(flagId) SetFlagForTest(__LINE__, flagId)
#define VAR_SET(varId, value) SetVarForTest(__LINE__, varId, value)
#define WITH_CONFIG(configTag, value) TestSetConfig(__LINE__, configTag, value)
#define WITH_CONFIG(configTag, value) TestSetConfig(__LINE__, CONFIG_##configTag, value)
#define PLAYER(species) for (OpenPokemon(__LINE__, B_TRAINER_0, species); gBattleTestRunnerState->data.currentMon; ClosePokemon(__LINE__))
#define OPPONENT(species) for (OpenPokemon(__LINE__, B_TRAINER_1, species); gBattleTestRunnerState->data.currentMon; ClosePokemon(__LINE__))

View File

@ -1361,7 +1361,7 @@ static s32 AI_CheckBadMove(enum BattlerId battlerAtk, enum BattlerId battlerDef,
} // def partner ability checks
// gen7+ dark type mons immune to priority->elevated moves from prankster
if (GetConfig(CONFIG_PRANKSTER_DARK_TYPES) >= GEN_7 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK)
if (GetConfig(B_PRANKSTER_DARK_TYPES) >= GEN_7 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK)
&& aiData->abilities[battlerAtk] == ABILITY_PRANKSTER && IsBattleMoveStatus(move)
&& moveTarget != TARGET_OPPONENTS_FIELD
&& moveTarget != TARGET_USER)
@ -3498,7 +3498,7 @@ static s32 AI_DoubleBattle(enum BattlerId battlerAtk, enum BattlerId battlerDef,
case ABILITY_VOLT_ABSORB:
if (moveType == TYPE_ELECTRIC)
{
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) < GEN_5 && atkPartnerAbility == ABILITY_LIGHTNING_ROD)
if (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) < GEN_5 && atkPartnerAbility == ABILITY_LIGHTNING_ROD)
{
RETURN_SCORE_MINUS(10);
}
@ -3544,7 +3544,7 @@ static s32 AI_DoubleBattle(enum BattlerId battlerAtk, enum BattlerId battlerDef,
case ABILITY_STORM_DRAIN:
if (moveType == TYPE_WATER)
{
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) < GEN_5 && atkPartnerAbility == ABILITY_STORM_DRAIN)
if (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) < GEN_5 && atkPartnerAbility == ABILITY_STORM_DRAIN)
{
RETURN_SCORE_MINUS(10);
}
@ -5552,7 +5552,7 @@ static s32 AI_CalcMoveEffectScore(enum BattlerId battlerAtk, enum BattlerId batt
case EFFECT_ION_DELUGE:
if ((aiData->abilities[battlerAtk] == ABILITY_VOLT_ABSORB
|| aiData->abilities[battlerAtk] == ABILITY_MOTOR_DRIVE
|| (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD))
|| (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD))
&& predictedType == TYPE_NORMAL)
ADJUST_SCORE(DECENT_EFFECT);
break;
@ -5613,7 +5613,7 @@ static s32 AI_CalcMoveEffectScore(enum BattlerId battlerAtk, enum BattlerId batt
if (predictedMove != MOVE_NONE
&& (aiData->abilities[battlerAtk] == ABILITY_VOLT_ABSORB
|| aiData->abilities[battlerAtk] == ABILITY_MOTOR_DRIVE
|| (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD)))
|| (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD)))
{
ADJUST_SCORE(DECENT_EFFECT);
}
@ -5880,8 +5880,11 @@ static s32 AI_CalcAdditionalEffectScore(enum BattlerId battlerAtk, enum BattlerI
// Set battlerDef best dmg moves
GetBestDmgMovesFromBattler(battlerDef, battlerAtk, AI_DEFENDING, defBestMoves);
if (IsSheerForceAffected(move, aiData->abilities[battlerAtk]))
if (IsSheerForceAffected(move, aiData->abilities[battlerAtk])
&& !(move == MOVE_ORDER_UP && gBattleStruct->battlerState[battlerAtk].commanderSpecies != SPECIES_NONE))
{
return score;
}
// check move additional effects that are likely to happen
for (u32 effectId = 0; effectId < additionalEffectCount; effectId++)

View File

@ -558,7 +558,6 @@ static bool32 FindMonThatAbsorbsOpponentsMove(enum BattlerId battler)
enum BattlerId opposingBattler = GetOppositeBattler(battler);
enum Move incomingMove = GetIncomingMove(battler, opposingBattler, gAiLogicData);
enum Type incomingType = CheckDynamicMoveType(GetBattlerMon(opposingBattler), incomingMove, opposingBattler, MON_IN_BATTLE);
bool32 isOpposingBattlerChargingOrInvulnerable = !BreaksThroughSemiInvulnerablity(battler, opposingBattler, gAiLogicData->abilities[battler], gAiLogicData->abilities[opposingBattler], incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove);
if (!(gAiThinkingStruct->aiFlags[battler] & AI_FLAG_SMART_SWITCHING))
return FALSE;
@ -593,44 +592,44 @@ static bool32 FindMonThatAbsorbsOpponentsMove(enum BattlerId battler)
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_FLASH_FIRE;
}
if (incomingType == TYPE_WATER || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_WATER))
if (incomingType == TYPE_WATER)
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_WATER_ABSORB;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_DRY_SKIN;
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5)
if (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) >= GEN_5)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_STORM_DRAIN;
}
if (incomingType == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_ELECTRIC))
if (incomingType == TYPE_ELECTRIC)
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_VOLT_ABSORB;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_MOTOR_DRIVE;
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5)
if (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) >= GEN_5)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LIGHTNING_ROD;
}
if (incomingType == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GRASS))
if (incomingType == TYPE_GRASS)
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SAP_SIPPER;
}
if (incomingType == TYPE_GROUND || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GROUND))
if (incomingType == TYPE_GROUND)
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_EARTH_EATER;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LEVITATE;
}
if (IsSoundMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsSoundMove(incomingMove)))
if (IsSoundMove(incomingMove))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SOUNDPROOF;
}
if (IsBallisticMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsBallisticMove(incomingMove)))
if (IsBallisticMove(incomingMove))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_BULLETPROOF;
}
if (IsWindMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsWindMove(incomingMove)))
if (IsWindMove(incomingMove))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_WIND_RIDER;
}
if (IsPowderMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsPowderMove(incomingMove)))
if (IsPowderMove(incomingMove))
{
if (GetConfig(CONFIG_POWDER_OVERCOAT) >= GEN_6)
if (GetConfig(B_POWDER_OVERCOAT) >= GEN_6)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_OVERCOAT;
}
if (numAbsorbingAbilities == 0)
@ -681,14 +680,23 @@ static bool32 ShouldSwitchIfOpponentChargingOrInvulnerable(enum BattlerId battle
{
enum BattlerId opposingBattler = GetOppositeBattler(battler);
enum Move incomingMove = GetIncomingMove(battler, opposingBattler, gAiLogicData);
bool32 isOpposingBattlerChargingOrInvulnerable = !BreaksThroughSemiInvulnerablity(battler, opposingBattler, gAiLogicData->abilities[battler], gAiLogicData->abilities[opposingBattler], incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove);
enum BattleMoveEffects effect = GetMoveEffect(incomingMove);
if (IsDoubleBattle() || !(gAiThinkingStruct->aiFlags[battler] & AI_FLAG_SMART_SWITCHING))
return FALSE;
// Two-turn attacks that charge without entering semi-invulnerable state (e.g. Solar Beam).
// First turn of Fly/Dive/Bounce/Sky Drop: move is selected this turn but user is not yet semi-invulnerable.
// Opponent is already semi-invulnerable.
if (!(IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove)
|| ((effect == EFFECT_SEMI_INVULNERABLE || effect == EFFECT_SKY_DROP) && !IsSemiInvulnerable(opposingBattler, CHECK_ALL))
|| IsSemiInvulnerable(opposingBattler, CHECK_ALL)))
{
return FALSE;
}
// In a world with a unified ShouldSwitch function, also want to check whether we already win 1v1 and if we do don't switch; not worth doubling the HasBadOdds computation for now
if (isOpposingBattlerChargingOrInvulnerable && gAiLogicData->mostSuitableMonId[battler] != PARTY_SIZE && RandomPercentage(RNG_AI_SWITCH_FREE_TURN, GetSwitchChance(SHOULD_SWITCH_FREE_TURN)))
if (gAiLogicData->mostSuitableMonId[battler] != PARTY_SIZE && RandomPercentage(RNG_AI_SWITCH_FREE_TURN, GetSwitchChance(SHOULD_SWITCH_FREE_TURN)))
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
return FALSE;
@ -717,7 +725,7 @@ static bool32 ShouldSwitchIfTrapperInParty(enum BattlerId battler)
for (u32 monIndex = firstId; monIndex < lastId; monIndex++)
{
if (IsAceMon(battler, monIndex))
return FALSE;
continue;
monAbility = GetMonAbility(&party[monIndex]);
@ -783,7 +791,7 @@ static bool32 ShouldSwitchIfBadlyStatused(enum BattlerId battler)
&& gAiLogicData->abilities[opposingBattler] != ABILITY_UNAWARE
&& gAiLogicData->abilities[opposingBattler] != ABILITY_KEEN_EYE
&& gAiLogicData->abilities[opposingBattler] != ABILITY_MINDS_EYE
&& (GetConfig(CONFIG_ILLUMINATE_EFFECT) >= GEN_9 && gAiLogicData->abilities[opposingBattler] != ABILITY_ILLUMINATE)
&& (GetConfig(B_ILLUMINATE_EFFECT) >= GEN_9 && gAiLogicData->abilities[opposingBattler] != ABILITY_ILLUMINATE)
&& !gBattleMons[battler].volatiles.foresight
&& !gBattleMons[battler].volatiles.miracleEye)
switchMon = FALSE;
@ -1371,7 +1379,7 @@ bool32 ShouldSwitchIfAllScoresBad(enum BattlerId battler)
score = gAiBattleData->finalScore[battler][opposingBattler][moveIndex];
if (score > AI_BAD_SCORE_THRESHOLD)
return FALSE;
}
}
}
if (RandomPercentage(RNG_AI_SWITCH_ALL_SCORES_BAD, GetSwitchChance(SHOULD_SWITCH_ALL_SCORES_BAD))
&& (gAiLogicData->mostSuitableMonId[battler] != PARTY_SIZE || !ALL_SCORES_BAD_NEEDS_GOOD_SWITCHIN))
@ -1681,7 +1689,7 @@ static u32 GetSwitchinStatusDamage(enum BattlerId battler)
{
if (status & STATUS1_BURN)
{
if (GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7 || GetConfig(CONFIG_BURN_DAMAGE) == GEN_1)
if (GetConfig(B_BURN_DAMAGE) >= GEN_7 || GetConfig(B_BURN_DAMAGE) == GEN_1)
statusDamage = maxHP / 16;
else
statusDamage = maxHP / 8;
@ -1692,7 +1700,7 @@ static u32 GetSwitchinStatusDamage(enum BattlerId battler)
}
else if (status & STATUS1_FROSTBITE)
{
if (GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7 || GetConfig(CONFIG_BURN_DAMAGE) == GEN_1)
if (GetConfig(B_BURN_DAMAGE) >= GEN_7 || GetConfig(B_BURN_DAMAGE) == GEN_1)
statusDamage = maxHP / 16;
else
statusDamage = maxHP / 8;
@ -1792,7 +1800,7 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, enum BattlerId battler, const st
currentHP = currentHP - damageTaken;
// One shot prevention effects
if (damageTaken >= maxHP && startingHP == maxHP && (heldItemEffect == HOLD_EFFECT_FOCUS_SASH || (!opponentCanBreakMold && GetConfig(CONFIG_STURDY) >= GEN_5 && ability == ABILITY_STURDY)) && hitsToKO < 1)
if (damageTaken >= maxHP && startingHP == maxHP && (heldItemEffect == HOLD_EFFECT_FOCUS_SASH || (!opponentCanBreakMold && GetConfig(B_STURDY) >= GEN_5 && ability == ABILITY_STURDY)) && hitsToKO < 1)
currentHP = 1;
// If mon is still alive, apply weather impact first, as it might KO the mon before it can heal with its item (order is weather -> item -> status)
@ -2201,7 +2209,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
maxHitsToKO = hitsToKOAI;
bestDefensiveMonId = monIndex;
}
}
}
}
if (canSwitchinWin1v1)
@ -2221,7 +2229,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
{
bestResistEffective = typeMatchup;
bestTypeMatchupEffectiveId = monIndex;
}
}
}
}
}

View File

@ -48,13 +48,14 @@ static bool32 AI_IsDoubleSpreadMove(enum BattlerId battlerAtk, enum Move move)
for (enum BattlerId battlerDef = 0; battlerDef < MAX_BATTLERS_COUNT; battlerDef++)
{
if (battlerAtk == battlerDef)
if (battlerAtk == battlerDef || !IsBattlerAlive(battlerDef))
continue;
if (moveTargetType == TARGET_BOTH && battlerAtk == BATTLE_PARTNER(battlerDef))
continue;
if (IsBattlerAlive(battlerDef) && !IsSemiInvulnerable(battlerDef, CHECK_ALL))
if (!IsSemiInvulnerable(battlerDef, CHECK_ALL)
|| BreaksThroughSemiInvulnerablity(battlerAtk, battlerDef, gAiLogicData->abilities[battlerAtk], gAiLogicData->abilities[battlerDef], move))
numOfTargets++;
}
@ -469,7 +470,7 @@ bool32 AI_CanBattlerEscape(enum BattlerId battler)
{
enum HoldEffect holdEffect = gAiLogicData->holdEffects[battler];
if (GetConfig(CONFIG_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
if (GetConfig(B_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
return TRUE;
if (holdEffect == HOLD_EFFECT_SHED_SHELL)
return TRUE;
@ -767,7 +768,7 @@ static inline void CalcDynamicMoveDamage(struct BattleContext *ctx, u16 *medianD
u32 strikeCount = GetMoveStrikeCount(ctx->move);
if (effect == EFFECT_BEAT_UP && GetConfig(CONFIG_BEAT_UP) >= GEN_5)
if (effect == EFFECT_BEAT_UP && GetConfig(B_BEAT_UP) >= GEN_5)
{
u32 partyCount = CalculatePartyCount(GetBattlerParty(ctx->battlerAtk));
u32 i;
@ -840,7 +841,7 @@ static inline bool32 ShouldCalcCritDamage(struct BattleContext *ctx)
s32 critChanceIndex = 0;
// Get crit chance
if (GetConfig(CONFIG_CRIT_CHANCE) == GEN_1)
if (GetConfig(B_CRIT_CHANCE) == GEN_1)
critChanceIndex = CalcCritChanceStageGen1(ctx);
else
critChanceIndex = CalcCritChanceStage(ctx);
@ -849,11 +850,11 @@ static inline bool32 ShouldCalcCritDamage(struct BattleContext *ctx)
return TRUE;
if (critChanceIndex >= RISKY_AI_CRIT_STAGE_THRESHOLD // Not guaranteed but above Risky threshold
&& (gAiThinkingStruct->aiFlags[ctx->battlerAtk] & AI_FLAG_RISKY)
&& GetConfig(CONFIG_CRIT_CHANCE) != GEN_1)
&& GetConfig(B_CRIT_CHANCE) != GEN_1)
return TRUE;
if (critChanceIndex >= RISKY_AI_CRIT_THRESHOLD_GEN_1 // Not guaranteed but above Risky threshold
&& (gAiThinkingStruct->aiFlags[ctx->battlerAtk] & AI_FLAG_RISKY)
&& GetConfig(CONFIG_CRIT_CHANCE) == GEN_1)
&& GetConfig(B_CRIT_CHANCE) == GEN_1)
return TRUE;
return FALSE;
@ -1036,8 +1037,11 @@ static bool32 AI_IsMoveEffectInPlus(enum BattlerId battlerAtk, enum BattlerId ba
enum Move predictedMoveSpeedCheck = GetIncomingMoveSpeedCheck(battlerAtk, battlerDef, gAiLogicData);
bool32 aiIsFaster = AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY);
if (IsSheerForceAffected(move, abilityAtk))
if (IsSheerForceAffected(move, abilityAtk)
&& !(move == MOVE_ORDER_UP && gBattleStruct->battlerState[battlerAtk].commanderSpecies != SPECIES_NONE))
{
return FALSE;
}
switch (GetMoveEffect(move))
{
@ -1254,7 +1258,7 @@ static bool32 AI_IsMoveEffectInMinus(enum BattlerId battlerAtk, enum BattlerId b
return TRUE;
break;
case EFFECT_DREAM_EATER:
if (abilityDef == ABILITY_LIQUID_OOZE && GetConfig(CONFIG_DREAM_EATER_LIQUID_OOZE) >= GEN_5)
if (abilityDef == ABILITY_LIQUID_OOZE && GetConfig(B_DREAM_EATER_LIQUID_OOZE) >= GEN_5)
return TRUE;
break;
default:
@ -1508,7 +1512,7 @@ bool32 CanEndureHit(enum BattlerId battler, enum BattlerId battlerTarget, enum M
if (!DoesBattlerIgnoreAbilityChecks(battler, gAiLogicData->abilities[battler], move))
{
if (GetConfig(CONFIG_STURDY) >= GEN_5 && gAiLogicData->abilities[battlerTarget] == ABILITY_STURDY)
if (GetConfig(B_STURDY) >= GEN_5 && gAiLogicData->abilities[battlerTarget] == ABILITY_STURDY)
return TRUE;
if (IsMimikyuDisguised(battlerTarget))
return TRUE;
@ -1927,7 +1931,7 @@ u32 AI_GetSwitchinWeather(enum BattlerId battler)
case ABILITY_SAND_STREAM:
return B_WEATHER_SANDSTORM;
case ABILITY_SNOW_WARNING:
return GetConfig(CONFIG_SNOW_WARNING) >= GEN_9 ? B_WEATHER_SNOW : B_WEATHER_HAIL;
return GetConfig(B_SNOW_WARNING) >= GEN_9 ? B_WEATHER_SNOW : B_WEATHER_HAIL;
default:
return gBattleWeather;
}
@ -2066,7 +2070,7 @@ bool32 IsHazardClearingMove(enum Move move)
case EFFECT_TIDY_UP:
return TRUE;
case EFFECT_DEFOG:
if (GetConfig(CONFIG_DEFOG_EFFECT_CLEARING) >= GEN_6)
if (GetConfig(B_DEFOG_EFFECT_CLEARING) >= GEN_6)
return TRUE;
break;
default:
@ -2351,7 +2355,7 @@ bool32 CanLowerStat(enum BattlerId battlerAtk, enum BattlerId battlerDef, struct
if (stat == STAT_DEF)
return FALSE;
case ABILITY_ILLUMINATE:
if (GetConfig(CONFIG_ILLUMINATE_EFFECT) < GEN_9)
if (GetConfig(B_ILLUMINATE_EFFECT) < GEN_9)
break;
case ABILITY_KEEN_EYE:
case ABILITY_MINDS_EYE:
@ -3104,7 +3108,7 @@ bool32 IsSwitchOutEffect(enum BattleMoveEffects effect)
switch (effect)
{
case EFFECT_TELEPORT:
if (GetConfig(CONFIG_TELEPORT_BEHAVIOR) >= GEN_8)
if (GetConfig(B_TELEPORT_BEHAVIOR) >= GEN_8)
return TRUE;
case EFFECT_HIT_ESCAPE:
case EFFECT_PARTING_SHOT:
@ -3345,23 +3349,31 @@ static u32 GetPoisonDamage(enum BattlerId battlerId)
return damage;
}
static bool32 BattlerAffectedBySandstorm(enum BattlerId battlerId, enum Ability ability)
static bool32 DoesBattlerTakeSandstormDamage(enum BattlerId battlerId, enum Ability ability)
{
if (!(AI_GetWeather() & B_WEATHER_SANDSTORM))
return FALSE;
if (!IS_BATTLER_ANY_TYPE(battlerId, TYPE_ROCK, TYPE_GROUND, TYPE_STEEL)
&& ability != ABILITY_SAND_VEIL
&& ability != ABILITY_SAND_FORCE
&& ability != ABILITY_SAND_RUSH
&& ability != ABILITY_MAGIC_GUARD
&& ability != ABILITY_OVERCOAT)
return TRUE;
return FALSE;
}
static bool32 BattlerAffectedByHail(enum BattlerId battlerId, enum Ability ability)
static bool32 DoesBattlerTakeHailDamage(enum BattlerId battlerId, enum Ability ability)
{
if (!(AI_GetWeather() & B_WEATHER_HAIL))
return FALSE;
if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_ICE)
&& ability != ABILITY_SNOW_CLOAK
&& ability != ABILITY_OVERCOAT
&& ability != ABILITY_ICE_BODY)
&& ability != ABILITY_ICE_BODY
&& ability != ABILITY_MAGIC_GUARD
&& ability != ABILITY_OVERCOAT)
return TRUE;
return FALSE;
}
@ -3377,7 +3389,7 @@ static u32 GetWeatherDamage(enum BattlerId battlerId)
if (weather & B_WEATHER_SANDSTORM)
{
if (BattlerAffectedBySandstorm(battlerId, ability)
if (DoesBattlerTakeSandstormDamage(battlerId, ability)
&& gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERGROUND
&& gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERWATER
&& holdEffect != HOLD_EFFECT_SAFETY_GOGGLES)
@ -3389,7 +3401,7 @@ static u32 GetWeatherDamage(enum BattlerId battlerId)
}
if ((weather & B_WEATHER_HAIL) && ability != ABILITY_ICE_BODY)
{
if (BattlerAffectedByHail(battlerId, ability)
if (DoesBattlerTakeHailDamage(battlerId, ability)
&& gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERGROUND
&& gBattleMons[battlerId].volatiles.semiInvulnerable != STATE_UNDERWATER
&& holdEffect != HOLD_EFFECT_SAFETY_GOGGLES)
@ -3421,8 +3433,11 @@ u32 GetBattlerSecondaryDamage(enum BattlerId battlerId)
bool32 BattlerWillFaintFromWeather(enum BattlerId battler, enum Ability ability)
{
if ((BattlerAffectedBySandstorm(battler, ability) || BattlerAffectedByHail(battler, ability))
&& gBattleMons[battler].hp <= max(1, gBattleMons[battler].maxHP / 16))
if (gAiLogicData->holdEffects[battler] == HOLD_EFFECT_SAFETY_GOGGLES)
return FALSE;
if ((DoesBattlerTakeSandstormDamage(battler, ability) || DoesBattlerTakeHailDamage(battler, ability))
&& gBattleMons[battler].hp <= max(1, GetNonDynamaxMaxHP(battler) / 16))
return TRUE;
return FALSE;
@ -3861,7 +3876,7 @@ bool32 AnyPartyMemberStatused(enum BattlerId battlerId, bool32 checkSoundproof)
battlerOnField1 = gBattlerPartyIndexes[battlerId];
battlerOnField2 = gBattlerPartyIndexes[GetPartnerBattler(battlerId)];
// Check partner's status
if ((GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5
if ((GetConfig(B_HEAL_BELL_SOUNDPROOF) == GEN_5
|| gAiLogicData->abilities[BATTLE_PARTNER(battlerId)] != ABILITY_SOUNDPROOF
|| !checkSoundproof)
&& GetMonData(&party[battlerOnField2], MON_DATA_STATUS) != STATUS1_NONE
@ -3875,8 +3890,8 @@ bool32 AnyPartyMemberStatused(enum BattlerId battlerId, bool32 checkSoundproof)
}
// Check attacker's status
if ((GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5
|| GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) >= GEN_8
if ((GetConfig(B_HEAL_BELL_SOUNDPROOF) == GEN_5
|| GetConfig(B_HEAL_BELL_SOUNDPROOF) >= GEN_8
|| gAiLogicData->abilities[battlerId] != ABILITY_SOUNDPROOF || !checkSoundproof)
&& GetMonData(&party[battlerOnField1], MON_DATA_STATUS) != STATUS1_NONE
&& ShouldCureStatus(battlerId, battlerId, gAiLogicData))
@ -3887,7 +3902,7 @@ bool32 AnyPartyMemberStatused(enum BattlerId battlerId, bool32 checkSoundproof)
{
if (monIndex == battlerOnField1 || monIndex == battlerOnField2)
continue;
if (GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) < GEN_5
if (GetConfig(B_HEAL_BELL_SOUNDPROOF) < GEN_5
&& checkSoundproof
&& GetMonAbility(&party[monIndex]) == ABILITY_SOUNDPROOF)
continue;
@ -5863,7 +5878,7 @@ bool32 ShouldTriggerAbility(enum BattlerId battlerAtk, enum BattlerId battlerDef
{
case ABILITY_LIGHTNING_ROD:
case ABILITY_STORM_DRAIN:
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) < GEN_5)
if (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) < GEN_5)
return FALSE;
else
return (BattlerStatCanRise(battlerDef, ability, STAT_SPATK) && HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL));

View File

@ -216,11 +216,32 @@ static void RecordedPartnerHandleDrawTrainerPic(enum BattlerId battler)
s16 xPos, yPos;
enum TrainerPicID trainerPicId;
trainerPicId = TRAINER_PIC_BACK_STEVEN;
xPos = 90;
yPos = (8 - gTrainerBacksprites[trainerPicId].coordinates.size) * 4 + 80;
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
isFrontPic = FALSE;
if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE))
{
trainerPicId = gBattlePartners[difficulty][gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerBackPic;
xPos = 90;
yPos = (8 - gTrainerBacksprites[trainerPicId].coordinates.size) * 4 + 80;
}
else if (IsAiVsAiBattle())
{
trainerPicId = GetTrainerPicFromId(gPartnerTrainerId);
xPos = 60;
yPos = 80;
}
else
{
trainerPicId = GetFrontierTrainerFrontSpriteId(gPartnerTrainerId);
xPos = 32;
yPos = 80;
}
// Use back pic only if the partner Steven or is custom.
if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE))
isFrontPic = FALSE;
else
isFrontPic = TRUE;
BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1);
}
@ -266,9 +287,9 @@ static void RecordedPartnerHandleIntroTrainerBallThrow(enum BattlerId battler)
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE))
trainerPal = gTrainerBacksprites[gBattlePartners[difficulty][gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerPic].palette.data;
trainerPal = gTrainerBacksprites[gBattlePartners[difficulty][gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerBackPic].palette.data;
else if (IsAiVsAiBattle())
trainerPal = gTrainerSprites[GetTrainerPicFromId(gPartnerTrainerId)].palette.data;
trainerPal = gTrainerSprites[GetTrainerBackPicFromId(gPartnerTrainerId)].palette.data;
else
trainerPal = gTrainerSprites[GetFrontierTrainerFrontSpriteId(gPartnerTrainerId)].palette.data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.

View File

@ -2472,8 +2472,8 @@ void BtlController_HandleDrawTrainerPic(enum BattlerId battler, enum TrainerPicI
// Sets sprite priority to 1 so mons don't remain in foreground
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.priority = 1;
// Aiming for palette slots 8 and 9 for Player and PlayerPartner to prevent Trainer Slides causing mons to change colour
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.paletteNum = (8 + battler/2);
// Aiming for palette slots 14 and 15 for Player and PlayerPartner to prevent Trainer Slides causing mons to change colour
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.paletteNum = (14 + battler/2);
}
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].x2 = DISPLAY_WIDTH;
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].sSpeedX = -2;
@ -2500,8 +2500,8 @@ void BtlController_HandleTrainerSlide(enum BattlerId battler, enum TrainerPicID
gBattlerSpriteIds[battler] = gBattleStruct->trainerSlideSpriteIds[battler];
// Sets sprite priority to 1 so mons don't remain in foreground
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.priority = 1;
// Aiming for palette slots 8 and 9 for Player and PlayerPartner to prevent Trainer Slides causing mons to change colour
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.paletteNum = (8 + battler/2);
// Aiming for palette slots 14 and 15 for Player and PlayerPartner to prevent Trainer Slides causing mons to change colour
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.paletteNum = (14 + battler/2);
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].x2 = -96;
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].sSpeedX = 2;
}
@ -2875,7 +2875,7 @@ void BtlController_HandleIntroTrainerBallThrow(enum BattlerId battler, u16 tagTr
paletteNum = AllocSpritePalette(tagTrainerPal);
LoadPalette(trainerPal, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP);
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.paletteNum = (8 + battler/2);
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.paletteNum = paletteNum;
}
else
{

View File

@ -5119,7 +5119,7 @@ static u16 GetWinningMove(int winnerTournamentId, int loserTournamentId, u8 roun
movePower = 40;
else if (movePower == 1)
movePower = 60;
else if (GetConfig(CONFIG_EXPLOSION_DEFENSE) < GEN_5 && IsExplosionMove(move))
else if (GetConfig(B_EXPLOSION_DEFENSE) < GEN_5 && IsExplosionMove(move))
movePower /= 2;
for (k = 0; k < FRONTIER_PARTY_SIZE; k++)

View File

@ -268,7 +268,7 @@ static bool32 HandleEndTurnWish(enum BattlerId battler)
s32 wishHeal = 0;
gBattlerTarget = battler;
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battler, gBattleStruct->wish[battler].partyId)
if (GetConfig(CONFIG_WISH_HP_SOURCE) >= GEN_5)
if (GetConfig(B_WISH_HP_SOURCE) >= GEN_5)
wishHeal = GetMonData(&GetBattlerParty(battler)[gBattleStruct->wish[battler].partyId], MON_DATA_MAX_HP) / 2;
else
wishHeal = GetNonDynamaxMaxHP(battler) / 2;
@ -522,7 +522,7 @@ static bool32 HandleEndTurnBurn(enum BattlerId battler)
&& IsBattlerAlive(battler)
&& !IsAbilityAndRecord(battler, ability, ABILITY_MAGIC_GUARD))
{
s32 burnDamage = GetNonDynamaxMaxHP(battler) / ((GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7 || GetConfig(CONFIG_BURN_DAMAGE) == GEN_1) ? 16 : 8);
s32 burnDamage = GetNonDynamaxMaxHP(battler) / ((GetConfig(B_BURN_DAMAGE) >= GEN_7 || GetConfig(B_BURN_DAMAGE) == GEN_1) ? 16 : 8);
if (ability == ABILITY_HEATPROOF)
{
if (burnDamage > (burnDamage / 2) + 1) // Record ability if the burn takes less damage than it normally would.
@ -547,7 +547,7 @@ static bool32 HandleEndTurnFrostbite(enum BattlerId battler)
&& IsBattlerAlive(battler)
&& !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD))
{
SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / ((GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7 || GetConfig(CONFIG_BURN_DAMAGE) == GEN_1) ? 16 : 8));
SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / ((GetConfig(B_BURN_DAMAGE) >= GEN_7 || GetConfig(B_BURN_DAMAGE) == GEN_1) ? 16 : 8));
BattleScriptExecute(BattleScript_FrostbiteTurnDmg);
effect = TRUE;
}

View File

@ -701,9 +701,8 @@ void DecompressTrainerBackPic(enum TrainerPicID backPicId, enum BattlerId battle
{
enum BattlerPosition position = GetBattlerPosition(battler);
CopyTrainerBackspriteFramesToDest(backPicId, gMonSpritesGfxPtr->spritesGfx[position]);
// Aiming for palette slots 8 and 9 for Player and PlayerPartner to prevent Trainer Slides causing mons to change colour
LoadPalette(gTrainerBacksprites[backPicId].palette.data,
OBJ_PLTT_ID(8 + battler/2), PLTT_SIZE_4BPP);
OBJ_PLTT_ID(14 + battler / 2), PLTT_SIZE_4BPP);
}
void FreeTrainerFrontPicPalette(u16 frontPicId)

View File

@ -3038,9 +3038,9 @@ static void ClearSetBScriptingStruct(void)
gBattleScripting.windowsType = temp;
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
#if TESTING
gBattleScripting.battleStyle = OPTIONS_BATTLE_STYLE_SET;
gBattleScripting.battleStyle = OPTIONS_BATTLE_STYLE_SET;
#endif
gBattleScripting.expOnCatch = (GetConfig(CONFIG_EXP_CATCH) >= GEN_6);
gBattleScripting.expOnCatch = (GetConfig(B_EXP_CATCH) >= GEN_6);
gBattleScripting.specialTrainerBattleType = specialBattleType;
}
@ -3381,6 +3381,9 @@ const u8* FaintClearSetData(enum BattlerId battler)
if (gBattleStruct->battlerState[battler].commanderSpecies != SPECIES_NONE)
{
enum BattlerId partner = BATTLE_PARTNER(battler);
// Clear commander state immediately so a replacement doesn't inherit it.
gBattleStruct->battlerState[battler].commanderSpecies = SPECIES_NONE;
gBattleMons[partner].volatiles.semiInvulnerable = STATE_NONE;
if (IsBattlerAlive(partner))
{
BtlController_EmitSpriteInvisibility(partner, B_COMM_TO_CONTROLLER, FALSE);
@ -4057,7 +4060,7 @@ u8 IsRunningFromBattleImpossible(enum BattlerId battler)
if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)
return BATTLE_RUN_SUCCESS;
if (GetConfig(CONFIG_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
if (GetConfig(B_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
return BATTLE_RUN_SUCCESS;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
return BATTLE_RUN_SUCCESS;
@ -4224,7 +4227,7 @@ static void HandleTurnActionSelectionState(void)
gBattleStruct->moveTarget[battler] = gBattleResources->bufferB[battler][3];
return;
}
else if (GetConfig(CONFIG_ENCORE_TARGET) < GEN_5 && gBattleMons[battler].volatiles.encoredMove != MOVE_NONE)
else if (GetConfig(B_ENCORE_TARGET) < GEN_5 && gBattleMons[battler].volatiles.encoredMove != MOVE_NONE)
{
gChosenMoveByBattler[battler] = gBattleMons[battler].volatiles.encoredMove;
gBattleStruct->chosenMovePositions[battler] = gBattleMons[battler].volatiles.encoredMovePos;
@ -4781,7 +4784,7 @@ u32 GetBattlerTotalSpeedStat(enum BattlerId battler, enum Ability ability, enum
// paralysis drop
if (gBattleMons[battler].status1 & STATUS1_PARALYSIS && ability != ABILITY_QUICK_FEET)
speed /= GetConfig(CONFIG_PARALYSIS_SPEED) >= GEN_7 ? 2 : 4;
speed /= GetConfig(B_PARALYSIS_SPEED) >= GEN_7 ? 2 : 4;
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SWAMP)
speed /= 4;
@ -4820,7 +4823,7 @@ s32 GetBattleMovePriority(enum BattlerId battler, enum Ability ability, enum Mov
priority = -8;
}
else if (ability == ABILITY_GALE_WINGS
&& (GetConfig(CONFIG_GALE_WINGS) < GEN_7 || IsBattlerAtMaxHp(battler))
&& (GetConfig(B_GALE_WINGS) < GEN_7 || IsBattlerAtMaxHp(battler))
&& GetMoveType(move) == TYPE_FLYING)
{
priority++;
@ -5176,7 +5179,7 @@ static bool32 TryDoGimmicksBeforeMoves(void)
}
}
if (GetConfig(CONFIG_MEGA_EVO_TURN_ORDER) >= GEN_7)
if (GetConfig(B_MEGA_EVO_TURN_ORDER) >= GEN_7)
TryChangeTurnOrder(); // This will just do nothing if no mon has mega evolved.
return FALSE;
}

View File

@ -257,7 +257,7 @@ static enum CancelerResult CancelerTruant(struct BattleContext *ctx)
static enum CancelerResult CancelerFocus(struct BattleContext *ctx)
{
u32 focusPunchFailureConfig = GetConfig(CONFIG_FOCUS_PUNCH_FAILURE);
u32 focusPunchFailureConfig = GetConfig(B_FOCUS_PUNCH_FAILURE);
// In Gens 3-4, only check if is using Focus Punch.
// In Gens 5-6, only check if the chosen move is Focus Punch.
@ -276,14 +276,14 @@ static enum CancelerResult CancelerFocus(struct BattleContext *ctx)
static enum CancelerResult CancelerFocusPreGen5(struct BattleContext *ctx)
{
if (GetConfig(CONFIG_FOCUS_PUNCH_FAILURE) < GEN_5)
if (GetConfig(B_FOCUS_PUNCH_FAILURE) < GEN_5)
return CancelerFocus(ctx);
return CANCELER_RESULT_SUCCESS;
}
static enum CancelerResult CancelerFocusGen5(struct BattleContext *ctx)
{
if (GetConfig(CONFIG_FOCUS_PUNCH_FAILURE) >= GEN_5)
if (GetConfig(B_FOCUS_PUNCH_FAILURE) >= GEN_5)
return CancelerFocus(ctx);
return CANCELER_RESULT_SUCCESS;
}
@ -342,7 +342,10 @@ static enum CancelerResult CancelerVolatileBlocked(struct BattleContext *ctx)
static enum CancelerResult CancelerTaunted(struct BattleContext *ctx)
{
if (GetActiveGimmick(ctx->battlerAtk) != GIMMICK_Z_MOVE && gBattleMons[ctx->battlerAtk].volatiles.tauntTimer && IsBattleMoveStatus(ctx->move))
if (GetActiveGimmick(ctx->battlerAtk) != GIMMICK_Z_MOVE
&& gBattleMons[ctx->battlerAtk].volatiles.tauntTimer
&& IsBattleMoveStatus(ctx->move)
&& (GetConfig(B_TAUNT_ME_FIRST) < GEN_5 || GetMoveEffect(ctx->move) != EFFECT_ME_FIRST))
{
CancelMultiTurnMoves(ctx->battlerAtk, SKY_DROP_ATTACKCANCELER_CHECK);
gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted;
@ -371,7 +374,7 @@ static enum CancelerResult CancelerConfused(struct BattleContext *ctx)
if (gBattleMons[ctx->battlerAtk].volatiles.confusionTurns)
{
// confusion dmg
if (RandomPercentage(RNG_CONFUSION, (GetConfig(CONFIG_CONFUSION_SELF_DMG_CHANCE) >= GEN_7 ? 33 : 50)))
if (RandomPercentage(RNG_CONFUSION, (GetConfig(B_CONFUSION_SELF_DMG_CHANCE) >= GEN_7 ? 33 : 50)))
{
gBattleCommunication[MULTISTRING_CHOOSER] = TRUE;
gBattlerTarget = gBattlerAttacker;
@ -1019,7 +1022,7 @@ static enum CancelerResult CancelerWeatherPrimal(struct BattleContext *ctx)
if (GetMovePower(ctx->move) > 0 && HasWeatherEffect())
{
enum Type moveType = GetBattleMoveType(ctx->move);
if (moveType == TYPE_FIRE && gBattleWeather & B_WEATHER_RAIN_PRIMAL && (GetConfig(CONFIG_POWDER_STATUS_HEAVY_RAIN) >= GEN_7 || !TryActivatePowderStatus(ctx->move)))
if (moveType == TYPE_FIRE && gBattleWeather & B_WEATHER_RAIN_PRIMAL && (GetConfig(B_POWDER_STATUS_HEAVY_RAIN) >= GEN_7 || !TryActivatePowderStatus(ctx->move)))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN;
result = CANCELER_RESULT_FAILURE;
@ -1046,7 +1049,7 @@ static bool32 ShouldSkipFailureCheckOnBattler(enum BattlerId battlerAtk, enum Ba
return TRUE;
if (checkResultFlag && gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT)
return TRUE;
if (GetConfig(CONFIG_CHECK_USER_FAILURE) >= GEN_5 && battlerAtk == battlerDef)
if (GetConfig(B_CHECK_USER_FAILURE) >= GEN_5 && battlerAtk == battlerDef)
return TRUE;
return FALSE;
}
@ -1116,12 +1119,12 @@ static enum CancelerResult CancelerMoveFailure(struct BattleContext *ctx)
// Counter / Metal Burst and took physical damage
else if (reflectCategory == DAMAGE_CATEGORY_PHYSICAL
&& gProtectStructs[ctx->battlerAtk].physicalDmg > 0
&& (GetConfig(CONFIG_COUNTER_TRY_HIT_PARTNER) >= GEN_5 || gBattleMons[gProtectStructs[ctx->battlerAtk].physicalBattlerId].hp))
&& (GetConfig(B_COUNTER_TRY_HIT_PARTNER) >= GEN_5 || gBattleMons[gProtectStructs[ctx->battlerAtk].physicalBattlerId].hp))
break;
// Mirror Coat / Metal Burst and took special damage
else if (reflectCategory == DAMAGE_CATEGORY_SPECIAL
&& gProtectStructs[ctx->battlerAtk].specialDmg > 0
&& (GetConfig(CONFIG_COUNTER_TRY_HIT_PARTNER) >= GEN_5 || gBattleMons[gProtectStructs[ctx->battlerAtk].specialBattlerId].hp))
&& (GetConfig(B_COUNTER_TRY_HIT_PARTNER) >= GEN_5 || gBattleMons[gProtectStructs[ctx->battlerAtk].specialBattlerId].hp))
break;
else
battleScript = BattleScript_ButItFailed;
@ -1162,8 +1165,8 @@ static enum CancelerResult CancelerMoveFailure(struct BattleContext *ctx)
{
enum ProtectMethod protectMethod = GetMoveProtectMethod(ctx->move);
bool32 canUseProtectSecondTime = CanUseMoveConsecutively(ctx->battlerAtk);
bool32 canUseWideGuard = (GetConfig(CONFIG_WIDE_GUARD) >= GEN_6 && protectMethod == PROTECT_WIDE_GUARD);
bool32 canUseQuickGuard = (GetConfig(CONFIG_QUICK_GUARD) >= GEN_6 && protectMethod == PROTECT_QUICK_GUARD);
bool32 canUseWideGuard = (GetConfig(B_WIDE_GUARD) >= GEN_6 && protectMethod == PROTECT_WIDE_GUARD);
bool32 canUseQuickGuard = (GetConfig(B_QUICK_GUARD) >= GEN_6 && protectMethod == PROTECT_QUICK_GUARD);
if (!canUseProtectSecondTime
&& !canUseWideGuard
@ -1411,7 +1414,7 @@ static enum CancelerResult CancelerProtean(struct BattleContext *ctx)
enum Type moveType = GetBattleMoveType(ctx->move);
if (ProteanTryChangeType(ctx->battlerAtk, ctx->abilityAtk, ctx->move, moveType))
{
if (GetConfig(CONFIG_PROTEAN_LIBERO) >= GEN_9)
if (GetConfig(B_PROTEAN_LIBERO) >= GEN_9)
gBattleMons[ctx->battlerAtk].volatiles.usedProteanLibero = TRUE;
PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
gBattlerAbility = ctx->battlerAtk;
@ -1856,7 +1859,7 @@ static void SetRandomMultiHitCounter()
{
if (GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_LOADED_DICE)
gMultiHitCounter = RandomUniform(RNG_LOADED_DICE, 4, 5);
else if (GetConfig(CONFIG_MULTI_HIT_CHANCE) >= GEN_5)
else if (GetConfig(B_MULTI_HIT_CHANCE) >= GEN_5)
gMultiHitCounter = RandomWeighted(RNG_HITS, 0, 0, 7, 7, 3, 3); // 35%: 2 hits, 35%: 3 hits, 15% 4 hits, 15% 5 hits.
else
gMultiHitCounter = RandomWeighted(RNG_HITS, 0, 0, 3, 3, 1, 1); // 37.5%: 2 hits, 37.5%: 3 hits, 12.5% 4 hits, 12.5% 5 hits.
@ -1919,7 +1922,7 @@ static enum CancelerResult CancelerMultihitMoves(struct BattleContext *ctx)
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& !GetMonData(&party[i], MON_DATA_STATUS))
{
if (GetConfig(CONFIG_BEAT_UP) >= GEN_5)
if (GetConfig(B_BEAT_UP) >= GEN_5)
gBattleStruct->beatUpSpecies[gMultiHitCounter] = species;
else
gBattleStruct->beatUpSpecies[gMultiHitCounter] = i;
@ -2114,13 +2117,13 @@ static void SetHealScript(s32 healAmount)
{
healAmount = GetDrainedBigRootHp(gBattlerAttacker, healAmount);
if (GetBattlerAbility(gBattlerTarget) == ABILITY_LIQUID_OOZE
&& (GetMoveEffect(gCurrentMove) != EFFECT_DREAM_EATER || GetConfig(CONFIG_DREAM_EATER_LIQUID_OOZE) >= GEN_5))
&& (GetMoveEffect(gCurrentMove) != EFFECT_DREAM_EATER || GetConfig(B_DREAM_EATER_LIQUID_OOZE) >= GEN_5))
{
SetPassiveDamageAmount(gBattlerAttacker, healAmount);
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB_OOZE;
BattleScriptCall(BattleScript_EffectAbsorbLiquidOoze);
}
else if (!IsBattlerAtMaxHp(gBattlerAttacker) || GetConfig(CONFIG_ABSORB_MESSAGE) < GEN_5)
else if (!IsBattlerAtMaxHp(gBattlerAttacker) || GetConfig(B_ABSORB_MESSAGE) < GEN_5)
{
SetHealAmount(gBattlerAttacker, healAmount);
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB;
@ -2398,7 +2401,7 @@ static enum MoveEndResult MoveEndSymbiosis(void)
for (enum BattlerId battler = 0; battler < gBattlersCount; battler++)
{
if ((gSpecialStatuses[battler].berryReduced
|| (GetConfig(CONFIG_SYMBIOSIS_GEMS) >= GEN_7 && gSpecialStatuses[battler].gemBoost))
|| (GetConfig(B_SYMBIOSIS_GEMS) >= GEN_7 && gSpecialStatuses[battler].gemBoost))
&& TryTriggerSymbiosis(battler, BATTLE_PARTNER(battler)))
{
BestowItem(BATTLE_PARTNER(battler), battler);
@ -2842,7 +2845,7 @@ static enum MoveEndResult MoveEndDefrost(void)
if (battler == gBattlerAttacker)
continue;
if (gBattleMons[battler].status1 & STATUS1_FREEZE
&& IsBattlerTurnDamaged(battler)
&& IsBattlerAlive(battler)
@ -2970,7 +2973,7 @@ static enum MoveEndResult MoveEndMoveBlock(void)
{
StealTargetItem(gBattlerAttacker, gBattlerTarget); // Attacker steals target item
if (!(GetConfig(CONFIG_STEAL_WILD_ITEMS) >= GEN_9
if (!(GetConfig(B_STEAL_WILD_ITEMS) >= GEN_9
&& !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))))
{
gBattleMons[gBattlerAttacker].item = gLastUsedItem;
@ -3101,7 +3104,7 @@ static enum MoveEndResult MoveEndMoveBlock(void)
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattlerAttacker, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerAttacker)))
{
SET_STATCHANGER(STAT_ATK, GetConfig(CONFIG_FELL_STINGER_STAT_RAISE) >= GEN_7 ? 3 : 2, FALSE);
SET_STATCHANGER(STAT_ATK, GetConfig(B_FELL_STINGER_STAT_RAISE) >= GEN_7 ? 3 : 2, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_FellStingerRaisesStat;

View File

@ -862,7 +862,7 @@ static bool8 DoesTypePreventStatus(u16 species, u32 status)
break;
case STATUS1_PARALYSIS:
if (GetSpeciesType(species, 0) == TYPE_GROUND || GetSpeciesType(species, 1) == TYPE_GROUND
|| (GetConfig(CONFIG_PARALYZE_ELECTRIC) >= GEN_6 && (GetSpeciesType(species, 0) == TYPE_ELECTRIC || GetSpeciesType(species, 1) == TYPE_ELECTRIC)))
|| (GetConfig(B_PARALYZE_ELECTRIC) >= GEN_6 && (GetSpeciesType(species, 0) == TYPE_ELECTRIC || GetSpeciesType(species, 1) == TYPE_ELECTRIC)))
ret = TRUE;
break;
case STATUS1_BURN:

View File

@ -1776,8 +1776,7 @@ static void MoveDamageDataHpUpdate(enum BattlerId battler, u32 scriptBattler, co
}
return;
}
else if (DoesDisguiseBlockMove(battler, gCurrentMove)
|| DoesIceFaceBlockMove(battler, gCurrentMove))
else if (DoesDisguiseBlockMove(battler, gCurrentMove) || DoesIceFaceBlockMove(battler, gCurrentMove))
{
// Damage deals typeless 0 HP.
gBattleStruct->moveResultFlags[battler] &= ~(MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE);
@ -1826,9 +1825,9 @@ static void MoveDamageDataHpUpdate(enum BattlerId battler, u32 scriptBattler, co
// Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat,
// they are used in combination as general damage trackers for other purposes.
if (GetConfig(CONFIG_COUNTER_MIRROR_COAT_ALLY) <= GEN_4 || !IsBattlerAlly(battler, gBattlerAttacker))
if (GetConfig(B_COUNTER_MIRROR_COAT_ALLY) <= GEN_4 || !IsBattlerAlly(battler, gBattlerAttacker))
{
if (IsBattleMovePhysical(gCurrentMove) || ((GetConfig(CONFIG_HIDDEN_POWER_COUNTER) < GEN_4) && GetMoveEffect(gCurrentMove) == EFFECT_HIDDEN_POWER))
if (IsBattleMovePhysical(gCurrentMove) || ((GetConfig(B_HIDDEN_POWER_COUNTER) < GEN_4) && GetMoveEffect(gCurrentMove) == EFFECT_HIDDEN_POWER))
{
gProtectStructs[battler].physicalDmg = gBattleStruct->moveDamage[battler] + 1;
gProtectStructs[battler].physicalBattlerId = gBattlerAttacker;
@ -2216,7 +2215,7 @@ void StealTargetItem(enum BattlerId battlerStealer, enum BattlerId itemBattler)
gLastUsedItem = gBattleMons[itemBattler].item;
gBattleMons[itemBattler].item = ITEM_NONE;
if (GetConfig(CONFIG_STEAL_WILD_ITEMS) >= GEN_9
if (GetConfig(B_STEAL_WILD_ITEMS) >= GEN_9
&& !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))
&& GetMoveEffect(gCurrentMove) == EFFECT_STEAL_ITEM
&& battlerStealer == gBattlerAttacker) // ensure that Pickpocket isn't activating this
@ -2427,7 +2426,9 @@ void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum
case MOVE_EFFECT_TOXIC:
case MOVE_EFFECT_FROSTBITE:
if (IsSafeguardProtected(gBattlerAttacker, gEffectBattler, GetBattlerAbility(gBattlerAttacker)) && !primary)
{
gBattlescriptCurrInstr = battleScript;
}
else if (CanSetNonVolatileStatus(
gBattlerAttacker,
gEffectBattler,
@ -2435,7 +2436,13 @@ void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum
abilities[gBattlerTarget],
moveEffect,
CHECK_TRIGGER))
{
SetNonVolatileStatus(gEffectBattler, moveEffect, battleScript, TRIGGER_ON_MOVE);
}
else
{
gBattlescriptCurrInstr = battleScript;
}
break;
case MOVE_EFFECT_CONFUSION:
if (!CanBeConfused(gEffectBattler)
@ -2828,8 +2835,11 @@ void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum
}
break;
case MOVE_EFFECT_THROAT_CHOP:
gBattleMons[gEffectBattler].volatiles.throatChopTimer = B_THROAT_CHOP_TIMER;
gBattlescriptCurrInstr = battleScript;
if (gBattleMons[gEffectBattler].volatiles.throatChopTimer == 0)
{
gBattleMons[gEffectBattler].volatiles.throatChopTimer = B_THROAT_CHOP_TIMER;
gBattlescriptCurrInstr = battleScript;
}
break;
case MOVE_EFFECT_INCINERATE:
if (((gBattleMons[gEffectBattler].item >= FIRST_BERRY_INDEX && gBattleMons[gEffectBattler].item <= LAST_BERRY_INDEX)
@ -3540,7 +3550,7 @@ void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum
}
break;
case MOVE_EFFECT_BEAT_UP_MESSAGE:
if (GetConfig(CONFIG_BEAT_UP) >= GEN_5) // Gen5+ don't print any custom message on attack
if (GetConfig(B_BEAT_UP) >= GEN_5) // Gen5+ don't print any custom message on attack
break;
if (!IsBattlerAlive(gBattlerTarget))
@ -3713,7 +3723,8 @@ static void Cmd_seteffectprimary(void)
enum BattlerId battler = GetBattlerForBattleScript(cmd->battler);
enum BattlerId effectBattler = GetBattlerForBattleScript(cmd->effectBattler);
SetMoveEffect(battler, effectBattler, gBattleScripting.moveEffect, cmd->nextInstr, EFFECT_PRIMARY);
gBattlescriptCurrInstr = cmd->nextInstr;
SetMoveEffect(battler, effectBattler, gBattleScripting.moveEffect, gBattlescriptCurrInstr, EFFECT_PRIMARY);
}
static void Cmd_seteffectsecondary(void)
@ -3722,7 +3733,8 @@ static void Cmd_seteffectsecondary(void)
enum BattlerId battler = GetBattlerForBattleScript(cmd->battler);
enum BattlerId effectBattler = GetBattlerForBattleScript(cmd->effectBattler);
SetMoveEffect(battler, effectBattler, gBattleScripting.moveEffect, cmd->nextInstr, EFFECT_PRIMARY);
gBattlescriptCurrInstr = cmd->nextInstr;
SetMoveEffect(battler, effectBattler, gBattleScripting.moveEffect, gBattlescriptCurrInstr, NO_FLAGS);
}
static void Cmd_clearvolatile(void)
@ -3900,7 +3912,7 @@ static void Cmd_jumpifability(void)
}
break;
case BS_TARGET_SIDE:
battler = IsAbilityOnOpposingSide(gBattlerAttacker, ability);
battler = IsAbilityOnSide(gBattlerTarget, ability);
if (battler)
{
battler--;
@ -4864,7 +4876,7 @@ static void Cmd_tryselfconfusiondmgformchange(void)
switch (ability)
{
case ABILITY_DISGUISE:
if (GetConfig(CONFIG_DISGUISE_HP_LOSS) >= GEN_8 && wasDisguised)
if (GetConfig(B_DISGUISE_HP_LOSS) >= GEN_8 && wasDisguised)
SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 8);
BattleScriptPush(BattleScript_MoveEnd);
gBattlescriptCurrInstr = BattleScript_BattlerFormChangeDisguise;
@ -7042,7 +7054,7 @@ static bool32 TryDefogClear(enum BattlerId battlerAtk, bool32 clear)
DEFOG_CLEAR(SIDE_STATUS_AURORA_VEIL, auroraVeilTimer, BattleScript_SideStatusWoreOffReturn, MOVE_AURORA_VEIL);
DEFOG_CLEAR(SIDE_STATUS_SAFEGUARD, safeguardTimer, BattleScript_SideStatusWoreOffReturn, MOVE_SAFEGUARD);
}
if (GetConfig(CONFIG_DEFOG_EFFECT_CLEARING) >= GEN_6)
if (GetConfig(B_DEFOG_EFFECT_CLEARING) >= GEN_6)
{
gBattlerAttacker = i; // For correct battle string. Ally's / Foe's
if (DefogClearHazards(saveBattler, i, clear))
@ -7057,7 +7069,7 @@ static bool32 TryDefogClear(enum BattlerId battlerAtk, bool32 clear)
}
return TRUE;
}
if (GetConfig(CONFIG_DEFOG_EFFECT_CLEARING) >= GEN_8 && (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY))
if (GetConfig(B_DEFOG_EFFECT_CLEARING) >= GEN_8 && (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY))
{
if (clear)
{
@ -7594,7 +7606,7 @@ static void TryPlayStatChangeAnimation(enum BattlerId battler, enum Ability abil
}
}
else if (!((ability == ABILITY_KEEN_EYE || ability == ABILITY_MINDS_EYE) && currStat == STAT_ACC)
&& !(GetConfig(CONFIG_ILLUMINATE_EFFECT) >= GEN_9 && ability == ABILITY_ILLUMINATE && currStat == STAT_ACC)
&& !(GetConfig(B_ILLUMINATE_EFFECT) >= GEN_9 && ability == ABILITY_ILLUMINATE && currStat == STAT_ACC)
&& !(ability == ABILITY_HYPER_CUTTER && currStat == STAT_ATK)
&& !(ability == ABILITY_BIG_PECKS && currStat == STAT_DEF))
{
@ -7759,7 +7771,7 @@ static u32 ChangeStatBuffs(enum BattlerId battler, s8 statValue, enum Stat statI
}
else if (!flags.certain
&& (((battlerAbility == ABILITY_KEEN_EYE || battlerAbility == ABILITY_MINDS_EYE) && statId == STAT_ACC)
|| (GetConfig(CONFIG_ILLUMINATE_EFFECT) >= GEN_9 && battlerAbility == ABILITY_ILLUMINATE && statId == STAT_ACC)
|| (GetConfig(B_ILLUMINATE_EFFECT) >= GEN_9 && battlerAbility == ABILITY_ILLUMINATE && statId == STAT_ACC)
|| (battlerAbility == ABILITY_HYPER_CUTTER && statId == STAT_ATK)
|| (battlerAbility == ABILITY_BIG_PECKS && statId == STAT_DEF)))
{
@ -8486,8 +8498,8 @@ static void Cmd_setfocusenergy(void)
}
else
{
if (GetConfig(CONFIG_FOCUS_ENERGY_CRIT_RATIO) >= GEN_3
|| GetConfig(CONFIG_CRIT_CHANCE) == GEN_1)
if (GetConfig(B_FOCUS_ENERGY_CRIT_RATIO) >= GEN_3
|| GetConfig(B_CRIT_CHANCE) == GEN_1)
gBattleMons[battler].volatiles.focusEnergy = TRUE;
else
gBattleMons[battler].volatiles.dragonCheer = TRUE;
@ -8502,10 +8514,11 @@ static void Cmd_transformdataexecution(void)
gChosenMove = MOVE_UNAVAILABLE;
gBattlescriptCurrInstr = cmd->nextInstr;
if (gBattleMons[gBattlerTarget].volatiles.transformed
|| DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)
|| gBattleStruct->illusion[gBattlerTarget].state == ILLUSION_ON
|| IsSemiInvulnerable(gBattlerTarget, EXCLUDE_COMMANDER))
if ((GetConfig(B_TRANSFORM_SEMI_INV_FAIL) >= GEN_2 && IsSemiInvulnerable(gBattlerTarget, EXCLUDE_COMMANDER))
|| (GetConfig(B_TRANSFORM_TARGET_FAIL) >= GEN_2 && gBattleMons[gBattlerTarget].volatiles.transformed)
|| (GetConfig(B_TRANSFORM_USER_FAIL) >= GEN_5 && gBattleMons[gBattlerAttacker].volatiles.transformed)
|| (GetConfig(B_TRANSFORM_SUBSTITUTE_FAIL) >= GEN_5 && DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
|| gBattleStruct->illusion[gBattlerTarget].state == ILLUSION_ON)
{
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FAILED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TRANSFORM_FAILED;
@ -8757,7 +8770,7 @@ static void Cmd_settypetorandomresistance(void)
enum Move moveToCheck;
enum Type typeToCheck;
if (GetConfig(CONFIG_UPDATED_CONVERSION_2) < GEN_5)
if (GetConfig(B_UPDATED_CONVERSION_2) < GEN_5)
{
moveToCheck = gLastLandedMoves[gBattlerAttacker];
if (GetMoveEffect(moveToCheck) == EFFECT_STRUGGLE)
@ -8907,7 +8920,7 @@ static void Cmd_settailwind(void)
if (!(gSideStatuses[side] & SIDE_STATUS_TAILWIND))
{
gSideStatuses[side] |= SIDE_STATUS_TAILWIND;
gSideTimers[side].tailwindTimer = (GetConfig(CONFIG_TAILWIND_TURNS) >= GEN_5 ? 4 : 3);
gSideTimers[side].tailwindTimer = (GetConfig(B_TAILWIND_TURNS) >= GEN_5 ? 4 : 3);
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
@ -8997,8 +9010,8 @@ static void Cmd_healpartystatus(void)
struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
bool32 isSoundMove = IsSoundMove(gCurrentMove);
if (GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5
|| GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) >= GEN_8
if (GetConfig(B_HEAL_BELL_SOUNDPROOF) == GEN_5
|| GetConfig(B_HEAL_BELL_SOUNDPROOF) >= GEN_8
|| !(isSoundMove && GetBattlerAbility(gBattlerAttacker) == ABILITY_SOUNDPROOF))
{
if (isSoundMove)
@ -9018,7 +9031,7 @@ static void Cmd_healpartystatus(void)
if (IsBattlerAlive(partner))
{
if (GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5
if (GetConfig(B_HEAL_BELL_SOUNDPROOF) == GEN_5
|| !(isSoundMove && GetBattlerAbility(partner) == ABILITY_SOUNDPROOF))
{
gBattleMons[partner].status1 = 0;
@ -9044,10 +9057,10 @@ static void Cmd_healpartystatus(void)
bool32 isAttacker = gBattlerPartyIndexes[gBattlerAttacker] == i;
bool32 isDoublesPartner = gBattlerPartyIndexes[partner] == i && IsBattlerAlive(partner);
if (GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5
|| (GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) >= GEN_8 && isAttacker))
if (GetConfig(B_HEAL_BELL_SOUNDPROOF) == GEN_5
|| (GetConfig(B_HEAL_BELL_SOUNDPROOF) >= GEN_8 && isAttacker))
ability = ABILITY_NONE;
else if (GetConfig(CONFIG_HEAL_BELL_SOUNDPROOF) > GEN_5 && !isAttacker && !isDoublesPartner)
else if (GetConfig(B_HEAL_BELL_SOUNDPROOF) > GEN_5 && !isAttacker && !isDoublesPartner)
ability = ABILITY_NONE;
else if (isAttacker)
ability = GetBattlerAbility(gBattlerAttacker);
@ -9221,13 +9234,17 @@ static void Cmd_presentdamagecalculation(void)
{
gBattlescriptCurrInstr = BattleScript_HitFromDamageCalc;
}
else if (gBattlerTarget == BATTLE_PARTNER(gBattlerAttacker) && GetBattlerAbility(gBattlerTarget) == ABILITY_TELEPATHY)
{
gBattlescriptCurrInstr = BattleScript_MoveMissedPause;
}
else if (gBattleMons[gBattlerTarget].maxHP == gBattleMons[gBattlerTarget].hp)
{
gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp;
}
else
{
gBattleStruct->moveResultFlags[gBattlerTarget] &= ~MOVE_RESULT_DOESNT_AFFECT_FOE;
gBattleStruct->moveResultFlags[gBattlerTarget] &= ~(MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE);
gBattlescriptCurrInstr = BattleScript_PresentHealTarget;
}
}
@ -9334,7 +9351,7 @@ static void Cmd_copyfoestats(void)
{
gBattleMons[gBattlerAttacker].statStages[i] = gBattleMons[gBattlerTarget].statStages[i];
}
if (GetConfig(CONFIG_PSYCH_UP_CRIT_RATIO) >= GEN_6)
if (GetConfig(B_PSYCH_UP_CRIT_RATIO) >= GEN_6)
{
// Copy crit boosts (Focus Energy, Dragon Cheer, G-Max Chi Strike)
gBattleMons[gBattlerAttacker].volatiles.focusEnergy = gBattleMons[gBattlerTarget].volatiles.focusEnergy;
@ -9400,7 +9417,7 @@ static void Cmd_recoverbasedonsunlight(void)
else
recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
}
else if (GetConfig(CONFIG_TIME_OF_DAY_HEALING_MOVES) != GEN_2)
else if (GetConfig(B_TIME_OF_DAY_HEALING_MOVES) != GEN_2)
{
if (!(gBattleWeather & B_WEATHER_ANY) || !HasWeatherEffect() || GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA)
recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
@ -9609,7 +9626,7 @@ static void Cmd_settaunt(void)
{
CMD_ARGS(const u8 *failInstr);
if (GetConfig(CONFIG_OBLIVIOUS_TAUNT) >= GEN_6 && GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS)
if (GetConfig(B_OBLIVIOUS_TAUNT) >= GEN_6 && GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS)
{
gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp;
gLastUsedAbility = ABILITY_OBLIVIOUS;
@ -9739,7 +9756,7 @@ static void Cmd_tryswapitems(void)
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_GORILLA_TACTICS
&& (!IsHoldEffectChoice(GetItemHoldEffect(oldItemDef))
|| (GetConfig(CONFIG_MODERN_TRICK_CHOICE_LOCK) >= GEN_5)))
|| (GetConfig(B_MODERN_TRICK_CHOICE_LOCK) >= GEN_5)))
{
gBattleStruct->choicedMove[gBattlerAttacker] = MOVE_NONE;
}
@ -10311,7 +10328,7 @@ bool32 DoesSubstituteBlockMove(enum BattlerId battlerAtk, enum BattlerId battler
return FALSE;
else if (MoveIgnoresSubstitute(move))
return FALSE;
else if (GetConfig(CONFIG_INFILTRATOR_SUBSTITUTE) < GEN_6)
else if (GetConfig(B_INFILTRATOR_SUBSTITUTE) < GEN_6)
return TRUE;
else if (GetMoveEffect(move) == EFFECT_TRANSFORM || GetMoveEffect(move) == EFFECT_SKY_DROP)
return TRUE;
@ -10476,7 +10493,7 @@ static void FinalizeCapture(void)
{
u32 ballId = ItemIdToBallId(gLastThrownBall);
enum NationalDexOrder natDexNo = SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species);
if (GetConfig(CONFIG_CRITICAL_CAPTURE_IF_OWNED) >= GEN_9 && GetSetPokedexFlag(natDexNo, FLAG_GET_CAUGHT))
if (GetConfig(B_CRITICAL_CAPTURE_IF_OWNED) >= GEN_9 && GetSetPokedexFlag(natDexNo, FLAG_GET_CAUGHT))
{
gBattleSpritesDataPtr->animationData->isCriticalCapture = TRUE;
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = TRUE;
@ -10747,22 +10764,22 @@ static u32 ComputeCaptureOdds(u32 wildMonBattler, u32 playerBattler)
if (FlagGet(i))
badgeCount++;
}
if (GetConfig(CONFIG_MISSING_BADGE_CATCH_MALUS) == GEN_8 && badgeCount < NUM_BADGES && gBattleMons[playerBattler].level < battleMon->level)
if (GetConfig(B_MISSING_BADGE_CATCH_MALUS) == GEN_8 && badgeCount < NUM_BADGES && gBattleMons[playerBattler].level < battleMon->level)
odds = odds * 410 / 4096;
if (GetConfig(CONFIG_MISSING_BADGE_CATCH_MALUS) == GEN_9 && badgeCount < NUM_BADGES)
if (GetConfig(B_MISSING_BADGE_CATCH_MALUS) == GEN_9 && badgeCount < NUM_BADGES)
{
for (u32 i = badgeCount; i < NUM_BADGES && battleMon->level > sBadgeLevel[i]; i++)
odds = odds * 4 / 5;
}
if (GetConfig(CONFIG_LOW_LEVEL_CATCH_BONUS) == GEN_8 && battleMon->level <= 20)
if (GetConfig(B_LOW_LEVEL_CATCH_BONUS) == GEN_8 && battleMon->level <= 20)
odds = odds * (30 - battleMon->level) / 10;
else if (GetConfig(CONFIG_LOW_LEVEL_CATCH_BONUS) >= GEN_9 && battleMon->level <= 13)
else if (GetConfig(B_LOW_LEVEL_CATCH_BONUS) >= GEN_9 && battleMon->level <= 13)
odds = odds * (36 - (battleMon->level * 2)) / 10;
if (battleMon->status1 & STATUS1_INCAPACITATED)
{
if (GetConfig(CONFIG_INCAPACITATED_CATCH_BONUS) >= GEN_5)
if (GetConfig(B_INCAPACITATED_CATCH_BONUS) >= GEN_5)
odds = (odds * 25) / 10;
else
odds *= 2;
@ -11639,7 +11656,7 @@ bool32 CanBurnHitThaw(enum Ability abilityAtk, enum Move move)
{
u8 i;
if (GetConfig(CONFIG_BURN_HIT_THAW) >= GEN_6 && abilityAtk != ABILITY_SHEER_FORCE)
if (GetConfig(B_BURN_HIT_THAW) >= GEN_6 && abilityAtk != ABILITY_SHEER_FORCE)
{
u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
for (i = 0; i < numAdditionalEffects; i++)
@ -12435,7 +12452,7 @@ void BS_TryAllySwitch(void)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else if (GetConfig(CONFIG_ALLY_SWITCH_FAIL_CHANCE) >= GEN_9)
else if (GetConfig(B_ALLY_SWITCH_FAIL_CHANCE) >= GEN_9)
{
TryResetConsecutiveUseCounter(gBattlerAttacker);
@ -13153,7 +13170,7 @@ void BS_JumpIfIntimidateAbilityPrevented(void)
case ABILITY_SCRAPPY:
case ABILITY_OWN_TEMPO:
case ABILITY_OBLIVIOUS:
if (GetConfig(CONFIG_UPDATED_INTIMIDATE) >= GEN_8)
if (GetConfig(B_UPDATED_INTIMIDATE) >= GEN_8)
{
hasAbility = TRUE;
gBattlescriptCurrInstr = BattleScript_IntimidatePrevented;
@ -14097,12 +14114,28 @@ void BS_TryAutotomize(void)
}
}
static inline bool32 IsInstructBannedChargingMove(u32 battler)
{
enum BattleMoveEffects moveEffect;
if (gChosenActionByBattler[battler] != B_ACTION_USE_MOVE || HasBattlerActedThisTurn(battler))
return FALSE;
moveEffect = GetMoveEffect(gChosenMoveByBattler[battler]);
return moveEffect == EFFECT_FOCUS_PUNCH
|| moveEffect == EFFECT_BEAK_BLAST
|| moveEffect == EFFECT_SHELL_TRAP;
}
void BS_TryInstruct(void)
{
NATIVE_ARGS(const u8 *failInstr);
enum Move move = gLastPrintedMoves[gBattlerTarget];
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || MoveHasAdditionalEffectSelf(move, MOVE_EFFECT_RECHARGE)
|| IsMoveInstructBanned(move)
|| IsInstructBannedChargingMove(gBattlerTarget)
|| gBattleMons[gBattlerTarget].volatiles.bideTurns != 0
|| gBattleMons[gBattlerTarget].volatiles.semiInvulnerable == STATE_SKY_DROP
|| gBattleMoveEffects[GetMoveEffect(move)].twoTurnEffect
|| (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX)
|| IsZMove(move)
@ -14707,7 +14740,7 @@ void BS_JumpIfAbilityPreventsRest(void)
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
enum BattlerId battler = GetBattlerForBattleScript(cmd->battler);
u32 ability = GetBattlerAbility(battler);
if (GetConfig(CONFIG_LEAF_GUARD_PREVENTS_REST) >= GEN_5 && IsLeafGuardProtected(battler, ability))
if (GetConfig(B_LEAF_GUARD_PREVENTS_REST) >= GEN_5 && IsLeafGuardProtected(battler, ability))
gBattlescriptCurrInstr = cmd->jumpInstr;
else if (IsShieldsDownProtected(battler, ability))
gBattlescriptCurrInstr = cmd->jumpInstr;
@ -14793,7 +14826,7 @@ void BS_BattlerItemToLastUsedItem(void)
void BS_JumpIfGenConfigLowerThan(void)
{
NATIVE_ARGS(u16 tag, u8 gen, const u8 *jumpInstr);
if (GetConfig(cmd->tag) < cmd->gen)
if (GetConfigInternal(cmd->tag) < cmd->gen)
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;

View File

@ -1467,6 +1467,13 @@ static void CB2_EndTrainerBattle(void)
DowngradeBadPoison();
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
else if (DidPlayerForfeitNormalTrainerBattle())
{
if (FlagGet(B_FLAG_NO_WHITEOUT) || CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || InTrainerHillChallenge())
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
else
SetMainCallback2(CB2_WhiteOut);
}
else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || InTrainerHillChallenge() || (!NoAliveMonsForPlayer()) || FlagGet(B_FLAG_NO_WHITEOUT))
@ -1474,10 +1481,6 @@ static void CB2_EndTrainerBattle(void)
else
SetMainCallback2(CB2_WhiteOut);
}
else if (DidPlayerForfeitNormalTrainerBattle())
{
SetMainCallback2(CB2_WhiteOut);
}
else
{
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);

View File

@ -183,7 +183,7 @@ bool32 DoSwitchInEvents(void)
static bool32 CanBattlerBeHealed(enum BattlerId battler)
{
if (GetConfig(CONFIG_HEALING_WISH_SWITCH) < GEN_8)
if (GetConfig(B_HEALING_WISH_SWITCH) < GEN_8)
return TRUE;
if (gBattleMons[battler].hp != gBattleMons[battler].maxHP || gBattleMons[battler].status1)

View File

@ -399,7 +399,7 @@ void HandleAction_UseMove(void)
{
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].volatiles.encoredMove;
gCurrMovePos = gChosenMovePos = gBattleMons[gBattlerAttacker].volatiles.encoredMovePos;
if (GetConfig(CONFIG_ENCORE_TARGET) < GEN_5)
if (GetConfig(B_ENCORE_TARGET) < GEN_5)
gBattleStruct->moveTarget[gBattlerAttacker] = GetBattleMoveTarget(gCurrentMove, TARGET_NONE);
}
// check if the encored move wasn't overwritten
@ -564,7 +564,7 @@ bool32 TryRunFromBattle(enum BattlerId battler)
gProtectStructs[battler].fleeType = FLEE_ITEM;
effect++;
}
else if (GetConfig(CONFIG_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
else if (GetConfig(B_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
{
effect++;
}
@ -923,7 +923,7 @@ void HandleAction_ActionFinished(void)
gBattleResources->battleScriptsStack->size = 0;
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
if (GetConfig(CONFIG_RECALC_TURN_AFTER_ACTIONS) >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove && !IsPursuitTargetSet())
if (GetConfig(B_RECALC_TURN_AFTER_ACTIONS) >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove && !IsPursuitTargetSet())
{
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
// taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action
@ -1195,7 +1195,7 @@ bool32 ShouldDefiantCompetitiveActivate(enum BattlerId battler, enum Ability abi
if (IsBattlerAlly(gSpecialStatuses[battler].changedStatsBattlerId, battler) && !gBattleScripting.stickyWebStatDrop)
return FALSE;
if (GetConfig(CONFIG_DEFIANT_STICKY_WEB) >= GEN_9 || !gBattleScripting.stickyWebStatDrop)
if (GetConfig(B_DEFIANT_STICKY_WEB) >= GEN_9 || !gBattleScripting.stickyWebStatDrop)
return TRUE;
// only activate Defiant/Competitive if Web was setup by foe
return gSideTimers[side].stickyWebBattlerSide != side;
@ -1233,7 +1233,7 @@ void PrepareStringBattle(enum StringID stringId, enum BattlerId battler)
stringId = STRINGID_STATSWONTINCREASE2;
break;
case STRINGID_PKMNCUTSATTACKWITH:
if (GetConfig(CONFIG_UPDATED_INTIMIDATE) >= GEN_8
if (GetConfig(B_UPDATED_INTIMIDATE) >= GEN_8
&& targetAbility == ABILITY_RATTLED
&& CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, targetAbility))
{
@ -1392,7 +1392,7 @@ u32 TrySetCantSelectMoveBattleScript(enum BattlerId battler)
u16 *choicedMove = &gBattleStruct->choicedMove[battler];
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
if (GetConfig(CONFIG_ENCORE_TARGET) >= GEN_5
if (GetConfig(B_ENCORE_TARGET) >= GEN_5
&& DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && gBattleMons[battler].volatiles.encoredMove != move && gBattleMons[battler].volatiles.encoredMove != MOVE_NONE)
{
gBattleScripting.battler = battler;
@ -1441,7 +1441,10 @@ u32 TrySetCantSelectMoveBattleScript(enum BattlerId battler)
}
}
if (GetActiveGimmick(battler) != GIMMICK_Z_MOVE && gBattleMons[battler].volatiles.tauntTimer != 0 && IsBattleMoveStatus(move))
if (GetActiveGimmick(battler) != GIMMICK_Z_MOVE
&& gBattleMons[battler].volatiles.tauntTimer != 0
&& IsBattleMoveStatus(move)
&& (GetConfig(B_TAUNT_ME_FIRST) < GEN_5 || moveEffect != EFFECT_ME_FIRST))
{
if ((GetActiveGimmick(battler) == GIMMICK_DYNAMAX))
gCurrentMove = MOVE_MAX_GUARD;
@ -1676,7 +1679,10 @@ u32 CheckMoveLimitations(enum BattlerId battler, u8 unusableMoves, u16 check)
else if (check & MOVE_LIMITATION_TORMENTED && move == gLastMoves[battler] && gBattleMons[battler].volatiles.torment == TRUE)
unusableMoves |= 1u << i;
// Taunt
else if (check & MOVE_LIMITATION_TAUNT && gBattleMons[battler].volatiles.tauntTimer && IsBattleMoveStatus(move))
else if (check & MOVE_LIMITATION_TAUNT
&& gBattleMons[battler].volatiles.tauntTimer
&& IsBattleMoveStatus(move)
&& (GetConfig(B_TAUNT_ME_FIRST) < GEN_5 || moveEffect != EFFECT_ME_FIRST))
unusableMoves |= 1u << i;
// Imprison
else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battler, move))
@ -2104,7 +2110,7 @@ bool32 TryChangeBattleWeather(enum BattlerId battler, u32 battleWeatherId, enum
return FALSE;
}
if (GetConfig(CONFIG_ABILITY_WEATHER) < GEN_6 && ability != ABILITY_NONE)
if (GetConfig(B_ABILITY_WEATHER) < GEN_6 && ability != ABILITY_NONE)
{
gBattleWeather = sBattleWeatherInfo[battleWeatherId].flag;
}
@ -2440,11 +2446,11 @@ bool32 CanAbilityAbsorbMove(struct BattleContext *ctx)
battleScript = AbsorbedByStatIncreaseAbility(ctx->battlerDef, ctx->abilityDef, STAT_SPEED, 1);
break;
case ABILITY_LIGHTNING_ROD:
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && ctx->moveType == TYPE_ELECTRIC)
if (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && ctx->moveType == TYPE_ELECTRIC)
battleScript = AbsorbedByStatIncreaseAbility(ctx->battlerDef, ctx->abilityDef, STAT_SPATK, 1);
break;
case ABILITY_STORM_DRAIN:
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && ctx->moveType == TYPE_WATER)
if (GetConfig(B_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && ctx->moveType == TYPE_WATER)
battleScript = AbsorbedByStatIncreaseAbility(ctx->battlerDef, ctx->abilityDef, STAT_SPATK, 1);
break;
case ABILITY_SAP_SIPPER:
@ -3372,7 +3378,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
if (!shouldAbilityTrigger)
break;
{
u32 weather = (GetConfig(CONFIG_SNOW_WARNING) >= GEN_9 ? BATTLE_WEATHER_SNOW : BATTLE_WEATHER_HAIL);
u32 weather = (GetConfig(B_SNOW_WARNING) >= GEN_9 ? BATTLE_WEATHER_SNOW : BATTLE_WEATHER_HAIL);
if (TryChangeBattleWeather(battler, weather, gLastUsedAbility))
{
BattleScriptCall(BattleScript_WeatherAbilityActivates);
@ -3462,7 +3468,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
case ABILITY_INTREPID_SWORD:
if (shouldAbilityTrigger && !GetBattlerPartyState(battler)->intrepidSwordBoost)
{
if (GetConfig(CONFIG_INTREPID_SWORD) == GEN_9)
if (GetConfig(B_INTREPID_SWORD) == GEN_9)
GetBattlerPartyState(battler)->intrepidSwordBoost = TRUE;
if (CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
@ -3476,7 +3482,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
case ABILITY_DAUNTLESS_SHIELD:
if (shouldAbilityTrigger && !GetBattlerPartyState(battler)->dauntlessShieldBoost)
{
if (GetConfig(CONFIG_DAUNTLESS_SHIELD) == GEN_9)
if (GetConfig(B_DAUNTLESS_SHIELD) == GEN_9)
GetBattlerPartyState(battler)->dauntlessShieldBoost = TRUE;
if (CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
@ -3681,7 +3687,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
break;
case ABILITY_SHED_SKIN:
if ((gBattleMons[battler].status1 & STATUS1_ANY)
&& (GetConfig(CONFIG_ABILITY_TRIGGER_CHANCE) == GEN_4 ? RandomPercentage(RNG_SHED_SKIN, 30) : RandomChance(RNG_SHED_SKIN, 1, 3)))
&& (GetConfig(B_ABILITY_TRIGGER_CHANCE) == GEN_4 ? RandomPercentage(RNG_SHED_SKIN, 30) : RandomChance(RNG_SHED_SKIN, 1, 3)))
{
ABILITY_HEAL_MON_STATUS:
if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON))
@ -3722,7 +3728,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
if (gBattleStruct->battlerState[battler].isFirstTurn != 2)
{
u32 validToRaise = 0, validToLower = 0;
u32 statsNum = GetConfig(CONFIG_MOODY_ACC_EVASION) >= GEN_8 ? NUM_STATS : NUM_BATTLE_STATS;
u32 statsNum = GetConfig(B_MOODY_ACC_EVASION) >= GEN_8 ? NUM_STATS : NUM_BATTLE_STATS;
for (i = STAT_ATK; i < statsNum; i++)
{
@ -4074,7 +4080,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
{
u32 poison, paralysis, sleep;
if (GetConfig(CONFIG_ABILITY_TRIGGER_CHANCE) >= GEN_5)
if (GetConfig(B_ABILITY_TRIGGER_CHANCE) >= GEN_5)
{
poison = 9;
paralysis = 19;
@ -4086,7 +4092,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
}
sleep = 30;
i = RandomUniform(RNG_EFFECT_SPORE, 0, GetConfig(CONFIG_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? 99 : 299);
i = RandomUniform(RNG_EFFECT_SPORE, 0, GetConfig(B_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? 99 : 299);
if (i < poison)
goto POISON_POINT;
if (i < paralysis)
@ -4112,7 +4118,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
}
break;
case ABILITY_POISON_POINT:
if (GetConfig(CONFIG_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_POISON_POINT, 30) : RandomChance(RNG_POISON_POINT, 1, 3))
if (GetConfig(B_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_POISON_POINT, 30) : RandomChance(RNG_POISON_POINT, 1, 3))
{
POISON_POINT:
{
@ -4134,7 +4140,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
}
break;
case ABILITY_STATIC:
if (GetConfig(CONFIG_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_STATIC, 30) : RandomChance(RNG_STATIC, 1, 3))
if (GetConfig(B_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_STATIC, 30) : RandomChance(RNG_STATIC, 1, 3))
{
STATIC:
{
@ -4161,7 +4167,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
&& !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker), move)
&& IsBattlerTurnDamaged(gBattlerTarget)
&& CanBeBurned(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
&& (GetConfig(CONFIG_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_FLAME_BODY, 30) : RandomChance(RNG_FLAME_BODY, 1, 3)))
&& (GetConfig(B_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_FLAME_BODY, 30) : RandomChance(RNG_FLAME_BODY, 1, 3)))
{
gEffectBattler = gBattlerAttacker;
gBattleScripting.battler = gBattlerTarget;
@ -4176,7 +4182,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
&& !gBattleStruct->unableToUseMove
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& (GetConfig(CONFIG_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_CUTE_CHARM, 30) : RandomChance(RNG_CUTE_CHARM, 1, 3))
&& (GetConfig(B_ABILITY_TRIGGER_CHANCE) >= GEN_4 ? RandomPercentage(RNG_CUTE_CHARM, 30) : RandomChance(RNG_CUTE_CHARM, 1, 3))
&& !(gBattleMons[gBattlerAttacker].volatiles.infatuation)
&& AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget)
&& !IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_OBLIVIOUS)
@ -4314,7 +4320,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
if (IsBattlerAlive(gBattlerTarget)
&& !gBattleStruct->unableToUseMove
&& CanBePoisoned(gBattlerAttacker, gBattlerTarget, gLastUsedAbility, GetBattlerAbility(gBattlerTarget))
&& !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker), move)
&& IsMoveMakingContact(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker), move)
&& IsBattlerTurnDamaged(gBattlerTarget) // Need to actually hit the target
&& RandomPercentage(RNG_POISON_TOUCH, 30))
{
@ -4374,7 +4380,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
break;
gBattleScripting.abilityPopupOverwrite = ability;
gBattleScripting.battler = battler;
gBattleScripting.battler = gBattlerAbility = battler;
effect++;
switch (ability)
@ -4400,7 +4406,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
}
break;
case ABILITY_DISGUISE:
if (GetConfig(CONFIG_DISGUISE_HP_LOSS) >= GEN_8 && ability == ABILITY_DISGUISE)
if (GetConfig(B_DISGUISE_HP_LOSS) >= GEN_8 && ability == ABILITY_DISGUISE)
SetPassiveDamageAmount(gBattlerTarget, GetNonDynamaxMaxHP(gBattlerTarget) / 8);
BattleScriptCall(BattleScript_BattlerFormChangeDisguise);
break;
@ -4540,7 +4546,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
if (GetBattlerPartyState(battler)->battleBondBoost || gBattleMons[battler].species != SPECIES_GRENINJA_BATTLE_BOND)
break;
if (GetConfig(CONFIG_BATTLE_BOND) < GEN_9)
if (GetConfig(B_BATTLE_BOND) < GEN_9)
{
// Can't use TryBattleFormChange as we can't test form change const data changes.
gLastUsedAbility = ability;
@ -4616,7 +4622,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
RecordAbilityBattle(gBattlerTarget, ABILITY_SYNCHRONIZE);
if (GetConfig(CONFIG_SYNCHRONIZE_TOXIC) < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
if (GetConfig(B_SYNCHRONIZE_TOXIC) < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
if (CanSetNonVolatileStatus(
@ -4646,7 +4652,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum
gBattleScripting.battler = gBattlerAbility = gBattlerAttacker;
RecordAbilityBattle(gBattlerAttacker, ABILITY_SYNCHRONIZE);
if (GetConfig(CONFIG_SYNCHRONIZE_TOXIC) < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
if (GetConfig(B_SYNCHRONIZE_TOXIC) < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
if (CanSetNonVolatileStatus(
@ -5007,7 +5013,7 @@ u32 IsAbilityOnFieldExcept(enum BattlerId battler, enum Ability ability)
u32 IsAbilityPreventingEscape(enum BattlerId battler)
{
if (GetConfig(CONFIG_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
if (GetConfig(B_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
return 0;
bool32 isBattlerGrounded = IsBattlerGrounded(battler, GetBattlerAbility(battler), GetBattlerHoldEffect(battler));
@ -5035,7 +5041,7 @@ bool32 CanBattlerEscape(enum BattlerId battler) // no ability check
{
if (gBattleStruct->battlerState[battler].commanderSpecies != SPECIES_NONE)
return FALSE;
else if (GetConfig(CONFIG_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
else if (GetConfig(B_GHOSTS_ESCAPE) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
return TRUE;
else if (gBattleMons[battler].volatiles.escapePrevention)
return FALSE;
@ -5343,7 +5349,7 @@ bool32 CanSetNonVolatileStatus(enum BattlerId battlerAtk, enum BattlerId battler
{
battleScript = BattleScript_AlreadyParalyzed;
}
else if (GetConfig(CONFIG_PARALYZE_ELECTRIC) >= GEN_6 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ELECTRIC))
else if (GetConfig(B_PARALYZE_ELECTRIC) >= GEN_6 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ELECTRIC))
{
battleScript = BattleScript_NotAffected;
}
@ -6452,7 +6458,7 @@ static inline u32 CalcMoveBasePower(struct BattleContext *ctx)
basePower *= 2;
break;
case EFFECT_BEAT_UP:
if (GetConfig(CONFIG_BEAT_UP) >= GEN_5)
if (GetConfig(B_BEAT_UP) >= GEN_5)
basePower = CalcBeatUpPower();
break;
case EFFECT_MAX_MOVE:
@ -6515,7 +6521,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct BattleContext *ctx)
modifier = uq4_12_multiply(modifier, UQ_4_12(2.0));
break;
case EFFECT_SOLAR_BEAM:
if ((GetConfig(CONFIG_SANDSTORM_SOLAR_BEAM) >= GEN_3 && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_LOW_LIGHT))
if ((GetConfig(B_SANDSTORM_SOLAR_BEAM) >= GEN_3 && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_LOW_LIGHT))
|| IsBattlerWeatherAffected(battlerAtk, (B_WEATHER_RAIN | B_WEATHER_ICY_ANY | B_WEATHER_FOG))) // Excludes Sandstorm
modifier = uq4_12_multiply(modifier, UQ_4_12(0.5));
break;
@ -6557,9 +6563,9 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct BattleContext *ctx)
if (IsPsychicTerrainAffected(battlerAtk, ctx->abilityAtk, ctx->holdEffectAtk, ctx->fieldStatuses) && moveType == TYPE_PSYCHIC)
modifier = uq4_12_multiply(modifier, (B_TERRAIN_TYPE_BOOST >= GEN_8 ? UQ_4_12(1.3) : UQ_4_12(1.5)));
if (IsFieldMudSportAffected(ctx->moveType))
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5));
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5));
if (IsFieldWaterSportAffected(ctx->moveType))
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5));
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5));
// attacker's abilities
switch (ctx->abilityAtk)
@ -6625,22 +6631,22 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct BattleContext *ctx)
break;
case ABILITY_PIXILATE:
if (moveType == TYPE_FAIRY && gBattleStruct->battlerState[battlerAtk].ateBoost)
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
break;
case ABILITY_GALVANIZE:
if (moveType == TYPE_ELECTRIC && gBattleStruct->battlerState[battlerAtk].ateBoost)
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
break;
case ABILITY_REFRIGERATE:
if (moveType == TYPE_ICE && gBattleStruct->battlerState[battlerAtk].ateBoost)
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
break;
case ABILITY_AERILATE:
if (moveType == TYPE_FLYING && gBattleStruct->battlerState[battlerAtk].ateBoost)
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
break;
case ABILITY_NORMALIZE:
if (moveType == TYPE_NORMAL && gBattleStruct->battlerState[battlerAtk].ateBoost && GetConfig(CONFIG_ATE_MULTIPLIER) >= GEN_7)
if (moveType == TYPE_NORMAL && gBattleStruct->battlerState[battlerAtk].ateBoost && GetConfig(B_ATE_MULTIPLIER) >= GEN_7)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.2));
break;
case ABILITY_PUNK_ROCK:
@ -6972,7 +6978,7 @@ static inline u32 CalcAttackStat(struct BattleContext *ctx)
case ABILITY_TRANSISTOR:
if (moveType == TYPE_ELECTRIC)
{
if (GetConfig(CONFIG_TRANSISTOR_BOOST) >= GEN_9)
if (GetConfig(B_TRANSISTOR_BOOST) >= GEN_9)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
else
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
@ -7081,7 +7087,7 @@ static inline u32 CalcAttackStat(struct BattleContext *ctx)
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
case HOLD_EFFECT_LIGHT_BALL:
if (atkBaseSpeciesId == SPECIES_PIKACHU && (GetConfig(CONFIG_LIGHT_BALL_ATTACK_BOOST) >= GEN_4 || IsBattleMoveSpecial(move)))
if (atkBaseSpeciesId == SPECIES_PIKACHU && (GetConfig(B_LIGHT_BALL_ATTACK_BOOST) >= GEN_4 || IsBattleMoveSpecial(move)))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
case HOLD_EFFECT_CHOICE_BAND:
@ -7161,7 +7167,7 @@ static inline u32 CalcDefenseStat(struct BattleContext *ctx)
}
// Self-destruct / Explosion cut defense in half
if (GetConfig(CONFIG_EXPLOSION_DEFENSE) < GEN_5 && IsExplosionMove(ctx->move))
if (GetConfig(B_EXPLOSION_DEFENSE) < GEN_5 && IsExplosionMove(ctx->move))
defStat /= 2;
// critical hits ignore positive stat changes
@ -7288,7 +7294,7 @@ static inline u32 CalcDefenseStat(struct BattleContext *ctx)
}
// sandstorm sp.def boost for rock types
if (GetConfig(CONFIG_SANDSTORM_SPDEF_BOOST) >= GEN_4 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ROCK) && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SANDSTORM) && !usesDefStat)
if (GetConfig(B_SANDSTORM_SPDEF_BOOST) >= GEN_4 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ROCK) && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SANDSTORM) && !usesDefStat)
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
// snow def boost for ice types
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SNOW) && usesDefStat)
@ -7366,12 +7372,12 @@ static inline uq4_12_t GetBurnOrFrostBiteModifier(struct BattleContext *ctx)
if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_BURN
&& IsBattleMovePhysical(ctx->move)
&& (GetConfig(CONFIG_BURN_FACADE_DMG) < GEN_6 || moveEffect != EFFECT_FACADE)
&& (GetConfig(B_BURN_FACADE_DMG) < GEN_6 || moveEffect != EFFECT_FACADE)
&& ctx->abilityAtk != ABILITY_GUTS)
return UQ_4_12(0.5);
if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FROSTBITE
&& IsBattleMoveSpecial(ctx->move)
&& (GetConfig(CONFIG_BURN_FACADE_DMG) < GEN_6 || moveEffect != EFFECT_FACADE))
&& (GetConfig(B_BURN_FACADE_DMG) < GEN_6 || moveEffect != EFFECT_FACADE))
return UQ_4_12(0.5);
return UQ_4_12(1.0);
}
@ -7379,7 +7385,7 @@ static inline uq4_12_t GetBurnOrFrostBiteModifier(struct BattleContext *ctx)
static inline uq4_12_t GetCriticalModifier(bool32 isCrit)
{
if (isCrit)
return GetConfig(CONFIG_CRIT_MULTIPLIER) >= GEN_6 ? UQ_4_12(1.5) : UQ_4_12(2.0);
return GetConfig(B_CRIT_MULTIPLIER) >= GEN_6 ? UQ_4_12(1.5) : UQ_4_12(2.0);
return UQ_4_12(1.0);
}
@ -7507,12 +7513,12 @@ static inline uq4_12_t GetDefenderAbilitiesModifier(struct BattleContext *ctx)
}
break;
case ABILITY_FLUFFY:
if (ctx->moveType == TYPE_FIRE && !IsMoveMakingContact(ctx->battlerAtk, ctx->battlerDef, ABILITY_NONE, ctx->holdEffectAtk, ctx->move))
if (ctx->moveType == TYPE_FIRE && !IsMoveMakingContact(ctx->battlerAtk, ctx->battlerDef, ctx->abilityAtk, ctx->holdEffectAtk, ctx->move))
{
modifier = UQ_4_12(2.0);
recordAbility = TRUE;
}
if (ctx->moveType != TYPE_FIRE && IsMoveMakingContact(ctx->battlerAtk, ctx->battlerDef, ABILITY_NONE, ctx->holdEffectAtk, ctx->move))
if (ctx->moveType != TYPE_FIRE && IsMoveMakingContact(ctx->battlerAtk, ctx->battlerDef, ctx->abilityAtk, ctx->holdEffectAtk, ctx->move))
{
modifier = UQ_4_12(0.5);
recordAbility = TRUE;
@ -7746,7 +7752,7 @@ s32 DoFixedDamageMoveCalc(struct BattleContext *ctx)
dmg = GetNonDynamaxHP(ctx->battlerAtk);
break;
case EFFECT_BEAT_UP:
if (GetConfig(CONFIG_BEAT_UP) < GEN_5)
if (GetConfig(B_BEAT_UP) < GEN_5)
dmg = CalcBeatUpDamage(ctx);
break;
case EFFECT_REFLECT_DAMAGE:
@ -7883,11 +7889,11 @@ static const u32 sGen2CriticalHitOdds[] = {17, 32, 64, 85, 128}; // X/256
static inline u32 GetCriticalHitOdds(u32 critChance)
{
if (GetConfig(CONFIG_CRIT_CHANCE) >= GEN_7)
if (GetConfig(B_CRIT_CHANCE) >= GEN_7)
return sGen7CriticalHitOdds[critChance];
if (GetConfig(CONFIG_CRIT_CHANCE) == GEN_6)
if (GetConfig(B_CRIT_CHANCE) == GEN_6)
return sGen6CriticalHitOdds[critChance];
if (GetConfig(CONFIG_CRIT_CHANCE) == GEN_2)
if (GetConfig(B_CRIT_CHANCE) == GEN_2)
return sGen2CriticalHitOdds[critChance];
return sCriticalHitOdds[critChance];
@ -8038,7 +8044,7 @@ static bool32 IsCriticalHit(struct BattleContext *ctx)
bool32 isCrit = FALSE;
s32 critChance = 0;
if (GetConfig(CONFIG_CRIT_CHANCE) == GEN_1)
if (GetConfig(B_CRIT_CHANCE) == GEN_1)
critChance = CalcCritChanceStageGen1(ctx);
else
critChance = CalcCritChanceStage(ctx);
@ -8047,9 +8053,9 @@ static bool32 IsCriticalHit(struct BattleContext *ctx)
isCrit = FALSE;
else if (critChance == CRITICAL_HIT_ALWAYS)
isCrit = TRUE;
else if (GetConfig(CONFIG_CRIT_CHANCE) == GEN_1)
else if (GetConfig(B_CRIT_CHANCE) == GEN_1)
isCrit = RandomChance(RNG_CRITICAL_HIT, critChance, 256);
else if (GetConfig(CONFIG_CRIT_CHANCE) == GEN_2)
else if (GetConfig(B_CRIT_CHANCE) == GEN_2)
isCrit = RandomChance(RNG_CRITICAL_HIT, GetCriticalHitOdds(critChance), 256);
else
isCrit = RandomChance(RNG_CRITICAL_HIT, 1, GetCriticalHitOdds(critChance));
@ -8093,7 +8099,7 @@ s32 GetAdjustedDamage(struct BattleContext *ctx, s32 damage)
gLastUsedItem = gBattleMons[ctx->battlerDef].item;
gBattleStruct->moveResultFlags[ctx->battlerDef] |= MOVE_RESULT_FOE_HUNG_ON;
}
else if (GetConfig(CONFIG_STURDY) >= GEN_5 && ctx->abilityDef == ABILITY_STURDY && IsBattlerAtMaxHp(ctx->battlerDef))
else if (GetConfig(B_STURDY) >= GEN_5 && ctx->abilityDef == ABILITY_STURDY && IsBattlerAtMaxHp(ctx->battlerDef))
{
enduredHit = TRUE;
RecordAbilityBattle(ctx->battlerDef, ABILITY_STURDY);
@ -8306,7 +8312,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(struct BattleCont
}
// Iron Ball ignores type modifiers for flying-type mons if it is the only source of grounding
if (GetConfig(CONFIG_IRON_BALL) >= GEN_5
if (GetConfig(B_IRON_BALL) >= GEN_5
&& ctx->moveType == TYPE_GROUND
&& ctx->holdEffectDef == HOLD_EFFECT_IRON_BALL
&& IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_FLYING)
@ -8687,7 +8693,7 @@ static bool32 CanBattlerFormChange(enum BattlerId battler, enum FormChanges meth
{
// Can't change form if transformed.
if (gBattleMons[battler].volatiles.transformed
&& B_TRANSFORM_FORM_CHANGES >= GEN_5)
&& GetConfig(B_TRANSFORM_FORM_CHANGES) >= GEN_5)
return FALSE;
switch (method)
@ -8984,7 +8990,7 @@ enum ImmunityHealStatusOutcome TryImmunityAbilityHealStatus(enum BattlerId battl
case ABILITY_OBLIVIOUS:
if (gBattleMons[battler].volatiles.infatuation)
outcome = IMMUNITY_INFATUATION_CLEARED;
else if (GetConfig(CONFIG_OBLIVIOUS_TAUNT) >= GEN_6 && gBattleMons[battler].volatiles.tauntTimer != 0)
else if (GetConfig(B_OBLIVIOUS_TAUNT) >= GEN_6 && gBattleMons[battler].volatiles.tauntTimer != 0)
outcome = IMMUNITY_TAUNT_CLEARED;
break;
default:
@ -9014,14 +9020,17 @@ enum ImmunityHealStatusOutcome TryImmunityAbilityHealStatus(enum BattlerId battl
}
gBattleScripting.battler = gBattlerAbility = battler;
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
if (outcome == IMMUNITY_STATUS_CLEARED)
{
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
}
return outcome;
}
uq4_12_t GetBadgeBoostModifier(void)
{
if (GetConfig(CONFIG_BADGE_BOOST) < GEN_3)
if (GetConfig(B_BADGE_BOOST) < GEN_3)
return UQ_4_12(1.125);
else
return UQ_4_12(1.1);
@ -9029,7 +9038,7 @@ uq4_12_t GetBadgeBoostModifier(void)
bool32 ShouldGetStatBadgeBoost(u16 badgeFlag, enum BattlerId battler)
{
if (GetConfig(CONFIG_BADGE_BOOST) <= GEN_3 && badgeFlag != 0)
if (GetConfig(B_BADGE_BOOST) <= GEN_3 && badgeFlag != 0)
{
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_FRONTIER))
return FALSE;
@ -9157,7 +9166,7 @@ bool32 CanFling(enum BattlerId battlerAtk)
enum Item item = gBattleMons[battlerAtk].item;
if (item == ITEM_NONE
|| (GetConfig(CONFIG_KLUTZ_FLING_INTERACTION) >= GEN_5 && GetBattlerAbility(battlerAtk) == ABILITY_KLUTZ)
|| (GetConfig(B_KLUTZ_FLING_INTERACTION) >= GEN_5 && GetBattlerAbility(battlerAtk) == ABILITY_KLUTZ)
|| gFieldStatuses & STATUS_FIELD_MAGIC_ROOM
|| gBattleMons[battlerAtk].volatiles.embargo
|| (GetItemTMHMIndex(item) != 0 && GetItemImportance(item) == 1) // don't fling reusable TMs
@ -9371,7 +9380,7 @@ bool32 CompareStat(enum BattlerId battler, enum Stat statId, u32 cmpTo, u32 cmpK
bool32 BlocksPrankster(enum Move move, enum BattlerId battlerPrankster, enum BattlerId battlerDef, bool32 checkTarget)
{
if (GetConfig(CONFIG_PRANKSTER_DARK_TYPES) < GEN_7)
if (GetConfig(B_PRANKSTER_DARK_TYPES) < GEN_7)
return FALSE;
if (!gProtectStructs[battlerPrankster].pranksterElevated)
return FALSE;
@ -9394,7 +9403,7 @@ bool32 CantPickupItem(u32 _battler)
{
enum BattlerId battler = _battler;
// Used by RandomUniformExcept() for RNG_PICKUP
if (battler == gBattlerAttacker && (GetConfig(CONFIG_PICKUP_WILD) < GEN_9 || gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK)))
if (battler == gBattlerAttacker && (GetConfig(B_PICKUP_WILD) < GEN_9 || gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK)))
return TRUE;
return !(IsBattlerAlive(battler) && GetBattlerPartyState(battler)->usedHeldItem && gBattleStruct->battlerState[battler].canPickupItem);
}
@ -9871,7 +9880,7 @@ void ClearDamageCalcResults(void)
bool32 DoesDestinyBondFail(enum BattlerId battler)
{
return GetConfig(CONFIG_DESTINY_BOND_FAIL) >= GEN_7 && gBattleMons[battler].volatiles.destinyBond;
return GetConfig(B_DESTINY_BOND_FAIL) >= GEN_7 && gBattleMons[battler].volatiles.destinyBond;
}
// This check has always to be the last in a condtion statement because of the recording of AI data.
@ -10004,7 +10013,7 @@ bool32 TrySwitchInEjectPack(enum EjectPackTiming timing)
if (gBattleMons[i].volatiles.tryEjectPack
&& GetBattlerHoldEffect(i) == HOLD_EFFECT_EJECT_PACK
&& IsBattlerAlive(i)
&& CountUsablePartyMons(i) > 0)
&& CanBattlerSwitch(i))
{
ejectPackBattlers |= 1u << i;
numEjectPackBattlers++;
@ -10075,7 +10084,7 @@ bool32 TrySymbiosis(enum BattlerId battler, enum Item itemId, bool32 moveEnd)
if (!gBattleStruct->itemLost[B_SIDE_PLAYER][gBattlerPartyIndexes[battler]].stolen
&& GetBattlerHoldEffect(battler) != HOLD_EFFECT_EJECT_BUTTON
&& GetBattlerHoldEffect(battler) != HOLD_EFFECT_EJECT_PACK
&& (GetConfig(CONFIG_SYMBIOSIS_GEMS) < GEN_7 || !(gSpecialStatuses[battler].gemBoost))
&& (GetConfig(B_SYMBIOSIS_GEMS) < GEN_7 || !(gSpecialStatuses[battler].gemBoost))
&& GetMoveEffect(gCurrentMove) != EFFECT_FLING //Fling and damage-reducing berries are handled separately.
&& !gSpecialStatuses[battler].berryReduced
&& TryTriggerSymbiosis(battler, BATTLE_PARTNER(battler)))
@ -10336,7 +10345,7 @@ u32 GetTotalAccuracy(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum
accStage = gBattleMons[battlerAtk].statStages[STAT_ACC];
evasionStage = gBattleMons[battlerDef].statStages[STAT_EVASION];
if (atkAbility == ABILITY_UNAWARE || atkAbility == ABILITY_KEEN_EYE || atkAbility == ABILITY_MINDS_EYE
|| (GetConfig(CONFIG_ILLUMINATE_EFFECT) >= GEN_9 && atkAbility == ABILITY_ILLUMINATE))
|| (GetConfig(B_ILLUMINATE_EFFECT) >= GEN_9 && atkAbility == ABILITY_ILLUMINATE))
evasionStage = DEFAULT_STAT_STAGE;
if (MoveIgnoresDefenseEvasionStages(move))
evasionStage = DEFAULT_STAT_STAGE;
@ -10607,9 +10616,9 @@ static bool32 IsOpposingSideEmpty(enum BattlerId battler)
bool32 IsAffectedByPowderMove(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect)
{
if (GetConfig(CONFIG_POWDER_OVERCOAT) >= GEN_6 && ability == ABILITY_OVERCOAT)
if (GetConfig(B_POWDER_OVERCOAT) >= GEN_6 && ability == ABILITY_OVERCOAT)
return FALSE;
if (GetConfig(CONFIG_POWDER_GRASS) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS))
if (GetConfig(B_POWDER_GRASS) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS))
return FALSE;
if (holdEffect == HOLD_EFFECT_SAFETY_GOGGLES)
return FALSE;
@ -10751,9 +10760,9 @@ void SetWrapTurns(enum BattlerId battler, enum HoldEffect holdEffect)
{
u32 normalWrapTurns = B_WRAP_TURNS - 2; // 5 turns
if (holdEffect == HOLD_EFFECT_GRIP_CLAW)
gBattleMons[battler].volatiles.wrapTurns = GetConfig(CONFIG_BINDING_TURNS) >= GEN_5 ? B_WRAP_TURNS : normalWrapTurns;
gBattleMons[battler].volatiles.wrapTurns = GetConfig(B_BINDING_TURNS) >= GEN_5 ? B_WRAP_TURNS : normalWrapTurns;
else
gBattleMons[battler].volatiles.wrapTurns = GetConfig(CONFIG_BINDING_TURNS) >= GEN_5 ? RandomUniform(RNG_WRAP, 4, normalWrapTurns) : RandomUniform(RNG_WRAP, 2, normalWrapTurns);
gBattleMons[battler].volatiles.wrapTurns = GetConfig(B_BINDING_TURNS) >= GEN_5 ? RandomUniform(RNG_WRAP, 4, normalWrapTurns) : RandomUniform(RNG_WRAP, 2, normalWrapTurns);
}
// Return True if the order was changed, and false if the order was not changed(for example because the target would move after the attacker anyway).
@ -10768,7 +10777,7 @@ bool32 ChangeOrderTargetAfterAttacker(void)
if (attackerTurnOrderNum > targetTurnOrderNum)
return FALSE;
if (attackerTurnOrderNum + 1 == targetTurnOrderNum)
return GetConfig(CONFIG_AFTER_YOU_TURN_ORDER) >= GEN_8;
return GetConfig(B_AFTER_YOU_TURN_ORDER) >= GEN_8;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
@ -10902,14 +10911,14 @@ void TryResetConsecutiveUseCounter(enum BattlerId battler)
enum BattleMoveEffects lastEffect = GetMoveEffect(lastMove);
if (!gBattleMoveEffects[lastEffect].usesProtectCounter)
{
if (GetConfig(CONFIG_ALLY_SWITCH_FAIL_CHANCE) < GEN_9 || lastEffect != EFFECT_ALLY_SWITCH)
if (GetConfig(B_ALLY_SWITCH_FAIL_CHANCE) < GEN_9 || lastEffect != EFFECT_ALLY_SWITCH)
gBattleMons[battler].volatiles.consecutiveMoveUses = 0;
}
}
void SetOrClearRageVolatile(void)
{
if (GetConfig(CONFIG_RAGE_BUILDS) <= GEN_3 && MoveHasAdditionalEffect(gCurrentMove, MOVE_EFFECT_RAGE))
if (GetConfig(B_RAGE_BUILDS) <= GEN_3 && MoveHasAdditionalEffect(gCurrentMove, MOVE_EFFECT_RAGE))
gBattleMons[gBattlerAttacker].volatiles.rage = TRUE;
else
gBattleMons[gBattlerAttacker].volatiles.rage = FALSE;

View File

@ -3081,10 +3081,11 @@ static void DebugAction_Give_Pokemon_SelectShiny(u8 taskId)
}
}
static void Debug_Display_Ability(enum Ability abilityId, u32 digit, u8 windowId)//(u32 natureId, u32 digit, u8 windowId)
static void Debug_Display_Ability(u32 abilityNum, u32 digit, u8 windowId)//(u32 natureId, u32 digit, u8 windowId)
{
enum Ability abilityId = GetAbilityBySpecies(sDebugMonData->species, abilityNum);
StringCopy(gStringVar2, gText_DigitIndicator[digit]);
ConvertIntToDecimalStringN(gStringVar3, abilityId, STR_CONV_MODE_LEADING_ZEROS, 2);
ConvertIntToDecimalStringN(gStringVar3, abilityNum, STR_CONV_MODE_LEFT_ALIGN, 2);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
u8 *end = StringCopy(gStringVar1, gAbilitiesInfo[abilityId].name);
WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(windowId));
@ -3123,8 +3124,7 @@ static void DebugAction_Give_Pokemon_SelectNature(u8 taskId)
gTasks[taskId].tInput = 0;
gTasks[taskId].tDigit = 0;
enum Ability abilityId = GetAbilityBySpecies(sDebugMonData->species, 0);
Debug_Display_Ability(abilityId, gTasks[taskId].tDigit, gTasks[taskId].tSubWindowId);
Debug_Display_Ability(0, gTasks[taskId].tDigit, gTasks[taskId].tSubWindowId);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectAbility;
}
@ -3148,8 +3148,7 @@ static void Debug_Display_TeraType(u32 typeId, u32 digit, u8 windowId)
static void DebugAction_Give_Pokemon_SelectAbility(u8 taskId)
{
u8 abilityCount = NUM_ABILITY_SLOTS - 1; //-1 for proper iteration
u8 i = 0;
s32 abilityNum = -1;
if (JOY_NEW(DPAD_ANY))
{
@ -3157,28 +3156,31 @@ static void DebugAction_Give_Pokemon_SelectAbility(u8 taskId)
if (JOY_NEW(DPAD_UP))
{
gTasks[taskId].tInput += sPowersOfTen[gTasks[taskId].tDigit];
if (gTasks[taskId].tInput > abilityCount)
gTasks[taskId].tInput = abilityCount;
abilityNum = gTasks[taskId].tInput + 1;
while (GetSpeciesAbility(sDebugMonData->species, abilityNum) == ABILITY_NONE && abilityNum < NUM_ABILITY_SLOTS)
{
abilityNum++;
}
}
if (JOY_NEW(DPAD_DOWN))
{
gTasks[taskId].tInput -= sPowersOfTen[gTasks[taskId].tDigit];
if (gTasks[taskId].tInput < 0)
gTasks[taskId].tInput = 0;
abilityNum = gTasks[taskId].tInput - 1;
while (GetSpeciesAbility(sDebugMonData->species, abilityNum) == ABILITY_NONE && abilityNum >= 0)
{
abilityNum--;
}
}
while (GetAbilityBySpecies(sDebugMonData->species, gTasks[taskId].tInput - i) == ABILITY_NONE && gTasks[taskId].tInput - i < NUM_ABILITY_SLOTS)
if (abilityNum >= 0 && abilityNum < NUM_ABILITY_SLOTS)
{
i++;
gTasks[taskId].tInput = abilityNum;
Debug_Display_Ability(abilityNum, gTasks[taskId].tDigit, gTasks[taskId].tSubWindowId);
}
enum Ability abilityId = GetAbilityBySpecies(sDebugMonData->species, gTasks[taskId].tInput - i);
Debug_Display_Ability(abilityId, gTasks[taskId].tDigit, gTasks[taskId].tSubWindowId);
}
if (JOY_NEW(A_BUTTON))
{
sDebugMonData->abilityNum = gTasks[taskId].tInput - i;
sDebugMonData->abilityNum = gTasks[taskId].tInput;
gTasks[taskId].tInput = 0;
gTasks[taskId].tDigit = 0;

View File

@ -841,14 +841,22 @@ void FieldEffectScript_LoadTiles(u8 **script)
(*script) += 4;
}
static bool32 ShouldFieldEffectBeFogBlended(u8 *script)
{
u32 ptr = FieldEffectScript_ReadWord(&script);
if (ptr == (u32)FldEff_TallGrass)
return FALSE;
return TRUE;
}
void FieldEffectScript_LoadFadedPalette(u8 **script)
{
struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
u32 paletteSlot = LoadSpritePalette(palette);
(*script) += 4;
SetPaletteColorMapType(paletteSlot + 16, T1_READ_8(*script));
UpdateSpritePaletteWithWeather(paletteSlot, TRUE);
(*script)++;
UpdateSpritePaletteWithWeather(paletteSlot, ShouldFieldEffectBeFogBlended(*script));
}
void FieldEffectScript_LoadPalette(u8 **script)

View File

@ -142,7 +142,7 @@ const struct FrontierBrain gFrontierBrainInfo[NUM_FRONTIER_FACILITIES] =
COMPOUND_STRING("My DOME ACE title isn't just for show!") //Gold
},
.battledBit = {1 << 2, 1 << 3},
.streakAppearances = {1, 2, 5, 0},
.streakAppearances = {4, 9, 5, 0},
},
[FRONTIER_FACILITY_PALACE] =
{

View File

@ -4,7 +4,7 @@
#include "constants/generational_changes.h"
#include "config/pokerus.h"
#define UNPACK_BATTLE_CONFIG_GEN_CHANGES(_name, _field, ...) ._field = B_##_name,
#define UNPACK_BATTLE_CONFIG_GEN_CHANGES(_name, _field, ...) ._field = _name,
#define UNPACK_POKEMON_CONFIG_GEN_CHANGES(_name, _field, ...) ._field = P_##_name,
const struct GenChanges sConfigChanges =
@ -32,7 +32,9 @@ EWRAM_DATA struct GenChanges *gConfigChangesTestOverride = NULL;
#define UNPACK_CONFIG_SETTERS(_name, _field, ...) case CONFIG_##_name: return;
#endif
u32 GetConfig(enum ConfigTag _genConfig)
// Gets the value of a volatile status flag for a certain battler
// Primarily used for the debug menu and scripts. Outside of it explicit references are preferred
u32 GetConfigInternal(enum ConfigTag _genConfig)
{
#if TESTING
if (gConfigChangesTestOverride == NULL)

View File

@ -1148,7 +1148,7 @@ static u32 GetBallThrowableState(void)
return BALL_THROW_UNABLE_TWO_MONS;
else if (IsPlayerPartyAndPokemonStorageFull() == TRUE)
return BALL_THROW_UNABLE_NO_ROOM;
else if (GetConfig(CONFIG_SEMI_INVULNERABLE_CATCH) >= GEN_4 && IsSemiInvulnerable(GetCatchingBattler(), CHECK_ALL))
else if (GetConfig(B_SEMI_INVULNERABLE_CATCH) >= GEN_4 && IsSemiInvulnerable(GetCatchingBattler(), CHECK_ALL))
return BALL_THROW_UNABLE_SEMI_INVULNERABLE;
else if (FlagGet(B_FLAG_NO_CATCHING) || !IsAllowedToUseBag())
return BALL_THROW_UNABLE_DISABLED_FLAG;

View File

@ -3926,6 +3926,9 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, enum Item item, u8 partyIndex,
u8 effectFlags;
s8 evChange;
u16 evCount;
u8 levelBefore;
bool8 didLevelUp = FALSE;
bool8 isLevelUpItem;
// Determine the EV cap to use
u32 maxAllowedEVs = !B_EV_ITEMS_CAP ? MAX_TOTAL_EVS : GetCurrentEVCap();
@ -3947,6 +3950,8 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, enum Item item, u8 partyIndex,
// Get item effect
itemEffect = GetItemEffect(item);
isLevelUpItem = (itemEffect[3] & ITEM3_LEVEL_UP) != 0;
levelBefore = GetMonData(mon, MON_DATA_LEVEL, NULL);
// Do item effect
for (i = 0; i < ITEM_EFFECT_ARG_START; i++)
@ -4001,6 +4006,8 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, enum Item item, u8 partyIndex,
{
SetMonData(mon, MON_DATA_EXP, &dataUnsigned);
CalculateMonStats(mon);
if (GetMonData(mon, MON_DATA_LEVEL, NULL) > levelBefore)
didLevelUp = TRUE;
retVal = FALSE;
}
}
@ -4119,6 +4126,11 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, enum Item item, u8 partyIndex,
{
u32 currentHP = GetMonData(mon, MON_DATA_HP);
u32 maxHP = GetMonData(mon, MON_DATA_MAX_HP);
if (isLevelUpItem && !didLevelUp && (effectFlags & (ITEM4_REVIVE >> 2)))
{
itemEffectParam++;
break;
}
// Check use validity.
if ((effectFlags & (ITEM4_REVIVE >> 2) && currentHP != 0)
|| (!(effectFlags & (ITEM4_REVIVE >> 2)) && currentHP == 0))

View File

@ -24,10 +24,10 @@ static u32 GetRandomPokerusStrain(void)
void RandomlyGivePartyPokerus(void)
{
if (!GetConfig(CONFIG_POKERUS_ENABLED))
if (!GetConfig(POKERUS_ENABLED))
return;
if ((GetConfig(CONFIG_POKERUS_INFECT_AGAIN) > GEN_2) && IsPokerusInParty())
if ((GetConfig(POKERUS_INFECT_AGAIN) > GEN_2) && IsPokerusInParty())
return;
if (P_POKERUS_FLAG_INFECTION && !FlagGet(P_POKERUS_FLAG_INFECTION))
@ -45,9 +45,9 @@ void RandomlyGivePartyPokerus(void)
mon = &gPlayerParty[i];
if (!GetMonData(mon, MON_DATA_SPECIES))
continue;
else if (!GetConfig(CONFIG_POKERUS_INFECT_EGG) && GetMonData(mon, MON_DATA_IS_EGG))
else if (!GetConfig(POKERUS_INFECT_EGG) && GetMonData(mon, MON_DATA_IS_EGG))
continue;
else if (!GetConfig(CONFIG_POKERUS_HERD_IMMUNITY) && CheckMonHasHadPokerus(mon))
else if (!GetConfig(POKERUS_HERD_IMMUNITY) && CheckMonHasHadPokerus(mon))
continue;
validTargets[validTargetsCount] = i;
validTargetsCount++;
@ -72,7 +72,7 @@ void RandomlyGivePartyPokerus(void)
bool32 IsPokerusInParty(void)
{
if (!GetConfig(CONFIG_POKERUS_ENABLED))
if (!GetConfig(POKERUS_ENABLED))
return FALSE;
for (u32 i = 0; i < PARTY_SIZE; i++)
@ -89,7 +89,7 @@ bool32 IsPokerusInParty(void)
bool32 CheckMonPokerus(struct Pokemon *mon)
{
if (!GetConfig(CONFIG_POKERUS_ENABLED))
if (!GetConfig(POKERUS_ENABLED))
return FALSE;
if (GetMonData(mon, MON_DATA_POKERUS_DAYS_LEFT))
@ -100,7 +100,7 @@ bool32 CheckMonPokerus(struct Pokemon *mon)
bool32 CheckMonHasHadPokerus(struct Pokemon *mon)
{
if (!GetConfig(CONFIG_POKERUS_ENABLED))
if (!GetConfig(POKERUS_ENABLED))
return FALSE;
if (GetMonData(mon, MON_DATA_POKERUS))
@ -134,7 +134,7 @@ bool32 ShouldPokemonShowCuredPokerus(struct Pokemon *mon)
void UpdatePartyPokerusTime(u32 days)
{
if (!GetConfig(CONFIG_POKERUS_ENABLED))
if (!GetConfig(POKERUS_ENABLED))
return;
for (u32 i = 0; i < PARTY_SIZE; i++)
@ -167,21 +167,21 @@ void UpdatePartyPokerusTime(u32 days)
static void SpreadPokerusToSpecificMon(struct Pokemon *mon, u32 strain, u32 daysLeft)
{
SetMonData(mon, MON_DATA_POKERUS_STRAIN, &strain);
if (GetConfig(CONFIG_POKERUS_SPREAD_DAYS_LEFT) < GEN_3)
if (GetConfig(POKERUS_SPREAD_DAYS_LEFT) < GEN_3)
daysLeft = GetDaysLeftBasedOnStrain(strain);
SetMonData(mon, MON_DATA_POKERUS_DAYS_LEFT, &daysLeft);
}
static bool32 CanReceivePokerusFromSpread(struct Pokemon *mon)
{
if (GetConfig(CONFIG_POKERUS_WEAK_VARIANT))
if (GetConfig(POKERUS_WEAK_VARIANT))
return !GetMonData(mon, MON_DATA_POKERUS_STRAIN);
return !GetMonData(mon, MON_DATA_POKERUS);
}
void PartySpreadPokerus(void)
{
if (!GetConfig(CONFIG_POKERUS_ENABLED))
if (!GetConfig(POKERUS_ENABLED))
return;
if (RandomUniform(RNG_POKERUS_SPREAD, 0, MAX_u16) >= P_POKERUS_SPREAD_ODDS)
@ -197,7 +197,7 @@ void PartySpreadPokerus(void)
if (daysLeft)
{
bool32 spreadUp = TRUE, spreadDown = TRUE;
if (GetConfig(CONFIG_POKERUS_SPREAD_ADJACENCY) < GEN_3)
if (GetConfig(POKERUS_SPREAD_ADJACENCY) < GEN_3)
{
if (i == (gPlayerPartyCount - 1))
spreadUp = FALSE;

View File

@ -330,7 +330,7 @@ void CreateBattlerSprite(enum BattlerId battler)
gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, 0x50,
(8 - gTrainerBacksprites[gSaveBlock2Ptr->playerGender].coordinates.size) * 4 + 80,
GetBattlerSpriteSubpriority(0));
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = (8 + battler / 2);
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = 14 + battler / 2;
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCallbackDummy;
gSprites[gBattlerSpriteIds[battler]].data[0] = battler;
}
@ -340,7 +340,7 @@ void CreateBattlerSprite(enum BattlerId battler)
gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, 0x50,
(8 - gTrainerBacksprites[IS_FRLG ? TRAINER_PIC_BACK_OLD_MAN : TRAINER_PIC_BACK_WALLY].coordinates.size) * 4 + 80,
GetBattlerSpriteSubpriority(0));
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = (8 + battler / 2);
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = 14 + battler / 2;
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCallbackDummy;
gSprites[gBattlerSpriteIds[battler]].data[0] = battler;
}

View File

@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Aerilate boosts power of affected moves by 20% (Gen7+) or 30
PARAMETRIZE { move = MOVE_SKILL_SWAP; genConfig = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, genConfig);
WITH_CONFIG(B_ATE_MULTIPLIER, genConfig);
ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
PLAYER(SPECIES_WOBBUFFET);

View File

@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Arena Trap doesn't prevent switch outs via moves that switch
GIVEN {
ASSUME(GetMoveEffect(move) == effect);
ASSUME(GetMoveEffect(MOVE_SOAK) == EFFECT_SOAK);
WITH_CONFIG(CONFIG_TELEPORT_BEHAVIOR, GEN_8);
WITH_CONFIG(B_TELEPORT_BEHAVIOR, GEN_8);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_DIGLETT) { Ability(ABILITY_ARENA_TRAP); }
@ -113,7 +113,7 @@ SINGLE_BATTLE_TEST("Arena Trap prevents switch outs from Ghost-type Pokémon (Ge
{
GIVEN {
ASSUME(GetSpeciesType(SPECIES_SHUPPET, 0) == TYPE_GHOST);
WITH_CONFIG(CONFIG_GHOSTS_ESCAPE, GEN_5);
WITH_CONFIG(B_GHOSTS_ESCAPE, GEN_5);
PLAYER(SPECIES_SHUPPET);
OPPONENT(SPECIES_DIGLETT) { Ability(ABILITY_ARENA_TRAP); }
} WHEN {
@ -129,7 +129,7 @@ SINGLE_BATTLE_TEST("Arena Trap doesn't prevent switch outs from Ghost-type Poké
{
GIVEN {
ASSUME(GetSpeciesType(SPECIES_SHUPPET, 0) == TYPE_GHOST);
WITH_CONFIG(CONFIG_GHOSTS_ESCAPE, GEN_6);
WITH_CONFIG(B_GHOSTS_ESCAPE, GEN_6);
PLAYER(SPECIES_SHUPPET);
OPPONENT(SPECIES_DIGLETT) { Ability(ABILITY_ARENA_TRAP); }
} WHEN {

View File

@ -22,6 +22,24 @@ DOUBLE_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Taunt")
}
}
DOUBLE_BATTLE_TEST("Aroma Veil protects the Pokémon's side from ally Taunt")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT);
ASSUME(GetMoveCategory(MOVE_HARDEN) == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_AROMATISSE) { Ability(ABILITY_AROMA_VEIL); Speed(1); }
PLAYER(SPECIES_WOBBUFFET) { Speed(2); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(3); }
OPPONENT(SPECIES_WYNAUT) { Speed(4); }
} WHEN {
TURN { MOVE(playerRight, MOVE_TAUNT, target: playerLeft); MOVE(playerLeft, MOVE_HARDEN); }
} SCENE {
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TAUNT, playerRight);
ABILITY_POPUP(playerLeft, ABILITY_AROMA_VEIL);
ANIMATION(ANIM_TYPE_MOVE, MOVE_HARDEN, playerLeft);
}
}
DOUBLE_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Torment")
{
struct BattlePokemon *moveTarget = NULL;

View File

@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Battle Bond transforms player's Greninja - Singles")
PARAMETRIZE { monsCountPlayer = 2; monsCountOpponent = 2; }
GIVEN {
WITH_CONFIG(CONFIG_BATTLE_BOND, GEN_8);
WITH_CONFIG(B_BATTLE_BOND, GEN_8);
PLAYER(SPECIES_GRENINJA_BATTLE_BOND);
if (monsCountPlayer == 2) {
PLAYER(SPECIES_WOBBUFFET);
@ -65,7 +65,7 @@ SINGLE_BATTLE_TEST("Battle Bond transforms opponent's Greninja - Singles")
PARAMETRIZE { monsCountPlayer = 2; monsCountOpponent = 2; }
GIVEN {
WITH_CONFIG(CONFIG_BATTLE_BOND, GEN_8);
WITH_CONFIG(B_BATTLE_BOND, GEN_8);
OPPONENT(SPECIES_GRENINJA_BATTLE_BOND);
if (monsCountOpponent == 2) {
OPPONENT(SPECIES_WOBBUFFET);
@ -113,7 +113,7 @@ DOUBLE_BATTLE_TEST("Battle Bond transforms player's Greninja when fainting its A
PARAMETRIZE { monsCountPlayer = 3; monsCountOpponent = 3; }
GIVEN {
WITH_CONFIG(CONFIG_BATTLE_BOND, GEN_8);
WITH_CONFIG(B_BATTLE_BOND, GEN_8);
PLAYER(SPECIES_GRENINJA_BATTLE_BOND);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
if (monsCountPlayer == 3) {
@ -145,7 +145,7 @@ DOUBLE_BATTLE_TEST("Battle Bond transforms player's Greninja when fainting its A
SINGLE_BATTLE_TEST("Battle Bond increases Atk, SpAtk and Speed by 1 stage (Gen9+)")
{
GIVEN {
WITH_CONFIG(CONFIG_BATTLE_BOND, GEN_9);
WITH_CONFIG(B_BATTLE_BOND, GEN_9);
PLAYER(SPECIES_GRENINJA_BATTLE_BOND) { Ability(ABILITY_BATTLE_BOND); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
@ -166,7 +166,7 @@ SINGLE_BATTLE_TEST("Battle Bond increases Atk, SpAtk and Speed by 1 stage (Gen9+
SINGLE_BATTLE_TEST("Battle Bond increases a Stat even if only one can be increased (Gen9+)")
{
GIVEN {
WITH_CONFIG(CONFIG_BATTLE_BOND, GEN_9);
WITH_CONFIG(B_BATTLE_BOND, GEN_9);
PLAYER(SPECIES_GRENINJA_BATTLE_BOND) { Ability(ABILITY_BATTLE_BOND); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);

View File

@ -163,7 +163,7 @@ WILD_BATTLE_TEST("Comatose boosts Dream Ball's multiplier")
GIVEN {
ASSUME(B_DREAM_BALL_MODIFIER >= GEN_8);
ASSUME(gSpeciesInfo[species].catchRate == 45);
WITH_CONFIG(CONFIG_MISSING_BADGE_CATCH_MALUS, GEN_7);
WITH_CONFIG(B_MISSING_BADGE_CATCH_MALUS, GEN_7);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); MaxHP(100); HP(1); }
} WHEN {

View File

@ -474,3 +474,35 @@ DOUBLE_BATTLE_TEST("Commander will not activate if partner Dondozo is about to s
NOT ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
}
}
DOUBLE_BATTLE_TEST("Commander clears when Dondozo is replaced and Tatsugiri can be hit")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_VOLT_SWITCH) == EFFECT_HIT_ESCAPE);
PLAYER(SPECIES_DONDOZO) { HP(1); Speed(1); }
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); MaxHP(400); HP(400); Speed(2); }
PLAYER(SPECIES_SEADRA) { Speed(3); }
OPPONENT(SPECIES_VENUSAUR) { Speed(5); }
OPPONENT(SPECIES_LUXRAY) { Speed(6); }
OPPONENT(SPECIES_BUTTERFREE) { Speed(4); }
} WHEN {
TURN {
MOVE(opponentLeft, MOVE_SEED_BOMB, target: playerRight);
MOVE(opponentRight, MOVE_VOLT_SWITCH, target: playerLeft);
SEND_OUT(opponentRight, 2);
SEND_OUT(playerLeft, 2);
}
TURN {
MOVE(opponentRight, MOVE_BUG_BUZZ, target: playerRight);
}
} SCENE {
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, opponentRight);
MESSAGE("Dondozo fainted!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_SEED_BOMB, opponentLeft);
HP_BAR(playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_BUG_BUZZ, opponentRight);
HP_BAR(playerRight);
}
}

View File

@ -140,7 +140,7 @@ SINGLE_BATTLE_TEST("Competitive activates after Sticky Web lowers Speed")
SINGLE_BATTLE_TEST("Competitive doesn't activate after Sticky Web lowers Speed if Court Changed (gen8)")
{
GIVEN {
WITH_CONFIG(CONFIG_DEFIANT_STICKY_WEB, GEN_8);
WITH_CONFIG(B_DEFIANT_STICKY_WEB, GEN_8);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_IGGLYBUFF) { Ability(ABILITY_COMPETITIVE); }
OPPONENT(SPECIES_WOBBUFFET);
@ -167,7 +167,7 @@ SINGLE_BATTLE_TEST("Competitive doesn't activate after Sticky Web lowers Speed i
SINGLE_BATTLE_TEST("Competitive correctly activates after Sticky Web lowers Speed if Court Changed (Gen8)")
{
GIVEN {
WITH_CONFIG(CONFIG_DEFIANT_STICKY_WEB, GEN_8);
WITH_CONFIG(B_DEFIANT_STICKY_WEB, GEN_8);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_IGGLYBUFF) { Ability(ABILITY_COMPETITIVE); }
OPPONENT(SPECIES_WOBBUFFET);

View File

@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Cute Charm triggers 1/3 times (Gen3) or 30% (Gen 4+) of the
PARAMETRIZE { config = GEN_4; passes = 3; trials = 10; } // 30%
PASSES_RANDOMLY(passes, trials, RNG_CUTE_CHARM);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); }
OPPONENT(SPECIES_CLEFAIRY) { Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM); }

View File

@ -668,7 +668,7 @@ SINGLE_BATTLE_TEST("Dancer user may hit itself in confusion instead of copying a
PARAMETRIZE { genConfig = GEN_7; pctChance = 33; }
PASSES_RANDOMLY(pctChance, 100, RNG_CONFUSION);
GIVEN {
WITH_CONFIG(CONFIG_CONFUSION_SELF_DMG_CHANCE, genConfig);
WITH_CONFIG(B_CONFUSION_SELF_DMG_CHANCE, genConfig);
ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_WOBBUFFET) { Speed(30); }
@ -835,7 +835,7 @@ SINGLE_BATTLE_TEST("Dancer can still copy status moves if the user is holding an
DOUBLE_BATTLE_TEST("Dancer copies Lunar Dance after the original user faints, but before the replacement is sent out")
{
GIVEN {
WITH_CONFIG(CONFIG_HEALING_WISH_SWITCH, GEN_7);
WITH_CONFIG(B_HEALING_WISH_SWITCH, GEN_7);
ASSUME(GetMoveEffect(MOVE_LUNAR_DANCE) == EFFECT_LUNAR_DANCE);
PLAYER(SPECIES_WOBBUFFET) { Speed(50); }
PLAYER(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Speed(20); }

View File

@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Dauntless Shield raises Defense by one stage")
SINGLE_BATTLE_TEST("Dauntless Shield raises Defense by one stage every time it switches in (Gen8)")
{
GIVEN {
WITH_CONFIG(CONFIG_DAUNTLESS_SHIELD, GEN_8);
WITH_CONFIG(B_DAUNTLESS_SHIELD, GEN_8);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); }
OPPONENT(SPECIES_WYNAUT);
@ -42,7 +42,7 @@ SINGLE_BATTLE_TEST("Dauntless Shield raises Defense by one stage every time it s
SINGLE_BATTLE_TEST("Dauntless Shield raises Defense by one stage only once per battle (Gen 9+)")
{
GIVEN {
WITH_CONFIG(CONFIG_DAUNTLESS_SHIELD, GEN_9);
WITH_CONFIG(B_DAUNTLESS_SHIELD, GEN_9);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); }
OPPONENT(SPECIES_WYNAUT);

View File

@ -142,7 +142,7 @@ SINGLE_BATTLE_TEST("Defiant activates after Sticky Web lowers Speed")
SINGLE_BATTLE_TEST("Defiant doesn't activate after Sticky Web lowers Speed if Court Changed (Gen8)")
{
GIVEN {
WITH_CONFIG(CONFIG_DEFIANT_STICKY_WEB, GEN_8);
WITH_CONFIG(B_DEFIANT_STICKY_WEB, GEN_8);
ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
ASSUME(GetMoveEffect(MOVE_COURT_CHANGE) == EFFECT_COURT_CHANGE);
@ -179,7 +179,7 @@ SINGLE_BATTLE_TEST("Defiant doesn't activate after Sticky Web lowers Speed if Co
SINGLE_BATTLE_TEST("Defiant activates after Sticky Web lowers Speed if Court Changed (Gen9)")
{
GIVEN {
WITH_CONFIG(CONFIG_DEFIANT_STICKY_WEB, GEN_9);
WITH_CONFIG(B_DEFIANT_STICKY_WEB, GEN_9);
ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
ASSUME(GetMoveEffect(MOVE_COURT_CHANGE) == EFFECT_COURT_CHANGE);

View File

@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu doesn't lose 1/8 of its max HP upon changi
PARAMETRIZE { species = SPECIES_MIMIKYU_DISGUISED; newSpecies = SPECIES_MIMIKYU_BUSTED; }
PARAMETRIZE { species = SPECIES_MIMIKYU_TOTEM_DISGUISED; newSpecies = SPECIES_MIMIKYU_BUSTED_TOTEM; }
GIVEN {
WITH_CONFIG(CONFIG_DISGUISE_HP_LOSS, GEN_7);
WITH_CONFIG(B_DISGUISE_HP_LOSS, GEN_7);
PLAYER(species) { Ability(ABILITY_DISGUISE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing
PARAMETRIZE { species = SPECIES_MIMIKYU_DISGUISED; newSpecies = SPECIES_MIMIKYU_BUSTED; }
PARAMETRIZE { species = SPECIES_MIMIKYU_TOTEM_DISGUISED; newSpecies = SPECIES_MIMIKYU_BUSTED_TOTEM; }
GIVEN {
WITH_CONFIG(CONFIG_DISGUISE_HP_LOSS, GEN_8);
WITH_CONFIG(B_DISGUISE_HP_LOSS, GEN_8);
PLAYER(species) { Ability(ABILITY_DISGUISE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -26,7 +26,7 @@ SINGLE_BATTLE_TEST("Drizzle summons rain", s16 damage)
SINGLE_BATTLE_TEST("Drizzle sets up rain for 5 turns (Gen6+)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_POLITOED) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DRIZZLE); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -48,7 +48,7 @@ SINGLE_BATTLE_TEST("Drizzle sets up rain for 5 turns (Gen6+)")
SINGLE_BATTLE_TEST("Drizzle sets up rain for 8 turns with Damp Rock (Gen6+)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_POLITOED) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DRIZZLE); Item(ITEM_DAMP_ROCK); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -76,7 +76,7 @@ SINGLE_BATTLE_TEST("Drizzle sets up rain for 8 turns with Damp Rock (Gen6+)")
SINGLE_BATTLE_TEST("Drizzle sets up permanent rain (Gen3-5)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_3);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_3);
PLAYER(SPECIES_POLITOED) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DRIZZLE); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {

View File

@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Drought sets up sun for 5 turns (Gen6+)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_NINETALES) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DROUGHT); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -26,7 +26,7 @@ SINGLE_BATTLE_TEST("Drought sets up sun for 5 turns (Gen6+)")
SINGLE_BATTLE_TEST("Drought sets up sun for 8 turns with Heat Rock (Gen6+)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_NINETALES) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DROUGHT); Item(ITEM_HEAT_ROCK); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Drought sets up sun for 8 turns with Heat Rock (Gen6+)")
SINGLE_BATTLE_TEST("Drought sets up permanent sun (Gen3-5)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_3);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_3);
PLAYER(SPECIES_NINETALES) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DROUGHT); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {

View File

@ -40,7 +40,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes poison 3.3% (Gen3), 10% (Gen4) and 9% (G
PARAMETRIZE { config = GEN_5; passes = 9; trials = 100; } // 9%
PASSES_RANDOMLY(passes, trials, RNG_EFFECT_SPORE);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
@ -63,7 +63,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes paralysis 3.3% (Gen3) and 10% (Gen4+) of
PARAMETRIZE { config = GEN_5; passes = 1; trials = 10; } // 10%
PASSES_RANDOMLY(passes, trials, RNG_EFFECT_SPORE);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
@ -86,7 +86,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes sleep 3.3% (Gen3), 10% (Gen4) and 11% (G
PARAMETRIZE { config = GEN_5; passes = 11; trials = 100; } // 11%
PASSES_RANDOMLY(passes, trials, RNG_EFFECT_SPORE);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
@ -109,7 +109,7 @@ SINGLE_BATTLE_TEST("Effect Spore will check if it can inflict status onto attack
PARAMETRIZE { config = GEN_5; passes = 11; trials = 100; } // 11%
PASSES_RANDOMLY(passes, trials, RNG_EFFECT_SPORE);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Status1(STATUS1_BURN); Ability(ABILITY_EFFECT_SPORE); }

View File

@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Flame Body triggers 1/3 times (Gen3) or 30% (Gen 4+) of the
PARAMETRIZE { config = GEN_4; passes = 3; trials = 10; } // 30%
PASSES_RANDOMLY(passes, trials, RNG_FLAME_BODY);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_MAGMAR) { Ability(ABILITY_FLAME_BODY); }

View File

@ -70,6 +70,7 @@ SINGLE_BATTLE_TEST("Fluffy halves damage taken from moves that make direct conta
PARAMETRIZE { ability = ABILITY_KLUTZ; }
PARAMETRIZE { ability = ABILITY_FLUFFY; }
GIVEN {
ASSUME(MoveMakesContact(MOVE_THUNDER_PUNCH));
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PROTECTIVE_PADS); }
OPPONENT(SPECIES_STUFFUL) { Ability(ability); }
} WHEN {
@ -88,6 +89,8 @@ SINGLE_BATTLE_TEST("Fluffy does not halve damage taken from moves that make dire
PARAMETRIZE { ability = ABILITY_KLUTZ; }
PARAMETRIZE { ability = ABILITY_FLUFFY; }
GIVEN {
ASSUME(MoveMakesContact(MOVE_THUNDER_PUNCH));
ASSUME(IsPunchingMove(MOVE_THUNDER_PUNCH));
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PUNCHING_GLOVE); }
OPPONENT(SPECIES_STUFFUL) { Ability(ability); }
} WHEN {
@ -99,3 +102,22 @@ SINGLE_BATTLE_TEST("Fluffy does not halve damage taken from moves that make dire
EXPECT_EQ(results[0].damage, results[1].damage);
}
}
SINGLE_BATTLE_TEST("Fluffy does not halve damage taken from moves that make direct contact but are ignored by Long Reach", s16 damage)
{
enum Ability ability;
PARAMETRIZE { ability = ABILITY_KLUTZ; }
PARAMETRIZE { ability = ABILITY_FLUFFY; }
GIVEN {
ASSUME(MoveMakesContact(MOVE_THUNDER_PUNCH));
PLAYER(SPECIES_ROWLET) { Ability(ABILITY_LONG_REACH); }
OPPONENT(SPECIES_STUFFUL) { Ability(ability); }
} WHEN {
TURN { MOVE(player, MOVE_THUNDER_PUNCH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER_PUNCH, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_EQ(results[0].damage, results[1].damage);
}
}

View File

@ -9,7 +9,7 @@ SINGLE_BATTLE_TEST("Gale Wings only grants priority at full HP (Gen 7+)")
PARAMETRIZE { hp = 100; config = GEN_6; }
PARAMETRIZE { hp = 99; config = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_GALE_WINGS, config);
WITH_CONFIG(B_GALE_WINGS, config);
ASSUME(GetMoveType(MOVE_AERIAL_ACE) == TYPE_FLYING);
PLAYER(SPECIES_TALONFLAME) { Ability(ABILITY_GALE_WINGS); HP(hp); MaxHP(100); Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }

View File

@ -52,7 +52,7 @@ SINGLE_BATTLE_TEST("Galvanize boosts power of affected moves by 20% (Gen7+) or 3
PARAMETRIZE { ability = ABILITY_GALVANIZE; genConfig = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, genConfig);
WITH_CONFIG(B_ATE_MULTIPLIER, genConfig);
PLAYER(SPECIES_GEODUDE_ALOLA) { Ability(ability); Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -230,6 +230,32 @@ SINGLE_BATTLE_TEST("Gulp Missile triggered by explosion doesn't freeze the game"
}
}
SINGLE_BATTLE_TEST("(Gulp Missile) Cramorant in Gorging damages an electric type without paralysing")
{
GIVEN {
PLAYER(SPECIES_CRAMORANT) { HP(120); MaxHP(250); Ability(ABILITY_GULP_MISSILE); }
OPPONENT(SPECIES_EELEKTROSS);
} WHEN {
TURN { MOVE(player, MOVE_SURF); MOVE(opponent, MOVE_SCRATCH); }
TURN { MOVE(player, MOVE_SCRATCH); MOVE(opponent, MOVE_SCRATCH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
HP_BAR(player);
ABILITY_POPUP(player, ABILITY_GULP_MISSILE);
HP_BAR(opponent);
NONE_OF {
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, opponent);
STATUS_ICON(opponent, paralysis: TRUE);
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
HP_BAR(player);
}
}
SINGLE_BATTLE_TEST("Gulp Missile only changes forms for Cramorant")
{
GIVEN {

View File

@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Heatproof halves the damage done by burn from 1/8th to 1/16t
PARAMETRIZE { config = GEN_6; burnRate = 16; }
GIVEN {
WITH_CONFIG(CONFIG_BURN_DAMAGE, config);
WITH_CONFIG(B_BURN_DAMAGE, config);
PLAYER (SPECIES_BRONZONG) { Ability(ABILITY_HEATPROOF); Status1(STATUS1_BURN); }
OPPONENT (SPECIES_WOBBUFFET);
}
@ -49,4 +49,3 @@ SINGLE_BATTLE_TEST("Heatproof halves the damage done by burn from 1/8th to 1/16t
HP_BAR(player, damage: maxHP / burnRate);
}
}

View File

@ -1,4 +1,4 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("TODO: Write Heavy Metal (Ability) test titles")
// Tests for Heavy Metal are handled in test/battle/ability/light_metal.c

View File

@ -117,7 +117,7 @@ SINGLE_BATTLE_TEST("Illusion breaks if user loses Illusion due to Worry Seed")
SINGLE_BATTLE_TEST("Illusion breaks when attacked behind a substitute")
{
GIVEN {
WITH_CONFIG(CONFIG_INFILTRATOR_SUBSTITUTE, GEN_6);
WITH_CONFIG(B_INFILTRATOR_SUBSTITUTE, GEN_6);
PLAYER(SPECIES_DRAGAPULT) { Ability(ABILITY_INFILTRATOR); Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
OPPONENT(SPECIES_ZOROARK) { Speed(2); }

View File

@ -167,7 +167,7 @@ SINGLE_BATTLE_TEST("Infiltrator bypasses the opponent's Substitute (Gen 6+)")
PARAMETRIZE { ability = ABILITY_INFILTRATOR; config = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_INFILTRATOR_SUBSTITUTE, config);
WITH_CONFIG(B_INFILTRATOR_SUBSTITUTE, config);
ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
ASSUME(!MoveIgnoresSubstitute(MOVE_SCRATCH));
PLAYER(SPECIES_DRAGAPULT) { Ability(ability); }
@ -194,7 +194,7 @@ DOUBLE_BATTLE_TEST("Infiltrator bypasses an ally's Substitute (Gen 6+)")
PARAMETRIZE { ability = ABILITY_INFILTRATOR; config = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_INFILTRATOR_SUBSTITUTE, config);
WITH_CONFIG(B_INFILTRATOR_SUBSTITUTE, config);
ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
ASSUME(!MoveIgnoresSubstitute(MOVE_SCRATCH));
PLAYER(SPECIES_DRAGAPULT) { Ability(ability); }
@ -223,7 +223,7 @@ SINGLE_BATTLE_TEST("Infiltrator doesn't ignore a battler's Substitute when using
PARAMETRIZE { ability = ABILITY_INFILTRATOR; move = MOVE_SKY_DROP; }
GIVEN {
WITH_CONFIG(CONFIG_INFILTRATOR_SUBSTITUTE, GEN_6);
WITH_CONFIG(B_INFILTRATOR_SUBSTITUTE, GEN_6);
ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
ASSUME(GetMoveEffect(MOVE_TRANSFORM) == EFFECT_TRANSFORM);
ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP);

View File

@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Inner Focus doesn't prevent intimidate (Gen3-7)")
s16 turnTwoHit;
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_7);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_7);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_ZUBAT) { Ability(ABILITY_INNER_FOCUS); }
@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Inner Focus prevents intimidate (Gen8+)")
s16 turnTwoHit;
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_8);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_8);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_ZUBAT) { Ability(ABILITY_INNER_FOCUS); }

View File

@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Intrepid Sword raises Attack by one stage")
SINGLE_BATTLE_TEST("Intrepid Sword raises Attack by one stage every time it switches in (Gen8)")
{
GIVEN {
WITH_CONFIG(CONFIG_INTREPID_SWORD, GEN_8);
WITH_CONFIG(B_INTREPID_SWORD, GEN_8);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); }
OPPONENT(SPECIES_WYNAUT);
@ -42,7 +42,7 @@ SINGLE_BATTLE_TEST("Intrepid Sword raises Attack by one stage every time it swit
SINGLE_BATTLE_TEST("Intrepid Sword raises Attack by one stage only once per battle (Gen9+)")
{
GIVEN {
WITH_CONFIG(CONFIG_INTREPID_SWORD, GEN_9);
WITH_CONFIG(B_INTREPID_SWORD, GEN_9);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); }
OPPONENT(SPECIES_WYNAUT);

View File

@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye prevent accuracy stag
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
GIVEN {
WITH_CONFIG(CONFIG_ILLUMINATE_EFFECT, GEN_9);
WITH_CONFIG(B_ILLUMINATE_EFFECT, GEN_9);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
} WHEN {
@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye ignore target's evasi
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
GIVEN {
WITH_CONFIG(CONFIG_ILLUMINATE_EFFECT, GEN_9);
WITH_CONFIG(B_ILLUMINATE_EFFECT, GEN_9);
ASSUME(GetMoveEffect(MOVE_DOUBLE_TEAM) == EFFECT_EVASION_UP);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
@ -81,7 +81,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye are ignored by Mold B
PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SCRATCH) * 3 / 4, 100, RNG_ACCURACY);
GIVEN {
WITH_CONFIG(CONFIG_ILLUMINATE_EFFECT, GEN_9);
WITH_CONFIG(B_ILLUMINATE_EFFECT, GEN_9);
PLAYER(speciesPlayer) { Ability(abilityPlayer); }
OPPONENT(speciesOpponent) { Ability(abilityOpponent); }
} WHEN {
@ -104,7 +104,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent Topsy-T
PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; }
GIVEN {
WITH_CONFIG(CONFIG_ILLUMINATE_EFFECT, GEN_9);
WITH_CONFIG(B_ILLUMINATE_EFFECT, GEN_9);
ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP);
ASSUME(GetMoveEffect(MOVE_TOPSY_TURVY) == EFFECT_TOPSY_TURVY);
PLAYER(SPECIES_WOBBUFFET);
@ -144,7 +144,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent receivi
PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; }
GIVEN {
WITH_CONFIG(CONFIG_ILLUMINATE_EFFECT, GEN_9);
WITH_CONFIG(B_ILLUMINATE_EFFECT, GEN_9);
ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@ -177,7 +177,7 @@ SINGLE_BATTLE_TEST("Keen Eye & Gen9+ Illuminate don't prevent Spectral Thief fro
PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; }
GIVEN {
WITH_CONFIG(CONFIG_ILLUMINATE_EFFECT, GEN_9);
WITH_CONFIG(B_ILLUMINATE_EFFECT, GEN_9);
ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP);
ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_STEAL_STATS));
PLAYER(SPECIES_WOBBUFFET);

View File

@ -125,7 +125,7 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun (Gen 5+)")
PARAMETRIZE { gen = GEN_4; }
PARAMETRIZE { gen = GEN_5; }
GIVEN {
WITH_CONFIG(CONFIG_LEAF_GUARD_PREVENTS_REST, gen);
WITH_CONFIG(B_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);
@ -155,7 +155,7 @@ SINGLE_BATTLE_TEST("Leaf Guard doesn't prevent Rest if Cloud Nine/Air Lock is on
PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
GIVEN {
WITH_CONFIG(CONFIG_LEAF_GUARD_PREVENTS_REST, GEN_5);
WITH_CONFIG(B_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); }

View File

@ -1,4 +1,30 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("TODO: Write Light Metal (Ability) test titles")
SINGLE_BATTLE_TEST("Light Metal and Heavy Metal affect the power of Low Kick", s16 damage)
{
enum Ability ability;
PARAMETRIZE { ability = ABILITY_LIGHT_METAL; } // 10.0 - 24.9 kg (40 power)
PARAMETRIZE { ability = ABILITY_STALWART; } // 25.0 - 49.9 kg (60 power)
PARAMETRIZE { ability = ABILITY_HEAVY_METAL; } // 50.0 - 99.9 kg (80 power)
GIVEN {
ASSUME(GetMoveEffect(MOVE_SOAK) == EFFECT_SOAK);
ASSUME(GetMoveArgType(MOVE_SOAK) == TYPE_WATER);
ASSUME(GetSpeciesWeight(SPECIES_DURALUDON) == 400);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_DURALUDON) { Ability(ability); }
} WHEN {
TURN { MOVE(player, MOVE_SOAK); } // To remove super-effectiveness, as it was messing with calculations.
TURN { MOVE(player, MOVE_LOW_KICK); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_LOW_KICK, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} THEN {
// Calc 20 power increase, with the first iteration being 40 power
if (i != 0)
EXPECT_MUL_EQ(results[0].damage, Q_4_12((i * 0.5) + 1), results[i].damage);
}
}
TO_DO_BATTLE_TEST("Light Metal and Heavy Metal don't affect Heavy Ball's multiplier")

View File

@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the
PARAMETRIZE { config = GEN_4; }
PARAMETRIZE { config = GEN_5; }
GIVEN {
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, config);
ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); }
@ -47,7 +47,7 @@ DOUBLE_BATTLE_TEST("Lightning Rod forces single-target Electric-type moves to ta
PARAMETRIZE { config = GEN_4; }
PARAMETRIZE { config = GEN_5; }
GIVEN {
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, config);
ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
@ -115,7 +115,7 @@ DOUBLE_BATTLE_TEST("Lightning Rod redirects an ally's attack")
DOUBLE_BATTLE_TEST("Lightning Rod absorbs moves that targets all battlers but does not redirect (Gen6+)")
{
GIVEN {
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, GEN_5);
ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);

View File

@ -142,7 +142,7 @@ SINGLE_BATTLE_TEST("Liquid Ooze causes Dream Eater users to lose HP instead of h
{
s16 damage;
GIVEN {
WITH_CONFIG(CONFIG_DREAM_EATER_LIQUID_OOZE, GEN_5);
WITH_CONFIG(B_DREAM_EATER_LIQUID_OOZE, GEN_5);
ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_NON_VOLATILE_STATUS);
ASSUME(GetMoveNonVolatileStatus(MOVE_SPORE) == MOVE_EFFECT_SLEEP);
ASSUME(GetMoveEffect(MOVE_DREAM_EATER) == EFFECT_DREAM_EATER);
@ -167,7 +167,7 @@ SINGLE_BATTLE_TEST("Liquid Ooze does not cause Dream Eater users to lose HP inst
{
s16 damage;
GIVEN {
WITH_CONFIG(CONFIG_DREAM_EATER_LIQUID_OOZE, GEN_3);
WITH_CONFIG(B_DREAM_EATER_LIQUID_OOZE, GEN_3);
ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_NON_VOLATILE_STATUS);
ASSUME(GetMoveNonVolatileStatus(MOVE_SPORE) == MOVE_EFFECT_SLEEP);
ASSUME(GetMoveEffect(MOVE_DREAM_EATER) == EFFECT_DREAM_EATER);

View File

@ -81,7 +81,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(CONFIG_POWDER_GRASS, GEN_6);
WITH_CONFIG(B_POWDER_GRASS, GEN_6);
ASSUME(IsPowderMove(MOVE_STUN_SPORE));
ASSUME(GetSpeciesType(SPECIES_ODDISH, 0) == TYPE_GRASS);
PLAYER(SPECIES_ODDISH);

View File

@ -11,7 +11,7 @@ SINGLE_BATTLE_TEST("Moody randomly raises the user's Attack, Defense, Sp. Atk, S
// HP is not included
PASSES_RANDOMLY(1, statsNum - 1, RNG_MOODY_INCREASE);
GIVEN {
WITH_CONFIG(CONFIG_MOODY_ACC_EVASION, config);
WITH_CONFIG(B_MOODY_ACC_EVASION, config);
PLAYER(SPECIES_OCTILLERY) { Ability(ABILITY_MOODY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Moody randomly lowers the user's Attack, Defense, Sp. Atk, S
// One stat becomes unavailable due to it already increasing
PASSES_RANDOMLY(1, statsNum - 2, RNG_MOODY_DECREASE);
GIVEN {
WITH_CONFIG(CONFIG_MOODY_ACC_EVASION, config);
WITH_CONFIG(B_MOODY_ACC_EVASION, config);
PLAYER(SPECIES_OCTILLERY) { Ability(ABILITY_MOODY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Moody randomly raises the holder's Attack, Defense, Sp. Atk,
PASSES_RANDOMLY(statsNum - 1, statsNum - 1, RNG_MOODY_DECREASE);
GIVEN {
WITH_CONFIG(CONFIG_MOODY_ACC_EVASION, config);
WITH_CONFIG(B_MOODY_ACC_EVASION, config);
PLAYER(SPECIES_OCTILLERY) { Ability(ABILITY_MOODY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -87,7 +87,7 @@ SINGLE_BATTLE_TEST("Normalize doesn't boost power of unaffected moves by 20% (<
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, GEN_6);
WITH_CONFIG(B_ATE_MULTIPLIER, GEN_6);
PLAYER(SPECIES_DELCATTY) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -106,7 +106,7 @@ SINGLE_BATTLE_TEST("Normalize boosts power of unaffected moves by 20% (Gen7+)",
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, GEN_7);
WITH_CONFIG(B_ATE_MULTIPLIER, GEN_7);
PLAYER(SPECIES_DELCATTY) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -125,7 +125,7 @@ SINGLE_BATTLE_TEST("Normalize doesn't boost power of affected moves by 20% (< Ge
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, GEN_6);
WITH_CONFIG(B_ATE_MULTIPLIER, GEN_6);
PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_WATER_GUN); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -144,7 +144,7 @@ SINGLE_BATTLE_TEST("Normalize boosts power of affected moves by 20% (Gen7+)", s1
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, GEN_7);
WITH_CONFIG(B_ATE_MULTIPLIER, GEN_7);
PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_WATER_GUN); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Taunt (Gen6+)")
PARAMETRIZE { gen = GEN_5; }
PARAMETRIZE { gen = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_OBLIVIOUS_TAUNT, gen);
WITH_CONFIG(B_OBLIVIOUS_TAUNT, gen);
ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT);
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); }
OPPONENT(SPECIES_WOBBUFFET);
@ -66,7 +66,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Taunt (Gen6+)")
SINGLE_BATTLE_TEST("Oblivious doesn't prevent Intimidate (Gen3-7)")
{
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_7);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_7);
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
@ -86,7 +86,7 @@ SINGLE_BATTLE_TEST("Oblivious doesn't prevent Intimidate (Gen3-7)")
SINGLE_BATTLE_TEST("Oblivious prevents Intimidate (Gen8+)")
{
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_8);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_8);
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
@ -99,3 +99,29 @@ SINGLE_BATTLE_TEST("Oblivious prevents Intimidate (Gen8+)")
MESSAGE("Slowpoke's Oblivious prevents stat loss!");
}
}
SINGLE_BATTLE_TEST("Oblivious cured infatuation should not persist toxic counter after switching")
{
s16 firstTick, secondTick, postSwitchTick;
GIVEN {
ASSUME(GetMoveEffect(MOVE_ATTRACT) == EFFECT_ATTRACT);
ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); Status1(STATUS1_TOXIC_POISON); MaxHP(160); HP(160); Speed(100); }
PLAYER(SPECIES_WYNAUT) { Speed(90); }
OPPONENT(SPECIES_SLOWPOKE) { Gender(MON_FEMALE); Ability(ABILITY_OBLIVIOUS); Speed(80); }
} WHEN {
TURN { MOVE(opponent, MOVE_ATTRACT); }
TURN { MOVE(opponent, MOVE_SKILL_SWAP); }
TURN { SWITCH(player, 1); }
TURN { SWITCH(player, 0); }
} SCENE {
HP_BAR(player, captureDamage: &firstTick);
HP_BAR(player, captureDamage: &secondTick);
HP_BAR(player, captureDamage: &postSwitchTick);
} THEN {
EXPECT_EQ(firstTick, 10);
EXPECT_EQ(secondTick, 20);
EXPECT_EQ(postSwitchTick, 10);
}
}

View File

@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Overcoat blocks powder and spore moves (Gen6+)")
PARAMETRIZE { gen = GEN_5; }
PARAMETRIZE { gen = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_POWDER_OVERCOAT, gen);
WITH_CONFIG(B_POWDER_OVERCOAT, gen);
ASSUME(IsPowderMove(MOVE_STUN_SPORE));
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_PINECO) { Ability(ABILITY_OVERCOAT); }
@ -78,7 +78,7 @@ SINGLE_BATTLE_TEST("Overcoat blocks Effect Spore's effect (Gen6+)")
PARAMETRIZE { config = GEN_5; }
PARAMETRIZE { config = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_POWDER_OVERCOAT, config);
WITH_CONFIG(B_POWDER_OVERCOAT, config);
PLAYER(SPECIES_PINECO) { Ability(ABILITY_OVERCOAT); }
OPPONENT(SPECIES_SHROOMISH) { Ability(ABILITY_EFFECT_SPORE); }
} WHEN {

View File

@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Own Tempo doesn't prevent Intimidate (Gen3-7)")
{
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_7);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_7);
ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }
@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Own Tempo doesn't prevent Intimidate (Gen3-7)")
SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes (Gen8+)")
{
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_8);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_8);
ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }
@ -143,3 +143,29 @@ SINGLE_BATTLE_TEST("Own Tempo prevents confusion from items")
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
}
}
SINGLE_BATTLE_TEST("Own Tempo cured confusion should not persist toxic counter after switching")
{
s16 firstTick, secondTick, postSwitchTick;
GIVEN {
ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_TOXIC_POISON); MaxHP(160); HP(160); Speed(100); }
PLAYER(SPECIES_WYNAUT) { Speed(90); }
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); Speed(80); }
} WHEN {
TURN { MOVE(opponent, MOVE_CONFUSE_RAY); }
TURN { MOVE(opponent, MOVE_SKILL_SWAP); MOVE(player, MOVE_CELEBRATE, WITH_RNG(RNG_CONFUSION, FALSE)); }
TURN { SWITCH(player, 1); }
TURN { SWITCH(player, 0); }
} SCENE {
HP_BAR(player, captureDamage: &firstTick);
HP_BAR(player, captureDamage: &secondTick);
HP_BAR(player, captureDamage: &postSwitchTick);
} THEN {
EXPECT_EQ(firstTick, 10);
EXPECT_EQ(secondTick, 20);
EXPECT_EQ(postSwitchTick, 10);
}
}

View File

@ -112,7 +112,7 @@ SINGLE_BATTLE_TEST("Parental Bond-converted moves only hit once on Lightning Rod
PARAMETRIZE { move = MOVE_THUNDERBOLT; ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; type = TYPE_ELECTRIC; }
PARAMETRIZE { move = MOVE_SURF; ability = ABILITY_STORM_DRAIN; species = SPECIES_LILEEP; type = TYPE_WATER; }
GIVEN {
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, GEN_5);
ASSUME(GetMoveStrikeCount(move) < 2);
ASSUME(GetMoveType(move) == type);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
@ -143,7 +143,7 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
PASSES_RANDOMLY(passes, trials, RNG_HITS);
GIVEN {
WITH_CONFIG(CONFIG_MULTI_HIT_CHANCE, genConfig);
WITH_CONFIG(B_MULTI_HIT_CHANCE, genConfig);
ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
ASSUME(IsMultiHitMove(MOVE_COMET_PUNCH));
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
@ -172,7 +172,7 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
PASSES_RANDOMLY(passes, trials, RNG_HITS);
GIVEN {
WITH_CONFIG(CONFIG_MULTI_HIT_CHANCE, genConfig);
WITH_CONFIG(B_MULTI_HIT_CHANCE, genConfig);
ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
ASSUME(IsMultiHitMove(MOVE_COMET_PUNCH));
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
@ -202,7 +202,7 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
PASSES_RANDOMLY(passes, trials, RNG_HITS);
GIVEN {
WITH_CONFIG(CONFIG_MULTI_HIT_CHANCE, genConfig);
WITH_CONFIG(B_MULTI_HIT_CHANCE, genConfig);
ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
ASSUME(IsMultiHitMove(MOVE_COMET_PUNCH));
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
@ -233,7 +233,7 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
PASSES_RANDOMLY(passes, trials, RNG_HITS);
GIVEN {
WITH_CONFIG(CONFIG_MULTI_HIT_CHANCE, genConfig);
WITH_CONFIG(B_MULTI_HIT_CHANCE, genConfig);
ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
ASSUME(IsMultiHitMove(MOVE_COMET_PUNCH));
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }

View File

@ -311,6 +311,35 @@ SINGLE_BATTLE_TEST("Pickpocket does not prevent King's Rock or Razor Fang flinch
}
}
SINGLE_BATTLE_TEST("Pickpocket activates when user has Protective Pads, but not with Punching Glove or Long Reach")
{
u32 item, ability;
PARAMETRIZE { item = ITEM_PROTECTIVE_PADS; ability = ABILITY_OVERGROW; }
PARAMETRIZE { item = ITEM_PUNCHING_GLOVE; ability = ABILITY_OVERGROW; }
PARAMETRIZE { item = ITEM_NONE; ability = ABILITY_LONG_REACH; }
GIVEN {
ASSUME(MoveMakesContact(MOVE_MACH_PUNCH));
ASSUME(IsPunchingMove(MOVE_MACH_PUNCH));
ASSUME(GetItemHoldEffect(ITEM_PROTECTIVE_PADS) == HOLD_EFFECT_PROTECTIVE_PADS);
ASSUME(GetItemHoldEffect(ITEM_PUNCHING_GLOVE) == HOLD_EFFECT_PUNCHING_GLOVE);
ASSUME(GetItemHoldEffect(ITEM_FOCUS_SASH) == HOLD_EFFECT_FOCUS_SASH);
PLAYER(SPECIES_DECIDUEYE) { Ability(ability); Item(item); }
OPPONENT(SPECIES_SNEASEL) { Ability(ABILITY_PICKPOCKET); Item(ITEM_FOCUS_SASH); }
} WHEN {
TURN { MOVE(player, MOVE_MACH_PUNCH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MACH_PUNCH, player);
if (item == ITEM_PROTECTIVE_PADS) {
ABILITY_POPUP(opponent, ABILITY_PICKPOCKET);
} else {
NOT ABILITY_POPUP(opponent, ABILITY_PICKPOCKET);
}
}
}
SINGLE_BATTLE_TEST("Pickpocket activates after an Item was knocked off")
{
GIVEN {
@ -327,3 +356,4 @@ SINGLE_BATTLE_TEST("Pickpocket activates after an Item was knocked off")
EXPECT(player->item == ITEM_NONE);
}
}

View File

@ -26,7 +26,7 @@ SINGLE_BATTLE_TEST("Pickup grants an item used by another Pokémon")
WILD_BATTLE_TEST("Pickup grants an item used by itself in wild battles (Gen9+)")
{
GIVEN {
WITH_CONFIG(CONFIG_PICKUP_WILD, GEN_9);
WITH_CONFIG(B_PICKUP_WILD, GEN_9);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -31,7 +31,7 @@ SINGLE_BATTLE_TEST("Pixilate boosts power of affected moves by 20% (Gen7+) or 30
PARAMETRIZE { ability = ABILITY_PIXILATE; genConfig = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, genConfig);
WITH_CONFIG(B_ATE_MULTIPLIER, genConfig);
PLAYER(SPECIES_SYLVEON) { Ability(ability); Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -38,7 +38,7 @@ SINGLE_BATTLE_TEST("Poison Point triggers 1/3 times (Gen3) or 30% (Gen 4+) of th
PARAMETRIZE { config = GEN_4; passes = 3; trials = 10; } // 30%
PASSES_RANDOMLY(passes, trials, RNG_POISON_POINT);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_NIDORAN_M) { Ability(ABILITY_POISON_POINT); }

View File

@ -75,3 +75,38 @@ SINGLE_BATTLE_TEST("Poison Touch applies between multi-hit move hits")
STATUS_ICON(opponent, poison: TRUE);
}
}
SINGLE_BATTLE_TEST("Poison Touch activates when user has Protective Pads, but not with Punching Glove")
{
u32 item;
PARAMETRIZE { item = ITEM_PROTECTIVE_PADS; }
PARAMETRIZE { item = ITEM_PUNCHING_GLOVE; }
GIVEN {
ASSUME(MoveMakesContact(MOVE_MACH_PUNCH));
ASSUME(IsPunchingMove(MOVE_MACH_PUNCH));
ASSUME(GetItemHoldEffect(ITEM_PROTECTIVE_PADS) == HOLD_EFFECT_PROTECTIVE_PADS);
ASSUME(GetItemHoldEffect(ITEM_PUNCHING_GLOVE) == HOLD_EFFECT_PUNCHING_GLOVE);
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_MACH_PUNCH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MACH_PUNCH, player);
if (item != ITEM_PUNCHING_GLOVE) {
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("The opposing Wobbuffet was poisoned by Grimer's Poison Touch!");
STATUS_ICON(opponent, poison: TRUE);
} else {
NONE_OF {
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("The opposing Wobbuffet was poisoned by Grimer's Poison Touch!");
STATUS_ICON(opponent, poison: TRUE);
}
}
}
}

View File

@ -13,7 +13,7 @@ SINGLE_BATTLE_TEST("Prankster-affected moves don't affect Dark-type Pokémon (Ge
PARAMETRIZE { gen = GEN_6; }
PARAMETRIZE { gen = GEN_7; }
GIVEN {
WITH_CONFIG(CONFIG_PRANKSTER_DARK_TYPES, gen);
WITH_CONFIG(B_PRANKSTER_DARK_TYPES, gen);
PLAYER(SPECIES_UMBREON);
OPPONENT(SPECIES_VOLBEAT) { Ability(ABILITY_PRANKSTER); }
} WHEN {
@ -31,7 +31,7 @@ SINGLE_BATTLE_TEST("Prankster-affected moves don't affect Dark-type Pokémon (Ge
SINGLE_BATTLE_TEST("Prankster-affected moves don't affect Dark-type Pokémon after they switch-in")
{
GIVEN {
WITH_CONFIG(CONFIG_PRANKSTER_DARK_TYPES, GEN_7);
WITH_CONFIG(B_PRANKSTER_DARK_TYPES, GEN_7);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_UMBREON);
OPPONENT(SPECIES_VOLBEAT) { Ability(ABILITY_PRANKSTER); }
@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Prankster-affected moves called via Assist don't affect Dark
PARAMETRIZE { gen = GEN_6; }
PARAMETRIZE { gen = GEN_7; }
GIVEN {
WITH_CONFIG(CONFIG_PRANKSTER_DARK_TYPES, gen);
WITH_CONFIG(B_PRANKSTER_DARK_TYPES, gen);
PLAYER(SPECIES_UMBREON);
OPPONENT(SPECIES_VOLBEAT) { Ability(ABILITY_PRANKSTER); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CONFUSE_RAY); }
@ -87,7 +87,7 @@ DOUBLE_BATTLE_TEST("Prankster-affected moves called via Instruct do not affect D
PARAMETRIZE { gen = GEN_6; }
PARAMETRIZE { gen = GEN_7; }
GIVEN {
WITH_CONFIG(CONFIG_PRANKSTER_DARK_TYPES, gen);
WITH_CONFIG(B_PRANKSTER_DARK_TYPES, gen);
PLAYER(SPECIES_VOLBEAT) { Speed(20); Ability(ABILITY_PRANKSTER); }
PLAYER(SPECIES_WOBBUFFET) { Speed(10); }
OPPONENT(SPECIES_UMBREON) { Speed(15); }
@ -203,7 +203,7 @@ SINGLE_BATTLE_TEST("Prankster-affected moves which are reflected by Magic Coat c
PARAMETRIZE { sableyeAbility = ABILITY_KEEN_EYE; }
GIVEN {
WITH_CONFIG(CONFIG_PRANKSTER_DARK_TYPES, GEN_7);
WITH_CONFIG(B_PRANKSTER_DARK_TYPES, GEN_7);
PLAYER(SPECIES_SABLEYE) { Ability(sableyeAbility); }
OPPONENT(SPECIES_MURKROW) { Ability(ABILITY_PRANKSTER); }
} WHEN {

View File

@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Protean/Libero changes the type of the user to the move used
PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; }
PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
WITH_CONFIG(CONFIG_PROTEAN_LIBERO, GEN_6);
WITH_CONFIG(B_PROTEAN_LIBERO, GEN_6);
PLAYER(SPECIES_REGIROCK);
OPPONENT(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
@ -45,7 +45,7 @@ SINGLE_BATTLE_TEST("Protean/Libero changes the type of the user only once per sw
PARAMETRIZE { ability = ABILITY_PROTEAN; species = SPECIES_KECLEON; }
PARAMETRIZE { ability = ABILITY_LIBERO; species = SPECIES_RABOOT; }
GIVEN {
WITH_CONFIG(CONFIG_PROTEAN_LIBERO, GEN_9);
WITH_CONFIG(B_PROTEAN_LIBERO, GEN_9);
PLAYER(SPECIES_REGIROCK);
OPPONENT(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);

View File

@ -59,7 +59,7 @@ SINGLE_BATTLE_TEST("Protosynthesis ability pop up activates only once during the
u16 turns;
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_WALKING_WAKE) { Ability(ABILITY_PROTOSYNTHESIS); }
OPPONENT(SPECIES_NINETALES) { Ability(ABILITY_DROUGHT); }
} WHEN {

View File

@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when hit by Bug, Dark or Ghost typ
SINGLE_BATTLE_TEST("Rattled does not boost speed by 1 when affected by Intimidate (Gen5-7)")
{
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_7);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_7);
PLAYER(SPECIES_GYARADOS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_SUDOWOODO) { Ability(ABILITY_RATTLED); }
} WHEN {
@ -75,7 +75,7 @@ SINGLE_BATTLE_TEST("Rattled does not boost speed by 1 when affected by Intimidat
SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when affected by Intimidate (Gen8+)")
{
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_8);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_8);
PLAYER(SPECIES_GYARADOS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_SUDOWOODO) { Ability(ABILITY_RATTLED); }
} WHEN {

View File

@ -30,7 +30,7 @@ SINGLE_BATTLE_TEST("Refrigerate boosts power of affected moves by 20% (Gen7+) or
PARAMETRIZE { ability = ABILITY_REFRIGERATE; genConfig = GEN_6; }
GIVEN {
WITH_CONFIG(CONFIG_ATE_MULTIPLIER, genConfig);
WITH_CONFIG(B_ATE_MULTIPLIER, genConfig);
PLAYER(SPECIES_AMAURA) { Ability(ability); Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Refrigerate doesn't affect Weather Ball's type", s16 damage)
PARAMETRIZE { move = MOVE_CELEBRATE; ability = ABILITY_REFRIGERATE; }
PARAMETRIZE { move = MOVE_SUNNY_DAY; ability = ABILITY_REFRIGERATE; }
GIVEN {
WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_9); //To prevent capturing hail damage
WITH_CONFIG(B_SNOW_WARNING, GEN_9); //To prevent capturing hail damage
ASSUME(GetMoveEffect(MOVE_WEATHER_BALL) == EFFECT_WEATHER_BALL);
ASSUME(GetSpeciesType(SPECIES_PINSIR, 0) == TYPE_BUG);
PLAYER(SPECIES_AMAURA) { Ability(ability); }

View File

@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Sand Stream sets up sandstorm for 5 turns (Gen6+)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_HIPPOWDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_STREAM); }
OPPONENT(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -26,7 +26,7 @@ SINGLE_BATTLE_TEST("Sand Stream sets up sandstorm for 5 turns (Gen6+)")
SINGLE_BATTLE_TEST("Sand Stream sets up sandstorm for 8 turns with Smooth Rock (Gen6+)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_HIPPOWDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_STREAM); Item(ITEM_SMOOTH_ROCK); }
OPPONENT(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Sand Stream sets up sandstorm for 8 turns with Smooth Rock (
SINGLE_BATTLE_TEST("Sand Stream sets up permanent sandstorm (Gen3-5)")
{
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_3);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_3);
PLAYER(SPECIES_HIPPOWDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_STREAM); }
OPPONENT(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); }
} WHEN {

View File

@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Scrappy doesn't prevent Intimidate (Gen4-7)")
s16 turnTwoHit;
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_7);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_7);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_KANGASKHAN) { Ability(ABILITY_SCRAPPY); }
@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Scrappy prevents Intimidate (Gen8+)")
s16 turnTwoHit;
GIVEN {
WITH_CONFIG(CONFIG_UPDATED_INTIMIDATE, GEN_8);
WITH_CONFIG(B_UPDATED_INTIMIDATE, GEN_8);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
OPPONENT(SPECIES_KANGASKHAN) { Ability(ABILITY_SCRAPPY); }

View File

@ -10,7 +10,7 @@ SINGLE_BATTLE_TEST("Shed Skin triggers 33% (Gen3, Gen5+) or 30% (Gen 4) of the t
PASSES_RANDOMLY(passes, 100, RNG_SHED_SKIN);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ARBOK) { Status1(STATUS1_POISON); Ability(ABILITY_SHED_SKIN); }

View File

@ -4,8 +4,8 @@
SINGLE_BATTLE_TEST("Snow Warning sets up hail for 5 turns (Gen6-8)")
{
GIVEN {
WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_8);
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_SNOW_WARNING, GEN_8);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -27,8 +27,8 @@ SINGLE_BATTLE_TEST("Snow Warning sets up hail for 5 turns (Gen6-8)")
SINGLE_BATTLE_TEST("Snow Warning sets up hail for 8 turns with Icy Rock (Gen6-8)")
{
GIVEN {
WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_8);
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6);
WITH_CONFIG(B_SNOW_WARNING, GEN_8);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_6);
PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); Item(ITEM_ICY_ROCK); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -56,8 +56,8 @@ SINGLE_BATTLE_TEST("Snow Warning sets up hail for 8 turns with Icy Rock (Gen6-8)
SINGLE_BATTLE_TEST("Snow Warning sets up permanent hail (Gen4-5)")
{
GIVEN {
WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_8);
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_5);
WITH_CONFIG(B_SNOW_WARNING, GEN_8);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_5);
PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -88,8 +88,8 @@ SINGLE_BATTLE_TEST("Snow Warning sets up permanent hail (Gen4-5)")
SINGLE_BATTLE_TEST("Snow Warning sets up snow for 5 turns (Gen9+)")
{
GIVEN {
WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_9);
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_9);
WITH_CONFIG(B_SNOW_WARNING, GEN_9);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_9);
PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {
@ -111,8 +111,8 @@ SINGLE_BATTLE_TEST("Snow Warning sets up snow for 5 turns (Gen9+)")
SINGLE_BATTLE_TEST("Snow Warning sets up snow for 8 turns with Icy Rock (Gen9+)")
{
GIVEN {
WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_9);
WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_9);
WITH_CONFIG(B_SNOW_WARNING, GEN_9);
WITH_CONFIG(B_ABILITY_WEATHER, GEN_9);
PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); Item(ITEM_ICY_ROCK); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); }
} WHEN {

View File

@ -27,7 +27,7 @@ DOUBLE_BATTLE_TEST("Stalwart stops Lightning Rod and Storm Drain from redirectin
PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; config = GEN_4; }
PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; config = GEN_5; }
GIVEN {
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, config);
ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC);
ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_STALWART); }

View File

@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Static triggers 1/3 times (Gen3) or 30% (Gen4+) of the time"
PARAMETRIZE { config = GEN_4; passes = 3; trials = 10; } // 30%
PASSES_RANDOMLY(passes, trials, RNG_STATIC);
GIVEN {
WITH_CONFIG(CONFIG_ABILITY_TRIGGER_CHANCE, config);
WITH_CONFIG(B_ABILITY_TRIGGER_CHANCE, config);
ASSUME(MoveMakesContact(MOVE_SCRATCH));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }

View File

@ -31,7 +31,7 @@ SINGLE_BATTLE_TEST("Sticky Hold prevents Incinerate from destroying berries")
SINGLE_BATTLE_TEST("Sticky Hold prevents Incinerate from destroying gems")
{
GIVEN {
WITH_CONFIG(CONFIG_INCINERATE_GEMS, GEN_6);
WITH_CONFIG(B_INCINERATE_GEMS, GEN_6);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_INCINERATE); }
OPPONENT(SPECIES_GASTRODON) { Ability(ABILITY_STICKY_HOLD); Item(ITEM_GHOST_GEM); }
} WHEN {

View File

@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. A
PARAMETRIZE { config = GEN_4; }
PARAMETRIZE { config = GEN_5; }
GIVEN {
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, config);
ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GASTRODON_EAST) { Ability(ABILITY_STORM_DRAIN); }
@ -41,7 +41,7 @@ DOUBLE_BATTLE_TEST("Storm Drain forces single-target Water-type moves to target
PARAMETRIZE { config = GEN_4; }
PARAMETRIZE { config = GEN_5; }
GIVEN {
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, config);
ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);

View File

@ -24,7 +24,7 @@ SINGLE_BATTLE_TEST("Sturdy prevents OHKOs (Gen5+)")
PARAMETRIZE { config = GEN_4; }
PARAMETRIZE { config = GEN_5; }
GIVEN {
WITH_CONFIG(CONFIG_STURDY, config);
WITH_CONFIG(B_STURDY, config);
PLAYER(SPECIES_GEODUDE) { Ability(ABILITY_STURDY); MaxHP(100); HP(100); }
PLAYER(SPECIES_GEODUDE);
OPPONENT(SPECIES_WOBBUFFET);

View File

@ -11,7 +11,7 @@ SINGLE_BATTLE_TEST("Super Luck increases the critical hit ratio by 1 stage")
PASSES_RANDOMLY(passes, trials, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(GetSpeciesBaseSpeed(SPECIES_TOGEPI) == 20);
WITH_CONFIG(CONFIG_CRIT_CHANCE, genConfig);
WITH_CONFIG(B_CRIT_CHANCE, genConfig);
PLAYER(SPECIES_TOGEPI) { Ability(ABILITY_SUPER_LUCK); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -137,7 +137,7 @@ DOUBLE_BATTLE_TEST("Symbiosis transfers its item after Gem consumption and move
{
GIVEN {
ASSUME(GetItemHoldEffect(ITEM_NORMAL_GEM) == HOLD_EFFECT_GEMS);
WITH_CONFIG(CONFIG_SYMBIOSIS_GEMS, GEN_7);
WITH_CONFIG(B_SYMBIOSIS_GEMS, GEN_7);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); }
PLAYER(SPECIES_ORANGURU) { Ability(ABILITY_SYMBIOSIS); Item(ITEM_TOXIC_ORB); }
OPPONENT(SPECIES_WOBBUFFET);
@ -160,7 +160,7 @@ DOUBLE_BATTLE_TEST("Symbiosis transfers its item after Gem consumption, but befo
{
GIVEN {
ASSUME(GetItemHoldEffect(ITEM_NORMAL_GEM) == HOLD_EFFECT_GEMS);
WITH_CONFIG(CONFIG_SYMBIOSIS_GEMS, GEN_6);
WITH_CONFIG(B_SYMBIOSIS_GEMS, GEN_6);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); }
PLAYER(SPECIES_ORANGURU) { Ability(ABILITY_SYMBIOSIS); Item(ITEM_TOXIC_ORB); }
OPPONENT(SPECIES_WOBBUFFET);

View File

@ -9,7 +9,7 @@ SINGLE_BATTLE_TEST("Synchronize will mirror back non volatile status back at opp
GIVEN {
ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_NON_VOLATILE_STATUS);
ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC);
WITH_CONFIG(CONFIG_SYNCHRONIZE_TOXIC, config);
WITH_CONFIG(B_SYNCHRONIZE_TOXIC, config);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); }
} WHEN {
@ -30,7 +30,7 @@ SINGLE_BATTLE_TEST("Synchronize will mirror back non volatile status back at opp
SINGLE_BATTLE_TEST("Synchronize will still show up the ability pop up even if it fails")
{
GIVEN {
WITH_CONFIG(CONFIG_PARALYZE_ELECTRIC, GEN_6);
WITH_CONFIG(B_PARALYZE_ELECTRIC, GEN_6);
ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }
OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); }

View File

@ -2,3 +2,27 @@
#include "test/battle.h"
TO_DO_BATTLE_TEST("TODO: Write Tough Claws (Ability) test titles")
SINGLE_BATTLE_TEST("Tough Claws boosts contact moves when user has Protective Pads, but not with Punching Glove", s16 damage)
{
u32 item;
PARAMETRIZE { item = ITEM_PROTECTIVE_PADS; }
PARAMETRIZE { item = ITEM_PUNCHING_GLOVE; }
GIVEN {
ASSUME(MoveMakesContact(MOVE_MACH_PUNCH));
ASSUME(IsPunchingMove(MOVE_MACH_PUNCH));
ASSUME(GetItemHoldEffect(ITEM_PROTECTIVE_PADS) == HOLD_EFFECT_PROTECTIVE_PADS);
ASSUME(GetItemHoldEffect(ITEM_PUNCHING_GLOVE) == HOLD_EFFECT_PUNCHING_GLOVE);
PLAYER(SPECIES_BARBARACLE) { Ability(ABILITY_TOUGH_CLAWS); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_MACH_PUNCH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MACH_PUNCH, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[1].damage, UQ_4_12(1.18), results[0].damage); // 1.3 / 1.1 ~= 1.18
}
}

View File

@ -1,4 +1,35 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(MoveMakesContact(MOVE_SCRATCH));
ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT);
}
TO_DO_BATTLE_TEST("TODO: Write Unseen Fist (Ability) test titles")
SINGLE_BATTLE_TEST("Unseen Fist ignores Protect when user has Protective Pads, but not with Punching Glove", s16 damage)
{
u32 item;
PARAMETRIZE { item = ITEM_PROTECTIVE_PADS; }
PARAMETRIZE { item = ITEM_PUNCHING_GLOVE; }
GIVEN {
ASSUME(MoveMakesContact(MOVE_MACH_PUNCH));
ASSUME(IsPunchingMove(MOVE_MACH_PUNCH));
ASSUME(GetItemHoldEffect(ITEM_PROTECTIVE_PADS) == HOLD_EFFECT_PROTECTIVE_PADS);
ASSUME(GetItemHoldEffect(ITEM_PUNCHING_GLOVE) == HOLD_EFFECT_PUNCHING_GLOVE);
PLAYER(SPECIES_URSHIFU) { Ability(ABILITY_UNSEEN_FIST); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_MACH_PUNCH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent);
if (item != ITEM_PUNCHING_GLOVE)
ANIMATION(ANIM_TYPE_MOVE, MOVE_MACH_PUNCH, player);
else
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_MACH_PUNCH, player);
}
}

View File

@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Weak Armor lowers Defense by 1 and boosts Speed by 1 (Gen5-6
PARAMETRIZE { move = MOVE_GUST; gen = GEN_7; }
GIVEN {
WITH_CONFIG(CONFIG_WEAK_ARMOR_SPEED, gen);
WITH_CONFIG(B_WEAK_ARMOR_SPEED, gen);
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Weak Armor still boosts Speed if Defense can't go any lower"
PARAMETRIZE { gen = GEN_6; }
PARAMETRIZE { gen = GEN_7; }
GIVEN {
WITH_CONFIG(CONFIG_WEAK_ARMOR_SPEED, gen);
WITH_CONFIG(B_WEAK_ARMOR_SPEED, gen);
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -143,7 +143,7 @@ SINGLE_BATTLE_TEST("Weak Armor doesn't interrupt multi hit moves if Defense can'
{
u32 j;
GIVEN {
WITH_CONFIG(CONFIG_WEAK_ARMOR_SPEED, GEN_7);
WITH_CONFIG(B_WEAK_ARMOR_SPEED, GEN_7);
PLAYER(SPECIES_MAGCARGO) { Ability(ABILITY_WEAK_ARMOR); Defense(999); }
OPPONENT(SPECIES_CLOYSTER) { Ability(ABILITY_SKILL_LINK); }
} WHEN {
@ -182,7 +182,7 @@ SINGLE_BATTLE_TEST("Weak Armor doesn't interrupt multi hit moves if Speed can't
{
u32 j;
GIVEN {
WITH_CONFIG(CONFIG_WEAK_ARMOR_SPEED, GEN_7);
WITH_CONFIG(B_WEAK_ARMOR_SPEED, GEN_7);
PLAYER(SPECIES_MAGCARGO) { Ability(ABILITY_WEAK_ARMOR); Defense(999); }
OPPONENT(SPECIES_CLOYSTER) { Ability(ABILITY_SKILL_LINK); }
} WHEN {

View File

@ -687,7 +687,7 @@ AI_SINGLE_BATTLE_TEST("AI won't use thawing moves if target is frozen unless it
PARAMETRIZE { status = STATUS1_FROSTBITE; aiMove = MOVE_EMBER; aiFlags = AI_FLAG_CHECK_BAD_MOVE; }
GIVEN {
WITH_CONFIG(CONFIG_BURN_HIT_THAW, GEN_6); // In Gen 5, non-Fire burning moves didn't cause thawing
WITH_CONFIG(B_BURN_HIT_THAW, GEN_6); // In Gen 5, non-Fire burning moves didn't cause thawing
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
@ -834,7 +834,7 @@ AI_DOUBLE_BATTLE_TEST("AI sees opposing drain ability")
ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
ASSUME(GetMoveType(MOVE_RAZOR_LEAF) != TYPE_ELECTRIC);
ASSUME(GetMoveType(MOVE_METAL_CLAW) != TYPE_ELECTRIC);
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, GEN_5);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); Moves(MOVE_CELEBRATE); }
PLAYER(SPECIES_KRABBY) { Ability(ABILITY_VOLT_ABSORB); Moves(MOVE_CELEBRATE); }
@ -931,7 +931,7 @@ AI_SINGLE_BATTLE_TEST("AI will see Magnitude damage")
AI_SINGLE_BATTLE_TEST("AI will prefer resisted move over failing move")
{
GIVEN {
WITH_CONFIG(CONFIG_POWDER_GRASS, GEN_6);
WITH_CONFIG(B_POWDER_GRASS, GEN_6);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY);
PLAYER(SPECIES_ROSELIA) { Moves(MOVE_ABSORB); }
OPPONENT(SPECIES_GLOOM) { Moves(MOVE_MEGA_DRAIN, MOVE_STUN_SPORE, MOVE_LEECH_SEED, MOVE_SYNTHESIS); }
@ -1144,7 +1144,7 @@ AI_SINGLE_BATTLE_TEST("AI's Explosion scoring handles multiple move effects and
PARAMETRIZE { genConfig = GEN_4; passesChance = EXPLOSION_MAXIMUM_CHANCE; }
PASSES_RANDOMLY(passesChance, 100, RNG_AI_CONSIDER_EXPLOSION);
GIVEN {
WITH_CONFIG(CONFIG_EXPLOSION_DEFENSE, genConfig);
WITH_CONFIG(B_EXPLOSION_DEFENSE, genConfig);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_CLOYSTER) { Level(44); HP(68); Moves(MOVE_DETECT, MOVE_RAZOR_SHELL, MOVE_ICICLE_SPEAR, MOVE_ICE_SHARD); }
OPPONENT(SPECIES_GLALIE_MEGA) { Level(44); HP(1); Ability(ABILITY_REFRIGERATE); Friendship(MAX_FRIENDSHIP); Moves(MOVE_RETURN, MOVE_EARTHQUAKE, MOVE_EXPLOSION, MOVE_CRUNCH); }

View File

@ -18,7 +18,7 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Facade")
PARAMETRIZE { status1 = STATUS1_BURN; expectedMove = MOVE_FACADE; }
GIVEN {
WITH_CONFIG(CONFIG_BURN_FACADE_DMG, GEN_6);
WITH_CONFIG(B_BURN_FACADE_DMG, GEN_6);
ASSUME(GetMoveEffect(MOVE_FACADE) == EFFECT_FACADE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(60); }
@ -239,7 +239,7 @@ AI_DOUBLE_BATTLE_TEST("AI chooses moves that cure self or partner")
GIVEN {
ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL);
WITH_CONFIG(CONFIG_HEAL_BELL_SOUNDPROOF, GEN_8);
WITH_CONFIG(B_HEAL_BELL_SOUNDPROOF, GEN_8);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
@ -288,7 +288,7 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves that cure inactive party members")
GIVEN {
ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL);
WITH_CONFIG(CONFIG_HEAL_BELL_SOUNDPROOF, config);
WITH_CONFIG(B_HEAL_BELL_SOUNDPROOF, config);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_REGIROCK) { Moves(MOVE_BODY_PRESS, MOVE_HEAL_BELL); }

View File

@ -670,7 +670,6 @@ AI_DOUBLE_BATTLE_TEST("AI sees corresponding absorbing abilities on partners")
AI_DOUBLE_BATTLE_TEST("AI treats an ally's redirection ability appropriately (gen 4)")
{
KNOWN_FAILING;
ASSUME(GetMoveTarget(MOVE_DISCHARGE) == TARGET_FOES_AND_ALLY);
ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC);
ASSUME(GetMoveTarget(MOVE_SURF) == TARGET_FOES_AND_ALLY);
@ -717,7 +716,7 @@ AI_DOUBLE_BATTLE_TEST("AI treats an ally's redirection ability appropriately (ge
ASSUME(GetMoveTarget(MOVE_SURF) == TARGET_FOES_AND_ALLY);
ASSUME(GetMoveType(MOVE_SURF) == TYPE_WATER);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_HP_AWARE);
WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config);
WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, config);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Moves(move, MOVE_HEADBUTT); }

Some files were not shown because too many files have changed in this diff Show More