Merge branch 'upcoming' into gen9-species-nomigration
This commit is contained in:
commit
4aa14355d7
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -28,7 +28,9 @@ jobs:
|
||||
repository: pret/agbcc
|
||||
|
||||
- name: Install binutils
|
||||
run: sudo apt install -y build-essential libpng-dev libelf-dev
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential libpng-dev libelf-dev
|
||||
# build-essential, git, and libpng-dev are already installed
|
||||
# gcc-arm-none-eabi is only needed for the modern build
|
||||
# as an alternative to dkP
|
||||
|
||||
@ -4061,58 +4061,57 @@ Move_BUG_BITE:
|
||||
end
|
||||
|
||||
Move_CHARGE_BEAM:
|
||||
loadspritegfx ANIM_TAG_BLACK_BALL_2
|
||||
loadspritegfx ANIM_TAG_ELECTRIC_ORBS
|
||||
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT
|
||||
loadspritegfx ANIM_TAG_ELECTRICITY
|
||||
loadspritegfx ANIM_TAG_SPARK_2
|
||||
delay 0
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_ATTACKER), -31, 1, 5, 5, RGB(31, 31, 22)
|
||||
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
|
||||
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 32, 24, 190, 12, 0, 1, 0
|
||||
delay 0
|
||||
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 80, 24, 22, 12, 0, 1, 0
|
||||
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 156, 24, 121, 13, 0, 1, 1
|
||||
delay 0
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_ATTACKER), -31, 1, 0, 0, RGB(31, 31, 22)
|
||||
delay 10
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_ATTACKER), -31, 1, 5, 5, RGB(31, 31, 22)
|
||||
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
|
||||
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 100, 24, 60, 10, 0, 1, 0
|
||||
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 170, 24, 42, 11, 0, 1, 1
|
||||
delay 0
|
||||
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 238, 24, 165, 10, 0, 1, 1
|
||||
delay 0
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_ATTACKER), -31, 1, 0, 0, RGB(31, 31, 22)
|
||||
setalpha 12, 8
|
||||
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 4, RGB_BLACK
|
||||
waitforvisualfinish
|
||||
createvisualtask AnimTask_ElectricChargingParticles, 2, ANIM_ATTACKER, 20, 0, 2
|
||||
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
|
||||
delay 12
|
||||
createsprite gGrowingShockWaveOrbSpriteTemplate, ANIM_ATTACKER, 2
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 0, 11, RGB(31, 31, 22)
|
||||
delay 50
|
||||
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 16, 0, 5
|
||||
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 4, 50, 1
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 50, 1
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 11, 0, RGB(31, 31, 22)
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 11, RGB(31, 31, 22)
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
call SparkBeam
|
||||
delay 20
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_ATTACKER), -31, 1, 7, 7, RGB(31, 31, 22)
|
||||
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 0, 20, 0, 0
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 64, 20, 1, 0
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 128, 20, 0, 0
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 192, 20, 2, 0
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 32, 20, 0, 0
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 96, 20, 1, 0
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 160, 20, 0, 0
|
||||
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 224, 20, 2, 0
|
||||
delay 4
|
||||
waitforvisualfinish
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_ATTACKER), -31, 1, 0, 0, RGB(31, 31, 22)
|
||||
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_ATTACKER
|
||||
createsprite gZapCannonBallSpriteTemplate, ANIM_TARGET, 3, 10, 0, 0, 0, 30, 0
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 0, 40, 0
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 64, 40, 1
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 128, 40, 0
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 192, 40, 2
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 32, 40, 0
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 96, 40, 1
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 160, 40, 0
|
||||
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 224, 40, 2
|
||||
waitforvisualfinish
|
||||
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 5, 1
|
||||
delay 15
|
||||
waitplaysewithpan SE_M_THUNDERBOLT2, SOUND_PAN_TARGET, 19
|
||||
call ElectricityEffect
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 11, 0, RGB(31, 31, 22)
|
||||
waitforvisualfinish
|
||||
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 4, 4, 0, RGB_BLACK
|
||||
blendoff
|
||||
end
|
||||
|
||||
SparkBeam:
|
||||
createsprite gSparkBeamSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0
|
||||
delay 1
|
||||
createsprite gSparkBeamSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0
|
||||
delay 1
|
||||
return
|
||||
|
||||
Move_WOOD_HAMMER:
|
||||
loadspritegfx ANIM_TAG_WOOD_HAMMER
|
||||
loadspritegfx ANIM_TAG_WOOD_HAMMER_HAMMER
|
||||
@ -4297,22 +4296,22 @@ Move_HEAL_ORDER:
|
||||
|
||||
Move_HEAD_SMASH:
|
||||
loadspritegfx ANIM_TAG_IMPACT
|
||||
call SetImpactBackground
|
||||
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 0
|
||||
loadspritegfx ANIM_TAG_ROCKS
|
||||
createvisualtask AnimTask_SkullBashPosition, 2, 0
|
||||
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
|
||||
waitforvisualfinish
|
||||
delay 2
|
||||
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 1
|
||||
playse SE_BANG
|
||||
call SetImpactBackground
|
||||
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 40, 1
|
||||
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 10, 0, 40, 1
|
||||
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 4, 0, 0, ANIM_TARGET, 0
|
||||
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
|
||||
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -12, 32, 3, 4
|
||||
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 8, 31, 2, 2
|
||||
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -4, 28, 2, 3
|
||||
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 12, 30, 4, 3
|
||||
waitforvisualfinish
|
||||
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 4, 1
|
||||
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
|
||||
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 2
|
||||
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 1
|
||||
loopsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET, 8, 3
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_TARGET
|
||||
blendoff
|
||||
delay 2
|
||||
createvisualtask AnimTask_SkullBashPosition, 2, 1
|
||||
restorebg
|
||||
waitbgfadein
|
||||
end
|
||||
@ -4861,19 +4860,82 @@ Move_WONDER_ROOM::
|
||||
end
|
||||
|
||||
Move_PSYSHOCK:
|
||||
loadspritegfx ANIM_TAG_RED_ORB_2
|
||||
loadspritegfx ANIM_TAG_POISON_JAB
|
||||
loadspritegfx ANIM_TAG_GRAY_SMOKE
|
||||
loadspritegfx ANIM_TAG_WISP_FIRE
|
||||
monbg ANIM_TARGET
|
||||
setalpha 8, 8
|
||||
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_ATTACKER
|
||||
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 10, 1
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 8, RGB(31, 23, 0)
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 8, RGB_WHITE
|
||||
waitforvisualfinish
|
||||
loopsewithpan SE_M_SUPERSONIC, SOUND_PAN_TARGET, 10, 3
|
||||
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 15, 1
|
||||
createvisualtask AnimTask_ScaleMonAndRestore, 5, -6, -6, 15, ANIM_TARGET, 1
|
||||
delay 10
|
||||
call PsyshockConverge
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_TARGET
|
||||
blendoff
|
||||
end
|
||||
|
||||
PsyshockConverge:
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 40, 40, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, -40, -40, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 0, 40, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 0, -40, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 40, -20, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 40, 20, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, -40, -20, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, -40, 20, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, -20, 30, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 20, -30, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, -20, -30, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 20, 30, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, -40, 0, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockOrbSpriteTemplate, ANIM_TARGET, 2, 40, 0, 16
|
||||
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
|
||||
delay 6
|
||||
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 15, 1
|
||||
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_TARGET, RGB_WHITE, 12, 0, 1
|
||||
createsprite gPsyshockSmokeSpriteTemplate, ANIM_TARGET, 2, 8, 8, 1, 0
|
||||
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockSmokeSpriteTemplate, ANIM_TARGET, 2, -8, -8, 1, 0
|
||||
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockSmokeSpriteTemplate, ANIM_TARGET, 2, 8, -8, 1, 0
|
||||
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gPsyshockSmokeSpriteTemplate, ANIM_TARGET, 2, -8, 8, 1, 0
|
||||
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
return
|
||||
|
||||
Move_VENOSHOCK:
|
||||
loadspritegfx ANIM_TAG_POISON_BUBBLE
|
||||
loadspritegfx ANIM_TAG_TOXIC_BUBBLE
|
||||
@ -5802,23 +5864,79 @@ Move_QUASH:
|
||||
|
||||
Move_ACROBATICS:
|
||||
loadspritegfx ANIM_TAG_ROUND_SHADOW
|
||||
loadspritegfx ANIM_TAG_WHITE_STREAK
|
||||
loadspritegfx ANIM_TAG_IMPACT
|
||||
monbg ANIM_TARGET
|
||||
setalpha 12, 8
|
||||
playsewithpan SE_M_FLY, SOUND_PAN_ATTACKER
|
||||
createsprite gFlyBallUpSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 13, 336
|
||||
waitforvisualfinish
|
||||
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
|
||||
createsprite gBounceBallLandSpriteTemplate, ANIM_TARGET, 3
|
||||
delay 7
|
||||
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
|
||||
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, 1, 0
|
||||
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 11, 1
|
||||
call SetSkyBg
|
||||
call AcrobaticsSlashes
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_TARGET
|
||||
blendoff
|
||||
visible ANIM_ATTACKER
|
||||
call UnsetSkyBg
|
||||
end
|
||||
|
||||
AcrobaticsSlashes:
|
||||
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 40, 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -10, 3
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, 24, -19
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -28, -15
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -6, -30
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -20, 6
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, 28, 2
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -14, -25
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, 9, -2
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -1, 0
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, 21, 4
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, 28, 20
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -7, 24
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -11, 1
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, 12, -18
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -21, -14
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -29, 7
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, 15, 28
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 1
|
||||
createsprite gAcrobaticsSlashesSpriteTemplate, ANIM_TARGET, 2, -21, -16
|
||||
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
|
||||
delay 2
|
||||
return
|
||||
|
||||
Move_REFLECT_TYPE:
|
||||
loadspritegfx ANIM_TAG_GUARD_RING @ring around user
|
||||
loadspritegfx ANIM_TAG_ICE_CHUNK @blue green color
|
||||
@ -8313,17 +8431,99 @@ Move_FELL_STINGER:
|
||||
end
|
||||
|
||||
Move_PHANTOM_FORCE:
|
||||
choosetwoturnanim PhantomForceSetUp, PhantomForceUnleash
|
||||
PhantomForceEnd:
|
||||
loadspritegfx ANIM_TAG_ROUND_SHADOW
|
||||
loadspritegfx ANIM_TAG_IMPACT
|
||||
choosetwoturnanim PhantomForcePrep PhantomForceAttack
|
||||
PhantomForceWaitEnd:
|
||||
waitforvisualfinish
|
||||
restorebg
|
||||
waitbgfadein
|
||||
end
|
||||
PhantomForceSetUp:
|
||||
PhantomForcePrep:
|
||||
monbg ANIM_ATTACKER
|
||||
fadetobg BG_GHOST
|
||||
waitbgfadein
|
||||
delay 0
|
||||
playsewithpan SE_M_FAINT_ATTACK, SOUND_PAN_ATTACKER
|
||||
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 1, 3
|
||||
createvisualtask AnimTask_AttackerFadeToInvisible, 2, 1
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_ATTACKER
|
||||
invisible ANIM_ATTACKER
|
||||
goto PhantomForceEnd
|
||||
PhantomForceUnleash:
|
||||
visible ANIM_ATTACKER
|
||||
goto PhantomForceEnd
|
||||
delay 1
|
||||
goto PhantomForceWaitEnd
|
||||
PhantomForceAttack:
|
||||
loadspritegfx ANIM_TAG_PURPLE_FLAME
|
||||
loadspritegfx ANIM_TAG_WHITE_SHADOW @Destiny Bond
|
||||
monbg ANIM_ATTACKER
|
||||
splitbgprio ANIM_ATTACKER
|
||||
fadetobg BG_GHOST
|
||||
waitbgfadein
|
||||
delay 1
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_IMPACT, 0, 12, 12, RGB(0, 0, 23)
|
||||
setalpha 12, 8
|
||||
waitforvisualfinish
|
||||
delay 10
|
||||
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
|
||||
createvisualtask AnimTask_PurpleFlamesOnTarget, 0x3
|
||||
createvisualtask AnimTask_DestinyBondWhiteShadow, 0x5, 0x0, 0x30
|
||||
delay 30
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_IMPACT, 0, 12, 12, RGB(0, 0, 23)
|
||||
waitforvisualfinish
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
|
||||
createvisualtask SoundTask_PlaySE1WithPanning, 5, 215, SOUND_PAN_TARGET
|
||||
delay 3
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_DEF_PARTNER, 2
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_ATK_PARTNER, 2
|
||||
createvisualtask SoundTask_PlaySE1WithPanning, 5, 215, SOUND_PAN_TARGET
|
||||
delay 3
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_DEF_PARTNER, 2
|
||||
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_ATK_PARTNER, 2
|
||||
createvisualtask SoundTask_PlaySE1WithPanning, 5, 215, SOUND_PAN_TARGET
|
||||
delay 3
|
||||
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 12, 1
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 0, 2, 0, 13, RGB_PURPLE
|
||||
waitforvisualfinish
|
||||
delay 1
|
||||
playsewithpan SOUND_PAN_ATTACKER, 192
|
||||
createvisualtask AnimTask_NightShadeClone, 5, 10
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_ATTACKER
|
||||
delay 1
|
||||
goto PhantomForceWaitEnd
|
||||
PhantomForceBg:
|
||||
fadetobg BG_DARK
|
||||
waitbgfadeout
|
||||
createvisualtask AnimTask_FadeScreenToWhite, 5
|
||||
waitbgfadein
|
||||
return
|
||||
|
||||
Move_TRICK_OR_TREAT:
|
||||
loadspritegfx ANIM_TAG_EYE_SPARKLE
|
||||
loadspritegfx ANIM_TAG_GHOSTLY_SPIRIT
|
||||
fadetobg BG_NIGHTMARE
|
||||
waitbgfadein
|
||||
delay 10
|
||||
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
|
||||
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 10, 1
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 8, RGB(10, 2, 19)
|
||||
waitforvisualfinish
|
||||
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
|
||||
createvisualtask AnimTask_ScaryFace, 5
|
||||
delay 13
|
||||
waitforvisualfinish
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 2, 2, 0, 12, RGB(10, 2, 19) @;Deep purple
|
||||
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
|
||||
createsprite gCurseGhostSpriteTemplate, ANIM_TARGET, 2
|
||||
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 14, 1
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_TARGET
|
||||
restorebg
|
||||
waitbgfadein
|
||||
end
|
||||
|
||||
Move_NOBLE_ROAR:
|
||||
|
||||
19
graphics/items/icon_palettes/fairy_feather.pal
Normal file
19
graphics/items/icon_palettes/fairy_feather.pal
Normal file
@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
180 180 180
|
||||
11 15 16
|
||||
33 19 27
|
||||
59 38 38
|
||||
102 90 92
|
||||
200 124 124
|
||||
182 116 141
|
||||
255 124 189
|
||||
227 140 140
|
||||
253 155 155
|
||||
222 173 189
|
||||
255 175 175
|
||||
195 191 192
|
||||
252 161 206
|
||||
225 221 223
|
||||
245 245 245
|
||||
BIN
graphics/items/icons/fairy_feather.png
Normal file
BIN
graphics/items/icons/fairy_feather.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 266 B |
BIN
graphics/pokemon/pikachu/iconf.png
Normal file
BIN
graphics/pokemon/pikachu/iconf.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 347 B |
BIN
graphics/pokemon/wobbuffet/iconf.png
Normal file
BIN
graphics/pokemon/wobbuffet/iconf.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 336 B |
@ -672,7 +672,7 @@ struct BattleStruct
|
||||
u8 lastMoveFailed; // as bits for each battler, for the sake of Stomping Tantrum
|
||||
u8 lastMoveTarget[MAX_BATTLERS_COUNT]; // The last target on which each mon used a move, for the sake of Instruct
|
||||
u16 tracedAbility[MAX_BATTLERS_COUNT];
|
||||
u16 hpBefore[MAX_BATTLERS_COUNT]; // Hp of battlers before using a move. For Berserk
|
||||
u16 hpBefore[MAX_BATTLERS_COUNT]; // Hp of battlers before using a move. For Berserk and Anger Shell.
|
||||
bool8 spriteIgnore0Hp;
|
||||
struct Illusion illusion[MAX_BATTLERS_COUNT];
|
||||
s32 aiFinalScore[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // AI, target, moves to make debugging easier
|
||||
|
||||
@ -91,7 +91,6 @@ bool32 AI_IsDamagedByRecoil(u32 battler);
|
||||
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
||||
u32 GetNoOfHitsToKOBattlerDmg(u32 dmg, u32 battlerDef);
|
||||
u32 GetNoOfHitsToKOBattler(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
|
||||
bool32 IsInIgnoredPowerfulMoveEffects(u32 effect);
|
||||
void SetMovesDamageResults(u32 battlerAtk, u16 *moves);
|
||||
u32 GetMoveDamageResult(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
|
||||
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef);
|
||||
@ -113,6 +112,7 @@ bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility);
|
||||
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 IsHazardMoveEffect(u32 moveEffect);
|
||||
bool32 IsEncoreEncouragedEffect(u32 moveEffect);
|
||||
bool32 IsChargingMove(u32 battlerAtk, u32 effect);
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
|
||||
bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
|
||||
bool32 ShouldSetHail(u32 battler, u32 ability, u32 holdEffect);
|
||||
|
||||
@ -25,10 +25,10 @@
|
||||
// Species-specific settings
|
||||
#define P_SHEDINJA_BALL GEN_LATEST // Since Gen 4, Shedinja requires a Poké Ball for its evolution. In Gen 3, Shedinja inherits Nincada's Ball.
|
||||
#define P_KADABRA_EVERSTONE GEN_LATEST // Since Gen 4, Kadabra can evolve even when holding an Everstone.
|
||||
#define P_HIPPO_GENDER_DIFF_ICONS TRUE // If TRUE, will give Hippopotas and Hippowdon custom icons for their female forms.
|
||||
#define P_SHUCKLE_BERRY_JUICE TRUE // In Gen 2, Shuckle had a 1/16 chance of converting Berry that it's holding into Berry Juice. Setting this to TRUE will allow to do this with an Oran Berry, which is the spiritual succesor of the Berry item.
|
||||
|
||||
// Other settings
|
||||
#define P_CUSTOM_GENDER_DIFF_ICONS TRUE // If TRUE, will give more Pokémon custom icons for their female forms, i.e. Hippopotas and Hippowdon
|
||||
#define P_LEGENDARY_PERFECT_IVS GEN_LATEST // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs.
|
||||
#define P_EV_CAP GEN_LATEST // Since Gen 6, the max EVs per stat is 252 instead of 255.
|
||||
|
||||
|
||||
@ -301,16 +301,16 @@
|
||||
#define MOVEEND_ATTACKER_VISIBLE 10
|
||||
#define MOVEEND_TARGET_VISIBLE 11
|
||||
#define MOVEEND_ITEM_EFFECTS_TARGET 12
|
||||
#define MOVEEND_ITEM_EFFECTS_ALL 13
|
||||
#define MOVEEND_KINGSROCK 14 // These item effects will occur each strike of a multi-hit move
|
||||
#define MOVEEND_SUBSTITUTE 15
|
||||
#define MOVEEND_SKY_DROP_CONFUSE 16
|
||||
#define MOVEEND_UPDATE_LAST_MOVES 17
|
||||
#define MOVEEND_MIRROR_MOVE 18
|
||||
#define MOVEEND_NEXT_TARGET 19 // Everything up until here is handled for each strike of a multi-hit move
|
||||
#define MOVEEND_MULTIHIT_MOVE 20
|
||||
#define MOVEEND_DEFROST 21
|
||||
#define MOVEEND_MOVE_EFFECTS2 22
|
||||
#define MOVEEND_MOVE_EFFECTS2 13
|
||||
#define MOVEEND_ITEM_EFFECTS_ALL 14
|
||||
#define MOVEEND_KINGSROCK 15 // These item effects will occur each strike of a multi-hit move
|
||||
#define MOVEEND_SUBSTITUTE 16
|
||||
#define MOVEEND_SKY_DROP_CONFUSE 17
|
||||
#define MOVEEND_UPDATE_LAST_MOVES 18
|
||||
#define MOVEEND_MIRROR_MOVE 19
|
||||
#define MOVEEND_NEXT_TARGET 20 // Everything up until here is handled for each strike of a multi-hit move
|
||||
#define MOVEEND_MULTIHIT_MOVE 21
|
||||
#define MOVEEND_DEFROST 22
|
||||
#define MOVEEND_RECOIL 23
|
||||
#define MOVEEND_MAGICIAN 24 // Occurs after final multi-hit strike, and after other items/abilities would activate
|
||||
#define MOVEEND_EJECT_BUTTON 25
|
||||
|
||||
@ -5227,6 +5227,9 @@ extern const u8 gMonIcon_Fearow[];
|
||||
extern const u8 gMonIcon_Ekans[];
|
||||
extern const u8 gMonIcon_Arbok[];
|
||||
extern const u8 gMonIcon_Pikachu[];
|
||||
#if P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
extern const u8 gMonIcon_PikachuF[];
|
||||
#endif
|
||||
extern const u8 gMonIcon_Raichu[];
|
||||
extern const u8 gMonIcon_Sandshrew[];
|
||||
extern const u8 gMonIcon_Sandslash[];
|
||||
@ -5404,6 +5407,9 @@ extern const u8 gMonIcon_Slowking[];
|
||||
extern const u8 gMonIcon_Misdreavus[];
|
||||
extern const u8 gMonIcon_Unown[];
|
||||
extern const u8 gMonIcon_Wobbuffet[];
|
||||
#if P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
extern const u8 gMonIcon_WobbuffetF[];
|
||||
#endif
|
||||
extern const u8 gMonIcon_Girafarig[];
|
||||
extern const u8 gMonIcon_Pineco[];
|
||||
extern const u8 gMonIcon_Forretress[];
|
||||
@ -5653,7 +5659,7 @@ extern const u8 gMonIcon_Riolu[];
|
||||
extern const u8 gMonIcon_Lucario[];
|
||||
extern const u8 gMonIcon_Hippopotas[];
|
||||
extern const u8 gMonIcon_Hippowdon[];
|
||||
#if P_HIPPO_GENDER_DIFF_ICONS == TRUE
|
||||
#if P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
extern const u8 gMonIcon_HippopotasF[];
|
||||
extern const u8 gMonIcon_HippowdonF[];
|
||||
#endif
|
||||
@ -10058,6 +10064,9 @@ extern const u32 gItemIconPalette_LustrousGlobe[];
|
||||
extern const u32 gItemIcon_BerserkGene[];
|
||||
extern const u32 gItemIconPalette_BerserkGene[];
|
||||
|
||||
extern const u32 gItemIcon_FairyFeather[];
|
||||
extern const u32 gItemIconPalette_FairyFeather[];
|
||||
|
||||
extern const u32 gItemIcon_ReturnToFieldArrow[];
|
||||
extern const u32 gItemIconPalette_ReturnToFieldArrow[];
|
||||
|
||||
|
||||
@ -760,6 +760,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER)
|
||||
RETURN_SCORE_MINUS(20); // if target off screen and we go first, don't use move
|
||||
|
||||
if (IsChargingMove(battlerAtk, moveEffect) && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
RETURN_SCORE_MINUS(10);
|
||||
|
||||
// check if negates type
|
||||
switch (effectiveness)
|
||||
{
|
||||
@ -1356,22 +1359,13 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
}
|
||||
break;
|
||||
//case EFFECT_BIDE:
|
||||
//case EFFECT_SUPER_FANG:
|
||||
//case EFFECT_RECHARGE:
|
||||
case EFFECT_LEVEL_DAMAGE:
|
||||
case EFFECT_PSYWAVE:
|
||||
//case EFFECT_COUNTER:
|
||||
//case EFFECT_FLAIL:
|
||||
case EFFECT_RETURN:
|
||||
case EFFECT_PRESENT:
|
||||
case EFFECT_FRUSTRATION:
|
||||
case EFFECT_SONICBOOM:
|
||||
//case EFFECT_MIRROR_COAT:
|
||||
case EFFECT_SKULL_BASH:
|
||||
case EFFECT_FOCUS_PUNCH:
|
||||
case EFFECT_SUPERPOWER:
|
||||
//case EFFECT_ENDEAVOR:
|
||||
case EFFECT_LOW_KICK:
|
||||
// AI_CBM_HighRiskForDamage
|
||||
if (aiData->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2)
|
||||
ADJUST_SCORE(-10);
|
||||
@ -1906,17 +1900,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
|| (gBattleMons[battlerDef].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))) //Leave out Illusion b/c AI is supposed to be fooled
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
if (aiData->holdEffects[battlerAtk] != HOLD_EFFECT_POWER_HERB && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
ADJUST_SCORE(-6);
|
||||
break;
|
||||
case EFFECT_RECHARGE:
|
||||
if (aiData->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (aiData->abilities[battlerAtk] != ABILITY_TRUANT
|
||||
&& !CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
ADJUST_SCORE(-2);
|
||||
break;
|
||||
case EFFECT_SPITE:
|
||||
case EFFECT_MIMIC:
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER) // Attacker should go first
|
||||
@ -2109,13 +2092,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
break;
|
||||
case EFFECT_SPECTRAL_THIEF:
|
||||
break;
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB
|
||||
|| ((AI_GetWeather(aiData) & B_WEATHER_SUN) && aiData->holdEffects[battlerAtk] != HOLD_EFFECT_UTILITY_UMBRELLA))
|
||||
break;
|
||||
if (CanTargetFaintAi(battlerDef, battlerAtk)) //Attacker can be knocked out
|
||||
ADJUST_SCORE(-4);
|
||||
break;
|
||||
case EFFECT_SEMI_INVULNERABLE:
|
||||
if (predictedMove != MOVE_NONE
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER
|
||||
@ -2674,6 +2650,10 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
&& !BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPDEF))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_LOW_KICK:
|
||||
if (IsDynamaxed(battlerDef))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_PLACEHOLDER:
|
||||
return 0; // cannot even select
|
||||
} // move effect checks
|
||||
@ -3151,7 +3131,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
||||
s32 score = 0;
|
||||
s32 leastHits = 1000;
|
||||
u16 *moves = GetMovesArray(battlerAtk);
|
||||
bool8 isPowerfulIgnoredEffect[MAX_MON_MOVES];
|
||||
bool8 isChargingMoveEffect[MAX_MON_MOVES];
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
@ -3163,13 +3143,13 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
||||
leastHits = noOfHits[i];
|
||||
}
|
||||
viableMoveScores[i] = AI_SCORE_DEFAULT;
|
||||
isPowerfulIgnoredEffect[i] = IsInIgnoredPowerfulMoveEffects(gBattleMoves[moves[i]].effect);
|
||||
isChargingMoveEffect[i] = IsChargingMove(battlerAtk, gBattleMoves[moves[i]].effect);
|
||||
}
|
||||
else
|
||||
{
|
||||
noOfHits[i] = -1;
|
||||
viableMoveScores[i] = 0;
|
||||
isPowerfulIgnoredEffect[i] = FALSE;
|
||||
isChargingMoveEffect[i] = FALSE;
|
||||
}
|
||||
/*
|
||||
MgbaPrintf_("%S: required hits: %d Dmg: %d", gMoveNames[moves[i]], noOfHits[i], AI_DATA->simulatedDmg[battlerAtk][battlerDef][i]);
|
||||
@ -3178,7 +3158,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
||||
|
||||
// Priority list:
|
||||
// 1. Less no of hits to ko
|
||||
// 2. Not in the powerful but ignored move effects table
|
||||
// 2. Not charging
|
||||
// 3. More accuracy
|
||||
// 4. Better effect
|
||||
|
||||
@ -3193,9 +3173,9 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
||||
{
|
||||
multipleBestMoves = TRUE;
|
||||
// We need to make sure it's the current move which is objectively better.
|
||||
if (isPowerfulIgnoredEffect[i] && !isPowerfulIgnoredEffect[currId])
|
||||
if (isChargingMoveEffect[i] && !isChargingMoveEffect[currId])
|
||||
viableMoveScores[i] -= 3;
|
||||
else if (!isPowerfulIgnoredEffect[i] && isPowerfulIgnoredEffect[currId])
|
||||
else if (!isChargingMoveEffect[i] && isChargingMoveEffect[currId])
|
||||
viableMoveScores[currId] -= 3;
|
||||
|
||||
switch (CompareMoveAccuracies(battlerAtk, battlerDef, currId, i))
|
||||
@ -4847,15 +4827,6 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
|
||||
IncreasePoisonScore(battlerAtk, battlerDef, move, &score);
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score);
|
||||
break;
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
if (GetNoOfHitsToKOBattler(battlerAtk, battlerDef, movesetIndex) >= 2
|
||||
&& HasMoveEffect(battlerAtk, EFFECT_SUNNY_DAY) && (AI_GetWeather(aiData) & B_WEATHER_SUN)) // Use Sunny Day to boost damage.
|
||||
ADJUST_SCORE(-3);
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
case EFFECT_SKULL_BASH:
|
||||
if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB)
|
||||
ADJUST_SCORE(2);
|
||||
break;
|
||||
case EFFECT_COUNTER:
|
||||
if (!IsBattlerIncapacitated(battlerDef, aiData->abilities[battlerDef]) && predictedMove != MOVE_NONE)
|
||||
{
|
||||
@ -5246,9 +5217,6 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_BELLY_DRUM:
|
||||
case EFFECT_PSYCH_UP:
|
||||
case EFFECT_MIRROR_COAT:
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
case EFFECT_ERUPTION:
|
||||
case EFFECT_TICKLE:
|
||||
case EFFECT_SUNNY_DAY:
|
||||
case EFFECT_SANDSTORM:
|
||||
|
||||
@ -363,25 +363,6 @@ static const u16 sEncouragedEncoreEffects[] =
|
||||
EFFECT_CAMOUFLAGE,
|
||||
};
|
||||
|
||||
// For the purposes of determining the most powerful move in a moveset, these
|
||||
// moves are treated the same as having a power of 0 or 1
|
||||
#define IGNORED_MOVES_END 0xFFFF
|
||||
static const u16 sIgnoredPowerfulMoveEffects[] =
|
||||
{
|
||||
EFFECT_EXPLOSION,
|
||||
EFFECT_DREAM_EATER,
|
||||
EFFECT_RECHARGE,
|
||||
EFFECT_SKULL_BASH,
|
||||
EFFECT_SOLAR_BEAM,
|
||||
EFFECT_FOCUS_PUNCH,
|
||||
EFFECT_SUPERPOWER,
|
||||
EFFECT_ERUPTION,
|
||||
EFFECT_OVERHEAT,
|
||||
EFFECT_MIND_BLOWN,
|
||||
EFFECT_MAKE_IT_RAIN,
|
||||
IGNORED_MOVES_END
|
||||
};
|
||||
|
||||
// Functions
|
||||
u32 GetAIChosenMove(u32 battlerId)
|
||||
{
|
||||
@ -980,6 +961,11 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
||||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_RECHARGE:
|
||||
case EFFECT_SUPERPOWER:
|
||||
case EFFECT_OVERHEAT:
|
||||
case EFFECT_MAKE_IT_RAIN:
|
||||
case EFFECT_MIND_BLOWN:
|
||||
case EFFECT_STEEL_BEAM:
|
||||
return TRUE;
|
||||
case EFFECT_RECOIL_25:
|
||||
case EFFECT_RECOIL_IF_MISS:
|
||||
@ -1054,22 +1040,6 @@ u32 GetNoOfHitsToKOBattler(u32 battlerAtk, u32 battlerDef, u32 moveIndex)
|
||||
return GetNoOfHitsToKOBattlerDmg(AI_DATA->simulatedDmg[battlerAtk][battlerDef][moveIndex], battlerDef);
|
||||
}
|
||||
|
||||
bool32 IsInIgnoredPowerfulMoveEffects(u32 effect)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; sIgnoredPowerfulMoveEffects[i] != IGNORED_MOVES_END; i++)
|
||||
{
|
||||
if (effect == sIgnoredPowerfulMoveEffects[i])
|
||||
{
|
||||
// Don't ingore Solar Beam if doesn't have a charging turn.
|
||||
if (effect == EFFECT_SOLAR_BEAM && (AI_GetWeather(AI_DATA) & B_WEATHER_SUN))
|
||||
break;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SetMovesDamageResults(u32 battlerAtk, u16 *moves)
|
||||
{
|
||||
s32 i, j, battlerDef, bestId, currId, hp, result;
|
||||
@ -1079,7 +1049,7 @@ void SetMovesDamageResults(u32 battlerAtk, u16 *moves)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
u32 move = moves[i];
|
||||
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || gBattleMoves[move].power == 0 || IsInIgnoredPowerfulMoveEffects(gBattleMoves[move].effect))
|
||||
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || gBattleMoves[move].power == 0)
|
||||
isNotConsidered[i] = TRUE;
|
||||
else
|
||||
isNotConsidered[i] = FALSE;
|
||||
@ -1094,11 +1064,10 @@ void SetMovesDamageResults(u32 battlerAtk, u16 *moves)
|
||||
|
||||
if (isNotConsidered[i])
|
||||
{
|
||||
result = MOVE_POWER_OTHER; // Move has a power of 0/1, or is in the group sIgnoredPowerfulMoveEffects
|
||||
result = MOVE_POWER_OTHER; // Move has a power of 0/1
|
||||
}
|
||||
else
|
||||
{
|
||||
// Considered move has power and is not in sIgnoredPowerfulMoveEffects
|
||||
// Check all other moves and calculate their power
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
@ -2394,6 +2363,24 @@ bool32 IsEncoreEncouragedEffect(u32 moveEffect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsChargingMove(u32 battlerAtk, u32 effect)
|
||||
{
|
||||
switch (effect)
|
||||
{
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
if (AI_GetWeather(AI_DATA) & B_WEATHER_SUN)
|
||||
return FALSE;
|
||||
case EFFECT_SKULL_BASH:
|
||||
case EFFECT_METEOR_BEAM:
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 GetLeechSeedDamage(u32 battlerId)
|
||||
{
|
||||
u32 damage = 0;
|
||||
|
||||
@ -158,6 +158,7 @@ static void AnimRockPolishSparkle(struct Sprite *);
|
||||
static void AnimPoisonJabProjectile(struct Sprite *);
|
||||
static void AnimNightSlash(struct Sprite *);
|
||||
static void AnimPluck(struct Sprite *);
|
||||
static void AnimAcrobaticsSlashes(struct Sprite *);
|
||||
|
||||
const union AnimCmd gPowderParticlesAnimCmds[] =
|
||||
{
|
||||
@ -3006,6 +3007,61 @@ const struct SpriteTemplate gSeedFlareGreenCirclesTemplate =
|
||||
.callback = AnimPowerAbsorptionOrb
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gSteelBeamBigOrbSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_STEEL_BEAM,
|
||||
.paletteTag = ANIM_TAG_STEEL_BEAM,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_8x8,
|
||||
.anims = gSolarBeamBigOrbAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSolarBeamBigOrb,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gSteelBeamSmallOrbSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_STEEL_BEAM,
|
||||
.paletteTag = ANIM_TAG_STEEL_BEAM,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_8x8,
|
||||
.anims = gSolarBeamSmallOrbAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSolarBeamSmallOrb,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gAcrobaticsSlashesSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_WHITE_STREAK,
|
||||
.paletteTag = ANIM_TAG_WHITE_STREAK,
|
||||
.oam = &gOamData_AffineDouble_ObjBlend_32x8,
|
||||
.anims = gRockPolishStreak_AnimCmds,
|
||||
.images = NULL,
|
||||
.affineAnims = gRockPolishStreak_AffineAnimCmds,
|
||||
.callback = AnimAcrobaticsSlashes,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gPsyshockOrbSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_RED_ORB_2,
|
||||
.paletteTag = ANIM_TAG_POISON_JAB,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_8x8,
|
||||
.anims = gDummySpriteAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimPoisonJabProjectile,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gPsyshockSmokeSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_GRAY_SMOKE,
|
||||
.paletteTag = ANIM_TAG_WISP_FIRE,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = gOctazookaAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSpriteOnMonPos,
|
||||
};
|
||||
|
||||
// functions
|
||||
static void AnimGrassKnot(struct Sprite *sprite)
|
||||
{
|
||||
@ -6971,28 +7027,6 @@ void AnimTask_CompressTargetHorizontally(u8 taskId)
|
||||
task->func = AnimTask_CompressTargetStep;
|
||||
}
|
||||
|
||||
const struct SpriteTemplate gSteelBeamBigOrbSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_STEEL_BEAM,
|
||||
.paletteTag = ANIM_TAG_STEEL_BEAM,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_8x8,
|
||||
.anims = gSolarBeamBigOrbAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSolarBeamBigOrb,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gSteelBeamSmallOrbSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_STEEL_BEAM,
|
||||
.paletteTag = ANIM_TAG_STEEL_BEAM,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_8x8,
|
||||
.anims = gSolarBeamSmallOrbAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSolarBeamSmallOrb,
|
||||
};
|
||||
|
||||
void AnimTask_CreateSmallSteelBeamOrbs(u8 taskId)
|
||||
{
|
||||
if (--gTasks[taskId].data[0] == -1)
|
||||
@ -7009,3 +7043,12 @@ void AnimTask_CreateSmallSteelBeamOrbs(u8 taskId)
|
||||
if (gTasks[taskId].data[1] == 15)
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
||||
static void AnimAcrobaticsSlashes(struct Sprite *sprite)
|
||||
{
|
||||
int affineAnimNum = Random2() % ARRAY_COUNT(gRockPolishStreak_AffineAnimCmds);
|
||||
InitSpritePosToAnimTarget(sprite, TRUE);
|
||||
StartSpriteAffineAnim(sprite, affineAnimNum);
|
||||
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
|
||||
sprite->callback = RunStoredCallbackWhenAnimEnds;
|
||||
}
|
||||
|
||||
@ -584,6 +584,28 @@ const struct SpriteTemplate gAquaTailHitSpriteTemplate =
|
||||
.callback = AnimAquaTail,
|
||||
};
|
||||
|
||||
static const union AnimCmd sAnimCmdAnimatedSpark2[] = {
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 0, 8),
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 1, 8),
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 2, 8),
|
||||
ANIMCMD_JUMP(0)
|
||||
};
|
||||
|
||||
static const union AnimCmd *const sAnimCmdTable_AnimatedSpark2[] = {
|
||||
sAnimCmdAnimatedSpark2,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gSparkBeamSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_SPARK_2,
|
||||
.paletteTag = ANIM_TAG_SPARK_2,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_16x16,
|
||||
.anims = sAnimCmdTable_AnimatedSpark2,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimToTargetInSinWave,
|
||||
};
|
||||
|
||||
static void AnimAquaTail(struct Sprite *sprite)
|
||||
{
|
||||
StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
|
||||
|
||||
@ -233,7 +233,7 @@ static u16 GetNextBall(u16 ballId)
|
||||
{
|
||||
if (ballId == gBagPockets[BALLS_POCKET].itemSlots[i].itemId)
|
||||
{
|
||||
ballNext = gBagPockets[BALLS_POCKET].itemSlots[i].itemId;
|
||||
ballNext = gBagPockets[BALLS_POCKET].itemSlots[i+1].itemId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1057,6 +1057,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
|
||||
|
||||
objVram = ConvertIntToDecimalStringN(text + 2, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
|
||||
xPos = 5 * (3 - (objVram - (text + 2)));
|
||||
MegaIndicator_SetVisibilities(healthboxSpriteId, TRUE);
|
||||
}
|
||||
|
||||
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, xPos, 3, 2, &windowId);
|
||||
|
||||
@ -3760,6 +3760,8 @@ u8 AtkCanceller_UnableToUseMove2(void)
|
||||
if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
|
||||
&& IsBattlerGrounded(gBattlerTarget)
|
||||
&& GetChosenMovePriority(gBattlerAttacker) > 0
|
||||
&& gBattleMoves[gCurrentMove].target != MOVE_TARGET_ALL_BATTLERS
|
||||
&& gBattleMoves[gCurrentMove].target != MOVE_TARGET_OPPONENTS_FIELD
|
||||
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
||||
{
|
||||
CancelMultiTurnMoves(gBattlerAttacker);
|
||||
@ -4095,6 +4097,13 @@ static uq4_12_t GetSupremeOverlordModifier(u32 battler)
|
||||
return modifier;
|
||||
}
|
||||
|
||||
static bool32 HadMoreThanHalfHpNowHasLess(u32 battler)
|
||||
{
|
||||
// Had more than half of hp before, now has less
|
||||
return (gBattleStruct->hpBefore[battler] >= gBattleMons[battler].maxHP / 2
|
||||
&& gBattleMons[battler].hp < gBattleMons[battler].maxHP / 2);
|
||||
}
|
||||
|
||||
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg)
|
||||
{
|
||||
u32 effect = 0;
|
||||
@ -5043,6 +5052,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, statId);
|
||||
}
|
||||
}
|
||||
|
||||
if (effect)
|
||||
gMultiHitCounter = 0; // Prevent multi-hit moves from hitting more than once after move has been absorbed.
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_MOVE_END: // Think contact abilities.
|
||||
@ -5107,9 +5119,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& IsBattlerAlive(battler)
|
||||
// Had more than half of hp before, now has less
|
||||
&& gBattleStruct->hpBefore[battler] >= gBattleMons[battler].maxHP / 2
|
||||
&& gBattleMons[battler].hp < gBattleMons[battler].maxHP / 2
|
||||
&& HadMoreThanHalfHpNowHasLess(battler)
|
||||
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
|
||||
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove))
|
||||
&& CompareStat(battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||
@ -5586,8 +5596,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1) // Activates after all hits from a multi-hit move.
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& (gBattleMons[gBattlerTarget].hp <= gBattleMons[gBattlerTarget].maxHP / 2)
|
||||
&& HadMoreThanHalfHpNowHasLess(gBattlerTarget)
|
||||
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove)))
|
||||
{
|
||||
gBattlerAttacker = gBattlerTarget;
|
||||
|
||||
@ -2023,3 +2023,6 @@ const u32 gItemIconPalette_LustrousGlobe[] = INCBIN_U32("graphics/items/icon_pal
|
||||
|
||||
const u32 gItemIcon_BerserkGene[] = INCBIN_U32("graphics/items/icons/berserk_gene.4bpp.lz");
|
||||
const u32 gItemIconPalette_BerserkGene[] = INCBIN_U32("graphics/items/icon_palettes/berserk_gene.gbapal.lz");
|
||||
|
||||
const u32 gItemIcon_FairyFeather[] = INCBIN_U32("graphics/items/icons/fairy_feather.4bpp.lz");
|
||||
const u32 gItemIconPalette_FairyFeather[] = INCBIN_U32("graphics/items/icon_palettes/fairy_feather.gbapal.lz");
|
||||
|
||||
@ -5199,6 +5199,9 @@ const u8 gMonIcon_Fearow[] = INCBIN_U8("graphics/pokemon/fearow/icon.4bpp");
|
||||
const u8 gMonIcon_Ekans[] = INCBIN_U8("graphics/pokemon/ekans/icon.4bpp");
|
||||
const u8 gMonIcon_Arbok[] = INCBIN_U8("graphics/pokemon/arbok/icon.4bpp");
|
||||
const u8 gMonIcon_Pikachu[] = INCBIN_U8("graphics/pokemon/pikachu/icon.4bpp");
|
||||
#if P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
const u8 gMonIcon_PikachuF[] = INCBIN_U8("graphics/pokemon/pikachu/iconf.4bpp");
|
||||
#endif
|
||||
const u8 gMonIcon_Raichu[] = INCBIN_U8("graphics/pokemon/raichu/icon.4bpp");
|
||||
const u8 gMonIcon_Sandshrew[] = INCBIN_U8("graphics/pokemon/sandshrew/icon.4bpp");
|
||||
const u8 gMonIcon_Sandslash[] = INCBIN_U8("graphics/pokemon/sandslash/icon.4bpp");
|
||||
@ -5376,6 +5379,9 @@ const u8 gMonIcon_Slowking[] = INCBIN_U8("graphics/pokemon/slowking/icon.4bpp");
|
||||
const u8 gMonIcon_Misdreavus[] = INCBIN_U8("graphics/pokemon/misdreavus/icon.4bpp");
|
||||
const u8 gMonIcon_Unown[] = INCBIN_U8("graphics/pokemon/unown/icon.4bpp");
|
||||
const u8 gMonIcon_Wobbuffet[] = INCBIN_U8("graphics/pokemon/wobbuffet/icon.4bpp");
|
||||
#if P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
const u8 gMonIcon_WobbuffetF[] = INCBIN_U8("graphics/pokemon/wobbuffet/iconf.4bpp");
|
||||
#endif
|
||||
const u8 gMonIcon_Girafarig[] = INCBIN_U8("graphics/pokemon/girafarig/icon.4bpp");
|
||||
const u8 gMonIcon_Pineco[] = INCBIN_U8("graphics/pokemon/pineco/icon.4bpp");
|
||||
const u8 gMonIcon_Forretress[] = INCBIN_U8("graphics/pokemon/forretress/icon.4bpp");
|
||||
@ -5625,7 +5631,7 @@ const u8 gMonIcon_Riolu[] = INCBIN_U8("graphics/pokemon/riolu/icon.4bpp");
|
||||
const u8 gMonIcon_Lucario[] = INCBIN_U8("graphics/pokemon/lucario/icon.4bpp");
|
||||
const u8 gMonIcon_Hippopotas[] = INCBIN_U8("graphics/pokemon/hippopotas/icon.4bpp");
|
||||
const u8 gMonIcon_Hippowdon[] = INCBIN_U8("graphics/pokemon/hippowdon/icon.4bpp");
|
||||
#if P_HIPPO_GENDER_DIFF_ICONS == TRUE
|
||||
#if P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
const u8 gMonIcon_HippopotasF[] = INCBIN_U8("graphics/pokemon/hippopotas/iconf.4bpp");
|
||||
const u8 gMonIcon_HippowdonF[] = INCBIN_U8("graphics/pokemon/hippowdon/iconf.4bpp");
|
||||
#endif
|
||||
|
||||
@ -844,7 +844,7 @@ const u32 *const gItemIconTable[ITEMS_COUNT + 1][2] =
|
||||
[ITEM_LINKING_CORD] = {gItemIcon_LinkingCord, gItemIconPalette_LinkingCord},
|
||||
[ITEM_PEAT_BLOCK] = {gItemIcon_PeatBlock, gItemIconPalette_PeatBlock},
|
||||
[ITEM_BERSERK_GENE] = {gItemIcon_BerserkGene, gItemIconPalette_BerserkGene},
|
||||
[ITEM_FAIRY_FEATHER] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_FairyFeather, gItemIconPalette_FairyFeather},
|
||||
[ITEM_FAIRY_FEATHER] = {gItemIcon_FairyFeather, gItemIconPalette_FairyFeather},
|
||||
[ITEM_SYRUPY_APPLE] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_SyrupyApple, gItemIconPalette_SyrupyApple},
|
||||
[ITEM_UNREMARKABLE_TEACUP] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_UnremarkableTeacup, gItemIconPalette_UnremarkableTeacup},
|
||||
[ITEM_MASTERPIECE_TEACUP] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_MasterpieceTeacup, gItemIconPalette_MasterpieceTeacup},
|
||||
|
||||
@ -1528,7 +1528,11 @@ const u8 *const gMonIconTable[NUM_SPECIES + 1] =
|
||||
// Female icon palette indexes still need to be defined in gMonIconPaletteIndicesFemale, even if they are the same as males.
|
||||
const u8 *const gMonIconTableFemale[NUM_SPECIES + 1] =
|
||||
{
|
||||
#if P_GEN_4_POKEMON == TRUE && P_HIPPO_GENDER_DIFF_ICONS == TRUE
|
||||
#if P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
[SPECIES_PIKACHU] = gMonIcon_PikachuF,
|
||||
[SPECIES_WOBBUFFET] = gMonIcon_WobbuffetF,
|
||||
#endif
|
||||
#if P_GEN_4_POKEMON == TRUE && P_CUSTOM_GENDER_DIFF_ICONS == TRUE
|
||||
[SPECIES_HIPPOPOTAS] = gMonIcon_HippopotasF,
|
||||
[SPECIES_HIPPOWDON] = gMonIcon_HippowdonF,
|
||||
#endif
|
||||
@ -2984,6 +2988,8 @@ const u8 gMonIconPaletteIndices[] =
|
||||
|
||||
const u8 gMonIconPaletteIndicesFemale[] =
|
||||
{
|
||||
[SPECIES_PIKACHU] = 2,
|
||||
[SPECIES_WOBBUFFET] = 0,
|
||||
#if P_GEN_4_POKEMON == TRUE
|
||||
[SPECIES_HIPPOPOTAS] = 1,
|
||||
[SPECIES_HIPPOWDON] = 1,
|
||||
|
||||
95
test/battle/ability/anger_shell.c
Normal file
95
test/battle/ability/anger_shell.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
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;
|
||||
|
||||
PARAMETRIZE { hp = 249; activates = FALSE; }
|
||||
PARAMETRIZE { hp = 100; activates = FALSE; }
|
||||
PARAMETRIZE { hp = 50; activates = FALSE; }
|
||||
PARAMETRIZE { hp = 251; activates = TRUE; }
|
||||
PARAMETRIZE { hp = 255; activates = TRUE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].power != 0);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(hp); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
if (activates) {
|
||||
ABILITY_POPUP(player, ABILITY_ANGER_SHELL);
|
||||
} else {
|
||||
NOT ABILITY_POPUP(player, ABILITY_ANGER_SHELL);
|
||||
}
|
||||
} THEN {
|
||||
if (activates) {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE - 1);
|
||||
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Anger Shell lowers Def/Sp.Def by 1 and raises Atk/Sp.Atk/Spd by 1")
|
||||
{
|
||||
u16 maxHp = 500;
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].power != 0);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(maxHp / 2 + 1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_ANGER_SHELL);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Wobbuffet's Defense fell!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Wobbuffet's Sp. Def fell!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Wobbuffet's Attack rose!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Wobbuffet's Sp. Atk rose!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Wobbuffet's Speed rose!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE - 1);
|
||||
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Anger Shell activates after all hits from a multi-hit move")
|
||||
{
|
||||
u32 j;
|
||||
u16 maxHp = 500;
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_DOUBLE_SLAP].effect == EFFECT_MULTI_HIT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(maxHp / 2 + 1); }
|
||||
OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); } // Always hits 5 times.
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_DOUBLE_SLAP); }
|
||||
} SCENE {
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_SLAP, opponent);
|
||||
NOT ABILITY_POPUP(player, ABILITY_ANGER_SHELL);
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_SLAP, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_ANGER_SHELL);
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE - 1);
|
||||
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1);
|
||||
EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
}
|
||||
@ -115,3 +115,26 @@ DOUBLE_BATTLE_TEST("Defiant sharply raises opponent's Attack after Intimidate")
|
||||
EXPECT_EQ(opponentRight->statStages[STAT_ATK], (abilityRight == ABILITY_DEFIANT) ? DEFAULT_STAT_STAGE + 2 : DEFAULT_STAT_STAGE - 2);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Defiant activates after Sticky Web lowers Speed")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_STICKY_WEB); }
|
||||
TURN { SWITCH(player, 1); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponent);
|
||||
// Switch-in - Sticky Web activates
|
||||
MESSAGE("Go! Mankey!");
|
||||
MESSAGE("Mankey was caught in a Sticky Web!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Mankey's Speed fell!");
|
||||
// Defiant activates
|
||||
ABILITY_POPUP(player, ABILITY_DEFIANT);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Mankey's Attack sharply rose!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,3 +57,24 @@ SINGLE_BATTLE_TEST("Sap Sipper does not increase Attack if already maxed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sap Sipper blocks multi-hit grass type moves")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT);
|
||||
PLAYER(SPECIES_MARILL) { Ability(ABILITY_SAP_SIPPER); }
|
||||
OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_BULLET_SEED); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Shellder used Bullet Seed!");
|
||||
ABILITY_POPUP(player, ABILITY_SAP_SIPPER);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
MESSAGE("Marill's Attack rose!");
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BULLET_SEED, opponent);
|
||||
HP_BAR(player);
|
||||
MESSAGE("Hit 5 time(s)!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,8 +260,8 @@ AI_SINGLE_BATTLE_TEST("AI can choose a status move that boosts the attack by two
|
||||
AI_SINGLE_BATTLE_TEST("AI chooses the safest option to faint the target, taking into account accuracy and move effect")
|
||||
{
|
||||
u16 move1 = MOVE_NONE, move2 = MOVE_NONE, move3 = MOVE_NONE, move4 = MOVE_NONE;
|
||||
u16 expectedMove, abilityAtk = ABILITY_NONE;
|
||||
u16 expectedMove2 = MOVE_NONE;
|
||||
u16 expectedMove, expectedMove2 = MOVE_NONE;
|
||||
u16 abilityAtk = ABILITY_NONE, holdItemAtk = ITEM_NONE;
|
||||
|
||||
// Psychic is not very effective, but always hits. Solarbeam requires a charging turn, Double Edge has recoil and Focus Blast can miss;
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SOLAR_BEAM; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE; expectedMove = MOVE_PSYCHIC; }
|
||||
@ -272,12 +272,24 @@ AI_SINGLE_BATTLE_TEST("AI chooses the safest option to faint the target, taking
|
||||
// This time it's Solarbeam + Psychic, because the weather is sunny.
|
||||
PARAMETRIZE { abilityAtk = ABILITY_DROUGHT; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SOLAR_BEAM; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_PSYCHIC; expectedMove2 = MOVE_SOLAR_BEAM; }
|
||||
// Psychic and Solar Beam are chosen because user is holding Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; holdItemAtk = ITEM_POWER_HERB; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SOLAR_BEAM; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_PSYCHIC; expectedMove2 = MOVE_SOLAR_BEAM; }
|
||||
// Psychic and Skull Bash are chosen because user is holding Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; holdItemAtk = ITEM_POWER_HERB; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SKULL_BASH; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_PSYCHIC; expectedMove2 = MOVE_SKULL_BASH; }
|
||||
// Skull Bash is chosen because it's the most accurate and is holding Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; holdItemAtk = ITEM_POWER_HERB; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SKULL_BASH; move3 = MOVE_SLAM; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_SKULL_BASH; }
|
||||
// Crabhammer is chosen even if Skull Bash is more accurate, the user has no Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SKULL_BASH; move3 = MOVE_SLAM; move4 = MOVE_CRABHAMMER;
|
||||
expectedMove = MOVE_CRABHAMMER; }
|
||||
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(5); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_GEODUDE) { Moves(move1, move2, move3, move4); Ability(abilityAtk); }
|
||||
OPPONENT(SPECIES_GEODUDE) { Moves(move1, move2, move3, move4); Ability(abilityAtk); Item(holdItemAtk); }
|
||||
} WHEN {
|
||||
TURN { if (expectedMove2 == MOVE_NONE) { EXPECT_MOVE(opponent, expectedMove); SEND_OUT(player, 1); }
|
||||
else {EXPECT_MOVES(opponent, expectedMove, expectedMove2); SCORE_EQ(opponent, expectedMove, expectedMove2); SEND_OUT(player, 1);}
|
||||
@ -288,6 +300,36 @@ AI_SINGLE_BATTLE_TEST("AI chooses the safest option to faint the target, taking
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI won't use Solar Beam if there is no Sun up or the user is not holding Power Herb")
|
||||
{
|
||||
u16 abilityAtk = ABILITY_NONE;
|
||||
u16 holdItemAtk = ITEM_NONE;
|
||||
|
||||
PARAMETRIZE { abilityAtk = ABILITY_DROUGHT; }
|
||||
PARAMETRIZE { holdItemAtk = ITEM_POWER_HERB; }
|
||||
PARAMETRIZE { }
|
||||
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(211); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_TYPHLOSION) { Moves(MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); Ability(abilityAtk); Item(holdItemAtk); }
|
||||
} WHEN {
|
||||
if (abilityAtk == ABILITY_DROUGHT) {
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); }
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); SEND_OUT(player, 1); }
|
||||
} else if (holdItemAtk == ITEM_POWER_HERB) {
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); MOVE(player, MOVE_KNOCK_OFF); }
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_GRASS_PLEDGE); SEND_OUT(player, 1); }
|
||||
} else {
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_GRASS_PLEDGE); }
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_GRASS_PLEDGE); SEND_OUT(player, 1); }
|
||||
}
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI won't use ground type attacks against flying type Pokemon unless Gravity is in effect")
|
||||
{
|
||||
GIVEN {
|
||||
|
||||
53
test/battle/move_effect/knock_off.c
Normal file
53
test/battle/move_effect/knock_off.c
Normal file
@ -0,0 +1,53 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Knock Off knocks a healing berry before it has the chance to activate")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); MaxHP(500); HP(255); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_KNOCK_OFF); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, player);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
|
||||
MESSAGE("Foe Wobbuffet's Sitrus Berry restored health!");
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_KNOCKOFF);
|
||||
MESSAGE("Wobbuffet knocked off Foe Wobbuffet's Sitrus Berry!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Knock Off activates after Rocky Helmet and Weakness Policy")
|
||||
{
|
||||
u16 item = 0;
|
||||
|
||||
PARAMETRIZE { item = ITEM_WEAKNESS_POLICY; }
|
||||
PARAMETRIZE { item = ITEM_ROCKY_HELMET; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(item); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_KNOCK_OFF); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
|
||||
if (item == ITEM_WEAKNESS_POLICY) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE);
|
||||
MESSAGE("Using WeaknssPolicy, the Attack of Foe Wobbuffet sharply rose!");
|
||||
MESSAGE("Using WeaknssPolicy, the Sp. Atk of Foe Wobbuffet sharply rose!");
|
||||
} else if (item == ITEM_ROCKY_HELMET) {
|
||||
HP_BAR(player);
|
||||
MESSAGE("Wobbuffet was hurt by Foe Wobbuffet's Rocky Helmet!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_KNOCKOFF);
|
||||
MESSAGE("Wobbuffet knocked off Foe Wobbuffet's Rocky Helmet!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,6 @@ SINGLE_BATTLE_TEST("Psychic Terrain doesn't block priority moves that target the
|
||||
|
||||
SINGLE_BATTLE_TEST("Psychic Terrain doesn't block priority moves that target all battlers")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_SABLEYE) { Ability(ABILITY_PRANKSTER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -93,7 +92,6 @@ SINGLE_BATTLE_TEST("Psychic Terrain doesn't block priority moves that target all
|
||||
|
||||
SINGLE_BATTLE_TEST("Psychic Terrain doesn't block priority moves that target all opponents")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_SABLEYE) { Ability(ABILITY_PRANKSTER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -124,7 +122,6 @@ DOUBLE_BATTLE_TEST("Psychic Terrain doesn't block priority moves that target all
|
||||
|
||||
SINGLE_BATTLE_TEST("Psychic Terrain doesn't block priority field moves")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_SABLEYE) { Ability(ABILITY_PRANKSTER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user