merge rhh/upcomig
@ -110,9 +110,9 @@ To compile the `modern` target with this toolchain, the subdirectories `lib`, `i
|
||||
|
||||
### Building with debug info
|
||||
|
||||
To build **pokeemerald.elf** with debug symbols under a modern toolchain:
|
||||
To build **pokeemerald.elf** with debug symbols and debug-compatible optimization under a modern toolchain:
|
||||
```bash
|
||||
make DINFO=1
|
||||
make debug
|
||||
```
|
||||
|
||||
# Useful additional tools
|
||||
|
||||
3
Makefile
@ -121,7 +121,7 @@ CPPFLAGS := $(INCLUDE_CPP_ARGS) -Wno-trigraphs -DMODERN=1 -DTESTING=$(TEST)
|
||||
ARMCC := $(PREFIX)gcc
|
||||
PATH_ARMCC := PATH="$(PATH)" $(ARMCC)
|
||||
CC1 := $(shell $(PATH_ARMCC) --print-prog-name=cc1) -quiet
|
||||
override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init
|
||||
override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init
|
||||
ifeq ($(ANALYZE),1)
|
||||
override CFLAGS += -fanalyzer
|
||||
endif
|
||||
@ -346,6 +346,7 @@ endif
|
||||
|
||||
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
|
||||
$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member
|
||||
$(C_BUILDDIR)/agb_flash.o: override CFLAGS += -fno-toplevel-reorder
|
||||
$(C_BUILDDIR)/pokedex_plus_hgss.o: CFLAGS := -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init
|
||||
# Annoyingly we can't turn this on just for src/data/trainers.h
|
||||
$(C_BUILDDIR)/data.o: CFLAGS += -fno-show-column -fno-diagnostics-show-caret
|
||||
|
||||
@ -1426,11 +1426,6 @@
|
||||
callnative BS_TryRevertWeatherForm
|
||||
.endm
|
||||
|
||||
.macro applysaltcure battler:req
|
||||
callnative BS_ApplySaltCure
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
.macro trysetoctolock battler:req, failInstr:req
|
||||
callnative BS_TrySetOctolock
|
||||
.byte \battler
|
||||
@ -2242,11 +2237,6 @@
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro eeriespellppreduce failInstr:req
|
||||
various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro jumpifteamhealthy battler:req, jumpInstr:req
|
||||
various \battler, VARIOUS_JUMP_IF_TEAM_HEALTHY
|
||||
.4byte \jumpInstr
|
||||
|
||||
@ -1226,6 +1226,13 @@
|
||||
.4byte \products
|
||||
.endm
|
||||
|
||||
@ Used as the endpoint for a Pokemart item list
|
||||
.macro pokemartlistend
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
.endm
|
||||
|
||||
@ Opens the Pokemart system and treats the list of items as decorations.
|
||||
@ Products should be a list of .2byte decoration values preceded by an .align 2
|
||||
.macro pokemartdecoration products:req
|
||||
|
||||
@ -134,7 +134,11 @@ BattleScript_EffectTidyUp::
|
||||
pause B_WAIT_TIME_MED
|
||||
ppreduce
|
||||
waitstate
|
||||
saveattacker
|
||||
savetarget
|
||||
trytidyup FALSE, BattleScript_EffectTidyUpDoMoveAnimation
|
||||
restoreattacker
|
||||
restoretarget
|
||||
goto BattleScript_EffectDragonDanceFromStatUp
|
||||
|
||||
BattleScript_EffectTidyUpDoMoveAnimation::
|
||||
@ -143,6 +147,8 @@ BattleScript_EffectTidyUpDoMoveAnimation::
|
||||
trytidyup TRUE, NULL
|
||||
printstring STRINGID_TIDYINGUPCOMPLETE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
restoreattacker
|
||||
restoretarget
|
||||
goto BattleScript_EffectDragonDanceFromStatUp
|
||||
|
||||
BattleScript_EffectUpperHand::
|
||||
@ -398,16 +404,10 @@ BattleScript_EffectHit_Pledge::
|
||||
tryfaintmon BS_TARGET
|
||||
return
|
||||
|
||||
BattleScript_EffectSaltCure::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
jumpiffainted BS_TARGET, TRUE, BattleScript_EffectSaltCure_End
|
||||
jumpifsubstituteblocks BattleScript_EffectSaltCure_End
|
||||
applysaltcure BS_TARGET
|
||||
BattleScript_MoveEffectSaltCure::
|
||||
printstring STRINGID_TARGETISBEINGSALTCURED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_EffectSaltCure_End:
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_SaltCureExtraDamage::
|
||||
playanimation BS_TARGET, B_ANIM_SALT_CURE_DAMAGE, NULL
|
||||
@ -951,13 +951,10 @@ BattleScript_HyperspaceFuryRemoveProtect::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_EffectPlasmaFists::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
orword gFieldStatuses, STATUS_FIELD_ION_DELUGE
|
||||
BattleScript_MoveEffectIonDeluge::
|
||||
printstring STRINGID_IONDELUGEON
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectSparklySwirl::
|
||||
call BattleScript_EffectHit_Ret
|
||||
@ -968,41 +965,25 @@ BattleScript_EffectSparklySwirl::
|
||||
waitstate
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectFreezyFrost::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
normalisebuffs
|
||||
BattleScript_MoveEffectHaze::
|
||||
printstring STRINGID_STATCHANGESGONE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectSappySeed::
|
||||
jumpifstatus3 BS_TARGET, STATUS3_LEECHSEED, BattleScript_EffectHit
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
jumpifhasnohp BS_TARGET, BattleScript_MoveEnd
|
||||
setseeded
|
||||
printfromtable gLeechSeedStringIds
|
||||
BattleScript_MoveEffectLeechSeed::
|
||||
printstring STRINGID_PKMNSEEDED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectBaddyBad::
|
||||
jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_REFLECT, BattleScript_EffectHit
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
setreflect
|
||||
BattleScript_MoveEffectReflect::
|
||||
printfromtable gReflectLightScreenSafeguardStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectGlitzyGlow::
|
||||
jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_LIGHTSCREEN, BattleScript_EffectHit
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
setlightscreen
|
||||
BattleScript_MoveEffectLightScreen::
|
||||
printfromtable gReflectLightScreenSafeguardStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectStuffCheeks::
|
||||
attackcanceler
|
||||
@ -1220,7 +1201,6 @@ BattleScript_StrengthSapLower:
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_StrengthSapHp
|
||||
@ Drain HP without lowering a stat
|
||||
BattleScript_StrengthSapHp:
|
||||
jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_StrengthSapManipulateDmg
|
||||
@ -2793,6 +2773,10 @@ BattleScript_EffectHitEscape::
|
||||
jumpifbattleend BattleScript_HitEscapeEnd
|
||||
jumpifbyte CMP_NOT_EQUAL, gBattleOutcome, 0, BattleScript_HitEscapeEnd
|
||||
jumpifemergencyexited BS_TARGET, BattleScript_HitEscapeEnd
|
||||
jumpiffainted BS_TARGET, FALSE, BattleScript_HitEscapeSwitch
|
||||
setbyte sGIVEEXP_STATE, 0
|
||||
getexp BS_TARGET
|
||||
BattleScript_HitEscapeSwitch:
|
||||
goto BattleScript_MoveSwitchPursuit
|
||||
BattleScript_HitEscapeEnd:
|
||||
end
|
||||
@ -4078,13 +4062,10 @@ BattleScript_EffectDestinyBond::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectEerieSpell::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
eeriespellppreduce BattleScript_MoveEnd
|
||||
BattleScript_MoveEffectEerieSpell::
|
||||
printstring STRINGID_PKMNREDUCEDPP
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectSpite::
|
||||
attackcanceler
|
||||
@ -6339,18 +6320,14 @@ BattleScript_GulpMissileGulping::
|
||||
datahpupdate BS_ATTACKER
|
||||
tryfaintmon BS_ATTACKER
|
||||
jumpiffainted BS_ATTACKER, TRUE, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifholdeffect BS_ATTACKER, HOLD_EFFECT_CLEAR_AMULET, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifability BS_ATTACKER, ABILITY_CLEAR_BODY, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifflowerveilattacker BattleScript_GulpMissileNoSecondEffectGulping
|
||||
BattleScript_GulpMissileNoDmgGulping:
|
||||
handleformchange BS_TARGET, 0
|
||||
playanimation BS_TARGET, B_ANIM_FORM_CHANGE
|
||||
waitanimation
|
||||
swapattackerwithtarget @ to make gStatDownStringIds down below print the right battler
|
||||
setstatchanger STAT_DEF, 1, TRUE
|
||||
statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_GulpMissileGorgingTargetDefenseCantGoLower
|
||||
statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_GulpMissileGulpingEnd
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_GulpMissileGulpingTargetDefenseCantGoLower
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printfromtable gStatDownStringIds
|
||||
@ -6362,9 +6339,11 @@ BattleScript_GulpMissileNoSecondEffectGulping:
|
||||
playanimation BS_TARGET, B_ANIM_FORM_CHANGE
|
||||
waitanimation
|
||||
return
|
||||
BattleScript_GulpMissileGorgingTargetDefenseCantGoLower:
|
||||
BattleScript_GulpMissileGulpingTargetDefenseCantGoLower:
|
||||
printstring STRINGID_STATSWONTDECREASE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_GulpMissileGulpingEnd:
|
||||
swapattackerwithtarget @ restore the battlers, just in case
|
||||
return
|
||||
|
||||
BattleScript_SeedSowerActivates::
|
||||
@ -6708,7 +6687,7 @@ BattleScript_WishComesTrue::
|
||||
playanimation BS_TARGET, B_ANIM_WISH_HEAL
|
||||
printstring STRINGID_PKMNWISHCAMETRUE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
printstring STRINGID_PKMNREGAINEDHEALTH
|
||||
@ -7092,7 +7071,8 @@ BattleScript_CottonDownLoop:
|
||||
jumpiffainted BS_TARGET, TRUE, BattleScript_CottonDownLoopIncrement
|
||||
setstatchanger STAT_SPEED, 1, TRUE
|
||||
jumpifbyteequal gBattlerTarget, gEffectBattler, BattleScript_CottonDownLoopIncrement
|
||||
statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_CottonDownTargetSpeedCantGoLower
|
||||
statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_CottonDownLoopIncrement
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_CottonDownTargetSpeedCantGoLower
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printfromtable gStatDownStringIds
|
||||
@ -9035,7 +9015,7 @@ BattleScript_BerryStatRaiseEnd2::
|
||||
BattleScript_BerryStatRaiseEnd2_AbilityPopup:
|
||||
call BattleScript_AbilityPopUp
|
||||
BattleScript_BerryStatRaiseEnd2_Anim:
|
||||
statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_BerryStatRaiseEnd2_End
|
||||
statbuffchange STAT_CHANGE_ALLOW_PTR | MOVE_EFFECT_AFFECTS_USER, BattleScript_BerryStatRaiseEnd2_End
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, sB_ANIM_ARG1
|
||||
setbyte cMULTISTRING_CHOOSER, B_MSG_STAT_ROSE_ITEM
|
||||
|
||||
@ -28,9 +28,7 @@ BattleFrontier_Mart_Pokemart:
|
||||
.2byte ITEM_ZINC
|
||||
.2byte ITEM_CARBOS
|
||||
.2byte ITEM_HP_UP
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
BattleFrontier_Mart_EventScript_OldMan::
|
||||
msgbox BattleFrontier_Mart_Text_ChaperonGrandson, MSGBOX_NPC
|
||||
|
||||
@ -45,9 +45,7 @@ EverGrandeCity_PokemonLeague_1F_Pokemart:
|
||||
.2byte ITEM_FULL_HEAL
|
||||
.2byte ITEM_REVIVE
|
||||
.2byte ITEM_MAX_REPEL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
@ The door guards only check for FLAG_BADGE06_GET because Winonas badge is the only one that can be skipped
|
||||
@ Its assumed the player has the remaining badges
|
||||
|
||||
@ -25,9 +25,7 @@ FallarborTown_Mart_Pokemart:
|
||||
.2byte ITEM_X_DEFENSE
|
||||
.2byte ITEM_DIRE_HIT
|
||||
.2byte ITEM_GUARD_SPEC
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
FallarborTown_Mart_EventScript_Woman::
|
||||
msgbox FallarborTown_Mart_Text_DecidingSkittyEvolve, MSGBOX_NPC
|
||||
|
||||
@ -29,9 +29,7 @@ FortreeCity_DecorationShop_PokemartDecor_Desks:
|
||||
.2byte DECOR_BRICK_DESK
|
||||
.2byte DECOR_CAMP_DESK
|
||||
.2byte DECOR_HARD_DESK
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
FortreeCity_DecorationShop_EventScript_ClerkChairs::
|
||||
lock
|
||||
@ -53,9 +51,7 @@ FortreeCity_DecorationShop_PokemartDecor_Chairs:
|
||||
.2byte DECOR_BRICK_CHAIR
|
||||
.2byte DECOR_CAMP_CHAIR
|
||||
.2byte DECOR_HARD_CHAIR
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
FortreeCity_DecorationShop_Text_MerchandiseSentToPC:
|
||||
.string "Merchandise you buy here is sent to\n"
|
||||
|
||||
@ -23,9 +23,7 @@ FortreeCity_Mart_Pokemart:
|
||||
.2byte ITEM_REVIVE
|
||||
.2byte ITEM_SUPER_REPEL
|
||||
.2byte ITEM_WOOD_MAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
FortreeCity_Mart_EventScript_Woman::
|
||||
msgbox FortreeCity_Mart_Text_SuperRepelBetter, MSGBOX_NPC
|
||||
|
||||
@ -17,9 +17,7 @@ LavaridgeTown_HerbShop_Pokemart:
|
||||
.2byte ITEM_ENERGY_ROOT
|
||||
.2byte ITEM_HEAL_POWDER
|
||||
.2byte ITEM_REVIVAL_HERB
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LavaridgeTown_HerbShop_EventScript_ExpertM::
|
||||
msgbox LavaridgeTown_HerbShop_Text_HerbalMedicineWorksButMonWillDislike, MSGBOX_NPC
|
||||
|
||||
@ -22,9 +22,7 @@ LavaridgeTown_Mart_Pokemart:
|
||||
.2byte ITEM_REVIVE
|
||||
.2byte ITEM_SUPER_REPEL
|
||||
.2byte ITEM_X_SPEED
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LavaridgeTown_Mart_EventScript_ExpertM::
|
||||
msgbox LavaridgeTown_Mart_Text_XSpeedFirstStrike, MSGBOX_NPC
|
||||
|
||||
@ -36,9 +36,7 @@ LilycoveCity_DepartmentStore_2F_Pokemart1:
|
||||
.2byte ITEM_ICE_HEAL
|
||||
.2byte ITEM_AWAKENING
|
||||
.2byte ITEM_FLUFFY_TAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_2F_EventScript_ClerkRight::
|
||||
lock
|
||||
@ -62,9 +60,7 @@ LilycoveCity_DepartmentStore_2F_Pokemart2:
|
||||
.2byte ITEM_MAX_REPEL
|
||||
.2byte ITEM_WAVE_MAIL
|
||||
.2byte ITEM_MECH_MAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_2F_Text_LearnToUseItemsProperly:
|
||||
.string "Learn to use items properly.\n"
|
||||
|
||||
@ -19,9 +19,7 @@ LilycoveCity_DepartmentStore_3F_Pokemart_Vitamins:
|
||||
.2byte ITEM_ZINC
|
||||
.2byte ITEM_CARBOS
|
||||
.2byte ITEM_HP_UP
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_3F_EventScript_ClerkRight::
|
||||
lock
|
||||
@ -42,9 +40,7 @@ LilycoveCity_DepartmentStore_3F_Pokemart_StatBoosters:
|
||||
.2byte ITEM_DIRE_HIT
|
||||
.2byte ITEM_GUARD_SPEC
|
||||
.2byte ITEM_X_ACCURACY
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_3F_EventScript_TriathleteM::
|
||||
msgbox LilycoveCity_DepartmentStore_3F_Text_ItemsBestForTougheningPokemon, MSGBOX_NPC
|
||||
|
||||
@ -29,9 +29,7 @@ LilycoveCity_DepartmentStore_4F_Pokemart_AttackTMs:
|
||||
.2byte ITEM_TM_THUNDER
|
||||
.2byte ITEM_TM_BLIZZARD
|
||||
.2byte ITEM_TM_HYPER_BEAM
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_4F_EventScript_ClerkRight::
|
||||
lock
|
||||
@ -49,9 +47,7 @@ LilycoveCity_DepartmentStore_4F_Pokemart_DefenseTMs:
|
||||
.2byte ITEM_TM_SAFEGUARD
|
||||
.2byte ITEM_TM_REFLECT
|
||||
.2byte ITEM_TM_LIGHT_SCREEN
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_4F_Text_AttackOrDefenseTM:
|
||||
.string "Hmm…\p"
|
||||
|
||||
@ -41,9 +41,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Dolls:
|
||||
.2byte DECOR_SKITTY_DOLL
|
||||
.2byte DECOR_SWABLU_DOLL
|
||||
.2byte DECOR_GULPIN_DOLL
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_5F_EventScript_ClerkMidLeft::
|
||||
lock
|
||||
@ -66,9 +64,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Cushions:
|
||||
.2byte DECOR_GRASS_CUSHION
|
||||
.2byte DECOR_FIRE_CUSHION
|
||||
.2byte DECOR_WATER_CUSHION
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_5F_EventScript_ClerkMidRight::
|
||||
lock
|
||||
@ -91,9 +87,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Posters:
|
||||
.2byte DECOR_LONG_POSTER
|
||||
.2byte DECOR_SEA_POSTER
|
||||
.2byte DECOR_SKY_POSTER
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_5F_EventScript_ClerkFarRight::
|
||||
lock
|
||||
@ -117,9 +111,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Mats:
|
||||
.2byte DECOR_GLITTER_MAT
|
||||
.2byte DECOR_JUMP_MAT
|
||||
.2byte DECOR_SPIN_MAT
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
LilycoveCity_DepartmentStore_5F_EventScript_PokefanF::
|
||||
msgbox LilycoveCity_DepartmentStore_5F_Text_PlaceFullOfCuteDolls, MSGBOX_NPC
|
||||
|
||||
@ -25,9 +25,7 @@ MauvilleCity_Mart_Pokemart:
|
||||
.2byte ITEM_GUARD_SPEC
|
||||
.2byte ITEM_DIRE_HIT
|
||||
.2byte ITEM_X_ACCURACY
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
MauvilleCity_Mart_EventScript_ExpertM::
|
||||
msgbox MauvilleCity_Mart_Text_ItemsToTemporarilyElevateStats, MSGBOX_NPC
|
||||
|
||||
@ -22,9 +22,7 @@ MossdeepCity_Mart_Pokemart:
|
||||
.2byte ITEM_MAX_REPEL
|
||||
.2byte ITEM_X_ATTACK
|
||||
.2byte ITEM_X_DEFENSE
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
MossdeepCity_Mart_EventScript_Woman::
|
||||
msgbox MossdeepCity_Mart_Text_ReviveIsFantastic, MSGBOX_NPC
|
||||
|
||||
@ -18,9 +18,7 @@ OldaleTown_Mart_Pokemart_Basic:
|
||||
.2byte ITEM_ANTIDOTE
|
||||
.2byte ITEM_PARALYZE_HEAL
|
||||
.2byte ITEM_AWAKENING
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
OldaleTown_Mart_ExpandedItems::
|
||||
pokemart OldaleTown_Mart_Pokemart_Expanded
|
||||
@ -35,9 +33,7 @@ OldaleTown_Mart_Pokemart_Expanded:
|
||||
.2byte ITEM_ANTIDOTE
|
||||
.2byte ITEM_PARALYZE_HEAL
|
||||
.2byte ITEM_AWAKENING
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
OldaleTown_Mart_EventScript_Woman::
|
||||
lock
|
||||
|
||||
@ -25,9 +25,7 @@ PetalburgCity_Mart_Pokemart_Basic:
|
||||
.2byte ITEM_X_ATTACK
|
||||
.2byte ITEM_X_DEFENSE
|
||||
.2byte ITEM_ORANGE_MAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
PetalburgCity_Mart_EventScript_ExpandedItems::
|
||||
pokemart PetalburgCity_Mart_Pokemart_Expanded
|
||||
@ -50,9 +48,7 @@ PetalburgCity_Mart_Pokemart_Expanded:
|
||||
.2byte ITEM_X_ATTACK
|
||||
.2byte ITEM_X_DEFENSE
|
||||
.2byte ITEM_ORANGE_MAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
PetalburgCity_Mart_EventScript_Woman::
|
||||
msgbox PetalburgCity_Mart_Text_WeakWillGrowStronger, MSGBOX_NPC
|
||||
|
||||
@ -59,9 +59,7 @@ Route104_PrettyPetalFlowerShop_Pokemart_Plants:
|
||||
.2byte DECOR_COLORFUL_PLANT
|
||||
.2byte DECOR_BIG_PLANT
|
||||
.2byte DECOR_GORGEOUS_PLANT
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
Route104_PrettyPetalFlowerShop_EventScript_WailmerPailGirl::
|
||||
lock
|
||||
|
||||
@ -28,9 +28,7 @@ RustboroCity_Mart_Pokemart_Basic:
|
||||
.2byte ITEM_X_SPEED
|
||||
.2byte ITEM_X_ATTACK
|
||||
.2byte ITEM_X_DEFENSE
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
RustboroCity_Mart_EventScript_PokemartExpanded::
|
||||
pokemart RustboroCity_Mart_Pokemart_Expanded
|
||||
@ -52,9 +50,7 @@ RustboroCity_Mart_Pokemart_Expanded:
|
||||
.2byte ITEM_X_SPEED
|
||||
.2byte ITEM_X_ATTACK
|
||||
.2byte ITEM_X_DEFENSE
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
RustboroCity_Mart_EventScript_PokefanF::
|
||||
msgbox RustboroCity_Mart_Text_BuyingHealsInCaseOfShroomish, MSGBOX_NPC
|
||||
|
||||
@ -154,9 +154,7 @@ SlateportCity_Pokemart_EnergyGuru:
|
||||
.2byte ITEM_ZINC
|
||||
.2byte ITEM_CALCIUM
|
||||
.2byte ITEM_HP_UP
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
SlateportCity_EventScript_EffortRibbonWoman::
|
||||
lock
|
||||
@ -514,9 +512,7 @@ SlateportCity_PokemartDecor_Dolls:
|
||||
.2byte DECOR_AZURILL_DOLL
|
||||
.2byte DECOR_MARILL_DOLL
|
||||
.2byte DECOR_SKITTY_DOLL
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
SlateportCity_EventScript_ComeBackWithSecretPower::
|
||||
msgbox gText_ComeBackWithSecretPower, MSGBOX_DEFAULT
|
||||
@ -550,9 +546,7 @@ SlateportCity_PokemartDecor:
|
||||
.2byte DECOR_A_NOTE_MAT
|
||||
.2byte DECOR_B_NOTE_MAT
|
||||
.2byte DECOR_C_HIGH_NOTE_MAT
|
||||
.2byte DECOR_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
SlateportCity_EventScript_PowerTMClerk::
|
||||
lock
|
||||
@ -568,9 +562,7 @@ SlateportCity_EventScript_PowerTMClerk::
|
||||
SlateportCity_Pokemart_PowerTMs:
|
||||
.2byte ITEM_TM_HIDDEN_POWER
|
||||
.2byte ITEM_TM_SECRET_POWER
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
@ Scene with Capt Sterns interview and Team Aqua announcing plans to steal Submarine
|
||||
SlateportCity_EventScript_CaptStern::
|
||||
|
||||
@ -22,9 +22,7 @@ SlateportCity_Mart_Pokemart:
|
||||
.2byte ITEM_ESCAPE_ROPE
|
||||
.2byte ITEM_REPEL
|
||||
.2byte ITEM_HARBOR_MAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
SlateportCity_Mart_EventScript_BlackBelt::
|
||||
msgbox SlateportCity_Mart_Text_SomeItemsOnlyAtMart, MSGBOX_NPC
|
||||
|
||||
@ -22,9 +22,7 @@ SootopolisCity_Mart_Pokemart:
|
||||
.2byte ITEM_X_ATTACK
|
||||
.2byte ITEM_X_DEFENSE
|
||||
.2byte ITEM_SHADOW_MAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
SootopolisCity_Mart_EventScript_FatMan::
|
||||
lock
|
||||
|
||||
@ -267,9 +267,7 @@ TrainerHill_Entrance_Pokemart_Basic:
|
||||
.2byte ITEM_DIRE_HIT
|
||||
.2byte ITEM_GUARD_SPEC
|
||||
.2byte ITEM_X_ACCURACY
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
TrainerHill_Entrance_EventScript_ExpandedPokemart::
|
||||
pokemart TrainerHill_Entrance_Pokemart_Expanded
|
||||
@ -291,9 +289,7 @@ TrainerHill_Entrance_Pokemart_Expanded:
|
||||
.2byte ITEM_DIRE_HIT
|
||||
.2byte ITEM_GUARD_SPEC
|
||||
.2byte ITEM_X_ACCURACY
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
TrainerHill_Entrance_Text_StillGettingReady:
|
||||
.string "This is the TRAINER HILL where\n"
|
||||
|
||||
@ -24,9 +24,7 @@ VerdanturfTown_Mart_Pokemart:
|
||||
.2byte ITEM_REPEL
|
||||
.2byte ITEM_X_SP_ATK
|
||||
.2byte ITEM_FLUFFY_TAIL
|
||||
.2byte ITEM_NONE
|
||||
release
|
||||
end
|
||||
pokemartlistend
|
||||
|
||||
VerdanturfTown_Mart_EventScript_Boy::
|
||||
msgbox VerdanturfTown_Mart_Text_XSpecialIsCrucial, MSGBOX_NPC
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
- [How to add a new move](tutorials/how_to_new_move.md)
|
||||
- [How to add a new trainer class](tutorials/how_to_trainer_class.md)
|
||||
- [How to add a new Pokémon]()
|
||||
- [v1.10.x](tutorials/how_to_new_pokemon_1_10_0.md)
|
||||
- [v1.9.x](tutorials/how_to_new_pokemon_1_9_0.md)
|
||||
- [v1.8.x](tutorials/how_to_new_pokemon_1_8_0.md)
|
||||
- [v1.7.x](tutorials/how_to_new_pokemon_1_7_0.md)
|
||||
|
||||
@ -1,51 +1,47 @@
|
||||
## How to add new Battle Script Commands/Macros
|
||||
|
||||
To preface this tutorial, the battle engine upgrade has exhausted all battle script command IDs, and instead uses the `various` command to effectively add new commands. This is preferential to creating a secondary battle script command table like is done in the CFRU.
|
||||
To preface this tutorial, the battle engine upgrade has exhausted all battle script command IDs. Historically, we've used the `various` command to effectively add new commands. However, this has caused issues of maintainability and readability due to the massive switch needed for it. Thanks to the cleanup made by the team and contributors, we now are able to call an infinite amount of commands by using `callnative`. This is preferential to creating a secondary battle script command table like is done in the CFRU.
|
||||
|
||||
In general, `gBattlescriptCurrInstr` tracks the current battle script position as a ROM address. Fortunately, we don't need to worry about ROM addresses when using the decomps, but it is important to understand because of how the `various` command is set up.
|
||||
In general, `gBattlescriptCurrInstr` tracks the current battle script position as a ROM address. Fortunately, we don't need to worry about ROM addresses when using the decomps, but it is important to understand because of how the `callnative` command is set up.
|
||||
|
||||
```
|
||||
.macro various battler:req, param1:req
|
||||
.byte 0x76
|
||||
.byte \battler
|
||||
.byte \param1
|
||||
.endm
|
||||
.macro callnative func:req
|
||||
.byte 0xff
|
||||
.4byte \func
|
||||
.endm
|
||||
```
|
||||
`callnative` uses the last battle script command ID in order to pass a native function as an argument. Additional optional arguments are added recursively via a macro, so no need to worry about how they need to align to the amount of instructions to skip.
|
||||
|
||||
`various` is 3 bytes in size, so if we wanted to advance to the next battle script command, we would write `gBattlescriptCurrInstr += 3`. Coincidentally, this is found at the end of `Cmd_Various` in `src/battle_script_commands.c`.
|
||||
|
||||
Now, how might we add a custom various command case? Here are the steps. We will use `VARIOUS_SET_SIMPLE_BEAM` as an example.
|
||||
### 1. Add a definition to `include/constants/battle_script_commands.h`.
|
||||
|
||||
For example, `#define VARIOUS_SET_SIMPLE_BEAM 39`
|
||||
|
||||
### 2. Create a macro in `asm/macros/battle_script.inc`. For example:
|
||||
Now, how might we add a custom `callnative` command? Here are the steps. We will use `BS_TrySetOctolock` as an example.
|
||||
### 1. Create a macro in `asm/macros/battle_script.inc`. For example:
|
||||
```c
|
||||
.macro setabilitysimple battler:req, ptr:req
|
||||
various \battler VARIOUS_SET_SIMPLE_BEAM
|
||||
.4byte \ptr
|
||||
.endm
|
||||
.macro trysetoctolock battler:req, failInstr:req
|
||||
callnative BS_TrySetOctolock
|
||||
.byte \battler
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
```
|
||||
|
||||
### 3. Add your new various command ID to `Cmd_Various`. For example:
|
||||
### 2. Add your new callnative command ID to `src/battle_script_commands.c`. For example:
|
||||
```c
|
||||
case VARIOUS_SET_SIMPLE_BEAM:
|
||||
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)
|
||||
|| gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE)
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE;
|
||||
RecordAbilityBattle(gActiveBattler, ABILITY_SIMPLE);
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
return;
|
||||
void BS_TrySetOctolock(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler, const u8 *failInstr);
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
|
||||
if (gDisableStructs[battler].octolock)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gDisableStructs[battler].octolock = TRUE;
|
||||
gBattleMons[battler].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gDisableStructs[battler].battlerPreventingEscape = gBattlerAttacker;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The macros' `battler` argument is the battler who will be affected/considered by your command. In our case, which battler we will try to give `ABILITY_SIMPLE`. Note that `gActiveBattler` is always set to this battler at the beginning of `Cmd_Various`.
|
||||
|
||||
The `ptr` argument is an extra argument that, in this case, provides a battle script to jump to in the event that we fail to set `ABILITY_SIMPLE`. We must add the `.4byte \ptr` inside our macro. So now when we want to advance to the next battle script command in our script, we must increment `gBattlescriptCurrInstr` by `7` because our overall macro is 3 bytes for the various command, and 4 bytes for the pointer. *IMPORTANT* the `return` at the end of the switch case is required because remember that `various` always defaults to `gBattlescriptCurrInstr += 3` at the very end of the function, so if we included `gBattlescriptCurrInstr += 7` with a `break`, we would end up effectively doing `gBattlescriptCurrInstr += 10`.
|
||||
|
||||
This behavior can be found under the `else` statement in the example above, corresponding to `ABILITY_SIMPLE` being correctly applied. If we are unable to set `ABILITY_SIMPLE`, however, notice the following `gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);`. This means we are jumping to the battle script provided by the pointer 3 bytes after our various command (which is the `ptr` argument described previously). We still must `return` or else we would actually jump to 3 bytes after the `ptr` battle script begins.
|
||||
Each of the arguments defined in the macro (`battler`, `failInstr`) need to be called at the start of the command using `NATIVE_ARGS`.
|
||||
The byte count in the macro should correspond to the type that will be used for the command (eg, `u8` is `byte`, while the pointer are `4byte`).
|
||||
These arguments can then be accessed as `cmd->battler` and `cmd->battler`.
|
||||
`gBattlescriptCurrInstr = cmd->nextInstr;` advances to the next instruction.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
8
|
||||
16
|
||||
255 255 164
|
||||
255 255 106
|
||||
222 222 90
|
||||
@ -9,3 +9,11 @@ JASC-PAL
|
||||
123 123 49
|
||||
90 90 32
|
||||
57 57 16
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 830 B After Width: | Height: | Size: 757 B |
@ -6,7 +6,7 @@ JASC-PAL
|
||||
120 120 112
|
||||
160 160 144
|
||||
8 8 8
|
||||
120 120 112
|
||||
84 84 78
|
||||
48 48 56
|
||||
232 232 232
|
||||
240 152 168
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 548 B After Width: | Height: | Size: 485 B |
@ -3,17 +3,17 @@ JASC-PAL
|
||||
16
|
||||
152 208 160
|
||||
8 48 56
|
||||
0 128 160
|
||||
36 103 149
|
||||
16 16 16
|
||||
80 64 40
|
||||
248 208 128
|
||||
176 152 88
|
||||
255 215 132
|
||||
181 158 90
|
||||
136 104 56
|
||||
152 232 248
|
||||
102 225 253
|
||||
96 192 216
|
||||
80 88 88
|
||||
168 168 168
|
||||
216 216 216
|
||||
48 56 40
|
||||
152 128 80
|
||||
136 88 56
|
||||
99 84 80
|
||||
201 185 131
|
||||
167 139 110
|
||||
|
||||
|
Before Width: | Height: | Size: 880 B After Width: | Height: | Size: 794 B |
|
Before Width: | Height: | Size: 481 B |
|
Before Width: | Height: | Size: 472 B After Width: | Height: | Size: 620 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.0 KiB |
@ -864,9 +864,10 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER
|
||||
#define F_DYNAMIC_TYPE_IGNORE_PHYSICALITY (1 << 6) // If set, the dynamic type's physicality won't be used for certain move effects.
|
||||
#define F_DYNAMIC_TYPE_SET (1 << 7) // Set for all dynamic types to distinguish a dynamic type of Normal (0) from no dynamic type.
|
||||
|
||||
#define IS_MOVE_PHYSICAL(move)(GetBattleMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL)
|
||||
#define IS_MOVE_SPECIAL(move)(GetBattleMoveCategory(move) == DAMAGE_CATEGORY_SPECIAL)
|
||||
#define IS_MOVE_STATUS(move)(gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS)
|
||||
#define IS_MOVE_PHYSICAL(move) (GetBattleMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL)
|
||||
#define IS_MOVE_SPECIAL(move) (GetBattleMoveCategory(move) == DAMAGE_CATEGORY_SPECIAL)
|
||||
#define IS_MOVE_STATUS(move) (gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS)
|
||||
|
||||
#define IS_MOVE_RECOIL(move)(gMovesInfo[move].recoil > 0 || gMovesInfo[move].effect == EFFECT_RECOIL_IF_MISS)
|
||||
|
||||
/* Checks if 'battlerId' is any of the types.
|
||||
|
||||
@ -116,7 +116,7 @@ bool32 HasOnlyMovesWithCategory(u32 battlerId, u32 category, bool32 onlyOffensiv
|
||||
bool32 HasMoveWithCategory(u32 battler, u32 category);
|
||||
bool32 HasMoveWithType(u32 battler, u32 type);
|
||||
bool32 HasMoveEffect(u32 battlerId, u32 moveEffect);
|
||||
bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument);
|
||||
bool32 IsPowerBasedOnStatus(u32 battlerId, u32 effect, u32 argument);
|
||||
bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect);
|
||||
bool32 HasMoveWithCriticalHitChance(u32 battlerId);
|
||||
bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception);
|
||||
|
||||
@ -804,18 +804,18 @@ extern const u8 BattleScript_EffectGeomancy[];
|
||||
extern const u8 BattleScript_EffectFairyLock[];
|
||||
extern const u8 BattleScript_EffectAllySwitch[];
|
||||
extern const u8 BattleScript_EffectRelicSong[];
|
||||
extern const u8 BattleScript_EffectEerieSpell[];
|
||||
extern const u8 BattleScript_MoveEffectEerieSpell[];
|
||||
extern const u8 BattleScript_EffectJungleHealing[];
|
||||
extern const u8 BattleScript_EffectCoaching[];
|
||||
extern const u8 BattleScript_EffectDecorate[];
|
||||
extern const u8 BattleScript_EffectRecoilHP25[];
|
||||
extern const u8 BattleScript_EffectStuffCheeks[];
|
||||
extern const u8 BattleScript_EffectGlitzyGlow[];
|
||||
extern const u8 BattleScript_EffectBaddyBad[];
|
||||
extern const u8 BattleScript_EffectSappySeed[];
|
||||
extern const u8 BattleScript_EffectFreezyFrost[];
|
||||
extern const u8 BattleScript_MoveEffectLightScreen[];
|
||||
extern const u8 BattleScript_MoveEffectReflect[];
|
||||
extern const u8 BattleScript_MoveEffectLeechSeed[];
|
||||
extern const u8 BattleScript_MoveEffectHaze[];
|
||||
extern const u8 BattleScript_EffectSparklySwirl[];
|
||||
extern const u8 BattleScript_EffectPlasmaFists[];
|
||||
extern const u8 BattleScript_MoveEffectIonDeluge[];
|
||||
extern const u8 BattleScript_EffectHyperspaceFury[];
|
||||
extern const u8 BattleScript_EffectAuraWheel[];
|
||||
extern const u8 BattleScript_EffectPhotonGeyser[];
|
||||
@ -838,7 +838,7 @@ extern const u8 BattleScript_EffectRevivalBlessing[];
|
||||
extern const u8 BattleScript_EffectSnow[];
|
||||
extern const u8 BattleScript_EffectTakeHeart[];
|
||||
extern const u8 BattleScript_EffectCorrosiveGas[];
|
||||
extern const u8 BattleScript_EffectSaltCure[];
|
||||
extern const u8 BattleScript_MoveEffectSaltCure[];
|
||||
extern const u8 BattleScript_EffectChillyReception[];
|
||||
extern const u8 BattleScript_EffectMaxMove[];
|
||||
extern const u8 BattleScript_EffectGlaiveRush[];
|
||||
|
||||
@ -100,33 +100,37 @@ struct TypePower
|
||||
enum
|
||||
{
|
||||
CANCELLER_FLAGS,
|
||||
CANCELLER_STANCE_CHANGE_1,
|
||||
CANCELLER_SKY_DROP,
|
||||
CANCELLER_RECHARGE,
|
||||
CANCELLER_ASLEEP,
|
||||
CANCELLER_FROZEN,
|
||||
CANCELLER_OBEDIENCE,
|
||||
CANCELLER_TRUANT,
|
||||
CANCELLER_RECHARGE,
|
||||
CANCELLER_FLINCH,
|
||||
CANCELLER_IN_LOVE,
|
||||
CANCELLER_DISABLED,
|
||||
CANCELLER_GRAVITY,
|
||||
CANCELLER_HEAL_BLOCKED,
|
||||
CANCELLER_GRAVITY,
|
||||
CANCELLER_THROAT_CHOP,
|
||||
CANCELLER_TAUNTED,
|
||||
CANCELLER_IMPRISONED,
|
||||
CANCELLER_CONFUSED,
|
||||
CANCELLER_PARALYSED,
|
||||
CANCELLER_IN_LOVE,
|
||||
CANCELLER_BIDE,
|
||||
CANCELLER_THAW,
|
||||
CANCELLER_STANCE_CHANGE_2,
|
||||
CANCELLER_WEATHER_PRIMAL,
|
||||
CANCELLER_DYNAMAX_BLOCKED,
|
||||
CANCELLER_POWDER_MOVE,
|
||||
CANCELLER_POWDER_STATUS,
|
||||
CANCELLER_THROAT_CHOP,
|
||||
CANCELLER_PROTEAN,
|
||||
CANCELLER_PSYCHIC_TERRAIN,
|
||||
CANCELLER_EXPLODING_DAMP,
|
||||
CANCELLER_MULTIHIT_MOVES,
|
||||
CANCELLER_Z_MOVES,
|
||||
CANCELLER_MULTI_TARGET_MOVES,
|
||||
CANCELLER_END,
|
||||
CANCELLER_PSYCHIC_TERRAIN,
|
||||
CANCELLER_END2,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -197,9 +201,8 @@ u8 DoBattlerEndTurnEffects(void);
|
||||
bool32 HandleWishPerishSongOnTurnEnd(void);
|
||||
bool32 HandleFaintedMonActions(void);
|
||||
void TryClearRageAndFuryCutter(void);
|
||||
u8 AtkCanceller_UnableToUseMove(u32 moveType);
|
||||
u32 AtkCanceller_MoveSuccessOrder(void);
|
||||
void SetAtkCancellerForCalledMove(void);
|
||||
u8 AtkCanceller_UnableToUseMove2(void);
|
||||
bool32 HasNoMonsToSwitch(u32 battler, u8 r1, u8 r2);
|
||||
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbility);
|
||||
u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef);
|
||||
@ -297,7 +300,7 @@ bool32 IsGen6ExpShareEnabled(void);
|
||||
bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance);
|
||||
bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
|
||||
bool32 IsMoveEffectRemoveSpeciesType(u32 move, u32 moveEffect, u32 argument);
|
||||
bool32 MoveHasChargeTurnAdditionalEffect(u32 move);
|
||||
bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef);
|
||||
|
||||
@ -156,6 +156,7 @@
|
||||
#define B_ABILITY_TRIGGER_CHANCE GEN_LATEST // In Gen3, Shed Skin, Cute Charm, Flame Body, Static and Poison Point have a 1/3 chance to trigger. In Gen 4+ it's 30%.
|
||||
// In Gen3, Effect Spore has a 10% chance to sleep, poison or paralyze, with an equal chance.
|
||||
// In Gen4, it's 30%. In Gen5+ it has 11% to sleep, 9% chance to poison and 10% chance to paralyze.
|
||||
#define B_PICKUP_WILD GEN_LATEST // In Gen9+, Pickup allows its user to pickup its own used item at the end of the turn in wild battles.
|
||||
|
||||
// Item settings
|
||||
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore HP activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.
|
||||
@ -165,6 +166,7 @@
|
||||
#define B_MENTAL_HERB GEN_LATEST // In Gen5+, the Mental Herb cures Taunt, Encore, Torment, Heal Block, and Disable in addition to Infatuation from before.
|
||||
#define B_TRAINERS_KNOCK_OFF_ITEMS TRUE // If TRUE, trainers can steal/swap your items (non-berries are restored after battle). In vanilla games trainers cannot steal items.
|
||||
#define B_RETURN_STOLEN_NPC_ITEMS GEN_LATEST // In Gen5+, Thief and Covet no longer steal items from NPCs.
|
||||
#define B_STEAL_WILD_ITEMS GEN_LATEST // In Gen9, Thief and Covet steal a wild pokemon's item and send it to the bag. Before Gen9, the stolen item would be held by the Thief/Covet user.
|
||||
#define B_RESTORE_HELD_BATTLE_ITEMS GEN_LATEST // In Gen9, all non-berry items are restored after battle.
|
||||
#define B_SOUL_DEW_BOOST GEN_LATEST // In Gens3-6, Soul Dew boosts Latis' Sp. Atk and Sp. Def. In Gen7+ it boosts the power of their Psychic and Dragon type moves instead.
|
||||
#define B_NET_BALL_MODIFIER GEN_LATEST // In Gen7+, Net Ball's catch multiplier is x5 instead of x3.
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
#define P_SHOW_TERA_TYPE GEN_8 // Since Gen 9, the Tera Type is shown on the summary screen.
|
||||
#define P_TM_LITERACY GEN_LATEST // Since Gen 6, TM illiterate Pokémon can learn TMs that teach moves that are in their level-up learnsets.
|
||||
#define P_CAN_FORGET_HIDDEN_MOVE FALSE // If TRUE, Pokémon can forget any move, even if it is a Hidden Move.
|
||||
#define P_EGG_CYCLE_LENGTH GEN_LATEST // Since Gen 8, egg cycles take half as many steps as before.
|
||||
#define P_EGG_CYCLE_LENGTH GEN_LATEST // Since Gen 8, egg cycles take half as many steps as before. Previous Gens have some varied step counts around 255.
|
||||
#define P_ONLY_OBTAINABLE_SHINIES FALSE // If TRUE, Pokémon encountered in the Battle Pyramid won't be shiny.
|
||||
#define P_NO_SHINIES_WITHOUT_POKEBALLS FALSE // If TRUE, Pokémon encountered when the player is out of Poké Balls won't be shiny
|
||||
#define P_SHOW_DYNAMIC_TYPES FALSE // If TRUE, all moves with dynamic type changes will be reflected as their current type in battle/summary screens instead of just select ones like in vanilla.
|
||||
|
||||
@ -325,7 +325,11 @@ enum BattleWeather
|
||||
#define MOVE_EFFECT_TOXIC 6
|
||||
#define MOVE_EFFECT_FROSTBITE 7
|
||||
#define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_FROSTBITE // All above move effects apply primary status
|
||||
#define MOVE_EFFECT_FREEZE_OR_FROSTBITE (B_USE_FROSTBITE == TRUE ? MOVE_EFFECT_FROSTBITE : MOVE_EFFECT_FREEZE)
|
||||
#if B_USE_FROSTBITE == TRUE
|
||||
#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FROSTBITE
|
||||
#else
|
||||
#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FREEZE
|
||||
#endif
|
||||
#define MOVE_EFFECT_CONFUSION 8
|
||||
#define MOVE_EFFECT_FLINCH 9
|
||||
#define MOVE_EFFECT_TRI_ATTACK 10
|
||||
@ -399,8 +403,16 @@ enum BattleWeather
|
||||
#define MOVE_EFFECT_PSYCHIC_NOISE 78
|
||||
#define MOVE_EFFECT_TERA_BLAST 79
|
||||
#define MOVE_EFFECT_ORDER_UP 80
|
||||
#define MOVE_EFFECT_ION_DELUGE 81
|
||||
#define MOVE_EFFECT_AROMATHERAPY 82 // No functionality yet
|
||||
#define MOVE_EFFECT_HAZE 83
|
||||
#define MOVE_EFFECT_LEECH_SEED 84
|
||||
#define MOVE_EFFECT_REFLECT 85
|
||||
#define MOVE_EFFECT_LIGHT_SCREEN 86
|
||||
#define MOVE_EFFECT_SALT_CURE 87
|
||||
#define MOVE_EFFECT_EERIE_SPELL 88
|
||||
|
||||
#define NUM_MOVE_EFFECTS 81
|
||||
#define NUM_MOVE_EFFECTS 88
|
||||
|
||||
#define MOVE_EFFECT_AFFECTS_USER 0x2000
|
||||
#define MOVE_EFFECT_CERTAIN 0x4000
|
||||
|
||||
@ -285,7 +285,6 @@ enum {
|
||||
EFFECT_ALLY_SWITCH,
|
||||
EFFECT_RELIC_SONG,
|
||||
EFFECT_BODY_PRESS,
|
||||
EFFECT_EERIE_SPELL,
|
||||
EFFECT_JUNGLE_HEALING,
|
||||
EFFECT_COACHING,
|
||||
EFFECT_LASH_OUT,
|
||||
@ -296,12 +295,7 @@ enum {
|
||||
EFFECT_RECOIL_HP_25,
|
||||
EFFECT_STUFF_CHEEKS,
|
||||
EFFECT_GRAV_APPLE,
|
||||
EFFECT_GLITZY_GLOW,
|
||||
EFFECT_BADDY_BAD,
|
||||
EFFECT_SAPPY_SEED,
|
||||
EFFECT_FREEZY_FROST,
|
||||
EFFECT_SPARKLY_SWIRL,
|
||||
EFFECT_PLASMA_FISTS,
|
||||
EFFECT_HYPERSPACE_FURY,
|
||||
EFFECT_AURA_WHEEL,
|
||||
EFFECT_PHOTON_GEYSER,
|
||||
@ -334,7 +328,6 @@ enum {
|
||||
EFFECT_COLLISION_COURSE,
|
||||
EFFECT_CORROSIVE_GAS,
|
||||
EFFECT_POPULATION_BOMB,
|
||||
EFFECT_SALT_CURE,
|
||||
EFFECT_CHILLY_RECEPTION,
|
||||
EFFECT_MAX_MOVE,
|
||||
EFFECT_GLAIVE_RUSH,
|
||||
|
||||
@ -88,138 +88,137 @@
|
||||
#define CMP_COMMON_BITS 4
|
||||
#define CMP_NO_COMMON_BITS 5
|
||||
|
||||
// Cmd_various
|
||||
#define VARIOUS_CANCEL_MULTI_TURN_MOVES 0
|
||||
#define VARIOUS_IS_RUNNING_IMPOSSIBLE 1
|
||||
#define VARIOUS_GET_MOVE_TARGET 2
|
||||
#define VARIOUS_GET_BATTLER_FAINTED 3
|
||||
#define VARIOUS_RESET_SWITCH_IN_ABILITY_BITS 4
|
||||
#define VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP 5
|
||||
#define VARIOUS_RESET_PLAYER_FAINTED 6
|
||||
#define VARIOUS_PALACE_FLAVOR_TEXT 7
|
||||
#define VARIOUS_ARENA_JUDGMENT_WINDOW 8
|
||||
#define VARIOUS_ARENA_OPPONENT_MON_LOST 9
|
||||
#define VARIOUS_ARENA_PLAYER_MON_LOST 10
|
||||
#define VARIOUS_ARENA_BOTH_MONS_LOST 11
|
||||
#define VARIOUS_EMIT_YESNOBOX 12
|
||||
#define VARIOUS_DRAW_ARENA_REF_TEXT_BOX 13
|
||||
#define VARIOUS_ERASE_ARENA_REF_TEXT_BOX 14
|
||||
#define VARIOUS_ARENA_JUDGMENT_STRING 15
|
||||
#define VARIOUS_ARENA_WAIT_STRING 16
|
||||
#define VARIOUS_WAIT_CRY 17
|
||||
#define VARIOUS_RETURN_OPPONENT_MON1 18
|
||||
#define VARIOUS_RETURN_OPPONENT_MON2 19
|
||||
#define VARIOUS_VOLUME_DOWN 20
|
||||
#define VARIOUS_VOLUME_UP 21
|
||||
#define VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT 22
|
||||
#define VARIOUS_PALACE_TRY_ESCAPE_STATUS 23
|
||||
#define VARIOUS_SET_TELEPORT_OUTCOME 24
|
||||
#define VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC 25
|
||||
#define VARIOUS_STAT_TEXT_BUFFER 26
|
||||
#define VARIOUS_SWITCHIN_ABILITIES 27
|
||||
#define VARIOUS_INSTANT_HP_DROP 28
|
||||
#define VARIOUS_CLEAR_STATUS 29
|
||||
#define VARIOUS_RESTORE_PP 30
|
||||
#define VARIOUS_TRY_ACTIVATE_MOXIE 31
|
||||
#define VARIOUS_TRY_ACTIVATE_FELL_STINGER 32
|
||||
#define VARIOUS_PLAY_MOVE_ANIMATION 33
|
||||
#define VARIOUS_SET_LUCKY_CHANT 34
|
||||
#define VARIOUS_SUCKER_PUNCH_CHECK 35
|
||||
#define VARIOUS_SET_SIMPLE_BEAM 36
|
||||
#define VARIOUS_TRY_ENTRAINMENT 37
|
||||
#define VARIOUS_SET_LAST_USED_ABILITY 38
|
||||
#define VARIOUS_INVERT_STAT_STAGES 39
|
||||
#define VARIOUS_TRY_ME_FIRST 40
|
||||
#define VARIOUS_JUMP_IF_BATTLE_END 41
|
||||
#define VARIOUS_TRY_ELECTRIFY 42
|
||||
#define VARIOUS_TRY_REFLECT_TYPE 43
|
||||
#define VARIOUS_TRY_SOAK 44
|
||||
#define VARIOUS_HANDLE_MEGA_EVO 45
|
||||
#define VARIOUS_TRY_LAST_RESORT 46
|
||||
#define VARIOUS_SET_ARG_TO_BATTLE_DAMAGE 47
|
||||
#define VARIOUS_TRY_AUTOTOMIZE 48
|
||||
#define VARIOUS_ABILITY_POPUP 49
|
||||
#define VARIOUS_JUMP_IF_TARGET_ALLY 50
|
||||
#define VARIOUS_TRY_SYNCHRONOISE 51
|
||||
#define VARIOUS_PSYCHO_SHIFT 52
|
||||
#define VARIOUS_CURE_STATUS 53
|
||||
#define VARIOUS_POWER_TRICK 54
|
||||
#define VARIOUS_AFTER_YOU 55
|
||||
#define VARIOUS_BESTOW 56
|
||||
#define VARIOUS_JUMP_IF_NOT_GROUNDED 57
|
||||
#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 58
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 59
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 60
|
||||
#define VARIOUS_SET_AURORA_VEIL 61
|
||||
#define VARIOUS_TRY_THIRD_TYPE 62
|
||||
#define VARIOUS_ACUPRESSURE 63
|
||||
#define VARIOUS_SET_POWDER 64
|
||||
#define VARIOUS_SPECTRAL_THIEF 65
|
||||
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 66
|
||||
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 67
|
||||
#define VARIOUS_JUMP_IF_ROAR_FAILS 68
|
||||
#define VARIOUS_TRY_INSTRUCT 69
|
||||
#define VARIOUS_JUMP_IF_NOT_BERRY 70
|
||||
#define VARIOUS_TRACE_ABILITY 71
|
||||
#define VARIOUS_UPDATE_NICK 72
|
||||
#define VARIOUS_TRY_ILLUSION_OFF 73
|
||||
#define VARIOUS_SET_SPRITEIGNORE0HP 74
|
||||
#define VARIOUS_HANDLE_FORM_CHANGE 75
|
||||
#define VARIOUS_GET_STAT_VALUE 76
|
||||
#define VARIOUS_JUMP_IF_FULL_HP 77
|
||||
#define VARIOUS_LOSE_TYPE 78
|
||||
#define VARIOUS_TRY_ACTIVATE_SOULHEART 79
|
||||
#define VARIOUS_TRY_ACTIVATE_RECEIVER 80
|
||||
#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 81
|
||||
#define VARIOUS_TRY_FRISK 82
|
||||
#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 83
|
||||
#define VARIOUS_TRY_FAIRY_LOCK 84
|
||||
#define VARIOUS_JUMP_IF_NO_ALLY 85
|
||||
#define VARIOUS_POISON_TYPE_IMMUNITY 86
|
||||
#define VARIOUS_JUMP_IF_HOLD_EFFECT 87
|
||||
#define VARIOUS_INFATUATE_WITH_BATTLER 88
|
||||
#define VARIOUS_SET_LAST_USED_ITEM 89
|
||||
#define VARIOUS_PARALYZE_TYPE_IMMUNITY 90
|
||||
#define VARIOUS_JUMP_IF_ABSENT 91
|
||||
#define VARIOUS_DESTROY_ABILITY_POPUP 92
|
||||
#define VARIOUS_TOTEM_BOOST 93
|
||||
#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 94
|
||||
#define VARIOUS_MOVEEND_ITEM_EFFECTS 95
|
||||
#define VARIOUS_TERRAIN_SEED 96
|
||||
#define VARIOUS_MAKE_INVISIBLE 97
|
||||
#define VARIOUS_ROOM_SERVICE 98
|
||||
#define VARIOUS_EERIE_SPELL_PP_REDUCE 99
|
||||
#define VARIOUS_JUMP_IF_TEAM_HEALTHY 100
|
||||
#define VARIOUS_TRY_HEAL_QUARTER_HP 101
|
||||
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 102
|
||||
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 103
|
||||
#define VARIOUS_GET_ROTOTILLER_TARGETS 104
|
||||
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 105
|
||||
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 106
|
||||
#define VARIOUS_CONSUME_BERRY 107
|
||||
#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 108
|
||||
#define VARIOUS_JUMP_IF_SPECIES 109
|
||||
#define VARIOUS_UPDATE_ABILITY_POPUP 110
|
||||
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 111
|
||||
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 112
|
||||
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 113
|
||||
#define VARIOUS_TRY_NO_RETREAT 114
|
||||
#define VARIOUS_CHECK_POLTERGEIST 115
|
||||
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 116
|
||||
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 117
|
||||
#define VARIOUS_JUMP_IF_UNDER_200 118
|
||||
#define VARIOUS_SET_SKY_DROP 119
|
||||
#define VARIOUS_CLEAR_SKY_DROP 120
|
||||
#define VARIOUS_SKY_DROP_YAWN 121
|
||||
#define VARIOUS_CURE_CERTAIN_STATUSES 122
|
||||
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 123
|
||||
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 124
|
||||
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 125
|
||||
#define VARIOUS_SAVE_BATTLER_ITEM 126
|
||||
#define VARIOUS_RESTORE_BATTLER_ITEM 127
|
||||
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 128
|
||||
#define VARIOUS_SWAP_SIDE_STATUSES 129
|
||||
#define VARIOUS_SWAP_STATS 130
|
||||
enum CmdVarious
|
||||
{
|
||||
VARIOUS_CANCEL_MULTI_TURN_MOVES,
|
||||
VARIOUS_IS_RUNNING_IMPOSSIBLE,
|
||||
VARIOUS_GET_MOVE_TARGET,
|
||||
VARIOUS_GET_BATTLER_FAINTED,
|
||||
VARIOUS_RESET_SWITCH_IN_ABILITY_BITS,
|
||||
VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP,
|
||||
VARIOUS_RESET_PLAYER_FAINTED,
|
||||
VARIOUS_PALACE_FLAVOR_TEXT,
|
||||
VARIOUS_ARENA_JUDGMENT_WINDOW,
|
||||
VARIOUS_ARENA_OPPONENT_MON_LOST,
|
||||
VARIOUS_ARENA_PLAYER_MON_LOST,
|
||||
VARIOUS_ARENA_BOTH_MONS_LOST,
|
||||
VARIOUS_EMIT_YESNOBOX,
|
||||
VARIOUS_DRAW_ARENA_REF_TEXT_BOX,
|
||||
VARIOUS_ERASE_ARENA_REF_TEXT_BOX,
|
||||
VARIOUS_ARENA_JUDGMENT_STRING,
|
||||
VARIOUS_ARENA_WAIT_STRING,
|
||||
VARIOUS_WAIT_CRY,
|
||||
VARIOUS_RETURN_OPPONENT_MON1,
|
||||
VARIOUS_RETURN_OPPONENT_MON2,
|
||||
VARIOUS_VOLUME_DOWN,
|
||||
VARIOUS_VOLUME_UP,
|
||||
VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT,
|
||||
VARIOUS_PALACE_TRY_ESCAPE_STATUS,
|
||||
VARIOUS_SET_TELEPORT_OUTCOME,
|
||||
VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC,
|
||||
VARIOUS_STAT_TEXT_BUFFER,
|
||||
VARIOUS_SWITCHIN_ABILITIES,
|
||||
VARIOUS_INSTANT_HP_DROP,
|
||||
VARIOUS_CLEAR_STATUS,
|
||||
VARIOUS_RESTORE_PP,
|
||||
VARIOUS_TRY_ACTIVATE_MOXIE,
|
||||
VARIOUS_TRY_ACTIVATE_FELL_STINGER,
|
||||
VARIOUS_PLAY_MOVE_ANIMATION,
|
||||
VARIOUS_SET_LUCKY_CHANT,
|
||||
VARIOUS_SUCKER_PUNCH_CHECK,
|
||||
VARIOUS_SET_SIMPLE_BEAM,
|
||||
VARIOUS_TRY_ENTRAINMENT,
|
||||
VARIOUS_SET_LAST_USED_ABILITY,
|
||||
VARIOUS_INVERT_STAT_STAGES,
|
||||
VARIOUS_TRY_ME_FIRST,
|
||||
VARIOUS_JUMP_IF_BATTLE_END,
|
||||
VARIOUS_TRY_ELECTRIFY,
|
||||
VARIOUS_TRY_SOAK,
|
||||
VARIOUS_TRY_LAST_RESORT,
|
||||
VARIOUS_SET_ARG_TO_BATTLE_DAMAGE,
|
||||
VARIOUS_TRY_AUTOTOMIZE,
|
||||
VARIOUS_ABILITY_POPUP,
|
||||
VARIOUS_JUMP_IF_TARGET_ALLY,
|
||||
VARIOUS_TRY_SYNCHRONOISE,
|
||||
VARIOUS_PSYCHO_SHIFT,
|
||||
VARIOUS_CURE_STATUS,
|
||||
VARIOUS_POWER_TRICK,
|
||||
VARIOUS_AFTER_YOU,
|
||||
VARIOUS_BESTOW,
|
||||
VARIOUS_JUMP_IF_NOT_GROUNDED,
|
||||
VARIOUS_HANDLE_TRAINER_SLIDE_MSG,
|
||||
VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF,
|
||||
VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON,
|
||||
VARIOUS_SET_AURORA_VEIL,
|
||||
VARIOUS_TRY_THIRD_TYPE,
|
||||
VARIOUS_ACUPRESSURE,
|
||||
VARIOUS_SET_POWDER,
|
||||
VARIOUS_SPECTRAL_THIEF,
|
||||
VARIOUS_GRAVITY_ON_AIRBORNE_MONS,
|
||||
VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS,
|
||||
VARIOUS_JUMP_IF_ROAR_FAILS,
|
||||
VARIOUS_TRY_INSTRUCT,
|
||||
VARIOUS_JUMP_IF_NOT_BERRY,
|
||||
VARIOUS_TRACE_ABILITY,
|
||||
VARIOUS_UPDATE_NICK,
|
||||
VARIOUS_TRY_ILLUSION_OFF,
|
||||
VARIOUS_SET_SPRITEIGNORE0HP,
|
||||
VARIOUS_HANDLE_FORM_CHANGE,
|
||||
VARIOUS_GET_STAT_VALUE,
|
||||
VARIOUS_JUMP_IF_FULL_HP,
|
||||
VARIOUS_LOSE_TYPE,
|
||||
VARIOUS_TRY_ACTIVATE_SOULHEART,
|
||||
VARIOUS_TRY_ACTIVATE_RECEIVER,
|
||||
VARIOUS_TRY_ACTIVATE_BEAST_BOOST,
|
||||
VARIOUS_TRY_FRISK,
|
||||
VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED,
|
||||
VARIOUS_TRY_FAIRY_LOCK,
|
||||
VARIOUS_JUMP_IF_NO_ALLY,
|
||||
VARIOUS_POISON_TYPE_IMMUNITY,
|
||||
VARIOUS_JUMP_IF_HOLD_EFFECT,
|
||||
VARIOUS_INFATUATE_WITH_BATTLER,
|
||||
VARIOUS_SET_LAST_USED_ITEM,
|
||||
VARIOUS_PARALYZE_TYPE_IMMUNITY,
|
||||
VARIOUS_JUMP_IF_ABSENT,
|
||||
VARIOUS_DESTROY_ABILITY_POPUP,
|
||||
VARIOUS_TOTEM_BOOST,
|
||||
VARIOUS_TRY_ACTIVATE_GRIM_NEIGH,
|
||||
VARIOUS_MOVEEND_ITEM_EFFECTS,
|
||||
VARIOUS_TERRAIN_SEED,
|
||||
VARIOUS_MAKE_INVISIBLE,
|
||||
VARIOUS_ROOM_SERVICE,
|
||||
VARIOUS_JUMP_IF_TEAM_HEALTHY,
|
||||
VARIOUS_TRY_HEAL_QUARTER_HP,
|
||||
VARIOUS_JUMP_IF_PRANKSTER_BLOCKED,
|
||||
VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER,
|
||||
VARIOUS_GET_ROTOTILLER_TARGETS,
|
||||
VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED,
|
||||
VARIOUS_TRY_ACTIVATE_BATTLE_BOND,
|
||||
VARIOUS_CONSUME_BERRY,
|
||||
VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL,
|
||||
VARIOUS_JUMP_IF_SPECIES,
|
||||
VARIOUS_UPDATE_ABILITY_POPUP,
|
||||
VARIOUS_JUMP_IF_WEATHER_AFFECTED,
|
||||
VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED,
|
||||
VARIOUS_SET_ATTACKER_STICKY_WEB_USER,
|
||||
VARIOUS_TRY_NO_RETREAT,
|
||||
VARIOUS_CHECK_POLTERGEIST,
|
||||
VARIOUS_CUT_1_3_HP_RAISE_STATS,
|
||||
VARIOUS_TRY_END_NEUTRALIZING_GAS,
|
||||
VARIOUS_JUMP_IF_UNDER_200,
|
||||
VARIOUS_SET_SKY_DROP,
|
||||
VARIOUS_CLEAR_SKY_DROP,
|
||||
VARIOUS_SKY_DROP_YAWN,
|
||||
VARIOUS_CURE_CERTAIN_STATUSES,
|
||||
VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES,
|
||||
VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY,
|
||||
VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT,
|
||||
VARIOUS_SAVE_BATTLER_ITEM,
|
||||
VARIOUS_RESTORE_BATTLER_ITEM,
|
||||
VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM,
|
||||
VARIOUS_SWAP_SIDE_STATUSES,
|
||||
VARIOUS_SWAP_STATS,
|
||||
};
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 1
|
||||
|
||||
@ -815,8 +815,7 @@ struct DayCare
|
||||
{
|
||||
struct DaycareMon mons[DAYCARE_MON_COUNT];
|
||||
u32 offspringPersonality;
|
||||
u8 stepCounter;
|
||||
//u8 padding[3];
|
||||
u32 stepCounter;
|
||||
};
|
||||
|
||||
struct LilycoveLadyQuiz
|
||||
|
||||
@ -495,6 +495,24 @@ struct MoveInfo
|
||||
u8 powerOverride;
|
||||
} zMove;
|
||||
|
||||
union {
|
||||
struct {
|
||||
u16 stringId;
|
||||
u16 status;
|
||||
} twoTurnAttack;
|
||||
struct {
|
||||
u16 side;
|
||||
u16 property; // can be used to remove the hardcoded values
|
||||
} protect;
|
||||
u32 status;
|
||||
u16 moveProperty;
|
||||
u16 holdEffect;
|
||||
u16 type;
|
||||
u16 fixedDamage;
|
||||
u16 absorbPercentage;
|
||||
u16 maxEffect;
|
||||
} argument;
|
||||
|
||||
s32 priority:4;
|
||||
u32 recoil:7;
|
||||
u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit.
|
||||
@ -548,8 +566,6 @@ struct MoveInfo
|
||||
u32 sketchBanned:1;
|
||||
u32 padding:5; // end of word
|
||||
|
||||
u32 argument;
|
||||
|
||||
// primary/secondary effects
|
||||
const struct AdditionalEffect *additionalEffects;
|
||||
|
||||
@ -564,8 +580,12 @@ struct MoveInfo
|
||||
#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__}
|
||||
#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ ))
|
||||
|
||||
// Just a hack to make a move boosted by Sheer Force despite having no secondary effects affected
|
||||
#define SHEER_FORCE_HACK { .moveEffect = 0, .chance = 100, }
|
||||
enum SheerForceBoost
|
||||
{
|
||||
SHEER_FORCE_AUTO_BOOST, // This is the default state when a move has a move effect with a chance
|
||||
SHEER_FORCE_BOOST, // If a move effect doesn't have an effect with a chance this can force a boost
|
||||
SHEER_FORCE_NO_BOOST, // Prevents a Sheer Force boost
|
||||
};
|
||||
|
||||
struct AdditionalEffect
|
||||
{
|
||||
@ -573,6 +593,8 @@ struct AdditionalEffect
|
||||
u8 self:1;
|
||||
u8 onlyIfTargetRaisedStats:1;
|
||||
u8 onChargeTurnOnly:1;
|
||||
u8 sheerForceBoost:2; // Handles edge cases for Sheer Force
|
||||
u8 padding:3;
|
||||
u8 chance; // 0% = effect certain, primary effect
|
||||
};
|
||||
|
||||
@ -885,6 +907,7 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
|
||||
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
|
||||
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
|
||||
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
|
||||
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
|
||||
bool32 SpeciesHasGenderDifferences(u16 species);
|
||||
bool32 TryFormChange(u32 monId, u32 side, u16 method);
|
||||
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define GUARD_RECORDED_BATTLE_H
|
||||
|
||||
#include "constants/battle.h"
|
||||
#include "link.h"
|
||||
#include "random.h"
|
||||
|
||||
#define BATTLER_RECORD_SIZE 664
|
||||
@ -10,13 +11,13 @@ struct RecordedBattleSave
|
||||
{
|
||||
struct Pokemon playerParty[PARTY_SIZE];
|
||||
struct Pokemon opponentParty[PARTY_SIZE];
|
||||
u8 playersName[MAX_BATTLERS_COUNT][PLAYER_NAME_LENGTH + 1];
|
||||
u8 playersGender[MAX_BATTLERS_COUNT];
|
||||
u32 playersTrainerId[MAX_BATTLERS_COUNT];
|
||||
u8 playersLanguage[MAX_BATTLERS_COUNT];
|
||||
u8 playersName[MAX_LINK_PLAYERS][PLAYER_NAME_LENGTH + 1];
|
||||
u8 playersGender[MAX_LINK_PLAYERS];
|
||||
u32 playersTrainerId[MAX_LINK_PLAYERS];
|
||||
u8 playersLanguage[MAX_LINK_PLAYERS];
|
||||
rng_value_t rngSeed;
|
||||
u32 battleFlags;
|
||||
u8 playersBattlers[MAX_BATTLERS_COUNT];
|
||||
u8 playersBattlers[MAX_LINK_PLAYERS];
|
||||
u16 opponentA;
|
||||
u16 opponentB;
|
||||
u16 partnerId;
|
||||
|
||||
@ -95,7 +95,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
|
||||
|
||||
#define ASSUMPTIONS \
|
||||
static void Assumptions(void); \
|
||||
__attribute__((section(".tests"), used)) static const struct Test sAssumptions = \
|
||||
__attribute__((section(".tests"), used, no_reorder)) static const struct Test sAssumptions = \
|
||||
{ \
|
||||
.name = "ASSUMPTIONS: " __FILE__, \
|
||||
.filename = __FILE__, \
|
||||
|
||||
@ -59,7 +59,9 @@ void rfu_LMAN_REQ_sendData(bool8 clockChangeFlag)
|
||||
clockChangeFlag = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
lman.parentAck_flag = 0;
|
||||
}
|
||||
rfu_REQ_sendData(clockChangeFlag);
|
||||
}
|
||||
|
||||
|
||||
@ -433,7 +433,7 @@ static void SetBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u3
|
||||
|
||||
if (move != 0
|
||||
&& move != 0xFFFF
|
||||
//&& gMovesInfo[move].power != 0 /* we want to get effectiveness and accuracy of status moves */
|
||||
//&& !IS_MOVE_STATUS(gMovesInfo[move]) /* we want to get effectiveness and accuracy of status moves */
|
||||
&& !(aiData->moveLimitations[battlerAtk] & (1u << moveIndex)))
|
||||
{
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE, weather, rollType);
|
||||
@ -2523,8 +2523,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-4);
|
||||
break;
|
||||
//TODO
|
||||
//case EFFECT_PLASMA_FISTS:
|
||||
//break;
|
||||
//case EFFECT_SHELL_TRAP:
|
||||
//break;
|
||||
//case EFFECT_BEAK_BLAST:
|
||||
@ -2619,8 +2617,8 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef))
|
||||
return score;
|
||||
|
||||
if (gMovesInfo[move].power == 0)
|
||||
return score; // can't make anything faint with no power
|
||||
if (IS_MOVE_STATUS(move))
|
||||
return score; // status moves aren't accounted here
|
||||
|
||||
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, movesetIndex, 0) && gMovesInfo[move].effect != EFFECT_EXPLOSION)
|
||||
{
|
||||
@ -4327,7 +4325,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case EFFECT_SOAK:
|
||||
if (HasMoveWithType(battlerAtk, TYPE_ELECTRIC) || HasMoveWithType(battlerAtk, TYPE_GRASS) || (HasMoveEffect(battlerAtk, EFFECT_SUPER_EFFECTIVE_ON_ARG) && gMovesInfo[move].argument == TYPE_WATER) )
|
||||
if (HasMoveWithType(battlerAtk, TYPE_ELECTRIC) || HasMoveWithType(battlerAtk, TYPE_GRASS) || (HasMoveEffect(battlerAtk, EFFECT_SUPER_EFFECTIVE_ON_ARG) && gMovesInfo[move].argument.type == TYPE_WATER) )
|
||||
ADJUST_SCORE(DECENT_EFFECT); // Get some super effective moves
|
||||
break;
|
||||
case EFFECT_THIRD_TYPE:
|
||||
@ -4437,10 +4435,6 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
|| gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY)
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
break;
|
||||
case EFFECT_SALT_CURE:
|
||||
if (IS_BATTLER_ANY_TYPE(battlerDef, TYPE_WATER, TYPE_STEEL))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
} // move effect checks
|
||||
|
||||
// check move additional effects that are likely to happen
|
||||
@ -4685,6 +4679,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
if (!HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_RAPID_SPIN) && ShouldTrap(battlerAtk, battlerDef, move))
|
||||
ADJUST_SCORE(BEST_EFFECT);
|
||||
break;
|
||||
case MOVE_EFFECT_SALT_CURE:
|
||||
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_WATER) || IS_BATTLER_OF_TYPE(battlerDef, TYPE_STEEL))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4937,7 +4936,7 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor
|
||||
{
|
||||
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef)
|
||||
|| CountUsablePartyMons(battlerAtk) == 0
|
||||
|| gMovesInfo[move].power != 0
|
||||
|| !IS_MOVE_STATUS(move)
|
||||
|| !HasMoveEffect(battlerAtk, EFFECT_BATON_PASS)
|
||||
|| IsBattlerTrapped(battlerAtk, TRUE))
|
||||
return score;
|
||||
|
||||
@ -122,8 +122,8 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
|
||||
hasStatusMove = TRUE;
|
||||
}
|
||||
|
||||
// Only check damage if move has power
|
||||
if (gMovesInfo[aiMove].power != 0)
|
||||
// Only check damage if it's a damaging move
|
||||
if (!IS_MOVE_STATUS(aiMove))
|
||||
{
|
||||
// Check if mon has a super effective move
|
||||
if (AI_GetMoveEffectiveness(aiMove, battler, opposingBattler) >= AI_EFFECTIVENESS_x2)
|
||||
@ -156,7 +156,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
playerMove = gBattleMons[opposingBattler].moves[i];
|
||||
if (playerMove != MOVE_NONE && gMovesInfo[playerMove].power != 0)
|
||||
if (playerMove != MOVE_NONE && !IS_MOVE_STATUS(playerMove))
|
||||
{
|
||||
damageTaken = AI_CalcDamage(playerMove, opposingBattler, battler, &effectiveness, FALSE, weather, DMG_ROLL_HIGHEST).expected;
|
||||
if (damageTaken > maxDamageTaken)
|
||||
@ -1242,7 +1242,7 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
aiMove = AI_DATA->switchinCandidate.battleMon.moves[j];
|
||||
if (aiMove != MOVE_NONE && gMovesInfo[aiMove].power != 0)
|
||||
if (aiMove != MOVE_NONE && !IS_MOVE_STATUS(aiMove))
|
||||
{
|
||||
aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j);
|
||||
dmg = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE, rollType);
|
||||
@ -1698,7 +1698,7 @@ static s32 GetMaxDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattle
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
playerMove = gBattleMons[opposingBattler].moves[i];
|
||||
if (playerMove != MOVE_NONE && gMovesInfo[playerMove].power != 0)
|
||||
if (playerMove != MOVE_NONE && !IS_MOVE_STATUS(playerMove))
|
||||
{
|
||||
damageTaken = AI_CalcPartyMonDamage(playerMove, opposingBattler, battler, battleMon, FALSE, DMG_ROLL_HIGHEST);
|
||||
if (damageTaken > maxDamageTaken)
|
||||
@ -1826,7 +1826,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
|
||||
{
|
||||
aiMove = AI_DATA->switchinCandidate.battleMon.moves[j];
|
||||
|
||||
if (aiMove != MOVE_NONE && gMovesInfo[aiMove].power != 0)
|
||||
if (aiMove != MOVE_NONE && !IS_MOVE_STATUS(aiMove))
|
||||
{
|
||||
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_CONSERVATIVE)
|
||||
damageDealt = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE, DMG_ROLL_LOWEST);
|
||||
@ -1856,7 +1856,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
|
||||
}
|
||||
|
||||
// Check for mon with resistance and super effective move for best type matchup mon with effective move
|
||||
if (aiMove != MOVE_NONE && gMovesInfo[aiMove].power != 0)
|
||||
if (aiMove != MOVE_NONE && !IS_MOVE_STATUS(aiMove))
|
||||
{
|
||||
if (typeMatchup < bestResistEffective)
|
||||
{
|
||||
|
||||
@ -470,11 +470,11 @@ bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveTy
|
||||
return TRUE;
|
||||
break;
|
||||
case EFFECT_FAIL_IF_NOT_ARG_TYPE:
|
||||
if (!IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[move].argument))
|
||||
if (!IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[move].argument.type))
|
||||
return TRUE;
|
||||
break;
|
||||
case EFFECT_HIT_SET_REMOVE_TERRAIN:
|
||||
if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) && gMovesInfo[move].argument == ARG_TRY_REMOVE_TERRAIN_FAIL)
|
||||
if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) && gMovesInfo[move].argument.moveProperty == ARG_TRY_REMOVE_TERRAIN_FAIL)
|
||||
return TRUE;
|
||||
break;
|
||||
case EFFECT_POLTERGEIST:
|
||||
@ -566,7 +566,7 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal
|
||||
expected = minimum = gBattleMons[damageCalcData->battlerAtk].level * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1);
|
||||
break;
|
||||
case EFFECT_FIXED_DAMAGE_ARG:
|
||||
expected = minimum = gMovesInfo[move].argument * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1);
|
||||
expected = minimum = gMovesInfo[move].argument.fixedDamage * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1);
|
||||
break;
|
||||
case EFFECT_MULTI_HIT:
|
||||
if (move == MOVE_WATER_SHURIKEN && gBattleMons[damageCalcData->battlerAtk].species == SPECIES_GRENINJA_ASH)
|
||||
@ -2027,7 +2027,7 @@ bool32 HasMoveEffect(u32 battlerId, u32 effect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument)
|
||||
bool32 IsPowerBasedOnStatus(u32 battlerId, u32 effect, u32 argument)
|
||||
{
|
||||
s32 i;
|
||||
u16 *moves = GetMovesArray(battlerId);
|
||||
@ -2036,7 +2036,7 @@ bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
|
||||
&& gMovesInfo[moves[i]].effect == effect
|
||||
&& (gMovesInfo[moves[i]].argument & argument))
|
||||
&& (gMovesInfo[moves[i]].argument.status & argument))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2419,7 +2419,7 @@ bool32 HasDamagingMove(u32 battlerId)
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].power != 0)
|
||||
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !IS_MOVE_STATUS(moves[i]))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2434,7 +2434,7 @@ bool32 HasDamagingMoveOfType(u32 battlerId, u32 type)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
|
||||
&& gMovesInfo[moves[i]].type == type && gMovesInfo[moves[i]].power != 0)
|
||||
&& gMovesInfo[moves[i]].type == type && !IS_MOVE_STATUS(moves[i]))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2477,7 +2477,7 @@ bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move)
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
return !(AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB
|
||||
|| (AI_GetWeather(AI_DATA) & gMovesInfo[move].argument));
|
||||
|| (AI_GetWeather(AI_DATA) & gMovesInfo[move].argument.twoTurnAttack.status));
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@ -3229,7 +3229,7 @@ bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage)
|
||||
if (move == 0xFFFF || AI_IsFaster(battlerAtk, battlerDef, move))
|
||||
{
|
||||
// using item or user goes first
|
||||
u32 healPercent = (gMovesInfo[move].argument == 0) ? 50 : gMovesInfo[move].argument;
|
||||
u32 healPercent = (gMovesInfo[move].argument.absorbPercentage == 0) ? 50 : gMovesInfo[move].argument.absorbPercentage;
|
||||
s32 healDmg = (healPercent * damage) / 100;
|
||||
|
||||
if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK)
|
||||
@ -3847,7 +3847,7 @@ void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
||||
if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveEffect(battlerAtk, EFFECT_PROTECT))
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT); // stall tactic
|
||||
|
||||
if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PSN_ANY)
|
||||
if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PSN_ANY)
|
||||
|| HasMoveEffect(battlerAtk, EFFECT_VENOM_DRENCH)
|
||||
|| AI_DATA->abilities[battlerAtk] == ABILITY_MERCILESS)
|
||||
ADJUST_SCORE_PTR(DECENT_EFFECT);
|
||||
@ -3874,8 +3874,8 @@ void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
}
|
||||
|
||||
if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN)
|
||||
|| HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN))
|
||||
if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN)
|
||||
|| IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN))
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
}
|
||||
}
|
||||
@ -3892,7 +3892,7 @@ void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
||||
u32 defSpeed = AI_DATA->speedStats[battlerDef];
|
||||
|
||||
if ((defSpeed >= atkSpeed && defSpeed / 2 < atkSpeed) // You'll go first after paralyzing foe
|
||||
|| HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS)
|
||||
|| IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS)
|
||||
|| (HasMoveWithMoveEffectExcept(battlerAtk, MOVE_EFFECT_FLINCH, EFFECT_FIRST_TURN_ONLY)) // filter out Fake Out
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_INFATUATION
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|
||||
@ -3917,8 +3917,8 @@ void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
||||
&& !(HasMoveEffect(battlerDef, EFFECT_SNORE) || HasMoveEffect(battlerDef, EFFECT_SLEEP_TALK)))
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
|
||||
if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP)
|
||||
|| HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP))
|
||||
if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP)
|
||||
|| IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP))
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
}
|
||||
|
||||
@ -3958,8 +3958,8 @@ void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
}
|
||||
|
||||
if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE)
|
||||
|| HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE))
|
||||
if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE)
|
||||
|| IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE))
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5413,7 +5413,9 @@ static void AnimMilkBottle_Step1(struct Sprite *sprite)
|
||||
sprite->data[6]++;
|
||||
}
|
||||
else if (sprite->data[7] > 0)
|
||||
{
|
||||
sprite->data[7]--;
|
||||
}
|
||||
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
|
||||
if (sprite->data[6] == 16 && sprite->data[7] == 0)
|
||||
@ -6642,6 +6644,79 @@ static void ReloadBattlerSprites(u32 battler, struct Pokemon *party)
|
||||
}
|
||||
}
|
||||
|
||||
static void TrySwapSkyDropTargets(u32 battlerAtk, u32 battlerPartner)
|
||||
{
|
||||
u32 i, temp;
|
||||
|
||||
// battlerAtk is using Ally Switch
|
||||
// check if our partner is the target of sky drop
|
||||
// If so, change that index to battlerAtk
|
||||
for (i = 0; i < gBattlersCount; i++) {
|
||||
if (gBattleStruct->skyDropTargets[i] == battlerPartner) {
|
||||
gBattleStruct->skyDropTargets[i] = battlerAtk;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Then swap our own sky drop targets with the partner in case our partner is mid-skydrop
|
||||
SWAP(gBattleStruct->skyDropTargets[battlerAtk], gBattleStruct->skyDropTargets[battlerPartner], temp);
|
||||
}
|
||||
|
||||
#define TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, side, field) \
|
||||
if (gSideTimers[side].field == battlerAtk) \
|
||||
gSideTimers[side].field = battlerPartner; \
|
||||
else if (gSideTimers[side].field == battlerPartner) \
|
||||
gSideTimers[side].field = battlerAtk;
|
||||
|
||||
static void TrySwapStickyWebBattlerId(u32 battlerAtk, u32 battlerPartner)
|
||||
{
|
||||
u32 atkSide = GetBattlerSide(battlerAtk);
|
||||
u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk));
|
||||
|
||||
// not all of these are needed to be swapped, but are done so to be robust to anything in the future that might care about them
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, reflectBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, lightscreenBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, mistBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, safeguardBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, auroraVeilBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, tailwindBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, luckyChantBattlerId);
|
||||
|
||||
// if we've set sticky web on the opposing side, need to swap stickyWebBattlerId for mirror armor
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, oppSide, stickyWebBattlerId);
|
||||
}
|
||||
#undef TRY_SIDE_TIMER_BATTLER_ID_SWAP
|
||||
|
||||
static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner)
|
||||
{
|
||||
u32 i, temp;
|
||||
u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk));
|
||||
|
||||
// if used future sight on opposing side, properly track who used it
|
||||
if (gSideStatuses[oppSide] & SIDE_STATUS_FUTUREATTACK) {
|
||||
for (i = 0; i < gBattlersCount; i++) {
|
||||
if (IsAlly(i,battlerAtk))
|
||||
continue; // only on opposing side
|
||||
if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerAtk) {
|
||||
// if target was attacked with future sight from us, now they'll be the partner slot
|
||||
gWishFutureKnock.futureSightBattlerIndex[i] = battlerPartner;
|
||||
gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerPartner];
|
||||
break;
|
||||
} else if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerPartner) {
|
||||
gWishFutureKnock.futureSightBattlerIndex[i] = battlerAtk;
|
||||
gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerAtk];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swap wish party indices
|
||||
if (gWishFutureKnock.wishCounter[battlerAtk] > 0
|
||||
|| gWishFutureKnock.wishCounter[battlerPartner] > 0) {
|
||||
SWAP(gWishFutureKnock.wishPartyId[battlerAtk], gWishFutureKnock.wishPartyId[battlerPartner], temp);
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
{
|
||||
s32 i, j;
|
||||
@ -6661,6 +6736,7 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
SwapStructData(&gSpecialStatuses[battlerAtk], &gSpecialStatuses[battlerPartner], data, sizeof(struct SpecialStatus));
|
||||
SwapStructData(&gProtectStructs[battlerAtk], &gProtectStructs[battlerPartner], data, sizeof(struct ProtectStruct));
|
||||
SwapStructData(&gBattleSpritesDataPtr->battlerData[battlerAtk], &gBattleSpritesDataPtr->battlerData[battlerPartner], data, sizeof(struct BattleSpriteInfo));
|
||||
SwapStructData(&gBattleStruct->illusion[battlerAtk], &gBattleStruct->illusion[battlerPartner], data, sizeof(struct Illusion));
|
||||
|
||||
SWAP(gBattleSpritesDataPtr->battlerData[battlerAtk].invisible, gBattleSpritesDataPtr->battlerData[battlerPartner].invisible, temp);
|
||||
SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp);
|
||||
@ -6684,6 +6760,7 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
break;
|
||||
}
|
||||
SWAP(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], temp);
|
||||
SWAP(gActionsByTurnOrder[i], gActionsByTurnOrder[j], temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -6692,6 +6769,10 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
SwitchTwoBattlersInParty(battlerAtk, battlerPartner);
|
||||
SWAP(gBattlerPartyIndexes[battlerAtk], gBattlerPartyIndexes[battlerPartner], temp);
|
||||
|
||||
TrySwapSkyDropTargets(battlerAtk, battlerPartner);
|
||||
TrySwapStickyWebBattlerId(battlerAtk, battlerPartner);
|
||||
TrySwapWishBattlerIds(battlerAtk, battlerPartner);
|
||||
|
||||
// For Snipe Shot and abilities Stalwart/Propeller Tail - keep the original target.
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
|
||||
@ -2266,7 +2266,9 @@ static void AnimTask_Splash_Step(u8 taskId)
|
||||
task->data[4] -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
task->data[1]++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (!RunAffineAnimFromTaskData(task))
|
||||
@ -3023,7 +3025,9 @@ static void AnimTask_SpeedDust_Step(u8 taskId)
|
||||
task->data[8] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
task->data[8] = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -742,7 +742,9 @@ static void AnimZapCannonSpark_Step(struct Sprite *sprite)
|
||||
sprite->invisible ^= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyAnimSprite(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimThunderboltOrb_Step(struct Sprite *sprite)
|
||||
@ -1024,7 +1026,9 @@ static void AnimTask_ElectricChargingParticles_Step(u8 taskId)
|
||||
}
|
||||
}
|
||||
else if(task->data[7] == 0)
|
||||
{
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimElectricChargingParticles_Step(struct Sprite *sprite)
|
||||
@ -1145,7 +1149,9 @@ void AnimTask_VoltTackleAttackerReappear(u8 taskId)
|
||||
gSprites[task->data[15]].x2 = task->data[14];
|
||||
}
|
||||
else
|
||||
{
|
||||
task->data[0]++;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@ -346,7 +346,9 @@ static void AnimConfuseRayBallBounce_Step2(struct Sprite *sprite)
|
||||
sprite->callback = DestroyAnimSpriteAndDisableBlend;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateConfuseRayBallBlend(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateConfuseRayBallBlend(struct Sprite *sprite)
|
||||
|
||||
@ -9244,7 +9244,7 @@ void AnimTask_DynamaxGrowth(u8 taskId) // from CFRU
|
||||
|
||||
void AnimTask_GetWeatherToSet(u8 taskId)
|
||||
{
|
||||
switch (gMovesInfo[gCurrentMove].argument)
|
||||
switch (gMovesInfo[gCurrentMove].argument.maxEffect)
|
||||
{
|
||||
case MAX_EFFECT_SUN:
|
||||
gBattleAnimArgs[ARG_RET_ID] = 1;
|
||||
|
||||
@ -1339,7 +1339,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
|
||||
gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleSpritesDataPtr->animationData->ballSubpx += 176;
|
||||
}
|
||||
|
||||
sprite->sTimer++;
|
||||
sprite->affineAnimPaused = FALSE;
|
||||
@ -1364,7 +1366,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
|
||||
ChangeSpriteAffineAnim(sprite, BALL_ROTATE_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->affineAnimPaused = TRUE;
|
||||
}
|
||||
break;
|
||||
case BALL_ROLL_2:
|
||||
if (gBattleSpritesDataPtr->animationData->ballSubpx > 255)
|
||||
@ -1373,7 +1377,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
|
||||
gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleSpritesDataPtr->animationData->ballSubpx += 176;
|
||||
}
|
||||
|
||||
sprite->sTimer++;
|
||||
sprite->affineAnimPaused = FALSE;
|
||||
@ -1408,7 +1414,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
|
||||
gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleSpritesDataPtr->animationData->ballSubpx += 176;
|
||||
}
|
||||
|
||||
sprite->sTimer++;
|
||||
sprite->affineAnimPaused = FALSE;
|
||||
@ -1598,7 +1606,9 @@ static void SpriteCB_Ball_FadeOut(struct Sprite *sprite)
|
||||
static void DestroySpriteAfterOneFrame(struct Sprite *sprite)
|
||||
{
|
||||
if (sprite->sFrame == 0)
|
||||
{
|
||||
sprite->sFrame = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeSpriteOamMatrix(sprite);
|
||||
@ -1618,7 +1628,9 @@ static void MakeCaptureStars(struct Sprite *sprite)
|
||||
u8 subpriority;
|
||||
|
||||
if (sprite->subpriority)
|
||||
{
|
||||
subpriority = sprite->subpriority - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
subpriority = 0;
|
||||
@ -2555,7 +2567,9 @@ static void SpriteCB_ShinyStars_Diagonal(struct Sprite *sprite)
|
||||
{
|
||||
// Delayed four frames to de-sync from encircling stars
|
||||
if (sprite->sTimer < 4)
|
||||
{
|
||||
sprite->sTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->invisible = FALSE;
|
||||
|
||||
@ -360,7 +360,7 @@ void BattleArena_AddMindPoints(u8 battler)
|
||||
// All moves with power != 0 give 1 point, with the following exceptions:
|
||||
// - Counter, Mirror Coat, and Bide give 0 points
|
||||
// - Fake Out subtracts 1 point
|
||||
// All moves with power == 0 give 0 points, with the following exceptions:
|
||||
// All status moves give 0 points, with the following exceptions:
|
||||
// - Protect, Detect, and Endure subtract 1 point
|
||||
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_FIRST_TURN_ONLY
|
||||
@ -369,7 +369,7 @@ void BattleArena_AddMindPoints(u8 battler)
|
||||
{
|
||||
gBattleStruct->arenaMindPoints[battler]--;
|
||||
}
|
||||
else if (gMovesInfo[gCurrentMove].power != 0
|
||||
else if (!IS_MOVE_STATUS(gCurrentMove)
|
||||
&& gMovesInfo[gCurrentMove].effect != EFFECT_COUNTER
|
||||
&& gMovesInfo[gCurrentMove].effect != EFFECT_MIRROR_COAT
|
||||
&& gMovesInfo[gCurrentMove].effect != EFFECT_METAL_BURST
|
||||
|
||||
@ -185,7 +185,9 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
|
||||
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
|
||||
{
|
||||
@ -198,13 +200,17 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
|
||||
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
|
||||
gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
|
||||
@ -274,7 +280,9 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
|
||||
m4aMPlayContinue(&gMPlayInfo_BGM);
|
||||
}
|
||||
else
|
||||
{
|
||||
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
|
||||
}
|
||||
}
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE;
|
||||
bgmRestored = TRUE;
|
||||
|
||||
@ -4326,7 +4326,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
|
||||
allocatedArray[k] = IsDomeStatusMoveEffect(move);
|
||||
break;
|
||||
case MOVE_POINTS_DMG:
|
||||
allocatedArray[k] = (gMovesInfo[move].power != 0) ? 1 : 0;
|
||||
allocatedArray[k] = (!IS_MOVE_STATUS(move)) ? 1 : 0;
|
||||
break;
|
||||
case MOVE_POINTS_DEF:
|
||||
allocatedArray[k] = IsDomeDefensiveMoveEffect(gMovesInfo[move].effect) ? 1 : 0;
|
||||
@ -5108,7 +5108,7 @@ static u16 GetWinningMove(int winnerTournamentId, int loserTournamentId, u8 roun
|
||||
moveIds[i * MAX_MON_MOVES + j] = gFacilityTrainerMons[DOME_MONS[winnerTournamentId][i]].moves[j];
|
||||
|
||||
movePower = gMovesInfo[moveIds[i * MAX_MON_MOVES + j]].power;
|
||||
if (movePower == 0)
|
||||
if (IS_MOVE_STATUS(moveIds[i * MAX_MON_MOVES + j]))
|
||||
movePower = 40;
|
||||
else if (movePower == 1)
|
||||
movePower = 60;
|
||||
|
||||
@ -320,7 +320,7 @@ u8 GetMaxMovePower(u32 move)
|
||||
{
|
||||
u8 tier;
|
||||
// G-Max Drum Solo, G-Max Hydrosnipe, and G-Max Fireball always have 160 base power.
|
||||
if (gMovesInfo[GetMaxMove(gBattlerAttacker, move)].argument == MAX_EFFECT_FIXED_POWER)
|
||||
if (gMovesInfo[GetMaxMove(gBattlerAttacker, move)].argument.maxEffect == MAX_EFFECT_FIXED_POWER)
|
||||
return 160;
|
||||
|
||||
// Exceptions to all other rules below:
|
||||
@ -470,7 +470,7 @@ void ChooseDamageNonTypesString(u8 type)
|
||||
// Returns the status effect that should be applied by a G-Max Move.
|
||||
static u32 GetMaxMoveStatusEffect(u32 move)
|
||||
{
|
||||
u8 maxEffect = gMovesInfo[move].argument;
|
||||
u8 maxEffect = gMovesInfo[move].argument.maxEffect;
|
||||
switch (maxEffect)
|
||||
{
|
||||
// Status 1
|
||||
@ -522,7 +522,7 @@ void BS_SetMaxMoveEffect(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
u16 effect = 0;
|
||||
u8 maxEffect = gMovesInfo[gCurrentMove].argument;
|
||||
u8 maxEffect = gMovesInfo[gCurrentMove].argument.maxEffect;
|
||||
|
||||
// Don't continue if the move didn't land.
|
||||
if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
@ -541,7 +541,7 @@ void BS_SetMaxMoveEffect(void)
|
||||
if (!NoAliveMonsForEitherParty())
|
||||
{
|
||||
// Max Effects are ordered by stat ID.
|
||||
SET_STATCHANGER(gMovesInfo[gCurrentMove].argument, 1, FALSE);
|
||||
SET_STATCHANGER(gMovesInfo[gCurrentMove].argument.maxEffect, 1, FALSE);
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_EffectRaiseStatAllies;
|
||||
effect++;
|
||||
@ -569,7 +569,7 @@ void BS_SetMaxMoveEffect(void)
|
||||
break;
|
||||
default:
|
||||
// Max Effects are ordered by stat ID.
|
||||
statId = gMovesInfo[gCurrentMove].argument - MAX_EFFECT_LOWER_ATTACK + 1;
|
||||
statId = gMovesInfo[gCurrentMove].argument.maxEffect - MAX_EFFECT_LOWER_ATTACK + 1;
|
||||
break;
|
||||
}
|
||||
SET_STATCHANGER(statId, stage, TRUE);
|
||||
@ -618,7 +618,7 @@ void BS_SetMaxMoveEffect(void)
|
||||
case MAX_EFFECT_PSYCHIC_TERRAIN:
|
||||
{
|
||||
u32 statusFlag = 0;
|
||||
switch (gMovesInfo[gCurrentMove].argument)
|
||||
switch (gMovesInfo[gCurrentMove].argument.moveProperty)
|
||||
{
|
||||
case MAX_EFFECT_MISTY_TERRAIN:
|
||||
statusFlag = STATUS_FIELD_MISTY_TERRAIN;
|
||||
|
||||
@ -754,13 +754,21 @@ bool8 BattleLoadAllHealthBoxesGfx(u8 state)
|
||||
LoadCompressedSpriteSheet(&sSpriteSheet_SinglesPlayerHealthbox);
|
||||
}
|
||||
else if (state == 3)
|
||||
{
|
||||
LoadCompressedSpriteSheet(&sSpriteSheet_SinglesOpponentHealthbox);
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
LoadCompressedSpriteSheet(&sSpriteSheets_HealthBar[GetBattlerPosition(0)]);
|
||||
}
|
||||
else if (state == 5)
|
||||
{
|
||||
LoadCompressedSpriteSheet(&sSpriteSheets_HealthBar[GetBattlerPosition(1)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -1517,7 +1517,9 @@ static void CB2_HandleStartMultiBattle(void)
|
||||
gBattleCommunication[MULTIUSE_STATE]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
case 3:
|
||||
if (IsLinkTaskFinished())
|
||||
@ -3228,6 +3230,13 @@ void SwitchInClearSetData(u32 battler)
|
||||
gBattleStruct->boosterEnergyActivates &= ~(1u << battler);
|
||||
gBattleStruct->canPickupItem &= ~(1u << battler);
|
||||
|
||||
if (gBattleStruct->pursuitTarget & (1u << battler))
|
||||
{
|
||||
gBattleStruct->pursuitTarget = 0;
|
||||
gBattleStruct->pursuitSwitchByMove = FALSE;
|
||||
gBattleStruct->pursuitStoredSwitch = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
||||
{
|
||||
// Switched into sticky web user slot, so reset stored battler ID
|
||||
@ -3358,9 +3367,13 @@ const u8* FaintClearSetData(u32 battler)
|
||||
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
|
||||
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
|
||||
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
|
||||
gBattleStruct->pursuitTarget = 0;
|
||||
gBattleStruct->pursuitSwitchByMove = FALSE;
|
||||
gBattleStruct->pursuitStoredSwitch = 0;
|
||||
|
||||
if (gBattleStruct->pursuitTarget & (1u << battler))
|
||||
{
|
||||
gBattleStruct->pursuitTarget = 0;
|
||||
gBattleStruct->pursuitSwitchByMove = FALSE;
|
||||
gBattleStruct->pursuitStoredSwitch = 0;
|
||||
}
|
||||
|
||||
gBattleStruct->palaceFlags &= ~(1u << battler);
|
||||
gBattleStruct->boosterEnergyActivates &= ~(1u << battler);
|
||||
@ -4844,7 +4857,7 @@ s8 GetMovePriority(u32 battler, u16 move)
|
||||
s8 priority;
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
|
||||
if (GetActiveGimmick(battler) == GIMMICK_Z_MOVE && gMovesInfo[move].power != 0)
|
||||
if (GetActiveGimmick(battler) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(move))
|
||||
move = GetUsableZMove(battler, move);
|
||||
|
||||
priority = gMovesInfo[move].priority;
|
||||
@ -5944,7 +5957,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost)
|
||||
}
|
||||
break;
|
||||
case EFFECT_CHANGE_TYPE_ON_ITEM:
|
||||
if (holdEffect == gMovesInfo[move].argument)
|
||||
if (holdEffect == gMovesInfo[move].argument.holdEffect)
|
||||
return ItemId_GetSecondaryId(heldItem);
|
||||
break;
|
||||
case EFFECT_REVELATION_DANCE:
|
||||
|
||||
@ -703,7 +703,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
[STRINGID_NOONEWILLBEABLETORUNAWAY] = COMPOUND_STRING("No one will be able to run away during the next turn!"),
|
||||
[STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} fell in love because of the {B_LAST_ITEM}!"),
|
||||
[STRINGID_CLOAKEDINAFREEZINGLIGHT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} became cloaked in a freezing light!"),
|
||||
[STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("The effects of the {B_LAST_ITEM} held by {B_DEF_NAME_WITH_PREFIX2} prevents its stats from being lowered!"),
|
||||
[STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("The effects of the {B_LAST_ITEM} held by {B_SCR_NAME_WITH_PREFIX2} prevents its stats from being lowered!"),
|
||||
[STRINGID_FERVENTWISHREACHED] = COMPOUND_STRING("{B_ATK_TRAINER_NAME}'s fervent wish has reached {B_ATK_NAME_WITH_PREFIX2}!"),
|
||||
[STRINGID_AIRLOCKACTIVATES] = COMPOUND_STRING("The effects of the weather disappeared."),
|
||||
[STRINGID_PRESSUREENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is exerting its pressure!"),
|
||||
@ -1277,7 +1277,10 @@ const u16 gWeatherStartsStringIds[] =
|
||||
|
||||
const u16 gTerrainStartsStringIds[] =
|
||||
{
|
||||
STRINGID_MISTSWIRLSAROUND, STRINGID_ELECTRICCURRENTISRUNNING, STRINGID_ISCOVEREDWITHGRASS, STRINGID_SEEMSWEIRD,
|
||||
[B_MSG_TERRAIN_SET_MISTY] = STRINGID_MISTSWIRLSAROUND,
|
||||
[B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_ELECTRICCURRENTISRUNNING,
|
||||
[B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_SEEMSWEIRD,
|
||||
[B_MSG_TERRAIN_SET_GRASSY] = STRINGID_ISCOVEREDWITHGRASS,
|
||||
};
|
||||
|
||||
const u16 gPrimalWeatherBlocksStringIds[] =
|
||||
@ -2630,7 +2633,9 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
|
||||
toCpy = gStringVar2;
|
||||
}
|
||||
else
|
||||
{
|
||||
toCpy = gBattleTextBuff2;
|
||||
}
|
||||
break;
|
||||
case B_TXT_BUFF3:
|
||||
if (gBattleTextBuff3[0] == B_BUFF_PLACEHOLDER_BEGIN)
|
||||
@ -2639,7 +2644,9 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
|
||||
toCpy = gStringVar3;
|
||||
}
|
||||
else
|
||||
{
|
||||
toCpy = gBattleTextBuff3;
|
||||
}
|
||||
break;
|
||||
case B_TXT_COPY_VAR_1:
|
||||
toCpy = gStringVar1;
|
||||
@ -2752,7 +2759,9 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
|
||||
toCpy = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
toCpy = sText_EnigmaBerry;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@ -1126,19 +1126,6 @@ static bool32 NoTargetPresent(u8 battler, u32 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 TryFormChangeBeforeMove(void)
|
||||
{
|
||||
bool32 result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE);
|
||||
if (!result)
|
||||
result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY);
|
||||
if (!result)
|
||||
return FALSE;
|
||||
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_AttackerFormChange;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType)
|
||||
{
|
||||
if ((ability == ABILITY_PROTEAN || ability == ABILITY_LIBERO)
|
||||
@ -1177,8 +1164,6 @@ static void Cmd_attackcanceler(void)
|
||||
CMD_ARGS();
|
||||
|
||||
s32 i;
|
||||
u16 attackerAbility = GetBattlerAbility(gBattlerAttacker);
|
||||
u32 moveType = GetMoveType(gCurrentMove);
|
||||
|
||||
if (gBattleStruct->usedEjectItem & (1u << gBattlerAttacker))
|
||||
{
|
||||
@ -1187,14 +1172,6 @@ static void Cmd_attackcanceler(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// Weight-based moves are blocked by Dynamax.
|
||||
if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove))
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gBattleOutcome != 0)
|
||||
{
|
||||
gCurrentActionFuncId = B_ACTION_FINISHED;
|
||||
@ -1207,28 +1184,8 @@ static void Cmd_attackcanceler(void)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEnd;
|
||||
return;
|
||||
}
|
||||
if (B_STANCE_CHANGE_FAIL < GEN_7 && TryFormChangeBeforeMove())
|
||||
if (AtkCanceller_MoveSuccessOrder())
|
||||
return;
|
||||
if (AtkCanceller_UnableToUseMove(moveType))
|
||||
return;
|
||||
|
||||
if (WEATHER_HAS_EFFECT && gMovesInfo[gCurrentMove].power)
|
||||
{
|
||||
if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL))
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove;
|
||||
return;
|
||||
}
|
||||
else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL))
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF
|
||||
&& GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND
|
||||
@ -1242,22 +1199,6 @@ static void Cmd_attackcanceler(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check Protean activation.
|
||||
if (ProteanTryChangeType(gBattlerAttacker, attackerAbility, gCurrentMove, moveType))
|
||||
{
|
||||
if (B_PROTEAN_LIBERO == GEN_9)
|
||||
gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE;
|
||||
PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
|
||||
gBattlerAbility = gBattlerAttacker;
|
||||
BattleScriptPushCursor();
|
||||
PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker);
|
||||
gBattleCommunication[MSG_DISPLAY] = 1;
|
||||
gBattlescriptCurrInstr = BattleScript_ProteanActivates;
|
||||
return;
|
||||
}
|
||||
|
||||
if (AtkCanceller_UnableToUseMove2())
|
||||
return;
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBattlerTarget, 0, 0, 0))
|
||||
return;
|
||||
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE
|
||||
@ -1268,8 +1209,6 @@ static void Cmd_attackcanceler(void)
|
||||
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
|
||||
return;
|
||||
}
|
||||
if (B_STANCE_CHANGE_FAIL >= GEN_7 && TryFormChangeBeforeMove())
|
||||
return;
|
||||
|
||||
gHitMarker &= ~HITMARKER_ALLOW_NO_PP;
|
||||
|
||||
@ -2503,7 +2442,9 @@ static void Cmd_attackanimation(void)
|
||||
{
|
||||
u32 multihit;
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_SUBSTITUTE)
|
||||
{
|
||||
multihit = gMultiHitCounter;
|
||||
}
|
||||
else if (gMultiHitCounter != 0 && gMultiHitCounter != 1)
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].hp <= gBattleStruct->moveDamage[gBattlerTarget])
|
||||
@ -2512,7 +2453,9 @@ static void Cmd_attackanimation(void)
|
||||
multihit = gMultiHitCounter;
|
||||
}
|
||||
else
|
||||
{
|
||||
multihit = gMultiHitCounter;
|
||||
}
|
||||
|
||||
BtlController_EmitMoveAnimation(gBattlerAttacker,
|
||||
BUFFER_A,
|
||||
@ -3133,17 +3076,26 @@ static void CheckSetUnburden(u8 battler)
|
||||
void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
||||
{
|
||||
gLastUsedItem = gBattleMons[battlerItem].item;
|
||||
gBattleMons[battlerItem].item = 0;
|
||||
gBattleMons[battlerItem].item = ITEM_NONE;
|
||||
|
||||
RecordItemEffectBattle(battlerItem, 0);
|
||||
RecordItemEffectBattle(battlerStealer, ItemId_GetHoldEffect(gLastUsedItem));
|
||||
gBattleMons[battlerStealer].item = gLastUsedItem;
|
||||
if (B_STEAL_WILD_ITEMS >= GEN_9
|
||||
&& !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))
|
||||
&& MoveHasAdditionalEffect(gCurrentMove, MOVE_EFFECT_STEAL_ITEM)
|
||||
&& battlerStealer == gBattlerAttacker) // ensure that Pickpocket isn't activating this
|
||||
{
|
||||
AddBagItem(gLastUsedItem, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecordItemEffectBattle(battlerStealer, ItemId_GetHoldEffect(gLastUsedItem));
|
||||
gBattleMons[battlerStealer].item = gLastUsedItem;
|
||||
gBattleResources->flags->flags[battlerStealer] &= ~RESOURCE_FLAG_UNBURDEN;
|
||||
BtlController_EmitSetMonData(battlerStealer, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gLastUsedItem), &gLastUsedItem); // set attacker item
|
||||
MarkBattlerForControllerExec(battlerStealer);
|
||||
}
|
||||
|
||||
RecordItemEffectBattle(battlerItem, ITEM_NONE);
|
||||
CheckSetUnburden(battlerItem);
|
||||
gBattleResources->flags->flags[battlerStealer] &= ~RESOURCE_FLAG_UNBURDEN;
|
||||
|
||||
BtlController_EmitSetMonData(battlerStealer, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gLastUsedItem), &gLastUsedItem); // set attacker item
|
||||
MarkBattlerForControllerExec(battlerStealer);
|
||||
|
||||
BtlController_EmitSetMonData(battlerItem, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].item), &gBattleMons[battlerItem].item); // remove target item
|
||||
MarkBattlerForControllerExec(battlerItem);
|
||||
@ -3172,7 +3124,8 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
bool32 statusChanged = FALSE;
|
||||
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
|
||||
u32 flags = 0;
|
||||
u16 battlerAbility;
|
||||
u32 battlerAbility;
|
||||
u32 side;
|
||||
bool8 activateAfterFaint = FALSE;
|
||||
|
||||
// NULL move effect
|
||||
@ -3395,7 +3348,9 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
RESET_RETURN
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
|
||||
{
|
||||
@ -3826,8 +3781,13 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
else
|
||||
{
|
||||
StealTargetItem(gBattlerAttacker, gBattlerTarget); // Attacker steals target item
|
||||
gBattleMons[gBattlerAttacker].item = ITEM_NONE; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
|
||||
gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
|
||||
|
||||
if (!(B_STEAL_WILD_ITEMS >= GEN_9
|
||||
&& !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))))
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].item = ITEM_NONE; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
|
||||
gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
|
||||
}
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_ItemSteal;
|
||||
}
|
||||
@ -4050,7 +4010,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
case MOVE_EFFECT_REMOVE_ARG_TYPE:
|
||||
// This seems unnecessary but is done to make it work properly with Parental Bond
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
switch (gMovesInfo[gCurrentMove].argument)
|
||||
switch (gMovesInfo[gCurrentMove].argument.type)
|
||||
{
|
||||
case TYPE_FIRE: // Burn Up
|
||||
gBattlescriptCurrInstr = BattleScript_RemoveFireType;
|
||||
@ -4062,7 +4022,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
gBattlescriptCurrInstr = BattleScript_RemoveGenericType;
|
||||
break;
|
||||
}
|
||||
RemoveBattlerType(gEffectBattler, gMovesInfo[gCurrentMove].argument);
|
||||
RemoveBattlerType(gEffectBattler, gMovesInfo[gCurrentMove].argument.type);
|
||||
break;
|
||||
case MOVE_EFFECT_ROUND:
|
||||
TryUpdateRoundTurnOrder(); // If another Pokémon uses Round before the user this turn, the user will use Round directly after it
|
||||
@ -4255,6 +4215,117 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_ION_DELUGE:
|
||||
if (!(gFieldStatuses & STATUS_FIELD_ION_DELUGE))
|
||||
{
|
||||
gFieldStatuses |= STATUS_FIELD_ION_DELUGE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectIonDeluge;
|
||||
}
|
||||
break;
|
||||
// TODO: The moves aromatherapy and heal bell need a refactor first
|
||||
// case MOVE_EFFECT_AROMATHERAPY:
|
||||
// break;
|
||||
case MOVE_EFFECT_HAZE:
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
TryResetBattlerStatChanges(i);
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectHaze;
|
||||
break;
|
||||
case MOVE_EFFECT_LEECH_SEED:
|
||||
if (!IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) && !(gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED))
|
||||
{
|
||||
gStatuses3[gBattlerTarget] |= gBattlerAttacker;
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_LEECHSEED;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectLeechSeed;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_REFLECT:
|
||||
side = GetBattlerSide(gBattlerAttacker);
|
||||
if (!(gSideStatuses[side] & SIDE_STATUS_REFLECT))
|
||||
{
|
||||
gSideStatuses[side] |= SIDE_STATUS_REFLECT;
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
|
||||
gSideTimers[side].reflectTimer = 8;
|
||||
else
|
||||
gSideTimers[side].reflectTimer = 5;
|
||||
gSideTimers[side].reflectBattlerId = gBattlerAttacker;
|
||||
|
||||
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_DOUBLE;
|
||||
else
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_SINGLE;
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectReflect;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_LIGHT_SCREEN:
|
||||
side = GetBattlerSide(gBattlerAttacker);
|
||||
if (!(gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN))
|
||||
{
|
||||
gSideStatuses[side] |= SIDE_STATUS_LIGHTSCREEN;
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
|
||||
gSideTimers[side].lightscreenTimer = 8;
|
||||
else
|
||||
gSideTimers[side].lightscreenTimer = 5;
|
||||
gSideTimers[side].lightscreenBattlerId = gBattlerAttacker;
|
||||
|
||||
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_DOUBLE;
|
||||
else
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_SINGLE;
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectLightScreen;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_SALT_CURE:
|
||||
if (!(gStatuses4[gBattlerTarget] & STATUS4_SALT_CURE))
|
||||
{
|
||||
gStatuses4[gBattlerTarget] |= STATUS4_SALT_CURE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectSaltCure;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_EERIE_SPELL:
|
||||
if (gLastMoves[gBattlerTarget] != MOVE_NONE && gLastMoves[gBattlerTarget] != 0xFFFF)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gLastMoves[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != MAX_MON_MOVES && gBattleMons[gBattlerTarget].pp[i] != 0)
|
||||
{
|
||||
u32 ppToDeduct = 3;
|
||||
|
||||
if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct)
|
||||
ppToDeduct = gBattleMons[gBattlerTarget].pp[i];
|
||||
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[gBattlerTarget])
|
||||
ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1);
|
||||
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
|
||||
gBattleMons[gBattlerTarget].pp[i] -= ppToDeduct;
|
||||
if (!(gDisableStructs[gBattlerTarget].mimickedMoves & (1u << i))
|
||||
&& !(gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED))
|
||||
{
|
||||
BtlController_EmitSetMonData(gBattlerTarget, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[gBattlerTarget].pp[i]), &gBattleMons[gBattlerTarget].pp[i]);
|
||||
MarkBattlerForControllerExec(gBattlerTarget);
|
||||
}
|
||||
|
||||
if (gBattleMons[gBattlerTarget].pp[i] == 0 && gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)
|
||||
CancelMultiTurnMoves(gBattlerTarget);
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectEerieSpell;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4875,13 +4946,10 @@ static void Cmd_getexp(void)
|
||||
{
|
||||
if (gBattlerPartyIndexes[2] == *expMonId && !(gAbsentBattlerFlags & 4))
|
||||
gBattleStruct->expGetterBattlerId = 2;
|
||||
else if (!(gAbsentBattlerFlags & 1))
|
||||
gBattleStruct->expGetterBattlerId = 0;
|
||||
else
|
||||
{
|
||||
if (!(gAbsentBattlerFlags & 1))
|
||||
gBattleStruct->expGetterBattlerId = 0;
|
||||
else
|
||||
gBattleStruct->expGetterBattlerId = 2;
|
||||
}
|
||||
gBattleStruct->expGetterBattlerId = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5959,7 +6027,9 @@ static void Cmd_moveend(void)
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_ABSORB:
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_ABSORB)
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_ABSORB
|
||||
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget))
|
||||
{
|
||||
if (gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && gMovesInfo[gCurrentMove].healingMove)
|
||||
{
|
||||
@ -5968,7 +6038,7 @@ static void Cmd_moveend(void)
|
||||
}
|
||||
else if (IsBattlerAlive(gBattlerAttacker) && MoveResultHasEffect(gBattlerTarget))
|
||||
{
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = max(1, (gBattleStruct->moveDamage[gBattlerTarget] * gMovesInfo[gCurrentMove].argument / 100));
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = max(1, (gBattleStruct->moveDamage[gBattlerTarget] * gMovesInfo[gCurrentMove].argument.absorbPercentage / 100));
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]);
|
||||
gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE;
|
||||
effect = TRUE;
|
||||
@ -5997,7 +6067,7 @@ static void Cmd_moveend(void)
|
||||
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)
|
||||
&& MoveResultHasEffect(gBattlerTarget)
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& gMovesInfo[gCurrentMove].power != 0
|
||||
&& !IS_MOVE_STATUS(gCurrentMove)
|
||||
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||
{
|
||||
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
||||
@ -6186,18 +6256,18 @@ static void Cmd_moveend(void)
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_REMOVE_STATUS: // Smelling salts, Wake-Up Slap, Sparkling Aria
|
||||
if ((gBattleMons[gBattlerTarget].status1 & gMovesInfo[gCurrentMove].argument)
|
||||
if ((gBattleMons[gBattlerTarget].status1 & gMovesInfo[gCurrentMove].argument.status)
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status1 &= ~(gMovesInfo[gCurrentMove].argument);
|
||||
gBattleMons[gBattlerTarget].status1 &= ~(gMovesInfo[gCurrentMove].argument.status);
|
||||
|
||||
BtlController_EmitSetMonData(gBattlerTarget, 0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerTarget].status1);
|
||||
MarkBattlerForControllerExec(gBattlerTarget);
|
||||
effect = TRUE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
|
||||
switch (gMovesInfo[gCurrentMove].argument)
|
||||
switch (gMovesInfo[gCurrentMove].argument.status)
|
||||
{
|
||||
case STATUS1_PARALYSIS:
|
||||
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal;
|
||||
@ -6501,7 +6571,7 @@ static void Cmd_moveend(void)
|
||||
if (gMultiHitCounter == 0)
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
if (gMovesInfo[gCurrentMove].argument == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty())
|
||||
if (gMovesInfo[gCurrentMove].argument.moveProperty == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty())
|
||||
gBattlescriptCurrInstr = BattleScript_ScaleShot;
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings;
|
||||
@ -9015,7 +9085,7 @@ static void Cmd_useitemonopponent(void)
|
||||
static bool32 HasAttackerFaintedTarget(void)
|
||||
{
|
||||
if (MoveResultHasEffect(gBattlerTarget)
|
||||
&& gMovesInfo[gCurrentMove].power != 0
|
||||
&& !IS_MOVE_STATUS(gCurrentMove)
|
||||
&& (gLastHitBy[gBattlerTarget] == 0xFF || gLastHitBy[gBattlerTarget] == gBattlerAttacker)
|
||||
&& gBattleStruct->moveTarget[gBattlerAttacker] == gBattlerTarget
|
||||
&& gBattlerTarget != gBattlerAttacker
|
||||
@ -9174,8 +9244,8 @@ static bool32 TryDefogClear(u32 battlerAtk, bool32 clear)
|
||||
|
||||
static bool32 TryTidyUpClear(u32 battlerAtk, bool32 clear)
|
||||
{
|
||||
s32 i;
|
||||
u8 saveBattler = gBattlerAttacker;
|
||||
u32 i;
|
||||
u32 saveBattler = gBattlerAttacker;
|
||||
|
||||
for (i = 0; i < NUM_BATTLE_SIDES; i++)
|
||||
{
|
||||
@ -9464,13 +9534,14 @@ static void Cmd_various(void)
|
||||
s32 i;
|
||||
u8 data[10];
|
||||
u32 battler, bits;
|
||||
enum CmdVarious variousId = cmd->id;
|
||||
|
||||
if (gBattleControllerExecFlags)
|
||||
return;
|
||||
|
||||
battler = GetBattlerForBattleScript(cmd->battler);
|
||||
|
||||
switch (cmd->id)
|
||||
switch (variousId)
|
||||
{
|
||||
// Roar will fail in a double wild battle when used by the player against one of the two alive wild mons.
|
||||
// Also when an opposing wild mon uses it againt its partner.
|
||||
@ -10399,7 +10470,7 @@ static void Cmd_various(void)
|
||||
case VARIOUS_SET_ARG_TO_BATTLE_DAMAGE:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = gMovesInfo[gCurrentMove].argument;
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = gMovesInfo[gCurrentMove].argument.fixedDamage;
|
||||
break;
|
||||
}
|
||||
case VARIOUS_TRY_AUTOTOMIZE:
|
||||
@ -10671,14 +10742,14 @@ static void Cmd_various(void)
|
||||
case VARIOUS_TRY_THIRD_TYPE:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
if (IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument) || GetActiveGimmick(battler) == GIMMICK_TERA)
|
||||
if (IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument.type) || GetActiveGimmick(battler) == GIMMICK_TERA)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[battler].types[2] = gMovesInfo[gCurrentMove].argument;
|
||||
PREPARE_TYPE_BUFFER(gBattleTextBuff1, gMovesInfo[gCurrentMove].argument);
|
||||
gBattleMons[battler].types[2] = gMovesInfo[gCurrentMove].argument.type;
|
||||
PREPARE_TYPE_BUFFER(gBattleTextBuff1, gMovesInfo[gCurrentMove].argument.type);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
return;
|
||||
@ -10787,53 +10858,6 @@ static void Cmd_various(void)
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
}
|
||||
case VARIOUS_EERIE_SPELL_PP_REDUCE:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
if (gLastMoves[battler] != 0 && gLastMoves[battler] != 0xFFFF)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gLastMoves[battler] == gBattleMons[battler].moves[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != MAX_MON_MOVES && gBattleMons[battler].pp[i] != 0)
|
||||
{
|
||||
s32 ppToDeduct = 3;
|
||||
|
||||
if (gBattleMons[battler].pp[i] < ppToDeduct)
|
||||
ppToDeduct = gBattleMons[battler].pp[i];
|
||||
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[battler])
|
||||
ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1);
|
||||
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
|
||||
gBattleMons[battler].pp[i] -= ppToDeduct;
|
||||
if (!(gDisableStructs[battler].mimickedMoves & (1u << i))
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
{
|
||||
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[battler].pp[i]), &gBattleMons[battler].pp[i]);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
|
||||
if (gBattleMons[battler].pp[i] == 0 && gBattleStruct->skyDropTargets[battler] == 0xFF)
|
||||
CancelMultiTurnMoves(battler);
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr; // continue
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp
|
||||
}
|
||||
return;
|
||||
}
|
||||
case VARIOUS_JUMP_IF_TEAM_HEALTHY:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *jumpInstr);
|
||||
@ -11345,7 +11369,7 @@ static void Cmd_setprotectlike(void)
|
||||
|| (gCurrentMove == MOVE_WIDE_GUARD && B_WIDE_GUARD != GEN_5)
|
||||
|| (gCurrentMove == MOVE_QUICK_GUARD && B_QUICK_GUARD != GEN_5))
|
||||
{
|
||||
if (!gMovesInfo[gCurrentMove].argument) // Protects one mon only.
|
||||
if (!gMovesInfo[gCurrentMove].argument.protect.side) // Protects one mon only.
|
||||
{
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_ENDURE)
|
||||
{
|
||||
@ -11902,8 +11926,8 @@ static void Cmd_setdrainedhp(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
|
||||
if (gMovesInfo[gCurrentMove].argument != 0)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = (gHpDealt * gMovesInfo[gCurrentMove].argument / 100);
|
||||
if (gMovesInfo[gCurrentMove].argument.absorbPercentage != 0)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = (gHpDealt * gMovesInfo[gCurrentMove].argument.absorbPercentage / 100);
|
||||
else
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = (gHpDealt / 2);
|
||||
|
||||
@ -12267,7 +12291,10 @@ static void Cmd_statbuffchange(void)
|
||||
const u8 *ptrBefore = gBattlescriptCurrInstr;
|
||||
const u8 *failInstr = cmd->failInstr;
|
||||
|
||||
if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger), GET_STAT_BUFF_ID(gBattleScripting.statChanger), flags, failInstr) == STAT_CHANGE_WORKED)
|
||||
if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger),
|
||||
GET_STAT_BUFF_ID(gBattleScripting.statChanger),
|
||||
flags,
|
||||
failInstr) == STAT_CHANGE_WORKED)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
else if (gBattlescriptCurrInstr == ptrBefore) // Prevent infinite looping.
|
||||
gBattlescriptCurrInstr = failInstr;
|
||||
@ -12320,7 +12347,7 @@ static void Cmd_twoturnmoveschargestringandanimation(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *animationThenStringPtr);
|
||||
|
||||
gBattleScripting.savedStringId = LOHALF(gMovesInfo[gCurrentMove].argument);
|
||||
gBattleScripting.savedStringId = gMovesInfo[gCurrentMove].argument.twoTurnAttack.stringId;
|
||||
if (B_UPDATED_MOVE_DATA < GEN_5 || MoveHasChargeTurnAdditionalEffect(gCurrentMove))
|
||||
gBattlescriptCurrInstr = cmd->animationThenStringPtr;
|
||||
else
|
||||
@ -12988,7 +13015,10 @@ static void Cmd_setsubstitute(void)
|
||||
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_SUBSTITUTE;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_WRAPPED;
|
||||
gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker];
|
||||
if (factor == 2)
|
||||
gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker] / 2;
|
||||
else
|
||||
gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker];
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SUBSTITUTE;
|
||||
gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE;
|
||||
}
|
||||
@ -13560,7 +13590,7 @@ static void Cmd_tryspiteppreduce(void)
|
||||
{
|
||||
s32 ppToDeduct = B_PP_REDUCED_BY_SPITE >= GEN_4 ? 4 : (Random() & 3) + 2;
|
||||
// G-Max Depletion only deducts 2 PP.
|
||||
if (IsMaxMove(gCurrentMove) && gMovesInfo[gCurrentMove].argument == MAX_EFFECT_SPITE)
|
||||
if (IsMaxMove(gCurrentMove) && gMovesInfo[gCurrentMove].argument.maxEffect == MAX_EFFECT_SPITE)
|
||||
ppToDeduct = 2;
|
||||
|
||||
if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct)
|
||||
@ -14277,6 +14307,7 @@ static void Cmd_trydobeatup(void)
|
||||
&& !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS))
|
||||
break;
|
||||
}
|
||||
|
||||
if (gBattleCommunication[0] < PARTY_SIZE)
|
||||
{
|
||||
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattleCommunication[0])
|
||||
@ -14294,9 +14325,13 @@ static void Cmd_trydobeatup(void)
|
||||
gBattleCommunication[0]++;
|
||||
}
|
||||
else if (beforeLoop != 0)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->endInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -14307,7 +14342,7 @@ static void Cmd_setsemiinvulnerablebit(void)
|
||||
|
||||
if (gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].semiInvulnerableEffect == TRUE)
|
||||
{
|
||||
u32 semiInvulnerableEffect = UNCOMPRESS_BITS(HIHALF(gMovesInfo[gCurrentMove].argument));
|
||||
u32 semiInvulnerableEffect = UNCOMPRESS_BITS(gMovesInfo[gCurrentMove].argument.twoTurnAttack.status);
|
||||
if (cmd->clear)
|
||||
gStatuses3[gBattlerAttacker] &= ~semiInvulnerableEffect;
|
||||
else
|
||||
@ -14331,7 +14366,7 @@ static bool32 CheckIfCanFireTwoTurnMoveNow(u8 battler, bool8 checkChargeTurnEffe
|
||||
|
||||
// Certain two-turn moves may fire on the first turn in the right weather (Solar Beam, Electro Shot)
|
||||
// By default, all two-turn moves have the option of adding weather to their argument
|
||||
if (IsBattlerWeatherAffected(battler, HIHALF(gMovesInfo[gCurrentMove].argument)))
|
||||
if (IsBattlerWeatherAffected(battler, gMovesInfo[gCurrentMove].argument.twoTurnAttack.status))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@ -15090,10 +15125,10 @@ static void Cmd_switchoutabilities(void)
|
||||
break;
|
||||
case ABILITY_REGENERATOR:
|
||||
{
|
||||
u32 regenerate = GetNonDynamaxMaxHP(gBattlerAttacker) / 3;
|
||||
u32 regenerate = GetNonDynamaxMaxHP(battler) / 3;
|
||||
regenerate += gBattleMons[battler].hp;
|
||||
if (gBattleStruct->moveDamage[gBattlerAttacker] > gBattleMons[battler].maxHP)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[battler].maxHP;
|
||||
if (regenerate > gBattleMons[battler].maxHP)
|
||||
regenerate = gBattleMons[battler].maxHP;
|
||||
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_HP_BATTLE,
|
||||
1u << *(gBattleStruct->battlerPartyIndexes + battler),
|
||||
sizeof(regenerate),
|
||||
@ -15126,7 +15161,7 @@ static void Cmd_jumpifnotcurrentmoveargtype(void)
|
||||
u8 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
const u8 *failInstr = cmd->failInstr;
|
||||
|
||||
if (!IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument))
|
||||
if (!IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument.type))
|
||||
gBattlescriptCurrInstr = failInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
@ -16885,20 +16920,11 @@ void BS_JumpIfElectricAbilityAffected(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_ApplySaltCure(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler);
|
||||
|
||||
u8 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
gStatuses4[battler] |= STATUS4_SALT_CURE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_JumpIfArgument(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 argument, const u8 *jumpInstr);
|
||||
|
||||
if (gMovesInfo[gCurrentMove].argument == cmd->argument)
|
||||
if (gMovesInfo[gCurrentMove].argument.moveProperty == cmd->argument)
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
@ -16928,7 +16954,7 @@ void BS_SetRemoveTerrain(void)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC;
|
||||
break;
|
||||
case EFFECT_HIT_SET_REMOVE_TERRAIN:
|
||||
switch (gMovesInfo[gCurrentMove].argument)
|
||||
switch (gMovesInfo[gCurrentMove].argument.moveProperty)
|
||||
{
|
||||
case ARG_SET_PSYCHIC_TERRAIN: // Genesis Supernova
|
||||
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN;
|
||||
@ -17245,7 +17271,7 @@ void BS_TryHealPulse(void)
|
||||
{
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && gMovesInfo[gCurrentMove].pulseMove)
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 75 / 100);
|
||||
else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && gMovesInfo[gCurrentMove].argument == MOVE_EFFECT_FLORAL_HEALING)
|
||||
else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && gMovesInfo[gCurrentMove].argument.moveProperty == MOVE_EFFECT_FLORAL_HEALING)
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 2 / 3);
|
||||
else
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) / 2);
|
||||
|
||||
1331
src/battle_util.c
@ -1711,11 +1711,13 @@ bool32 IsEnigmaBerryValid(void)
|
||||
const struct Berry *GetBerryInfo(u8 berry)
|
||||
{
|
||||
if (berry == ITEM_TO_BERRY(ITEM_ENIGMA_BERRY_E_READER) && IsEnigmaBerryValid())
|
||||
{
|
||||
#if FREE_ENIGMA_BERRY == FALSE
|
||||
return (struct Berry *)(&gSaveBlock1Ptr->enigmaBerry.berry);
|
||||
#else
|
||||
return &gBerries[0]; //never reached, but will appease the compiler gods
|
||||
#endif //FREE_ENIGMA_BERRY
|
||||
}
|
||||
else
|
||||
{
|
||||
if (berry == BERRY_NONE || berry > ITEM_TO_BERRY(LAST_BERRY_INDEX))
|
||||
@ -2037,7 +2039,9 @@ static u8 CalcBerryYieldInternal(u16 max, u16 min, u8 water)
|
||||
u32 extraYield;
|
||||
|
||||
if (water == 0 || OW_BERRY_MOISTURE)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
else
|
||||
{
|
||||
randMin = (max - min) * (water - 1);
|
||||
|
||||
@ -3398,7 +3398,9 @@ static u32 Cmd_StopGame(struct BerryCrushGame *game, u8 *args)
|
||||
break;
|
||||
case 2:
|
||||
if (game->gfx.counter != 0)
|
||||
{
|
||||
game->gfx.counter--;
|
||||
}
|
||||
else
|
||||
{
|
||||
RunOrScheduleCommand(CMD_CLOSE_LINK, SCHEDULE_CMD, NULL);
|
||||
|
||||
@ -389,7 +389,9 @@ static u8 AcroBikeHandleInputWheelieStanding(u8 *newDirection, u16 newKeys, u16
|
||||
gPlayerAvatar.runningState = NOT_MOVING;
|
||||
|
||||
if (heldKeys & B_BUTTON)
|
||||
{
|
||||
gPlayerAvatar.bikeFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// B button was released.
|
||||
|
||||
@ -54,7 +54,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
|
||||
if (B_LEVEL_CAP_EXP_UP)
|
||||
{
|
||||
levelDifference = currentLevelCap - level;
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingUp))
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingUp) - 1)
|
||||
return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingUp) - 1]);
|
||||
else
|
||||
return expValue + (expValue / sExpScalingUp[levelDifference]);
|
||||
@ -71,7 +71,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
|
||||
else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT)
|
||||
{
|
||||
levelDifference = level - currentLevelCap;
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingDown))
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingDown) - 1)
|
||||
return expValue / sExpScalingDown[ARRAY_COUNT(sExpScalingDown) - 1];
|
||||
else
|
||||
return expValue / sExpScalingDown[levelDifference];
|
||||
|
||||
@ -2767,7 +2767,9 @@ static void Task_EndAppeals(u8 taskId)
|
||||
CalculateFinalScores();
|
||||
ContestClearGeneralTextWindow();
|
||||
if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK))
|
||||
{
|
||||
BravoTrainerPokemonProfile_BeforeInterview1(eContestantStatus[gContestPlayerMonIndex].prevMove);
|
||||
}
|
||||
else
|
||||
{
|
||||
CalculateContestLiveUpdateData();
|
||||
|
||||
@ -619,15 +619,18 @@ static void ContestEffect_QualityDependsOnTiming(void)
|
||||
{
|
||||
appeal = 10;
|
||||
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_NOT_VERY_WELL);
|
||||
} else if (rval < 6)
|
||||
}
|
||||
else if (rval < 6)
|
||||
{
|
||||
appeal = 20;
|
||||
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_SLIGHTLY_WELL2);
|
||||
} else if (rval < 8)
|
||||
}
|
||||
else if (rval < 8)
|
||||
{
|
||||
appeal = 40;
|
||||
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_PRETTY_WELL2);
|
||||
} else if (rval < 9)
|
||||
}
|
||||
else if (rval < 9)
|
||||
{
|
||||
appeal = 60;
|
||||
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_VERY_WELL);
|
||||
@ -868,7 +871,9 @@ static void ContestEffect_ScrambleNextTurnOrder(void)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
rval--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -908,7 +913,9 @@ static void ContestEffect_BadlyStartleMonsWithGoodAppeals(void)
|
||||
eContestAppealResults.jam = RoundUp(eContestAppealResults.jam);
|
||||
}
|
||||
else
|
||||
{
|
||||
eContestAppealResults.jam = 10;
|
||||
}
|
||||
eContestAppealResults.jamQueue[0] = i;
|
||||
eContestAppealResults.jamQueue[1] = CONTESTANT_NONE;
|
||||
if (WasAtLeastOneOpponentJammed())
|
||||
@ -1071,7 +1078,9 @@ static s16 RoundTowardsZero(s16 score)
|
||||
score -= 10 - absScore;
|
||||
}
|
||||
else
|
||||
{
|
||||
score -= absScore;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
|
||||
@ -1832,12 +1832,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_EERIE_SPELL] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectEerieSpell,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_JUNGLE_HEALING] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectJungleHealing,
|
||||
@ -1901,42 +1895,12 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_GLITZY_GLOW] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectGlitzyGlow,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_BADDY_BAD] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectBaddyBad,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_SAPPY_SEED] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSappySeed,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_FREEZY_FROST] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectFreezyFrost,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_SPARKLY_SWIRL] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSparklySwirl,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_PLASMA_FISTS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectPlasmaFists,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_HYPERSPACE_FURY] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectHyperspaceFury,
|
||||
@ -2134,12 +2098,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_SALT_CURE] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSaltCure,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_CHILLY_RECEPTION] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectChillyReception,
|
||||
|
||||
@ -14459,11 +14459,11 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
|
||||
#endif //P_FAMILY_SHIELDON
|
||||
|
||||
#if P_FAMILY_BURMY
|
||||
const u32 gMonFrontPic_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/anim_front.4bpp.lz");
|
||||
const u32 gMonPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/normal.gbapal.lz");
|
||||
const u32 gMonBackPic_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/back.4bpp.lz");
|
||||
const u32 gMonShinyPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/shiny.gbapal.lz");
|
||||
const u8 gMonIcon_BurmyPlantCloak[] = INCBIN_U8("graphics/pokemon/burmy/icon.4bpp");
|
||||
const u32 gMonFrontPic_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/anim_front.4bpp.lz");
|
||||
const u32 gMonPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/normal.gbapal.lz");
|
||||
const u32 gMonBackPic_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/back.4bpp.lz");
|
||||
const u32 gMonShinyPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/shiny.gbapal.lz");
|
||||
const u8 gMonIcon_BurmyPlant[] = INCBIN_U8("graphics/pokemon/burmy/icon.4bpp");
|
||||
#if P_FOOTPRINTS
|
||||
const u8 gMonFootprint_Burmy[] = INCBIN_U8("graphics/pokemon/burmy/footprint.1bpp");
|
||||
#endif //P_FOOTPRINTS
|
||||
@ -14481,24 +14481,24 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
|
||||
const u8 gMonIcon_BurmyTrash[] = INCBIN_U8("graphics/pokemon/burmy/trash/icon.4bpp");
|
||||
|
||||
#if OW_POKEMON_OBJECT_EVENTS
|
||||
const u32 gObjectEventPic_BurmyPlantCloak[] = INCBIN_COMP("graphics/pokemon/burmy/overworld.4bpp");
|
||||
const u32 gObjectEventPic_BurmyPlant[] = INCBIN_COMP("graphics/pokemon/burmy/overworld.4bpp");
|
||||
const u32 gObjectEventPic_BurmySandy[] = INCBIN_COMP("graphics/pokemon/burmy/sandy/overworld.4bpp");
|
||||
const u32 gObjectEventPic_BurmyTrash[] = INCBIN_COMP("graphics/pokemon/burmy/trash/overworld.4bpp");
|
||||
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
|
||||
const u32 gOverworldPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_BurmySandy[] = INCBIN_U32("graphics/pokemon/burmy/sandy/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_BurmyTrash[] = INCBIN_U32("graphics/pokemon/burmy/trash/overworld_normal.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BurmySandy[] = INCBIN_U32("graphics/pokemon/burmy/sandy/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BurmyTrash[] = INCBIN_U32("graphics/pokemon/burmy/trash/overworld_shiny.gbapal.lz");
|
||||
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
|
||||
#endif //OW_POKEMON_OBJECT_EVENTS
|
||||
|
||||
const u32 gMonFrontPic_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/anim_front.4bpp.lz");
|
||||
const u32 gMonPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/normal.gbapal.lz");
|
||||
const u32 gMonBackPic_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/back.4bpp.lz");
|
||||
const u32 gMonShinyPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/shiny.gbapal.lz");
|
||||
const u8 gMonIcon_WormadamPlantCloak[] = INCBIN_U8("graphics/pokemon/wormadam/icon.4bpp");
|
||||
const u32 gMonFrontPic_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/anim_front.4bpp.lz");
|
||||
const u32 gMonPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/normal.gbapal.lz");
|
||||
const u32 gMonBackPic_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/back.4bpp.lz");
|
||||
const u32 gMonShinyPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/shiny.gbapal.lz");
|
||||
const u8 gMonIcon_WormadamPlant[] = INCBIN_U8("graphics/pokemon/wormadam/icon.4bpp");
|
||||
#if P_FOOTPRINTS
|
||||
const u8 gMonFootprint_Wormadam[] = INCBIN_U8("graphics/pokemon/wormadam/footprint.1bpp");
|
||||
#endif //P_FOOTPRINTS
|
||||
@ -14516,14 +14516,14 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
|
||||
const u8 gMonIcon_WormadamTrash[] = INCBIN_U8("graphics/pokemon/wormadam/trash/icon.4bpp");
|
||||
|
||||
#if OW_POKEMON_OBJECT_EVENTS
|
||||
const u32 gObjectEventPic_WormadamPlantCloak[] = INCBIN_COMP("graphics/pokemon/wormadam/overworld.4bpp");
|
||||
const u32 gObjectEventPic_WormadamPlant[] = INCBIN_COMP("graphics/pokemon/wormadam/overworld.4bpp");
|
||||
const u32 gObjectEventPic_WormadamSandy[] = INCBIN_COMP("graphics/pokemon/wormadam/sandy/overworld.4bpp");
|
||||
const u32 gObjectEventPic_WormadamTrash[] = INCBIN_COMP("graphics/pokemon/wormadam/trash/overworld.4bpp");
|
||||
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
|
||||
const u32 gOverworldPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_WormadamSandy[] = INCBIN_U32("graphics/pokemon/wormadam/sandy/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_WormadamTrash[] = INCBIN_U32("graphics/pokemon/wormadam/trash/overworld_normal.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_WormadamSandy[] = INCBIN_U32("graphics/pokemon/wormadam/sandy/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_WormadamTrash[] = INCBIN_U32("graphics/pokemon/wormadam/trash/overworld_shiny.gbapal.lz");
|
||||
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
|
||||
|
||||
@ -3136,8 +3136,8 @@ static const struct SpriteFrameImage sPicTable_Bastiodon[] = {
|
||||
#endif //P_FAMILY_SHIELDON
|
||||
|
||||
#if P_FAMILY_BURMY
|
||||
static const struct SpriteFrameImage sPicTable_BurmyPlantCloak[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_BurmyPlantCloak, 4, 4),
|
||||
static const struct SpriteFrameImage sPicTable_BurmyPlant[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_BurmyPlant, 4, 4),
|
||||
};
|
||||
static const struct SpriteFrameImage sPicTable_BurmySandy[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_BurmySandy, 4, 4),
|
||||
@ -3145,8 +3145,8 @@ static const struct SpriteFrameImage sPicTable_BurmySandy[] = {
|
||||
static const struct SpriteFrameImage sPicTable_BurmyTrash[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_BurmyTrash, 4, 4),
|
||||
};
|
||||
static const struct SpriteFrameImage sPicTable_WormadamPlantCloak[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_WormadamPlantCloak, 4, 4),
|
||||
static const struct SpriteFrameImage sPicTable_WormadamPlant[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_WormadamPlant, 4, 4),
|
||||
};
|
||||
static const struct SpriteFrameImage sPicTable_WormadamSandy[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_WormadamSandy, 4, 4),
|
||||
|
||||
@ -7717,7 +7717,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
|
||||
LEVEL_UP_MOVE(10, MOVE_PROTECT),
|
||||
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
|
||||
|
||||
@ -7961,7 +7961,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
|
||||
LEVEL_UP_MOVE(10, MOVE_PROTECT),
|
||||
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
|
||||
|
||||
@ -8187,7 +8187,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
|
||||
LEVEL_UP_MOVE(10, MOVE_PROTECT),
|
||||
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
|
||||
|
||||
@ -9461,7 +9461,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
|
||||
LEVEL_UP_MOVE(10, MOVE_PROTECT),
|
||||
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
|
||||
|
||||
@ -9920,7 +9920,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
|
||||
LEVEL_UP_MOVE(10, MOVE_PROTECT),
|
||||
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
|
||||
|
||||
@ -10382,7 +10382,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
|
||||
LEVEL_UP_MOVE(10, MOVE_PROTECT),
|
||||
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
|
||||
|
||||
@ -10610,7 +10610,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 0, MOVE_QUIVER_DANCE),
|
||||
LEVEL_UP_MOVE( 1, MOVE_QUIVER_DANCE),
|
||||
LEVEL_UP_MOVE( 1, MOVE_SUCKER_PUNCH),
|
||||
|
||||
@ -10633,7 +10633,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 0, MOVE_QUIVER_DANCE),
|
||||
LEVEL_UP_MOVE( 1, MOVE_QUIVER_DANCE),
|
||||
LEVEL_UP_MOVE( 1, MOVE_SUCKER_PUNCH),
|
||||
|
||||
@ -10291,7 +10291,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
|
||||
LEVEL_UP_END
|
||||
};
|
||||
|
||||
static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
|
||||
static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE( 0, MOVE_QUIVER_DANCE),
|
||||
LEVEL_UP_MOVE( 1, MOVE_QUIVER_DANCE),
|
||||
LEVEL_UP_MOVE( 1, MOVE_SUCKER_PUNCH),
|
||||
|
||||
@ -2533,7 +2533,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
||||
.frontPicSize = MON_COORDS_SIZE(32, 40),
|
||||
.frontPicYOffset = 13,
|
||||
.frontAnimFrames = sAnims_PichuSpikyEared,
|
||||
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
|
||||
.frontAnimId = ANIM_V_JUMPS_H_JUMPS,
|
||||
.backPic = gMonBackPic_PichuSpikyEared,
|
||||
.backPicSize = MON_COORDS_SIZE(48, 56),
|
||||
.backPicYOffset = 8,
|
||||
@ -2544,11 +2544,12 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
||||
.iconPalIndex = 1,
|
||||
SHADOW(2, 0, SHADOW_SIZE_S)
|
||||
FOOTPRINT(Pichu)
|
||||
OVERWORLD(
|
||||
OVERWORLD_SET_ANIM(
|
||||
sPicTable_PichuSpikyEared,
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
sAnimTable_Following_Asym,
|
||||
gOverworldPalette_PichuSpikyEared,
|
||||
gShinyOverworldPalette_PichuSpikyEared
|
||||
)
|
||||
|
||||
@ -1656,29 +1656,29 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
|
||||
.pokemonOffset = 24,
|
||||
.trainerScale = 256,
|
||||
.trainerOffset = 0,
|
||||
.frontPic = gMonFrontPic_BurmyPlantCloak,
|
||||
.frontPic = gMonFrontPic_BurmyPlant,
|
||||
.frontPicSize = MON_COORDS_SIZE(32, 56),
|
||||
.frontPicYOffset = 13,
|
||||
.frontAnimFrames = sAnims_Burmy,
|
||||
.frontAnimId = ANIM_V_STRETCH,
|
||||
.enemyMonElevation = 10,
|
||||
.backPic = gMonBackPic_BurmyPlantCloak,
|
||||
.backPic = gMonBackPic_BurmyPlant,
|
||||
.backPicSize = MON_COORDS_SIZE(40, 56),
|
||||
.backPicYOffset = 6,
|
||||
.backAnimId = BACK_ANIM_H_SHAKE,
|
||||
.palette = gMonPalette_BurmyPlantCloak,
|
||||
.shinyPalette = gMonShinyPalette_BurmyPlantCloak,
|
||||
.iconSprite = gMonIcon_BurmyPlantCloak,
|
||||
.palette = gMonPalette_BurmyPlant,
|
||||
.shinyPalette = gMonShinyPalette_BurmyPlant,
|
||||
.iconSprite = gMonIcon_BurmyPlant,
|
||||
.iconPalIndex = 1,
|
||||
SHADOW(-1, 8, SHADOW_SIZE_S)
|
||||
FOOTPRINT(Burmy)
|
||||
OVERWORLD(
|
||||
sPicTable_BurmyPlantCloak,
|
||||
sPicTable_BurmyPlant,
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
gOverworldPalette_BurmyPlantCloak,
|
||||
gShinyOverworldPalette_BurmyPlantCloak
|
||||
gOverworldPalette_BurmyPlant,
|
||||
gShinyOverworldPalette_BurmyPlant
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.levelUpLearnset = sBurmyLevelUpLearnset,
|
||||
@ -1858,32 +1858,32 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
|
||||
.pokemonOffset = 13,
|
||||
.trainerScale = 256,
|
||||
.trainerOffset = 0,
|
||||
.frontPic = gMonFrontPic_WormadamPlantCloak,
|
||||
.frontPic = gMonFrontPic_WormadamPlant,
|
||||
.frontPicSize = MON_COORDS_SIZE(48, 56),
|
||||
.frontPicYOffset = 10,
|
||||
.frontAnimFrames = sAnims_Wormadam,
|
||||
.frontAnimId = ANIM_SWING_CONVEX_FAST_SHORT,
|
||||
.enemyMonElevation = 8,
|
||||
.backPic = gMonBackPic_WormadamPlantCloak,
|
||||
.backPic = gMonBackPic_WormadamPlant,
|
||||
.backPicSize = MON_COORDS_SIZE(56, 64),
|
||||
.backPicYOffset = 2,
|
||||
.backAnimId = BACK_ANIM_V_SHAKE,
|
||||
.palette = gMonPalette_WormadamPlantCloak,
|
||||
.shinyPalette = gMonShinyPalette_WormadamPlantCloak,
|
||||
.iconSprite = gMonIcon_WormadamPlantCloak,
|
||||
.palette = gMonPalette_WormadamPlant,
|
||||
.shinyPalette = gMonShinyPalette_WormadamPlant,
|
||||
.iconSprite = gMonIcon_WormadamPlant,
|
||||
.iconPalIndex = 1,
|
||||
SHADOW(0, 9, SHADOW_SIZE_S)
|
||||
FOOTPRINT(Wormadam)
|
||||
OVERWORLD(
|
||||
sPicTable_WormadamPlantCloak,
|
||||
sPicTable_WormadamPlant,
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
gOverworldPalette_WormadamPlantCloak,
|
||||
gShinyOverworldPalette_WormadamPlantCloak
|
||||
gOverworldPalette_WormadamPlant,
|
||||
gShinyOverworldPalette_WormadamPlant
|
||||
)
|
||||
.levelUpLearnset = sWormadamPlantCloakLevelUpLearnset,
|
||||
.teachableLearnset = sWormadamPlantCloakTeachableLearnset,
|
||||
.levelUpLearnset = sWormadamPlantLevelUpLearnset,
|
||||
.teachableLearnset = sWormadamPlantTeachableLearnset,
|
||||
.formSpeciesIdTable = sWormadamFormSpeciesIdTable,
|
||||
},
|
||||
|
||||
|
||||
@ -18903,7 +18903,7 @@ static const u16 sBurmyTeachableLearnset[] = {
|
||||
MOVE_UNAVAILABLE,
|
||||
};
|
||||
|
||||
static const u16 sWormadamPlantCloakTeachableLearnset[] = {
|
||||
static const u16 sWormadamPlantTeachableLearnset[] = {
|
||||
MOVE_ATTRACT,
|
||||
MOVE_BULLET_SEED,
|
||||
MOVE_DIG,
|
||||
|
||||
@ -340,7 +340,17 @@ static const union AnimCmd sAnim_Pichu_1[] =
|
||||
ANIMCMD_END,
|
||||
};
|
||||
|
||||
PLACEHOLDER_ANIM_SINGLE_FRAME(PichuSpikyEared);
|
||||
static const union AnimCmd sAnim_PichuSpikyEared_1[] =
|
||||
{
|
||||
ANIMCMD_FRAME(0, 10),
|
||||
ANIMCMD_FRAME(1, 10),
|
||||
ANIMCMD_FRAME(0, 10),
|
||||
ANIMCMD_FRAME(1, 10),
|
||||
ANIMCMD_FRAME(0, 10),
|
||||
ANIMCMD_FRAME(1, 10),
|
||||
ANIMCMD_FRAME(0, 1),
|
||||
ANIMCMD_END,
|
||||
};
|
||||
#endif //P_GEN_2_CROSS_EVOS
|
||||
|
||||
static const union AnimCmd sAnim_Pikachu_1[] =
|
||||
|
||||
@ -590,27 +590,6 @@ static void UNUSED TriggerPendingDaycareMaleEgg(void)
|
||||
_TriggerPendingDaycareMaleEgg(&gSaveBlock1Ptr->daycare);
|
||||
}
|
||||
|
||||
// Removes the selected index from the given IV list and shifts the remaining
|
||||
// elements to the left.
|
||||
static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
|
||||
{
|
||||
s32 i, j;
|
||||
u8 temp[NUM_STATS];
|
||||
|
||||
ivs[selectedIv] = 0xFF;
|
||||
for (i = 0; i < NUM_STATS; i++)
|
||||
{
|
||||
temp[i] = ivs[i];
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < NUM_STATS; i++)
|
||||
{
|
||||
if (temp[i] != 0xFF)
|
||||
ivs[j++] = temp[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare)
|
||||
{
|
||||
u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);
|
||||
@ -1154,11 +1133,17 @@ static bool8 TryProduceOrHatchEgg(struct DayCare *daycare)
|
||||
}
|
||||
|
||||
// Try to hatch Egg
|
||||
if (++daycare->stepCounter == ((P_EGG_CYCLE_LENGTH >= GEN_8) ? 127 : 255))
|
||||
daycare->stepCounter++;
|
||||
if (((P_EGG_CYCLE_LENGTH <= GEN_3 || P_EGG_CYCLE_LENGTH == GEN_7) && daycare->stepCounter >= 256)
|
||||
|| (P_EGG_CYCLE_LENGTH == GEN_4 && daycare->stepCounter >= 255)
|
||||
|| ((P_EGG_CYCLE_LENGTH == GEN_5 || P_EGG_CYCLE_LENGTH == GEN_6) && daycare->stepCounter >= 257)
|
||||
|| (P_EGG_CYCLE_LENGTH >= GEN_8 && daycare->stepCounter >= 128))
|
||||
{
|
||||
u32 eggCycles;
|
||||
u8 toSub = GetEggCyclesToSubtract();
|
||||
|
||||
daycare->stepCounter = 0;
|
||||
|
||||
for (i = 0; i < gPlayerPartyCount; i++)
|
||||
{
|
||||
if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
|
||||
|
||||
@ -150,7 +150,9 @@ static void SpriteCB_Sparkle_SpiralUpward(struct Sprite *sprite)
|
||||
sprite->oam.matrixNum = matrixNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroySprite(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateSparkle_SpiralUpward(u8 trigIdx)
|
||||
@ -178,7 +180,9 @@ static void SpriteCB_Sparkle_ArcDown(struct Sprite *sprite)
|
||||
sprite->sTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroySprite(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateSparkle_ArcDown(u8 trigIdx)
|
||||
@ -206,7 +210,9 @@ static void SpriteCB_Sparkle_CircleInward(struct Sprite *sprite)
|
||||
sprite->sTrigIdx += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroySprite(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateSparkle_CircleInward(u8 trigIdx, u8 speed)
|
||||
@ -238,7 +244,9 @@ static void SpriteCB_Sparkle_Spray(struct Sprite *sprite)
|
||||
sprite->sTrigIdx++;
|
||||
matrixNum = 31 - (sprite->sTrigIdx * 12 / 128);
|
||||
if (sprite->sTrigIdx > 64)
|
||||
{
|
||||
sprite->subpriority = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->invisible = FALSE;
|
||||
@ -252,7 +260,9 @@ static void SpriteCB_Sparkle_Spray(struct Sprite *sprite)
|
||||
sprite->sTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroySprite(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateSparkle_Spray(u8 id)
|
||||
@ -348,7 +358,9 @@ static void Task_Sparkles_ArcDown(u8 taskId)
|
||||
gTasks[taskId].tTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].func = Task_Sparkles_ArcDown_End;
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_Sparkles_ArcDown_End(u8 taskId)
|
||||
@ -388,7 +400,9 @@ static void Task_Sparkles_CircleInward(u8 taskId)
|
||||
gTasks[taskId].tTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].func = Task_Sparkles_CircleInward_End;
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_Sparkles_CircleInward_End(u8 taskId)
|
||||
@ -437,7 +451,9 @@ static void Task_Sparkles_SprayAndFlash(u8 taskId)
|
||||
gTasks[taskId].tTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].func = Task_Sparkles_SprayAndFlash_End;
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_Sparkles_SprayAndFlash_End(u8 taskId)
|
||||
@ -486,7 +502,9 @@ static void Task_Sparkles_SprayAndFlashTrade(u8 taskId)
|
||||
gTasks[taskId].tTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].func = Task_Sparkles_SprayAndFlash_End;
|
||||
}
|
||||
}
|
||||
|
||||
#undef tTimer
|
||||
@ -560,9 +578,13 @@ static void Task_CycleEvolutionMonSprite_Init(u8 taskId)
|
||||
static void Task_CycleEvolutionMonSprite_TryEnd(u8 taskId)
|
||||
{
|
||||
if (gTasks[taskId].tEvoStopped)
|
||||
{
|
||||
EndOnPreEvoMon(taskId);
|
||||
}
|
||||
else if (gTasks[taskId].tScaleSpeed == 128)
|
||||
{
|
||||
EndOnPostEvoMon(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].tScaleSpeed += 2;
|
||||
@ -574,7 +596,9 @@ static void Task_CycleEvolutionMonSprite_TryEnd(u8 taskId)
|
||||
static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
|
||||
{
|
||||
if (gTasks[taskId].tEvoStopped)
|
||||
{
|
||||
gTasks[taskId].func = EndOnPreEvoMon;
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 oamMatrixArg;
|
||||
@ -583,7 +607,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
|
||||
{
|
||||
// Set pre-evo sprite growth
|
||||
if (gTasks[taskId].tPreEvoScale < MON_MAX_SCALE - gTasks[taskId].tScaleSpeed)
|
||||
{
|
||||
gTasks[taskId].tPreEvoScale += gTasks[taskId].tScaleSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].tPreEvoScale = MON_MAX_SCALE;
|
||||
@ -592,7 +618,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
|
||||
|
||||
// Set post-evo sprite shrink
|
||||
if (gTasks[taskId].tPostEvoScale > MON_MIN_SCALE + gTasks[taskId].tScaleSpeed)
|
||||
{
|
||||
gTasks[taskId].tPostEvoScale -= gTasks[taskId].tScaleSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].tPostEvoScale = MON_MIN_SCALE;
|
||||
@ -603,7 +631,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
|
||||
{
|
||||
// Set post-evo sprite growth
|
||||
if (gTasks[taskId].tPostEvoScale < MON_MAX_SCALE - gTasks[taskId].tScaleSpeed)
|
||||
{
|
||||
gTasks[taskId].tPostEvoScale += gTasks[taskId].tScaleSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].tPostEvoScale = MON_MAX_SCALE;
|
||||
@ -612,7 +642,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
|
||||
|
||||
// Set pre-evo sprite shrink
|
||||
if (gTasks[taskId].tPreEvoScale > MON_MIN_SCALE + gTasks[taskId].tScaleSpeed)
|
||||
{
|
||||
gTasks[taskId].tPreEvoScale -= gTasks[taskId].tScaleSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].tPreEvoScale = MON_MIN_SCALE;
|
||||
|
||||
@ -231,7 +231,9 @@ static void DrawMetatileAt(const struct MapLayout *mapLayout, u16 offset, int x,
|
||||
if (metatileId > NUM_METATILES_TOTAL)
|
||||
metatileId = 0;
|
||||
if (metatileId < NUM_METATILES_IN_PRIMARY)
|
||||
{
|
||||
metatiles = mapLayout->primaryTileset->metatiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
metatiles = mapLayout->secondaryTileset->metatiles;
|
||||
|
||||