Merge branch 'battle_engine' of https://github.com/rh-hideout/pokeemerald-expansion into primalReversionTweaks
@ -1877,6 +1877,53 @@
|
||||
.2byte \species
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryendneutralizinggas battler:req
|
||||
various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS
|
||||
.endm
|
||||
|
||||
.macro trytoapplymimicry battler:req, ptr:req
|
||||
various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro trynoretreat battler:req, ptr:req
|
||||
various \battler, VARIOUS_TRY_NO_RETREAT
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro trytarshot battler:req, ptr:req
|
||||
various \battler, VARIOUS_TRY_TAR_SHOT
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro cantarshotwork battler:req, ptr:req
|
||||
various \battler, VARIOUS_CAN_TAR_SHOT_WORK
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro checkpoltergeist battler:req, ptr:req
|
||||
various \battler, VARIOUS_CHECK_POLTERGEIST
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro setoctolock battler:req, ptr:req
|
||||
various \battler, VARIOUS_SET_OCTOLOCK
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro cutonethirdhpraisestats ptr:req
|
||||
various BS_ATTACKER, VARIOUS_CUT_1_3_HP_RAISE_STATS
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro photongeysercheck
|
||||
various BS_ATTACKER, VARIOUS_PHOTON_GEYSER_CHECK
|
||||
.endm
|
||||
|
||||
.macro shellsidearmcheck
|
||||
various BS_ATTACKER, VARIOUS_SHELL_SIDE_ARM_CHECK
|
||||
.endm
|
||||
|
||||
@ helpful macros
|
||||
.macro setstatchanger stat:req, stages:req, down:req
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "constants/moves.h"
|
||||
#include "constants/pokemon.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/battle_config.h"
|
||||
.include "asm/macros.inc"
|
||||
.include "asm/macros/battle_anim_script.inc"
|
||||
.include "constants/constants.inc"
|
||||
@ -1893,7 +1894,7 @@ Move_AURA_SPHERE:
|
||||
monbg ANIM_ATK_PARTNER
|
||||
monbgprio_28 ANIM_ATTACKER
|
||||
setalpha 12, 8
|
||||
call SetHighSpeedBg
|
||||
call SetAuraSphereBG
|
||||
playsewithpan SE_M_SKY_UPPERCUT, 0
|
||||
delay 60
|
||||
createsprite gAuraSphereBlast, ANIM_TARGET, 3, 0
|
||||
@ -1908,6 +1909,10 @@ Move_AURA_SPHERE:
|
||||
delay 1
|
||||
end
|
||||
|
||||
SetAuraSphereBG:
|
||||
fadetobg BG_AURA_SPHERE
|
||||
goto SetHighSpeedBgFade
|
||||
|
||||
Move_ROCK_POLISH:
|
||||
loadspritegfx ANIM_TAG_WHITE_STREAK
|
||||
loadspritegfx ANIM_TAG_SPARKLE_3
|
||||
@ -2378,7 +2383,7 @@ Move_FOCUS_BLAST:
|
||||
monbg ANIM_ATK_PARTNER
|
||||
monbgprio_28 ANIM_ATTACKER
|
||||
setalpha 12, 8
|
||||
call SetHighSpeedBg
|
||||
call SetFocusBlastBG
|
||||
createsprite gSuperpowerOrbSpriteTemplate, ANIM_TARGET, 2, 0
|
||||
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER
|
||||
waitforvisualfinish
|
||||
@ -2391,6 +2396,10 @@ Move_FOCUS_BLAST:
|
||||
delay 1
|
||||
end
|
||||
|
||||
SetFocusBlastBG:
|
||||
fadetobg BG_FOCUS_BLAST
|
||||
goto SetHighSpeedBgFade
|
||||
|
||||
Move_ENERGY_BALL:
|
||||
loadspritegfx ANIM_TAG_ENERGY_BALL
|
||||
monbg ANIM_TARGET
|
||||
@ -2497,20 +2506,30 @@ Move_GIGA_IMPACT:
|
||||
loadspritegfx ANIM_TAG_IMPACT
|
||||
monbg ANIM_DEF_PARTNER
|
||||
setalpha 12, 8
|
||||
createvisualtask AnimTask_IsContest, 2
|
||||
jumprettrue SetGigaImpactContestsBG
|
||||
createvisualtask AnimTask_IsTargetPlayerSide, 2
|
||||
jumpretfalse SetGigaImpactOpponentBG
|
||||
goto SetGigaImpactPlayerBG
|
||||
SetGigaImpactOpponentBG:
|
||||
fadetobg BG_GIGA_IMPACT_OPPONENT
|
||||
goto GigaImpactContinuity
|
||||
SetGigaImpactPlayerBG:
|
||||
fadetobg BG_GIGA_IMPACT_PLAYER
|
||||
goto GigaImpactContinuity
|
||||
SetGigaImpactContestsBG:
|
||||
fadetobg BG_GIGA_IMPACT_CONTEST
|
||||
goto GigaImpactContinuity
|
||||
GigaImpactContinuity:
|
||||
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
|
||||
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
|
||||
waitforvisualfinish
|
||||
delay 11
|
||||
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5
|
||||
delay 6
|
||||
@monbg ANIM_DEF_PARTNER
|
||||
@setalpha 12, 8
|
||||
@createvisualtask AnimTask_WindUpLunge, 5, 7, 0, -18, 8, 23, 10, 40, 10
|
||||
@delay 35
|
||||
createsprite gComplexPaletteBlendSpriteTemplate, 2, 7, 31, 3, 1, 0, 10, 0, 0
|
||||
waitbgfadeout
|
||||
createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0
|
||||
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
|
||||
call SetImpactBackground
|
||||
delay 1
|
||||
createsprite gSlideMonToOffsetSpriteTemplate 2, 5, 1, -16, 0, 0, 4
|
||||
waitforvisualfinish
|
||||
@ -2525,6 +2544,7 @@ Move_GIGA_IMPACT:
|
||||
blendoff
|
||||
restorebg
|
||||
waitbgfadein
|
||||
waitforvisualfinish
|
||||
end
|
||||
|
||||
Move_NASTY_PLOT:
|
||||
@ -3437,6 +3457,7 @@ Move_GUNK_SHOT:
|
||||
monbg ANIM_DEF_PARTNER
|
||||
monbgprio_28 ANIM_TARGET
|
||||
setalpha 12, 8
|
||||
call SetGunkShotBG
|
||||
createvisualtask AnimTask_ShakeMon 5, 5, ANIM_ATTACKER, 0, 2, 40, 1
|
||||
delay 6
|
||||
panse_1B SE_M_HYDRO_PUMP, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 2, 0
|
||||
@ -3464,6 +3485,7 @@ Move_GUNK_SHOT:
|
||||
call GunkShotImpact
|
||||
call PoisonBubblesEffect
|
||||
waitforvisualfinish
|
||||
call UnsetHighSpeedBg
|
||||
clearmonbg ANIM_DEF_PARTNER
|
||||
blendoff
|
||||
end
|
||||
@ -3479,6 +3501,10 @@ GunkShotImpact:
|
||||
createsprite gGunkShotImpactSpriteTemplate, 4, 4, 0, 15, 1, 1
|
||||
createsprite gGunkShotImpactSpriteTemplate, 4, 4, 0, -15, 1, 1
|
||||
return
|
||||
SetGunkShotBG:
|
||||
fadetobg BG_GUNK_SHOT
|
||||
goto SetHighSpeedBgFade
|
||||
|
||||
|
||||
Move_IRON_HEAD:
|
||||
loadspritegfx ANIM_TAG_GUST
|
||||
@ -7264,7 +7290,7 @@ Move_RELIC_SONG:
|
||||
monbg ANIM_DEF_PARTNER
|
||||
launchtask AnimTask_MusicNotesRainbowBlend 0x2 0x0
|
||||
waitforvisualfinish
|
||||
panse_1B 0x1DF, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 0x2, 0x0 @ ???
|
||||
createvisualtask SoundTask_PlayCryWithEcho, 2, ANIM_ATTACKER, 2
|
||||
launchtask AnimTask_UproarDistortion 0x2 0x1 0x0
|
||||
launchtemplate gUproarRingSpriteTemplate 0x3 0x6 0x0 0x0 0x0 0x0 0x1f 0x8
|
||||
launchtemplate gJaggedMusicNoteSpriteTemplate 0x2 0x4 0x0 0x1d 0xfff4 0x0
|
||||
@ -14012,7 +14038,50 @@ Move_METEOR_BEAM::
|
||||
end @to do:
|
||||
|
||||
Move_SHELL_SIDE_ARM::
|
||||
end @to do:
|
||||
launchtask AnimTask_ShellSideArm 0x5 0x0
|
||||
jumpargeq 0x0, TRUE, Move_SHELL_SIDE_ARM_PHYSICAL
|
||||
jumpargeq 0x0, FALSE, Move_SHELL_SIDE_ARM_SPECIAL
|
||||
Move_SHELL_SIDE_ARM_PHYSICAL: @ Modified Body Slam, placeholder
|
||||
loadspritegfx ANIM_TAG_IMPACT
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_IMPACT, 0, 6, 6, RGB_MAGENTA
|
||||
monbg ANIM_DEF_PARTNER
|
||||
setalpha 12, 8
|
||||
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
|
||||
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
|
||||
waitforvisualfinish
|
||||
delay 11
|
||||
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5
|
||||
delay 6
|
||||
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 4, -10, 0, ANIM_TARGET, 0
|
||||
loopsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET, 10, 2
|
||||
delay 1
|
||||
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -28, 0, 0, 3
|
||||
waitforvisualfinish
|
||||
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
|
||||
waitforvisualfinish
|
||||
delay 10
|
||||
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 6
|
||||
delay 5
|
||||
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 6
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_DEF_PARTNER
|
||||
blendoff
|
||||
end
|
||||
Move_SHELL_SIDE_ARM_SPECIAL: @ Modified Snipe Shot, placeholder
|
||||
loadspritegfx ANIM_TAG_IMPACT_2
|
||||
loadspritegfx ANIM_TAG_LEER
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_IMPACT_2, 0, 6, 6, RGB_MAGENTA
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_LEER, 0, 6, 6, RGB_MAGENTA
|
||||
launchtemplate gLeerSpriteTemplate 0x82, 2 0x18 -12
|
||||
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
|
||||
waitforvisualfinish
|
||||
delay 0x20
|
||||
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
|
||||
launchtemplate gSnipeShotBallTemplate 0x82, 3, 0 0 24,
|
||||
waitforvisualfinish
|
||||
launchtask AnimTask_ShakeMon2 2 5 1 4 0 8, 1
|
||||
waitforvisualfinish
|
||||
end
|
||||
|
||||
Move_MISTY_EXPLOSION::
|
||||
end @to do:
|
||||
@ -14024,7 +14093,87 @@ Move_RISING_VOLTAGE::
|
||||
end @to do:
|
||||
|
||||
Move_TERRAIN_PULSE::
|
||||
end @to do:
|
||||
loadspritegfx ANIM_TAG_DRAGON_PULSE
|
||||
monbg ANIM_TARGET
|
||||
setalpha 12, 8
|
||||
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 0, 7, RGB_BLACK
|
||||
launchtask AnimTask_TerrainPulse 0x5 0x0
|
||||
jumpargeq 0x0, TYPE_ELECTRIC, TerrainPulseElectric
|
||||
jumpargeq 0x0, TYPE_GRASS, TerrainPulseGrass
|
||||
jumpargeq 0x0, TYPE_FAIRY, TerrainPulseFairy
|
||||
jumpargeq 0x0, TYPE_PSYCHIC, TerrainPulsePsychic
|
||||
TerrainPulseNormal:
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB_WHITE
|
||||
waitforvisualfinish
|
||||
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
|
||||
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
createvisualtask AnimTask_SwayMon, 5, 0, 2, 51200, 24, ANIM_TARGET
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB_WHITE
|
||||
goto TerrainPulseEnd
|
||||
|
||||
TerrainPulseElectric:
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(27, 27, 0)
|
||||
waitforvisualfinish
|
||||
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
|
||||
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(27, 27, 0)
|
||||
goto TerrainPulseEnd
|
||||
|
||||
TerrainPulseGrass:
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(11, 26, 11)
|
||||
waitforvisualfinish
|
||||
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
|
||||
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(11, 26, 11)
|
||||
goto TerrainPulseEnd
|
||||
|
||||
TerrainPulseFairy:
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(31, 24, 31)
|
||||
waitforvisualfinish
|
||||
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
|
||||
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(31, 24, 31)
|
||||
goto TerrainPulseEnd
|
||||
|
||||
TerrainPulsePsychic:
|
||||
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(27, 0, 13)
|
||||
waitforvisualfinish
|
||||
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
|
||||
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(27, 0, 13)
|
||||
goto TerrainPulseEnd
|
||||
|
||||
TerrainPulseEnd:
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
call DragonPulseParticle
|
||||
waitforvisualfinish
|
||||
delay 1
|
||||
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 7, 0, RGB_BLACK
|
||||
waitforvisualfinish
|
||||
blendoff
|
||||
clearmonbg ANIM_TARGET
|
||||
end
|
||||
|
||||
Move_SKITTER_SMACK::
|
||||
end @to do:
|
||||
@ -23296,17 +23445,50 @@ Move_SKY_UPPERCUT:
|
||||
end
|
||||
|
||||
Move_SECRET_POWER:
|
||||
createvisualtask AnimTask_GetFieldTerrain, 5
|
||||
jumpargeq 0, STATUS_FIELD_MISTY_TERRAIN, Move_FAIRY_WIND
|
||||
jumpargeq 0, STATUS_FIELD_GRASSY_TERRAIN, Move_NEEDLE_ARM
|
||||
jumpargeq 0, STATUS_FIELD_ELECTRIC_TERRAIN, Move_THUNDER_SHOCK
|
||||
jumpargeq 0, STATUS_FIELD_PSYCHIC_TERRAIN, Move_CONFUSION
|
||||
createvisualtask AnimTask_GetBattleTerrain, 5
|
||||
jumpargeq 0, BATTLE_TERRAIN_GRASS, Move_NEEDLE_ARM
|
||||
jumpargeq 0, BATTLE_TERRAIN_LONG_GRASS, Move_MAGICAL_LEAF
|
||||
jumpargeq 0, BATTLE_TERRAIN_SAND, Move_MUD_SHOT
|
||||
jumpargeq 0, BATTLE_TERRAIN_UNDERWATER, Move_WATERFALL
|
||||
jumpargeq 0, BATTLE_TERRAIN_WATER, Move_SURF
|
||||
jumpargeq 0, BATTLE_TERRAIN_POND, Move_BUBBLE_BEAM
|
||||
jumpargeq 0, BATTLE_TERRAIN_MOUNTAIN, Move_ROCK_THROW
|
||||
jumpargeq 0, BATTLE_TERRAIN_CAVE, Move_BITE
|
||||
jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH
|
||||
jumpargeq 0, BATTLE_TERRAIN_GRASS, Move_NEEDLE_ARM
|
||||
jumpargeq 0, BATTLE_TERRAIN_LONG_GRASS, Move_MAGICAL_LEAF
|
||||
jumpargeq 0, BATTLE_TERRAIN_SAND, Move_MUD_SHOT
|
||||
jumpargeq 0, BATTLE_TERRAIN_UNDERWATER, Move_WATERFALL
|
||||
jumpargeq 0, BATTLE_TERRAIN_WATER, Move_SURF
|
||||
jumpargeq 0, BATTLE_TERRAIN_POND, Move_BUBBLE_BEAM
|
||||
jumpargeq 0, BATTLE_TERRAIN_MOUNTAIN, Move_ROCK_THROW
|
||||
jumpargeq 0, BATTLE_TERRAIN_CAVE, Move_BITE
|
||||
jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH
|
||||
jumpargeq 0, BATTLE_TERRAIN_SOARING, Move_GUST
|
||||
jumpargeq 0, BATTLE_TERRAIN_SKY_PILLAR, Move_GUST
|
||||
jumpargeq 0, BATTLE_TERRAIN_BURIAL_GROUND, Move_SHADOW_SNEAK
|
||||
jumpargeq 0, BATTLE_TERRAIN_PUDDLE, Move_MUD_SHOT
|
||||
jumpargeq 0, BATTLE_TERRAIN_MARSH, Move_MUD_SHOT
|
||||
jumpargeq 0, BATTLE_TERRAIN_SWAMP, Move_MUD_SHOT
|
||||
.if B_SECRET_POWER_ANIMATION >= GEN_7
|
||||
jumpargeq 0, BATTLE_TERRAIN_SNOW, Move_ICE_SHARD
|
||||
.else
|
||||
jumpargeq 0, BATTLE_TERRAIN_SNOW, Move_AVALANCHE
|
||||
.endif
|
||||
jumpargeq 0, BATTLE_TERRAIN_ICE, Move_ICE_SHARD
|
||||
jumpargeq 0, BATTLE_TERRAIN_VOLCANO, Move_INCINERATE
|
||||
jumpargeq 0, BATTLE_TERRAIN_DISTORTION_WORLD, Move_POUND
|
||||
jumpargeq 0, BATTLE_TERRAIN_SPACE, Move_SWIFT
|
||||
jumpargeq 0, BATTLE_TERRAIN_ULTRA_SPACE, Move_PSYWAVE
|
||||
.if B_SECRET_POWER_ANIMATION >= GEN_7
|
||||
jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_SPIT_UP
|
||||
goto Move_SPIT_UP
|
||||
.elseif B_SECRET_POWER_ANIMATION == GEN_6
|
||||
jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_BODY_SLAM
|
||||
goto Move_BODY_SLAM
|
||||
.elseif B_SECRET_POWER_ANIMATION == GEN_5 || B_SECRET_POWER_ANIMATION == GEN_4
|
||||
jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_BODY_SLAM
|
||||
goto Move_MUD_SLAP
|
||||
.else
|
||||
jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH
|
||||
goto Move_SLAM
|
||||
.endif
|
||||
|
||||
Move_TWISTER:
|
||||
loadspritegfx ANIM_TAG_LEAF
|
||||
@ -24023,6 +24205,7 @@ General_TurnTrap:
|
||||
jumpargeq 0, TRAP_ANIM_WHIRLPOOL, Status_Whirlpool
|
||||
jumpargeq 0, TRAP_ANIM_CLAMP, Status_Clamp
|
||||
jumpargeq 0, TRAP_ANIM_SAND_TOMB, Status_SandTomb
|
||||
jumpargeq 0, TRAP_ANIM_MAGMA_STORM, Status_MagmaStorm
|
||||
jumpargeq 0, TRAP_ANIM_INFESTATION, Status_Infestation
|
||||
goto Status_BindWrap
|
||||
Status_BindWrap:
|
||||
@ -24049,6 +24232,32 @@ Status_FireSpin:
|
||||
stopsound
|
||||
end
|
||||
|
||||
Status_MagmaStorm:
|
||||
loadspritegfx ANIM_TAG_SMALL_EMBER
|
||||
fadetobg BG_MAGMA_STORM
|
||||
waitbgfadeout
|
||||
createvisualtask AnimTask_MoveSeismicTossBg, 3
|
||||
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET
|
||||
loopsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET, 5, 8
|
||||
createvisualtask AnimTask_SeismicTossBgAccelerateDownAtEnd, 3
|
||||
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 2, 47, 1
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 6, 4, 2, 2, 0, 12, RGB(22, 9, 7)
|
||||
call FireSpinEffect
|
||||
call FireSpinEffect
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 6, 4, 2, 2, 0, 12, RGB(22, 9, 7)
|
||||
call FireSpinEffect
|
||||
call FireSpinEffect
|
||||
createvisualtask AnimTask_BlendColorCycle, 2, 6, 4, 2, 2, 0, 12, RGB(22, 9, 7)
|
||||
call FireSpinEffect
|
||||
restorebg
|
||||
waitbgfadeout
|
||||
setarg 7, 0xFFF
|
||||
waitbgfadein
|
||||
stopsound
|
||||
clearmonbg ANIM_DEF_PARTNER
|
||||
blendoff
|
||||
end
|
||||
|
||||
Status_Whirlpool:
|
||||
loadspritegfx ANIM_TAG_WATER_ORB
|
||||
monbg ANIM_DEF_PARTNER
|
||||
|
@ -367,7 +367,7 @@ gBattleScriptsForMoveEffects::
|
||||
.4byte BattleScript_EffectGeomancy @ EFFECT_GEOMANCY
|
||||
.4byte BattleScript_EffectFairyLock @ EFFECT_FAIRY_LOCK
|
||||
.4byte BattleScript_EffectAllySwitch @ EFFECT_ALLY_SWITCH
|
||||
.4byte BattleScript_EffectSleepHit @ EFFECT_SLEEP_HIT
|
||||
.4byte BattleScript_EffectRelicSong @ EFFECT_RELIC_SONG
|
||||
.4byte BattleScript_EffectAttackerDefenseDownHit @ EFFECT_ATTACKER_DEFENSE_DOWN_HIT
|
||||
.4byte BattleScript_EffectHit @ EFFECT_BODY_PRESS
|
||||
.4byte BattleScript_EffectEerieSpell @ EFFECT_EERIE_SPELL
|
||||
@ -392,10 +392,164 @@ gBattleScriptsForMoveEffects::
|
||||
.4byte BattleScript_EffectSparklySwirl @ EFFECT_SPARKLY_SWIRL
|
||||
.4byte BattleScript_EffectPlasmaFists @ EFFECT_PLASMA_FISTS
|
||||
.4byte BattleScript_EffectHyperspaceFury @ EFFECT_HYPERSPACE_FURY
|
||||
.4byte BattleScript_EffectAuraWheel @ EFFECT_AURA_WHEEL
|
||||
.4byte BattleScript_EffectPhotonGeyser @ EFFECT_PHOTON_GEYSER
|
||||
.4byte BattleScript_EffectShellSideArm @ EFFECT_SHELL_SIDE_ARM
|
||||
.4byte BattleScript_EffectHit @ EFFECT_TERRAIN_PULSE
|
||||
.4byte BattleScript_EffectJawLock @ EFFECT_JAW_LOCK
|
||||
.4byte BattleScript_EffectNoRetreat @ EFFECT_NO_RETREAT
|
||||
.4byte BattleScript_EffectTarShot @ EFFECT_TAR_SHOT
|
||||
.4byte BattleScript_EffectPoltergeist @ EFFECT_POLTERGEIST
|
||||
.4byte BattleScript_EffectOctolock @ EFFECT_OCTOLOCK
|
||||
.4byte BattleScript_EffectClangorousSoul @ EFFECT_CLANGOROUS_SOUL
|
||||
.4byte BattleScript_EffectHit @ EFFECT_BOLT_BEAK
|
||||
|
||||
BattleScript_EffectShellSideArm:
|
||||
shellsidearmcheck
|
||||
setmoveeffect MOVE_EFFECT_POISON
|
||||
goto BattleScript_EffectHit
|
||||
|
||||
BattleScript_EffectPhotonGeyser:
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
attackstring
|
||||
ppreduce
|
||||
critcalc
|
||||
damagecalc
|
||||
adjustdamage
|
||||
photongeysercheck
|
||||
attackanimation
|
||||
waitanimation
|
||||
effectivenesssound
|
||||
hitanimation BS_TARGET
|
||||
waitstate
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
critmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
seteffectwithchance
|
||||
tryfaintmon BS_TARGET, FALSE, NULL
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectAuraWheel: @ Aura Wheel can only be used by Morpeko
|
||||
jumpifspecies BS_ATTACKER, SPECIES_MORPEKO, BattleScript_EffectSpeedUpHit
|
||||
jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_HANGRY, BattleScript_EffectSpeedUpHit
|
||||
printstring STRINGID_BUTPOKEMONCANTUSETHEMOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectClangorousSoul:
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
cutonethirdhpraisestats BattleScript_ButItFailed
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_SKIP_DMG_TRACK | HITMARKER_PASSIVE_DAMAGE | HITMARKER_IGNORE_DISGUISE
|
||||
attackanimation
|
||||
waitanimation
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
call BattleScript_AllStatsUp
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectOctolock:
|
||||
attackcanceler
|
||||
jumpifsubstituteblocks BattleScript_ButItFailedAtkStringPpReduce
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
attackstring
|
||||
ppreduce
|
||||
setoctolock BS_TARGET, BattleScript_ButItFailed
|
||||
attackanimation
|
||||
waitanimation
|
||||
printstring STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_OctolockEndTurn::
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockLowerDef
|
||||
jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_OctolockTryLowerSpDef
|
||||
goto BattleScript_OctolockEnd2
|
||||
BattleScript_OctolockLowerDef:
|
||||
jumpifability BS_TARGET, ABILITY_BIG_PECKS, BattleScript_OctolockTryLowerSpDef
|
||||
playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE
|
||||
setbyte sSTAT_ANIM_PLAYED, TRUE
|
||||
setstatchanger STAT_DEF, 1, TRUE
|
||||
statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockTryLowerSpDef
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_OctolockTryLowerSpDef:
|
||||
jumpifbyte CMP_EQUAL, sSTAT_ANIM_PLAYED, TRUE, BattleScript_OctolockSkipSpDefAnim
|
||||
playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_NEGATIVE
|
||||
BattleScript_OctolockSkipSpDefAnim:
|
||||
setstatchanger STAT_SPDEF, 1, TRUE
|
||||
statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockEnd2
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockEnd2
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_OctolockEnd2::
|
||||
end2
|
||||
|
||||
BattleScript_EffectPoltergeist:
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
checkpoltergeist BS_TARGET, BattleScript_ButItFailed
|
||||
printstring STRINGID_ABOUTTOUSEPOLTERGEIST
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_HitFromCritCalc
|
||||
|
||||
BattleScript_EffectTarShot:
|
||||
attackcanceler
|
||||
jumpifsubstituteblocks BattleScript_ButItFailedAtkStringPpReduce
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
cantarshotwork BS_TARGET, BattleScript_ButItFailedAtkStringPpReduce
|
||||
attackstring
|
||||
ppreduce
|
||||
setstatchanger STAT_SPEED, 1, TRUE
|
||||
attackanimation
|
||||
waitanimation
|
||||
statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_TryTarShot
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_TryTarShot:
|
||||
trytarshot BS_TARGET, BattleScript_MoveEnd
|
||||
printstring STRINGID_PKMNBECAMEWEAKERTOFIRE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectNoRetreat:
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
attackstring
|
||||
ppreduce
|
||||
trynoretreat BS_TARGET, BattleScript_ButItFailed
|
||||
attackanimation
|
||||
waitanimation
|
||||
call BattleScript_AllStatsUp
|
||||
jumpifstatus2 BS_TARGET, STATUS2_ESCAPE_PREVENTION, BattleScript_MoveEnd
|
||||
setmoveeffect MOVE_EFFECT_PREVENT_ESCAPE
|
||||
seteffectprimary
|
||||
printstring STRINGID_CANTESCAPEDUETOUSEDMOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectJawLock:
|
||||
setmoveeffect MOVE_EFFECT_TRAP_BOTH | MOVE_EFFECT_CERTAIN
|
||||
goto BattleScript_EffectHit
|
||||
|
||||
BattleScript_BothCanNoLongerEscape::
|
||||
printstring STRINGID_BOTHCANNOLONGERESCAPE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_EffectHyperspaceFury:
|
||||
jumpifspecies BS_ATTACKER, SPECIES_TREECKO, BattleScript_EffectHyperspaceFuryUnbound
|
||||
jumpifspecies BS_ATTACKER, SPECIES_MUDKIP, BattleScript_ButHoopaCantUseIt
|
||||
jumpifspecies BS_ATTACKER, SPECIES_HOOPA_UNBOUND, BattleScript_EffectHyperspaceFuryUnbound
|
||||
jumpifspecies BS_ATTACKER, SPECIES_HOOPA, BattleScript_ButHoopaCantUseIt
|
||||
printstring STRINGID_BUTPOKEMONCANTUSETHEMOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
@ -734,9 +888,30 @@ BattleScript_EffectAttackerDefenseDownHit:
|
||||
setmoveeffect MOVE_EFFECT_DEF_MINUS_1 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
|
||||
goto BattleScript_EffectHit
|
||||
|
||||
BattleScript_EffectSleepHit:
|
||||
setmoveeffect MOVE_EFFECT_SLEEP
|
||||
goto BattleScript_EffectHit
|
||||
BattleScript_EffectRelicSong:
|
||||
setmoveeffect MOVE_EFFECT_RELIC_SONG | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
attackstring
|
||||
ppreduce
|
||||
critcalc
|
||||
damagecalc
|
||||
adjustdamage
|
||||
attackanimation
|
||||
waitanimation
|
||||
effectivenesssound
|
||||
hitanimation BS_TARGET
|
||||
waitstate
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
critmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
seteffectwithchance
|
||||
argumentstatuseffect
|
||||
tryfaintmon BS_TARGET, FALSE, NULL
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectAllySwitch:
|
||||
attackcanceler
|
||||
@ -1707,7 +1882,7 @@ BattleScript_EffectSoak:
|
||||
attackanimation
|
||||
waitanimation
|
||||
trysoak BattleScript_ButItFailed
|
||||
printstring STRINGID_TRANSFORMEDINTOWATERTYPE
|
||||
printstring STRINGID_TARGETCHANGEDTYPE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
@ -1908,6 +2083,23 @@ BattleScript_EffectPsychicTerrain:
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG, NULL
|
||||
call BattleScript_TerrainSeedLoop
|
||||
jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_ApplyMimicry::
|
||||
savetarget
|
||||
setbyte gBattlerTarget, 0
|
||||
BattleScript_MimicryLoopIter:
|
||||
copybyte sBATTLER, gBattlerTarget
|
||||
trytoapplymimicry BS_TARGET, BattleScript_MimicryLoop_NextBattler
|
||||
copybyte gBattlerAbility, sBATTLER
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_BATTLERTYPECHANGEDTO
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_MimicryLoop_NextBattler:
|
||||
addbyte gBattlerTarget, 0x1
|
||||
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_MimicryLoopIter
|
||||
restoretarget
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectTopsyTurvy:
|
||||
@ -1995,6 +2187,7 @@ BattleScript_EffectSimpleBeam:
|
||||
trytoclearprimalweather
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
waitmessage 1
|
||||
tryendneutralizinggas BS_TARGET
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectSuckerPunch:
|
||||
@ -2217,6 +2410,7 @@ BattleScript_EffectGastroAcid:
|
||||
trytoclearprimalweather
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
waitmessage 1
|
||||
tryendneutralizinggas BS_TARGET
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectToxicSpikes:
|
||||
@ -6289,7 +6483,7 @@ BattleScript_AttackerItemStatRaise::
|
||||
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
waitanimation
|
||||
printstring STRINGID_USINGITEMSTATOFPKMNROSE
|
||||
waitmessage 0x40
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_ATTACKER
|
||||
BattleScript_AttackerItemStatRaiseRet:
|
||||
return
|
||||
@ -6972,6 +7166,7 @@ BattleScript_AttackerFormChange::
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
waitmessage 1
|
||||
BattleScript_AttackerFormChangeNoPopup::
|
||||
handleformchange BS_ATTACKER, 0
|
||||
handleformchange BS_ATTACKER, 1
|
||||
playanimation BS_ATTACKER, B_ANIM_FORM_CHANGE, NULL
|
||||
@ -6983,6 +7178,21 @@ BattleScript_AttackerFormChangeEnd3::
|
||||
call BattleScript_AttackerFormChange
|
||||
end3
|
||||
|
||||
BattleScript_AttackerFormChangeEnd3NoPopup::
|
||||
call BattleScript_AttackerFormChangeNoPopup
|
||||
|
||||
BattleScript_AttackerFormChangeMoveEffect::
|
||||
waitmessage 1
|
||||
handleformchange BS_ATTACKER, 0
|
||||
handleformchange BS_ATTACKER, 1
|
||||
playanimation BS_ATTACKER, B_ANIM_FORM_CHANGE, NULL
|
||||
waitanimation
|
||||
copybyte sBATTLER, gBattlerAttacker
|
||||
printstring STRINGID_PKMNTRANSFORMED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
handleformchange BS_ATTACKER, 2
|
||||
end3
|
||||
|
||||
BattleScript_BallFetch::
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_FETCHEDPOKEBALL
|
||||
@ -8006,6 +8216,12 @@ BattleScript_ColorChangeActivates::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_MimicryActivatesEnd3::
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_BATTLERTYPECHANGEDTO
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end3
|
||||
|
||||
BattleScript_ProteanActivates::
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_PKMNCHANGEDTYPE
|
||||
@ -8168,6 +8384,12 @@ BattleScript_SwitchInAbilityMsg::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end3
|
||||
|
||||
BattleScript_SwitchInAbilityMsgRet::
|
||||
call BattleScript_AbilityPopUp
|
||||
printfromtable gSwitchInAbilityStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_ActivateAsOne::
|
||||
call BattleScript_AbilityPopUp
|
||||
printfromtable gSwitchInAbilityStringIds
|
||||
@ -8931,7 +9153,7 @@ BattleScript_StickyBarbTransfer::
|
||||
BattleScript_RedCardActivates::
|
||||
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
|
||||
printstring STRINGID_REDCARDACTIVATE
|
||||
waitmessage 0x40
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
swapattackerwithtarget
|
||||
jumpifstatus3 BS_EFFECT_BATTLER, STATUS3_ROOTED, BattleScript_RedCardIngrain
|
||||
jumpifability BS_EFFECT_BATTLER, ABILITY_SUCTION_CUPS, BattleScript_RedCardSuctionCups
|
||||
@ -8942,13 +9164,13 @@ BattleScript_RedCardEnd:
|
||||
return
|
||||
BattleScript_RedCardIngrain:
|
||||
printstring STRINGID_PKMNANCHOREDITSELF
|
||||
waitmessage 0x40
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_SCRIPTING
|
||||
swapattackerwithtarget
|
||||
return
|
||||
BattleScript_RedCardSuctionCups:
|
||||
printstring STRINGID_PKMNANCHORSITSELFWITH
|
||||
waitmessage 0x40
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_SCRIPTING
|
||||
swapattackerwithtarget
|
||||
return
|
||||
@ -8957,7 +9179,7 @@ BattleScript_EjectButtonActivates::
|
||||
makevisible BS_ATTACKER
|
||||
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
|
||||
printstring STRINGID_EJECTBUTTONACTIVATE
|
||||
waitmessage 0x40
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_SCRIPTING
|
||||
makeinvisible BS_SCRIPTING
|
||||
openpartyscreen BS_SCRIPTING, BattleScript_EjectButtonEnd
|
||||
@ -9021,3 +9243,19 @@ BattleScript_PastelVeilLoopIncrement:
|
||||
goto BattleScript_PastelVeilEnd
|
||||
BattleScript_PastelVeilEnd:
|
||||
end3
|
||||
|
||||
sByteFour:
|
||||
.byte MAX_BATTLERS_COUNT
|
||||
|
||||
BattleScript_NeutralizingGasExits::
|
||||
savetarget
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_NEUTRALIZINGGASOVER
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setbyte gBattlerTarget, 0
|
||||
BattleScript_NeutralizingGasExitsLoop:
|
||||
switchinabilities BS_TARGET
|
||||
addbyte gBattlerTarget, 1
|
||||
jumpifbytenotequal gBattlerTarget, sByteFour, BattleScript_NeutralizingGasExitsLoop @ SOMEHOW, comparing to gBattlersCount is problematic.
|
||||
restoretarget
|
||||
return
|
||||
|
@ -1,19 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
131 131 131
|
||||
123 123 123
|
||||
115 115 115
|
||||
106 106 106
|
||||
98 98 98
|
||||
82 82 82
|
||||
65 65 65
|
||||
49 49 49
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
Before Width: | Height: | Size: 6.9 KiB |
@ -1,19 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
255 214 0
|
||||
255 197 0
|
||||
255 173 0
|
||||
255 165 0
|
||||
148 90 222
|
||||
255 107 0
|
||||
255 132 0
|
||||
255 148 0
|
||||
255 156 41
|
||||
0 0 0
|
||||
0 90 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
@ -2,14 +2,14 @@ JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
131 131 131
|
||||
123 123 123
|
||||
115 115 115
|
||||
106 106 106
|
||||
98 98 98
|
||||
82 82 82
|
||||
65 65 65
|
||||
49 49 49
|
||||
48 48 48
|
||||
72 72 72
|
||||
88 88 88
|
||||
120 120 120
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 984 B |
19
graphics/battle_anims/backgrounds/new/giga_impact.pal
Normal file
@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
240 136 184
|
||||
232 104 168
|
||||
136 8 40
|
||||
248 24 104
|
||||
216 32 96
|
||||
224 72 136
|
||||
160 0 48
|
||||
216 0 64
|
||||
200 40 88
|
||||
192 0 56
|
||||
176 32 128
|
||||
176 24 72
|
||||
152 16 56
|
||||
200 48 80
|
||||
216 56 160
|
BIN
graphics/battle_anims/backgrounds/new/giga_impact.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
@ -0,0 +1,3 @@
|
||||
<EFBFBD>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> D!E!F!G!H!I!@!<21>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> њ ћ ќ § ў џ ђ Ј$Ї$І$Ѕ$Є$Ѓ$Ђ$Ё$ $ Ё Ђ Ѓ Є Ѕ І Ї Ј Љ Њ Ћ Ќ Ў Џ
|
||||
!!!
!!!!И$З$Ж$Е$Д$Г$В$Б$А$А Б В Г Д Е Ж З И Й К Л М Н О П !!!!!!!Ш$Ч$Ц$Х$Ф$У$Т$С$Р$Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я *!+!,!-!.!/!"!и$з$ж$е$д$г$в$б$а$а б в г д е ж з и й к л м н о п :!;!<!=!>!?!2!ш$ч$ц$х$ф$у$т$с$р$р с т у ф х ц ч ш щ ъ ы ь э ю я J!K!L!M!N!O!B!ш,ч,ц,х,ф,у,т,с,р,р(с(т(у(ф(х(ц(ч(ш(щ(ъ(ы(ь(э(ю(я(J)K)L)M)N)O)B)и,з,ж,е,д,г,в,б,а,а(б(в(г(д(е(ж(з(и(й(к(л(м(н(о(п(:);)<)=)>)?)2)Ш,Ч,Ц,Х,Ф,У,Т,С,Р,Р(С(Т(У(Ф(Х(Ц(Ч(Ш(Щ(Ъ(Ы(Ь(Э(Ю(Я(*)+),)-).)/)")И,З,Ж,Е,Д,Г,В,Б,А,А(Б(В(Г(Д(Е(Ж(З(И(Й(К(Л(М(Н(О(П()))))))Ј,Ї,І,Ѕ,Є,Ѓ,Ђ,Ё, , (Ё(Ђ(Ѓ(Є(Ѕ(І(Ї(Ј(Љ(Њ(Ћ(Ќ((Ў(Џ(
|
||||
)))
))))<29>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(њ(ћ(ќ(§(ў(џ(ђ(<28>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(D)E)F)G)H)I)@)
|
@ -1,19 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
41 49 49
|
||||
106 139 189
|
||||
246 131 180
|
||||
255 0 255
|
||||
255 16 98
|
||||
238 98 164
|
||||
230 65 131
|
||||
222 0 57
|
||||
222 24 90
|
||||
205 41 74
|
||||
205 32 82
|
||||
189 0 49
|
||||
172 16 65
|
||||
156 0 41
|
||||
148 16 49
|
||||
131 8 32
|
Before Width: | Height: | Size: 3.0 KiB |
@ -1,19 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
255 255 255
|
||||
255 0 255
|
||||
255 16 98
|
||||
246 131 180
|
||||
238 98 164
|
||||
230 65 131
|
||||
222 0 57
|
||||
222 24 90
|
||||
205 32 82
|
||||
205 41 74
|
||||
189 0 49
|
||||
172 16 65
|
||||
156 0 41
|
||||
148 16 49
|
||||
131 8 32
|
Before Width: | Height: | Size: 3.0 KiB |
@ -2,12 +2,12 @@ JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
164 156 24
|
||||
156 148 24
|
||||
197 189 32
|
||||
172 164 32
|
||||
115 106 16
|
||||
0 0 0
|
||||
248 248 144
|
||||
224 224 120
|
||||
200 200 96
|
||||
176 176 72
|
||||
152 152 48
|
||||
120 120 16
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
@ -1,3 +0,0 @@
|
||||
@%I%H%G%F%E%D%<25>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> ђ$џ$ў$§$ќ$ћ$њ$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> %%%
%%%
|
||||
%Џ$Ў$$Ќ$Ћ$Њ$Љ$Ј$Ї$І$Ѕ$Є$Ѓ$Ђ$Ё$ $ Ё Ђ Ѓ Є Ѕ І Ї Ј %%%%%%%П$О$Н$М$Л$К$Й$И$З$Ж$Е$Д$Г$В$Б$А$А Б В Г Д Е Ж З И "%/%.%-%,%+%*%Я$Ю$Э$Ь$Ы$Ъ$Щ$Ш$Ч$Ц$Х$Ф$У$Т$С$Р$Р С Т У Ф Х Ц Ч Ш 2%?%>%=%<%;%:%п$о$н$м$л$к$й$и$з$ж$е$д$г$в$б$а$а б в г д е ж з и B%O%N%M%L%K%J%я$ю$э$ь$ы$ъ$щ$ш$ч$ц$х$ф$у$т$с$р$р с т у ф х ц ч ш B-O-N-M-L-K-J-я,ю,э,ь,ы,ъ,щ,ш,ч,ц,х,ф,у,т,с,р,р(с(т(у(ф(х(ц(ч(ш(2-?->-=-<-;-:-п,о,н,м,л,к,й,и,з,ж,е,д,г,в,б,а,а(б(в(г(д(е(ж(з(и("-/-.---,-+-*-Я,Ю,Э,Ь,Ы,Ъ,Щ,Ш,Ч,Ц,Х,Ф,У,Т,С,Р,Р(С(Т(У(Ф(Х(Ц(Ч(Ш(-------П,О,Н,М,Л,К,Й,И,З,Ж,Е,Д,Г,В,Б,А,А(Б(В(Г(Д(Е(Ж(З(И(---
---
|
||||
-Џ,Ў,,Ќ,Ћ,Њ,Љ,Ј,Ї,І,Ѕ,Є,Ѓ,Ђ,Ё, , (Ё(Ђ(Ѓ(Є(Ѕ(І(Ї(Ј(ђ,џ,ў,§,ќ,ћ,њ,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(@-I-H-G-F-E-D-<2D>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(
|
@ -2,12 +2,12 @@ JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
106 123 139
|
||||
90 106 139
|
||||
123 139 164
|
||||
123 139 197
|
||||
65 74 115
|
||||
0 0 0
|
||||
152 184 248
|
||||
128 160 240
|
||||
104 136 216
|
||||
80 112 192
|
||||
56 88 168
|
||||
24 56 136
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.7 KiB |
@ -2,10 +2,10 @@ JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
131 205 230
|
||||
123 180 213
|
||||
115 156 205
|
||||
115 139 164
|
||||
128 200 232
|
||||
120 176 216
|
||||
112 152 200
|
||||
112 136 160
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 814 B |
@ -2,12 +2,12 @@ JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
214 55 93
|
||||
199 40 78
|
||||
222 91 123
|
||||
223 96 127
|
||||
158 31 62
|
||||
0 0 0
|
||||
248 144 248
|
||||
224 120 224
|
||||
200 96 200
|
||||
176 72 176
|
||||
152 48 152
|
||||
120 16 120
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
@ -62,12 +62,13 @@ struct ResourceFlags
|
||||
u32 flags[4];
|
||||
};
|
||||
|
||||
#define RESOURCE_FLAG_FLASH_FIRE 0x1
|
||||
#define RESOURCE_FLAG_ROOST 0x2
|
||||
#define RESOURCE_FLAG_UNBURDEN 0x4
|
||||
#define RESOURCE_FLAG_INTIMIDATED 0x8
|
||||
#define RESOURCE_FLAG_TRACED 0x10
|
||||
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
|
||||
#define RESOURCE_FLAG_FLASH_FIRE 0x1
|
||||
#define RESOURCE_FLAG_ROOST 0x2
|
||||
#define RESOURCE_FLAG_UNBURDEN 0x4
|
||||
#define RESOURCE_FLAG_INTIMIDATED 0x8
|
||||
#define RESOURCE_FLAG_TRACED 0x10
|
||||
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
|
||||
#define RESOURCE_FLAG_NEUTRALIZING_GAS 0x40
|
||||
|
||||
struct DisableStruct
|
||||
{
|
||||
@ -112,6 +113,9 @@ struct DisableStruct
|
||||
u8 throatChopTimer;
|
||||
u8 usedMoves:4;
|
||||
u8 wrapTurns;
|
||||
u8 noRetreat:1;
|
||||
u8 tarShot:1;
|
||||
u8 octolock:1;
|
||||
};
|
||||
|
||||
struct ProtectStruct
|
||||
@ -181,6 +185,8 @@ struct SpecialStatus
|
||||
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
|
||||
u8 dancerUsedMove:1;
|
||||
u8 dancerOriginalTarget:3;
|
||||
u8 announceNeutralizingGas:1; // See Cmd_switchineffects
|
||||
u8 neutralizingGasRemoved:1; // See VARIOUS_TRY_END_NEUTRALIZING_GAS
|
||||
s32 dmg;
|
||||
s32 physicalDmg;
|
||||
s32 specialDmg;
|
||||
@ -222,10 +228,7 @@ struct FieldTimer
|
||||
u8 wonderRoomTimer;
|
||||
u8 magicRoomTimer;
|
||||
u8 trickRoomTimer;
|
||||
u8 grassyTerrainTimer;
|
||||
u8 mistyTerrainTimer;
|
||||
u8 electricTerrainTimer;
|
||||
u8 psychicTerrainTimer;
|
||||
u8 terrainTimer;
|
||||
u8 gravityTimer;
|
||||
u8 fairyLockTimer;
|
||||
};
|
||||
@ -236,7 +239,7 @@ struct WishFutureKnock
|
||||
u8 futureSightAttacker[MAX_BATTLERS_COUNT];
|
||||
u16 futureSightMove[MAX_BATTLERS_COUNT];
|
||||
u8 wishCounter[MAX_BATTLERS_COUNT];
|
||||
u8 wishMonId[MAX_BATTLERS_COUNT];
|
||||
u8 wishPartyId[MAX_BATTLERS_COUNT];
|
||||
u8 weatherDuration;
|
||||
u8 knockedOffMons[2]; // Each battler is represented by a bit. The array entry is dependent on the battler's side.
|
||||
};
|
||||
@ -929,5 +932,6 @@ extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
|
||||
extern bool8 gHasFetchedBall;
|
||||
extern u8 gLastUsedBall;
|
||||
extern u16 gLastThrownBall;
|
||||
extern bool8 gSwapDamageCategory; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
|
||||
#endif // GUARD_BATTLE_H
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef GUARD_BATTLE_AI_UTIL_H
|
||||
#define GUARD_BATTLE_AI_UTIL_H
|
||||
|
||||
// for IsAiFaster
|
||||
#define AI_CHECK_FASTER 0 // if_user_faster
|
||||
#define AI_CHECK_SLOWER 1 // if_target_faster
|
||||
// for AI_WhoStrikesFirst
|
||||
#define AI_IS_FASTER 0
|
||||
#define AI_IS_SLOWER 1
|
||||
|
||||
#define FOE(battler) ((battler ^ BIT_SIDE) & BIT_SIDE)
|
||||
|
||||
@ -21,12 +21,13 @@ void SaveBattlerData(u8 battlerId);
|
||||
void SetBattlerData(u8 battlerId);
|
||||
void RestoreBattlerData(u8 battlerId);
|
||||
|
||||
bool32 WillAIStrikeFirst(void);
|
||||
u32 GetTotalBaseStat(u32 species);
|
||||
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
|
||||
bool32 AtMaxHp(u8 battler);
|
||||
u32 GetHealthPercentage(u8 battler);
|
||||
bool32 IsBattlerTrapped(u8 battler, bool8 switching);
|
||||
bool32 IsAiFaster(u8 battler);
|
||||
u8 AI_WhoStrikesFirst(u8 battlerAI, u8 battler2);
|
||||
bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk);
|
||||
bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits);
|
||||
bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod);
|
||||
@ -35,7 +36,8 @@ u16 AI_GetHoldEffect(u32 battlerId);
|
||||
u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u8 atkHoldEffect, u8 defHoldEffect, u16 move);
|
||||
bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move);
|
||||
bool32 AI_WeatherHasEffect(void);
|
||||
bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits);
|
||||
bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits);
|
||||
bool32 CanIndexMoveFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits);
|
||||
bool32 AI_IsTerrainAffected(u8 battlerId, u32 flags);
|
||||
bool32 AI_IsBattlerGrounded(u8 battlerId);
|
||||
bool32 HasDamagingMove(u8 battlerId);
|
||||
@ -51,9 +53,13 @@ bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent);
|
||||
bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect);
|
||||
bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex);
|
||||
bool32 IsRecycleEncouragedItem(u16 item);
|
||||
bool32 ShouldRestoreHpBerry(u8 battlerAtk, u16 item);
|
||||
bool32 IsStatBoostingBerry(u16 item);
|
||||
bool32 CanKnockOffItem(u8 battler, u16 item);
|
||||
bool32 IsAbilityOfRating(u16 ability, s8 rating);
|
||||
s8 GetAbilityRating(u16 ability);
|
||||
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability);
|
||||
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move);
|
||||
|
||||
// stat stage checks
|
||||
bool32 AnyStatIsRaised(u8 battlerId);
|
||||
@ -120,7 +126,6 @@ bool32 IsSemiInvulnerable(u8 battlerDef, u16 move);
|
||||
|
||||
// status checks
|
||||
bool32 AI_CanBeBurned(u8 battler, u16 ability);
|
||||
bool32 AI_CanBePoisoned(u8 battler, u16 ability);
|
||||
bool32 AI_CanBeConfused(u8 battler, u16 ability);
|
||||
bool32 AI_CanSleep(u8 battler, u16 ability);
|
||||
bool32 IsBattlerIncapacitated(u8 battler, u16 ability);
|
||||
|
@ -310,6 +310,5 @@ extern const u8 gText_BattleTourney[];
|
||||
|
||||
extern const u16 gMissStringIds[];
|
||||
extern const u16 gStatUpStringIds[];
|
||||
extern const u16 gTrappingMoves[];
|
||||
|
||||
#endif // GUARD_BATTLE_MESSAGE_H
|
||||
|
@ -36,6 +36,7 @@ u32 IsAbilityStatusProtected(u32 battler);
|
||||
bool32 TryResetBattlerStatChanges(u8 battler);
|
||||
bool32 CanCamouflage(u8 battlerId);
|
||||
u16 GetNaturePowerMove(void);
|
||||
u16 GetSecretPowerMoveEffect(void);
|
||||
void StealTargetItem(u8 battlerStealer, u8 battlerItem);
|
||||
u8 GetCatchingBattler(void);
|
||||
|
||||
|
@ -261,6 +261,7 @@ extern const u8 BattleScript_AttackerAbilityStatRaiseEnd3[];
|
||||
extern const u8 BattleScript_PoisonHealActivates[];
|
||||
extern const u8 BattleScript_BadDreamsActivates[];
|
||||
extern const u8 BattleScript_SwitchInAbilityMsg[];
|
||||
extern const u8 BattleScript_SwitchInAbilityMsgRet[];
|
||||
extern const u8 BattleScript_ToxicSpikesPoisoned[];
|
||||
extern const u8 BattleScript_ToxicSpikesAbsorbed[];
|
||||
extern const u8 BattleScript_StickyWebOnSwitchIn[];
|
||||
@ -407,5 +408,12 @@ extern const u8 BattleScript_WanderingSpiritActivates[];
|
||||
extern const u8 BattleScript_MirrorArmorReflect[];
|
||||
extern const u8 BattleScript_GooeyActivates[];
|
||||
extern const u8 BattleScript_PastelVeilActivates[];
|
||||
extern const u8 BattleScript_MimicryActivatesEnd3[];
|
||||
extern const u8 BattleScript_ApplyMimicry[];
|
||||
extern const u8 BattleScript_AttackerFormChangeEnd3NoPopup[];
|
||||
extern const u8 BattleScript_AttackerFormChangeMoveEffect[];
|
||||
extern const u8 BattleScript_BothCanNoLongerEscape[];
|
||||
extern const u8 BattleScript_OctolockEndTurn[];
|
||||
extern const u8 BattleScript_NeutralizingGasExits[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
@ -8,21 +8,23 @@
|
||||
#define MOVE_LIMITATION_TAUNT (1 << 4)
|
||||
#define MOVE_LIMITATION_IMPRISON (1 << 5)
|
||||
|
||||
#define ABILITYEFFECT_ON_SWITCHIN 0x0
|
||||
#define ABILITYEFFECT_ENDTURN 0x1
|
||||
#define ABILITYEFFECT_MOVES_BLOCK 0x2
|
||||
#define ABILITYEFFECT_ABSORBING 0x3
|
||||
#define ABILITYEFFECT_MOVE_END_ATTACKER 0x4
|
||||
#define ABILITYEFFECT_MOVE_END 0x5
|
||||
#define ABILITYEFFECT_IMMUNITY 0x6
|
||||
#define ABILITYEFFECT_FORECAST 0x7
|
||||
#define ABILITYEFFECT_SYNCHRONIZE 0x8
|
||||
#define ABILITYEFFECT_ATK_SYNCHRONIZE 0x9
|
||||
#define ABILITYEFFECT_INTIMIDATE1 0xA
|
||||
#define ABILITYEFFECT_INTIMIDATE2 0xB
|
||||
#define ABILITYEFFECT_TRACE1 0xC
|
||||
#define ABILITYEFFECT_TRACE2 0xD
|
||||
#define ABILITYEFFECT_MOVE_END_OTHER 0xE
|
||||
#define ABILITYEFFECT_ON_SWITCHIN 0
|
||||
#define ABILITYEFFECT_ENDTURN 1
|
||||
#define ABILITYEFFECT_MOVES_BLOCK 2
|
||||
#define ABILITYEFFECT_ABSORBING 3
|
||||
#define ABILITYEFFECT_MOVE_END_ATTACKER 4
|
||||
#define ABILITYEFFECT_MOVE_END 5
|
||||
#define ABILITYEFFECT_IMMUNITY 6
|
||||
#define ABILITYEFFECT_FORECAST 7
|
||||
#define ABILITYEFFECT_SYNCHRONIZE 8
|
||||
#define ABILITYEFFECT_ATK_SYNCHRONIZE 9
|
||||
#define ABILITYEFFECT_INTIMIDATE1 10
|
||||
#define ABILITYEFFECT_INTIMIDATE2 11
|
||||
#define ABILITYEFFECT_TRACE1 12
|
||||
#define ABILITYEFFECT_TRACE2 13
|
||||
#define ABILITYEFFECT_MOVE_END_OTHER 14
|
||||
#define ABILITYEFFECT_NEUTRALIZINGGAS 15
|
||||
// Special cases
|
||||
#define ABILITYEFFECT_SWITCH_IN_TERRAIN 0xFE
|
||||
#define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF
|
||||
|
||||
@ -102,6 +104,7 @@ u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability);
|
||||
u32 IsAbilityOnField(u32 ability);
|
||||
u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability);
|
||||
u32 IsAbilityPreventingEscape(u32 battlerId);
|
||||
bool32 IsBattlerProtected(u8 battlerId, u16 move);
|
||||
bool32 CanBattlerEscape(u32 battlerId); // no ability check
|
||||
void BattleScriptExecute(const u8* BS_ptr);
|
||||
void BattleScriptPushCursorAndCallback(const u8* BS_ptr);
|
||||
@ -157,8 +160,11 @@ void DoBurmyFormChange(u32 monId);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
|
||||
u16 GetUsedHeldItem(u8 battler);
|
||||
bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags);
|
||||
void TryToApplyMimicry(u8 battlerId, bool8 various);
|
||||
void TryToRevertMimicry(void);
|
||||
void RestoreBattlerOriginalTypes(u8 battlerId);
|
||||
|
||||
// ability checks
|
||||
// Ability checks
|
||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
|
||||
bool32 IsRolePlayBannedAbility(u16 ability);
|
||||
bool32 IsSkillSwapBannedAbility(u16 ability);
|
||||
|
@ -358,22 +358,39 @@
|
||||
#define MOVE_EFFECT_INCINERATE 0x44
|
||||
#define MOVE_EFFECT_BUG_BITE 0x45
|
||||
#define MOVE_EFFECT_RECOIL_HP_25 0x46
|
||||
#define NUM_MOVE_EFFECTS 0x47
|
||||
#define MOVE_EFFECT_RELIC_SONG 0x47
|
||||
#define MOVE_EFFECT_TRAP_BOTH 0x48
|
||||
#define NUM_MOVE_EFFECTS 0x49
|
||||
|
||||
#define MOVE_EFFECT_AFFECTS_USER 0x4000
|
||||
#define MOVE_EFFECT_CERTAIN 0x8000
|
||||
|
||||
// Battle terrain defines for gBattleTerrain.
|
||||
#define BATTLE_TERRAIN_GRASS 0
|
||||
#define BATTLE_TERRAIN_LONG_GRASS 1
|
||||
#define BATTLE_TERRAIN_SAND 2
|
||||
#define BATTLE_TERRAIN_UNDERWATER 3
|
||||
#define BATTLE_TERRAIN_WATER 4
|
||||
#define BATTLE_TERRAIN_POND 5
|
||||
#define BATTLE_TERRAIN_MOUNTAIN 6
|
||||
#define BATTLE_TERRAIN_CAVE 7
|
||||
#define BATTLE_TERRAIN_BUILDING 8
|
||||
#define BATTLE_TERRAIN_PLAIN 9
|
||||
#define BATTLE_TERRAIN_GRASS 0
|
||||
#define BATTLE_TERRAIN_LONG_GRASS 1
|
||||
#define BATTLE_TERRAIN_SAND 2
|
||||
#define BATTLE_TERRAIN_UNDERWATER 3
|
||||
#define BATTLE_TERRAIN_WATER 4
|
||||
#define BATTLE_TERRAIN_POND 5
|
||||
#define BATTLE_TERRAIN_MOUNTAIN 6
|
||||
#define BATTLE_TERRAIN_CAVE 7
|
||||
#define BATTLE_TERRAIN_BUILDING 8
|
||||
#define BATTLE_TERRAIN_PLAIN 9
|
||||
// New battle terrains are used for Secret Power but not fully implemented.
|
||||
#define BATTLE_TERRAIN_SOARING 10
|
||||
#define BATTLE_TERRAIN_SKY_PILLAR 11
|
||||
#define BATTLE_TERRAIN_BURIAL_GROUND 12
|
||||
#define BATTLE_TERRAIN_PUDDLE 13
|
||||
#define BATTLE_TERRAIN_MARSH 14
|
||||
#define BATTLE_TERRAIN_SWAMP 15
|
||||
#define BATTLE_TERRAIN_SNOW 16
|
||||
#define BATTLE_TERRAIN_ICE 17
|
||||
#define BATTLE_TERRAIN_VOLCANO 18
|
||||
#define BATTLE_TERRAIN_DISTORTION_WORLD 19
|
||||
#define BATTLE_TERRAIN_SPACE 20
|
||||
#define BATTLE_TERRAIN_ULTRA_SPACE 21
|
||||
|
||||
#define BATTLE_TERRAIN_COUNT 22
|
||||
|
||||
#define B_WAIT_TIME_LONG 64
|
||||
#define B_WAIT_TIME_MED 48
|
||||
|
@ -565,7 +565,8 @@
|
||||
#define TRAP_ANIM_WHIRLPOOL 2
|
||||
#define TRAP_ANIM_CLAMP 3
|
||||
#define TRAP_ANIM_SAND_TOMB 4
|
||||
#define TRAP_ANIM_INFESTATION 5
|
||||
#define TRAP_ANIM_MAGMA_STORM 5
|
||||
#define TRAP_ANIM_INFESTATION 6
|
||||
|
||||
// Weather defines for battle animation scripts.
|
||||
#define ANIM_WEATHER_NONE 0
|
||||
|
@ -47,6 +47,11 @@
|
||||
#define SPECIES_GRENINJA_ASH 10017
|
||||
#define SPECIES_HOOPA 0
|
||||
#define SPECIES_HOOPA_UNBOUND 10018
|
||||
#define SPECIES_MELOETTA 0
|
||||
#define SPECIES_MELOETTA_PIROUETTE 10019
|
||||
#define SPECIES_MORPEKO 0
|
||||
#define SPECIES_MORPEKO_HANGRY 10020
|
||||
#define SPECIES_SIRFETCHD 10021
|
||||
#endif
|
||||
|
||||
// Items with peculiar battle effects.
|
||||
@ -87,11 +92,13 @@
|
||||
#define GEN_8 5
|
||||
#endif
|
||||
|
||||
// Mega Evolution settings
|
||||
#define B_MEGA_EVO_TURN_ORDER GEN_7 // In Gen7, a Pokémon's Speed after Mega Evolution is used to determine turn order, not its Speed before.
|
||||
|
||||
// Calculation settings
|
||||
#define B_CRIT_CHANCE GEN_7 // Chances of a critical hit landing. See CalcCritChanceStage.
|
||||
#define B_CRIT_MULTIPLIER GEN_7 // In Gen6+, critical hits multiply damage by 1.5 instead of 2.
|
||||
#define B_PARALYSIS_SPEED GEN_7 // In Gen7+, Speed is decreased by 50% instead of 75%.
|
||||
#define B_TERRAIN_TYPE_BOOST GEN_8 // In Gen8, damage is boosted by 30% instead of 50%.
|
||||
#define B_CONFUSION_SELF_DMG_CHANCE GEN_7 // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%.
|
||||
#define B_MULTI_HIT_CHANCE GEN_7 // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values.
|
||||
|
||||
@ -111,6 +118,7 @@
|
||||
#define B_PAYBACK_SWITCH_BOOST GEN_7 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled.
|
||||
#define B_HIDDEN_POWER_DMG GEN_7 // In Gen6+, Hidden Power's base power was set to always be 60. Before, it was determined by the mon's IVs.
|
||||
#define B_ROUGH_SKIN_DMG GEN_7 // In Gen4+, Rough Skin contact damage is 1/8th of max HP instead of 1/16th. This will also affect Iron Barbs.
|
||||
#define B_KNOCK_OFF_DMG GEN_8 // In Gen6+, Knock Off deals 50% more damage when knocking off an item
|
||||
|
||||
// Type settings
|
||||
#define B_GHOSTS_ESCAPE GEN_7 // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle.
|
||||
@ -149,6 +157,9 @@
|
||||
#define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6.
|
||||
#define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally.
|
||||
#define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use.
|
||||
#define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune.
|
||||
#define B_WISH_HP_SOURCE GEN_7 // In Gen5+, Wish heals half of the user's max HP instead of the target's.
|
||||
#define B_RAMPAGE_CANCELLING GEN_7 // In Gen5+, a failed Thrash, etc, will cancel except on its last turn.
|
||||
|
||||
// Ability settings
|
||||
#define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability.
|
||||
@ -157,7 +168,8 @@
|
||||
#define B_SHADOW_TAG_ESCAPE GEN_7 // In Gen4+, if both sides have a Pokémon with Shadow Tag, all battlers can escape. Before, neither side could escape this situation.
|
||||
#define B_MOODY_ACC_EVASION GEN_8 // In Gen8, Moody CANNOT raise Accuracy and Evasion anymore.
|
||||
#define B_FLASH_FIRE_FROZEN GEN_7 // In Gen5+, Flash Fire can trigger even when frozen, when it couldn't before.
|
||||
#define B_SYNCHRONIZE_NATURE GEN_8 // In Gen8, if the Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same ability, as opposed to 50% previously.
|
||||
#define B_SYNCHRONIZE_NATURE GEN_8 // In Gen8, if a Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same ability, as opposed to 50% previously.
|
||||
#define B_SYNCHRONIZE_TOXIC GEN_8 // In Gen5+, if a Pokémon with Synchronize is badly poisoned, the opponent will also become badly poisoned. Previously, the opponent would become regular poisoned.
|
||||
#define B_UPDATED_INTIMIDATE GEN_8 // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities.
|
||||
|
||||
// Item settings
|
||||
@ -166,6 +178,19 @@
|
||||
#define B_X_ITEMS_BUFF GEN_7 // In Gen7+, the X Items raise a stat by 2 stages instead of 1.
|
||||
#define B_MENTAL_HERB GEN_5 // In Gen5+, the Mental Herb cures Infatuation, Taunt, Encore, Torment, Heal Block, and Disable
|
||||
#define B_TRAINERS_KNOCK_OFF_ITEMS TRUE // If TRUE, trainers can steal/swap your items (non-berries are restored after battle). In vanilla games trainers cannot steal items.
|
||||
#define B_SOUL_DEW_BOOST GEN_7 // In Gens3-6, Soul Dew boosts Lati@s' Sp. Atk and Sp. Def. In Gen7+ it boosts the power of their Psychic and Dragon type moves instead.
|
||||
#define B_NET_BALL_MODIFIER GEN_7 // In Gen7+, Net Ball's catch multiplier is x5 instead of x3.
|
||||
#define B_DIVE_BALL_MODIFIER GEN_7 // In Gen4+, Dive Ball's effectiveness increases by when Surfing or Fishing.
|
||||
#define B_NEST_BALL_MODIFIER GEN_7 // Nest Ball's formula varies depending on the Gen. See Cmd_handleballthrow.
|
||||
#define B_REPEAT_BALL_MODIFIER GEN_7 // In Gen7+, Repeat Ball's catch multiplier is x3.5 instead of x3.
|
||||
#define B_TIMER_BALL_MODIFIER GEN_7 // In Gen5+, Timer Ball's effectiveness increases by x0.3 per turn instead of x0.1
|
||||
#define B_DUSK_BALL_MODIFIER GEN_7 // In Gen7+, Dusk Ball's catch multiplier is x3 instead of x3.5.
|
||||
#define B_QUICK_BALL_MODIFIER GEN_7 // In Gen5+, Quick Ball's catch multiplier is x5 instead of x4.
|
||||
#define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3.
|
||||
#define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow.
|
||||
#define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose.
|
||||
#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts the added flinch chance of King's Rock and Razor Fang.
|
||||
#define B_LEEK_ALWAYS_CRIT GEN_7 // In Gen6+, if a Farfetch'd or Sirfetch'd holding a Leek use a move with increased Critical Hit ratio, it will always result in a Critical Hit.
|
||||
|
||||
// Flag settings
|
||||
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
|
||||
@ -178,26 +203,31 @@
|
||||
// Eg: Replace with VAR_UNUSED_0x40F7 so you can use VAR_TERRAIN for that feature.
|
||||
#define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active
|
||||
|
||||
// Terrain settings
|
||||
#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades.
|
||||
#define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8.
|
||||
#define B_TERRAIN_TYPE_BOOST GEN_8 // In Gen8, damage is boosted by 30% instead of 50%.
|
||||
#define B_SECRET_POWER_EFFECT GEN_7 // Secret Power's effects change depending on terrain and generation. See GetSecretPowerMoveEffect.
|
||||
#define B_SECRET_POWER_ANIMATION GEN_7 // Secret Power's animations change depending on terrain and generation.
|
||||
#define B_NATURE_POWER_MOVES GEN_8 // Nature Power calls different moves depending on terrain and generation. See sNaturePowerMoves.
|
||||
#define B_CAMOUFLAGE_TYPES GEN_7 // Camouflage changes the user to different types depending on terrain and generation. See sTerrainToType.
|
||||
|
||||
// Interface settings
|
||||
#define B_ABILITY_POP_UP TRUE // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle.
|
||||
#define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end.
|
||||
#define B_SHOW_TARGETS TRUE // If set to TRUE, all available targets, for moves hitting 2 or 3 Pokémon, will be shown before selecting a move.
|
||||
#define B_SHOW_SPLIT_ICON TRUE // If set to TRUE, it will show an icon in the summary showing the move's category split.
|
||||
#define B_HIDE_HEALTHBOX_IN_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations.
|
||||
#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades.
|
||||
|
||||
// Critical Capture
|
||||
#define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled.
|
||||
#define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm.
|
||||
|
||||
// Last Used Ball
|
||||
#define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented
|
||||
#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball.
|
||||
// Catching settings
|
||||
#define B_SEMI_INVULNERABLE_CATCH GEN_7 // In Gen4+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc)
|
||||
#define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm.
|
||||
#define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled.
|
||||
#define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented
|
||||
#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball.
|
||||
|
||||
// Other
|
||||
#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter.
|
||||
#define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8.
|
||||
#define B_SEMI_INVULNERABLE_CATCH GEN_7 // In Gen4+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc)
|
||||
|
||||
// Animation Settings
|
||||
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.
|
||||
|
@ -350,7 +350,7 @@
|
||||
#define EFFECT_GEOMANCY 344
|
||||
#define EFFECT_FAIRY_LOCK 345
|
||||
#define EFFECT_ALLY_SWITCH 346
|
||||
#define EFFECT_SLEEP_HIT 347
|
||||
#define EFFECT_RELIC_SONG 347
|
||||
#define EFFECT_ATTACKER_DEFENSE_DOWN_HIT 348
|
||||
#define EFFECT_BODY_PRESS 349
|
||||
#define EFFECT_EERIE_SPELL 350
|
||||
@ -375,7 +375,18 @@
|
||||
#define EFFECT_SPARKLY_SWIRL 369
|
||||
#define EFFECT_PLASMA_FISTS 370
|
||||
#define EFFECT_HYPERSPACE_FURY 371
|
||||
#define EFFECT_AURA_WHEEL 372
|
||||
#define EFFECT_PHOTON_GEYSER 373
|
||||
#define EFFECT_SHELL_SIDE_ARM 374
|
||||
#define EFFECT_TERRAIN_PULSE 375
|
||||
#define EFFECT_JAW_LOCK 376
|
||||
#define EFFECT_NO_RETREAT 377
|
||||
#define EFFECT_TAR_SHOT 378
|
||||
#define EFFECT_POLTERGEIST 379
|
||||
#define EFFECT_OCTOLOCK 380
|
||||
#define EFFECT_CLANGOROUS_SOUL 381
|
||||
#define EFFECT_BOLT_BEAK 382
|
||||
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 372
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 383
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
|
||||
|
@ -198,6 +198,16 @@
|
||||
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125
|
||||
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126
|
||||
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127
|
||||
#define VARIOUS_TRY_TO_APPLY_MIMICRY 128
|
||||
#define VARIOUS_PHOTON_GEYSER_CHECK 129
|
||||
#define VARIOUS_SHELL_SIDE_ARM_CHECK 130
|
||||
#define VARIOUS_TRY_NO_RETREAT 131
|
||||
#define VARIOUS_TRY_TAR_SHOT 132
|
||||
#define VARIOUS_CAN_TAR_SHOT_WORK 133
|
||||
#define VARIOUS_CHECK_POLTERGEIST 134
|
||||
#define VARIOUS_SET_OCTOLOCK 135
|
||||
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 136
|
||||
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 137
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
@ -216,6 +226,7 @@
|
||||
// Cmd_statbuffchange
|
||||
#define STAT_BUFF_ALLOW_PTR (1 << 0) // If set, allow use of jumpptr. Set in every use of statbuffchange
|
||||
#define STAT_BUFF_NOT_PROTECT_AFFECTED (1 << 5)
|
||||
#define STAT_BUFF_UPDATE_MOVE_EFFECT (1 << 6)
|
||||
|
||||
// stat change flags for Cmd_playstatchangeanimation
|
||||
#define STAT_CHANGE_NEGATIVE (1 << 0)
|
||||
|
@ -410,7 +410,7 @@
|
||||
#define STRINGID_PKMNTWISTEDDIMENSIONS 406
|
||||
#define STRINGID_POINTEDSTONESFLOAT 407
|
||||
#define STRINGID_CLOAKEDINMYSTICALMOONLIGHT 408
|
||||
#define STRINGID_TRAPPERBYSWIRLINGMAGMA 409
|
||||
#define STRINGID_TRAPPEDBYSWIRLINGMAGMA 409
|
||||
#define STRINGID_VANISHEDINSTANTLY 410
|
||||
#define STRINGID_PROTECTEDTEAM 411
|
||||
#define STRINGID_SHAREDITSGUARD 412
|
||||
@ -420,7 +420,7 @@
|
||||
#define STRINGID_HURLEDINTOTHEAIR 416
|
||||
#define STRINGID_HELDITEMSLOSEEFFECTS 417
|
||||
#define STRINGID_FELLSTRAIGHTDOWN 418
|
||||
#define STRINGID_TRANSFORMEDINTOWATERTYPE 419
|
||||
#define STRINGID_TARGETCHANGEDTYPE 419
|
||||
#define STRINGID_PKMNACQUIREDSIMPLE 420
|
||||
#define STRINGID_EMPTYSTRING5 421
|
||||
#define STRINGID_KINDOFFER 422
|
||||
@ -601,8 +601,16 @@
|
||||
#define STRINGID_SWAPPEDABILITIES 598
|
||||
#define STRINGID_PASTELVEILPROTECTED 599
|
||||
#define STRINGID_PASTELVEILENTERS 600
|
||||
#define STRINGID_BATTLERTYPECHANGEDTO 601
|
||||
#define STRINGID_BOTHCANNOLONGERESCAPE 602
|
||||
#define STRINGID_CANTESCAPEDUETOUSEDMOVE 603
|
||||
#define STRINGID_PKMNBECAMEWEAKERTOFIRE 604
|
||||
#define STRINGID_ABOUTTOUSEPOLTERGEIST 605
|
||||
#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 606
|
||||
#define STRINGID_NEUTRALIZINGGASENTERS 607
|
||||
#define STRINGID_NEUTRALIZINGGASOVER 608
|
||||
|
||||
#define BATTLESTRINGS_COUNT 601
|
||||
#define BATTLESTRINGS_COUNT 609
|
||||
|
||||
// The below IDs are all indexes into battle message tables,
|
||||
// used to determine which of a set of messages to print.
|
||||
@ -838,6 +846,7 @@
|
||||
#define B_MSG_SWITCHIN_ASONE 13
|
||||
#define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14
|
||||
#define B_MSG_SWITCHIN_PASTEL_VEIL 15
|
||||
#define B_MSG_SWITCHIN_NEUTRALIZING_GAS 16
|
||||
|
||||
// gMentalHerbCureStringIds
|
||||
#define B_MSG_MENTALHERBCURE_INFATUATION 0
|
||||
|
@ -62,12 +62,12 @@
|
||||
#define HOLD_EFFECT_FIRE_POWER 58
|
||||
#define HOLD_EFFECT_DRAGON_POWER 59
|
||||
#define HOLD_EFFECT_NORMAL_POWER 60
|
||||
#define HOLD_EFFECT_UP_GRADE 61
|
||||
#define HOLD_EFFECT_UPGRADE 61
|
||||
#define HOLD_EFFECT_SHELL_BELL 62
|
||||
#define HOLD_EFFECT_LUCKY_PUNCH 63
|
||||
#define HOLD_EFFECT_METAL_POWDER 64
|
||||
#define HOLD_EFFECT_THICK_CLUB 65
|
||||
#define HOLD_EFFECT_STICK 66
|
||||
#define HOLD_EFFECT_LEEK 66
|
||||
|
||||
// Gen4 hold effects.
|
||||
#define HOLD_EFFECT_CHOICE_SCARF 67
|
||||
|
@ -308,6 +308,7 @@
|
||||
#define FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING (1 << 24) // Makes a Ground type move do 1x damage to flying and levitating targets
|
||||
#define FLAG_THAW_USER (1 << 25)
|
||||
#define FLAG_HIT_IN_SUBSTITUTE (1 << 26) // Hyperspace Fury
|
||||
#define FLAG_TWO_STRIKES (1 << 27) // A move with this flag will strike twice, and may apply its effect on each hit
|
||||
|
||||
// Split defines.
|
||||
#define SPLIT_PHYSICAL 0x0
|
||||
|
@ -4937,11 +4937,13 @@ extern const u32 gBattleAnimBgImage_Hurricane[];
|
||||
extern const u32 gBattleAnimBgPalette_Hurricane[];
|
||||
extern const u32 gBattleAnimBgTilemap_Hurricane[];
|
||||
extern const u32 gBattleAnimBgPalette_RockWrecker[];
|
||||
extern const u32 gBattleAnimBgTilemap_GigaImpactPlayer[];
|
||||
extern const u32 gBattleAnimBgTilemap_GigaImpactOpponent[];
|
||||
extern const u32 gBattleAnimBgTilemap_GigaImpactContest[];
|
||||
extern const u32 gBattleAnimBgImage_GigaImpact[];
|
||||
extern const u32 gBattleAnimBgPalette_GigaImpact[];
|
||||
extern const u32 gBattleAnimBgImage_SpacialRend[];
|
||||
extern const u32 gBattleAnimBgPalette_SpacialRend[];
|
||||
extern const u32 gBattleAnimBgTilemap_SpacialRendOpponent[];
|
||||
extern const u32 gBattleAnimBgTilemap_SpacialRendPlayer[];
|
||||
extern const u32 gBattleAnimBgImage_DarkVoid[];
|
||||
extern const u32 gBattleAnimBgPalette_DarkVoid[];
|
||||
extern const u32 gBattleAnimBgTilemap_DarkVoid[];
|
||||
extern const u32 gBattleAnimBgPalette_Dark[];
|
||||
@ -4961,7 +4963,6 @@ extern const u32 gBattleAnimBgPalette_Fissure[];
|
||||
extern const u32 gBattleAnimBgPalette_Bug[];
|
||||
extern const u32 gBattleAnimBgPalette_Solarbeam[];
|
||||
extern const u32 gBattleAnimBgPalette_MagmaStorm[];
|
||||
extern const u32 gBattleAnimBgPalette_GigaImpact[];
|
||||
extern const u32 gBattleAnimBgPalette_TrickRoom[];
|
||||
extern const u32 gBattleAnimBgTilemap_Dark[];
|
||||
extern const u32 gBattleAnimBgTilemap_Ghost[];
|
||||
|
@ -30,6 +30,8 @@ struct WildPokemonHeader
|
||||
};
|
||||
|
||||
extern const struct WildPokemonHeader gWildMonHeaders[];
|
||||
extern bool8 gIsFishingEncounter;
|
||||
extern bool8 gIsSurfingEncounter;
|
||||
|
||||
void DisableWildEncounters(bool8 disabled);
|
||||
bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavior);
|
||||
|
@ -278,6 +278,7 @@ static u8 ChooseMoveOrAction_Singles(void)
|
||||
return AI_CHOICE_WATCH;
|
||||
|
||||
gActiveBattler = sBattler_AI;
|
||||
|
||||
// If can switch.
|
||||
if (CountUsablePartyMons(sBattler_AI) > 0
|
||||
&& !IsAbilityPreventingEscape(sBattler_AI)
|
||||
@ -318,7 +319,7 @@ static u8 ChooseMoveOrAction_Singles(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
numOfBestMoves = 1;
|
||||
currentMoveArray[0] = AI_THINKING_STRUCT->score[0];
|
||||
consideredMoveArray[0] = 0;
|
||||
@ -559,7 +560,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// check off screen
|
||||
if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) != 1)
|
||||
if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER)
|
||||
RETURN_SCORE_MINUS(20); // if target off screen and we go first, don't use move
|
||||
|
||||
// check if negates type
|
||||
@ -578,6 +579,21 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
switch (AI_DATA->defAbility)
|
||||
{
|
||||
case ABILITY_MAGIC_GUARD:
|
||||
switch (moveEffect)
|
||||
{
|
||||
case EFFECT_POISON:
|
||||
case EFFECT_WILL_O_WISP:
|
||||
case EFFECT_TOXIC:
|
||||
case EFFECT_LEECH_SEED:
|
||||
score -= 5;
|
||||
break;
|
||||
case EFFECT_CURSE:
|
||||
if (IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GHOST)) // Don't use Curse if you're a ghost type vs a Magic Guard user, they'll take no damage.
|
||||
score -= 5;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITY_VOLT_ABSORB:
|
||||
case ABILITY_MOTOR_DRIVE:
|
||||
case ABILITY_LIGHTNING_ROD:
|
||||
@ -1243,7 +1259,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
&& (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect != HOLD_EFFECT_MENTAL_HERB)
|
||||
&& !PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove))
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker should go first
|
||||
{
|
||||
if (gLastMoves[battlerDef] == MOVE_NONE || gLastMoves[battlerDef] == 0xFFFF)
|
||||
score -= 10; // no anticipated move to disable
|
||||
@ -1263,7 +1279,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
&& (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect != HOLD_EFFECT_MENTAL_HERB)
|
||||
&& !DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove))
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker should go first
|
||||
{
|
||||
if (gLastMoves[battlerDef] == MOVE_NONE || gLastMoves[battlerDef] == 0xFFFF)
|
||||
score -= 10; // no anticipated move to encore
|
||||
@ -1377,22 +1393,22 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
break;
|
||||
case EFFECT_SANDSTORM:
|
||||
if (gBattleWeather & WEATHER_SANDSTORM_ANY //TODO | WEATHER_PRIMAL_ANY)
|
||||
if (gBattleWeather & (WEATHER_SANDSTORM_ANY | WEATHER_PRIMAL_ANY)
|
||||
|| PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove))
|
||||
score -= 8;
|
||||
break;
|
||||
case EFFECT_SUNNY_DAY:
|
||||
if (gBattleWeather & WEATHER_SUN_ANY //TODO | WEATHER_PRIMAL_ANY)
|
||||
if (gBattleWeather & (WEATHER_SUN_ANY | WEATHER_PRIMAL_ANY)
|
||||
|| PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove))
|
||||
score -= 8;
|
||||
break;
|
||||
case EFFECT_RAIN_DANCE:
|
||||
if (gBattleWeather & WEATHER_RAIN_ANY //TODO | WEATHER_PRIMAL_ANY)
|
||||
if (gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_PRIMAL_ANY)
|
||||
|| PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove))
|
||||
score -= 8;
|
||||
break;
|
||||
case EFFECT_HAIL:
|
||||
if (gBattleWeather & WEATHER_HAIL_ANY //TODO | WEATHER_PRIMAL_ANY)
|
||||
if (gBattleWeather & (WEATHER_HAIL_ANY | WEATHER_PRIMAL_ANY)
|
||||
|| PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove))
|
||||
score -= 8;
|
||||
break;
|
||||
@ -1458,7 +1474,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
else if (move == MOVE_FAKE_OUT) // filter out first impression
|
||||
{
|
||||
if ((AI_DATA->atkHoldEffect == HOLD_EFFECT_CHOICE_BAND || AI_DATA->atkAbility == ABILITY_GORILLA_TACTICS)
|
||||
&& (CountUsablePartyMons(battlerDef) > 0 || !CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)))
|
||||
&& (CountUsablePartyMons(battlerDef) > 0 || !CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)))
|
||||
{
|
||||
if (CountUsablePartyMons(battlerAtk) == 0)
|
||||
score -= 10; // Don't lock the attacker into Fake Out if they can't switch out afterwards.
|
||||
@ -1699,12 +1715,12 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2)
|
||||
score -= 10;
|
||||
else if (AI_DATA->atkAbility != ABILITY_TRUANT
|
||||
&& !CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
&& !CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
score -= 2;
|
||||
break;
|
||||
case EFFECT_SPITE:
|
||||
case EFFECT_MIMIC:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker should go first
|
||||
{
|
||||
if (gLastMoves[battlerDef] == MOVE_NONE
|
||||
|| gLastMoves[battlerDef] == 0xFFFF)
|
||||
@ -1861,7 +1877,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (isDoubleBattle)
|
||||
{
|
||||
if (IsHazardMoveEffect(gBattleMoves[AI_DATA->partnerMove].effect) // partner is going to set up hazards
|
||||
&& GetWhoStrikesFirst(AI_DATA->battlerAtkPartner, battlerAtk, FALSE)) // partner is going to set up before the potential Defog
|
||||
&& AI_WhoStrikesFirst(AI_DATA->battlerAtkPartner, battlerAtk) == AI_IS_FASTER) // partner is going to set up before the potential Defog
|
||||
{
|
||||
score -= 10;
|
||||
break; // Don't use Defog if partner is going to set up hazards
|
||||
@ -1899,7 +1915,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
break;
|
||||
case EFFECT_SEMI_INVULNERABLE:
|
||||
if (predictedMove != MOVE_NONE
|
||||
&& GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER
|
||||
&& gBattleMoves[predictedMove].effect == EFFECT_SEMI_INVULNERABLE)
|
||||
score -= 10; // Don't Fly/dig/etc if opponent is going to fly/dig/etc after you
|
||||
|
||||
@ -2080,7 +2096,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case EFFECT_ME_FIRST:
|
||||
if (predictedMove != MOVE_NONE)
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1)
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER)
|
||||
score -= 10; // Target is predicted to go first, Me First will fail
|
||||
else
|
||||
return AI_CheckBadMove(battlerAtk, battlerDef, predictedMove, score);
|
||||
@ -2267,7 +2283,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
break;
|
||||
case EFFECT_ELECTRIFY:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER
|
||||
//|| GetMoveTypeSpecial(battlerDef, predictedMove) == TYPE_ELECTRIC // Move will already be electric type
|
||||
|| PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove))
|
||||
score -= 10;
|
||||
@ -2296,7 +2312,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case EFFECT_INSTRUCT:
|
||||
{
|
||||
u16 instructedMove;
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1)
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER)
|
||||
instructedMove = predictedMove;
|
||||
else
|
||||
instructedMove = gLastMoves[battlerDef];
|
||||
@ -2305,7 +2321,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
|| IsInstructBannedMove(instructedMove)
|
||||
|| MoveRequiresRecharging(instructedMove)
|
||||
|| MoveCallsOtherMove(instructedMove)
|
||||
#ifdef ITEM_Z_RING
|
||||
#ifdef ITEM_Z_POWER_RING
|
||||
//|| (IsZMove(instructedMove))
|
||||
#endif
|
||||
|| (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF)
|
||||
@ -2336,21 +2352,21 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
break;
|
||||
case EFFECT_QUASH:
|
||||
if (!isDoubleBattle
|
||||
|| GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1
|
||||
|| AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER
|
||||
|| PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove))
|
||||
score -= 10;
|
||||
break;
|
||||
case EFFECT_AFTER_YOU:
|
||||
if (!IsTargetingPartner(battlerAtk, battlerDef)
|
||||
|| !isDoubleBattle
|
||||
|| GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1
|
||||
|| AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER
|
||||
|| PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove))
|
||||
score -= 10;
|
||||
break;
|
||||
case EFFECT_SUCKER_PUNCH:
|
||||
if (predictedMove != MOVE_NONE)
|
||||
{
|
||||
if (IS_MOVE_STATUS(predictedMove) || GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // opponent going first
|
||||
if (IS_MOVE_STATUS(predictedMove) || AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER) // Opponent going first
|
||||
score -= 10;
|
||||
}
|
||||
break;
|
||||
@ -2398,11 +2414,11 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score--;
|
||||
break;
|
||||
case EFFECT_VITAL_THROW:
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && GetHealthPercentage(battlerAtk) < 40)
|
||||
if (WillAIStrikeFirst() && GetHealthPercentage(battlerAtk) < 40)
|
||||
score--; // don't want to move last
|
||||
break;
|
||||
case EFFECT_FLAIL:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1 // opponent should go first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER // Opponent should go first
|
||||
|| GetHealthPercentage(battlerAtk) > 50)
|
||||
score -= 4;
|
||||
break;
|
||||
@ -2450,10 +2466,10 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (gBattleMoves[move].power == 0)
|
||||
return score; // can't make anything faint with no power
|
||||
|
||||
if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0) && gBattleMoves[move].effect != EFFECT_EXPLOSION)
|
||||
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0) && gBattleMoves[move].effect != EFFECT_EXPLOSION)
|
||||
{
|
||||
// this move can faint the target
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 || GetMovePriority(battlerAtk, move) > 0)
|
||||
if (!WillAIStrikeFirst() || GetMovePriority(battlerAtk, move) > 0)
|
||||
score += 4; // we go first or we're using priority move
|
||||
else
|
||||
score += 2;
|
||||
@ -2501,7 +2517,7 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
//AI_TryToFaint_CheckIfDanger
|
||||
if (!IsAiFaster(AI_CHECK_FASTER) && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
if (!WillAIStrikeFirst() && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
{ // AI_TryToFaint_Danger
|
||||
if (GetMoveDamageResult(move) != MOVE_POWER_BEST)
|
||||
score--;
|
||||
@ -2551,7 +2567,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
// Ally decided to use Frost Breath on us. we must have Anger Point as our ability
|
||||
if (AI_DATA->atkAbility == ABILITY_ANGER_POINT)
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerAtkPartner, TRUE) == 1) // partner moving first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerAtkPartner) == AI_IS_SLOWER) // Partner moving first
|
||||
{
|
||||
// discourage raising our attack since it's about to be maxed out
|
||||
if (IsAttackBoostMoveEffect(effect))
|
||||
@ -2692,7 +2708,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
&& !IS_MOVE_STATUS(move)
|
||||
&& HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL)
|
||||
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)
|
||||
&& !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
|
||||
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
|
||||
{
|
||||
RETURN_SCORE_PLUS(1);
|
||||
}
|
||||
@ -2701,7 +2717,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (!IS_MOVE_STATUS(move)
|
||||
&& (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG)
|
||||
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPEED)
|
||||
&& !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
|
||||
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
|
||||
{
|
||||
RETURN_SCORE_PLUS(1);
|
||||
}
|
||||
@ -2767,7 +2783,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
&& !IS_MOVE_STATUS(move)
|
||||
&& HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL)
|
||||
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)
|
||||
&& !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
{
|
||||
RETURN_SCORE_PLUS(1);
|
||||
}
|
||||
@ -2818,22 +2834,22 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case EFFECT_INSTRUCT:
|
||||
{
|
||||
u16 instructedMove;
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerAtkPartner, TRUE) == 0)
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerAtkPartner) == AI_IS_FASTER)
|
||||
instructedMove = AI_DATA->partnerMove;
|
||||
else
|
||||
instructedMove = gLastMoves[battlerAtkPartner];
|
||||
|
||||
if (instructedMove != MOVE_NONE
|
||||
&& !IS_MOVE_STATUS(instructedMove)
|
||||
&& gBattleMoves[instructedMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) //Use instruct on multi-target moves
|
||||
&& gBattleMoves[instructedMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) // Use instruct on multi-target moves
|
||||
{
|
||||
RETURN_SCORE_PLUS(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_AFTER_YOU:
|
||||
if (GetWhoStrikesFirst(battlerAtkPartner, FOE(battlerAtkPartner), TRUE) == 1 // opponent mon 1 goes before partner
|
||||
|| GetWhoStrikesFirst(battlerAtkPartner, BATTLE_PARTNER(FOE(battlerAtkPartner)), TRUE) == 1) // opponent mon 2 goes before partner
|
||||
if (AI_WhoStrikesFirst(battlerAtkPartner, FOE(battlerAtkPartner) == AI_IS_SLOWER) // Opponent mon 1 goes before partner
|
||||
|| AI_WhoStrikesFirst(battlerAtkPartner, BATTLE_PARTNER(FOE(battlerAtkPartner)) == AI_IS_SLOWER)) // Opponent mon 2 goes before partner
|
||||
{
|
||||
if (gBattleMoves[AI_DATA->partnerMove].effect == EFFECT_COUNTER || gBattleMoves[AI_DATA->partnerMove].effect == EFFECT_MIRROR_COAT)
|
||||
break; // These moves need to go last
|
||||
@ -2859,7 +2875,9 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case EFFECT_EARTHQUAKE:
|
||||
case EFFECT_MAGNITUDE:
|
||||
if (!IsBattlerGrounded(battlerAtkPartner)
|
||||
|| (GetWhoStrikesFirst(battlerAtk, battlerAtkPartner, TRUE) == 1 && IsUngroundingEffect(gBattleMoves[AI_DATA->partnerMove].effect)))
|
||||
|| (IsBattlerGrounded(battlerAtkPartner)
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerAtkPartner) == AI_IS_SLOWER
|
||||
&& IsUngroundingEffect(gBattleMoves[AI_DATA->partnerMove].effect)))
|
||||
score += 2;
|
||||
else if (IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_FIRE)
|
||||
|| IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_ELECTRIC)
|
||||
@ -2910,9 +2928,9 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
// check already dead
|
||||
if (!IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility)
|
||||
&& CanTargetFaintAi(battlerAtk, battlerDef)
|
||||
&& GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // opponent should go first
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER) // Opponent should go first
|
||||
{
|
||||
if (atkPriority > 0)
|
||||
if (atkPriority > 0)
|
||||
score++;
|
||||
else
|
||||
score--;
|
||||
@ -2949,38 +2967,26 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
}
|
||||
|
||||
// ability checks
|
||||
// attacker ability checks
|
||||
switch (AI_DATA->atkAbility)
|
||||
{
|
||||
case ABILITY_MOXIE:
|
||||
case ABILITY_BEAST_BOOST:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first
|
||||
case ABILITY_CHILLING_NEIGH:
|
||||
case ABILITY_GRIM_NEIGH:
|
||||
case ABILITY_AS_ONE_ICE_RIDER:
|
||||
case ABILITY_AS_ONE_SHADOW_RIDER:
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker should go first
|
||||
{
|
||||
if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
score += 8; // prioritize killing target for stat boost
|
||||
}
|
||||
break;
|
||||
case ABILITY_MAGIC_GUARD:
|
||||
switch (moveEffect)
|
||||
{
|
||||
case EFFECT_POISON:
|
||||
case EFFECT_WILL_O_WISP:
|
||||
case EFFECT_TOXIC:
|
||||
case EFFECT_LEECH_SEED:
|
||||
score -= 5;
|
||||
break;
|
||||
case EFFECT_CURSE:
|
||||
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST))
|
||||
score -= 5;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} // ability checks
|
||||
|
||||
// move effect checks
|
||||
switch (moveEffect)
|
||||
{
|
||||
|
||||
case EFFECT_HIT:
|
||||
break;
|
||||
case EFFECT_SLEEP:
|
||||
@ -3042,7 +3048,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
break;
|
||||
case EFFECT_SPEED_UP:
|
||||
case EFFECT_SPEED_UP_2:
|
||||
if (IsAiFaster(AI_CHECK_SLOWER))
|
||||
if (!WillAIStrikeFirst())
|
||||
{
|
||||
if (!AI_RandLessThan(70))
|
||||
score += 3;
|
||||
@ -3140,7 +3146,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
break;
|
||||
case EFFECT_SPEED_DOWN:
|
||||
case EFFECT_SPEED_DOWN_2:
|
||||
if (IsAiFaster(AI_CHECK_FASTER))
|
||||
if (WillAIStrikeFirst())
|
||||
score -= 3;
|
||||
else if (!AI_RandLessThan(70))
|
||||
score += 2;
|
||||
@ -3243,6 +3249,10 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case EFFECT_MULTI_HIT:
|
||||
case EFFECT_DOUBLE_HIT:
|
||||
case EFFECT_TRIPLE_KICK:
|
||||
if (AI_MoveMakesContact(AI_DATA->atkAbility, AI_DATA->atkHoldEffect, move)
|
||||
&& AI_DATA->atkAbility != ABILITY_MAGIC_GUARD
|
||||
&& AI_DATA->defHoldEffect == HOLD_EFFECT_ROCKY_HELMET)
|
||||
score -= 2;
|
||||
break;
|
||||
case EFFECT_CONVERSION:
|
||||
if (!IS_BATTLER_OF_TYPE(battlerAtk, gBattleMoves[gBattleMons[battlerAtk].moves[0]].type))
|
||||
@ -3381,7 +3391,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score += 2;
|
||||
break;
|
||||
case EFFECT_SPEED_DOWN_HIT:
|
||||
if (IsAiFaster(AI_CHECK_FASTER))
|
||||
if (WillAIStrikeFirst())
|
||||
score -= 2;
|
||||
else if (!AI_RandLessThan(70))
|
||||
score++;
|
||||
@ -3413,7 +3423,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score++;
|
||||
break;
|
||||
case EFFECT_MIMIC:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0)
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER)
|
||||
{
|
||||
if (gLastMoves[battlerDef] != MOVE_NONE && gLastMoves[battlerDef] != 0xFFFF)
|
||||
return AI_CheckViability(battlerAtk, battlerDef, gLastMoves[battlerDef], score);
|
||||
@ -3472,7 +3482,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (gDisableStructs[battlerDef].disableTimer == 0
|
||||
&& (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect != HOLD_EFFECT_MENTAL_HERB)) // mental herb
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // AI goes first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // AI goes first
|
||||
{
|
||||
if (gLastMoves[battlerDef] != MOVE_NONE
|
||||
&& gLastMoves[battlerDef] != 0xFFFF)
|
||||
@ -3522,11 +3532,11 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score++;
|
||||
break;
|
||||
case EFFECT_SPEED_UP_HIT:
|
||||
if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY && IsAiFaster(AI_CHECK_SLOWER))
|
||||
if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY && !WillAIStrikeFirst())
|
||||
score += 3;
|
||||
break;
|
||||
case EFFECT_DESTINY_BOND:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
score += 3;
|
||||
break;
|
||||
case EFFECT_SPITE:
|
||||
@ -3772,9 +3782,9 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case EFFECT_FELL_STINGER:
|
||||
if (gBattleMons[battlerAtk].statStages[STAT_ATK] < MAX_STAT_STAGE
|
||||
&& AI_DATA->atkAbility != ABILITY_CONTRARY
|
||||
&& CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
&& CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker goes first
|
||||
score += 9;
|
||||
else
|
||||
score += 3;
|
||||
@ -3819,7 +3829,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score++;
|
||||
if (predictedMove != MOVE_NONE && !isDoubleBattle)
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker goes first
|
||||
{
|
||||
if (gBattleMoves[predictedMove].effect == EFFECT_EXPLOSION
|
||||
|| gBattleMoves[predictedMove].effect == EFFECT_PROTECT)
|
||||
@ -3886,7 +3896,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
break;
|
||||
case EFFECT_ATTRACT:
|
||||
if (!isDoubleBattle && BattlerWillFaintFromSecondaryDamage(battlerDef, AI_DATA->defAbility)
|
||||
&& GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // Target goes first
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER) // Target goes first
|
||||
break; // Don't use if the attract won't have a change to activate
|
||||
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_ANY
|
||||
@ -3931,7 +3941,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (isDoubleBattle)
|
||||
{
|
||||
if (IsHazardMoveEffect(gBattleMoves[AI_DATA->partnerMove].effect) // Partner is going to set up hazards
|
||||
&& GetWhoStrikesFirst(battlerAtk, AI_DATA->battlerAtkPartner, TRUE) == 1) // Partner going first
|
||||
&& AI_WhoStrikesFirst(battlerAtk, AI_DATA->battlerAtkPartner) == AI_IS_SLOWER) // Partner going first
|
||||
break; // Don't use Defog if partner is going to set up hazards
|
||||
}
|
||||
|
||||
@ -3999,7 +4009,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score += 2;
|
||||
break;
|
||||
case HOLD_EFFECT_TOXIC_ORB:
|
||||
if (!ShouldPoisonSelf(battlerAtk, AI_DATA->atkAbility) && AI_CanBePoisoned(battlerDef, AI_DATA->defAbility))
|
||||
if (!ShouldPoisonSelf(battlerAtk, AI_DATA->atkAbility))
|
||||
score += 2;
|
||||
break;
|
||||
case HOLD_EFFECT_FLAME_ORB:
|
||||
@ -4101,6 +4111,18 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score++;
|
||||
if (IsRecycleEncouragedItem(GetUsedHeldItem(battlerAtk)))
|
||||
score++;
|
||||
if (AI_DATA->atkAbility == ABILITY_RIPEN)
|
||||
{
|
||||
u16 item = GetUsedHeldItem(battlerAtk);
|
||||
u16 toHeal = (ItemId_GetHoldEffectParam(item) == 10) ? 10 : gBattleMons[battlerAtk].maxHP / ItemId_GetHoldEffectParam(item);
|
||||
|
||||
if (IsStatBoostingBerry(item) && atkHpPercent > 60)
|
||||
score++;
|
||||
else if (ShouldRestoreHpBerry(battlerAtk, item) && !CanAIFaintTarget(battlerAtk, battlerDef, 0)
|
||||
&& ((GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 0))
|
||||
|| !CanTargetFaintAiWithMod(battlerDef, battlerAtk, toHeal, 0)))
|
||||
score++; // Recycle healing berry if we can't otherwise faint the target and the target wont kill us after we activate the berry
|
||||
}
|
||||
break;
|
||||
case EFFECT_BRICK_BREAK:
|
||||
if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_REFLECT)
|
||||
@ -4305,7 +4327,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (!IsBattlerGrounded(battlerDef))
|
||||
score += 3;
|
||||
break;
|
||||
case EFFECT_SLEEP_HIT: // Relic Song
|
||||
case EFFECT_RELIC_SONG:
|
||||
#if (defined SPECIES_MELOETTA && defined SPECIES_MELOETTA_PIROUETTE)
|
||||
if (AI_DATA->atkSpecies == SPECIES_MELOETTA && gBattleMons[battlerDef].defense < gBattleMons[battlerDef].spDefense)
|
||||
score += 3; // Change to pirouette if can do more damage
|
||||
@ -4408,13 +4430,13 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score++;
|
||||
break;
|
||||
case EFFECT_THROAT_CHOP:
|
||||
if (predictedMove != MOVE_NONE && TestMoveFlags(predictedMove, FLAG_SOUND) && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0)
|
||||
if (predictedMove != MOVE_NONE && TestMoveFlags(predictedMove, FLAG_SOUND) && AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER)
|
||||
score += 3; // Ai goes first and predicts the target will use a sound move
|
||||
else if (TestMoveFlagsInMoveset(battlerDef, FLAG_SOUND))
|
||||
score += 3;
|
||||
break;
|
||||
case EFFECT_HEAL_BLOCK:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && predictedMove != MOVE_NONE && IsHealingMoveEffect(gBattleMoves[predictedMove].effect))
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER && predictedMove != MOVE_NONE && IsHealingMoveEffect(gBattleMoves[predictedMove].effect))
|
||||
score += 3; // Try to cancel healing move
|
||||
else if (HasHealingEffect(battlerDef) || AI_DATA->defHoldEffect == HOLD_EFFECT_LEFTOVERS
|
||||
|| (AI_DATA->defHoldEffect == HOLD_EFFECT_BLACK_SLUDGE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_POISON)))
|
||||
@ -4450,7 +4472,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
break;
|
||||
case EFFECT_QUASH:
|
||||
if (isDoubleBattle
|
||||
&& GetWhoStrikesFirst(AI_DATA->battlerAtkPartner, battlerDef, TRUE) == 1) // Attacker partner wouldn't go before target
|
||||
&& AI_WhoStrikesFirst(AI_DATA->battlerAtkPartner, battlerDef) == AI_IS_SLOWER) // Attacker partner wouldn't go before target
|
||||
score++;
|
||||
break;
|
||||
case EFFECT_TAILWIND:
|
||||
@ -4472,8 +4494,8 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (IsBattlerGrounded(battlerAtk) && HasDamagingMoveOfType(battlerDef, TYPE_ELECTRIC)
|
||||
&& !(AI_GetTypeEffectiveness(MOVE_EARTHQUAKE, battlerDef, battlerAtk) == AI_EFFECTIVENESS_x0)) // Doesn't resist ground move
|
||||
{
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first
|
||||
{
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker goes first
|
||||
{
|
||||
if (gBattleMoves[predictedMove].type == TYPE_GROUND)
|
||||
score += 3; // Cause the enemy's move to fail
|
||||
break;
|
||||
@ -4487,7 +4509,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
break;
|
||||
case EFFECT_CAMOUFLAGE:
|
||||
if (predictedMove != MOVE_NONE && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 // Attacker goes first
|
||||
if (predictedMove != MOVE_NONE && AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER // Attacker goes first
|
||||
&& !IS_MOVE_STATUS(move) && AI_GetTypeEffectiveness(predictedMove, battlerDef, battlerAtk) != AI_EFFECTIVENESS_x0)
|
||||
score++;
|
||||
break;
|
||||
@ -4530,7 +4552,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
break;
|
||||
case EFFECT_FLAIL:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Ai goes first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Ai goes first
|
||||
{
|
||||
if (GetHealthPercentage(battlerAtk) < 20)
|
||||
score++;
|
||||
@ -4572,7 +4594,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score += 2;
|
||||
break;
|
||||
case EFFECT_ENDEAVOR:
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // Opponent faster
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER) // Opponent faster
|
||||
{
|
||||
if (GetHealthPercentage(battlerAtk) < 40)
|
||||
score++;
|
||||
@ -4603,7 +4625,7 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
return score;
|
||||
|
||||
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING
|
||||
&& GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER
|
||||
&& CanTargetFaintAi(battlerDef, battlerAtk)
|
||||
&& GetMovePriority(battlerAtk, move) == 0)
|
||||
{
|
||||
@ -4923,7 +4945,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
}
|
||||
|
||||
// consider target HP
|
||||
if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
{
|
||||
score += 2;
|
||||
}
|
||||
|
@ -12,12 +12,14 @@
|
||||
#include "constants/item_effects.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/battle_ai.h"
|
||||
|
||||
// this file's functions
|
||||
static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
|
||||
static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent);
|
||||
static bool8 ShouldUseItem(void);
|
||||
|
||||
// Functions
|
||||
void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId)
|
||||
{
|
||||
if (BATTLE_TWO_VS_ONE_OPPONENT && (battlerId & BIT_SIDE) == B_SIDE_OPPONENT)
|
||||
@ -82,7 +84,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
|
||||
|
||||
opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler));
|
||||
|
||||
if (gBattleMons[GetBattlerAtPosition(opposingPosition)].ability != ABILITY_WONDER_GUARD)
|
||||
if (GetBattlerAbility(GetBattlerAtPosition(opposingPosition)) != ABILITY_WONDER_GUARD)
|
||||
return FALSE;
|
||||
|
||||
// Check if Pokemon has a super effective move.
|
||||
@ -176,7 +178,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility)
|
||||
if (AI_GetAbility(gActiveBattler) == absorbingTypeAbility)
|
||||
return FALSE;
|
||||
|
||||
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||
@ -228,7 +230,7 @@ static bool8 ShouldSwitchIfNaturalCure(void)
|
||||
{
|
||||
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].ability != ABILITY_NATURAL_CURE)
|
||||
if (AI_GetAbility(gActiveBattler) != ABILITY_NATURAL_CURE)
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2)
|
||||
return FALSE;
|
||||
@ -407,7 +409,6 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
|
||||
if (AI_GetTypeEffectiveness(move, gActiveBattler, battlerIn1) >= UQ_4_12(2.0) && Random() % moduloPercent == 0)
|
||||
{
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = i;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -436,6 +437,7 @@ bool32 ShouldSwitch(void)
|
||||
return FALSE;
|
||||
|
||||
availableToSwitch = 0;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
battlerIn1 = gActiveBattler;
|
||||
@ -564,6 +566,7 @@ void AI_TrySwitchOrUseItem(void)
|
||||
}
|
||||
}
|
||||
|
||||
// AI has decided it shouldn't switch or use an item, so it will now choose a move to use
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_USE_MOVE, (gActiveBattler ^ BIT_SIDE) << 8);
|
||||
}
|
||||
|
||||
@ -851,7 +854,8 @@ static bool8 ShouldUseItem(void)
|
||||
break;
|
||||
if (gBattleMons[gActiveBattler].hp == 0)
|
||||
break;
|
||||
if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 4 || gBattleMons[gActiveBattler].maxHP - gBattleMons[gActiveBattler].hp > itemEffects[paramOffset])
|
||||
if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 4
|
||||
|| gBattleMons[gActiveBattler].maxHP - gBattleMons[gActiveBattler].hp > itemEffects[paramOffset])
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case AI_ITEM_CURE_CONDITION:
|
||||
|
@ -439,6 +439,11 @@ static const u16 sOtherMoveCallingMoves[] =
|
||||
};
|
||||
|
||||
// Functions
|
||||
bool32 WillAIStrikeFirst(void)
|
||||
{
|
||||
return (AI_WhoStrikesFirst(sBattler_AI, gBattlerTarget) == AI_IS_FASTER);
|
||||
}
|
||||
|
||||
bool32 AI_RandLessThan(u8 val)
|
||||
{
|
||||
if ((Random() % 0xFF) < val)
|
||||
@ -632,7 +637,7 @@ bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler)
|
||||
u32 move = gBattleResources->battleHistory->usedMoves[opposingBattler][i];
|
||||
if (gBattleMoves[move].effect == EFFECT_PROTECT && move != MOVE_ENDURE)
|
||||
return TRUE;
|
||||
if (gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE && GetWhoStrikesFirst(battlerAI, opposingBattler, TRUE) == 1)
|
||||
if (gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE && AI_WhoStrikesFirst(battlerAI, opposingBattler) == AI_IS_SLOWER)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@ -660,9 +665,9 @@ bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE
|
||||
&& moves[i] != 0xFFFF
|
||||
&& GetBattleMoveSplit(moves[i]) == split
|
||||
&& !(unusable & gBitTable[i]))
|
||||
&& moves[i] != 0xFFFF
|
||||
&& GetBattleMoveSplit(moves[i]) == split
|
||||
&& !(unusable & gBitTable[i]))
|
||||
{
|
||||
SetTypeBeforeUsingMove(moves[i], attacker);
|
||||
GET_MOVE_TYPE(moves[i], moveType);
|
||||
@ -733,28 +738,45 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
else
|
||||
dmg = (critDmg + normalDmg * (critChance - 1)) / critChance;
|
||||
|
||||
// handle dynamic move damage
|
||||
// Handle dynamic move damage
|
||||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_LEVEL_DAMAGE:
|
||||
case EFFECT_PSYWAVE:
|
||||
//psywave's expected damage is equal to the user's level
|
||||
dmg = gBattleMons[battlerAtk].level;
|
||||
dmg = gBattleMons[battlerAtk].level * (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND ? 2 : 1);
|
||||
break;
|
||||
case EFFECT_DRAGON_RAGE:
|
||||
dmg = 40;
|
||||
dmg = 40 * (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND ? 2 : 1);
|
||||
break;
|
||||
case EFFECT_SONICBOOM:
|
||||
dmg = 20;
|
||||
dmg = 20 * (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND ? 2 : 1);
|
||||
break;
|
||||
//case EFFECT_METAL_BURST:
|
||||
//case EFFECT_COUNTER:
|
||||
default:
|
||||
//do not add the random factor, it's an average case analysis
|
||||
//dmg *= (100 - (Random() % 10)) / 100; // add random factor
|
||||
case EFFECT_MULTI_HIT:
|
||||
dmg *= (AI_DATA->atkAbility == ABILITY_SKILL_LINK ? 5 : 3);
|
||||
break;
|
||||
case EFFECT_TRIPLE_KICK:
|
||||
dmg *= (AI_DATA->atkAbility == ABILITY_SKILL_LINK ? 6 : 5);
|
||||
break;
|
||||
case EFFECT_ENDEAVOR:
|
||||
// If target has less HP than user, Endeavor does no damage
|
||||
dmg = max(0, gBattleMons[battlerDef].hp - gBattleMons[battlerAtk].hp);
|
||||
break;
|
||||
case EFFECT_SUPER_FANG:
|
||||
dmg = (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND
|
||||
? max(2, gBattleMons[battlerDef].hp * 3 / 4)
|
||||
: max(1, gBattleMons[battlerDef].hp / 2));
|
||||
break;
|
||||
case EFFECT_FINAL_GAMBIT:
|
||||
dmg = gBattleMons[battlerAtk].hp;
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle other multi-strike moves
|
||||
if (gBattleMoves[move].flags & FLAG_TWO_STRIKES)
|
||||
dmg *= 2;
|
||||
else if (move == MOVE_SURGING_STRIKES || (move == MOVE_WATER_SHURIKEN && gBattleMons[battlerAtk].species == SPECIES_GRENINJA_ASH))
|
||||
dmg *= 3;
|
||||
|
||||
RestoreBattlerData(battlerAtk);
|
||||
RestoreBattlerData(battlerDef);
|
||||
|
||||
@ -964,48 +986,43 @@ u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
return damageVar;
|
||||
}
|
||||
|
||||
// AI_CHECK_FASTER: is user(ai) faster
|
||||
// AI_CHECK_SLOWER: is target faster
|
||||
bool32 IsAiFaster(u8 battler)
|
||||
/* Checks to see if AI will move ahead of another battler
|
||||
* Output:
|
||||
* AI_IS_FASTER: is user(ai) faster
|
||||
* AI_IS_SLOWER: is target faster
|
||||
*/
|
||||
u8 AI_WhoStrikesFirst(u8 battlerAI, u8 battler2)
|
||||
{
|
||||
u32 fasterAI = 0, fasterPlayer = 0, i;
|
||||
s8 prioAI, prioPlayer;
|
||||
s8 prioAI = 0;
|
||||
s8 prioPlayer = 0;
|
||||
|
||||
// Check move priorities first.
|
||||
prioAI = GetMovePriority(sBattler_AI, AI_THINKING_STRUCT->moveConsidered);
|
||||
SaveBattlerData(gBattlerTarget);
|
||||
SetBattlerData(gBattlerTarget);
|
||||
prioAI = GetMovePriority(battlerAI, AI_THINKING_STRUCT->moveConsidered);
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].moves[i] == 0 || gBattleMons[gBattlerTarget].moves[i] == 0xFFFF)
|
||||
if (gBattleMons[battler2].moves[i] == 0 || gBattleMons[battler2].moves[i] == 0xFFFF)
|
||||
continue;
|
||||
|
||||
prioPlayer = GetMovePriority(gBattlerTarget, gBattleMons[gBattlerTarget].moves[i]);
|
||||
prioPlayer = GetMovePriority(battler2, gBattleMons[battler2].moves[i]);
|
||||
if (prioAI > prioPlayer)
|
||||
fasterAI++;
|
||||
else if (prioPlayer > prioAI)
|
||||
fasterPlayer++;
|
||||
}
|
||||
RestoreBattlerData(gBattlerTarget);
|
||||
|
||||
if (fasterAI > fasterPlayer)
|
||||
{
|
||||
if (battler == 0) // is user (ai) faster
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
return AI_IS_FASTER;
|
||||
}
|
||||
else if (fasterAI < fasterPlayer)
|
||||
{
|
||||
if (battler == 1) // is target (player) faster
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
return AI_IS_SLOWER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Priorities are the same(at least comparing to moves the AI is aware of), decide by speed.
|
||||
if (GetWhoStrikesFirst(sBattler_AI, gBattlerTarget, TRUE) == battler)
|
||||
if (GetWhoStrikesFirst(battlerAI, battler2, TRUE) == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@ -1016,7 +1033,7 @@ bool32 IsAiFaster(u8 battler)
|
||||
bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk)
|
||||
{
|
||||
s32 i, dmg;
|
||||
u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP);
|
||||
u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF);
|
||||
u16 *moves = gBattleResources->battleHistory->usedMoves[battlerDef];
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
@ -1031,10 +1048,36 @@ bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check if AI mon has the means to faint the target with any of its moves.
|
||||
// If numHits > 1, check if the target will be KO'ed by that number of hits (ignoring healing effects)
|
||||
bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits)
|
||||
{
|
||||
s32 i, dmg;
|
||||
u32 moveLimitations = CheckMoveLimitations(battlerAtk, 0, 0xFF);
|
||||
u16 *moves = gBattleMons[battlerAtk].moves;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && !(moveLimitations & gBitTable[i]))
|
||||
{
|
||||
// Use the pre-calculated value in simulatedDmg instead of re-calculating it
|
||||
dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][i];
|
||||
|
||||
if (numHits)
|
||||
dmg *= numHits;
|
||||
|
||||
if (gBattleMons[battlerDef].hp <= dmg)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits)
|
||||
{
|
||||
s32 i, dmg;
|
||||
u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP);
|
||||
u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF);
|
||||
|
||||
if (move != MOVE_NONE && move != 0xFFFF && !(unusable & gBitTable[i]) && AI_CalcDamage(move, battlerDef, battlerAtk) >= gBattleMons[battlerAtk].hp)
|
||||
return TRUE;
|
||||
@ -1046,13 +1089,17 @@ bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits)
|
||||
bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod)
|
||||
{
|
||||
u32 i;
|
||||
u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP);
|
||||
u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF);
|
||||
s32 dmg;
|
||||
u16 *moves = gBattleResources->battleHistory->usedMoves[battlerDef];
|
||||
u32 hpCheck = gBattleMons[battlerAtk].hp + hpMod;
|
||||
|
||||
if (hpCheck > gBattleMons[battlerAtk].maxHP)
|
||||
hpCheck = gBattleMons[battlerAtk].maxHP;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
u32 dmg = AI_CalcDamage(moves[i], battlerDef, battlerAtk);
|
||||
u32 hpCheck = gBattleMons[battlerAtk].hp + hpMod;
|
||||
dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][i];
|
||||
if (dmgMod)
|
||||
dmg *= dmgMod;
|
||||
|
||||
@ -1065,34 +1112,48 @@ bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgM
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability)
|
||||
{
|
||||
if (IsBattlerAlive(battlerId) && AI_GetAbility(battlerId) == ability)
|
||||
return TRUE;
|
||||
else if (IsBattlerAlive(BATTLE_PARTNER(battlerId)) && AI_GetAbility(BATTLE_PARTNER(battlerId)) == ability)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// does NOT include ability suppression checks
|
||||
s32 AI_GetAbility(u32 battlerId)
|
||||
{
|
||||
u32 knownAbility = GetBattlerAbility(battlerId);
|
||||
|
||||
// The AI knows its own ability.
|
||||
if (IsBattlerAIControlled(battlerId))
|
||||
return gBattleMons[battlerId].ability;
|
||||
return knownAbility;
|
||||
|
||||
// Check neutralizing gas, gastro acid
|
||||
if (knownAbility == ABILITY_NONE)
|
||||
return knownAbility;
|
||||
|
||||
if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE)
|
||||
return BATTLE_HISTORY->abilities[battlerId];
|
||||
|
||||
// Abilities that prevent fleeing.
|
||||
if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG
|
||||
|| gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL
|
||||
|| gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP)
|
||||
return gBattleMons[battlerId].ability;
|
||||
// Abilities that prevent fleeing - treat as always known
|
||||
if (knownAbility == ABILITY_SHADOW_TAG || knownAbility == ABILITY_MAGNET_PULL || knownAbility == ABILITY_ARENA_TRAP)
|
||||
return knownAbility;
|
||||
|
||||
// Else, guess the ability
|
||||
if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE)
|
||||
{
|
||||
if (gBaseStats[gBattleMons[battlerId].species].abilities[1] != ABILITY_NONE)
|
||||
u16 abilityGuess = ABILITY_NONE;
|
||||
while (abilityGuess == ABILITY_NONE)
|
||||
{
|
||||
// AI has no knowledge of opponent, so it guesses which ability.
|
||||
return gBaseStats[gBattleMons[battlerId].species].abilities[Random() & 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return gBaseStats[gBattleMons[battlerId].species].abilities[0]; // It's definitely ability 1.
|
||||
abilityGuess = gBaseStats[gBattleMons[battlerId].species].abilities[Random() % NUM_ABILITY_SLOTS];
|
||||
}
|
||||
|
||||
return abilityGuess;
|
||||
}
|
||||
|
||||
return ABILITY_NONE; // Unknown.
|
||||
}
|
||||
|
||||
@ -1650,7 +1711,7 @@ u32 CountNegativeStatStages(u8 battlerId)
|
||||
|
||||
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_ATK] > 4
|
||||
@ -1658,7 +1719,7 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
//&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_HYPER_CUTTER)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -1666,7 +1727,7 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
|
||||
bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4
|
||||
@ -1674,7 +1735,7 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
//&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_BIG_PECKS)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -1682,13 +1743,13 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
|
||||
bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (IsAiFaster(AI_CHECK_SLOWER)
|
||||
if (!WillAIStrikeFirst()
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
//&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -1696,14 +1757,14 @@ bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
|
||||
bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 4
|
||||
&& HasMoveWithSplit(battlerDef, SPLIT_SPECIAL)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
//&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -1711,14 +1772,14 @@ bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
|
||||
bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_SPDEF] > 4
|
||||
&& HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
//&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -1726,13 +1787,13 @@ bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
|
||||
bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
//&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_KEEN_EYE)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -1740,19 +1801,19 @@ bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
|
||||
bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
{
|
||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
if (WillAIStrikeFirst() && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return FALSE; // Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
//&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_FULL_METAL_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits)
|
||||
bool32 CanIndexMoveFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits)
|
||||
{
|
||||
s32 dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][index];
|
||||
|
||||
@ -2355,9 +2416,19 @@ static bool32 AnyUsefulStatIsRaised(u8 battler)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct Pokemon *GetPartyBattlerPartyData(u8 battlerId, u8 switchBattler)
|
||||
{
|
||||
struct Pokemon *mon;
|
||||
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
||||
mon = &gPlayerParty[switchBattler];
|
||||
else
|
||||
mon = &gEnemyParty[switchBattler];
|
||||
return mon;
|
||||
}
|
||||
|
||||
static bool32 PartyBattlerShouldAvoidHazards(u8 currBattler, u8 switchBattler)
|
||||
{
|
||||
struct Pokemon *mon = GetBattlerPartyData(switchBattler);
|
||||
struct Pokemon *mon = GetPartyBattlerPartyData(currBattler, switchBattler);
|
||||
u16 ability = GetMonAbility(mon); // we know our own party data
|
||||
u16 holdEffect = GetBattlerHoldEffect(GetMonData(mon, MON_DATA_HELD_ITEM), TRUE);
|
||||
u32 flags = gSideStatuses[GetBattlerSide(currBattler)] & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES);
|
||||
@ -2404,11 +2475,11 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo
|
||||
/*if (IsPredictedToSwitch(battlerDef, battlerAtk) && !hasStatBoost)
|
||||
return PIVOT; // Try pivoting so you can switch to a better matchup to counter your new opponent*/
|
||||
|
||||
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER) // Attacker goes first
|
||||
{
|
||||
if (!CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) // Can't KO foe otherwise
|
||||
if (!CanAIFaintTarget(battlerAtk, battlerDef, 0)) // Can't KO foe otherwise
|
||||
{
|
||||
if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 2))
|
||||
if (CanAIFaintTarget(battlerAtk, battlerDef, 2))
|
||||
{
|
||||
// attacker can kill target in two hits (theoretically)
|
||||
if (CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
@ -2473,7 +2544,7 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo
|
||||
}
|
||||
else if (CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 2)) // Foe can 2HKO AI
|
||||
{
|
||||
if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0))
|
||||
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
{
|
||||
if (!BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility))
|
||||
return CAN_TRY_PIVOT; // Use this move to KO if you must
|
||||
@ -2485,7 +2556,7 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo
|
||||
}
|
||||
else // Foe can 3HKO+ AI
|
||||
{
|
||||
if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0))
|
||||
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
{
|
||||
if (!BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility) // This is the only move that can KO
|
||||
&& !hasStatBoost) //You're not wasting a valuable stat boost
|
||||
@ -2493,7 +2564,7 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo
|
||||
return CAN_TRY_PIVOT;
|
||||
}
|
||||
}
|
||||
else if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 2))
|
||||
else if (CanAIFaintTarget(battlerAtk, battlerDef, 2))
|
||||
{
|
||||
// can knock out foe in 2 hits
|
||||
if (IS_MOVE_STATUS(move) && (shouldSwitch //Damaging move
|
||||
@ -2606,27 +2677,38 @@ bool32 AI_CanSleep(u8 battler, u16 ability)
|
||||
bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanSleep(battlerDef, defAbility)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 AI_CanBePoisoned(u8 battler, u16 ability)
|
||||
static bool32 AI_CanPoisonType(u8 battlerAttacker, u8 battlerTarget)
|
||||
{
|
||||
if (ability == ABILITY_IMMUNITY
|
||||
|| IsAbilityOnSide(battler, ABILITY_PASTEL_VEIL)
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD)
|
||||
return ((AI_GetAbility(battlerAttacker) == ABILITY_CORROSION && gBattleMoves[gCurrentMove].split == SPLIT_STATUS)
|
||||
|| !(IS_BATTLER_OF_TYPE(battlerTarget, TYPE_POISON) || IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL)));
|
||||
}
|
||||
|
||||
static bool32 AI_CanBePoisoned(u8 battlerAtk, u8 battlerDef)
|
||||
{
|
||||
u16 ability = AI_GetAbility(battlerDef);
|
||||
|
||||
if (!(AI_CanPoisonType(battlerAtk, battlerDef))
|
||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|
||||
|| ability == ABILITY_IMMUNITY
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| AI_IsAbilityOnSide(battlerDef, ABILITY_PASTEL_VEIL)
|
||||
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battlerDef)
|
||||
|| AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 ShouldPoisonSelf(u8 battler, u16 ability)
|
||||
{
|
||||
if (AI_CanBePoisoned(battler, ability) && (
|
||||
if (AI_CanBePoisoned(battler, battler) && (
|
||||
ability == ABILITY_MARVEL_SCALE
|
||||
|| ability == ABILITY_POISON_HEAL
|
||||
|| ability == ABILITY_QUICK_FEET
|
||||
@ -2641,7 +2723,7 @@ bool32 ShouldPoisonSelf(u8 battler, u16 ability)
|
||||
|
||||
bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!AI_CanBePoisoned(battlerDef, defAbility)
|
||||
if (!AI_CanBePoisoned(battlerAtk, battlerDef)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
|
||||
@ -2654,7 +2736,7 @@ bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool32 CanBeParayzed(u8 battler, u16 ability)
|
||||
static bool32 AI_CanBeParalyzed(u8 battler, u16 ability)
|
||||
{
|
||||
if (ability == ABILITY_LIMBER
|
||||
|| IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC)
|
||||
@ -2666,7 +2748,7 @@ static bool32 CanBeParayzed(u8 battler, u16 ability)
|
||||
|
||||
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!CanBeParayzed(battlerDef, defAbility)
|
||||
if (!AI_CanBeParalyzed(battlerDef, defAbility)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
@ -2744,7 +2826,7 @@ bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGe
|
||||
|| atkGender == defGender
|
||||
|| atkGender == MON_GENDERLESS
|
||||
|| defGender == MON_GENDERLESS
|
||||
|| IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL))
|
||||
|| AI_IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
@ -2753,7 +2835,7 @@ u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbili
|
||||
{
|
||||
if (defAbility == ABILITY_INNER_FOCUS
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // opponent goes first
|
||||
|| AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_SLOWER) // Opponent goes first
|
||||
{
|
||||
return 0; // don't try to flinch
|
||||
}
|
||||
@ -2866,7 +2948,7 @@ bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveI
|
||||
if (recoilDmg >= gBattleMons[battlerAtk].hp //Recoil kills attacker
|
||||
&& CountUsablePartyMons(battlerDef) != 0) //Foe has more than 1 target left
|
||||
{
|
||||
if (recoilDmg >= gBattleMons[battlerDef].hp && !CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0))
|
||||
if (recoilDmg >= gBattleMons[battlerDef].hp && !CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return TRUE; //If it's the only KO move then just use it
|
||||
else
|
||||
return FALSE; //Not as good to use move if you'll faint and not win
|
||||
@ -2877,7 +2959,7 @@ bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveI
|
||||
|
||||
bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage)
|
||||
{
|
||||
if (move == 0xFFFF || GetWhoStrikesFirst(battlerAtk, gBattlerTarget, TRUE) == 0)
|
||||
if (move == 0xFFFF || AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER)
|
||||
{
|
||||
// using item or user goes first
|
||||
u8 healPercent = (gBattleMoves[move].argument == 0) ? 50 : gBattleMoves[move].argument;
|
||||
@ -2904,7 +2986,7 @@ bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage)
|
||||
|
||||
bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent)
|
||||
{
|
||||
if (move == 0xFFFF || GetWhoStrikesFirst(battlerAtk, gBattlerTarget, TRUE) == 0)
|
||||
if (move == 0xFFFF || AI_WhoStrikesFirst(battlerAtk, battlerDef) == AI_IS_FASTER)
|
||||
{
|
||||
// using item or user going first
|
||||
s32 damage = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex];
|
||||
@ -3304,6 +3386,47 @@ static const u16 sRecycleEncouragedItems[] =
|
||||
// TODO expand this
|
||||
};
|
||||
|
||||
// Its assumed that the berry is strategically given, so no need to check benefits of the berry
|
||||
bool32 IsStatBoostingBerry(u16 item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case ITEM_LIECHI_BERRY:
|
||||
case ITEM_GANLON_BERRY:
|
||||
case ITEM_SALAC_BERRY:
|
||||
case ITEM_PETAYA_BERRY:
|
||||
case ITEM_APICOT_BERRY:
|
||||
//case ITEM_LANSAT_BERRY:
|
||||
case ITEM_STARF_BERRY:
|
||||
#ifdef ITEM_EXPANSION
|
||||
case ITEM_MICLE_BERRY:
|
||||
#endif
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 ShouldRestoreHpBerry(u8 battlerAtk, u16 item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case ITEM_ORAN_BERRY:
|
||||
if (gBattleMons[battlerAtk].maxHP <= 50)
|
||||
return TRUE; // Only worth it in the early game
|
||||
return FALSE;
|
||||
case ITEM_SITRUS_BERRY:
|
||||
case ITEM_FIGY_BERRY:
|
||||
case ITEM_WIKI_BERRY:
|
||||
case ITEM_MAGO_BERRY:
|
||||
case ITEM_AGUAV_BERRY:
|
||||
case ITEM_IAPAPA_BERRY:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 IsRecycleEncouragedItem(u16 item)
|
||||
{
|
||||
u32 i;
|
||||
@ -3325,6 +3448,9 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
|
||||
|
||||
if (GetHealthPercentage(battlerAtk) < 80 && AI_RandLessThan(128))
|
||||
return;
|
||||
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return; // Damaging moves would get a score boost from AI_TryToFaint or PreferStrongestMove so we don't consider them here
|
||||
|
||||
switch (statId)
|
||||
{
|
||||
@ -3350,7 +3476,7 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
|
||||
}
|
||||
break;
|
||||
case STAT_SPEED:
|
||||
if (IsAiFaster(AI_CHECK_SLOWER))
|
||||
if (!WillAIStrikeFirst())
|
||||
{
|
||||
if (gBattleMons[battlerAtk].statStages[STAT_SPEED] < STAT_UP_2_STAGE)
|
||||
*score += 2;
|
||||
@ -3397,6 +3523,9 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
|
||||
|
||||
void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return;
|
||||
|
||||
if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove) && GetHealthPercentage(battlerDef) > 20)
|
||||
{
|
||||
if (!HasDamagingMove(battlerDef))
|
||||
@ -3417,6 +3546,9 @@ void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return;
|
||||
|
||||
if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove))
|
||||
{
|
||||
(*score)++; // burning is good
|
||||
@ -3433,6 +3565,9 @@ void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return;
|
||||
|
||||
if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove))
|
||||
{
|
||||
u8 atkSpeed = GetBattlerTotalSpeedStat(battlerAtk);
|
||||
@ -3451,6 +3586,9 @@ void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return;
|
||||
|
||||
if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove))
|
||||
*score += 2;
|
||||
else
|
||||
@ -3466,6 +3604,9 @@ void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
return;
|
||||
|
||||
if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)
|
||||
&& AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_CONFUSION
|
||||
&& AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_STATUS)
|
||||
@ -3478,3 +3619,12 @@ void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
*score += 2;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move)
|
||||
{
|
||||
if (TestMoveFlags(move, FLAG_MAKES_CONTACT)
|
||||
&& ability != ABILITY_LONG_REACH
|
||||
&& holdEffect != HOLD_EFFECT_PROTECTIVE_PADS)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -2052,14 +2052,14 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
|
||||
[BG_SOLARBEAM_CONTESTS] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_Solarbeam, gBattleAnimBgTilemap_ImpactContests},
|
||||
//new bgs
|
||||
[BG_MAGMA_STORM] = {gBattleAnimBgImage_InAir, gBattleAnimBgPalette_MagmaStorm, gBattleAnimBgTilemap_InAir},
|
||||
[BG_GIGA_IMPACT_OPPONENT] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactOpponent},
|
||||
[BG_GIGA_IMPACT_PLAYER] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactPlayer},
|
||||
[BG_GIGA_IMPACT_CONTEST] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactContests},
|
||||
[BG_GIGA_IMPACT_OPPONENT] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactOpponent},
|
||||
[BG_GIGA_IMPACT_PLAYER] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactPlayer},
|
||||
[BG_GIGA_IMPACT_CONTEST] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactContest},
|
||||
[BG_TRICK_ROOM] = {gBattleAnimBgImage_TrickRoom, gBattleAnimBgPalette_TrickRoom, gBattleAnimBgTilemap_TrickRoom},
|
||||
[BG_ROCK_WRECKER] = {gBattleAnimBgImage_Hurricane, gBattleAnimBgPalette_RockWrecker, gBattleAnimBgTilemap_Hurricane},
|
||||
[BG_SPACIAL_REND_ON_OPPONENT] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_SpacialRendOpponent},
|
||||
[BG_SPACIAL_REND_ON_PLAYER] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_SpacialRendPlayer},
|
||||
[BG_DARK_VOID] = {gBattleAnimBgImage_DarkVoid, gBattleAnimBgPalette_DarkVoid, gBattleAnimBgTilemap_DarkVoid},
|
||||
[BG_SPACIAL_REND_ON_OPPONENT] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_GigaImpactOpponent},
|
||||
[BG_SPACIAL_REND_ON_PLAYER] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_GigaImpactPlayer},
|
||||
[BG_DARK_VOID] = {gBattleAnimBgImage_Waterfall, gBattleAnimBgPalette_DarkVoid, gBattleAnimBgTilemap_DarkVoid},
|
||||
[BG_WATER] = {gBattleAnimBgImage_HydroPump, gBattleAnimBgPalette_HydroPump, gBattleAnimBgTilemap_HydroPump},
|
||||
[BG_NIGHTMARE] = {gBattleAnimBgImage_Nightmare, gBattleAnimBgPalette_Nightmare, gBattleAnimBgTilemap_Nightmare},
|
||||
[BG_LEAF_STORM] = {gBattleAnimBgImage_LeafStorm, gBattleAnimBgPalette_LeafStorm, gBattleAnimBgTilemap_LeafStorm},
|
||||
|
@ -5064,3 +5064,34 @@ void AnimTask_PrimalReversion(u8 taskId)
|
||||
gBattleAnimArgs[0] = 0;
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
||||
void AnimTask_ShellSideArm(u8 taskId)
|
||||
{
|
||||
if (gSwapDamageCategory)
|
||||
gBattleAnimArgs[0] = TRUE;
|
||||
else
|
||||
gBattleAnimArgs[0] = FALSE;
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
||||
void AnimTask_TerrainPulse(u8 taskId)
|
||||
{
|
||||
if (IsBattlerTerrainAffected(gBattleAnimAttacker, STATUS_FIELD_TERRAIN_ANY))
|
||||
{
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
|
||||
gBattleAnimArgs[0] = TYPE_ELECTRIC;
|
||||
else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN)
|
||||
gBattleAnimArgs[0] = TYPE_GRASS;
|
||||
else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)
|
||||
gBattleAnimArgs[0] = TYPE_FAIRY;
|
||||
else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN)
|
||||
gBattleAnimArgs[0] = TYPE_PSYCHIC;
|
||||
else //failsafe
|
||||
gBattleAnimArgs[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleAnimArgs[0] = 0;
|
||||
}
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
@ -2496,6 +2496,8 @@ void AnimTask_GetTrappedMoveAnimId(u8 taskId)
|
||||
gBattleAnimArgs[0] = TRAP_ANIM_CLAMP;
|
||||
else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_SAND_TOMB)
|
||||
gBattleAnimArgs[0] = TRAP_ANIM_SAND_TOMB;
|
||||
else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_MAGMA_STORM)
|
||||
gBattleAnimArgs[0] = TRAP_ANIM_MAGMA_STORM;
|
||||
else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_INFESTATION)
|
||||
gBattleAnimArgs[0] = TRAP_ANIM_INFESTATION;
|
||||
else
|
||||
|
@ -136,6 +136,7 @@ void AnimTask_SetCamouflageBlend(u8 taskId)
|
||||
gBattleAnimArgs[4] = RGB(31, 31, 31);
|
||||
break;
|
||||
case BATTLE_TERRAIN_PLAIN:
|
||||
default:
|
||||
gBattleAnimArgs[4] = RGB(31, 31, 31);
|
||||
break;
|
||||
}
|
||||
@ -904,6 +905,12 @@ void AnimTask_GetBattleTerrain(u8 taskId)
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
||||
void AnimTask_GetFieldTerrain(u8 taskId)
|
||||
{
|
||||
gBattleAnimArgs[0] = gFieldStatuses & STATUS_FIELD_TERRAIN_ANY;
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
||||
void AnimTask_AllocBackupPalBuffer(u8 taskId)
|
||||
{
|
||||
gMonSpritesGfxPtr->buffer = AllocZeroed(0x2000);
|
||||
|
@ -1545,7 +1545,7 @@ static void OpponentHandlePrintSelectionString(void)
|
||||
|
||||
static void OpponentHandleChooseAction(void)
|
||||
{
|
||||
AI_TrySwitchOrUseItem();
|
||||
AI_TrySwitchOrUseItem(); // TODO consider move choice first
|
||||
OpponentBufferExecCompleted();
|
||||
}
|
||||
|
||||
@ -1565,12 +1565,12 @@ static void OpponentHandleChooseMove(void)
|
||||
{
|
||||
u8 chosenMoveId;
|
||||
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]);
|
||||
|
||||
|
||||
if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER))
|
||||
{
|
||||
BattleAI_SetupAIData(0xF);
|
||||
chosenMoveId = BattleAI_ChooseMoveOrAction();
|
||||
|
||||
|
||||
switch (chosenMoveId)
|
||||
{
|
||||
case AI_CHOICE_WATCH:
|
||||
@ -1594,15 +1594,18 @@ static void OpponentHandleChooseMove(void)
|
||||
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
||||
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
||||
}
|
||||
if (CanMegaEvolve(gActiveBattler)) // If opponent can mega evolve, do it.
|
||||
|
||||
// If opponent can mega evolve, do it.
|
||||
if (CanMegaEvolve(gActiveBattler))
|
||||
BtlController_EmitTwoReturnValues(1, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
|
||||
else
|
||||
BtlController_EmitTwoReturnValues(1, 10, (chosenMoveId) | (gBattlerTarget << 8));
|
||||
break;
|
||||
}
|
||||
|
||||
OpponentBufferExecCompleted();
|
||||
}
|
||||
else
|
||||
else // Wild pokemon - use random move
|
||||
{
|
||||
u16 move;
|
||||
do
|
||||
|
@ -1539,6 +1539,7 @@ static void PlayerPartnerHandleChooseMove(void)
|
||||
BtlController_EmitTwoReturnValues(1, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
|
||||
else
|
||||
BtlController_EmitTwoReturnValues(1, 10, (chosenMoveId) | (gBattlerTarget << 8));
|
||||
|
||||
PlayerPartnerBufferExecCompleted();
|
||||
}
|
||||
|
||||
|
@ -1924,12 +1924,20 @@ static const u8 sText_HoldEffectPsychicPower[] = _("Psychic Power");
|
||||
static const u8 sText_HoldEffectFirePower[] = _("Fire Power");
|
||||
static const u8 sText_HoldEffectDragonPower[] = _("Dragon Power");
|
||||
static const u8 sText_HoldEffectNormalPower[] = _("Normal Power");
|
||||
static const u8 sText_HoldEffectUpGrade[] = _("Up Grade");
|
||||
#ifdef ITEM_EXPANSION
|
||||
static const u8 sText_HoldEffectUpgrade[] = _("Upgrade");
|
||||
#else
|
||||
static const u8 sText_HoldEffectUpgrade[] = _("Up Grade");
|
||||
#endif
|
||||
static const u8 sText_HoldEffectShellBell[] = _("Shell Bell");
|
||||
static const u8 sText_HoldEffectLuckyPunch[] = _("Lucky Punch");
|
||||
static const u8 sText_HoldEffectMetalPowder[] = _("Metal Powder");
|
||||
static const u8 sText_HoldEffectThickClub[] = _("Thick Club");
|
||||
static const u8 sText_HoldEffectStick[] = _("Stick");
|
||||
#ifdef ITEM_EXPANSION
|
||||
static const u8 sText_HoldEffectLeek[] = _("Leek");
|
||||
#else
|
||||
static const u8 sText_HoldEffectLeek[] = _("Stick");
|
||||
#endif
|
||||
static const u8 sText_HoldEffectChoiceScarf[] = _("Choice Scarf");
|
||||
static const u8 sText_HoldEffectChoiceSpecs[] = _("Choice Specs");
|
||||
static const u8 sText_HoldEffectDampRock[] = _("Damp Rock");
|
||||
@ -2064,12 +2072,12 @@ static const u8 *const sHoldEffectNames[] =
|
||||
[HOLD_EFFECT_FIRE_POWER] = sText_HoldEffectFirePower,
|
||||
[HOLD_EFFECT_DRAGON_POWER] = sText_HoldEffectDragonPower,
|
||||
[HOLD_EFFECT_NORMAL_POWER] = sText_HoldEffectNormalPower,
|
||||
[HOLD_EFFECT_UP_GRADE] = sText_HoldEffectUpGrade,
|
||||
[HOLD_EFFECT_UPGRADE] = sText_HoldEffectUpgrade,
|
||||
[HOLD_EFFECT_SHELL_BELL] = sText_HoldEffectShellBell,
|
||||
[HOLD_EFFECT_LUCKY_PUNCH] = sText_HoldEffectLuckyPunch,
|
||||
[HOLD_EFFECT_METAL_POWDER] = sText_HoldEffectMetalPowder,
|
||||
[HOLD_EFFECT_THICK_CLUB] = sText_HoldEffectThickClub,
|
||||
[HOLD_EFFECT_STICK] = sText_HoldEffectStick,
|
||||
[HOLD_EFFECT_LEEK] = sText_HoldEffectLeek,
|
||||
[HOLD_EFFECT_CHOICE_SCARF] = sText_HoldEffectChoiceScarf,
|
||||
[HOLD_EFFECT_CHOICE_SPECS] = sText_HoldEffectChoiceSpecs,
|
||||
[HOLD_EFFECT_DAMP_ROCK] = sText_HoldEffectDampRock,
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "trig.h"
|
||||
#include "tv.h"
|
||||
#include "util.h"
|
||||
#include "wild_encounter.h"
|
||||
#include "window.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "constants/battle_config.h"
|
||||
@ -103,6 +104,7 @@ static void RunTurnActionsFunctions(void);
|
||||
static void SetActionsAndBattlersTurnOrder(void);
|
||||
static void sub_803CDF8(void);
|
||||
static bool8 AllAtActionConfirmed(void);
|
||||
static void TryChangeTurnOrder(void);
|
||||
static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void);
|
||||
static void CheckMegaEvolutionBeforeTurn(void);
|
||||
static void CheckQuickClaw_CustapBerryActivation(void);
|
||||
@ -232,6 +234,7 @@ EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0};
|
||||
EWRAM_DATA bool8 gHasFetchedBall = FALSE;
|
||||
EWRAM_DATA u8 gLastUsedBall = 0;
|
||||
EWRAM_DATA u16 gLastThrownBall = 0;
|
||||
EWRAM_DATA bool8 gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
|
||||
// IWRAM common vars
|
||||
void (*gPreBattleCallback1)(void);
|
||||
@ -2941,6 +2944,8 @@ static void BattleStartClearSetData(void)
|
||||
gBattleStruct->usedHeldItems[i][1] = 0;
|
||||
gBattleStruct->itemStolen[i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
|
||||
}
|
||||
|
||||
gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
}
|
||||
|
||||
void SwitchInClearSetData(void)
|
||||
@ -3544,7 +3549,11 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check neutralizing gas
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, 0, 0, 0, 0) != 0)
|
||||
return;
|
||||
|
||||
// Check all switch in abilities happening from the fastest mon to slowest.
|
||||
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
|
||||
{
|
||||
@ -3883,7 +3892,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
gBattleMons[gActiveBattler].ppBonuses,
|
||||
i);
|
||||
}
|
||||
|
||||
|
||||
BtlController_EmitChooseMove(0, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, &moveInfo);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
}
|
||||
@ -4680,10 +4689,37 @@ static void CheckMegaEvolutionBeforeTurn(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if B_MEGA_EVO_TURN_ORDER <= GEN_6
|
||||
gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts;
|
||||
gBattleStruct->focusPunchBattlerId = 0;
|
||||
#else
|
||||
gBattleMainFunc = TryChangeTurnOrder; // This will just do nothing if no mon has mega evolved
|
||||
#endif
|
||||
}
|
||||
|
||||
// In gen7, priority and speed are recalculated during the turn in which a pokemon mega evolves
|
||||
static void TryChangeTurnOrder(void)
|
||||
{
|
||||
s32 i, j;
|
||||
for (i = 0; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
u8 battler1 = gBattlerByTurnOrder[i];
|
||||
u8 battler2 = gBattlerByTurnOrder[j];
|
||||
if (gActionsByTurnOrder[i] == B_ACTION_USE_MOVE
|
||||
&& gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)
|
||||
{
|
||||
if (GetWhoStrikesFirst(battler1, battler2, FALSE))
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts;
|
||||
gBattleStruct->focusPunchBattlerId = 0;
|
||||
}
|
||||
|
||||
|
||||
static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void)
|
||||
{
|
||||
u32 i;
|
||||
@ -5018,6 +5054,8 @@ static void FreeResetData_ReturnToOvOrDoEvolutions(void)
|
||||
{
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
gIsFishingEncounter = FALSE;
|
||||
gIsSurfingEncounter = FALSE;
|
||||
ResetSpriteData();
|
||||
if (gLeveledUpInBattle && (gBattleOutcome == B_OUTCOME_WON || gBattleOutcome == B_OUTCOME_CAUGHT))
|
||||
{
|
||||
@ -5189,6 +5227,22 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
|
||||
if (ItemId_GetPocket(gBattleMons[battlerAtk].item) == POCKET_BERRIES)
|
||||
gBattleStruct->dynamicMoveType = gNaturalGiftTable[ITEM_TO_BERRY(gBattleMons[battlerAtk].item)].type;
|
||||
}
|
||||
else if (gBattleMoves[move].effect == EFFECT_TERRAIN_PULSE)
|
||||
{
|
||||
if (IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_TERRAIN_ANY))
|
||||
{
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
|
||||
gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | 0x80;
|
||||
else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN)
|
||||
gBattleStruct->dynamicMoveType = TYPE_GRASS | 0x80;
|
||||
else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)
|
||||
gBattleStruct->dynamicMoveType = TYPE_FAIRY | 0x80;
|
||||
else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN)
|
||||
gBattleStruct->dynamicMoveType = TYPE_PSYCHIC | 0x80;
|
||||
else //failsafe
|
||||
gBattleStruct->dynamicMoveType = TYPE_NORMAL | 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
attackerAbility = GetBattlerAbility(battlerAtk);
|
||||
GET_MOVE_TYPE(move, moveType);
|
||||
@ -5229,6 +5283,10 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
|
||||
{
|
||||
gBattleStruct->dynamicMoveType = 0x80 | TYPE_ELECTRIC;
|
||||
}
|
||||
else if (move == MOVE_AURA_WHEEL && gBattleMons[battlerAtk].species == SPECIES_MORPEKO_HANGRY)
|
||||
{
|
||||
gBattleStruct->dynamicMoveType = 0x80 | TYPE_DARK;
|
||||
}
|
||||
|
||||
// Check if a gem should activate.
|
||||
GET_MOVE_TYPE(move, moveType);
|
||||
|
@ -549,7 +549,7 @@ static const u8 sText_BecameNimble[] =_("{B_ATK_NAME_WITH_PREFIX} became nimble!
|
||||
static const u8 sText_HurledIntoTheAir[] =_("{B_DEF_NAME_WITH_PREFIX} was hurled\ninto the air!");
|
||||
static const u8 sText_HeldItemsLoseEffects[] =_("It created a bizarre area in which\nPokémon's held items lose their effects!");
|
||||
static const u8 sText_FellStraightDown[] =_("{B_DEF_NAME_WITH_PREFIX} fell\nstraight down!");
|
||||
static const u8 sText_TransformedIntoWaterType[] =_("{B_DEF_NAME_WITH_PREFIX} transformed\ninto the water type!");
|
||||
static const u8 sText_TargetChangedType[] =_("{B_DEF_NAME_WITH_PREFIX} transformed\ninto the {B_BUFF1} type!");
|
||||
static const u8 sText_PkmnAcquiredSimple[] =_("{B_DEF_NAME_WITH_PREFIX} acquired\nSimple!");
|
||||
static const u8 sText_KindOffer[] =_("{B_DEF_NAME_WITH_PREFIX}\ntook the kind offer!");
|
||||
static const u8 sText_ResetsTargetsStatLevels[] =_("{B_DEF_NAME_WITH_PREFIX}'s stat changes\nwere removed!");
|
||||
@ -629,7 +629,7 @@ static const u8 sText_TerrainBecomesGrassy[] = _("Grass grew to cover\nthe battl
|
||||
static const u8 sText_TerrainBecomesElectric[] = _("An electric current runs across\nthe battlefield!");
|
||||
static const u8 sText_TerrainBecomesPsychic[] = _("The battlefield got weird!");
|
||||
static const u8 sText_TargetElectrified[] = _("The {B_DEF_NAME_WITH_PREFIX}'s moves\nhave been electrified!");
|
||||
static const u8 sText_AssaultVestDoesntAllow[] = _("The effects of the {B_LAST_ITEM} prevent status\nmoves from being used!\p");
|
||||
static const u8 sText_AssaultVestDoesntAllow[] = _("{B_LAST_ITEM}'s effects prevent\nstatus moves from being used!\p");
|
||||
static const u8 sText_GravityPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} can't use {B_CURRENT_MOVE}\nbecause of gravity!\p");
|
||||
static const u8 sText_HealBlockPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} was\nprevented from healing!\p");
|
||||
static const u8 sText_MegaEvoReacting[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ITEM} is \nreacting to {B_ATK_TRAINER_NAME}'s Mega Ring!");
|
||||
@ -727,9 +727,20 @@ static const u8 sText_AbilityAllowsOnlyMove[] = _("{B_ATK_ABILITY} allows the\nu
|
||||
static const u8 sText_SwappedAbilities[] = _("{B_DEF_NAME_WITH_PREFIX} swapped Abilities\nwith its target!");
|
||||
static const u8 sText_PastelVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is protected\nby a pastel veil!");
|
||||
static const u8 sText_PastelVeilEnters[] = _("{B_DEF_NAME_WITH_PREFIX} was cured\nof its poisoning!");
|
||||
static const u8 sText_BattlerTypeChangedTo[] = _("{B_BUFF1}'s type\nchanged to {B_BUFF2}!");
|
||||
static const u8 sText_BothCanNoLongerEscape[] = _("Neither POKéMON can run away!");
|
||||
static const u8 sText_CantEscapeDueToUsedMove[] = _("{B_ATK_NAME_WITH_PREFIX} can no longer escape\nbecause it used {B_CURRENT_MOVE}!");
|
||||
static const u8 sText_PkmnBecameWeakerToFire[] = _("{B_DEF_NAME_WITH_PREFIX} became\nweaker to fire!");
|
||||
static const u8 sText_PkmnAboutToBeAttackedByItsItem[] = _("{B_DEF_NAME_WITH_PREFIX} is about\nto be attacked by its {B_BUFF1}!");
|
||||
static const u8 sText_CantEscapeBecauseOfCurrentMove[] = _("{B_DEF_NAME_WITH_PREFIX} can no longer escape\nbecause of {B_CURRENT_MOVE}!");
|
||||
static const u8 sText_NeutralizingGasEnters[] = _("Neutralizing Gas filled the area!");
|
||||
static const u8 sText_NeutralizingGasOver[] = _("The effects of Neutralizing\nGas wore off!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_NEUTRALIZINGGASOVER - 12] = sText_NeutralizingGasOver,
|
||||
[STRINGID_NEUTRALIZINGGASENTERS - 12] = sText_NeutralizingGasEnters,
|
||||
[STRINGID_BATTLERTYPECHANGEDTO - 12] = sText_BattlerTypeChangedTo,
|
||||
[STRINGID_PASTELVEILENTERS - 12] = sText_PastelVeilEnters,
|
||||
[STRINGID_PASTELVEILPROTECTED -12] = sText_PastelVeilProtected,
|
||||
[STRINGID_SWAPPEDABILITIES - 12] = sText_SwappedAbilities,
|
||||
@ -1198,7 +1209,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
[STRINGID_PKMNTWISTEDDIMENSIONS - 12] = sText_PkmnTwistedDimensions,
|
||||
[STRINGID_POINTEDSTONESFLOAT - 12] = sText_PointedStonesFloat,
|
||||
[STRINGID_CLOAKEDINMYSTICALMOONLIGHT - 12] = sText_CloakedInMysticalMoonlight,
|
||||
[STRINGID_TRAPPERBYSWIRLINGMAGMA - 12] = sText_TrappedBySwirlingMagma,
|
||||
[STRINGID_TRAPPEDBYSWIRLINGMAGMA - 12] = sText_TrappedBySwirlingMagma,
|
||||
[STRINGID_VANISHEDINSTANTLY - 12] = sText_VanishedInstantly,
|
||||
[STRINGID_PROTECTEDTEAM - 12] = sText_ProtectedTeam,
|
||||
[STRINGID_SHAREDITSGUARD - 12] = sText_SharedItsGuard,
|
||||
@ -1208,7 +1219,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
[STRINGID_HURLEDINTOTHEAIR - 12] = sText_HurledIntoTheAir,
|
||||
[STRINGID_HELDITEMSLOSEEFFECTS - 12] = sText_HeldItemsLoseEffects,
|
||||
[STRINGID_FELLSTRAIGHTDOWN - 12] = sText_FellStraightDown,
|
||||
[STRINGID_TRANSFORMEDINTOWATERTYPE - 12] = sText_TransformedIntoWaterType,
|
||||
[STRINGID_TARGETCHANGEDTYPE - 12] = sText_TargetChangedType,
|
||||
[STRINGID_PKMNACQUIREDSIMPLE - 12] = sText_PkmnAcquiredSimple,
|
||||
[STRINGID_EMPTYSTRING5 - 12] = sText_EmptyString4,
|
||||
[STRINGID_KINDOFFER - 12] = sText_KindOffer,
|
||||
@ -1318,6 +1329,11 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
[STRINGID_AURABREAKENTERS - 12] = sText_AuraBreakActivates,
|
||||
[STRINGID_COMATOSEENTERS - 12] = sText_ComatoseActivates,
|
||||
[STRINGID_SCREENCLEANERENTERS - 12] = sText_ScreenCleanerActivates,
|
||||
[STRINGID_BOTHCANNOLONGERESCAPE - 12] = sText_BothCanNoLongerEscape,
|
||||
[STRINGID_CANTESCAPEDUETOUSEDMOVE - 12] = sText_CantEscapeDueToUsedMove,
|
||||
[STRINGID_PKMNBECAMEWEAKERTOFIRE - 12] = sText_PkmnBecameWeakerToFire,
|
||||
[STRINGID_ABOUTTOUSEPOLTERGEIST - 12] = sText_PkmnAboutToBeAttackedByItsItem,
|
||||
[STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE - 12] = sText_CantEscapeBecauseOfCurrentMove,
|
||||
};
|
||||
|
||||
const u16 gMentalHerbCureStringIds[] =
|
||||
@ -1380,6 +1396,7 @@ const u16 gSwitchInAbilityStringIds[] =
|
||||
[B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS,
|
||||
[B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS,
|
||||
[B_MSG_SWITCHIN_PASTEL_VEIL] = STRINGID_PASTELVEILENTERS,
|
||||
[B_MSG_SWITCHIN_NEUTRALIZING_GAS] = STRINGID_NEUTRALIZINGGASENTERS,
|
||||
};
|
||||
|
||||
const u16 gMissStringIds[] =
|
||||
@ -1533,16 +1550,17 @@ const u16 gFirstTurnOfTwoStringIds[] =
|
||||
[B_MSG_TURN1_FREEZE_SHOCK] = STRINGID_CLOAKEDINAFREEZINGLIGHT,
|
||||
};
|
||||
|
||||
// Index copied from move's index in gTrappingMoves
|
||||
// Index copied from move's index in sTrappingMoves
|
||||
const u16 gWrappedStringIds[] =
|
||||
{
|
||||
STRINGID_PKMNSQUEEZEDBYBIND, // MOVE_BIND
|
||||
STRINGID_PKMNWRAPPEDBY, // MOVE_WRAP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_FIRE_SPIN
|
||||
STRINGID_PKMNCLAMPED, // MOVE_CLAMP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_WHIRLPOOL
|
||||
STRINGID_PKMNTRAPPEDBYSANDTOMB,// MOVE_SAND_TOMB
|
||||
STRINGID_INFESTATION, // MOVE_INFESTATION
|
||||
STRINGID_PKMNSQUEEZEDBYBIND, // MOVE_BIND
|
||||
STRINGID_PKMNWRAPPEDBY, // MOVE_WRAP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_FIRE_SPIN
|
||||
STRINGID_PKMNCLAMPED, // MOVE_CLAMP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_WHIRLPOOL
|
||||
STRINGID_PKMNTRAPPEDBYSANDTOMB, // MOVE_SAND_TOMB
|
||||
STRINGID_TRAPPEDBYSWIRLINGMAGMA, // MOVE_MAGMA_STORM
|
||||
STRINGID_INFESTATION, // MOVE_INFESTATION
|
||||
};
|
||||
|
||||
const u16 gMistUsedStringIds[] =
|
||||
@ -1753,11 +1771,6 @@ const u16 gCaughtMonStringIds[] =
|
||||
[B_MSG_LANETTES_BOX_FULL] = STRINGID_PKMNBOXLANETTESPCFULL,
|
||||
};
|
||||
|
||||
const u16 gTrappingMoves[] =
|
||||
{
|
||||
MOVE_BIND, MOVE_WRAP, MOVE_FIRE_SPIN, MOVE_CLAMP, MOVE_WHIRLPOOL, MOVE_SAND_TOMB, MOVE_INFESTATION, 0xFFFF
|
||||
};
|
||||
|
||||
const u16 gRoomsStringIds[] =
|
||||
{
|
||||
STRINGID_PKMNTWISTEDDIMENSIONS, STRINGID_TRICKROOMENDS,
|
||||
|
@ -317,8 +317,8 @@ void HandleAction_UseMove(void)
|
||||
else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
&& gSideTimers[side].followmeTimer == 0
|
||||
&& (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER)
|
||||
&& ((gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|
||||
|| (gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
|
||||
&& ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|
||||
|| (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
|
||||
{
|
||||
side = GetBattlerSide(gBattlerAttacker);
|
||||
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
||||
@ -387,9 +387,9 @@ void HandleAction_UseMove(void)
|
||||
{
|
||||
gActiveBattler = gBattlerByTurnOrder[var];
|
||||
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
|
||||
if (gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD)
|
||||
if (GetBattlerAbility(gActiveBattler) == ABILITY_LIGHTNING_ROD)
|
||||
gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE;
|
||||
else if (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN)
|
||||
else if (GetBattlerAbility(gActiveBattler) == ABILITY_STORM_DRAIN)
|
||||
gSpecialStatuses[gActiveBattler].stormDrainRedirected = TRUE;
|
||||
gBattlerTarget = gActiveBattler;
|
||||
}
|
||||
@ -627,7 +627,7 @@ bool8 TryRunFromBattle(u8 battler)
|
||||
effect++;
|
||||
}
|
||||
#endif
|
||||
else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY)
|
||||
else if (GetBattlerAbility(battler) == ABILITY_RUN_AWAY)
|
||||
{
|
||||
if (InBattlePyramid())
|
||||
{
|
||||
@ -1762,7 +1762,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
limitations++;
|
||||
}
|
||||
}
|
||||
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0)
|
||||
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0 && move != MOVE_ME_FIRST)
|
||||
{
|
||||
gCurrentMove = move;
|
||||
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
||||
@ -1834,7 +1834,7 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
|
||||
unusableMoves |= gBitTable[i];
|
||||
else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i])
|
||||
unusableMoves |= gBitTable[i];
|
||||
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0)
|
||||
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST)
|
||||
unusableMoves |= gBitTable[i];
|
||||
else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i]))
|
||||
unusableMoves |= gBitTable[i];
|
||||
@ -1894,6 +1894,57 @@ u8 GetImprisonedMovesCount(u8 battlerId, u16 move)
|
||||
return imprisonedMoves;
|
||||
}
|
||||
|
||||
void RestoreBattlerOriginalTypes(u8 battlerId)
|
||||
{
|
||||
gBattleMons[battlerId].type1 = gBaseStats[gBattleMons[battlerId].species].type1;
|
||||
gBattleMons[battlerId].type2 = gBaseStats[gBattleMons[battlerId].species].type2;
|
||||
}
|
||||
|
||||
void TryToApplyMimicry(u8 battlerId, bool8 various)
|
||||
{
|
||||
u32 moveType, move;
|
||||
|
||||
GET_MOVE_TYPE(move, moveType);
|
||||
switch (gFieldStatuses)
|
||||
{
|
||||
case STATUS_FIELD_ELECTRIC_TERRAIN:
|
||||
moveType = TYPE_ELECTRIC;
|
||||
break;
|
||||
case STATUS_FIELD_MISTY_TERRAIN:
|
||||
moveType = TYPE_FAIRY;
|
||||
break;
|
||||
case STATUS_FIELD_GRASSY_TERRAIN:
|
||||
moveType = TYPE_GRASS;
|
||||
break;
|
||||
case STATUS_FIELD_PSYCHIC_TERRAIN:
|
||||
moveType = TYPE_PSYCHIC;
|
||||
break;
|
||||
default:
|
||||
moveType = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (moveType != 0 && !IS_BATTLER_OF_TYPE(battlerId, moveType))
|
||||
{
|
||||
SET_BATTLER_TYPE(battlerId, moveType);
|
||||
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battlerId, gBattlerPartyIndexes[battlerId])
|
||||
PREPARE_TYPE_BUFFER(gBattleTextBuff2, moveType);
|
||||
if (!various)
|
||||
BattleScriptPushCursorAndCallback(BattleScript_MimicryActivatesEnd3);
|
||||
}
|
||||
}
|
||||
|
||||
void TryToRevertMimicry(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
if (GetBattlerAbility(i) == ABILITY_MIMICRY)
|
||||
RestoreBattlerOriginalTypes(i);
|
||||
}
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
ENDTURN_ORDER,
|
||||
@ -2275,9 +2326,10 @@ u8 DoFieldEndTurnEffects(void)
|
||||
break;
|
||||
case ENDTURN_ELECTRIC_TERRAIN:
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0))
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0))
|
||||
{
|
||||
gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT);
|
||||
TryToRevertMimicry();
|
||||
BattleScriptExecute(BattleScript_ElectricTerrainEnds);
|
||||
effect++;
|
||||
}
|
||||
@ -2285,9 +2337,10 @@ u8 DoFieldEndTurnEffects(void)
|
||||
break;
|
||||
case ENDTURN_MISTY_TERRAIN:
|
||||
if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0))
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0))
|
||||
{
|
||||
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN);
|
||||
TryToRevertMimicry();
|
||||
BattleScriptExecute(BattleScript_MistyTerrainEnds);
|
||||
effect++;
|
||||
}
|
||||
@ -2297,9 +2350,11 @@ u8 DoFieldEndTurnEffects(void)
|
||||
if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN)
|
||||
{
|
||||
if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT)
|
||||
&& (gFieldTimers.grassyTerrainTimer == 0 || --gFieldTimers.grassyTerrainTimer == 0))
|
||||
&& (gFieldTimers.terrainTimer == 0 || --gFieldTimers.terrainTimer == 0))
|
||||
{
|
||||
gFieldStatuses &= ~(STATUS_FIELD_GRASSY_TERRAIN);
|
||||
|
||||
TryToRevertMimicry();
|
||||
}
|
||||
BattleScriptExecute(BattleScript_GrassyTerrainHeals);
|
||||
effect++;
|
||||
}
|
||||
@ -2307,9 +2362,10 @@ u8 DoFieldEndTurnEffects(void)
|
||||
break;
|
||||
case ENDTURN_PSYCHIC_TERRAIN:
|
||||
if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0))
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0))
|
||||
{
|
||||
gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN);
|
||||
TryToRevertMimicry();
|
||||
BattleScriptExecute(BattleScript_PsychicTerrainEnds);
|
||||
effect++;
|
||||
}
|
||||
@ -2382,6 +2438,7 @@ enum
|
||||
ENDTURN_NIGHTMARES,
|
||||
ENDTURN_CURSE,
|
||||
ENDTURN_WRAP,
|
||||
ENDTURN_OCTOLOCK,
|
||||
ENDTURN_UPROAR,
|
||||
ENDTURN_THRASH,
|
||||
ENDTURN_FLINCH,
|
||||
@ -2652,13 +2709,25 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
}
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_OCTOLOCK:
|
||||
if (gDisableStructs[gActiveBattler].octolock
|
||||
&& !(GetBattlerAbility(gActiveBattler) == ABILITY_CLEAR_BODY
|
||||
|| GetBattlerAbility(gActiveBattler) == ABILITY_FULL_METAL_BODY
|
||||
|| GetBattlerAbility(gActiveBattler) == ABILITY_WHITE_SMOKE))
|
||||
{
|
||||
gBattlerTarget = gActiveBattler;
|
||||
BattleScriptExecute(BattleScript_OctolockEndTurn);
|
||||
effect++;
|
||||
}
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_UPROAR: // uproar
|
||||
if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR)
|
||||
{
|
||||
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
|
||||
{
|
||||
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
|
||||
&& gBattleMons[gBattlerAttacker].ability != ABILITY_SOUNDPROOF)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status1 &= ~(STATUS1_SLEEP);
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE);
|
||||
@ -2726,6 +2795,7 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
case ENDTURN_FLINCH: // reset flinch
|
||||
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_FLINCHED);
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_DISABLE: // disable
|
||||
if (gDisableStructs[gActiveBattler].disableTimer != 0)
|
||||
{
|
||||
@ -3242,7 +3312,7 @@ u8 AtkCanceller_UnableToUseMove(void)
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_TRUANT: // truant
|
||||
if (gBattleMons[gBattlerAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter)
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter)
|
||||
{
|
||||
CancelMultiTurnMoves(gBattlerAttacker);
|
||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||
@ -3683,7 +3753,7 @@ u8 TryWeatherFormChange(u8 battler)
|
||||
|
||||
if (gBattleMons[battler].species == SPECIES_CASTFORM)
|
||||
{
|
||||
if (gBattleMons[battler].ability != ABILITY_FORECAST || gBattleMons[battler].hp == 0)
|
||||
if (GetBattlerAbility(battler) != ABILITY_FORECAST || gBattleMons[battler].hp == 0)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
@ -3719,11 +3789,11 @@ u8 TryWeatherFormChange(u8 battler)
|
||||
}
|
||||
else if (gBattleMons[battler].species == SPECIES_CHERRIM)
|
||||
{
|
||||
if (gBattleMons[battler].ability != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0)
|
||||
if (GetBattlerAbility(battler) != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0)
|
||||
ret = 0;
|
||||
else if (gBattleMonForms[battler] == 0 && weatherEffect && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & WEATHER_SUN_ANY)
|
||||
ret = 2;
|
||||
else if (gBattleMonForms[battler] != 0 && (!weatherEffect || holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA || !(gBattleWeather & WEATHER_SUN_ANY)))
|
||||
else if (gBattleMonForms[battler] != 0 && (!weatherEffect || holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA || !(gBattleWeather & WEATHER_SUN_ANY)))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
@ -3809,7 +3879,7 @@ static bool32 ShouldChangeFormHpBased(u32 battler)
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(forms); i++)
|
||||
{
|
||||
if (gBattleMons[battler].ability == forms[i][0])
|
||||
if (GetBattlerAbility(battler) == forms[i][0])
|
||||
{
|
||||
if (gBattleMons[battler].species == forms[i][2]
|
||||
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / forms[i][3])
|
||||
@ -4282,28 +4352,28 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
}
|
||||
break;
|
||||
case ABILITY_ELECTRIC_SURGE:
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.electricTerrainTimer))
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.terrainTimer))
|
||||
{
|
||||
BattleScriptPushCursorAndCallback(BattleScript_ElectricSurgeActivates);
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_GRASSY_SURGE:
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.grassyTerrainTimer))
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer))
|
||||
{
|
||||
BattleScriptPushCursorAndCallback(BattleScript_GrassySurgeActivates);
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_MISTY_SURGE:
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN, &gFieldTimers.mistyTerrainTimer))
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN, &gFieldTimers.terrainTimer))
|
||||
{
|
||||
BattleScriptPushCursorAndCallback(BattleScript_MistySurgeActivates);
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_PSYCHIC_SURGE:
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN, &gFieldTimers.psychicTerrainTimer))
|
||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN, &gFieldTimers.terrainTimer))
|
||||
{
|
||||
BattleScriptPushCursorAndCallback(BattleScript_PsychicSurgeActivates);
|
||||
effect++;
|
||||
@ -4390,6 +4460,13 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_MIMICRY:
|
||||
if (gBattleMons[battler].hp != 0 && gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)
|
||||
{
|
||||
TryToApplyMimicry(battler, FALSE);
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_ENDTURN: // 1
|
||||
@ -4572,6 +4649,22 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_HUNGER_SWITCH:
|
||||
if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
{
|
||||
if (gBattleMons[battler].species == SPECIES_MORPEKO)
|
||||
{
|
||||
gBattleMons[battler].species = SPECIES_MORPEKO_HANGRY;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3NoPopup);
|
||||
}
|
||||
else if (gBattleMons[battler].species == SPECIES_MORPEKO_HANGRY)
|
||||
{
|
||||
gBattleMons[battler].species = SPECIES_MORPEKO;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3NoPopup);
|
||||
}
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4837,7 +4930,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT))
|
||||
&& (IsMoveMakingContact(move, gBattlerAttacker)))
|
||||
{
|
||||
switch (gBattleMons[gBattlerAttacker].ability)
|
||||
{
|
||||
@ -5056,7 +5149,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& gBattleMons[gBattlerAttacker].hp != 0
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
|
||||
&& (IsMoveMakingContact(move, gBattlerAttacker))
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& CanBeBurned(gBattlerAttacker)
|
||||
&& (Random() % 3) == 0)
|
||||
@ -5072,7 +5165,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& gBattleMons[gBattlerAttacker].hp != 0
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
|
||||
&& (IsMoveMakingContact(move, gBattlerAttacker))
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& gBattleMons[gBattlerTarget].hp != 0
|
||||
&& (Random() % 3) == 0
|
||||
@ -5148,7 +5241,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& IsBattlerAlive(battler)
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
|
||||
&& (IsMoveMakingContact(move, gBattlerAttacker))
|
||||
&& !(gStatuses3[gBattlerAttacker] & STATUS3_PERISH_SONG))
|
||||
{
|
||||
if (!(gStatuses3[battler] & STATUS3_PERISH_SONG))
|
||||
@ -5281,7 +5374,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
case ABILITYEFFECT_IMMUNITY: // 5
|
||||
for (battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
switch (gBattleMons[battler].ability)
|
||||
switch (GetBattlerAbility(battler))
|
||||
{
|
||||
case ABILITY_IMMUNITY:
|
||||
if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON | STATUS1_TOXIC_COUNTER))
|
||||
@ -5371,7 +5464,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
case ABILITYEFFECT_FORECAST: // 6
|
||||
for (battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (gBattleMons[battler].ability == ABILITY_FORECAST || gBattleMons[battler].ability == ABILITY_FLOWER_GIFT)
|
||||
if (GetBattlerAbility(battler) == ABILITY_FORECAST || GetBattlerAbility(battler) == ABILITY_FLOWER_GIFT)
|
||||
{
|
||||
effect = TryWeatherFormChange(battler);
|
||||
if (effect)
|
||||
@ -5392,8 +5485,10 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
if (!(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY))
|
||||
{
|
||||
gBattleStruct->synchronizeMoveEffect &= ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
|
||||
if (gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
|
||||
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
|
||||
#if B_SYNCHRONIZE_TOXIC < GEN_5
|
||||
if (gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
|
||||
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
|
||||
#endif
|
||||
|
||||
gBattleScripting.moveEffect = gBattleStruct->synchronizeMoveEffect + MOVE_EFFECT_AFFECTS_USER;
|
||||
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
|
||||
@ -5430,7 +5525,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
case ABILITYEFFECT_INTIMIDATE2:
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED)
|
||||
if (GetBattlerAbility(i) == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED)
|
||||
{
|
||||
gLastUsedAbility = ABILITY_INTIMIDATE;
|
||||
gBattleResources->flags->flags[i] &= ~(RESOURCE_FLAG_INTIMIDATED);
|
||||
@ -5497,6 +5592,23 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_NEUTRALIZINGGAS:
|
||||
// Prints message only. separate from ABILITYEFFECT_ON_SWITCHIN bc activates before entry hazards
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gBattleResources->flags->flags[i] & RESOURCE_FLAG_NEUTRALIZING_GAS))
|
||||
{
|
||||
gBattleResources->flags->flags[i] |= RESOURCE_FLAG_NEUTRALIZING_GAS;
|
||||
gBattlerAbility = i;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg);
|
||||
effect++;
|
||||
}
|
||||
|
||||
if (effect)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (effect && gLastUsedAbility != 0xFF)
|
||||
@ -5507,11 +5619,51 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
return effect;
|
||||
}
|
||||
|
||||
bool32 IsNeutralizingGasBannedAbility(u32 ability)
|
||||
{
|
||||
switch (ability)
|
||||
{
|
||||
case ABILITY_MULTITYPE:
|
||||
case ABILITY_ZEN_MODE:
|
||||
case ABILITY_STANCE_CHANGE:
|
||||
case ABILITY_POWER_CONSTRUCT:
|
||||
case ABILITY_SCHOOLING:
|
||||
case ABILITY_RKS_SYSTEM:
|
||||
case ABILITY_SHIELDS_DOWN:
|
||||
case ABILITY_COMATOSE:
|
||||
case ABILITY_DISGUISE:
|
||||
case ABILITY_GULP_MISSILE:
|
||||
case ABILITY_ICE_FACE:
|
||||
case ABILITY_AS_ONE_ICE_RIDER:
|
||||
case ABILITY_AS_ONE_SHADOW_RIDER:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 IsNeutralizingGasOnField(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gStatuses3[i] & STATUS3_GASTRO_ACID))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 GetBattlerAbility(u8 battlerId)
|
||||
{
|
||||
if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID)
|
||||
return ABILITY_NONE;
|
||||
else if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|
||||
|
||||
if (IsNeutralizingGasOnField() && !IsNeutralizingGasBannedAbility(gBattleMons[battlerId].ability))
|
||||
return ABILITY_NONE;
|
||||
|
||||
if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|
||||
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT
|
||||
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE)
|
||||
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
|
||||
@ -5521,8 +5673,8 @@ u32 GetBattlerAbility(u8 battlerId)
|
||||
&& gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE
|
||||
&& gCurrentTurnActionNumber < gBattlersCount)
|
||||
return ABILITY_NONE;
|
||||
else
|
||||
return gBattleMons[battlerId].ability;
|
||||
|
||||
return gBattleMons[battlerId].ability;
|
||||
}
|
||||
|
||||
u32 IsAbilityOnSide(u32 battlerId, u32 ability)
|
||||
@ -5574,7 +5726,7 @@ u32 IsAbilityPreventingEscape(u32 battlerId)
|
||||
return 0;
|
||||
#endif
|
||||
#if B_SHADOW_TAG_ESCAPE >= GEN_4
|
||||
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG)
|
||||
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && GetBattlerAbility(battlerId) != ABILITY_SHADOW_TAG)
|
||||
#else
|
||||
if (id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG))
|
||||
#endif
|
||||
@ -6766,6 +6918,10 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
|
||||
switch (atkHoldEffect)
|
||||
{
|
||||
case HOLD_EFFECT_FLINCH:
|
||||
#if B_SERENE_GRACE_BOOST >= GEN_5
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE)
|
||||
atkHoldEffectParam *= 2;
|
||||
#endif
|
||||
if (gBattleMoveDamage != 0 // Need to have done damage
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& TARGET_TURN_DAMAGED
|
||||
@ -7121,7 +7277,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
|
||||
targetBattler = SetRandomTarget(gBattlerAttacker);
|
||||
if (gBattleMoves[move].type == TYPE_ELECTRIC
|
||||
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD)
|
||||
&& gBattleMons[targetBattler].ability != ABILITY_LIGHTNING_ROD)
|
||||
&& GetBattlerAbility(targetBattler) != ABILITY_LIGHTNING_ROD)
|
||||
{
|
||||
targetBattler ^= BIT_FLANK;
|
||||
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
|
||||
@ -7129,7 +7285,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
|
||||
}
|
||||
else if (gBattleMoves[move].type == TYPE_WATER
|
||||
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN)
|
||||
&& gBattleMons[targetBattler].ability != ABILITY_STORM_DRAIN)
|
||||
&& GetBattlerAbility(targetBattler) != ABILITY_STORM_DRAIN)
|
||||
{
|
||||
targetBattler ^= BIT_FLANK;
|
||||
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
|
||||
@ -7307,7 +7463,7 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating)
|
||||
return HOLD_EFFECT_NONE;
|
||||
if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)
|
||||
return HOLD_EFFECT_NONE;
|
||||
if (gBattleMons[battlerId].ability == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID))
|
||||
if (GetBattlerAbility(battlerId) == ABILITY_KLUTZ)
|
||||
return HOLD_EFFECT_NONE;
|
||||
}
|
||||
|
||||
@ -7332,15 +7488,73 @@ u32 GetBattlerHoldEffectParam(u8 battlerId)
|
||||
bool32 IsMoveMakingContact(u16 move, u8 battlerAtk)
|
||||
{
|
||||
if (!(gBattleMoves[move].flags & FLAG_MAKES_CONTACT))
|
||||
return FALSE;
|
||||
{
|
||||
if (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gSwapDamageCategory)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else if (GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (GetBattlerHoldEffect(battlerAtk, TRUE) == HOLD_EFFECT_PROTECTIVE_PADS)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 IsBattlerProtected(u8 battlerId, u16 move)
|
||||
{
|
||||
// Decorate bypasses protect and detect, but not crafty shield
|
||||
if (move == MOVE_DECORATE)
|
||||
{
|
||||
if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD)
|
||||
return TRUE;
|
||||
else if (gProtectStructs[battlerId].protected)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here.
|
||||
// This means extra logic is needed to handle Shell Side Arm.
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT || (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gSwapDamageCategory)))
|
||||
return FALSE;
|
||||
else if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED))
|
||||
return FALSE;
|
||||
else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT)
|
||||
return FALSE;
|
||||
else if (gProtectStructs[battlerId].protected)
|
||||
return TRUE;
|
||||
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD
|
||||
&& gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
|
||||
return TRUE;
|
||||
else if (gProtectStructs[battlerId].banefulBunkered)
|
||||
return TRUE;
|
||||
else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move))
|
||||
return TRUE;
|
||||
else if (gProtectStructs[battlerId].spikyShielded)
|
||||
return TRUE;
|
||||
else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0)
|
||||
return TRUE;
|
||||
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD
|
||||
&& GetChosenMovePriority(gBattlerAttacker) > 0)
|
||||
return TRUE;
|
||||
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD
|
||||
&& IS_MOVE_STATUS(move))
|
||||
return TRUE;
|
||||
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK
|
||||
&& !IS_MOVE_STATUS(move))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool32 IsBattlerGrounded(u8 battlerId)
|
||||
{
|
||||
if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL)
|
||||
@ -7696,7 +7910,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
if (weight >= ARRAY_COUNT(sHeatCrashPowerTable))
|
||||
basePower = sHeatCrashPowerTable[ARRAY_COUNT(sHeatCrashPowerTable) - 1];
|
||||
else
|
||||
basePower = sHeatCrashPowerTable[i];
|
||||
basePower = sHeatCrashPowerTable[weight];
|
||||
break;
|
||||
case EFFECT_PUNISHMENT:
|
||||
basePower = 60 + (CountBattlerStatIncreases(battlerDef, FALSE) * 20);
|
||||
@ -7731,6 +7945,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
&& (gDisableStructs[battlerDef].isFirstTurn != 2 || B_PAYBACK_SWITCH_BOOST < GEN_5))
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_BOLT_BEAK:
|
||||
if (GetBattlerTurnOrderNum(battlerAtk) < GetBattlerTurnOrderNum(battlerDef))
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_ROUND:
|
||||
if (gChosenMoveByBattler[BATTLE_PARTNER(battlerAtk)] == MOVE_ROUND && !(gAbsentBattlerFlags & gBitTable[BATTLE_PARTNER(battlerAtk)]))
|
||||
basePower *= 2;
|
||||
@ -7773,6 +7991,11 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
|
||||
MulModifier(&basePower, UQ_4_12(1.5));
|
||||
break;
|
||||
case EFFECT_TERRAIN_PULSE:
|
||||
if ((gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)
|
||||
&& IsBattlerGrounded(gBattlerAttacker))
|
||||
basePower *= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// move-specific base power changes
|
||||
@ -7846,7 +8069,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
MulModifier(&modifier, UQ_4_12(1.3));
|
||||
break;
|
||||
case ABILITY_TOUGH_CLAWS:
|
||||
if (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
|
||||
if (IsMoveMakingContact(move, battlerAtk))
|
||||
MulModifier(&modifier, UQ_4_12(1.3));
|
||||
break;
|
||||
case ABILITY_STRONG_JAW:
|
||||
@ -7914,7 +8137,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
if (IsAbilityOnField(ABILITY_AURA_BREAK))
|
||||
MulModifier(&modifier, UQ_4_12(0.75));
|
||||
else
|
||||
MulModifier(&modifier, UQ_4_12(1.25));
|
||||
MulModifier(&modifier, UQ_4_12(1.33));
|
||||
}
|
||||
|
||||
// attacker partner's abilities
|
||||
@ -7996,7 +8219,11 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
MulModifier(&modifier, holdEffectModifier);
|
||||
break;
|
||||
case HOLD_EFFECT_SOUL_DEW:
|
||||
if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS) && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER))
|
||||
#if B_SOUL_DEW_BOOST >= GEN_7
|
||||
if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS) && (moveType == TYPE_PSYCHIC || moveType == TYPE_DRAGON))
|
||||
#else
|
||||
if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS) && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && IS_MOVE_SPECIAL(move))
|
||||
#endif
|
||||
MulModifier(&modifier, holdEffectModifier);
|
||||
break;
|
||||
case HOLD_EFFECT_GEMS:
|
||||
@ -8071,8 +8298,11 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
MulModifier(&modifier, UQ_4_12(0.5));
|
||||
break;
|
||||
case EFFECT_KNOCK_OFF:
|
||||
if (gBattleMons[battlerDef].item != ITEM_NONE && GetBattlerAbility(battlerDef) != ABILITY_STICKY_HOLD)
|
||||
#if B_KNOCK_OFF_DMG >= GEN_6
|
||||
if (gBattleMons[battlerDef].item != ITEM_NONE
|
||||
&& CanBattlerGetOrLoseItem(battlerDef, gBattleMons[battlerDef].item))
|
||||
MulModifier(&modifier, UQ_4_12(1.5));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -8409,6 +8639,14 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
|
||||
if (!usesDefStat)
|
||||
MulModifier(&modifier, UQ_4_12(1.5));
|
||||
break;
|
||||
#if B_SOUL_DEW_BOOST <= GEN_6
|
||||
case HOLD_EFFECT_SOUL_DEW:
|
||||
if ((gBattleMons[battlerDef].species == SPECIES_LATIAS || gBattleMons[battlerDef].species == SPECIES_LATIOS)
|
||||
&& !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
|
||||
&& !usesDefStat)
|
||||
MulModifier(&modifier, UQ_4_12(1.5));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
// sandstorm sp.def boost for rock types
|
||||
@ -8479,7 +8717,9 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
||||
if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move))
|
||||
|| (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move))
|
||||
|| (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL))
|
||||
&& abilityAtk != ABILITY_INFILTRATOR)
|
||||
&& abilityAtk != ABILITY_INFILTRATOR
|
||||
&& !(isCrit)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg)
|
||||
{
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
MulModifier(&finalModifier, UQ_4_12(0.66));
|
||||
@ -8648,9 +8888,8 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt
|
||||
mod = UQ_4_12(2.0);
|
||||
if (moveType == TYPE_GROUND && defType == TYPE_FLYING && IsBattlerGrounded(battlerDef) && mod == UQ_4_12(0.0))
|
||||
mod = UQ_4_12(1.0);
|
||||
|
||||
if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT)
|
||||
mod = UQ_4_12(1.0);
|
||||
if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot)
|
||||
mod = UQ_4_12(2.0);
|
||||
|
||||
// WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon
|
||||
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS)
|
||||
@ -8875,9 +9114,9 @@ bool32 CanMegaEvolve(u8 battlerId)
|
||||
struct MegaEvolutionData *mega = &(((struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]))->mega);
|
||||
|
||||
#ifdef ITEM_EXPANSION
|
||||
// Check if Player has a Mega Bracelet
|
||||
// Check if Player has a Mega Ring
|
||||
if ((GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT || (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battlerId) == B_POSITION_PLAYER_RIGHT))
|
||||
&& !CheckBagHasItem(ITEM_MEGA_BRACELET, 1))
|
||||
&& !CheckBagHasItem(ITEM_MEGA_RING, 1))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
@ -8969,6 +9208,7 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
|
||||
// Changed Form ID Default Form ID Should change on switch
|
||||
{SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU, FALSE},
|
||||
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND, FALSE},
|
||||
{SPECIES_MELOETTA_PIROUETTE, SPECIES_MELOETTA, FALSE},
|
||||
{SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH, TRUE},
|
||||
{SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN, TRUE},
|
||||
{SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED, TRUE},
|
||||
@ -8981,6 +9221,7 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
|
||||
{SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, TRUE},
|
||||
{SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT, TRUE},
|
||||
{SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT, TRUE},
|
||||
{SPECIES_MORPEKO_HANGRY, SPECIES_MORPEKO, TRUE},
|
||||
};
|
||||
|
||||
currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);
|
||||
@ -9126,7 +9367,9 @@ bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 battlerId)
|
||||
|
||||
u8 GetBattleMoveSplit(u32 moveId)
|
||||
{
|
||||
if (IS_MOVE_STATUS(moveId) || B_PHYSICAL_SPECIAL_SPLIT >= GEN_4)
|
||||
if (gSwapDamageCategory) // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
return SPLIT_PHYSICAL;
|
||||
else if (IS_MOVE_STATUS(moveId) || B_PHYSICAL_SPECIAL_SPLIT >= GEN_4)
|
||||
return gBattleMoves[moveId].split;
|
||||
else if (gBattleMoves[moveId].type < TYPE_MYSTERY)
|
||||
return SPLIT_PHYSICAL;
|
||||
|
@ -142,7 +142,7 @@ u32 sub_805725C(u8 battlerId)
|
||||
{
|
||||
u32 toSub;
|
||||
|
||||
if (gBattleMons[battlerId].ability == ABILITY_EARLY_BIRD)
|
||||
if (GetBattlerAbility(battlerId) == ABILITY_EARLY_BIRD)
|
||||
toSub = 2;
|
||||
else
|
||||
toSub = 1;
|
||||
|
@ -378,7 +378,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
@ -649,7 +649,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 20,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
@ -2460,7 +2460,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
@ -7267,7 +7267,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
@ -8367,7 +8367,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
@ -8575,7 +8575,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
@ -8614,7 +8614,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_RELIC_SONG] =
|
||||
{
|
||||
.effect = EFFECT_SLEEP_HIT,
|
||||
.effect = EFFECT_RELIC_SONG,
|
||||
.power = 75,
|
||||
.type = TYPE_NORMAL,
|
||||
.accuracy = 100,
|
||||
@ -8624,6 +8624,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND | FLAG_SHEER_FORCE_BOOST,
|
||||
.split = SPLIT_SPECIAL,
|
||||
.argument = STATUS1_SLEEP,
|
||||
},
|
||||
|
||||
[MOVE_SECRET_SWORD] =
|
||||
@ -10454,7 +10455,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_PHOTON_GEYSER] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, // Needs a custom move effect
|
||||
.effect = EFFECT_PHOTON_GEYSER,
|
||||
.power = 100,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 100,
|
||||
@ -10462,7 +10463,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_FOES_AND_ALLY,
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TARGET_ABILITY_IGNORED,
|
||||
.split = SPLIT_SPECIAL,
|
||||
},
|
||||
|
||||
@ -10726,9 +10727,9 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
[MOVE_DOUBLE_IRON_BASH] =
|
||||
{
|
||||
#if B_UPDATED_MOVE_DATA >= GEN_8
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST | FLAG_TWO_STRIKES,
|
||||
#else
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST | FLAG_TWO_STRIKES,
|
||||
#endif
|
||||
.effect = EFFECT_DOUBLE_IRON_BASH,
|
||||
.power = 60,
|
||||
@ -10771,7 +10772,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_JAW_LOCK] =
|
||||
{
|
||||
.effect = EFFECT_MEAN_LOOK,
|
||||
.effect = EFFECT_JAW_LOCK,
|
||||
.power = 80,
|
||||
.type = TYPE_DARK,
|
||||
.accuracy = 100,
|
||||
@ -10799,7 +10800,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_NO_RETREAT] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //TODO
|
||||
.effect = EFFECT_NO_RETREAT,
|
||||
.power = 0,
|
||||
.type = TYPE_FIGHTING,
|
||||
.accuracy = 0,
|
||||
@ -10813,7 +10814,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_TAR_SHOT] =
|
||||
{
|
||||
.effect = EFFECT_SPEED_DOWN,
|
||||
.effect = EFFECT_TAR_SHOT,
|
||||
.power = 0,
|
||||
.type = TYPE_ROCK,
|
||||
.accuracy = 100,
|
||||
@ -10827,7 +10828,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_MAGIC_POWDER] =
|
||||
{
|
||||
.effect = EFFECT_THIRD_TYPE,
|
||||
.effect = EFFECT_SOAK,
|
||||
.power = 0,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 100,
|
||||
@ -10850,7 +10851,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
@ -10870,7 +10871,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_OCTOLOCK] =
|
||||
{
|
||||
.effect = EFFECT_MEAN_LOOK,
|
||||
.effect = EFFECT_OCTOLOCK,
|
||||
.power = 0,
|
||||
.type = TYPE_FIGHTING,
|
||||
.accuracy = 100,
|
||||
@ -10884,7 +10885,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_BOLT_BEAK] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //TODO
|
||||
.effect = EFFECT_BOLT_BEAK,
|
||||
.power = 85,
|
||||
.type = TYPE_ELECTRIC,
|
||||
.accuracy = 100,
|
||||
@ -10898,7 +10899,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_FISHIOUS_REND] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //TODO. same as bolt beak
|
||||
.effect = EFFECT_BOLT_BEAK,
|
||||
.power = 85,
|
||||
.type = TYPE_WATER,
|
||||
.accuracy = 100,
|
||||
@ -10926,7 +10927,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_CLANGOROUS_SOUL] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //TODO
|
||||
.effect = EFFECT_CLANGOROUS_SOUL,
|
||||
.power = 0,
|
||||
.type = TYPE_DRAGON,
|
||||
.accuracy = 100,
|
||||
@ -11038,7 +11039,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_AURA_WHEEL] =
|
||||
{
|
||||
.effect = EFFECT_SPEED_UP_HIT,
|
||||
.effect = EFFECT_AURA_WHEEL,
|
||||
.power = 110,
|
||||
.type = TYPE_ELECTRIC,
|
||||
.accuracy = 100,
|
||||
@ -11290,12 +11291,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_SHELL_SIDE_ARM] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //TODO
|
||||
.effect = EFFECT_SHELL_SIDE_ARM,
|
||||
.power = 90,
|
||||
.type = TYPE_POISON,
|
||||
.accuracy = 100,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.secondaryEffectChance = 20,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST,
|
||||
@ -11346,7 +11347,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_TERRAIN_PULSE] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //TODO
|
||||
.effect = EFFECT_TERRAIN_PULSE,
|
||||
.power = 50,
|
||||
.type = TYPE_NORMAL,
|
||||
.accuracy = 100,
|
||||
@ -11402,7 +11403,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
|
||||
[MOVE_POLTERGEIST] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //TODO
|
||||
.effect = EFFECT_POLTERGEIST,
|
||||
.power = 110,
|
||||
.type = TYPE_GHOST,
|
||||
.accuracy = 90,
|
||||
@ -11480,7 +11481,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_TWO_STRIKES,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
},
|
||||
|
||||
|
@ -2680,7 +2680,7 @@ const struct Item gItems[] =
|
||||
.name = _("UP-GRADE"),
|
||||
.itemId = ITEM_UP_GRADE,
|
||||
.price = 2100,
|
||||
.holdEffect = HOLD_EFFECT_UP_GRADE,
|
||||
.holdEffect = HOLD_EFFECT_UPGRADE,
|
||||
.description = sUpGradeDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -2767,7 +2767,7 @@ const struct Item gItems[] =
|
||||
.name = _("STICK"),
|
||||
.itemId = ITEM_STICK,
|
||||
.price = 200,
|
||||
.holdEffect = HOLD_EFFECT_STICK,
|
||||
.holdEffect = HOLD_EFFECT_LEEK,
|
||||
.description = sStickDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
|
@ -2839,7 +2839,7 @@ static const u8 sMETEOR_BEAMDescription[] = _(
|
||||
"Sp. Attack before attacking.");
|
||||
|
||||
static const u8 sSHELL_SIDE_ARMDescription[] = _(
|
||||
"Uses higher of physical and\n"
|
||||
"Deals better of physical and\n"
|
||||
"special damage. May poison.");
|
||||
|
||||
static const u8 sMISTY_EXPLOSIONDescription[] = _(
|
||||
|
@ -1395,11 +1395,6 @@ const u32 gBattleAnimBgPalette_Solarbeam[] = INCBIN_U32("graphics/battle_anims/b
|
||||
const u32 gBattleAnimBgPalette_MagmaStorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/magma_storm.gbapal.lz");
|
||||
|
||||
//new battle bgs
|
||||
const u32 gBattleAnimBgPalette_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/giga_impact.gbapal.lz");
|
||||
|
||||
//const u32 gBattleAnimBgImage_TrickRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/trick_room.4bpp.lz");
|
||||
//const u32 gBattleAnimBgPalette_TrickRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/trick_room.gbapal.lz");
|
||||
//const u32 gBattleAnimBgTilemap_TrickRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/trick_room_map.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_Hurricane[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/hurricane.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_Hurricane[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/hurricane.gbapal.lz");
|
||||
@ -1407,15 +1402,14 @@ const u32 gBattleAnimBgTilemap_Hurricane[] = INCBIN_U32("graphics/battle_anims/b
|
||||
|
||||
const u32 gBattleAnimBgPalette_RockWrecker[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/rock_wrecker.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimBgTilemap_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.bin.lz");
|
||||
const u32 gBattleAnimBgTilemap_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin.lz");
|
||||
const u32 gBattleAnimBgTilemap_GigaImpactContest[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_contest.bin.lz");
|
||||
const u32 gBattleAnimBgImage_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_SpacialRend[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_SpacialRend[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_SpacialRendOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin.lz");
|
||||
const u32 gBattleAnimBgTilemap_SpacialRendPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend_player.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/dark_void.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/dark_void.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/dark_void.bin.lz");
|
||||
|
||||
|
||||
const u32 gBattleAnimBgPalette_SludgeWave[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/sludge_wave.gbapal.lz");
|
||||
|
||||
@ -1441,10 +1435,6 @@ const u32 gBattleAnimBgImage_ClangorousSoulblaze[] = INCBIN_U32("graphics/battle
|
||||
const u32 gBattleAnimBgPalette_ClangorousSoulblaze[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/clangorous_soulblaze.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_ClangorousSoulblaze[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/clangorous_soulblaze.bin.lz");
|
||||
|
||||
//const u32 gBattleAnimBgImage_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/dark_void.4bpp.lz");
|
||||
//const u32 gBattleAnimBgPalette_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/dark_void.gbapal.lz");
|
||||
//const u32 gBattleAnimBgTilemap_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/dark_void.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgPalette_DynamaxCannon[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/dynamax_cannon.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/electric_terrain.4bpp.lz");
|
||||
@ -1463,14 +1453,6 @@ const u32 gBattleAnimBgTilemap_FocusBlast[] = INCBIN_U32("graphics/battle_anims/
|
||||
|
||||
const u32 gBattleAnimBgPalette_GarbageFalls[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/garbage_falls.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.bin.lz");
|
||||
@ -1497,8 +1479,6 @@ const u32 gBattleAnimBgImage_LeafStorm[] = INCBIN_U32("graphics/battle_anims/bac
|
||||
const u32 gBattleAnimBgPalette_LeafStorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/leaf_storm.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_LeafStorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/leaf_storm.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgPalette_MagicRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/magic_room.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_MaliciousMoonsault[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/malicious_moonsault.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_MaliciousMoonsault[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/malicious_moonsault.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_MaliciousMoonsault[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/malicious_moonsault.bin.lz");
|
||||
@ -1553,6 +1533,10 @@ const u32 gBattleAnimBgImage_TrickRoom[] = INCBIN_U32("graphics/battle_anims/bac
|
||||
const u32 gBattleAnimBgPalette_TrickRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/trick_room.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_TrickRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/trick_room.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgPalette_MagicRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/magic_room.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimBgPalette_WonderRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/wonder_room.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_TwinkleTackle[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/twinkle_tackle.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_TwinkleTackle[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/twinkle_tackle.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_TwinkleTackle[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/twinkle_tackle.bin.lz");
|
||||
@ -1565,7 +1549,8 @@ const u32 gBattleAnimBgImage_Waterfall[] = INCBIN_U32("graphics/battle_anims/bac
|
||||
const u32 gBattleAnimBgPalette_Waterfall[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/waterfall.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_Waterfall[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/waterfall.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgPalette_WonderRoom[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/wonder_room.gbapal.lz");
|
||||
const u32 gBattleAnimBgPalette_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/dark_void.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_DarkVoid[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/dark_void.bin.lz");
|
||||
|
||||
const u32 gBattleAnimBgImage_ZMoveActivate[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/zmove_activate.4bpp.lz");
|
||||
const u32 gBattleAnimBgPalette_ZMoveActivate[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/zmove_activate.gbapal.lz");
|
||||
|
@ -41,6 +41,8 @@ static bool8 IsAbilityAllowingEncounter(u8 level);
|
||||
// EWRAM vars
|
||||
EWRAM_DATA static u8 sWildEncountersDisabled = 0;
|
||||
EWRAM_DATA static u32 sFeebasRngValue = 0;
|
||||
EWRAM_DATA bool8 gIsFishingEncounter = 0;
|
||||
EWRAM_DATA bool8 gIsSurfingEncounter = 0;
|
||||
|
||||
#include "data/wild_encounters.h"
|
||||
|
||||
@ -652,6 +654,7 @@ bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavi
|
||||
{
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
|
||||
{
|
||||
gIsSurfingEncounter = TRUE;
|
||||
if (TryDoDoubleWildBattle())
|
||||
{
|
||||
struct Pokemon mon1 = gEnemyParty[0];
|
||||
@ -803,6 +806,7 @@ void FishingWildEncounter(u8 rod)
|
||||
}
|
||||
IncrementGameStat(GAME_STAT_FISHING_CAPTURES);
|
||||
SetPokemonAnglerSpecies(species);
|
||||
gIsFishingEncounter = TRUE;
|
||||
BattleSetup_StartWildBattle();
|
||||
}
|
||||
|
||||
|