Updated to latest master branch + add PLA's data to teachable_learnsets.h

This commit is contained in:
Blackforest92 2022-08-29 21:01:31 +07:00
commit 61c33f56a0
100 changed files with 36060 additions and 36633 deletions

View File

@ -869,6 +869,7 @@ gBattleAnims_General::
.4byte General_BeakBlastSetUp @ B_ANIM_BEAK_BLAST_SETUP
.4byte General_ShellTrapSetUp @ B_ANIM_SHELL_TRAP_SETUP
.4byte General_ZMoveActivate @ B_ANIM_ZMOVE_ACTIVATE
.4byte General_AffectionHangedOn @ B_ANIM_AFFECTION_HANGED_ON
.align 2
gBattleAnims_Special::
@ -14697,14 +14698,14 @@ Move_DOUBLE_EDGE:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -10, 0, ANIM_TARGET, 0
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -32, 0, 0, 3
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, 0, 0
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, 1, 0
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 0
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 4, 0, 12, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 16, 0, RGB_WHITE
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, 0, 1
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, 1, 1
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 1
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 1
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
delay 3
@ -16341,7 +16342,7 @@ Move_HORN_ATTACK:
Move_FURY_ATTACK:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HORN_HIT
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 4, 256, 0, 2
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 4, 256, ANIM_ATTACKER, 2
choosetwoturnanim FuryAttackRight, FuryAttackLeft
FuryAttackContinue:
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
@ -16490,7 +16491,7 @@ Move_LOW_KICK:
createsprite gSlidingKickSpriteTemplate, ANIM_TARGET, 2, -24, 28, 40, 8, 160, 0
delay 4
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -8, 8, ANIM_TARGET, 2
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 6, 384, 1, 2
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 6, 384, ANIM_TARGET, 2
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 4
@ -16735,7 +16736,7 @@ SkullBashSetUpHeadDown:
createsprite gSlideMonToOffsetAndBackSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER, -24, 0, 0, 10, 0
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 16, 96, 0, 2
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 16, 96, ANIM_ATTACKER, 2
waitforvisualfinish
createsprite gSlideMonToOffsetAndBackSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER, 24, 0, 0, 10, 1
waitforvisualfinish
@ -17854,7 +17855,7 @@ Move_MIST_BALL:
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_BG, 1, 1, RGB(23, 16, 31), 16, RGB_WHITE, 16
delay 0
playsewithpan SE_M_HAZE, 0
createvisualtask AnimTask_LoadMistTiles, 5
createvisualtask AnimTask_MistBallFog, 5
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 3, 0, 16, RGB_WHITE
delay 8
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 4, 0, 70, 0
@ -22454,14 +22455,14 @@ Move_ARM_THRUST:
loadspritegfx ANIM_TAG_IMPACT
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_RotateMonSpriteToSide, 5, 8, 5, 0, 0
createvisualtask AnimTask_RotateMonSpriteToSide, 5, 8, 5, ANIM_ATTACKER, 0
delay 6
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 3
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gArmThrustHandSpriteTemplate, ANIM_TARGET, 2, 10, -8, 14, 3
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 5, 8, 5, 0, 1
createvisualtask AnimTask_RotateMonSpriteToSide, 5, 8, 5, ANIM_ATTACKER, 1
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
choosetwoturnanim ArmThrustRight, ArmThrustLeft
ArmThrustContinue:
@ -24884,6 +24885,27 @@ PrimalReversionParticles:
delay 3
return
General_AffectionHangedOn::
loadspritegfx ANIM_TAG_RED_HEART
loopsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER, 12, 3
createvisualtask AnimTask_SwayMon, 5, 0, 12, 4096, 4, ANIM_ATTACKER
delay 15
launchtask AnimTask_AffectionHangedOn 0x5 0x0
jumpargeq 0x0, FRIENDSHIP_100_TO_149, General_AffectionHangedOn_3Hearts
jumpargeq 0x0, FRIENDSHIP_150_TO_199, General_AffectionHangedOn_4Hearts
jumpargeq 0x0, FRIENDSHIP_200_TO_254, General_AffectionHangedOn_5Hearts
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, -384, -31
General_AffectionHangedOn_5Hearts:
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, -128, -22
General_AffectionHangedOn_4Hearts:
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, 416, -38
General_AffectionHangedOn_3Hearts:
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, 160, -32
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, -256, -40
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, 128, -16
waitforvisualfinish
end
SnatchMoveTrySwapFromSubstitute:
createvisualtask AnimTask_IsAttackerBehindSubstitute, 2
jumprettrue SnatchMoveSwapSubstituteForMon

View File

@ -415,6 +415,41 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectExtremeEvoboost @ EFFECT_EXTREME_EVOBOOST
.4byte BattleScript_EffectTerrainHit @ EFFECT_DAMAGE_SET_TERRAIN
BattleScript_AffectionBasedEndurance::
playanimation BS_TARGET, B_ANIM_AFFECTION_HANGED_ON
printstring STRINGID_TARGETTOUGHEDITOUT
waitmessage B_WAIT_TIME_LONG
return
BattleScript_AffectionBasedStatusHeal::
jumpifstatus BS_ATTACKER, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AffectionBasedStatus_HealPoisonString
jumpifstatus BS_ATTACKER, STATUS1_SLEEP, BattleScript_AffectionBasedStatus_HealSleepString
jumpifstatus BS_ATTACKER, STATUS1_PARALYSIS, BattleScript_AffectionBasedStatus_HealParalysisString
jumpifstatus BS_ATTACKER, STATUS1_BURN, BattleScript_AffectionBasedStatus_HealBurnString
jumpifstatus BS_ATTACKER, STATUS1_FREEZE, BattleScript_AffectionBasedStatus_HealFreezeString
end2
BattleScript_AffectionBasedStatus_HealPoisonString:
printstring STRINGID_ATTACKEREXPELLEDTHEPOISON
goto BattleScript_AffectionBasedStatusHeal_Continue
BattleScript_AffectionBasedStatus_HealSleepString:
printstring STRINGID_ATTACKERSHOOKITSELFAWAKE
goto BattleScript_AffectionBasedStatusHeal_Continue
BattleScript_AffectionBasedStatus_HealParalysisString:
printstring STRINGID_ATTACKERBROKETHROUGHPARALYSIS
goto BattleScript_AffectionBasedStatusHeal_Continue
BattleScript_AffectionBasedStatus_HealBurnString:
printstring STRINGID_ATTACKERHEALEDITSBURN
goto BattleScript_AffectionBasedStatusHeal_Continue
BattleScript_AffectionBasedStatus_HealFreezeString:
printstring STRINGID_ATTACKERMELTEDTHEICE
BattleScript_AffectionBasedStatusHeal_Continue:
waitmessage B_WAIT_TIME_LONG
clearstatus BS_ATTACKER
waitstate
updatestatusicon BS_ATTACKER
waitstate
end2
BattleScript_EffectSteelBeam::
attackcanceler
attackstring
@ -7257,6 +7292,10 @@ BattleScript_SelectingNotAllowedStuffCheeks::
printselectionstring STRINGID_STUFFCHEEKSCANTSELECT
endselectionscript
BattleScript_SelectingNotAllowedStuffCheeksInPalace::
printstring STRINGID_STUFFCHEEKSCANTSELECT
goto BattleScript_SelectingUnusableMoveInPalace
BattleScript_SelectingNotAllowedBelch::
printselectionstring STRINGID_BELCHCANTSELECT
endselectionscript
@ -9197,14 +9236,34 @@ BattleScript_SelectingNotAllowedMoveChoiceItem::
printselectionstring STRINGID_ITEMALLOWSONLYYMOVE
endselectionscript
BattleScript_SelectingNotAllowedMoveChoiceItemInPalace::
printstring STRINGID_ITEMALLOWSONLYYMOVE
goto BattleScript_SelectingUnusableMoveInPalace
BattleScript_SelectingNotAllowedMoveGorillaTactics::
printselectionstring STRINGID_ABILITYALLOWSONLYMOVE
endselectionscript
BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace::
printstring STRINGID_ABILITYALLOWSONLYMOVE
goto BattleScript_SelectingUnusableMoveInPalace
BattleScript_SelectingNotAllowedMoveAssaultVest::
printselectionstring STRINGID_ASSAULTVESTDOESNTALLOW
endselectionscript
BattleScript_SelectingNotAllowedMoveAssaultVestInPalace::
printstring STRINGID_ASSAULTVESTDOESNTALLOW
goto BattleScript_SelectingUnusableMoveInPalace
BattleScript_SelectingNotAllowedPlaceholder::
printselectionstring STRINGID_NOTDONEYET
endselectionscript
BattleScript_SelectingNotAllowedPlaceholderInPalace::
printstring STRINGID_NOTDONEYET
goto BattleScript_SelectingUnusableMoveInPalace
BattleScript_HangedOnMsg::
playanimation BS_TARGET, B_ANIM_HANGED_ON
printstring STRINGID_PKMNHUNGONWITHX

View File

@ -67,51 +67,61 @@ BattleFrontier_Lounge7_EventScript_ChooseNewLeftTutorMove::
BattleFrontier_Lounge7_EventScript_Softboiled::
setvar VAR_0x8008, 16
setvar VAR_0x8005, MOVE_SOFT_BOILED
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_SeismicToss::
setvar VAR_0x8008, 24
setvar VAR_0x8005, MOVE_SEISMIC_TOSS
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_DreamEater::
setvar VAR_0x8008, 24
setvar VAR_0x8005, MOVE_DREAM_EATER
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_MegaPunch::
setvar VAR_0x8008, 24
setvar VAR_0x8005, MOVE_MEGA_PUNCH
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_MegaKick::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_MEGA_KICK
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_BodySlam::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_BODY_SLAM
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_RockSlide::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_ROCK_SLIDE
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_Counter::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_COUNTER
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_ThunderWave::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_THUNDER_WAVE
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_SwordsDance::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_SWORDS_DANCE
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
@ -135,7 +145,6 @@ BattleFrontier_Lounge7_EventScript_ChooseRightTutorMove::
waitmessage
special ShowBattlePointsWindow
setvar VAR_TEMP_E, 1
setvar VAR_0x8004, SCROLL_MULTI_BF_MOVE_TUTOR_2
setvar VAR_0x8006, 0
special ShowScrollableMultichoice
waitstate
@ -159,7 +168,6 @@ BattleFrontier_Lounge7_EventScript_ChooseNewRightTutorMove::
message BattleFrontier_Lounge7_Text_TeachWhichMove
waitmessage
setvar VAR_TEMP_E, 1
setvar VAR_0x8004, SCROLL_MULTI_BF_MOVE_TUTOR_2
setvar VAR_0x8006, 1
special ShowScrollableMultichoice
waitstate
@ -181,51 +189,61 @@ BattleFrontier_Lounge7_EventScript_ChooseNewRightTutorMove::
BattleFrontier_Lounge7_EventScript_DefenseCurl::
setvar VAR_0x8008, 16
setvar VAR_0x8005, MOVE_DEFENSE_CURL
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_Snore::
setvar VAR_0x8008, 24
setvar VAR_0x8005, MOVE_SNORE
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_MudSlap::
setvar VAR_0x8008, 24
setvar VAR_0x8005, MOVE_MUD_SLAP
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_Swift::
setvar VAR_0x8008, 24
setvar VAR_0x8005, MOVE_SWIFT
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_IcyWind::
setvar VAR_0x8008, 24
setvar VAR_0x8005, MOVE_ICY_WIND
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_Endure::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_ENDURE
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_PsychUp::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_PSYCH_UP
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_IcePunch::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_ICE_PUNCH
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_ThunderPunch::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_THUNDER_PUNCH
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
BattleFrontier_Lounge7_EventScript_FirePunch::
setvar VAR_0x8008, 48
setvar VAR_0x8005, MOVE_FIRE_PUNCH
goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection
end
@ -246,11 +264,8 @@ BattleFrontier_Lounge7_EventScript_CancelChooseMon::
@ VAR_TEMP_D is the move selection
@ VAR_TEMP_E is which move tutor was spoken to
BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection::
copyvar VAR_0x8004, VAR_TEMP_D
copyvar VAR_0x8005, VAR_TEMP_E
special BufferBattleFrontierTutorMoveName
buffernumberstring STR_VAR_2, VAR_0x8008
copyvar VAR_0x8004, VAR_TEMP_C
msgbox BattleFrontier_Lounge7_Text_MoveWillBeXBattlePoints, MSGBOX_YESNO
goto_if_eq VAR_RESULT, NO, BattleFrontier_Lounge7_EventScript_ChooseNewMove
specialvar VAR_TEMP_1, GetFrontierBattlePoints
@ -261,7 +276,6 @@ BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection::
BattleFrontier_Lounge7_EventScript_TeachTutorMove::
msgbox BattleFrontier_Lounge7_Text_TeachMoveToWhichMon, MSGBOX_DEFAULT
special GetBattleFrontierTutorMoveIndex
fadescreen FADE_TO_BLACK
special CloseBattlePointsWindow
special CloseBattleFrontierTutorWindow

View File

@ -158,7 +158,7 @@
"y": 9,
"elevation": 0,
"player_facing_dir": "BG_EVENT_PLAYER_FACING_ANY",
"script": "OldaleTown_EventScript_CitySign"
"script": "OldaleTown_EventScript_TownSign"
},
{
"type": "sign",

View File

@ -29,8 +29,8 @@ OldaleTown_EventScript_MoveMartEmployee::
setobjectmovementtype LOCALID_MART_EMPLOYEE, MOVEMENT_TYPE_FACE_DOWN
return
OldaleTown_EventScript_CitySign::
msgbox OldaleTown_Text_CitySign, MSGBOX_SIGN
OldaleTown_EventScript_TownSign::
msgbox OldaleTown_Text_TownSign, MSGBOX_SIGN
end
OldaleTown_EventScript_Girl::
@ -395,7 +395,7 @@ OldaleTown_Text_BrendanLetsGoBack:
.string "LAB now.\l"
.string "{PLAYER}, you should hustle back, too.$"
OldaleTown_Text_CitySign:
OldaleTown_Text_TownSign:
.string "OLDALE TOWN\n"
.string "“Where things start off scarce.”$"

View File

@ -11,9 +11,9 @@ PacifidlogTown_House2_EventScript_FanClubYoungerBrother::
call_if_unset FLAG_MET_FANCLUB_YOUNGER_BROTHER, PacifidlogTown_House2_EventScript_FirstMonAssessment
setflag FLAG_MET_FANCLUB_YOUNGER_BROTHER
specialvar VAR_RESULT, GetLeadMonFriendshipScore
goto_if_ge VAR_RESULT, 4, PacifidlogTown_House2_EventScript_GiveReturn
goto_if_ge VAR_RESULT, FRIENDSHIP_150_TO_199, PacifidlogTown_House2_EventScript_GiveReturn
specialvar VAR_RESULT, GetLeadMonFriendshipScore
goto_if_ge VAR_RESULT, 2, PacifidlogTown_House2_EventScript_PutInEffort
goto_if_ge VAR_RESULT, FRIENDSHIP_50_TO_99, PacifidlogTown_House2_EventScript_PutInEffort
goto PacifidlogTown_House2_EventScript_GiveFrustration
end

View File

@ -192,7 +192,7 @@ SlateportCity_PokemonFanClub_EventScript_SootheBellWoman::
goto_if_set FLAG_RECEIVED_SOOTHE_BELL, SlateportCity_PokemonFanClub_EventScript_ReceivedSootheBell
msgbox SlateportCity_PokemonFanClub_Text_ShowMePokemonThatLoveYou, MSGBOX_DEFAULT
specialvar VAR_RESULT, GetLeadMonFriendshipScore
goto_if_ge VAR_RESULT, 4, SlateportCity_PokemonFanClub_EventScript_GiveSootheBell
goto_if_ge VAR_RESULT, FRIENDSHIP_150_TO_199, SlateportCity_PokemonFanClub_EventScript_GiveSootheBell
release
end

View File

@ -7,13 +7,13 @@ VerdanturfTown_FriendshipRatersHouse_EventScript_FriendshipRater::
msgbox VerdanturfTown_FriendshipRatersHouse_Text_SeeHowMuchPokemonLikesYou, MSGBOX_DEFAULT
specialvar VAR_RESULT, GetLeadMonFriendshipScore
switch VAR_RESULT
case 0, VerdanturfTown_FriendshipRatersHouse_EventScript_DetestsYou
case 1, VerdanturfTown_FriendshipRatersHouse_EventScript_VeryWary
case 2, VerdanturfTown_FriendshipRatersHouse_EventScript_NotUsedToYou
case 3, VerdanturfTown_FriendshipRatersHouse_EventScript_GettingUsedToYou
case 4, VerdanturfTown_FriendshipRatersHouse_EventScript_LikesYouQuiteALot
case 5, VerdanturfTown_FriendshipRatersHouse_EventScript_VeryHappy
case 6, VerdanturfTown_FriendshipRatersHouse_EventScript_AdoresYou
case FRIENDSHIP_NONE, VerdanturfTown_FriendshipRatersHouse_EventScript_DetestsYou
case FRIENDSHIP_1_TO_49, VerdanturfTown_FriendshipRatersHouse_EventScript_VeryWary
case FRIENDSHIP_50_TO_99, VerdanturfTown_FriendshipRatersHouse_EventScript_NotUsedToYou
case FRIENDSHIP_100_TO_149, VerdanturfTown_FriendshipRatersHouse_EventScript_GettingUsedToYou
case FRIENDSHIP_150_TO_199, VerdanturfTown_FriendshipRatersHouse_EventScript_LikesYouQuiteALot
case FRIENDSHIP_200_TO_254, VerdanturfTown_FriendshipRatersHouse_EventScript_VeryHappy
case FRIENDSHIP_MAX, VerdanturfTown_FriendshipRatersHouse_EventScript_AdoresYou
release
end

View File

@ -7,7 +7,7 @@ SlateportCity_PokemonFanClub_EventScript_SwaggerTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SwaggerDeclined
msgbox MoveTutor_Text_SwaggerWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_SWAGGER
setvar VAR_0x8005, MOVE_SWAGGER
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_SwaggerDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_SWAGGER
@ -33,7 +33,7 @@ MauvilleCity_EventScript_RolloutTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_RolloutDeclined
msgbox MoveTutor_Text_RolloutWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_ROLLOUT
setvar VAR_0x8005, MOVE_ROLLOUT
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_RolloutDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT
@ -59,7 +59,7 @@ VerdanturfTown_PokemonCenter_1F_EventScript_FuryCutterTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_FuryCutterDeclined
msgbox MoveTutor_Text_FuryCutterWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_FURY_CUTTER
setvar VAR_0x8005, MOVE_FURY_CUTTER
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_FuryCutterDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER
@ -85,7 +85,7 @@ LavaridgeTown_House_EventScript_MimicTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_MimicDeclined
msgbox MoveTutor_Text_MimicWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_MIMIC
setvar VAR_0x8005, MOVE_MIMIC
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_MimicDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_MIMIC
@ -111,7 +111,7 @@ FallarborTown_Mart_EventScript_MetronomeTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_MetronomeDeclined
msgbox MoveTutor_Text_MetronomeWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_METRONOME
setvar VAR_0x8005, MOVE_METRONOME
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_MetronomeDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_METRONOME
@ -137,7 +137,7 @@ FortreeCity_House2_EventScript_SleepTalkTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SleepTalkDeclined
msgbox MoveTutor_Text_SleepTalkWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_SLEEP_TALK
setvar VAR_0x8005, MOVE_SLEEP_TALK
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_SleepTalkDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK
@ -163,7 +163,7 @@ LilycoveCity_DepartmentStoreRooftop_EventScript_SubstituteTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SubstituteDeclined
msgbox MoveTutor_Text_SubstituteWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_SUBSTITUTE
setvar VAR_0x8005, MOVE_SUBSTITUTE
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_SubstituteDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE
@ -189,7 +189,7 @@ MossdeepCity_EventScript_DynamicPunchTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_DynamicPunchDeclined
msgbox MoveTutor_Text_DynamicPunchWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_DYNAMIC_PUNCH
setvar VAR_0x8005, MOVE_DYNAMIC_PUNCH
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_DynamicPunchDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH
@ -215,7 +215,7 @@ SootopolisCity_PokemonCenter_1F_EventScript_DoubleEdgeTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_DoubleEdgeDeclined
msgbox MoveTutor_Text_DoubleEdgeWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_DOUBLE_EDGE
setvar VAR_0x8005, MOVE_DOUBLE_EDGE
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_DoubleEdgeDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE
@ -241,7 +241,7 @@ PacifidlogTown_PokemonCenter_1F_EventScript_ExplosionTutor::
call MoveTutor_EventScript_CanOnlyBeLearnedOnce
goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_ExplosionDeclined
msgbox MoveTutor_Text_ExplosionWhichMon, MSGBOX_DEFAULT
setvar VAR_0x8005, TUTOR_MOVE_EXPLOSION
setvar VAR_0x8005, MOVE_EXPLOSION
call MoveTutor_EventScript_OpenPartyMenu
goto_if_eq VAR_RESULT, 0, MoveTutor_EventScript_ExplosionDeclined
setflag FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION

View File

@ -486,7 +486,6 @@ gSpecials::
def_special CloseBattleFrontierTutorWindow
def_special ScrollableMultichoice_RedrawPersistentMenu
def_special ChooseMonForMoveTutor
def_special GetBattleFrontierTutorMoveIndex
def_special ScrollableMultichoice_ClosePersistentMenu
def_special DoDeoxysRockInteraction
def_special SetDeoxysRockPalette

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 324 B

View File

@ -178,6 +178,7 @@ struct SpecialStatus
u8 dancerOriginalTarget:3;
u8 announceNeutralizingGas:1; // See Cmd_switchineffects
u8 neutralizingGasRemoved:1; // See VARIOUS_TRY_END_NEUTRALIZING_GAS
u8 affectionEndured:1;
s32 dmg;
s32 physicalDmg;
s32 specialDmg;

View File

@ -124,7 +124,7 @@ void PrepareBattlerSpriteForRotScale(u8 spriteId, u8 objMode);
void SetBattlerSpriteYOffsetFromRotation(u8 spriteId);
u32 GetBattlePalettesMask(bool8 battleBackground, bool8 attacker, bool8 target, bool8 attackerPartner, bool8 targetPartner, bool8 anim1, bool8 anim2);
u32 GetBattleMonSpritePalettesMask(u8 playerLeft, u8 playerRight, u8 opponentLeft, u8 opponentRight);
u8 AnimDummyReturnArg(u8 battler);
u8 GetSpritePalIdxByBattler(u8 battler);
s16 CloneBattlerSpriteWithBlend(u8);
void DestroySpriteWithActiveSheet(struct Sprite *);
u8 CreateInvisibleSpriteCopy(int, u8, int);

View File

@ -6,7 +6,8 @@
enum
{
HP_CURRENT,
HP_MAX
HP_MAX,
HP_BOTH
};
enum
@ -34,22 +35,25 @@ enum
#define TAG_HEALTHBAR_PLAYER2_TILE 0xD706
#define TAG_HEALTHBAR_OPPONENT2_TILE 0xD707
#define TAG_HEALTHBOX_PALS_1 0xD709
#define TAG_HEALTHBOX_PALS_2 0xD70A
#define TAG_HEALTHBOX_SAFARI_TILE 0xD70B
#define TAG_STATUS_SUMMARY_BAR_TILE 0xD70C
#define TAG_STATUS_SUMMARY_BAR_PAL 0xD710
#define TAG_STATUS_SUMMARY_BALLS_PAL 0xD712
#define TAG_STATUS_SUMMARY_BALLS_TILE 0xD714
#define TAG_HEALTHBAR_PAL TAG_HEALTHBAR_PLAYER1_TILE
#define TAG_HEALTHBOX_PAL TAG_HEALTHBOX_PLAYER1_TILE
#define TAG_MEGA_TRIGGER_TILE 0xD777
#define TAG_MEGA_INDICATOR_TILE 0xD778
#define TAG_ALPHA_INDICATOR_TILE 0xD779
#define TAG_OMEGA_INDICATOR_TILE 0xD77A
#define TAG_ZMOVE_TRIGGER_TILE 0xD77B
#define TAG_HEALTHBOX_PAL 0xD6FF
#define TAG_HEALTHBAR_PAL 0xD704
#define TAG_STATUS_SUMMARY_BAR_PAL 0xD710
#define TAG_STATUS_SUMMARY_BALLS_PAL 0xD712
#define TAG_MEGA_TRIGGER_PAL 0xD777
#define TAG_MEGA_INDICATOR_PAL 0xD778
#define TAG_ALPHA_INDICATOR_PAL 0xD779
@ -72,6 +76,7 @@ enum
HEALTHBOX_SAFARI_BALLS_TEXT
};
u32 WhichBattleCoords(u32 battlerId);
u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId);
u8 CreateBattlerHealthboxSprites(u8 battler);
u8 CreateSafariPlayerHealthboxSprites(void);
@ -82,7 +87,7 @@ void DestoryHealthboxSprite(u8 healthboxSpriteId);
void DummyBattleInterfaceFunc(u8 healthboxSpriteId, bool8 isDoubleBattleBankOnly);
void UpdateOamPriorityInAllHealthboxes(u8 priority, bool32 hideHpBoxes);
void InitBattlerHealthboxCoords(u8 battler);
void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent);
void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp);
void SwapHpBarsWithHpText(void);
void ChangeMegaTriggerSprite(u8 spriteId, u8 animId);
void CreateMegaTriggerSprite(u8 battlerId, u8 palId);

View File

@ -210,6 +210,7 @@ extern const u8 BattleScript_BerryPPHealEnd2[];
extern const u8 BattleScript_ItemHealHP_End2[];
extern const u8 BattleScript_ItemHealHP_Ret[];
extern const u8 BattleScript_SelectingNotAllowedMoveChoiceItem[];
extern const u8 BattleScript_SelectingNotAllowedMoveChoiceItemInPalace[];
extern const u8 BattleScript_HangedOnMsg[];
extern const u8 BattleScript_BerryConfuseHealEnd2[];
extern const u8 BattleScript_BerryConfuseHealRet[];
@ -275,6 +276,9 @@ extern const u8 BattleScript_SnowWarningActivates[];
extern const u8 BattleScript_HarvestActivates[];
extern const u8 BattleScript_ImposterActivates[];
extern const u8 BattleScript_SelectingNotAllowedMoveAssaultVest[];
extern const u8 BattleScript_SelectingNotAllowedMoveAssaultVestInPalace[];
extern const u8 BattleScript_SelectingNotAllowedPlaceholder[];
extern const u8 BattleScript_SelectingNotAllowedPlaceholderInPalace[];
extern const u8 BattleScript_SelectingNotAllowedMoveGravity[];
extern const u8 BattleScript_MoveUsedGravityPrevents[];
extern const u8 BattleScript_SelectingNotAllowedMoveGravityInPalace[];
@ -301,6 +305,7 @@ extern const u8 BattleScript_DazzlingProtected[];
extern const u8 BattleScript_MoveUsedPsychicTerrainPrevents[];
extern const u8 BattleScript_MoveUsedPowder[];
extern const u8 BattleScript_SelectingNotAllowedStuffCheeks[];
extern const u8 BattleScript_SelectingNotAllowedStuffCheeksInPalace[];
extern const u8 BattleScript_SelectingNotAllowedBelch[];
extern const u8 BattleScript_SelectingNotAllowedBelchInPalace[];
extern const u8 BattleScript_PsychicSurgeActivates[];
@ -405,6 +410,7 @@ extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
extern const u8 BattleScript_PrimalReversion[];
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[];
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace[];
extern const u8 BattleScript_WanderingSpiritActivates[];
extern const u8 BattleScript_MirrorArmorReflect[];
extern const u8 BattleScript_GooeyActivates[];
@ -420,6 +426,8 @@ extern const u8 BattleScript_MagicianActivates[];
extern const u8 BattleScript_BeakBlastSetUp[];
extern const u8 BattleScript_BeakBlastBurn[];
extern const u8 BattleScript_DefDownSpeedUp[];
extern const u8 BattleScript_AffectionBasedStatusHeal[];
extern const u8 BattleScript_AffectionBasedEndurance[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -7,7 +7,17 @@
#define MOVE_LIMITATION_TORMENTED (1 << 3)
#define MOVE_LIMITATION_TAUNT (1 << 4)
#define MOVE_LIMITATION_IMPRISON (1 << 5)
#define MOVE_LIMITATIONS_ALL 0xFF
#define MOVE_LIMITATION_ENCORE (1 << 6)
#define MOVE_LIMITATION_CHOICE_ITEM (1 << 7)
#define MOVE_LIMITATION_ASSAULT_VEST (1 << 8)
#define MOVE_LIMITATION_GRAVITY (1 << 9)
#define MOVE_LIMITATION_HEAL_BLOCK (1 << 10)
#define MOVE_LIMITATION_BELCH (1 << 11)
#define MOVE_LIMITATION_THROAT_CHOP (1 << 12)
#define MOVE_LIMITATION_STUFF_CHEEKS (1 << 13)
#define MOVE_LIMITATION_PLACEHOLDER (1 << 15)
#define MOVE_LIMITATIONS_ALL 0xFFFF
#define ABILITYEFFECT_ON_SWITCHIN 0
#define ABILITYEFFECT_ENDTURN 1
@ -89,7 +99,7 @@ void BattleScriptPush(const u8 *bsPtr);
void BattleScriptPushCursor(void);
void BattleScriptPop(void);
u8 TrySetCantSelectMoveBattleScript(void);
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check);
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u16 check);
bool8 AreAllMovesUnusable(void);
u8 GetImprisonedMovesCount(u8 battlerId, u16 move);
u8 DoFieldEndTurnEffects(void);
@ -191,5 +201,6 @@ bool32 CanBeParalyzed(u8 battlerId);
bool32 CanBeFrozen(u8 battlerId);
bool32 CanBeConfused(u8 battlerId);
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag);
u32 GetMonFriendshipScore(struct Pokemon *pokemon);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -26,7 +26,7 @@
#endif
// Uncomment to fix some identified minor bugs
//#define BUGFIX
#define BUGFIX
// Various undefined behavior bugs may or may not prevent compilation with
// newer compilers. So always fix them when using a modern compiler.
@ -36,4 +36,12 @@
#endif
#endif
// Compatibility definition for other projects to detect pokeemerald-expansion
#define RHH_EXPANSION
// Legacy branch-based defines included for backwards compatibility
#define BATTLE_ENGINE
#define POKEMON_EXPANSION
#define ITEM_EXPANSION
#endif // GUARD_CONFIG_H

View File

@ -81,7 +81,7 @@
#define WILD_DOUBLE_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER))))
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gTrainerBattleOpponent_B == 0xFFFF))
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER | BATTLE_TYPE_INGAME_PARTNER)
// Battle Outcome defines
@ -259,6 +259,7 @@
#define MOVE_RESULT_FOE_ENDURED (1 << 6)
#define MOVE_RESULT_FOE_HUNG_ON (1 << 7)
#define MOVE_RESULT_STURDIED (1 << 8)
#define MOVE_RESULT_FOE_ENDURED_AFFECTION (1 << 9)
#define MOVE_RESULT_NO_EFFECT (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED)
// Battle Weather flags

View File

@ -536,6 +536,7 @@
#define B_ANIM_BEAK_BLAST_SETUP 33
#define B_ANIM_SHELL_TRAP_SETUP 34
#define B_ANIM_ZMOVE_ACTIVATE 35 // Using Z Moves
#define B_ANIM_AFFECTION_HANGED_ON 36
// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0

View File

@ -1,8 +1,6 @@
#ifndef GUARD_CONSTANTS_BATTLE_CONFIG_H
#define GUARD_CONSTANTS_BATTLE_CONFIG_H
#include "constants/expansion_branches.h"
#ifndef GEN_3
#define GEN_3 0
#define GEN_4 1
@ -177,6 +175,7 @@
#define B_MULTI_BATTLE_WHITEOUT GEN_8 // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight.
#define B_EVOLUTION_AFTER_WHITEOUT GEN_6 // In Gen6+, Pokemon that qualify for evolution after battle will evolve even if the player loses.
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)
#define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
// Animation Settings
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.

View File

@ -624,8 +624,14 @@
#define STRINGID_ZMOVESTATUP 622
#define STRINGID_ZMOVEHPTRAP 623
#define STRINGID_TERRAINREMOVED 624
#define STRINGID_ATTACKEREXPELLEDTHEPOISON 625
#define STRINGID_ATTACKERSHOOKITSELFAWAKE 626
#define STRINGID_ATTACKERBROKETHROUGHPARALYSIS 627
#define STRINGID_ATTACKERHEALEDITSBURN 628
#define STRINGID_ATTACKERMELTEDTHEICE 629
#define STRINGID_TARGETTOUGHEDITOUT 630
#define BATTLESTRINGS_COUNT 625
#define BATTLESTRINGS_COUNT 631
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,

View File

@ -1,12 +0,0 @@
#ifndef GUARD_CONSTANTS_EXPANSION_BRANCHES_H
#define GUARD_CONSTANTS_EXPANSION_BRANCHES_H
// Branch defines: Used by other branches to detect each other.
// Each define must be here for each of RHH's branch you have pulled.
// e.g. If you have both the battle_engine and pokemon_expansion branch,
// then both BATTLE_ENGINE and POKEMON_EXPANSION must be defined here.
#define BATTLE_ENGINE
#define POKEMON_EXPANSION
#define ITEM_EXPANSION
#endif

View File

@ -1,8 +1,6 @@
#ifndef GUARD_CONSTANTS_ITEM_CONFIG_H
#define GUARD_CONSTANTS_ITEM_CONFIG_H
#include "constants/expansion_branches.h"
#ifndef GEN_3
#define GEN_3 0
#define GEN_4 1

View File

@ -973,6 +973,13 @@
#define MACH_BIKE 0
#define ACRO_BIKE 1
// Item parameters for EXP Candies
#define EXP_100 1
#define EXP_800 2
#define EXP_3000 3
#define EXP_10000 4
#define EXP_30000 5
// Item type IDs (used to determine the exit callback)
#define ITEM_USE_MAIL 0
#define ITEM_USE_PARTY_MENU 1

View File

@ -12,38 +12,6 @@
#define AILMENT_PKRS 6
#define AILMENT_FNT 7
#define TUTOR_MOVE_MEGA_PUNCH 0
#define TUTOR_MOVE_SWORDS_DANCE 1
#define TUTOR_MOVE_MEGA_KICK 2
#define TUTOR_MOVE_BODY_SLAM 3
#define TUTOR_MOVE_DOUBLE_EDGE 4
#define TUTOR_MOVE_COUNTER 5
#define TUTOR_MOVE_SEISMIC_TOSS 6
#define TUTOR_MOVE_MIMIC 7
#define TUTOR_MOVE_METRONOME 8
#define TUTOR_MOVE_SOFT_BOILED 9
#define TUTOR_MOVE_DREAM_EATER 10
#define TUTOR_MOVE_THUNDER_WAVE 11
#define TUTOR_MOVE_EXPLOSION 12
#define TUTOR_MOVE_ROCK_SLIDE 13
#define TUTOR_MOVE_SUBSTITUTE 14
#define TUTOR_MOVE_DYNAMIC_PUNCH 15
#define TUTOR_MOVE_ROLLOUT 16
#define TUTOR_MOVE_PSYCH_UP 17
#define TUTOR_MOVE_SNORE 18
#define TUTOR_MOVE_ICY_WIND 19
#define TUTOR_MOVE_ENDURE 20
#define TUTOR_MOVE_MUD_SLAP 21
#define TUTOR_MOVE_ICE_PUNCH 22
#define TUTOR_MOVE_SWAGGER 23
#define TUTOR_MOVE_SLEEP_TALK 24
#define TUTOR_MOVE_SWIFT 25
#define TUTOR_MOVE_DEFENSE_CURL 26
#define TUTOR_MOVE_THUNDER_PUNCH 27
#define TUTOR_MOVE_FIRE_PUNCH 28
#define TUTOR_MOVE_FURY_CUTTER 29
#define TUTOR_MOVE_COUNT 30
#define PARTY_LAYOUT_SINGLE 0
#define PARTY_LAYOUT_DOUBLE 1
#define PARTY_LAYOUT_MULTI 2

View File

@ -182,6 +182,15 @@
#define FRIENDSHIP_EVENT_FAINT_FIELD_PSN 7
#define FRIENDSHIP_EVENT_FAINT_LARGE 8 // If opponent was >= 30 levels higher. See AdjustFriendshipOnBattleFaint
// Constants for GetLeadMonFriendshipScore
#define FRIENDSHIP_NONE 0
#define FRIENDSHIP_1_TO_49 1
#define FRIENDSHIP_50_TO_99 2
#define FRIENDSHIP_100_TO_149 3
#define FRIENDSHIP_150_TO_199 4
#define FRIENDSHIP_200_TO_254 5
#define FRIENDSHIP_MAX 6
#define MAX_FRIENDSHIP 255
#define MAX_SHEEN 255
#define MAX_CONDITION 255

View File

@ -1,8 +1,6 @@
#ifndef GUARD_CONSTANTS_POKEMON_CONFIG_H
#define GUARD_CONSTANTS_POKEMON_CONFIG_H
#include "constants/expansion_branches.h"
#ifndef GEN_3
#define GEN_3 0
#define GEN_4 1
@ -14,7 +12,7 @@
#define P_UPDATED_TYPES GEN_8 // Since Gen 6, several Pokémon were changed to be partially or fully Fairy type.
#define P_UPDATED_STATS GEN_8 // Since Gen 6, Pokémon stats are updated with each passing generation.
#define P_UPDATED_ABILITIES GEN_8 // Since Gen 6, certain Pokémon have their abilities changed. Requires BATTLE_ENGINE for Gen4+ abilities.
#define P_UPDATED_ABILITIES GEN_8 // Since Gen 6, certain Pokémon have their abilities changed.
#define P_UPDATED_EGG_GROUPS GEN_8 // Since Gen 8, certain Pokémon have gained new egg groups.
#define P_SHEDINJA_BALL GEN_8 // Since Gen 4, Shedinja requires a Poké Ball for its evolution. In Gen 3, Shedinja inherits Nincada's Ball.
#define P_LEGENDARY_PERFECT_IVS GEN_8 // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs.

View File

@ -19,10 +19,9 @@ bool8 LoadCompressedSpritePaletteUsingHeap(const struct CompressedSpritePalette
void DecompressPicFromTable(const struct CompressedSpriteSheet *src, void *buffer, s32 species);
void DecompressPicFromTableGender(void* buffer, s32 species, u32 personality);
void HandleLoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality);
void HandleLoadSpecialPokePicCustom(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFemale);
void HandleLoadSpecialPokePic(bool32 isFrontPic, void *dest, s32 species, u32 personality);
void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFrontPic);
void LoadSpecialPokePic(void *dest, s32 species, u32 personality, bool8 isFrontPic);
u32 GetDecompressedDataSize(const u32 *ptr);

View File

@ -15,7 +15,6 @@
#include "constants/pokemon.h"
#include "constants/easy_chat.h"
#include "constants/trainer_hill.h"
#include "constants/expansion_branches.h"
// Prevent cross-jump optimization.
#define BLOCK_CROSS_JUMP asm("");

View File

@ -29,8 +29,6 @@ extern u8 gBattlePartyCurrentOrder[PARTY_SIZE / 2];
extern void (*gItemUseCB)(u8, TaskFunc);
extern const u16 gTutorMoves[];
void AnimatePartySlot(u8 slot, u8 animNum);
bool8 IsMultiBattle(void);
u8 GetCursorSelectionMonId(void);

View File

@ -397,6 +397,7 @@ extern const struct BaseStats gBaseStats[];
extern const u8 *const gItemEffectTable[];
extern const u32 gExperienceTables[][MAX_LEVEL + 1];
extern const struct LevelUpMove *const gLevelUpLearnsets[];
extern const u16 *const gTeachableLearnsets[];
extern const u8 gPPUpGetMask[];
extern const u8 gPPUpClearMask[];
extern const u8 gPPUpAddValues[];
@ -509,8 +510,7 @@ u8 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection);
void UpdatePartyPokerusTime(u16 days);
void PartySpreadPokerus(struct Pokemon *party);
bool8 TryIncrementMonLevel(struct Pokemon *mon);
u32 CanMonLearnTMHM(struct Pokemon *mon, u8 tm);
u32 CanSpeciesLearnTMHM(u16 species, u8 tm);
u8 CanLearnTeachableMove(u16 species, u16 move);
u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves);
u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves);
u8 GetNumberOfRelearnableMoves(struct Pokemon *mon);
@ -558,5 +558,6 @@ u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
bool32 ShouldShowFemaleDifferences(u16 species, u32 personality);
#endif // GUARD_POKEMON_H

View File

@ -21,7 +21,6 @@ u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s1
void FreeMonIconPalette(u16 species);
void FreeAndDestroyMonIconSprite(struct Sprite *sprite);
u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality);
u8 CreateMonIconCustom(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool8 isFemale, bool8 isShiny);
u8 UpdateMonIconFrame(struct Sprite *sprite);
void LoadMonIconPalette(u16 species);
void SpriteCB_MonIcon(struct Sprite *sprite);

View File

@ -6,6 +6,7 @@
extern u8 gLastViewedMonIndex;
extern const u8 *const gMoveDescriptionPointers[];
extern const u8 gNotDoneYetDescription[];
extern const u8 *const gNatureNamePointers[];
void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void));

View File

@ -499,6 +499,7 @@ extern const u8 gText_12PoofForgotMove[];
extern const u8 gText_StopLearningMove2[];
extern const u8 gText_MoveNotLearned[];
extern const u8 gText_PkmnElevatedToLvVar2[];
extern const u8 gText_PkmnGainedExp[];
extern const u8 gText_RemoveMailBeforeItem[];
extern const u8 gText_PkmnHoldingItemCantHoldMail[];
extern const u8 gText_MailTransferredFromMailbox[];

View File

@ -376,7 +376,7 @@ static u16 GetRandomAlternateMove(u8 monId)
do
{
id = Random() % (NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES);
shouldUseMove = CanSpeciesLearnTMHM(species, id);
shouldUseMove = CanLearnTeachableMove(species, ItemIdToBattleMoveId(ITEM_TM01 + id));
}
while (!shouldUseMove);

View File

@ -245,7 +245,7 @@ static void SetBattlerAiData(u8 battlerId)
AI_DATA->holdEffectParams[battlerId] = GetBattlerHoldEffectParam(battlerId);
AI_DATA->predictedMoves[battlerId] = gLastMoves[battlerId];
AI_DATA->hpPercents[battlerId] = GetHealthPercentage(battlerId);
AI_DATA->moveLimitations[battlerId] = CheckMoveLimitations(battlerId, 0, 0xFF);
AI_DATA->moveLimitations[battlerId] = CheckMoveLimitations(battlerId, 0, MOVE_LIMITATIONS_ALL);
}
void GetAiLogicData(void)
@ -2512,6 +2512,8 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (gBattleMons[battlerAtk].hp <= gBattleMons[battlerAtk].maxHP / 3)
score -= 10;
break;*/
case EFFECT_PLACEHOLDER:
return 0; // cannot even select
} // move effect checks
if (score < 0)

View File

@ -154,7 +154,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
return FALSE;
if (gLastLandedMoves[gActiveBattler] == MOVE_UNAVAILABLE)
return FALSE;
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0)
if (IS_MOVE_STATUS(gLastLandedMoves[gActiveBattler]))
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
@ -245,8 +245,7 @@ static bool8 ShouldSwitchIfNaturalCure(void)
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
return TRUE;
}
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0
&& Random() & 1)
else if (IS_MOVE_STATUS(gLastLandedMoves[gActiveBattler]) && Random() & 1)
{
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
@ -350,7 +349,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
return FALSE;
if (gLastHitBy[gActiveBattler] == 0xFF)
return FALSE;
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0)
if (IS_MOVE_STATUS(gLastLandedMoves[gActiveBattler]))
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)

View File

@ -71,7 +71,7 @@ static void AnimProtect_Step(struct Sprite *);
static void AnimMilkBottle(struct Sprite *);
static void AnimMilkBottle_Step1(struct Sprite *);
static void AnimMilkBottle_Step2(struct Sprite *, int, int);
static void AnimSparkingStars(struct Sprite *);
static void AnimSparklingStars(struct Sprite *);
static void AnimBubbleBurst(struct Sprite *);
static void AnimBubbleBurst_Step(struct Sprite *);
static void AnimSleepLetterZ(struct Sprite *);
@ -1696,7 +1696,7 @@ const struct SpriteTemplate gSparklingStarsSpriteTemplate =
.anims = gGrantingStarsAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSparkingStars,
.callback = AnimSparklingStars,
};
static const union AnimCmd sAnim_BubbleBurst[] =
@ -4290,14 +4290,14 @@ static void AnimItemSteal_Step3(struct Sprite *sprite)
sprite->y2 = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8);
if (sprite->y2 == 0)
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
if (moveAlongLinearPath(sprite))
{
sprite->y2 = 0;
sprite->data[0] = 0;
sprite->callback = AnimItemSteal_Step2;
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(-64));
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
}
}
@ -5243,7 +5243,7 @@ void AnimGrantingStars(struct Sprite *sprite)
sprite->callback = TranslateSpriteLinearFixedPoint;
}
static void AnimSparkingStars(struct Sprite *sprite)
static void AnimSparklingStars(struct Sprite *sprite)
{
u8 battler;
if (!gBattleAnimArgs[2])
@ -5370,7 +5370,7 @@ static void AnimLockOnTarget_Step1(struct Sprite *sprite)
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, AnimLockOnTarget_Step2);
sprite->data[5] += 0x100;
PlaySE12WithPanning(SE_M_LOCK_ON, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_LOCK_ON, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
break;
}
@ -5456,7 +5456,7 @@ static void AnimLockOnTarget_Step4(struct Sprite *sprite)
sprite->data[2]++;
pal = sprite->oam.paletteNum;
LoadPalette(&gPlttBufferUnfaded[0x108 + pal * 16], pal * 16 | 0x101, 4);
PlaySE12WithPanning(SE_M_LEER, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_LEER, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
}
else if (sprite->data[1] == 0)
{
@ -5918,7 +5918,7 @@ static void AnimSharpenSphere(struct Sprite *sprite)
sprite->data[2] = 0;
sprite->data[3] = 0;
sprite->data[4] = 0;
sprite->data[5] = BattleAnimAdjustPanning(-64);
sprite->data[5] = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
sprite->callback = AnimSharpenSphere_Step;
}

View File

@ -1678,7 +1678,7 @@ static void AirCutterProjectileStep1(u8 taskId)
gTasks[taskId].data[gTasks[taskId].data[1] + 13] = spriteId;
gTasks[taskId].data[0] = gTasks[taskId].data[3];
gTasks[taskId].data[1]++;
PlaySE12WithPanning(SE_M_BLIZZARD2, BattleAnimAdjustPanning(-63));
PlaySE12WithPanning(SE_M_BLIZZARD2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER + 1));
if (gTasks[taskId].data[1] > 2)
gTasks[taskId].func = AirCutterProjectileStep2;
}
@ -1875,7 +1875,7 @@ static void AnimBulletSeed_Step1(struct Sprite *sprite)
int i;
u16 rand;
s16 *ptr;
PlaySE12WithPanning(SE_M_HORN_ATTACK, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_HORN_ATTACK, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
@ -2521,7 +2521,7 @@ static void AnimPencil(struct Sprite *sprite)
sprite->data[3] = 16;
sprite->data[4] = 0;
sprite->data[5] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT) + 2;
sprite->data[6] = BattleAnimAdjustPanning(63);
sprite->data[6] = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
sprite->callback = AnimPencil_Step;
}
@ -3079,9 +3079,7 @@ void AnimTask_FreeMusicNotesPals(u8 taskId)
static void SetMusicNotePalette(struct Sprite *sprite, u8 a, u8 b)
{
u8 tile;
tile = (b & 1);
tile = ((-tile | tile) >> 31) & 32;
u8 tile = (b & 1) ? 32 : 0;
sprite->oam.tileNum += tile + (a << 2);
sprite->oam.paletteNum = IndexOfSpritePaletteTag(sMusicNotePaletteTagsTable[b >> 1]);
}
@ -3828,8 +3826,7 @@ static void AnimPerishSongMusicNote_Step2(struct Sprite *sprite)
if (sprite->data[4] > 3)
{
int var1 = sprite->data[2];
sprite->invisible = var1 - (((s32)(var1 + ((u32)var1 >> 31)) >> 1) << 1);
sprite->invisible = sprite->data[2] % 2;
DestroyAnimSprite(sprite);
}

View File

@ -1739,7 +1739,7 @@ static void AnimClappingHand_Step(struct Sprite *sprite)
sprite->data[2]++;
if (sprite->data[3] == 0)
{
PlaySE1WithPanning(SE_M_ENCORE, BattleAnimAdjustPanning(-64));
PlaySE1WithPanning(SE_M_ENCORE, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
}
}
}
@ -2023,7 +2023,7 @@ static void TormentAttacker_Step(u8 taskId)
y = task->data[3] + task->data[5];
spriteId = CreateSprite(&gThoughtBubbleSpriteTemplate, x, y, 6 - task->data[1]);
PlaySE12WithPanning(SE_M_METRONOME, BattleAnimAdjustPanning(-64));
PlaySE12WithPanning(SE_M_METRONOME, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
if (spriteId != MAX_SPRITES)
{
@ -2200,7 +2200,7 @@ static void AnimWishStar(struct Sprite *sprite)
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x = -16;
else
sprite->x = 256;
sprite->x = DISPLAY_WIDTH + 16;
sprite->y = 0;
sprite->callback = AnimWishStar_Step;
@ -2229,7 +2229,7 @@ static void AnimWishStar_Step(struct Sprite *sprite)
}
newX = sprite->x + sprite->x2 + 32;
if (newX > 304)
if (newX > DISPLAY_WIDTH + 64)
DestroyAnimSprite(sprite);
}
@ -2504,7 +2504,7 @@ void AnimTask_MorningSunLightBeam(u8 taskId)
gTasks[taskId].data[11] = gBattle_BG1_Y;
gTasks[taskId].data[0]++;
PlaySE12WithPanning(SE_M_MORNING_SUN, BattleAnimAdjustPanning(-64));
PlaySE12WithPanning(SE_M_MORNING_SUN, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
break;
case 1:
if (gTasks[taskId].data[4]++ > 0)
@ -2539,7 +2539,7 @@ void AnimTask_MorningSunLightBeam(u8 taskId)
{
gTasks[taskId].data[3] = 0;
gTasks[taskId].data[0] = 1;
PlaySE12WithPanning(SE_M_MORNING_SUN, BattleAnimAdjustPanning(-64));
PlaySE12WithPanning(SE_M_MORNING_SUN, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
}
break;
case 4:
@ -3276,7 +3276,7 @@ static void AnimReversalOrb_Step(struct Sprite *sprite)
// Copies the target mon's sprite, and makes a white silhouette that shrinks away.
void AnimTask_RolePlaySilhouette(u8 taskId)
{
u8 isBackPic;
bool8 isBackPic;
u32 personality;
u32 otId;
u16 species;
@ -3299,7 +3299,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
isBackPic = 0;
isBackPic = FALSE;
personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY);
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID);
if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE)
@ -3319,7 +3319,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId)
}
else
{
isBackPic = 1;
isBackPic = TRUE;
personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY);
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID);
if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE)
@ -4949,7 +4949,7 @@ static void AnimTask_MonToSubstituteDoll(u8 taskId)
if (gSprites[spriteId].y2 == 0)
{
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(-64));
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
gTasks[taskId].data[10] -= 0x800;
gTasks[taskId].data[0]++;
}
@ -4971,7 +4971,7 @@ static void AnimTask_MonToSubstituteDoll(u8 taskId)
if (gSprites[spriteId].y2 == 0)
{
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(-64));
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
DestroyAnimVisualTask(taskId);
}
break;
@ -5008,7 +5008,7 @@ static void AnimBlockX_Step(struct Sprite *sprite)
sprite->y2 += 10;
if (sprite->y2 >= 0)
{
PlaySE12WithPanning(SE_M_SKETCH, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_SKETCH, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->y2 = 0;
sprite->data[0]++;
}
@ -5018,7 +5018,7 @@ static void AnimBlockX_Step(struct Sprite *sprite)
sprite->y2 = -(gSineTable[sprite->data[1]] >> 3);
if (sprite->data[1] > 0x7F)
{
PlaySE12WithPanning(SE_M_SKETCH, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_SKETCH, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->data[1] = 0;
sprite->y2 = 0;
sprite->data[0]++;
@ -5037,7 +5037,7 @@ static void AnimBlockX_Step(struct Sprite *sprite)
case 3:
if (++sprite->data[1] > 8)
{
PlaySE12WithPanning(SE_M_LEER, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_LEER, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->data[1] = 0;
sprite->data[0]++;
}
@ -5201,7 +5201,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId)
gTasks[taskId].data[1] &= 0xFF;
x = gSprites[spriteId].x + gSprites[spriteId].x2;
if ((u16)(x + 32) > 304)
if (x < -32 || x > DISPLAY_WIDTH + 32)
{
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[0]++;
@ -5284,7 +5284,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId)
}
}
if ((u16)(x + 32) > 304)
if (x < -32 || x > DISPLAY_WIDTH + 32)
{
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[0]++;
@ -5331,7 +5331,7 @@ static void AnimUnusedItemBagSteal(struct Sprite *sprite)
case 0:
if (gBattleAnimArgs[7] == -1)
{
PlaySE12WithPanning(SE_M_VITAL_THROW, BattleAnimAdjustPanning(63));
PlaySE12WithPanning(SE_M_VITAL_THROW, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 16;
sprite->data[0] = -32;
sprite->data[7]++;

View File

@ -676,7 +676,7 @@ void AnimZapCannonSpark(struct Sprite *sprite)
sprite->data[7] = gBattleAnimArgs[4];
sprite->oam.tileNum += gBattleAnimArgs[6] * 4;
sprite->callback = AnimZapCannonSpark_Step;
AnimZapCannonSpark_Step(sprite);
sprite->callback(sprite);
}
static void AnimZapCannonSpark_Step(struct Sprite *sprite)
@ -1262,7 +1262,7 @@ void AnimTask_ShockWaveProgressingBolt(u8 taskId)
task->data[4] = 7;
task->data[5] = -1;
task->data[11] = 12;
task->data[12] = BattleAnimAdjustPanning(task->data[11] - 76);
task->data[12] = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
task->data[13] = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
task->data[14] = task->data[12];
task->data[15] = (task->data[13] - task->data[12]) / 3;

View File

@ -572,7 +572,7 @@ static void AnimFistOrFootRandomPos(struct Sprite *sprite)
sprite->data[0] = gBattleAnimArgs[1];
sprite->data[7] = CreateSprite(&gBasicHitSplatSpriteTemplate, sprite->x, sprite->y, sprite->subpriority + 1);
if (sprite->data[7] != 64)
if (sprite->data[7] != MAX_SPRITES)
{
StartSpriteAffineAnim(&gSprites[sprite->data[7]], 0);
gSprites[sprite->data[7]].callback = SpriteCallbackDummy;
@ -585,7 +585,7 @@ static void AnimFistOrFootRandomPos_Step(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
if (sprite->data[7] != 64)
if (sprite->data[7] != MAX_SPRITES)
{
FreeOamMatrix(gSprites[sprite->data[7]].oam.matrixNum);
DestroySprite(&gSprites[sprite->data[7]]);

View File

@ -1309,8 +1309,8 @@ void AnimTask_MoveHeatWaveTargets(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[12] = !GetBattlerSide(gBattleAnimAttacker) ? 1 : -1;
task->data[13] = IsBattlerSpriteVisible(gBattleAnimTarget ^ 2) + 1;
task->data[12] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1;
task->data[13] = IsBattlerSpriteVisible(gBattleAnimTarget ^ BIT_FLANK) + 1;
task->data[14] = GetAnimBattlerSpriteId(ANIM_TARGET);
task->data[15] = GetAnimBattlerSpriteId(ANIM_DEF_PARTNER);

View File

@ -1211,7 +1211,7 @@ void AnimSkyAttackBird_Step(struct Sprite *sprite)
sprite->x = sprite->data[4] >> 4;
sprite->y = sprite->data[5] >> 4;
if (sprite->x > 285 || sprite->x < -45
if (sprite->x > DISPLAY_WIDTH + 45 || sprite->x < -45
|| sprite->y > 157 || sprite->y < -45)
DestroySpriteAndMatrix(sprite);
}

View File

@ -41,7 +41,7 @@ static void AnimThrowIceBall(struct Sprite *);
static void InitIceBallParticle(struct Sprite *);
static void AnimIceBallParticle(struct Sprite *);
static void AnimTask_HazeScrollingFog_Step(u8);
static void AnimTask_LoadMistTiles_Step(u8);
static void AnimTask_MistBallFog_Step(u8);
static void AnimTask_Hail2(u8);
static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId, u8 c);
static void AvalancheAnim_Step(struct Sprite *sprite);
@ -351,7 +351,7 @@ const struct SpriteTemplate gMistBallSpriteTemplate =
.callback = AnimThrowMistBall,
};
static const u8 wMistBlendAmounts[] =
static const u8 sMistBlendAmounts[] =
{
0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
};
@ -779,7 +779,8 @@ static void AnimSwirlingSnowball(struct Sprite *sprite)
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 16
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
break;
@ -845,7 +846,8 @@ static void AnimSwirlingSnowball_End(struct Sprite *sprite)
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
if (sprite->x + sprite->x2 > 256
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > 256
|| sprite->y + sprite->y2 < -16)
DestroyAnimSprite(sprite);
@ -899,7 +901,8 @@ void AnimMoveParticleBeyondTarget(struct Sprite *sprite)
{
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 16
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
break;
@ -929,7 +932,8 @@ static void AnimWiggleParticleTowardsTarget(struct Sprite *sprite)
sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
if (sprite->data[0] == 1)
{
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 16
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
DestroyAnimSprite(sprite);
@ -1169,7 +1173,7 @@ void AnimThrowMistBall(struct Sprite *sprite)
}
// Displays misty background in Mist Ball.
void AnimTask_LoadMistTiles(u8 taskId)
void AnimTask_MistBallFog(u8 taskId)
{
struct BattleAnimBgData animBg;
@ -1192,10 +1196,10 @@ void AnimTask_LoadMistTiles(u8 taskId)
LoadPalette(&gFogPalette, animBg.paletteId * 16, 32);
gTasks[taskId].data[15] = -1;
gTasks[taskId].func = AnimTask_LoadMistTiles_Step;
gTasks[taskId].func = AnimTask_MistBallFog_Step;
}
static void AnimTask_LoadMistTiles_Step(u8 taskId)
static void AnimTask_MistBallFog_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
@ -1206,7 +1210,7 @@ static void AnimTask_LoadMistTiles_Step(u8 taskId)
{
case 0:
gTasks[taskId].data[9] += 1;
gTasks[taskId].data[11] = wMistBlendAmounts[gTasks[taskId].data[9]];
gTasks[taskId].data[11] = sMistBlendAmounts[gTasks[taskId].data[9]];
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 17 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 5)
{
@ -1493,14 +1497,14 @@ static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId,
}
else
{
battlerX = (sHailCoordData[hailStructId].x);
battlerY = (sHailCoordData[hailStructId].y);
battlerX = sHailCoordData[hailStructId].x;
battlerY = sHailCoordData[hailStructId].y;
}
}
else
{
battlerX = (sHailCoordData[hailStructId].x);
battlerY = (sHailCoordData[hailStructId].y);
battlerX = sHailCoordData[hailStructId].x;
battlerY = sHailCoordData[hailStructId].y;
}
spriteX = battlerX - ((battlerY + 8) / 2);
id = CreateSprite(&gHailParticleSpriteTemplate, spriteX, -8, 18);

View File

@ -5,7 +5,6 @@
#include "task.h"
#include "trig.h"
// This file's functions.
static void AnimTask_ShakeMon_Step(u8 taskId);
static void AnimTask_ShakeMon2_Step(u8 taskId);
static void AnimTask_ShakeMonInPlace_Step(u8 taskId);
@ -109,7 +108,7 @@ void AnimTask_ShakeMon(u8 taskId)
gTasks[taskId].data[4] = gBattleAnimArgs[1];
gTasks[taskId].data[5] = gBattleAnimArgs[2];
gTasks[taskId].func = AnimTask_ShakeMon_Step;
AnimTask_ShakeMon_Step(taskId);
gTasks[taskId].func(taskId);
}
static void AnimTask_ShakeMon_Step(u8 taskId)
@ -157,17 +156,14 @@ static void AnimTask_ShakeMon_Step(u8 taskId)
void AnimTask_ShakeMon2(u8 taskId)
{
u8 spriteId;
bool8 destroy = FALSE;
bool8 abort = FALSE;
u8 battlerId;
if (gBattleAnimArgs[0] < MAX_BATTLERS_COUNT)
{
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == SPRITE_NONE)
{
DestroyAnimVisualTask(taskId);
return;
}
abort = TRUE;
}
else if (gBattleAnimArgs[0] != 8)
{
@ -189,7 +185,7 @@ void AnimTask_ShakeMon2(u8 taskId)
}
if (IsBattlerSpriteVisible(battlerId) == FALSE)
destroy = TRUE;
abort = TRUE;
spriteId = gBattlerSpriteIds[battlerId];
}
@ -198,7 +194,7 @@ void AnimTask_ShakeMon2(u8 taskId)
spriteId = gBattlerSpriteIds[gBattleAnimAttacker];
}
if (destroy)
if (abort)
{
DestroyAnimVisualTask(taskId);
return;
@ -340,10 +336,8 @@ void AnimTask_ShakeAndSinkMon(u8 taskId)
static void AnimTask_ShakeAndSinkMon_Step(u8 taskId)
{
s16 x;
u8 spriteId;
spriteId = gTasks[taskId].data[0];
x = gTasks[taskId].data[1];
u8 spriteId = gTasks[taskId].data[0];
s16 x = gTasks[taskId].data[1];
if (gTasks[taskId].data[2] == gTasks[taskId].data[8]++)
{
gTasks[taskId].data[8] = 0;
@ -373,11 +367,8 @@ static void AnimTask_ShakeAndSinkMon_Step(u8 taskId)
void AnimTask_TranslateMonElliptical(u8 taskId)
{
u8 i;
u8 spriteId;
u8 wavePeriod;
wavePeriod = 1;
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
u8 wavePeriod = 1;
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (gBattleAnimArgs[4] > 5)
gBattleAnimArgs[4] = 5;
@ -750,7 +741,7 @@ static void AnimTask_SlideOffScreen_Step(u8 taskId)
{
u8 spriteId = gTasks[taskId].data[0];
gSprites[spriteId].x2 += gTasks[taskId].data[1];
if (gSprites[spriteId].x2 + gSprites[spriteId].x + 0x20 > 0x130u)
if (gSprites[spriteId].x2 + gSprites[spriteId].x < -32 || gSprites[spriteId].x2 + gSprites[spriteId].x > DISPLAY_WIDTH + 32)
{
DestroyAnimVisualTask(taskId);
return;
@ -844,8 +835,7 @@ static void AnimTask_SwayMonStep(u8 taskId)
// arg 4: sprite object mode
void AnimTask_ScaleMonAndRestore(u8 taskId)
{
u8 spriteId;
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]);
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]);
PrepareBattlerSpriteForRotScale(spriteId, gBattleAnimArgs[4]);
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[1] = gBattleAnimArgs[1];
@ -906,7 +896,7 @@ void AnimTask_RotateMonSpriteToSide(u8 taskId)
}
else
{
if (gBattleAnimArgs[2] == 0)
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
{
gTasks[taskId].data[7] = !GetBattlerSide(gBattleAnimAttacker);
}
@ -929,8 +919,7 @@ void AnimTask_RotateMonSpriteToSide(u8 taskId)
// Rotates mon to side and back to original position. For Peck and when a held item activates
void AnimTask_RotateMonToSideAndRestore(u8 taskId)
{
u8 spriteId;
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = gBattleAnimArgs[0];

View File

@ -1,6 +1,7 @@
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_interface.h"
#include "bg.h"
#include "contest.h"
#include "data.h"
@ -89,7 +90,7 @@ static const u8 sCastformBackSpriteYCoords[NUM_CASTFORM_FORMS] =
#define TAG_MOVE_EFFECT_MON_1 55125
#define TAG_MOVE_EFFECT_MON_2 55126
static const struct SpriteTemplate sSpriteTemplate_MoveEffectMons[] =
static const struct SpriteTemplate sSpriteTemplates_MoveEffectMons[] =
{
{
.tileTag = TAG_MOVE_EFFECT_MON_1,
@ -111,7 +112,7 @@ static const struct SpriteTemplate sSpriteTemplate_MoveEffectMons[] =
}
};
static const struct SpriteSheet sSpriteSheet_MoveEffectMons[] =
static const struct SpriteSheet sSpriteSheets_MoveEffectMons[] =
{
{ gMiscBlank_Gfx, MON_PIC_SIZE, TAG_MOVE_EFFECT_MON_1, },
{ gMiscBlank_Gfx, MON_PIC_SIZE, TAG_MOVE_EFFECT_MON_2, },
@ -134,10 +135,10 @@ u8 GetBattlerSpriteCoord(u8 battlerId, u8 coordType)
{
case BATTLER_COORD_X:
case BATTLER_COORD_X_2:
retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].x;
retVal = sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].x;
break;
case BATTLER_COORD_Y:
retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
retVal = sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].y;
break;
case BATTLER_COORD_Y_PIC_OFFSET:
case BATTLER_COORD_Y_PIC_OFFSET_DEFAULT:
@ -278,7 +279,7 @@ u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3)
offset = GetBattlerYDelta(battlerId, species);
offset -= GetBattlerElevation(battlerId, species);
}
y = offset + sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
y = offset + sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].y;
if (a3)
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
@ -438,7 +439,7 @@ void SetCallbackToStoredInData6(struct Sprite *sprite)
#define sAmplitudeX sAmplitude
#define sAmplitudeY data[4]
// TranslateSpriteInWavePattern
// TranslateSpriteInLissajousCurve
#define sCirclePosX sCirclePos
#define sCircleSpeedX sCircleSpeed
#define sCirclePosY data[4]
@ -485,7 +486,7 @@ void TranslateSpriteInGrowingCircle(struct Sprite *sprite)
// Unused
// Exact shape depends on arguments. Can move in a figure-8-like pattern, or circular, etc.
static void TranslateSpriteInWavePattern(struct Sprite *sprite)
static void TranslateSpriteInLissajousCurve(struct Sprite *sprite)
{
if (sprite->sDuration)
{
@ -1548,13 +1549,13 @@ u32 GetBattleMonSpritePalettesMask(u8 playerLeft, u8 playerRight, u8 opponentLef
return selectedPalettes;
}
// Presumably something commented here, just returns arg
u8 AnimDummyReturnArg(u8 battler)
u8 GetSpritePalIdxByBattler(u8 battler)
{
return battler;
}
static u8 GetBattlerAtPosition_(u8 position)
// Unused
static u8 GetSpritePalIdxByPosition(u8 position)
{
return GetBattlerAtPosition(position);
}
@ -1596,20 +1597,20 @@ void AnimSpriteOnMonPos(struct Sprite *sprite)
// arg 5: lower 8 bits = location on attacking mon, upper 8 bits = location on target mon pick to target
void TranslateAnimSpriteToTargetMonLocation(struct Sprite *sprite)
{
bool8 v1;
bool8 respectMonPicOffsets;
u8 coordType;
if (!(gBattleAnimArgs[5] & 0xff00))
v1 = TRUE;
respectMonPicOffsets = TRUE;
else
v1 = FALSE;
respectMonPicOffsets = FALSE;
if (!(gBattleAnimArgs[5] & 0xff))
coordType = BATTLER_COORD_Y_PIC_OFFSET;
else
coordType = BATTLER_COORD_Y;
InitSpritePosToAnimAttacker(sprite, v1);
InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
@ -2141,16 +2142,15 @@ u8 GetBattlerSpriteBGPriorityRank(u8 battlerId)
u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId)
{
u8 spriteId;
u16 sheet = LoadSpriteSheet(&sSpriteSheet_MoveEffectMons[id]);
u16 palette = AllocSpritePalette(sSpriteTemplate_MoveEffectMons[id].paletteTag);
u16 sheet = LoadSpriteSheet(&sSpriteSheets_MoveEffectMons[id]);
u16 palette = AllocSpritePalette(sSpriteTemplates_MoveEffectMons[id].paletteTag);
if (gMonSpritesGfxPtr != NULL && gMonSpritesGfxPtr->buffer == NULL)
gMonSpritesGfxPtr->buffer = AllocZeroed(0x2000);
if (!isBackpic)
{
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
LoadSpecialPokePic(&gMonFrontPicTable[species],
gMonSpritesGfxPtr->buffer,
LoadSpecialPokePic(gMonSpritesGfxPtr->buffer,
species,
personality,
TRUE);
@ -2158,8 +2158,7 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16
else
{
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
LoadSpecialPokePic(&gMonBackPicTable[species],
gMonSpritesGfxPtr->buffer,
LoadSpecialPokePic(gMonSpritesGfxPtr->buffer,
species,
personality,
FALSE);
@ -2169,9 +2168,9 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16
FREE_AND_SET_NULL(gMonSpritesGfxPtr->buffer);
if (!isBackpic)
spriteId = CreateSprite(&sSpriteTemplate_MoveEffectMons[id], x, y + gMonFrontPicCoords[species].y_offset, subpriority);
spriteId = CreateSprite(&sSpriteTemplates_MoveEffectMons[id], x, y + gMonFrontPicCoords[species].y_offset, subpriority);
else
spriteId = CreateSprite(&sSpriteTemplate_MoveEffectMons[id], x, y + gMonBackPicCoords[species].y_offset, subpriority);
spriteId = CreateSprite(&sSpriteTemplates_MoveEffectMons[id], x, y + gMonBackPicCoords[species].y_offset, subpriority);
if (IsContest())
{

View File

@ -18,6 +18,7 @@
#include "constants/moves.h"
#include "constants/hold_effects.h"
#include "constants/items.h"
#include "constants/pokemon.h"
// function declarations
static void SpriteCB_SpriteToCentreOfSide(struct Sprite *sprite);
@ -7892,3 +7893,12 @@ void AnimTask_TerrainPulse(u8 taskId)
}
DestroyAnimVisualTask(taskId);
}
void AnimTask_AffectionHangedOn(u8 taskId)
{
int side = GetBattlerSide(gBattleAnimTarget);
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
gBattleAnimArgs[0] = GetMonFriendshipScore(&party[gBattlerPartyIndexes[gBattleAnimTarget]]);
DestroyAnimVisualTask(taskId);
}

View File

@ -935,7 +935,7 @@ static void AnimTask_ImprisonOrbs_Step(u8 taskId)
{
for (i = 8; i < 13; i++)
{
if (task->data[i] != 64)
if (task->data[i] != MAX_SPRITES)
DestroySprite(&gSprites[task->data[i]]);
}
@ -1114,12 +1114,10 @@ void AnimTask_ExtrasensoryDistortion(u8 taskId)
scanlineParams.dmaDest = &REG_BG2HOFS;
}
i = task->data[14];
while (i <= task->data[14] + 64)
for (i = task->data[14]; i <= task->data[14] + 64; i++)
{
gScanlineEffectRegBuffers[0][i] = task->data[10];
gScanlineEffectRegBuffers[1][i] = task->data[10];
i++;
}
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
@ -1254,7 +1252,7 @@ void AnimPsychoBoost(struct Sprite *sprite)
case 1:
if (sprite->affineAnimEnded)
{
PlaySE12WithPanning(SE_M_TELEPORT, BattleAnimAdjustPanning(-64));
PlaySE12WithPanning(SE_M_TELEPORT, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
ChangeSpriteAffineAnim(sprite, 1);
sprite->data[0]++;
}

View File

@ -692,8 +692,8 @@ void AnimTask_Rollout(u8 taskId)
task->data[6] = 0;
task->data[7] = 0;
pan1 = BattleAnimAdjustPanning(-64);
pan2 = BattleAnimAdjustPanning(63);
pan1 = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
pan2 = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
task->data[13] = pan1;
task->data[14] = (pan2 - pan1) / task->data[8];

View File

@ -104,7 +104,7 @@ void SoundTask_LoopSEAdjustPanning(u8 taskId)
gTasks[taskId].data[12] = r9;
gTasks[taskId].func = SoundTask_LoopSEAdjustPanning_Step;
SoundTask_LoopSEAdjustPanning_Step(taskId);
gTasks[taskId].func(taskId);
}
static void SoundTask_LoopSEAdjustPanning_Step(u8 taskId)
@ -389,7 +389,7 @@ void SoundTask_AdjustPanningVar(u8 taskId)
gTasks[taskId].data[11] = sourcePan;
gTasks[taskId].func = SoundTask_AdjustPanningVar_Step;
SoundTask_AdjustPanningVar_Step(taskId);
gTasks[taskId].func(taskId);
}
static void SoundTask_AdjustPanningVar_Step(u8 taskId)

View File

@ -768,8 +768,8 @@ static void LoadHealthboxPalsForLevelUp(u8 *paletteId1, u8 *paletteId2, u8 battl
healthBoxSpriteId = gHealthboxSpriteIds[battler];
spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam;
spriteId2 = gSprites[healthBoxSpriteId].data[5];
*paletteId1 = AllocSpritePalette(0xD709);
*paletteId2 = AllocSpritePalette(0xD70A);
*paletteId1 = AllocSpritePalette(TAG_HEALTHBOX_PALS_1);
*paletteId2 = AllocSpritePalette(TAG_HEALTHBOX_PALS_2);
offset1 = (gSprites[healthBoxSpriteId].oam.paletteNum * 16) + 0x100;
offset2 = (gSprites[spriteId2].oam.paletteNum * 16) + 0x100;
@ -798,10 +798,10 @@ static void FreeHealthboxPalsForLevelUp(u8 battler)
spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam;
spriteId2 = gSprites[healthBoxSpriteId].data[5];
FreeSpritePaletteByTag(0xD709);
FreeSpritePaletteByTag(0xD70A);
paletteId1 = IndexOfSpritePaletteTag(0xD6FF);
paletteId2 = IndexOfSpritePaletteTag(0xD704);
FreeSpritePaletteByTag(TAG_HEALTHBOX_PALS_1);
FreeSpritePaletteByTag(TAG_HEALTHBOX_PALS_2);
paletteId1 = IndexOfSpritePaletteTag(TAG_HEALTHBOX_PAL);
paletteId2 = IndexOfSpritePaletteTag(TAG_HEALTHBAR_PAL);
gSprites[healthBoxSpriteId].oam.paletteNum = paletteId1;
gSprites[spriteId1].oam.paletteNum = paletteId1;
gSprites[spriteId2].oam.paletteNum = paletteId2;
@ -829,7 +829,7 @@ static void AnimTask_FlashHealthboxOnLevelUp_Step(u8 taskId)
if (gTasks[taskId].data[0]++ >= gTasks[taskId].data[11])
{
gTasks[taskId].data[0] = 0;
paletteNum = IndexOfSpritePaletteTag(0xD709);
paletteNum = IndexOfSpritePaletteTag(TAG_HEALTHBOX_PALS_1);
colorOffset = gTasks[taskId].data[10] == 0 ? 6 : 2;
switch (gTasks[taskId].data[1])
{

View File

@ -97,7 +97,7 @@ void AnimTask_BlendBattleAnimPalExclude(u8 taskId)
for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++)
{
if (battler != animBattlers[0] && battler != animBattlers[1] && IsBattlerSpriteVisible(battler))
selectedPalettes |= 0x10000 << AnimDummyReturnArg(battler);
selectedPalettes |= 0x10000 << GetSpritePalIdxByBattler(battler);
}
StartBlendAnimSpriteColor(taskId, selectedPalettes);
@ -536,9 +536,9 @@ static void StatsChangeAnimation_Step2(u8 taskId)
gTasks[taskId].func = StatsChangeAnimation_Step3;
if (sAnimStatsChangeData->data[0] == 0)
PlaySE12WithPanning(SE_M_STAT_INCREASE, BattleAnimAdjustPanning2(-64));
PlaySE12WithPanning(SE_M_STAT_INCREASE, BattleAnimAdjustPanning2(SOUND_PAN_ATTACKER));
else
PlaySE12WithPanning(SE_M_STAT_DECREASE, BattleAnimAdjustPanning2(-64));
PlaySE12WithPanning(SE_M_STAT_DECREASE, BattleAnimAdjustPanning2(SOUND_PAN_ATTACKER));
}
static void StatsChangeAnimation_Step3(u8 taskId)

View File

@ -392,7 +392,7 @@ static void CompleteOnHealthbarDone(void)
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
{

View File

@ -278,7 +278,7 @@ static void CompleteOnHealthbarDone(void)
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
{

View File

@ -410,7 +410,7 @@ static void CompleteOnHealthbarDone(void)
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
OpponentBufferExecCompleted();

View File

@ -1346,7 +1346,7 @@ static void CompleteOnHealthbarDone(void)
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
{
@ -2952,7 +2952,7 @@ static void PlayerHandleHealthBarUpdate(void)
u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP);
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], 0, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP);
}
gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone;

View File

@ -292,7 +292,7 @@ static void CompleteOnHealthbarDone(void)
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
{

View File

@ -376,7 +376,7 @@ static void CompleteOnHealthbarDone(void)
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
{

View File

@ -351,7 +351,7 @@ static void CompleteOnHealthbarDone(void)
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
{
@ -1481,7 +1481,7 @@ static void RecordedPlayerHandleHealthBarUpdate(void)
u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP);
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], 0, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP);
}
gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone;

View File

@ -352,7 +352,7 @@ static void CompleteOnHealthbarDone(void)
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP);
}
else
{
@ -1277,7 +1277,7 @@ static void WallyHandleHealthBarUpdate(void)
u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP);
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], 0, HP_CURRENT);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP);
}
gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone;

View File

@ -2747,7 +2747,7 @@ static int GetTypeEffectivenessPoints(int move, int targetSpecies, int mode)
int i = 0;
int typePower = TYPE_x1;
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || gBattleMoves[move].power == 0)
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || IS_MOVE_STATUS(move))
return 0;
defType1 = gBaseStats[targetSpecies].type1;

View File

@ -282,7 +282,7 @@ static u8 GetBattlePalaceMoveGroup(u8 battlerId, u16 move)
case MOVE_TARGET_RANDOM:
case MOVE_TARGET_BOTH:
case MOVE_TARGET_FOES_AND_ALLY:
if (gBattleMoves[move].power == 0)
if (IS_MOVE_STATUS(move))
return PALACE_MOVE_GROUP_SUPPORT;
else
return PALACE_MOVE_GROUP_ATTACK;
@ -578,13 +578,13 @@ static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 op
position = GetBattlerPosition(battlerId);
if (opponent)
{
HandleLoadSpecialPokePic(&gMonFrontPicTable[species],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[position],
species, currentPersonality);
}
else
{
HandleLoadSpecialPokePic(&gMonBackPicTable[species],
HandleLoadSpecialPokePic(FALSE,
gMonSpritesGfxPtr->sprites.ptr[position],
species, currentPersonality);
}
@ -715,7 +715,12 @@ bool8 BattleLoadAllHealthBoxesGfx(u8 state)
else
{
if (state == 2)
{
if (WhichBattleCoords(0))
LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[0]);
else
LoadCompressedSpriteSheet(&sSpriteSheet_SinglesPlayerHealthbox);
}
else if (state == 3)
LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[1]);
else if (state == 4)
@ -860,7 +865,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 castform, bo
personalityValue = gContestResources->moveAnim->personality;
otId = gContestResources->moveAnim->otId;
HandleLoadSpecialPokePic(&gMonBackPicTable[targetSpecies],
HandleLoadSpecialPokePic(FALSE,
gMonSpritesGfxPtr->sprites.ptr[position],
targetSpecies,
gContestResources->moveAnim->targetPersonality);
@ -879,7 +884,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 castform, bo
personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
HandleLoadSpecialPokePic(&gMonBackPicTable[targetSpecies],
HandleLoadSpecialPokePic(FALSE,
gMonSpritesGfxPtr->sprites.ptr[position],
targetSpecies,
gTransformedPersonalities[battlerAtk]);
@ -889,7 +894,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 castform, bo
personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
HandleLoadSpecialPokePic(&gMonFrontPicTable[targetSpecies],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[position],
targetSpecies,
gTransformedPersonalities[battlerAtk]);

View File

@ -161,7 +161,7 @@ static const u8 *GetHealthboxElementGfxPtr(u8);
static u8 *AddTextPrinterAndCreateWindowOnHealthbox(const u8 *, u32, u32, u32, u32 *);
static void RemoveWindowOnHealthbox(u32 windowId);
static void UpdateHpTextInHealthboxInDoubles(u8, s16, u8);
static void UpdateHpTextInHealthboxInDoubles(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp);
static void UpdateStatusIconInHealthbox(u8);
static void TextIntoHealthboxObject(void *, u8 *, s32);
@ -764,6 +764,15 @@ static void InitLastUsedBallAssets(void)
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
}
// This function is here to cover a specific case - one player's mon in a 2 vs 1 double battle. In this scenario - display singles layout.
u32 WhichBattleCoords(u32 battlerId) // 0 - singles, 1 - doubles
{
if (GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT && gPlayerPartyCount == 1)
return 0;
else
return IsDoubleBattle();
}
u8 CreateBattlerHealthboxSprites(u8 battlerId)
{
s16 data6 = 0;
@ -771,7 +780,7 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId)
u8 healthbarSpriteId, megaIndicatorSpriteId;
struct Sprite *healthBarSpritePtr;
if (!IsDoubleBattle())
if (WhichBattleCoords(battlerId) == 0) // Singles
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
{
@ -1035,7 +1044,7 @@ void GetBattlerHealthboxCoords(u8 battler, s16 *x, s16 *y)
{
*x = 0, *y = 0;
if (!IsDoubleBattle())
if (!WhichBattleCoords(battler))
{
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
*x = 44, *y = 30;
@ -1102,7 +1111,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
{
objVram = (void *)(OBJ_VRAM0);
if (!IsDoubleBattle())
if (!WhichBattleCoords(battler))
objVram += spriteTileNum + 0x820;
else
objVram += spriteTileNum + 0x420;
@ -1116,69 +1125,94 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
RemoveWindowOnHealthbox(windowId);
}
void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
static void PrintHpOnHealthbox(u32 spriteId, s16 currHp, s16 maxHp, u32 bgColor, u32 rightTile, u32 leftTile)
{
u32 windowId, spriteTileNum;
u8 *windowTileData;
u8 text[32];
void *objVram;
u32 windowId, tilesCount, x, healthboxTileNum;
u8 text[28], *txtPtr;
void *objVram = (void *)(OBJ_VRAM0) + gSprites[spriteId].oam.tileNum * TILE_SIZE_4BPP;
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER && !IsDoubleBattle())
{
spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP;
if (maxOrCurrent != HP_CURRENT) // singles, max
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, 2, &windowId);
objVram = (void *)(OBJ_VRAM0);
objVram += spriteTileNum + 0xB40;
HpTextIntoHealthboxObject(objVram, windowTileData, 2);
// To fit 4 digit HP values we need to modify a bit the way hp is printed on Healthbox.
// 6 chars can fit on the right healthbox, the rest goes to the left one
txtPtr = ConvertIntToDecimalStringN(text, currHp, STR_CONV_MODE_RIGHT_ALIGN, 4);
*txtPtr++ = CHAR_SLASH;
txtPtr = ConvertIntToDecimalStringN(txtPtr, maxHp, STR_CONV_MODE_LEFT_ALIGN, 4);
// Print last 6 chars on the right window
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(txtPtr - 6, 0, 5, bgColor, &windowId);
HpTextIntoHealthboxObject(objVram + rightTile, windowTileData, 4);
RemoveWindowOnHealthbox(windowId);
}
else // singles, current
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
text[3] = CHAR_SLASH;
text[4] = EOS;
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 4, 5, 2, &windowId);
objVram = (void *)(OBJ_VRAM0);
objVram += spriteTileNum + 0x3E0;
HpTextIntoHealthboxObject(objVram, windowTileData, 1);
objVram = (void *)(OBJ_VRAM0);
objVram += spriteTileNum + 0xB00;
HpTextIntoHealthboxObject(objVram, windowTileData + 0x20, 2);
// Print the rest of the chars on the left window
txtPtr[-6] = EOS;
// if max hp is 3 digits print on block closer to the right window, if 4 digits print further from the right window
if (maxHp >= 1000)
x = 9, tilesCount = 3;
else
x = 6, tilesCount = 2, leftTile += 0x20;
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, x, 5, bgColor, &windowId);
HpTextIntoHealthboxObject(objVram + leftTile, windowTileData, tilesCount);
RemoveWindowOnHealthbox(windowId);
}
}
// Note: this is only possible to trigger via debug, it was an unused GF function.
static void UpdateOpponentHpTextDoubles(u32 healthboxSpriteId, u32 barSpriteId, s16 value, u8 maxOrCurrent)
{
u8 text[32], *txtPtr;
u32 i, var;
u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible
{
memcpy(text, sEmptyWhiteText_TransparentHighlight, sizeof(sEmptyWhiteText_TransparentHighlight));
if (maxOrCurrent == HP_CURRENT)
var = 0;
else
var = 4;
txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
if (!maxOrCurrent)
StringCopy(txtPtr, gText_Slash);
RenderTextHandleBold(gMonSpritesGfxPtr->barFontGfx, FONT_BOLD, text);
for (i = var; i < var + 3; i++)
{
if (i < 3)
{
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
(void *)((OBJ_VRAM0) + 32 * (1 + gSprites[barSpriteId].oam.tileNum + i)),
0x20);
}
else
{
u8 battler;
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
(void *)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[barSpriteId].oam.tileNum)),
0x20);
}
}
if (maxOrCurrent == HP_CURRENT)
{
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224],
(void *)((OBJ_VRAM0) + ((gSprites[barSpriteId].oam.tileNum + 4) * TILE_SIZE_4BPP)),
0x20);
CpuFill32(0, (void *)((OBJ_VRAM0) + (gSprites[barSpriteId].oam.tileNum * TILE_SIZE_4BPP)), 0x20);
}
}
}
// Same with this one.
static void UpdateOpponentHpTextSingles(u32 healthboxSpriteId, s16 value, u32 maxOrCurrent)
{
u8 text[32];
u32 var, i;
u32 battler = gSprites[healthboxSpriteId].hMain_Battler;
memcpy(text, sEmptyWhiteText_GrayHighlight, sizeof(sEmptyWhiteText_GrayHighlight));
battler = gSprites[healthboxSpriteId].hMain_Battler;
if (IsDoubleBattle() == TRUE)
{
UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, value, maxOrCurrent);
}
else if (gBattleSpritesDataPtr->battlerData[battler].hpNumbersNoBars) // don't print text if only bars are visible
{
u32 var;
u8 i;
if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER)
{
if (maxOrCurrent == HP_CURRENT)
var = 29;
else
var = 89;
}
else
if (gBattleSpritesDataPtr->battlerData[battler].hpNumbersNoBars) // don't print text if only bars are visible
{
if (maxOrCurrent == HP_CURRENT)
var = 21;
else
var = 49;
}
ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_LEADING_ZEROS, 3);
RenderTextHandleBold(gMonSpritesGfxPtr->barFontGfx, FONT_BOLD, text);
@ -1190,101 +1224,50 @@ void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
0x20);
}
}
}
void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp)
{
u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
if (WhichBattleCoords(battlerId))
{
UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, maxOrCurrent, currHp, maxHp);
}
else // Single Battle
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Player
{
PrintHpOnHealthbox(healthboxSpriteId, currHp, maxHp, 2, 0xB00, 0x3A0);
}
else // Opponent
{
UpdateOpponentHpTextSingles(healthboxSpriteId, currHp, HP_CURRENT);
UpdateOpponentHpTextSingles(healthboxSpriteId, maxHp, HP_MAX);
}
}
}
static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
static void UpdateHpTextInHealthboxInDoubles(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp)
{
u32 windowId, spriteTileNum;
u8 *windowTileData;
u8 text[32];
void *objVram;
u32 barSpriteId = gSprites[healthboxSpriteId].data[5];
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
{
if (gBattleSpritesDataPtr->battlerData[gSprites[healthboxSpriteId].data[6]].hpNumbersNoBars) // don't print text if only bars are visible
{
spriteTileNum = gSprites[gSprites[healthboxSpriteId].data[5]].oam.tileNum * TILE_SIZE_4BPP;
objVram = (void *)(OBJ_VRAM0) + spriteTileNum;
if (maxOrCurrent != HP_CURRENT) // doubles, max hp
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, 0, &windowId);
HpTextIntoHealthboxObject((void *)(OBJ_VRAM0) + spriteTileNum + 0xC0, windowTileData, 2);
RemoveWindowOnHealthbox(windowId);
PrintHpOnHealthbox(barSpriteId, currHp, maxHp, 0, 0x80, 0x20);
// Clears the end of the healthbar gfx.
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_FRAME_END),
(void *)(OBJ_VRAM0 + 0x680) + (gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP),
0x20);
// Erases HP bar leftover.
FillHealthboxObject((void *)(OBJ_VRAM0) + (gSprites[barSpriteId].oam.tileNum * TILE_SIZE_4BPP), 0, 2);
}
else
}
else // Opponent
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
text[3] = CHAR_SLASH;
text[4] = EOS;
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 4, 5, 0, &windowId);
FillHealthboxObject(objVram, 0, 3); // Erases HP bar leftover.
HpTextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x60) + spriteTileNum, windowTileData, 3);
RemoveWindowOnHealthbox(windowId);
}
}
}
else
{
u8 battlerId;
memcpy(text, sEmptyWhiteText_TransparentHighlight, sizeof(sEmptyWhiteText_TransparentHighlight));
battlerId = gSprites[healthboxSpriteId].hMain_Battler;
if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible
{
u8 var = 4;
u8 r7;
u8 *txtPtr;
u8 i;
if (maxOrCurrent == HP_CURRENT)
var = 0;
r7 = gSprites[healthboxSpriteId].data[5];
txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
if (!maxOrCurrent)
StringCopy(txtPtr, gText_Slash);
RenderTextHandleBold(gMonSpritesGfxPtr->barFontGfx, FONT_BOLD, text);
for (i = var; i < var + 3; i++)
{
if (i < 3)
{
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
(void *)((OBJ_VRAM0) + 32 * (1 + gSprites[r7].oam.tileNum + i)),
0x20);
}
else
{
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
(void *)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[r7].oam.tileNum)),
0x20);
}
}
if (maxOrCurrent == HP_CURRENT)
{
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224],
(void *)((OBJ_VRAM0) + ((gSprites[r7].oam.tileNum + 4) * TILE_SIZE_4BPP)),
0x20);
CpuFill32(0, (void *)((OBJ_VRAM0) + (gSprites[r7].oam.tileNum * TILE_SIZE_4BPP)), 0x20);
}
else
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Impossible to reach part, because the battlerId is from the opponent's side.
{
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_FRAME_END),
(void *)(OBJ_VRAM0) + ((gSprites[healthboxSpriteId].oam.tileNum + 52) * TILE_SIZE_4BPP),
0x20);
}
}
}
UpdateOpponentHpTextDoubles(healthboxSpriteId, barSpriteId, maxHp, HP_MAX);
UpdateOpponentHpTextDoubles(healthboxSpriteId, barSpriteId, currHp, HP_CURRENT);
}
}
@ -1355,22 +1338,23 @@ static void PrintSafariMonInfo(u8 healthboxSpriteId, struct Pokemon *mon)
void SwapHpBarsWithHpText(void)
{
s32 i;
u8 healthBarSpriteId;
u32 healthBarSpriteId, i;
for (i = 0; i < gBattlersCount; i++)
{
if (gSprites[gHealthboxSpriteIds[i]].callback == SpriteCallbackDummy
&& GetBattlerSide(i) != B_SIDE_OPPONENT
&& (IsDoubleBattle() || GetBattlerSide(i) != B_SIDE_PLAYER))
&& (WhichBattleCoords(i) || GetBattlerSide(i) != B_SIDE_PLAYER))
{
s32 currHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP);
s32 maxHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP);
bool8 noBars;
gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars ^= 1;
noBars = gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars;
if (GetBattlerSide(i) == B_SIDE_PLAYER)
{
if (!IsDoubleBattle())
if (!WhichBattleCoords(i))
continue;
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
continue;
@ -1380,8 +1364,7 @@ void SwapHpBarsWithHpText(void)
healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId;
CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 0x100);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], HP_BOTH, currHp, maxHp);
}
else // text to bars
{
@ -1404,8 +1387,7 @@ void SwapHpBarsWithHpText(void)
healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId;
CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 0x100);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], HP_BOTH, currHp, maxHp);
}
}
else // text to bars
@ -1666,7 +1648,7 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo,
{
isOpponent = TRUE;
if (!skipPlayer || !IsDoubleBattle())
if (!skipPlayer || !WhichBattleCoords(battlerId))
bar_X = 104, bar_Y = 40;
else
bar_X = 104, bar_Y = 16;
@ -2152,7 +2134,7 @@ static void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon)
{
TextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x40 + spriteTileNum), windowTileData, 6);
ptr = (void *)(OBJ_VRAM0);
if (!IsDoubleBattle())
if (!WhichBattleCoords(gSprites[healthboxSpriteId].data[6]))
ptr += spriteTileNum + 0x800;
else
ptr += spriteTileNum + 0x400;
@ -2203,7 +2185,7 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
{
status = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS);
if (!IsDoubleBattle())
if (!WhichBattleCoords(battlerId))
tileNumAdder = 0x1A;
else
tileNumAdder = 0x12;
@ -2259,7 +2241,7 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
FillPalette(sStatusIconColors[statusPalId], pltAdder + 0x100, 2);
CpuCopy16(gPlttBufferUnfaded + 0x100 + pltAdder, (void *)(OBJ_PLTT + pltAdder * 2), 2);
CpuCopy32(statusGfxPtr, (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * TILE_SIZE_4BPP), 96);
if (IsDoubleBattle() == TRUE || GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
if (WhichBattleCoords(battlerId) == 1 || GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
{
if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
{
@ -2361,28 +2343,31 @@ static void UpdateLeftNoOfBallsTextOnHealthbox(u8 healthboxSpriteId)
void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId)
{
s32 maxHp, currHp;
u8 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
s32 maxHp = GetMonData(mon, MON_DATA_MAX_HP);
s32 currHp = GetMonData(mon, MON_DATA_HP);
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
{
u8 isDoubles;
u8 isDoubles = WhichBattleCoords(battlerId);
if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL)
UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));
if (elementId == HEALTHBOX_CURRENT_HP || elementId == HEALTHBOX_ALL)
UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_HP), HP_CURRENT);
if (elementId == HEALTHBOX_MAX_HP || elementId == HEALTHBOX_ALL)
UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_MAX_HP), HP_MAX);
if (elementId == HEALTHBOX_ALL)
UpdateHpTextInHealthbox(healthboxSpriteId, HP_BOTH, currHp, maxHp);
else if (elementId == HEALTHBOX_MAX_HP)
UpdateHpTextInHealthbox(healthboxSpriteId, HP_MAX, currHp, maxHp);
else if (elementId == HEALTHBOX_CURRENT_HP)
UpdateHpTextInHealthbox(healthboxSpriteId, HP_CURRENT, currHp, maxHp);
if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL)
{
LoadBattleBarGfx(0);
maxHp = GetMonData(mon, MON_DATA_MAX_HP);
currHp = GetMonData(mon, MON_DATA_HP);
SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0);
MoveBattleBar(battlerId, healthboxSpriteId, HEALTH_BAR, 0);
}
isDoubles = IsDoubleBattle();
if (!isDoubles && (elementId == HEALTHBOX_EXP_BAR || elementId == HEALTHBOX_ALL))
{
u16 species;
@ -2413,15 +2398,18 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem
{
if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL)
UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));
if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars && (elementId == HEALTHBOX_CURRENT_HP || elementId == HEALTHBOX_ALL))
UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_HP), HP_CURRENT);
if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars && (elementId == HEALTHBOX_MAX_HP || elementId == HEALTHBOX_ALL))
UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_MAX_HP), HP_MAX);
if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
{
if (elementId == HEALTHBOX_ALL)
UpdateHpTextInHealthbox(healthboxSpriteId, HP_BOTH, currHp, maxHp);
else if (elementId == HEALTHBOX_MAX_HP)
UpdateHpTextInHealthbox(healthboxSpriteId, HP_MAX, currHp, maxHp);
else if (elementId == HEALTHBOX_CURRENT_HP)
UpdateHpTextInHealthbox(healthboxSpriteId, HP_CURRENT, currHp, maxHp);
}
if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL)
{
LoadBattleBarGfx(0);
maxHp = GetMonData(mon, MON_DATA_MAX_HP);
currHp = GetMonData(mon, MON_DATA_HP);
SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0);
MoveBattleBar(battlerId, healthboxSpriteId, HEALTH_BAR, 0);
}
@ -2908,7 +2896,7 @@ static void TextIntoAbilityPopUp(void *dest, u8 *windowTileData, s32 arg2, bool3
#define MAX_CHARS_PRINTED 12
static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTileData2, u32 x1, u32 x2, u32 y, u32 color1, u32 color2, u32 color3)
static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTileData2, u32 x1, u32 x2, u32 y, u32 color1, u32 color2, u32 color3, bool32 alignAbilityChars)
{
u32 windowId, i;
u8 *windowTileData;
@ -2923,6 +2911,15 @@ static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTi
}
text1[i] = EOS;
// Because there are two Windows, we need to align the strings, so that the first char in the second window starts right after the last char in the first window.
// Windows are 64 pixels in width.
if (alignAbilityChars && i == MAX_CHARS_PRINTED)
{
u32 width = GetStringWidth(FONT_SMALL, text1, 0);
if (x1 + width < 64)
x1 += 64 - (x1 + width);
}
windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text1, x1, y, color1, color2, color3, &windowId);
TextIntoAbilityPopUp(spriteTileData1, windowTileData, 8, (y == 0));
RemoveWindow(windowId);
@ -2951,7 +2948,8 @@ static void ClearAbilityName(u8 spriteId1, u8 spriteId2)
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256,
6, 1,
4,
7, 9, 1);
7, 9, 1,
FALSE);
}
static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2)
@ -2988,7 +2986,8 @@ static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2)
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32),
7, 0,
0,
2, 7, 1);
2, 7, 1,
FALSE);
}
static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2)
@ -2996,9 +2995,10 @@ static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2)
PrintOnAbilityPopUp(gAbilityNames[ability],
(void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32) + 256,
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256,
6, 1,
6, 0,
4,
7, 9, 1);
7, 9, 1,
TRUE);
}
#define PIXEL_COORDS_TO_OFFSET(x, y)( \

View File

@ -3342,7 +3342,7 @@ static void DoBattleIntro(void)
MarkBattlerForControllerExec(gActiveBattler);
}
}
else // wild mon 2
else if (IsBattlerAlive(gActiveBattler)) // wild mon 2 if alive
{
BtlController_EmitLoadMonSprite(BUFFER_A);
MarkBattlerForControllerExec(gActiveBattler);

View File

@ -753,10 +753,22 @@ static const u8 sText_TargetTooHeavy[] = _("But the target\nwas too heavy!");
static const u8 sText_MeteorBeamCharging[] = _("{B_ATK_NAME_WITH_PREFIX} is overflowing\nwith space energy!");
static const u8 sText_HeatingUpBeak[] = _("{B_ATK_NAME_WITH_PREFIX} started\nheating up its beak!");
static const u8 sText_CourtChange[] = _("{B_ATK_NAME_WITH_PREFIX} swapped the battle\neffects affecting each side!");
static const u8 sText_AttackerExpelledThePoison[] = _("{B_ATK_NAME_WITH_PREFIX} managed to\nexpel the poison!");
static const u8 sText_AttackerShookItselfAwake[] = _("{B_ATK_NAME_WITH_PREFIX} shook itself awake!");
static const u8 sText_AttackerBrokeThroughParalysis[] = _("{B_ATK_NAME_WITH_PREFIX} gathered all its energy\nto overcome its paralysis!");
static const u8 sText_AttackerHealedItsBurn[] = _("{B_ATK_NAME_WITH_PREFIX} healed its burn with\nits sheer determination!");
static const u8 sText_AttackerMeltedTheIce[] = _("{B_ATK_NAME_WITH_PREFIX} melted the ice with\nits fiery determination!");
static const u8 sText_TargetToughedItOut[] = _("{B_DEF_NAME_WITH_PREFIX} toughed it out\nto show you its best side!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_TARGETTOUGHEDITOUT - BATTLESTRINGS_TABLE_START] = sText_TargetToughedItOut,
[STRINGID_ATTACKERMELTEDTHEICE - BATTLESTRINGS_TABLE_START] = sText_AttackerMeltedTheIce,
[STRINGID_ATTACKERHEALEDITSBURN - BATTLESTRINGS_TABLE_START] = sText_AttackerHealedItsBurn,
[STRINGID_ATTACKERBROKETHROUGHPARALYSIS - BATTLESTRINGS_TABLE_START] = sText_AttackerBrokeThroughParalysis,
[STRINGID_ATTACKERSHOOKITSELFAWAKE - BATTLESTRINGS_TABLE_START] = sText_AttackerShookItselfAwake,
[STRINGID_ATTACKEREXPELLEDTHEPOISON - BATTLESTRINGS_TABLE_START] = sText_AttackerExpelledThePoison,
[STRINGID_ZPOWERSURROUNDS - BATTLESTRINGS_TABLE_START] = sText_ZPowerSurrounds,
[STRINGID_ZMOVEUNLEASHED - BATTLESTRINGS_TABLE_START] = sText_ZPowerUnleashed,
[STRINGID_ZMOVERESETSSTATS - BATTLESTRINGS_TABLE_START] = sText_ZMoveResetsStats,

View File

@ -59,6 +59,7 @@
#include "constants/songs.h"
#include "constants/trainers.h"
#include "battle_util.h"
#include "constants/pokemon.h"
extern struct Evolution gEvolutionTable[][EVOS_PER_MON];
@ -1345,7 +1346,7 @@ static bool32 TryAegiFormChange(void)
default:
return FALSE;
case SPECIES_AEGISLASH: // Shield -> Blade
if (gBattleMoves[gCurrentMove].power == 0)
if (IS_MOVE_STATUS(gCurrentMove))
return FALSE;
gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_BLADE;
break;
@ -1687,7 +1688,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
&& (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
moveAcc = 50;
// Check Wonder Skin.
if (defAbility == ABILITY_WONDER_SKIN && gBattleMoves[move].power == 0)
if (defAbility == ABILITY_WONDER_SKIN && IS_MOVE_STATUS(move) && moveAcc > 50)
moveAcc = 50;
calc = gAccuracyStageRatios[buff].dividend * moveAcc;
@ -1730,6 +1731,13 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
calc = (calc * 5) / 3; // 1.66 Gravity acc boost
#if B_AFFECTION_MECHANICS == TRUE
// With high affection/friendship there's a chance to evade a move by substracting 10% of its accuracy.
// I can't find exact information about that chance, so I'm just gonna write it as a 20% chance for now.
if (GetMonFriendshipScore(&gPlayerParty[gBattlerPartyIndexes[battlerDef]]) >= FRIENDSHIP_150_TO_199 && (Random() % 100) <= 20)
calc = (calc * 90) / 100;
#endif
return calc;
}
@ -1898,6 +1906,9 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi
+ (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS)
+ 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY)
+ 2 * BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk)
#if B_AFFECTION_MECHANICS == TRUE
+ 2 * (GetMonFriendshipScore(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]]) >= FRIENDSHIP_200_TO_254)
#endif
+ (abilityAtk == ABILITY_SUPER_LUCK);
if (critChance >= ARRAY_COUNT(sCriticalHitChance))
@ -1966,6 +1977,8 @@ static void Cmd_adjustdamage(void)
{
u8 holdEffect, param;
u32 moveType;
u32 friendshipScore = GetMonFriendshipScore(&gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]]);
u32 rand = Random() % 100;
GET_MOVE_TYPE(gCurrentMove, moveType);
@ -1981,7 +1994,7 @@ static void Cmd_adjustdamage(void)
gPotentialItemEffectBattler = gBattlerTarget;
if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param)
if (holdEffect == HOLD_EFFECT_FOCUS_BAND && rand < param)
{
RecordItemEffectBattle(gBattlerTarget, holdEffect);
gSpecialStatuses[gBattlerTarget].focusBanded = TRUE;
@ -1998,11 +2011,24 @@ static void Cmd_adjustdamage(void)
RecordItemEffectBattle(gBattlerTarget, holdEffect);
gSpecialStatuses[gBattlerTarget].focusSashed = TRUE;
}
#if B_AFFECTION_MECHANICS == TRUE
else if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER && friendshipScore >= FRIENDSHIP_100_TO_149)
{
if ((friendshipScore == FRIENDSHIP_MAX && rand < 25)
|| (friendshipScore == FRIENDSHIP_200_TO_254 && rand < 20)
|| (friendshipScore == FRIENDSHIP_150_TO_199 && rand < 15)
|| (friendshipScore == FRIENDSHIP_100_TO_149 && rand < 10))
gSpecialStatuses[gBattlerTarget].affectionEndured = TRUE;
}
#endif
if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE
&& !gProtectStructs[gBattlerTarget].endured
&& !gSpecialStatuses[gBattlerTarget].focusBanded
&& !gSpecialStatuses[gBattlerTarget].focusSashed
#if B_AFFECTION_MECHANICS == TRUE
&& !gSpecialStatuses[gBattlerTarget].affectionEndured
#endif
&& !gSpecialStatuses[gBattlerTarget].sturdied)
goto END;
@ -2023,6 +2049,12 @@ static void Cmd_adjustdamage(void)
gMoveResultFlags |= MOVE_RESULT_STURDIED;
gLastUsedAbility = ABILITY_STURDY;
}
#if B_AFFECTION_MECHANICS == TRUE
else if (gSpecialStatuses[gBattlerTarget].affectionEndured)
{
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED_AFFECTION;
}
#endif
END:
gBattlescriptCurrInstr++;
@ -2478,6 +2510,16 @@ static void Cmd_resultmessage(void)
{
stringId = STRINGID_BUTITFAILED;
}
#if B_AFFECTION_MECHANICS == TRUE
else if (gMoveResultFlags & MOVE_RESULT_FOE_ENDURED_AFFECTION)
{
gSpecialStatuses[gBattlerTarget].affectionEndured = FALSE;
gMoveResultFlags &= ~MOVE_RESULT_FOE_ENDURED_AFFECTION;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AffectionBasedEndurance;
return;
}
#endif
else
{
gBattleCommunication[MSG_DISPLAY] = 0;
@ -4020,6 +4062,10 @@ static void Cmd_getexp(void)
gBattleMoveDamage = value + 1;
}
#endif
#if B_AFFECTION_MECHANICS == TRUE
if (GetMonFriendshipScore(&gPlayerParty[gBattleStruct->expGetterMonId]) >= FRIENDSHIP_50_TO_99)
gBattleMoveDamage = (gBattleMoveDamage * 120) / 100;
#endif
if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterMonId]))
{
@ -8395,7 +8441,7 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else if (gBattleMoves[gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]].power == 0)
else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
@ -8493,7 +8539,7 @@ static void Cmd_various(void)
case VARIOUS_TRY_ME_FIRST:
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else if (gBattleMoves[gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]].power == 0)
else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
{
@ -10571,19 +10617,20 @@ static void Cmd_setmultihitcounter(void)
}
else if (B_MULTI_HIT_CHANCE >= GEN_5)
{
// 2 and 3 hits: 33.3%
// 4 and 5 hits: 16.7%
gMultiHitCounter = Random() % 4;
if (gMultiHitCounter > 2)
{
gMultiHitCounter = (Random() % 3);
if (gMultiHitCounter < 2)
// Based on Gen 5's odds
// 35% for 2 hits
// 35% for 3 hits
// 15% for 4 hits
// 15% for 5 hits
gMultiHitCounter = Random() % 100;
if (gMultiHitCounter < 35)
gMultiHitCounter = 2;
else
else if (gMultiHitCounter < 35 + 35)
gMultiHitCounter = 3;
}
else if (gMultiHitCounter < 35 + 35 + 15)
gMultiHitCounter = 4;
else
gMultiHitCounter += 3;
gMultiHitCounter = 5;
}
else
{
@ -11008,6 +11055,13 @@ static void Cmd_tryKO(void)
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
gLastUsedItem = gBattleMons[gBattlerTarget].item;
}
#if B_AFFECTION_MECHANICS == TRUE
else if (gSpecialStatuses[gBattlerTarget].affectionEndured)
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED_AFFECTION;
}
#endif
else
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp;
@ -13451,11 +13505,11 @@ bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
{
if (GetBattlerAbility(battlerDef) != ABILITY_DISGUISE
|| gBattleMons[battlerDef].species != SPECIES_MIMIKYU
if (gBattleMons[battlerDef].species != SPECIES_MIMIKYU
|| gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED
|| gBattleMoves[move].power == 0
|| gHitMarker & HITMARKER_IGNORE_DISGUISE)
|| IS_MOVE_STATUS(move)
|| gHitMarker & HITMARKER_IGNORE_DISGUISE
|| GetBattlerAbility(battlerDef) != ABILITY_DISGUISE)
return FALSE;
else
return TRUE;
@ -13674,7 +13728,7 @@ static void Cmd_handleballthrow(void)
case ITEM_NET_BALL:
if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG))
#if B_NET_BALL_MODIFIER >= GEN_7
ballMultiplier = 50;
ballMultiplier = 35;
#else
ballMultiplier = 30;
#endif
@ -13870,13 +13924,13 @@ static void Cmd_handleballthrow(void)
u8 shakes;
u8 maxShakes;
gBattleSpritesDataPtr->animationData->isCriticalCapture = 0;
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 0;
gBattleSpritesDataPtr->animationData->isCriticalCapture = FALSE;
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = FALSE;
if (CriticalCapture(odds))
{
maxShakes = BALL_1_SHAKE; // critical capture doesn't guarantee capture
gBattleSpritesDataPtr->animationData->isCriticalCapture = 1;
gBattleSpritesDataPtr->animationData->isCriticalCapture = TRUE;
}
else
{
@ -13900,7 +13954,7 @@ static void Cmd_handleballthrow(void)
if (shakes == maxShakes) // mon caught, copy of the code above
{
if (IsCriticalCapture())
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 1;
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = TRUE;
UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget), FALSE);
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;

View File

@ -1435,7 +1435,7 @@ static void TrySetBattleSeminarShow(void)
return;
else if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID))
return;
else if (gBattleMoves[gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]].power == 0)
else if (IS_MOVE_STATUS(gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]))
return;
i = 0;
@ -1496,7 +1496,7 @@ static void TrySetBattleSeminarShow(void)
static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride)
{
if (gBattleMoves[moveId].power == 0)
if (IS_MOVE_STATUS(moveId))
{
*dmg = 0;
return FALSE;

View File

@ -45,6 +45,7 @@
#include "constants/species.h"
#include "constants/trainers.h"
#include "constants/weather.h"
#include "constants/pokemon.h"
extern struct Evolution gEvolutionTable[][EVOS_PER_MON];
@ -1764,7 +1765,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
}
}
if (!gBattleStruct->zmove.active && gDisableStructs[gActiveBattler].tauntTimer != 0 && gBattleMoves[move].power == 0)
if (!gBattleStruct->zmove.active && gDisableStructs[gActiveBattler].tauntTimer != 0 && IS_MOVE_STATUS(move))
{
gCurrentMove = move;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
@ -1859,7 +1860,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
gCurrentMove = move;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedBelchInPalace;
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedStuffCheeksInPalace;
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
}
else
@ -1876,6 +1877,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
gLastUsedItem = gBattleMons[gActiveBattler].item;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveChoiceItemInPalace;
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
}
else
@ -1884,12 +1886,13 @@ u8 TrySetCantSelectMoveBattleScript(void)
limitations++;
}
}
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0 && move != MOVE_ME_FIRST)
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && move != MOVE_ME_FIRST)
{
gCurrentMove = move;
gLastUsedItem = gBattleMons[gActiveBattler].item;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveAssaultVestInPalace;
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
}
else
@ -1905,6 +1908,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
gLastUsedItem = gBattleMons[gActiveBattler].item;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace;
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
}
else
@ -1927,10 +1931,24 @@ u8 TrySetCantSelectMoveBattleScript(void)
}
}
if (gBattleMoves[move].effect == EFFECT_PLACEHOLDER)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedPlaceholderInPalace;
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
}
else
{
gSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedPlaceholder;
limitations++;
}
}
return limitations;
}
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u16 check)
{
u8 holdEffect = GetBattlerHoldEffect(battlerId, TRUE);
u16 *choicedMove = &gBattleStruct->choicedMove[battlerId];
@ -1941,49 +1959,52 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
for (i = 0; i < MAX_MON_MOVES; i++)
{
// No move
if (gBattleMons[battlerId].moves[i] == MOVE_NONE && check & MOVE_LIMITATION_ZEROMOVE)
if (check & MOVE_LIMITATION_ZEROMOVE && gBattleMons[battlerId].moves[i] == MOVE_NONE)
unusableMoves |= gBitTable[i];
// No PP
else if (gBattleMons[battlerId].pp[i] == 0 && check & MOVE_LIMITATION_PP)
else if (check & MOVE_LIMITATION_PP && gBattleMons[battlerId].pp[i] == 0)
unusableMoves |= gBitTable[i];
// Placeholder
else if (check & MOVE_LIMITATION_PLACEHOLDER && gBattleMoves[gBattleMons[battlerId].moves[i]].effect == EFFECT_PLACEHOLDER)
unusableMoves |= gBitTable[i];
// Disable
else if (gBattleMons[battlerId].moves[i] == gDisableStructs[battlerId].disabledMove && check & MOVE_LIMITATION_DISABLED)
else if (check & MOVE_LIMITATION_DISABLED && gBattleMons[battlerId].moves[i] == gDisableStructs[battlerId].disabledMove)
unusableMoves |= gBitTable[i];
// Torment
else if (gBattleMons[battlerId].moves[i] == gLastMoves[battlerId] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[battlerId].status2 & STATUS2_TORMENT)
else if (check & MOVE_LIMITATION_TORMENTED && gBattleMons[battlerId].moves[i] == gLastMoves[battlerId] && gBattleMons[battlerId].status2 & STATUS2_TORMENT)
unusableMoves |= gBitTable[i];
// Taunt
else if (gDisableStructs[battlerId].tauntTimer && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0)
else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battlerId].tauntTimer && IS_MOVE_STATUS(gBattleMons[battlerId].moves[i]))
unusableMoves |= gBitTable[i];
// Imprison
else if (GetImprisonedMovesCount(battlerId, gBattleMons[battlerId].moves[i]) && check & MOVE_LIMITATION_IMPRISON)
else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battlerId, gBattleMons[battlerId].moves[i]))
unusableMoves |= gBitTable[i];
// Encore
else if (gDisableStructs[battlerId].encoreTimer && gDisableStructs[battlerId].encoredMove != gBattleMons[battlerId].moves[i])
else if (check & MOVE_LIMITATION_ENCORE && gDisableStructs[battlerId].encoreTimer && gDisableStructs[battlerId].encoredMove != gBattleMons[battlerId].moves[i])
unusableMoves |= gBitTable[i];
// Choice Items
else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
else if (check & MOVE_LIMITATION_CHOICE_ITEM && HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
unusableMoves |= gBitTable[i];
// Assault Vest
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST)
else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(gBattleMons[battlerId].moves[i]) && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST)
unusableMoves |= gBitTable[i];
// Gravity
else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i]))
else if (check & MOVE_LIMITATION_GRAVITY && IsGravityPreventingMove(gBattleMons[battlerId].moves[i]))
unusableMoves |= gBitTable[i];
// Heal Block
else if (IsHealBlockPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
else if (check & MOVE_LIMITATION_HEAL_BLOCK && IsHealBlockPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
unusableMoves |= gBitTable[i];
// Belch
else if (IsBelchPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
else if (check & MOVE_LIMITATION_BELCH && IsBelchPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
unusableMoves |= gBitTable[i];
// Throat Chop
else if (gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND)
else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND)
unusableMoves |= gBitTable[i];
// Stuff Cheeks
else if (gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
else if (check & MOVE_LIMITATION_STUFF_CHEEKS && gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
unusableMoves |= gBitTable[i];
// Gorilla Tactics
else if (GetBattlerAbility(battlerId) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battlerId) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
unusableMoves |= gBitTable[i];
}
return unusableMoves;
@ -2083,6 +2104,26 @@ void TryToRevertMimicry(void)
}
}
u32 GetMonFriendshipScore(struct Pokemon *pokemon)
{
u32 friendshipScore = GetMonData(pokemon, MON_DATA_FRIENDSHIP);
if (friendshipScore == MAX_FRIENDSHIP)
return FRIENDSHIP_MAX;
if (friendshipScore >= 200)
return FRIENDSHIP_200_TO_254;
if (friendshipScore >= 150)
return FRIENDSHIP_150_TO_199;
if (friendshipScore >= 100)
return FRIENDSHIP_100_TO_149;
if (friendshipScore >= 50)
return FRIENDSHIP_50_TO_99;
if (friendshipScore >= 1)
return FRIENDSHIP_1_TO_49;
return FRIENDSHIP_NONE;
}
enum
{
ENDTURN_ORDER,
@ -2111,6 +2152,7 @@ enum
ENDTURN_ION_DELUGE,
ENDTURN_FAIRY_LOCK,
ENDTURN_RETALIATE,
ENDTURN_STATUS_HEAL,
ENDTURN_FIELD_COUNT,
};
@ -2341,6 +2383,7 @@ u8 DoFieldEndTurnEffects(void)
if (effect == 0)
{
gBattleStruct->turnCountersTracker++;
gBattleStruct->turnSideTracker = 0;
}
break;
case ENDTURN_RAIN:
@ -2557,6 +2600,22 @@ u8 DoFieldEndTurnEffects(void)
gSideTimers[B_SIDE_OPPONENT].retaliateTimer--;
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_STATUS_HEAL:
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
{
#if B_AFFECTION_MECHANICS == TRUE
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER
&& GetMonFriendshipScore(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]]) >= FRIENDSHIP_150_TO_199
&& (Random() % 100 < 20))
{
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
BattleScriptExecute(BattleScript_AffectionBasedStatusHeal);
break;
}
#endif
}
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_FIELD_COUNT:
effect++;
break;
@ -3545,7 +3604,7 @@ u8 AtkCanceller_UnableToUseMove(void)
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_TAUNTED: // taunt
if (gDisableStructs[gBattlerAttacker].tauntTimer && gBattleMoves[gCurrentMove].power == 0)
if (gDisableStructs[gBattlerAttacker].tauntTimer && IS_MOVE_STATUS(gCurrentMove))
{
gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE;
CancelMultiTurnMoves(gBattlerAttacker);
@ -8076,7 +8135,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
basePower = 10 * (gBattleMons[battlerAtk].friendship) / 25;
break;
case EFFECT_FRUSTRATION:
basePower = 10 * (255 - gBattleMons[battlerAtk].friendship) / 25;
basePower = 10 * (MAX_FRIENDSHIP - gBattleMons[battlerAtk].friendship) / 25;
break;
case EFFECT_FURY_CUTTER:
for (i = 1; i < gDisableStructs[battlerAtk].furyCutterCounter; i++)
@ -8476,15 +8535,15 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
MulModifier(&modifier, holdEffectModifier);
break;
case HOLD_EFFECT_LUSTROUS_ORB:
if (gBattleMons[battlerAtk].species == SPECIES_PALKIA && (moveType == TYPE_WATER || moveType == TYPE_DRAGON))
if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_PALKIA && (moveType == TYPE_WATER || moveType == TYPE_DRAGON))
MulModifier(&modifier, holdEffectModifier);
break;
case HOLD_EFFECT_ADAMANT_ORB:
if (gBattleMons[battlerAtk].species == SPECIES_DIALGA && (moveType == TYPE_STEEL || moveType == TYPE_DRAGON))
if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_DIALGA && (moveType == TYPE_STEEL || moveType == TYPE_DRAGON))
MulModifier(&modifier, holdEffectModifier);
break;
case HOLD_EFFECT_GRISEOUS_ORB:
if (gBattleMons[battlerAtk].species == SPECIES_GIRATINA && (moveType == TYPE_GHOST || moveType == TYPE_DRAGON))
if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_GIRATINA && (moveType == TYPE_GHOST || moveType == TYPE_DRAGON))
MulModifier(&modifier, holdEffectModifier);
break;
case HOLD_EFFECT_SOUL_DEW:

View File

@ -3121,7 +3121,7 @@ static u8 CreateContestantSprite(u16 species, u32 otId, u32 personality, u32 ind
u8 spriteId;
species = SanitizeSpecies(species);
HandleLoadSpecialPokePic(&gMonBackPicTable[species], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], species, personality);
HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], species, personality);
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x120, 0x20);
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_PLAYER_LEFT);

View File

@ -367,8 +367,7 @@ static void InitContestMonPixels(u16 species, bool8 backPic)
LZDecompressVram(pal, gContestPaintingMonPalette);
if (!backPic)
{
HandleLoadSpecialPokePic(
&gMonFrontPicTable[species],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
species,
gContestPaintingWinner->personality);
@ -376,8 +375,7 @@ static void InitContestMonPixels(u16 species, bool8 backPic)
}
else
{
HandleLoadSpecialPokePic(
&gMonBackPicTable[species],
HandleLoadSpecialPokePic(FALSE,
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT],
species,
gContestPaintingWinner->personality);

View File

@ -892,8 +892,7 @@ static void Task_ShowWinnerMonBanner(u8 taskId)
species = gContestMons[i].species;
personality = gContestMons[i].personality;
otId = gContestMons[i].otId;
HandleLoadSpecialPokePic(
&gMonFrontPicTable[species],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
species,
personality);
@ -2572,7 +2571,7 @@ void ShowContestEntryMonPic(void)
taskId = CreateTask(Task_ShowContestEntryMonPic, 0x50);
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = species;
HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
palette = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
LoadCompressedSpritePalette(palette);

View File

@ -1371,10 +1371,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy XS"),
.itemId = ITEM_EXP_CANDY_XS,
.price = 20,
.holdEffectParam = EXP_100,
.description = sExpCandyXSDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},
@ -1383,10 +1384,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy S"),
.itemId = ITEM_EXP_CANDY_S,
.price = 240,
.holdEffectParam = EXP_800,
.description = sExpCandyXSDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},
@ -1395,10 +1397,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy M"),
.itemId = ITEM_EXP_CANDY_M,
.price = 1000,
.holdEffectParam = EXP_3000,
.description = sExpCandyMDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},
@ -1407,10 +1410,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy L"),
.itemId = ITEM_EXP_CANDY_L,
.price = 3000,
.holdEffectParam = EXP_10000,
.description = sExpCandyLDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},
@ -1419,10 +1423,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy XL"),
.itemId = ITEM_EXP_CANDY_XL,
.price = 10000,
.holdEffectParam = EXP_30000,
.description = sExpCandyXLDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},

View File

@ -510,11 +510,11 @@ const u8 *const gItemEffectTable[] =
// Candy
[ITEM_RARE_CANDY - ITEM_POTION] = gItemEffect_RareCandy,
//[ITEM_EXP_CANDY_XS - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_S - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_M - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_L - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_XL - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
[ITEM_EXP_CANDY_XS - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_S - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_M - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_L - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_XL - ITEM_POTION] = gItemEffect_RareCandy,
//[ITEM_DYNAMAX_CANDY - ITEM_POTION] = gItemEffect_DynamaxCandy, // Todo
// Medicinal Flutes

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2978,8 +2978,9 @@ static const u8 sEerieSpellDescription[] = _(
"Attacks with psychic power.\n"
"Foe's last move has 3 PP cut.");
static const u8 sNotDoneYetDescription[] = _(
"Not done yet.");
const u8 gNotDoneYetDescription[] = _(
"This move can't be used. Its\n"
"effect is in development.");
// MOVE_NONE is ignored in this table. Make sure to always subtract 1 before getting the right pointer.
const u8 *const gMoveDescriptionPointers[MOVES_COUNT - 1] =

View File

@ -695,7 +695,8 @@ static void BuildEggMoveset(struct Pokemon *egg, struct BoxPokemon *father, stru
{
for (j = 0; j < NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES; j++)
{
if (sHatchedEggFatherMoves[i] == ItemIdToBattleMoveId(ITEM_TM01_FOCUS_PUNCH + j) && CanMonLearnTMHM(egg, j))
u16 moveId = ItemIdToBattleMoveId(ITEM_TM01 + j);
if (sHatchedEggFatherMoves[i] == moveId && CanLearnTeachableMove(GetMonData(egg, MON_DATA_SPECIES2), moveId))
{
if (GiveMoveToMon(egg, sHatchedEggFatherMoves[i]) == MON_HAS_MAX_MOVES)
DeleteFirstMoveAndGiveMoveToMon(egg, sHatchedEggFatherMoves[i]);

View File

@ -70,25 +70,18 @@ void DecompressPicFromTable(const struct CompressedSpriteSheet *src, void *buffe
void DecompressPicFromTableGender(void* buffer, s32 species, u32 personality)
{
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
if (ShouldShowFemaleDifferences(species, personality))
DecompressPicFromTable(&gMonFrontPicTableFemale[species], buffer, species);
else
DecompressPicFromTable(&gMonFrontPicTable[species], buffer, species);
}
void HandleLoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality)
void HandleLoadSpecialPokePic(bool32 isFrontPic, void *dest, s32 species, u32 personality)
{
bool8 isFrontPic;
if (src == &gMonFrontPicTable[species])
isFrontPic = TRUE; // frontPic
else
isFrontPic = FALSE; // backPic
LoadSpecialPokePic(src, dest, species, personality, isFrontPic);
LoadSpecialPokePic(dest, species, personality, isFrontPic);
}
void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFrontPic)
void LoadSpecialPokePic(void *dest, s32 species, u32 personality, bool8 isFrontPic)
{
if (species == SPECIES_UNOWN)
{
@ -100,8 +93,13 @@ void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32
LZ77UnCompWram(gMonFrontPicTable[id].data, dest);
}
else if (species > NUM_SPECIES) // is species unknown? draw the ? icon
{
if (isFrontPic)
LZ77UnCompWram(gMonFrontPicTable[0].data, dest);
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
else
LZ77UnCompWram(gMonBackPicTable[0].data, dest);
}
else if (ShouldShowFemaleDifferences(species, personality))
{
if (isFrontPic)
LZ77UnCompWram(gMonFrontPicTableFemale[species].data, dest);
@ -109,49 +107,15 @@ void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32
LZ77UnCompWram(gMonBackPicTableFemale[species].data, dest);
}
else
LZ77UnCompWram(src->data, dest);
DrawSpindaSpots(species, personality, dest, isFrontPic);
}
#if P_ENABLE_DEBUG == TRUE
static void LoadSpecialPokePicCustom(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFrontPic, bool8 isFemale)
{
if (species == SPECIES_UNOWN)
{
u32 id = GetUnownSpeciesId(personality);
if (!isFrontPic)
LZ77UnCompWram(gMonBackPicTable[id].data, dest);
else
LZ77UnCompWram(gMonFrontPicTable[id].data, dest);
}
else if (species > NUM_SPECIES) // is species unknown? draw the ? icon
LZ77UnCompWram(gMonFrontPicTable[0].data, dest);
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && isFemale)
{
if (isFrontPic)
LZ77UnCompWram(gMonFrontPicTableFemale[species].data, dest);
LZ77UnCompWram(gMonFrontPicTable[species].data, dest);
else
LZ77UnCompWram(gMonBackPicTableFemale[species].data, dest);
LZ77UnCompWram(gMonBackPicTable[species].data, dest);
}
else
LZ77UnCompWram(src->data, dest);
DrawSpindaSpots(species, personality, dest, isFrontPic);
}
void HandleLoadSpecialPokePicCustom(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFemale)
{
bool8 isFrontPic;
if (src == &gMonFrontPicTable[species])
isFrontPic = TRUE; // frontPic
else
isFrontPic = FALSE; // backPic
LoadSpecialPokePicCustom(src, dest, species, personality, isFrontPic, isFemale);
}
#endif
void Unused_LZDecompressWramIndirect(const void **src, void *dest)
{

View File

@ -444,7 +444,7 @@ static u8 EggHatchCreateMonSprite(u8 useAlt, u8 state, u8 partyId, u16 *speciesL
{
u16 species = GetMonData(mon, MON_DATA_SPECIES);
u32 pid = GetMonData(mon, MON_DATA_PERSONALITY);
HandleLoadSpecialPokePic(&gMonFrontPicTable[species],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[(useAlt * 2) + B_POSITION_OPPONENT_LEFT],
species, pid);
LoadCompressedSpritePalette(GetMonSpritePalStruct(mon));

View File

@ -65,6 +65,7 @@
#include "constants/weather.h"
#include "constants/metatile_labels.h"
#include "palette.h"
#include "battle_util.h"
EWRAM_DATA bool8 gBikeCyclingChallenge = FALSE;
EWRAM_DATA u8 gBikeCollisions = 0;
@ -868,7 +869,7 @@ static void PetalburgGymSetDoorMetatiles(u8 roomNumber, u16 metatileId)
for (i = 0; i < nDoors; i++)
{
MapGridSetMetatileIdAt(doorCoordsX[i] + MAP_OFFSET, doorCoordsY[i] + MAP_OFFSET, metatileId | MAPGRID_COLLISION_MASK);
MapGridSetMetatileIdAt(doorCoordsX[i] + MAP_OFFSET, doorCoordsY[i] + MAP_OFFSET + 1, (metatileId + 8) | MAPGRID_COLLISION_MASK);
MapGridSetMetatileIdAt(doorCoordsX[i] + MAP_OFFSET, doorCoordsY[i] + MAP_OFFSET + 1, (metatileId + METATILE_ROW_WIDTH) | MAPGRID_COLLISION_MASK);
}
DrawWholeMapView();
}
@ -939,21 +940,7 @@ u16 GetWeekCount(void)
u8 GetLeadMonFriendshipScore(void)
{
struct Pokemon *pokemon = &gPlayerParty[GetLeadMonIndex()];
if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) == MAX_FRIENDSHIP)
return 6;
if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 200)
return 5;
if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 150)
return 4;
if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 100)
return 3;
if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 50)
return 2;
if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 1)
return 1;
return 0;
return GetMonFriendshipScore(&gPlayerParty[GetLeadMonIndex()]);
}
static void CB2_FieldShowRegionMap(void)
@ -2986,40 +2973,9 @@ static void HideFrontierExchangeCornerItemIcon(u16 menu, u16 unused)
}
}
static const u16 sBattleFrontier_TutorMoves1[] =
{
MOVE_SOFT_BOILED,
MOVE_SEISMIC_TOSS,
MOVE_DREAM_EATER,
MOVE_MEGA_PUNCH,
MOVE_MEGA_KICK,
MOVE_BODY_SLAM,
MOVE_ROCK_SLIDE,
MOVE_COUNTER,
MOVE_THUNDER_WAVE,
MOVE_SWORDS_DANCE
};
static const u16 sBattleFrontier_TutorMoves2[] =
{
MOVE_DEFENSE_CURL,
MOVE_SNORE,
MOVE_MUD_SLAP,
MOVE_SWIFT,
MOVE_ICY_WIND,
MOVE_ENDURE,
MOVE_PSYCH_UP,
MOVE_ICE_PUNCH,
MOVE_THUNDER_PUNCH,
MOVE_FIRE_PUNCH
};
void BufferBattleFrontierTutorMoveName(void)
{
if (gSpecialVar_0x8005 != 0)
StringCopy(gStringVar1, gMoveNames[sBattleFrontier_TutorMoves2[gSpecialVar_0x8004]]);
else
StringCopy(gStringVar1, gMoveNames[sBattleFrontier_TutorMoves1[gSpecialVar_0x8004]]);
StringCopy(gStringVar1, gMoveNames[gSpecialVar_0x8005]);
}
static void ShowBattleFrontierTutorWindow(u8 menu, u16 selection)
@ -3115,44 +3071,6 @@ void ScrollableMultichoice_RedrawPersistentMenu(void)
}
}
void GetBattleFrontierTutorMoveIndex(void)
{
u8 i;
u16 moveTutor = 0;
u16 moveIndex = 0;
gSpecialVar_0x8005 = 0;
moveTutor = VarGet(VAR_TEMP_E);
moveIndex = VarGet(VAR_TEMP_D);
if (moveTutor != 0)
{
i = 0;
do
{
if (gTutorMoves[i] == sBattleFrontier_TutorMoves2[moveIndex])
{
gSpecialVar_0x8005 = i;
break;
}
i++;
} while (i < TUTOR_MOVE_COUNT);
}
else
{
i = 0;
do
{
if (gTutorMoves[i] == sBattleFrontier_TutorMoves1[moveIndex])
{
gSpecialVar_0x8005 = i;
break;
}
i++;
} while (i < TUTOR_MOVE_COUNT);
}
}
// Never called
// Close a scrollable multichoice that stays open after selection
void ScrollableMultichoice_ClosePersistentMenu(void)

View File

@ -2033,12 +2033,3 @@ const u16 gFrontierPassCancelButtonHighlighted_Tilemap[] = INCBIN_U16("graphics/
const u16 gBerryCrush_Crusher_Pal[] = INCBIN_U16("graphics/berry_crush/crusher.gbapal");
const u32 gBerryCrush_Crusher_Gfx[] = INCBIN_U32("graphics/berry_crush/crusher.4bpp.lz");
const u32 gBerryCrush_TextWindows_Tilemap[] = INCBIN_U32("graphics/berry_crush/text_windows.bin.lz");
// random garbage at the end.
static const u8 sEmpty3[0x54BAC] = {0};
static const u8 sUnused1[] = {0x0D, 0x00, 0x58, 0x02};
static const u8 sEmpty4[0x1145] = {0};
static const u8 sUnused2[] = {0x02};
static const u8 sEmpty5[0x3242] = {0};
static const u8 sUnused3[] = {0x40};
static const u8 sEmpty6[0x13] = {0};

View File

@ -922,6 +922,9 @@ static void ItemUseOnFieldCB_EscapeRope(u8 taskId)
Overworld_ResetStateAfterDigEscRope();
#if I_KEY_ESCAPE_ROPE < GEN_8
RemoveUsedItem();
#else
CopyItemName(gSpecialVar_ItemId, gStringVar2);
StringExpandPlaceholders(gStringVar4, gText_PlayerUsedVar2);
#endif
gTasks[taskId].data[0] = 0;
DisplayItemMessageOnField(taskId, gStringVar4, Task_UseDigEscapeRopeOnField);

View File

@ -24,6 +24,7 @@
#include "trig.h"
#include "window.h"
#include "constants/songs.h"
#include "constants/battle_move_effects.h"
#include "gba/io_reg.h"
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
@ -807,7 +808,11 @@ static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove)
}
AddTextPrinterParameterized(0, FONT_NORMAL, str, 0x6A, 0x29, TEXT_SKIP_DRAW, NULL);
if (move->effect != EFFECT_PLACEHOLDER)
str = gMoveDescriptionPointers[chosenMove - 1];
else
str = gNotDoneYetDescription;
AddTextPrinterParameterized(0, FONT_NARROW, str, 0, 0x41, 0, NULL);
}
@ -1075,7 +1080,7 @@ void GetConditionMenuMonGfx(void *tilesDst, void *palDst, u16 boxId, u16 monId,
u32 trainerId = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
u32 personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
LoadSpecialPokePic(&gMonFrontPicTable[species], tilesDst, species, personality, TRUE);
LoadSpecialPokePic(tilesDst, species, personality, TRUE);
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), palDst);
}
}

View File

@ -2525,8 +2525,7 @@ static u16 KeyInterCB_Idle(u32 key)
return LINK_KEY_CODE_EMPTY;
}
// Ignore the player's inputs as long as there is an event script
// in ScriptContext2.
// Ignore the player's inputs as long as there is an event script being executed.
static u16 KeyInterCB_DeferToEventScript(u32 key)
{
u16 retVal;

View File

@ -225,6 +225,8 @@ EWRAM_DATA u8 gSelectedOrderFromParty[MAX_FRONTIER_PARTY_SIZE] = {0};
static EWRAM_DATA u16 sPartyMenuItemId = 0;
static EWRAM_DATA u16 sUnused = 0;
EWRAM_DATA u8 gBattlePartyCurrentOrder[PARTY_SIZE / 2] = {0}; // bits 0-3 are the current pos of Slot 1, 4-7 are Slot 2, and so on
static EWRAM_DATA u8 sInitialLevel = 0;
static EWRAM_DATA u8 sFinalLevel = 0;
// IWRAM common
void (*gItemUseCB)(u8, TaskFunc);
@ -265,12 +267,12 @@ static void DisplayPartyPokemonMaxHPCheck(struct Pokemon *, struct PartyMenuBox
static void DisplayPartyPokemonHPBarCheck(struct Pokemon *, struct PartyMenuBox *);
static void DisplayPartyPokemonDescriptionText(u8, struct PartyMenuBox *, u8);
static bool8 IsMonAllowedInMinigame(u8);
static void DisplayPartyPokemonDataToTeachMove(u8, u16, u8);
static u8 CanMonLearnTMTutor(struct Pokemon *, u16, u8);
static void DisplayPartyPokemonDataToTeachMove(u8, u16);
static u8 CanTeachMove(struct Pokemon *, u16);
static void DisplayPartyPokemonBarDetail(u8, const u8 *, u8, const u8 *);
static void DisplayPartyPokemonLevel(u8, struct PartyMenuBox *);
static void DisplayPartyPokemonGender(u8, u16, u8 *, struct PartyMenuBox *);
static void DisplayPartyPokemonHP(u16, struct PartyMenuBox *);
static void DisplayPartyPokemonHP(u16 hp, u16 maxHp, struct PartyMenuBox *menuBox);
static void DisplayPartyPokemonMaxHP(u16, struct PartyMenuBox *);
static void DisplayPartyPokemonHPBar(u16, u16, struct PartyMenuBox *);
static void CreatePartyMonIconSpriteParameterized(u16, u32, struct PartyMenuBox *, u8);
@ -326,8 +328,6 @@ static bool16 IsMonAllowedInPokemonJump(struct Pokemon *);
static bool16 IsMonAllowedInDodrioBerryPicking(struct Pokemon *);
static void Task_CancelParticipationYesNo(u8);
static void Task_HandleCancelParticipationYesNoInput(u8);
static bool8 CanLearnTutorMove(u16, u8);
static u16 GetTutorMove(u8);
static bool8 ShouldUseChooseMonText(void);
static void SetPartyMonFieldSelectionActions(struct Pokemon *, u8);
static u8 GetPartyMenuActionsTypeInBattle(struct Pokemon *);
@ -479,7 +479,6 @@ static bool8 SetUpFieldMove_Dive(void);
void TryItemHoldFormChange(struct Pokemon *mon);
// static const data
#include "data/pokemon/tutor_learnsets.h"
#include "data/party_menu.h"
// code
@ -973,7 +972,7 @@ static bool8 DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(u8 slot)
if (gPartyMenu.action == PARTY_ACTION_MOVE_TUTOR)
{
gSpecialVar_Result = FALSE;
DisplayPartyPokemonDataToTeachMove(slot, 0, gSpecialVar_0x8005);
DisplayPartyPokemonDataToTeachMove(slot, gSpecialVar_0x8005);
}
else
{
@ -985,7 +984,7 @@ static bool8 DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(u8 slot)
default:
return FALSE;
case 1: // TM/HM
DisplayPartyPokemonDataToTeachMove(slot, item, 0);
DisplayPartyPokemonDataToTeachMove(slot, ItemIdToBattleMoveId(item));
break;
case 2: // Evolution stone
if (!GetMonData(currentPokemon, MON_DATA_IS_EGG) && GetEvolutionTargetSpecies(currentPokemon, EVO_MODE_ITEM_CHECK, item, NULL) != SPECIES_NONE)
@ -997,9 +996,9 @@ static bool8 DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(u8 slot)
return TRUE;
}
static void DisplayPartyPokemonDataToTeachMove(u8 slot, u16 item, u8 tutor)
static void DisplayPartyPokemonDataToTeachMove(u8 slot, u16 move)
{
switch (CanMonLearnTMTutor(&gPlayerParty[slot], item, tutor))
switch (CanTeachMove(&gPlayerParty[slot], move))
{
case CANNOT_LEARN_MOVE:
case CANNOT_LEARN_MOVE_IS_EGG:
@ -1032,7 +1031,7 @@ static void DisplayPartyPokemonDataForMultiBattle(u8 slot)
DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, menuBox->infoRects->dimensions);
DisplayPartyPokemonLevel(gMultiPartnerParty[actualSlot].level, menuBox);
DisplayPartyPokemonGender(gMultiPartnerParty[actualSlot].gender, gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].nickname, menuBox);
DisplayPartyPokemonHP(gMultiPartnerParty[actualSlot].hp, menuBox);
DisplayPartyPokemonHP(gMultiPartnerParty[actualSlot].hp, gMultiPartnerParty[actualSlot].maxhp, menuBox);
DisplayPartyPokemonMaxHP(gMultiPartnerParty[actualSlot].maxhp, menuBox);
DisplayPartyPokemonHPBar(gMultiPartnerParty[actualSlot].hp, gMultiPartnerParty[actualSlot].maxhp, menuBox);
}
@ -2029,47 +2028,18 @@ static void Task_HandleCancelParticipationYesNoInput(u8 taskId)
}
}
static u8 CanMonLearnTMTutor(struct Pokemon *mon, u16 item, u8 tutor)
static u8 CanTeachMove(struct Pokemon *mon, u16 move)
{
u16 move;
if (GetMonData(mon, MON_DATA_IS_EGG))
return CANNOT_LEARN_MOVE_IS_EGG;
if (item >= ITEM_TM01)
{
if (!CanMonLearnTMHM(mon, item - ITEM_TM01 - ((item > ITEM_TM100) ? 50 : 0)))
else if (!CanLearnTeachableMove(GetMonData(mon, MON_DATA_SPECIES2), move))
return CANNOT_LEARN_MOVE;
else
move = ItemIdToBattleMoveId(item);
}
else
{
if (!CanLearnTutorMove(GetMonData(mon, MON_DATA_SPECIES), tutor))
return CANNOT_LEARN_MOVE;
else
move = GetTutorMove(tutor);
}
if (MonKnowsMove(mon, move) == TRUE)
else if (MonKnowsMove(mon, move) == TRUE)
return ALREADY_KNOWS_MOVE;
else
return CAN_LEARN_MOVE;
}
static u16 GetTutorMove(u8 tutor)
{
return gTutorMoves[tutor];
}
static bool8 CanLearnTutorMove(u16 species, u8 tutor)
{
if (sTutorLearnsets[species] & (1 << tutor))
return TRUE;
else
return FALSE;
}
static void InitPartyMenuWindows(u8 layout)
{
u8 i;
@ -2359,17 +2329,30 @@ static void DisplayPartyPokemonHPCheck(struct Pokemon *mon, struct PartyMenuBox
if (c != 0)
menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->dimensions[12] >> 3, (menuBox->infoRects->dimensions[13] >> 3) + 1, menuBox->infoRects->dimensions[14] >> 3, menuBox->infoRects->dimensions[15] >> 3, FALSE);
if (c != 2)
DisplayPartyPokemonHP(GetMonData(mon, MON_DATA_HP), menuBox);
DisplayPartyPokemonHP(GetMonData(mon, MON_DATA_HP), GetMonData(mon, MON_DATA_MAX_HP), menuBox);
}
}
static void DisplayPartyPokemonHP(u16 hp, struct PartyMenuBox *menuBox)
static void DisplayParty4DigitsHP(struct PartyMenuBox *menuBox, const u8 *str, const u8 *origAlings, u32 toSub)
{
u8 *strOut = ConvertIntToDecimalStringN(gStringVar1, hp, STR_CONV_MODE_RIGHT_ALIGN, 3);
u8 newAligns[4];
memcpy(newAligns, origAlings, sizeof(newAligns));
newAligns[0] -= toSub; // x, so that the hp fits
DisplayPartyPokemonBarDetail(menuBox->windowId, str, 0, newAligns);
}
static void DisplayPartyPokemonHP(u16 hp, u16 maxhp, struct PartyMenuBox *menuBox)
{
bool32 fourDigits = (maxhp >= 1000);
u8 *strOut = ConvertIntToDecimalStringN(gStringVar1, hp, STR_CONV_MODE_RIGHT_ALIGN, fourDigits ? 4 : 3);
strOut[0] = CHAR_SLASH;
strOut[1] = EOS;
if (fourDigits)
DisplayParty4DigitsHP(menuBox, gStringVar1, &menuBox->infoRects->dimensions[12], 10);
else
DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[12]);
}
@ -2386,9 +2369,15 @@ static void DisplayPartyPokemonMaxHPCheck(struct Pokemon *mon, struct PartyMenuB
static void DisplayPartyPokemonMaxHP(u16 maxhp, struct PartyMenuBox *menuBox)
{
ConvertIntToDecimalStringN(gStringVar2, maxhp, STR_CONV_MODE_RIGHT_ALIGN, 3);
bool32 fourDigits = (maxhp >= 1000);
ConvertIntToDecimalStringN(gStringVar2, maxhp, STR_CONV_MODE_RIGHT_ALIGN, fourDigits ? 4 : 3);
StringCopy(gStringVar1, gText_Slash);
StringAppend(gStringVar1, gStringVar2);
if (fourDigits)
DisplayParty4DigitsHP(menuBox, gStringVar1, &menuBox->infoRects->dimensions[16], 5);
else
DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[16]);
}
@ -4933,19 +4922,18 @@ static void DisplayLearnMoveMessageAndClose(u8 taskId, const u8 *str)
void ItemUseCB_TMHM(u8 taskId, TaskFunc task)
{
struct Pokemon *mon;
s16 *move;
u16 item;
u16 item = gSpecialVar_ItemId;
u16 move = ItemIdToBattleMoveId(item);
gPartyMenu.data1 = move;
PlaySE(SE_SELECT);
mon = &gPlayerParty[gPartyMenu.slotId];
move = &gPartyMenu.data1;
item = gSpecialVar_ItemId;
GetMonNickname(mon, gStringVar1);
move[0] = ItemIdToBattleMoveId(item);
StringCopy(gStringVar2, gMoveNames[move[0]]);
move[1] = 0;
switch (CanMonLearnTMTutor(mon, item, 0))
GetMonNickname(mon, gStringVar1);
StringCopy(gStringVar2, gMoveNames[move]);
switch (CanTeachMove(mon, move))
{
case CANNOT_LEARN_MOVE:
DisplayLearnMoveMessageAndClose(taskId, gText_PkmnCantLearnMove);
@ -4955,7 +4943,7 @@ void ItemUseCB_TMHM(u8 taskId, TaskFunc task)
return;
}
if (GiveMoveToMon(mon, move[0]) != MON_HAS_MAX_MOVES)
if (GiveMoveToMon(mon, move) != MON_HAS_MAX_MOVES)
{
gTasks[taskId].func = Task_LearnedMove;
}
@ -5052,6 +5040,7 @@ static void CB2_ShowSummaryScreenToForgetMove(void)
static void CB2_ReturnToPartyMenuWhileLearningMove(void)
{
SetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_LEVEL, &sFinalLevel); // to avoid displaying incorrect level
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, TRUE, PARTY_MSG_NONE, Task_ReturnToPartyMenuWhileLearningMove, gPartyMenu.exitCallback);
}
@ -5157,8 +5146,9 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
s16 *arrayPtr = ptr->data;
u16 *itemPtr = &gSpecialVar_ItemId;
bool8 cannotUseEffect;
sInitialLevel = GetMonData(mon, MON_DATA_LEVEL);
if (GetMonData(mon, MON_DATA_LEVEL) != MAX_LEVEL)
if (sInitialLevel != MAX_LEVEL)
{
BufferMonStatsToTaskData(mon, arrayPtr);
cannotUseEffect = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, *itemPtr, 0);
@ -5178,17 +5168,30 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
}
else
{
sFinalLevel = GetMonData(mon, MON_DATA_LEVEL, NULL);
gPartyMenuUseExitCallback = TRUE;
PlayFanfareByFanfareNum(FANFARE_LEVEL_UP);
UpdateMonDisplayInfoAfterRareCandy(gPartyMenu.slotId, mon);
RemoveBagItem(gSpecialVar_ItemId, 1);
GetMonNickname(mon, gStringVar1);
ConvertIntToDecimalStringN(gStringVar2, GetMonData(mon, MON_DATA_LEVEL), STR_CONV_MODE_LEFT_ALIGN, 3);
if (sFinalLevel > sInitialLevel)
{
PlayFanfareByFanfareNum(FANFARE_LEVEL_UP);
ConvertIntToDecimalStringN(gStringVar2, sFinalLevel, STR_CONV_MODE_LEFT_ALIGN, 3);
StringExpandPlaceholders(gStringVar4, gText_PkmnElevatedToLvVar2);
DisplayPartyMenuMessage(gStringVar4, TRUE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = Task_DisplayLevelUpStatsPg1;
}
else
{
PlaySE(SE_USE_ITEM);
gPartyMenuUseExitCallback = FALSE;
StringExpandPlaceholders(gStringVar4, gText_PkmnGainedExp);
DisplayPartyMenuMessage(gStringVar4, FALSE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = task;
}
}
}
static void UpdateMonDisplayInfoAfterRareCandy(u8 slot, struct Pokemon *mon)
@ -5220,6 +5223,7 @@ static void Task_DisplayLevelUpStatsPg2(u8 taskId)
{
PlaySE(SE_SELECT);
DisplayLevelUpStatsPg2(taskId);
sInitialLevel += 1; // so the Pokemon doesn't learn a move meant for its previous level
gTasks[taskId].func = Task_TryLearnNewMoves;
}
}
@ -5250,11 +5254,15 @@ static void Task_TryLearnNewMoves(u8 taskId)
if (WaitFanfare(FALSE) && ((JOY_NEW(A_BUTTON)) || (JOY_NEW(B_BUTTON))))
{
RemoveLevelUpStatsWindow();
for (; sInitialLevel <= sFinalLevel; sInitialLevel++)
{
SetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_LEVEL, &sInitialLevel);
learnMove = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], TRUE);
gPartyMenu.learnMoveState = 1;
switch (learnMove)
{
case 0: // No moves to learn
if (sInitialLevel >= sFinalLevel)
PartyMenuTryEvolution(taskId);
break;
case MON_HAS_MAX_MOVES:
@ -5267,17 +5275,22 @@ static void Task_TryLearnNewMoves(u8 taskId)
DisplayMonLearnedMove(taskId, learnMove);
break;
}
if (learnMove)
break;
}
}
}
static void Task_TryLearningNextMove(u8 taskId)
{
u16 result = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], FALSE);
u16 result;
for (; sInitialLevel <= sFinalLevel; sInitialLevel++)
{
SetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_LEVEL, &sInitialLevel);
result = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], FALSE);
switch (result)
{
case 0: // No moves to learn
PartyMenuTryEvolution(taskId);
break;
case MON_HAS_MAX_MOVES:
DisplayMonNeedsToReplaceMove(taskId);
@ -5288,6 +5301,11 @@ static void Task_TryLearningNextMove(u8 taskId)
DisplayMonLearnedMove(taskId, result);
break;
}
if (result)
break;
}
if (sInitialLevel >= sFinalLevel)
PartyMenuTryEvolution(taskId);
}
static void PartyMenuTryEvolution(u8 taskId)
@ -5676,10 +5694,10 @@ static void TryTutorSelectedMon(u8 taskId)
mon = &gPlayerParty[gPartyMenu.slotId];
move = &gPartyMenu.data1;
GetMonNickname(mon, gStringVar1);
gPartyMenu.data1 = GetTutorMove(gSpecialVar_0x8005);
gPartyMenu.data1 = gSpecialVar_0x8005;
StringCopy(gStringVar2, gMoveNames[gPartyMenu.data1]);
move[1] = 2;
switch (CanMonLearnTMTutor(mon, 0, gSpecialVar_0x8005))
switch (CanTeachMove(mon, gPartyMenu.data1))
{
case CANNOT_LEARN_MOVE:
DisplayLearnMoveMessageAndClose(taskId, gText_PkmnCantLearnMove);
@ -6115,7 +6133,7 @@ void ChooseMonForWirelessMinigame(void)
static u8 GetPartyLayoutFromBattleType(void)
{
if (IsDoubleBattle() == FALSE)
if (!IsDoubleBattle() || gPlayerPartyCount == 1) // Draw the single layout in a double battle where the player has only one pokemon.
return PARTY_LAYOUT_SINGLE;
if (IsMultiBattle() == TRUE)
return PARTY_LAYOUT_MULTI;

View File

@ -727,7 +727,7 @@ static bool8 LoadMonAndSceneGfx(struct Pokemon *mon)
// Load mon gfx
species = GetMonData(mon, MON_DATA_SPECIES2);
personality = GetMonData(mon, MON_DATA_PERSONALITY);
HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
sPokeblockFeed->loadGfxState++;
break;
case 1:

View File

@ -1918,17 +1918,18 @@ const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] =
[NATURE_QUIRKY] = { 0, 0, 0, 0, 0},
};
#include "data/pokemon/tmhm_learnsets.h"
#include "data/pokemon/trainer_class_lookups.h"
#include "data/pokemon/experience_tables.h"
#include "data/pokemon/base_stats.h"
#include "data/pokemon/level_up_learnsets.h"
#include "data/pokemon/teachable_learnsets.h"
#if P_NEW_POKEMON == TRUE
#include "data/pokemon/evolution.h"
#else
#include "data/pokemon/evolution_old.h"
#endif
#include "data/pokemon/level_up_learnset_pointers.h"
#include "data/pokemon/teachable_learnset_pointers.h"
#include "data/pokemon/form_species_tables.h"
#include "data/pokemon/form_species_table_pointers.h"
#include "data/pokemon/form_change_tables.h"
@ -5505,6 +5506,15 @@ bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex,
} \
}
// EXP candies store an index for this table in their holdEffectParam.
static const u32 sExpCandyExperienceTable[] = {
[EXP_100 - 1] = 100,
[EXP_800 - 1] = 800,
[EXP_3000 - 1] = 3000,
[EXP_10000 - 1] = 10000,
[EXP_30000 - 1] = 30000,
};
// Returns TRUE if the item has no effect on the Pokémon, FALSE otherwise
bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, bool8 usedByAI)
{
@ -5699,11 +5709,22 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
retVal = FALSE;
}
// Rare Candy
// Rare Candy / EXP Candy
if ((itemEffect[i] & ITEM3_LEVEL_UP)
&& GetMonData(mon, MON_DATA_LEVEL, NULL) != MAX_LEVEL)
{
u8 param = ItemId_GetHoldEffectParam(item);
if (param == 0) // Rare Candy
{
dataUnsigned = gExperienceTables[gBaseStats[GetMonData(mon, MON_DATA_SPECIES, NULL)].growthRate][GetMonData(mon, MON_DATA_LEVEL, NULL) + 1];
}
else if (param < ARRAY_COUNT(sExpCandyExperienceTable)) // EXP Candies
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
dataUnsigned = sExpCandyExperienceTable[param - 1] + GetMonData(mon, MON_DATA_EXP, NULL);
if (dataUnsigned > gExperienceTables[gBaseStats[species].growthRate][MAX_LEVEL])
dataUnsigned = gExperienceTables[gBaseStats[species].growthRate][MAX_LEVEL];
}
SetMonData(mon, MON_DATA_EXP, &dataUnsigned);
CalculateMonStats(mon);
retVal = FALSE;
@ -7278,40 +7299,22 @@ bool8 TryIncrementMonLevel(struct Pokemon *mon)
}
}
u32 CanMonLearnTMHM(struct Pokemon *mon, u8 tm)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
if (species == SPECIES_EGG)
{
return 0;
}
else if (tm < 32)
{
u32 mask = 1 << tm;
return gTMHMLearnsets[species][0] & mask;
}
else
{
u32 mask = 1 << (tm - 32);
return gTMHMLearnsets[species][1] & mask;
}
}
u32 CanSpeciesLearnTMHM(u16 species, u8 tm)
u8 CanLearnTeachableMove(u16 species, u16 move)
{
if (species == SPECIES_EGG)
{
return 0;
}
else if (tm < 32)
{
u32 mask = 1 << tm;
return gTMHMLearnsets[species][0] & mask;
return FALSE;
}
else
{
u32 mask = 1 << (tm - 32);
return gTMHMLearnsets[species][1] & mask;
u8 i;
for (i = 0; gTeachableLearnsets[species][i] != MOVE_UNAVAILABLE; i++)
{
if (gTeachableLearnsets[species][i] == move) {
return TRUE;
}
}
return FALSE;
}
}
@ -7555,14 +7558,14 @@ const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 p
shinyValue = GET_SHINY_VALUE(otId, personality);
if (shinyValue < SHINY_ODDS)
{
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
if (ShouldShowFemaleDifferences(species, personality))
return gMonShinyPaletteTableFemale[species].data;
else
return gMonShinyPaletteTable[species].data;
}
else
{
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
if (ShouldShowFemaleDifferences(species, personality))
return gMonPaletteTableFemale[species].data;
else
return gMonPaletteTable[species].data;
@ -7584,14 +7587,14 @@ const struct CompressedSpritePalette *GetMonSpritePalStructFromOtIdPersonality(u
shinyValue = GET_SHINY_VALUE(otId, personality);
if (shinyValue < SHINY_ODDS)
{
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
if (ShouldShowFemaleDifferences(species, personality))
return &gMonShinyPaletteTableFemale[species];
else
return &gMonShinyPaletteTable[species];
}
else
{
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
if (ShouldShowFemaleDifferences(species, personality))
return &gMonPaletteTableFemale[species];
else
return &gMonPaletteTable[species];
@ -8394,3 +8397,8 @@ void TrySpecialOverworldEvo(void)
sTriedEvolving = 0;
SetMainCallback2(CB2_ReturnToField);
}
bool32 ShouldShowFemaleDifferences(u16 species, u32 personality)
{
return (gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE;
}

View File

@ -1107,6 +1107,9 @@ static void ResetPokemonDebugWindows(void)
}
}
#define MALE_PERSONALITY 0xFE
#define FEMALE_PERSONALITY 0X0
void CB2_Debug_Pokemon(void)
{
u8 taskId;
@ -1180,7 +1183,7 @@ void CB2_Debug_Pokemon(void)
palette = GetMonSpritePalStructCustom(species, data->isFemale, data->isShiny);
LoadCompressedSpritePalette(palette);
//Front
HandleLoadSpecialPokePicCustom(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[1], species, 0, data->isFemale);
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[1], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
data->isShiny = FALSE;
data->isFemale = FALSE;
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 1);
@ -1195,7 +1198,7 @@ void CB2_Debug_Pokemon(void)
LoadAndCreateEnemyShadowSpriteCustom(data, species);
//Back
HandleLoadSpecialPokePicCustom(&gMonBackPicTable[species], gMonSpritesGfxPtr->sprites.ptr[2], species, 0, data->isFemale);
HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[2], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 4);
SetMultiuseSpriteTemplateToPokemon(species, 2);
offset_y = gMonBackPicCoords[species].y_offset;
@ -1205,7 +1208,7 @@ void CB2_Debug_Pokemon(void)
gSprites[data->backspriteId].oam.priority = 0;
//Icon Sprite
data->iconspriteId = CreateMonIconCustom(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, data->isShiny, data->isFemale, data->isShiny);
data->iconspriteId = CreateMonIcon(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
gSprites[data->iconspriteId].oam.priority = 0;
//Modify Arrows
@ -1692,7 +1695,7 @@ static void ReloadPokemonSprites(struct PokemonDebugMenu *data)
palette = GetMonSpritePalStructCustom(species, data->isFemale, data->isShiny);
LoadCompressedSpritePalette(palette);
//Front
HandleLoadSpecialPokePicCustom(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[1], species, 0, data->isFemale);
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[1], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 1);
SetMultiuseSpriteTemplateToPokemon(species, 1);
gMultiuseSpriteTemplate.paletteTag = palette->tag;
@ -1705,7 +1708,7 @@ static void ReloadPokemonSprites(struct PokemonDebugMenu *data)
LoadAndCreateEnemyShadowSpriteCustom(data, species);
//Back
HandleLoadSpecialPokePicCustom(&gMonBackPicTable[species], gMonSpritesGfxPtr->sprites.ptr[2], species, 0, data->isFemale);
HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[2], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 5);
SetMultiuseSpriteTemplateToPokemon(species, 2);
offset_y = gMonBackPicCoords[species].y_offset;
@ -1715,7 +1718,7 @@ static void ReloadPokemonSprites(struct PokemonDebugMenu *data)
gSprites[data->backspriteId].oam.priority = 0;
//Icon Sprite
data->iconspriteId = CreateMonIconCustom(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, data->isShiny, data->isFemale, data->isShiny);
data->iconspriteId = CreateMonIcon(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
gSprites[data->iconspriteId].oam.priority = 0;
//Modify Arrows

View File

@ -23,10 +23,6 @@ struct MonIconSpriteTemplate
static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *, s16, s16, u8);
static void FreeAndDestroyMonIconSprite_(struct Sprite *sprite);
#if P_ENABLE_DEBUG == TRUE
static const u8 *GetMonIconPtrCustom(u16 species, u32 personality, bool8 isFemale);
static const u8 *GetMonIconTilesCustom(u16 species, bool8 isFemale);
#endif
const u8 *const gMonIconTable[] =
{
@ -2652,7 +2648,7 @@ u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u
if (species > NUM_SPECIES)
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG;
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
else if (ShouldShowFemaleDifferences(species, personality))
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndicesFemale[species];
spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
@ -2662,32 +2658,6 @@ u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u
return spriteId;
}
#if P_ENABLE_DEBUG == TRUE
u8 CreateMonIconCustom(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool8 isFemale, bool8 isShiny)
{
u8 spriteId;
struct MonIconSpriteTemplate iconTemplate =
{
.oam = &sMonIconOamData,
.image = GetMonIconPtrCustom(species, personality, isFemale),
.anims = sMonIconAnims,
.affineAnims = sMonIconAffineAnims,
.callback = callback,
.paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species],
};
if (species > NUM_SPECIES)
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG;
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && isFemale)
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndicesFemale[species];
spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
UpdateMonIconFrame(&gSprites[spriteId]);
return spriteId;
}
#endif
u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority)
{
@ -2760,13 +2730,6 @@ const u8 *GetMonIconPtr(u16 species, u32 personality)
return GetMonIconTiles(GetIconSpecies(species, personality), personality);
}
#if P_ENABLE_DEBUG == TRUE
static const u8 *GetMonIconPtrCustom(u16 species, u32 personality, bool8 isFemale)
{
return GetMonIconTilesCustom(GetIconSpecies(species, personality), isFemale);
}
#endif
void FreeAndDestroyMonIconSprite(struct Sprite *sprite)
{
FreeAndDestroyMonIconSprite_(sprite);
@ -2828,24 +2791,15 @@ void SpriteCB_MonIcon(struct Sprite *sprite)
const u8 *GetMonIconTiles(u16 species, u32 personality)
{
const u8 *iconSprite = gMonIconTable[species];
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
{
const u8 *iconSprite;
if (ShouldShowFemaleDifferences(species, personality))
iconSprite = gMonIconTableFemale[species];
}
else
iconSprite = gMonIconTable[species];
return iconSprite;
}
#if P_ENABLE_DEBUG == TRUE
static const u8 *GetMonIconTilesCustom(u16 species, bool8 isFemale)
{
const u8 *iconSprite = gMonIconTable[species];
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && isFemale)
{
iconSprite = gMonIconTableFemale[species];
}
return iconSprite;
}
#endif
void TryLoadAllMonIconPalettesAtOffset(u16 offset)
{

View File

@ -2905,8 +2905,7 @@ static void CreateJumpMonSprite(struct PokemonJumpGfx *jumpGfx, struct PokemonJu
if (buffer && unusedBuffer)
{
HandleLoadSpecialPokePic(
&gMonFrontPicTable[monInfo->species],
HandleLoadSpecialPokePic(TRUE,
buffer,
monInfo->species,
monInfo->personality);

View File

@ -3991,7 +3991,7 @@ static void LoadDisplayMonGfx(u16 species, u32 pid)
if (species != SPECIES_NONE)
{
LoadSpecialPokePic(&gMonFrontPicTable[species], sStorage->tileBuffer, species, pid, TRUE);
LoadSpecialPokePic(sStorage->tileBuffer, species, pid, TRUE);
LZ77UnCompWram(sStorage->displayMonPalette, sStorage->displayMonPalBuffer);
CpuCopy32(sStorage->tileBuffer, sStorage->displayMonTilePtr, MON_PIC_SIZE);
LoadPalette(sStorage->displayMonPalBuffer, sStorage->displayMonPalOffset, 0x20);
@ -5109,7 +5109,7 @@ static u16 TryLoadMonIconTiles(u16 species, u32 personality)
u16 i, offset;
// Treat female mons as a seperate species as they may have a different icon than males
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
if (ShouldShowFemaleDifferences(species, personality))
species |= 0x8000; // 1 << 15
// Search icon list for this species
@ -5176,7 +5176,7 @@ static struct Sprite *CreateMonIconSprite(u16 species, u32 personality, s16 x, s
struct SpriteTemplate template = sSpriteTemplate_MonIcon;
species = GetIconSpecies(species, personality);
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
if (ShouldShowFemaleDifferences(species, personality))
{
template.paletteTag = PALTAG_MON_ICON_0 + gMonIconPaletteIndicesFemale[species];
}
@ -6893,7 +6893,6 @@ static void ReshowDisplayMon(void)
void SetMonFormPSS(struct BoxPokemon *boxMon)
{
u16 species = GetMonData(boxMon, MON_DATA_SPECIES);
u16 targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_ITEM_HOLD_ABILITY, 0);
if (targetSpecies == SPECIES_NONE)
targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_ITEM_HOLD, 0);

View File

@ -41,13 +41,14 @@
#include "text.h"
#include "tv.h"
#include "window.h"
#include "constants/battle_config.h"
#include "constants/battle_move_effects.h"
#include "constants/items.h"
#include "constants/moves.h"
#include "constants/party_menu.h"
#include "constants/region_map_sections.h"
#include "constants/rgb.h"
#include "constants/songs.h"
#include "constants/battle_config.h"
enum {
PSS_PAGE_INFO,
@ -3730,15 +3731,21 @@ static void PrintContestMoveDescription(u8 moveSlot)
static void PrintMoveDetails(u16 move)
{
u8 windowId = AddWindowFromTemplateList(sPageMovesTemplate, PSS_DATA_WINDOW_MOVE_DESCRIPTION);
u8 moveEffect;
FillWindowPixelBuffer(windowId, PIXEL_FILL(0));
if (move != MOVE_NONE)
{
if (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES)
{
moveEffect = gBattleMoves[move].effect;
if (B_SHOW_SPLIT_ICON == TRUE)
ShowSplitIcon(GetBattleMoveSplit(move));
PrintMovePowerAndAccuracy(move);
if (moveEffect != EFFECT_PLACEHOLDER)
PrintTextOnWindow(windowId, gMoveDescriptionPointers[move - 1], 6, 1, 0, 0);
else
PrintTextOnWindow(windowId, gNotDoneYetDescription, 6, 1, 0, 0);
}
else
{
@ -3980,7 +3987,7 @@ static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state)
case 0:
if (gMain.inBattle)
{
HandleLoadSpecialPokePic(&gMonFrontPicTable[summary->species2],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
summary->species2,
summary->pid);
@ -3989,14 +3996,14 @@ static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state)
{
if (gMonSpritesGfxPtr != NULL)
{
HandleLoadSpecialPokePic(&gMonFrontPicTable[summary->species2],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
summary->species2,
summary->pid);
}
else
{
HandleLoadSpecialPokePic(&gMonFrontPicTable[summary->species2],
HandleLoadSpecialPokePic(TRUE,
MonSpritesGfxManager_GetSpritePtr(MON_SPR_GFX_MANAGER_A, B_POSITION_OPPONENT_LEFT),
summary->species2,
summary->pid);

View File

@ -534,7 +534,7 @@ static void ConditionGraphDrawMonPic(s16 listId, u8 loadId)
species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES2, NULL);
tid = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
LoadSpecialPokePic(&gMonFrontPicTable[species], menu->monPicGfx[loadId], species, personality, TRUE);
LoadSpecialPokePic(menu->monPicGfx[loadId], species, personality, TRUE);
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, tid, personality), menu->monPal[loadId]);
}

View File

@ -417,6 +417,7 @@ const u8 gText_PkmnRegainhedHealth[] = _("{STR_VAR_1} regained health.{PAUSE_UNT
const u8 gText_PkmnBecameHealthy[] = _("{STR_VAR_1} became healthy.{PAUSE_UNTIL_PRESS}");
const u8 gText_MovesPPIncreased[] = _("{STR_VAR_1}'s PP increased.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnElevatedToLvVar2[] = _("{STR_VAR_1} was elevated to\nLv. {STR_VAR_2}.");
const u8 gText_PkmnGainedExp[] = _("{STR_VAR_1} gained Exp. Points!{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnBaseVar2StatIncreased[] = _("{STR_VAR_1}'s base {STR_VAR_2}\nstat was raised.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnFriendlyBaseVar2Fell[] = _("{STR_VAR_1} turned friendly.\nThe base {STR_VAR_2} fell!{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnAdoresBaseVar2Fell[] = _("{STR_VAR_1} adores you!\nThe base {STR_VAR_2} fell!{PAUSE_UNTIL_PRESS}");

View File

@ -2734,7 +2734,7 @@ static void LoadTradeMonPic(u8 whichParty, u8 state)
species = GetMonData(mon, MON_DATA_SPECIES2);
personality = GetMonData(mon, MON_DATA_PERSONALITY);
HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[whichParty * 2 + B_POSITION_OPPONENT_LEFT], species, personality);
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[whichParty * 2 + B_POSITION_OPPONENT_LEFT], species, personality);
LoadCompressedSpritePalette(GetMonSpritePalStruct(mon));
sTradeData->monSpecies[whichParty] = species;
@ -3727,7 +3727,7 @@ static bool8 AnimateTradeSequenceCable(void)
case TS_STATE_POKEBALL_ARRIVE_WAIT:
if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy)
{
HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeData->monSpecies[TRADE_PARTNER]], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], sTradeData->monSpecies[TRADE_PARTNER], sTradeData->monPersonalities[TRADE_PARTNER]);
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], sTradeData->monSpecies[TRADE_PARTNER], sTradeData->monPersonalities[TRADE_PARTNER]);
sTradeData->state++;
}
break;
@ -4224,7 +4224,7 @@ static bool8 AnimateTradeSequenceWireless(void)
case TS_STATE_POKEBALL_ARRIVE_WAIT:
if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy)
{
HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeData->monSpecies[TRADE_PARTNER]],
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT],
sTradeData->monSpecies[TRADE_PARTNER],
sTradeData->monPersonalities[TRADE_PARTNER]);

View File

@ -59,11 +59,11 @@ static bool16 DecompressPic(u16 species, u32 personality, bool8 isFrontPic, u8 *
{
if (isFrontPic)
{
LoadSpecialPokePic(&gMonFrontPicTable[species], dest, species, personality, isFrontPic);
LoadSpecialPokePic(dest, species, personality, isFrontPic);
}
else
{
LoadSpecialPokePic(&gMonBackPicTable[species], dest, species, personality, isFrontPic);
LoadSpecialPokePic(dest, species, personality, isFrontPic);
}
}
else