Merge branch 'BattleEngine' into booleanStandard

# Conflicts:
#	src/battle_main.c
This commit is contained in:
Eduardo Quezada D'Ottone 2021-11-03 20:44:25 -03:00
commit 6ee2a3aba1
108 changed files with 4412 additions and 1346 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
@ -1580,6 +1585,10 @@
.macro showabilitypopup battler:req
various \battler, VARIOUS_ABILITY_POPUP
.endm
.macro updateabilitypopup battler:req
various \battler, VARIOUS_UPDATE_ABILITY_POPUP
.endm
.macro defogclear battler:req, clear:req, ptr:req
various \battler, VARIOUS_DEFOG
@ -1768,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
@ -1821,6 +1835,49 @@
various BS_ATTACKER, VARIOUS_REMOVE_TERRAIN
.endm
.macro trytoclearprimalweather
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
.endm
.macro setattackertostickywebuser
various BS_TARGET, VARIOUS_SET_ATTACKER_STICKY_WEB_USER
.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 jumpifweatheraffected battler:req, weather:req, ptr:req
various \battler, VARIOUS_JUMP_IF_WEATHER_AFFECTED
.4byte \weather
.4byte \ptr
.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
@ -1925,6 +1982,12 @@
1:
.endm
.macro jumpifflowerveilattacker jumpptr:req
jumpifnottype BS_ATTACKER, TYPE_GRASS, 1f
jumpifability BS_ATTACKER_SIDE, ABILITY_FLOWER_VEIL, \jumpptr
1:
.endm
.macro setallytonexttarget jumpptr:req
jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f
addbyte gBattlerTarget, 0x2
@ -1934,10 +1997,9 @@
goto \jumpptr
.endm
.macro jumpifleafguard jumpptr:req
jumpifhalfword CMP_NO_COMMON_BITS, gBattleWeather, WEATHER_SUN_ANY, 1f
jumpifability BS_TARGET, ABILITY_LEAF_GUARD, \jumpptr
1:
.macro jumpifleafguardprotected battler:req, jumpptr:req
various \battler, VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED
.4byte \jumpptr
.endm
.macro jumpifsafeguard jumpptr:req

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"
@ -477,7 +478,7 @@ gBattleAnims_Moves::
.4byte Move_HEAD_SMASH
.4byte Move_DOUBLE_HIT
.4byte Move_ROAR_OF_TIME
.4byte Move_SPECIAL_REND
.4byte Move_SPACIAL_REND
.4byte Move_LUNAR_DANCE
.4byte Move_CRUSH_GRIP
.4byte Move_MAGMA_STORM
@ -532,7 +533,7 @@ gBattleAnims_Moves::
.4byte Move_QUASH
.4byte Move_ACROBATICS
.4byte Move_REFLECT_TYPE
.4byte Move_RETALITATE
.4byte Move_RETALIATE
.4byte Move_FINAL_GAMBIT
.4byte Move_BESTOW
.4byte Move_INFERNO
@ -822,6 +823,9 @@ gBattleAnims_General::
.4byte General_SlideOffScreen @ B_ANIM_SLIDE_OFFSCREEN
.4byte General_RestoreBg @ B_ANIM_RESTORE_BG
.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::
@ -4162,7 +4166,7 @@ Move_ROAR_OF_TIME:
waitforvisualfinish
end
Move_SPECIAL_REND:
Move_SPACIAL_REND:
loadspritegfx ANIM_TAG_PUNISHMENT_BLADES
loadspritegfx ANIM_TAG_PINK_HEART_2 @ANIM_TAG_BERRY_EATEN
monbg ANIM_ATK_PARTNER
@ -5372,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:
@ -5610,7 +5639,7 @@ Move_REFLECT_TYPE:
blendoff
end
Move_RETALITATE:
Move_RETALIATE:
loadspritegfx ANIM_TAG_CUT @Cut
monbg ANIM_DEF_PARTNER
setalpha 9, 8
@ -6607,7 +6636,7 @@ Move_HURRICANE:
monbg ANIM_DEF_PARTNER
monbgprio_28 ANIM_TARGET
setalpha 12, 8
fadetobg BG_HIGH_SPEED
fadetobg BG_HURRICANE
waitbgfadeout
launchtask AnimTask_StartSlidingBg 0x5 0x4 0x1000 0x0 0x1 0xffff
waitbgfadein
@ -13911,47 +13940,64 @@ Move_ETERNA_BEAM::
goto Move_HYPER_BEAM
Move_STEEL_BEAM::
loadspritegfx ANIM_TAG_CLAW_SLASH
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 0, 0, 0
delay 48
loadspritegfx ANIM_TAG_ELECTRIC_ORBS
loadspritegfx ANIM_TAG_GUST
loadspritegfx ANIM_TAG_SPIKES
launchtask AnimTask_BlendBattleAnimPal 0xa 0x5 ANIM_PAL_BG 0x0 0x0 0x10 0x6B59 @To gray
launchtask AnimTask_ElectricChargingParticles 0x2 0x4 0x0 0x14 0x0 0x2
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
delay 0x14
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 0x9, 15
launchtask AnimTask_ShakeMon 0x2 0x5 ANIM_ATTACKER 0x0 0x4 72 0x1
call SteelBeamShards
call SteelBeamShards
launchtemplate gSlideMonToOffsetSpriteTemplate 0x2 0x5 ANIM_TARGET, -30, 0x0 TRUE 145
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
call SteelBeamShards
waitforvisualfinish
launchtemplate gSlideMonToOriginalPosSpriteTemplate 0x2 0x3 ANIM_TARGET 0x0 0x6
launchtask AnimTask_BlendBattleAnimPal 0xa 0x5 ANIM_PAL_BG 0x1 0xE 0x0 0x6B59 @From gray
delay 20
loadspritegfx ANIM_TAG_STEEL_BEAM
call SetSteelBeamBackground
panse_1B SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
createvisualtask AnimTask_CreateSmallSteelBeamOrbs, 5
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 0
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 1
delay 4
createvisualtask AnimTask_BlendBattleAnimPal, 10, 4, 1, 0, 10, RGB(24, 24, 48)
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 2
delay 4
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 2, 0, 65, 1
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 3
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 4
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 5
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 6
delay 4
call SteelBeam_Continuity
call SteelBeam_Continuity
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, 4, 1, 10, 0, RGB(24, 24, 48)
call UnsetHighSpeedBg
end
SteelBeamShards:
launchtemplate gSteelBeamSpikeShardTemplate 0x80, 0x5 0xf 0xf 0x14 0x0 0x0
launchtemplate gSteelBeamSpikeShardTemplate 0x80, 0x5 0xf 0xf 0x14 0xa 0x5
launchtemplate gSteelBeamSpikeShardTemplate 0x80, 0x5 0xf 0xf 0x14 0xfff6 0xfffb
delay 0x2
launchtemplate gSteelBeamSpikeShardTemplate 0x80, 0x5 0xf 0xf 0x14 0x14 0xa
launchtemplate gSteelBeamSpikeShardTemplate 0x80, 0x5 0xf 0xf 0x14 0xffec 0xfff6
delay 0x2
SteelBeam_Continuity:
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 0
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 1
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 2
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 3
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 4
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 5
delay 4
createsprite gSteelBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 6
delay 4
return
SetSteelBeamBackground:
createvisualtask AnimTask_GetAttackerSide, 2
jumprettrue SetSteelBeamBgPlayer
fadetobg BG_STEEL_BEAM_OPPONENT
goto SetHighSpeedBgFade
SetSteelBeamBgPlayer:
fadetobg BG_STEEL_BEAM_PLAYER
Move_EXPANDING_FORCE::
end @to do:
@ -24408,6 +24454,104 @@ RainbowEndureEffect:
delay 0x3
return
General_GulpMissile: @ Tackle anim (placeholder)
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_ATTACKER
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_ATTACKER, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 3, 0, 6, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
end
General_StrongWinds::
loadspritegfx ANIM_TAG_FLYING_DIRT
playsewithpan SE_M_GUST, 0
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_FLYING_DIRT, 0, 12, 12, RGB(20, 20, 20)
waitforvisualfinish
createvisualtask AnimTask_LoadWindstormBackground, 5, FALSE
delay 32
waitforvisualfinish
stopsound
end
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:
createvisualtask AnimTask_IsAttackerBehindSubstitute, 2
jumprettrue SnatchMoveSwapSubstituteForMon

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

View File

@ -1,19 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 246 0
255 238 0
255 222 0
255 205 0
255 189 0
255 172 0
255 156 8
255 139 8
255 123 8
255 106 8
255 90 8
255 74 8
255 49 8
255 41 8
246 24 0
96 192 24
248 248 216
248 248 176
248 240 144
248 232 120
248 232 112
248 216 96
240 200 88
232 192 72
232 184 64
232 176 56
224 160 32
216 152 32
208 136 40
192 120 40
176 88 40

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
208 112 200
216 184 249
216 160 232
211 107 195
208 104 192
217 129 209
216 135 215
209 120 208
218 153 226
216 168 232
217 176 241
220 188 252
203 115 203
223 182 246
216 192 248

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
255 0 0
222 156 230
222 180 246
213 123 205
213 189 246
205 115 205
213 164 230
213 131 213
222 197 255
222 189 255
213 139 222
213 172 238
213 106 197
222 131 213
213 115 205
205 106 197

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
255 0 0
213 156 230
222 180 246
213 123 205
213 189 246
213 131 213
205 115 205
213 164 230
222 197 255
213 139 222
222 189 255
213 172 238
213 106 197
213 115 205
222 156 230
205 106 197

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
184 192 224
168 176 208
144 152 192
112 120 168
96 104 160
88 96 144
80 88 136
72 80 120
64 72 112
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
255 0 0
222 156 230
222 180 246
213 123 205
213 189 246
205 115 205
213 164 230
213 131 213
222 197 255
222 189 255
213 139 222
213 172 238
213 106 197
222 131 213
213 115 205
205 106 197

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
255 0 0
213 156 230
222 180 246
213 123 205
213 189 246
213 131 213
205 115 205
213 164 230
222 197 255
213 139 222
222 189 255
213 172 238
213 106 197
213 115 205
222 156 230
205 106 197

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
112 120 208
128 136 216
144 152 224
160 168 232
176 184 240
192 200 248
208 216 248
248 248 248
0 0 0
0 0 0
0 0 0
0 0 0
248 192 216
248 248 168
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
1 177 91
143 129 149
103 91 111
79 65 85
59 31 81
103 89 109
231 239 245
249 253 255
0 0 0
0 0 0
107 115 115
74 66 82
0 0 0
214 214 206
132 140 140
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

View File

@ -37,6 +37,7 @@
#define B_ACTION_CANCEL_PARTNER 12 // when choosing an action
#define B_ACTION_NOTHING_FAINTED 13 // when choosing an action
#define B_ACTION_DEBUG 20
#define B_ACTION_THROW_BALL 21 // R to throw last used ball
#define B_ACTION_NONE 0xFF
#define MAX_TRAINER_ITEMS 4
@ -150,6 +151,7 @@ struct ProtectStruct
u32 disableEjectPack:1;
u32 statFell:1;
u32 pranksterElevated:1;
u32 quickDraw:1;
u32 physicalDmg;
u32 specialDmg;
u8 physicalBattlerId;
@ -174,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;
@ -209,6 +212,7 @@ struct SideTimer
u8 tailwindBattlerId;
u8 luckyChantTimer;
u8 luckyChantBattlerId;
u8 retaliateTimer;
};
struct FieldTimer
@ -461,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
@ -488,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;
@ -539,7 +547,7 @@ struct BattleStruct
u16 synchronizeMoveEffect;
bool8 anyMonHasTransformed;
void (*savedCallback)(void);
u16 usedHeldItems[MAX_BATTLERS_COUNT];
u16 usedHeldItems[PARTY_SIZE][2]; // For each party member and side. For harvest, recycle
u16 chosenItem[MAX_BATTLERS_COUNT];
u8 AI_itemType[2];
u8 AI_itemFlags[2];
@ -593,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.
@ -602,6 +611,8 @@ struct BattleStruct
u8 quickClawBattlerId;
struct StolenItem itemStolen[PARTY_SIZE]; // Player's team that had items stolen (two bytes per party member)
u8 blunderPolicy:1; // should blunder policy activate
u8 ballSpriteIds[2]; // item gfx, window gfx
u8 stickyWebUser;
};
#define GET_MOVE_TYPE(move, typeArg) \
@ -628,6 +639,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
@ -676,6 +697,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
@ -855,6 +877,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;
@ -905,5 +928,6 @@ extern u8 gNumberOfMovesToChoose;
extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
extern bool8 gHasFetchedBall;
extern u8 gLastUsedBall;
extern u16 gLastThrownBall;
#endif // GUARD_BATTLE_H

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
{
@ -93,5 +97,10 @@ u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale);
u8 GetHPBarLevel(s16 hp, s16 maxhp);
void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle);
void DestroyAbilityPopUp(u8 battlerId);
bool32 CanThrowLastUsedBall(void);
void TryHideLastUsedBall(void);
void TryRestoreLastUsedBall(void);
void TryAddLastUsedBallItemSprites(void);
void UpdateAbilityPopup(u8 battlerId);
#endif // GUARD_BATTLE_INTERFACE_H

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[];
@ -386,5 +388,23 @@ extern const u8 BattleScript_TerrainPreventsEnd2[];
extern const u8 BattleScript_MistyTerrainPrevents[];
extern const u8 BattleScript_ElectricTerrainPrevents[];
extern const u8 BattleScript_DarkTypePreventsPrankster[];
extern const u8 BattleScript_GulpMissileGorging[];
extern const u8 BattleScript_GulpMissileGulping[];
extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[];
extern const u8 BattleScript_DesolateLandActivates[];
extern const u8 BattleScript_DesolateLandEvaporatesWaterTypeMoves[];
extern const u8 BattleScript_PrimordialSeaActivates[];
extern const u8 BattleScript_PrimordialSeaFizzlesOutFireTypeMoves[];
extern const u8 BattleScript_DeltaStreamActivates[];
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_SelectingNotAllowedMoveGorillaTactics[];
extern const u8 BattleScript_WanderingSpiritActivates[];
extern const u8 BattleScript_MirrorArmorReflect[];
extern const u8 BattleScript_GooeyActivates[];
#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)))
@ -47,6 +48,7 @@ struct TypePower
extern const struct TypePower gNaturalGiftTable[];
void HandleAction_ThrowBall(void);
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move);
void HandleAction_UseMove(void);
void HandleAction_Switch(void);
@ -107,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);
@ -152,7 +154,9 @@ 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);
u16 GetUsedHeldItem(u8 battler);
bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags);
// ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability);

View File

@ -169,12 +169,14 @@
#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_SKIP_DMG_TRACK (1 << 5)
#define HITMARKER_DESTINYBOND (1 << 6)
#define HITMARKER_NO_ANIMATIONS (1 << 7)
#define HITMARKER_IGNORE_SUBSTITUTE (1 << 8)
@ -188,7 +190,7 @@
#define HITMARKER_IGNORE_DISGUISE (1 << 16)
// 3 free spots because of change in handling of UNDERGROUND/UNDERWATER/ON AIR
#define HITMARKER_UNABLE_TO_USE_MOVE (1 << 19)
#define HITMARKER_x100000 (1 << 20)
#define HITMARKER_PASSIVE_DAMAGE (1 << 20)
#define HITMARKER_x200000 (1 << 21)
#define HITMARKER_x400000 (1 << 22)
#define HITMARKER_x800000 (1 << 23)
@ -257,24 +259,31 @@
#define WEATHER_RAIN_TEMPORARY (1 << 0)
#define WEATHER_RAIN_DOWNPOUR (1 << 1) // unused
#define WEATHER_RAIN_PERMANENT (1 << 2)
#define WEATHER_RAIN_ANY (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_DOWNPOUR | WEATHER_RAIN_PERMANENT)
#define WEATHER_SANDSTORM_TEMPORARY (1 << 3)
#define WEATHER_SANDSTORM_PERMANENT (1 << 4)
#define WEATHER_RAIN_PRIMAL (1 << 3)
#define WEATHER_RAIN_ANY (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_DOWNPOUR | WEATHER_RAIN_PERMANENT | WEATHER_RAIN_PRIMAL)
#define WEATHER_SANDSTORM_TEMPORARY (1 << 4)
#define WEATHER_SANDSTORM_PERMANENT (1 << 5)
#define WEATHER_SANDSTORM_ANY (WEATHER_SANDSTORM_TEMPORARY | WEATHER_SANDSTORM_PERMANENT)
#define WEATHER_SUN_TEMPORARY (1 << 5)
#define WEATHER_SUN_PERMANENT (1 << 6)
#define WEATHER_SUN_ANY (WEATHER_SUN_TEMPORARY | WEATHER_SUN_PERMANENT)
#define WEATHER_HAIL_TEMPORARY (1 << 7)
#define WEATHER_HAIL_PERMANENT (1 << 8)
#define WEATHER_SUN_TEMPORARY (1 << 6)
#define WEATHER_SUN_PERMANENT (1 << 7)
#define WEATHER_SUN_PRIMAL (1 << 8)
#define WEATHER_SUN_ANY (WEATHER_SUN_TEMPORARY | WEATHER_SUN_PERMANENT | WEATHER_SUN_PRIMAL)
#define WEATHER_HAIL_TEMPORARY (1 << 9)
#define WEATHER_HAIL_PERMANENT (1 << 10)
#define WEATHER_HAIL_ANY (WEATHER_HAIL_TEMPORARY | WEATHER_HAIL_PERMANENT)
#define WEATHER_ANY (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY)
#define WEATHER_STRONG_WINDS (1 << 11)
#define WEATHER_ANY (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY | WEATHER_STRONG_WINDS)
#define WEATHER_PRIMAL_ANY (WEATHER_RAIN_PRIMAL | WEATHER_SUN_PRIMAL | WEATHER_STRONG_WINDS)
// Battle Weather as enum
#define ENUM_WEATHER_NONE 0
#define ENUM_WEATHER_RAIN 1
#define ENUM_WEATHER_SUN 2
#define ENUM_WEATHER_SANDSTORM 3
#define ENUM_WEATHER_HAIL 4
#define ENUM_WEATHER_NONE 0
#define ENUM_WEATHER_RAIN 1
#define ENUM_WEATHER_SUN 2
#define ENUM_WEATHER_SANDSTORM 3
#define ENUM_WEATHER_HAIL 4
#define ENUM_WEATHER_SUN_PRIMAL 5
#define ENUM_WEATHER_RAIN_PRIMAL 6
#define ENUM_WEATHER_STRONG_WINDS 7
// Move Effects
#define MOVE_EFFECT_SLEEP 0x1
@ -347,7 +356,8 @@
#define MOVE_EFFECT_THROAT_CHOP 0x43
#define MOVE_EFFECT_INCINERATE 0x44
#define MOVE_EFFECT_BUG_BITE 0x45
#define NUM_MOVE_EFFECTS 0x46
#define MOVE_EFFECT_RECOIL_HP_25 0x46
#define NUM_MOVE_EFFECTS 0x47
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000
@ -378,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,10 @@
#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)
#define ANIM_TAG_STEEL_BEAM (ANIM_SPRITES_START + 385)
// battlers
#define ANIM_ATTACKER 0
@ -458,7 +462,7 @@
#define BG_WATER_2 41
#define BG_POISON 42
#define BG_AEROBLAST 43
#define BG_HIGH_SPEED 44 //hurricane, close combat
#define BG_HURRICANE 44
#define BG_ELECTRIC_TERRAIN 45
#define BG_GRASSY_TERRAIN 46
#define BG_MISTY_TERRAIN 47
@ -492,6 +496,8 @@
#define BG_HYPER_BEAM 75
#define BG_DYNAMAX_CANNON 76
#define BG_AURA_SPHERE 77
#define BG_STEEL_BEAM_OPPONENT 78
#define BG_STEEL_BEAM_PLAYER 79
// table ids for general animations (gBattleAnims_General)
#define B_ANIM_CASTFORM_CHANGE 0
@ -523,6 +529,9 @@
#define B_ANIM_SLIDE_OFFSCREEN 26 // for Emergency Exit
#define B_ANIM_RESTORE_BG 27 // for Terrain Endings
#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

@ -40,6 +40,13 @@
#define SPECIES_BURMY 0
#define SPECIES_BURMY_SANDY_CLOAK 10013
#define SPECIES_BURMY_TRASH_CLOAK 10014
#define SPECIES_CRAMORANT 0
#define SPECIES_CRAMORANT_GORGING 10015
#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.
@ -83,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.
@ -103,38 +133,39 @@
#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_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally.
#define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use.
// 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.
@ -152,21 +183,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.
@ -185,8 +216,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

@ -236,7 +236,7 @@
#define EFFECT_ROUND 230
#define EFFECT_BRINE 231
#define EFFECT_VENOSHOCK 232
#define EFFECT_RETALITATE 233
#define EFFECT_RETALIATE 233
#define EFFECT_BULLDOZE 234
#define EFFECT_FOUL_PLAY 235
#define EFFECT_PSYSHOCK 236
@ -363,7 +363,19 @@
#define EFFECT_DECORATE 357
#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 360
#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
@ -184,6 +185,19 @@
#define VARIOUS_TRY_HEAL_QUARTER_HP 112
#define VARIOUS_REMOVE_TERRAIN 113
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115
#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
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

File diff suppressed because it is too large Load Diff

View File

@ -238,5 +238,9 @@
#define COMBO_STARTER_THOUSAND_WAVES 82
#define COMBO_STARTER_HYPERSPACE_FURY 83
#define COMBO_STARTER_SHADOW_BONE 84
#define COMBO_STARTER_ELECTRIC_TERRAIN 85
#define COMBO_STARTER_MISTY_TERRAIN 86
#define COMBO_STARTER_GRASSY_TERRAIN 87
#define COMBO_STARTER_PSYCHIC_TERRAIN 88
#endif // GUARD_CONSTANTS_CONTEST_H

View File

@ -130,7 +130,7 @@
// Gen6 hold effects
#define HOLD_EFFECT_FAIRY_POWER 139
#define HOLD_EFFECT_MEGA_STONE 140
#define HOLD_EFFECT_SAFETY_GOOGLES 141
#define HOLD_EFFECT_SAFETY_GOGGLES 141
#define HOLD_EFFECT_LUMINOUS_MOSS 142
#define HOLD_EFFECT_SNOWBALL 143
#define HOLD_EFFECT_WEAKNESS_POLICY 144

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

@ -4697,6 +4697,7 @@ extern const u32 gBattleAnimSpritePal_MagnifyingGlass[];
extern const u32 gBattleAnimSpritePal_BrownOrb[];
extern const u32 gBattleAnimSpritePal_MetalSoundWaves[];
extern const u32 gBattleAnimSpritePal_FlyingDirt[];
extern const u32 gBattleAnimSpritePal_Windstorm[];
extern const u32 gBattleAnimSpritePal_IcicleSpear[];
extern const u32 gBattleAnimSpritePal_Hail[];
extern const u32 gBattleAnimSpritePal_GlowyRedOrb[];
@ -4748,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[];
@ -4764,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[];
@ -4866,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[];
@ -4926,12 +4933,13 @@ extern const u32 gBattleAnimBgImage_InAir[];
extern const u32 gBattleAnimBgImage_Aurora[];
extern const u32 gBattleAnimBgImage_Fissure[];
extern const u32 gBattleAnimBgImage_TrickRoom[];
extern const u32 gBattleAnimBgImage_RockWrecker[];
extern const u32 gBattleAnimBgImage_SpacialRendOpponent[];
extern const u32 gBattleAnimBgPalette_SpacialRendOpponent[];
extern const u32 gBattleAnimBgImage_Hurricane[];
extern const u32 gBattleAnimBgPalette_Hurricane[];
extern const u32 gBattleAnimBgTilemap_Hurricane[];
extern const u32 gBattleAnimBgPalette_RockWrecker[];
extern const u32 gBattleAnimBgImage_SpacialRend[];
extern const u32 gBattleAnimBgPalette_SpacialRend[];
extern const u32 gBattleAnimBgTilemap_SpacialRendOpponent[];
extern const u32 gBattleAnimBgImage_SpacialRendPlayer[];
extern const u32 gBattleAnimBgPalette_SpacialRendPlayer[];
extern const u32 gBattleAnimBgTilemap_SpacialRendPlayer[];
extern const u32 gBattleAnimBgImage_DarkVoid[];
extern const u32 gBattleAnimBgPalette_DarkVoid[];
@ -4955,7 +4963,6 @@ extern const u32 gBattleAnimBgPalette_Solarbeam[];
extern const u32 gBattleAnimBgPalette_MagmaStorm[];
extern const u32 gBattleAnimBgPalette_GigaImpact[];
extern const u32 gBattleAnimBgPalette_TrickRoom[];
extern const u32 gBattleAnimBgPalette_RockWrecker[];
extern const u32 gBattleAnimBgTilemap_Dark[];
extern const u32 gBattleAnimBgTilemap_Ghost[];
extern const u32 gBattleAnimBgTilemap_Psychic[];
@ -4967,7 +4974,6 @@ extern const u32 gBattleAnimBgTilemap_DrillContests[];
extern const u32 gBattleAnimBgTilemap_HighspeedOpponent[];
extern const u32 gBattleAnimBgTilemap_HighspeedPlayer[];
extern const u32 gBattleAnimBgTilemap_TrickRoom[];
extern const u32 gBattleAnimBgTilemap_RockWrecker[];
extern const u32 gBattleAnimMaskImage_LightBeam[];
extern const u32 gBattleAnimMaskPalette_LightBeam[];
extern const u32 gBattleAnimMaskTilemap_LightBeam[];
@ -5013,9 +5019,6 @@ extern const u32 gBattleAnimBgImage_GrassyTerrain[];
extern const u32 gBattleAnimBgPalette_GrassyTerrain[];
extern const u32 gBattleAnimBgTilemap_GrassyTerrain[];
extern const u32 gBattleAnimBgPalette_GunkShot[];
extern const u32 gBattleAnimBgImage_HighSpeed[];
extern const u32 gBattleAnimBgPalette_HighSpeed[];
extern const u32 gBattleAnimBgTilemap_HighSpeed[];
extern const u32 gBattleAnimBgImage_HydroCannon[];
extern const u32 gBattleAnimBgPalette_HydroCannon[];
extern const u32 gBattleAnimBgTilemap_HydroCannon[];
@ -5082,7 +5085,8 @@ extern const u32 gBattleAnimBgTilemap_ZMoveActivate[];
extern const u32 gBattleAnimBgImage_ZMoveMountain[];
extern const u32 gBattleAnimBgPalette_ZMoveMountain[];
extern const u32 gBattleAnimBgTilemap_ZMoveMountain[];
extern const u32 gBattleAnimSpritePal_SteelBeam[];
extern const u32 gBattleAnimBgPalette_SteelBeam[];
extern const u32 gMetalShineGfx[];
extern const u32 gMetalShinePalette[];
@ -5199,6 +5203,9 @@ extern const u16 gSlotMachineReelTimePikachu_Pal[];
extern const u32 gBattleAnimBgTilemap_Sandstorm[];
extern const u32 gBattleAnimBgImage_Sandstorm[];
extern const u32 gBattleAnimBgTilemap_Windstorm[];
extern const u32 gBattleAnimBgImage_Windstorm[];
// Pokedex Area Screen
extern const u32 gPokedexAreaScreenAreaUnknown_Gfx[];
extern const u16 gPokedexAreaScreenAreaUnknown_Pal[];

View File

@ -33,5 +33,6 @@ void ItemUseInBattle_EnigmaBerry(u8);
void Task_UseDigEscapeRopeOnField(u8 taskId);
u8 CanUseDigOrEscapeRopeOnCurMap(void);
u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId);
u32 CanThrowBall(void);
#endif // GUARD_ITEM_USE_H

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];
}
}
}
@ -512,16 +520,21 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// move data
u8 atkPriority = GetMovePriority(battlerAtk, move);
u16 moveEffect = gBattleMoves[move].effect;
u8 moveType = gBattleMoves[move].type;
u8 moveTarget = gBattleMoves[move].target;
s32 moveType;
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);
u32 i;
u16 predictedMove = gLastMoves[battlerDef]; // TODO better move prediction
SetTypeBeforeUsingMove(move, battlerAtk);
GET_MOVE_TYPE(move, moveType);
if (IsTargetingPartner(battlerAtk, battlerDef))
return score;
GET_MOVE_TYPE(move, moveType);
// check non-user target
if (!(gBattleMoves[move].target & MOVE_TARGET_USER))
@ -748,7 +761,34 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move))
return 0; // Can't even select heal blocked move
// primal weather check
//TODO
if (WEATHER_HAS_EFFECT)
{
if (gBattleWeather & WEATHER_PRIMAL_ANY)
{
switch (move)
{
case MOVE_SUNNY_DAY:
case MOVE_RAIN_DANCE:
case MOVE_HAIL:
case MOVE_SANDSTORM:
RETURN_SCORE_MINUS(30);
}
}
if (!IS_MOVE_STATUS(move))
{
if (gBattleWeather & WEATHER_SUN_PRIMAL)
{
if (moveType == TYPE_WATER)
RETURN_SCORE_MINUS(30);
}
else if (gBattleWeather & WEATHER_RAIN_PRIMAL)
{
if (moveType == TYPE_FIRE)
RETURN_SCORE_MINUS(30);
}
}
}
// check move effects
switch (moveEffect)
@ -792,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:
@ -1494,7 +1530,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 10;
break;
case EFFECT_RECYCLE:
if (gBattleStruct->usedHeldItems[battlerAtk] == 0 || gBattleMons[battlerAtk].item != 0)
if (GetUsedHeldItem(battlerAtk) == 0 || gBattleMons[battlerAtk].item != 0)
score -= 10;
break;
case EFFECT_IMPRISON:
@ -1915,7 +1951,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 10;
break;
case EFFECT_BELCH:
if (ItemId_GetPocket(gBattleStruct->usedHeldItems[battlerAtk]) != POCKET_BERRIES)
if (ItemId_GetPocket(GetUsedHeldItem(battlerAtk)) != POCKET_BERRIES)
score -= 10; // attacker has not consumed a berry
break;
case EFFECT_YAWN:
@ -2434,13 +2470,32 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
switch (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef))
{
case AI_EFFECTIVENESS_x4:
score += 4;
if (WEATHER_HAS_EFFECT
&& gBattleWeather & WEATHER_STRONG_WINDS
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
{
if (AI_RandLessThan(176)) //Consider it supereffective instead of hypereffective.
score += 2;
else
score++;
}
else
score += 4;
break;
case AI_EFFECTIVENESS_x2:
if (AI_RandLessThan(176))
score += 2;
if (WEATHER_HAS_EFFECT
&& gBattleWeather & WEATHER_STRONG_WINDS
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
{
break; // Don't increase score, consider it neutral.
}
else
score++;
{
if (AI_RandLessThan(176))
score += 2;
else
score++;
}
break;
}
}
@ -2463,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;
@ -2472,7 +2527,10 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
bool32 attackerHasBadAbility = (GetAbilityRating(AI_DATA->atkAbility) < 0);
bool32 partnerHasBadAbility = (GetAbilityRating(atkPartnerAbility) < 0);
u16 predictedMove = gLastMoves[battlerDef]; //for now
SetTypeBeforeUsingMove(move, battlerAtk);
GET_MOVE_TYPE(move, moveType);
// check what effect partner is using
if (AI_DATA->partnerMove != 0)
{
@ -3277,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
@ -3309,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:
@ -4035,9 +4097,9 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 3;
break;
case EFFECT_RECYCLE:
if (gBattleStruct->usedHeldItems[battlerAtk] != ITEM_NONE)
if (GetUsedHeldItem(battlerAtk) != ITEM_NONE)
score++;
if (IsRecycleEncouragedItem(gBattleStruct->usedHeldItems[battlerAtk]))
if (IsRecycleEncouragedItem(GetUsedHeldItem(battlerAtk)))
score++;
break;
case EFFECT_BRICK_BREAK:
@ -4751,7 +4813,10 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
{
u16 effect = gBattleMoves[move].effect;
u8 moveType = gBattleMoves[move].type;
SetTypeBeforeUsingMove(move, battlerAtk);
GET_MOVE_TYPE(move, moveType);
if (IsTargetingPartner(battlerAtk, battlerDef))
{
if ((effect == EFFECT_HEAL_PULSE || effect == EFFECT_HIT_ENEMY_HEAL_ALLY)

View File

@ -643,7 +643,7 @@ bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect)
{
if ((B_POWDER_GRASS >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS))
|| ability == ABILITY_OVERCOAT
|| holdEffect == HOLD_EFFECT_SAFETY_GOOGLES)
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES)
return FALSE;
return TRUE;
}
@ -1448,7 +1448,7 @@ bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect)
|| ability == ABILITY_SAND_FORCE
|| ability == ABILITY_OVERCOAT
|| ability == ABILITY_MAGIC_GUARD
|| holdEffect == HOLD_EFFECT_SAFETY_GOOGLES
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES
|| IS_BATTLER_OF_TYPE(battler, TYPE_ROCK)
|| IS_BATTLER_OF_TYPE(battler, TYPE_STEEL)
|| IS_BATTLER_OF_TYPE(battler, TYPE_GROUND)
@ -1473,7 +1473,7 @@ bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect)
|| ability == ABILITY_SLUSH_RUSH
|| ability == ABILITY_MAGIC_GUARD
|| ability == ABILITY_OVERCOAT
|| holdEffect == HOLD_EFFECT_SAFETY_GOOGLES
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES
|| IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|| HasMove(battler, MOVE_BLIZZARD)
|| HasMoveEffect(battler, EFFECT_AURORA_VEIL)
@ -2273,7 +2273,7 @@ static u32 GetWeatherDamage(u8 battlerId)
{
if (BattlerAffectedBySandstorm(battlerId, ability)
&& !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& holdEffect != HOLD_EFFECT_SAFETY_GOOGLES)
&& holdEffect != HOLD_EFFECT_SAFETY_GOGGLES)
{
damage = gBattleMons[battlerId].maxHP / 16;
if (damage == 0)
@ -2284,7 +2284,7 @@ static u32 GetWeatherDamage(u8 battlerId)
{
if (BattlerAffectedByHail(battlerId, ability)
&& !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& holdEffect != HOLD_EFFECT_SAFETY_GOOGLES)
&& holdEffect != HOLD_EFFECT_SAFETY_GOGGLES)
{
damage = gBattleMons[battlerId].maxHP / 16;
if (damage == 0)

View File

@ -1564,6 +1564,10 @@ 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},
{gBattleAnimSpriteGfx_Orbs, 0x0180, ANIM_TAG_STEEL_BEAM},
};
const struct CompressedSpritePalette gBattleAnimPaletteTable[] =
@ -2011,6 +2015,10 @@ 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},
{gBattleAnimSpritePal_SteelBeam, ANIM_TAG_STEEL_BEAM},
};
const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
@ -2048,9 +2056,9 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
[BG_GIGA_IMPACT_PLAYER] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactPlayer},
[BG_GIGA_IMPACT_CONTEST] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactContests},
[BG_TRICK_ROOM] = {gBattleAnimBgImage_TrickRoom, gBattleAnimBgPalette_TrickRoom, gBattleAnimBgTilemap_TrickRoom},
[BG_ROCK_WRECKER] = {gBattleAnimBgImage_RockWrecker, gBattleAnimBgPalette_RockWrecker, gBattleAnimBgTilemap_RockWrecker},
[BG_SPACIAL_REND_ON_OPPONENT] = {gBattleAnimBgImage_SpacialRendOpponent, gBattleAnimBgPalette_SpacialRendOpponent, gBattleAnimBgTilemap_SpacialRendOpponent},
[BG_SPACIAL_REND_ON_PLAYER] = {gBattleAnimBgImage_SpacialRendPlayer, gBattleAnimBgPalette_SpacialRendPlayer, gBattleAnimBgTilemap_SpacialRendPlayer},
[BG_ROCK_WRECKER] = {gBattleAnimBgImage_Hurricane, gBattleAnimBgPalette_RockWrecker, gBattleAnimBgTilemap_Hurricane},
[BG_SPACIAL_REND_ON_OPPONENT] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_SpacialRendOpponent},
[BG_SPACIAL_REND_ON_PLAYER] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_SpacialRendPlayer},
[BG_DARK_VOID] = {gBattleAnimBgImage_DarkVoid, gBattleAnimBgPalette_DarkVoid, gBattleAnimBgTilemap_DarkVoid},
[BG_WATER] = {gBattleAnimBgImage_HydroPump, gBattleAnimBgPalette_HydroPump, gBattleAnimBgTilemap_HydroPump},
[BG_NIGHTMARE] = {gBattleAnimBgImage_Nightmare, gBattleAnimBgPalette_Nightmare, gBattleAnimBgTilemap_Nightmare},
@ -2060,7 +2068,7 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
[BG_WATER_2] = {gBattleAnimBgImage_Waterfall, gBattleAnimBgPalette_Waterfall, gBattleAnimBgTilemap_Waterfall},
[BG_POISON] = {gBattleAnimBgImage_Waterfall, gBattleAnimBgPalette_PoisonFalls, gBattleAnimBgTilemap_Waterfall},
[BG_AEROBLAST] = {gBattleAnimBgImage_Aeroblast, gBattleAnimBgPalette_Aeroblast, gBattleAnimBgTilemap_Aeroblast},
[BG_HIGH_SPEED] = {gBattleAnimBgImage_HighSpeed, gBattleAnimBgPalette_HighSpeed, gBattleAnimBgTilemap_HighSpeed},
[BG_HURRICANE] = {gBattleAnimBgImage_Hurricane, gBattleAnimBgPalette_Hurricane, gBattleAnimBgTilemap_Hurricane},
[BG_ELECTRIC_TERRAIN] = {gBattleAnimBgImage_ElectricTerrain, gBattleAnimBgPalette_ElectricTerrain, gBattleAnimBgTilemap_ElectricTerrain},
[BG_GRASSY_TERRAIN] = {gBattleAnimBgImage_GrassyTerrain, gBattleAnimBgPalette_GrassyTerrain, gBattleAnimBgTilemap_GrassyTerrain},
[BG_MISTY_TERRAIN] = {gBattleAnimBgImage_MistyTerrain, gBattleAnimBgPalette_MistyTerrain, gBattleAnimBgTilemap_MistyTerrain},
@ -2094,6 +2102,8 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
[BG_HYPER_BEAM] = {gBattleAnimBgImage_HydroCannon, gBattleAnimBgPalette_HyperBeam, gBattleAnimBgTilemap_HydroCannon},
[BG_DYNAMAX_CANNON] = {gBattleAnimBgImage_HydroCannon, gBattleAnimBgPalette_DynamaxCannon, gBattleAnimBgTilemap_HydroCannon},
[BG_AURA_SPHERE] = {gBattleAnimBgImage_FocusBlast, gBattleAnimBgPalette_AuraSphere, gBattleAnimBgTilemap_FocusBlast},
[BG_STEEL_BEAM_OPPONENT] = {gBattleAnimBgImage_Highspeed, gBattleAnimBgPalette_SteelBeam, gBattleAnimBgTilemap_HighspeedOpponent},
[BG_STEEL_BEAM_PLAYER] = {gBattleAnimBgImage_Highspeed, gBattleAnimBgPalette_SteelBeam, gBattleAnimBgTilemap_HighspeedPlayer},
};
static void (* const sScriptCmdTable[])(void) =
@ -2213,6 +2223,7 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo
case B_ANIM_DOOM_DESIRE_HIT:
case B_ANIM_WISH_HEAL:
case B_ANIM_MEGA_EVOLUTION:
case B_ANIM_GULP_MISSILE:
hideHpBoxes = TRUE;
break;
default:

View File

@ -6803,3 +6803,42 @@ void AnimTask_CompressTargetHorizontally(u8 taskId)
PrepareAffineAnimInTaskData(task, spriteId, sCompressTargetHorizontallyAffineAnimCmds);
task->func = AnimTask_CompressTargetStep;
}
const struct SpriteTemplate gSteelBeamBigOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_STEEL_BEAM,
.paletteTag = ANIM_TAG_STEEL_BEAM,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gSolarbeamBigOrbAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSolarbeamBigOrb,
};
const struct SpriteTemplate gSteelBeamSmallOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_STEEL_BEAM,
.paletteTag = ANIM_TAG_STEEL_BEAM,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gSolarbeamSmallOrbAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSolarbeamSmallOrb,
};
void AnimTask_CreateSmallSteelBeamOrbs(u8 taskId)
{
if (--gTasks[taskId].data[0] == -1)
{
gTasks[taskId].data[1]++;
gTasks[taskId].data[0] = 6;
gBattleAnimArgs[0] = 15;
gBattleAnimArgs[1] = 0;
gBattleAnimArgs[2] = 80;
gBattleAnimArgs[3] = 0;
CreateSpriteAndAnimate(&gSteelBeamSmallOrbSpriteTemplate, 0, 0, GetBattlerSpriteSubpriority(gBattleAnimTarget) + 1);
}
if (gTasks[taskId].data[1] == 15)
DestroyAnimVisualTask(taskId);
}

View File

@ -22,6 +22,7 @@
#include "constants/rgb.h"
#include "constants/songs.h"
#include "constants/weather.h"
#include "constants/hold_effects.h"
extern const struct SpriteTemplate gThoughtBubbleSpriteTemplate;
@ -1219,6 +1220,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];
@ -5471,10 +5527,12 @@ static void AnimRecycle_Step(struct Sprite *sprite)
void AnimTask_GetWeather(u8 taskId)
{
bool32 utilityUmbrellaAffected = GetBattlerHoldEffect(gBattleAnimAttacker, TRUE) == HOLD_EFFECT_UTILITY_UMBRELLA;
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_NONE;
if (gWeatherMoveAnim & WEATHER_SUN_ANY)
if (gWeatherMoveAnim & WEATHER_SUN_ANY && !utilityUmbrellaAffected)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SUN;
else if (gWeatherMoveAnim & WEATHER_RAIN_ANY)
else if (gWeatherMoveAnim & WEATHER_RAIN_ANY && !utilityUmbrellaAffected)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_RAIN;
else if (gWeatherMoveAnim & WEATHER_SANDSTORM_ANY)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SANDSTORM;

View File

@ -5,6 +5,8 @@
#include "constants/battle_anim.h"
#include "constants/rgb.h"
#include "random.h"
#include "gpu_regs.h"
#include "graphics.h"
extern const struct SpriteTemplate gFlashingHitSplatSpriteTemplate;
@ -30,7 +32,7 @@ static void AnimUnusedFlashingLight_Step(struct Sprite *);
static void AnimSkyAttackBird(struct Sprite *);
static void AnimSkyAttackBird_Step(struct Sprite *);
static void AnimTask_AnimateGustTornadoPalette_Step(u8);
static void AnimTask_LoadWindstormBackground_Step(u8 taskId);
const struct SpriteTemplate gEllipticalGustSpriteTemplate =
{
@ -1231,3 +1233,99 @@ static void AnimTask_SetAttackerVisibility(u8 taskId)
}
DestroyAnimVisualTask(taskId);
}
void AnimTask_LoadWindstormBackground(u8 taskId)
{
int var0;
struct BattleAnimBgData animBg;
var0 = 0;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
GetBattleAnimBg1Data(&animBg);
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimBgImage_Windstorm, animBg.tilesOffset);
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimBgTilemap_Windstorm, 0);
LoadCompressedPalette(gBattleAnimSpritePal_Windstorm, animBg.paletteId * 16, 32);
if (gBattleAnimArgs[0] && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
var0 = 1;
gTasks[taskId].data[0] = var0;
gTasks[taskId].func = AnimTask_LoadWindstormBackground_Step;
}
static void AnimTask_LoadWindstormBackground_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
if (gTasks[taskId].data[0] == 0)
gBattle_BG1_X += -6;
else
gBattle_BG1_X += 6;
gBattle_BG1_Y += -1;
switch (gTasks[taskId].data[12])
{
case 0:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 7)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 1:
if (++gTasks[taskId].data[11] == 101)
{
gTasks[taskId].data[11] = 7;
gTasks[taskId].data[12]++;
}
break;
case 2:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 0)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 3:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(animBg.bgId);
gTasks[taskId].data[12]++;
break;
case 4:
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
break;
}
}

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

@ -249,7 +249,8 @@ static void HandleInputChooseAction(void)
if (JOY_NEW(A_BUTTON))
{
PlaySE(SE_SELECT);
TryHideLastUsedBall();
switch (gActionSelectionCursor[gActiveBattler])
{
case 0:
@ -336,6 +337,15 @@ static void HandleInputChooseAction(void)
BtlController_EmitTwoReturnValues(1, B_ACTION_DEBUG, 0);
PlayerBufferExecCompleted();
}
#if B_LAST_USED_BALL == TRUE
else if (JOY_NEW(B_LAST_USED_BALL_BUTTON) && CanThrowLastUsedBall())
{
PlaySE(SE_SELECT);
TryHideLastUsedBall();
BtlController_EmitTwoReturnValues(1, B_ACTION_THROW_BALL, 0);
PlayerBufferExecCompleted();
}
#endif
}
static void UnusedEndBounceEffect(void)
@ -372,6 +382,7 @@ static void HandleInputChooseTarget(void)
else
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX);
TryHideLastUsedBall();
HideMegaTriggerSprite();
PlayerBufferExecCompleted();
}
@ -485,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;
@ -498,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)
@ -514,6 +566,7 @@ static void HandleInputShowTargets(void)
else
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
HideMegaTriggerSprite();
TryHideLastUsedBall();
PlayerBufferExecCompleted();
}
else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59)
@ -537,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]);
@ -589,27 +642,40 @@ 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
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
HideMegaTriggerSprite();
TryHideLastUsedBall();
PlayerBufferExecCompleted();
}
else if (canSelectTarget == 1)
{
break;
case 1:
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget;
if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
@ -620,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)
@ -2696,6 +2765,7 @@ static void PlayerHandleChooseAction(void)
for (i = 0; i < 4; i++)
ActionSelectionDestroyCursorAt(i);
TryRestoreLastUsedBall();
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo);
BattlePutTextOnWindow(gDisplayedStringBattle, 1);

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[] =
@ -541,7 +559,7 @@ static const struct BgTemplate sBgTemplates[] =
},
{
.bg = 1,
.charBaseIndex = 10,
.charBaseIndex = 2,
.mapBaseIndex = 20,
.screenSize = 0,
.paletteMode = 0,
@ -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);
@ -1951,7 +1985,7 @@ static const u8 sText_HoldEffectAbsorbBulb[] = _("Absorb Bulb");
static const u8 sText_HoldEffectCellBattery[] = _("Cell Battery");
static const u8 sText_HoldEffectFairyPower[] = _("Fairy Power");
static const u8 sText_HoldEffectMegaStone[] = _("Mega Stone");
static const u8 sText_HoldEffectSafetyGoogles[] = _("Safety Googles");
static const u8 sText_HoldEffectSafetyGoggles[] = _("Safety Goggles");
static const u8 sText_HoldEffectLuminousMoss[] = _("Luminous Moss");
static const u8 sText_HoldEffectSnowball[] = _("Snowball");
static const u8 sText_HoldEffectWeaknessPolicy[] = _("Weakness Policy");
@ -2091,7 +2125,7 @@ static const u8 *const sHoldEffectNames[] =
[HOLD_EFFECT_CELL_BATTERY] = sText_HoldEffectCellBattery,
[HOLD_EFFECT_FAIRY_POWER] = sText_HoldEffectFairyPower,
[HOLD_EFFECT_MEGA_STONE] = sText_HoldEffectMegaStone,
[HOLD_EFFECT_SAFETY_GOOGLES] = sText_HoldEffectSafetyGoogles,
[HOLD_EFFECT_SAFETY_GOGGLES] = sText_HoldEffectSafetyGoggles,
[HOLD_EFFECT_LUMINOUS_MOSS] = sText_HoldEffectLuminousMoss,
[HOLD_EFFECT_SNOWBALL] = sText_HoldEffectSnowball,
[HOLD_EFFECT_WEAKNESS_POLICY] = sText_HoldEffectWeaknessPolicy,

View File

@ -27,6 +27,10 @@
#include "constants/battle_config.h"
#include "data.h"
#include "pokemon_summary_screen.h"
#include "item_icon.h"
#include "item_use.h"
#include "item.h"
#include "constants/items.h"
enum
{ // Corresponds to gHealthboxElementsGfxTable (and the tables after it) in graphics.c
@ -196,6 +200,9 @@ static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32
static void SpriteCb_AbilityPopUp(struct Sprite *sprite);
static void Task_FreeAbilityPopUpGfx(u8 taskId);
static void SpriteCB_LastUsedBall(struct Sprite *sprite);
static void SpriteCB_LastUsedBallWin(struct Sprite *sprite);
// const rom data
static const struct OamData sUnknown_0832C138 =
{
@ -665,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,
@ -693,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
@ -723,6 +774,12 @@ u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId)
return gSprites[spriteId].hOther_IndicatorSpriteId;
}
static void InitLastUsedBallAssets(void)
{
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
}
u8 CreateBattlerHealthboxSprites(u8 battlerId)
{
s16 data6 = 0;
@ -805,13 +862,17 @@ 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;
}
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
return healthboxLeftSpriteId;
}
@ -910,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)
@ -978,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
@ -1033,10 +1095,12 @@ 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;
}
else
{
@ -1044,6 +1108,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
text[1] = CHAR_LV_2;
objVram = ConvertIntToDecimalStringN(text + 2, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
xPos = 5 * (3 - (objVram - (text + 2)));
}
xPos = 5 * (3 - (objVram - (text + 2)));
@ -1491,18 +1556,12 @@ void DestroyMegaTriggerSprite(void)
gBattleStruct->mega.triggerSpriteId = 0xFF;
}
static const s8 sIndicatorPosSingles[][2] =
static const s8 sIndicatorPositions[][2] =
{
[B_POSITION_PLAYER_LEFT] = {53, -8},
[B_POSITION_OPPONENT_LEFT] = {45, -8},
};
static const s8 sIndicatorPosDoubles[][2] =
{
[B_POSITION_PLAYER_LEFT] = {53, -8},
[B_POSITION_OPPONENT_LEFT] = {45, -8},
[B_POSITION_PLAYER_RIGHT] = {53, -8},
[B_POSITION_OPPONENT_RIGHT] = {45, -8},
[B_POSITION_PLAYER_LEFT] = {52, -9},
[B_POSITION_OPPONENT_LEFT] = {44, -9},
[B_POSITION_PLAYER_RIGHT] = {52, -9},
[B_POSITION_OPPONENT_RIGHT] = {44, -9},
};
u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which)
@ -1510,24 +1569,49 @@ 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);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
x += sIndicatorPosDoubles[position][0];
y += sIndicatorPosDoubles[position][1];
}
else
{
x += sIndicatorPosSingles[position][0];
y += sIndicatorPosSingles[position][1];
}
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_MegaIndicator, x, y, 0);
gSprites[gSprites[gHealthboxSpriteIds[battlerId]].oam.affineParam].hOther_IndicatorSpriteId = spriteId;
x += sIndicatorPositions[position][0];
y += sIndicatorPositions[position][1];
if (gBattleMons[battlerId].level >= 100)
x -= 4;
else if (gBattleMons[battlerId].level < 10)
x += 5;
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;
}
@ -3054,8 +3138,8 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle)
gSprites[spriteId2].tRightToLeft = FALSE;
}
gBattleStruct->abilityPopUpSpriteIds[gBattleAnimAttacker][0] = spriteId1;
gBattleStruct->abilityPopUpSpriteIds[gBattleAnimAttacker][1] = spriteId2;
gBattleStruct->abilityPopUpSpriteIds[battlerId][0] = spriteId1;
gBattleStruct->abilityPopUpSpriteIds[battlerId][1] = spriteId2;
taskId = CreateTask(Task_FreeAbilityPopUpGfx, 5);
gTasks[taskId].tSpriteId1 = spriteId1;
@ -3073,6 +3157,16 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle)
RestoreOverwrittenPixels((void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32));
}
void UpdateAbilityPopup(u8 battlerId)
{
u8 spriteId1 = gBattleStruct->abilityPopUpSpriteIds[battlerId][0];
u8 spriteId2 = gBattleStruct->abilityPopUpSpriteIds[battlerId][1];
u16 ability = (gBattleScripting.abilityPopupOverwrite != 0) ? gBattleScripting.abilityPopupOverwrite : gBattleMons[battlerId].ability;
PrintAbilityOnAbilityPopUp(ability, spriteId1, spriteId2);
RestoreOverwrittenPixels((void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32));
}
#define FRAMES_TO_WAIT 48
static void SpriteCb_AbilityPopUp(struct Sprite *sprite)
@ -3128,3 +3222,200 @@ static void Task_FreeAbilityPopUpGfx(u8 taskId)
DestroyTask(taskId);
}
}
// last used ball
#define LAST_BALL_WINDOW_TAG 0xD721
static const struct OamData sOamData_LastUsedBall =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = SPRITE_SHAPE(32x32),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x32),
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0,
};
static const struct SpriteTemplate sSpriteTemplate_LastUsedBallWindow =
{
.tileTag = LAST_BALL_WINDOW_TAG,
.paletteTag = ABILITY_POP_UP_TAG,
.oam = &sOamData_LastUsedBall,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_LastUsedBallWin
};
#if B_LAST_USED_BALL_BUTTON == R_BUTTON
static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_r.4bpp");
#else
static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_l.4bpp");
#endif
static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow =
{
sLastUsedBallWindowGfx, sizeof(sLastUsedBallWindowGfx), LAST_BALL_WINDOW_TAG
};
#define LAST_USED_BALL_X_F 15
#define LAST_USED_BALL_X_0 -15
#define LAST_USED_BALL_Y ((IsDoubleBattle()) ? 78 : 68)
#define LAST_BALL_WIN_X_F (LAST_USED_BALL_X_F - 1)
#define LAST_BALL_WIN_X_0 (LAST_USED_BALL_X_0 - 0)
#define LAST_USED_WIN_Y (LAST_USED_BALL_Y - 8)
#define sHide data[0]
bool32 CanThrowLastUsedBall(void)
{
#if B_LAST_USED_BALL == FALSE
return FALSE;
#else
return (!(CanThrowBall() != 0
|| (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|| !CheckBagHasItem(gLastThrownBall, 1)));
#endif
}
void TryAddLastUsedBallItemSprites(void)
{
#if B_LAST_USED_BALL == TRUE
if (gLastThrownBall == 0
|| (gLastThrownBall != 0 && !CheckBagHasItem(gLastThrownBall, 1)))
{
// we're out of the last used ball, so just set it to the first ball in the bag
// we have to compact the bag first bc it is typically only compacted when you open it
CompactItemsInBagPocket(&gBagPockets[BALLS_POCKET]);
gLastThrownBall = gBagPockets[BALLS_POCKET].itemSlots[0].itemId;
}
if (CanThrowBall() != 0
|| (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|| !CheckBagHasItem(gLastThrownBall, 1))
return;
// ball
if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES)
{
gBattleStruct->ballSpriteIds[0] = AddItemIconSprite(102, 102, gLastThrownBall);
gSprites[gBattleStruct->ballSpriteIds[0]].x = LAST_USED_BALL_X_0;
gSprites[gBattleStruct->ballSpriteIds[0]].y = LAST_USED_BALL_Y;
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore
gSprites[gBattleStruct->ballSpriteIds[0]].callback = SpriteCB_LastUsedBall;
}
// window
LoadSpritePalette(&sSpritePalette_AbilityPopUp);
if (GetSpriteTileStartByTag(LAST_BALL_WINDOW_TAG) == 0xFFFF)
LoadSpriteSheet(&sSpriteSheet_LastUsedBallWindow);
if (gBattleStruct->ballSpriteIds[1] == MAX_SPRITES)
{
gBattleStruct->ballSpriteIds[1] = CreateSprite(&sSpriteTemplate_LastUsedBallWindow,
LAST_BALL_WIN_X_0,
LAST_USED_WIN_Y, 5);
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore
}
#endif
}
static void DestroyLastUsedBallWinGfx(struct Sprite *sprite)
{
FreeSpriteTilesByTag(LAST_BALL_WINDOW_TAG);
FreeSpritePaletteByTag(ABILITY_POP_UP_TAG);
DestroySprite(sprite);
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
}
static void DestroyLastUsedBallGfx(struct Sprite *sprite)
{
FreeSpriteTilesByTag(102);
FreeSpritePaletteByTag(102);
DestroySprite(sprite);
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
}
static void SpriteCB_LastUsedBallWin(struct Sprite *sprite)
{
if (sprite->sHide)
{
if (sprite->x != LAST_BALL_WIN_X_0)
sprite->x--;
if (sprite->x == LAST_BALL_WIN_X_0)
DestroyLastUsedBallWinGfx(sprite);
}
else
{
if (sprite->x != LAST_BALL_WIN_X_F)
sprite->x++;
}
}
static void SpriteCB_LastUsedBall(struct Sprite *sprite)
{
if (sprite->sHide)
{
if (sprite->x != LAST_USED_BALL_X_0)
sprite->x--;
if (sprite->x == LAST_USED_BALL_X_0)
DestroyLastUsedBallGfx(sprite);
}
else
{
if (sprite->x != LAST_USED_BALL_X_F)
sprite->x++;
}
}
static void TryHideOrRestoreLastUsedBall(u8 caseId)
{
#if B_LAST_USED_BALL == TRUE
if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES)
return;
switch (caseId)
{
case 0: // hide
if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = TRUE; // hide
if (gBattleStruct->ballSpriteIds[1] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[1]].sHide = TRUE; // hide
break;
case 1: // restore
if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore
if (gBattleStruct->ballSpriteIds[1] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[1]].sHide = FALSE; // restore
break;
}
#endif
}
void TryHideLastUsedBall(void)
{
#if B_LAST_USED_BALL == TRUE
TryHideOrRestoreLastUsedBall(0);
#endif
}
void TryRestoreLastUsedBall(void)
{
#if B_LAST_USED_BALL == TRUE
if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES)
TryHideOrRestoreLastUsedBall(1);
else
TryAddLastUsedBallItemSprites();
#endif
}

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;
@ -230,6 +231,7 @@ EWRAM_DATA u16 gPartnerSpriteId = 0;
EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA bool8 gHasFetchedBall = FALSE;
EWRAM_DATA u8 gLastUsedBall = 0;
EWRAM_DATA u16 gLastThrownBall = 0;
// IWRAM common vars
void (*gPreBattleCallback1)(void);
@ -401,6 +403,7 @@ static void (* const sTurnActionsFuncsTable[])(void) =
[B_ACTION_TRY_FINISH] = HandleAction_TryFinish,
[B_ACTION_FINISHED] = HandleAction_ActionFinished,
[B_ACTION_NOTHING_FAINTED] = HandleAction_NothingIsFainted,
[B_ACTION_THROW_BALL] = HandleAction_ThrowBall,
};
static void (* const sEndTurnFuncsTable[])(void) =
@ -2847,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;
@ -2858,7 +2862,6 @@ static void BattleStartClearSetData(void)
gBattleResources->flags->flags[i] = 0;
gPalaceSelectionBattleScripts[i] = 0;
gBattleStruct->lastTakenMove[i] = 0;
gBattleStruct->usedHeldItems[i] = 0;
gBattleStruct->choicedMove[i] = 0;
gBattleStruct->changedItems[i] = 0;
gBattleStruct->lastTakenMoveFrom[i][0] = 0;
@ -2930,8 +2933,14 @@ static void BattleStartClearSetData(void)
gBattleStruct->mega.triggerSpriteId = 0xFF;
gBattleStruct->stickyWebUser = 0xFF;
for (i = 0; i < PARTY_SIZE; i++)
{
gBattleStruct->usedHeldItems[i][0] = 0;
gBattleStruct->usedHeldItems[i][1] = 0;
gBattleStruct->itemStolen[i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
}
}
void SwitchInClearSetData(void)
@ -2958,7 +2967,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++)
{
@ -2978,6 +2989,8 @@ void SwitchInClearSetData(void)
gBattleMons[gActiveBattler].status2 = 0;
gStatuses3[gActiveBattler] = 0;
}
gStatuses4[gActiveBattler] = 0;
for (i = 0; i < gBattlersCount; i++)
{
@ -3019,6 +3032,9 @@ void SwitchInClearSetData(void)
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
gBattleStruct->lastMoveFailed &= ~(gBitTable[gActiveBattler]);
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
if (gActiveBattler == gBattleStruct->stickyWebUser)
gBattleStruct->stickyWebUser = 0xFF; // Switched into sticky web user slot so reset it
for (i = 0; i < gBattlersCount; i++)
{
@ -3051,6 +3067,7 @@ void FaintClearSetData(void)
gBattleMons[gActiveBattler].status2 = 0;
gStatuses3[gActiveBattler] = 0;
gStatuses4[gActiveBattler] = 0;
for (i = 0; i < gBattlersCount; i++)
{
@ -3095,6 +3112,7 @@ void FaintClearSetData(void)
gProtectStructs[gActiveBattler].usedThroatChopPreventedMove = FALSE;
gProtectStructs[gActiveBattler].statRaised = FALSE;
gProtectStructs[gActiveBattler].statFell = FALSE;
gProtectStructs[gActiveBattler].pranksterElevated = FALSE;
gDisableStructs[gActiveBattler].isFirstTurn = 2;
@ -3114,6 +3132,9 @@ void FaintClearSetData(void)
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
if (gActiveBattler == gBattleStruct->stickyWebUser)
gBattleStruct->stickyWebUser = 0xFF; // User of sticky web fainted, so reset the stored battler ID
for (i = 0; i < gBattlersCount; i++)
{
@ -3465,10 +3486,13 @@ static void TryDoEventsBeforeFirstTurn(void)
return;
// Set invalid mons as absent(for example when starting a double battle with only one pokemon).
for (i = 0; i < gBattlersCount; i++)
if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI))
{
if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE)
gAbsentBattlerFlags |= gBitTable[i];
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE)
gAbsentBattlerFlags |= gBitTable[i];
}
}
if (gBattleStruct->switchInAbilitiesCounter == 0)
@ -3509,6 +3533,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)
{
@ -3610,7 +3646,7 @@ void BattleTurnPassed(void)
gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING);
gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE);
gHitMarker &= ~(HITMARKER_x400000);
gHitMarker &= ~(HITMARKER_x100000);
gHitMarker &= ~(HITMARKER_PASSIVE_DAMAGE);
gBattleScripting.animTurn = 0;
gBattleScripting.animTargetsHit = 0;
gBattleScripting.moveendState = 0;
@ -3680,9 +3716,13 @@ 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 (gBattleMons[gActiveBattler].ability == ABILITY_RUN_AWAY)
if (GetBattlerAbility(gActiveBattler) == ABILITY_RUN_AWAY)
return 0;
if ((i = IsAbilityPreventingEscape(gActiveBattler)))
@ -4070,6 +4110,10 @@ static void HandleTurnActionSelectionState(void)
case B_ACTION_SAFARI_BALL:
gBattleCommunication[gActiveBattler]++;
break;
case B_ACTION_THROW_BALL:
gBattleStruct->throwingPokeBall = TRUE;
gBattleCommunication[gActiveBattler]++;
break;
case B_ACTION_SAFARI_POKEBLOCK:
if ((gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8)) != 0)
{
@ -4183,6 +4227,13 @@ static void HandleTurnActionSelectionState(void)
if (gBattleCommunication[ACTIONS_CONFIRMED_COUNT] == gBattlersCount)
{
sub_818603C(1);
if (WILD_DOUBLE_BATTLE && gBattleStruct->throwingPokeBall) {
// if we choose to throw a ball with our second mon, skip the action of the first
// (if we have chosen throw ball with first, second's is already skipped)
gChosenActionByBattler[B_POSITION_PLAYER_LEFT] = B_ACTION_NOTHING_FAINTED;
}
gBattleMainFunc = SetActionsAndBattlersTurnOrder;
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
@ -4246,9 +4297,9 @@ u32 GetBattlerTotalSpeedStat(u8 battlerId)
// weather abilities
if (WEATHER_HAS_EFFECT)
{
if (ability == ABILITY_SWIFT_SWIM && gBattleWeather & WEATHER_RAIN_ANY)
if (ability == ABILITY_SWIFT_SWIM && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & WEATHER_RAIN_ANY)
speed *= 2;
else if (ability == ABILITY_CHLOROPHYLL && gBattleWeather & WEATHER_SUN_ANY)
else if (ability == ABILITY_CHLOROPHYLL && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & WEATHER_SUN_ANY)
speed *= 2;
else if (ability == ABILITY_SAND_RUSH && gBattleWeather & WEATHER_SANDSTORM_ANY)
speed *= 2;
@ -4363,20 +4414,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].usedCustapBerry = 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].usedCustapBerry = TRUE;
if (!ignoreChosenMoves)
@ -4392,8 +4455,12 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
// QUICK CLAW / CUSTAP - always first
// LAGGING TAIL - always last
// STALL - always last
if (gProtectStructs[battler1].usedCustapBerry && !gProtectStructs[battler2].usedCustapBerry)
if (gProtectStructs[battler1].quickDraw && !gProtectStructs[battler2].quickDraw)
strikesFirst = 0;
else if (!gProtectStructs[battler1].quickDraw && gProtectStructs[battler2].quickDraw)
strikesFirst = 1;
else if (gProtectStructs[battler1].usedCustapBerry && !gProtectStructs[battler2].usedCustapBerry)
strikesFirst = 0;
else if (gProtectStructs[battler2].usedCustapBerry && !gProtectStructs[battler1].usedCustapBerry)
strikesFirst = 1;
@ -4504,7 +4571,9 @@ static void SetActionsAndBattlersTurnOrder(void)
{
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM || gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH)
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM
|| gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH
|| gChosenActionByBattler[gActiveBattler] == B_ACTION_THROW_BALL)
{
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
@ -4513,7 +4582,9 @@ static void SetActionsAndBattlersTurnOrder(void)
}
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM && gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH)
if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM
&& gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH
&& gChosenActionByBattler[gActiveBattler] != B_ACTION_THROW_BALL)
{
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
@ -4529,7 +4600,9 @@ static void SetActionsAndBattlersTurnOrder(void)
if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM
&& gActionsByTurnOrder[j] != B_ACTION_USE_ITEM
&& gActionsByTurnOrder[i] != B_ACTION_SWITCH
&& gActionsByTurnOrder[j] != B_ACTION_SWITCH)
&& gActionsByTurnOrder[j] != B_ACTION_SWITCH
&& gActionsByTurnOrder[i] != B_ACTION_THROW_BALL
&& gActionsByTurnOrder[j] != B_ACTION_THROW_BALL)
{
if (GetWhoStrikesFirst(battler1, battler2, FALSE))
SwapTurnOrder(i, j);
@ -4648,22 +4721,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].usedCustapBerry
&& (gProtectStructs[gActiveBattler].usedCustapBerry || gProtectStructs[gActiveBattler].quickDraw)
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
&& !(gDisableStructs[gBattlerAttacker].truantCounter)
&& !(gProtectStructs[gActiveBattler].noValidMoves))
{
gProtectStructs[gActiveBattler].usedCustapBerry = FALSE;
gLastUsedItem = gBattleMons[gActiveBattler].item;
if (GetBattlerHoldEffect(gActiveBattler, FALSE) == HOLD_EFFECT_CUSTAP_BERRY)
if (gProtectStructs[gActiveBattler].usedCustapBerry)
{
// don't record berry since its gone now
BattleScriptExecute(BattleScript_CustapBerryActivation);
gProtectStructs[gActiveBattler].usedCustapBerry = 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;
}
@ -4698,7 +4783,7 @@ static void RunTurnActionsFunctions(void)
if (gCurrentTurnActionNumber >= gBattlersCount) // everyone did their actions, turn finished
{
gHitMarker &= ~(HITMARKER_x100000);
gHitMarker &= ~(HITMARKER_PASSIVE_DAMAGE);
gBattleMainFunc = sEndTurnFuncsTable[gBattleOutcome & 0x7F];
}
else
@ -4908,6 +4993,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;
}
@ -5035,6 +5131,7 @@ void RunBattleScriptCommands(void)
void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
{
u32 moveType, ateType, attackerAbility;
u16 holdEffect = GetBattlerHoldEffect(battlerAtk, TRUE);
if (move == MOVE_STRUGGLE)
return;
@ -5047,11 +5144,11 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
{
if (WEATHER_HAS_EFFECT)
{
if (gBattleWeather & WEATHER_RAIN_ANY)
if (gBattleWeather & WEATHER_RAIN_ANY && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA)
gBattleStruct->dynamicMoveType = TYPE_WATER | 0x80;
else if (gBattleWeather & WEATHER_SANDSTORM_ANY)
gBattleStruct->dynamicMoveType = TYPE_ROCK | 0x80;
else if (gBattleWeather & WEATHER_SUN_ANY)
else if (gBattleWeather & WEATHER_SUN_ANY && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA)
gBattleStruct->dynamicMoveType = TYPE_FIRE | 0x80;
else if (gBattleWeather & WEATHER_HAIL_ANY)
gBattleStruct->dynamicMoveType = TYPE_ICE | 0x80;
@ -5075,7 +5172,7 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
}
else if (gBattleMoves[move].effect == EFFECT_CHANGE_TYPE_ON_ITEM)
{
if (GetBattlerHoldEffect(battlerAtk, TRUE) == gBattleMoves[move].argument)
if (holdEffect == gBattleMoves[move].argument)
gBattleStruct->dynamicMoveType = ItemId_GetSecondaryId(gBattleMons[battlerAtk].item) | 0x80;
}
else if (gBattleMoves[move].effect == EFFECT_REVELATION_DANCE)
@ -5096,7 +5193,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;
}
@ -5128,10 +5225,14 @@ 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);
if (GetBattlerHoldEffect(battlerAtk, TRUE) == HOLD_EFFECT_GEMS
if (holdEffect == HOLD_EFFECT_GEMS
&& moveType == ItemId_GetSecondaryId(gBattleMons[battlerAtk].item))
{
gSpecialStatuses[battlerAtk].gemParam = GetBattlerHoldEffectParam(battlerAtk);

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