merge rhh/upcomig

This commit is contained in:
AlexOn1ine 2024-12-28 21:03:34 +01:00
commit 74f1d7cb80
188 changed files with 3821 additions and 1714 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

After

Width:  |  Height:  |  Size: 757 B

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 485 B

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

After

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 B

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

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

View File

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

View File

@ -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[];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -815,8 +815,7 @@ struct DayCare
{
struct DaycareMon mons[DAYCARE_MON_COUNT];
u32 offspringPersonality;
u8 stepCounter;
//u8 padding[3];
u32 stepCounter;
};
struct LilycoveLadyQuiz

View File

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

View File

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

View File

@ -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__, \

View File

@ -59,7 +59,9 @@ void rfu_LMAN_REQ_sendData(bool8 clockChangeFlag)
clockChangeFlag = FALSE;
}
else
{
lman.parentAck_flag = 0;
}
rfu_REQ_sendData(clockChangeFlag);
}

View File

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

View File

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

View File

@ -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);
}
}

View File

@ -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++)
{

View File

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

View File

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

View File

@ -346,7 +346,9 @@ static void AnimConfuseRayBallBounce_Step2(struct Sprite *sprite)
sprite->callback = DestroyAnimSpriteAndDisableBlend;
}
else
{
UpdateConfuseRayBallBlend(sprite);
}
}
static void UpdateConfuseRayBallBlend(struct Sprite *sprite)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -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();

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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[] =

View File

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

View File

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

View File

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

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