Merge branch 'battle_engine' of https://github.com/rh-hideout/pokeemerald into multistrike

This commit is contained in:
BuffelSaft 2021-10-09 15:18:51 +13:00
commit 07bdd2ffe6
24 changed files with 1608 additions and 672 deletions

View File

@ -1797,6 +1797,11 @@
.4byte \ptr
.endm
.macro jumpifpranksterblocked battler:req, ptr:req
various \battler, VARIOUS_JUMP_IF_PRANKSTER_BLOCKED
.4byte \ptr
.endm
.macro eeriespellppreduce ptr:req
various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE
.4byte \ptr
@ -1816,6 +1821,10 @@
various BS_ATTACKER, VARIOUS_REMOVE_TERRAIN
.endm
.macro trytoclearprimalweather
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
.endm
@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7
@ -1920,6 +1929,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

View File

@ -532,7 +532,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 +822,8 @@ 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
.align 2
gBattleAnims_Special::
@ -5610,7 +5612,7 @@ Move_REFLECT_TYPE:
blendoff
end
Move_RETALITATE:
Move_RETALIATE:
loadspritegfx ANIM_TAG_CUT @Cut
monbg ANIM_DEF_PARTNER
setalpha 9, 8
@ -24397,6 +24399,31 @@ General_TotemFlare::
clearmonbg ANIM_ATTACKER
end
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
RainbowEndureEffect:
launchtemplate gBlueEndureEnergySpriteTemplate 0x2 0x4 0x0 0xffe8 0x1a 0x2
delay 0x3

View File

@ -252,7 +252,7 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectHit @ EFFECT_ROUND
.4byte BattleScript_EffectHit @ EFFECT_BRINE
.4byte BattleScript_EffectHit @ EFFECT_VENOSHOCK
.4byte BattleScript_EffectHit @ EFFECT_RETALITATE
.4byte BattleScript_EffectHit @ EFFECT_RETALIATE
.4byte BattleScript_EffectBulldoze @ EFFECT_BULLDOZE
.4byte BattleScript_EffectHit @ EFFECT_FOUL_PLAY
.4byte BattleScript_EffectHit @ EFFECT_PSYSHOCK
@ -378,6 +378,8 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectHit @ EFFECT_DYNAMAX_DOUBLE_DMG
.4byte BattleScript_EffectDecorate @ EFFECT_DECORATE
.4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT
.4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT
.4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25
BattleScript_EffectDecorate:
attackcanceler
@ -649,6 +651,9 @@ BattleScript_MoveEffectCoreEnforcer::
setgastroacid BattleScript_CoreEnforcerRet
printstring STRINGID_PKMNSABILITYSUPPRESSED
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
BattleScript_CoreEnforcerRet:
return
@ -741,6 +746,9 @@ BattleScript_EffectPartingShotSwitch:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -1745,6 +1753,9 @@ BattleScript_EffectSimpleBeam:
waitanimation
printstring STRINGID_PKMNACQUIREDSIMPLE
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
goto BattleScript_MoveEnd
BattleScript_EffectSuckerPunch:
@ -1793,6 +1804,9 @@ BattleScript_EffectHealingWish:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -1830,6 +1844,9 @@ BattleScript_EffectWorrySeed:
waitanimation
printstring STRINGID_PKMNACQUIREDABILITY
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
goto BattleScript_MoveEnd
BattleScript_EffectPowerSplit:
@ -1958,6 +1975,9 @@ BattleScript_EffectGastroAcid:
waitanimation
printstring STRINGID_PKMNSABILITYSUPPRESSED
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
goto BattleScript_MoveEnd
BattleScript_EffectToxicSpikes:
@ -2152,6 +2172,9 @@ BattleScript_EffectHitEscape:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -3092,6 +3115,9 @@ BattleScript_EffectTransform::
attackcanceler
attackstring
ppreduce
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
transformdataexecution
attackanimation
waitanimation
@ -3825,23 +3851,32 @@ BattleScript_EffectPerishSong::
waitanimation
printstring STRINGID_FAINTINTHREE
waitmessage B_WAIT_TIME_LONG
setbyte sBATTLER, 0
setbyte gBattlerTarget, 0
BattleScript_PerishSongLoop::
jumpifability BS_SCRIPTING, ABILITY_SOUNDPROOF, BattleScript_PerishSongNotAffected
jumpifability BS_TARGET, ABILITY_SOUNDPROOF, BattleScript_PerishSongBlocked
jumpifpranksterblocked BS_TARGET, BattleScript_PerishSongNotAffected
BattleScript_PerishSongLoopIncrement::
addbyte sBATTLER, 1
jumpifbytenotequal sBATTLER, gBattlersCount, BattleScript_PerishSongLoop
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_PerishSongLoop
goto BattleScript_MoveEnd
BattleScript_PerishSongNotAffected::
BattleScript_PerishSongBlocked::
printstring STRINGID_PKMNSXBLOCKSY2
waitmessage B_WAIT_TIME_LONG
goto BattleScript_PerishSongLoopIncrement
BattleScript_PerishSongNotAffected:
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
goto BattleScript_PerishSongLoopIncrement
BattleScript_EffectSandstorm::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
setsandstorm
goto BattleScript_MoveWeatherChange
@ -3975,6 +4010,9 @@ BattleScript_EffectBatonPass::
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -4044,6 +4082,9 @@ BattleScript_EffectRainDance::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
setrain
BattleScript_MoveWeatherChange::
attackanimation
@ -4057,9 +4098,80 @@ BattleScript_EffectSunnyDay::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
setsunny
goto BattleScript_MoveWeatherChange
BattleScript_ExtremelyHarshSunlightWasNotLessened:
pause B_WAIT_TIME_SHORT
printstring STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_ExtremelyHarshSunlightWasNotLessenedEnd3:
pause B_WAIT_TIME_SHORT
printstring STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_ExtremelyHarshSunlightWasNotLessenedRet:
pause B_WAIT_TIME_SHORT
printstring STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED
waitmessage B_WAIT_TIME_LONG
return
BattleScript_NoReliefFromHeavyRain:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NORELIEFROMHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_NoReliefFromHeavyRainEnd3:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NORELIEFROMHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_NoReliefFromHeavyRainRet:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NORELIEFROMHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
return
BattleScript_MysteriousAirCurrentBlowsOn:
pause B_WAIT_TIME_SHORT
printstring STRINGID_MYSTERIOUSAIRCURRENTBLOWSON
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_MysteriousAirCurrentBlowsOnEnd3:
pause B_WAIT_TIME_SHORT
printstring STRINGID_MYSTERIOUSAIRCURRENTBLOWSON
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_MysteriousAirCurrentBlowsOnRet:
pause B_WAIT_TIME_SHORT
printstring STRINGID_MYSTERIOUSAIRCURRENTBLOWSON
waitmessage B_WAIT_TIME_LONG
return
BattleScript_BlockedByPrimalWeatherEnd3::
call BattleScript_AbilityPopUp
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessenedEnd3
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRainEnd3
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOnEnd3
end3
BattleScript_BlockedByPrimalWeatherRet::
call BattleScript_AbilityPopUp
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessenedRet
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRainRet
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOnRet
return
BattleScript_EffectDefenseUpHit::
setmoveeffect MOVE_EFFECT_DEF_PLUS_1 | MOVE_EFFECT_AFFECTS_USER
goto BattleScript_EffectHit
@ -4425,6 +4537,9 @@ BattleScript_EffectHail::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
sethail
goto BattleScript_MoveWeatherChange
@ -4853,6 +4968,12 @@ BattleScript_EffectSecretPower::
getsecretpowereffect
goto BattleScript_EffectHit
BattleScript_EffectRecoilHP25:
setmoveeffect MOVE_EFFECT_RECOIL_HP_25 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
jumpifnotmove MOVE_STRUGGLE, BattleScript_EffectHit
incrementgamestat GAME_STAT_USED_STRUGGLE
goto BattleScript_EffectHit
BattleScript_EffectTeeterDance::
attackcanceler
attackstring
@ -5167,6 +5288,9 @@ BattleScript_FaintedMonTryChooseAnother:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_ATTACKER
switchinanim BS_ATTACKER, 0
@ -5177,6 +5301,9 @@ BattleScript_FaintedMonChooseAnother:
getswitchedmondata BS_FAINTED
switchindataupdate BS_FAINTED
hpthresholds BS_FAINTED
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_FAINTED
switchinanim BS_FAINTED, FALSE
@ -5209,6 +5336,9 @@ BattleScript_HandleFaintedMonLoop::
getswitchedmondata BS_FAINTED
switchindataupdate BS_FAINTED
hpthresholds BS_FAINTED
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_FAINTED
switchinanim BS_FAINTED, FALSE
@ -5411,6 +5541,9 @@ BattleScript_DoSwitchOut::
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_ATTACKER
switchinanim BS_ATTACKER, FALSE
@ -5712,6 +5845,9 @@ BattleScript_RoarSuccessSwitch::
call BattleScript_RoarSuccessRet
getswitchedmondata BS_TARGET
switchindataupdate BS_TARGET
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
switchinanim BS_TARGET, FALSE
waitstate
printstring STRINGID_PKMNWASDRAGGEDOUT
@ -5942,6 +6078,76 @@ BattleScript_PerishBodyActivates::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
return
BattleScript_GulpMissileGorging::
call BattleScript_AbilityPopUp
playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE, NULL
waitanimation
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
effectivenesssound
hitanimation BS_ATTACKER
waitstate
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGorging
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
tryfaintmon BS_ATTACKER, FALSE, NULL
getbattlerfainted BS_ATTACKER
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGorging
BattleScript_GulpMissileNoDmgGorging:
handleformchange BS_TARGET, 0
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
waitanimation
swapattackerwithtarget
setmoveeffect MOVE_EFFECT_PARALYSIS
seteffectprimary
swapattackerwithtarget
return
BattleScript_GulpMissileNoSecondEffectGorging:
handleformchange BS_TARGET, 0
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
waitanimation
return
BattleScript_GulpMissileGulping::
call BattleScript_AbilityPopUp
playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE, NULL
waitanimation
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
effectivenesssound
hitanimation BS_ATTACKER
waitstate
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGulping
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
tryfaintmon BS_ATTACKER, FALSE, NULL
getbattlerfainted BS_ATTACKER
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGulping
jumpifability BS_ATTACKER, ABILITY_CLEAR_BODY, BattleScript_GulpMissileNoSecondEffectGulping
jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping
jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping
jumpifflowerveilattacker BattleScript_GulpMissileNoSecondEffectGulping
BattleScript_GulpMissileNoDmgGulping:
handleformchange BS_TARGET, 0
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
waitanimation
swapattackerwithtarget @ to make gStatDownStringIds down below print the right battler
setstatchanger STAT_DEF, 1, TRUE
statbuffchange STAT_BUFF_NOT_PROTECT_AFFECTED, BattleScript_GulpMissileGorgingTargetDefenseCantGoLower
setgraphicalstatchangevalues
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatDownStringIds
waitmessage B_WAIT_TIME_LONG
swapattackerwithtarget @ restore the battlers, just in case
return
BattleScript_GulpMissileNoSecondEffectGulping:
handleformchange BS_TARGET, 0
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
waitanimation
return
BattleScript_GulpMissileGorgingTargetDefenseCantGoLower:
printstring STRINGID_STATSWONTDECREASE
waitmessage B_WAIT_TIME_LONG
return
BattleScript_PerishSongCountGoesDown::
printstring STRINGID_PKMNPERISHCOUNTFELL
waitmessage B_WAIT_TIME_LONG
@ -6276,6 +6482,17 @@ BattleScript_MagicCoatBounce::
setmagiccoattarget BS_ATTACKER
return
BattleScript_MagicCoatBouncePrankster::
attackstring
ppreduce
pause B_WAIT_TIME_SHORT
printfromtable gMagicCoatBounceStringIds
waitmessage B_WAIT_TIME_LONG
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
goto BattleScript_MoveEnd
BattleScript_SnatchedMove::
attackstring
ppreduce
@ -7071,6 +7288,56 @@ BattleScript_DroughtActivates::
call BattleScript_WeatherFormChanges
end3
BattleScript_DesolateLandActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_EXTREMELYHARSHSUNLIGHT
waitstate
playanimation BS_BATTLER_0, B_ANIM_SUN_CONTINUES, NULL
call BattleScript_WeatherFormChanges
end3
BattleScript_DesolateLandEvaporatesWaterTypeMoves::
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
pause B_WAIT_TIME_SHORT
ppreduce
printstring STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_PrimordialSeaActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_HEAVYRAIN
waitstate
playanimation BS_BATTLER_0, B_ANIM_RAIN_CONTINUES, NULL
call BattleScript_WeatherFormChanges
end3
BattleScript_PrimordialSeaFizzlesOutFireTypeMoves::
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
pause B_WAIT_TIME_SHORT
ppreduce
printstring STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_DeltaStreamActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_MYSTERIOUSAIRCURRENT
waitstate
playanimation BS_ATTACKER, B_ANIM_STRONG_WINDS, NULL
end3
BattleScript_AttackWeakenedByStrongWinds::
pause B_WAIT_TIME_SHORT
printstring STRINGID_ATTACKWEAKENEDBSTRONGWINDS
waitmessage B_WAIT_TIME_LONG
return
BattleScript_SnowWarningActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
@ -7571,6 +7838,19 @@ BattleScript_AbilityStatusEffect::
seteffectsecondary
return
BattleScript_BattleBondActivatesOnMoveEndAttacker::
pause 5
copybyte gBattlerAbility, gBattlerAttacker
call BattleScript_AbilityPopUp
printstring STRINGID_ATTACKERBECAMEFULLYCHARGED
handleformchange BS_ATTACKER, 0
handleformchange BS_ATTACKER, 1
playanimation BS_ATTACKER, B_ANIM_FORM_CHANGE, NULL
waitanimation
handleformchange BS_ATTACKER, 2
printstring STRINGID_ATTACKERBECAMEASHSPECIES
return
BattleScript_DancerActivates::
call BattleScript_AbilityPopUp
waitmessage B_WAIT_TIME_SHORT
@ -8242,6 +8522,9 @@ BattleScript_EjectButtonActivates::
getswitchedmondata BS_SCRIPTING
switchindataupdate BS_SCRIPTING
hpthresholds BS_SCRIPTING
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring 0x3
switchinanim BS_SCRIPTING 0x1
waitstate
@ -8259,3 +8542,12 @@ BattleScript_EjectPackActivate_End2::
BattleScript_EjectPackActivates::
jumpifcantswitch BS_SCRIPTING, BattleScript_EjectButtonEnd
goto BattleScript_EjectPackActivate_Ret
BattleScript_DarkTypePreventsPrankster::
attackstring
ppreduce
pause B_WAIT_TIME_SHORT
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
goto BattleScript_MoveEnd

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -149,6 +149,7 @@ struct ProtectStruct
u32 touchedProtectLike:1;
u32 disableEjectPack:1;
u32 statFell:1;
u32 pranksterElevated:1;
u32 physicalDmg;
u32 specialDmg;
u8 physicalBattlerId;

View File

@ -97,6 +97,7 @@ extern const u8 BattleScript_SelectingImprisonedMove[];
extern const u8 BattleScript_SelectingImprisonedMoveInPalace[];
extern const u8 BattleScript_GrudgeTakesPp[];
extern const u8 BattleScript_MagicCoatBounce[];
extern const u8 BattleScript_MagicCoatBouncePrankster[];
extern const u8 BattleScript_SnatchedMove[];
extern const u8 BattleScript_EnduredMsg[];
extern const u8 BattleScript_OneHitKOMsg[];
@ -384,6 +385,19 @@ extern const u8 BattleScript_MentalHerbCureEnd2[];
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_MultiHitPrintStrings[];
extern const u8 BattleScript_BurnUpRemoveType[];

View File

@ -152,6 +152,7 @@ bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind);
bool32 TryRoomService(u8 battlerId);
void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
void DoBurmyFormChange(u32 monId);
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef);
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId);
// ability checks

View File

@ -257,24 +257,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
@ -344,7 +351,8 @@
#define MOVE_EFFECT_INCINERATE 0x40
#define MOVE_EFFECT_BUG_BITE 0x41
#define MOVE_EFFECT_BURN_UP 0x42
#define NUM_MOVE_EFFECTS 0x43
#define MOVE_EFFECT_RECOIL_HP_25 0x43
#define NUM_MOVE_EFFECTS 0x44
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000

View File

@ -523,6 +523,8 @@
#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
// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0

View File

@ -40,6 +40,11 @@
#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
#endif
// Items with peculiar battle effects.
@ -125,10 +130,12 @@
#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.
#define B_PARENTAL_BOND_DAMAGE GEN_8 // In Gen7+, Parental Bond's second hit does 25% of the initial hits damage. Before, it did 50%.
// Item settings

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,8 @@
#define EFFECT_DECORATE 357
#define EFFECT_SNIPE_SHOT 358
#define EFFECT_TRIPLE_HIT 359
#define EFFECT_RECOIL_HP_25 360
#define NUM_BATTLE_MOVE_EFFECTS 360
#define NUM_BATTLE_MOVE_EFFECTS 361
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -183,6 +183,8 @@
#define VARIOUS_JUMP_IF_TEAM_HEALTHY 111
#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
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

File diff suppressed because it is too large Load Diff

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[];
@ -5199,6 +5200,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

@ -512,7 +512,7 @@ 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;
s32 moveType;
u8 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);
@ -520,8 +520,13 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
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 +753,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)
@ -2434,13 +2466,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;
}
}
@ -2472,7 +2523,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)
{
@ -4751,7 +4805,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

@ -2213,6 +2213,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

@ -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

@ -1037,6 +1037,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
if (gBattleStruct->mega.evolvedPartyIds[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 +1045,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 +1493,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)
@ -1515,16 +1511,15 @@ u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which)
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];
}
x += sIndicatorPositions[position][0];
y += sIndicatorPositions[position][1];
if (gBattleMons[battlerId].level >= 100)
x -= 4;
else if (gBattleMons[battlerId].level < 10)
x += 5;
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_MegaIndicator, x, y, 0);
gSprites[gSprites[gHealthboxSpriteIds[battlerId]].oam.affineParam].hOther_IndicatorSpriteId = spriteId;

View File

@ -3095,6 +3095,7 @@ void FaintClearSetData(void)
gProtectStructs[gActiveBattler].usedGravityPreventedMove = 0;
gProtectStructs[gActiveBattler].usedThroatChopPreventedMove = 0;
gProtectStructs[gActiveBattler].statRaised = 0;
gProtectStructs[gActiveBattler].statFell = 0;
gDisableStructs[gActiveBattler].isFirstTurn = 2;
@ -3465,10 +3466,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)
@ -3682,7 +3686,7 @@ u8 IsRunningFromBattleImpossible(void)
return 0;
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)))
@ -4303,6 +4307,7 @@ s8 GetChosenMovePriority(u32 battlerId)
{
u16 move;
gProtectStructs[battlerId].pranksterElevated = 0;
if (gProtectStructs[battlerId].noValidMoves)
move = MOVE_STRUGGLE;
else
@ -4324,6 +4329,7 @@ s8 GetMovePriority(u32 battlerId, u16 move)
}
else if (GetBattlerAbility(battlerId) == ABILITY_PRANKSTER && IS_MOVE_STATUS(move))
{
gProtectStructs[battlerId].pranksterElevated = 1;
priority++;
}
else if (gBattleMoves[move].effect == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battlerId))

View File

@ -704,10 +704,37 @@ static const u8 sText_EjectButtonActivate[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}
static const u8 sText_AttackerGotOverInfatuation[] =_("{B_ATK_NAME_WITH_PREFIX} got over\nits infatuation!");
static const u8 sText_TormentedNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is\ntormented no more!");
static const u8 sText_HealBlockedNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is cured of\nits heal block!");
static const u8 sText_AttackerBecameFullyCharged[] = _("{B_ATK_NAME_WITH_PREFIX} became fully charged\ndue to its bond with its trainer!\p");
static const u8 sText_AttackerBecameAshSpecies[] = _("{B_ATK_NAME_WITH_PREFIX} became Ash-{B_BUFF1}!\p");
static const u8 sText_ExtremelyHarshSunlight[] = _("The sunlight turned\nextremely harsh!");
static const u8 sText_ExtremeSunlightFaded[] = _("The extreme sunlight faded.{PAUSE 64}");
static const u8 sText_MoveEvaporatedInTheHarshSunlight[] = _("The Water-type attack evaporated\nin the harsh sunlight!");
static const u8 sText_ExtremelyHarshSunlightWasNotLessened[] = _("The extremely harsh sunlight\nwas not lessened at all!");
static const u8 sText_HeavyRain[] = _("A heavy rain began to fall!");
static const u8 sText_HeavyRainLifted[] = _("The heavy rain has lifted!{PAUSE 64}");
static const u8 sText_MoveFizzledOutInTheHeavyRain[] = _("The Fire-type attack fizzled out\nin the heavy rain!");
static const u8 sText_NoReliefFromHeavyRain[] = _("There is no relief from\nthis heavy rain!");
static const u8 sText_MysteriousAirCurrent[] = _("A mysterious air current is\nprotecting Flying-type Pokémon!");
static const u8 sText_StrongWindsDissipated[] = _("The mysterious strong winds\nhave dissipated!{PAUSE 64}");
static const u8 sText_MysteriousAirCurrentBlowsOn[] = _("The mysterious air current\nblows on regardless!");
static const u8 sText_AttackWeakenedByStrongWinds[] = _("The mysterious strong winds\nweakened the attack!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_ATTACKWEAKENEDBSTRONGWINDS - 12] = sText_AttackWeakenedByStrongWinds,
[STRINGID_MYSTERIOUSAIRCURRENTBLOWSON - 12] = sText_MysteriousAirCurrentBlowsOn,
[STRINGID_STRONGWINDSDISSIPATED - 12] = sText_StrongWindsDissipated,
[STRINGID_MYSTERIOUSAIRCURRENT - 12] = sText_MysteriousAirCurrent,
[STRINGID_NORELIEFROMHEAVYRAIN - 12] = sText_NoReliefFromHeavyRain,
[STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN - 12] = sText_MoveFizzledOutInTheHeavyRain,
[STRINGID_HEAVYRAINLIFTED - 12] = sText_HeavyRainLifted,
[STRINGID_HEAVYRAIN - 12] = sText_HeavyRain,
[STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED - 12] = sText_ExtremelyHarshSunlightWasNotLessened,
[STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT - 12] = sText_MoveEvaporatedInTheHarshSunlight,
[STRINGID_EXTREMESUNLIGHTFADED - 12] = sText_ExtremeSunlightFaded,
[STRINGID_EXTREMELYHARSHSUNLIGHT - 12] = sText_ExtremelyHarshSunlight,
[STRINGID_ATTACKERBECAMEASHSPECIES - 12] = sText_AttackerBecameAshSpecies,
[STRINGID_ATTACKERBECAMEFULLYCHARGED - 12] = sText_AttackerBecameFullyCharged,
[STRINGID_HEALBLOCKEDNOMORE - 12] = sText_HealBlockedNoMore,
[STRINGID_TORMENTEDNOMORE - 12] = sText_TormentedNoMore,
[STRINGID_ATKGOTOVERINFATUATION - 12] = sText_AttackerGotOverInfatuation,

View File

@ -1371,6 +1371,28 @@ static void Cmd_attackcanceler(void)
{
s32 i, moveType;
GET_MOVE_TYPE(gCurrentMove, moveType);
if (moveType == TYPE_FIRE
&& (gBattleWeather & WEATHER_RAIN_PRIMAL)
&& WEATHER_HAS_EFFECT
&& gBattleMoves[gCurrentMove].power)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_PrimordialSeaFizzlesOutFireTypeMoves;
return;
}
if (moveType == TYPE_WATER
&& (gBattleWeather & WEATHER_SUN_PRIMAL)
&& WEATHER_HAS_EFFECT
&& gBattleMoves[gCurrentMove].power)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_DesolateLandEvaporatesWaterTypeMoves;
return;
}
if (gBattleOutcome != 0)
{
gCurrentActionFuncId = B_ACTION_FINISHED;
@ -1401,7 +1423,6 @@ static void Cmd_attackcanceler(void)
}
// Check Protean activation.
GET_MOVE_TYPE(gCurrentMove, moveType);
if ((GetBattlerAbility(gBattlerAttacker) == ABILITY_PROTEAN || GetBattlerAbility(gBattlerAttacker) == ABILITY_LIBERO)
&& (gBattleMons[gBattlerAttacker].type1 != moveType || gBattleMons[gBattlerAttacker].type2 != moveType ||
(gBattleMons[gBattlerAttacker].type3 != moveType && gBattleMons[gBattlerAttacker].type3 != TYPE_MYSTERY))
@ -1464,8 +1485,17 @@ static void Cmd_attackcanceler(void)
gProtectStructs[gBattlerTarget].bounceMove = 0;
gProtectStructs[gBattlerTarget].usesBouncedMove = 1;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce;
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker))
{
// Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker
gBattlerTarget = gBattlerAttacker;
gBattlescriptCurrInstr = BattleScript_MagicCoatBouncePrankster;
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce;
}
return;
}
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE
@ -1940,6 +1970,9 @@ static void Cmd_typecalc(void)
static void Cmd_adjustdamage(void)
{
u8 holdEffect, param;
u32 moveType;
GET_MOVE_TYPE(gCurrentMove, moveType);
if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
goto END;
@ -2017,6 +2050,23 @@ END:
gBattlescriptCurrInstr = BattleScript_GemActivates;
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
}
// WEATHER_STRONG_WINDS prints a string when it's about to reduce the power
// of a move that is Super Effective against a Flying-type Pokémon.
if (gBattleWeather & WEATHER_STRONG_WINDS)
{
if ((gBattleMons[gBattlerTarget].type1 == TYPE_FLYING
&& GetTypeModifier(moveType, gBattleMons[gBattlerTarget].type1) >= UQ_4_12(2.0))
|| (gBattleMons[gBattlerTarget].type2 == TYPE_FLYING
&& GetTypeModifier(moveType, gBattleMons[gBattlerTarget].type2) >= UQ_4_12(2.0))
|| (gBattleMons[gBattlerTarget].type3 == TYPE_FLYING
&& GetTypeModifier(moveType, gBattleMons[gBattlerTarget].type3) >= UQ_4_12(2.0)))
{
gBattlerAbility = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AttackWeakenedByStrongWinds;
}
}
}
static void Cmd_multihitresultmessage(void)
@ -3095,6 +3145,61 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleMons[gBattlerAttacker].status2 |= STATUS2_RAGE;
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_STEAL_ITEM:
{
if (!CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item))
{
gBattlescriptCurrInstr++;
break;
}
side = GetBattlerSide(gBattlerAttacker);
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT
&& !(gBattleTypeFlags &
(BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_RECORDED_LINK
| BATTLE_TYPE_SECRET_BASE)))
{
gBattlescriptCurrInstr++;
}
else if (!(gBattleTypeFlags &
(BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_RECORDED_LINK
| BATTLE_TYPE_SECRET_BASE))
&& (gWishFutureKnock.knockedOffMons[side] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]))
{
gBattlescriptCurrInstr++;
}
else if (gBattleMons[gBattlerTarget].item
&& GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_NoItemSteal;
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
}
else if (gBattleMons[gBattlerAttacker].item != 0
|| gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY
|| gBattleMons[gBattlerTarget].item == 0)
{
gBattlescriptCurrInstr++;
}
else
{
StealTargetItem(gBattlerAttacker, gBattlerTarget); // Attacker steals target item
gBattleMons[gBattlerAttacker].item = 0; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_ItemSteal;
}
}
break;
case MOVE_EFFECT_PREVENT_ESCAPE:
gBattleMons[gBattlerTarget].status2 |= STATUS2_ESCAPE_PREVENTION;
gDisableStructs[gBattlerTarget].battlerPreventingEscape = gBattlerAttacker;
@ -3120,6 +3225,14 @@ void SetMoveEffect(bool32 primary, u32 certain)
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_DefSpDefDown;
break;
case MOVE_EFFECT_RECOIL_HP_25: // Struggle
gBattleMoveDamage = (gBattleMons[gEffectBattler].maxHP) / 4;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
break;
case MOVE_EFFECT_THRASH:
if (gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE)
{
@ -5142,6 +5255,7 @@ static void Cmd_moveend(void)
MoveValuesCleanUp();
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
gBattleStruct->atkCancellerTracker = 0; // Run all cancellers on next target
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
@ -5286,6 +5400,7 @@ static void Cmd_moveend(void)
u8 battler = battlers[i];
if (IsBattlerAlive(battler)
&& gProtectStructs[battler].statFell
&& gProtectStructs[battler].disableEjectPack == 0
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_PACK
&& !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker)) // Does not activate if attacker used Parting Shot and can switch out
&& CountUsablePartyMons(battler) > 0) // Has mon to switch into
@ -6676,6 +6791,7 @@ static void Cmd_jumptocalledmove(void)
else
gChosenMove = gCurrentMove = gCalledMove;
gBattleStruct->atkCancellerTracker = 0;
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
}
@ -7376,7 +7492,7 @@ u32 IsLeafGuardProtected(u32 battler)
bool32 IsShieldsDownProtected(u32 battler)
{
return (gBattleMons[battler].ability == ABILITY_SHIELDS_DOWN
&& gBattleMons[battler].species == SPECIES_MINIOR);
&& GetFormIdFromFormSpeciesId(gBattleMons[battler].species) < GetFormIdFromFormSpeciesId(SPECIES_MINIOR_CORE_RED)); // Minior is not in core form
}
u32 IsAbilityStatusProtected(u32 battler)
@ -8001,15 +8117,15 @@ static void Cmd_various(void)
gBattlescriptCurrInstr += 7;
return;
case VARIOUS_SET_SIMPLE_BEAM:
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gActiveBattler].ability))
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)
|| gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
gBattleMons[gActiveBattler].ability = ABILITY_SIMPLE;
gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE;
gBattlescriptCurrInstr += 7;
break;
}
return;
case VARIOUS_TRY_ENTRAINMENT:
@ -8230,7 +8346,8 @@ static void Cmd_various(void)
// Change species.
if (gBattlescriptCurrInstr[3] == 0)
{
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
if (!gBattleTextBuff1)
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
BtlController_EmitSetMonData(0, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], 2, &gBattleMons[gActiveBattler].species);
MarkBattlerForControllerExec(gActiveBattler);
}
@ -8824,6 +8941,45 @@ static void Cmd_various(void)
}
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
break;
case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
case VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER:
{
bool8 shouldNotClear = FALSE;
for (i = 0; i < gBattlersCount; i++)
{
if (((GetBattlerAbility(i) == ABILITY_DESOLATE_LAND && gBattleWeather & WEATHER_SUN_PRIMAL)
|| (GetBattlerAbility(i) == ABILITY_PRIMORDIAL_SEA && gBattleWeather & WEATHER_RAIN_PRIMAL)
|| (GetBattlerAbility(i) == ABILITY_DELTA_STREAM && gBattleWeather & WEATHER_STRONG_WINDS))
&& IsBattlerAlive(i)
&& !(gStatuses3[i] & STATUS3_GASTRO_ACID))
shouldNotClear = TRUE;
}
if (gBattleWeather & WEATHER_SUN_PRIMAL && !shouldNotClear)
{
gBattleWeather &= ~WEATHER_SUN_PRIMAL;
PrepareStringBattle(STRINGID_EXTREMESUNLIGHTFADED, gActiveBattler);
gBattleCommunication[MSG_DISPLAY] = 1;
}
else if (gBattleWeather & WEATHER_RAIN_PRIMAL && !shouldNotClear)
{
gBattleWeather &= ~WEATHER_RAIN_PRIMAL;
PrepareStringBattle(STRINGID_HEAVYRAINLIFTED, gActiveBattler);
gBattleCommunication[MSG_DISPLAY] = 1;
}
else if (gBattleWeather & WEATHER_STRONG_WINDS && !shouldNotClear)
{
gBattleWeather &= ~WEATHER_STRONG_WINDS;
PrepareStringBattle(STRINGID_STRONGWINDSDISSIPATED, gActiveBattler);
gBattleCommunication[MSG_DISPLAY] = 1;
}
break;
}
}
gBattlescriptCurrInstr += 3;
@ -9206,7 +9362,7 @@ bool8 UproarWakeUpCheck(u8 battlerId)
for (i = 0; i < gBattlersCount; i++)
{
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[battlerId].ability == ABILITY_SOUNDPROOF)
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || GetBattlerAbility(battlerId) == ABILITY_SOUNDPROOF)
continue;
gBattleScripting.battler = i;
@ -9528,9 +9684,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
}
else
{
// Check eject pack. disableEjectPack set for edge cases (e.g. attacking weak armor'd eject pack holder with u-turn)
if (gProtectStructs[gActiveBattler].disableEjectPack == 0)
gProtectStructs[gActiveBattler].statFell = 1;
gProtectStructs[gActiveBattler].statFell = 1; // Eject pack, lash out
gBattleCommunication[MULTISTRING_CHOOSER] = (gBattlerTarget == gActiveBattler); // B_MSG_ATTACKER_STAT_FELL or B_MSG_DEFENDER_STAT_FELL
}
}
@ -10857,7 +11011,7 @@ static void Cmd_healpartystatus(void)
else
party = gEnemyParty;
if (gBattleMons[gBattlerAttacker].ability != ABILITY_SOUNDPROOF)
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)
{
gBattleMons[gBattlerAttacker].status1 = 0;
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE);
@ -10873,7 +11027,7 @@ static void Cmd_healpartystatus(void)
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
{
if (gBattleMons[gActiveBattler].ability != ABILITY_SOUNDPROOF)
if (GetBattlerAbility(gActiveBattler) != ABILITY_SOUNDPROOF)
{
gBattleMons[gActiveBattler].status1 = 0;
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_NIGHTMARE);
@ -10986,7 +11140,8 @@ static void Cmd_trysetperishsong(void)
for (i = 0; i < gBattlersCount; i++)
{
if (gStatuses3[i] & STATUS3_PERISH_SONG
|| gBattleMons[i].ability == ABILITY_SOUNDPROOF)
|| GetBattlerAbility(i) == ABILITY_SOUNDPROOF
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i))
{
notAffectedCount++;
}
@ -11712,7 +11867,7 @@ static void Cmd_tryswapitems(void) // trick
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
// check if ability prevents swapping
else if (gBattleMons[gBattlerTarget].ability == ABILITY_STICKY_HOLD)
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD)
{
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates;
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;

View File

@ -1015,6 +1015,11 @@ static const u8 sAbilitiesAffectedByMoldBreaker[] =
[ABILITY_FLUFFY] = 1,
[ABILITY_QUEENLY_MAJESTY] = 1,
[ABILITY_WATER_BUBBLE] = 1,
[ABILITY_MIRROR_ARMOR] = 1,
[ABILITY_PUNK_ROCK] = 1,
[ABILITY_ICE_SCALES] = 1,
[ABILITY_ICE_FACE] = 1,
[ABILITY_PASTEL_VEIL] = 1,
};
static const u8 sAbilitiesNotTraced[ABILITIES_COUNT] =
@ -1295,7 +1300,7 @@ void PressurePPLose(u8 target, u8 attacker, u16 move)
{
int moveIndex;
if (gBattleMons[target].ability != ABILITY_PRESSURE)
if (GetBattlerAbility(target) != ABILITY_PRESSURE)
return;
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
@ -1327,7 +1332,7 @@ void PressurePPLoseOnUsingImprison(u8 attacker)
for (i = 0; i < gBattlersCount; i++)
{
if (atkSide != GetBattlerSide(i) && gBattleMons[i].ability == ABILITY_PRESSURE)
if (atkSide != GetBattlerSide(i) && GetBattlerAbility(i) == ABILITY_PRESSURE)
{
for (j = 0; j < MAX_MON_MOVES; j++)
{
@ -1360,7 +1365,7 @@ void PressurePPLoseOnUsingPerishSong(u8 attacker)
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].ability == ABILITY_PRESSURE && i != attacker)
if (GetBattlerAbility(i) == ABILITY_PRESSURE && i != attacker)
{
for (j = 0; j < MAX_MON_MOVES; j++)
{
@ -2133,7 +2138,8 @@ u8 DoFieldEndTurnEffects(void)
case ENDTURN_RAIN:
if (gBattleWeather & WEATHER_RAIN_ANY)
{
if (!(gBattleWeather & WEATHER_RAIN_PERMANENT))
if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)
&& !(gBattleWeather & WEATHER_RAIN_PRIMAL))
{
if (--gWishFutureKnock.weatherDuration == 0)
{
@ -2183,7 +2189,9 @@ u8 DoFieldEndTurnEffects(void)
case ENDTURN_SUN:
if (gBattleWeather & WEATHER_SUN_ANY)
{
if (!(gBattleWeather & WEATHER_SUN_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
if (!(gBattleWeather & WEATHER_SUN_PERMANENT)
&& !(gBattleWeather & WEATHER_SUN_PRIMAL)
&& --gWishFutureKnock.weatherDuration == 0)
{
gBattleWeather &= ~WEATHER_SUN_TEMPORARY;
gBattlescriptCurrInstr = BattleScript_SunlightFaded;
@ -2755,8 +2763,8 @@ u8 DoBattlerEndTurnEffects(void)
{
gStatuses3[gActiveBattler] -= STATUS3_YAWN_TURN(1);
if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
&& gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT
&& gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)
&& GetBattlerAbility(gActiveBattler) != ABILITY_VITAL_SPIRIT
&& GetBattlerAbility(gActiveBattler) != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)
&& !IsLeafGuardProtected(gActiveBattler))
{
CancelMultiTurnMoves(gActiveBattler);
@ -3119,6 +3127,7 @@ enum
CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS,
CANCELLER_THROAT_CHOP,
CANCELLER_PRANKSTER,
CANCELLER_MULTIHIT_MOVES,
CANCELLER_END,
CANCELLER_PSYCHIC_TERRAIN,
@ -3154,7 +3163,7 @@ u8 AtkCanceller_UnableToUseMove(void)
else
{
u8 toSub;
if (gBattleMons[gBattlerAttacker].ability == ABILITY_EARLY_BIRD)
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_EARLY_BIRD)
toSub = 2;
else
toSub = 1;
@ -3164,7 +3173,7 @@ u8 AtkCanceller_UnableToUseMove(void)
gBattleMons[gBattlerAttacker].status1 -= toSub;
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
{
if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK)
if (gChosenMove != MOVE_SNORE && gChosenMove != MOVE_SLEEP_TALK)
{
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
@ -3448,6 +3457,16 @@ u8 AtkCanceller_UnableToUseMove(void)
}
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_PRANKSTER:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget)
&& !(IS_MOVE_STATUS(gCurrentMove) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE))
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster;
effect = 1;
}
case CANCELLER_MULTIHIT_MOVES:
if (gBattleMoves[gCurrentMove].effect == EFFECT_MULTI_HIT)
{
@ -3780,9 +3799,12 @@ u8 TryWeatherFormChange(u8 battler)
static const u16 sWeatherFlagsInfo[][3] =
{
[ENUM_WEATHER_RAIN] = {WEATHER_RAIN_TEMPORARY, WEATHER_RAIN_PERMANENT, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_RAIN_PRIMAL] = {WEATHER_RAIN_PRIMAL, WEATHER_RAIN_PRIMAL, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_SUN] = {WEATHER_SUN_TEMPORARY, WEATHER_SUN_PERMANENT, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SUN_PRIMAL] = {WEATHER_SUN_PRIMAL, WEATHER_SUN_PRIMAL, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SANDSTORM] = {WEATHER_SANDSTORM_TEMPORARY, WEATHER_SANDSTORM_PERMANENT, HOLD_EFFECT_SMOOTH_ROCK},
[ENUM_WEATHER_HAIL] = {WEATHER_HAIL_TEMPORARY, WEATHER_HAIL_PERMANENT, HOLD_EFFECT_ICY_ROCK},
[ENUM_WEATHER_STRONG_WINDS] = {WEATHER_STRONG_WINDS, WEATHER_STRONG_WINDS, HOLD_EFFECT_NONE},
};
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
@ -3793,6 +3815,13 @@ bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]);
return TRUE;
}
else if (gBattleWeather & WEATHER_PRIMAL_ANY
&& GetBattlerAbility(battler) != ABILITY_DESOLATE_LAND
&& GetBattlerAbility(battler) != ABILITY_PRIMORDIAL_SEA
&& GetBattlerAbility(battler) != ABILITY_DELTA_STREAM)
{
return FALSE;
}
else if (!(gBattleWeather & (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1])))
{
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0]);
@ -3840,6 +3869,8 @@ static bool32 ShouldChangeFormHpBased(u32 battler)
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW, 2},
{ABILITY_SCHOOLING, SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, 4},
{ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GORGING, 2},
{ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GULPING, 1},
};
u32 i;
@ -4261,6 +4292,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_SAND_STREAM:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE))
@ -4268,6 +4305,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_DROUGHT:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SUN, TRUE))
@ -4275,6 +4318,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_SNOW_WARNING:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_HAIL, TRUE))
@ -4282,6 +4331,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_ELECTRIC_SURGE:
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.electricTerrainTimer))
@ -4371,6 +4426,27 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
effect++;
}
break;
case ABILITY_DESOLATE_LAND:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SUN_PRIMAL, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_DesolateLandActivates);
effect++;
}
break;
case ABILITY_PRIMORDIAL_SEA:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_RAIN_PRIMAL, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_PrimordialSeaActivates);
effect++;
}
break;
case ABILITY_DELTA_STREAM:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_STRONG_WINDS, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_DeltaStreamActivates);
effect++;
}
break;
}
break;
case ABILITYEFFECT_ENDTURN: // 1
@ -5062,13 +5138,20 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY)
&& TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE))
&& TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE)
&& !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY))
{
gBattleScripting.battler = gActiveBattler = battler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SandSpitActivates;
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BlockedByPrimalWeatherRet;
effect++;
}
break;
case ABILITY_PERISH_BODY:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
@ -5092,6 +5175,42 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
effect++;
}
break;
case ABILITY_GULP_MISSILE:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerAlive(battler))
{
if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GORGING)
{
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species;
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
}
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_GulpMissileGorging;
effect++;
}
else if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GULPING)
{
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species;
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
}
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_GulpMissileGulping;
effect++;
}
}
break;
}
break;
case ABILITYEFFECT_MOVE_END_ATTACKER: // Same as above, but for attacker
@ -5128,6 +5247,27 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
effect++;
}
break;
case ABILITY_GULP_MISSILE:
if (((gCurrentMove == MOVE_SURF && TARGET_TURN_DAMAGED) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER)
&& (effect = ShouldChangeFormHpBased(gBattlerAttacker)))
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AttackerFormChange;
effect++;
}
break;
case ABILITY_BATTLE_BOND:
if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND
&& gBattleResults.opponentFaintCounter != 0
&& CalculateEnemyPartyCount() > 1)
{
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;
}
break;
}
break;
case ABILITYEFFECT_MOVE_END_OTHER: // Abilities that activate on *another* battler's moveend: Dancer, Soul-Heart, Receiver, Symbiosis
@ -5450,11 +5590,15 @@ u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability)
u32 IsAbilityPreventingEscape(u32 battlerId)
{
u32 id;
if (B_GHOSTS_ESCAPE >= GEN_6 && IS_BATTLER_OF_TYPE(battlerId, TYPE_GHOST))
return 0;
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG)
#if B_GHOSTS_ESCAPE >= GEN_6
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_GHOST))
return 0;
#endif
#if B_SHADOW_TAG_ESCAPE >= GEN_4
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG)
#else
if (id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG))
#endif
return id;
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_ARENA_TRAP)) && IsBattlerGrounded(battlerId))
return id;
@ -6121,6 +6265,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_EJECT_PACK:
if (gProtectStructs[battlerId].statFell
&& gProtectStructs[battlerId].disableEjectPack == 0
&& !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker))) // Does not activate if attacker used Parting Shot and can switch out
{
gProtectStructs[battlerId].statFell = FALSE;
@ -6229,7 +6374,20 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_BLACK_SLUDGE:
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_POISON))
{
goto LEFTOVERS;
}
else if (GetBattlerAbility(battlerId) != ABILITY_MAGIC_GUARD && !moveTurn)
{
gBattleMoveDamage = gBattleMons[battlerId].maxHP / 8;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptExecute(BattleScript_ItemHurtEnd2);
effect = ITEM_HP_CHANGE;
RecordItemEffectBattle(battlerId, battlerHoldEffect);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem);
}
break;
case HOLD_EFFECT_LEFTOVERS:
LEFTOVERS:
if (gBattleMons[battlerId].hp < gBattleMons[battlerId].maxHP && !moveTurn)
@ -6959,7 +7117,11 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
moveTarget = setTarget - 1;
else
moveTarget = gBattleMoves[move].target;
// Special cases
if (move == MOVE_CURSE && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
moveTarget = MOVE_TARGET_USER;
switch (moveTarget)
{
case MOVE_TARGET_SELECTED:
@ -7350,7 +7512,7 @@ static const u16 sWeightToDamageTable[] =
};
static const u8 sSpeedDiffPowerTable[] = {40, 60, 80, 120, 150};
static const u8 sHeatCrushPowerTable[] = {40, 40, 60, 80, 100, 120};
static const u8 sHeatCrashPowerTable[] = {40, 40, 60, 80, 100, 120};
static const u8 sTrumpCardPowerTable[] = {200, 80, 60, 50, 40};
const struct TypePower gNaturalGiftTable[] =
@ -7522,7 +7684,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
if (gBattleMons[battlerAtk].pp[i] >= ARRAY_COUNT(sTrumpCardPowerTable))
basePower = sTrumpCardPowerTable[ARRAY_COUNT(sTrumpCardPowerTable) - 1];
else
basePower = sTrumpCardPowerTable[i];
basePower = sTrumpCardPowerTable[gBattleMons[battlerAtk].pp[i]];
}
break;
case EFFECT_ACROBATICS:
@ -7545,10 +7707,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
break;
case EFFECT_HEAT_CRASH:
weight = GetBattlerWeight(battlerAtk) / GetBattlerWeight(battlerDef);
if (weight >= ARRAY_COUNT(sHeatCrushPowerTable))
basePower = sHeatCrushPowerTable[ARRAY_COUNT(sHeatCrushPowerTable) - 1];
if (weight >= ARRAY_COUNT(sHeatCrashPowerTable))
basePower = sHeatCrashPowerTable[ARRAY_COUNT(sHeatCrashPowerTable) - 1];
else
basePower = sHeatCrushPowerTable[i];
basePower = sHeatCrashPowerTable[i];
break;
case EFFECT_PUNISHMENT:
basePower = 60 + (CountBattlerStatIncreases(battlerDef, FALSE) * 20);
@ -7613,6 +7775,15 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
}
// move-specific base power changes
switch (move)
{
case MOVE_WATER_SHURIKEN:
if (gBattleMons[battlerAtk].species == SPECIES_GRENINJA_ASH)
basePower = 20;
break;
}
if (basePower == 0)
basePower = 1;
return basePower;
@ -7876,7 +8047,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)
MulModifier(&modifier, UQ_4_12(2.0));
break;
case EFFECT_RETALITATE:
case EFFECT_RETALIATE:
// todo
break;
case EFFECT_SOLARBEAM:
@ -8254,6 +8425,7 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
u32 abilityDef = GetBattlerAbility(battlerDef);
u32 defSide = GET_BATTLER_SIDE(battlerDef);
u16 finalModifier = UQ_4_12(1.0);
u16 itemDef = gBattleMons[battlerDef].item;
// check multiple targets in double battle
if (GetMoveTargetCount(move, battlerAtk, battlerDef) >= 2)
@ -8383,7 +8555,8 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
// berries reducing dmg
case HOLD_EFFECT_RESIST_BERRY:
if (moveType == GetBattlerHoldEffectParam(battlerDef)
&& (moveType == TYPE_NORMAL || typeEffectivenessModifier >= UQ_4_12(2.0)))
&& (moveType == TYPE_NORMAL || typeEffectivenessModifier >= UQ_4_12(2.0))
&& !UnnerveOn(battlerDef, itemDef))
{
if (abilityDef == ABILITY_RIPEN)
MulModifier(&finalModifier, UQ_4_12(0.25));
@ -8481,6 +8654,13 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt
if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT)
mod = UQ_4_12(1.0);
// WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS)
{
if (defType == TYPE_FLYING && mod >= UQ_4_12(2.0))
mod = UQ_4_12(1.0);
}
MulModifier(modifier, mod);
}
@ -8784,6 +8964,9 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
{SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET},
{SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW},
{SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI},
{SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT},
{SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT},
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND},
};
if (isSwitchingOut) // Don't revert Mimikyu Busted when switching out
@ -9369,6 +9552,20 @@ void DoBurmyFormChange(u32 monId)
}
}
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef)
{
#if B_PRANKSTER_DARK_TYPES >= GEN_7
if (gProtectStructs[battlerPrankster].pranksterElevated
&& GetBattlerSide(battlerPrankster) != GetBattlerSide(battlerDef)
&& !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)) // Don't block hazards, assist-type moves
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) // Only Dark-types can block Prankster'd
&& !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE))
return TRUE;
else
#endif
return FALSE;
}
// Move Checks
bool8 IsTwoStrikesMove(u16 move)
{

View File

@ -2599,11 +2599,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
#if B_UPDATED_MOVE_DATA >= GEN_4
.accuracy = 0,
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
.effect = EFFECT_RECOIL_HP_25,
#else
.accuracy = 100,
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
.effect = EFFECT_RECOIL_25,
#endif
.effect = EFFECT_RECOIL_25,
.power = 50,
.type = TYPE_NORMAL,
.pp = 1,
@ -3424,6 +3425,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_HEAL_BELL] =
{
#if B_UPDATED_MOVE_DATA != GEN_5
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
#else
.flags = FLAG_SNATCH_AFFECTED,
#endif
.effect = EFFECT_HEAL_BELL,
.power = 0,
.type = TYPE_NORMAL,
@ -3432,7 +3438,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.priority = 0,
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
.split = SPLIT_STATUS,
},
@ -5338,6 +5343,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_HOWL] =
{
#if B_UPDATED_MOVE_DATA >= GEN_8
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
#else
.flags = FLAG_SNATCH_AFFECTED,
#endif
.effect = EFFECT_ATTACK_UP,
.power = 0,
.type = TYPE_NORMAL,
@ -5346,7 +5356,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.priority = 0,
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
.split = SPLIT_STATUS,
},
@ -8097,7 +8106,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_RETALIATE] =
{
.effect = EFFECT_RETALITATE,
.effect = EFFECT_RETALIATE,
.power = 70,
.type = TYPE_NORMAL,
.accuracy = 100,
@ -10226,7 +10235,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_PSYCHIC_FANGS] =
{
.effect = EFFECT_BRICK_BREAK,
.power = 75,
.power = 85,
.type = TYPE_PSYCHIC,
.accuracy = 100,
.pp = 15,

View File

@ -1312,11 +1312,14 @@ const u32 gUnknown_08D85A1C[] = INCBIN_U32("graphics/battle_frontier/battle_tile
#include "data/graphics/intro_scene.h"
const u32 gBattleAnimSpriteGfx_FlyingDirt[] = INCBIN_U32("graphics/battle_anims/sprites/flying_dirt.4bpp.lz");
const u32 gBattleAnimSpritePal_FlyingDirt[] = INCBIN_U32("graphics/battle_anims/sprites/flying_dirt.gbapal.lz");
const u32 gBattleAnimBgTilemap_Sandstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/sandstorm_brew.bin.lz");
const u32 gBattleAnimBgImage_Sandstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/sandstorm_brew.4bpp.lz");
const u32 gBattleAnimSpritePal_FlyingDirt[] = INCBIN_U32("graphics/battle_anims/sprites/flying_dirt.gbapal.lz");
const u32 gBattleAnimBgTilemap_Windstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/sandstorm_brew.bin.lz");
const u32 gBattleAnimBgImage_Windstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/windstorm_brew.4bpp.lz");
const u32 gBattleAnimSpritePal_Windstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/windstorm_brew.gbapal.lz");
const u32 gBattleAnimSpriteGfx_MetalSoundWaves[] = INCBIN_U32("graphics/battle_anims/sprites/metal_sound_waves.4bpp.lz");
const u32 gBattleAnimSpritePal_MetalSoundWaves[] = INCBIN_U32("graphics/battle_anims/sprites/metal_sound_waves.gbapal.lz");