Merge branch '_RHH/master' into _RHH/upcoming

This commit is contained in:
Eduardo Quezada 2024-08-14 17:10:20 -04:00
commit 661ec0a9fd
77 changed files with 1500 additions and 237 deletions

View File

@ -1670,6 +1670,10 @@
callnative BS_DamageToQuarterTargetHP
.endm
.macro ficklebeamdamagecalculation
callnative BS_FickleBeamDamageCalculation
.endm
@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES

View File

@ -16219,6 +16219,12 @@ Move_RAGING_BULL::
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_ANGER
loadspritegfx ANIM_TAG_BREATH
loadspritegfx ANIM_TAG_BLUE_LIGHT_WALL
loadspritegfx ANIM_TAG_TORN_METAL
choosetwoturnanim RagingBullNormal, RagingBullShatteredWall
RagingBullNormal:
monbg ANIM_TARGET
setalpha 12, 8
createsprite gBreathPuffSpriteTemplate, ANIM_ATTACKER, 2
loopsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 4, 2
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, -20, -28
@ -16250,6 +16256,49 @@ Move_RAGING_BULL::
waitforvisualfinish
restorebg
waitbgfadein
clearmonbg ANIM_TARGET
end
RagingBullShatteredWall:
monbg ANIM_TARGET
setalpha 12, 8
createsprite gBreathPuffSpriteTemplate, ANIM_ATTACKER, 2
loopsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 4, 2
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, -20, -28
delay 20
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, -28
waitforvisualfinish
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 2, 4
waitforvisualfinish
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
call SetImpactBackground
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4
delay 3
waitforvisualfinish
createsprite gBrickBreakWallSpriteTemplate, ANIM_ATTACKER, 3, ANIM_TARGET, 0, 0, 90, 10
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -10, 0, ANIM_TARGET, 0
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -32, 0, 0, 3
delay 20
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 0
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 4, 0, 12, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
delay 20
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 1
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 1
waitforvisualfinish
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0, -8, -12
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 1, 8, -12
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 2, -8, 12
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 3, 8, 12
playsewithpan SE_M_BRICK_BREAK, SOUND_PAN_TARGET
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
delay 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 7
waitforvisualfinish
restorebg
waitbgfadein
clearmonbg ANIM_TARGET
end
@ Credits to Z-nogyroP. Simple anim that combines Force Palm + Fake Out
@ -17013,44 +17062,597 @@ Move_AXE_KICK::
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 4
end
Move_SPIN_OUT::
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_RAPID_SPIN
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 0, 0, RGB_BLACK
waitforvisualfinish
call SetHighSpeedBg
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 3
waitforvisualfinish
monbg ANIM_ATTACKER
createsprite gRapidSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 32, -32, 40, -2
createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 0
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 10, 1, 0
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
waitforvisualfinish
delay 8
createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 1
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4
waitforvisualfinish
call UnsetHighSpeedBg
clearmonbg ANIM_ATTACKER
end
Move_MORTAL_SPIN::
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_RAPID_SPIN
loadspritegfx ANIM_TAG_POISON_BUBBLE
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_RAPID_SPIN, 0, 6, 6, RGB(15, 0, 15)
monbg ANIM_ATTACKER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 1, 0, 13, RGB(10, 2, 19)
delay 16
createsprite gRapidSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 32, -32, 40, -2
createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 0
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 10, 1, 0
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 1, 13, 0, RGB(10, 2, 19)
call PoisonBubblesEffect
waitforvisualfinish
delay 8
createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 1
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
end
Move_FILLET_AWAY::
loadspritegfx ANIM_TAG_CUT
createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0
playsewithpan SE_M_CUT, SOUND_PAN_ATTACKER
delay 5
createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 20, -27, 0
playsewithpan SE_M_CUT, SOUND_PAN_ATTACKER
delay 5
createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 60, -37, 0
playsewithpan SE_M_CUT, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 0, 9, 0x7FFF
waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 2, 4, 4
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 9, 0, 0x7FFF
waitforvisualfinish
blendoff
end
Move_FLOWER_TRICK::
loadspritegfx ANIM_TAG_SPOTLIGHT
loadspritegfx ANIM_TAG_LEAF @leaves
loadspritegfx ANIM_TAG_FLOWER @flowers
loadspritegfx ANIM_TAG_IMPACT
createvisualtask AnimTask_CreateSpotlight, 2
createvisualtask AnimTask_HardwarePaletteFade, 2, (BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN), 3, 0, 10, FALSE
waitforvisualfinish
createsprite gSpotlightSpriteTemplate, ANIM_TARGET, 2, 0, -8
delay 16
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_ENCORE2, SOUND_PAN_TARGET
createvisualtask AnimTask_SwayMon, 5, 1, 8, 1536, 5, ANIM_TARGET
waitforvisualfinish
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, 192, 176, 40
createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, -192, 240, 40
createsprite gTropKickFlowerTemplate, ANIM_TARGET, 1, 0, 10, 192, -160, 40
createsprite gTropKickFlowerTemplate, ANIM_TARGET, 1, 0, 10, -192, -112, 40
createsprite gTropKickFlowerTemplate, ANIM_TARGET, 1, 0, 10, 160, 48, 40
createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, -224, -32, 40
createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, 112, -128, 40
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
createvisualtask AnimTask_HardwarePaletteFade, 2, (BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN), 3, 10, 0, TRUE
createvisualtask AnimTask_RemoveSpotlight, 2
end
Move_MAKE_IT_RAIN::
loadspritegfx ANIM_TAG_COIN
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_ATTACKER
setalpha 12, 8
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gCoinThrowSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 1152
waitforvisualfinish
playsewithpan SE_M_PAY_DAY, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, 0, 0, ANIM_TARGET, 2
createsprite gFallingCoinSpriteTemplate, ANIM_ATTACKER, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 6, 1
waitforvisualfinish
delay 20
createvisualtask AnimTask_IsTargetPlayerSide, 2
jumpretfalse MakingItRainOnOpponent
jumprettrue MakingItRainOnPlayer
MakingItRainContinue:
waitbgfadeout
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 7, 1, 11, 1
loopsewithpan SE_M_PAY_DAY, SOUND_PAN_TARGET, 8, 15
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -5, 0, -5, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 5, 0, 6, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 19, 0, 10, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -23, 0, -10, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 5, 50, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_DEF_PARTNER, 0, 5, 50, 1
call MakingItRain
call MakingItRain
call MakingItRain
restorebg
waitbgfadein
blendoff
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
MakingItRainOnOpponent:
fadetobg BG_IMPACT_OPPONENT
goto MakingItRainContinue
MakingItRainOnPlayer:
fadetobg BG_IMPACT_PLAYER
goto MakingItRainContinue
MakingItRain:
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -20, 0, -10, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 28, 0, 10, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -10, 0, -5, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 10, 0, 6, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 24, 0, 10, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -32, 0, -10, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -20, 0, -10, 1
delay 2
createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 30, 0, 10, 1
delay 2
return
Move_SHED_TAIL::
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 24, 3
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 12, 4, 2, 3
waitforvisualfinish
playsewithpan SE_M_ATTRACT, SOUND_PAN_ATTACKER
createvisualtask AnimTask_MonToSubstitute, 2
end
Move_HYPER_DRILL::
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HORN_HIT
fadetobgfromset BG_GUILLOTINE_OPPONENT, BG_GUILLOTINE_PLAYER, BG_GUILLOTINE_CONTESTS
waitbgfadein
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 0
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 2
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 1
createsprite gHornHitSpriteTemplate, ANIM_TARGET, 4, 0, 0, 12
waitforvisualfinish
playse 20
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 40, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 10, 0, 40, 1
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 2, 1, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -4, 3, 1, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -8, -5, 1, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 4, -12, 1, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 16, 0, 1, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 5, 18, 1, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -17, 12, 1, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -21, -15, 1, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 8, -27, 1, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 32, 0, 1, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 2
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0
restorebg
waitbgfadein
blendoff
end
Move_TWIN_BEAM::
loadspritegfx ANIM_TAG_BLUE_RING
loadspritegfx ANIM_TAG_GOLD_RING
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
call SetPsychicBackground
createvisualtask AnimTask_StartSinAnimTimer, 5, 100
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_TELEPORT, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 2, 9, 0, 10
call PsywaveRings
call PsybeamRings
call PsywaveRings
call PsybeamRings
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 1, 4, 0, 12, RGB(31, 18, 31)
call PsywaveRings
call PsybeamRings
call PsywaveRings
call PsybeamRings
call PsywaveRings
call PsybeamRings
call PsywaveRings
call PsybeamRings
waitforvisualfinish
delay 1
call UnsetPsychicBg
end
Move_COMEUPPANCE::
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
fadetobg BG_DARK
waitbgfadein
delay 0
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon2, 5, ANIM_ATTACKER, 1, 0, 15, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 0, 9, RGB_RED
waitforvisualfinish
delay 10
createvisualtask AnimTask_SwayMon, 5, 0, 16, 6144, 8, ANIM_ATTACKER
delay 5
setalpha 12, 8
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 30, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 0
playsewithpan SE_M_COMET_PUNCH, +63
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 24, 8, 1, 0
playsewithpan SE_M_COMET_PUNCH, +63
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -24, -16, 1, 0
playsewithpan SE_M_COMET_PUNCH, +63
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 8, 4, 1, 0
playsewithpan SE_M_COMET_PUNCH, +63
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -16, 19, 1, 0
playsewithpan SE_M_COMET_PUNCH, +63
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 18, -18, 1, 0
playsewithpan SE_M_COMET_PUNCH, +63
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
restorebg
waitbgfadein
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 9, 0, RGB_RED
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_BLOOD_MOON::
loadspritegfx ANIM_TAG_BLOOD_MOON
loadspritegfx ANIM_TAG_BEAM
loadspritegfx ANIM_TAG_RED_EXPLOSION
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 0, 16, 16, RGB_BLACK
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 8, 1, ANIM_ATTACKER
delay 8
playsewithpan SE_M_BARRIER, SOUND_PAN_ATTACKER
createsprite gMoonUpSpriteTemplate, ANIM_ATTACKER, 2
waitforvisualfinish
delay 15
playsewithpan SE_M_DETECT, 0
waitforvisualfinish
createvisualtask AnimTask_IsTargetPlayerSide, 2
jumpargeq 7 ANIM_TARGET BloodMoonOnPlayer
BloodMoonOnOpponent:
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_HYPER_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 10, 0, 5
call BloodMoonOnslaughtOpponent
call BloodMoonOnslaughtOpponent
call BloodMoonOnslaughtOpponent
call BloodMoonOnslaughtOpponent
call BloodMoonOnslaughtOpponent
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 6, 5, 1, 0
delay 0
waitforvisualfinish
goto BloodMoonFinish
BloodMoonOnPlayer:
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_HYPER_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 10, 0, 5
call BloodMoonOnslaughtPlayer
call BloodMoonOnslaughtPlayer
call BloodMoonOnslaughtPlayer
call BloodMoonOnslaughtPlayer
call BloodMoonOnslaughtPlayer
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
delay 0
waitforvisualfinish
BloodMoonFinish:
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 0, 0, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
BloodMoonOnslaughtOpponent:
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 6, 5, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -16, -15, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 16, -5, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -12, 18, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 0, 5, 1, 0
delay 0
return
BloodMoonOnslaughtPlayer:
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 6, 5, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -16, -15, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 16, -5, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -12, 18, 1, 0
delay 0
createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 0, 5, 1, 0
delay 0
return
Move_FICKLE_BEAM::
createvisualtask AnimTask_IsPowerOver99, 2
waitforvisualfinish
jumpreteq FALSE, FickleBeamRegular
jumpreteq TRUE, FickleBeamIntense
FickleBeamRegular:
loadspritegfx ANIM_TAG_GOLD_RING
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15
call PsybeamRings
call PsybeamRings
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 4, 25, 1
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 2, 2, 0, 12, RGB(15, 8, 30)
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
waitforvisualfinish
end
FickleBeamIntense:
loadspritegfx ANIM_TAG_ORBS
fadetobgfromset BG_SPACIAL_REND_ON_OPPONENT BG_SPACIAL_REND_ON_PLAYER BG_SPACIAL_REND_ON_OPPONENT
waitbgfadein
delay 10
playsewithpan SE_M_HYPER_BEAM, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 4, 1
waitforvisualfinish
delay 30
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_HYPER_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 15, 0, 5
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 4, 50, 1
createvisualtask AnimTask_FlashAnimTagWithColor, 2, ANIM_TAG_ORBS, 1, 12, RGB_RED, 16, 0, 0
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 50, 1
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
waitforvisualfinish
restorebg
waitbgfadein
end
Move_THUNDERCLAP::
loadspritegfx ANIM_TAG_LIGHTNING
monbg ANIM_ATK_PARTNER
setalpha 12, 8
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 24, 6, 1, 5
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 7, 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
delay 4
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -32
playsewithpan SE_M_TRI_ATTACK2, SOUND_PAN_TARGET
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -16
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, 0
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, 16
delay 10
createvisualtask AnimTask_ShakeTargetInPattern, 2, 30, 3, TRUE, 0
delay 2
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 3, 16, 0, RGB_WHITE
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_TARGET, 0, 16, 16, RGB_BLACK
delay 4
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_TARGET, 0, 0, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
waitforvisualfinish
end
Move_HARD_PRESS::
loadspritegfx ANIM_TAG_EXPLOSION
loadspritegfx ANIM_TAG_ACUPRESSURE
loadspritegfx ANIM_TAG_PURPLE_HAND_OUTLINE
setalpha 15, 0
call SetSteelBeamBackground
createvisualtask AnimTask_CompressTargetHorizontallyFast, 2
createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, 0, 0, 1, 1
delay 3
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, 24, -24, 1, 1
delay 3
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, -16, 16, 1, 1
delay 3
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, -24, -12, 1, 1
delay 3
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, 16, 16, 1, 1
waitforvisualfinish
blendoff
call UnsetHighSpeedBg
end
Move_DRAGON_CHEER::
loadspritegfx ANIM_TAG_NOISE_LINE
loadspritegfx ANIM_TAG_CONFETTI
loadspritegfx ANIM_TAG_PINK_CLOUD
createvisualtask AnimTask_DeepInhale, 2, ANIM_ATTACKER
delay 12
call RoarEffect
createvisualtask SoundTask_PlayCryHighPitch, 2, ANIM_ATTACKER, 3
waitforvisualfinish
monbg ANIM_ATTACKER
playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 122, 3, -14, 18, 24
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 121, 3, 14, 6, 24
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 120, 3, -12, 12, 24
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 119, 3, 14, 18, 24
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 118, 3, 0, 0, 24
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
waitforvisualfinish
clearmonbg ANIM_ATTACKER
delay 10
end
Move_MALIGNANT_CHAIN::
loadspritegfx ANIM_TAG_PURPLE_CHAIN
loadspritegfx ANIM_TAG_POISON_BUBBLE
loopsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET, 6, 2
createsprite gChainBindingSpriteTemplate, ANIM_TARGET, 4, 0, 16, 0, 1
delay 7
createsprite gChainBindingSpriteTemplate, ANIM_TARGET, 2, 0, 8, 1, 1
delay 3
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
delay 20
setarg 7, -1
playsewithpan SE_M_BIND, SOUND_PAN_TARGET
waitforvisualfinish
call PoisonBubblesEffect
waitforvisualfinish
end
Move_TERA_BLAST::
Move_ORDER_UP::
Move_SPIN_OUT::
Move_POPULATION_BOMB::
Move_GLAIVE_RUSH::
Move_REVIVAL_BLESSING::
Move_SALT_CURE::
Move_TRIPLE_DIVE::
Move_MORTAL_SPIN::
Move_DOODLE::
Move_FILLET_AWAY::
Move_FLOWER_TRICK::
Move_MAKE_IT_RAIN::
Move_RUINATION::
Move_COLLISION_COURSE::
Move_ELECTRO_DRIFT::
Move_SHED_TAIL::
Move_HYPER_DRILL::
Move_TWIN_BEAM::
Move_ARMOR_CANNON::
Move_COMEUPPANCE::
Move_BLAZING_TORQUE::
Move_WICKED_TORQUE::
Move_NOXIOUS_TORQUE::
Move_COMBAT_TORQUE::
Move_MAGICAL_TORQUE::
Move_PSYBLADE::
Move_BLOOD_MOON::
Move_MATCHA_GOTCHA::
Move_TERA_STARSTORM::
Move_FICKLE_BEAM::
Move_THUNDERCLAP::
Move_MIGHTY_CLEAVE::
Move_TACHYON_CUTTER::
Move_HARD_PRESS::
Move_DRAGON_CHEER::
Move_SUPERCELL_SLAM::
Move_MALIGNANT_CHAIN::
end @to do
@@@@@@@@@@@@@@@@@@@@@@@ GEN 1-3 @@@@@@@@@@@@@@@@@@@@@@@

View File

@ -30,6 +30,19 @@ BattleScript_DamageToQuarterTargetHP::
damagetoquartertargethp
goto BattleScript_HitFromAtkAnimation
BattleScript_EffectFickleBeam::
attackcanceler
attackstring
ppreduce
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
ficklebeamdamagecalculation
goto BattleScript_HitFromCritCalc
BattleScript_FickleBeamDoubled::
pause B_WAIT_TIME_SHORTEST
printstring STRINGID_FICKLEBEAMDOUBLED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_HitFromCritCalc
BattleScript_Terastallization::
@ TODO: no string prints in S/V, but right now this helps with clarity
printstring STRINGID_PKMNSTORINGENERGY
@ -865,6 +878,7 @@ BattleScript_OctlockTurnDmgEnd:
BattleScript_EffectPoltergeist::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
checkpoltergeist BS_TARGET, BattleScript_ButItFailed

View File

@ -3,6 +3,8 @@
- [README](./README.md)
- [Installation](./INSTALL.md)
- [Setting up WSL1 (Legacy Portion)](./legacy_WSL1_INSTALL.md)
- [Run documentation site locally](local_mdbook/index.md)
- [Ubuntu WSL1/WSL2](local_mdbook/ubuntu_WSL.md)
- [AI Flags](./ai_flags.md)
- [Tutorials]()
- [How to add new AI Flags](./ai_logic.md)

View File

@ -0,0 +1,2 @@
## Running documentation website locally
- [Ubuntu WSL1/WSL2](/docs/local_mdbook/ubuntu_WSL.md)

View File

@ -0,0 +1,51 @@
Note: For further information beyond this very basic guide, please visit mdBook's [official documentation](https://rust-lang.github.io/mdBook/).
## Running documentation website locally (Ubuntu WSL1/WSL2)
### Previous Requirements:
- Option 1: Install via Rust toolchain
- Install Rust toolchain if you don't have it via the `sudo apt install cargo` command.
- Install mdBook via the `cargo install mdbook` command. Once finished, this message will pop up, with {USER} being your Ubuntu
```
warning: be sure to add `/home/{USER}/.cargo/bin` to your PATH to be able to run the installed binaries
```
- Add `/home/{USER}/.cargo/bin` to your PATH (with {USER} being the Ubuntu username.)
- Run command `nano ~/.profile` to edit the file.
- Add the following lines, ***replacing {USER} with your Linux username.***
```diff
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
+# set PATH so it includes cargo bin if it exists
+if [ -d "/home/{USER}/.cargo/bin" ] ; then
+ PATH="/home/{USER}/.cargo/bin:$PATH"
+fi
```
- Run the `source ~/.profile` command to refresh the path in the current session.
- Option 2: Install downloaded binaries directly
- TODO: Add documentation of this process.
### Running the website
- Navigate to the `docs` folder on the repository.
- Run `mdbook serve`. Once started, you may now open the website on your browser by going to `http://127.0.0.1:3000`.
- Every change done to the `docs` folder will be reflected with an automatic refresh.
- To stop the server and go back to the terminal, press `Ctrl + C`.
### Modifying the website
- The navigation menu on the left is handled by `docs/SUMMARY.md`. Every file added needs to be added somewhere here in order to become visible, otherwise you'll get a 404 error.
- Any Markdown files (.md extension) added to the `docs/` directory will automatically be read by mdBook.
- To add Markdown files that are not in the `docs/` directory, you may create an empty `.md` file and add the following ***without the "----"***:
```md
{{ ----#include ../INSTALL.md}}`
```
This will include the `INSTALL.md` Markdown file from the root directory.
Once you're set up, you can now check your changes before pushing them to your repo! :D
We hope that this will make it easier for users to contribute to the documentation :)

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

View File

@ -800,6 +800,7 @@ struct BattleStruct
u8 distortedTypeMatchups;
u8 categoryOverride; // for Z-Moves and Max Moves
u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side
u8 fickleBeamBoosted:1;
};
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,

View File

@ -252,6 +252,7 @@ void AnimParticleBurst(struct Sprite *);
void AnimPowerAbsorptionOrb(struct Sprite *sprite);
void AnimNeedleArmSpike(struct Sprite *);
void AnimTask_CompressTargetHorizontally(u8 taskId);
void AnimTask_CompressTargetHorizontallyFast(u8 taskId);
void AnimSporeParticle(struct Sprite *sprite);
void AnimAbsorptionOrb(struct Sprite *sprite);
void AnimPetalDanceSmallFlower(struct Sprite *sprite);

View File

@ -843,5 +843,7 @@ extern const u8 BattleScript_EffectUpperHand[];
extern const u8 BattleScript_EffectTidyUp[];
extern const u8 BattleScript_EffectSpicyExtract[];
extern const u8 BattleScript_DamageToQuarterTargetHP[];
extern const u8 BattleScript_EffectFickleBeam[];
extern const u8 BattleScript_FickleBeamDoubled[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -251,22 +251,22 @@
#define B_TRY_CATCH_TRAINER_BALL GEN_LATEST // In Gen4+, trying to catch a Trainer's Pokémon does not consume the Poké Ball.
// Animation Settings
#define B_NEW_SWORD_PARTICLE TRUE // If set to TRUE, it updates Swords Dance's particle.
#define B_NEW_LEECH_SEED_PARTICLE TRUE // If set to TRUE, it updates Leech Seed's animation particle.
#define B_NEW_HORN_ATTACK_PARTICLE TRUE // If set to TRUE, it updates Horn Attack's horn particle.
#define B_NEW_ROCKS_PARTICLE TRUE // If set to TRUE, it updates rock particles.
#define B_NEW_LEAF_PARTICLE TRUE // If set to TRUE, it updates leaf particle.
#define B_NEW_EMBER_PARTICLES TRUE // If set to TRUE, it updates Ember's fire particle.
#define B_NEW_MEAN_LOOK_PARTICLE TRUE // If set to TRUE, it updates Mean Look's eye particle.
#define B_NEW_TEETH_PARTICLE TRUE // If set to TRUE, it updates Bite/Crunch teeth particle.
#define B_NEW_HANDS_FEET_PARTICLE TRUE // If set to TRUE, it updates chop/kick/punch particles.
#define B_NEW_SPIKES_PARTICLE TRUE // If set to TRUE, it updates Spikes particle.
#define B_NEW_FLY_BUBBLE_PARTICLE TRUE // If set to TRUE, it updates Fly's 'bubble' particle.
#define B_NEW_CURSE_NAIL_PARTICLE TRUE // If set to TRUE, it updates Curse's nail.
#define B_NEW_BATON_PASS_BALL_PARTICLE TRUE // If set to TRUE, it updates Baton Pass' Poké Ball sprite.
#define B_NEW_MORNING_SUN_STAR_PARTICLE TRUE // If set to TRUE, it updates Morning Sun's star particles.
#define B_NEW_IMPACT_PALETTE TRUE // If set to TRUE, it updates the basic 'hit' palette.
#define B_NEW_SURF_PARTICLE_PALETTE TRUE // If set to TRUE, it updates Surf's wave palette.
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.
#define B_NEW_LEECH_SEED_PARTICLE FALSE // If set to TRUE, it updates Leech Seed's animation particle.
#define B_NEW_HORN_ATTACK_PARTICLE FALSE // If set to TRUE, it updates Horn Attack's horn particle.
#define B_NEW_ROCKS_PARTICLE FALSE // If set to TRUE, it updates rock particles.
#define B_NEW_LEAF_PARTICLE FALSE // If set to TRUE, it updates leaf particle.
#define B_NEW_EMBER_PARTICLES FALSE // If set to TRUE, it updates Ember's fire particle.
#define B_NEW_MEAN_LOOK_PARTICLE FALSE // If set to TRUE, it updates Mean Look's eye particle.
#define B_NEW_TEETH_PARTICLE FALSE // If set to TRUE, it updates Bite/Crunch teeth particle.
#define B_NEW_HANDS_FEET_PARTICLE FALSE // If set to TRUE, it updates chop/kick/punch particles.
#define B_NEW_SPIKES_PARTICLE FALSE // If set to TRUE, it updates Spikes particle.
#define B_NEW_FLY_BUBBLE_PARTICLE FALSE // If set to TRUE, it updates Fly's 'bubble' particle.
#define B_NEW_CURSE_NAIL_PARTICLE FALSE // If set to TRUE, it updates Curse's nail.
#define B_NEW_BATON_PASS_BALL_PARTICLE FALSE // If set to TRUE, it updates Baton Pass' Poké Ball sprite.
#define B_NEW_MORNING_SUN_STAR_PARTICLE FALSE // If set to TRUE, it updates Morning Sun's star particles.
#define B_NEW_IMPACT_PALETTE FALSE // If set to TRUE, it updates the basic 'hit' palette.
#define B_NEW_SURF_PARTICLE_PALETTE FALSE // If set to TRUE, it updates Surf's wave palette.
// Poké Ball animation and sounds
#define B_ENEMY_THROW_BALLS GEN_LATEST // In GEN_6+, enemy Trainers throw Poké Balls into battle instead of them just appearing on the ground and opening.

View File

@ -412,6 +412,10 @@
#define ANIM_TAG_TERA_CRYSTAL (ANIM_SPRITES_START + 398)
#define ANIM_TAG_TERA_SHATTER (ANIM_SPRITES_START + 399)
#define ANIM_TAG_DREEPY_SHINY (ANIM_SPRITES_START + 400)
#define ANIM_TAG_BLOOD_MOON (ANIM_SPRITES_START + 401)
#define ANIM_TAG_BEAM (ANIM_SPRITES_START + 402)
#define ANIM_TAG_RED_EXPLOSION (ANIM_SPRITES_START + 403)
#define ANIM_TAG_PURPLE_CHAIN (ANIM_SPRITES_START + 404)
// battlers
#define ANIM_ATTACKER 0

View File

@ -712,8 +712,9 @@
#define STRINGID_FOGISDEEP 710
#define STRINGID_FOGLIFTED 711
#define STRINGID_PKMNMADESHELLGLEAM 712
#define STRINGID_FICKLEBEAMDOUBLED 713
#define BATTLESTRINGS_COUNT 713
#define BATTLESTRINGS_COUNT 714
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,

View File

@ -130,7 +130,7 @@ struct MapEvents
struct MapConnection
{
u8 direction;
u32 offset;
s32 offset;
u8 mapGroup;
u8 mapNum;
};

View File

@ -2724,6 +2724,8 @@ extern const u32 gBattleAnimSpritePal_AuraSphere[];
extern const u32 gBattleAnimSpritePal_AvalancheRocks[];
extern const u32 gBattleAnimSpriteGfx_NewPokeball[];
extern const u32 gBattleAnimSpritePal_NewPokeball[];
extern const u32 gBattleAnimSpriteGfx_Beam[];
extern const u32 gBattleAnimSpritePal_Beam[];
extern const u32 gBattleAnimSpriteGfx_BerryEaten[];
extern const u32 gBattleAnimSpritePal_BerryEaten[];
extern const u32 gBattleAnimSpriteGfx_BerryNormal[];
@ -2732,6 +2734,8 @@ extern const u32 gBattleAnimSpriteGfx_BigRock[];
extern const u32 gBattleAnimSpritePal_BigRock[];
extern const u32 gBattleAnimSpriteGfx_BlacephalonHead[];
extern const u32 gBattleAnimSpritePal_BlacephalonHead[];
extern const u32 gBattleAnimSpriteGfx_BloodMoon[];
extern const u32 gBattleAnimSpritePal_BloodMoon[];
extern const u32 gBattleAnimSpritePal_BlueFlare[];
extern const u32 gBattleAnimSpriteGfx_Branch[];
extern const u32 gBattleAnimSpritePal_Branch[];
@ -2825,12 +2829,16 @@ extern const u32 gBattleAnimSpriteGfx_PoisonColumn[];
extern const u32 gBattleAnimSpritePal_PoisonColumn[];
extern const u32 gBattleAnimSpriteGfx_PowerTrick[];
extern const u32 gBattleAnimSpritePal_PowerTrick[];
extern const u32 gBattleAnimSpriteGfx_PurpleChain[];
extern const u32 gBattleAnimSpritePal_PurpleChain[];
extern const u32 gBattleAnimSpriteGfx_PurpleDrake[];
extern const u32 gBattleAnimSpritePal_PurpleDrake[];
extern const u32 gBattleAnimSpriteGfx_QuickGuard[];
extern const u32 gBattleAnimSpritePal_QuickGuard[];
extern const u32 gBattleAnimSpriteGfx_RazorShell[];
extern const u32 gBattleAnimSpritePal_RazorShell[];
extern const u32 gBattleAnimSpriteGfx_RedExplosion[];
extern const u32 gBattleAnimSpritePal_RedExplosion[];
extern const u32 gBattleAnimSpriteGfx_RocksSmall[];
extern const u32 gBattleAnimSpriteGfx_NewRocks[];
extern const u32 gBattleAnimSpritePal_NewRocks[];

View File

@ -3101,6 +3101,17 @@ const struct SpriteTemplate gPsyshockSmokeSpriteTemplate =
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gChainBindingSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_CHAIN,
.paletteTag = ANIM_TAG_PURPLE_CHAIN,
.oam = &gOamData_AffineNormal_ObjNormal_64x32,
.anims = sAnims_ConstrictBinding,
.images = NULL,
.affineAnims = sAffineAnims_ConstrictBinding,
.callback = AnimConstrictBinding,
};
// functions
static void AnimGrassKnot(struct Sprite *sprite)
{
@ -7229,6 +7240,14 @@ static const union AffineAnimCmd sCompressTargetHorizontallyAffineAnimCmds[] =
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sCompressTargetHorizontallyAffineAnimCmdsFast[] =
{
AFFINEANIMCMD_FRAME(32, 0, 0, 16), //Compress
AFFINEANIMCMD_FRAME(0, 0, 0, 32),
AFFINEANIMCMD_FRAME(-32, 0, 0, 16),
AFFINEANIMCMD_END,
};
static void AnimTask_CompressTargetStep(u8 taskId)
{
struct Task* task = &gTasks[taskId];
@ -7245,6 +7264,14 @@ void AnimTask_CompressTargetHorizontally(u8 taskId)
task->func = AnimTask_CompressTargetStep;
}
void AnimTask_CompressTargetHorizontallyFast(u8 taskId)
{
struct Task* task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
PrepareAffineAnimInTaskData(task, spriteId, sCompressTargetHorizontallyAffineAnimCmdsFast);
task->func = AnimTask_CompressTargetStep;
}
void AnimTask_CreateSmallSteelBeamOrbs(u8 taskId)
{
if (--gTasks[taskId].data[0] == -1)

View File

@ -99,6 +99,7 @@ static void SpriteCB_GlacialLance_Step1(struct Sprite* sprite);
static void SpriteCB_GlacialLance_Step2(struct Sprite* sprite);
static void SpriteCB_GlacialLance(struct Sprite* sprite);
static void SpriteCB_TripleArrowKick(struct Sprite* sprite);
static void AnimMakingItRain(struct Sprite *sprite);
// const data
// general
@ -7234,6 +7235,51 @@ const struct SpriteTemplate gBitterBladeImpactTemplate =
.callback = AnimClawSlash
};
// Make It Rain
const struct SpriteTemplate gMakingItRainTemplate =
{
.tileTag = ANIM_TAG_COIN,
.paletteTag = ANIM_TAG_COIN,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gCoinAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMakingItRain,
};
const struct SpriteTemplate gRedExplosionSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_EXPLOSION,
.paletteTag = ANIM_TAG_RED_EXPLOSION,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gExplosionAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gBloodMoonOnslaughtSpriteTemplate =
{
.tileTag = ANIM_TAG_BEAM,
.paletteTag = ANIM_TAG_BEAM,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sArrowRaidOnslaughtAffineAnimTable,
.callback = AnimAssistPawprint
};
const struct SpriteTemplate gMoonUpSpriteTemplate =
{
.tileTag = ANIM_TAG_BLOOD_MOON,
.paletteTag = ANIM_TAG_BLOOD_MOON,
.oam = &gOamData_AffineOff_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWeatherBallUp,
};
// functions
//general
void AnimTask_IsTargetPartner(u8 taskId)
@ -9219,3 +9265,23 @@ void AnimTask_StickySyrup(u8 taskId)
gBattleAnimArgs[0] = gAnimDisableStructPtr->syrupBombIsShiny;
DestroyAnimVisualTask(taskId);
}
static void AnimMakingItRain(struct Sprite *sprite)
{
if (gBattleAnimArgs[3] != 0)
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &sprite->x, &sprite->y); //coin shower on target
sprite->x += gBattleAnimArgs[0];
sprite->y += 14;
StartSpriteAnim(sprite, gBattleAnimArgs[1]);
AnimateSprite(sprite);
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2] = 4;
sprite->data[3] = 16;
sprite->data[4] = -70;
sprite->data[5] = gBattleAnimArgs[2];
StoreSpriteCallbackInData6(sprite, AnimFallingRock_Step);
sprite->callback = TranslateSpriteInEllipse;
sprite->callback(sprite);
}

View File

@ -4717,7 +4717,6 @@ void SwapTurnOrder(u8 id1, u8 id2)
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
{
u32 speed = gBattleMons[battler].speed;
u32 highestStat = GetHighestStatId(battler);
// weather abilities
if (WEATHER_HAS_EFFECT)
@ -4739,10 +4738,10 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
speed *= 2;
else if (ability == ABILITY_SLOW_START && gDisableStructs[battler].slowStartTimer != 0)
speed /= 2;
else if (ability == ABILITY_PROTOSYNTHESIS && gBattleWeather & B_WEATHER_SUN && highestStat == STAT_SPEED)
speed = (speed * 150) / 100;
else if (ability == ABILITY_QUARK_DRIVE && gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && highestStat == STAT_SPEED)
speed = (speed * 150) / 100;
else if (ability == ABILITY_PROTOSYNTHESIS && (gBattleWeather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & gBitTable[battler]))
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
else if (ability == ABILITY_QUARK_DRIVE && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & gBitTable[battler]))
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
// stat stages
speed *= gStatStageRatios[gBattleMons[battler].statStages[STAT_SPEED]][0];

View File

@ -849,9 +849,11 @@ static const u8 sText_ShedItsTail[] = _("{B_ATK_NAME_WITH_PREFIX} shed its tail\
static const u8 sText_PkmnTerastallizedInto[] = _("{B_ATK_NAME_WITH_PREFIX} terastallized\ninto the {B_BUFF1} type!");
static const u8 sText_SupersweetAromaWafts[] = _("A supersweet aroma is wafting from\nthe syrup covering {B_ATK_NAME_WITH_PREFIX}!");
static const u8 sText_TidyingUpComplete[] = _("Tidying up complete!");
static const u8 sText_FickleBeamDoubled[] = _("{B_ATK_NAME_WITH_PREFIX} is going all\nout for this attack!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_FICKLEBEAMDOUBLED - BATTLESTRINGS_TABLE_START] = sText_FickleBeamDoubled,
[STRINGID_PKMNTERASTALLIZEDINTO - BATTLESTRINGS_TABLE_START] = sText_PkmnTerastallizedInto,
[STRINGID_TIDYINGUPCOMPLETE - BATTLESTRINGS_TABLE_START] = sText_TidyingUpComplete,
[STRINGID_SUPERSWEETAROMAWAFTS - BATTLESTRINGS_TABLE_START] = sText_SupersweetAromaWafts,

View File

@ -6391,6 +6391,7 @@ static void Cmd_moveend(void)
gBattleStruct->enduredDamage = 0;
gBattleStruct->additionalEffectsCounter = 0;
gBattleStruct->poisonPuppeteerConfusion = FALSE;
gBattleStruct->fickleBeamBoosted = FALSE;
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE)
SetActiveGimmick(gBattlerAttacker, GIMMICK_NONE);
gBattleStruct->distortedTypeMatchups = 0;
@ -17123,3 +17124,19 @@ void BS_DamageToQuarterTargetHP(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_FickleBeamDamageCalculation(void)
{
NATIVE_ARGS();
gBattleStruct->fickleBeamBoosted = FALSE;
if (RandomPercentage(RNG_FICKLE_BEAM, 30))
{
gBattleStruct->fickleBeamBoosted = TRUE;
gBattlescriptCurrInstr = BattleScript_FickleBeamDoubled;
}
else
{
gBattlescriptCurrInstr = cmd->nextInstr;
}
}

View File

@ -4095,7 +4095,7 @@ static void ChooseStatBoostAnimation(u32 battler)
if (gBattleScripting.animArg1 != 0) // Already set in a different stat so now boosting multiple stats
gBattleScripting.animArg1 = (statBuffMoreThan1 ? STAT_ANIM_MULTIPLE_PLUS2 : STAT_ANIM_MULTIPLE_PLUS1);
else
gBattleScripting.animArg1 = GET_STAT_BUFF_ID((statsOrder[stat] + 1)) + (!statBuffMoreThan1 ? STAT_ANIM_PLUS1 : STAT_ANIM_PLUS2);
gBattleScripting.animArg1 = GET_STAT_BUFF_ID((statsOrder[stat] + 1)) + (statBuffMoreThan1 ? STAT_ANIM_PLUS2 : STAT_ANIM_PLUS1);
}
}
#undef ANIM_STAT_HP
@ -9071,7 +9071,7 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3
basePower = (basePower > 350) ? 350 : basePower;
break;
case EFFECT_FICKLE_BEAM:
if (RandomPercentage(RNG_FICKLE_BEAM, 30))
if (gBattleStruct->fickleBeamBoosted)
basePower *= 2;
break;
case EFFECT_TERA_BLAST:

View File

@ -1461,6 +1461,10 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] =
{gBattleAnimSpriteGfx_TeraCrystal, 0x800, ANIM_TAG_TERA_CRYSTAL},
{gBattleAnimSpriteGfx_TeraShatter, 0x0180, ANIM_TAG_TERA_SHATTER},
{gBattleAnimSpriteGfx_DreepyMissile, 0x200, ANIM_TAG_DREEPY_SHINY},
{gBattleAnimSpriteGfx_BloodMoon, 0x0800, ANIM_TAG_BLOOD_MOON},
{gBattleAnimSpriteGfx_RedExplosion, 0x0800, ANIM_TAG_RED_EXPLOSION},
{gBattleAnimSpriteGfx_Beam, 0x0800, ANIM_TAG_BEAM},
{gBattleAnimSpriteGfx_PurpleChain, 0x1000, ANIM_TAG_PURPLE_CHAIN},
};
const struct CompressedSpritePalette gBattleAnimPaletteTable[] =
@ -1923,6 +1927,10 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] =
{gBattleAnimSpritePal_TeraCrystal, ANIM_TAG_TERA_CRYSTAL},
{gBattleAnimSpritePal_TeraShatter, ANIM_TAG_TERA_SHATTER},
{gBattleAnimSpritePal_DreepyMissileShiny, ANIM_TAG_DREEPY_SHINY},
{gBattleAnimSpritePal_BloodMoon, ANIM_TAG_BLOOD_MOON},
{gBattleAnimSpritePal_RedExplosion, ANIM_TAG_RED_EXPLOSION},
{gBattleAnimSpritePal_Beam, ANIM_TAG_BEAM},
{gBattleAnimSpritePal_PurpleChain, ANIM_TAG_PURPLE_CHAIN},
};
const struct BattleAnimBackground gBattleAnimBackgroundTable[] =

View File

@ -2169,7 +2169,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_FICKLE_BEAM] =
{
.battleScript = BattleScript_EffectHit,
.battleScript = BattleScript_EffectFickleBeam,
.battleTvScore = 0, // TODO: Assign points
},

View File

@ -141,7 +141,7 @@ static void InitBackupMapLayoutConnections(struct MapHeader *mapHeader)
for (i = 0; i < count; i++, connection++)
{
struct MapHeader const *cMap = GetMapHeaderFromConnection(connection);
u32 offset = connection->offset;
s32 offset = connection->offset;
switch (connection->direction)
{
case CONNECTION_SOUTH:

View File

@ -81,6 +81,9 @@ const u32 gBattleAnimSpritePal_AvalancheRocks[] = INCBIN_U32("graphics/battle_an
const u32 gBattleAnimSpriteGfx_NewPokeball[] = INCBIN_U32("graphics/battle_anims/sprites/baton_pass_ball.4bpp.lz");
const u32 gBattleAnimSpritePal_NewPokeball[] = INCBIN_U32("graphics/battle_anims/sprites/baton_pass_ball.gbapal.lz");
const u32 gBattleAnimSpriteGfx_Beam[] = INCBIN_U32("graphics/battle_anims/sprites/beam.4bpp.lz");
const u32 gBattleAnimSpritePal_Beam[] = INCBIN_U32("graphics/battle_anims/sprites/beam.gbapal.lz");
const u32 gBattleAnimSpriteGfx_BerryEaten[] = INCBIN_U32("graphics/battle_anims/sprites/berry_eaten.4bpp.lz");
const u32 gBattleAnimSpritePal_BerryEaten[] = INCBIN_U32("graphics/battle_anims/sprites/berry_eaten.gbapal.lz");
@ -93,6 +96,9 @@ const u32 gBattleAnimSpritePal_BigRock[] = INCBIN_U32("graphics/battle_anims/spr
const u32 gBattleAnimSpriteGfx_BlacephalonHead[] = INCBIN_U32("graphics/battle_anims/sprites/blacephalon_head.4bpp.lz");
const u32 gBattleAnimSpritePal_BlacephalonHead[] = INCBIN_U32("graphics/battle_anims/sprites/blacephalon_head.gbapal.lz");
const u32 gBattleAnimSpriteGfx_BloodMoon[] = INCBIN_U32("graphics/battle_anims/sprites/blood_moon.4bpp.lz");
const u32 gBattleAnimSpritePal_BloodMoon[] = INCBIN_U32("graphics/battle_anims/sprites/blood_moon.gbapal.lz");
const u32 gBattleAnimSpritePal_BlueFlare[] = INCBIN_U32("graphics/battle_anims/sprites/blue_flare.gbapal.lz");
const u32 gBattleAnimSpriteGfx_Branch[] = INCBIN_U32("graphics/battle_anims/sprites/branch.4bpp.lz");
@ -233,12 +239,18 @@ const u32 gBattleAnimSpritePal_PoisonColumn[] = INCBIN_U32("graphics/battle_anim
const u32 gBattleAnimSpriteGfx_PowerTrick[] = INCBIN_U32("graphics/battle_anims/sprites/power_trick.4bpp.lz");
const u32 gBattleAnimSpritePal_PowerTrick[] = INCBIN_U32("graphics/battle_anims/sprites/power_trick.gbapal.lz");
const u32 gBattleAnimSpriteGfx_PurpleChain[] = INCBIN_U32("graphics/battle_anims/sprites/purple_chain.4bpp.lz");
const u32 gBattleAnimSpritePal_PurpleChain[] = INCBIN_U32("graphics/battle_anims/sprites/purple_chain.gbapal.lz");
const u32 gBattleAnimSpriteGfx_PurpleDrake[] = INCBIN_U32("graphics/battle_anims/sprites/purple_drake.4bpp.lz");
const u32 gBattleAnimSpritePal_PurpleDrake[] = INCBIN_U32("graphics/battle_anims/sprites/purple_drake.gbapal.lz");
const u32 gBattleAnimSpriteGfx_RazorShell[] = INCBIN_U32("graphics/battle_anims/sprites/razor_shell.4bpp.lz");
const u32 gBattleAnimSpritePal_RazorShell[] = INCBIN_U32("graphics/battle_anims/sprites/razor_shell.gbapal.lz");
const u32 gBattleAnimSpriteGfx_RedExplosion[] = INCBIN_U32("graphics/battle_anims/sprites/red_explosion.4bpp.lz");
const u32 gBattleAnimSpritePal_RedExplosion[] = INCBIN_U32("graphics/battle_anims/sprites/red_explosion.gbapal.lz");
const u32 gBattleAnimSpriteGfx_RocksSmall[] = INCBIN_U32("graphics/battle_anims/sprites/rock_small.4bpp.lz");
const u32 gBattleAnimSpriteGfx_NewRocks[] = INCBIN_U32("graphics/battle_anims/sprites/rocks_new.4bpp.lz");

View File

@ -430,46 +430,43 @@ static bool8 IsHiddenItemPresentAtCoords(const struct MapEvents *events, s16 x,
static bool8 IsHiddenItemPresentInConnection(const struct MapConnection *connection, int x, int y)
{
s16 connectionX, connectionY;
struct MapHeader const *const connectionHeader = GetMapHeaderFromConnection(connection);
u16 localX, localY;
u32 localOffset;
s32 localLength;
struct MapHeader const *const mapHeader = GetMapHeaderFromConnection(connection);
// To convert our x/y into coordinates that are relative to the connected map, we must:
// - Subtract the virtual offset used for the border buffer (MAP_OFFSET).
// - Subtract the horizontal offset between North/South connections, or the vertical offset for East/West
// - Account for map size. (0,0) is in the NW corner of our map, so when looking North/West we have to add the height/width of the connected map,
// and when looking South/East we have to subtract the height/width of our current map.
#define localX (x - MAP_OFFSET)
#define localY (y - MAP_OFFSET)
switch (connection->direction)
{
// same weird temp variable behavior seen in IsHiddenItemPresentAtCoords
case CONNECTION_NORTH:
localOffset = connection->offset + MAP_OFFSET;
localX = x - localOffset;
localLength = mapHeader->mapLayout->height - MAP_OFFSET;
localY = localLength + y; // additions are reversed for some reason
connectionX = localX - connection->offset;
connectionY = connectionHeader->mapLayout->height + localY;
break;
case CONNECTION_SOUTH:
localOffset = connection->offset + MAP_OFFSET;
localX = x - localOffset;
localLength = gMapHeader.mapLayout->height + MAP_OFFSET;
localY = y - localLength;
connectionX = localX - connection->offset;
connectionY = localY - gMapHeader.mapLayout->height;
break;
case CONNECTION_WEST:
localLength = mapHeader->mapLayout->width - MAP_OFFSET;
localX = localLength + x; // additions are reversed for some reason
localOffset = connection->offset + MAP_OFFSET;
localY = y - localOffset;
connectionX = connectionHeader->mapLayout->width + localX;
connectionY = localY - connection->offset;
break;
case CONNECTION_EAST:
localLength = gMapHeader.mapLayout->width + MAP_OFFSET;
localX = x - localLength;
localOffset = connection->offset + MAP_OFFSET;
localY = y - localOffset;
connectionX = localX - gMapHeader.mapLayout->width;
connectionY = localY - connection->offset;
break;
default:
return FALSE;
}
return IsHiddenItemPresentAtCoords(mapHeader->events, localX, localY);
return IsHiddenItemPresentAtCoords(connectionHeader->events, connectionX, connectionY);
}
#undef localX
#undef localY
static void CheckForHiddenItemsInMapConnection(u8 taskId)
{
s16 playerX, playerY;

View File

@ -0,0 +1,46 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Adaptability increases same-type attack bonus from x1.5 to x2");
SINGLE_BATTLE_TEST("(TERA) Terastallizing into a different type with Adaptability gives 2.0x STAB", s16 damage)
{
bool32 tera;
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_NORMAL); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_HEADBUTT, gimmick: tera); }
} SCENE {
MESSAGE("Crawdaunt used Headbutt!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_HEADBUTT, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
// The jump from no STAB to 2.0x STAB is a 2.0x boost.
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
}
}
SINGLE_BATTLE_TEST("(TERA) Terastallizing into the same type with Adaptability gives 2.25x STAB", s16 damage)
{
bool32 tera;
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_WATER); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_WATER_PULSE, gimmick: tera); }
} SCENE {
MESSAGE("Crawdaunt used Water Pulse!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PULSE, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
// The jump from 2x STAB to 2.25x STAB is a 1.125x boost.
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.125), results[1].damage);
}
}
TO_DO_BATTLE_TEST("Adaptability does not affect Stellar-type moves");

View File

@ -0,0 +1,33 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
}
SINGLE_BATTLE_TEST("Aerilate turns a Normal-type move into Flying-type move")
{
GIVEN {
PLAYER(SPECIES_MEGANIUM);
OPPONENT(SPECIES_SALAMENCE) { Item(ITEM_SALAMENCITE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
TO_DO_BATTLE_TEST("Aerilate can not turn certain moves into Flying type moves");
TO_DO_BATTLE_TEST("Aerilate boosts power of affected moves by 20% (Gen7+)");
TO_DO_BATTLE_TEST("Aerilate boosts power of affected moves by 30% (Gen6)");
// Gen 6-7
TO_DO_BATTLE_TEST("Aerilate overrides Electrify (Gen6-7)");
TO_DO_BATTLE_TEST("Aerilate overrides Ion Deluge (Gen6-7)");
// Gen 8+
//TO_DO_BATTLE_TEST("Aerilate doesn't override Electrify (Gen8+)"); // No mon with Aerilate exists in Gen8+, but probably behaves similar to Pixilate, which does.
//TO_DO_BATTLE_TEST("Aerilate doesn't override Ion Deluge (Gen8+)"); // Ion Deluge doesn't exist in Gen 8+, but we probably could assume it behaves similar to under Electrify. TODO: Test by hacking SV.

View File

@ -0,0 +1,4 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Aftermath damages the attacker by 1/4th of its max HP if they faint the target has this ability by a contact move");

View File

@ -0,0 +1,4 @@
#include "global.h"
#include "test/battle.h"
// Tests for Air Lock are handled in test/battle/ability/cloud_nine.c

View File

@ -0,0 +1,11 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Analytic increases the power of moves by 30% if it's the last one that uses its move");
TO_DO_BATTLE_TEST("Analytic takes into account modifications to speeed an priority (Gen 5-8)"); //Eg. Paralysis, Power Weight, Stall
TO_DO_BATTLE_TEST("Analytic does not take into account modifications to speeed an priority (Gen 8)"); //Eg. Paralysis, Power Weight, Stall
TO_DO_BATTLE_TEST("Analytic takes into account the turn order of what fainted Pokémon would've moved");
// Triple Battles needed to test
//TO_DO_BATTLE_TEST("If the Pokémon with Analytic is targeting a Pokémon in a flank position that chooses to switch with its ally in the middle, its move's power will always be normal when it attacks the Pokémon that is shifted into the flank position");
//TO_DO_BATTLE_TEST("If the Pokémon with Analytic targets a Pokémon in the middle whose ally on a flank chooses to shift into the middle position, its move's power still depends on whether the Pokémon that was in the middle (and is now on a flank) has acted when the Pokémon with Analytic uses its move");

View File

@ -47,7 +47,9 @@ SINGLE_BATTLE_TEST("Anger Point does not trigger when already at maximum Attack
}
}
SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit")
TO_DO_BATTLE_TEST("Anger Point triggers when a substitute takes the hit (Gen4)");
SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit (Gen5+)")
{
ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);

View File

@ -1,7 +1,7 @@
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Anger Shell activates only if the target had more than 50% of its hp")
SINGLE_BATTLE_TEST("Anger Shell activates only if the target had more than 50% of its HP")
{
bool32 activates = FALSE;
u16 maxHp = 500, hp = 0;

View File

@ -0,0 +1,24 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Anticipation causes notifies if an opponent has a super-effective move");
TO_DO_BATTLE_TEST("Anticipation causes notifies if an opponent has a One-hit KO move");
TO_DO_BATTLE_TEST("Anticipation causes notifies if an opponent has a Self-Destruct or Explosion (Gen4)");
TO_DO_BATTLE_TEST("Anticipation treats Self-Destruct and Explosion like all other Normal types (Gen5+)");
TO_DO_BATTLE_TEST("Anticipation considers Scrappy and Normalize into their effectiveness (Gen4)");
TO_DO_BATTLE_TEST("Anticipation doesn't consider Scrappy and Normalize into their effectiveness (Gen5+)");
TO_DO_BATTLE_TEST("Anticipation considers Gravity into their effectiveness (Gen4)");
TO_DO_BATTLE_TEST("Anticipation doesn't consider Gravity into their effectiveness (Gen5+)");
TO_DO_BATTLE_TEST("Anticipation doesn't trigger from Counter, Metal Burst or Mirror Coat (Gen4)");
TO_DO_BATTLE_TEST("Anticipation counts Counter, Metal Burst or Mirror Coat as attacking moves of their types (Gen5+)");
TO_DO_BATTLE_TEST("Anticipation considers Synchronoise as an ordinary Psychic-type move");
TO_DO_BATTLE_TEST("Anticipation considers Freeze-Dry as an ordinary Ice-type move");
TO_DO_BATTLE_TEST("Anticipation considers Flying Press as an ordinary Fighting-type move");
TO_DO_BATTLE_TEST("Anticipation considers Aura Wheel as an ordinary Electric-type move");
TO_DO_BATTLE_TEST("Anticipation considers Inverse Battle types"); //Check with Normal-type moves
TO_DO_BATTLE_TEST("Anticipation treats dynamic move types as their base type (Normal)"); // Judgment, Weather Ball, Natural Gift, Techno Blast, Revelation Dance, Multi Attack
TO_DO_BATTLE_TEST("Anticipation treats Hidden Power as Normal Type (Gen4-5)");
TO_DO_BATTLE_TEST("Anticipation treats Hidden Power as its dynamic type (Gen6+)");
TO_DO_BATTLE_TEST("Anticipation does not consider Strong Winds on type matchups");
TO_DO_BATTLE_TEST("Anticipation does not consider ate-abilities");

View File

@ -0,0 +1,11 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Arena Trap prevents grounded adjacent opponents from switching out");
TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs if the Pokémon is switched in the same turn the opponent decided to switch out");
TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via moves that switch out"); // Baton Pass, U-Turn, Volt Switch, Flip Turn, Parting Shot
TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via Shed Shell, but not via Teleport");
TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via Run Away");
TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via Smoke Ball");
TO_DO_BATTLE_TEST("Arena Trap prevents switch outs from Ghost-type Pokémon (Gen3-5)");
TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs from Ghost-type Pokémon (Gen6+)");

View File

@ -0,0 +1,15 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Taunt");
TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Torment");
TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Encore");
TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Disable");
TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Cursed Body");
TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Heal Block");
TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Infatuation");
TO_DO_BATTLE_TEST("Aroma Veil does not protect the Pokémon's side from Imprison");
// Marked in Bulbapedia as need of research
//TO_DO_BATTLE_TEST("Aroma Veil prevents G-Max Meltdown's effect");
//TO_DO_BATTLE_TEST("Aroma Veil prevents Psychic Noise's effect");

View File

@ -0,0 +1,7 @@
#include "global.h"
#include "test/battle.h"
// Tests for the individual ability effects are handled in the following times:
// - Unnerve: test/battle/ability/unnerve.c
// - Chilling Neigh: test/battle/ability/chilling_neigh.c
// - Grim Neigh: test/battle/ability/grim_neigh.c

View File

@ -0,0 +1,6 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Aura Break inverts Fairy Aura's effect");
TO_DO_BATTLE_TEST("Aura Break inverts Dark Aura's effect");
TO_DO_BATTLE_TEST("Aura Break ignores Mold Breaker abilities");

View File

@ -0,0 +1,4 @@
#include "global.h"
#include "test/battle.h"
// Tests for Chilling Neigh are handled in test/battle/ability/moxie.c

View File

@ -0,0 +1,6 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Chlorophyll doubles speed if it's sunny");
TO_DO_BATTLE_TEST("Chlorophyll doesn't double speed if Cloud Nine/Air Lock is on the field");
TO_DO_BATTLE_TEST("Chlorophyll doesn't double speed if they have an Utility Umbrella");

View File

@ -1,16 +1,41 @@
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Cloud Nine prevents weather effects")
SINGLE_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Sandstorm")
{
u32 species = 0, ability = 0;
PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; }
PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
GIVEN {
ASSUME(gMovesInfo[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM);
PLAYER(SPECIES_PSYDUCK) { Ability(ABILITY_CLOUD_NINE); }
PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SANDSTORM); }
TURN {}
} SCENE {
NONE_OF { HP_BAR(player); }
ABILITY_POPUP(player, ability);
MESSAGE("The effects of weather disappeared.");
MESSAGE("Foe Wobbuffet used Sandstorm!");
MESSAGE("The sandstorm rages.");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SANDSTORM_CONTINUES);
NONE_OF {
HP_BAR(player);
HP_BAR(opponent);
MESSAGE("Foe Wobbuffet is buffeted by the sandstorm!");
}
MESSAGE("The sandstorm rages.");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SANDSTORM_CONTINUES);
}
}
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Sun");
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Rain");
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Hail");
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Snow");
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Fog");
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Primal Sun");
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Primal Rain");
TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Strong Winds");
// Moves and abilities that are affected by weather should have new tests that check for Clould Nine/Air Lock, like Mold-Breaker Abilities

View File

@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Damp prevents explosion-like moves from self")
}
}
SINGLE_BATTLE_TEST("Damp prevents damage from aftermath")
SINGLE_BATTLE_TEST("Damp prevents damage from Aftermath")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);

View File

@ -0,0 +1,5 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Drought sets up sun for 5 turns (Gen6+)");
TO_DO_BATTLE_TEST("Drought sets up permanent sun (Gen3-5)");

View File

@ -15,6 +15,8 @@ SINGLE_BATTLE_TEST("Dry Skin causes 1/8th Max HP damage in Sun")
}
}
TO_DO_BATTLE_TEST("Dry Skin doesn't get damaged in Sun if Cloud Nine/Air Lock is on the field");
SINGLE_BATTLE_TEST("Dry Skin heals 1/8th Max HP in Rain")
{
GIVEN {
@ -29,6 +31,8 @@ SINGLE_BATTLE_TEST("Dry Skin heals 1/8th Max HP in Rain")
}
}
TO_DO_BATTLE_TEST("Dry Skin doesn't heal in Rain if Cloud Nine/Air Lock is on the field");
SINGLE_BATTLE_TEST("Dry Skin increases damage taken from Fire-type moves by 25%", s16 damage)
{
u32 ability;

View File

@ -17,6 +17,8 @@ SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim in harsh sunlight")
}
}
TO_DO_BATTLE_TEST("Flower Gift doesn't transform Cherrim if Cloud Nine/Air Lock is on the field");
SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal when weather changes")
{
GIVEN {
@ -61,6 +63,8 @@ SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal when its abili
}
}
TO_DO_BATTLE_TEST("Forecast transforms Castform back to normal under Cloud Nine/Air Lock");
DOUBLE_BATTLE_TEST("Flower Gift increases the attack of Cherrim and its allies by 1.5x", s16 damageL, s16 damageR)
{
bool32 sunny;

View File

@ -264,12 +264,15 @@ SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal when Sandstorm i
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal under Air Lock")
SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal under Cloud Nine/Air Lock")
{
u32 species = 0, ability = 0;
PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; }
PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
GIVEN {
PLAYER(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_RAYQUAZA);
OPPONENT(species) { Ability(ability); }
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
TURN { SWITCH(opponent, 1); }
@ -279,7 +282,7 @@ SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal under Air Lock")
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
// back to normal
ABILITY_POPUP(opponent, ABILITY_AIR_LOCK);
ABILITY_POPUP(opponent, ability);
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");

View File

@ -7,6 +7,19 @@ ASSUMPTIONS
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
}
SINGLE_BATTLE_TEST("Galvanize turns a normal type move into Electric")
{
GIVEN {
PLAYER(SPECIES_KRABBY);
OPPONENT(SPECIES_GEODUDE_ALOLAN) { Ability(ABILITY_GALVANIZE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
SINGLE_BATTLE_TEST("Galvanize can not turn certain moves into Electric type moves")
{
u32 move;
@ -29,56 +42,7 @@ SINGLE_BATTLE_TEST("Galvanize can not turn certain moves into Electric type move
}
}
SINGLE_BATTLE_TEST("Galvanize turns a normal type move into Electric")
{
GIVEN {
PLAYER(SPECIES_KRABBY);
OPPONENT(SPECIES_GEODUDE_ALOLAN) { Ability(ABILITY_GALVANIZE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
SINGLE_BATTLE_TEST("Pixilate turns a normal type move into Fairy")
{
GIVEN {
PLAYER(SPECIES_DRAGONITE);
OPPONENT(SPECIES_ALTARIA) { Item(ITEM_ALTARIANITE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
SINGLE_BATTLE_TEST("Refrigerate turns a normal type move into Ice")
{
GIVEN {
PLAYER(SPECIES_MEGANIUM);
OPPONENT(SPECIES_AMAURA) { Ability(ABILITY_REFRIGERATE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
SINGLE_BATTLE_TEST("Aerilate turns a normal type move into Flying")
{
GIVEN {
PLAYER(SPECIES_MEGANIUM);
OPPONENT(SPECIES_SALAMENCE) { Item(ITEM_SALAMENCITE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
TO_DO_BATTLE_TEST("Galvanize boosts power of affected moves by 20% (Gen7+)");
TO_DO_BATTLE_TEST("Galvanize boosts power of affected moves by 30% (Gen6)");
TO_DO_BATTLE_TEST("(DYNAMAX) Galvanize turns Max Strike into Max Lightning when not used by Gigantamax Pikachu/Toxtricity");
//TO_DO_BATTLE_TEST("(DYNAMAX) Galvanize doesn't turn Max Strike into Max Lightning when used by Gigantamax Pikachu/Toxtricity, instead becoming G-Max Volt Crash/Stun Shock"); // Marked in Bulbapedia as "needs research", so this assumes that it behaves like Pixilate.

View File

@ -0,0 +1,109 @@
#include "global.h"
#include "test/battle.h"
DOUBLE_BATTLE_TEST("Grim Neigh raises Sp. Attack by one stage after directly causing a Pokemon to faint")
{
u32 species = 0, ability = 0, abilityPopUp = 0;
PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_SHADOW_RIDER; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; }
GIVEN {
ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_SNORUNT) { HP(1); }
OPPONENT(SPECIES_GLALIE) { HP(1); }
OPPONENT(SPECIES_ABRA) { HP(1); }
OPPONENT(SPECIES_ABRA);
} WHEN {
TURN { MOVE(playerLeft, MOVE_DISCHARGE); SEND_OUT(opponentLeft, 2); }
} SCENE {
int i;
ANIMATION(ANIM_TYPE_MOVE, MOVE_DISCHARGE, playerLeft);
for (i = 0; i < 3; i++) {
ONE_OF {
MESSAGE("Snorunt fainted!");
MESSAGE("Foe Glalie fainted!");
MESSAGE("Foe Abra fainted!");
}
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
if (species == SPECIES_SPECTRIER)
MESSAGE("Spectrier's Grim Neigh raised its Sp. Atk!");
else
MESSAGE("Calyrex's Grim Neigh raised its Sp. Atk!");
}
} THEN {
EXPECT_EQ(playerLeft->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 3);
}
}
DOUBLE_BATTLE_TEST("Grim Neigh does not trigger if Pokemon faint to indirect damage or damage from other Pokemon")
{
u32 species = 0, ability = 0, abilityPopUp = 0;
PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_SHADOW_RIDER; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; }
GIVEN {
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_SNORUNT) { HP(1); Status1(STATUS1_POISON); }
OPPONENT(SPECIES_GLALIE) { HP(1); Status1(STATUS1_BURN); }
OPPONENT(SPECIES_ABRA) { HP(1); }
OPPONENT(SPECIES_ABRA);
} WHEN {
TURN { MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentRight); SEND_OUT(opponentLeft, 2); }
} SCENE {
int i;
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, playerRight);
for (i = 0; i < 3; i++) {
ONE_OF {
MESSAGE("Snorunt fainted!");
MESSAGE("Foe Glalie fainted!");
MESSAGE("Foe Abra fainted!");
}
NONE_OF {
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
MESSAGE("Salamence's Moxie raised its Sp. Atk!");
MESSAGE("Spectrier's Grim Neigh raised its Sp. Atk!");
MESSAGE("Calyrex's Grim Neigh raised its Sp. Atk!");
}
}
} THEN {
EXPECT_EQ(playerLeft->statStages[STAT_SPATK], DEFAULT_STAT_STAGE);
}
}
DOUBLE_BATTLE_TEST("Grim Neigh does not increase damage done by the same move that causes another Pokemon to faint")
{
s16 damage[2];
u32 species = 0, ability = 0, abilityPopUp = 0;
PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_SHADOW_RIDER; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; }
KNOWN_FAILING; // Requires simultaneous damage implementation
GIVEN {
ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_ABRA) { HP(1); }
OPPONENT(SPECIES_GLALIE);
OPPONENT(SPECIES_GLALIE);
OPPONENT(SPECIES_ABRA);
} WHEN {
TURN { MOVE(playerLeft, MOVE_DISCHARGE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DISCHARGE, playerLeft);
HP_BAR(opponentLeft, captureDamage: &damage[0]);
HP_BAR(playerRight);
MESSAGE("Abra fainted!");
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
if (species == SPECIES_SPECTRIER)
MESSAGE("Spectrier's Grim Neigh raised its Sp. Atk!");
else
MESSAGE("Calyrex's Grim Neigh raised its Sp. Atk!");
HP_BAR(opponentRight, captureDamage: &damage[1]);
} THEN {
EXPECT_EQ(playerLeft->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1);
EXPECT_EQ(damage[0], damage[1]);
}
}

View File

@ -3,6 +3,7 @@
TO_DO_BATTLE_TEST("Harvest has a 50% chance to restore a Berry at the end of the turn");
TO_DO_BATTLE_TEST("Harvest always restores a Berry in Sunlight");
TO_DO_BATTLE_TEST("Harvest doesn't always restore a Berry if Cloud Nine/Air Lock is on the field");
TO_DO_BATTLE_TEST("Harvest restores a Berry even after being switched out and back in");
TO_DO_BATTLE_TEST("Harvest restores a Berry consumed by Fling");
TO_DO_BATTLE_TEST("Harvest restores a Berry consumed by Natural Gift");

View File

@ -14,3 +14,5 @@ SINGLE_BATTLE_TEST("Hydration cures non-volatile Status conditions if it is rain
STATUS_ICON(player, none: TRUE);
}
}
TO_DO_BATTLE_TEST("Hydration doesn't cure status conditions if Cloud Nine/Air Lock is on the field");

View File

@ -26,3 +26,5 @@ SINGLE_BATTLE_TEST("Ice Body recovers 1/16th of Max HP in hail.")
MESSAGE("Glalie's Ice Body healed it a little bit!");
}
}
TO_DO_BATTLE_TEST("Sand Rush doesn't recover HP if Cloud Nine/Air Lock is on the field");

View File

@ -0,0 +1,9 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form"); // Include Special move in test
TO_DO_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face Eiscue is out");
TO_DO_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while hail or snow is active");
TO_DO_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face form while there's already hail");
TO_DO_BATTLE_TEST("Ice Face form change persists after switching out");
TO_DO_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field");

View File

@ -27,6 +27,8 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun")
}
}
TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent non-volatile status conditions if Cloud Nine/Air Lock is on the field");
SINGLE_BATTLE_TEST("Leaf Guard prevents status conditions from Flame Orb and Toxic Orb")
{
u32 item;
@ -49,6 +51,8 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents status conditions from Flame Orb and Tox
}
}
TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent status conditions from Flame Orb and Toxic Orb if Cloud Nine/Air Lock is on the field");
SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun")
{
GIVEN {
@ -66,3 +70,5 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun")
}
}
}
TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent Rest if Cloud Nine/Air Lock is on the field");

View File

@ -1,12 +1,15 @@
#include "global.h"
#include "test/battle.h"
DOUBLE_BATTLE_TEST("Moxie raises Attack by one stage after directly causing a Pokemon to faint")
DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh raises Attack by one stage after directly causing a Pokemon to faint")
{
ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
u32 species = 0, ability = 0, abilityPopUp = 0;
PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; }
PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; }
GIVEN {
PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); }
ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_SNORUNT) { HP(1); }
OPPONENT(SPECIES_GLALIE) { HP(1); }
OPPONENT(SPECIES_ABRA) { HP(1); }
@ -23,19 +26,28 @@ DOUBLE_BATTLE_TEST("Moxie raises Attack by one stage after directly causing a Po
MESSAGE("Foe Glalie fainted!");
MESSAGE("Foe Abra fainted!");
}
ABILITY_POPUP(playerLeft, ABILITY_MOXIE);
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
MESSAGE("Salamence's Moxie raised its Attack!");
if (species == SPECIES_SALAMENCE)
MESSAGE("Salamence's Moxie raised its Attack!");
else if (species == SPECIES_GLASTRIER)
MESSAGE("Glastrier's Chilling Neigh raised its Attack!");
else
MESSAGE("Calyrex's Chilling Neigh raised its Attack!");
}
} THEN {
EXPECT_EQ(playerLeft->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 3);
}
}
DOUBLE_BATTLE_TEST("Moxie does not trigger if Pokemon faint to indirect damage or damage from other Pokemon")
DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not trigger if Pokemon faint to indirect damage or damage from other Pokemon")
{
u32 species = 0, ability = 0, abilityPopUp = 0;
PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; }
PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; }
GIVEN {
PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); }
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_SNORUNT) { HP(1); Status1(STATUS1_POISON); }
OPPONENT(SPECIES_GLALIE) { HP(1); Status1(STATUS1_BURN); }
OPPONENT(SPECIES_ABRA) { HP(1); }
@ -53,9 +65,11 @@ DOUBLE_BATTLE_TEST("Moxie does not trigger if Pokemon faint to indirect damage o
MESSAGE("Foe Abra fainted!");
}
NONE_OF {
ABILITY_POPUP(playerLeft, ABILITY_MOXIE);
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
MESSAGE("Salamence's Moxie raised its Attack!");
MESSAGE("Glastrier's Chilling Neigh raised its Attack!");
MESSAGE("Calyrex's Chilling Neigh raised its Attack!");
}
}
} THEN {
@ -63,12 +77,15 @@ DOUBLE_BATTLE_TEST("Moxie does not trigger if Pokemon faint to indirect damage o
}
}
SINGLE_BATTLE_TEST("Moxie does not trigger when already at maximum Attack stage")
SINGLE_BATTLE_TEST("Moxie/Chilling Neigh does not trigger when already at maximum Attack stage")
{
ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
u32 species = 0, ability = 0, abilityPopUp = 0;
PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; }
PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; }
GIVEN {
PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); }
ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_SNORUNT) { HP(1); }
OPPONENT(SPECIES_SNORUNT);
} WHEN {
@ -77,28 +94,38 @@ SINGLE_BATTLE_TEST("Moxie does not trigger when already at maximum Attack stage"
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Salamence cut its own HP and maximized ATTACK!");
if (species == SPECIES_SALAMENCE)
MESSAGE("Salamence cut its own HP and maximized ATTACK!");
else if (species == SPECIES_GLASTRIER)
MESSAGE("Glastrier cut its own HP and maximized ATTACK!");
else
MESSAGE("Calyrex cut its own HP and maximized ATTACK!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, player);
MESSAGE("Foe Snorunt fainted!");
NONE_OF {
ABILITY_POPUP(player, ABILITY_MOXIE);
NONE_OF {
ABILITY_POPUP(player, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Salamence's Moxie raised its Attack!");
MESSAGE("Glastrier's Chilling Neigh raised its Attack!");
MESSAGE("Calyrex's Chilling Neigh raised its Attack!");
}
} THEN {
EXPECT_EQ(player->statStages[STAT_ATK], MAX_STAT_STAGE);
}
}
DOUBLE_BATTLE_TEST("Moxie does not increase damage done by the same move that causes another Pokemon to faint")
DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not increase damage done by the same move that causes another Pokemon to faint")
{
s16 damage[2];
ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
u32 species = 0, ability = 0, abilityPopUp = 0;
PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; }
PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; }
KNOWN_FAILING; // Requires simultaneous damage implementation
GIVEN {
PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); }
ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_ABRA) { HP(1); }
OPPONENT(SPECIES_GLALIE);
OPPONENT(SPECIES_GLALIE);
@ -110,9 +137,14 @@ DOUBLE_BATTLE_TEST("Moxie does not increase damage done by the same move that ca
HP_BAR(opponentLeft, captureDamage: &damage[0]);
HP_BAR(playerRight);
MESSAGE("Abra fainted!");
ABILITY_POPUP(playerLeft, ABILITY_MOXIE);
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
MESSAGE("Salamence's Moxie raised its Attack!");
if (species == SPECIES_SALAMENCE)
MESSAGE("Salamence's Moxie raised its Attack!");
else if (species == SPECIES_GLASTRIER)
MESSAGE("Glastrier's Chilling Neigh raised its Attack!");
else
MESSAGE("Calyrex's Chilling Neigh raised its Attack!");
HP_BAR(opponentRight, captureDamage: &damage[1]);
} THEN {
EXPECT_EQ(playerLeft->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);

View File

@ -0,0 +1,16 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Normalize tuns a move into a Normal-type move");
TO_DO_BATTLE_TEST("Normalize boosts power of both affected and originally Normal-type moves by 20% (Gen7+)");
TO_DO_BATTLE_TEST("Normalize affects status moves"); // Eg. Thunder Wave can affect Ground types
TO_DO_BATTLE_TEST("Normalize makes Flying Press do Normal/Flying damage");
TO_DO_BATTLE_TEST("Normalize still makes Freeze-Dry do super effective damage to Water-type Pokémon");
TO_DO_BATTLE_TEST("Normalize-affected moves become Electric-type under Electrify's effect");
TO_DO_BATTLE_TEST("Normalize-affected moves become Electric-type under Ion Deluge's effect");
TO_DO_BATTLE_TEST("Normalize doesn't affect Hidden Power's type");
TO_DO_BATTLE_TEST("Normalize doesn't affect Weather Ball's type");
TO_DO_BATTLE_TEST("Normalize doesn't affect Natural Gift's type");
TO_DO_BATTLE_TEST("Normalize doesn't affect Judgment/Techno Blast/Multi-Attack's type");
TO_DO_BATTLE_TEST("Normalize doesn't affect Terrain Pulse's type");
TO_DO_BATTLE_TEST("Normalize doesn't affect damaging Z-Move types");

View File

@ -0,0 +1,5 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Orichalcum Pulse sets up sun for 5 turns");
TO_DO_BATTLE_TEST("Orichalcum Pulse boosts the Pokémon's Attack by 33% in sun, even if it's holding an Utility Umbrella");

View File

@ -0,0 +1,35 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
}
SINGLE_BATTLE_TEST("Pixilate turns a Normal-type move into a Fairy-type move")
{
GIVEN {
PLAYER(SPECIES_DRAGONITE);
OPPONENT(SPECIES_ALTARIA) { Item(ITEM_ALTARIANITE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
TO_DO_BATTLE_TEST("Pixilate can not turn certain moves into Fairy type moves");
TO_DO_BATTLE_TEST("Pixilate boosts power of affected moves by 20% (Gen7+)");
TO_DO_BATTLE_TEST("Pixilate boosts power of affected moves by 30% (Gen6)");
TO_DO_BATTLE_TEST("(DYNAMAX) Pixilate turns Max Strike into Max Starfall when not used by Gigantamax Alcremie");
TO_DO_BATTLE_TEST("(DYNAMAX) Pixilate doesn't turn Max Strike into Max Starfall when used by Gigantamax Alcremie, instead becoming G-Max Finale");
// Gen 6-7
TO_DO_BATTLE_TEST("Pixilate overrides Electrify (Gen6-7)");
TO_DO_BATTLE_TEST("Pixilate overrides Ion Deluge (Gen6-7)");
// Gen 8+
TO_DO_BATTLE_TEST("Pixilate doesn't override Electrify (Gen8+)");
//TO_DO_BATTLE_TEST("Pixilate doesn't override Ion Deluge (Gen8+)"); // Ion Deluge doesn't exist in Gen 8+, but we probably could assume it behaves similar to under Electrify. TODO: Test by hacking SV.

View File

@ -99,3 +99,7 @@ SINGLE_BATTLE_TEST("Protosynthesis activates on switch-in")
MESSAGE("Roaring Moon's Attack was heightened!");
}
}
TO_DO_BATTLE_TEST("Protosynthesis activates in sun before Booster Energy");
TO_DO_BATTLE_TEST("Protosynthesis activates even if the Pokémon is holding an Utility Umbrella");
TO_DO_BATTLE_TEST("Protosynthesis doesn't activate if Cloud Nine/Air Lock is on the field");

View File

@ -14,3 +14,5 @@ SINGLE_BATTLE_TEST("Rain Dish recovers 1/16th of Max HP in Rain")
HP_BAR(player, damage: -(100 / 16));
}
}
TO_DO_BATTLE_TEST("Rain Dish doesn't recover HP if Cloud Nine/Air Lock is on the field");

View File

@ -0,0 +1,34 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
}
SINGLE_BATTLE_TEST("Refrigerate turns a Normal-type move into a Ice-type move")
{
GIVEN {
PLAYER(SPECIES_MEGANIUM);
OPPONENT(SPECIES_AMAURA) { Ability(ABILITY_REFRIGERATE); }
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
MESSAGE("It's super effective!");
}
}
TO_DO_BATTLE_TEST("Refrigerate can not turn certain moves into Ice type moves");
TO_DO_BATTLE_TEST("Refrigerate boosts power of affected moves by 20% (Gen7+)");
TO_DO_BATTLE_TEST("Refrigerate boosts power of affected moves by 30% (Gen6)");
TO_DO_BATTLE_TEST("(DYNAMAX) Refrigerate turns Max Strike into Max Hailstorm when not used by Gigantamax Lapras");
//TO_DO_BATTLE_TEST("(DYNAMAX) Refrigerate doesn't turn Max Strike into Max Hailstorm when used by Gigantamax Lapras, instead becoming G-Max Resonance"); // Marked in Bulbapedia as "needs research", so this assumes that it behaves like Pixilate.
// Gen 6-7
TO_DO_BATTLE_TEST("Refrigerate overrides Electrify (Gen6-7)");
TO_DO_BATTLE_TEST("Refrigerate overrides Ion Deluge (Gen6-7)");
// Gen 8+
//TO_DO_BATTLE_TEST("Refrigerate doesn't override Electrify (Gen8+)"); // Bulbapedia doesn't list this effect, so it assumes it behaves like Pixilate.
//TO_DO_BATTLE_TEST("Refrigerate doesn't override Ion Deluge (Gen8+)"); // Ion Deluge doesn't exist in Gen 8+, but we probably could assume it behaves similar to under Electrify. TODO: Test by hacking SV.

View File

@ -0,0 +1,6 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Sand Force prevents damage from sandstorm");
TO_DO_BATTLE_TEST("Sand Force increases the power of Rock-, Ground- and Steel-type moves by 30% in sandstorm");
TO_DO_BATTLE_TEST("Sand Force increases move power if Cloud Nine/Air Lock is on the field");

View File

@ -0,0 +1,6 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Sand Rush prevents damage from sandstorm");
TO_DO_BATTLE_TEST("Sand Rush doubles speed from sandstorm");
TO_DO_BATTLE_TEST("Sand Rush doesn't double speed if Cloud Nine/Air Lock is on the field");

View File

@ -28,3 +28,6 @@ SINGLE_BATTLE_TEST("Sand Veil increases evasion during sandstorm")
HP_BAR(player);
}
}
TO_DO_BATTLE_TEST("Sand Veil doesn't prevent Sandstorm damage if Cloud Nine/Air Lock is on the field");
TO_DO_BATTLE_TEST("Sand Veil doesn't increase evasion if Cloud Nine/Air Lock is on the field");

View File

@ -0,0 +1,6 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Slush Rush doubles speed from hail");
TO_DO_BATTLE_TEST("Slush Rush doubles speed from snow");
TO_DO_BATTLE_TEST("Slush Rush doesn't double speed if Cloud Nine/Air Lock is on the field");

View File

@ -27,3 +27,6 @@ SINGLE_BATTLE_TEST("Snow Cloak increases evasion during hail")
HP_BAR(player);
}
}
TO_DO_BATTLE_TEST("Snow Cloak doesn't prevent hail damage if Cloud Nine/Air Lock is on the field");
TO_DO_BATTLE_TEST("Snow Cloak doesn't increase evasion if Cloud Nine/Air Lock is on the field");

View File

@ -0,0 +1,7 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Solar Power increases a Sp. Attack by x1.5 in Sun");
TO_DO_BATTLE_TEST("Solar Power doesn't increases a Sp. Attack if Cloud Nine/Air Lock is on the field");
TO_DO_BATTLE_TEST("Solar Power causes the Pokémon to lose 1/8 max HP in Sun");
TO_DO_BATTLE_TEST("Solar Power doesn't cause the Pokémon to lose 1/8 max HP if Cloud Nine/Air Lock is on the field");

View File

@ -0,0 +1,6 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Swift Swim doubles speed if it's raining");
TO_DO_BATTLE_TEST("Swift Swim doesn't double speed if Cloud Nine/Air Lock is on the field");
TO_DO_BATTLE_TEST("Swift Swim doesn't double speed if they have an Utility Umbrella");

View File

@ -0,0 +1,6 @@
#include "global.h"
#include "test/battle.h"
// Remember to add a PARAMETRIZE for As One in the following tests:
TO_DO_BATTLE_TEST("Unnerve prevents opposing Pokémon from eating their own berries");
TO_DO_BATTLE_TEST("Unnerve doesn't prevent opposing Pokémon from using Natural Gift");

View File

@ -86,46 +86,6 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing into the same type gives that type 2x
}
}
SINGLE_BATTLE_TEST("(TERA) Terastallizing into a different type with Adaptability gives 2.0x STAB", s16 damage)
{
bool32 tera;
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_NORMAL); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_HEADBUTT, gimmick: tera); }
} SCENE {
MESSAGE("Crawdaunt used Headbutt!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_HEADBUTT, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
// The jump from no STAB to 2.0x STAB is a 2.0x boost.
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
}
}
SINGLE_BATTLE_TEST("(TERA) Terastallizing into the same type with Adaptability gives 2.25x STAB", s16 damage)
{
bool32 tera;
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_WATER); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_WATER_PULSE, gimmick: tera); }
} SCENE {
MESSAGE("Crawdaunt used Water Pulse!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PULSE, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
// The jump from 2x STAB to 2.25x STAB is a 1.125x boost.
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.125), results[1].damage);
}
}
SINGLE_BATTLE_TEST("(TERA) Terastallizing boosts moves of the same type to 60 BP", s16 damage)
{
bool32 tera;

View File

@ -52,3 +52,5 @@ SINGLE_BATTLE_TEST("Utility Umbrella blocks Rain damage modifiers", s16 damage)
EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage);
}
}
// Moves and abilities affected by Utility Umbrella have their tests in the respective files

View File

@ -80,57 +80,57 @@ SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie
}
}
DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [doubles]")
DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [doubles]", u32 permutations)
{
struct BattlePokemon *order[4] = { NULL, NULL, NULL, NULL };
u32 a, b, c, d;
// TODO: Test all of these in a single PASSES_RANDOMLY pass rather
// than 24 PARAMETRIZEd passes.
PARAMETRIZE { a = 0; b = 1; c = 2; d = 3; }
PARAMETRIZE { a = 0; b = 1; c = 3; d = 2; }
PARAMETRIZE { a = 0; b = 2; c = 1; d = 3; }
PARAMETRIZE { a = 0; b = 2; c = 3; d = 1; }
PARAMETRIZE { a = 0; b = 3; c = 1; d = 2; }
PARAMETRIZE { a = 0; b = 3; c = 2; d = 1; }
PARAMETRIZE { a = 1; b = 0; c = 2; d = 3; }
PARAMETRIZE { a = 1; b = 0; c = 3; d = 2; }
PARAMETRIZE { a = 1; b = 2; c = 0; d = 3; }
PARAMETRIZE { a = 1; b = 2; c = 3; d = 0; }
PARAMETRIZE { a = 1; b = 3; c = 0; d = 2; }
PARAMETRIZE { a = 1; b = 3; c = 2; d = 0; }
PARAMETRIZE { a = 2; b = 0; c = 1; d = 3; }
PARAMETRIZE { a = 2; b = 0; c = 3; d = 1; }
PARAMETRIZE { a = 2; b = 1; c = 0; d = 3; }
PARAMETRIZE { a = 2; b = 1; c = 3; d = 0; }
PARAMETRIZE { a = 2; b = 3; c = 0; d = 1; }
PARAMETRIZE { a = 2; b = 3; c = 1; d = 0; }
PARAMETRIZE { a = 3; b = 0; c = 1; d = 2; }
PARAMETRIZE { a = 3; b = 0; c = 2; d = 1; }
PARAMETRIZE { a = 3; b = 1; c = 0; d = 2; }
PARAMETRIZE { a = 3; b = 1; c = 2; d = 0; }
PARAMETRIZE { a = 3; b = 2; c = 0; d = 1; }
PARAMETRIZE { a = 3; b = 2; c = 1; d = 0; }
order[a] = playerLeft;
order[b] = playerRight;
order[c] = opponentLeft;
order[d] = opponentRight;
PASSES_RANDOMLY(1, 24, RNG_SPEED_TIE);
PARAMETRIZE {} // Hack to make permutations legal.
PASSES_RANDOMLY(24, 24, RNG_SPEED_TIE);
ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR);
ASSUME(gMovesInfo[MOVE_LIFE_DEW].effect == EFFECT_JUNGLE_HEALING);
ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_VARY_POWER_BASED_ON_HP);
ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG);
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
PLAYER(SPECIES_WOBBUFFET) { MaxHP(480); HP(360); Defense(100); Speed(1); }
PLAYER(SPECIES_WYNAUT) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Attack(100); Speed(1); }
OPPONENT(SPECIES_WYNAUT) { Speed(1); }
} WHEN {
TURN { MOVE(playerLeft, MOVE_SPLASH); MOVE(playerRight, MOVE_SPLASH); MOVE(opponentLeft, MOVE_SPLASH); MOVE(opponentRight, MOVE_SPLASH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[0]);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[1]);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[2]);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[3]);
TURN { MOVE(playerLeft, MOVE_ENDEAVOR, target: opponentLeft); MOVE(playerRight, MOVE_LIFE_DEW); MOVE(opponentLeft, MOVE_CRUSH_GRIP, target: playerLeft, WITH_RNG(RNG_DAMAGE_MODIFIER, 0)); MOVE(opponentRight, MOVE_SUPER_FANG, target: playerLeft); }
} THEN {
// This tests for unique combinatins of HP values depending on which order the moves are executed in
// The unique outcomes arise from the specific attacks and HP, Def, and Atk values chosen
// The switch is then set up in such a way that the only way for this test to pass exactly one is for each HP combination to occur exactly once
#define HP_PAIR(a, b) ((a) * 1000 + (b))
switch (HP_PAIR(playerLeft->hp, opponentLeft->hp))
{
case HP_PAIR(188, 360): results[i].permutations += 1 << 0; break;
case HP_PAIR(189, 360): results[i].permutations += 1 << 1; break;
case HP_PAIR(261, 360): results[i].permutations += 1 << 2; break;
case HP_PAIR(235, 360): results[i].permutations += 1 << 3; break;
case HP_PAIR(262, 360): results[i].permutations += 1 << 4; break;
case HP_PAIR(202, 360): results[i].permutations += 1 << 5; break;
case HP_PAIR(189, 378): results[i].permutations += 1 << 6; break;
case HP_PAIR(189, 189): results[i].permutations += 1 << 7; break;
case HP_PAIR(189, 480): results[i].permutations += 1 << 8; break;
case HP_PAIR(188, 480): results[i].permutations += 1 << 9; break;
case HP_PAIR(188, 240): results[i].permutations += 1 << 10; break;
case HP_PAIR(188, 188): results[i].permutations += 1 << 11; break;
case HP_PAIR(262, 262): results[i].permutations += 1 << 12; break;
case HP_PAIR(262, 142): results[i].permutations += 1 << 13; break;
case HP_PAIR(202, 403): results[i].permutations += 1 << 14; break;
case HP_PAIR(202, 202): results[i].permutations += 1 << 15; break;
case HP_PAIR(262, 283): results[i].permutations += 1 << 16; break;
case HP_PAIR(202, 283): results[i].permutations += 1 << 17; break;
case HP_PAIR(235, 180): results[i].permutations += 1 << 18; break;
case HP_PAIR(261, 180): results[i].permutations += 1 << 19; break;
case HP_PAIR(235, 235): results[i].permutations += 1 << 20; break;
case HP_PAIR(235, 300): results[i].permutations += 1 << 21; break;
case HP_PAIR(261, 141): results[i].permutations += 1 << 22; break;
case HP_PAIR(261, 261): results[i].permutations += 1 << 23; break;
}
#undef HP_PAIR
} FINALLY {
EXPECT_EQ(results[i].permutations, (1 << 24) - 1);
}
}

View File

@ -78,3 +78,5 @@ SINGLE_BATTLE_TEST("Weather Ball doubles its power and turns to an Ice-type move
EXPECT_MUL_EQ(results[0].damage, Q_4_12(4.0), results[1].damage); // double base power + type effectiveness.
}
}
TO_DO_BATTLE_TEST("Weather Ball doesn't double its power or change type if Cloud Nine/Air Lock is on the field");

View File

@ -1327,7 +1327,7 @@ void TestRunner_Battle_AfterLastTurn(void)
}
STATE->runThen = TRUE;
STATE->runFinally = STATE->runParameter + 1 == STATE->parameters;
STATE->runFinally = STATE->runParameter + 1 == STATE->parameters && STATE->runTrial + 1 >= STATE->trials;
InvokeTestFunction(test);
STATE->runThen = FALSE;
STATE->runFinally = FALSE;
@ -1369,6 +1369,7 @@ static inline rng_value_t MakeRngValue(const u16 seed)
return ISO_RANDOMIZE1(seed);
#endif
}
static void CB2_BattleTest_NextTrial(void)
{
ClearFlagAfterTest();
@ -1452,7 +1453,7 @@ void Randomly(u32 sourceLine, u32 passes, u32 trials, struct RandomlyContext ctx
{
const struct BattleTest *test = GetBattleTest();
INVALID_IF(STATE->trials != 0, "PASSES_RANDOMLY can only be used once per test");
INVALID_IF(test->resultsSize > 0, "PASSES_RANDOMLY is incompatible with results");
INVALID_IF(test->resultsSize > 0 && STATE->parametersCount > 1, "PASSES_RANDOMLY is incompatible with results");
INVALID_IF(passes > trials, "%d passes specified, but only %d trials", passes, trials);
STATE->rngTag = ctx.tag;
STATE->rngTrialOffset = 0;