Merge branch 'upcoming' into fix-stat-boost-on-hit

This commit is contained in:
BuffelSaft 2022-11-03 22:01:30 +13:00 committed by GitHub
commit c169a9523e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 1844 additions and 1165 deletions

View File

@ -1988,6 +1988,12 @@
various \battler, VARIOUS_GET_BATTLER_SIDE various \battler, VARIOUS_GET_BATTLER_SIDE
.endm .endm
.macro checkparentalbondcounter counter:req, ptr:req
various BS_ATTACKER, VARIOUS_CHECK_PARENTAL_BOND_COUNTER
.byte \counter
.4byte \ptr
.endm
@ helpful macros @ helpful macros
.macro setstatchanger stat:req, stages:req, down:req .macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7 setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7

View File

@ -2987,21 +2987,26 @@ Move_MUD_BOMB:
end end
Move_PSYCHO_CUT: Move_PSYCHO_CUT:
loadspritegfx ANIM_TAG_SPIRAL loadspritegfx ANIM_TAG_SPIRAL
loadspritegfx ANIM_TAG_PSYCHO_CUT loadspritegfx ANIM_TAG_PSYCHO_CUT
monbg ANIM_ATK_PARTNER loadspritegfx ANIM_TAG_CROSS_IMPACT
monbg ANIM_ATK_PARTNER
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_CROSS_IMPACT, 0, 9, 9, RGB_PURPLE
createvisualtask AnimTask_SwayMon, 5, 0, 6, 2048, 2, ANIM_ATTACKER
createsprite gPsychoCutSpiralSpriteTemplate, 2, 4, 0, 0, 0, 0 createsprite gPsychoCutSpiralSpriteTemplate, 2, 4, 0, 0, 0, 0
createvisualtask AnimTask_BlendBattleAnimPal, 1, 1, 2, 0, 4, RGB_BLACK createvisualtask AnimTask_BlendBattleAnimPal, 1, 1, 2, 0, 4, RGB_BLACK
createvisualtask AnimTask_BlendBattleAnimPal, 1, 2, 2, 0, 10, RGB(20, 12, 23) createvisualtask AnimTask_BlendBattleAnimPal, 1, 2, 2, 0, 10, RGB(20, 12, 23)
delay 30 delay 30
clearmonbg ANIM_ATK_PARTNER clearmonbg ANIM_ATK_PARTNER
waitforvisualfinish waitforvisualfinish
monbg ANIM_TARGET monbg ANIM_TARGET
splitbgprio ANIM_TARGET splitbgprio ANIM_TARGET
setalpha 12, 8 setalpha 12, 8
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER,
createsprite gPsychoCutSpriteTemplate, 130, 5, 20, 0, -8, 0, 20 createsprite gPsychoCutSpriteTemplate, ANIM_TARGET, 2, 20, 0, -8, 0, 20
waitforvisualfinish waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 7, 0, 9, 1
createsprite gCrossImpactSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 20
createvisualtask AnimTask_BlendBattleAnimPal, 1, 1, 2, 4, 0, RGB_BLACK createvisualtask AnimTask_BlendBattleAnimPal, 1, 1, 2, 4, 0, RGB_BLACK
createvisualtask AnimTask_BlendBattleAnimPal, 1, 2, 2, 10, 0, RGB(20, 12, 23) createvisualtask AnimTask_BlendBattleAnimPal, 1, 2, 2, 10, 0, RGB(20, 12, 23)
clearmonbg ANIM_TARGET clearmonbg ANIM_TARGET

View File

@ -51,7 +51,7 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectBide @ EFFECT_BIDE .4byte BattleScript_EffectBide @ EFFECT_BIDE
.4byte BattleScript_EffectRampage @ EFFECT_RAMPAGE .4byte BattleScript_EffectRampage @ EFFECT_RAMPAGE
.4byte BattleScript_EffectRoar @ EFFECT_ROAR .4byte BattleScript_EffectRoar @ EFFECT_ROAR
.4byte BattleScript_EffectMultiHit @ EFFECT_MULTI_HIT .4byte BattleScript_EffectHit @ EFFECT_MULTI_HIT
.4byte BattleScript_EffectConversion @ EFFECT_CONVERSION .4byte BattleScript_EffectConversion @ EFFECT_CONVERSION
.4byte BattleScript_EffectFlinchHit @ EFFECT_FLINCH_HIT .4byte BattleScript_EffectFlinchHit @ EFFECT_FLINCH_HIT
.4byte BattleScript_EffectRestoreHp @ EFFECT_RESTORE_HP .4byte BattleScript_EffectRestoreHp @ EFFECT_RESTORE_HP
@ -66,11 +66,10 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectDragonRage @ EFFECT_DRAGON_RAGE .4byte BattleScript_EffectDragonRage @ EFFECT_DRAGON_RAGE
.4byte BattleScript_EffectTrap @ EFFECT_TRAP .4byte BattleScript_EffectTrap @ EFFECT_TRAP
.4byte BattleScript_EffectHealBlock @ EFFECT_HEAL_BLOCK .4byte BattleScript_EffectHealBlock @ EFFECT_HEAL_BLOCK
.4byte BattleScript_EffectDoubleHit @ EFFECT_DOUBLE_HIT
.4byte BattleScript_EffectRecoilIfMiss @ EFFECT_RECOIL_IF_MISS .4byte BattleScript_EffectRecoilIfMiss @ EFFECT_RECOIL_IF_MISS
.4byte BattleScript_EffectMist @ EFFECT_MIST .4byte BattleScript_EffectMist @ EFFECT_MIST
.4byte BattleScript_EffectFocusEnergy @ EFFECT_FOCUS_ENERGY .4byte BattleScript_EffectFocusEnergy @ EFFECT_FOCUS_ENERGY
.4byte BattleScript_EffectRecoil25 @ EFFECT_RECOIL_25 .4byte BattleScript_EffectHit @ EFFECT_RECOIL_25
.4byte BattleScript_EffectConfuse @ EFFECT_CONFUSE .4byte BattleScript_EffectConfuse @ EFFECT_CONFUSE
.4byte BattleScript_EffectAttackUp2 @ EFFECT_ATTACK_UP_2 .4byte BattleScript_EffectAttackUp2 @ EFFECT_ATTACK_UP_2
.4byte BattleScript_EffectDefenseUp2 @ EFFECT_DEFENSE_UP_2 .4byte BattleScript_EffectDefenseUp2 @ EFFECT_DEFENSE_UP_2
@ -99,7 +98,6 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectHit @ EFFECT_EVASION_DOWN_HIT .4byte BattleScript_EffectHit @ EFFECT_EVASION_DOWN_HIT
.4byte BattleScript_EffectTwoTurnsAttack @ EFFECT_TWO_TURNS_ATTACK .4byte BattleScript_EffectTwoTurnsAttack @ EFFECT_TWO_TURNS_ATTACK
.4byte BattleScript_EffectConfuseHit @ EFFECT_CONFUSE_HIT .4byte BattleScript_EffectConfuseHit @ EFFECT_CONFUSE_HIT
.4byte BattleScript_EffectTwineedle @ EFFECT_TWINEEDLE
.4byte BattleScript_EffectHit @ EFFECT_VITAL_THROW .4byte BattleScript_EffectHit @ EFFECT_VITAL_THROW
.4byte BattleScript_EffectSubstitute @ EFFECT_SUBSTITUTE .4byte BattleScript_EffectSubstitute @ EFFECT_SUBSTITUTE
.4byte BattleScript_EffectRecharge @ EFFECT_RECHARGE .4byte BattleScript_EffectRecharge @ EFFECT_RECHARGE
@ -220,7 +218,7 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectSnatch @ EFFECT_SNATCH .4byte BattleScript_EffectSnatch @ EFFECT_SNATCH
.4byte BattleScript_EffectHit @ EFFECT_LOW_KICK .4byte BattleScript_EffectHit @ EFFECT_LOW_KICK
.4byte BattleScript_EffectSecretPower @ EFFECT_SECRET_POWER .4byte BattleScript_EffectSecretPower @ EFFECT_SECRET_POWER
.4byte BattleScript_EffectRecoil33 @ EFFECT_RECOIL_33 .4byte BattleScript_EffectHit @ EFFECT_RECOIL_33
.4byte BattleScript_EffectTeeterDance @ EFFECT_TEETER_DANCE .4byte BattleScript_EffectTeeterDance @ EFFECT_TEETER_DANCE
.4byte BattleScript_EffectHitEscape @ EFFECT_HIT_ESCAPE .4byte BattleScript_EffectHitEscape @ EFFECT_HIT_ESCAPE
.4byte BattleScript_EffectMudSport @ EFFECT_MUD_SPORT .4byte BattleScript_EffectMudSport @ EFFECT_MUD_SPORT
@ -309,9 +307,9 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectGrowth @ EFFECT_GROWTH .4byte BattleScript_EffectGrowth @ EFFECT_GROWTH
.4byte BattleScript_EffectCloseCombat @ EFFECT_CLOSE_COMBAT .4byte BattleScript_EffectCloseCombat @ EFFECT_CLOSE_COMBAT
.4byte BattleScript_EffectLastResort @ EFFECT_LAST_RESORT .4byte BattleScript_EffectLastResort @ EFFECT_LAST_RESORT
.4byte BattleScript_EffectRecoil33Status @ EFFECT_RECOIL_33_STATUS .4byte BattleScript_EffectHit @ EFFECT_RECOIL_33_STATUS
.4byte BattleScript_EffectFlinchStatus @ EFFECT_FLINCH_STATUS .4byte BattleScript_EffectFlinchStatus @ EFFECT_FLINCH_STATUS
.4byte BattleScript_EffectRecoil50 @ EFFECT_RECOIL_50 .4byte BattleScript_EffectHit @ EFFECT_RECOIL_50
.4byte BattleScript_EffectShellSmash @ EFFECT_SHELL_SMASH .4byte BattleScript_EffectShellSmash @ EFFECT_SHELL_SMASH
.4byte BattleScript_EffectShiftGear @ EFFECT_SHIFT_GEAR .4byte BattleScript_EffectShiftGear @ EFFECT_SHIFT_GEAR
.4byte BattleScript_EffectDefenseUp3 @ EFFECT_DEFENSE_UP_3 .4byte BattleScript_EffectDefenseUp3 @ EFFECT_DEFENSE_UP_3
@ -381,12 +379,10 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectHit @ EFFECT_DYNAMAX_DOUBLE_DMG .4byte BattleScript_EffectHit @ EFFECT_DYNAMAX_DOUBLE_DMG
.4byte BattleScript_EffectDecorate @ EFFECT_DECORATE .4byte BattleScript_EffectDecorate @ EFFECT_DECORATE
.4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT .4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT
.4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT
.4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25 .4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25
.4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS .4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS
.4byte BattleScript_EffectDefenseDownHit @ EFFECT_GRAV_APPLE .4byte BattleScript_EffectDefenseDownHit @ EFFECT_GRAV_APPLE
.4byte BattleScript_EffectEvasionUpHit @ EFFECT_EVASION_UP_HIT .4byte BattleScript_EffectEvasionUpHit @ EFFECT_EVASION_UP_HIT
.4byte BattleScript_EffectDoubleIronBash @ EFFECT_DOUBLE_IRON_BASH
.4byte BattleScript_EffectGlitzyGlow @ EFFECT_GLITZY_GLOW .4byte BattleScript_EffectGlitzyGlow @ EFFECT_GLITZY_GLOW
.4byte BattleScript_EffectBaddyBad @ EFFECT_BADDY_BAD .4byte BattleScript_EffectBaddyBad @ EFFECT_BADDY_BAD
.4byte BattleScript_EffectSappySeed @ EFFECT_SAPPY_SEED .4byte BattleScript_EffectSappySeed @ EFFECT_SAPPY_SEED
@ -1074,16 +1070,6 @@ BattleScript_EffectGlitzyGlow:
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_EffectDoubleIronBash:
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
setmultihitcounter 2
initmultihitstring
sethword sMULTIHIT_EFFECT, MOVE_EFFECT_FLINCH
goto BattleScript_MultiHitLoop
BattleScript_EffectEvasionUpHit: BattleScript_EffectEvasionUpHit:
setmoveeffect MOVE_EFFECT_EVS_PLUS_1 | MOVE_EFFECT_AFFECTS_USER setmoveeffect MOVE_EFFECT_EVS_PLUS_1 | MOVE_EFFECT_AFFECTS_USER
goto BattleScript_EffectHit goto BattleScript_EffectHit
@ -1286,28 +1272,17 @@ BattleScript_EffectBurnUp:
ppreduce ppreduce
jumpiftype BS_ATTACKER, TYPE_FIRE, BattleScript_BurnUpWorks jumpiftype BS_ATTACKER, TYPE_FIRE, BattleScript_BurnUpWorks
goto BattleScript_ButItFailed goto BattleScript_ButItFailed
BattleScript_BurnUpWorks: BattleScript_BurnUpWorks:
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE setmoveeffect MOVE_EFFECT_BURN_UP | MOVE_EFFECT_CERTAIN
critcalc goto BattleScript_EffectHit
damagecalc
adjustdamage BattleScript_BurnUpRemoveType::
attackanimation
waitanimation
effectivenesssound
hitanimation BS_TARGET
waitstate
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
critmessage
waitmessage B_WAIT_TIME_LONG
resultmessage
waitmessage B_WAIT_TIME_LONG
losetype BS_ATTACKER, TYPE_FIRE losetype BS_ATTACKER, TYPE_FIRE
printstring STRINGID_ATTACKERLOSTFIRETYPE printstring STRINGID_ATTACKERLOSTFIRETYPE
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
tryfaintmon BS_TARGET return
goto BattleScript_MoveEnd
BattleScript_EffectPurify: BattleScript_EffectPurify:
attackcanceler attackcanceler
attackstring attackstring
@ -3026,6 +3001,7 @@ BattleScript_EffectNaturalGift:
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
seteffectwithchance seteffectwithchance
jumpifmovehadnoeffect BattleScript_EffectNaturalGiftEnd jumpifmovehadnoeffect BattleScript_EffectNaturalGiftEnd
checkparentalbondcounter 2, BattleScript_EffectNaturalGiftEnd
removeitem BS_ATTACKER removeitem BS_ATTACKER
BattleScript_EffectNaturalGiftEnd: BattleScript_EffectNaturalGiftEnd:
tryfaintmon BS_TARGET tryfaintmon BS_TARGET
@ -3571,6 +3547,8 @@ BattleScript_MultiHitPrintStrings::
copyarray gBattleTextBuff1, sMULTIHIT_STRING, 6 copyarray gBattleTextBuff1, sMULTIHIT_STRING, 6
printstring STRINGID_HITXTIMES printstring STRINGID_HITXTIMES
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
return
BattleScript_MultiHitEnd:: BattleScript_MultiHitEnd::
seteffectwithchance seteffectwithchance
tryfaintmon BS_TARGET tryfaintmon BS_TARGET
@ -3789,26 +3767,6 @@ BattleScript_EffectTrap::
setmoveeffect MOVE_EFFECT_WRAP setmoveeffect MOVE_EFFECT_WRAP
goto BattleScript_EffectHit goto BattleScript_EffectHit
BattleScript_EffectTripleHit::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
setmultihitcounter 3
initmultihitstring
sethword sMULTIHIT_EFFECT, 0
goto BattleScript_MultiHitLoop
BattleScript_EffectDoubleHit::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
setmultihitcounter 2
initmultihitstring
sethword sMULTIHIT_EFFECT, 0
goto BattleScript_MultiHitLoop
BattleScript_EffectRecoilIfMiss:: BattleScript_EffectRecoilIfMiss::
attackcanceler attackcanceler
accuracycheck BattleScript_MoveMissedDoDamage, ACC_CURR_MOVE accuracycheck BattleScript_MoveMissedDoDamage, ACC_CURR_MOVE
@ -4165,16 +4123,6 @@ BattleScript_EffectConfuseHit::
setmoveeffect MOVE_EFFECT_CONFUSION setmoveeffect MOVE_EFFECT_CONFUSION
goto BattleScript_EffectHit goto BattleScript_EffectHit
BattleScript_EffectTwineedle::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
sethword sMULTIHIT_EFFECT, MOVE_EFFECT_POISON
attackstring
ppreduce
setmultihitcounter 2
initmultihitstring
goto BattleScript_MultiHitLoop
BattleScript_EffectSubstitute:: BattleScript_EffectSubstitute::
attackcanceler attackcanceler
ppreduce ppreduce
@ -4520,64 +4468,16 @@ BattleScript_PartyHealEnd::
BattleScript_EffectTripleKick:: BattleScript_EffectTripleKick::
attackcanceler attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring attackstring
ppreduce ppreduce
sethword sTRIPLE_KICK_POWER, 0 jumpifmove MOVE_TRIPLE_AXEL BS_TripleAxel
initmultihitstring addbyte sTRIPLE_KICK_POWER, 10 @ triple kick gets +10 power
setmultihit 3 goto BattleScript_HitFromAtkString
BattleScript_TripleKickLoop::
jumpifhasnohp BS_ATTACKER, BattleScript_TripleKickEnd BS_TripleAxel:
jumpifhasnohp BS_TARGET, BattleScript_TripleKickNoMoreHits addbyte sTRIPLE_KICK_POWER, 20 @ triple axel gets +20 power
jumpifhalfword CMP_EQUAL, gChosenMove, MOVE_SLEEP_TALK, BattleScript_DoTripleKickAttack goto BattleScript_HitFromAtkString
jumpifstatus BS_ATTACKER, STATUS1_SLEEP, BattleScript_TripleKickNoMoreHits
BattleScript_DoTripleKickAttack::
accuracycheck BattleScript_TripleKickNoMoreHits, ACC_CURR_MOVE
movevaluescleanup
jumpifmove MOVE_SURGING_STRIKES, EffectTripleKick_DoDmgCalcs @ no power boost each hit
jumpifmove MOVE_TRIPLE_AXEL, EffectTripleKick_TripleAxelBoost @ triple axel gets +20 power
addbyte sTRIPLE_KICK_POWER, 10 @ triple kick gets +10 power
goto EffectTripleKick_DoDmgCalcs
EffectTripleKick_TripleAxelBoost:
addbyte sTRIPLE_KICK_POWER, 20
EffectTripleKick_DoDmgCalcs:
addbyte sTRIPLE_KICK_POWER, 10
addbyte sMULTIHIT_STRING + 4, 1
critcalc
damagecalc
adjustdamage
jumpifmovehadnoeffect BattleScript_TripleKickNoMoreHits
attackanimation
waitanimation
effectivenesssound
hitanimation BS_TARGET
waitstate
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
critmessage
waitmessage B_WAIT_TIME_LONG
printstring STRINGID_EMPTYSTRING3
waitmessage 1
moveendto MOVEEND_NEXT_TARGET
jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_FOE_ENDURED, BattleScript_TripleKickPrintStrings
decrementmultihit BattleScript_TripleKickLoop
goto BattleScript_TripleKickPrintStrings
BattleScript_TripleKickNoMoreHits::
pause B_WAIT_TIME_SHORT
jumpifbyte CMP_EQUAL, sMULTIHIT_STRING + 4, 0, BattleScript_TripleKickPrintStrings
bichalfword gMoveResultFlags, MOVE_RESULT_MISSED
BattleScript_TripleKickPrintStrings::
resultmessage
waitmessage B_WAIT_TIME_LONG
jumpifbyte CMP_EQUAL, sMULTIHIT_STRING + 4, 0, BattleScript_TripleKickEnd
jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_TripleKickEnd
copyarray gBattleTextBuff1, sMULTIHIT_STRING, 6
printstring STRINGID_HITXTIMES
waitmessage B_WAIT_TIME_LONG
BattleScript_TripleKickEnd::
seteffectwithchance
tryfaintmon BS_TARGET
moveendfrom MOVEEND_UPDATE_LAST_MOVES
end
BattleScript_EffectThief:: BattleScript_EffectThief::
setmoveeffect MOVE_EFFECT_STEAL_ITEM setmoveeffect MOVE_EFFECT_STEAL_ITEM
@ -5217,6 +5117,7 @@ BattleScript_EffectTeleportNew:
BattleScript_EffectTeleportNewEnd: BattleScript_EffectTeleportNewEnd:
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
.if B_BEAT_UP < GEN_5
BattleScript_EffectBeatUp:: BattleScript_EffectBeatUp::
attackcanceler attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
@ -5249,6 +5150,13 @@ BattleScript_BeatUpAttack::
goto BattleScript_BeatUpLoop goto BattleScript_BeatUpLoop
BattleScript_BeatUpEnd:: BattleScript_BeatUpEnd::
end end
.else
BattleScript_EffectBeatUp::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
addbyte gBattleCommunication, 1
goto BattleScript_HitFromAtkString
.endif
BattleScript_EffectSemiInvulnerable:: BattleScript_EffectSemiInvulnerable::
jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_SecondTurnSemiInvulnerable jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_SecondTurnSemiInvulnerable
@ -5411,9 +5319,11 @@ BattleScript_EffectSpitUp::
stockpiletobasedamage BattleScript_SpitUpFail stockpiletobasedamage BattleScript_SpitUpFail
goto BattleScript_HitFromAtkAnimation goto BattleScript_HitFromAtkAnimation
BattleScript_SpitUpFail:: BattleScript_SpitUpFail::
checkparentalbondcounter 2, BattleScript_SpitUpEnd
pause B_WAIT_TIME_SHORT pause B_WAIT_TIME_SHORT
printstring STRINGID_FAILEDTOSPITUP printstring STRINGID_FAILEDTOSPITUP
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
BattleScript_SpitUpEnd:
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_SpitUpFailProtect:: BattleScript_SpitUpFailProtect::
@ -5898,24 +5808,6 @@ BattleScript_EffectSecretPower::
getsecretpowereffect getsecretpowereffect
goto BattleScript_EffectHit goto BattleScript_EffectHit
BattleScript_EffectRecoil25:
setmoveeffect MOVE_EFFECT_RECOIL_25 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
jumpifnotmove MOVE_STRUGGLE, BattleScript_EffectHit
incrementgamestat GAME_STAT_USED_STRUGGLE
goto BattleScript_EffectHit
BattleScript_EffectRecoil33::
setmoveeffect MOVE_EFFECT_RECOIL_33 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
goto BattleScript_EffectHit
BattleScript_EffectRecoil33Status:
setmoveeffect MOVE_EFFECT_RECOIL_33_STATUS | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
goto BattleScript_EffectHit
BattleScript_EffectRecoil50:
setmoveeffect MOVE_EFFECT_RECOIL_50 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
goto BattleScript_EffectHit
BattleScript_EffectRecoilHP25: BattleScript_EffectRecoilHP25:
setmoveeffect MOVE_EFFECT_RECOIL_HP_25 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN setmoveeffect MOVE_EFFECT_RECOIL_HP_25 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
jumpifnotmove MOVE_STRUGGLE, BattleScript_EffectHit jumpifnotmove MOVE_STRUGGLE, BattleScript_EffectHit
@ -8045,7 +7937,6 @@ BattleScript_MoveEffectConfusion::
BattleScript_MoveEffectRecoilWithStatus:: BattleScript_MoveEffectRecoilWithStatus::
argumentstatuseffect argumentstatuseffect
copyword gBattleMoveDamage, sSAVED_DMG
BattleScript_MoveEffectRecoil:: BattleScript_MoveEffectRecoil::
jumpifmove MOVE_STRUGGLE, BattleScript_DoRecoil jumpifmove MOVE_STRUGGLE, BattleScript_DoRecoil
jumpifability BS_ATTACKER, ABILITY_ROCK_HEAD, BattleScript_RecoilEnd jumpifability BS_ATTACKER, ABILITY_ROCK_HEAD, BattleScript_RecoilEnd
@ -9126,6 +9017,7 @@ BattleScript_BerryCureSlpRet::
BattleScript_GemActivates:: BattleScript_GemActivates::
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
waitanimation waitanimation
setlastuseditem BS_ATTACKER
printstring STRINGID_GEMACTIVATES printstring STRINGID_GEMACTIVATES
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
removeitem BS_ATTACKER removeitem BS_ATTACKER
@ -9134,6 +9026,7 @@ BattleScript_GemActivates::
BattleScript_BerryReduceDmg:: BattleScript_BerryReduceDmg::
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT
waitanimation waitanimation
setlastuseditem BS_TARGET
printstring STRINGID_TARGETATEITEM printstring STRINGID_TARGETATEITEM
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
removeitem BS_TARGET removeitem BS_TARGET

View File

@ -30,6 +30,7 @@
#include "constants/frontier_util.h" #include "constants/frontier_util.h"
#include "constants/game_stat.h" #include "constants/game_stat.h"
#include "constants/item.h" #include "constants/item.h"
#include "constants/item_config.h"
#include "constants/items.h" #include "constants/items.h"
#include "constants/heal_locations.h" #include "constants/heal_locations.h"
#include "constants/layouts.h" #include "constants/layouts.h"

View File

@ -1,6 +1,115 @@
EventScript_RepelWoreOff:: EventScript_RepelWoreOff::
.if I_REPEL_LURE_MENU == TRUE
checkitem ITEM_REPEL, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_RepelUseAnother
checkitem ITEM_SUPER_REPEL, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_RepelUseAnother
checkitem ITEM_MAX_REPEL, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_RepelUseAnother
.else
checkitem VAR_LAST_REPEL_LURE_USED, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_RepelUseAnother
.endif
lock
msgbox Text_RepelWoreOff, MSGBOX_SIGN msgbox Text_RepelWoreOff, MSGBOX_SIGN
release
end
EventScript_RepelUseAnother:
lock
msgbox Text_UseAnotherRepel, MSGBOX_YESNO
.if I_REPEL_LURE_MENU == TRUE
callnative TryDrawRepelMenu
goto_if_eq VAR_RESULT, FALSE, EventScript_RepelWoreOff_Chose
waitstate
goto_if_eq VAR_RESULT, 127, EventScript_RepelWoreOff_End
EventScript_RepelWoreOff_Chose:
callnative HandleRepelMenuChoice
bufferitemname 1, VAR_0x8004
removeitem VAR_0x8004, 1
playse SE_REPEL
msgbox Text_UsedNewRepelLure, MSGBOX_SIGN
.else
goto_if_eq VAR_RESULT, YES, EventScript_UsedRepel
.endif
EventScript_RepelWoreOff_End:
release
end
EventScript_UsedRepel:
bufferitemname 1, VAR_LAST_REPEL_LURE_USED
playse SE_REPEL
lock
msgbox Text_UsedNewRepelLure, MSGBOX_SIGN
removeitem VAR_LAST_REPEL_LURE_USED, 1
waitse
callnative HandleUseExpiredRepel
release
end
EventScript_LureWoreOff::
.if I_REPEL_LURE_MENU == TRUE
checkitem ITEM_LURE, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_LureUseAnother
checkitem ITEM_SUPER_LURE, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_LureUseAnother
checkitem ITEM_MAX_LURE, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_LureUseAnother
.else
checkitem VAR_LAST_REPEL_LURE_USED, 1
goto_if_eq VAR_RESULT, TRUE, EventScript_LureUseAnother
.endif
lock
msgbox Text_LureWoreOff, MSGBOX_SIGN
release
end
EventScript_LureUseAnother:
lock
msgbox Text_UseAnotherLure, MSGBOX_YESNO
.if I_REPEL_LURE_MENU == TRUE
callnative TryDrawLureMenu
goto_if_eq VAR_RESULT, FALSE, EventScript_LureWoreOff_Chose
waitstate
goto_if_eq VAR_RESULT, 127, EventScript_LureWoreOff_End
EventScript_LureWoreOff_Chose:
callnative HandleLureMenuChoice
bufferitemname 1, VAR_0x8004
removeitem VAR_0x8004, 1
playse SE_REPEL
msgbox Text_UsedNewRepelLure, MSGBOX_SIGN
.else
goto_if_eq VAR_RESULT, YES, EventScript_UsedLure
.endif
EventScript_LureWoreOff_End:
release
end
EventScript_UsedLure:
bufferitemname 1, VAR_LAST_REPEL_LURE_USED
playse SE_REPEL
lock
msgbox Text_UsedNewRepelLure, MSGBOX_SIGN
removeitem VAR_LAST_REPEL_LURE_USED, 1
waitse
callnative HandleUseExpiredLure
release
end end
Text_RepelWoreOff: Text_RepelWoreOff:
.string "REPEL's effect wore off…$" .string "REPEL's effect wore off…$"
Text_UseAnotherRepel::
.string "REPEL's effect wore off!\n"
.string "Use another?$"
Text_LureWoreOff:
.string "Lure's effect wore off…$"
Text_UseAnotherLure::
.string "Lure's effect wore off!\n"
.string "Use another?$"
Text_UsedNewRepelLure::
.string "{PLAYER} used the\n"
.string "{STR_VAR_2}.$"

View File

@ -163,15 +163,20 @@ struct SpecialStatus
u8 ppNotAffectedByPressure:1; u8 ppNotAffectedByPressure:1;
u8 faintedHasReplacement:1; u8 faintedHasReplacement:1;
u8 focusBanded:1; u8 focusBanded:1;
// End of byte
u8 focusSashed:1; u8 focusSashed:1;
u8 sturdied:1; u8 sturdied:1;
u8 stormDrainRedirected:1; u8 stormDrainRedirected:1;
u8 switchInAbilityDone:1; u8 switchInAbilityDone:1;
u8 switchInItemDone:1; u8 switchInItemDone:1;
u8 instructedChosenTarget:3; u8 instructedChosenTarget:3;
// End of byte
u8 berryReduced:1; u8 berryReduced:1;
u8 gemBoost:1; u8 gemBoost:1;
u8 rototillerAffected:1; // to be affected by rototiller u8 rototillerAffected:1; // to be affected by rototiller
u8 parentalBondState:2;
u8 multiHitOn:1;
// End of byte, two bits unused
u8 gemParam; u8 gemParam;
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute. u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
u8 dancerUsedMove:1; u8 dancerUsedMove:1;

View File

@ -429,6 +429,8 @@ extern const u8 BattleScript_DefDownSpeedUp[];
extern const u8 BattleScript_AffectionBasedStatusHeal[]; extern const u8 BattleScript_AffectionBasedStatusHeal[];
extern const u8 BattleScript_AffectionBasedEndurance[]; extern const u8 BattleScript_AffectionBasedEndurance[];
extern const u8 BattleScript_SymbiosisActivates[]; extern const u8 BattleScript_SymbiosisActivates[];
extern const u8 BattleScript_MultiHitPrintStrings[];
extern const u8 BattleScript_BurnUpRemoveType[];
extern const u8 BattleScript_TargetAbilityStatRaiseRet[]; extern const u8 BattleScript_TargetAbilityStatRaiseRet[];
// zmoves // zmoves

View File

@ -186,6 +186,7 @@ void TryToRevertMimicry(void);
void RestoreBattlerOriginalTypes(u8 battlerId); void RestoreBattlerOriginalTypes(u8 battlerId);
u32 GetBattlerMoveTargetType(u8 battlerId, u16 move); u32 GetBattlerMoveTargetType(u8 battlerId, u16 move);
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move); bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move);
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId);
// Ability checks // Ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability); bool32 IsRolePlayBannedAbilityAtk(u16 ability);
bool32 IsRolePlayBannedAbility(u16 ability); bool32 IsRolePlayBannedAbility(u16 ability);

View File

@ -307,7 +307,7 @@
#define MOVE_EFFECT_PAYDAY 0xB #define MOVE_EFFECT_PAYDAY 0xB
#define MOVE_EFFECT_CHARGING 0xC #define MOVE_EFFECT_CHARGING 0xC
#define MOVE_EFFECT_WRAP 0xD #define MOVE_EFFECT_WRAP 0xD
#define MOVE_EFFECT_RECOIL_25 0xE #define MOVE_EFFECT_BURN_UP 0xE // MOVE_EFFECT_BURN_UP replaces unused MOVE_EFFECT_RECOIL_25 so that stat change animations don't break
#define MOVE_EFFECT_ATK_PLUS_1 0xF #define MOVE_EFFECT_ATK_PLUS_1 0xF
#define MOVE_EFFECT_DEF_PLUS_1 0x10 #define MOVE_EFFECT_DEF_PLUS_1 0x10
#define MOVE_EFFECT_SPD_PLUS_1 0x11 #define MOVE_EFFECT_SPD_PLUS_1 0x11
@ -331,7 +331,7 @@
#define MOVE_EFFECT_RAPIDSPIN 0x23 #define MOVE_EFFECT_RAPIDSPIN 0x23
#define MOVE_EFFECT_REMOVE_STATUS 0x24 #define MOVE_EFFECT_REMOVE_STATUS 0x24
#define MOVE_EFFECT_ATK_DEF_DOWN 0x25 #define MOVE_EFFECT_ATK_DEF_DOWN 0x25
#define MOVE_EFFECT_RECOIL_33 0x26 #define MOVE_EFFECT_SCALE_SHOT 0x26 // MOVE_EFFECT_SCALE_SHOT replaces unused MOVE_EFFECT_RECOIL_33 so that stat change animations don't break
#define MOVE_EFFECT_ATK_PLUS_2 0x27 #define MOVE_EFFECT_ATK_PLUS_2 0x27
#define MOVE_EFFECT_DEF_PLUS_2 0x28 #define MOVE_EFFECT_DEF_PLUS_2 0x28
#define MOVE_EFFECT_SPD_PLUS_2 0x29 #define MOVE_EFFECT_SPD_PLUS_2 0x29
@ -349,27 +349,23 @@
#define MOVE_EFFECT_THRASH 0x35 #define MOVE_EFFECT_THRASH 0x35
#define MOVE_EFFECT_KNOCK_OFF 0x36 #define MOVE_EFFECT_KNOCK_OFF 0x36
#define MOVE_EFFECT_DEF_SPDEF_DOWN 0x37 #define MOVE_EFFECT_DEF_SPDEF_DOWN 0x37
#define MOVE_EFFECT_RECOIL_33_STATUS 0x38 #define MOVE_EFFECT_CLEAR_SMOG 0x38
#define MOVE_EFFECT_RECOIL_50 0x39 #define MOVE_EFFECT_SP_ATK_TWO_DOWN 0x39
#define MOVE_EFFECT_CLEAR_SMOG 0x3A #define MOVE_EFFECT_SMACK_DOWN 0x3A
#define MOVE_EFFECT_SP_ATK_TWO_DOWN 0x3B #define MOVE_EFFECT_FLAME_BURST 0x3B
#define MOVE_EFFECT_SMACK_DOWN 0x3C #define MOVE_EFFECT_FEINT 0x3C
#define MOVE_EFFECT_FLAME_BURST 0x3D #define MOVE_EFFECT_SPECTRAL_THIEF 0x3D
#define MOVE_EFFECT_FEINT 0x3E #define MOVE_EFFECT_V_CREATE 0x3E
#define MOVE_EFFECT_SPECTRAL_THIEF 0x3F #define MOVE_EFFECT_HAPPY_HOUR 0x3F
#define MOVE_EFFECT_V_CREATE 0x40 #define MOVE_EFFECT_CORE_ENFORCER 0x40
#define MOVE_EFFECT_HAPPY_HOUR 0x41 #define MOVE_EFFECT_THROAT_CHOP 0x41
#define MOVE_EFFECT_CORE_ENFORCER 0x42 #define MOVE_EFFECT_INCINERATE 0x42
#define MOVE_EFFECT_THROAT_CHOP 0x43 #define MOVE_EFFECT_BUG_BITE 0x43
#define MOVE_EFFECT_INCINERATE 0x44 #define MOVE_EFFECT_RECOIL_HP_25 0x44
#define MOVE_EFFECT_BUG_BITE 0x45 #define MOVE_EFFECT_RELIC_SONG 0x45
#define MOVE_EFFECT_RECOIL_HP_25 0x46 #define MOVE_EFFECT_TRAP_BOTH 0x46
#define MOVE_EFFECT_RELIC_SONG 0x47
#define MOVE_EFFECT_TRAP_BOTH 0x48
#define MOVE_EFFECT_SKY_DROP 0x49
#define MOVE_EFFECT_SCALE_SHOT 0x4A
#define NUM_MOVE_EFFECTS 0x4B #define NUM_MOVE_EFFECTS 0x47
#define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000 #define MOVE_EFFECT_CERTAIN 0x8000
@ -483,4 +479,9 @@
// For the second argument of GetMoveTarget, when no target override is needed // For the second argument of GetMoveTarget, when no target override is needed
#define NO_TARGET_OVERRIDE 0 #define NO_TARGET_OVERRIDE 0
// Constants for Parental Bond
#define PARENTAL_BOND_1ST_HIT 2
#define PARENTAL_BOND_2ND_HIT 1
#define PARENTAL_BOND_OFF 0
#endif // GUARD_CONSTANTS_BATTLE_H #endif // GUARD_CONSTANTS_BATTLE_H

View File

@ -29,6 +29,7 @@
#define B_KNOCK_OFF_DMG GEN_LATEST // In Gen6+, Knock Off deals 50% more damage when knocking off an item. #define B_KNOCK_OFF_DMG GEN_LATEST // In Gen6+, Knock Off deals 50% more damage when knocking off an item.
#define B_SPORT_DMG_REDUCTION GEN_LATEST // In Gen5+, Water/Mud Sport reduce Fire/Electric Damage by 67% instead of 50%. #define B_SPORT_DMG_REDUCTION GEN_LATEST // In Gen5+, Water/Mud Sport reduce Fire/Electric Damage by 67% instead of 50%.
#define B_EXPLOSION_DEFENSE GEN_LATEST // In Gen5+, Self-Destruct and Explosion don't halve the targets' defense. #define B_EXPLOSION_DEFENSE GEN_LATEST // In Gen5+, Self-Destruct and Explosion don't halve the targets' defense.
#define B_PARENTAL_BOND_DMG GEN_LATEST // In Gen7+, Parental Bond's second hit does 25% of the initial hits damage. Before, it did 50%.
// Type settings // Type settings
#define B_GHOSTS_ESCAPE GEN_LATEST // 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_GHOSTS_ESCAPE GEN_LATEST // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle.
@ -89,6 +90,7 @@
#define B_ROOTED_GROUNDING GEN_LATEST // In Gen4+, Ingrain causes the affected Pokémon to become grounded. #define B_ROOTED_GROUNDING GEN_LATEST // In Gen4+, Ingrain causes the affected Pokémon to become grounded.
#define B_METRONOME_MOVES GEN_LATEST // This config will determine up to which generation will Metronome pull moves from. #define B_METRONOME_MOVES GEN_LATEST // This config will determine up to which generation will Metronome pull moves from.
#define B_TELEPORT_BEHAVIOR GEN_LATEST // In Gen7+, starting with Pokémon LGPE, Teleport allows the user to swap out with another party member. #define B_TELEPORT_BEHAVIOR GEN_LATEST // In Gen7+, starting with Pokémon LGPE, Teleport allows the user to swap out with another party member.
#define B_BEAT_UP GEN_LATEST // In Gen5+, Beat Up uses a different formula to calculate its damage, and deals Dark-type damage. Prior to Gen 5, each hit also announces the party member's name.
// Ability settings // Ability settings
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters. #define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.
@ -175,6 +177,7 @@
#define B_EVOLUTION_AFTER_WHITEOUT GEN_LATEST // In Gen6+, Pokemon that qualify for evolution after battle will evolve even if the player loses. #define B_EVOLUTION_AFTER_WHITEOUT GEN_LATEST // In Gen6+, Pokemon that qualify for evolution after battle will evolve even if the player loses.
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper) #define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)
#define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead. #define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_TRAINER_CLASS_POKE_BALLS GEN_LATEST // In Gen7+, trainers will use certain types of Poké Balls depending on their trainer class.
// Animation Settings // Animation Settings
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.

View File

@ -1,402 +1,398 @@
#ifndef GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H #ifndef GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
#define GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H #define GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
#define EFFECT_HIT 0 #define EFFECT_HIT 0
#define EFFECT_SLEEP 1 #define EFFECT_SLEEP 1
#define EFFECT_POISON_HIT 2 #define EFFECT_POISON_HIT 2
#define EFFECT_ABSORB 3 #define EFFECT_ABSORB 3
#define EFFECT_BURN_HIT 4 #define EFFECT_BURN_HIT 4
#define EFFECT_FREEZE_HIT 5 #define EFFECT_FREEZE_HIT 5
#define EFFECT_PARALYZE_HIT 6 #define EFFECT_PARALYZE_HIT 6
#define EFFECT_EXPLOSION 7 #define EFFECT_EXPLOSION 7
#define EFFECT_DREAM_EATER 8 #define EFFECT_DREAM_EATER 8
#define EFFECT_MIRROR_MOVE 9 #define EFFECT_MIRROR_MOVE 9
#define EFFECT_ATTACK_UP 10 #define EFFECT_ATTACK_UP 10
#define EFFECT_DEFENSE_UP 11 #define EFFECT_DEFENSE_UP 11
#define EFFECT_SPEED_UP 12 #define EFFECT_SPEED_UP 12
#define EFFECT_SPECIAL_ATTACK_UP 13 #define EFFECT_SPECIAL_ATTACK_UP 13
#define EFFECT_SPECIAL_DEFENSE_UP 14 #define EFFECT_SPECIAL_DEFENSE_UP 14
#define EFFECT_ACCURACY_UP 15 #define EFFECT_ACCURACY_UP 15
#define EFFECT_EVASION_UP 16 #define EFFECT_EVASION_UP 16
#define EFFECT_SPECIAL_ATTACK_UP_3 17 #define EFFECT_SPECIAL_ATTACK_UP_3 17
#define EFFECT_ATTACK_DOWN 18 #define EFFECT_ATTACK_DOWN 18
#define EFFECT_DEFENSE_DOWN 19 #define EFFECT_DEFENSE_DOWN 19
#define EFFECT_SPEED_DOWN 20 #define EFFECT_SPEED_DOWN 20
#define EFFECT_SPECIAL_ATTACK_DOWN 21 #define EFFECT_SPECIAL_ATTACK_DOWN 21
#define EFFECT_SPECIAL_DEFENSE_DOWN 22 #define EFFECT_SPECIAL_DEFENSE_DOWN 22
#define EFFECT_ACCURACY_DOWN 23 #define EFFECT_ACCURACY_DOWN 23
#define EFFECT_EVASION_DOWN 24 #define EFFECT_EVASION_DOWN 24
#define EFFECT_HAZE 25 #define EFFECT_HAZE 25
#define EFFECT_BIDE 26 #define EFFECT_BIDE 26
#define EFFECT_RAMPAGE 27 #define EFFECT_RAMPAGE 27
#define EFFECT_ROAR 28 #define EFFECT_ROAR 28
#define EFFECT_MULTI_HIT 29 #define EFFECT_MULTI_HIT 29
#define EFFECT_CONVERSION 30 #define EFFECT_CONVERSION 30
#define EFFECT_FLINCH_HIT 31 #define EFFECT_FLINCH_HIT 31
#define EFFECT_RESTORE_HP 32 #define EFFECT_RESTORE_HP 32
#define EFFECT_TOXIC 33 #define EFFECT_TOXIC 33
#define EFFECT_PAY_DAY 34 #define EFFECT_PAY_DAY 34
#define EFFECT_LIGHT_SCREEN 35 #define EFFECT_LIGHT_SCREEN 35
#define EFFECT_TRI_ATTACK 36 #define EFFECT_TRI_ATTACK 36
#define EFFECT_REST 37 #define EFFECT_REST 37
#define EFFECT_OHKO 38 #define EFFECT_OHKO 38
#define EFFECT_FUSION_COMBO 39 #define EFFECT_FUSION_COMBO 39
#define EFFECT_SUPER_FANG 40 #define EFFECT_SUPER_FANG 40
#define EFFECT_DRAGON_RAGE 41 #define EFFECT_DRAGON_RAGE 41
#define EFFECT_TRAP 42 #define EFFECT_TRAP 42
#define EFFECT_HEAL_BLOCK 43 #define EFFECT_HEAL_BLOCK 43
#define EFFECT_DOUBLE_HIT 44 #define EFFECT_RECOIL_IF_MISS 44
#define EFFECT_RECOIL_IF_MISS 45 #define EFFECT_MIST 45
#define EFFECT_MIST 46 #define EFFECT_FOCUS_ENERGY 46
#define EFFECT_FOCUS_ENERGY 47 #define EFFECT_RECOIL_25 47
#define EFFECT_RECOIL_25 48 #define EFFECT_CONFUSE 48
#define EFFECT_CONFUSE 49 #define EFFECT_ATTACK_UP_2 49
#define EFFECT_ATTACK_UP_2 50 #define EFFECT_DEFENSE_UP_2 50
#define EFFECT_DEFENSE_UP_2 51 #define EFFECT_SPEED_UP_2 51
#define EFFECT_SPEED_UP_2 52 #define EFFECT_SPECIAL_ATTACK_UP_2 52
#define EFFECT_SPECIAL_ATTACK_UP_2 53 #define EFFECT_SPECIAL_DEFENSE_UP_2 53
#define EFFECT_SPECIAL_DEFENSE_UP_2 54 #define EFFECT_ACCURACY_UP_2 54
#define EFFECT_ACCURACY_UP_2 55 #define EFFECT_EVASION_UP_2 55
#define EFFECT_EVASION_UP_2 56 #define EFFECT_TRANSFORM 56
#define EFFECT_TRANSFORM 57 #define EFFECT_ATTACK_DOWN_2 57
#define EFFECT_ATTACK_DOWN_2 58 #define EFFECT_DEFENSE_DOWN_2 58
#define EFFECT_DEFENSE_DOWN_2 59 #define EFFECT_SPEED_DOWN_2 59
#define EFFECT_SPEED_DOWN_2 60 #define EFFECT_SPECIAL_ATTACK_DOWN_2 60
#define EFFECT_SPECIAL_ATTACK_DOWN_2 61 #define EFFECT_SPECIAL_DEFENSE_DOWN_2 61
#define EFFECT_SPECIAL_DEFENSE_DOWN_2 62 #define EFFECT_ACCURACY_DOWN_2 62
#define EFFECT_ACCURACY_DOWN_2 63 #define EFFECT_EVASION_DOWN_2 63
#define EFFECT_EVASION_DOWN_2 64 #define EFFECT_REFLECT 64
#define EFFECT_REFLECT 65 #define EFFECT_POISON 65
#define EFFECT_POISON 66 #define EFFECT_PARALYZE 66
#define EFFECT_PARALYZE 67 #define EFFECT_ATTACK_DOWN_HIT 67
#define EFFECT_ATTACK_DOWN_HIT 68 #define EFFECT_DEFENSE_DOWN_HIT 68
#define EFFECT_DEFENSE_DOWN_HIT 69 #define EFFECT_SPEED_DOWN_HIT 69
#define EFFECT_SPEED_DOWN_HIT 70 #define EFFECT_SPECIAL_ATTACK_DOWN_HIT 70
#define EFFECT_SPECIAL_ATTACK_DOWN_HIT 71 #define EFFECT_SPECIAL_DEFENSE_DOWN_HIT 71
#define EFFECT_SPECIAL_DEFENSE_DOWN_HIT 72 #define EFFECT_ACCURACY_DOWN_HIT 72
#define EFFECT_ACCURACY_DOWN_HIT 73 #define EFFECT_EVASION_DOWN_HIT 73
#define EFFECT_EVASION_DOWN_HIT 74 #define EFFECT_TWO_TURNS_ATTACK 74
#define EFFECT_TWO_TURNS_ATTACK 75 #define EFFECT_CONFUSE_HIT 75
#define EFFECT_CONFUSE_HIT 76 #define EFFECT_VITAL_THROW 76
#define EFFECT_TWINEEDLE 77 #define EFFECT_SUBSTITUTE 77
#define EFFECT_VITAL_THROW 78 #define EFFECT_RECHARGE 78
#define EFFECT_SUBSTITUTE 79 #define EFFECT_RAGE 79
#define EFFECT_RECHARGE 80 #define EFFECT_MIMIC 80
#define EFFECT_RAGE 81 #define EFFECT_METRONOME 81
#define EFFECT_MIMIC 82 #define EFFECT_LEECH_SEED 82
#define EFFECT_METRONOME 83 #define EFFECT_DO_NOTHING 83
#define EFFECT_LEECH_SEED 84 #define EFFECT_DISABLE 84
#define EFFECT_DO_NOTHING 85 #define EFFECT_LEVEL_DAMAGE 85
#define EFFECT_DISABLE 86 #define EFFECT_PSYWAVE 86
#define EFFECT_LEVEL_DAMAGE 87 #define EFFECT_COUNTER 87
#define EFFECT_PSYWAVE 88 #define EFFECT_ENCORE 88
#define EFFECT_COUNTER 89 #define EFFECT_PAIN_SPLIT 89
#define EFFECT_ENCORE 90 #define EFFECT_SNORE 90
#define EFFECT_PAIN_SPLIT 91 #define EFFECT_CONVERSION_2 91
#define EFFECT_SNORE 92 #define EFFECT_LOCK_ON 92
#define EFFECT_CONVERSION_2 93 #define EFFECT_SKETCH 93
#define EFFECT_LOCK_ON 94 #define EFFECT_HAMMER_ARM 94
#define EFFECT_SKETCH 95 #define EFFECT_SLEEP_TALK 95
#define EFFECT_HAMMER_ARM 96 #define EFFECT_DESTINY_BOND 96
#define EFFECT_SLEEP_TALK 97 #define EFFECT_FLAIL 97
#define EFFECT_DESTINY_BOND 98 #define EFFECT_SPITE 98
#define EFFECT_FLAIL 99 #define EFFECT_FALSE_SWIPE 99
#define EFFECT_SPITE 100 #define EFFECT_HEAL_BELL 100
#define EFFECT_FALSE_SWIPE 101 #define EFFECT_ALWAYS_CRIT 101
#define EFFECT_HEAL_BELL 102 #define EFFECT_TRIPLE_KICK 102
#define EFFECT_ALWAYS_CRIT 103 #define EFFECT_THIEF 103
#define EFFECT_TRIPLE_KICK 104 #define EFFECT_MEAN_LOOK 104
#define EFFECT_THIEF 105 #define EFFECT_NIGHTMARE 105
#define EFFECT_MEAN_LOOK 106 #define EFFECT_MINIMIZE 106
#define EFFECT_NIGHTMARE 107 #define EFFECT_CURSE 107
#define EFFECT_MINIMIZE 108 #define EFFECT_HEALING_WISH 108
#define EFFECT_CURSE 109 #define EFFECT_PROTECT 109
#define EFFECT_HEALING_WISH 110 #define EFFECT_SPIKES 110
#define EFFECT_PROTECT 111 #define EFFECT_FORESIGHT 111
#define EFFECT_SPIKES 112 #define EFFECT_PERISH_SONG 112
#define EFFECT_FORESIGHT 113 #define EFFECT_SANDSTORM 113
#define EFFECT_PERISH_SONG 114 #define EFFECT_ENDURE 114
#define EFFECT_SANDSTORM 115 #define EFFECT_ROLLOUT 115
#define EFFECT_ENDURE 116 #define EFFECT_SWAGGER 116
#define EFFECT_ROLLOUT 117 #define EFFECT_FURY_CUTTER 117
#define EFFECT_SWAGGER 118 #define EFFECT_ATTRACT 118
#define EFFECT_FURY_CUTTER 119 #define EFFECT_RETURN 119
#define EFFECT_ATTRACT 120 #define EFFECT_PRESENT 120
#define EFFECT_RETURN 121 #define EFFECT_FRUSTRATION 121
#define EFFECT_PRESENT 122 #define EFFECT_SAFEGUARD 122
#define EFFECT_FRUSTRATION 123 #define EFFECT_UNUSED_125 123
#define EFFECT_SAFEGUARD 124 #define EFFECT_MAGNITUDE 124
#define EFFECT_UNUSED_125 125 #define EFFECT_BATON_PASS 125
#define EFFECT_MAGNITUDE 126 #define EFFECT_PURSUIT 126
#define EFFECT_BATON_PASS 127 #define EFFECT_RAPID_SPIN 127
#define EFFECT_PURSUIT 128 #define EFFECT_SONICBOOM 128
#define EFFECT_RAPID_SPIN 129 #define EFFECT_CAPTIVATE 129
#define EFFECT_SONICBOOM 130 #define EFFECT_MORNING_SUN 130
#define EFFECT_CAPTIVATE 131 #define EFFECT_SYNTHESIS 131
#define EFFECT_MORNING_SUN 132 #define EFFECT_MOONLIGHT 132
#define EFFECT_SYNTHESIS 133 #define EFFECT_HIDDEN_POWER 133
#define EFFECT_MOONLIGHT 134 #define EFFECT_RAIN_DANCE 134
#define EFFECT_HIDDEN_POWER 135 #define EFFECT_SUNNY_DAY 135
#define EFFECT_RAIN_DANCE 136 #define EFFECT_DEFENSE_UP_HIT 136
#define EFFECT_SUNNY_DAY 137 #define EFFECT_ATTACK_UP_HIT 137
#define EFFECT_DEFENSE_UP_HIT 138 #define EFFECT_ALL_STATS_UP_HIT 138
#define EFFECT_ATTACK_UP_HIT 139 #define EFFECT_FELL_STINGER 139
#define EFFECT_ALL_STATS_UP_HIT 140 #define EFFECT_BELLY_DRUM 140
#define EFFECT_FELL_STINGER 141 #define EFFECT_PSYCH_UP 141
#define EFFECT_BELLY_DRUM 142 #define EFFECT_MIRROR_COAT 142
#define EFFECT_PSYCH_UP 143 #define EFFECT_SKULL_BASH 143
#define EFFECT_MIRROR_COAT 144 #define EFFECT_TWISTER 144
#define EFFECT_SKULL_BASH 145 #define EFFECT_EARTHQUAKE 145
#define EFFECT_TWISTER 146 #define EFFECT_FUTURE_SIGHT 146
#define EFFECT_EARTHQUAKE 147 #define EFFECT_GUST 147
#define EFFECT_FUTURE_SIGHT 148 #define EFFECT_FLINCH_MINIMIZE_HIT 148
#define EFFECT_GUST 149 #define EFFECT_SOLAR_BEAM 149
#define EFFECT_FLINCH_MINIMIZE_HIT 150 #define EFFECT_THUNDER 150
#define EFFECT_SOLAR_BEAM 151 #define EFFECT_TELEPORT 151
#define EFFECT_THUNDER 152 #define EFFECT_BEAT_UP 152
#define EFFECT_TELEPORT 153 #define EFFECT_SEMI_INVULNERABLE 153
#define EFFECT_BEAT_UP 154 #define EFFECT_DEFENSE_CURL 154
#define EFFECT_SEMI_INVULNERABLE 155 #define EFFECT_SOFTBOILED 155
#define EFFECT_DEFENSE_CURL 156 #define EFFECT_FAKE_OUT 156
#define EFFECT_SOFTBOILED 157 #define EFFECT_UPROAR 157
#define EFFECT_FAKE_OUT 158 #define EFFECT_STOCKPILE 158
#define EFFECT_UPROAR 159 #define EFFECT_SPIT_UP 159
#define EFFECT_STOCKPILE 160 #define EFFECT_SWALLOW 160
#define EFFECT_SPIT_UP 161 #define EFFECT_WORRY_SEED 161
#define EFFECT_SWALLOW 162 #define EFFECT_HAIL 162
#define EFFECT_WORRY_SEED 163 #define EFFECT_TORMENT 163
#define EFFECT_HAIL 164 #define EFFECT_FLATTER 164
#define EFFECT_TORMENT 165 #define EFFECT_WILL_O_WISP 165
#define EFFECT_FLATTER 166 #define EFFECT_MEMENTO 166
#define EFFECT_WILL_O_WISP 167 #define EFFECT_FACADE 167
#define EFFECT_MEMENTO 168 #define EFFECT_FOCUS_PUNCH 168
#define EFFECT_FACADE 169 #define EFFECT_SMELLINGSALT 169
#define EFFECT_FOCUS_PUNCH 170 #define EFFECT_FOLLOW_ME 170
#define EFFECT_SMELLINGSALT 171 #define EFFECT_NATURE_POWER 171
#define EFFECT_FOLLOW_ME 172 #define EFFECT_CHARGE 172
#define EFFECT_NATURE_POWER 173 #define EFFECT_TAUNT 173
#define EFFECT_CHARGE 174 #define EFFECT_HELPING_HAND 174
#define EFFECT_TAUNT 175 #define EFFECT_TRICK 175
#define EFFECT_HELPING_HAND 176 #define EFFECT_ROLE_PLAY 176
#define EFFECT_TRICK 177 #define EFFECT_WISH 177
#define EFFECT_ROLE_PLAY 178 #define EFFECT_ASSIST 178
#define EFFECT_WISH 179 #define EFFECT_INGRAIN 179
#define EFFECT_ASSIST 180 #define EFFECT_SUPERPOWER 180
#define EFFECT_INGRAIN 181 #define EFFECT_MAGIC_COAT 181
#define EFFECT_SUPERPOWER 182 #define EFFECT_RECYCLE 182
#define EFFECT_MAGIC_COAT 183 #define EFFECT_REVENGE 183
#define EFFECT_RECYCLE 184 #define EFFECT_BRICK_BREAK 184
#define EFFECT_REVENGE 185 #define EFFECT_YAWN 185
#define EFFECT_BRICK_BREAK 186 #define EFFECT_KNOCK_OFF 186
#define EFFECT_YAWN 187 #define EFFECT_ENDEAVOR 187
#define EFFECT_KNOCK_OFF 188 #define EFFECT_ERUPTION 188
#define EFFECT_ENDEAVOR 189 #define EFFECT_SKILL_SWAP 189
#define EFFECT_ERUPTION 190 #define EFFECT_IMPRISON 190
#define EFFECT_SKILL_SWAP 191 #define EFFECT_REFRESH 191
#define EFFECT_IMPRISON 192 #define EFFECT_GRUDGE 192
#define EFFECT_REFRESH 193 #define EFFECT_SNATCH 193
#define EFFECT_GRUDGE 194 #define EFFECT_LOW_KICK 194
#define EFFECT_SNATCH 195 #define EFFECT_SECRET_POWER 195
#define EFFECT_LOW_KICK 196 #define EFFECT_RECOIL_33 196
#define EFFECT_SECRET_POWER 197 #define EFFECT_TEETER_DANCE 197
#define EFFECT_RECOIL_33 198 #define EFFECT_HIT_ESCAPE 198
#define EFFECT_TEETER_DANCE 199 #define EFFECT_MUD_SPORT 199
#define EFFECT_HIT_ESCAPE 200 #define EFFECT_POISON_FANG 200
#define EFFECT_MUD_SPORT 201 #define EFFECT_WEATHER_BALL 201
#define EFFECT_POISON_FANG 202 #define EFFECT_OVERHEAT 202
#define EFFECT_WEATHER_BALL 203 #define EFFECT_TICKLE 203
#define EFFECT_OVERHEAT 204 #define EFFECT_COSMIC_POWER 204
#define EFFECT_TICKLE 205 #define EFFECT_SKY_UPPERCUT 205
#define EFFECT_COSMIC_POWER 206 #define EFFECT_BULK_UP 206
#define EFFECT_SKY_UPPERCUT 207 #define EFFECT_PLACEHOLDER 207
#define EFFECT_BULK_UP 208 #define EFFECT_WATER_SPORT 208
#define EFFECT_PLACEHOLDER 209 #define EFFECT_CALM_MIND 209
#define EFFECT_WATER_SPORT 210 #define EFFECT_DRAGON_DANCE 210
#define EFFECT_CALM_MIND 211 #define EFFECT_CAMOUFLAGE 211
#define EFFECT_DRAGON_DANCE 212
#define EFFECT_CAMOUFLAGE 213
// New move effects // New move effects
#define EFFECT_PLEDGE 214 #define EFFECT_PLEDGE 212
#define EFFECT_FLING 215 #define EFFECT_FLING 213
#define EFFECT_NATURAL_GIFT 216 #define EFFECT_NATURAL_GIFT 214
#define EFFECT_WAKE_UP_SLAP 217 #define EFFECT_WAKE_UP_SLAP 215
#define EFFECT_WRING_OUT 218 #define EFFECT_WRING_OUT 216
#define EFFECT_HEX 219 #define EFFECT_HEX 217
#define EFFECT_ASSURANCE 220 #define EFFECT_ASSURANCE 218
#define EFFECT_TRUMP_CARD 221 #define EFFECT_TRUMP_CARD 219
#define EFFECT_ACROBATICS 222 #define EFFECT_ACROBATICS 220
#define EFFECT_HEAT_CRASH 223 #define EFFECT_HEAT_CRASH 221
#define EFFECT_PUNISHMENT 224 #define EFFECT_PUNISHMENT 222
#define EFFECT_STORED_POWER 225 #define EFFECT_STORED_POWER 223
#define EFFECT_ELECTRO_BALL 226 #define EFFECT_ELECTRO_BALL 224
#define EFFECT_GYRO_BALL 227 #define EFFECT_GYRO_BALL 225
#define EFFECT_ECHOED_VOICE 228 #define EFFECT_ECHOED_VOICE 226
#define EFFECT_PAYBACK 229 #define EFFECT_PAYBACK 227
#define EFFECT_ROUND 230 #define EFFECT_ROUND 228
#define EFFECT_BRINE 231 #define EFFECT_BRINE 229
#define EFFECT_VENOSHOCK 232 #define EFFECT_VENOSHOCK 230
#define EFFECT_RETALIATE 233 #define EFFECT_RETALIATE 231
#define EFFECT_BULLDOZE 234 #define EFFECT_BULLDOZE 232
#define EFFECT_FOUL_PLAY 235 #define EFFECT_FOUL_PLAY 233
#define EFFECT_PSYSHOCK 236 #define EFFECT_PSYSHOCK 234
#define EFFECT_ROOST 237 #define EFFECT_ROOST 235
#define EFFECT_GRAVITY 238 #define EFFECT_GRAVITY 236
#define EFFECT_MIRACLE_EYE 239 #define EFFECT_MIRACLE_EYE 237
#define EFFECT_TAILWIND 240 #define EFFECT_TAILWIND 238
#define EFFECT_EMBARGO 241 #define EFFECT_EMBARGO 239
#define EFFECT_AQUA_RING 242 #define EFFECT_AQUA_RING 240
#define EFFECT_TRICK_ROOM 243 #define EFFECT_TRICK_ROOM 241
#define EFFECT_WONDER_ROOM 244 #define EFFECT_WONDER_ROOM 242
#define EFFECT_MAGIC_ROOM 245 #define EFFECT_MAGIC_ROOM 243
#define EFFECT_MAGNET_RISE 246 #define EFFECT_MAGNET_RISE 244
#define EFFECT_TOXIC_SPIKES 247 #define EFFECT_TOXIC_SPIKES 245
#define EFFECT_GASTRO_ACID 248 #define EFFECT_GASTRO_ACID 246
#define EFFECT_STEALTH_ROCK 249 #define EFFECT_STEALTH_ROCK 247
#define EFFECT_TELEKINESIS 250 #define EFFECT_TELEKINESIS 248
#define EFFECT_POWER_SWAP 251 #define EFFECT_POWER_SWAP 249
#define EFFECT_GUARD_SWAP 252 #define EFFECT_GUARD_SWAP 250
#define EFFECT_HEART_SWAP 253 #define EFFECT_HEART_SWAP 251
#define EFFECT_POWER_SPLIT 254 #define EFFECT_POWER_SPLIT 252
#define EFFECT_GUARD_SPLIT 255 #define EFFECT_GUARD_SPLIT 253
#define EFFECT_STICKY_WEB 256 #define EFFECT_STICKY_WEB 254
#define EFFECT_METAL_BURST 257 #define EFFECT_METAL_BURST 255
#define EFFECT_LUCKY_CHANT 258 #define EFFECT_LUCKY_CHANT 256
#define EFFECT_SUCKER_PUNCH 259 #define EFFECT_SUCKER_PUNCH 257
#define EFFECT_SPECIAL_DEFENSE_DOWN_HIT_2 260 #define EFFECT_SPECIAL_DEFENSE_DOWN_HIT_2 258
#define EFFECT_SIMPLE_BEAM 261 #define EFFECT_SIMPLE_BEAM 259
#define EFFECT_ENTRAINMENT 262 #define EFFECT_ENTRAINMENT 260
#define EFFECT_HEAL_PULSE 263 #define EFFECT_HEAL_PULSE 261
#define EFFECT_QUASH 264 #define EFFECT_QUASH 262
#define EFFECT_ION_DELUGE 265 #define EFFECT_ION_DELUGE 263
#define EFFECT_FREEZE_DRY 266 #define EFFECT_FREEZE_DRY 264
#define EFFECT_TOPSY_TURVY 267 #define EFFECT_TOPSY_TURVY 265
#define EFFECT_MISTY_TERRAIN 268 #define EFFECT_MISTY_TERRAIN 266
#define EFFECT_GRASSY_TERRAIN 269 #define EFFECT_GRASSY_TERRAIN 267
#define EFFECT_ELECTRIC_TERRAIN 270 #define EFFECT_ELECTRIC_TERRAIN 268
#define EFFECT_PSYCHIC_TERRAIN 271 #define EFFECT_PSYCHIC_TERRAIN 269
#define EFFECT_ATTACK_ACCURACY_UP 272 #define EFFECT_ATTACK_ACCURACY_UP 270
#define EFFECT_ATTACK_SPATK_UP 273 #define EFFECT_ATTACK_SPATK_UP 271
#define EFFECT_HURRICANE 274 #define EFFECT_HURRICANE 272
#define EFFECT_TWO_TYPED_MOVE 275 #define EFFECT_TWO_TYPED_MOVE 273
#define EFFECT_ME_FIRST 276 #define EFFECT_ME_FIRST 274
#define EFFECT_SPEED_UP_HIT 277 #define EFFECT_SPEED_UP_HIT 275
#define EFFECT_QUIVER_DANCE 278 #define EFFECT_QUIVER_DANCE 276
#define EFFECT_COIL 279 #define EFFECT_COIL 277
#define EFFECT_ELECTRIFY 280 #define EFFECT_ELECTRIFY 278
#define EFFECT_SCALD 281 #define EFFECT_SCALD 279
#define EFFECT_REFLECT_TYPE 282 #define EFFECT_REFLECT_TYPE 280
#define EFFECT_SOAK 283 #define EFFECT_SOAK 281
#define EFFECT_GROWTH 284 #define EFFECT_GROWTH 282
#define EFFECT_CLOSE_COMBAT 285 #define EFFECT_CLOSE_COMBAT 283
#define EFFECT_LAST_RESORT 286 #define EFFECT_LAST_RESORT 284
#define EFFECT_RECOIL_33_STATUS 287 #define EFFECT_RECOIL_33_STATUS 285
#define EFFECT_FLINCH_STATUS 288 #define EFFECT_FLINCH_STATUS 286
#define EFFECT_RECOIL_50 289 #define EFFECT_RECOIL_50 287
#define EFFECT_SHELL_SMASH 290 #define EFFECT_SHELL_SMASH 288
#define EFFECT_SHIFT_GEAR 291 #define EFFECT_SHIFT_GEAR 289
#define EFFECT_DEFENSE_UP_3 292 #define EFFECT_DEFENSE_UP_3 290
#define EFFECT_NOBLE_ROAR 293 #define EFFECT_NOBLE_ROAR 291
#define EFFECT_VENOM_DRENCH 294 #define EFFECT_VENOM_DRENCH 292
#define EFFECT_TOXIC_THREAD 295 #define EFFECT_TOXIC_THREAD 293
#define EFFECT_CLEAR_SMOG 296 #define EFFECT_CLEAR_SMOG 294
#define EFFECT_HIT_SWITCH_TARGET 297 #define EFFECT_HIT_SWITCH_TARGET 295
#define EFFECT_FINAL_GAMBIT 298 #define EFFECT_FINAL_GAMBIT 296
#define EFFECT_CHANGE_TYPE_ON_ITEM 299 #define EFFECT_CHANGE_TYPE_ON_ITEM 297
#define EFFECT_AUTOTOMIZE 300 #define EFFECT_AUTOTOMIZE 298
#define EFFECT_COPYCAT 301 #define EFFECT_COPYCAT 299
#define EFFECT_DEFOG 302 #define EFFECT_DEFOG 300
#define EFFECT_HIT_ENEMY_HEAL_ALLY 303 #define EFFECT_HIT_ENEMY_HEAL_ALLY 301
#define EFFECT_SMACK_DOWN 304 #define EFFECT_SMACK_DOWN 302
#define EFFECT_SYNCHRONOISE 305 #define EFFECT_SYNCHRONOISE 303
#define EFFECT_PSYCHO_SHIFT 306 #define EFFECT_PSYCHO_SHIFT 304
#define EFFECT_POWER_TRICK 307 #define EFFECT_POWER_TRICK 305
#define EFFECT_FLAME_BURST 308 #define EFFECT_FLAME_BURST 306
#define EFFECT_AFTER_YOU 309 #define EFFECT_AFTER_YOU 307
#define EFFECT_BESTOW 310 #define EFFECT_BESTOW 308
#define EFFECT_ROTOTILLER 311 #define EFFECT_ROTOTILLER 309
#define EFFECT_FLOWER_SHIELD 312 #define EFFECT_FLOWER_SHIELD 310
#define EFFECT_HIT_PREVENT_ESCAPE 313 #define EFFECT_HIT_PREVENT_ESCAPE 311
#define EFFECT_SPEED_SWAP 314 #define EFFECT_SPEED_SWAP 312
#define EFFECT_DEFENSE_UP2_HIT 315 #define EFFECT_DEFENSE_UP2_HIT 313
#define EFFECT_REVELATION_DANCE 316 #define EFFECT_REVELATION_DANCE 314
#define EFFECT_AURORA_VEIL 317 #define EFFECT_AURORA_VEIL 315
#define EFFECT_THIRD_TYPE 318 #define EFFECT_THIRD_TYPE 316
#define EFFECT_FEINT 319 #define EFFECT_FEINT 317
#define EFFECT_SPARKLING_ARIA 320 #define EFFECT_SPARKLING_ARIA 318
#define EFFECT_ACUPRESSURE 321 #define EFFECT_ACUPRESSURE 319
#define EFFECT_AROMATIC_MIST 322 #define EFFECT_AROMATIC_MIST 320
#define EFFECT_POWDER 323 #define EFFECT_POWDER 321
#define EFFECT_SP_ATTACK_UP_HIT 324 #define EFFECT_SP_ATTACK_UP_HIT 322
#define EFFECT_BELCH 325 #define EFFECT_BELCH 323
#define EFFECT_PARTING_SHOT 326 #define EFFECT_PARTING_SHOT 324
#define EFFECT_SPECTRAL_THIEF 327 #define EFFECT_SPECTRAL_THIEF 325
#define EFFECT_V_CREATE 328 #define EFFECT_V_CREATE 326
#define EFFECT_MAT_BLOCK 329 #define EFFECT_MAT_BLOCK 327
#define EFFECT_STOMPING_TANTRUM 330 #define EFFECT_STOMPING_TANTRUM 328
#define EFFECT_CORE_ENFORCER 331 #define EFFECT_CORE_ENFORCER 329
#define EFFECT_INSTRUCT 332 #define EFFECT_INSTRUCT 330
#define EFFECT_THROAT_CHOP 333 #define EFFECT_THROAT_CHOP 331
#define EFFECT_LASER_FOCUS 334 #define EFFECT_LASER_FOCUS 332
#define EFFECT_MAGNETIC_FLUX 335 #define EFFECT_MAGNETIC_FLUX 333
#define EFFECT_GEAR_UP 336 #define EFFECT_GEAR_UP 334
#define EFFECT_INCINERATE 337 #define EFFECT_INCINERATE 335
#define EFFECT_BUG_BITE 338 #define EFFECT_BUG_BITE 336
#define EFFECT_STRENGTH_SAP 339 #define EFFECT_STRENGTH_SAP 337
#define EFFECT_MIND_BLOWN 340 #define EFFECT_MIND_BLOWN 338
#define EFFECT_PURIFY 341 #define EFFECT_PURIFY 339
#define EFFECT_BURN_UP 342 #define EFFECT_BURN_UP 340
#define EFFECT_SHORE_UP 343 #define EFFECT_SHORE_UP 341
#define EFFECT_GEOMANCY 344 #define EFFECT_GEOMANCY 342
#define EFFECT_FAIRY_LOCK 345 #define EFFECT_FAIRY_LOCK 343
#define EFFECT_ALLY_SWITCH 346 #define EFFECT_ALLY_SWITCH 344
#define EFFECT_RELIC_SONG 347 #define EFFECT_RELIC_SONG 345
#define EFFECT_ATTACKER_DEFENSE_DOWN_HIT 348 #define EFFECT_ATTACKER_DEFENSE_DOWN_HIT 346
#define EFFECT_BODY_PRESS 349 #define EFFECT_BODY_PRESS 347
#define EFFECT_EERIE_SPELL 350 #define EFFECT_EERIE_SPELL 348
#define EFFECT_JUNGLE_HEALING 351 #define EFFECT_JUNGLE_HEALING 349
#define EFFECT_COACHING 352 #define EFFECT_COACHING 350
#define EFFECT_LASH_OUT 353 #define EFFECT_LASH_OUT 351
#define EFFECT_GRASSY_GLIDE 354 #define EFFECT_GRASSY_GLIDE 352
#define EFFECT_REMOVE_TERRAIN 355 #define EFFECT_REMOVE_TERRAIN 353
#define EFFECT_DYNAMAX_DOUBLE_DMG 356 #define EFFECT_DYNAMAX_DOUBLE_DMG 354
#define EFFECT_DECORATE 357 #define EFFECT_DECORATE 355
#define EFFECT_SNIPE_SHOT 358 #define EFFECT_SNIPE_SHOT 356
#define EFFECT_TRIPLE_HIT 359 #define EFFECT_RECOIL_HP_25 357
#define EFFECT_RECOIL_HP_25 360 #define EFFECT_STUFF_CHEEKS 358
#define EFFECT_STUFF_CHEEKS 361 #define EFFECT_GRAV_APPLE 359
#define EFFECT_GRAV_APPLE 362 #define EFFECT_EVASION_UP_HIT 360
#define EFFECT_EVASION_UP_HIT 363 #define EFFECT_GLITZY_GLOW 361
#define EFFECT_DOUBLE_IRON_BASH 364 #define EFFECT_BADDY_BAD 362
#define EFFECT_GLITZY_GLOW 365 #define EFFECT_SAPPY_SEED 363
#define EFFECT_BADDY_BAD 366 #define EFFECT_FREEZY_FROST 364
#define EFFECT_SAPPY_SEED 367 #define EFFECT_SPARKLY_SWIRL 365
#define EFFECT_FREEZY_FROST 368 #define EFFECT_PLASMA_FISTS 366
#define EFFECT_SPARKLY_SWIRL 369 #define EFFECT_HYPERSPACE_FURY 367
#define EFFECT_PLASMA_FISTS 370 #define EFFECT_AURA_WHEEL 368
#define EFFECT_HYPERSPACE_FURY 371 #define EFFECT_PHOTON_GEYSER 369
#define EFFECT_AURA_WHEEL 372 #define EFFECT_SHELL_SIDE_ARM 370
#define EFFECT_PHOTON_GEYSER 373 #define EFFECT_TERRAIN_PULSE 371
#define EFFECT_SHELL_SIDE_ARM 374 #define EFFECT_JAW_LOCK 372
#define EFFECT_TERRAIN_PULSE 375 #define EFFECT_NO_RETREAT 373
#define EFFECT_JAW_LOCK 376 #define EFFECT_TAR_SHOT 374
#define EFFECT_NO_RETREAT 377 #define EFFECT_POLTERGEIST 375
#define EFFECT_TAR_SHOT 378 #define EFFECT_OCTOLOCK 376
#define EFFECT_POLTERGEIST 379 #define EFFECT_CLANGOROUS_SOUL 377
#define EFFECT_OCTOLOCK 380 #define EFFECT_BOLT_BEAK 378
#define EFFECT_CLANGOROUS_SOUL 381 #define EFFECT_SKY_DROP 379
#define EFFECT_BOLT_BEAK 382 #define EFFECT_EXPANDING_FORCE 380
#define EFFECT_SKY_DROP 383 #define EFFECT_SCALE_SHOT 381
#define EFFECT_EXPANDING_FORCE 384 #define EFFECT_METEOR_BEAM 382
#define EFFECT_SCALE_SHOT 385 #define EFFECT_RISING_VOLTAGE 383
#define EFFECT_METEOR_BEAM 386 #define EFFECT_BEAK_BLAST 384
#define EFFECT_RISING_VOLTAGE 387 #define EFFECT_COURT_CHANGE 385
#define EFFECT_BEAK_BLAST 388 #define EFFECT_STEEL_BEAM 386
#define EFFECT_COURT_CHANGE 389 #define EFFECT_EXTREME_EVOBOOST 387
#define EFFECT_STEEL_BEAM 390 #define EFFECT_DAMAGE_SET_TERRAIN 388 // genesis supernova
#define EFFECT_EXTREME_EVOBOOST 391
#define EFFECT_DAMAGE_SET_TERRAIN 392 // genesis supernova
#define NUM_BATTLE_MOVE_EFFECTS 393 #define NUM_BATTLE_MOVE_EFFECTS 389
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -245,6 +245,7 @@
#define VARIOUS_TRY_SYMBIOSIS 154 #define VARIOUS_TRY_SYMBIOSIS 154
#define VARIOUS_CAN_TELEPORT 155 #define VARIOUS_CAN_TELEPORT 155
#define VARIOUS_GET_BATTLER_SIDE 156 #define VARIOUS_GET_BATTLER_SIDE 156
#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0
@ -284,40 +285,43 @@
#define PARTY_SCREEN_OPTIONAL (1 << 7) // Flag for first argument to openpartyscreen #define PARTY_SCREEN_OPTIONAL (1 << 7) // Flag for first argument to openpartyscreen
// cases for Cmd_moveend // cases for Cmd_moveend
#define MOVEEND_PROTECT_LIKE_EFFECT 0 #define MOVEEND_SUM_DAMAGE 0
#define MOVEEND_RAGE 1 #define MOVEEND_PROTECT_LIKE_EFFECT 1
#define MOVEEND_DEFROST 2 #define MOVEEND_RAGE 2
#define MOVEEND_SYNCHRONIZE_TARGET 3 #define MOVEEND_SYNCHRONIZE_TARGET 3
#define MOVEEND_ABILITIES 4 #define MOVEEND_ABILITIES 4
#define MOVEEND_ABILITIES_ATTACKER 5 #define MOVEEND_ABILITIES_ATTACKER 5
#define MOVEEND_STATUS_IMMUNITY_ABILITIES 6 #define MOVEEND_STATUS_IMMUNITY_ABILITIES 6
#define MOVEEND_SYNCHRONIZE_ATTACKER 7 #define MOVEEND_SYNCHRONIZE_ATTACKER 7
#define MOVEEND_CHOICE_MOVE 8 #define MOVEEND_CHOICE_MOVE 8
#define MOVEEND_CHANGED_ITEMS 9 #define MOVEEND_ATTACKER_INVISIBLE 9
#define MOVEEND_ATTACKER_INVISIBLE 10 #define MOVEEND_ATTACKER_VISIBLE 10
#define MOVEEND_ATTACKER_VISIBLE 11 #define MOVEEND_TARGET_VISIBLE 11
#define MOVEEND_TARGET_VISIBLE 12 #define MOVEEND_ITEM_EFFECTS_TARGET 12
#define MOVEEND_ITEM_EFFECTS_TARGET 13 #define MOVEEND_ITEM_EFFECTS_ALL 13
#define MOVEEND_MOVE_EFFECTS2 14 #define MOVEEND_KINGSROCK 14 // These item effects will occur each strike of a multi-hit move
#define MOVEEND_ITEM_EFFECTS_ALL 15 #define MOVEEND_SUBSTITUTE 15
#define MOVEEND_KINGSROCK 16 // These item effects will occur each strike of a multi-hit move #define MOVEEND_SKY_DROP_CONFUSE 16
#define MOVEEND_SUBSTITUTE 17 #define MOVEEND_UPDATE_LAST_MOVES 17
#define MOVEEND_SKY_DROP_CONFUSE 18 #define MOVEEND_MIRROR_MOVE 18
#define MOVEEND_UPDATE_LAST_MOVES 19 #define MOVEEND_NEXT_TARGET 19 // Everything up until here is handled for each strike of a multi-hit move
#define MOVEEND_MIRROR_MOVE 20 #define MOVEEND_MULTIHIT_MOVE 20
#define MOVEEND_NEXT_TARGET 21 // Everything up until here is handled for each strike of a multi-hit move #define MOVEEND_DEFROST 21
#define MOVEEND_MAGICIAN 22 // Occurs after final multi-hit strike, and after other items/abilities would activate #define MOVEEND_MOVE_EFFECTS2 22
#define MOVEEND_EJECT_BUTTON 23 #define MOVEEND_RECOIL 23
#define MOVEEND_RED_CARD 24 #define MOVEEND_MAGICIAN 24 // Occurs after final multi-hit strike, and after other items/abilities would activate
#define MOVEEND_EJECT_PACK 25 #define MOVEEND_EJECT_BUTTON 25
#define MOVEEND_LIFEORB_SHELLBELL 26 // Includes shell bell, throat spray, etc #define MOVEEND_RED_CARD 26
#define MOVEEND_PICKPOCKET 27 #define MOVEEND_EJECT_PACK 27
#define MOVEEND_DANCER 28 #define MOVEEND_LIFEORB_SHELLBELL 28 // Includes shell bell, throat spray, etc
#define MOVEEND_EMERGENCY_EXIT 29 #define MOVEEND_CHANGED_ITEMS 29
#define MOVEEND_WEATHER_FORM 30 #define MOVEEND_PICKPOCKET 30
#define MOVEEND_SYMBIOSIS 31 #define MOVEEND_DANCER 31
#define MOVEEND_CLEAR_BITS 32 #define MOVEEND_EMERGENCY_EXIT 32
#define MOVEEND_COUNT 33 #define MOVEEND_WEATHER_FORM 33
#define MOVEEND_SYMBIOSIS 34
#define MOVEEND_CLEAR_BITS 35
#define MOVEEND_COUNT 36
// switch cases // switch cases
#define B_SWITCH_NORMAL 0 #define B_SWITCH_NORMAL 0

View File

@ -16,4 +16,10 @@
#define KEYITEMS_POCKET 4 #define KEYITEMS_POCKET 4
#define POCKETS_COUNT 5 #define POCKETS_COUNT 5
#define REPEL_LURE_MASK (1 << 15)
#define IS_LAST_USED_LURE(var) (var & REPEL_LURE_MASK)
#define REPEL_LURE_STEPS(var) (var & (REPEL_LURE_MASK - 1))
#define LURE_STEP_COUNT (IS_LAST_USED_LURE(VarGet(VAR_REPEL_STEP_COUNT)) ? REPEL_LURE_STEPS(VarGet(VAR_REPEL_STEP_COUNT)) : 0)
#define REPEL_STEP_COUNT (!IS_LAST_USED_LURE(VarGet(VAR_REPEL_STEP_COUNT)) ? REPEL_LURE_STEPS(VarGet(VAR_REPEL_STEP_COUNT)) : 0)
#endif // GUARD_ITEM_CONSTANTS_H #endif // GUARD_ITEM_CONSTANTS_H

View File

@ -9,4 +9,9 @@
#define I_SITRUS_BERRY_HEAL GEN_LATEST // In Gen4+, Sitrus Berry was changed from healing 30 HP to healing 25% of Max HP. #define I_SITRUS_BERRY_HEAL GEN_LATEST // In Gen4+, Sitrus Berry was changed from healing 30 HP to healing 25% of Max HP.
#define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8, the Vitamins no longer have a cap of 100 EV per stat. #define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8, the Vitamins no longer have a cap of 100 EV per stat.
// Repel/Lure config
// These two settings are both independent and complementary.
#define VAR_LAST_REPEL_LURE_USED 0 // If this var has been assigned, last Repel/Lure used will be saved and the player will get prompted with the vanilla repel YES/NO option, unless I_REPEL_LURE_MENU is set to TRUE.
#define I_REPEL_LURE_MENU TRUE // If TRUE, the player is able to choose which Repel/Lure to use once the previous one runs out. Cursor position is saved by VAR_LAST_REPEL_LURE_USED if not 0.
#endif // GUARD_CONSTANTS_ITEM_CONFIG_H #endif // GUARD_CONSTANTS_ITEM_CONFIG_H

View File

@ -1,9 +1,12 @@
#ifndef GUARD_CONSTANTS_OVERWORLD_CONFIG_H #ifndef GUARD_CONSTANTS_OVERWORLD_CONFIG_H
#define GUARD_CONSTANTS_OVERWORLD_CONFIG_H #define GUARD_CONSTANTS_OVERWORLD_CONFIG_H
// Movement config
#define OW_RUNNING_INDOORS GEN_LATEST // In Gen4+, players are allowed to run indoors.
// Overworld flags // Overworld flags
#define OW_FLAG_NO_ENCOUNTER 0 // If this flag is set, wild encounters will be disabled. #define OW_FLAG_NO_ENCOUNTER 0 // If this flag is set, wild encounters will be disabled.
#define OW_FLAG_NO_TRAINER_SEE 0 // If this flag is set, trainers will not battle the player unless they're talked to. #define OW_FLAG_NO_TRAINER_SEE 0 // If this flag is set, trainers will not battle the player unless they're talked to.
// Debug options // Debug options
#define DEBUG_SYSTEM_ENABLE TRUE // Enables a overworld debug menu for changing flags, variables, giving pokemon and more, accessed by holding R and pressing START while in the overworld by default. #define DEBUG_SYSTEM_ENABLE TRUE // Enables a overworld debug menu for changing flags, variables, giving pokemon and more, accessed by holding R and pressing START while in the overworld by default.
@ -13,6 +16,5 @@
// Replace the used flags with others or disable with a 0 // Replace the used flags with others or disable with a 0
#define DEBUG_FLAG_NO_COLLISION 0 // If this flag is set, the debug function in the Utility submenu to disable player collision can be used. #define DEBUG_FLAG_NO_COLLISION 0 // If this flag is set, the debug function in the Utility submenu to disable player collision can be used.
#define DEBUG_FLAG_PC_FROM_DEBUG_MENU 0 // If this flag is set, the debug function in debug menu to access the player PC works.
#endif // GUARD_CONSTANTS_OVERWORLD_CONFIG_H #endif // GUARD_CONSTANTS_OVERWORLD_CONFIG_H

View File

@ -329,9 +329,10 @@
#define MON_PIC_HEIGHT 64 #define MON_PIC_HEIGHT 64
#define MON_PIC_SIZE (MON_PIC_WIDTH * MON_PIC_HEIGHT / 2) #define MON_PIC_SIZE (MON_PIC_WIDTH * MON_PIC_HEIGHT / 2)
#define BATTLE_ALIVE_EXCEPT_ACTIVE 0 #define BATTLE_ALIVE_EXCEPT_ACTIVE 0
#define BATTLE_ALIVE_ATK_SIDE 1 #define BATTLE_ALIVE_ATK_SIDE 1
#define BATTLE_ALIVE_DEF_SIDE 2 #define BATTLE_ALIVE_DEF_SIDE 2
#define BATTLE_ALIVE_EXCEPT_ATTACKER 3
#define SKIP_FRONT_ANIM (1 << 7) #define SKIP_FRONT_ANIM (1 << 7)

View File

@ -352,6 +352,7 @@
#define TRAINER_CLASS_PIKE_QUEEN 0x3f #define TRAINER_CLASS_PIKE_QUEEN 0x3f
#define TRAINER_CLASS_PYRAMID_KING 0x40 #define TRAINER_CLASS_PYRAMID_KING 0x40
#define TRAINER_CLASS_RS_PROTAG 0x41 #define TRAINER_CLASS_RS_PROTAG 0x41
#define TRAINER_CLASS_COUNT 0x42
#define TRAINER_ENCOUNTER_MUSIC_MALE 0 // standard male encounter music #define TRAINER_ENCOUNTER_MUSIC_MALE 0 // standard male encounter music
#define TRAINER_ENCOUNTER_MUSIC_FEMALE 1 // standard female encounter music #define TRAINER_ENCOUNTER_MUSIC_FEMALE 1 // standard female encounter music

View File

@ -35,6 +35,7 @@ bool8 FldEff_UseStrength(void);
// sweet scent // sweet scent
bool8 SetUpFieldMove_SweetScent(void); bool8 SetUpFieldMove_SweetScent(void);
bool8 FldEff_SweetScent(void); bool8 FldEff_SweetScent(void);
void StartSweetScentFieldEffect(void);
// teleport // teleport
bool8 SetUpFieldMove_Teleport(void); bool8 SetUpFieldMove_Teleport(void);

View File

@ -20,6 +20,7 @@ void ItemUseOutOfBattle_PPUp(u8);
void ItemUseOutOfBattle_RareCandy(u8); void ItemUseOutOfBattle_RareCandy(u8);
void ItemUseOutOfBattle_TMHM(u8); void ItemUseOutOfBattle_TMHM(u8);
void ItemUseOutOfBattle_Repel(u8); void ItemUseOutOfBattle_Repel(u8);
void ItemUseOutOfBattle_Lure(u8);
void ItemUseOutOfBattle_EscapeRope(u8); void ItemUseOutOfBattle_EscapeRope(u8);
void ItemUseOutOfBattle_BlackWhiteFlute(u8); void ItemUseOutOfBattle_BlackWhiteFlute(u8);
void ItemUseOutOfBattle_EvolutionStone(u8); void ItemUseOutOfBattle_EvolutionStone(u8);
@ -27,6 +28,7 @@ void ItemUseOutOfBattle_Berry(u8);
void ItemUseOutOfBattle_EnigmaBerry(u8); void ItemUseOutOfBattle_EnigmaBerry(u8);
void ItemUseOutOfBattle_FormChange(u8); void ItemUseOutOfBattle_FormChange(u8);
void ItemUseOutOfBattle_FormChange_ConsumedOnUse(u8); void ItemUseOutOfBattle_FormChange_ConsumedOnUse(u8);
void ItemUseOutOfBattle_Honey(u8);
void ItemUseOutOfBattle_CannotUse(u8); void ItemUseOutOfBattle_CannotUse(u8);
void ItemUseInBattle_PokeBall(u8); void ItemUseInBattle_PokeBall(u8);
void ItemUseInBattle_StatIncrease(u8); void ItemUseInBattle_StatIncrease(u8);

View File

@ -938,6 +938,7 @@ extern const u8 gText_BootedUpTM[];
extern const u8 gText_TMHMContainedVar1[]; extern const u8 gText_TMHMContainedVar1[];
extern const u8 gText_PlayerUsedVar2[]; extern const u8 gText_PlayerUsedVar2[];
extern const u8 gText_RepelEffectsLingered[]; extern const u8 gText_RepelEffectsLingered[];
extern const u8 gText_LureEffectsLingered[];
extern const u8 gText_UsedVar2WildLured[]; extern const u8 gText_UsedVar2WildLured[];
extern const u8 gText_UsedVar2WildRepelled[]; extern const u8 gText_UsedVar2WildRepelled[];
extern const u8 gText_BoxFull[]; extern const u8 gText_BoxFull[];

View File

@ -3407,7 +3407,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += min(CountPositiveStatStages(battlerDef), 4); score += min(CountPositiveStatStages(battlerDef), 4);
break; break;
case EFFECT_MULTI_HIT: case EFFECT_MULTI_HIT:
case EFFECT_DOUBLE_HIT:
case EFFECT_TRIPLE_KICK: case EFFECT_TRIPLE_KICK:
if (AI_MoveMakesContact(AI_DATA->abilities[battlerAtk], AI_DATA->holdEffects[battlerAtk], move) if (AI_MoveMakesContact(AI_DATA->abilities[battlerAtk], AI_DATA->holdEffects[battlerAtk], move)
&& AI_DATA->abilities[battlerAtk] != ABILITY_MAGIC_GUARD && AI_DATA->abilities[battlerAtk] != ABILITY_MAGIC_GUARD

View File

@ -1333,7 +1333,7 @@ bool32 IsConfusionMoveEffect(u16 moveEffect)
{ {
switch (moveEffect) switch (moveEffect)
{ {
case EFFECT_CONFUSE_HIT: case EFFECT_CONFUSE:
case EFFECT_SWAGGER: case EFFECT_SWAGGER:
case EFFECT_FLATTER: case EFFECT_FLATTER:
case EFFECT_TEETER_DANCE: case EFFECT_TEETER_DANCE:

View File

@ -1548,18 +1548,17 @@ static void OpponentHandleYesNoBox(void)
static void OpponentHandleChooseMove(void) static void OpponentHandleChooseMove(void)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_PALACE) u8 chosenMoveId;
{ struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]);
BtlController_EmitTwoReturnValues(BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace());
OpponentBufferExecCompleted();
}
else
{
u8 chosenMoveId;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]);
if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER) if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)
|| IsWildMonSmart()) || IsWildMonSmart())
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
BtlController_EmitTwoReturnValues(BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace());
}
else
{ {
chosenMoveId = gBattleStruct->aiMoveOrAction[gActiveBattler]; chosenMoveId = gBattleStruct->aiMoveOrAction[gActiveBattler];
gBattlerTarget = gBattleStruct->aiChosenTarget[gActiveBattler]; gBattlerTarget = gBattleStruct->aiChosenTarget[gActiveBattler];
@ -1598,66 +1597,66 @@ static void OpponentHandleChooseMove(void)
} }
break; break;
} }
OpponentBufferExecCompleted();
} }
else // Wild pokemon - use random move OpponentBufferExecCompleted();
}
else // Wild pokemon - use random move
{
u16 move;
u8 target;
do
{ {
u16 move; chosenMoveId = Random() & 3;
u8 target; move = moveInfo->moves[chosenMoveId];
do } while (move == MOVE_NONE);
{
chosenMoveId = Random() & 3;
move = moveInfo->moves[chosenMoveId];
} while (move == MOVE_NONE);
if (GetBattlerMoveTargetType(gActiveBattler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) if (GetBattlerMoveTargetType(gActiveBattler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gActiveBattler << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gActiveBattler << 8));
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{ {
do { do {
target = GetBattlerAtPosition(Random() & 2); target = GetBattlerAtPosition(Random() & 2);
} while (!CanTargetBattler(gActiveBattler, target, move)); } while (!CanTargetBattler(gActiveBattler, target, move));
#if B_WILD_NATURAL_ENEMIES == TRUE #if B_WILD_NATURAL_ENEMIES == TRUE
// Don't bother to loop through table if the move can't attack ally // Don't bother to loop through table if the move can't attack ally
if (!(gBattleMoves[move].target & MOVE_TARGET_BOTH)) if (!(gBattleMoves[move].target & MOVE_TARGET_BOTH))
{
u16 i, speciesAttacker, speciesTarget, isPartnerEnemy = FALSE;
static const u16 naturalEnemies[][2] =
{ {
u16 i, speciesAttacker, speciesTarget, isPartnerEnemy = FALSE; // Attacker Target
static const u16 naturalEnemies[][2] = {SPECIES_ZANGOOSE, SPECIES_SEVIPER},
{ {SPECIES_SEVIPER, SPECIES_ZANGOOSE},
// Attacker Target {SPECIES_HEATMOR, SPECIES_DURANT},
{SPECIES_ZANGOOSE, SPECIES_SEVIPER}, {SPECIES_DURANT, SPECIES_HEATMOR},
{SPECIES_SEVIPER, SPECIES_ZANGOOSE}, {SPECIES_SABLEYE, SPECIES_CARBINK},
{SPECIES_HEATMOR, SPECIES_DURANT}, {SPECIES_MAREANIE, SPECIES_CORSOLA},
{SPECIES_DURANT, SPECIES_HEATMOR}, };
{SPECIES_SABLEYE, SPECIES_CARBINK}, speciesAttacker = gBattleMons[gActiveBattler].species;
{SPECIES_MAREANIE, SPECIES_CORSOLA}, speciesTarget = gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler))].species;
};
speciesAttacker = gBattleMons[gActiveBattler].species;
speciesTarget = gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler))].species;
for (i = 0; i < ARRAY_COUNT(naturalEnemies); i++) for (i = 0; i < ARRAY_COUNT(naturalEnemies); i++)
{
if (speciesAttacker == naturalEnemies[i][0] && speciesTarget == naturalEnemies[i][1])
{ {
if (speciesAttacker == naturalEnemies[i][0] && speciesTarget == naturalEnemies[i][1]) isPartnerEnemy = TRUE;
{ break;
isPartnerEnemy = TRUE;
break;
}
} }
if (isPartnerEnemy && CanTargetBattler(gActiveBattler, target, move))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler)) << 8));
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8));
} }
if (isPartnerEnemy && CanTargetBattler(gActiveBattler, target, move))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler)) << 8));
else else
#endif
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8));
} }
else else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) << 8)); #endif
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8));
OpponentBufferExecCompleted();
} }
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) << 8));
OpponentBufferExecCompleted();
} }
} }

View File

@ -164,6 +164,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
{ {
gBattleStruct->palaceFlags &= 0xF; gBattleStruct->palaceFlags &= 0xF;
gBattleStruct->palaceFlags |= (selectedMoves << 4); gBattleStruct->palaceFlags |= (selectedMoves << 4);
sBattler_AI = gActiveBattler;
BattleAI_SetupAIData(selectedMoves); BattleAI_SetupAIData(selectedMoves);
chosenMoveId = BattleAI_ChooseMoveOrAction(); chosenMoveId = BattleAI_ChooseMoveOrAction();
} }
@ -171,8 +172,9 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
// If no moves matched the selected group, pick a new move from groups the pokemon has // If no moves matched the selected group, pick a new move from groups the pokemon has
// In this case the AI is not checked again, so the choice may be worse // In this case the AI is not checked again, so the choice may be worse
// If a move is chosen this way, there's a 50% chance that it will be unable to use it anyway // If a move is chosen this way, there's a 50% chance that it will be unable to use it anyway
if (chosenMoveId == -1) if (chosenMoveId == -1 || chosenMoveId >= MAX_MON_MOVES)
{ {
chosenMoveId = -1;
if (unusableMovesBits != 0xF) if (unusableMovesBits != 0xF)
{ {
validMoveFlags = 0, numValidMoveGroups = 0; validMoveFlags = 0, numValidMoveGroups = 0;

View File

@ -392,6 +392,32 @@ const struct TrainerMoney gTrainerMoneyTable[] =
{0xFF, 5}, // Any trainer class not listed above uses this {0xFF, 5}, // Any trainer class not listed above uses this
}; };
#if B_TRAINER_CLASS_POKE_BALLS >= GEN_7
static const u16 sTrainerBallTable[TRAINER_CLASS_COUNT] =
{
#if B_TRAINER_CLASS_POKE_BALLS == GEN_7
[TRAINER_CLASS_PKMN_BREEDER] = ITEM_FRIEND_BALL,
#elif B_TRAINER_CLASS_POKE_BALLS == GEN_8
[TRAINER_CLASS_PKMN_BREEDER] = ITEM_HEAL_BALL,
#endif
[TRAINER_CLASS_COOLTRAINER] = ITEM_ULTRA_BALL,
[TRAINER_CLASS_COLLECTOR] = ITEM_PREMIER_BALL,
[TRAINER_CLASS_SWIMMER_M] = ITEM_DIVE_BALL,
[TRAINER_CLASS_BLACK_BELT] = ITEM_ULTRA_BALL,
[TRAINER_CLASS_AQUA_LEADER] = ITEM_MASTER_BALL,
[TRAINER_CLASS_GENTLEMAN] = ITEM_LUXURY_BALL,
[TRAINER_CLASS_ELITE_FOUR] = ITEM_ULTRA_BALL,
#if B_TRAINER_CLASS_POKE_BALLS == GEN_7
[TRAINER_CLASS_FISHERMAN] = ITEM_LURE_BALL,
#elif B_TRAINER_CLASS_POKE_BALLS == GEN_8
[TRAINER_CLASS_FISHERMAN] = ITEM_DIVE_BALL,
#endif
[TRAINER_CLASS_SWIMMER_F] = ITEM_DIVE_BALL,
[TRAINER_CLASS_COOLTRAINER_2] = ITEM_ULTRA_BALL,
[TRAINER_CLASS_MAGMA_LEADER] = ITEM_MASTER_BALL,
};
#endif
#include "data/text/abilities.h" #include "data/text/abilities.h"
static void (* const sTurnActionsFuncsTable[])(void) = static void (* const sTurnActionsFuncsTable[])(void) =
@ -1847,6 +1873,7 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
u8 fixedIV; u8 fixedIV;
s32 i, j; s32 i, j;
u8 monsCount; u8 monsCount;
u16 ball;
if (trainerNum == TRAINER_SECRET_BASE) if (trainerNum == TRAINER_SECRET_BASE)
return 0; return 0;
@ -1950,6 +1977,11 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
break; break;
} }
} }
#if B_TRAINER_CLASS_POKE_BALLS >= GEN_7
ball = (sTrainerBallTable[gTrainers[trainerNum].trainerClass]) ? sTrainerBallTable[gTrainers[trainerNum].trainerClass] : ITEM_POKE_BALL;
SetMonData(&party[i], MON_DATA_POKEBALL, &ball);
#endif
} }
gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle; gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle;
@ -2969,6 +3001,7 @@ static void BattleStartClearSetData(void)
gBattleScripting.monCaught = FALSE; gBattleScripting.monCaught = FALSE;
gMultiHitCounter = 0; gMultiHitCounter = 0;
gBattleScripting.savedDmg = 0;
gBattleOutcome = 0; gBattleOutcome = 0;
gBattleControllerExecFlags = 0; gBattleControllerExecFlags = 0;
gPaydayMoney = 0; gPaydayMoney = 0;
@ -3127,7 +3160,7 @@ void SwitchInClearSetData(void)
// Reset damage to prevent things like red card activating if the switched-in mon is holding it // Reset damage to prevent things like red card activating if the switched-in mon is holding it
gSpecialStatuses[gActiveBattler].physicalDmg = 0; gSpecialStatuses[gActiveBattler].physicalDmg = 0;
gSpecialStatuses[gActiveBattler].specialDmg = 0; gSpecialStatuses[gActiveBattler].specialDmg = 0;
gBattleStruct->overwrittenAbilities[gActiveBattler] = ABILITY_NONE; gBattleStruct->overwrittenAbilities[gActiveBattler] = ABILITY_NONE;
Ai_UpdateSwitchInData(gActiveBattler); Ai_UpdateSwitchInData(gActiveBattler);
@ -3232,7 +3265,7 @@ void FaintClearSetData(void)
UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]); UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]);
gBattleStruct->overwrittenAbilities[gActiveBattler] = ABILITY_NONE; gBattleStruct->overwrittenAbilities[gActiveBattler] = ABILITY_NONE;
// If the fainted mon was involved in a Sky Drop // If the fainted mon was involved in a Sky Drop
if (gBattleStruct->skyDropTargets[gActiveBattler] != 0xFF) if (gBattleStruct->skyDropTargets[gActiveBattler] != 0xFF)
{ {
@ -3271,6 +3304,11 @@ void FaintClearSetData(void)
} }
} }
} }
// Clear Z-Move data
gBattleStruct->zmove.active = FALSE;
gBattleStruct->zmove.toBeUsed[gActiveBattler] = MOVE_NONE;
gBattleStruct->zmove.effect = EFFECT_HIT;
} }
static void DoBattleIntro(void) static void DoBattleIntro(void)
@ -3936,7 +3974,8 @@ static void HandleTurnActionSelectionState(void)
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
// Do AI score computations here so we can use them in AI_TrySwitchOrUseItem // Do AI score computations here so we can use them in AI_TrySwitchOrUseItem
if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart()) && IsBattlerAIControlled(gActiveBattler)) { if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart())
&& (IsBattlerAIControlled(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE))) {
gBattleStruct->aiMoveOrAction[gActiveBattler] = ComputeBattleAiScores(gActiveBattler); gBattleStruct->aiMoveOrAction[gActiveBattler] = ComputeBattleAiScores(gActiveBattler);
} }
break; break;
@ -4804,6 +4843,8 @@ static void TurnValuesCleanUp(bool8 var0)
if (gDisableStructs[gActiveBattler].substituteHP == 0) if (gDisableStructs[gActiveBattler].substituteHP == 0)
gBattleMons[gActiveBattler].status2 &= ~STATUS2_SUBSTITUTE; gBattleMons[gActiveBattler].status2 &= ~STATUS2_SUBSTITUTE;
gSpecialStatuses[gActiveBattler].parentalBondState = PARENTAL_BOND_OFF;
} }
gSideStatuses[0] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK); gSideStatuses[0] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);

View File

@ -318,6 +318,7 @@ static void DrawLevelUpBannerText(void);
static void SpriteCB_MonIconOnLvlUpBanner(struct Sprite *sprite); static void SpriteCB_MonIconOnLvlUpBanner(struct Sprite *sprite);
static bool32 CriticalCapture(u32 odds); static bool32 CriticalCapture(u32 odds);
static void BestowItem(u32 battlerAtk, u32 battlerDef); static void BestowItem(u32 battlerAtk, u32 battlerDef);
static bool8 IsFinalStrikeEffect(u16 move);
static void Cmd_attackcanceler(void); static void Cmd_attackcanceler(void);
static void Cmd_accuracycheck(void); static void Cmd_accuracycheck(void);
@ -884,8 +885,6 @@ static const u8 *const sMoveEffectBS_Ptrs[] =
[MOVE_EFFECT_UPROAR] = BattleScript_MoveEffectUproar, [MOVE_EFFECT_UPROAR] = BattleScript_MoveEffectUproar,
[MOVE_EFFECT_PAYDAY] = BattleScript_MoveEffectPayDay, [MOVE_EFFECT_PAYDAY] = BattleScript_MoveEffectPayDay,
[MOVE_EFFECT_WRAP] = BattleScript_MoveEffectWrap, [MOVE_EFFECT_WRAP] = BattleScript_MoveEffectWrap,
[MOVE_EFFECT_RECOIL_25] = BattleScript_MoveEffectRecoil,
[MOVE_EFFECT_RECOIL_33] = BattleScript_MoveEffectRecoil,
}; };
static const struct WindowTemplate sUnusedWinTemplate = static const struct WindowTemplate sUnusedWinTemplate =
@ -938,6 +937,7 @@ static const u16 sProtectSuccessRates[] = {USHRT_MAX, USHRT_MAX / 2, USHRT_MAX /
#define FORBIDDEN_COPYCAT (1 << 3) #define FORBIDDEN_COPYCAT (1 << 3)
#define FORBIDDEN_SLEEP_TALK (1 << 4) #define FORBIDDEN_SLEEP_TALK (1 << 4)
#define FORBIDDEN_INSTRUCT (1 << 5) #define FORBIDDEN_INSTRUCT (1 << 5)
#define FORBIDDEN_PARENTAL_BOND (1 << 6)
static const u8 sForbiddenMoves[MOVES_COUNT] = static const u8 sForbiddenMoves[MOVES_COUNT] =
{ {
@ -945,28 +945,35 @@ static const u8 sForbiddenMoves[MOVES_COUNT] =
[MOVE_STRUGGLE] = 0xFF, // Neither Struggle [MOVE_STRUGGLE] = 0xFF, // Neither Struggle
[MOVE_AFTER_YOU] = FORBIDDEN_METRONOME, [MOVE_AFTER_YOU] = FORBIDDEN_METRONOME,
[MOVE_APPLE_ACID] = FORBIDDEN_METRONOME, [MOVE_APPLE_ACID] = FORBIDDEN_METRONOME,
[MOVE_ARM_THRUST] = FORBIDDEN_PARENTAL_BOND,
[MOVE_ASSIST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_ASSIST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_ASTRAL_BARRAGE] = FORBIDDEN_METRONOME, [MOVE_ASTRAL_BARRAGE] = FORBIDDEN_METRONOME,
[MOVE_AURA_WHEEL] = FORBIDDEN_METRONOME, [MOVE_AURA_WHEEL] = FORBIDDEN_METRONOME,
[MOVE_BADDY_BAD] = FORBIDDEN_METRONOME, [MOVE_BADDY_BAD] = FORBIDDEN_METRONOME,
[MOVE_BANEFUL_BUNKER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BANEFUL_BUNKER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_BARRAGE] = FORBIDDEN_PARENTAL_BOND,
[MOVE_BEAK_BLAST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_BEAK_BLAST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_BEAT_UP] = FORBIDDEN_PARENTAL_BOND,
[MOVE_BEHEMOTH_BASH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BEHEMOTH_BASH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_BEHEMOTH_BLADE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BEHEMOTH_BLADE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_BELCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_BELCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_BESTOW] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BESTOW] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_BIDE] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_BIDE] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND, // Note: Bide should work with Parental Bond. This will be addressed in future.
[MOVE_BLAST_BURN] = FORBIDDEN_INSTRUCT, [MOVE_BLAST_BURN] = FORBIDDEN_INSTRUCT,
[MOVE_BODY_PRESS] = FORBIDDEN_METRONOME, [MOVE_BODY_PRESS] = FORBIDDEN_METRONOME,
[MOVE_BOUNCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_BONE_RUSH] = FORBIDDEN_PARENTAL_BOND,
[MOVE_BONEMERANG] = FORBIDDEN_PARENTAL_BOND,
[MOVE_BOUNCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_BOUNCY_BUBBLE] = FORBIDDEN_METRONOME, [MOVE_BOUNCY_BUBBLE] = FORBIDDEN_METRONOME,
[MOVE_BRANCH_POKE] = FORBIDDEN_METRONOME, [MOVE_BRANCH_POKE] = FORBIDDEN_METRONOME,
[MOVE_BREAKING_SWIPE] = FORBIDDEN_METRONOME, [MOVE_BREAKING_SWIPE] = FORBIDDEN_METRONOME,
[MOVE_BULLET_SEED] = FORBIDDEN_PARENTAL_BOND,
[MOVE_BUZZY_BUZZ] = FORBIDDEN_METRONOME, [MOVE_BUZZY_BUZZ] = FORBIDDEN_METRONOME,
[MOVE_CELEBRATE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_CELEBRATE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_CHATTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_CHATTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_CIRCLE_THROW] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_CIRCLE_THROW] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_CLANGOROUS_SOUL] = FORBIDDEN_METRONOME, [MOVE_CLANGOROUS_SOUL] = FORBIDDEN_METRONOME,
[MOVE_COMET_PUNCH] = FORBIDDEN_PARENTAL_BOND,
[MOVE_COPYCAT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_COPYCAT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_COUNTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_COUNTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_COVET] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_COVET] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
@ -975,41 +982,57 @@ static const u8 sForbiddenMoves[MOVES_COUNT] =
[MOVE_DESTINY_BOND] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_DESTINY_BOND] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_DETECT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_DETECT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_DIAMOND_STORM] = FORBIDDEN_METRONOME, [MOVE_DIAMOND_STORM] = FORBIDDEN_METRONOME,
[MOVE_DIG] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_DIG] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_DIVE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_DIVE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_DOUBLE_IRON_BASH] = FORBIDDEN_METRONOME, [MOVE_DOUBLE_IRON_BASH] = FORBIDDEN_METRONOME | FORBIDDEN_PARENTAL_BOND,
[MOVE_DOUBLE_HIT] = FORBIDDEN_PARENTAL_BOND,
[MOVE_DOUBLE_KICK] = FORBIDDEN_PARENTAL_BOND,
[MOVE_DOUBLE_SLAP] = FORBIDDEN_PARENTAL_BOND,
[MOVE_DRAGON_ASCENT] = FORBIDDEN_METRONOME, [MOVE_DRAGON_ASCENT] = FORBIDDEN_METRONOME,
[MOVE_DRAGON_ENERGY] = FORBIDDEN_METRONOME, [MOVE_DRAGON_ENERGY] = FORBIDDEN_METRONOME,
[MOVE_DRAGON_DARTS] = FORBIDDEN_PARENTAL_BOND,
[MOVE_DRAGON_TAIL] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_DRAGON_TAIL] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_DRUM_BEATING] = FORBIDDEN_METRONOME, [MOVE_DRUM_BEATING] = FORBIDDEN_METRONOME,
[MOVE_DUAL_CHOP] = FORBIDDEN_PARENTAL_BOND,
[MOVE_DUAL_WINGBEAT] = FORBIDDEN_PARENTAL_BOND,
[MOVE_DYNAMAX_CANNON] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_DYNAMAX_CANNON] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_ENDEAVOR] = FORBIDDEN_PARENTAL_BOND,
[MOVE_ENDURE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ENDURE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_ETERNABEAM] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT, [MOVE_ETERNABEAM] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT,
[MOVE_EXPLOSION] = FORBIDDEN_PARENTAL_BOND,
[MOVE_FALSE_SURRENDER] = FORBIDDEN_METRONOME, [MOVE_FALSE_SURRENDER] = FORBIDDEN_METRONOME,
[MOVE_FEINT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_FEINT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_FIERY_WRATH] = FORBIDDEN_METRONOME, [MOVE_FIERY_WRATH] = FORBIDDEN_METRONOME,
[MOVE_FINAL_GAMBIT] = FORBIDDEN_PARENTAL_BOND,
[MOVE_FISSURE] = FORBIDDEN_PARENTAL_BOND,
[MOVE_FLEUR_CANNON] = FORBIDDEN_METRONOME, [MOVE_FLEUR_CANNON] = FORBIDDEN_METRONOME,
[MOVE_FLING] = FORBIDDEN_PARENTAL_BOND,
[MOVE_FLOATY_FALL] = FORBIDDEN_METRONOME, [MOVE_FLOATY_FALL] = FORBIDDEN_METRONOME,
[MOVE_FLY] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_FLY] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_FOCUS_PUNCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_FOCUS_PUNCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_FOLLOW_ME] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_FOLLOW_ME] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_FREEZE_SHOCK] = FORBIDDEN_METRONOME | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_FREEZE_SHOCK] = FORBIDDEN_METRONOME | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT| FORBIDDEN_PARENTAL_BOND,
[MOVE_FREEZING_GLARE] = FORBIDDEN_METRONOME, [MOVE_FREEZING_GLARE] = FORBIDDEN_METRONOME,
[MOVE_FREEZY_FROST] = FORBIDDEN_METRONOME, [MOVE_FREEZY_FROST] = FORBIDDEN_METRONOME,
[MOVE_FRENZY_PLANT] = FORBIDDEN_INSTRUCT, [MOVE_FURY_ATTACK] = FORBIDDEN_PARENTAL_BOND,
[MOVE_GEOMANCY] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_FURY_SWIPES] = FORBIDDEN_PARENTAL_BOND,
[MOVE_GEAR_GRIND] = FORBIDDEN_PARENTAL_BOND,
[MOVE_GEOMANCY] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_GIGA_IMPACT] = FORBIDDEN_INSTRUCT, [MOVE_GIGA_IMPACT] = FORBIDDEN_INSTRUCT,
[MOVE_GLACIAL_LANCE] = FORBIDDEN_METRONOME, [MOVE_GLACIAL_LANCE] = FORBIDDEN_METRONOME,
[MOVE_GLITZY_GLOW] = FORBIDDEN_METRONOME, [MOVE_GLITZY_GLOW] = FORBIDDEN_METRONOME,
[MOVE_GRAV_APPLE] = FORBIDDEN_METRONOME, [MOVE_GRAV_APPLE] = FORBIDDEN_METRONOME,
[MOVE_GUILLOTINE] = FORBIDDEN_PARENTAL_BOND,
[MOVE_HELPING_HAND] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_HELPING_HAND] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_HOLD_HANDS] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_HOLD_HANDS] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_HORN_DRILL] = FORBIDDEN_PARENTAL_BOND,
[MOVE_HYDRO_CANNON] = FORBIDDEN_INSTRUCT, [MOVE_HYDRO_CANNON] = FORBIDDEN_INSTRUCT,
[MOVE_HYPER_BEAM] = FORBIDDEN_INSTRUCT, [MOVE_HYPER_BEAM] = FORBIDDEN_INSTRUCT,
[MOVE_HYPERSPACE_FURY] = FORBIDDEN_METRONOME, [MOVE_HYPERSPACE_FURY] = FORBIDDEN_METRONOME,
[MOVE_HYPERSPACE_HOLE] = FORBIDDEN_METRONOME, [MOVE_HYPERSPACE_HOLE] = FORBIDDEN_METRONOME,
[MOVE_ICE_BALL] = FORBIDDEN_INSTRUCT, [MOVE_ICE_BALL] = FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_ICE_BURN] = FORBIDDEN_METRONOME | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_ICE_BURN] = FORBIDDEN_METRONOME | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_ICICLE_SPEAR] = FORBIDDEN_PARENTAL_BOND,
[MOVE_INSTRUCT] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT, [MOVE_INSTRUCT] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT,
[MOVE_JUNGLE_HEALING] = FORBIDDEN_METRONOME, [MOVE_JUNGLE_HEALING] = FORBIDDEN_METRONOME,
[MOVE_KINGS_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_INSTRUCT, [MOVE_KINGS_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_INSTRUCT,
@ -1018,12 +1041,13 @@ static const u8 sForbiddenMoves[MOVES_COUNT] =
[MOVE_MAT_BLOCK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_MAT_BLOCK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_ME_FIRST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_ME_FIRST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_METEOR_ASSAULT] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT, [MOVE_METEOR_ASSAULT] = FORBIDDEN_METRONOME | FORBIDDEN_INSTRUCT,
[MOVE_METEOR_BEAM] = FORBIDDEN_INSTRUCT, [MOVE_METEOR_BEAM] = FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_METRONOME] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_METRONOME] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_MIMIC] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_MIMIC] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_MIND_BLOWN] = FORBIDDEN_METRONOME, [MOVE_MIND_BLOWN] = FORBIDDEN_METRONOME,
[MOVE_MIRROR_COAT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_MIRROR_COAT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_MIRROR_MOVE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_MIRROR_MOVE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_MISTY_EXPLOSION] = FORBIDDEN_PARENTAL_BOND,
[MOVE_MOONGEIST_BEAM] = FORBIDDEN_METRONOME, [MOVE_MOONGEIST_BEAM] = FORBIDDEN_METRONOME,
[MOVE_NATURE_POWER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_NATURE_POWER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_NATURES_MADNESS] = FORBIDDEN_METRONOME, [MOVE_NATURES_MADNESS] = FORBIDDEN_METRONOME,
@ -1031,42 +1055,43 @@ static const u8 sForbiddenMoves[MOVES_COUNT] =
[MOVE_ORIGIN_PULSE] = FORBIDDEN_METRONOME, [MOVE_ORIGIN_PULSE] = FORBIDDEN_METRONOME,
[MOVE_OUTRAGE] = FORBIDDEN_INSTRUCT, [MOVE_OUTRAGE] = FORBIDDEN_INSTRUCT,
[MOVE_OVERDRIVE] = FORBIDDEN_METRONOME, [MOVE_OVERDRIVE] = FORBIDDEN_METRONOME,
[MOVE_PETAL_DANCE] = FORBIDDEN_INSTRUCT, [MOVE_PHANTOM_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_PHANTOM_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_PHOTON_GEYSER] = FORBIDDEN_METRONOME, [MOVE_PHOTON_GEYSER] = FORBIDDEN_METRONOME,
[MOVE_PIKA_PAPOW] = FORBIDDEN_METRONOME,
[MOVE_PLASMA_FISTS] = FORBIDDEN_METRONOME,
[MOVE_PRECIPICE_BLADES] = FORBIDDEN_METRONOME,
[MOVE_PRISMATIC_LASER] = FORBIDDEN_INSTRUCT, [MOVE_PRISMATIC_LASER] = FORBIDDEN_INSTRUCT,
[MOVE_PROTECT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_PROTECT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_PYRO_BALL] = FORBIDDEN_METRONOME, [MOVE_PYRO_BALL] = FORBIDDEN_METRONOME,
[MOVE_QUASH] = FORBIDDEN_METRONOME, [MOVE_QUASH] = FORBIDDEN_METRONOME,
[MOVE_QUICK_GUARD] = FORBIDDEN_METRONOME, [MOVE_QUICK_GUARD] = FORBIDDEN_METRONOME,
[MOVE_RAGE_POWDER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_RAGE_POWDER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_RAZOR_WIND] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_RAZOR_WIND] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_RELIC_SONG] = FORBIDDEN_METRONOME, [MOVE_RELIC_SONG] = FORBIDDEN_METRONOME,
[MOVE_ROAR] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ROAR] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_ROAR_OF_TIME] = FORBIDDEN_INSTRUCT, [MOVE_ROAR_OF_TIME] = FORBIDDEN_INSTRUCT,
[MOVE_ROCK_BLAST] = FORBIDDEN_PARENTAL_BOND,
[MOVE_ROCK_WRECKER] = FORBIDDEN_INSTRUCT, [MOVE_ROCK_WRECKER] = FORBIDDEN_INSTRUCT,
[MOVE_ROLLOUT] = FORBIDDEN_INSTRUCT, [MOVE_ROLLOUT] = FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_SAPPY_SEED] = FORBIDDEN_METRONOME, [MOVE_SAPPY_SEED] = FORBIDDEN_METRONOME,
[MOVE_SCALE_SHOT] = FORBIDDEN_PARENTAL_BOND,
[MOVE_SECRET_SWORD] = FORBIDDEN_METRONOME, [MOVE_SECRET_SWORD] = FORBIDDEN_METRONOME,
[MOVE_SHADOW_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SELF_DESTRUCT] = FORBIDDEN_PARENTAL_BOND,
[MOVE_SHADOW_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_SHEER_COLD] = FORBIDDEN_PARENTAL_BOND,
[MOVE_SHELL_TRAP] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SHELL_TRAP] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_SIZZLY_SLIDE] = FORBIDDEN_METRONOME, [MOVE_SIZZLY_SLIDE] = FORBIDDEN_METRONOME,
[MOVE_SKETCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SKETCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_SKULL_BASH] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SKULL_BASH] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_SKY_ATTACK] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SKY_ATTACK] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_SKY_DROP] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SKY_DROP] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_SLEEP_TALK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SLEEP_TALK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT,
[MOVE_SNAP_TRAP] = FORBIDDEN_METRONOME, [MOVE_SNAP_TRAP] = FORBIDDEN_METRONOME,
[MOVE_SNARL] = FORBIDDEN_METRONOME, [MOVE_SNARL] = FORBIDDEN_METRONOME,
[MOVE_SNATCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_INSTRUCT, [MOVE_SNATCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_INSTRUCT,
[MOVE_SNORE] = FORBIDDEN_METRONOME, [MOVE_SNORE] = FORBIDDEN_METRONOME,
[MOVE_SOLAR_BEAM] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SOLAR_BEAM] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_SOLAR_BLADE] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_SOLAR_BLADE] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_SPARKLY_SWIRL] = FORBIDDEN_METRONOME, [MOVE_SPARKLY_SWIRL] = FORBIDDEN_METRONOME,
[MOVE_SPECTRAL_THIEF] = FORBIDDEN_METRONOME, [MOVE_SPECTRAL_THIEF] = FORBIDDEN_METRONOME,
[MOVE_SPIKE_CANNON] = FORBIDDEN_PARENTAL_BOND,
[MOVE_SPIKY_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_SPIKY_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_SPIRIT_BREAK] = FORBIDDEN_METRONOME, [MOVE_SPIRIT_BREAK] = FORBIDDEN_METRONOME,
[MOVE_SPLISHY_SPLASH] = FORBIDDEN_METRONOME, [MOVE_SPLISHY_SPLASH] = FORBIDDEN_METRONOME,
@ -1075,8 +1100,9 @@ static const u8 sForbiddenMoves[MOVES_COUNT] =
[MOVE_STEEL_BEAM] = FORBIDDEN_METRONOME, [MOVE_STEEL_BEAM] = FORBIDDEN_METRONOME,
[MOVE_STRANGE_STEAM] = FORBIDDEN_METRONOME, [MOVE_STRANGE_STEAM] = FORBIDDEN_METRONOME,
[MOVE_SUNSTEEL_STRIKE] = FORBIDDEN_METRONOME, [MOVE_SUNSTEEL_STRIKE] = FORBIDDEN_METRONOME,
[MOVE_SURGING_STRIKES] = FORBIDDEN_METRONOME, [MOVE_SURGING_STRIKES] = FORBIDDEN_METRONOME | FORBIDDEN_PARENTAL_BOND,
[MOVE_SWITCHEROO] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_SWITCHEROO] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_TAIL_SLAP] = FORBIDDEN_PARENTAL_BOND,
[MOVE_TECHNO_BLAST] = FORBIDDEN_METRONOME, [MOVE_TECHNO_BLAST] = FORBIDDEN_METRONOME,
[MOVE_THIEF] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_THIEF] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_THOUSAND_ARROWS] = FORBIDDEN_METRONOME, [MOVE_THOUSAND_ARROWS] = FORBIDDEN_METRONOME,
@ -1086,15 +1112,36 @@ static const u8 sForbiddenMoves[MOVES_COUNT] =
[MOVE_THUNDEROUS_KICK] = FORBIDDEN_METRONOME, [MOVE_THUNDEROUS_KICK] = FORBIDDEN_METRONOME,
[MOVE_TRANSFORM] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_INSTRUCT, [MOVE_TRANSFORM] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_INSTRUCT,
[MOVE_TRICK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_TRICK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_UPROAR] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT, [MOVE_TRIPLE_AXEL] = FORBIDDEN_PARENTAL_BOND,
[MOVE_TRIPLE_KICK] = FORBIDDEN_PARENTAL_BOND,
[MOVE_TWINEEDLE] = FORBIDDEN_PARENTAL_BOND,
[MOVE_UPROAR] = FORBIDDEN_SLEEP_TALK | FORBIDDEN_INSTRUCT | FORBIDDEN_PARENTAL_BOND,
[MOVE_V_CREATE] = FORBIDDEN_METRONOME, [MOVE_V_CREATE] = FORBIDDEN_METRONOME,
[MOVE_VEEVEE_VOLLEY] = FORBIDDEN_METRONOME, [MOVE_VEEVEE_VOLLEY] = FORBIDDEN_METRONOME,
[MOVE_WATER_SHURIKEN] = FORBIDDEN_PARENTAL_BOND,
[MOVE_WHIRLWIND] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_WHIRLWIND] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT,
[MOVE_WICKED_BLOW] = FORBIDDEN_METRONOME, [MOVE_WICKED_BLOW] = FORBIDDEN_METRONOME,
[MOVE_WIDE_GUARD] = FORBIDDEN_METRONOME, [MOVE_WIDE_GUARD] = FORBIDDEN_METRONOME,
[MOVE_ZIPPY_ZAP] = FORBIDDEN_METRONOME, [MOVE_ZIPPY_ZAP] = FORBIDDEN_METRONOME,
}; };
static const u16 sFinalStrikeOnlyEffects[] =
{
EFFECT_RELIC_SONG,
EFFECT_BUG_BITE,
EFFECT_THIEF,
EFFECT_BURN_UP,
EFFECT_SECRET_POWER,
EFFECT_SMACK_DOWN,
EFFECT_SPARKLING_ARIA,
EFFECT_SMELLINGSALT,
EFFECT_WAKE_UP_SLAP,
EFFECT_HIT_ESCAPE,
EFFECT_RECOIL_HP_25,
EFFECT_HIT_PREVENT_ESCAPE,
EFFECT_HIT_SWITCH_TARGET,
};
static const u16 sNaturePowerMoves[BATTLE_TERRAIN_COUNT] = static const u16 sNaturePowerMoves[BATTLE_TERRAIN_COUNT] =
{ {
#if B_NATURE_POWER_MOVES >= GEN_7 #if B_NATURE_POWER_MOVES >= GEN_7
@ -1404,6 +1451,18 @@ static void Cmd_attackcanceler(void)
if (AtkCanceller_UnableToUseMove()) if (AtkCanceller_UnableToUseMove())
return; return;
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF
&& GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND
&& IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker)
&& !(gAbsentBattlerFlags & gBitTable[gBattlerTarget])
&& gBattleStruct->zmove.toBeUsed[gBattlerAttacker] == MOVE_NONE)
{
gSpecialStatuses[gBattlerAttacker].parentalBondState = PARENTAL_BOND_1ST_HIT;
gMultiHitCounter = 2;
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
return;
}
// Check Protean activation. // Check Protean activation.
if ((attackerAbility == ABILITY_PROTEAN || attackerAbility == ABILITY_LIBERO) if ((attackerAbility == ABILITY_PROTEAN || attackerAbility == ABILITY_LIBERO)
&& (gBattleMons[gBattlerAttacker].type1 != moveType || gBattleMons[gBattlerAttacker].type2 != moveType || && (gBattleMons[gBattlerAttacker].type1 != moveType || gBattleMons[gBattlerAttacker].type2 != moveType ||
@ -1535,6 +1594,13 @@ static void Cmd_attackcanceler(void)
gMoveResultFlags |= MOVE_RESULT_MISSED; gMoveResultFlags |= MOVE_RESULT_MISSED;
gLastLandedMoves[gBattlerTarget] = 0; gLastLandedMoves[gBattlerTarget] = 0;
gLastHitByType[gBattlerTarget] = 0; gLastHitByType[gBattlerTarget] = 0;
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_1ST_HIT)
{
gSpecialStatuses[gBattlerAttacker].parentalBondState = PARENTAL_BOND_OFF; // No second hit if first hit was blocked
gSpecialStatuses[gBattlerAttacker].multiHitOn = 0;
gMultiHitCounter = 0;
}
gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED; gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED;
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
@ -1784,6 +1850,13 @@ static void Cmd_accuracycheck(void)
else if (!JumpIfMoveAffectedByProtect(0)) else if (!JumpIfMoveAffectedByProtect(0))
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
} }
else if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT
|| (gSpecialStatuses[gBattlerAttacker].multiHitOn && (gBattleMoves[move].effect != EFFECT_TRIPLE_KICK
|| GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK)))
{
// No acc checks for second hit of Parental Bond or multi hit moves, except Triple Kick/Triple Axel
gBattlescriptCurrInstr += 7;
}
else else
{ {
GET_MOVE_TYPE(move, type); GET_MOVE_TYPE(move, type);
@ -1866,7 +1939,8 @@ static void Cmd_ppreduce(void)
// For item Metronome, echoed voice // For item Metronome, echoed voice
if (gCurrentMove == gLastResultingMoves[gBattlerAttacker] if (gCurrentMove == gLastResultingMoves[gBattlerAttacker]
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& !WasUnableToUseMove(gBattlerAttacker)) && !WasUnableToUseMove(gBattlerAttacker)
&& gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT) // Don't increment counter on first hit
gBattleStruct->sameMoveTurns[gBattlerAttacker]++; gBattleStruct->sameMoveTurns[gBattlerAttacker]++;
else else
gBattleStruct->sameMoveTurns[gBattlerAttacker] = 0; gBattleStruct->sameMoveTurns[gBattlerAttacker] = 0;
@ -2183,6 +2257,12 @@ static void Cmd_attackanimation(void)
} }
else else
{ {
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT) // No animation on second hit
{
gBattlescriptCurrInstr++;
return;
}
if ((moveTarget & MOVE_TARGET_BOTH if ((moveTarget & MOVE_TARGET_BOTH
|| moveTarget & MOVE_TARGET_FOES_AND_ALLY || moveTarget & MOVE_TARGET_FOES_AND_ALLY
|| moveTarget & MOVE_TARGET_DEPENDS) || moveTarget & MOVE_TARGET_DEPENDS)
@ -2470,10 +2550,12 @@ static void Cmd_resultmessage(void)
switch (gMoveResultFlags & ~MOVE_RESULT_MISSED) switch (gMoveResultFlags & ~MOVE_RESULT_MISSED)
{ {
case MOVE_RESULT_SUPER_EFFECTIVE: case MOVE_RESULT_SUPER_EFFECTIVE:
stringId = STRINGID_SUPEREFFECTIVE; if (!gMultiHitCounter) // Don't print effectiveness on each hit in a multi hit attack
stringId = STRINGID_SUPEREFFECTIVE;
break; break;
case MOVE_RESULT_NOT_VERY_EFFECTIVE: case MOVE_RESULT_NOT_VERY_EFFECTIVE:
stringId = STRINGID_NOTVERYEFFECTIVE; if (!gMultiHitCounter)
stringId = STRINGID_NOTVERYEFFECTIVE;
break; break;
case MOVE_RESULT_ONE_HIT_KO: case MOVE_RESULT_ONE_HIT_KO:
stringId = STRINGID_ONEHITKO; stringId = STRINGID_ONEHITKO;
@ -2562,7 +2644,6 @@ static void Cmd_resultmessage(void)
if (gSpecialStatuses[gBattlerTarget].berryReduced if (gSpecialStatuses[gBattlerTarget].berryReduced
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
{ {
gLastUsedItem = gBattleMons[gBattlerTarget].item;
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE; gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
BattleScriptPushCursor(); BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_PrintBerryReduceString; gBattlescriptCurrInstr = BattleScript_PrintBerryReduceString;
@ -2709,9 +2790,19 @@ void SetMoveEffect(bool32 primary, u32 certain)
u32 flags = 0; u32 flags = 0;
u16 battlerAbility; u16 battlerAbility;
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_1ST_HIT
&& gBattleMons[gBattlerTarget].hp != 0
&& IsFinalStrikeEffect(gCurrentMove))
{
gBattlescriptCurrInstr++;
return;
}
switch (gBattleScripting.moveEffect) // Set move effects which happen later on switch (gBattleScripting.moveEffect) // Set move effects which happen later on
{ {
case MOVE_EFFECT_KNOCK_OFF: case MOVE_EFFECT_KNOCK_OFF:
case MOVE_EFFECT_SMACK_DOWN:
case MOVE_EFFECT_REMOVE_STATUS:
gBattleStruct->moveEffect2 = gBattleScripting.moveEffect; gBattleStruct->moveEffect2 = gBattleScripting.moveEffect;
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
return; return;
@ -3074,15 +3165,21 @@ void SetMoveEffect(bool32 primary, u32 certain)
} }
break; break;
case MOVE_EFFECT_PAYDAY: case MOVE_EFFECT_PAYDAY:
if (GET_BATTLER_SIDE(gBattlerAttacker) == B_SIDE_PLAYER) // Don't scatter coins on the second hit of Parental Bond
if (GET_BATTLER_SIDE(gBattlerAttacker) == B_SIDE_PLAYER && gSpecialStatuses[gBattlerAttacker].parentalBondState!= PARENTAL_BOND_2ND_HIT)
{ {
u16 payday = gPaydayMoney; u16 payday = gPaydayMoney;
gPaydayMoney += (gBattleMons[gBattlerAttacker].level * 5); gPaydayMoney += (gBattleMons[gBattlerAttacker].level * 5);
if (payday > gPaydayMoney) if (payday > gPaydayMoney)
gPaydayMoney = 0xFFFF; gPaydayMoney = 0xFFFF;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectPayDay;
}
else
{
gBattlescriptCurrInstr++;
} }
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect];
break; break;
case MOVE_EFFECT_HAPPY_HOUR: case MOVE_EFFECT_HAPPY_HOUR:
if (GET_BATTLER_SIDE(gBattlerAttacker) == B_SIDE_PLAYER && !gBattleStruct->moneyMultiplierMove) if (GET_BATTLER_SIDE(gBattlerAttacker) == B_SIDE_PLAYER && !gBattleStruct->moneyMultiplierMove)
@ -3320,34 +3417,6 @@ void SetMoveEffect(bool32 primary, u32 certain)
BattleScriptPush(gBattlescriptCurrInstr + 1); BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_RapidSpinAway; gBattlescriptCurrInstr = BattleScript_RapidSpinAway;
break; break;
case MOVE_EFFECT_REMOVE_STATUS: // Smelling salts
if (!(gBattleMons[gBattlerTarget].status1 & gBattleMoves[gCurrentMove].argument))
{
gBattlescriptCurrInstr++;
}
else
{
gBattleMons[gBattlerTarget].status1 &= ~gBattleMoves[gCurrentMove].argument;
gActiveBattler = gBattlerTarget;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
BattleScriptPush(gBattlescriptCurrInstr + 1);
switch (gBattleMoves[gCurrentMove].argument)
{
case STATUS1_PARALYSIS:
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal;
break;
case STATUS1_SLEEP:
gBattlescriptCurrInstr = BattleScript_TargetWokeUp;
break;
case STATUS1_BURN:
gBattlescriptCurrInstr = BattleScript_TargetBurnHeal;
break;
}
}
break;
case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower
if (!NoAliveMonsForEitherParty()) if (!NoAliveMonsForEitherParty())
{ {
@ -3362,42 +3431,12 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattlescriptCurrInstr = BattleScript_DefSpDefDown; gBattlescriptCurrInstr = BattleScript_DefSpDefDown;
} }
break; break;
case MOVE_EFFECT_RECOIL_25: // Take Down, 25% recoil
gBattleMoveDamage = (gHpDealt) / 4;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect];
break;
case MOVE_EFFECT_RECOIL_33: // Double Edge, 33 % recoil
gBattleMoveDamage = gHpDealt / 3;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect];
break;
case MOVE_EFFECT_RECOIL_50: // Head Smash, 50 % recoil
gBattleMoveDamage = gHpDealt / 2;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
break;
case MOVE_EFFECT_RECOIL_33_STATUS: // Flare Blitz - can burn, Volt Tackle - can paralyze
gBattleScripting.savedDmg = gHpDealt / 3;
if (gBattleScripting.savedDmg == 0)
gBattleScripting.savedDmg = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoilWithStatus;
break;
case MOVE_EFFECT_RECOIL_HP_25: // Struggle case MOVE_EFFECT_RECOIL_HP_25: // Struggle
gBattleMoveDamage = (gBattleMons[gEffectBattler].maxHP) / 4; gBattleMoveDamage = (gBattleMons[gEffectBattler].maxHP) / 4;
if (gBattleMoveDamage == 0) if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1; gBattleMoveDamage = 1;
if (GetBattlerAbility(gEffectBattler) == ABILITY_PARENTAL_BOND)
gBattleMoveDamage *= 2;
BattleScriptPush(gBattlescriptCurrInstr + 1); BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil; gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
@ -3435,15 +3474,6 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattlescriptCurrInstr = BattleScript_MoveEffectClearSmog; gBattlescriptCurrInstr = BattleScript_MoveEffectClearSmog;
} }
break; break;
case MOVE_EFFECT_SMACK_DOWN:
if (!IsBattlerGrounded(gBattlerTarget))
{
gStatuses3[gBattlerTarget] |= STATUS3_SMACKED_DOWN;
gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR);
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectSmackDown;
}
break;
case MOVE_EFFECT_FLAME_BURST: case MOVE_EFFECT_FLAME_BURST:
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget)) && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD) if (IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget)) && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD)
{ {
@ -3616,6 +3646,11 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattlescriptCurrInstr = BattleScript_DefDownSpeedUp; gBattlescriptCurrInstr = BattleScript_DefDownSpeedUp;
} }
break; break;
case MOVE_EFFECT_BURN_UP:
// This seems unnecessary but is done to make it work properly with Parental Bond
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_BurnUpRemoveType;
break;
} }
} }
} }
@ -5134,6 +5169,10 @@ static void Cmd_moveend(void)
{ {
switch (gBattleScripting.moveendState) switch (gBattleScripting.moveendState)
{ {
case MOVEEND_SUM_DAMAGE: // Sum and store damage dealt for multi strike recoil
gBattleScripting.savedDmg += gHpDealt;
gBattleScripting.moveendState++;
break;
case MOVEEND_PROTECT_LIKE_EFFECT: case MOVEEND_PROTECT_LIKE_EFFECT:
if (gProtectStructs[gBattlerAttacker].touchedProtectLike) if (gProtectStructs[gBattlerAttacker].touchedProtectLike)
{ {
@ -5232,6 +5271,42 @@ static void Cmd_moveend(void)
} }
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
case MOVEEND_RECOIL:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& IsBattlerAlive(gBattlerAttacker)
&& gBattleScripting.savedDmg != 0) // Some checks may be redundant alongside this one
{
switch (gBattleMoves[gCurrentMove].effect)
{
case EFFECT_RECOIL_25: // Take Down, 25% recoil
gBattleMoveDamage = max(1, gBattleScripting.savedDmg / 4);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
effect = TRUE;
break;
case EFFECT_RECOIL_33: // Double Edge, 33 % recoil
gBattleMoveDamage = max(1, gBattleScripting.savedDmg / 3);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
effect = TRUE;
break;
case EFFECT_RECOIL_50: // Head Smash, 50 % recoil
gBattleMoveDamage = max(1, gBattleScripting.savedDmg / 2);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
effect = TRUE;
break;
case EFFECT_RECOIL_33_STATUS: // Flare Blitz - can burn, Volt Tackle - can paralyze
gBattleMoveDamage = max(1, gBattleScripting.savedDmg / 3);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoilWithStatus;
effect = TRUE;
break;
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_SYNCHRONIZE_TARGET: // target synchronize case MOVEEND_SYNCHRONIZE_TARGET: // target synchronize
if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBattlerTarget, 0, 0, 0)) if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBattlerTarget, 0, 0, 0))
effect = TRUE; effect = TRUE;
@ -5299,15 +5374,51 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
case MOVEEND_MOVE_EFFECTS2: // For effects which should happen after target items, for example Knock Off after damage from Rocky Helmet. case MOVEEND_MOVE_EFFECTS2: // For effects which should happen after target items, for example Knock Off after damage from Rocky Helmet.
{
switch (gBattleStruct->moveEffect2) switch (gBattleStruct->moveEffect2)
{ {
case MOVE_EFFECT_KNOCK_OFF: case MOVE_EFFECT_KNOCK_OFF:
effect = TryKnockOffBattleScript(gBattlerTarget); effect = TryKnockOffBattleScript(gBattlerTarget);
break; break;
case MOVE_EFFECT_SMACK_DOWN:
if (!IsBattlerGrounded(gBattlerTarget) && IsBattlerAlive(gBattlerTarget))
{
gStatuses3[gBattlerTarget] |= STATUS3_SMACKED_DOWN;
gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR);
effect = TRUE;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectSmackDown;
}
break;
case MOVE_EFFECT_REMOVE_STATUS: // Smelling salts, Wake-Up Slap, Sparkling Aria
if ((gBattleMons[gBattlerTarget].status1 & gBattleMoves[gCurrentMove].argument) && IsBattlerAlive(gBattlerTarget))
{
gBattleMons[gBattlerTarget].status1 &= ~(gBattleMoves[gCurrentMove].argument);
gActiveBattler = gBattlerTarget;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
effect = TRUE;
BattleScriptPush(gBattlescriptCurrInstr + 1);
switch (gBattleMoves[gCurrentMove].argument)
{
case STATUS1_PARALYSIS:
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal;
break;
case STATUS1_SLEEP:
gBattlescriptCurrInstr = BattleScript_TargetWokeUp;
break;
case STATUS1_BURN:
gBattlescriptCurrInstr = BattleScript_TargetBurnHeal;
break;
}
}
break; // MOVE_EFFECT_REMOVE_STATUS
} }
gBattleStruct->moveEffect2 = 0; gBattleStruct->moveEffect2 = 0;
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break; // MOVEEND_MOVE_EFFECTS2
}
case MOVEEND_ITEM_EFFECTS_ALL: // item effects for all battlers case MOVEEND_ITEM_EFFECTS_ALL: // item effects for all battlers
if (ItemBattleEffects(ITEMEFFECT_MOVE_END, 0, FALSE)) if (ItemBattleEffects(ITEMEFFECT_MOVE_END, 0, FALSE))
effect = TRUE; effect = TRUE;
@ -5555,6 +5666,61 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
} }
case MOVEEND_MULTIHIT_MOVE:
{
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gMultiHitCounter
&& !(gCurrentMove == MOVE_PRESENT && gBattleStruct->presentBasePower == 0)) // Silly edge case
{
gBattleScripting.multihitString[4]++;
if (--gMultiHitCounter == 0)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings;
effect = TRUE;
}
else
{
if (gCurrentMove == MOVE_DRAGON_DARTS)
{
// TODO
}
if (gBattleMons[gBattlerAttacker].hp
&& gBattleMons[gBattlerTarget].hp
&& (gChosenMove == MOVE_SLEEP_TALK || !(gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP))
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE))
{
if (gSpecialStatuses[gBattlerAttacker].parentalBondState)
gSpecialStatuses[gBattlerAttacker].parentalBondState--;
gHitMarker |= (HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING);
gBattleScripting.animTargetsHit = 0;
gBattleScripting.moveendState = 0;
gSpecialStatuses[gBattlerTarget].sturdied = 0;
gSpecialStatuses[gBattlerTarget].focusBanded = 0; // Delete this line to make Focus Band last for the duration of the whole move turn.
gSpecialStatuses[gBattlerTarget].focusSashed = 0; // Delete this line to make Focus Sash last for the duration of the whole move turn.
gSpecialStatuses[gBattlerAttacker].multiHitOn = TRUE;
MoveValuesCleanUp();
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings;
effect = TRUE;
}
}
}
gMultiHitCounter = 0;
gSpecialStatuses[gBattlerAttacker].parentalBondState = PARENTAL_BOND_OFF;
gSpecialStatuses[gBattlerAttacker].multiHitOn = 0;
gBattleScripting.moveendState++;
break;
}
case MOVEEND_EJECT_BUTTON: case MOVEEND_EJECT_BUTTON:
if (gCurrentMove != MOVE_DRAGON_TAIL if (gCurrentMove != MOVE_DRAGON_TAIL
&& gCurrentMove != MOVE_CIRCLE_THROW && gCurrentMove != MOVE_CIRCLE_THROW
@ -9898,6 +10064,18 @@ static void Cmd_various(void)
else else
gBattleCommunication[0] = B_SIDE_OPPONENT; gBattleCommunication[0] = B_SIDE_OPPONENT;
break; break;
case VARIOUS_CHECK_PARENTAL_BOND_COUNTER:
{
// Some effects should only happen on the first or second strike of Parental Bond,
// so a way to check this in battle scripts is useful
u8 counter = T1_READ_8(gBattlescriptCurrInstr + 3);
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == counter && gBattleMons[gBattlerTarget].hp != 0)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4);
else
gBattlescriptCurrInstr += 8;
return;
}
break;
} // End of switch (gBattlescriptCurrInstr[2]) } // End of switch (gBattlescriptCurrInstr[2])
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;
@ -10372,10 +10550,13 @@ static void Cmd_stockpiletobasedamage(void)
if (gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED) if (gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED)
gBattleScripting.animTurn = gDisableStructs[gBattlerAttacker].stockpileCounter; gBattleScripting.animTurn = gDisableStructs[gBattlerAttacker].stockpileCounter;
gDisableStructs[gBattlerAttacker].stockpileCounter = 0; if (!(gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_1ST_HIT && gBattleMons[gBattlerTarget].hp != 0))
// Restore stat changes from stockpile. {
gBattleMons[gBattlerAttacker].statStages[STAT_DEF] -= gDisableStructs[gBattlerAttacker].stockpileDef; gDisableStructs[gBattlerAttacker].stockpileCounter = 0;
gBattleMons[gBattlerAttacker].statStages[STAT_SPDEF] -= gDisableStructs[gBattlerAttacker].stockpileSpDef; // Restore stat changes from stockpile.
gBattleMons[gBattlerAttacker].statStages[STAT_DEF] -= gDisableStructs[gBattlerAttacker].stockpileDef;
gBattleMons[gBattlerAttacker].statStages[STAT_SPDEF] -= gDisableStructs[gBattlerAttacker].stockpileSpDef;
}
gBattlescriptCurrInstr += 5; gBattlescriptCurrInstr += 5;
} }
} }
@ -12266,7 +12447,8 @@ static void Cmd_handlefurycutter(void)
} }
else else
{ {
if (gDisableStructs[gBattlerAttacker].furyCutterCounter != 5) if (gDisableStructs[gBattlerAttacker].furyCutterCounter != 5
&& gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT) // Don't increment counter on first hit
gDisableStructs[gBattlerAttacker].furyCutterCounter++; gDisableStructs[gBattlerAttacker].furyCutterCounter++;
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
@ -12291,27 +12473,37 @@ static void Cmd_presentdamagecalculation(void)
{ {
u32 rand = Random() & 0xFF; u32 rand = Random() & 0xFF;
if (rand < 102) /* Don't reroll present effect/power for the second hit of Parental Bond.
* Not sure if this is the correct behaviour, but bulbapedia states
* that if present heals the foe, it doesn't strike twice, and if it deals
* damage, the second strike will always deal damage too. This is a simple way
* to replicate that effect.
*/
if (gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_2ND_HIT)
{ {
gBattleStruct->presentBasePower = 40; if (rand < 102)
} {
else if (rand < 178) gBattleStruct->presentBasePower = 40;
{ }
gBattleStruct->presentBasePower = 80; else if (rand < 178)
} {
else if (rand < 204) gBattleStruct->presentBasePower = 80;
{ }
gBattleStruct->presentBasePower = 120; else if (rand < 204)
} {
else gBattleStruct->presentBasePower = 120;
{ }
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 4; else
if (gBattleMoveDamage == 0) {
gBattleMoveDamage = 1; gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 4;
gBattleMoveDamage *= -1; if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
gBattleStruct->presentBasePower = 0;
}
} }
if (rand < 204) if (gBattleStruct->presentBasePower)
{ {
gBattlescriptCurrInstr = BattleScript_HitFromCritCalc; gBattlescriptCurrInstr = BattleScript_HitFromCritCalc;
} }
@ -14643,3 +14835,44 @@ static bool32 CriticalCapture(u32 odds)
return FALSE; return FALSE;
#endif #endif
} }
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId)
{
if (gBattleMoves[move].split != SPLIT_STATUS
&& !(sForbiddenMoves[move] & FORBIDDEN_PARENTAL_BOND))
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
switch (GetBattlerMoveTargetType(battlerId, move))
{
// Both foes are alive, spread move strikes once
case MOVE_TARGET_BOTH:
if (CountAliveMonsInBattle(BATTLE_ALIVE_DEF_SIDE) >= 2)
return FALSE;
break;
// Either both foes or one foe and its ally are alive; spread move strikes once
case MOVE_TARGET_FOES_AND_ALLY:
if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ATTACKER) >= 2)
return FALSE;
break;
default:
break;
}
}
return TRUE;
}
return FALSE;
}
static bool8 IsFinalStrikeEffect(u16 move)
{
u32 i;
u16 moveEffect = gBattleMoves[move].effect;
for (i = 0; i < ARRAY_COUNT(sFinalStrikeOnlyEffects); i++)
{
if (moveEffect == sFinalStrikeOnlyEffects[i])
return TRUE;
}
return FALSE;
}

View File

@ -130,7 +130,7 @@ static const u16 sPoints_MoveEffect[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_DRAGON_RAGE] = 2, [EFFECT_DRAGON_RAGE] = 2,
[EFFECT_TRAP] = 4, [EFFECT_TRAP] = 4,
// [EFFECT_HIGH_CRITICAL] = 1, // [EFFECT_HIGH_CRITICAL] = 1,
[EFFECT_DOUBLE_HIT] = 1, // [EFFECT_DOUBLE_HIT] = 1,
[EFFECT_RECOIL_IF_MISS] = 1, [EFFECT_RECOIL_IF_MISS] = 1,
[EFFECT_MIST] = 5, [EFFECT_MIST] = 5,
[EFFECT_FOCUS_ENERGY] = 1, [EFFECT_FOCUS_ENERGY] = 1,
@ -163,7 +163,7 @@ static const u16 sPoints_MoveEffect[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_EVASION_DOWN_HIT] = 1, [EFFECT_EVASION_DOWN_HIT] = 1,
// [EFFECT_SKY_ATTACK] = 4, // [EFFECT_SKY_ATTACK] = 4,
[EFFECT_CONFUSE_HIT] = 1, [EFFECT_CONFUSE_HIT] = 1,
[EFFECT_TWINEEDLE] = 1, // [EFFECT_TWINEEDLE] = 1,
[EFFECT_VITAL_THROW] = 1, [EFFECT_VITAL_THROW] = 1,
[EFFECT_SUBSTITUTE] = 4, [EFFECT_SUBSTITUTE] = 4,
[EFFECT_RECHARGE] = 5, [EFFECT_RECHARGE] = 5,

View File

@ -59,6 +59,7 @@ functions instead of at the top of the file with the other declarations.
static bool32 TryRemoveScreens(u8 battler); static bool32 TryRemoveScreens(u8 battler);
static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId); static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId);
static u8 GetFlingPowerFromItemId(u16 itemId); static u8 GetFlingPowerFromItemId(u16 itemId);
static void SetRandomMultiHitCounter();
extern const u8 *const gBattleScriptsForMoveEffects[]; extern const u8 *const gBattleScriptsForMoveEffects[];
extern const u8 *const gBattlescriptsForRunningByItem[]; extern const u8 *const gBattlescriptsForRunningByItem[];
@ -218,6 +219,23 @@ static const u16 sEntrainmentTargetSimpleBeamBannedAbilities[] =
ABILITY_GULP_MISSILE, ABILITY_GULP_MISSILE,
}; };
static u8 CalcBeatUpPower(void)
{
struct Pokemon *party;
u8 basePower;
u16 species;
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
// Party slot is set in the battle script for Beat Up
species = GetMonData(&party[gBattleCommunication[0] - 1], MON_DATA_SPECIES);
basePower = (gBaseStats[species].baseAttack / 10) + 5;
return basePower;
}
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move) bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
{ {
u32 ability = GetBattlerAbility(battlerAtk); u32 ability = GetBattlerAbility(battlerAtk);
@ -252,6 +270,7 @@ void HandleAction_UseMove(void)
gBattleStruct->atkCancellerTracker = 0; gBattleStruct->atkCancellerTracker = 0;
gMoveResultFlags = 0; gMoveResultFlags = 0;
gMultiHitCounter = 0; gMultiHitCounter = 0;
gBattleScripting.savedDmg = 0;
gBattleCommunication[MISS_TYPE] = 0; gBattleCommunication[MISS_TYPE] = 0;
gBattleScripting.savedMoveEffect = 0; gBattleScripting.savedMoveEffect = 0;
gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker); gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker);
@ -3457,6 +3476,7 @@ enum
CANCELLER_POWDER_MOVE, CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS, CANCELLER_POWDER_STATUS,
CANCELLER_THROAT_CHOP, CANCELLER_THROAT_CHOP,
CANCELLER_MULTIHIT_MOVES,
CANCELLER_Z_MOVES, CANCELLER_Z_MOVES,
CANCELLER_END, CANCELLER_END,
CANCELLER_PSYCHIC_TERRAIN, CANCELLER_PSYCHIC_TERRAIN,
@ -3474,6 +3494,7 @@ u8 AtkCanceller_UnableToUseMove(void)
case CANCELLER_FLAGS: // flags clear case CANCELLER_FLAGS: // flags clear
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND; gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND;
gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE; gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE;
gBattleScripting.tripleKickPower = 0;
gBattleStruct->atkCancellerTracker++; gBattleStruct->atkCancellerTracker++;
break; break;
case CANCELLER_SKY_DROP: case CANCELLER_SKY_DROP:
@ -3831,6 +3852,67 @@ u8 AtkCanceller_UnableToUseMove(void)
} }
gBattleStruct->atkCancellerTracker++; gBattleStruct->atkCancellerTracker++;
break; break;
case CANCELLER_MULTIHIT_MOVES:
if (gBattleMoves[gCurrentMove].effect == EFFECT_MULTI_HIT)
{
u16 ability = gBattleMons[gBattlerAttacker].ability;
if (ability == ABILITY_SKILL_LINK)
{
gMultiHitCounter = 5;
}
else if (ability == ABILITY_BATTLE_BOND
&& gCurrentMove == MOVE_WATER_SHURIKEN
&& gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_ASH)
{
gMultiHitCounter = 3;
}
else
{
SetRandomMultiHitCounter();
}
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
}
else if (gBattleMoves[gCurrentMove].flags & FLAG_TWO_STRIKES)
{
gMultiHitCounter = 2;
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
if (gCurrentMove == MOVE_DRAGON_DARTS)
{
// TODO
}
}
else if (gBattleMoves[gCurrentMove].effect == EFFECT_TRIPLE_KICK || gCurrentMove == MOVE_SURGING_STRIKES)
{
gMultiHitCounter = 3;
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
}
#if B_BEAT_UP >= GEN_5
else if (gBattleMoves[gCurrentMove].effect == EFFECT_BEAT_UP)
{
struct Pokemon* party;
int i;
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&party[i], MON_DATA_HP)
&& GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& !GetMonData(&party[i], MON_DATA_STATUS))
gMultiHitCounter++;
}
gBattleCommunication[0] = 0; // For later
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
}
#endif
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_END: case CANCELLER_END:
break; break;
} }
@ -8410,6 +8492,11 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN)) if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN))
basePower *= 2; basePower *= 2;
break; break;
case EFFECT_BEAT_UP:
#if B_BEAT_UP >= GEN_5
basePower = CalcBeatUpPower();
#endif
break;
} }
// Move-specific base power changes // Move-specific base power changes
@ -9184,6 +9271,15 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
MulModifier(&finalModifier, UQ_4_12(0.5)); MulModifier(&finalModifier, UQ_4_12(0.5));
} }
// Parental Bond Second Strike
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT)
{
if (B_PARENTAL_BOND_DMG < GEN_7)
MulModifier(&finalModifier, UQ_4_12(0.5));
else
MulModifier(&finalModifier, UQ_4_12(0.25));
}
// attacker's abilities // attacker's abilities
switch (abilityAtk) switch (abilityAtk)
{ {
@ -9858,7 +9954,7 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId)
bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 battlerId) bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 battlerId)
{ {
#if B_BADGE_BOOST != GEN_3 #if B_BADGE_BOOST == GEN_3
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_FRONTIER)) if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_FRONTIER))
return FALSE; return FALSE;
else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
@ -9989,7 +10085,7 @@ bool32 CanFling(u8 battlerId)
#endif #endif
|| gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM
|| gDisableStructs[battlerId].embargoTimer != 0 || gDisableStructs[battlerId].embargoTimer != 0
|| GetFlingPowerFromItemId(item) != 0 || GetFlingPowerFromItemId(item) == 0
|| !CanBattlerGetOrLoseItem(battlerId, item)) || !CanBattlerGetOrLoseItem(battlerId, item))
return FALSE; return FALSE;
@ -10402,3 +10498,31 @@ bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move)
return FALSE; // Pokémon affected by Heal Block cannot target allies with Pollen Puff return FALSE; // Pokémon affected by Heal Block cannot target allies with Pollen Puff
return TRUE; return TRUE;
} }
static void SetRandomMultiHitCounter()
{
#if (B_MULTI_HIT_CHANCE >= GEN_5)
// Based on Gen 5's odds
// 35% for 2 hits
// 35% for 3 hits
// 15% for 4 hits
// 15% for 5 hits
gMultiHitCounter = Random() % 100;
if (gMultiHitCounter < 35)
gMultiHitCounter = 2;
else if (gMultiHitCounter < 35 + 35)
gMultiHitCounter = 3;
else if (gMultiHitCounter < 35 + 35 + 15)
gMultiHitCounter = 4;
else
gMultiHitCounter = 5;
#else
// 2 and 3 hits: 37.5%
// 4 and 5 hits: 12.5%
gMultiHitCounter = Random() % 4;
if (gMultiHitCounter > 1)
gMultiHitCounter = (Random() % 4) + 2;
else
gMultiHitCounter += 2;
#endif
}

View File

@ -1053,7 +1053,11 @@ void Bike_HandleBumpySlopeJump(void)
bool32 IsRunningDisallowed(u8 metatile) bool32 IsRunningDisallowed(u8 metatile)
{ {
#if OW_RUNNING_INDOORS == GEN_3
if (!gMapHeader.allowRunning || IsRunningDisallowedByMetatile(metatile) == TRUE) if (!gMapHeader.allowRunning || IsRunningDisallowedByMetatile(metatile) == TRUE)
#else
if (IsRunningDisallowedByMetatile(metatile) == TRUE)
#endif
return TRUE; return TRUE;
else else
return FALSE; return FALSE;

View File

@ -417,7 +417,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_DOUBLE_KICK] = [MOVE_DOUBLE_KICK] =
{ {
.effect = EFFECT_DOUBLE_HIT, .effect = EFFECT_HIT,
.power = 30, .power = 30,
.type = TYPE_FIGHTING, .type = TYPE_FIGHTING,
.accuracy = 100, .accuracy = 100,
@ -725,7 +725,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_TWINEEDLE] = [MOVE_TWINEEDLE] =
{ {
.effect = EFFECT_TWINEEDLE, .effect = EFFECT_POISON_HIT,
.power = 25, .power = 25,
.type = TYPE_BUG, .type = TYPE_BUG,
.accuracy = 100, .accuracy = 100,
@ -2782,7 +2782,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_BONEMERANG] = [MOVE_BONEMERANG] =
{ {
.effect = EFFECT_DOUBLE_HIT, .effect = EFFECT_HIT,
.power = 50, .power = 50,
.type = TYPE_GROUND, .type = TYPE_GROUND,
.accuracy = 90, .accuracy = 90,
@ -8224,7 +8224,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_DOUBLE_HIT] = [MOVE_DOUBLE_HIT] =
{ {
.effect = EFFECT_DOUBLE_HIT, .effect = EFFECT_HIT,
.power = 35, .power = 35,
.type = TYPE_NORMAL, .type = TYPE_NORMAL,
.accuracy = 90, .accuracy = 90,
@ -9477,7 +9477,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_DUAL_CHOP] = [MOVE_DUAL_CHOP] =
{ {
.effect = EFFECT_DOUBLE_HIT, .effect = EFFECT_HIT,
.power = 40, .power = 40,
.type = TYPE_DRAGON, .type = TYPE_DRAGON,
.accuracy = 90, .accuracy = 90,
@ -9714,7 +9714,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_GEAR_GRIND] = [MOVE_GEAR_GRIND] =
{ {
.effect = EFFECT_DOUBLE_HIT, .effect = EFFECT_HIT,
.power = 50, .power = 50,
.type = TYPE_STEEL, .type = TYPE_STEEL,
.accuracy = 85, .accuracy = 85,
@ -11387,7 +11387,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
.type = TYPE_FIRE, .type = TYPE_FIRE,
.accuracy = 100, .accuracy = 100,
.pp = 5, .pp = 5,
.secondaryEffectChance = 0, .secondaryEffectChance = 100,
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_THAW_USER, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_THAW_USER,
@ -12181,7 +12181,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
#else #else
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST | FLAG_TWO_STRIKES, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST | FLAG_TWO_STRIKES,
#endif #endif
.effect = EFFECT_DOUBLE_IRON_BASH, .effect = EFFECT_FLINCH_HIT,
.power = 60, .power = 60,
.type = TYPE_STEEL, .type = TYPE_STEEL,
.accuracy = 100, .accuracy = 100,
@ -13029,7 +13029,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_DUAL_WINGBEAT] = [MOVE_DUAL_WINGBEAT] =
{ {
.effect = EFFECT_DOUBLE_HIT, .effect = EFFECT_HIT,
.power = 40, .power = 40,
.type = TYPE_FLYING, .type = TYPE_FLYING,
.accuracy = 90, .accuracy = 90,
@ -13092,7 +13092,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_SURGING_STRIKES] = [MOVE_SURGING_STRIKES] =
{ {
.effect = EFFECT_TRIPLE_HIT, .effect = EFFECT_ALWAYS_CRIT,
.power = 25, .power = 25,
.type = TYPE_WATER, .type = TYPE_WATER,
.accuracy = 100, .accuracy = 100,

View File

@ -1565,7 +1565,7 @@ const struct Item gItems[] =
.description = sLureDesc, .description = sLureDesc,
.pocket = POCKET_ITEMS, .pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU, .type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, .fieldUseFunc = ItemUseOutOfBattle_Lure,
.secondaryId = 0, .secondaryId = 0,
.flingPower = 30, .flingPower = 30,
}, },
@ -1579,7 +1579,7 @@ const struct Item gItems[] =
.description = sSuperLureDesc, .description = sSuperLureDesc,
.pocket = POCKET_ITEMS, .pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU, .type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, .fieldUseFunc = ItemUseOutOfBattle_Lure,
.secondaryId = 0, .secondaryId = 0,
.flingPower = 30, .flingPower = 30,
}, },
@ -1593,7 +1593,7 @@ const struct Item gItems[] =
.description = sMaxLureDesc, .description = sMaxLureDesc,
.pocket = POCKET_ITEMS, .pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU, .type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, .fieldUseFunc = ItemUseOutOfBattle_Lure,
.secondaryId = 0, .secondaryId = 0,
.flingPower = 30, .flingPower = 30,
}, },
@ -2035,8 +2035,8 @@ const struct Item gItems[] =
.price = 300, .price = 300,
.description = sHoneyDesc, .description = sHoneyDesc,
.pocket = POCKET_ITEMS, .pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU, .type = ITEM_USE_FIELD,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, .fieldUseFunc = ItemUseOutOfBattle_Honey,
.flingPower = 30, .flingPower = 30,
}, },

File diff suppressed because it is too large Load Diff

View File

@ -2792,16 +2792,6 @@ static void DebugAction_Give_CHEAT(u8 taskId)
ScriptContext_SetupScript(Debug_CheatStart); ScriptContext_SetupScript(Debug_CheatStart);
} }
static void Task_WaitFadeAccessPC(u8 taskId)
{
if (!gPaletteFade.active)
{
DestroyTask(taskId);
FlagSet(DEBUG_FLAG_PC_FROM_DEBUG_MENU);
EnterPokeStorage(2);
}
}
static void DebugAction_AccessPC(u8 taskId) static void DebugAction_AccessPC(u8 taskId)
{ {
Debug_DestroyMenu_Full(taskId); Debug_DestroyMenu_Full(taskId);

View File

@ -19,7 +19,6 @@
#include "constants/songs.h" #include "constants/songs.h"
static void FieldCallback_SweetScent(void); static void FieldCallback_SweetScent(void);
static void StartSweetScentFieldEffect(void);
static void TrySweetScentEncounter(u8 taskId); static void TrySweetScentEncounter(u8 taskId);
static void FailSweetScentEncounter(u8 taskId); static void FailSweetScentEncounter(u8 taskId);
@ -47,14 +46,15 @@ bool8 FldEff_SweetScent(void)
return FALSE; return FALSE;
} }
static void StartSweetScentFieldEffect(void) void StartSweetScentFieldEffect(void)
{ {
u8 taskId; u8 taskId;
u32 palettes = ~(1 << (gSprites[GetPlayerAvatarSpriteId()].oam.paletteNum + 16) | (1 << 13) | (1 << 14) | (1 << 15));
PlaySE(SE_M_SWEET_SCENT); PlaySE(SE_M_SWEET_SCENT);
CpuFastSet(gPlttBufferUnfaded, gPaletteDecompressionBuffer, 0x100); CpuFastSet(gPlttBufferUnfaded, gPaletteDecompressionBuffer, 0x100);
CpuFastSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x100); CpuFastSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x100);
BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarSpriteId()].oam.paletteNum + 16)), 4, 0, 8, RGB_RED); BeginNormalPaletteFade(palettes, 4, 0, 8, RGB_RED);
taskId = CreateTask(TrySweetScentEncounter, 0); taskId = CreateTask(TrySweetScentEncounter, 0);
gTasks[taskId].data[0] = 0; gTasks[taskId].data[0] = 0;
FieldEffectActiveListRemove(FLDEFF_SWEET_SCENT); FieldEffectActiveListRemove(FLDEFF_SWEET_SCENT);

View File

@ -880,12 +880,6 @@ const u8 *ItemId_GetName(u16 itemId)
return gItems[SanitizeItemId(itemId)].name; return gItems[SanitizeItemId(itemId)].name;
} }
// Unused
u16 ItemId_GetId(u16 itemId)
{
return gItems[SanitizeItemId(itemId)].itemId;
}
u16 ItemId_GetPrice(u16 itemId) u16 ItemId_GetPrice(u16 itemId)
{ {
return gItems[SanitizeItemId(itemId)].price; return gItems[SanitizeItemId(itemId)].price;

View File

@ -18,6 +18,7 @@
#include "field_player_avatar.h" #include "field_player_avatar.h"
#include "field_screen_effect.h" #include "field_screen_effect.h"
#include "field_weather.h" #include "field_weather.h"
#include "fldeff.h"
#include "item.h" #include "item.h"
#include "item_menu.h" #include "item_menu.h"
#include "item_use.h" #include "item_use.h"
@ -67,10 +68,13 @@ static void Task_ShowTMHMContainedMessage(u8);
static void UseTMHMYesNo(u8); static void UseTMHMYesNo(u8);
static void UseTMHM(u8); static void UseTMHM(u8);
static void Task_StartUseRepel(u8); static void Task_StartUseRepel(u8);
static void Task_StartUseLure(u8 taskId);
static void Task_UseRepel(u8); static void Task_UseRepel(u8);
static void Task_UseLure(u8 taskId);
static void Task_CloseCantUseKeyItemMessage(u8); static void Task_CloseCantUseKeyItemMessage(u8);
static void SetDistanceOfClosestHiddenItem(u8, s16, s16); static void SetDistanceOfClosestHiddenItem(u8, s16, s16);
static void CB2_OpenPokeblockFromBag(void); static void CB2_OpenPokeblockFromBag(void);
static void ItemUseOnFieldCB_Honey(u8 taskId);
// EWRAM variables // EWRAM variables
EWRAM_DATA static void(*sItemUseOnFieldCB)(u8 taskId) = NULL; EWRAM_DATA static void(*sItemUseOnFieldCB)(u8 taskId) = NULL;
@ -846,7 +850,7 @@ static void RemoveUsedItem(void)
void ItemUseOutOfBattle_Repel(u8 taskId) void ItemUseOutOfBattle_Repel(u8 taskId)
{ {
if (VarGet(VAR_REPEL_STEP_COUNT) == 0) if (REPEL_STEP_COUNT == 0)
gTasks[taskId].func = Task_StartUseRepel; gTasks[taskId].func = Task_StartUseRepel;
else if (!InBattlePyramid()) else if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gText_RepelEffectsLingered, CloseItemMessage); DisplayItemMessage(taskId, FONT_NORMAL, gText_RepelEffectsLingered, CloseItemMessage);
@ -871,6 +875,9 @@ static void Task_UseRepel(u8 taskId)
if (!IsSEPlaying()) if (!IsSEPlaying())
{ {
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId)); VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId));
#if VAR_LAST_REPEL_LURE_USED != 0
VarSet(VAR_LAST_REPEL_LURE_USED, gSpecialVar_ItemId);
#endif
RemoveUsedItem(); RemoveUsedItem();
if (!InBattlePyramid()) if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage); DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage);
@ -878,6 +885,57 @@ static void Task_UseRepel(u8 taskId)
DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage); DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage);
} }
} }
void HandleUseExpiredRepel(void)
{
#if VAR_LAST_REPEL_LURE_USED != 0
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(VarGet(VAR_LAST_REPEL_LURE_USED)));
#endif
}
void ItemUseOutOfBattle_Lure(u8 taskId)
{
if (LURE_STEP_COUNT == 0)
gTasks[taskId].func = Task_StartUseLure;
else if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gText_LureEffectsLingered, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, gText_LureEffectsLingered, Task_CloseBattlePyramidBagMessage);
}
static void Task_StartUseLure(u8 taskId)
{
s16* data = gTasks[taskId].data;
if (++data[8] > 7)
{
data[8] = 0;
PlaySE(SE_REPEL);
gTasks[taskId].func = Task_UseLure;
}
}
static void Task_UseLure(u8 taskId)
{
if (!IsSEPlaying())
{
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId) | REPEL_LURE_MASK);
#if VAR_LAST_REPEL_LURE_USED != 0
VarSet(VAR_LAST_REPEL_LURE_USED, gSpecialVar_ItemId);
#endif
RemoveUsedItem();
if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage);
}
}
void HandleUseExpiredLure(void)
{
#if VAR_LAST_REPEL_LURE_USED != 0
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(VarGet(VAR_LAST_REPEL_LURE_USED)) | REPEL_LURE_MASK);
#endif
}
static void Task_UsedBlackWhiteFlute(u8 taskId) static void Task_UsedBlackWhiteFlute(u8 taskId)
{ {
@ -1202,6 +1260,29 @@ void ItemUseOutOfBattle_FormChange_ConsumedOnUse(u8 taskId)
SetUpItemUseCallback(taskId); SetUpItemUseCallback(taskId);
} }
void Task_UseHoneyOnField(u8 taskId)
{
//ResetInitialPlayerAvatarState();
StartSweetScentFieldEffect();
DestroyTask(taskId);
}
static void ItemUseOnFieldCB_Honey(u8 taskId)
{
Overworld_ResetStateAfterDigEscRope();
RemoveUsedItem();
gTasks[taskId].data[0] = 0;
DisplayItemMessageOnField(taskId, gStringVar4, Task_UseHoneyOnField);
}
void ItemUseOutOfBattle_Honey(u8 taskId)
{
sItemUseOnFieldCB = ItemUseOnFieldCB_Honey;
gFieldCallback = FieldCB_UseItemOnField;
gBagMenu->newScreenCallback = CB2_ReturnToField;
Task_FadeAndCloseBagMenu(taskId);
}
void ItemUseOutOfBattle_CannotUse(u8 taskId) void ItemUseOutOfBattle_CannotUse(u8 taskId)
{ {
DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem); DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);

View File

@ -408,9 +408,7 @@ static void IntrDummy(void)
static void WaitForVBlank(void) static void WaitForVBlank(void)
{ {
gMain.intrCheck &= ~INTR_FLAG_VBLANK; gMain.intrCheck &= ~INTR_FLAG_VBLANK;
VBlankIntrWait();
while (!(gMain.intrCheck & INTR_FLAG_VBLANK))
;
} }
void SetTrainerHillVBlankCounter(u32 *counter) void SetTrainerHillVBlankCounter(u32 *counter)

View File

@ -4928,6 +4928,7 @@ void ItemUseCB_TMHM(u8 taskId, TaskFunc task)
u16 move = ItemIdToBattleMoveId(item); u16 move = ItemIdToBattleMoveId(item);
gPartyMenu.data1 = move; gPartyMenu.data1 = move;
gPartyMenu.learnMoveState = 0;
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
mon = &gPlayerParty[gPartyMenu.slotId]; mon = &gPlayerParty[gPartyMenu.slotId];

View File

@ -3329,7 +3329,6 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
} }
else // Player is the OT else // Player is the OT
{ {
u32 shinyValue;
value = gSaveBlock2Ptr->playerTrainerId[0] value = gSaveBlock2Ptr->playerTrainerId[0]
| (gSaveBlock2Ptr->playerTrainerId[1] << 8) | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
| (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
@ -3337,22 +3336,24 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
if (gBaseStats[species].flags & SPECIES_FLAG_SHINY_LOCKED) if (gBaseStats[species].flags & SPECIES_FLAG_SHINY_LOCKED)
{ {
do while (GET_SHINY_VALUE(value, personality) < SHINY_ODDS)
{ {
// Choose random personalities until one that results in a non-shiny Pokémon
personality = Random32(); personality = Random32();
shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality); }
} while (shinyValue < SHINY_ODDS);
} }
else if (CheckBagHasItem(ITEM_SHINY_CHARM, 1)) else
{ {
u32 rolls = 0; u32 totalRerolls = 0;
do if (CheckBagHasItem(ITEM_SHINY_CHARM, 1))
totalRerolls += I_SHINY_CHARM_REROLLS;
if (LURE_STEP_COUNT != 0)
totalRerolls += 1;
while (GET_SHINY_VALUE(value, personality) >= SHINY_ODDS && totalRerolls > 0)
{ {
personality = Random32(); personality = Random32();
shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality); totalRerolls--;
rolls++; }
} while (shinyValue >= SHINY_ODDS && rolls < I_SHINY_CHARM_REROLLS);
} }
} }
@ -4238,6 +4239,13 @@ u8 CountAliveMonsInBattle(u8 caseId)
retVal++; retVal++;
} }
break; break;
case BATTLE_ALIVE_EXCEPT_ATTACKER:
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (i != gBattlerAttacker && !(gAbsentBattlerFlags & gBitTable[i]))
retVal++;
}
break;
} }
return retVal; return retVal;

View File

@ -1380,7 +1380,7 @@ static void UpdateSubmenuOneOptionValue(u8 taskId, bool8 increment)
UpdateBattlerValue(data); UpdateBattlerValue(data);
ReloadPokemonSprites(data); ReloadPokemonSprites(data);
while (!(gMain.intrCheck & INTR_FLAG_VBLANK)); VBlankIntrWait();
PlaySE(SE_DEX_SCROLL); PlaySE(SE_DEX_SCROLL);
} }
break; break;
@ -1499,7 +1499,7 @@ static void Handle_Input_Debug_Pokemon(u8 taskId)
PrintDigitChars(data); PrintDigitChars(data);
UpdateBattlerValue(data); UpdateBattlerValue(data);
ReloadPokemonSprites(data); ReloadPokemonSprites(data);
while (!(gMain.intrCheck & INTR_FLAG_VBLANK)); VBlankIntrWait();
PlaySE(SE_DEX_SCROLL); PlaySE(SE_DEX_SCROLL);
} }
@ -1531,7 +1531,7 @@ static void Handle_Input_Debug_Pokemon(u8 taskId)
ResetOffsetSpriteValues(data); ResetOffsetSpriteValues(data);
} }
PlaySE(SE_DEX_SCROLL); PlaySE(SE_DEX_SCROLL);
while (!(gMain.intrCheck & INTR_FLAG_VBLANK)); VBlankIntrWait();
} }
else if (JOY_NEW(DPAD_UP)) else if (JOY_NEW(DPAD_UP))
{ {

View File

@ -1669,18 +1669,10 @@ static void FieldTask_ReturnToPcMenu(void)
MainCallback vblankCb = gMain.vblankCallback; MainCallback vblankCb = gMain.vblankCallback;
SetVBlankCallback(NULL); SetVBlankCallback(NULL);
if (!FlagGet(DEBUG_FLAG_PC_FROM_DEBUG_MENU)) taskId = CreateTask(Task_PCMainMenu, 80);
{ gTasks[taskId].tState = 0;
taskId = CreateTask(Task_PCMainMenu, 80); gTasks[taskId].tSelectedOption = sPreviousBoxOption;
gTasks[taskId].tState = 0; Task_PCMainMenu(taskId);
gTasks[taskId].tSelectedOption = sPreviousBoxOption;
Task_PCMainMenu(taskId);
}
else
{
FlagClear(DEBUG_FLAG_PC_FROM_DEBUG_MENU);
ScriptContext_Enable();
}
SetVBlankCallback(vblankCb); SetVBlankCallback(vblankCb);
FadeInFromBlack(); FadeInFromBlack();
} }

View File

@ -90,12 +90,10 @@ static u16 GetLengthWithExpandedPlayerName(const u8 *str)
return length; return length;
} }
static void DrawMultichoiceMenu(u8 left, u8 top, u8 multichoiceId, bool8 ignoreBPress, u8 cursorPos) static void DrawMultichoiceMenuInternal(u8 left, u8 top, u8 multichoiceId, bool8 ignoreBPress, u8 cursorPos, const struct MenuAction *actions, int count)
{ {
int i; int i;
u8 windowId; u8 windowId;
u8 count = sMultichoiceLists[multichoiceId].count;
const struct MenuAction *actions = sMultichoiceLists[multichoiceId].list;
int width = 0; int width = 0;
u8 newWidth; u8 newWidth;
@ -114,6 +112,84 @@ static void DrawMultichoiceMenu(u8 left, u8 top, u8 multichoiceId, bool8 ignoreB
InitMultichoiceCheckWrap(ignoreBPress, count, windowId, multichoiceId); InitMultichoiceCheckWrap(ignoreBPress, count, windowId, multichoiceId);
} }
static void DrawMultichoiceMenu(u8 left, u8 top, u8 multichoiceId, bool8 ignoreBPress, u8 cursorPos)
{
DrawMultichoiceMenuInternal(left, top, multichoiceId, ignoreBPress, cursorPos, sMultichoiceLists[multichoiceId].list, sMultichoiceLists[multichoiceId].count);
}
#if I_REPEL_LURE_MENU == TRUE
void TryDrawRepelMenu(void)
{
static const u16 repelItems[] = {ITEM_REPEL, ITEM_SUPER_REPEL, ITEM_MAX_REPEL};
struct MenuAction menuItems[ARRAY_COUNT(repelItems) + 1] = {NULL};
int i, count = 0, menuPos = 0;
for (i = 0; i < ARRAY_COUNT(repelItems); i++)
{
if (CheckBagHasItem(repelItems[i], 1))
{
VarSet(VAR_0x8004 + count, repelItems[i]);
#if VAR_LAST_REPEL_LURE_USED != 0
if (VarGet(VAR_LAST_REPEL_LURE_USED) == repelItems[i])
menuPos = count;
#endif
menuItems[count].text = ItemId_GetName(repelItems[i]);
count++;
}
}
if (count > 1)
DrawMultichoiceMenuInternal(0, 0, 0, FALSE, menuPos, menuItems, count);
gSpecialVar_Result = (count > 1);
}
void HandleRepelMenuChoice(void)
{
gSpecialVar_0x8004 = VarGet(VAR_0x8004 + gSpecialVar_Result); // Get item Id;
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_0x8004));
#if VAR_LAST_REPEL_LURE_USED != 0
VarSet(VAR_LAST_REPEL_LURE_USED, gSpecialVar_0x8004);
#endif
}
void TryDrawLureMenu(void)
{
static const u16 lureItems[] = {ITEM_LURE, ITEM_SUPER_LURE, ITEM_MAX_LURE};
struct MenuAction menuItems[ARRAY_COUNT(lureItems) + 1] = {NULL};
int i, count = 0, menuPos = 0;
for (i = 0; i < ARRAY_COUNT(lureItems); i++)
{
if (CheckBagHasItem(lureItems[i], 1))
{
VarSet(VAR_0x8004 + count, lureItems[i]);
#if VAR_LAST_REPEL_LURE_USED != 0
if (VarGet(VAR_LAST_REPEL_LURE_USED) == lureItems[i])
menuPos = count;
#endif
menuItems[count].text = ItemId_GetName(lureItems[i]);
count++;
}
}
if (count > 1)
DrawMultichoiceMenuInternal(0, 0, 0, FALSE, menuPos, menuItems, count);
gSpecialVar_Result = (count > 1);
}
void HandleLureMenuChoice(void)
{
gSpecialVar_0x8004 = VarGet(VAR_0x8004 + gSpecialVar_Result); // Get item Id;
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_0x8004) | REPEL_LURE_MASK);
#if VAR_LAST_REPEL_LURE_USED != 0
VarSet(VAR_LAST_REPEL_LURE_USED, gSpecialVar_0x8004);
#endif
}
#endif //I_REPEL_LURE_MENU == TRUE
#define tLeft data[0] #define tLeft data[0]
#define tTop data[1] #define tTop data[1]
#define tRight data[2] #define tRight data[2]

View File

@ -244,6 +244,7 @@ const u8 gText_BootedUpHM[] = _("Booted up an HM.");
const u8 gText_TMHMContainedVar1[] = _("It contained\n{STR_VAR_1}.\pTeach {STR_VAR_1}\nto a POKéMON?"); const u8 gText_TMHMContainedVar1[] = _("It contained\n{STR_VAR_1}.\pTeach {STR_VAR_1}\nto a POKéMON?");
const u8 gText_PlayerUsedVar2[] = _("{PLAYER} used the\n{STR_VAR_2}.{PAUSE_UNTIL_PRESS}"); const u8 gText_PlayerUsedVar2[] = _("{PLAYER} used the\n{STR_VAR_2}.{PAUSE_UNTIL_PRESS}");
const u8 gText_RepelEffectsLingered[] = _("But the effects of a REPEL\nlingered from earlier.{PAUSE_UNTIL_PRESS}"); const u8 gText_RepelEffectsLingered[] = _("But the effects of a REPEL\nlingered from earlier.{PAUSE_UNTIL_PRESS}");
const u8 gText_LureEffectsLingered[] = _("But the effects of a Lure\nlingered from earlier.{PAUSE_UNTIL_PRESS}");
const u8 gText_UsedVar2WildLured[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be lured.{PAUSE_UNTIL_PRESS}"); const u8 gText_UsedVar2WildLured[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be lured.{PAUSE_UNTIL_PRESS}");
const u8 gText_UsedVar2WildRepelled[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be repelled.{PAUSE_UNTIL_PRESS}"); const u8 gText_UsedVar2WildRepelled[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be repelled.{PAUSE_UNTIL_PRESS}");
const u8 gText_BoxFull[] = _("The BOX is full.{PAUSE_UNTIL_PRESS}"); const u8 gText_BoxFull[] = _("The BOX is full.{PAUSE_UNTIL_PRESS}");

View File

@ -20,11 +20,13 @@
#include "constants/abilities.h" #include "constants/abilities.h"
#include "constants/battle_config.h" #include "constants/battle_config.h"
#include "constants/game_stat.h" #include "constants/game_stat.h"
#include "constants/item.h"
#include "constants/items.h" #include "constants/items.h"
#include "constants/layouts.h" #include "constants/layouts.h"
#include "constants/weather.h" #include "constants/weather.h"
extern const u8 EventScript_RepelWoreOff[]; extern const u8 EventScript_RepelWoreOff[];
extern const u8 EventScript_LureWoreOff[];
#define MAX_ENCOUNTER_RATE 2880 #define MAX_ENCOUNTER_RATE 2880
@ -54,6 +56,7 @@ static void FeebasSeedRng(u16 seed);
static bool8 IsWildLevelAllowedByRepel(u8 level); static bool8 IsWildLevelAllowedByRepel(u8 level);
static void ApplyFluteEncounterRateMod(u32 *encRate); static void ApplyFluteEncounterRateMod(u32 *encRate);
static void ApplyCleanseTagEncounterRateMod(u32 *encRate); static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16 species, u8 area);
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u16 ability, u8 *monIndex); static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u16 ability, u8 *monIndex);
static bool8 IsAbilityAllowingEncounter(u8 level); static bool8 IsAbilityAllowingEncounter(u8 level);
@ -181,58 +184,82 @@ static void FeebasSeedRng(u16 seed)
// LAND_WILD_COUNT // LAND_WILD_COUNT
static u8 ChooseWildMonIndex_Land(void) static u8 ChooseWildMonIndex_Land(void)
{ {
u8 wildMonIndex = 0;
bool8 swap = FALSE;
u8 rand = Random() % ENCOUNTER_CHANCE_LAND_MONS_TOTAL; u8 rand = Random() % ENCOUNTER_CHANCE_LAND_MONS_TOTAL;
if (rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_0) if (rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_0)
return 0; wildMonIndex = 0;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_1) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_1)
return 1; wildMonIndex = 1;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_2) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_2)
return 2; wildMonIndex = 2;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_3) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_3)
return 3; wildMonIndex = 3;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_4) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_4)
return 4; wildMonIndex = 4;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_5) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_5)
return 5; wildMonIndex = 5;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_6) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_6)
return 6; wildMonIndex = 6;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_7) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_7)
return 7; wildMonIndex = 7;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_8) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_8)
return 8; wildMonIndex = 8;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_9) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_9)
return 9; wildMonIndex = 9;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_9 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_10) else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_9 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_10)
return 10; wildMonIndex = 10;
else else
return 11; wildMonIndex = 11;
if (LURE_STEP_COUNT != 0 && (Random() % 10 < 2))
swap = TRUE;
if (swap)
wildMonIndex = 11 - wildMonIndex;
return wildMonIndex;
} }
// ROCK_WILD_COUNT / WATER_WILD_COUNT // ROCK_WILD_COUNT / WATER_WILD_COUNT
static u8 ChooseWildMonIndex_WaterRock(void) static u8 ChooseWildMonIndex_WaterRock(void)
{ {
u8 wildMonIndex = 0;
bool8 swap = FALSE;
u8 rand = Random() % ENCOUNTER_CHANCE_WATER_MONS_TOTAL; u8 rand = Random() % ENCOUNTER_CHANCE_WATER_MONS_TOTAL;
if (rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_0) if (rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_0)
return 0; wildMonIndex = 0;
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_1) else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_1)
return 1; wildMonIndex = 1;
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_2) else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_2)
return 2; wildMonIndex = 2;
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_3) else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_3)
return 3; wildMonIndex = 3;
else else
return 4; wildMonIndex = 4;
if (LURE_STEP_COUNT != 0 && (Random() % 10 < 2))
swap = TRUE;
if (swap)
wildMonIndex = 4 - wildMonIndex;
return wildMonIndex;
} }
// FISH_WILD_COUNT // FISH_WILD_COUNT
static u8 ChooseWildMonIndex_Fishing(u8 rod) static u8 ChooseWildMonIndex_Fishing(u8 rod)
{ {
u8 wildMonIndex = 0; u8 wildMonIndex = 0;
bool8 swap = FALSE;
u8 rand = Random() % max(max(ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_TOTAL, ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_TOTAL), u8 rand = Random() % max(max(ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_TOTAL, ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_TOTAL),
ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_TOTAL); ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_TOTAL);
if (LURE_STEP_COUNT != 0 && (Random() % 10 < 2))
swap = TRUE;
switch (rod) switch (rod)
{ {
case OLD_ROD: case OLD_ROD:
@ -240,6 +267,9 @@ static u8 ChooseWildMonIndex_Fishing(u8 rod)
wildMonIndex = 0; wildMonIndex = 0;
else else
wildMonIndex = 1; wildMonIndex = 1;
if (swap)
wildMonIndex = 1 - wildMonIndex;
break; break;
case GOOD_ROD: case GOOD_ROD:
if (rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2) if (rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2)
@ -248,6 +278,9 @@ static u8 ChooseWildMonIndex_Fishing(u8 rod)
wildMonIndex = 3; wildMonIndex = 3;
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 && rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4) if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 && rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4)
wildMonIndex = 4; wildMonIndex = 4;
if (swap)
wildMonIndex = 6 - wildMonIndex;
break; break;
case SUPER_ROD: case SUPER_ROD:
if (rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5) if (rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5)
@ -260,46 +293,61 @@ static u8 ChooseWildMonIndex_Fishing(u8 rod)
wildMonIndex = 8; wildMonIndex = 8;
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8 && rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_9) if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8 && rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_9)
wildMonIndex = 9; wildMonIndex = 9;
if (swap)
wildMonIndex = 14 - wildMonIndex;
break; break;
} }
return wildMonIndex; return wildMonIndex;
} }
static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon) static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon, u8 wildMonIndex, u8 area)
{ {
u8 min; u8 min;
u8 max; u8 max;
u8 range; u8 range;
u8 rand; u8 rand;
// Make sure minimum level is less than maximum level if (LURE_STEP_COUNT == 0)
if (wildPokemon->maxLevel >= wildPokemon->minLevel)
{ {
min = wildPokemon->minLevel; // Make sure minimum level is less than maximum level
max = wildPokemon->maxLevel; if (wildPokemon[wildMonIndex].maxLevel >= wildPokemon[wildMonIndex].minLevel)
{
min = wildPokemon[wildMonIndex].minLevel;
max = wildPokemon[wildMonIndex].maxLevel;
}
else
{
min = wildPokemon[wildMonIndex].maxLevel;
max = wildPokemon[wildMonIndex].minLevel;
}
range = max - min + 1;
rand = Random() % range;
// check ability for max level mon
if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
{
u16 ability = GetMonAbility(&gPlayerParty[0]);
if (ability == ABILITY_HUSTLE || ability == ABILITY_VITAL_SPIRIT || ability == ABILITY_PRESSURE)
{
if (Random() % 2 == 0)
return max;
if (rand != 0)
rand--;
}
}
return min + rand;
} }
else else
{ {
min = wildPokemon->maxLevel; // Looks for the max level of all slots that share the same species as the selected slot.
max = wildPokemon->minLevel; max = GetMaxLevelOfSpeciesInWildTable(wildPokemon, wildPokemon[wildMonIndex].species, area);
if (max > 0)
return max + 1;
else // Failsafe
return wildPokemon[wildMonIndex].maxLevel + 1;
} }
range = max - min + 1;
rand = Random() % range;
// check ability for max level mon
if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
{
u16 ability = GetMonAbility(&gPlayerParty[0]);
if (ability == ABILITY_HUSTLE || ability == ABILITY_VITAL_SPIRIT || ability == ABILITY_PRESSURE)
{
if (Random() % 2 == 0)
return max;
if (rand != 0)
rand--;
}
}
return min + rand;
} }
static u16 GetCurrentMapWildMonHeaderId(void) static u16 GetCurrentMapWildMonHeaderId(void)
@ -461,7 +509,7 @@ static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 ar
break; break;
} }
level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]); level = ChooseWildMonLevel(wildMonInfo->wildPokemon, wildMonIndex, area);
if (flags & WILD_CHECK_REPEL && !IsWildLevelAllowedByRepel(level)) if (flags & WILD_CHECK_REPEL && !IsWildLevelAllowedByRepel(level))
return FALSE; return FALSE;
if (gMapHeader.mapLayoutId != LAYOUT_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS && flags & WILD_CHECK_KEEN_EYE && !IsAbilityAllowingEncounter(level)) if (gMapHeader.mapLayoutId != LAYOUT_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS && flags & WILD_CHECK_KEEN_EYE && !IsAbilityAllowingEncounter(level))
@ -474,7 +522,7 @@ static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 ar
static u16 GenerateFishingWildMon(const struct WildPokemonInfo *wildMonInfo, u8 rod) static u16 GenerateFishingWildMon(const struct WildPokemonInfo *wildMonInfo, u8 rod)
{ {
u8 wildMonIndex = ChooseWildMonIndex_Fishing(rod); u8 wildMonIndex = ChooseWildMonIndex_Fishing(rod);
u8 level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]); u8 level = ChooseWildMonLevel(wildMonInfo->wildPokemon, wildMonIndex, WILD_AREA_FISHING);
CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level); CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
return wildMonInfo->wildPokemon[wildMonIndex].species; return wildMonInfo->wildPokemon[wildMonIndex].species;
@ -521,6 +569,8 @@ static bool8 DoWildEncounterRateTest(u32 encounterRate, bool8 ignoreAbility)
encounterRate = encounterRate * 80 / 100; encounterRate = encounterRate * 80 / 100;
ApplyFluteEncounterRateMod(&encounterRate); ApplyFluteEncounterRateMod(&encounterRate);
ApplyCleanseTagEncounterRateMod(&encounterRate); ApplyCleanseTagEncounterRateMod(&encounterRate);
if (LURE_STEP_COUNT != 0)
encounterRate *= 2;
if (!ignoreAbility && !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) if (!ignoreAbility && !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
{ {
u32 ability = GetMonAbility(&gPlayerParty[0]); u32 ability = GetMonAbility(&gPlayerParty[0]);
@ -825,7 +875,7 @@ void FishingWildEncounter(u8 rod)
if (CheckFeebas() == TRUE) if (CheckFeebas() == TRUE)
{ {
u8 level = ChooseWildMonLevel(&sWildFeebas); u8 level = ChooseWildMonLevel(&sWildFeebas, 0, WILD_AREA_FISHING);
species = sWildFeebas.species; species = sWildFeebas.species;
CreateWildMon(species, level); CreateWildMon(species, level);
@ -892,24 +942,37 @@ u16 GetLocalWaterMon(void)
bool8 UpdateRepelCounter(void) bool8 UpdateRepelCounter(void)
{ {
u16 steps; u16 repelLureVar = VarGet(VAR_REPEL_STEP_COUNT);
u16 steps = REPEL_LURE_STEPS(repelLureVar);
bool32 isLure = IS_LAST_USED_LURE(repelLureVar);
if (InBattlePike() || InBattlePyramid()) if (InBattlePike() || InBattlePyramid())
return FALSE; return FALSE;
if (InUnionRoom() == TRUE) if (InUnionRoom() == TRUE)
return FALSE; return FALSE;
steps = VarGet(VAR_REPEL_STEP_COUNT);
if (steps != 0) if (steps != 0)
{ {
steps--; steps--;
VarSet(VAR_REPEL_STEP_COUNT, steps); if (!isLure)
if (steps == 0)
{ {
ScriptContext_SetupScript(EventScript_RepelWoreOff); VarSet(VAR_REPEL_STEP_COUNT, steps);
return TRUE; if (steps == 0)
{
ScriptContext_SetupScript(EventScript_RepelWoreOff);
return TRUE;
}
} }
else
{
VarSet(VAR_REPEL_STEP_COUNT, steps | REPEL_LURE_MASK);
if (steps == 0)
{
ScriptContext_SetupScript(EventScript_LureWoreOff);
return TRUE;
}
}
} }
return FALSE; return FALSE;
} }
@ -918,7 +981,7 @@ static bool8 IsWildLevelAllowedByRepel(u8 wildLevel)
{ {
u8 i; u8 i;
if (!VarGet(VAR_REPEL_STEP_COUNT)) if (!REPEL_STEP_COUNT)
return TRUE; return TRUE;
for (i = 0; i < PARTY_SIZE; i++) for (i = 0; i < PARTY_SIZE; i++)
@ -976,6 +1039,34 @@ static bool8 TryGetRandomWildMonIndexByType(const struct WildPokemon *wildMon, u
return TRUE; return TRUE;
} }
#include "data.h"
static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16 species, u8 area)
{
u8 i, maxLevel = 0, numMon = 0;
switch (area)
{
case WILD_AREA_LAND:
numMon = LAND_WILD_COUNT;
break;
case WILD_AREA_WATER:
numMon = WATER_WILD_COUNT;
break;
case WILD_AREA_ROCKS:
numMon = ROCK_WILD_COUNT;
break;
}
for (i = 0; i < numMon; i++)
{
if (wildMon[i].species == species && wildMon[i].maxLevel > maxLevel)
maxLevel = wildMon[i].maxLevel;
}
return maxLevel;
}
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u16 ability, u8 *monIndex) static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u16 ability, u8 *monIndex)
{ {
if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))