merge with be

This commit is contained in:
ghoulslash 2021-10-28 17:03:10 -04:00
commit f342e7c590
38 changed files with 1474 additions and 324 deletions

View File

@ -1543,6 +1543,11 @@
.byte \case
.endm
.macro handleprimalreversion battler:req, case:req
various \battler, VARIOUS_HANDLE_PRIMAL_REVERSION
.byte \case
.endm
.macro handleformchange battler:req, case:req
various \battler, VARIOUS_HANDLE_FORM_CHANGE
.byte \case
@ -1772,6 +1777,11 @@
.macro tryactivategrimneigh, battler:req
various \battler, VARIOUS_TRY_ACTIVATE_GRIM_NEIGH
.endm
.macro consumeberry battler:req, restoreItem=FALSE
various \battler, VARIOUS_CONSUME_BERRY
.byte \restoreItem
.endm
.macro activateitemeffects battler:req
various \battler, VARIOUS_MOVEEND_ITEM_EFFECTS
@ -1828,7 +1838,36 @@
.macro trytoclearprimalweather
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
.endm
.macro getrototillertargets ptr:req
various BS_ATTACKER, VARIOUS_GET_ROTOTILLER_TARGETS
.4byte \ptr
.endm
.macro jumpifnotrototilleraffected battler:req, ptr:req
various \battler, VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED
.4byte \ptr
.endm
.macro tryactivatebattlebond battler:req
various \battler, VARIOUS_TRY_ACTIVATE_BATTLE_BOND
.endm
.macro jumpifcantreverttoprimal ptr:req
various BS_ATTACKER, VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL
.4byte \ptr
.endm
.macro applyplasmafists
various BS_ATTACKER, VARIOUS_APPLY_PLASMA_FISTS
.endm
.macro jumpifspecies battler:req, species:req, ptr:req
various \battler, VARIOUS_JUMP_IF_SPECIES
.2byte \species
.4byte \ptr
.endm
@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7

View File

@ -4,6 +4,7 @@
#include "constants/songs.h"
#include "constants/moves.h"
#include "constants/pokemon.h"
#include "constants/items.h"
.include "asm/macros.inc"
.include "asm/macros/battle_anim_script.inc"
.include "constants/constants.inc"
@ -824,6 +825,7 @@ gBattleAnims_General::
.4byte General_TotemFlare @ B_ANIM_TOTEM_FLARE
.4byte General_GulpMissile @ B_ANIM_GULP_MISSILE
.4byte General_StrongWinds @ B_ANIM_STRONG_WINDS
.4byte General_PrimalReversion @ B_ANIM_PRIMAL_REVERSION
.align 2
gBattleAnims_Special::
@ -5374,6 +5376,31 @@ ScaldHitSplats:
return
Move_SHELL_SMASH:
loadspritegfx ANIM_TAG_SHELL_RIGHT
loadspritegfx ANIM_TAG_SHELL_LEFT
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_ROCKS
loadspritegfx ANIM_TAG_HANDS_AND_FEET
playsewithpan SE_M_SCRATCH, SOUND_PAN_ATTACKER
createsprite gShellSmashRightShellSpriteTemplate, ANIM_ATTACKER, 2, 0xffd7, 0x0, 0x2, 0x333, 0x0, 0xa
createsprite gShellSmashLeftShellSpriteTemplate, ANIM_ATTACKER, 2, 0x20, 0x0, 0x6, 0xfccd, 0x0, 0xa
delay 10
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x1, 0x1
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 3, 0x0, 0x0, 0x8, 0x1, 0x0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, 1, 3, 0, 5, 1
waitforvisualfinish
playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x14, 0x18, 0xe, 0x2
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x5, 0x0, 0xffec, 0x18, 0xe, 0x1
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x5, 0x14, 0xffe8, 0xe, 0x2
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0xfffb, 0x0, 0xffec, 0xffe8, 0xe, 0x2
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0xfffb, 0x1e, 0x12, 0x8, 0x2
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x1e, 0xffee, 0x8, 0x2
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0xffe2, 0x12, 0x8, 0x2
createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0xffe2, 0xffee, 0x8, 0x2
createvisualtask AnimTask_ShakeMon, 2, 1, 0, 3, 7, 1
waitforvisualfinish
end
Move_HEAL_PULSE:
@ -24399,6 +24426,17 @@ General_TotemFlare::
clearmonbg ANIM_ATTACKER
end
RainbowEndureEffect:
launchtemplate gBlueEndureEnergySpriteTemplate 0x2 0x4 0x0 0xffe8 0x1a 0x2
delay 0x3
launchtemplate gEndureEnergySpriteTemplate 0x2 0x4 0x0 0xe 0x1c 0x1 @Red Buff
delay 0x3
launchtemplate gGreenEndureEnergySpriteTemplate 0x2 0x4 0x0 0xfffb 0xa 0x2
delay 0x3
launchtemplate gYellowEndureEnergySpriteTemplate 0x2 0x4 0x0 0x1c 0x1a 0x3
delay 0x3
return
General_GulpMissile: @ Tackle anim (placeholder)
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_ATTACKER
@ -24424,15 +24462,77 @@ General_StrongWinds::
stopsound
end
RainbowEndureEffect:
launchtemplate gBlueEndureEnergySpriteTemplate 0x2 0x4 0x0 0xffe8 0x1a 0x2
delay 0x3
launchtemplate gEndureEnergySpriteTemplate 0x2 0x4 0x0 0xe 0x1c 0x1 @Red Buff
delay 0x3
launchtemplate gGreenEndureEnergySpriteTemplate 0x2 0x4 0x0 0xfffb 0xa 0x2
delay 0x3
launchtemplate gYellowEndureEnergySpriteTemplate 0x2 0x4 0x0 0x1c 0x1a 0x3
delay 0x3
General_PrimalReversion::
launchtask AnimTask_PrimalReversion 0x5 0x0
jumpargeq 0x0, ITEM_RED_ORB, General_PrimalReversion_Omega
jumpargeq 0x1, ITEM_BLUE_ORB, General_PrimalReversion_Alpha
General_PrimalReversion_Alpha:
loadspritegfx ANIM_TAG_ALPHA_STONE
loadspritegfx ANIM_TAG_PRIMAL_PARTICLES
loadspritegfx ANIM_TAG_ALPHA_SYMBOL
monbg ANIM_ATTACKER
setalpha 12, 8
loopsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER, 13, 3
createvisualtask AnimTask_BlendColorCycle, 2, 2, 0, 6, 0, 11, RGB(31, 31, 11)
call PrimalReversionParticles
call PrimalReversionParticles
call PrimalReversionParticles
waitforvisualfinish
playsewithpan SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER
createsprite gAlphaStoneSpriteTemplate, ANIM_ATTACKER, 41, 0, 0, 0, 0
delay 20
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
waitforvisualfinish
createvisualtask AnimTask_TransformMon, 2, 0, 1
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
createvisualtask AnimTask_HorizontalShake, 5, 1, 5, 14
waitforvisualfinish
createsprite gAlphaSymbolSpriteTemplate ANIM_ATTACKER, 2
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
General_PrimalReversion_Omega:
loadspritegfx ANIM_TAG_OMEGA_STONE
loadspritegfx ANIM_TAG_PRIMAL_PARTICLES
loadspritegfx ANIM_TAG_OMEGA_SYMBOL
monbg ANIM_ATTACKER
setalpha 12, 8
loopsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER, 13, 3
createvisualtask AnimTask_BlendColorCycle, 2, 2, 0, 6, 0, 11, RGB(31, 31, 11)
call PrimalReversionParticles
call PrimalReversionParticles
call PrimalReversionParticles
waitforvisualfinish
playsewithpan SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER
createsprite gOmegaStoneSpriteTemplate, ANIM_ATTACKER, 41, 0, 0, 0, 0
delay 20
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
waitforvisualfinish
createvisualtask AnimTask_TransformMon, 2, 0, 1
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
createvisualtask AnimTask_HorizontalShake, 5, 1, 5, 14
waitforvisualfinish
createsprite gOmegaSymbolSpriteTemplate ANIM_ATTACKER, 2
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
PrimalReversionParticles:
createsprite gPrimalParticlesSpriteTemplate, ANIM_ATTACKER, 2, 40, -10, 13
delay 3
createsprite gPrimalParticlesSpriteTemplate, ANIM_ATTACKER, 2, -35, -10, 13
delay 3
createsprite gPrimalParticlesSpriteTemplate, ANIM_ATTACKER, 2, 15, -40, 13
delay 3
createsprite gPrimalParticlesSpriteTemplate, ANIM_ATTACKER, 2, -10, -32, 13
delay 3
createsprite gPrimalParticlesSpriteTemplate, ANIM_ATTACKER, 2, 25, -20, 13
delay 3
createsprite gPrimalParticlesSpriteTemplate, ANIM_ATTACKER, 2, -40, -20, 13
delay 3
createsprite gPrimalParticlesSpriteTemplate, ANIM_ATTACKER, 2, 5, -40, 13
delay 3
return
SnatchMoveTrySwapFromSubstitute:

View File

@ -11,6 +11,7 @@
#include "constants/game_stat.h"
#include "constants/trainers.h"
#include "constants/battle_config.h"
#include "constants/species.h"
.include "asm/macros.inc"
.include "asm/macros/battle_script.inc"
.include "constants/constants.inc"
@ -380,6 +381,238 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT
.4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT
.4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25
.4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS
.4byte BattleScript_EffectDefenseDownHit @ EFFECT_GRAV_APPLE
.4byte BattleScript_EffectEvasionUpHit @ EFFECT_EVASION_UP_HIT
.4byte BattleScript_EffectDoubleIronBash @ EFFECT_DOUBLE_IRON_BASH
.4byte BattleScript_EffectGlitzyGlow @ EFFECT_GLITZY_GLOW
.4byte BattleScript_EffectBaddyBad @ EFFECT_BADDY_BAD
.4byte BattleScript_EffectSappySeed @ EFFECT_SAPPY_SEED
.4byte BattleScript_EffectFreezyFrost @ EFFECT_FREEZY_FROST
.4byte BattleScript_EffectSparklySwirl @ EFFECT_SPARKLY_SWIRL
.4byte BattleScript_EffectPlasmaFists @ EFFECT_PLASMA_FISTS
.4byte BattleScript_EffectHyperspaceFury @ EFFECT_HYPERSPACE_FURY
BattleScript_EffectHyperspaceFury:
jumpifspecies BS_ATTACKER, SPECIES_TREECKO, BattleScript_EffectHyperspaceFuryUnbound
jumpifspecies BS_ATTACKER, SPECIES_MUDKIP, BattleScript_ButHoopaCantUseIt
printstring STRINGID_BUTPOKEMONCANTUSETHEMOVE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectHyperspaceFuryUnbound::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
pause B_WAIT_TIME_LONG
ppreduce
setmoveeffect MOVE_EFFECT_FEINT
seteffectwithchance
setmoveeffect MOVE_EFFECT_DEF_MINUS_1 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
goto BattleScript_HitFromCritCalc
BattleScript_ButHoopaCantUseIt:
printstring STRINGID_BUTHOOPACANTUSEIT
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_HyperspaceFuryRemoveProtect::
printstring STRINGID_BROKETHROUGHPROTECTION
waitmessage B_WAIT_TIME_LONG
return
BattleScript_EffectPlasmaFists:
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
tryfaintmon BS_TARGET, FALSE, NULL
applyplasmafists
printstring STRINGID_IONDELUGEON
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectSparklySwirl:
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
tryfaintmon BS_TARGET, FALSE, NULL
healpartystatus
waitstate
updatestatusicon BS_ATTACKER_WITH_PARTNER
waitstate
goto BattleScript_MoveEnd
BattleScript_EffectFreezyFrost:
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
tryfaintmon BS_TARGET, FALSE, NULL
normalisebuffs
printstring STRINGID_STATCHANGESGONE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectSappySeed:
jumpifstatus3 BS_TARGET, STATUS3_LEECHSEED, BattleScript_EffectHit
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
tryfaintmon BS_TARGET, FALSE, NULL
jumpifhasnohp BS_TARGET, BattleScript_MoveEnd
setseeded
printfromtable gLeechSeedStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectBaddyBad:
jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_REFLECT, BattleScript_EffectHit
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
tryfaintmon BS_TARGET, FALSE, NULL
setreflect
printfromtable gReflectLightScreenSafeguardStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectGlitzyGlow:
jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_LIGHTSCREEN, BattleScript_EffectHit
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
tryfaintmon BS_TARGET, FALSE, NULL
setlightscreen
printfromtable gReflectLightScreenSafeguardStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectDoubleIronBash:
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
setmultihitcounter 2
initmultihitstring
sethword sMULTIHIT_EFFECT, MOVE_EFFECT_FLINCH
goto BattleScript_MultiHitLoop
BattleScript_EffectEvasionUpHit:
setmoveeffect MOVE_EFFECT_EVS_PLUS_1 | MOVE_EFFECT_AFFECTS_USER
goto BattleScript_EffectHit
BattleScript_EffectStuffCheeks::
attackcanceler
attackstring
ppreduce
jumpifnotberry BS_ATTACKER, BattleScript_ButItFailed
attackanimation
waitanimation
BattleScript_StuffCheeksEatBerry:
setbyte sBERRY_OVERRIDE, TRUE
orword gHitMarker, HITMARKER_NO_ANIMATIONS
consumeberry BS_ATTACKER
bicword gHitMarker, HITMARKER_NO_ANIMATIONS
setbyte sBERRY_OVERRIDE, FALSE
setstatchanger STAT_DEF, 2, FALSE
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_StuffCheeksEnd
setgraphicalstatchangevalues
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_StuffCheeksEnd @ cant raise def
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_StuffCheeksEnd:
goto BattleScript_MoveEnd
BattleScript_EffectDecorate:
attackcanceler
@ -636,6 +869,11 @@ BattleScript_MoveEffectIncinerate::
BattleScript_MoveEffectBugBite::
printstring STRINGID_BUGBITE
waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_NO_ANIMATIONS
setbyte sBERRY_OVERRIDE, TRUE @ override the requirements for eating berries
consumeberry BS_ATTACKER, TRUE @ consume the berry, then restore the item from changedItems
bicword gHitMarker, HITMARKER_NO_ANIMATIONS
setbyte sBERRY_OVERRIDE, FALSE
return
BattleScript_EffectCoreEnforcer:
@ -947,27 +1185,24 @@ BattleScript_FlowerShieldMoveTargetEnd:
moveendto MOVEEND_NEXT_TARGET
jumpifnexttargetvalid BattleScript_FlowerShieldLoop
end
BattleScript_EffectRototiller:
attackcanceler
attackstring
ppreduce
selectfirstvalidtarget
BattleScript_RototillerLoop:
movevaluescleanup
jumpifnotgrounded BS_TARGET, BattleScript_RototillerNoEffect
jumpiftype BS_TARGET, TYPE_GRASS, BattleScript_RototillerLoop2
BattleScript_RototillerNoEffect:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NOEFFECTONTARGET
waitmessage B_WAIT_TIME_LONG
goto BattleScript_RototillerMoveTargetEnd
BattleScript_RototillerLoop2:
jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerDoMoveAnim
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats
BattleScript_RototillerDoMoveAnim::
getrototillertargets BattleScript_ButItFailed
@ at least one battler is affected
attackanimation
waitanimation
savetarget
setbyte gBattlerTarget, 0
BattleScript_RototillerLoop:
movevaluescleanup
jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerCheckAffected
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats
BattleScript_RototillerCheckAffected:
jumpifnotrototilleraffected BS_TARGET, BattleScript_RototillerNoEffect
BattleScript_RototillerAffected:
setbyte sSTAT_ANIM_PLAYED, FALSE
playstatchangeanimation BS_TARGET, BIT_ATK | BIT_SPATK, 0
setstatchanger STAT_ATK, 1, FALSE
@ -983,13 +1218,22 @@ BattleScript_RototillerTrySpAtk::
waitmessage B_WAIT_TIME_LONG
BattleScript_RototillerMoveTargetEnd:
moveendto MOVEEND_NEXT_TARGET
jumpifnexttargetvalid BattleScript_RototillerLoop
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_RototillerLoop
end
BattleScript_RototillerCantRaiseMultipleStats:
copybyte gBattlerAttacker, gBattlerTarget
printstring STRINGID_STATSWONTINCREASE2
waitmessage B_WAIT_TIME_LONG
goto BattleScript_RototillerMoveTargetEnd
BattleScript_RototillerNoEffect:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NOEFFECTONTARGET
waitmessage B_WAIT_TIME_LONG
goto BattleScript_RototillerMoveTargetEnd
BattleScript_EffectBestow:
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, NO_ACC_CALC_CHECK_LOCK_ON
@ -2981,7 +3225,7 @@ BattleScript_EffectRecoilIfMiss::
accuracycheck BattleScript_MoveMissedDoDamage, ACC_CURR_MOVE
.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4
typecalc
jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveMissedDoDamage
jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveMissedDoDamage
.endif
goto BattleScript_HitFromAtkString
BattleScript_MoveMissedDoDamage::
@ -2992,7 +3236,7 @@ BattleScript_MoveMissedDoDamage::
resultmessage
waitmessage B_WAIT_TIME_LONG
.if B_CRASH_IF_TARGET_IMMUNE < GEN_4
jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd
jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd
.endif
printstring STRINGID_PKMNCRASHED
waitmessage B_WAIT_TIME_LONG
@ -3193,7 +3437,11 @@ BattleScript_EffectParalyze:
jumpifleafguard BattleScript_LeafGuardProtects
jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects
jumpifsubstituteblocks BattleScript_ButItFailed
.if B_GLARE_GHOST >= GEN_4
jumpifmove MOVE_GLARE, BattleScript_BattleScript_EffectParalyzeNoTypeCalc
.endif
typecalc
BattleScript_BattleScript_EffectParalyzeNoTypeCalc:
jumpifmovehadnoeffect BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed
tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
@ -3734,7 +3982,7 @@ BattleScript_TripleKickPrintStrings::
resultmessage
waitmessage B_WAIT_TIME_LONG
jumpifbyte CMP_EQUAL, sMULTIHIT_STRING + 4, 0, BattleScript_TripleKickEnd
jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_TripleKickEnd
jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_TripleKickEnd
copyarray gBattleTextBuff1, sMULTIHIT_STRING, 6
printstring STRINGID_HITXTIMES
waitmessage B_WAIT_TIME_LONG
@ -3759,6 +4007,9 @@ BattleScript_EffectMeanLook::
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
jumpifstatus2 BS_TARGET, STATUS2_ESCAPE_PREVENTION, BattleScript_ButItFailed
jumpifsubstituteblocks BattleScript_ButItFailed
.if B_GHOSTS_ESCAPE >= GEN_6
jumpiftype BS_TARGET, TYPE_GHOST, BattleScript_ButItFailed
.endif
attackanimation
waitanimation
setmoveeffect MOVE_EFFECT_PREVENT_ESCAPE
@ -4081,6 +4332,7 @@ BattleScript_EffectRapidSpin::
waitmessage B_WAIT_TIME_LONG
resultmessage
waitmessage B_WAIT_TIME_LONG
jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd
setmoveeffect MOVE_EFFECT_RAPIDSPIN | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
seteffectwithchance
setstatchanger STAT_SPEED, 1, FALSE
@ -4096,8 +4348,8 @@ BattleScript_EffectRapidSpinEnd::
end
.else
setmoveeffect MOVE_EFFECT_RAPIDSPIN | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
.endif
goto BattleScript_EffectHit
.endif
BattleScript_EffectSonicboom::
attackcanceler
@ -5288,6 +5540,7 @@ BattleScript_FaintTarget::
tryactivatemoxie BS_ATTACKER @ and chilling neigh, as one ice rider
tryactivatebeastboost BS_ATTACKER
tryactivategrimneigh BS_ATTACKER @ and as one shadow rider
tryactivatebattlebond BS_ATTACKER
trytrainerslidefirstdownmsg BS_TARGET
return
@ -5600,6 +5853,9 @@ BattleScript_DoSwitchOut::
hidepartystatussummary BS_ATTACKER
switchinanim BS_ATTACKER, FALSE
waitstate
jumpifcantreverttoprimal BattleScript_DoSwitchOut2
call BattleScript_PrimalReversionRet
BattleScript_DoSwitchOut2:
switchineffects BS_ATTACKER
moveendcase MOVEEND_STATUS_IMMUNITY_ABILITIES
moveendcase MOVEEND_MIRROR_MOVE
@ -6391,6 +6647,10 @@ BattleScript_SelectingNotAllowedMoveGravity::
printselectionstring STRINGID_GRAVITYPREVENTSUSAGE
endselectionscript
BattleScript_SelectingNotAllowedStuffCheeks::
printselectionstring STRINGID_STUFFCHEEKSCANTSELECT
endselectionscript
BattleScript_SelectingNotAllowedBelch::
printselectionstring STRINGID_BELCHCANTSELECT
endselectionscript
@ -6626,6 +6886,33 @@ BattleScript_WishMegaEvolution::
switchinabilities BS_ATTACKER
end2
BattleScript_PrimalReversion::
printstring STRINGID_EMPTYSTRING3
waitmessage 1
setbyte gIsCriticalHit, 0
handleprimalreversion BS_ATTACKER, 0
handleprimalreversion BS_ATTACKER, 1
playanimation BS_ATTACKER, B_ANIM_PRIMAL_REVERSION, NULL
waitanimation
handleprimalreversion BS_ATTACKER, 2
printstring STRINGID_PKMNREVERTEDTOPRIMAL
waitmessage B_WAIT_TIME_LONG
switchinabilities BS_ATTACKER
end2
BattleScript_PrimalReversionRet::
printstring STRINGID_EMPTYSTRING3
waitmessage 1
setbyte gIsCriticalHit, 0
handleprimalreversion BS_ATTACKER, 0
handleprimalreversion BS_ATTACKER, 1
playanimation BS_ATTACKER, B_ANIM_PRIMAL_REVERSION, NULL
waitanimation
handleprimalreversion BS_ATTACKER, 2
printstring STRINGID_PKMNREVERTEDTOPRIMAL
waitmessage B_WAIT_TIME_LONG
return
BattleScript_AttackerFormChange::
pause 5
copybyte gBattlerAbility, gBattlerAttacker
@ -7519,6 +7806,7 @@ BattleScript_MoveStatDrain::
waitanimation
printstring STRINGID_TARGETABILITYSTATRAISE
waitmessage B_WAIT_TIME_LONG
clearsemiinvulnerablebit
tryfaintmon BS_ATTACKER, FALSE, NULL
goto BattleScript_MoveEnd
@ -8487,6 +8775,14 @@ BattleScript_QuickClawActivation::
waitmessage B_WAIT_TIME_LONG
end2
BattleScript_QuickDrawActivation::
printstring STRINGID_EMPTYSTRING3
waitmessage 1
call BattleScript_AbilityPopUp
printstring STRINGID_CANACTFASTERTHANKSTO
waitmessage B_WAIT_TIME_LONG
end2
BattleScript_CustapBerryActivation::
printstring STRINGID_EMPTYSTRING3
waitmessage 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

View File

@ -151,6 +151,7 @@ struct ProtectStruct
u32 disableEjectPack:1;
u32 statFell:1;
u32 pranksterElevated:1;
u32 quickDraw:1;
u32 physicalDmg;
u32 specialDmg;
u8 physicalBattlerId;
@ -175,6 +176,7 @@ struct SpecialStatus
u8 instructedChosenTarget:3;
u8 berryReduced:1;
u8 gemBoost:1;
u8 rototillerAffected:1; // to be affected by rototiller
u8 gemParam;
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
u8 dancerUsedMove:1;
@ -210,6 +212,7 @@ struct SideTimer
u8 tailwindBattlerId;
u8 luckyChantTimer;
u8 luckyChantBattlerId;
u8 retaliateTimer;
};
struct FieldTimer
@ -462,10 +465,14 @@ struct MegaEvolutionData
bool8 alreadyEvolved[4]; // Array id is used for mon position.
u16 evolvedSpecies[MAX_BATTLERS_COUNT];
u16 playerEvolvedSpecies;
u8 primalRevertedPartyIds[2]; // As flags using gBitTable;
u16 primalRevertedSpecies[MAX_BATTLERS_COUNT];
u16 playerPrimalRevertedSpecies;
u8 battlerId;
bool8 playerSelect;
u8 triggerSpriteId;
bool8 isWishMegaEvo;
bool8 isPrimalReversion;
};
struct Illusion
@ -489,7 +496,7 @@ struct BattleStruct
u8 turnEffectsBattlerId;
u8 turnCountersTracker;
u16 wrappedMove[MAX_BATTLERS_COUNT];
u8 moveTarget[MAX_BATTLERS_COUNT];
u16 moveTarget[MAX_BATTLERS_COUNT];
u8 expGetterMonId;
u8 wildVictorySong;
u8 dynamicMoveType;
@ -594,6 +601,7 @@ struct BattleStruct
bool8 spriteIgnore0Hp;
struct Illusion illusion[MAX_BATTLERS_COUNT];
s8 aiFinalScore[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // AI, target, moves to make debugging easier
s32 aiSimulatedDamage[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // attacker, target, move to make debugging easier
u8 soulheartBattlerId;
u8 friskedBattler; // Frisk needs to identify 2 battlers in double battles.
bool8 friskedAbility; // If identifies two mons, show the ability pop-up only once.
@ -630,6 +638,16 @@ struct BattleStruct
gBattleMons[battlerId].type3 = TYPE_MYSTERY; \
}
#define IS_BATTLER_PROTECTED(battlerId)(gProtectStructs[battlerId].protected \
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD \
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD \
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD \
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK \
|| gProtectStructs[battlerId].spikyShielded \
|| gProtectStructs[battlerId].kingsShielded \
|| gProtectStructs[battlerId].banefulBunkered \
|| gProtectStructs[battlerId].obstructed) \
#define GET_STAT_BUFF_ID(n)((n & 7)) // first three bits 0x1, 0x2, 0x4
#define GET_STAT_BUFF_VALUE_WITH_SIGN(n)((n & 0xF8))
#define GET_STAT_BUFF_VALUE(n)(((n >> 3) & 0xF)) // 0x8, 0x10, 0x20, 0x40
@ -678,6 +696,7 @@ struct BattleScripting
bool8 fixedPopup; // Force ability popup to stick until manually called back
u16 abilityPopupOverwrite;
u8 switchCase; // Special switching conditions, eg. red card
u8 overrideBerryRequirements;
};
// rom_80A5C6C
@ -857,6 +876,7 @@ extern u8 gUnusedFirstBattleVar2;
extern u32 gSideStatuses[2];
extern struct SideTimer gSideTimers[2];
extern u32 gStatuses3[MAX_BATTLERS_COUNT];
extern u32 gStatuses4[MAX_BATTLERS_COUNT];
extern struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT];
extern u16 gPauseCounterBattle;
extern u16 gPaydayMoney;

View File

@ -442,6 +442,7 @@ extern const union AffineAnimCmd *const gAffineAnims_SpinningHandOrFoot[];
extern const union AnimCmd *const gAnims_RevengeBigScratch[];
// battle_anim_rock.c
extern const union AnimCmd *const gAnims_FlyingRock[];
extern const union AffineAnimCmd *const gAffineAnims_Whirlpool[];
extern const union AffineAnimCmd *const gAffineAnims_BasicRock[];
void AnimParticleInVortex(struct Sprite *sprite);
@ -449,6 +450,7 @@ void AnimFallingRock(struct Sprite *sprite);
void AnimRaiseSprite(struct Sprite *sprite);
void AnimFallingRock_Step(struct Sprite *sprite);
void AnimFlyingSandCrescent(struct Sprite *sprite);
void AnimRockFragment(struct Sprite *);
// battle_anim_dark.c
void AnimClawSlash(struct Sprite *sprite);

View File

@ -39,16 +39,20 @@ enum
#define TAG_STATUS_SUMMARY_BAR_TILE 0xD70C
#define TAG_STATUS_SUMMARY_BALLS_TILE 0xD714
#define TAG_MEGA_TRIGGER_TILE 0xD777
#define TAG_MEGA_TRIGGER_TILE 0xD777
#define TAG_MEGA_INDICATOR_TILE 0xD778
#define TAG_ALPHA_INDICATOR_TILE 0xD779
#define TAG_OMEGA_INDICATOR_TILE 0xD77A
#define TAG_HEALTHBOX_PAL 0xD6FF
#define TAG_HEALTHBAR_PAL 0xD704
#define TAG_STATUS_SUMMARY_BAR_PAL 0xD710
#define TAG_STATUS_SUMMARY_BALLS_PAL 0xD712
#define TAG_MEGA_TRIGGER_PAL 0xD777
#define TAG_MEGA_INDICATOR_PAL 0xD778
#define TAG_MEGA_TRIGGER_PAL 0xD777
#define TAG_MEGA_INDICATOR_PAL 0xD778
#define TAG_ALPHA_INDICATOR_PAL 0xD779
#define TAG_OMEGA_INDICATOR_PAL 0xD77A
enum
{

View File

@ -37,6 +37,7 @@ bool32 TryResetBattlerStatChanges(u8 battler);
bool32 CanCamouflage(u8 battlerId);
u16 GetNaturePowerMove(void);
void StealTargetItem(u8 battlerStealer, u8 battlerItem);
u8 GetCatchingBattler(void);
extern void (* const gBattleScriptingCommandsTable[])(void);
extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4];

View File

@ -298,6 +298,7 @@ extern const u8 BattleScript_ProteanActivates[];
extern const u8 BattleScript_DazzlingProtected[];
extern const u8 BattleScript_MoveUsedPsychicTerrainPrevents[];
extern const u8 BattleScript_MoveUsedPowder[];
extern const u8 BattleScript_SelectingNotAllowedStuffCheeks[];
extern const u8 BattleScript_SelectingNotAllowedBelch[];
extern const u8 BattleScript_SelectingNotAllowedBelchInPalace[];
extern const u8 BattleScript_PsychicSurgeActivates[];
@ -365,6 +366,7 @@ extern const u8 BattleScript_PerishBodyActivates[];
extern const u8 BattleScript_ActivateAsOne[];
extern const u8 BattleScript_RaiseStatOnFaintingTarget[];
extern const u8 BattleScript_QuickClawActivation[];
extern const u8 BattleScript_QuickDrawActivation[];
extern const u8 BattleScript_CustapBerryActivation[];
extern const u8 BattleScript_MicleBerryActivateEnd2[];
extern const u8 BattleScript_MicleBerryActivateRet[];
@ -398,6 +400,8 @@ extern const u8 BattleScript_MysteriousAirCurrentBlowsOn[];
extern const u8 BattleScript_AttackWeakenedByStrongWinds[];
extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[];
extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
extern const u8 BattleScript_PrimalReversion[];
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
extern const u8 BattleScript_WanderingSpiritActivates[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -32,6 +32,7 @@
#define ITEMEFFECT_TARGET 0x5
#define ITEMEFFECT_ORBS 0x6
#define ITEMEFFECT_LIFEORB_SHELLBELL 0x7
#define ITEMEFFECT_BATTLER_MOVE_END 0x8 // move end effects for just the battler, not whole field
#define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK)))
@ -108,7 +109,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn);
void ClearFuryCutterDestinyBondGrudge(u8 battlerId);
void HandleAction_RunBattleScript(void);
u32 SetRandomTarget(u32 battlerId);
u8 GetMoveTarget(u16 move, u8 setTarget);
u32 GetMoveTarget(u16 move, u8 setTarget);
u8 IsMonDisobedient(void);
u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating);
u32 GetBattlerHoldEffectParam(u8 battlerId);
@ -153,7 +154,7 @@ bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind);
bool32 TryRoomService(u8 battlerId);
void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
void DoBurmyFormChange(u32 monId);
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef);
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
// ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability);

View File

@ -169,10 +169,12 @@
#define STATUS3_HEAL_BLOCK (1 << 27)
#define STATUS3_AQUA_RING (1 << 28)
#define STATUS3_LASER_FOCUS (1 << 29)
#define STATUS3_ELECTRIFIED (1 << 30)
#define STATUS3_POWER_TRICK (1 << 31)
#define STATUS3_POWER_TRICK (1 << 30)
#define STATUS3_SEMI_INVULNERABLE (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER | STATUS3_PHANTOM_FORCE)
#define STATUS4_ELECTRIFIED (1 << 0)
#define STATUS4_PLASMA_FISTS (1 << 1)
#define HITMARKER_x10 (1 << 4)
#define HITMARKER_x20 (1 << 5)
#define HITMARKER_DESTINYBOND (1 << 6)
@ -386,5 +388,6 @@
#define MOVE_TARGET_FOES_AND_ALLY 0x20
#define MOVE_TARGET_OPPONENTS_FIELD 0x40
#define MOVE_TARGET_ALLY 0x80
#define MOVE_TARGET_ALL_BATTLERS (0x100 | MOVE_TARGET_USER)
#endif // GUARD_CONSTANTS_BATTLE_H

View File

@ -391,6 +391,9 @@
#define ANIM_TAG_DREEPY (ANIM_SPRITES_START + 379)
#define ANIM_TAG_ICE_ROCK_SINGLE (ANIM_SPRITES_START + 380)
#define ANIM_TAG_STONE_PILLAR_MULTI (ANIM_SPRITES_START + 381)
#define ANIM_TAG_ALPHA_SYMBOL (ANIM_SPRITES_START + 382)
#define ANIM_TAG_OMEGA_SYMBOL (ANIM_SPRITES_START + 383)
#define ANIM_TAG_PRIMAL_PARTICLES (ANIM_SPRITES_START + 384)
// battlers
#define ANIM_ATTACKER 0
@ -525,6 +528,7 @@
#define B_ANIM_TOTEM_FLARE 28 // Totem boosts aura flare
#define B_ANIM_GULP_MISSILE 29
#define B_ANIM_STRONG_WINDS 30
#define B_ANIM_PRIMAL_REVERSION 31
// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0

View File

@ -45,6 +45,8 @@
#define SPECIES_CRAMORANT_GULPING 10016
#define SPECIES_GRENINJA_BATTLE_BOND 0
#define SPECIES_GRENINJA_ASH 10017
#define SPECIES_HOOPA 0
#define SPECIES_HOOPA_UNBOUND 10018
#endif
// Items with peculiar battle effects.
@ -88,19 +90,42 @@
// 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.
// Exp and stat settings
#define B_EXP_CATCH GEN_7 // In Gen6+, Pokémon get experience from catching.
#define B_TRAINER_EXP_MULTIPLIER GEN_7 // In Gen7+, trainer battles no longer give a 1.5 multiplier to EXP gain.
#define B_SPLIT_EXP GEN_7 // In Gen6+, all participating mon get full experience.
#define B_SCALED_EXP GEN_7 // In Gen5 and Gen7+, experience is weighted by level difference.
#define B_BURN_DAMAGE GEN_7 // In Gen7+, burn damage is 1/16th of max HP instead of 1/8th.
#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_BINDING_DAMAGE GEN_7 // In Gen6+, binding damage is 1/8 of max HP instead of 1/16. (With Binding Band, 1/6 and 1/8 respectively.)
#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.
#define B_RECOIL_IF_MISS_DMG GEN_7 // In Gen5+, Jump Kick and High Jump Kick will always do half of the user's max HP when missing.
#define B_PSYWAVE_DMG GEN_7 // Psywave's damage formula. See Cmd_psywavedamageeffect.
#define B_BADGE_BOOST GEN_7 // In Gen4+, Gym Badges no longer boost a Pokémon's stats.
#define B_MAX_LEVEL_EV_GAINS GEN_7 // In Gen5+, Lv100 Pokémon can obtain Effort Values normally.
#define B_RECALCULATE_STATS GEN_7 // In Gen5+, the stats of the Pokémon who participate in battle are recalculated at the end of each battle.
// Damage settings
#define B_BURN_DAMAGE GEN_7 // In Gen7+, burn damage is 1/16th of max HP instead of 1/8th.
#define B_BINDING_DAMAGE GEN_7 // In Gen6+, binding damage is 1/8 of max HP instead of 1/16. (With Binding Band, 1/6 and 1/8 respectively.)
#define B_PSYWAVE_DMG GEN_7 // Psywave's damage formula. See Cmd_psywavedamageeffect.
#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.
// 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.
#define B_PARALYZE_ELECTRIC GEN_7 // In Gen6+, Electric-type Pokémon can't be paralyzed.
#define B_POWDER_GRASS GEN_7 // In Gen6+, Grass-type Pokémon are immune to powder and spore moves.
#define B_STEEL_RESISTANCES GEN_7 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark-type and Ghost-type moves.
#define B_PRANKSTER_DARK_TYPES GEN_7 // In Gen7+, Prankster-elevated status moves do not affect Dark type Pokémon.
// Turn count settings
#define B_BINDING_TURNS GEN_7 // In Gen5+, binding moves last for 4-5 turns instead of 2-5 turns. (With Grip Claw, 7 and 5 turns respectively.)
#define B_UPROAR_TURNS GEN_7 // In Gen5+, Uproar lasts for 3 turns instead of 2-5 turns.
#define B_DISABLE_TURNS GEN_7 // Disable's turns. See Cmd_disablelastusedattack.
#define B_TAILWIND_TURNS GEN_7 // In Gen5+, Tailwind lasts 4 turns instead of 3.
#define B_SLEEP_TURNS GEN_7 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns.
#define B_TAUNT_TURNS GEN_7 // In Gen5+, Taunt lasts 3 turns if the user acts before the target, or 4 turns if the target acted before the user. In Gen3, taunt lasts 2 turns and in Gen 4, 3-5 turns.
// Move data settings
#define B_UPDATED_MOVE_DATA GEN_8 // Updates move data in gBattleMoves, including Power, Accuracy, PP, stat changes, targets, chances of secondary effects, etc.
@ -108,40 +133,38 @@
#define B_FELL_STINGER_STAT_RAISE GEN_7 // In Gen7+, it raises Atk by 3 stages instead of 2 if it causes the target to faint.
#define B_KINGS_SHIELD_LOWER_ATK GEN_7 // In Gen7+, it lowers Atk by 1 stage instead of 2 of oponents that hit it.
#define B_SPEED_BUFFING_RAPID_SPIN GEN_8 // In Gen8, Rapid Spin raises the user's Speed by 1 stage.
#define B_RECOIL_IF_MISS_DMG GEN_7 // In Gen5+, Jump Kick and High Jump Kick will always do half of the user's max HP when missing.
// Move accuracy settings
#define B_TOXIC_NEVER_MISS GEN_7 // In Gen6+, if Toxic is used by a Poison-type Pokémon, it will never miss.
#define B_MINIMIZE_DMG_ACC GEN_7 // In Gen6+, moves that causes double damage to minimized Pokémon will also skip accuracy checks.
#define B_BLIZZARD_HAIL GEN_7 // In Gen4+, Blizzard bypasses accuracy checks if it's hailing.
// Other move settings
#define B_SOUND_SUBSTITUTE GEN_7 // In Gen6+, sound moves bypass Substitute.
#define B_TOXIC_NEVER_MISS GEN_7 // In Gen6+, if Toxic is used by a Poison-type Pokémon, it will never miss.
#define B_PAYBACK_SWITCH_BOOST GEN_7 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled.
#define B_BINDING_TURNS GEN_7 // In Gen5+, binding moves last for 4-5 turns instead of 2-5 turns. (With Grip Claw, 7 and 5 turns respectively.)
#define B_UPROAR_TURNS GEN_7 // In Gen5+, Uproar lasts for 3 turns instead of 2-5 turns.
#define B_DISABLE_TURNS GEN_7 // Disable's turns. See Cmd_disablelastusedattack.
#define B_INCINERATE_GEMS GEN_7 // In Gen6+, Incinerate can destroy Gems.
#define B_MINIMIZE_DMG_ACC GEN_7 // In Gen6+, moves that causes double damage to minimized Pokémon will also skip accuracy checks.
#define B_PP_REDUCED_BY_SPITE GEN_7 // In Gen4+, Spite reduces the foe's last move's PP by 4, instead of 2 to 5.
#define B_CAN_SPITE_FAIL GEN_7 // In Gen4+, Spite can no longer fail if the foe's last move only has 1 remaining PP.
#define B_CRASH_IF_TARGET_IMMUNE GEN_7 // In Gen4+, The user of Jump Kick or High Jump Kick will "keep going and crash" if it attacks a target that is immune to the move.
#define B_TAILWIND_TIMER GEN_7 // In Gen5+, Tailwind lasts 4 turns instead of 3.
#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_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_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally.
// 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.
#define B_GALE_WINGS GEN_7 // In Gen7+ requires full HP to trigger.
#define B_STANCE_CHANGE_FAIL GEN_7 // In Gen7+, Stance Change fails if the Pokémon is unable to use a move because of confusion, paralysis, etc. In Gen6, it doesn't.
#define B_GHOSTS_ESCAPE GEN_7 // In Gen6+, Ghost-type Pokémon can escape even when blocked by abilities such as Shadow Tag.
#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_UPDATED_INTIMIDATE GEN_8 // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities.
#define B_PRANKSTER_DARK_TYPES GEN_7 // In Gen7+, Prankster-elevated status moves do not affect Dark type Pokémon.
// Item settings
#define B_HP_BERRIES GEN_7 // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.
#define B_BERRIES_INSTANT GEN_7 // In Gen4+, most berries activate on battle start/switch-in if applicable. In Gen3, they only activate either at the move end or turn end.
#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.
// Flag settings
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
@ -159,25 +182,21 @@
#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.
// Item Theft Settings
#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.
// 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.
// Other
#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter.
#define B_SLEEP_TURNS GEN_7 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns.
#define B_PARALYZE_ELECTRIC GEN_7 // In Gen6+, Electric-type Pokémon can't be paralyzed.
#define B_POWDER_GRASS GEN_7 // In Gen6+, Grass-type Pokémon are immune to powder and spore moves.
#define B_STEEL_RESISTANCES GEN_7 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark-type and Ghost-type moves.
#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.
@ -196,8 +215,6 @@
#define B_NEW_IMPACT_PALETTE FALSE // If set to TRUE, it updates the basic 'hit' palette.
#define B_NEW_SURF_PARTICLE_PALETTE FALSE // If set to TRUE, it updates Surf's wave palette.
#define B_HIDE_HEALTHBOXES_DURING_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.
#define B_ENABLE_DEBUG TRUE // If set to TRUE, enables a debug menu to use in battles by pressing the Select button.
#endif // GUARD_CONSTANTS_BATTLE_CONFIG_H

View File

@ -364,7 +364,18 @@
#define EFFECT_SNIPE_SHOT 358
#define EFFECT_TRIPLE_HIT 359
#define EFFECT_RECOIL_HP_25 360
#define EFFECT_STUFF_CHEEKS 361
#define EFFECT_GRAV_APPLE 362
#define EFFECT_EVASION_UP_HIT 363
#define EFFECT_DOUBLE_IRON_BASH 364
#define EFFECT_GLITZY_GLOW 365
#define EFFECT_BADDY_BAD 366
#define EFFECT_SAPPY_SEED 367
#define EFFECT_FREEZY_FROST 368
#define EFFECT_SPARKLY_SWIRL 369
#define EFFECT_PLASMA_FISTS 370
#define EFFECT_HYPERSPACE_FURY 371
#define NUM_BATTLE_MOVE_EFFECTS 361
#define NUM_BATTLE_MOVE_EFFECTS 372
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -38,6 +38,7 @@
#define sFIXED_ABILITY_POPUP gBattleScripting + 0x33
#define sABILITY_OVERWRITE gBattleScripting + 0x34
#define sSWITCH_CASE gBattleScripting + 0x36
#define sBERRY_OVERRIDE gBattleScripting + 0x37
#define cMULTISTRING_CHOOSER gBattleCommunication + 5
#define cMISS_TYPE gBattleCommunication + 6
@ -185,7 +186,15 @@
#define VARIOUS_REMOVE_TERRAIN 113
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115
#define VARIOUS_UPDATE_ABILITY_POPUP 116
#define VARIOUS_GET_ROTOTILLER_TARGETS 116
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 117
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 118
#define VARIOUS_CONSUME_BERRY 119
#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 120
#define VARIOUS_HANDLE_PRIMAL_REVERSION 121
#define VARIOUS_APPLY_PLASMA_FISTS 122
#define VARIOUS_JUMP_IF_SPECIES 123
#define VARIOUS_UPDATE_ABILITY_POPUP 124
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -592,9 +592,14 @@
#define STRINGID_STRONGWINDSDISSIPATED 588
#define STRINGID_MYSTERIOUSAIRCURRENTBLOWSON 589
#define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 590
#define STRINGID_SWAPPEDABILITIES 591
#define STRINGID_STUFFCHEEKSCANTSELECT 592
#define STRINGID_PKMNREVERTEDTOPRIMAL 593
#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 594
#define STRINGID_BUTHOOPACANTUSEIT 595
#define STRINGID_BROKETHROUGHPROTECTION 596
#define STRINGID_SWAPPEDABILITIES 597
#define BATTLESTRINGS_COUNT 592
#define BATTLESTRINGS_COUNT 598
// The below IDs are all indexes into battle message tables,
// used to determine which of a set of messages to print.

View File

@ -281,32 +281,33 @@
#define EV_ITEM_RAISE_LIMIT 100
// Battle move flags
#define FLAG_MAKES_CONTACT (1 << 0)
#define FLAG_PROTECT_AFFECTED (1 << 1)
#define FLAG_MAGIC_COAT_AFFECTED (1 << 2)
#define FLAG_SNATCH_AFFECTED (1 << 3)
#define FLAG_MIRROR_MOVE_AFFECTED (1 << 4)
#define FLAG_KINGS_ROCK_AFFECTED (1 << 5)
#define FLAG_HIGH_CRIT (1 << 6)
#define FLAG_RECKLESS_BOOST (1 << 7)
#define FLAG_IRON_FIST_BOOST (1 << 8)
#define FLAG_SHEER_FORCE_BOOST (1 << 9)
#define FLAG_STRONG_JAW_BOOST (1 << 10)
#define FLAG_MEGA_LAUNCHER_BOOST (1 << 11)
#define FLAG_STAT_STAGES_IGNORED (1 << 12)
#define FLAG_DMG_MINIMIZE (1 << 13)
#define FLAG_DMG_UNDERGROUND (1 << 14)
#define FLAG_DMG_UNDERWATER (1 << 15)
#define FLAG_SOUND (1 << 16)
#define FLAG_BALLISTIC (1 << 17)
#define FLAG_PROTECTION_MOVE (1 << 18)
#define FLAG_POWDER (1 << 19)
#define FLAG_TARGET_ABILITY_IGNORED (1 << 20)
#define FLAG_DANCE (1 << 21)
#define FLAG_DMG_2X_IN_AIR (1 << 22) // If target is in the air, can hit and deal double damage.
#define FLAG_DMG_IN_AIR (1 << 23) // If target is in the air, can hit.
#define FLAG_MAKES_CONTACT (1 << 0)
#define FLAG_PROTECT_AFFECTED (1 << 1)
#define FLAG_MAGIC_COAT_AFFECTED (1 << 2)
#define FLAG_SNATCH_AFFECTED (1 << 3)
#define FLAG_MIRROR_MOVE_AFFECTED (1 << 4)
#define FLAG_KINGS_ROCK_AFFECTED (1 << 5)
#define FLAG_HIGH_CRIT (1 << 6)
#define FLAG_RECKLESS_BOOST (1 << 7)
#define FLAG_IRON_FIST_BOOST (1 << 8)
#define FLAG_SHEER_FORCE_BOOST (1 << 9)
#define FLAG_STRONG_JAW_BOOST (1 << 10)
#define FLAG_MEGA_LAUNCHER_BOOST (1 << 11)
#define FLAG_STAT_STAGES_IGNORED (1 << 12)
#define FLAG_DMG_MINIMIZE (1 << 13)
#define FLAG_DMG_UNDERGROUND (1 << 14)
#define FLAG_DMG_UNDERWATER (1 << 15)
#define FLAG_SOUND (1 << 16)
#define FLAG_BALLISTIC (1 << 17)
#define FLAG_PROTECTION_MOVE (1 << 18)
#define FLAG_POWDER (1 << 19)
#define FLAG_TARGET_ABILITY_IGNORED (1 << 20)
#define FLAG_DANCE (1 << 21)
#define FLAG_DMG_2X_IN_AIR (1 << 22) // If target is in the air, can hit and deal double damage.
#define FLAG_DMG_IN_AIR (1 << 23) // If target is in the air, can hit.
#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_THAW_USER (1 << 25)
#define FLAG_HIT_IN_SUBSTITUTE (1 << 26) // Hyperspace Fury
// Split defines.
#define SPLIT_PHYSICAL 0x0
@ -336,25 +337,43 @@
#define F_SUMMARY_SCREEN_FLIP_SPRITE 0x80
// Evolution types
#define EVO_MEGA_EVOLUTION 0xffff // Not an actual evolution, used to temporarily mega evolve in battle.
#define EVO_MOVE_MEGA_EVOLUTION 0xfffe // Mega Evolution that checks for a move instead of held item.
#define EVO_FRIENDSHIP 1 // Pokémon levels up with friendship ≥ 220
#define EVO_FRIENDSHIP_DAY 2 // Pokémon levels up during the day with friendship ≥ 220
#define EVO_FRIENDSHIP_NIGHT 3 // Pokémon levels up at night with friendship ≥ 220
#define EVO_LEVEL 4 // Pokémon reaches the specified level
#define EVO_TRADE 5 // Pokémon is traded
#define EVO_TRADE_ITEM 6 // Pokémon is traded while it's holding the specified item
#define EVO_ITEM 7 // specified item is used on Pokémon
#define EVO_LEVEL_ATK_GT_DEF 8 // Pokémon reaches the specified level with attack > defense
#define EVO_LEVEL_ATK_EQ_DEF 9 // Pokémon reaches the specified level with attack = defense
#define EVO_LEVEL_ATK_LT_DEF 10 // Pokémon reaches the specified level with attack < defense
#define EVO_LEVEL_SILCOON 11 // Pokémon reaches the specified level with a Silcoon personality value
#define EVO_LEVEL_CASCOON 12 // Pokémon reaches the specified level with a Cascoon personality value
#define EVO_LEVEL_NINJASK 13 // Pokémon reaches the specified level (special value for Ninjask)
#define EVO_LEVEL_SHEDINJA 14 // Pokémon reaches the specified level (special value for Shedinja)
#define EVO_BEAUTY 15 // Pokémon levels up with beauty ≥ specified value
#define EVO_MEGA_EVOLUTION 0xffff // Not an actual evolution, used to temporarily mega evolve in battle.
#define EVO_MOVE_MEGA_EVOLUTION 0xfffe // Mega Evolution that checks for a move instead of held item.
#define EVO_PRIMAL_REVERSION 0xfffd // Not an actual evolution, used to undergo primal reversion in battle.
#define EVO_FRIENDSHIP 1 // Pokémon levels up with friendship ≥ 220
#define EVO_FRIENDSHIP_DAY 2 // Pokémon levels up during the day with friendship ≥ 220
#define EVO_FRIENDSHIP_NIGHT 3 // Pokémon levels up at night with friendship ≥ 220
#define EVO_LEVEL 4 // Pokémon reaches the specified level
#define EVO_TRADE 5 // Pokémon is traded
#define EVO_TRADE_ITEM 6 // Pokémon is traded while it's holding the specified item
#define EVO_ITEM 7 // specified item is used on Pokémon
#define EVO_LEVEL_ATK_GT_DEF 8 // Pokémon reaches the specified level with attack > defense
#define EVO_LEVEL_ATK_EQ_DEF 9 // Pokémon reaches the specified level with attack = defense
#define EVO_LEVEL_ATK_LT_DEF 10 // Pokémon reaches the specified level with attack < defense
#define EVO_LEVEL_SILCOON 11 // Pokémon reaches the specified level with a Silcoon personality value
#define EVO_LEVEL_CASCOON 12 // Pokémon reaches the specified level with a Cascoon personality value
#define EVO_LEVEL_NINJASK 13 // Pokémon reaches the specified level (special value for Ninjask)
#define EVO_LEVEL_SHEDINJA 14 // Pokémon reaches the specified level (special value for Shedinja)
#define EVO_BEAUTY 15 // Pokémon levels up with beauty ≥ specified value
#define EVO_LEVEL_FEMALE 16 // Pokémon reaches the specified level, is female
#define EVO_LEVEL_MALE 17 // Pokémon reaches the specified level, is male
#define EVO_LEVEL_NIGHT 18 // Pokémon reaches the specified level, is night
#define EVO_LEVEL_DAY 19 // Pokémon reaches the specified level, is day
#define EVO_LEVEL_DUSK 20 // Pokémon reaches the specified level, is dusk (5-6 P.M)
#define EVO_ITEM_HOLD_DAY 21 // Pokémon levels up, holds specified item at day
#define EVO_ITEM_HOLD_NIGHT 22 // Pokémon levels up, holds specified item at night
#define EVO_MOVE 23 // Pokémon levels up, knows specified move
#define EVO_MOVE_TYPE 24 // Pokémon levels up, knows move with specified type
#define EVO_MAPSEC 25 // Pokémon levels up on specified mapsec
#define EVO_ITEM_MALE 26 // specified item is used on a male Pokémon
#define EVO_ITEM_FEMALE 27 // specified item is used on a female Pokémon
#define EVO_LEVEL_RAIN 28 // Pokémon reaches the specified level while it's raining
#define EVO_SPECIFIC_MON_IN_PARTY 29 // Pokémon levels up with a specified Pokémon in party
#define EVO_LEVEL_DARK_TYPE_MON_IN_PARTY 30 // Pokémon reaches the specified level with a Dark Type Pokémon in party
#define EVO_TRADE_SPECIFIC_MON 31 // Pokémon is traded for a specified Pokémon
#define EVO_SPECIFIC_MAP 32 // Pokémon levels up on specified map
#define EVOS_PER_MON 5
#define EVOS_PER_MON 10
// Evolution 'modes,' for GetEvolutionTargetSpecies
#define EVO_MODE_NORMAL 0

View File

@ -4749,6 +4749,8 @@ extern const u32 gBattleAnimSpriteGfx_MegaStone[];
extern const u32 gBattleAnimSpritePal_MegaStone[];
extern const u32 gBattleAnimSpriteGfx_MegaParticles[];
extern const u32 gBattleAnimSpritePal_MegaParticles[];
extern const u32 gBattleAnimSpriteGfx_PrimalParticles[];
extern const u32 gBattleAnimSpritePal_PrimalParticles[];
extern const u32 gBattleAnimSpriteGfx_MegaSymbol[];
extern const u32 gBattleAnimSpritePal_MegaSymbol[];
extern const u32 gBattleAnimSpriteGfx_FlashCannonBall[];
@ -4765,6 +4767,8 @@ extern const u32 gBattleAnimSpriteGfx_AcupressureFinger[];
extern const u32 gBattleAnimSpritePal_AcupressureFinger[];
extern const u32 gBattleAnimSpriteGfx_AlphaStone[];
extern const u32 gBattleAnimSpritePal_AlphaStone[];
extern const u32 gBattleAnimSpriteGfx_AlphaSymbol[];
extern const u32 gBattleAnimSpritePal_AlphaSymbol[];
extern const u32 gBattleAnimSpriteGfx_Anchor[];
extern const u32 gBattleAnimSpriteGfx_Apple[];
extern const u32 gBattleAnimSpritePal_Apple[];
@ -4867,6 +4871,8 @@ extern const u32 gBattleAnimSpriteGfx_Obstruct[];
extern const u32 gBattleAnimSpritePal_Obstruct[];
extern const u32 gBattleAnimSpriteGfx_OmegaStone[];
extern const u32 gBattleAnimSpritePal_OmegaStone[];
extern const u32 gBattleAnimSpriteGfx_OmegaSymbol[];
extern const u32 gBattleAnimSpritePal_OmegaSymbol[];
extern const u32 gBattleAnimSpriteGfx_PinkDiamond[];
extern const u32 gBattleAnimSpritePal_PinkDiamond[];
extern const u32 gBattleAnimSpriteGfx_PoisonColumn[];

View File

@ -216,7 +216,7 @@ struct BattleMove
u8 accuracy;
u8 pp;
u8 secondaryEffectChance;
u8 target;
u16 target;
s8 priority;
u32 flags;
u8 split;

View File

@ -177,10 +177,10 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves)
}
sBattler_AI = gActiveBattler;
// Simulate dmg for all AI moves against all opposing targets
// Simulate dmg for all AI moves against all other targets
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
if (GET_BATTLER_SIDE2(sBattler_AI) == GET_BATTLER_SIDE2(gBattlerTarget))
if (sBattler_AI == gBattlerTarget)
continue;
for (i = 0; i < MAX_MON_MOVES; i++)
{
@ -209,7 +209,11 @@ u8 BattleAI_ChooseMoveOrAction(void)
ret = ChooseMoveOrAction_Singles();
else
ret = ChooseMoveOrAction_Doubles();
// Clear protect structures, some flags may be set during AI calcs
// e.g. pranksterElevated from GetMovePriority
memset(&gProtectStructs[gActiveBattler], 0, sizeof(struct ProtectStruct));
gCurrentMove = savedCurrentMove;
return ret;
}
@ -262,8 +266,10 @@ static u8 ChooseMoveOrAction_Singles(void)
AI_THINKING_STRUCT->movesetIndex = 0;
}
for (i = 0; i < MAX_MON_MOVES; i++)
for (i = 0; i < MAX_MON_MOVES; i++) {
gBattleStruct->aiFinalScore[sBattler_AI][gBattlerTarget][i] = AI_THINKING_STRUCT->score[i];
gBattleStruct->aiSimulatedDamage[sBattler_AI][gBattlerTarget][i] = AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][i];
}
// Check special AI actions.
if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE)
@ -428,8 +434,10 @@ static u8 ChooseMoveOrAction_Doubles(void)
}
}
for (j = 0; j < MAX_MON_MOVES; j++)
for (j = 0; j < MAX_MON_MOVES; j++) {
gBattleStruct->aiFinalScore[sBattler_AI][gBattlerTarget][j] = AI_THINKING_STRUCT->score[j];
gBattleStruct->aiSimulatedDamage[sBattler_AI][gBattlerTarget][j] = AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][j];
}
}
}
@ -513,7 +521,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
u8 atkPriority = GetMovePriority(battlerAtk, move);
u16 moveEffect = gBattleMoves[move].effect;
s32 moveType;
u8 moveTarget = gBattleMoves[move].target;
u16 moveTarget = gBattleMoves[move].target;
u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move);
u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef);
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
@ -824,21 +832,17 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL))
score -= 10;
break;
case EFFECT_DEFENSE_UP_2:
if (move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battlerAtk].item) != POCKET_BERRIES)
score -= 10;
case EFFECT_STUFF_CHEEKS:
if (ItemId_GetPocket(gBattleMons[battlerAtk].item) != POCKET_BERRIES)
return 0; // cannot even select
//fallthrough
case EFFECT_DEFENSE_UP:
case EFFECT_DEFENSE_UP_2:
case EFFECT_DEFENSE_UP_3:
case EFFECT_DEFENSE_CURL:
if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF))
score -= 10;
break;
case EFFECT_SPEED_UP:
case EFFECT_SPEED_UP_2:
if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED))
score -= 10;
break;
case EFFECT_SPECIAL_ATTACK_UP:
case EFFECT_SPECIAL_ATTACK_UP_2:
case EFFECT_SPECIAL_ATTACK_UP_3:
@ -2514,7 +2518,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// move data
u8 moveType = gBattleMoves[move].type;
u16 effect = gBattleMoves[move].effect;
u8 target = gBattleMoves[move].target;
u16 target = gBattleMoves[move].target;
// ally data
u8 battlerAtkPartner = AI_DATA->battlerAtkPartner;
u16 atkPartnerAbility = AI_DATA->atkPartnerAbility;
@ -3331,7 +3335,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_TRAP:
case EFFECT_MEAN_LOOK:
if (HasMoveEffect(battlerDef, EFFECT_RAPID_SPIN)
|| IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST)
|| (B_GHOSTS_ESCAPE >= GEN_6 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST))
|| gBattleMons[battlerDef].status2 & STATUS2_WRAPPED)
{
break; // in this case its a bad attacking move
@ -3363,6 +3367,10 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_PARALYZE:
IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score);
break;
case EFFECT_GRAV_APPLE:
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
score += 2;
// fall through
case EFFECT_ATTACK_DOWN_HIT:
case EFFECT_DEFENSE_DOWN_HIT:
case EFFECT_SPECIAL_ATTACK_DOWN_HIT:

View File

@ -1564,6 +1564,9 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] =
{gBattleAnimSpriteGfx_DreepyMissile, 0x200, ANIM_TAG_DREEPY},
{gBattleAnimSpriteGfx_IceRock, 0x1800, ANIM_TAG_ICE_ROCK_SINGLE},
{gBattleAnimSpriteGfx_StonePillar, 0x1800, ANIM_TAG_STONE_PILLAR_MULTI},
{gBattleAnimSpriteGfx_AlphaSymbol, 0x0200, ANIM_TAG_ALPHA_SYMBOL},
{gBattleAnimSpriteGfx_OmegaSymbol, 0x0200, ANIM_TAG_OMEGA_SYMBOL},
{gBattleAnimSpriteGfx_PrimalParticles, 0x0180, ANIM_TAG_PRIMAL_PARTICLES},
};
const struct CompressedSpritePalette gBattleAnimPaletteTable[] =
@ -2011,6 +2014,9 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] =
{gBattleAnimSpritePal_DreepyMissile, ANIM_TAG_DREEPY},
{gBattleAnimSpritePal_IceRock, ANIM_TAG_ICE_ROCK_SINGLE},
{gBattleAnimSpritePal_StonePillar, ANIM_TAG_STONE_PILLAR_MULTI},
{gBattleAnimSpritePal_AlphaSymbol, ANIM_TAG_ALPHA_SYMBOL},
{gBattleAnimSpritePal_OmegaSymbol, ANIM_TAG_OMEGA_SYMBOL},
{gBattleAnimSpritePal_PrimalParticles, ANIM_TAG_PRIMAL_PARTICLES},
};
const struct BattleAnimBackground gBattleAnimBackgroundTable[] =

View File

@ -1219,6 +1219,61 @@ const struct SpriteTemplate gMegaSymbolSpriteTemplate =
.callback = AnimGhostStatusSprite,
};
const struct SpriteTemplate gAlphaStoneSpriteTemplate =
{
.tileTag = ANIM_TAG_ALPHA_STONE,
.paletteTag = ANIM_TAG_ALPHA_STONE,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_LusterPurgeCircle,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gOmegaStoneSpriteTemplate =
{
.tileTag = ANIM_TAG_OMEGA_STONE,
.paletteTag = ANIM_TAG_OMEGA_STONE,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_LusterPurgeCircle,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gPrimalParticlesSpriteTemplate =
{
.tileTag = ANIM_TAG_PRIMAL_PARTICLES,
.paletteTag = ANIM_TAG_PRIMAL_PARTICLES,
.oam = &gOamData_AffineNormal_ObjBlend_16x16,
.anims = gPowerAbsorptionOrbAnimTable,
.images = NULL,
.affineAnims = gPowerAbsorptionOrbAffineAnimTable,
.callback = AnimPowerAbsorptionOrb,
};
const struct SpriteTemplate gAlphaSymbolSpriteTemplate =
{
.tileTag = ANIM_TAG_ALPHA_SYMBOL,
.paletteTag = ANIM_TAG_ALPHA_SYMBOL,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGhostStatusSprite,
};
const struct SpriteTemplate gOmegaSymbolSpriteTemplate =
{
.tileTag = ANIM_TAG_OMEGA_SYMBOL,
.paletteTag = ANIM_TAG_OMEGA_SYMBOL,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGhostStatusSprite,
};
void AnimBlackSmoke(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];

View File

@ -15,6 +15,7 @@
#include "battle_controllers.h"
#include "constants/moves.h"
#include "constants/hold_effects.h"
#include "constants/items.h"
//// function declarations
static void SpriteCB_SpriteToCentreOfSide(struct Sprite* sprite);
@ -93,6 +94,40 @@ const struct SpriteTemplate gPowerTrickSpriteTemplate =
//// GEN 5
//shell smash
const struct SpriteTemplate gShellSmashLeftShellSpriteTemplate =
{
.tileTag = ANIM_TAG_SHELL_RIGHT,
.paletteTag = ANIM_TAG_SHELL_RIGHT,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_Bite,
.callback = AnimBite
};
const struct SpriteTemplate gShellSmashRightShellSpriteTemplate =
{
.tileTag = ANIM_TAG_SHELL_LEFT,
.paletteTag = ANIM_TAG_SHELL_LEFT,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_Bite,
.callback = AnimBite
};
const struct SpriteTemplate gShellSmashPurpleRocksSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_SHELL_RIGHT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_FlyingRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockFragment
};
//wide guard
const struct SpriteTemplate gWideGuardBlueConversionTemplate =
{
@ -5020,3 +5055,12 @@ void AnimTask_TechnoBlast(u8 taskId)
gBattleAnimArgs[0] = 0;
DestroyAnimVisualTask(taskId);
}
void AnimTask_PrimalReversion(u8 taskId)
{
if (ItemId_GetId(gBattleMons[gBattleAnimAttacker].item) == ITEM_RED_ORB)
gBattleAnimArgs[0] = ItemId_GetId(gBattleMons[gBattleAnimAttacker].item);
else
gBattleAnimArgs[0] = 0;
DestroyAnimVisualTask(taskId);
}

View File

@ -9,7 +9,6 @@
#include "constants/rgb.h"
#include "constants/songs.h"
static void AnimRockFragment(struct Sprite *);
static void AnimTask_Rollout_Step(u8 taskId);
static void AnimRolloutParticle(struct Sprite *);
static void AnimRockTomb(struct Sprite *);
@ -43,7 +42,7 @@ static const union AnimCmd sAnim_FlyingRock_2[] =
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_FlyingRock[] =
const union AnimCmd *const gAnims_FlyingRock[] =
{
sAnim_FlyingRock_0,
sAnim_FlyingRock_1,
@ -55,7 +54,7 @@ const struct SpriteTemplate gFallingRockSpriteTemplate =
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FlyingRock,
.anims = gAnims_FlyingRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFallingRock,
@ -66,7 +65,7 @@ const struct SpriteTemplate gRockFragmentSpriteTemplate =
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FlyingRock,
.anims = gAnims_FlyingRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockFragment,
@ -430,7 +429,7 @@ void AnimFallingRock_Step(struct Sprite *sprite)
}
// Animates the rock particles that are shown on the impact for Rock Blast / Rock Smash
static void AnimRockFragment(struct Sprite *sprite)
void AnimRockFragment(struct Sprite *sprite)
{
StartSpriteAnim(sprite, gBattleAnimArgs[5]);
AnimateSprite(sprite);

View File

@ -496,6 +496,19 @@ static void HandleInputChooseTarget(void)
}
}
static void HideAllTargets(void)
{
s32 i;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (IsBattlerAlive(i) && gBattleSpritesDataPtr->healthBoxesData[i].healthboxIsBouncing)
{
gSprites[gBattlerSpriteIds[i]].callback = SpriteCb_HideAsMoveTarget;
EndBounceEffect(i, BOUNCE_HEALTHBOX);
}
}
}
static void HideShownTargets(void)
{
s32 i;
@ -509,6 +522,34 @@ static void HideShownTargets(void)
}
}
static void HandleInputShowEntireFieldTargets(void)
{
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
gPlayerDpadHoldFrames++;
else
gPlayerDpadHoldFrames = 0;
if (JOY_NEW(A_BUTTON))
{
PlaySE(SE_SELECT);
HideAllTargets();
if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
HideMegaTriggerSprite();
PlayerBufferExecCompleted();
}
else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59)
{
PlaySE(SE_SELECT);
HideAllTargets();
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove;
DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1);
DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1);
}
}
static void HandleInputShowTargets(void)
{
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
@ -549,7 +590,7 @@ static void TryShowAsTarget(u32 battlerId)
static void HandleInputChooseMove(void)
{
u8 moveTarget;
u16 moveTarget;
u32 canSelectTarget = 0;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]);
@ -601,18 +642,31 @@ static void HandleInputChooseMove(void)
}
// Show all available targets for multi-target moves
if (B_SHOW_TARGETS && moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
if (B_SHOW_TARGETS)
{
TryShowAsTarget(gMultiUsePlayerCursor);
TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor));
if (moveTarget & MOVE_TARGET_FOES_AND_ALLY)
TryShowAsTarget(BATTLE_PARTNER(gActiveBattler));
canSelectTarget = 2;
if ((moveTarget & MOVE_TARGET_ALL_BATTLERS) == MOVE_TARGET_ALL_BATTLERS)
{
u32 i = 0;
for (i = 0; i < gBattlersCount; i++)
TryShowAsTarget(i);
canSelectTarget = 3;
}
else if (moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
{
TryShowAsTarget(gMultiUsePlayerCursor);
TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor));
if (moveTarget & MOVE_TARGET_FOES_AND_ALLY)
TryShowAsTarget(BATTLE_PARTNER(gActiveBattler));
canSelectTarget = 2;
}
}
}
if (canSelectTarget == 0)
switch (canSelectTarget)
{
case 0:
default:
if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else
@ -620,9 +674,8 @@ static void HandleInputChooseMove(void)
HideMegaTriggerSprite();
TryHideLastUsedBall();
PlayerBufferExecCompleted();
}
else if (canSelectTarget == 1)
{
break;
case 1:
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget;
if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
@ -633,10 +686,13 @@ static void HandleInputChooseMove(void)
gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCb_ShowAsMoveTarget;
}
else
{
break;
case 2:
gBattlerControllerFuncs[gActiveBattler] = HandleInputShowTargets;
break;
case 3: // Entire field
gBattlerControllerFuncs[gActiveBattler] = HandleInputShowEntireFieldTargets;
break;
}
}
else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59)

View File

@ -97,6 +97,7 @@ enum
LIST_ITEM_STATUS1,
LIST_ITEM_STATUS2,
LIST_ITEM_STATUS3,
LIST_ITEM_STATUS4,
LIST_ITEM_SIDE_STATUS,
LIST_ITEM_AI,
LIST_ITEM_AI_MOVES_PTS,
@ -164,6 +165,7 @@ static const u8 sText_StatStages[] = _("Stat Stages");
static const u8 sText_Status1[] = _("Status1");
static const u8 sText_Status2[] = _("Status2");
static const u8 sText_Status3[] = _("Status3");
static const u8 sText_Status4[] = _("Status4");
static const u8 sText_HeldItem[] = _("Held Item");
static const u8 sText_SideStatus[] = _("Side Status");
static const u8 sText_MaxHp[] = _("HP Max");
@ -207,6 +209,8 @@ static const u8 sText_GastroAcid[] = _("Gastro Acid");
static const u8 sText_SmackDown[] = _("Smacked Down");
static const u8 sText_MiracleEye[] = _("Miracle Eye");
static const u8 sText_AquaRing[] = _("Aqua Ring");
static const u8 sText_LaserFocus[] = _("Laser Focused");
static const u8 sText_Electrified[] = _("Electrified");
static const u8 sText_AuroraVeil[] = _("Aurora Veil");
static const u8 sText_LuckyChant[] = _("Lucky Chant");
static const u8 sText_Tailwind[] = _("Tailwind");
@ -228,7 +232,7 @@ static const u8 sText_InDoubles[] = _("In Doubles");
static const u8 sText_HpAware[] = _("HP aware");
static const u8 sText_Unknown[] = _("Unknown");
static const u8 sText_InLove[] = _("In Love");
static const u8 sText_AIMovePts[] = _("AI Move Pts");
static const u8 sText_AIMovePts[] = _("AI Pts/Dmg");
static const u8 sText_AiKnowledge[] = _("AI Info");
static const u8 sText_EffectOverride[] = _("Effect Override");
@ -295,6 +299,13 @@ static const struct BitfieldInfo sStatus3Bitfield[] =
// Magnet Rise 1, 26,
// Heal Block 1, 27,
{/*Aqua Ring*/ 1, 28},
{/*Laser Focus*/ 1, 29},
// Power Trick 1, 30,
};
static const struct BitfieldInfo sStatus4Bitfield[] =
{
{/*Electrified*/ 1, 0,}
};
static const struct BitfieldInfo sAIBitfield[] =
@ -324,6 +335,7 @@ static const struct ListMenuItem sMainListItems[] =
{sText_Status1, LIST_ITEM_STATUS1},
{sText_Status2, LIST_ITEM_STATUS2},
{sText_Status3, LIST_ITEM_STATUS3},
{sText_Status4, LIST_ITEM_STATUS4},
{sText_SideStatus, LIST_ITEM_SIDE_STATUS},
{sText_AI, LIST_ITEM_AI},
{sText_AIMovePts, LIST_ITEM_AI_MOVES_PTS},
@ -408,6 +420,12 @@ static const struct ListMenuItem sStatus3ListItems[] =
{sText_SmackDown, 8},
{sText_MiracleEye, 9},
{sText_AquaRing, 10},
{sText_LaserFocus, 11},
};
static const struct ListMenuItem sStatus4ListItems[] =
{
{sText_Electrified, 0},
};
static const struct ListMenuItem sSideStatusListItems[] =
@ -713,6 +731,12 @@ static void PutMovesPointsText(struct BattleDebugMenu *data)
gBattleStruct->aiFinalScore[data->aiBattlerId][gSprites[data->aiIconSpriteIds[j]].data[0]][i],
STR_CONV_MODE_RIGHT_ALIGN, 3);
AddTextPrinterParameterized(data->aiMovesWindowId, 1, text, 83 + count * 54, i * 15, 0, NULL);
ConvertIntToDecimalStringN(text,
gBattleStruct->aiSimulatedDamage[data->aiBattlerId][gSprites[data->aiIconSpriteIds[j]].data[0]][i],
STR_CONV_MODE_RIGHT_ALIGN, 3);
AddTextPrinterParameterized(data->aiMovesWindowId, 1, text, 110 + count * 54, i * 15, 0, NULL);
count++;
}
}
@ -780,7 +804,7 @@ static void Task_ShowAiPoints(u8 taskId)
break;
// Put text
case 1:
winTemplate = CreateWindowTemplate(1, 0, 4, 27, 14, 15, 0x200);
winTemplate = CreateWindowTemplate(1, 0, 4, 30, 14, 15, 0x200);
data->aiMovesWindowId = AddWindow(&winTemplate);
PutWindowTilemap(data->aiMovesWindowId);
PutMovesPointsText(data);
@ -1176,6 +1200,11 @@ static void CreateSecondaryListMenu(struct BattleDebugMenu *data)
itemsCount = ARRAY_COUNT(sStatus3ListItems);
data->bitfield = sStatus3Bitfield;
break;
case LIST_ITEM_STATUS4:
listTemplate.items = sStatus4ListItems;
itemsCount = ARRAY_COUNT(sStatus4ListItems);
data->bitfield = sStatus4Bitfield;
break;
case LIST_ITEM_AI:
listTemplate.items = sAIListItems;
itemsCount = ARRAY_COUNT(sAIListItems);
@ -1734,6 +1763,11 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data)
data->modifyArrows.currValue = GetBitfieldValue(gStatuses3[data->battlerId], data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount);
data->modifyArrows.typeOfVal = VAL_BITFIELD_32;
goto CASE_ITEM_STATUS;
case LIST_ITEM_STATUS4:
data->modifyArrows.modifiedValPtr = &gStatuses4[data->battlerId];
data->modifyArrows.currValue = GetBitfieldValue(gStatuses4[data->battlerId], data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount);
data->modifyArrows.typeOfVal = VAL_BITFIELD_32;
goto CASE_ITEM_STATUS;
case LIST_ITEM_AI:
data->modifyArrows.modifiedValPtr = &gBattleResources->ai->aiFlags;
data->modifyArrows.currValue = GetBitfieldValue(gBattleResources->ai->aiFlags, data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount);

View File

@ -672,6 +672,28 @@ static const struct SpritePalette sSpritePalette_MegaIndicator =
sMegaIndicatorPal, TAG_MEGA_INDICATOR_PAL
};
static const u8 sAlphaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/alpha_indicator.4bpp");
static const u16 sAlphaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/alpha_indicator.gbapal");
static const u8 sOmegaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/omega_indicator.4bpp");
static const u16 sOmegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/omega_indicator.gbapal");
static const struct SpriteSheet sSpriteSheet_AlphaIndicator =
{
sAlphaIndicatorGfx, sizeof(sAlphaIndicatorGfx), TAG_ALPHA_INDICATOR_TILE
};
static const struct SpritePalette sSpritePalette_AlphaIndicator =
{
sAlphaIndicatorPal, TAG_ALPHA_INDICATOR_PAL
};
static const struct SpriteSheet sSpriteSheet_OmegaIndicator =
{
sOmegaIndicatorGfx, sizeof(sOmegaIndicatorGfx), TAG_OMEGA_INDICATOR_TILE
};
static const struct SpritePalette sSpritePalette_OmegaIndicator =
{
sOmegaIndicatorPal, TAG_OMEGA_INDICATOR_PAL
};
static const struct OamData sOamData_MegaIndicator =
{
.y = 0,
@ -700,6 +722,28 @@ static const struct SpriteTemplate sSpriteTemplate_MegaIndicator =
.callback = SpriteCb_MegaIndicator,
};
static const struct SpriteTemplate sSpriteTemplate_AlphaIndicator =
{
.tileTag = TAG_ALPHA_INDICATOR_TILE,
.paletteTag = TAG_ALPHA_INDICATOR_PAL,
.oam = &sOamData_MegaIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_MegaIndicator,
};
static const struct SpriteTemplate sSpriteTemplate_OmegaIndicator =
{
.tileTag = TAG_OMEGA_INDICATOR_TILE,
.paletteTag = TAG_OMEGA_INDICATOR_PAL,
.oam = &sOamData_MegaIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_MegaIndicator,
};
// code
@ -818,8 +862,9 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId)
healthBarSpritePtr->hBar_Data6 = data6;
healthBarSpritePtr->invisible = TRUE;
// Create mega indicator sprite if is a mega evolved mon.
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
// Create mega indicator sprite if is a mega evolved or a primal reverted mon.
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]]
|| gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
megaIndicatorSpriteId = CreateMegaIndicatorSprite(battlerId, 0);
gSprites[megaIndicatorSpriteId].invisible = TRUE;
@ -926,7 +971,8 @@ void SetHealthboxSpriteVisible(u8 healthboxSpriteId)
gSprites[healthboxSpriteId].invisible = FALSE;
gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = FALSE;
gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = FALSE;
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]]
|| gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
u8 spriteId = GetMegaIndicatorSpriteId(healthboxSpriteId);
if (spriteId != 0xFF)
@ -994,7 +1040,7 @@ void UpdateOamPriorityInAllHealthboxes(u8 priority, bool32 hideHPBoxes)
if (indicatorSpriteId != 0xFF)
gSprites[indicatorSpriteId].oam.priority = priority;
#if B_HIDE_HEALTHBOXES_DURING_ANIMS
#if B_HIDE_HEALTHBOX_IN_ANIMS
if (hideHPBoxes && IsBattlerAlive(i))
TryToggleHealboxVisibility(priority, healthboxLeftSpriteId, healthboxRightSpriteId, healthbarSpriteId, indicatorSpriteId);
#endif
@ -1049,8 +1095,9 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
u8 *objVram;
u8 battler = gSprites[healthboxSpriteId].hMain_Battler;
// Don't print Lv char if mon is mega evolved.
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])
// Don't print Lv char if mon is mega evolved or primal reverted.
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]]
|| gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])
{
objVram = ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
xPos = 5 * (3 - (objVram - (text + 2))) - 1;
@ -1522,12 +1569,28 @@ u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which)
u32 spriteId, position;
s16 x, y;
LoadSpritePalette(&sSpritePalette_MegaIndicator);
LoadSpriteSheet(&sSpriteSheet_MegaIndicator);
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
LoadSpritePalette(&sSpritePalette_MegaIndicator);
LoadSpriteSheet(&sSpriteSheet_MegaIndicator);
}
else if (gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_GROUDON)
{
LoadSpritePalette(&sSpritePalette_OmegaIndicator);
LoadSpriteSheet(&sSpriteSheet_OmegaIndicator);
}
else if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_KYOGRE)
{
LoadSpritePalette(&sSpritePalette_AlphaIndicator);
LoadSpriteSheet(&sSpriteSheet_AlphaIndicator);
}
}
position = GetBattlerPosition(battlerId);
GetBattlerHealthboxCoords(battlerId, &x, &y);
x += sIndicatorPositions[position][0];
y += sIndicatorPositions[position][1];
@ -1535,10 +1598,20 @@ u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which)
x -= 4;
else if (gBattleMons[battlerId].level < 10)
x += 5;
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_MegaIndicator, x, y, 0);
gSprites[gSprites[gHealthboxSpriteIds[battlerId]].oam.affineParam].hOther_IndicatorSpriteId = spriteId;
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_MegaIndicator, x, y, 0);
}
else if (gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_GROUDON)
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_OmegaIndicator, x, y, 0);
else if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_KYOGRE)
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_AlphaIndicator, x, y, 0);
}
gSprites[gSprites[gHealthboxSpriteIds[battlerId]].oam.affineParam].hOther_IndicatorSpriteId = spriteId;
gSprites[spriteId].tBattler = battlerId;
return spriteId;
}

View File

@ -190,6 +190,7 @@ EWRAM_DATA u8 gUnusedFirstBattleVar2 = 0; // Never read
EWRAM_DATA u32 gSideStatuses[2] = {0};
EWRAM_DATA struct SideTimer gSideTimers[2] = {0};
EWRAM_DATA u32 gStatuses3[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u32 gStatuses4[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u16 gPauseCounterBattle = 0;
EWRAM_DATA u16 gPaydayMoney = 0;
@ -2849,6 +2850,7 @@ static void BattleStartClearSetData(void)
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
gStatuses3[i] = 0;
gStatuses4[i] = 0;
gDisableStructs[i].isFirstTurn = 2;
gLastMoves[i] = 0;
gLastLandedMoves[i] = 0;
@ -2960,7 +2962,9 @@ void SwitchInClearSetData(void)
if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS)
{
gBattleMons[gActiveBattler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED);
gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED
| STATUS3_GASTRO_ACID | STATUS3_EMBARGO | STATUS3_TELEKINESIS | STATUS3_MAGNET_RISE | STATUS3_HEAL_BLOCK
| STATUS3_AQUA_RING | STATUS3_POWER_TRICK);
for (i = 0; i < gBattlersCount; i++)
{
@ -2980,6 +2984,8 @@ void SwitchInClearSetData(void)
gBattleMons[gActiveBattler].status2 = 0;
gStatuses3[gActiveBattler] = 0;
}
gStatuses4[gActiveBattler] = 0;
for (i = 0; i < gBattlersCount; i++)
{
@ -3053,6 +3059,7 @@ void FaintClearSetData(void)
gBattleMons[gActiveBattler].status2 = 0;
gStatuses3[gActiveBattler] = 0;
gStatuses4[gActiveBattler] = 0;
for (i = 0; i < gBattlersCount; i++)
{
@ -3097,6 +3104,7 @@ void FaintClearSetData(void)
gProtectStructs[gActiveBattler].usedThroatChopPreventedMove = 0;
gProtectStructs[gActiveBattler].statRaised = 0;
gProtectStructs[gActiveBattler].statFell = 0;
gProtectStructs[gActiveBattler].pranksterElevated = 0;
gDisableStructs[gActiveBattler].isFirstTurn = 2;
@ -3514,6 +3522,18 @@ static void TryDoEventsBeforeFirstTurn(void)
}
memset(gTotemBoosts, 0, sizeof(gTotemBoosts)); // erase all totem boosts just to be safe
// Primal Reversion
for (i = 0; i < gBattlersCount; i++)
{
if (CanMegaEvolve(i)
&& GetBattlerHoldEffect(i, TRUE) == HOLD_EFFECT_PRIMAL_ORB)
{
gBattlerAttacker = i;
BattleScriptExecute(BattleScript_PrimalReversion);
return;
}
}
// Check all switch in abilities happening from the fastest mon to slowest.
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
{
@ -3685,6 +3705,10 @@ u8 IsRunningFromBattleImpossible(void)
if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)
return 0;
#if B_GHOSTS_ESCAPE >= GEN_6
if (IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_GHOST))
return 0;
#endif
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
return 0;
if (GetBattlerAbility(gActiveBattler) == ABILITY_RUN_AWAY)
@ -4379,20 +4403,32 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
u32 holdEffectBattler1 = 0, holdEffectBattler2 = 0;
s8 priority1 = 0, priority2 = 0;
// Battler 1
speedBattler1 = GetBattlerTotalSpeedStat(battler1);
holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
if ((holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler1)) / 100)
// Quick Draw
if (!ignoreChosenMoves && GetBattlerAbility(battler1) == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && Random() % 100 < 30)
gProtectStructs[battler1].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler1].quickDraw
&& ((holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler1)) / 100)
|| (!IsAbilityOnOpposingSide(battler1, ABILITY_UNNERVE)
&& holdEffectBattler1 == HOLD_EFFECT_CUSTAP_BERRY
&& HasEnoughHpToEatBerry(battler1, 4, gBattleMons[battler1].item)))
&& HasEnoughHpToEatBerry(battler1, 4, gBattleMons[battler1].item))))
gProtectStructs[battler1].custap = TRUE;
// Battler 2
speedBattler2 = GetBattlerTotalSpeedStat(battler2);
holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
if ((holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler2)) / 100)
// Quick Draw
if (!ignoreChosenMoves && GetBattlerAbility(battler2) == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && Random() % 100 < 30)
gProtectStructs[battler2].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler2].quickDraw
&& ((holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler2)) / 100)
|| (!IsAbilityOnOpposingSide(battler2, ABILITY_UNNERVE)
&& holdEffectBattler2 == HOLD_EFFECT_CUSTAP_BERRY
&& HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item)))
&& HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item))))
gProtectStructs[battler2].custap = TRUE;
if (!ignoreChosenMoves)
@ -4408,8 +4444,12 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
// QUICK CLAW / CUSTAP - always first
// LAGGING TAIL - always last
// STALL - always last
if (gProtectStructs[battler1].custap && !gProtectStructs[battler2].custap)
if (gProtectStructs[battler1].quickDraw && !gProtectStructs[battler2].quickDraw)
strikesFirst = 0;
else if (!gProtectStructs[battler1].quickDraw && gProtectStructs[battler2].quickDraw)
strikesFirst = 1;
else if (gProtectStructs[battler1].custap && !gProtectStructs[battler2].custap)
strikesFirst = 0;
else if (gProtectStructs[battler2].custap && !gProtectStructs[battler1].custap)
strikesFirst = 1;
@ -4670,22 +4710,34 @@ static void CheckQuickClaw_CustapBerryActivation(void)
gBattleStruct->quickClawBattlerId++;
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_MOVE
&& gChosenMoveByBattler[gActiveBattler] != MOVE_FOCUS_PUNCH // quick claw message doesn't need to activate here
&& gProtectStructs[gActiveBattler].custap
&& (gProtectStructs[gActiveBattler].custap || gProtectStructs[gActiveBattler].quickDraw)
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
&& !(gDisableStructs[gBattlerAttacker].truantCounter)
&& !(gProtectStructs[gActiveBattler].noValidMoves))
{
gProtectStructs[gActiveBattler].custap = FALSE;
gLastUsedItem = gBattleMons[gActiveBattler].item;
if (GetBattlerHoldEffect(gActiveBattler, FALSE) == HOLD_EFFECT_CUSTAP_BERRY)
if (gProtectStructs[gActiveBattler].custap)
{
// don't record berry since its gone now
BattleScriptExecute(BattleScript_CustapBerryActivation);
gProtectStructs[gActiveBattler].custap = FALSE;
gLastUsedItem = gBattleMons[gActiveBattler].item;
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem);
if (GetBattlerHoldEffect(gActiveBattler, FALSE) == HOLD_EFFECT_CUSTAP_BERRY)
{
// don't record berry since its gone now
BattleScriptExecute(BattleScript_CustapBerryActivation);
}
else
{
RecordItemEffectBattle(gActiveBattler, GetBattlerHoldEffect(gActiveBattler, FALSE));
BattleScriptExecute(BattleScript_QuickClawActivation);
}
}
else
else if (gProtectStructs[gActiveBattler].quickDraw)
{
RecordItemEffectBattle(gActiveBattler, GetBattlerHoldEffect(gActiveBattler, FALSE));
BattleScriptExecute(BattleScript_QuickClawActivation);
gProtectStructs[gActiveBattler].quickDraw = FALSE;
gLastUsedAbility = gBattleMons[gActiveBattler].ability;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
BattleScriptExecute(BattleScript_QuickDrawActivation);
}
return;
}
@ -4930,6 +4982,17 @@ static void HandleEndTurn_FinishBattle(void)
UndoFormChange(i, B_SIDE_PLAYER, FALSE);
DoBurmyFormChange(i);
}
#if B_RECALCULATE_STATS >= GEN_5
// Recalculate the stats of every party member before the end
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_NONE
&& GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_EGG)
{
CalculateMonStats(&gPlayerParty[i]);
}
}
#endif
gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions;
gCB2_AfterEvolution = BattleMainCB2;
}
@ -5118,7 +5181,7 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
attackerAbility = GetBattlerAbility(battlerAtk);
GET_MOVE_TYPE(move, moveType);
if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL)
|| gStatuses3[battlerAtk] & STATUS3_ELECTRIFIED)
|| gStatuses4[battlerAtk] & STATUS4_ELECTRIFIED)
{
gBattleStruct->dynamicMoveType = 0x80 | TYPE_ELECTRIC;
}
@ -5150,6 +5213,10 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
{
gBattleStruct->dynamicMoveType = 0x80 | TYPE_WATER;
}
else if (gStatuses4[battlerAtk] & STATUS4_PLASMA_FISTS && moveType == TYPE_NORMAL)
{
gBattleStruct->dynamicMoveType = 0x80 | TYPE_ELECTRIC;
}
// Check if a gem should activate.
GET_MOVE_TYPE(move, moveType);

View File

@ -692,7 +692,7 @@ static const u8 sText_PkmnsWillPerishIn3Turns[] = _("Both Pokémon will perish\n
static const u8 sText_AbilityRaisedStatDrastically[] = _("{B_DEF_ABILITY} raised {B_DEF_NAME_WITH_PREFIX}'s\n{B_BUFF1} drastically!");
static const u8 sText_AsOneEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} has two Abilities!");
static const u8 sText_CuriousMedicineEnters[] = _("{B_EFF_NAME_WITH_PREFIX}'s\nstat changes were reset!");
static const u8 sText_CanActFaster[] = _("{B_ATK_NAME_WITH_PREFIX} can act faster,\nthanks to {B_LAST_ITEM}!");
static const u8 sText_CanActFaster[] = _("{B_ATK_NAME_WITH_PREFIX} can act faster,\nthanks to {B_BUFF1}!");
static const u8 sText_MicleBerryActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted the accuracy of its\nnext move using {B_LAST_ITEM}!");
static const u8 sText_PkmnShookOffTheTaunt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shook off\nthe taunt!");
static const u8 sText_PkmnGotOverItsInfatuation[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} got over\nits infatuation!");
@ -718,11 +718,21 @@ static const u8 sText_MysteriousAirCurrent[] = _("A mysterious air current is\np
static const u8 sText_StrongWindsDissipated[] = _("The mysterious strong winds\nhave dissipated!{PAUSE 64}");
static const u8 sText_MysteriousAirCurrentBlowsOn[] = _("The mysterious air current\nblows on regardless!");
static const u8 sText_AttackWeakenedByStrongWinds[] = _("The mysterious strong winds\nweakened the attack!");
static const u8 sText_StuffCheeksCantSelect[] = _("Stuff Cheeks cannot be\nselected without a Berry!\p");
static const u8 sText_PkmnRevertedToPrimal[] = _("{B_ATK_NAME_WITH_PREFIX}'s Primal Reversion!\nIt reverted to its primal form!");
static const u8 sText_ButPokemonCantUseTheMove[] = _("But {B_ATK_NAME_WITH_PREFIX} can't\nuse the move!");
static const u8 sText_ButHoopaCantUseIt[] = _("But Hoopa can't use it\nthe way it is now!");
static const u8 sText_BrokeThroughProtection[] = _("It broke through the\n{B_DEF_NAME_WITH_PREFIX}'s protection!");
static const u8 sText_SwappedAbilities[] = _("{B_DEF_NAME_WITH_PREFIX} swapped Abilities\nwith its target!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_SWAPPEDABILITIES - 12] = sText_SwappedAbilities,
[STRINGID_BROKETHROUGHPROTECTION - 12] = sText_BrokeThroughProtection,
[STRINGID_BUTPOKEMONCANTUSETHEMOVE - 12] = sText_ButPokemonCantUseTheMove,
[STRINGID_BUTHOOPACANTUSEIT - 12] = sText_ButHoopaCantUseIt,
[STRINGID_PKMNREVERTEDTOPRIMAL - 12] = sText_PkmnRevertedToPrimal,
[STRINGID_STUFFCHEEKSCANTSELECT - 12] = sText_StuffCheeksCantSelect,
[STRINGID_ATTACKWEAKENEDBSTRONGWINDS - 12] = sText_AttackWeakenedByStrongWinds,
[STRINGID_MYSTERIOUSAIRCURRENTBLOWSON - 12] = sText_MysteriousAirCurrentBlowsOn,
[STRINGID_STRONGWINDSDISSIPATED - 12] = sText_StrongWindsDissipated,

View File

@ -56,6 +56,7 @@
#include "constants/party_menu.h"
extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct Evolution gEvolutionTable[][EVOS_PER_MON];
extern const u8* const gBattleScriptsForMoveEffects[];
@ -1392,7 +1393,8 @@ static void Cmd_attackcanceler(void)
return;
if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBattlerTarget, 0, 0, 0))
return;
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & (HITMARKER_x800000 | HITMARKER_NO_ATTACKSTRING))
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE
&& !(gHitMarker & (HITMARKER_x800000 | HITMARKER_NO_ATTACKSTRING | HITMARKER_NO_PPDEDUCT))
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
{
gBattlescriptCurrInstr = BattleScript_NoPPForMove;
@ -1437,7 +1439,7 @@ static void Cmd_attackcanceler(void)
gProtectStructs[gBattlerTarget].bounceMove = 0;
gProtectStructs[gBattlerTarget].usesBouncedMove = 1;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker))
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE))
{
// Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker
gBattlerTarget = gBattlerAttacker;
@ -1597,7 +1599,7 @@ static bool32 AccuracyCalcHelper(u16 move)
if ((WEATHER_HAS_EFFECT &&
(((gBattleWeather & WEATHER_RAIN_ANY) && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
|| (((gBattleWeather & WEATHER_HAIL_ANY) && move == MOVE_BLIZZARD))))
|| ((B_BLIZZARD_HAIL >= GEN_4 && (gBattleWeather & WEATHER_HAIL_ANY) && move == MOVE_BLIZZARD))))
|| (gBattleMoves[move].effect == EFFECT_VITAL_THROW)
|| (gBattleMoves[move].accuracy == 0)
|| ((B_MINIMIZE_DMG_ACC >= GEN_6) && (gStatuses3[gBattlerTarget] & STATUS3_MINIMIZED) && (gBattleMoves[move].flags & FLAG_DMG_MINIMIZE)))
@ -3276,15 +3278,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
}
break;
case MOVE_EFFECT_FEINT:
if (gProtectStructs[gBattlerTarget].protected
|| gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_WIDE_GUARD
|| gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_QUICK_GUARD
|| gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_CRAFTY_SHIELD
|| gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_MAT_BLOCK
|| gProtectStructs[gBattlerTarget].spikyShielded
|| gProtectStructs[gBattlerTarget].kingsShielded
|| gProtectStructs[gBattlerTarget].banefulBunkered
|| gProtectStructs[gBattlerTarget].obstructed)
if (IS_BATTLER_PROTECTED(gBattlerTarget))
{
gProtectStructs[gBattlerTarget].protected = 0;
gSideStatuses[GetBattlerSide(gBattlerTarget)] &= ~(SIDE_STATUS_WIDE_GUARD);
@ -3300,6 +3294,11 @@ void SetMoveEffect(bool32 primary, u32 certain)
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectFeint;
}
else if (gCurrentMove == MOVE_HYPERSPACE_FURY)
{
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_HyperspaceFuryRemoveProtect;
}
}
break;
case MOVE_EFFECT_SPECTRAL_THIEF:
@ -3373,16 +3372,22 @@ void SetMoveEffect(bool32 primary, u32 certain)
}
break;
case MOVE_EFFECT_BUG_BITE:
if ((gBattleMons[gEffectBattler].item >= FIRST_BERRY_INDEX && gBattleMons[gEffectBattler].item <= LAST_BERRY_INDEX)
if (ItemId_GetPocket(gBattleMons[gEffectBattler].item) == POCKET_BERRIES
&& GetBattlerAbility(gEffectBattler) != ABILITY_STICKY_HOLD)
{
// target loses their berry
gLastUsedItem = gBattleMons[gEffectBattler].item;
gBattleMons[gEffectBattler].item = 0;
CheckSetUnburden(gEffectBattler);
gActiveBattler = gEffectBattler;
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gEffectBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
// attacker temporarily gains their item
gBattleStruct->changedItems[gBattlerAttacker] = gBattleMons[gBattlerAttacker].item;
gBattleMons[gBattlerAttacker].item = gLastUsedItem;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectBugBite;
}
@ -3499,12 +3504,14 @@ static void Cmd_tryfaintmon(void)
if (gBattleResults.playerFaintCounter < 0xFF)
gBattleResults.playerFaintCounter++;
AdjustFriendshipOnBattleFaint(gActiveBattler);
gSideTimers[0].retaliateTimer = 2;
}
else
{
if (gBattleResults.opponentFaintCounter < 0xFF)
gBattleResults.opponentFaintCounter++;
gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL);
gSideTimers[1].retaliateTimer = 2;
}
if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBattlerAttacker].hp != 0)
{
@ -3831,6 +3838,9 @@ static void Cmd_getexp(void)
*(&gBattleStruct->sentInPokes) >>= 1;
gBattleScripting.getexpState = 5;
gBattleMoveDamage = 0; // used for exp
#if B_MAX_LEVEL_EV_GAINS >= GEN_5
MonGainEVs(&gPlayerParty[gBattleStruct->expGetterMonId], gBattleMons[gBattlerFainted].species);
#endif
}
else
{
@ -4527,12 +4537,13 @@ static void Cmd_endselectionscript(void)
static void Cmd_playanimation(void)
{
const u16* argumentPtr;
u8 animId = gBattlescriptCurrInstr[2];
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
#if B_TERRAIN_BG_CHANGE == FALSE
if (gBattlescriptCurrInstr[2] == B_ANIM_RESTORE_BG)
if (animId == B_ANIM_RESTORE_BG)
{
// workaround for .if not working
gBattlescriptCurrInstr += 7;
@ -4540,28 +4551,29 @@ static void Cmd_playanimation(void)
}
#endif
if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE
|| gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE
|| gBattlescriptCurrInstr[2] == B_ANIM_MEGA_EVOLUTION
|| gBattlescriptCurrInstr[2] == B_ANIM_ILLUSION_OFF
|| gBattlescriptCurrInstr[2] == B_ANIM_FORM_CHANGE
|| gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE)
if (animId == B_ANIM_STATS_CHANGE
|| animId == B_ANIM_SNATCH_MOVE
|| animId == B_ANIM_MEGA_EVOLUTION
|| animId == B_ANIM_ILLUSION_OFF
|| animId == B_ANIM_FORM_CHANGE
|| animId == B_ANIM_SUBSTITUTE_FADE
|| animId == B_ANIM_PRIMAL_REVERSION)
{
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7;
}
else if (gHitMarker & HITMARKER_NO_ANIMATIONS)
else if (gHitMarker & HITMARKER_NO_ANIMATIONS && animId != B_ANIM_RESTORE_BG)
{
BattleScriptPush(gBattlescriptCurrInstr + 7);
gBattlescriptCurrInstr = BattleScript_Pausex20;
}
else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES)
else if (animId == B_ANIM_RAIN_CONTINUES
|| animId == B_ANIM_SUN_CONTINUES
|| animId == B_ANIM_SANDSTORM_CONTINUES
|| animId == B_ANIM_HAIL_CONTINUES)
{
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7;
}
@ -4571,7 +4583,7 @@ static void Cmd_playanimation(void)
}
else
{
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7;
}
@ -4591,7 +4603,8 @@ static void Cmd_playanimation2(void) // animation Id is stored in the first poin
|| *animationIdPtr == B_ANIM_MEGA_EVOLUTION
|| *animationIdPtr == B_ANIM_ILLUSION_OFF
|| *animationIdPtr == B_ANIM_FORM_CHANGE
|| *animationIdPtr == B_ANIM_SUBSTITUTE_FADE)
|| *animationIdPtr == B_ANIM_SUBSTITUTE_FADE
|| *animationIdPtr == B_ANIM_PRIMAL_REVERSION)
{
BtlController_EmitBattleAnimation(0, *animationIdPtr, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
@ -5150,7 +5163,6 @@ static void Cmd_moveend(void)
MoveValuesCleanUp();
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
gBattleStruct->atkCancellerTracker = 0; // Run all cancellers on next target
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
@ -6633,7 +6645,6 @@ static void Cmd_jumptocalledmove(void)
else
gChosenMove = gCurrentMove = gCalledMove;
gBattleStruct->atkCancellerTracker = 0;
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
}
@ -7376,6 +7387,21 @@ static u32 GetHighestStatId(u32 battlerId)
return highestId;
}
static bool32 IsRototillerAffected(u32 battlerId)
{
if (!IsBattlerAlive(battlerId))
return FALSE;
if (!IsBattlerGrounded(battlerId))
return FALSE; // Only grounded battlers affected
if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_GRASS))
return FALSE; // Only grass types affected
if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE)
return FALSE; // Rototiller doesn't affected semi-invulnerable battlers
if (BlocksPrankster(MOVE_ROTOTILLER, gBattlerAttacker, battlerId, FALSE))
return FALSE;
return TRUE;
}
static void Cmd_various(void)
{
struct Pokemon *mon;
@ -8089,7 +8115,7 @@ static void Cmd_various(void)
}
else
{
gStatuses3[gBattlerTarget] |= STATUS3_ELECTRIFIED;
gStatuses4[gBattlerTarget] |= STATUS4_ELECTRIFIED;
gBattlescriptCurrInstr += 7;
}
return;
@ -8179,6 +8205,47 @@ static void Cmd_various(void)
}
gBattlescriptCurrInstr += 4;
return;
case VARIOUS_HANDLE_PRIMAL_REVERSION:
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
else
mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
// Change species.
if (gBattlescriptCurrInstr[3] == 0)
{
u16 primalSpecies;
gBattleStruct->mega.primalRevertedSpecies[gActiveBattler] = gBattleMons[gActiveBattler].species;
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT
|| (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))))
{
gBattleStruct->mega.playerPrimalRevertedSpecies = gBattleStruct->mega.primalRevertedSpecies[gActiveBattler];
}
// Checks Primal Reversion
primalSpecies = GetMegaEvolutionSpecies(gBattleStruct->mega.primalRevertedSpecies[gActiveBattler], gBattleMons[gActiveBattler].item);
gBattleMons[gActiveBattler].species = primalSpecies;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
BtlController_EmitSetMonData(0, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], 2, &gBattleMons[gActiveBattler].species);
MarkBattlerForControllerExec(gActiveBattler);
}
// Change stats.
else if (gBattlescriptCurrInstr[3] == 1)
{
RecalcBattlerStats(gActiveBattler, mon);
gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]];
}
// Update healthbox and elevation.
else
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL);
CreateMegaIndicatorSprite(gActiveBattler, 0);
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species);
}
gBattlescriptCurrInstr += 4;
return;
case VARIOUS_HANDLE_FORM_CHANGE:
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
@ -8787,7 +8854,7 @@ static void Cmd_various(void)
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
break;
case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler))
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler, TRUE))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
@ -8825,6 +8892,97 @@ static void Cmd_various(void)
}
break;
}
case VARIOUS_GET_ROTOTILLER_TARGETS:
// Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!'
{
u32 count = 0;
for (i = 0; i < gBattlersCount; i++)
{
gSpecialStatuses[i].rototillerAffected = FALSE;
if (IsRototillerAffected(i))
{
gSpecialStatuses[i].rototillerAffected = TRUE;
count++;
}
}
if (count == 0)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Rototiller fails
else
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED:
if (gSpecialStatuses[gActiveBattler].rototillerAffected)
{
gSpecialStatuses[gActiveBattler].rototillerAffected = FALSE;
gBattlescriptCurrInstr += 7;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET
}
return;
case VARIOUS_TRY_ACTIVATE_BATTLE_BOND:
if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND
&& HasAttackerFaintedTarget()
&& CalculateEnemyPartyCount() > 1)
{
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;
return;
}
break;
case VARIOUS_CONSUME_BERRY:
if (ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item) == HOLD_EFFECT_NONE)
{
gBattlescriptCurrInstr += 4;
return;
}
gBattleScripting.battler = gEffectBattler = gBattlerTarget = gActiveBattler; // Cover all berry effect battlerId cases. e.g. ChangeStatBuffs uses target ID
// Do move end berry effects for just a single battler, instead of looping through all battlers
if (ItemBattleEffects(ITEMEFFECT_BATTLER_MOVE_END, gActiveBattler, FALSE))
return;
if (gBattlescriptCurrInstr[3])
{
gBattleMons[gActiveBattler].item = gBattleStruct->changedItems[gActiveBattler];
gBattleStruct->changedItems[gActiveBattler] = ITEM_NONE;
gBattleResources->flags->flags[gActiveBattler] &= ~(RESOURCE_FLAG_UNBURDEN);
}
gBattlescriptCurrInstr += 4;
return;
case VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL:
{
bool8 canDoPrimalReversion = FALSE;
for (i = 0; i < EVOS_PER_MON; i++)
{
if (gEvolutionTable[gBattleMons[gActiveBattler].species][i].method == EVO_PRIMAL_REVERSION
&& gEvolutionTable[gBattleMons[gActiveBattler].species][i].param == gBattleMons[gActiveBattler].item)
canDoPrimalReversion = TRUE;
}
if (!canDoPrimalReversion)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
}
case VARIOUS_APPLY_PLASMA_FISTS:
for (i = 0; i < gBattlersCount; i++)
gStatuses4[i] |= STATUS4_PLASMA_FISTS;
break;
case VARIOUS_JUMP_IF_SPECIES:
if (gBattleMons[gActiveBattler].species == T1_READ_16(gBattlescriptCurrInstr + 3))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5);
else
gBattlescriptCurrInstr += 9;
return;
}
gBattlescriptCurrInstr += 3;
@ -10770,7 +10928,7 @@ static void Cmd_settailwind(void)
{
gSideStatuses[side] |= SIDE_STATUS_TAILWIND;
gSideTimers[side].tailwindBattlerId = gBattlerAttacker;
gSideTimers[side].tailwindTimer = (B_TAILWIND_TIMER >= GEN_5) ? 4 : 3;
gSideTimers[side].tailwindTimer = (B_TAILWIND_TURNS >= GEN_5) ? 4 : 3;
gBattlescriptCurrInstr += 5;
}
else
@ -10986,7 +11144,7 @@ static void Cmd_trysetperishsong(void)
{
if (gStatuses3[i] & STATUS3_PERISH_SONG
|| GetBattlerAbility(i) == ABILITY_SOUNDPROOF
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i))
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE))
{
notAffectedCount++;
}
@ -11523,7 +11681,7 @@ static void Cmd_jumpifattackandspecialattackcannotfall(void) // memento
&& gBattleMons[gBattlerTarget].statStages[STAT_SPATK] == MIN_STAT_STAGE
&& gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED)
#else
if (gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED
if (gBattleCommunication[MISS_TYPE] == B_MSG_PROTECTED
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE
|| IsBattlerProtected(gBattlerTarget, gCurrentMove)
|| DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
@ -11626,9 +11784,15 @@ static void Cmd_settaunt(void)
}
else if (gDisableStructs[gBattlerTarget].tauntTimer == 0)
{
u8 turns = 4;
if (GetBattlerTurnOrderNum(gBattlerTarget) > GetBattlerTurnOrderNum(gBattlerAttacker))
turns--; // If the target hasn't yet moved this turn, Taunt lasts for only three turns (source: Bulbapedia)
#if B_TAUNT_TURNS >= GEN_5
u8 turns = 4;
if (GetBattlerTurnOrderNum(gBattlerTarget) > GetBattlerTurnOrderNum(gBattlerAttacker))
turns--; // If the target hasn't yet moved this turn, Taunt lasts for only three turns (source: Bulbapedia)
#elif B_TAUNT_TURNS == GEN_4
u8 turns = (Random() & 2) + 3;
#else
u8 turns = 2;
#endif
gDisableStructs[gBattlerTarget].tauntTimer = gDisableStructs[gBattlerTarget].tauntTimer2 = turns;
gBattlescriptCurrInstr += 5;
@ -12355,6 +12519,8 @@ bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
return FALSE;
else if (GetBattlerAbility(battlerAtk) == ABILITY_INFILTRATOR)
return FALSE;
else if (gBattleMoves[move].flags & FLAG_HIT_IN_SUBSTITUTE)
return FALSE;
else
return TRUE;
}
@ -12481,7 +12647,7 @@ static void Cmd_removelightscreenreflect(void) // brick break
gBattlescriptCurrInstr++;
}
static u8 GetCatchingBattler(void)
u8 GetCatchingBattler(void)
{
if (IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)))
return GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);

View File

@ -621,6 +621,12 @@ bool8 TryRunFromBattle(u8 battler)
gProtectStructs[battler].fleeFlag = 1;
effect++;
}
#if B_GHOSTS_ESCAPE >= GEN_6
else if (IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
{
effect++;
}
#endif
else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY)
{
if (InBattlePyramid())
@ -1725,6 +1731,21 @@ u8 TrySetCantSelectMoveBattleScript(void)
limitations++;
}
}
if (move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
{
gCurrentMove = move;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedBelchInPalace;
gProtectStructs[gActiveBattler].palaceUnableToUseMove = 1;
}
else
{
gSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedStuffCheeks;
limitations++;
}
}
gPotentialItemEffectBattler = gActiveBattler;
if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move)
@ -1808,6 +1829,8 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
unusableMoves |= gBitTable[i];
else if (gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND)
unusableMoves |= gBitTable[i];
else if (gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
unusableMoves |= gBitTable[i];
}
return unusableMoves;
}
@ -1881,6 +1904,7 @@ enum
ENDTURN_PSYCHIC_TERRAIN,
ENDTURN_ION_DELUGE,
ENDTURN_FAIRY_LOCK,
ENDTURN_RETALIATE,
ENDTURN_FIELD_COUNT,
};
@ -2234,7 +2258,7 @@ 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.electricTerrainTimer == 0))
{
gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT);
BattleScriptExecute(BattleScript_ElectricTerrainEnds);
@ -2244,7 +2268,7 @@ 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.mistyTerrainTimer == 0))
{
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN);
BattleScriptExecute(BattleScript_MistyTerrainEnds);
@ -2266,7 +2290,7 @@ 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.psychicTerrainTimer == 0))
{
gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN);
BattleScriptExecute(BattleScript_PsychicTerrainEnds);
@ -2312,6 +2336,13 @@ u8 DoFieldEndTurnEffects(void)
}
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_RETALIATE:
if (gSideTimers[B_SIDE_PLAYER].retaliateTimer > 0)
gSideTimers[B_SIDE_PLAYER].retaliateTimer--;
if (gSideTimers[B_SIDE_OPPONENT].retaliateTimer > 0)
gSideTimers[B_SIDE_OPPONENT].retaliateTimer--;
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_FIELD_COUNT:
effect++;
break;
@ -2355,6 +2386,7 @@ enum
ENDTURN_POWDER,
ENDTURN_THROAT_CHOP,
ENDTURN_SLOW_START,
ENDTURN_PLASMA_FISTS,
ENDTURN_BATTLER_COUNT
};
@ -2838,7 +2870,7 @@ u8 DoBattlerEndTurnEffects(void)
gBattleStruct->turnEffectsTracker++;
break;
case ENDTURN_ELECTRIFY:
gStatuses3[gActiveBattler] &= ~(STATUS3_ELECTRIFIED);
gStatuses4[gActiveBattler] &= ~(STATUS4_ELECTRIFIED);
gBattleStruct->turnEffectsTracker++;
case ENDTURN_POWDER:
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_POWDER);
@ -2861,6 +2893,11 @@ u8 DoBattlerEndTurnEffects(void)
}
gBattleStruct->turnEffectsTracker++;
break;
case ENDTURN_PLASMA_FISTS:
for (i = 0; i < gBattlersCount; i++)
gStatuses4[i] &= ~(STATUS4_PLASMA_FISTS);
gBattleStruct->turnEffectsTracker++;
break;
case ENDTURN_BATTLER_COUNT: // done
gBattleStruct->turnEffectsTracker = 0;
gBattleStruct->turnEffectsBattlerId++;
@ -3106,7 +3143,6 @@ enum
CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS,
CANCELLER_THROAT_CHOP,
CANCELLER_PRANKSTER,
CANCELLER_END,
CANCELLER_PSYCHIC_TERRAIN,
CANCELLER_END2,
@ -3435,18 +3471,6 @@ u8 AtkCanceller_UnableToUseMove(void)
}
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_PRANKSTER:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget)
&& !(IS_MOVE_STATUS(gCurrentMove) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE))
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster;
effect = 1;
}
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_END:
break;
}
@ -4548,6 +4572,16 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
gBattlescriptCurrInstr = BattleScript_DazzlingProtected;
effect = 1;
}
else if (BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE)
&& !(IS_MOVE_STATUS(move) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE))
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster;
effect = 1;
}
break;
case ABILITYEFFECT_ABSORBING: // 3
if (move != MOVE_NONE)
@ -4890,7 +4924,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& TARGET_TURN_DAMAGED
&& IsMoveMakingContact(move, gBattlerAttacker))
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 8;
#if B_ROUGH_SKIN_DMG >= GEN_4
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 8;
#else
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16;
#endif
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
@ -5062,20 +5100,21 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY)
&& TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE)
&& !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY))
&& !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY))
{
gBattleScripting.battler = gActiveBattler = battler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SandSpitActivates;
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BlockedByPrimalWeatherRet;
effect++;
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BlockedByPrimalWeatherRet;
effect++;
}
else if (TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE))
{
gBattleScripting.battler = gActiveBattler = battler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SandSpitActivates;
effect++;
}
}
break;
case ABILITY_PERISH_BODY:
@ -5181,18 +5220,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
effect++;
}
break;
case ABILITY_BATTLE_BOND:
if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND
&& gBattleResults.opponentFaintCounter != 0
&& CalculateEnemyPartyCount() > 1)
{
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;
}
break;
}
break;
case ABILITYEFFECT_MOVE_END_OTHER: // Abilities that activate on *another* battler's moveend: Dancer, Soul-Heart, Receiver, Symbiosis
@ -5674,6 +5701,8 @@ bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId)
if (gBattleMons[battlerId].hp == 0)
return FALSE;
if (gBattleScripting.overrideBerryRequirements)
return TRUE;
// Unnerve prevents consumption of opponents' berries.
if (isBerry && IsUnnerveAbilityOnOpposingSide(battlerId))
return FALSE;
@ -5877,7 +5906,8 @@ u8 TryHandleSeed(u8 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 exec
static u8 ItemHealHp(u32 battlerId, u32 itemId, bool32 end2, bool32 percentHeal)
{
if (HasEnoughHpToEatBerry(battlerId, 2, itemId))
if (HasEnoughHpToEatBerry(battlerId, 2, itemId)
&& !(gBattleScripting.overrideBerryRequirements && gBattleMons[battlerId].hp == gBattleMons[battlerId].maxHP))
{
if (percentHeal)
gBattleMoveDamage = (gBattleMons[battlerId].maxHP * GetBattlerHoldEffectParam(battlerId) / 100) * -1;
@ -6504,11 +6534,14 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
}
}
break;
case ITEMEFFECT_BATTLER_MOVE_END:
goto DO_ITEMEFFECT_MOVE_END; // this hurts a bit to do, but is an easy solution
case ITEMEFFECT_MOVE_END:
for (battlerId = 0; battlerId < gBattlersCount; battlerId++)
{
gLastUsedItem = gBattleMons[battlerId].item;
battlerHoldEffect = GetBattlerHoldEffect(battlerId, TRUE);
DO_ITEMEFFECT_MOVE_END:
switch (battlerHoldEffect)
{
case HOLD_EFFECT_MICLE_BERRY:
@ -7033,7 +7066,7 @@ u32 SetRandomTarget(u32 battlerId)
return target;
}
u8 GetMoveTarget(u16 move, u8 setTarget)
u32 GetMoveTarget(u16 move, u8 setTarget)
{
u8 targetBattler = 0;
u32 i, moveTarget, side;
@ -7708,6 +7741,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
#endif
break;
}
case EFFECT_GRAV_APPLE:
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
MulModifier(&basePower, UQ_4_12(1.5));
break;
}
// move-specific base power changes
@ -7731,6 +7768,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
u16 basePower = CalcMoveBasePower(move, battlerAtk, battlerDef);
u16 holdEffectModifier;
u16 modifier = UQ_4_12(1.0);
u32 atkSide = GET_BATTLER_SIDE(battlerAtk);
// attacker's abilities
switch (GetBattlerAbility(battlerAtk))
@ -7983,7 +8021,8 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
MulModifier(&modifier, UQ_4_12(2.0));
break;
case EFFECT_RETALIATE:
// todo
if (gSideTimers[atkSide].retaliateTimer == 1)
MulModifier(&modifier, UQ_4_12(2.0));
break;
case EFFECT_SOLARBEAM:
if (WEATHER_HAS_EFFECT && gBattleWeather & (WEATHER_HAIL_ANY | WEATHER_SANDSTORM_ANY | WEATHER_RAIN_ANY))
@ -8216,7 +8255,8 @@ static bool32 CanEvolve(u32 species)
{
if (gEvolutionTable[species][i].method
&& gEvolutionTable[species][i].method != EVO_MEGA_EVOLUTION
&& gEvolutionTable[species][i].method != EVO_MOVE_MEGA_EVOLUTION)
&& gEvolutionTable[species][i].method != EVO_MOVE_MEGA_EVOLUTION
&& gEvolutionTable[species][i].method != EVO_PRIMAL_REVERSION)
return TRUE;
}
return FALSE;
@ -8770,9 +8810,10 @@ u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId)
for (i = 0; i < EVOS_PER_MON; i++)
{
if (gEvolutionTable[preEvoSpecies][i].method == EVO_MEGA_EVOLUTION
&& gEvolutionTable[preEvoSpecies][i].param == heldItemId)
return gEvolutionTable[preEvoSpecies][i].targetSpecies;
if ((gEvolutionTable[preEvoSpecies][i].method == EVO_MEGA_EVOLUTION
|| gEvolutionTable[preEvoSpecies][i].method == EVO_PRIMAL_REVERSION)
&& gEvolutionTable[preEvoSpecies][i].param == heldItemId)
return gEvolutionTable[preEvoSpecies][i].targetSpecies;
}
return SPECIES_NONE;
}
@ -8837,12 +8878,20 @@ bool32 CanMegaEvolve(u8 battlerId)
else
holdEffect = ItemId_GetHoldEffect(itemId);
// Can Mega Evolve via Item.
// Can Mega Evolve via Mega Stone.
if (holdEffect == HOLD_EFFECT_MEGA_STONE)
{
gBattleStruct->mega.isWishMegaEvo = FALSE;
return TRUE;
}
// Can undergo Primal Reversion.
if (holdEffect == HOLD_EFFECT_PRIMAL_ORB)
{
gBattleStruct->mega.isWishMegaEvo = FALSE;
gBattleStruct->mega.isPrimalReversion = TRUE;
return TRUE;
}
}
// Check if there is an entry in the evolution table for Wish Mega Evolution.
@ -8858,12 +8907,20 @@ bool32 CanMegaEvolve(u8 battlerId)
void UndoMegaEvolution(u32 monId)
{
u16 baseSpecies = GET_BASE_SPECIES_ID(GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES));
if (gBattleStruct->mega.evolvedPartyIds[B_SIDE_PLAYER] & gBitTable[monId])
{
gBattleStruct->mega.evolvedPartyIds[B_SIDE_PLAYER] &= ~(gBitTable[monId]);
SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleStruct->mega.playerEvolvedSpecies);
CalculateMonStats(&gPlayerParty[monId]);
}
else if (gBattleStruct->mega.primalRevertedPartyIds[B_SIDE_PLAYER] & gBitTable[monId])
{
gBattleStruct->mega.primalRevertedPartyIds[B_SIDE_PLAYER] &= ~(gBitTable[monId]);
SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &baseSpecies);
CalculateMonStats(&gPlayerParty[monId]);
}
// While not exactly a mega evolution, Zygarde follows the same rules.
else if (GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, NULL) == SPECIES_ZYGARDE_COMPLETE)
{
@ -8880,6 +8937,7 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
static const u16 species[][2] = // changed form id, default form id
{
{SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU},
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND},
{SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH},
{SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN},
{SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED},
@ -8892,11 +8950,10 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
{SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI},
{SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT},
{SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT},
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND},
};
if (isSwitchingOut) // Don't revert Mimikyu Busted when switching out
i = 1;
if (isSwitchingOut) // Don't revert Mimikyu Busted or Ash-Greninja when switching out
i = 2;
else
i = 0;
@ -9478,16 +9535,21 @@ void DoBurmyFormChange(u32 monId)
}
}
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef)
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget)
{
#if B_PRANKSTER_DARK_TYPES >= GEN_7
if (gProtectStructs[battlerPrankster].pranksterElevated
&& GetBattlerSide(battlerPrankster) != GetBattlerSide(battlerDef)
&& !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)) // Don't block hazards, assist-type moves
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) // Only Dark-types can block Prankster'd
&& !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE))
return TRUE;
else
#endif
if (!gProtectStructs[battlerPrankster].pranksterElevated)
return FALSE;
if (GetBattlerSide(battlerPrankster) == GetBattlerSide(battlerDef))
return FALSE;
if (checkTarget && (gBattleMoves[move].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)))
return FALSE;
if (!IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK))
return FALSE;
if (gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)
return FALSE;
return TRUE;
#endif
return FALSE;
}

View File

@ -1789,7 +1789,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 30,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = FLAG_PROTECT_AFFECTED,
.split = SPLIT_STATUS,
@ -3101,7 +3101,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 5,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = FLAG_SOUND,
.split = SPLIT_STATUS,
@ -3205,7 +3205,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -3809,7 +3809,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 5,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -3823,7 +3823,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 5,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -4130,7 +4130,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = FLAG_PROTECT_AFFECTED,
.split = SPLIT_STATUS,
@ -4773,7 +4773,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100,
.pp = 15,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -5513,7 +5513,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100,
.pp = 15,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -5670,7 +5670,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 5,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -6884,7 +6884,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 5,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = -7,
.flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS,
@ -7415,6 +7415,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.split = SPLIT_PHYSICAL,
.argument = MOVE_EFFECT_FEINT,
},
[MOVE_HONE_CLAWS] =
@ -7487,7 +7488,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS,
},
@ -7579,7 +7580,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS,
},
@ -7944,7 +7945,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_SCALD] =
{
.effect = EFFECT_SCALD,
#if B_UPDATED_MOVE_DATA >= GEN_6
.effect = EFFECT_SCALD,
#else
.effect = EFFECT_BURN_HIT,
#endif
.power = 80,
.type = TYPE_WATER,
.accuracy = 100,
@ -8847,7 +8852,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -8941,7 +8946,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 25,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 1,
.flags = 0,
.split = SPLIT_STATUS,
@ -9092,7 +9097,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER | MOVE_TARGET_FOES_AND_ALLY,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -9106,7 +9111,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -9120,7 +9125,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -9204,7 +9209,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS,
@ -9454,7 +9459,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -9687,15 +9692,15 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_HYPERSPACE_FURY] =
{
.effect = EFFECT_PLACEHOLDER,
.power = 0,
.effect = EFFECT_HYPERSPACE_FURY,
.power = 100,
.type = TYPE_DARK,
.accuracy = 0,
.pp = 0,
.secondaryEffectChance = 0,
.pp = 5,
.secondaryEffectChance = 100,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = 0,
.flags = FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIT_IN_SUBSTITUTE,
.split = SPLIT_PHYSICAL,
},
@ -9974,7 +9979,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -10435,7 +10440,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_PLASMA_FISTS] =
{
.effect = EFFECT_PLACEHOLDER, // Needs a custom move effect
.effect = EFFECT_PLASMA_FISTS,
.power = 100,
.type = TYPE_ELECTRIC,
.accuracy = 100,
@ -10465,7 +10470,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
{
#if B_UPDATED_MOVE_DATA >= GEN_8
.power = 80,
.effect = EFFECT_PLACEHOLDER, // TODO: EFFECT_EVASION_UP_HIT
.effect = EFFECT_EVASION_UP_HIT,
.pp = 10,
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST,
#else
@ -10608,7 +10613,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100,
.flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
#endif
.effect = EFFECT_PLACEHOLDER, //TODO (Light Screen + Hit)
.effect = EFFECT_GLITZY_GLOW,
.type = TYPE_PSYCHIC,
.pp = 15,
.secondaryEffectChance = 0,
@ -10628,7 +10633,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100,
.flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
#endif
.effect = EFFECT_PLACEHOLDER, //TODO (Reflect + Hit)
.effect = EFFECT_BADDY_BAD,
.type = TYPE_DARK,
.pp = 15,
.secondaryEffectChance = 0,
@ -10650,7 +10655,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.pp = 15,
.flags = FLAG_PROTECT_AFFECTED | FLAG_MAGIC_COAT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
#endif
.effect = EFFECT_PLACEHOLDER, //TODO (Leech Seed + Hit)
.effect = EFFECT_SAPPY_SEED,
.type = TYPE_GRASS,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_SELECTED,
@ -10671,7 +10676,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.pp = 15,
.flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
#endif
.effect = EFFECT_PLACEHOLDER, //TODO (Haze + Hit)
.effect = EFFECT_FREEZY_FROST,
.type = TYPE_ICE,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_SELECTED,
@ -10692,7 +10697,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.pp = 15,
.flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
#endif
.effect = EFFECT_PLACEHOLDER, //TODO (Heal Bell + Hit)
.effect = EFFECT_SPARKLY_SWIRL,
.type = TYPE_FAIRY,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_SELECTED,
@ -10725,7 +10730,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
#else
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST,
#endif
.effect = EFFECT_PLACEHOLDER, //TODO (EFFECT_FLINCH_HIT + EFFECT_DOUBLE_HIT)
.effect = EFFECT_DOUBLE_IRON_BASH,
.power = 60,
.type = TYPE_STEEL,
.accuracy = 100,
@ -10738,7 +10743,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_DYNAMAX_CANNON] =
{
.effect = EFFECT_HIT,
.effect = EFFECT_DYNAMAX_DOUBLE_DMG,
.power = 100,
.type = TYPE_DRAGON,
.accuracy = 100,
@ -10780,7 +10785,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_STUFF_CHEEKS] =
{
.effect = EFFECT_DEFENSE_UP_2,
.effect = EFFECT_STUFF_CHEEKS,
.power = 0,
.type = TYPE_NORMAL,
.accuracy = 0,
@ -10857,7 +10862,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = 0,
.split = SPLIT_STATUS,
@ -10913,7 +10918,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100,
.pp = 10,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0,
.flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS,
@ -11103,7 +11108,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_GRAV_APPLE] =
{
.effect = EFFECT_DEFENSE_DOWN_HIT,
.effect = EFFECT_GRAV_APPLE,
.power = 80,
.type = TYPE_GRASS,
.accuracy = 100,

View File

@ -41,6 +41,15 @@ const u32 gBattleAnimSpritePal_MegaParticles[] = INCBIN_U32("graphics/battle_ani
const u32 gBattleAnimSpriteGfx_MegaSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/mega_symbol.4bpp.lz");
const u32 gBattleAnimSpritePal_MegaSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/mega_symbol.gbapal.lz");
const u32 gBattleAnimSpriteGfx_AlphaSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/alpha_symbol.4bpp.lz");
const u32 gBattleAnimSpritePal_AlphaSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/alpha_symbol.gbapal.lz");
const u32 gBattleAnimSpriteGfx_OmegaSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/omega_symbol.4bpp.lz");
const u32 gBattleAnimSpritePal_OmegaSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/omega_symbol.gbapal.lz");
const u32 gBattleAnimSpriteGfx_PrimalParticles[] = INCBIN_U32("graphics/battle_anims/sprites/primal_particles.4bpp.lz");
const u32 gBattleAnimSpritePal_PrimalParticles[] = INCBIN_U32("graphics/battle_anims/sprites/primal_particles.gbapal.lz");
const u32 gBattleAnimSpriteGfx_FlashCannonBall[] = INCBIN_U32("graphics/battle_anims/sprites/flash_cannon_ball.4bpp.lz");
const u32 gBattleAnimSpritePal_FlashCannonBall[] = INCBIN_U32("graphics/battle_anims/sprites/flash_cannon_ball.gbapal.lz");

View File

@ -947,11 +947,18 @@ u32 CanThrowBall(void)
{
return 2; // No room for mon
}
#if B_SEMI_INVULNERABLE_CATCH >= GEN_4
else if (gStatuses3[GetCatchingBattler()] & STATUS3_SEMI_INVULNERABLE)
{
return 3; // in semi-invulnerable state
}
#endif
return 0; // usable
}
static const u8 sText_CantThrowPokeBall_TwoMons[] = _("Cannot throw a ball!\nThere are two pokemon out there!\p");
static const u8 sText_CantThrowPokeBall_TwoMons[] = _("Cannot throw a ball!\nThere are two Pokémon out there!\p");
static const u8 sText_CantThrowPokeBall_SemiInvulnerable[] = _("Cannot throw a ball!\nThere's no Pokémon in sight!\p");
void ItemUseInBattle_PokeBall(u8 taskId)
{
switch (CanThrowBall())
@ -976,6 +983,14 @@ void ItemUseInBattle_PokeBall(u8 taskId)
else
DisplayItemMessageInBattlePyramid(taskId, gText_BoxFull, Task_CloseBattlePyramidBagMessage);
break;
#if B_SEMI_INVULNERABLE_CATCH >= GEN_4
case 3: // Semi-Invulnerable
if (!InBattlePyramid())
DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_SemiInvulnerable, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_SemiInvulnerable, Task_CloseBattlePyramidBagMessage);
break;
#endif
}
}