diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 61ad675492..66c82f39e5 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1022,7 +1022,7 @@ .4byte \ptr .endm - .macro trydobeatup endPtr:req, failPtr:req + .macro trydobeatup endPtr=NULL, failPtr=NULL .byte 0xc4 .4byte \endPtr .4byte \failPtr @@ -1941,6 +1941,31 @@ .macro shellsidearmcheck various BS_ATTACKER, VARIOUS_SHELL_SIDE_ARM_CHECK .endm + + .macro jumpifrodaffected battler:req, ptr:req + various \battler, VARIOUS_JUMP_IF_ROD + .4byte \ptr + .endm + + .macro jumpifabsorbaffected battler:req, ptr:req + various \battler, VARIOUS_JUMP_IF_ABSORB + .4byte \ptr + .endm + + .macro jumpifmotoraffected battler:req, ptr:req + various \battler, VARIOUS_JUMP_IF_MOTOR + .4byte \ptr + .endm + + .macro jumpifteanoberry ptr:req + various BS_ATTACKER, VARIOUS_TEATIME_TARGETS + .4byte \ptr + .endm + + .macro jumpifteainvulnerable battler:req, ptr:req + various \battler, VARIOUS_TEATIME_INVUL + .4byte \ptr + .endm .macro jumpifcantfling battler:req, ptr:req various \battler, VARIOUS_JUMP_IF_CANT_FLING @@ -2005,6 +2030,19 @@ .byte \stat .endm + .macro trywindriderpower battler:req, ptr:req + various \battler, VARIOUS_TRY_WIND_RIDER_POWER + .4byte \ptr + .endm + + .macro activateweatherchangeabilities battler:req + various \battler, VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES + .endm + + .macro activateterrainchangeabilities battler:req + various \battler, VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7 @@ -2162,3 +2200,34 @@ .macro trysymbiosis various BS_ATTACKER, VARIOUS_TRY_SYMBIOSIS .endm + + @ Tries to increase or decrease a battler's stat's stat stage by a specified amount. If impossible, jumps to \script. + .macro modifybattlerstatstage battler:req, stat:req, mode:req, amount:req, script:req, animation:req, customString + + @ \mode parameters + INCREASE = FALSE + DECREASE = TRUE + + @ \animation parameters + ANIM_OFF = FALSE + ANIM_ON = TRUE + + setstatchanger \stat, \amount, \mode + statbuffchange STAT_CHANGE_ALLOW_PTR, \script + setgraphicalstatchangevalues + .if \animation == TRUE + playanimation \battler, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + .endif + .ifnb \customString + printstring \customString + .else + .if \mode == DECREASE + printfromtable gStatDownStringIds + .else + .if \mode == INCREASE + printfromtable gStatUpStringIds + .endif + .endif + .endif + waitmessage B_WAIT_TIME_LONG + .endm diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 1deac08900..1006694655 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -13478,7 +13478,18 @@ Move_DRAGON_DARTS:: end Move_TEATIME:: - goto Move_MILK_DRINK + loadspritegfx ANIM_TAG_TEAPOT + loadspritegfx ANIM_TAG_THOUGHT_BUBBLE + createsprite gThoughtBubbleSpriteTemplate, ANIM_ATTACKER, 11, 0, 100 + playsewithpan SE_M_ICY_WIND, SOUND_PAN_ATTACKER + delay 6 + createsprite gTeapotSpriteTemplate, ANIM_ATTACKER, 12, 0 + createvisualtask AnimTask_RockMonBackAndForth, 5, ANIM_ATTACKER, 2, 0 + createvisualtask AnimTask_RockMonBackAndForth, 5, ANIM_ATK_PARTNER, 2, 0 + delay 24 + loopsewithpan SE_M_HEAL_BELL, SOUND_PAN_ATTACKER, 22, 3 + waitforvisualfinish + end Move_OCTOLOCK:: loadspritegfx ANIM_TAG_TENDRILS @@ -24938,7 +24949,7 @@ General_StrongWinds:: General_PrimalReversion:: launchtask AnimTask_PrimalReversion 0x5 0x0 jumpargeq 0x0, ITEM_RED_ORB, General_PrimalReversion_Omega - jumpargeq 0x1, ITEM_BLUE_ORB, General_PrimalReversion_Alpha + jumpargeq 0x0, ITEM_BLUE_ORB, General_PrimalReversion_Alpha General_PrimalReversion_Alpha: loadspritegfx ANIM_TAG_ALPHA_STONE loadspritegfx ANIM_TAG_MEGA_PARTICLES diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 94a220608a..4845b49aad 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -410,12 +410,80 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectCourtChange @ EFFECT_COURT_CHANGE .4byte BattleScript_EffectSteelBeam @ EFFECT_STEEL_BEAM .4byte BattleScript_EffectExtremeEvoboost @ EFFECT_EXTREME_EVOBOOST - .4byte BattleScript_EffectTerrainHit @ EFFECT_DAMAGE_SET_TERRAIN + .4byte BattleScript_EffectHitSetRemoveTerrain @ EFFECT_HIT_SET_REMOVE_TERRAIN .4byte BattleScript_EffectDarkVoid @ EFFECT_DARK_VOID .4byte BattleScript_EffectSleepHit @ EFFECT_SLEEP_HIT .4byte BattleScript_EffectDoubleShock @ EFFECT_DOUBLE_SHOCK .4byte BattleScript_EffectSpecialAttackUpHit @ EFFECT_SPECIAL_ATTACK_UP_HIT .4byte BattleScript_EffectVictoryDance @ EFFECT_VICTORY_DANCE + .4byte BattleScript_EffectTeatime @ EFFECT_TEATIME + +BattleScript_EffectTeatime:: + attackcanceler + attackstring + ppreduce + jumpifteanoberry BattleScript_ButItFailed +@ at least one battler is affected + attackanimation + waitanimation +BattleScript_TeatimeLoop: + jumpifteainvulnerable BS_TARGET, BattleScript_Teatimevul + jumpifrodaffected BS_TARGET, BattleScript_Teatimerod + jumpifabsorbaffected BS_TARGET, BattleScript_Teatimesorb + jumpifmotoraffected BS_TARGET, BattleScript_Teatimemotor + orword gHitMarker, HITMARKER_NO_ANIMATIONS | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE + setbyte sBERRY_OVERRIDE, TRUE @ override the requirements for eating berries + consumeberry BS_TARGET, TRUE @ consume the berry, then restore the item from changedItems + bicword gHitMarker, HITMARKER_NO_ANIMATIONS | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE + setbyte sBERRY_OVERRIDE, FALSE + removeitem BS_TARGET + moveendto MOVEEND_NEXT_TARGET + jumpifnexttargetvalid BattleScript_TeatimeLoop + moveendcase MOVEEND_CLEAR_BITS + goto BattleScript_MoveEnd +BattleScript_Teatimevul: + moveendto MOVEEND_NEXT_TARGET + jumpifnexttargetvalid BattleScript_TeatimeLoop + moveendcase MOVEEND_CLEAR_BITS + goto BattleScript_MoveEnd +BattleScript_Teatimesorb: + copybyte gBattlerAbility, gBattlerTarget + call BattleScript_AbilityPopUp + moveendto MOVEEND_NEXT_TARGET + jumpifnexttargetvalid BattleScript_TeatimeLoop + moveendcase MOVEEND_CLEAR_BITS + goto BattleScript_MoveEnd +BattleScript_Teatimerod: + copybyte gBattlerAbility, gBattlerTarget + call BattleScript_AbilityPopUp + playstatchangeanimation BS_TARGET, BIT_SPATK, STAT_CHANGE_BY_TWO + setstatchanger STAT_SPATK, 1, FALSE + statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_TeatimeBuffer + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_TeatimeBuffer + printfromtable gStatUpStringIds + waitmessage 0x40 + moveendto MOVEEND_NEXT_TARGET + jumpifnexttargetvalid BattleScript_TeatimeLoop + moveendcase MOVEEND_CLEAR_BITS + goto BattleScript_MoveEnd +BattleScript_Teatimemotor: + copybyte gBattlerAbility, gBattlerTarget + call BattleScript_AbilityPopUp + playstatchangeanimation BS_TARGET, BIT_SPEED, STAT_CHANGE_BY_TWO + setstatchanger STAT_SPEED, 1, FALSE + statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_TeatimeBuffer + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_TeatimeBuffer + printfromtable gStatUpStringIds + waitmessage 0x40 + moveendto MOVEEND_NEXT_TARGET + jumpifnexttargetvalid BattleScript_TeatimeLoop + moveendcase MOVEEND_CLEAR_BITS + goto BattleScript_MoveEnd +BattleScript_TeatimeBuffer: + moveendto MOVEEND_NEXT_TARGET + jumpifnexttargetvalid BattleScript_TeatimeLoop + moveendcase MOVEEND_CLEAR_BITS + goto BattleScript_MoveEnd BattleScript_AffectionBasedEndurance:: playanimation BS_TARGET, B_ANIM_AFFECTION_HANGED_ON @@ -2456,6 +2524,7 @@ BattleScript_EffectPsychicTerrain: printfromtable gTerrainStringIds waitmessage B_WAIT_TIME_LONG playanimation BS_ATTACKER, B_ANIM_RESTORE_BG + call BattleScript_ActivateTerrainAbilities call BattleScript_TerrainSeedLoop jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry goto BattleScript_MoveEnd @@ -2876,8 +2945,38 @@ BattleScript_EffectTailwind: waitanimation printstring STRINGID_TAILWINDBLEW waitmessage B_WAIT_TIME_LONG + call BattleScript_TryTailwindAbilitiesLoop goto BattleScript_MoveEnd +BattleScript_TryTailwindAbilitiesLoop: + savetarget + setbyte gBattlerTarget, 0 +BattleScript_TryTailwindAbilitiesLoop_Iter: + trywindriderpower BS_TARGET, BattleScript_TryTailwindAbilitiesLoop_Increment + jumpifability BS_TARGET, ABILITY_WIND_RIDER, BattleScript_TryTailwindAbilitiesLoop_WindRider + jumpifability BS_TARGET, ABILITY_WIND_POWER, BattleScript_TryTailwindAbilitiesLoop_WindPower +BattleScript_TryTailwindAbilitiesLoop_Increment: + addbyte gBattlerTarget, 0x1 + jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_TryTailwindAbilitiesLoop_Iter +BattleScript_TryTailwindAbilitiesLoop_Ret: + restoretarget + return + +BattleScript_TryTailwindAbilitiesLoop_WindRider: + call BattleScript_AbilityPopUp + modifybattlerstatstage BS_TARGET, STAT_ATK, INCREASE, 1, BattleScript_TryTailwindAbilitiesLoop_Increment, ANIM_ON + goto BattleScript_TryTailwindAbilitiesLoop_Increment + +BattleScript_TryTailwindAbilitiesLoop_WindPower: + call BattleScript_AbilityPopUp + copybyte sSAVED_BATTLER, gBattlerAttacker + copybyte gBattlerAttacker, gBattlerTarget + setcharge + printstring STRINGID_BEINGHITCHARGEDPKMNWITHPOWER + waitmessage B_WAIT_TIME_LONG + copybyte gBattlerAttacker, sSAVED_BATTLER + goto BattleScript_TryTailwindAbilitiesLoop_Increment + BattleScript_EffectMircleEye: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE @@ -2965,6 +3064,7 @@ BattleScript_EffectHitEscape: resultmessage waitmessage B_WAIT_TIME_LONG jumpifmovehadnoeffect BattleScript_MoveEnd + jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_MoveEnd seteffectwithchance tryfaintmon BS_TARGET moveendto MOVEEND_ATTACKER_VISIBLE @@ -3086,6 +3186,7 @@ BattleScript_EffectSleep:: jumpifstatus BS_TARGET, STATUS1_SLEEP, BattleScript_AlreadyAsleep jumpifcantmakeasleep BattleScript_CantMakeAsleep jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifability BS_TARGET_SIDE, ABILITY_SWEET_VEIL, BattleScript_SweetVeilProtects jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects @@ -3555,6 +3656,7 @@ BattleScript_EffectRoar:: attackstring ppreduce jumpifroarfails BattleScript_ButItFailed + jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_ButItFailed jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON @@ -3679,6 +3781,7 @@ BattleScript_EffectToxic:: ppreduce jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects @@ -4017,6 +4120,7 @@ BattleScript_EffectPoison:: ppreduce jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects @@ -4043,6 +4147,7 @@ BattleScript_EffectParalyze: ppreduce jumpifability BS_TARGET, ABILITY_LIMBER, BattleScript_LimberProtected jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects @@ -5183,10 +5288,18 @@ BattleScript_EffectTeleportNew: BattleScript_EffectTeleportNewEnd: goto BattleScript_MoveEnd -.if B_BEAT_UP < GEN_5 BattleScript_EffectBeatUp:: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE +.if B_BEAT_UP >= GEN_5 + attackstring + ppreduce + critcalc + damagecalc + adjustdamage + trydobeatup + goto BattleScript_HitFromAtkAnimation +.else attackstring pause B_WAIT_TIME_SHORT ppreduce @@ -5216,12 +5329,6 @@ BattleScript_BeatUpAttack:: goto BattleScript_BeatUpLoop BattleScript_BeatUpEnd:: end -.else -BattleScript_EffectBeatUp:: - attackcanceler - accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE - addbyte gBattleCommunication, 1 - goto BattleScript_HitFromAtkString .endif BattleScript_EffectSemiInvulnerable:: @@ -5470,6 +5577,7 @@ BattleScript_EffectWillOWisp:: jumpifability BS_TARGET, ABILITY_WATER_VEIL, BattleScript_WaterVeilPrevents jumpifability BS_TARGET, ABILITY_WATER_BUBBLE, BattleScript_WaterVeilPrevents jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects @@ -5762,6 +5870,7 @@ BattleScript_EffectYawn:: jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_PrintBankAbilityMadeIneffective jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_PrintBankAbilityMadeIneffective jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_PrintBankAbilityMadeIneffective + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects @@ -6644,6 +6753,27 @@ BattleScript_TailwindEnds:: waitmessage B_WAIT_TIME_LONG end2 +BattleScript_WindPowerActivatesEnd2:: + setbyte gBattlerAttacker, 0 +BattleScript_WindPowerLoop: + printstring STRINGID_EMPTYSTRING3 + jumpifability BS_ATTACKER, ABILITY_WIND_POWER, BattleScript_WindPowerLoop_Cont + goto BattleScript_WindPowerIncrement +BattleScript_WindPowerLoop_Cont: + jumpifstatus3 BS_ATTACKER, STATUS3_CHARGED_UP, BattleScript_WindPowerIncrement + goto BattleScript_WindPower_Activate +BattleScript_WindPower_Activate: + call BattleScript_AbilityPopUp + setcharge + printstring STRINGID_BEINGHITCHARGEDPKMNWITHPOWER + waitmessage B_WAIT_TIME_LONG +BattleScript_WindPowerIncrement: + addbyte gBattlerAttacker, 1 + jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_WindPowerLoop +BattleScript_WindPowerEnd: + destroyabilitypopup + end2 + BattleScript_TrickRoomEnds:: printstring STRINGID_TRICKROOMENDS waitmessage B_WAIT_TIME_LONG @@ -7084,6 +7214,70 @@ BattleScript_GulpMissileGorgingTargetDefenseCantGoLower: waitmessage B_WAIT_TIME_LONG return +BattleScript_SeedSowerActivates:: + pause B_WAIT_TIME_SHORT + call BattleScript_AbilityPopUp + printstring STRINGID_TERRAINBECOMESGRASSY + waitmessage B_WAIT_TIME_LONG + playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG + call BattleScript_ActivateTerrainAbilities + call BattleScript_TerrainSeedLoop + return + +BattleScript_AngerShellActivates:: + call BattleScript_AbilityPopUp + jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_AngerShellTryDef + jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_AngerShellTryDef + jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_SPEED, MAX_STAT_STAGE, BattleScript_AngerShellTryDef + jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_AngerShellTryDef + jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_ButItFailed +BattleScript_AngerShellTryDef:: + setbyte sSTAT_ANIM_PLAYED, FALSE + modifybattlerstatstage BS_ATTACKER, STAT_DEF, DECREASE, 1, BattleScript_AngerShellTrySpDef, ANIM_ON +BattleScript_AngerShellTrySpDef: + modifybattlerstatstage BS_ATTACKER, STAT_SPDEF, DECREASE, 1, BattleScript_AngerShellTryAttack, ANIM_ON +BattleScript_AngerShellTryAttack: + setbyte sSTAT_ANIM_PLAYED, FALSE + modifybattlerstatstage BS_ATTACKER, STAT_ATK, INCREASE, 1, BattleScript_AngerShellTrySpAtk, ANIM_ON +BattleScript_AngerShellTrySpAtk: + modifybattlerstatstage BS_ATTACKER, STAT_SPATK, INCREASE, 1, BattleScript_AngerShellTrySpeed, ANIM_ON +BattleScript_AngerShellTrySpeed: + modifybattlerstatstage BS_ATTACKER, STAT_SPEED, INCREASE, 1, BattleScript_AngerShellRet, ANIM_ON +BattleScript_AngerShellRet: + return + +BattleScript_WindPowerActivates:: +.if B_CHECK_IF_CHARGED_UP == TRUE + jumpifstatus3 BS_ATTACKER, STATUS3_CHARGED_UP, BattleScript_WindPowerActivates_Ret +.endif + call BattleScript_AbilityPopUp + setcharge + printstring STRINGID_BEINGHITCHARGEDPKMNWITHPOWER + waitmessage B_WAIT_TIME_LONG +BattleScript_WindPowerActivates_Ret: + return + +BattleScript_ToxicDebrisActivates:: + call BattleScript_AbilityPopUp + pause B_WAIT_TIME_SHORT + settoxicspikes BattleScript_ToxicDebrisRet + printstring STRINGID_POISONSPIKESSCATTERED + waitmessage B_WAIT_TIME_LONG +BattleScript_ToxicDebrisRet: + return + +BattleScript_EarthEaterActivates:: + call BattleScript_AbilityPopUp + pause B_WAIT_TIME_LONG + tryhealquarterhealth BS_TARGET, BattleScript_EarthEaterRet + orword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + printstring STRINGID_PKMNREGAINEDHEALTH + waitmessage B_WAIT_TIME_LONG +BattleScript_EarthEaterRet: + return + BattleScript_PerishSongCountGoesDown:: printstring STRINGID_PKMNPERISHCOUNTFELL waitmessage B_WAIT_TIME_LONG @@ -7605,6 +7799,17 @@ BattleScript_BallFetch:: waitmessage B_WAIT_TIME_LONG end3 +BattleScript_CudChewActivates:: + pause B_WAIT_TIME_SHORTEST + call BattleScript_AbilityPopUp + setbyte sBERRY_OVERRIDE, 1 @ override the requirements for eating berries + consumeberry BS_TARGET, FALSE + orword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + setbyte sBERRY_OVERRIDE, 0 + end3 + BattleScript_TargetFormChange:: pause 5 copybyte gBattlerAbility, gBattlerTarget @@ -8215,6 +8420,7 @@ BattleScript_WeatherFormChanges:: setbyte sBATTLER, 0 BattleScript_WeatherFormChangesLoop:: tryweatherformdatachange + activateweatherchangeabilities BS_SCRIPTING addbyte sBATTLER, 1 jumpifbytenotequal sBATTLER, gBattlersCount, BattleScript_WeatherFormChangesLoop return @@ -8277,13 +8483,15 @@ BattleScript_IntimidateLoop: jumpifability BS_TARGET, ABILITY_OWN_TEMPO, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_OBLIVIOUS, BattleScript_IntimidatePrevented .endif + jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_IntimidateInReverse BattleScript_IntimidateEffect: - copybyte sBATTLER, gBattlerTarget - statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN, NULL + copybyte sBATTLER, gBattlerAttacker + statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_IntimidateLoopIncrement setgraphicalstatchangevalues playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 printstring STRINGID_PKMNCUTSATTACKWITH waitmessage B_WAIT_TIME_LONG + copybyte sBATTLER, gBattlerTarget call BattleScript_TryAdrenalineOrb BattleScript_IntimidateLoopIncrement: addbyte gBattlerTarget, 1 @@ -8303,6 +8511,15 @@ BattleScript_IntimidatePrevented: call BattleScript_TryAdrenalineOrb goto BattleScript_IntimidateLoopIncrement +BattleScript_IntimidateInReverse: + copybyte sBATTLER, gBattlerTarget + copybyte gBattlerAbility, gBattlerTarget + call BattleScript_AbilityPopUp + pause B_WAIT_TIME_SHORT + modifybattlerstatstage BS_TARGET, STAT_ATK, INCREASE, 1, BattleScript_IntimidateLoopIncrement, ANIM_ON + call BattleScript_TryAdrenalineOrb + goto BattleScript_IntimidateLoopIncrement + BattleScript_DroughtActivates:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp @@ -8360,6 +8577,42 @@ BattleScript_DeltaStreamActivates:: playanimation BS_ATTACKER, B_ANIM_STRONG_WINDS end3 +BattleScript_ProtosynthesisActivates:: + call BattleScript_AbilityPopUp + printstring STRINGID_SUNLIGHTACTIVATEDABILITY + waitmessage B_WAIT_TIME_MED + printstring STRINGID_STATWASHEIGHTENED + waitmessage B_WAIT_TIME_MED + end3 + +BattleScript_QuarkDriveActivates:: + call BattleScript_AbilityPopUp + printstring STRINGID_ELECTRICTERRAINACTIVATEDABILITY + waitmessage B_WAIT_TIME_MED + printstring STRINGID_STATWASHEIGHTENED + waitmessage B_WAIT_TIME_MED + end3 + +BattleScript_RuinAbilityActivates:: + call BattleScript_AbilityPopUp + printstring STRINGID_ABILITYWEAKENEDFSURROUNDINGMONSSTAT + waitmessage B_WAIT_TIME_LONG + end3 + +BattleScript_SupremeOverlordActivates:: + pause B_WAIT_TIME_SHORT + call BattleScript_AbilityPopUp + printstring STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN + waitmessage B_WAIT_TIME_LONG + end3 + +BattleScript_CostarActivates:: + pause B_WAIT_TIME_SHORT + call BattleScript_AbilityPopUp + printstring STRINGID_PKMNCOPIEDSTATCHANGES + waitmessage B_WAIT_TIME_LONG + end3 + BattleScript_AttackWeakenedByStrongWinds:: pause B_WAIT_TIME_SHORT printstring STRINGID_ATTACKWEAKENEDBSTRONGWINDS @@ -8388,12 +8641,35 @@ BattleScript_TerrainSeedLoop_NextBattler: restoretarget return +BattleScript_ActivateSwitchInAbilities: + copybyte sBATTLER, gBattlerAttacker + setbyte gBattlerAttacker, 0 +BattleScript_ActivateSwitchInAbilities_Loop: + switchinabilities BS_ATTACKER +BattleScript_ActivateSwitchInAbilities_Increment: + addbyte gBattlerAttacker, 1 + jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_ActivateSwitchInAbilities_Loop + copybyte gBattlerAttacker, sBATTLER + return + +BattleScript_ActivateTerrainAbilities: + copybyte sBATTLER, gBattlerAttacker + setbyte gBattlerAttacker, 0 +BattleScript_ActivateTerrainAbilities_Loop: + activateterrainchangeabilities BS_ATTACKER +BattleScript_ActivateTerrainAbilities_Increment: + addbyte gBattlerAttacker, 1 + jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_ActivateTerrainAbilities_Loop + copybyte gBattlerAttacker, sBATTLER + return + BattleScript_ElectricSurgeActivates:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp printstring STRINGID_TERRAINBECOMESELECTRIC waitmessage B_WAIT_TIME_LONG playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG + call BattleScript_ActivateTerrainAbilities call BattleScript_TerrainSeedLoop end3 @@ -8403,6 +8679,7 @@ BattleScript_MistySurgeActivates:: printstring STRINGID_TERRAINBECOMESMISTY waitmessage B_WAIT_TIME_LONG playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG + call BattleScript_ActivateTerrainAbilities call BattleScript_TerrainSeedLoop end3 @@ -8412,6 +8689,7 @@ BattleScript_GrassySurgeActivates:: printstring STRINGID_TERRAINBECOMESGRASSY waitmessage B_WAIT_TIME_LONG playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG + call BattleScript_ActivateTerrainAbilities call BattleScript_TerrainSeedLoop end3 @@ -8421,6 +8699,7 @@ BattleScript_PsychicSurgeActivates:: printstring STRINGID_TERRAINBECOMESPSYCHIC waitmessage B_WAIT_TIME_LONG playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG + call BattleScript_ActivateTerrainAbilities call BattleScript_TerrainSeedLoop end3 @@ -8501,8 +8780,15 @@ BattleScript_MoveStatDrain:: setgraphicalstatchangevalues playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 waitanimation +.if B_ABSORBING_ABILITY_STRING >= GEN_5 + statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_MoveStatDrain_Cont + printfromtable gStatUpStringIds + waitmessage B_WAIT_TIME_LONG +.else printstring STRINGID_TARGETABILITYSTATRAISE waitmessage B_WAIT_TIME_LONG +.endif +BattleScript_MoveStatDrain_Cont: clearsemiinvulnerablebit tryfaintmon BS_ATTACKER goto BattleScript_MoveEnd @@ -9682,7 +9968,7 @@ BattleScript_ExtremeEvoboostSpDef:: BattleScript_ExtremeEvoboostEnd:: goto BattleScript_MoveEnd -BattleScript_EffectTerrainHit: +BattleScript_EffectHitSetRemoveTerrain: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring @@ -9704,6 +9990,7 @@ BattleScript_EffectTerrainHit: setterrain BattleScript_TryFaint playanimation BS_ATTACKER, B_ANIM_RESTORE_BG printfromtable gTerrainStringIds + call BattleScript_ActivateTerrainAbilities BattleScript_TryFaint: tryfaintmon BS_TARGET goto BattleScript_MoveEnd @@ -9802,6 +10089,35 @@ BattleScript_DarkTypePreventsPrankster:: orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT goto BattleScript_MoveEnd +BattleScript_WellBakedBodyActivates:: + attackstring + ppreduce + pause B_WAIT_TIME_SHORT + showabilitypopup BS_TARGET + orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT + modifybattlerstatstage BS_TARGET, STAT_DEF, INCREASE, 1, BattleScript_WellBakedBodyEnd, ANIM_ON +BattleScript_WellBakedBodyEnd: + goto BattleScript_MoveEnd + +BattleScript_WindRiderActivatesMoveEnd:: + attackstring + ppreduce + pause B_WAIT_TIME_SHORT + showabilitypopup BS_TARGET + orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT + modifybattlerstatstage BS_TARGET, STAT_ATK, INCREASE, 1, BattleScript_WindRiderActivatesMoveEnd_End, ANIM_ON +BattleScript_WindRiderActivatesMoveEnd_End: + goto BattleScript_MoveEnd + +BattleScript_GoodAsGoldActivates:: + attackstring + ppreduce + showabilitypopup BS_TARGET + pause B_WAIT_TIME_SHORT + printstring STRINGID_ITDOESNTAFFECT + waitmessage B_WAIT_TIME_MED + goto BattleScript_MoveEnd + BattleScript_PastelVeilActivates:: setbyte gBattleCommunication, 0 setbyte gBattleCommunication + 1, 0 diff --git a/data/maps/BattleFrontier_Lounge7/scripts.inc b/data/maps/BattleFrontier_Lounge7/scripts.inc index 9528dd11da..467f6ba9ae 100644 --- a/data/maps/BattleFrontier_Lounge7/scripts.inc +++ b/data/maps/BattleFrontier_Lounge7/scripts.inc @@ -145,6 +145,7 @@ 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 @@ -168,6 +169,7 @@ 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 diff --git a/data/scripts/repel.inc b/data/scripts/repel.inc index fc32df1d9c..ab7924bd21 100644 --- a/data/scripts/repel.inc +++ b/data/scripts/repel.inc @@ -19,6 +19,7 @@ EventScript_RepelUseAnother: lock msgbox Text_UseAnotherRepel, MSGBOX_YESNO .if I_REPEL_LURE_MENU == TRUE + goto_if_eq VAR_RESULT, NO, EventScript_RepelWoreOff_End callnative TryDrawRepelMenu goto_if_eq VAR_RESULT, FALSE, EventScript_RepelWoreOff_Chose waitstate @@ -68,6 +69,7 @@ EventScript_LureUseAnother: lock msgbox Text_UseAnotherLure, MSGBOX_YESNO .if I_REPEL_LURE_MENU == TRUE + goto_if_eq VAR_RESULT, NO, EventScript_LureWoreOff_End callnative TryDrawLureMenu goto_if_eq VAR_RESULT, FALSE, EventScript_LureWoreOff_Chose waitstate diff --git a/gflib/bg.c b/gflib/bg.c index f300e4609d..968c46272f 100644 --- a/gflib/bg.c +++ b/gflib/bg.c @@ -1053,7 +1053,7 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt for (x16 = x; x16 < (x + width); x16++) { CopyTileMapEntry(&firstTileNum, &((u16 *)sGpuBgConfigs2[bg].tilemap)[(u16)GetTileMapIndexFromCoords(x16, y16, attribute, mode, mode2)], paletteSlot, 0, 0); - firstTileNum = (firstTileNum & (MAPGRID_COLLISION_MASK | MAPGRID_ELEVATION_MASK)) + ((firstTileNum + tileNumDelta) & MAPGRID_METATILE_ID_MASK); + firstTileNum = (firstTileNum & 0xFC00) + ((firstTileNum + tileNumDelta) & 0x3FF); } } break; @@ -1064,7 +1064,7 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt for (x16 = x; x16 < (x + width); x16++) { ((u8 *)sGpuBgConfigs2[bg].tilemap)[(y16 * mode3) + x16] = firstTileNum; - firstTileNum = (firstTileNum & (MAPGRID_COLLISION_MASK | MAPGRID_ELEVATION_MASK)) + ((firstTileNum + tileNumDelta) & MAPGRID_METATILE_ID_MASK); + firstTileNum = (firstTileNum & 0xFC00) + ((firstTileNum + tileNumDelta) & 0x3FF); } } break; diff --git a/graphics/battle_anims/sprites/new/teapot.pal b/graphics/battle_anims/sprites/new/teapot.pal new file mode 100644 index 0000000000..f8319ce121 --- /dev/null +++ b/graphics/battle_anims/sprites/new/teapot.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +10 247 12 +144 141 173 +255 255 255 +207 232 255 +106 104 120 +190 211 255 +166 169 214 +214 171 113 +162 119 89 +72 71 81 +251 255 211 +232 207 121 +255 255 153 +124 86 73 +0 0 0 +0 0 0 diff --git a/graphics/battle_anims/sprites/new/teapot.png b/graphics/battle_anims/sprites/new/teapot.png new file mode 100644 index 0000000000..6be0680dfc Binary files /dev/null and b/graphics/battle_anims/sprites/new/teapot.png differ diff --git a/graphics/battle_interface/ball_display_unused_extra.png b/graphics/battle_interface/ball_caught_indicator.png similarity index 100% rename from graphics/battle_interface/ball_display_unused_extra.png rename to graphics/battle_interface/ball_caught_indicator.png diff --git a/include/battle.h b/include/battle.h index a38c28db87..aafc3d2f6d 100644 --- a/include/battle.h +++ b/include/battle.h @@ -104,6 +104,7 @@ struct DisableStruct u8 noRetreat:1; u8 tarShot:1; u8 octolock:1; + u8 cudChew:1; }; struct ProtectStruct @@ -650,6 +651,7 @@ struct BattleStruct u8 skyDropTargets[MAX_BATTLERS_COUNT]; // For Sky Drop, to account for if multiple Pokemon use Sky Drop in a double battle. // When using a move which hits multiple opponents which is then bounced by a target, we need to make sure, the move hits both opponents, the one with bounce, and the one without. u8 attackerBeforeBounce:2; + u8 beatUpSlot:3; u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit. u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching) }; diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index 44185a11a3..60fd9b156b 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -43,6 +43,7 @@ u16 GetNaturePowerMove(void); u16 GetSecretPowerMoveEffect(void); void StealTargetItem(u8 battlerStealer, u8 battlerItem); u8 GetCatchingBattler(void); +u32 GetHighestStatId(u32 battlerId); extern void (* const gBattleScriptingCommandsTable[])(void); extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4]; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 75afdbf633..d79566a44b 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -433,6 +433,21 @@ extern const u8 BattleScript_MultiHitPrintStrings[]; extern const u8 BattleScript_BurnUpRemoveType[]; extern const u8 BattleScript_TargetAbilityStatRaiseRet[]; extern const u8 BattleScript_DoubleShockRemoveType[]; +extern const u8 BattleScript_SeedSowerActivates[]; +extern const u8 BattleScript_AngerShellActivates[]; +extern const u8 BattleScript_WellBakedBodyActivates[]; +extern const u8 BattleScript_WindRiderActivatesMoveEnd[]; +extern const u8 BattleScript_WindPowerActivates[]; +extern const u8 BattleScript_WindPowerActivatesEnd2[]; +extern const u8 BattleScript_ProtosynthesisActivates[]; +extern const u8 BattleScript_QuarkDriveActivates[]; +extern const u8 BattleScript_GoodAsGoldActivates[]; +extern const u8 BattleScript_RuinAbilityActivates[]; +extern const u8 BattleScript_CudChewActivates[]; +extern const u8 BattleScript_SupremeOverlordActivates[]; +extern const u8 BattleScript_CostarActivates[]; +extern const u8 BattleScript_ToxicDebrisActivates[]; +extern const u8 BattleScript_EarthEaterActivates[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; diff --git a/include/battle_util.h b/include/battle_util.h index 257b5a7433..1a05c246cf 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -34,6 +34,8 @@ #define ABILITYEFFECT_MOVE_END_OTHER 12 #define ABILITYEFFECT_NEUTRALIZINGGAS 13 #define ABILITYEFFECT_FIELD_SPORT 14 // Only used if B_SPORT_TURNS < GEN_6 +#define ABILITYEFFECT_ON_WEATHER 15 +#define ABILITYEFFECT_ON_TERRAIN 16 // Special cases #define ABILITYEFFECT_MUD_SPORT 252 // Only used if B_SPORT_TURNS < GEN_6 #define ABILITYEFFECT_WATER_SPORT 253 // Only used if B_SPORT_TURNS < GEN_6 @@ -142,6 +144,7 @@ u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 bat u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef); u16 GetTypeModifier(u8 atkType, u8 defType); s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId); +s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp); u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId); u16 GetPrimalReversionSpecies(u16 preEvoSpecies, u16 heldItemId); u16 GetWishMegaEvolutionSpecies(u16 preEvoSpecies, u16 moveId1, u16 moveId2, u16 moveId3, u16 moveId4); @@ -202,5 +205,7 @@ bool32 CanBeFrozen(u8 battlerId); bool32 CanBeConfused(u8 battlerId); bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag); u32 GetBattlerFriendshipScore(u8 battlerId); +u32 CountBattlerStatIncreases(u8 battlerId, bool32 countEvasionAcc); +bool32 IsMyceliumMightOnField(void); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/config/battle.h b/include/config/battle.h index 47a2acee47..d6099dbc26 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -30,6 +30,7 @@ #define B_SPORT_DMG_REDUCTION GEN_LATEST // In Gen5+, Water/Mud Sport reduce Fire/Electric Damage by 67% instead of 50%. #define B_EXPLOSION_DEFENSE GEN_LATEST // In Gen5+, Self-Destruct and Explosion don't halve the targets' defense. #define B_PARENTAL_BOND_DMG GEN_LATEST // In Gen7+, Parental Bond's second hit does 25% of the initial hits damage. Before, it did 50%. +#define B_MULTIPLE_TARGETS_DMG GEN_LATEST // In Gen4+, damage dealt by moves that hit multiple targets at once is reduced to 75%. Before, it was 50%. // Type settings #define B_GHOSTS_ESCAPE GEN_LATEST // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle. @@ -110,6 +111,8 @@ #define B_PLUS_MINUS_INTERACTION GEN_LATEST // In Gen5+, Plus and Minus can be activated with themselves and the opposite ability. Before, only the opposing ability could activate it. #define B_WEATHER_FORMS GEN_LATEST // In Gen5+, Castform and Cherrim revert to their base form upon losing their respective ability. Cherrim needs Flower Gift to swap forms. #define B_SYMBIOSIS_GEMS GEN_LATEST // In Gen7+, Symbiosis passes an item after a gem-boosted attack. Previously, items are passed before the gem-boosted attack hits, making the item effect apply. +#define B_CHECK_IF_CHARGED_UP TRUE // If set to TRUE, certain abilities such as Electromorphosis WILL check if the STATUS3_CHARGED_UP status flag is applied. +#define B_ABSORBING_ABILITY_STRING GEN_LATEST // In Gen5+, the abilities that absorb moves of a certain type use a generic string for stat increases and decreases. // Item settings #define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn. diff --git a/include/config/pokemon.h b/include/config/pokemon.h index 81772f98e8..5e3463e677 100644 --- a/include/config/pokemon.h +++ b/include/config/pokemon.h @@ -9,7 +9,6 @@ #define P_LEGENDARY_PERFECT_IVS GEN_LATEST // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs. #define P_KADABRA_EVERSTONE GEN_LATEST // Since Gen 4, Kadabra can evolve even when holding an Everstone. #define P_NIDORAN_M_DITTO_BREED GEN_LATEST // Since Gen 5, when Nidoran♂ breeds with Ditto it can produce Nidoran♀ offspring. Before, it would only yield male offspring. This change also applies to Volbeat. -#define P_SHINY_BASE_CHANCE GEN_LATEST // Since Gen 6, the base chances of encountering a Shiny Pokémon was raised to 1/4096. This config adds an extra roll to the calculation, which effectively does the same thing. #define P_HIPPO_GENDER_DIFF_ICONS TRUE // If TRUE, will give Hippopotas and Hippowdon custom icons for their female forms. // Flag settings diff --git a/include/constants/abilities.h b/include/constants/abilities.h index 23b9fe2b72..94e5986f77 100644 --- a/include/constants/abilities.h +++ b/include/constants/abilities.h @@ -292,6 +292,41 @@ #define ABILITIES_COUNT_GEN8 268 -#define ABILITIES_COUNT ABILITIES_COUNT_GEN8 +// Gen 9 +#define ABILITY_LINGERING_AROMA 268 +#define ABILITY_SEED_SOWER 269 +#define ABILITY_THERMAL_EXCHANGE 270 +#define ABILITY_ANGER_SHELL 271 +#define ABILITY_PURIFYING_SALT 272 +#define ABILITY_WELL_BAKED_BODY 273 +#define ABILITY_WIND_RIDER 274 +#define ABILITY_GUARD_DOG 275 +#define ABILITY_ROCKY_PAYLOAD 276 +#define ABILITY_WIND_POWER 277 +#define ABILITY_ZERO_TO_HERO 278 +#define ABILITY_COMMANDER 279 +#define ABILITY_ELECTROMORPHOSIS 280 +#define ABILITY_PROTOSYNTHESIS 281 +#define ABILITY_QUARK_DRIVE 282 +#define ABILITY_GOOD_AS_GOLD 283 +#define ABILITY_VESSEL_OF_RUIN 284 +#define ABILITY_SWORD_OF_RUIN 285 +#define ABILITY_TABLETS_OF_RUIN 286 +#define ABILITY_BEADS_OF_RUIN 287 +#define ABILITY_ORICHALCUM_PULSE 288 +#define ABILITY_HADRON_ENGINE 289 +#define ABILITY_OPPORTUNIST 290 +#define ABILITY_CUD_CHEW 291 +#define ABILITY_SHARPNESS 292 +#define ABILITY_SUPREME_OVERLORD 293 +#define ABILITY_COSTAR 294 +#define ABILITY_TOXIC_DEBRIS 295 +#define ABILITY_ARMOR_TAIL 296 +#define ABILITY_EARTH_EATER 297 +#define ABILITY_MYCELIUM_MIGHT 298 + +#define ABILITIES_COUNT_GEN9 299 + +#define ABILITIES_COUNT ABILITIES_COUNT_GEN9 #endif // GUARD_CONSTANTS_ABILITIES_H diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 52b20ecaa4..0e8aaea83c 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -394,6 +394,8 @@ #define ANIM_TAG_OMEGA_SYMBOL (ANIM_SPRITES_START + 382) #define ANIM_TAG_STEEL_BEAM (ANIM_SPRITES_START + 383) #define ANIM_TAG_POLTERGEIST (ANIM_SPRITES_START + 384) +#define ANIM_TAG_TEAPOT (ANIM_SPRITES_START + 385) + // battlers #define ANIM_ATTACKER 0 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 5af1017a9d..89613f2778 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -391,13 +391,15 @@ #define EFFECT_COURT_CHANGE 385 #define EFFECT_STEEL_BEAM 386 #define EFFECT_EXTREME_EVOBOOST 387 -#define EFFECT_DAMAGE_SET_TERRAIN 388 // genesis supernova +#define EFFECT_HIT_SET_REMOVE_TERRAIN 388 #define EFFECT_DARK_VOID 389 #define EFFECT_SLEEP_HIT 390 #define EFFECT_DOUBLE_SHOCK 391 #define EFFECT_SPECIAL_ATTACK_UP_HIT 392 #define EFFECT_VICTORY_DANCE 393 +#define EFFECT_TEATIME 394 + +#define NUM_BATTLE_MOVE_EFFECTS 395 -#define NUM_BATTLE_MOVE_EFFECTS 394 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 0fcb2bbb0c..8f9ce0af8a 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -247,6 +247,14 @@ #define VARIOUS_GET_BATTLER_SIDE 156 #define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157 #define VARIOUS_SWAP_STATS 158 +#define VARIOUS_JUMP_IF_ROD 159 +#define VARIOUS_JUMP_IF_ABSORB 160 +#define VARIOUS_JUMP_IF_MOTOR 161 +#define VARIOUS_TEATIME_INVUL 162 +#define VARIOUS_TEATIME_TARGETS 163 +#define VARIOUS_TRY_WIND_RIDER_POWER 164 +#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 165 +#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 166 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 8dd94cca4d..f63aa79bce 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -632,8 +632,14 @@ #define STRINGID_TARGETTOUGHEDITOUT 630 #define STRINGID_ATTACKERLOSTELECTRICTYPE 631 #define STRINGID_ATTACKERSWITCHEDSTATWITHTARGET 632 +#define STRINGID_BEINGHITCHARGEDPKMNWITHPOWER 633 +#define STRINGID_SUNLIGHTACTIVATEDABILITY 634 +#define STRINGID_STATWASHEIGHTENED 635 +#define STRINGID_ELECTRICTERRAINACTIVATEDABILITY 636 +#define STRINGID_ABILITYWEAKENEDFSURROUNDINGMONSSTAT 637 +#define STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN 638 -#define BATTLESTRINGS_COUNT 633 +#define BATTLESTRINGS_COUNT 639 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, diff --git a/include/constants/metatile_labels.h b/include/constants/metatile_labels.h index ff10f52ee1..71aac2308a 100644 --- a/include/constants/metatile_labels.h +++ b/include/constants/metatile_labels.h @@ -684,8 +684,6 @@ #define METATILE_SecretBase_BigPlant_TopRight 0x2E6 #define METATILE_SecretBase_BigPlant_BaseLeft1 0x2EC #define METATILE_SecretBase_BigPlant_BaseRight1 0x2ED -#define METATILE_SecretBase_BigPlant_TopLeftWall 0x2E5 -#define METATILE_SecretBase_BigPlant_TopRightWall 0x2E6 #define METATILE_SecretBase_BigPlant_BaseLeft2 0x2EE #define METATILE_SecretBase_BigPlant_BaseRight2 0x2EF #define METATILE_SecretBase_GorgeousPlant_TopLeft 0x2F0 diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index 006e2a703f..35eca5bbc4 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -235,6 +235,8 @@ #define FLAG_THAW_USER (1 << 25) #define FLAG_HIT_IN_SUBSTITUTE (1 << 26) // Hyperspace Fury #define FLAG_TWO_STRIKES (1 << 27) // A move with this flag will strike twice, and may apply its effect on each hit +#define FLAG_WIND_MOVE (1 << 28) +#define FLAG_SLICING_MOVE (1 << 29) // Split defines. #define SPLIT_PHYSICAL 0x0 diff --git a/include/gba/multiboot.h b/include/gba/multiboot.h index 14b6594b29..64a8602843 100644 --- a/include/gba/multiboot.h +++ b/include/gba/multiboot.h @@ -10,7 +10,7 @@ struct MultiBootParam { u32 system_work[5]; // 00 u8 handshake_data; // 14 - u8 padding; // 15 + //u8 padding; // 15 u16 handshake_timeout; // 16 u8 probe_count; // 18 u8 client_data[MULTIBOOT_NCHILD]; // 19 diff --git a/include/global.berry.h b/include/global.berry.h index 8d1aa369de..29f1cfe14a 100644 --- a/include/global.berry.h +++ b/include/global.berry.h @@ -40,6 +40,7 @@ struct Berry2 u8 bitter; u8 sour; u8 smoothness; + //u8 padding; }; struct EnigmaBerry diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 4da3154e25..26e5c44bf1 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -41,7 +41,7 @@ struct Tileset /*0x01*/ bool8 isSecondary; /*0x04*/ const u32 *tiles; /*0x08*/ const u16 (*palettes)[16]; - /*0x0c*/ const u16 *metatiles; + /*0x0C*/ const u16 *metatiles; /*0x10*/ const u16 *metatileAttributes; /*0x14*/ TilesetCB callback; }; @@ -51,7 +51,7 @@ struct MapLayout /*0x00*/ s32 width; /*0x04*/ s32 height; /*0x08*/ u16 *border; - /*0x0c*/ u16 *map; + /*0x0C*/ u16 *map; /*0x10*/ struct Tileset *primaryTileset; /*0x14*/ struct Tileset *secondaryTileset; }; @@ -68,16 +68,19 @@ struct ObjectEventTemplate /*0x00*/ u8 localId; /*0x01*/ u8 graphicsId; /*0x02*/ u8 inConnection; // Leftover from FRLG + /*0x03*/ //u8 padding1; /*0x04*/ s16 x; /*0x06*/ s16 y; /*0x08*/ u8 elevation; /*0x09*/ u8 movementType; /*0x0A*/ u16 movementRangeX:4; u16 movementRangeY:4; + //u16 padding2:8; /*0x0C*/ u16 trainerType; /*0x0E*/ u16 trainerRange_berryTreeId; /*0x10*/ const u8 *script; /*0x14*/ u16 flagId; + /*0x16*/ //u8 padding3[2]; }; struct WarpEvent @@ -192,6 +195,7 @@ struct ObjectEvent u32 disableJumpLandingGroundEffect:1; u32 fixedPriority:1; u32 hideReflection:1; + //u32 padding:4; /*0x04*/ u8 spriteId; /*0x05*/ u8 graphicsId; /*0x06*/ u8 movementType; @@ -217,6 +221,7 @@ struct ObjectEvent /*0x20*/ u8 previousMovementDirection; /*0x21*/ u8 directionSequenceIndex; /*0x22*/ u8 playerCopyableMovement; // COPY_MOVE_* + /*0x23*/ //u8 padding2; /*size = 0x24*/ }; diff --git a/include/global.h b/include/global.h index 2f5a5c8710..22dc82ecb3 100644 --- a/include/global.h +++ b/include/global.h @@ -249,9 +249,11 @@ struct ApprenticeMon struct Apprentice { u8 id:5; - u8 lvlMode:2; // + 1 + u8 lvlMode:2; + //u8 padding1:1; u8 numQuestions; u8 number; + //u8 padding2; struct ApprenticeMon party[MULTI_PARTY_SIZE]; u16 speechWon[EASY_CHAT_BATTLE_WORDS_COUNT]; u8 playerId[TRAINER_ID_LENGTH]; @@ -299,6 +301,7 @@ struct EmeraldBattleTowerRecord /*0x28*/ u16 speechLost[EASY_CHAT_BATTLE_WORDS_COUNT]; /*0x34*/ struct BattleTowerPokemon party[MAX_FRONTIER_PARTY_SIZE]; /*0xE4*/ u8 language; + /*0xE7*/ //u8 padding[3]; /*0xE8*/ u32 checksum; }; @@ -331,14 +334,17 @@ struct DomeMonData u16 moves[MAX_MON_MOVES]; u8 evs[NUM_STATS]; u8 nature; + //u8 padding; }; struct RentalMon { u16 monId; + //u8 padding1[2]; u32 personality; u8 ivs; u8 abilityNum; + //u8 padding2[2]; }; struct BattleDomeTrainer @@ -360,8 +366,9 @@ struct BattleFrontier /*0xBEC*/ struct BattleTowerEReaderTrainer ereaderTrainer; /*0xCA8*/ u8 challengeStatus; /*0xCA9*/ u8 lvlMode:2; - /*0xCA9*/ u8 challengePaused:1; - /*0xCA9*/ u8 disableRecordBattle:1; + u8 challengePaused:1; + u8 disableRecordBattle:1; + //u8 padding1:4; /*0xCAA*/ u16 selectedPartyMons[MAX_FRONTIER_PARTY_SIZE]; /*0xCB2*/ u16 curChallengeBattleNum; // Battle number / room number (Pike) / floor number (Pyramid) /*0xCB4*/ u16 trainerIds[20]; @@ -405,16 +412,19 @@ struct BattleFrontier /*0xE08*/ u16 pikeRecordStreaks[FRONTIER_LVL_MODE_COUNT]; /*0xE0C*/ u16 pikeTotalStreaks[FRONTIER_LVL_MODE_COUNT]; /*0xE10*/ u8 pikeHintedRoomIndex:3; - /*0xE10*/ u8 pikeHintedRoomType:4; - /*0xE10*/ u8 pikeHealingRoomsDisabled:1; + u8 pikeHintedRoomType:4; + u8 pikeHealingRoomsDisabled:1; + /*0xE11*/ //u8 padding2; /*0xE12*/ u16 pikeHeldItemsBackup[FRONTIER_PARTY_SIZE]; /*0xE18*/ u16 pyramidPrize; /*0xE1A*/ u16 pyramidWinStreaks[FRONTIER_LVL_MODE_COUNT]; /*0xE1E*/ u16 pyramidRecordStreaks[FRONTIER_LVL_MODE_COUNT]; /*0xE22*/ u16 pyramidRandoms[4]; /*0xE2A*/ u8 pyramidTrainerFlags; // 1 bit for each trainer (MAX_PYRAMID_TRAINERS) + /*0xE2B*/ //u8 padding3; /*0xE2C*/ struct PyramidBag pyramidBag; /*0xE68*/ u8 pyramidLightRadius; + /*0xE69*/ //u8 padding4; /*0xE6A*/ u16 verdanturfTentPrize; /*0xE6C*/ u16 fallarborTentPrize; /*0xE6E*/ u16 slateportTentPrize; @@ -439,6 +449,7 @@ struct ApprenticeQuestion u8 monId:2; u8 moveSlot:2; u8 suggestedChange:2; // TRUE if told to use held item or second move, FALSE if told to use no item or first move + //u8 padding; u16 data; // used both as an itemId and a moveId }; @@ -449,9 +460,11 @@ struct PlayersApprentice /*0xB1*/ u8 questionsAnswered:4; /*0xB1*/ u8 leadMonId:2; /*0xB2*/ u8 party:3; - /*0xB2*/ u8 saveId:2; + u8 saveId:2; + //u8 padding1:3; /*0xB3*/ u8 unused; /*0xB4*/ u8 speciesIds[MULTI_PARTY_SIZE]; + /*0xB7*/ //u8 padding2; /*0xB8*/ struct ApprenticeQuestion questions[APPRENTICE_MAX_QUESTIONS]; }; @@ -461,6 +474,7 @@ struct RankingHall1P u16 winStreak; u8 name[PLAYER_NAME_LENGTH + 1]; u8 language; + //u8 padding; }; struct RankingHall2P @@ -471,6 +485,7 @@ struct RankingHall2P u8 name1[PLAYER_NAME_LENGTH + 1]; u8 name2[PLAYER_NAME_LENGTH + 1]; u8 language; + //u8 padding; }; struct SaveBlock2 @@ -490,6 +505,8 @@ struct SaveBlock2 u16 optionsBattleStyle:1; // OPTIONS_BATTLE_STYLE_[SHIFT/SET] u16 optionsBattleSceneOff:1; // whether battle animations are disabled u16 regionMapZoom:1; // whether the map is zoomed in + //u16 padding1:4; + //u16 padding2; /*0x18*/ struct Pokedex pokedex; /*0x90*/ u8 filler_90[0x8]; /*0x98*/ struct Time localTimeOffset; @@ -534,6 +551,7 @@ struct SecretBase /*0x1AAD*/ u8 unused; /*0x1AAE*/ u8 decorations[DECOR_MAX_SECRET_BASE]; /*0x1ABE*/ u8 decorationPositions[DECOR_MAX_SECRET_BASE]; + /*0x1ACE*/ //u8 padding[2]; /*0x1AD0*/ struct SecretBaseParty party; }; @@ -548,6 +566,7 @@ struct WarpData s8 mapGroup; s8 mapNum; s8 warpId; + //u8 padding; s16 x, y; }; @@ -592,6 +611,7 @@ struct RamScriptData u8 mapNum; u8 objectId; u8 script[995]; + //u8 padding; }; struct RamScript @@ -606,6 +626,7 @@ struct DewfordTrend u16 trendiness:7; u16 maxTrendiness:7; u16 gainingTrendiness:1; + //u16 padding:1; u16 rand; u16 words[2]; }; /*size = 0x8*/ @@ -618,6 +639,7 @@ struct MauvilleManCommon struct MauvilleManBard { /*0x00*/ u8 id; + /*0x01*/ //u8 padding1; /*0x02*/ u16 songLyrics[BARD_SONG_LENGTH]; /*0x0E*/ u16 temporaryLyrics[BARD_SONG_LENGTH]; /*0x1A*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; @@ -625,6 +647,7 @@ struct MauvilleManBard /*0x25*/ u8 playerTrainerId[TRAINER_ID_LENGTH]; /*0x29*/ bool8 hasChangedSong; /*0x2A*/ u8 language; + /*0x2B*/ //u8 padding2; }; /*size = 0x2C*/ struct MauvilleManStoryteller @@ -643,9 +666,11 @@ struct MauvilleManGiddy /*0x00*/ u8 id; /*0x01*/ u8 taleCounter; /*0x02*/ u8 questionNum; + /*0x03*/ //u8 padding1; /*0x04*/ u16 randomWords[GIDDY_MAX_TALES]; /*0x18*/ u8 questionList[GIDDY_MAX_QUESTIONS]; /*0x20*/ u8 language; + /*0x21*/ //u8 padding2; }; /*size = 0x2C*/ struct MauvilleManHipster @@ -690,6 +715,7 @@ struct LinkBattleRecords { struct LinkBattleRecord entries[LINK_B_RECORDS_COUNT]; u8 languages[LINK_B_RECORDS_COUNT]; + //u8 padding; }; struct RecordMixingGiftData @@ -715,6 +741,7 @@ struct ContestWinner u8 monName[POKEMON_NAME_LENGTH + 1]; u8 trainerName[PLAYER_NAME_LENGTH + 1]; u8 contestRank; + //u8 padding; }; struct Mail @@ -747,6 +774,7 @@ struct DayCare struct DaycareMon mons[DAYCARE_MON_COUNT]; u32 offspringPersonality; u8 stepCounter; + //u8 padding[3]; }; struct LilycoveLadyQuiz @@ -759,10 +787,10 @@ struct LilycoveLadyQuiz /*0x018*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x020*/ u16 playerTrainerId[TRAINER_ID_LENGTH]; /*0x028*/ u16 prize; - /*0x02a*/ bool8 waitingForChallenger; - /*0x02b*/ u8 questionId; - /*0x02c*/ u8 prevQuestionId; - /*0x02d*/ u8 language; + /*0x02A*/ bool8 waitingForChallenger; + /*0x02B*/ u8 questionId; + /*0x02C*/ u8 prevQuestionId; + /*0x02D*/ u8 language; }; struct LilycoveLadyFavor @@ -772,10 +800,12 @@ struct LilycoveLadyFavor /*0x002*/ bool8 likedItem; /*0x003*/ u8 numItemsGiven; /*0x004*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; - /*0x00c*/ u8 favorId; - /*0x00e*/ u16 itemId; + /*0x00C*/ u8 favorId; + /*0x00D*/ //u8 padding1; + /*0x00E*/ u16 itemId; /*0x010*/ u16 bestItem; /*0x012*/ u8 language; + /*0x013*/ //u8 padding2; }; struct LilycoveLadyContest @@ -785,9 +815,9 @@ struct LilycoveLadyContest /*0x002*/ u8 numGoodPokeblocksGiven; /*0x003*/ u8 numOtherPokeblocksGiven; /*0x004*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; - /*0x00c*/ u8 maxSheen; - /*0x00d*/ u8 category; - /*0x00e*/ u8 language; + /*0x00C*/ u8 maxSheen; + /*0x00D*/ u8 category; + /*0x00E*/ u8 language; }; typedef union // 3b58 @@ -796,7 +826,7 @@ typedef union // 3b58 struct LilycoveLadyFavor favor; struct LilycoveLadyContest contest; u8 id; - u8 pad[0x40]; + u8 filler[0x40]; } LilycoveLady; struct WaldaPhrase @@ -806,6 +836,7 @@ struct WaldaPhrase u8 iconId; u8 patternId; bool8 patternUnlocked; + //u8 padding; }; struct TrainerNameRecord @@ -821,12 +852,13 @@ struct TrainerHillSave /*0x3D6C*/ u8 unk_3D6C; /*0x3D6D*/ u8 unused; /*0x3D6E*/ u16 receivedPrize:1; - /*0x3D6E*/ u16 checkedFinalTime:1; - /*0x3D6E*/ u16 spokeToOwner:1; - /*0x3D6E*/ u16 hasLost:1; - /*0x3D6E*/ u16 maybeECardScanDuringChallenge:1; - /*0x3D6E*/ u16 field_3D6E_0f:1; - /*0x3D6E*/ u16 mode:2; // HILL_MODE_* + u16 checkedFinalTime:1; + u16 spokeToOwner:1; + u16 hasLost:1; + u16 maybeECardScanDuringChallenge:1; + u16 field_3D6E_0f:1; + u16 mode:2; // HILL_MODE_* + //u16 padding:8; }; struct WonderNewsMetadata @@ -835,6 +867,7 @@ struct WonderNewsMetadata u8 sentCounter:3; u8 getCounter:3; u8 rand; + //u8 padding[2]; }; struct WonderNews @@ -860,6 +893,7 @@ struct WonderCard u8 bodyText[WONDER_CARD_BODY_TEXT_LINES][WONDER_CARD_TEXT_LENGTH]; u8 footerLine1Text[WONDER_CARD_TEXT_LENGTH]; u8 footerLine2Text[WONDER_CARD_TEXT_LENGTH]; + //u8 padding[2]; }; struct WonderCardMetadata @@ -906,7 +940,7 @@ struct ExternalEventFlags { u8 usedBoxRS:1; // Set by Pokémon Box: Ruby & Sapphire; denotes whether this save has connected to it and triggered the free False Swipe Swablu Egg giveaway. u8 boxRSEggsUnlocked:2; // Set by Pokémon Box: Ruby & Sapphire; denotes the number of Eggs unlocked from deposits; 1 for ExtremeSpeed Zigzagoon (at 100 deposited), 2 for Pay Day Skitty (at 500 deposited), 3 for Surf Pichu (at 1499 deposited) - u8 padding:5; + //u8 padding:5; u8 unknownFlag1; u8 receivedGCNJirachi; // Both the US Colosseum Bonus Disc and PAL/AUS Pokémon Channel use this field. One cannot receive a WISHMKR Jirachi and CHANNEL Jirachi with the same savefile. u8 unknownFlag3; @@ -942,9 +976,11 @@ struct SaveBlock1 /*0x2E*/ u8 weather; /*0x2F*/ u8 weatherCycleStage; /*0x30*/ u8 flashLevel; + /*0x31*/ //u8 padding1; /*0x32*/ u16 mapLayoutId; /*0x34*/ u16 mapView[0x100]; /*0x234*/ u8 playerPartyCount; + /*0x235*/ //u8 padding2[3]; /*0x238*/ struct Pokemon playerParty[PARTY_SIZE]; /*0x490*/ u32 money; /*0x494*/ u16 coins; @@ -961,6 +997,7 @@ struct SaveBlock1 /*0x9C2*/ u8 unused_9C2[6]; /*0x9C8*/ u16 trainerRematchStepCounter; /*0x9CA*/ u8 trainerRematches[MAX_REMATCH_ENTRIES]; + /*0xA2E*/ //u8 padding3[2]; /*0xA30*/ struct ObjectEvent objectEvents[OBJECT_EVENTS_COUNT]; /*0xC70*/ struct ObjectEventTemplate objectEventTemplates[OBJECT_EVENT_TEMPLATES_COUNT]; /*0x1270*/ u8 flags[NUM_FLAG_BYTES]; @@ -978,6 +1015,7 @@ struct SaveBlock1 /*0x278E*/ u8 decorationPosters[10]; /*0x2798*/ u8 decorationDolls[40]; /*0x27C0*/ u8 decorationCushions[10]; + /*0x27CA*/ //u8 padding4[2]; /*0x27CC*/ TVShow tvShows[TV_SHOWS_COUNT]; /*0x2B50*/ PokeNews pokeNews[POKE_NEWS_COUNT]; /*0x2B90*/ u16 outbreakPokemonSpecies; @@ -997,6 +1035,7 @@ struct SaveBlock1 /*0x2BD4*/ u16 easyChatBattleLost[EASY_CHAT_BATTLE_WORDS_COUNT]; /*0x2BE0*/ struct Mail mail[MAIL_COUNT]; /*0x2E20*/ u8 additionalPhrases[NUM_ADDITIONAL_PHRASE_BYTES]; // bitfield for 33 additional phrases in easy chat system + /*0x2E25*/ //u8 padding5[3]; /*0x2E28*/ OldMan oldMan; /*0x2e64*/ struct DewfordTrend dewfordTrends[SAVED_TRENDS_COUNT]; /*0x2e90*/ struct ContestWinner contestWinners[NUM_CONTEST_WINNERS]; // see CONTEST_WINNER_* diff --git a/include/global.tv.h b/include/global.tv.h index 1fb1b8a333..3729562cd6 100644 --- a/include/global.tv.h +++ b/include/global.tv.h @@ -36,6 +36,7 @@ typedef union // size = 0x24 /*0x04*/ u16 words[6]; /*0x10*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u8 language; + /*0x19*/ //u8 padding; } fanclubLetter; // TVSHOW_RECENT_HAPPENINGS @@ -46,6 +47,7 @@ typedef union // size = 0x24 /*0x04*/ u16 words[6]; /*0x10*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u8 language; + /*0x19*/ //u8 padding; } recentHappenings; // TVSHOW_PKMN_FAN_CLUB_OPINIONS @@ -54,7 +56,7 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u16 species; /*0x04*/ u8 friendshipHighNybble:4; - /*0x04*/ u8 questionAsked:4; + u8 questionAsked:4; /*0x05*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x0D*/ u8 language; /*0x0E*/ u8 pokemonNameLanguage; @@ -70,8 +72,8 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u16 words[2]; /*0x06*/ u16 species; - /*0x08*/ u8 pad_08[3]; - /*0x0b*/ u8 name[12]; + /*0x08*/ u8 filler_08[3]; + /*0x0B*/ u8 name[12]; /*0x17*/ u8 language; } dummy; @@ -98,8 +100,9 @@ typedef union // size = 0x24 /*0x04*/ u16 words[2]; /*0x08*/ u8 pokemonNickname[POKEMON_NAME_LENGTH + 1]; /*0x13*/ u8 contestCategory:3; - /*0x13*/ u8 contestRank:2; - /*0x13*/ u8 contestResult:2; + u8 contestRank:2; + u8 contestResult:2; + //u8 padding:1; /*0x14*/ u16 move; /*0x16*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x1E*/ u8 language; @@ -121,6 +124,7 @@ typedef union // size = 0x24 /*0x1C*/ bool8 wonTheChallenge; /*0x1D*/ u8 language; /*0x1E*/ u8 pokemonNameLanguage; + /*0x1F*/ //u8 padding; } bravoTrainerTower; // TVSHOW_CONTEST_LIVE_UPDATES @@ -131,14 +135,15 @@ typedef union // size = 0x24 /*0x04*/ u8 losingTrainerName[PLAYER_NAME_LENGTH + 1]; /*0x0C*/ u8 loserAppealFlag; /*0x0D*/ u8 round1Placing; - /*0x0e*/ u8 round2Placing; - /*0x0f*/ u8 winnerAppealFlag; + /*0x0E*/ u8 round2Placing; + /*0x0F*/ u8 winnerAppealFlag; /*0x10*/ u16 move; /*0x12*/ u16 winningSpecies; /*0x14*/ u8 winningTrainerName[PLAYER_NAME_LENGTH + 1]; /*0x1C*/ u8 category; /*0x1D*/ u8 winningTrainerLanguage; /*0x1E*/ u8 losingTrainerLanguage; + /*0x1F*/ //u8 padding; } contestLiveUpdates; // TVSHOW_3_CHEERS_FOR_POKEBLOCKS @@ -147,7 +152,8 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u8 sheen; /*0x03*/ u8 flavor:3; - /*0x03*/ u8 color:2; + u8 color:2; + //u8 padding:3; /*0x04*/ u8 worstBlenderName[PLAYER_NAME_LENGTH + 1]; /*0x0C*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x14*/ u8 language; @@ -166,6 +172,7 @@ typedef union // size = 0x24 /*0x18*/ u8 battleType; /*0x19*/ u8 language; /*0x1A*/ u8 linkOpponentLanguage; + /*0x1B*/ //u8 padding; } battleUpdate; // TVSHOW_FAN_CLUB_SPECIAL @@ -173,13 +180,14 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; - /*0x0a*/ u8 idLo; - /*0x0b*/ u8 idHi; - /*0x0c*/ u8 idolName[PLAYER_NAME_LENGTH + 1]; + /*0x0A*/ u8 idLo; + /*0x0B*/ u8 idHi; + /*0x0C*/ u8 idolName[PLAYER_NAME_LENGTH + 1]; /*0x14*/ u16 words[1]; /*0x16*/ u8 score; /*0x17*/ u8 language; /*0x18*/ u8 idolNameLanguage; + /*0x19*/ //u8 padding; } fanClubSpecial; // TVSHOW_LILYCOVE_CONTEST_LADY @@ -187,8 +195,8 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; - /*0x0a*/ u8 contestCategory; - /*0x0b*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; + /*0x0A*/ u8 contestCategory; + /*0x0B*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; /*0x16*/ u8 pokeblockState; /*0x17*/ u8 language; /*0x18*/ u8 pokemonNameLanguage; @@ -206,6 +214,7 @@ typedef union // size = 0x24 /*0x10*/ u16 species; /*0x12*/ u8 nBallsUsed; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } pokemonToday; // TVSHOW_SMART_SHOPPER @@ -214,11 +223,12 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u8 priceReduced; /*0x03*/ u8 language; - /*0x04*/ u8 pad04[2]; + /*0x04*/ u8 filler_04[2]; /*0x06*/ u16 itemIds[SMARTSHOPPER_NUM_ITEMS]; /*0x0C*/ u16 itemAmounts[SMARTSHOPPER_NUM_ITEMS]; /*0x12*/ u8 shopLocation; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } smartshopperShow; // TVSHOW_POKEMON_TODAY_FAILED @@ -226,13 +236,14 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u8 language; - /*0x03*/ u8 pad03[9]; - /*0x0c*/ u16 species; - /*0x0e*/ u16 species2; + /*0x03*/ u8 filler_03[9]; + /*0x0C*/ u16 species; + /*0x0E*/ u16 species2; /*0x10*/ u8 nBallsUsed; /*0x11*/ u8 outcome; /*0x12*/ u8 location; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } pokemonTodayFailed; // TVSHOW_FISHING_ADVICE @@ -243,8 +254,9 @@ typedef union // size = 0x24 /*0x03*/ u8 nFails; /*0x04*/ u16 species; /*0x06*/ u8 language; - /*0x07*/ u8 pad07[12]; + /*0x07*/ u8 filler_07[12]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } pokemonAngler; // TVSHOW_WORLD_OF_MASTERS @@ -255,10 +267,11 @@ typedef union // size = 0x24 /*0x04*/ u16 caughtPoke; /*0x06*/ u16 steps; /*0x08*/ u16 species; - /*0x0a*/ u8 location; - /*0x0b*/ u8 language; - /*0x0c*/ u8 pad0c[7]; + /*0x0A*/ u8 location; + /*0x0B*/ u8 language; + /*0x0C*/ u8 filler_0C[7]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding2; } worldOfMasters; // TVSHOW_TODAYS_RIVAL_TRAINER @@ -271,10 +284,11 @@ typedef union // size = 0x24 /*0x06*/ u8 nGoldSymbols; /*0x07*/ u8 location; /*0x08*/ u16 battlePoints; - /*0x0a*/ u16 mapLayoutId; - /*0x0c*/ u8 language; - /*0x0d*/ u8 filler_0d[6]; + /*0x0A*/ u16 mapLayoutId; + /*0x0C*/ u8 language; + /*0x0D*/ u8 filler_0D[6]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding2; } rivalTrainer; // TVSHOW_TREND_WATCHER @@ -285,8 +299,9 @@ typedef union // size = 0x24 /*0x04*/ u16 words[2]; /*0x08*/ u8 gender; /*0x09*/ u8 language; - /*0x0a*/ u8 filler_0a[9]; + /*0x0A*/ u8 filler_0a[9]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } trendWatcher; // TVSHOW_TREASURE_INVESTIGATORS @@ -299,6 +314,7 @@ typedef union // size = 0x24 /*0x06*/ u16 mapLayoutId; /*0x08*/ u8 filler_08[11]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } treasureInvestigators; // TVSHOW_FIND_THAT_GAMER @@ -312,6 +328,7 @@ typedef union // size = 0x24 /*0x08*/ u8 language; /*0x09*/ u8 filler_09[10]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } findThatGamer; // TVSHOW_BREAKING_NEWS @@ -323,11 +340,12 @@ typedef union // size = 0x24 /*0x05*/ u8 outcome; /*0x06*/ u16 caughtMonBall; /*0x08*/ u16 balls; - /*0x0a*/ u16 poke1Species; - /*0x0c*/ u16 lastUsedMove; - /*0x0e*/ u8 language; - /*0x0f*/ u8 filler_0f[4]; + /*0x0A*/ u16 poke1Species; + /*0x0C*/ u16 lastUsedMove; + /*0x0E*/ u8 language; + /*0x0F*/ u8 filler_0f[4]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } breakingNews; // TVSHOW_SECRET_BASE_VISIT @@ -338,10 +356,11 @@ typedef union // size = 0x24 /*0x03*/ u8 numDecorations; /*0x04*/ u8 decorations[4]; /*0x08*/ u16 species; - /*0x0a*/ u16 move; - /*0x0c*/ u8 language; - /*0x0d*/ u8 filler_0d[6]; + /*0x0A*/ u16 move; + /*0x0C*/ u8 language; + /*0x0D*/ u8 filler_0d[6]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } secretBaseVisit; // TVSHOW_LOTTO_WINNER @@ -353,6 +372,7 @@ typedef union // size = 0x24 /*0x05*/ u8 language; /*0x06*/ u8 filler_06[13]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } lottoWinner; // TVSHOW_BATTLE_SEMINAR @@ -363,11 +383,12 @@ typedef union // size = 0x24 /*0x04*/ u16 foeSpecies; /*0x06*/ u16 species; /*0x08*/ u16 otherMoves[3]; - /*0x0e*/ u16 betterMove; + /*0x0E*/ u16 betterMove; /*0x10*/ u8 nOtherMoves; /*0x11*/ u8 language; /*0x12*/ u8 filler_12[1]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } battleSeminar; // TVSHOW_TRAINER_FAN_CLUB @@ -379,6 +400,7 @@ typedef union // size = 0x24 /*0x08*/ u8 language; /*0x09*/ u8 filler_09[10]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } trainerFanClub; // TVSHOW_CUTIES @@ -388,7 +410,7 @@ typedef union // size = 0x24 /*0x02*/ u8 nRibbons; /*0x03*/ u8 selectedRibbon; /*0x04*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; - /*0x0f*/ u8 language; + /*0x0F*/ u8 language; /*0x10*/ u8 pokemonNameLanguage; /*0x11*/ u8 filler_12[2]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; @@ -402,11 +424,12 @@ typedef union // size = 0x24 /*0x04*/ u16 species1; /*0x06*/ u16 species2; /*0x08*/ u16 species3; - /*0x0a*/ u16 species4; - /*0x0c*/ u8 language; - /*0x0d*/ u8 facilityAndMode; - /*0x0e*/ u8 filler_0e[5]; + /*0x0A*/ u16 species4; + /*0x0C*/ u8 language; + /*0x0D*/ u8 facilityAndMode; + /*0x0E*/ u8 filler_0e[5]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } frontier; // TVSHOW_NUMBER_ONE @@ -418,6 +441,7 @@ typedef union // size = 0x24 /*0x05*/ u8 language; /*0x06*/ u8 filler_06[13]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x1B*/ //u8 padding; } numberOne; // TVSHOW_SECRET_BASE_SECRETS @@ -426,12 +450,13 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u16 stepsInBase; /*0x04*/ u8 baseOwnersName[PLAYER_NAME_LENGTH + 1]; - /*0x0c*/ u32 flags; + /*0x0C*/ u32 flags; /*0x10*/ u16 item; /*0x12*/ u8 savedState; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; - /*0x1b*/ u8 language; - /*0x1c*/ u8 baseOwnersNameLanguage; + /*0x1B*/ u8 language; + /*0x1C*/ u8 baseOwnersNameLanguage; + /*0x1D*/ //u8 padding[3]; } secretBaseSecrets; // TVSHOW_SAFARI_FAN_CLUB @@ -463,6 +488,7 @@ typedef union // size = 0x24 /*0x15*/ u8 unused5; /*0x16*/ u16 daysLeft; /*0x18*/ u8 language; + /*0x19*/ //u8 padding; } massOutbreak; } TVShow; @@ -475,23 +501,23 @@ typedef struct struct GabbyAndTyData { - /*2ba4*/ u16 mon1; - /*2ba6*/ u16 mon2; - /*2ba8*/ u16 lastMove; - /*2baa*/ u16 quote[1]; - /*2bac*/ u8 mapnum; - /*2bad*/ u8 battleNum; - /*2bae*/ u8 battleTookMoreThanOneTurn:1; - /*2bae*/ u8 playerLostAMon:1; - /*2bae*/ u8 playerUsedHealingItem:1; - /*2bae*/ u8 playerThrewABall:1; - /*2bae*/ u8 onAir:1; - /*2bae*/ u8 valA_5:3; - /*2baf*/ u8 battleTookMoreThanOneTurn2:1; - /*2baf*/ u8 playerLostAMon2:1; - /*2baf*/ u8 playerUsedHealingItem2:1; - /*2baf*/ u8 playerThrewABall2:1; - /*2baf*/ u8 valB_4:4; + /*2BA4*/ u16 mon1; + /*2BA6*/ u16 mon2; + /*2BA8*/ u16 lastMove; + /*2BAA*/ u16 quote[1]; + /*2BAC*/ u8 mapnum; + /*2BAD*/ u8 battleNum; + /*2BAE*/ u8 battleTookMoreThanOneTurn:1; + u8 playerLostAMon:1; + u8 playerUsedHealingItem:1; + u8 playerThrewABall:1; + u8 onAir:1; + u8 valA_5:3; + /*2BAF*/ u8 battleTookMoreThanOneTurn2:1; + u8 playerLostAMon2:1; + u8 playerUsedHealingItem2:1; + u8 playerThrewABall2:1; + u8 valB_4:4; }; #endif //GUARD_GLOBAL_TV_H diff --git a/include/graphics.h b/include/graphics.h index 6c247e1ecd..df3f16e8f9 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -9956,6 +9956,8 @@ extern const u32 gBattleAnimSpriteGfx_Tornado[]; extern const u32 gBattleAnimSpritePal_Tornado[]; extern const u32 gBattleAnimSpriteGfx_ZMoveSymbol[]; extern const u32 gBattleAnimSpritePal_ZMoveSymbol[]; +extern const u32 gBattleAnimSpriteGfx_Teapot[]; +extern const u32 gBattleAnimSpritePal_Teapot[]; extern const u32 gBattleAnimBgImage_Dark[]; extern const u32 gBattleAnimBgImage_Ghost[]; diff --git a/include/link_rfu.h b/include/link_rfu.h index c576d04a1e..cf4bb2ca76 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -109,7 +109,7 @@ struct __attribute__((packed, aligned(2))) RfuGameData u8 playerGender:1; u8 tradeLevel:7; u8 tradeType:6; - u8 padding:2; + u8 filler:2; }; // Constants for getting/setting information in 'partnerInfo' of RfuGameData. diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 128f223a1a..ef97ab9a1c 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2429,19 +2429,41 @@ static bool32 PartyBattlerShouldAvoidHazards(u8 currBattler, u8 switchBattler) { struct Pokemon *mon = GetPartyBattlerPartyData(currBattler, switchBattler); u16 ability = GetMonAbility(mon); // we know our own party data - u16 holdEffect = GetBattlerHoldEffect(GetMonData(mon, MON_DATA_HELD_ITEM), TRUE); + u16 holdEffect; + u16 species = GetMonData(mon, MON_DATA_SPECIES); u32 flags = gSideStatuses[GetBattlerSide(currBattler)] & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES); + s32 hazardDamage = 0; + u8 type1 = gSpeciesInfo[species].type1; + u8 type2 = gSpeciesInfo[species].type2; + u32 maxHp = GetMonData(mon, MON_DATA_MAX_HP); if (flags == 0) return FALSE; - if (ability == ABILITY_MAGIC_GUARD || ability == ABILITY_LEVITATE - || holdEffect == HOLD_EFFECT_HEAVY_DUTY_BOOTS) + if (ability == ABILITY_MAGIC_GUARD) + return FALSE; + if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || ability == ABILITY_KLUTZ) + holdEffect = HOLD_EFFECT_NONE; + else + holdEffect = gItems[GetMonData(mon, MON_DATA_HELD_ITEM)].holdEffect; + if (holdEffect == HOLD_EFFECT_HEAVY_DUTY_BOOTS) return FALSE; - if (flags & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK) && GetMonData(mon, MON_DATA_HP) < (GetMonData(mon, MON_DATA_MAX_HP) / 8)) - return TRUE; + if (flags & SIDE_STATUS_STEALTH_ROCK) + hazardDamage += GetStealthHazardDamageByTypesAndHP(gBattleMoves[MOVE_STEALTH_ROCK].type, type1, type2, maxHp); + if (flags & SIDE_STATUS_SPIKES && ((type1 != TYPE_FLYING && type2 != TYPE_FLYING + && ability != ABILITY_LEVITATE && holdEffect != HOLD_EFFECT_AIR_BALLOON) + || holdEffect == HOLD_EFFECT_IRON_BALL || gFieldStatuses & STATUS_FIELD_GRAVITY)) + { + u8 spikesDmg = maxHp / ((5 - gSideTimers[GetBattlerSide(currBattler)].spikesAmount) * 2); + if (spikesDmg == 0) + spikesDmg = 1; + hazardDamage += spikesDmg; + } + + if (hazardDamage >= GetMonData(mon, MON_DATA_HP)) + return TRUE; return FALSE; } diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index 0db7f69d55..ea36b2eac9 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -2447,6 +2447,39 @@ const struct SpriteTemplate gFollowMeFingerSpriteTemplate = .callback = AnimFollowMeFinger, }; +const union AffineAnimCmd gTeaAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0), + AFFINEANIMCMD_FRAME(0x1E, 0x1E, 0, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gTeaAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -3, 11), + AFFINEANIMCMD_FRAME(0x0, 0x0, 3, 11), + AFFINEANIMCMD_LOOP(2), + AFFINEANIMCMD_FRAME(0xFFE2, 0xFFE2, 0, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gTeaAffineAnimTable[] = +{ + gTeaAffineAnimCmds1, + gTeaAffineAnimCmds2, +}; + +const struct SpriteTemplate gTeapotSpriteTemplate = +{ + .tileTag = ANIM_TAG_TEAPOT, + .paletteTag = ANIM_TAG_TEAPOT, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gTeaAffineAnimTable, + .callback = AnimMetronomeFinger, +}; + const union AnimCmd gTauntFingerAnimCmds1[] = { ANIMCMD_FRAME(0, 1), diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c index 0a65deb282..b3502fcb9e 100644 --- a/src/battle_anim_new.c +++ b/src/battle_anim_new.c @@ -7857,7 +7857,7 @@ static void SpriteCB_TwinkleOnBattler(struct Sprite *sprite) void AnimTask_PrimalReversion(u8 taskId) { - if (gBattleMons[gBattleAnimAttacker].item == ITEM_RED_ORB) + if (gBattleMons[gBattleAnimAttacker].item == ITEM_RED_ORB || gBattleMons[gBattleAnimAttacker].item == ITEM_BLUE_ORB) gBattleAnimArgs[0] = gBattleMons[gBattleAnimAttacker].item; else gBattleAnimArgs[0] = 0; diff --git a/src/battle_debug.c b/src/battle_debug.c index be7dbf715c..1fd2d9b00f 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -1759,7 +1759,7 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) { case LIST_ITEM_ABILITY: data->modifyArrows.minValue = 0; - data->modifyArrows.maxValue = ABILITIES_COUNT_GEN8 - 1; + data->modifyArrows.maxValue = ABILITIES_COUNT - 1; data->modifyArrows.maxDigits = 3; data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].ability; data->modifyArrows.typeOfVal = VAL_U16; diff --git a/src/battle_main.c b/src/battle_main.c index d138cf2311..56b009cbb7 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -101,7 +101,7 @@ static void SetActionsAndBattlersTurnOrder(void); static void UpdateBattlerPartyOrdersOnSwitch(void); static bool8 AllAtActionConfirmed(void); static void TryChangeTurnOrder(void); -static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void); +static void CheckChosenMoveForEffectsBeforeTurnStarts(void); static void CheckMegaEvolutionBeforeTurn(void); static void CheckQuickClaw_CustapBerryActivation(void); static void FreeResetData_ReturnToOvOrDoEvolutions(void); @@ -3039,6 +3039,7 @@ static void BattleStartClearSetData(void) gBattleStruct->stickyWebUser = 0xFF; gBattleStruct->appearedInBattle = 0; + gBattleStruct->beatUpSlot = 0; for (i = 0; i < PARTY_SIZE; i++) { @@ -4480,6 +4481,7 @@ u32 GetBattlerTotalSpeedStat(u8 battlerId) u32 speed = gBattleMons[battlerId].speed; u32 ability = GetBattlerAbility(battlerId); u32 holdEffect = GetBattlerHoldEffect(battlerId, TRUE); + u32 highestStat = GetHighestStatId(battlerId); // weather abilities if (WEATHER_HAS_EFFECT) @@ -4501,6 +4503,10 @@ u32 GetBattlerTotalSpeedStat(u8 battlerId) speed *= 2; else if (ability == ABILITY_SLOW_START && gDisableStructs[battlerId].slowStartTimer != 0) speed /= 2; + else if (ability == ABILITY_PROTOSYNTHESIS && gBattleWeather & B_WEATHER_SUN && highestStat == STAT_SPEED) + speed = (speed * 150) / 100; + else if (ability == ABILITY_QUARK_DRIVE && gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && highestStat == STAT_SPEED) + speed = (speed * 150) / 100; // stat stages speed *= gStatStageRatios[gBattleMons[battlerId].statStages[STAT_SPEED]][0]; @@ -4666,6 +4672,10 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves) strikesFirst = 1; else if (ability2 == ABILITY_STALL && ability1 != ABILITY_STALL) strikesFirst = 0; + else if (ability1 == ABILITY_MYCELIUM_MIGHT && ability2 != ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gCurrentMove)) + strikesFirst = 1; + else if (ability2 == ABILITY_MYCELIUM_MIGHT && ability1 != ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gCurrentMove)) + strikesFirst = 0; else { if (speedBattler1 == speedBattler2 && Random() & 1) @@ -4878,7 +4888,7 @@ static void CheckMegaEvolutionBeforeTurn(void) } #if B_MEGA_EVO_TURN_ORDER <= GEN_6 - gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; + gBattleMainFunc = CheckChosenMoveForEffectsBeforeTurnStarts; gBattleStruct->focusPunchBattlerId = 0; #else gBattleMainFunc = TryChangeTurnOrder; // This will just do nothing if no mon has mega evolved @@ -4903,11 +4913,11 @@ static void TryChangeTurnOrder(void) } } } - gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; + gBattleMainFunc = CheckChosenMoveForEffectsBeforeTurnStarts; gBattleStruct->focusPunchBattlerId = 0; } -static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void) +static void CheckChosenMoveForEffectsBeforeTurnStarts(void) { u32 i; @@ -4921,7 +4931,7 @@ static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void) && !(gDisableStructs[gBattlerAttacker].truantCounter) && !(gProtectStructs[gActiveBattler].noValidMoves)) { - switch(gChosenMoveByBattler[gActiveBattler]) + switch (gChosenMoveByBattler[gActiveBattler]) { case MOVE_FOCUS_PUNCH: BattleScriptExecute(BattleScript_FocusPunchSetUp); diff --git a/src/battle_message.c b/src/battle_message.c index 031261a289..1189cf3e1c 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -616,7 +616,7 @@ static const u8 sText_HealingWishCameTrue[] = _("The healing wish came true\nfor static const u8 sText_HealingWishHealed[] = _("{B_ATK_NAME_WITH_PREFIX} regained health!"); static const u8 sText_LunarDanceCameTrue[] = _("{B_ATK_NAME_WITH_PREFIX} became cloaked\nin mystical moonlight!"); static const u8 sText_CursedBodyDisabled[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was disabled\nby {B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}!"); -static const u8 sText_AttackerAquiredAbility[] = _("{B_ATK_NAME_WITH_PREFIX} acquired {B_LAST_ABILITY}!"); +static const u8 sText_AttackerAquiredAbility[] = _("{B_ATK_NAME_WITH_PREFIX} acquired\n{B_LAST_ABILITY}!"); static const u8 sText_TargetStatWontGoHigher[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}\nwon't go higher!"); static const u8 sText_PkmnMoveBouncedViaAbility[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} was\nbounced back by {B_DEF_NAME_WITH_PREFIX}'s\l{B_DEF_ABILITY}!"); static const u8 sText_ImposterTransform[] = _("{B_ATK_NAME_WITH_PREFIX} transformed into\n{B_DEF_NAME_WITH_PREFIX} using {B_LAST_ABILITY}!"); @@ -761,9 +761,21 @@ static const u8 sText_AttackerMeltedTheIce[] = _("{B_ATK_NAME_WITH_PREFIX} melte static const u8 sText_TargetToughedItOut[] = _("{B_DEF_NAME_WITH_PREFIX} toughed it out\nto show you its best side!"); static const u8 sText_AttackerLostElectricType[] = _("{B_ATK_NAME_WITH_PREFIX} used up all\nof its electricity!"); static const u8 sText_AttackerSwitchedStatWithTarget[] = _("{B_ATK_NAME_WITH_PREFIX} switched {B_BUFF1}\nwith its target!"); +static const u8 sText_BeingHitChargedPkmnWithPower[] = _("Being hit by {B_CURRENT_MOVE}\ncharged {B_ATK_NAME_WITH_PREFIX} with power!"); +static const u8 sText_SunlightActivatedAbility[] = _("The harsh sunlight activated\n{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}!"); +static const u8 sText_StatWasHeightened[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"); +static const u8 sText_ElectricTerrainActivatedAbility[] = _("The Electric Terrain activated\n{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}!"); +static const u8 sText_AbilityWeakenedSurroundingMonsStat[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nweakened the {B_BUFF1} of\lall surrounding Pokémon!\p"); +static const u8 sText_AttackerGainedStrengthFromTheFallen[] = _("{B_ATK_NAME_WITH_PREFIX} gained strength\nfrom the fallen!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN - BATTLESTRINGS_TABLE_START] = sText_AttackerGainedStrengthFromTheFallen, + [STRINGID_ABILITYWEAKENEDFSURROUNDINGMONSSTAT - BATTLESTRINGS_TABLE_START] = sText_AbilityWeakenedSurroundingMonsStat, + [STRINGID_ELECTRICTERRAINACTIVATEDABILITY - BATTLESTRINGS_TABLE_START] = sText_ElectricTerrainActivatedAbility, + [STRINGID_STATWASHEIGHTENED - BATTLESTRINGS_TABLE_START] = sText_StatWasHeightened, + [STRINGID_SUNLIGHTACTIVATEDABILITY - BATTLESTRINGS_TABLE_START] = sText_SunlightActivatedAbility, + [STRINGID_BEINGHITCHARGEDPKMNWITHPOWER - BATTLESTRINGS_TABLE_START] = sText_BeingHitChargedPkmnWithPower, [STRINGID_ATTACKERSWITCHEDSTATWITHTARGET - BATTLESTRINGS_TABLE_START] = sText_AttackerSwitchedStatWithTarget, [STRINGID_TARGETTOUGHEDITOUT - BATTLESTRINGS_TABLE_START] = sText_TargetToughedItOut, [STRINGID_ATTACKERMELTEDTHEICE - BATTLESTRINGS_TABLE_START] = sText_AttackerMeltedTheIce, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 9c780c28ee..e0ba27bec7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1808,7 +1808,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u if (atkHoldEffect == HOLD_EFFECT_WIDE_LENS) calc = (calc * (100 + atkParam)) / 100; - else if (atkHoldEffect == HOLD_EFFECT_ZOOM_LENS && GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef)); + else if (atkHoldEffect == HOLD_EFFECT_ZOOM_LENS && GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef)) calc = (calc * (100 + atkParam)) / 100; if (gProtectStructs[battlerAtk].usedMicleBerry) @@ -5757,7 +5757,8 @@ static void Cmd_moveend(void) if (gCurrentMove != MOVE_DRAGON_TAIL && gCurrentMove != MOVE_CIRCLE_THROW && IsBattlerAlive(gBattlerAttacker) - && !TestSheerForceFlag(gBattlerAttacker, gCurrentMove)) + && !TestSheerForceFlag(gBattlerAttacker, gCurrentMove) + && GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG) { // Since we check if battler was damaged, we don't need to check move result. // In fact, doing so actually prevents multi-target moves from activating red card properly @@ -7941,7 +7942,7 @@ static void HandleTerrainMove(u16 move) statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN; gBattleCommunication[MULTISTRING_CHOOSER] = 3; break; - case EFFECT_DAMAGE_SET_TERRAIN: + case EFFECT_HIT_SET_REMOVE_TERRAIN: switch (gBattleMoves[move].argument) { case 0: //genesis supernova @@ -8099,7 +8100,7 @@ static void RecalcBattlerStats(u32 battler, struct Pokemon *mon) gBattleMons[battler].type2 = gSpeciesInfo[gBattleMons[battler].species].type2; } -static u32 GetHighestStatId(u32 battlerId) +u32 GetHighestStatId(u32 battlerId) { u32 i, highestId = STAT_ATK, highestStat = gBattleMons[battlerId].attack; @@ -8130,6 +8131,67 @@ static bool32 IsRototillerAffected(u32 battlerId) return TRUE; } + +static bool32 IsAbilityRodAffected(void) +{ + u32 moveType; + + if (gBattleStruct->dynamicMoveType == 0) + moveType = gBattleMoves[gCurrentMove].type; + else if (!(gBattleStruct->dynamicMoveType & 0x40)) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[gCurrentMove].type; + + if (moveType == TYPE_ELECTRIC && GetBattlerAbility(gBattlerTarget) == ABILITY_LIGHTNING_ROD) + return TRUE; + else + return FALSE; +} + +static bool32 IsAbilityMotorAffected(void) +{ + u32 moveType; + + if (gBattleStruct->dynamicMoveType == 0) + moveType = gBattleMoves[gCurrentMove].type; + else if (!(gBattleStruct->dynamicMoveType & 0x40)) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[gCurrentMove].type; + + if (moveType == TYPE_ELECTRIC && GetBattlerAbility(gBattlerTarget) == ABILITY_MOTOR_DRIVE) + return TRUE; + else + return FALSE; +} + +static bool32 IsAbilityAbsorbAffected(void) +{ + u32 moveType; + + if (gBattleStruct->dynamicMoveType == 0) + moveType = gBattleMoves[gCurrentMove].type; + else if (!(gBattleStruct->dynamicMoveType & 0x40)) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[gCurrentMove].type; + + if (moveType == TYPE_ELECTRIC && GetBattlerAbility(gBattlerTarget) == ABILITY_VOLT_ABSORB) + return TRUE; + else + return FALSE; +} + +static bool32 IsTeatimeAffected(u32 battlerId) +{ + if (ItemId_GetPocket(gBattleMons[battlerId].item) != POCKET_BERRIES) + return FALSE; // Only berries + if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE) + return FALSE; // Teatime doesn't affected semi-invulnerable battlers + return TRUE; +} + #define COURTCHANGE_SWAP(status, structField, temp) \ { \ temp = gSideStatuses[B_SIDE_PLAYER]; \ @@ -9131,9 +9193,10 @@ static void Cmd_various(void) break; case VARIOUS_TRY_HIT_SWITCH_TARGET: if (IsBattlerAlive(gBattlerAttacker) - && IsBattlerAlive(gBattlerTarget) - && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && TARGET_TURN_DAMAGED) + && IsBattlerAlive(gBattlerTarget) + && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && TARGET_TURN_DAMAGED + && GetBattlerAbility(gBattlerTarget) != ABILITY_GUARD_DOG) { gBattleScripting.switchCase = B_SWITCH_HIT; gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch; @@ -10031,7 +10094,7 @@ static void Cmd_various(void) gBattleMons[gActiveBattler].item = gLastUsedItem; break; case VARIOUS_SET_BEAK_BLAST: - gProtectStructs[gBattlerAttacker].beakBlastCharge = TRUE; + gProtectStructs[gActiveBattler].beakBlastCharge = TRUE; break; case VARIOUS_SWAP_SIDE_STATUSES: CourtChangeSwapSideStatuses(); @@ -10098,6 +10161,70 @@ static void Cmd_various(void) PREPARE_STAT_BUFFER(gBattleTextBuff1, statId); } break; + case VARIOUS_TEATIME_TARGETS: + { + u32 count = 0; + + for (i = 0; i < gBattlersCount; i++) + { + if (IsTeatimeAffected(i)) + count++; + } + if (count == 0) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Teatime fails + else + gBattlescriptCurrInstr += 7; + } + return; + case VARIOUS_TEATIME_INVUL: + if (ItemId_GetPocket(gBattleMons[gActiveBattler].item) == POCKET_BERRIES && !(gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE))) + gBattlescriptCurrInstr += 7; + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + return; + case VARIOUS_JUMP_IF_ROD: + if (IsAbilityRodAffected()) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; + return; + case VARIOUS_JUMP_IF_MOTOR: + if (IsAbilityMotorAffected()) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; + return; + case VARIOUS_JUMP_IF_ABSORB: + if (IsAbilityAbsorbAffected()) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; + return; + case VARIOUS_TRY_WIND_RIDER_POWER: + { + u16 ability = GetBattlerAbility(gActiveBattler); + if (GetBattlerSide(gActiveBattler) == GetBattlerSide(gBattlerAttacker) + && (ability == ABILITY_WIND_RIDER || ability == ABILITY_WIND_POWER)) + { + gLastUsedAbility = ability; + RecordAbilityBattle(gActiveBattler, gLastUsedAbility); + gBattlerAbility = gBattleScripting.battler = gActiveBattler; + gBattlescriptCurrInstr += 7; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + } + return; + case VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES: + gBattlescriptCurrInstr += 3; + AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, gActiveBattler, 0, 0, 0); + return; + case VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES: + gBattlescriptCurrInstr += 3; + AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0); + return; } // End of switch (gBattlescriptCurrInstr[2]) gBattlescriptCurrInstr += 3; @@ -10776,7 +10903,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr else if ((activeBattlerAbility == ABILITY_CLEAR_BODY || activeBattlerAbility == ABILITY_FULL_METAL_BODY || activeBattlerAbility == ABILITY_WHITE_SMOKE) - && !certain && gCurrentMove != MOVE_CURSE) + && !affectsUser && !certain && gCurrentMove != MOVE_CURSE) { if (flags == STAT_CHANGE_ALLOW_PTR) { @@ -11926,8 +12053,9 @@ static void Cmd_trysetencore(void) } if (gLastMoves[gBattlerTarget] == MOVE_STRUGGLE - || gLastMoves[gBattlerTarget] == MOVE_ENCORE - || gLastMoves[gBattlerTarget] == MOVE_MIRROR_MOVE) + || gLastMoves[gBattlerTarget] == MOVE_ENCORE + || gLastMoves[gBattlerTarget] == MOVE_MIRROR_MOVE + || gLastMoves[gBattlerTarget] == MOVE_SHELL_TRAP) { i = MAX_MON_MOVES; } @@ -12855,6 +12983,10 @@ static void Cmd_trysetfutureattack(void) static void Cmd_trydobeatup(void) { +#if B_BEAT_UP >= GEN_5 + gBattleStruct->beatUpSlot++; + gBattlescriptCurrInstr += 9; +#else struct Pokemon *party; if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) @@ -12898,6 +13030,7 @@ static void Cmd_trydobeatup(void) else gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5); } +#endif } static void Cmd_setsemiinvulnerablebit(void) diff --git a/src/battle_tv.c b/src/battle_tv.c index 9d2ec244e8..33483da061 100644 --- a/src/battle_tv.c +++ b/src/battle_tv.c @@ -476,7 +476,7 @@ static const u16 sPoints_MoveEffect[NUM_BATTLE_MOVE_EFFECTS] = [EFFECT_COURT_CHANGE] = 0, // TODO: Assign points [EFFECT_STEEL_BEAM] = 0, // TODO: Assign points [EFFECT_EXTREME_EVOBOOST] = 0, // TODO: Assign points - [EFFECT_DAMAGE_SET_TERRAIN] = 0, // TODO: Assign points + [EFFECT_HIT_SET_REMOVE_TERRAIN] = 0, // TODO: Assign points [EFFECT_DARK_VOID] = 0, // TODO: Assign points [EFFECT_SLEEP_HIT] = 1, [EFFECT_DOUBLE_SHOCK] = 0, // TODO: Assign points diff --git a/src/battle_util.c b/src/battle_util.c index 00e3b869b1..cf65ee88e0 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -230,8 +230,9 @@ static u8 CalcBeatUpPower(void) party = gPlayerParty; else party = gEnemyParty; - // Party slot is set in the battle script for Beat Up - species = GetMonData(&party[gBattleCommunication[0] - 1], MON_DATA_SPECIES); + + // Party slot is incremented by the battle script for Beat Up after this damage calculation + species = GetMonData(&party[gBattleStruct->beatUpSlot], MON_DATA_SPECIES); basePower = (gSpeciesInfo[species].baseAttack / 10) + 5; return basePower; @@ -419,7 +420,7 @@ void HandleAction_UseMove(void) battlerAbility = GetBattlerAbility(gActiveBattler); RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); - if (battlerAbility == ABILITY_LIGHTNING_ROD) + if (battlerAbility == ABILITY_LIGHTNING_ROD && gCurrentMove != MOVE_TEATIME) gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE; else if (battlerAbility == ABILITY_STORM_DRAIN) gSpecialStatuses[gActiveBattler].stormDrainRedirected = TRUE; @@ -1065,6 +1066,11 @@ static const u8 sAbilitiesAffectedByMoldBreaker[] = [ABILITY_ICE_SCALES] = 1, [ABILITY_ICE_FACE] = 1, [ABILITY_PASTEL_VEIL] = 1, + [ABILITY_ARMOR_TAIL] = 1, + [ABILITY_EARTH_EATER] = 1, + [ABILITY_GOOD_AS_GOLD] = 1, + [ABILITY_PURIFYING_SALT] = 1, + [ABILITY_WELL_BAKED_BODY] = 1, }; static const u8 sAbilitiesNotTraced[ABILITIES_COUNT] = @@ -2654,6 +2660,7 @@ enum ENDTURN_THROAT_CHOP, ENDTURN_SLOW_START, ENDTURN_PLASMA_FISTS, + ENDTURN_CUD_CHEW, ENDTURN_BATTLER_COUNT }; @@ -3195,6 +3202,11 @@ u8 DoBattlerEndTurnEffects(void) gStatuses4[gActiveBattler] &= ~STATUS4_PLASMA_FISTS; gBattleStruct->turnEffectsTracker++; break; + case ENDTURN_CUD_CHEW: + if (GetBattlerAbility(gActiveBattler) == ABILITY_CUD_CHEW && !gDisableStructs[gActiveBattler].cudChew && ItemId_GetPocket(GetUsedHeldItem(gActiveBattler)) == POCKET_BERRIES) + gDisableStructs[gActiveBattler].cudChew = TRUE; + gBattleStruct->turnEffectsTracker++; + break; case ENDTURN_BATTLER_COUNT: // done gBattleStruct->turnEffectsTracker = 0; gBattleStruct->turnEffectsBattlerId++; @@ -3875,7 +3887,7 @@ u8 AtkCanceller_UnableToUseMove(void) gMultiHitCounter++; } - gBattleCommunication[0] = 0; // For later + gBattleStruct->beatUpSlot = 0; PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) } #endif @@ -4719,6 +4731,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITY_ELECTRIC_SURGE: + case ABILITY_HADRON_ENGINE: if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.terrainTimer)) { BattleScriptPushCursorAndCallback(BattleScript_ElectricSurgeActivates); @@ -4755,19 +4768,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; - case ABILITY_FORECAST: -#if B_WEATHER_FORMS >= GEN_5 - case ABILITY_FLOWER_GIFT: -#else - TRY_WEATHER_FORM: -#endif - effect = TryWeatherFormChange(battler); - if (effect != 0) - { - BattleScriptPushCursorAndCallback(BattleScript_WeatherFormChange); - *(&gBattleStruct->formToChangeInto) = effect - 1; - } - break; case ABILITY_TRACE: if (!(gSpecialStatuses[battler].traced)) { @@ -4842,6 +4842,89 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; + case ABILITY_PROTOSYNTHESIS: + if (!gSpecialStatuses[battler].switchInAbilityDone && gBattleWeather & B_WEATHER_SUN) + { + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + BattleScriptPushCursorAndCallback(BattleScript_ProtosynthesisActivates); + effect++; + } + break; + case ABILITY_QUARK_DRIVE: + if (!gSpecialStatuses[battler].switchInAbilityDone && gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + { + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); + effect++; + } + break; + case ABILITY_VESSEL_OF_RUIN: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK); + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + BattleScriptPushCursorAndCallback(BattleScript_RuinAbilityActivates); + effect++; + } + break; + case ABILITY_SWORD_OF_RUIN: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_DEF); + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + BattleScriptPushCursorAndCallback(BattleScript_RuinAbilityActivates); + effect++; + } + break; + case ABILITY_TABLETS_OF_RUIN: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK); + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + BattleScriptPushCursorAndCallback(BattleScript_RuinAbilityActivates); + effect++; + } + break; + case ABILITY_BEADS_OF_RUIN: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPDEF); + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + BattleScriptPushCursorAndCallback(BattleScript_RuinAbilityActivates); + effect++; + } + break; + case ABILITY_ORICHALCUM_PULSE: + if (TryChangeBattleWeather(battler, ENUM_WEATHER_SUN, TRUE)) + { + BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates); + effect++; + } + break; + case ABILITY_SUPREME_OVERLORD: + if (!gSpecialStatuses[battler].switchInAbilityDone && CountUsablePartyMons(battler) < PARTY_SIZE) + { + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + BattleScriptPushCursorAndCallback(BattleScript_SupremeOverlordActivates); + effect++; + } + break; + case ABILITY_COSTAR: + if (!gSpecialStatuses[battler].switchInAbilityDone + && IsDoubleBattle() + && IsBattlerAlive(BATTLE_PARTNER(battler)) + && CountBattlerStatIncreases(BATTLE_PARTNER(battler), FALSE)) + { + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + for (i = 0; i < NUM_BATTLE_STATS; i++) + gBattleMons[battler].statStages[i] = gBattleMons[BATTLE_PARTNER(battler)].statStages[i]; + gBattlerTarget = BATTLE_PARTNER(battler); + BattleScriptPushCursorAndCallback(BattleScript_CostarActivates); + effect++; + } + break; #if B_WEATHER_FORMS < GEN_5 default: if (gBattleMons[battler].species == SPECIES_CHERRIM) @@ -5045,48 +5128,66 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; + case ABILITY_CUD_CHEW: + if (ItemId_GetPocket(GetUsedHeldItem(battler)) == POCKET_BERRIES && gDisableStructs[gActiveBattler].cudChew == TRUE) + { + gLastUsedItem = gBattleStruct->usedHeldItems[battler][GetBattlerSide(battler)]; + gBattleStruct->usedHeldItems[battler][GetBattlerSide(battler)] = ITEM_NONE; + BattleScriptPushCursorAndCallback(BattleScript_CudChewActivates); + effect++; + } + break; } } break; case ABILITYEFFECT_MOVES_BLOCK: // 2 - { - u16 moveTarget = GetBattlerMoveTargetType(battler, move); + { + u16 moveTarget = GetBattlerMoveTargetType(battler, move); + u16 battlerAbility = GetBattlerAbility(battler); + u16 targetAbility = GetBattlerAbility(gBattlerTarget); - if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && !(moveTarget & MOVE_TARGET_USER)) - || (gLastUsedAbility == ABILITY_BULLETPROOF && gBattleMoves[move].flags & FLAG_BALLISTIC)) - { - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS) - gHitMarker |= HITMARKER_NO_PPDEDUCT; - gBattlescriptCurrInstr = BattleScript_SoundproofProtected; - effect = 1; + if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && !(moveTarget & MOVE_TARGET_USER)) + || (gLastUsedAbility == ABILITY_BULLETPROOF && gBattleMoves[move].flags & FLAG_BALLISTIC)) + { + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS) + gHitMarker |= HITMARKER_NO_PPDEDUCT; + gBattlescriptCurrInstr = BattleScript_SoundproofProtected; + effect = 1; + } + else if ((gLastUsedAbility == ABILITY_DAZZLING || gLastUsedAbility == ABILITY_QUEENLY_MAJESTY || gLastUsedAbility == ABILITY_ARMOR_TAIL || IsBattlerAlive(battler ^= BIT_FLANK)) + && (battlerAbility == ABILITY_DAZZLING || battlerAbility == ABILITY_QUEENLY_MAJESTY || battlerAbility == ABILITY_ARMOR_TAIL) + && GetChosenMovePriority(gBattlerAttacker) > 0 + && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(battler)) + { + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS) + gHitMarker |= HITMARKER_NO_PPDEDUCT; + gBattlescriptCurrInstr = BattleScript_DazzlingProtected; + effect = 1; + } + else if (BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE) && !(IS_MOVE_STATUS(move) && targetAbility == ABILITY_MAGIC_BOUNCE)) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) + CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected + gBattleScripting.battler = gBattlerAbility = gBattlerTarget; + gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster; + effect = 1; + } + else if (GetBattlerAbility(gBattlerTarget) == ABILITY_GOOD_AS_GOLD + && IS_MOVE_STATUS(gCurrentMove) + && !(moveTarget & MOVE_TARGET_USER) + && !(moveTarget & MOVE_TARGET_OPPONENTS_FIELD) + && !(moveTarget & MOVE_TARGET_ALL_BATTLERS)) + { + gBattlescriptCurrInstr = BattleScript_GoodAsGoldActivates; + effect = 1; + } + break; } - else if ((((gLastUsedAbility == ABILITY_DAZZLING || gLastUsedAbility == ABILITY_QUEENLY_MAJESTY - || (IsBattlerAlive(battler ^= BIT_FLANK) - && ((GetBattlerAbility(battler) == ABILITY_DAZZLING) || GetBattlerAbility(battler) == ABILITY_QUEENLY_MAJESTY))) - )) - && GetChosenMovePriority(gBattlerAttacker) > 0 - && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(battler)) - { - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS) - gHitMarker |= HITMARKER_NO_PPDEDUCT; - gBattlescriptCurrInstr = BattleScript_DazzlingProtected; - effect = 1; - } - else if (BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE) - && !(IS_MOVE_STATUS(move) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE)) - { - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) - CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected - gBattleScripting.battler = gBattlerAbility = gBattlerTarget; - gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster; - effect = 1; - } - break; - } case ABILITYEFFECT_ABSORBING: // 3 if (move != MOVE_NONE) { u8 statId; + u8 statAmount = 1; switch (gLastUsedAbility) { case ABILITY_VOLT_ABSORB: @@ -5144,6 +5245,18 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } } break; + case ABILITY_WELL_BAKED_BODY: + if (moveType == TYPE_FIRE) + effect = 2, statId = STAT_DEF, statAmount = 2; + break; + case ABILITY_WIND_RIDER: + if (gBattleMoves[gCurrentMove].flags & FLAG_WIND_MOVE && !(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove) & MOVE_TARGET_USER)) + effect = 2, statId = STAT_ATK; + break; + case ABILITY_EARTH_EATER: + if (moveType == TYPE_GROUND) + effect = 1; + break; } if (effect == 1) // Drain Hp ability. @@ -5188,9 +5301,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move else gBattlescriptCurrInstr = BattleScript_MoveStatDrain_PPLoss; - SET_STATCHANGER(statId, 1, FALSE); + SET_STATCHANGER(statId, statAmount, FALSE); + #if B_ABSORBING_ABILITY_STRING < GEN_5 gBattleMons[battler].statStages[statId]++; PREPARE_STAT_BUFFER(gBattleTextBuff1, statId); + #endif } } } @@ -5324,11 +5439,13 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; + case ABILITY_LINGERING_AROMA: case ABILITY_MUMMY: if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED - && (IsMoveMakingContact(move, gBattlerAttacker))) + && IsMoveMakingContact(move, gBattlerAttacker) + && gBattleStruct->overwrittenAbilities[gBattlerAttacker] != GetBattlerAbility(gBattlerTarget)) { switch (gBattleMons[gBattlerAttacker].ability) { @@ -5344,7 +5461,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITY_STANCE_CHANGE: break; default: - gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = ABILITY_MUMMY; + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MummyActivates; effect++; @@ -5691,6 +5808,75 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } } break; + case ABILITY_SEED_SOWER: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && TARGET_TURN_DAMAGED + && IsBattlerAlive(gBattlerTarget) + && TryChangeBattleTerrain(gBattlerTarget, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer)) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SeedSowerActivates; + effect++; + } + break; + case ABILITY_THERMAL_EXCHANGE: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && TARGET_TURN_DAMAGED + && IsBattlerAlive(gBattlerTarget) + && CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) + && moveType == TYPE_FIRE) + { + gEffectBattler = gBattlerTarget; + SET_STATCHANGER(STAT_ATK, 1, FALSE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TargetAbilityStatRaiseRet; + effect++; + } + break; + case ABILITY_ANGER_SHELL: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && TARGET_TURN_DAMAGED + && (gBattleMons[gBattlerTarget].hp <= gBattleMons[gBattlerTarget].maxHP / 2) + && !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove))) + { + gBattlerAttacker = gBattlerTarget; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AngerShellActivates; + effect++; + } + break; + case ABILITY_WIND_POWER: + if (!(gBattleMoves[gCurrentMove].flags & FLAG_WIND_MOVE)) + break; + // fall through + case ABILITY_ELECTROMORPHOSIS: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && TARGET_TURN_DAMAGED + && IsBattlerAlive(gBattlerTarget)) + { + gBattlerAttacker = gBattlerTarget; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WindPowerActivates; + effect++; + } + break; + case ABILITY_TOXIC_DEBRIS: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && IS_MOVE_PHYSICAL(gCurrentMove) + && TARGET_TURN_DAMAGED + && !(gSideStatuses[gBattlerAttacker] & SIDE_STATUS_TOXIC_SPIKES) + && IsBattlerAlive(gBattlerTarget)) + { + gBattlerTarget = gBattlerAttacker; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ToxicDebrisActivates; + effect++; + } + break; } break; case ABILITYEFFECT_MOVE_END_ATTACKER: // Same as above, but for attacker @@ -6022,6 +6208,47 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move break; } break; + case ABILITYEFFECT_ON_WEATHER: // For ability effects that activate when the battle weather changes. + battler = gBattlerAbility = gBattlerAttacker = gBattleScripting.battler; + switch (GetBattlerAbility(battler)) + { + case ABILITY_FORECAST: +#if B_WEATHER_FORMS >= GEN_5 + case ABILITY_FLOWER_GIFT: +#else + TRY_WEATHER_FORM: +#endif + effect = TryWeatherFormChange(battler); + if (effect != 0) + { + BattleScriptPushCursorAndCallback(BattleScript_WeatherFormChange); + *(&gBattleStruct->formToChangeInto) = effect - 1; + } + break; + case ABILITY_PROTOSYNTHESIS: + if (IsBattlerWeatherAffected(battler, B_WEATHER_SUN)) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + BattleScriptPushCursorAndCallback(BattleScript_ProtosynthesisActivates); + effect++; + } + break; + } + break; + case ABILITYEFFECT_ON_TERRAIN: // For ability effects that activate when the field terrain changes. + battler = gBattlerAbility = gBattlerAttacker = gBattleScripting.battler; + switch (GetBattlerAbility(battler)) + { + case ABILITY_QUARK_DRIVE: + if (IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); + BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); + effect++; + } + break; + } + break; } if (effect && gLastUsedAbility != 0xFF) @@ -6068,6 +6295,19 @@ bool32 IsNeutralizingGasOnField(void) return FALSE; } +bool32 IsMyceliumMightOnField(void) +{ + u32 i; + + for (i = 0; i < gBattlersCount; i++) + { + if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gCurrentMove)) + return TRUE; + } + + return FALSE; +} + u32 GetBattlerAbility(u8 battlerId) { if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID) @@ -6076,6 +6316,9 @@ u32 GetBattlerAbility(u8 battlerId) if (IsNeutralizingGasOnField() && !IsNeutralizingGasBannedAbility(gBattleMons[battlerId].ability)) return ABILITY_NONE; + if (IsMyceliumMightOnField()) + return ABILITY_NONE; + if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER || gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT || gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE) @@ -6249,6 +6492,7 @@ bool32 CanBeBurned(u8 battlerId) || ability == ABILITY_WATER_VEIL || ability == ABILITY_WATER_BUBBLE || ability == ABILITY_COMATOSE + || ability == ABILITY_THERMAL_EXCHANGE || IsAbilityStatusProtected(battlerId) || IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN)) return FALSE; @@ -7981,6 +8225,11 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move) else if (gProtectStructs[battlerId].protected) return FALSE; } + + if (move == MOVE_TEATIME) + { + return FALSE; + } // Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here. // This means extra logic is needed to handle Shell Side Arm. @@ -8499,17 +8748,41 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) return basePower; } +// Supreme Overlord adds a damage boost for each fainted ally. +// The first ally adds a x1.2 boost, and subsequent allies add an extra x0.1 boost each. +static u16 GetSupremeOverlordModifier(u8 battlerId) +{ + u32 i; + u8 side = GetBattlerSide(battlerId); + struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty; + u16 modifier = UQ_4_12(1.0); + bool8 appliedFirstBoost = FALSE; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[i], MON_DATA_IS_EGG) + && GetMonData(&party[i], MON_DATA_HP) == 0) + modifier += (!appliedFirstBoost) ? UQ_4_12(0.2) : UQ_4_12(0.1); + appliedFirstBoost = TRUE; + } + + return modifier; +} + static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, bool32 updateFlags) { - u32 i, ability; + u32 i; u32 holdEffectAtk, holdEffectParamAtk; u16 basePower = CalcMoveBasePower(move, battlerAtk, battlerDef); u16 holdEffectModifier; u16 modifier = UQ_4_12(1.0); u32 atkSide = GET_BATTLER_SIDE(battlerAtk); + u16 atkAbility = GetBattlerAbility(battlerAtk); + u16 defAbility = GetBattlerAbility(battlerDef); // attacker's abilities - switch (GetBattlerAbility(battlerAtk)) + switch (atkAbility) { case ABILITY_TECHNICIAN: if (basePower <= 60) @@ -8615,11 +8888,44 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe if (IS_MOVE_PHYSICAL(move)) MulModifier(&modifier, UQ_4_12(1.5)); break; + case ABILITY_ROCKY_PAYLOAD: + if (moveType == TYPE_ROCK) + MulModifier(&modifier, UQ_4_12(1.5)); + break; + case ABILITY_PROTOSYNTHESIS: + { + u8 atkHighestStat = GetHighestStatId(battlerAtk); + if (gBattleWeather & B_WEATHER_SUN && WEATHER_HAS_EFFECT && (atkHighestStat == STAT_ATK || atkHighestStat == STAT_SPATK)) + MulModifier(&modifier, UQ_4_12(1.3)); + } + break; + case ABILITY_QUARK_DRIVE: + { + u8 atkHighestStat = GetHighestStatId(battlerAtk); + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && (atkHighestStat == STAT_ATK || atkHighestStat == STAT_SPATK)) + MulModifier(&modifier, UQ_4_12(1.3)); + } + break; + case ABILITY_ORICHALCUM_PULSE: + if (gBattleWeather & B_WEATHER_SUN && WEATHER_HAS_EFFECT) + MulModifier(&modifier, UQ_4_12(1.3)); + break; + case ABILITY_HADRON_ENGINE: + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + MulModifier(&modifier, UQ_4_12(1.3)); + break; + case ABILITY_SHARPNESS: + if (gBattleMoves[move].flags & FLAG_SLICING_MOVE) + MulModifier(&modifier, UQ_4_12(1.5)); + break; + case ABILITY_SUPREME_OVERLORD: + MulModifier(&modifier, GetSupremeOverlordModifier(battlerAtk)); + break; } // field abilities if ((IsAbilityOnField(ABILITY_DARK_AURA) && moveType == TYPE_DARK) - || (IsAbilityOnField(ABILITY_FAIRY_AURA) && moveType == TYPE_FAIRY)) + || (IsAbilityOnField(ABILITY_FAIRY_AURA) && moveType == TYPE_FAIRY)) { if (IsAbilityOnField(ABILITY_AURA_BREAK)) MulModifier(&modifier, UQ_4_12(0.75)); @@ -8627,6 +8933,18 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe MulModifier(&modifier, UQ_4_12(1.33)); } + if (IsAbilityOnField(ABILITY_VESSEL_OF_RUIN) && atkAbility != ABILITY_VESSEL_OF_RUIN && IS_MOVE_SPECIAL(gCurrentMove)) + MulModifier(&modifier, UQ_4_12(0.25)); + + if (IsAbilityOnField(ABILITY_SWORD_OF_RUIN) && defAbility != ABILITY_SWORD_OF_RUIN && IS_MOVE_PHYSICAL(gCurrentMove)) + MulModifier(&modifier, UQ_4_12(0.25)); + + if (IsAbilityOnField(ABILITY_TABLETS_OF_RUIN) && atkAbility != ABILITY_TABLETS_OF_RUIN && IS_MOVE_PHYSICAL(gCurrentMove)) + MulModifier(&modifier, UQ_4_12(0.25)); + + if (IsAbilityOnField(ABILITY_BEADS_OF_RUIN) && defAbility != ABILITY_BEADS_OF_RUIN && IS_MOVE_SPECIAL(gCurrentMove)) + MulModifier(&modifier, UQ_4_12(0.25)); + // attacker partner's abilities if (IsBattlerAlive(BATTLE_PARTNER(battlerAtk))) { @@ -8647,8 +8965,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe } // target's abilities - ability = GetBattlerAbility(battlerDef); - switch (ability) + switch (defAbility) { case ABILITY_HEATPROOF: case ABILITY_WATER_BUBBLE: @@ -8656,7 +8973,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe { MulModifier(&modifier, UQ_4_12(0.5)); if (updateFlags) - RecordAbilityBattle(battlerDef, ability); + RecordAbilityBattle(battlerDef, defAbility); } break; case ABILITY_DRY_SKIN: @@ -8668,11 +8985,25 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe { MulModifier(&modifier, UQ_4_12(0.5)); if (updateFlags) - RecordAbilityBattle(battlerDef, ability); + RecordAbilityBattle(battlerDef, defAbility); } if (moveType == TYPE_FIRE) MulModifier(&modifier, UQ_4_12(2.0)); break; + case ABILITY_PROTOSYNTHESIS: + { + u8 defHighestStat = GetHighestStatId(battlerDef); + if (gBattleWeather & B_WEATHER_SUN && WEATHER_HAS_EFFECT && (defHighestStat == STAT_DEF || defHighestStat == STAT_SPDEF)) + MulModifier(&modifier, UQ_4_12(0.7)); + } + break; + case ABILITY_QUARK_DRIVE: + { + u8 defHighestStat = GetHighestStatId(battlerDef); + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && (defHighestStat == STAT_DEF || defHighestStat == STAT_SPDEF)) + MulModifier(&modifier, UQ_4_12(0.7)); + } + break; } holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE); @@ -8799,7 +9130,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe #define TERRAIN_TYPE_BOOST UQ_4_12(1.5) #endif - // various effecs + // various effects if (gProtectStructs[battlerAtk].helpingHand) MulModifier(&modifier, UQ_4_12(1.5)); if (gStatuses3[battlerAtk] & STATUS3_CHARGED_UP && moveType == TYPE_ELECTRIC) @@ -9129,6 +9460,10 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, if (gBattleMoves[move].flags & FLAG_SOUND) MulModifier(&modifier, UQ_4_12(2.0)); break; + case ABILITY_PURIFYING_SALT: + if (gBattleMoves[move].type == TYPE_GHOST) + MulModifier(&modifier, UQ_4_12(2.0)); + break; } // ally's abilities @@ -9197,7 +9532,11 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move // check multiple targets in double battle if (GetMoveTargetCount(move, battlerAtk, battlerDef) >= 2) + #if B_MULTIPLE_TARGETS_DMG >= GEN_4 MulModifier(&finalModifier, UQ_4_12(0.75)); + #else + MulModifier(&finalModifier, UQ_4_12(0.5)); + #endif // take type effectiveness MulModifier(&finalModifier, typeEffectivenessModifier); @@ -9596,11 +9935,8 @@ u16 GetTypeModifier(u8 atkType, u8 defType) return sTypeEffectivenessTable[atkType][defType]; } -s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId) +s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp) { - u8 type1 = gBattleMons[battlerId].type1; - u8 type2 = gBattleMons[battlerId].type2; - u32 maxHp = gBattleMons[battlerId].maxHP; s32 dmg = 0; u16 modifier = UQ_4_12(1.0); @@ -9643,6 +9979,15 @@ s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId) return dmg; } +s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId) +{ + u8 type1 = gBattleMons[battlerId].type1; + u8 type2 = gBattleMons[battlerId].type2; + u32 maxHp = gBattleMons[battlerId].maxHP; + + return GetStealthHazardDamageByTypesAndHP(hazardType, type1, type2, maxHp); +} + bool32 IsPartnerMonFromSameTrainer(u8 battlerId) { if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h index e6e03f06c1..5be53fe661 100644 --- a/src/data/battle_anim.h +++ b/src/data/battle_anim.h @@ -1450,6 +1450,7 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] = {gBattleAnimSpriteGfx_OmegaSymbol, 0x0200, ANIM_TAG_OMEGA_SYMBOL}, {gBattleAnimSpriteGfx_Orbs, 0x0180, ANIM_TAG_STEEL_BEAM}, {gBattleAnimSpriteGfx_AuraSphere, 0x200, ANIM_TAG_POLTERGEIST}, + {gBattleAnimSpriteGfx_Teapot, 0x1800, ANIM_TAG_TEAPOT}, }; const struct CompressedSpritePalette gBattleAnimPaletteTable[] = @@ -1900,6 +1901,7 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] = {gBattleAnimSpritePal_OmegaSymbol, ANIM_TAG_OMEGA_SYMBOL}, {gBattleAnimSpritePal_SteelBeam, ANIM_TAG_STEEL_BEAM}, {gBattleAnimSpritePal_Poltergeist, ANIM_TAG_POLTERGEIST}, + {gBattleAnimSpritePal_Teapot, ANIM_TAG_TEAPOT}, }; const struct BattleAnimBackground gBattleAnimBackgroundTable[] = diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index ef4d150396..f5cc351f2b 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -256,7 +256,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 100, .zMoveEffect = Z_EFFECT_NONE, @@ -272,7 +272,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_DMG_2X_IN_AIR, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_DMG_2X_IN_AIR | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMovePower = 100, .zMoveEffect = Z_EFFECT_NONE, @@ -298,7 +298,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = { #if B_UPDATED_MOVE_DATA >= GEN_6 .accuracy = 0, - .flags = FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_WIND_MOVE, #elif B_UPDATED_MOVE_DATA == GEN_5 .accuracy = 100, .flags = FLAG_PROTECT_AFFECTED | FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, @@ -1073,7 +1073,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 10, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMoveEffect = Z_EFFECT_NONE, }, @@ -1354,7 +1354,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 100, .zMoveEffect = Z_EFFECT_NONE, @@ -2932,7 +2932,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 140, .zMoveEffect = Z_EFFECT_NONE, @@ -3541,7 +3541,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 100, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMovePower = 100, .zMoveEffect = Z_EFFECT_NONE, @@ -3643,7 +3643,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, - .flags = 0, + .flags = FLAG_WIND_MOVE, .split = SPLIT_STATUS, .zMovePower = 0, .zMoveEffect = Z_EFFECT_SPD_UP_1, @@ -3819,7 +3819,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 100, .zMoveEffect = Z_EFFECT_NONE, @@ -4304,7 +4304,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = [MOVE_TWISTER] = { #if B_UPDATED_MOVE_DATA >= GEN_5 - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_2X_IN_AIR, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_2X_IN_AIR | FLAG_WIND_MOVE, #else .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_2X_IN_AIR, #endif @@ -4677,7 +4677,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 10, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMoveEffect = Z_EFFECT_NONE, }, @@ -5674,7 +5674,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SLICING_MOVE | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMoveEffect = Z_EFFECT_NONE, }, @@ -6007,7 +6007,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 120, .zMoveEffect = Z_EFFECT_NONE, @@ -6304,7 +6304,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMoveEffect = Z_EFFECT_NONE, }, @@ -6635,7 +6635,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, .priority = 0, - .flags = FLAG_SNATCH_AFFECTED, + .flags = FLAG_SNATCH_AFFECTED | FLAG_WIND_MOVE, .split = SPLIT_STATUS, .zMovePower = 0, .zMoveEffect = Z_EFFECT_BOOST_CRITS, @@ -7239,7 +7239,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 140, .zMoveEffect = Z_EFFECT_NONE, @@ -7281,7 +7281,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = { #if B_UPDATED_MOVE_DATA >= GEN_6 .pp = 15, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SLICING_MOVE, #elif B_UPDATED_MOVE_DATA == GEN_5 .pp = 20, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, @@ -7311,7 +7311,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 160, .zMoveEffect = Z_EFFECT_NONE, @@ -7721,7 +7721,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 140, .zMoveEffect = Z_EFFECT_NONE, @@ -7943,7 +7943,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 10, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIGH_CRIT | FLAG_SHEER_FORCE_BOOST | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 140, .zMoveEffect = Z_EFFECT_NONE, @@ -9559,7 +9559,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_STAT_STAGES_IGNORED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_STAT_STAGES_IGNORED | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 175, .zMoveEffect = Z_EFFECT_NONE, @@ -9575,7 +9575,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 50, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 140, .zMoveEffect = Z_EFFECT_NONE, @@ -9713,7 +9713,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_IN_AIR, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_IN_AIR | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMoveEffect = Z_EFFECT_NONE, }, @@ -10223,7 +10223,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_FOES_AND_ALLY, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_WIND_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 175, .zMoveEffect = Z_EFFECT_NONE, @@ -10422,7 +10422,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMovePower = 100, .zMoveEffect = Z_EFFECT_NONE, @@ -11208,7 +11208,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 190, .zMoveEffect = Z_EFFECT_NONE, @@ -12351,13 +12351,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = [MOVE_TEATIME] = { - .effect = EFFECT_PLACEHOLDER, //TODO + .effect = EFFECT_TEATIME, .power = 0, .type = TYPE_NORMAL, .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_ALL_BATTLERS, + .target = MOVE_TARGET_USER, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -12535,7 +12535,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 180, .zMoveEffect = Z_EFFECT_NONE, @@ -13334,7 +13334,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 120, .zMoveEffect = Z_EFFECT_NONE, @@ -13354,7 +13354,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMovePower = 175, .zMoveEffect = Z_EFFECT_NONE, @@ -13606,7 +13606,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SLICING_MOVE, .split = SPLIT_PHYSICAL, .zMovePower = 120, .zMoveEffect = Z_EFFECT_NONE, @@ -13627,7 +13627,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMovePower = 175, .zMoveEffect = Z_EFFECT_NONE, @@ -13648,7 +13648,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 20, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMovePower = 175, .zMoveEffect = Z_EFFECT_NONE, @@ -13669,7 +13669,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .secondaryEffectChance = 20, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_WIND_MOVE, .split = SPLIT_SPECIAL, .zMovePower = 175, .zMoveEffect = Z_EFFECT_NONE, @@ -13872,7 +13872,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = [MOVE_ICE_SPINNER] = { - .effect = EFFECT_DAMAGE_SET_TERRAIN, + .effect = EFFECT_HIT_SET_REMOVE_TERRAIN, .power = 80, .type = TYPE_ICE, .accuracy = 100, @@ -13884,7 +13884,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .split = SPLIT_PHYSICAL, .zMovePower = 160, .zMoveEffect = Z_EFFECT_NONE, - .argument = 1, //remove terrain + .argument = 1, // Remove the active field terrain if there is one. }, [MOVE_GLAIVE_RUSH] = @@ -14839,7 +14839,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = }, [MOVE_GENESIS_SUPERNOVA] = { - .effect = EFFECT_DAMAGE_SET_TERRAIN, + .effect = EFFECT_HIT_SET_REMOVE_TERRAIN, .power = 185, .type = TYPE_PSYCHIC, .accuracy = 0, @@ -14850,7 +14850,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .flags = 0, .zMovePower = 0, .split = SPLIT_SPECIAL, - .argument = 0, //psychic terrain + .argument = 0, // Set Psychic Terrain. If there's a different field terrain active, overwrite it. .zMoveEffect = 0 }, [MOVE_SINISTER_ARROW_RAID] = @@ -14900,7 +14900,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = }, [MOVE_SPLINTERED_STORMSHARDS] = { - .effect = EFFECT_DAMAGE_SET_TERRAIN, + .effect = EFFECT_HIT_SET_REMOVE_TERRAIN, .power = 190, .type = TYPE_ROCK, .accuracy = 0, @@ -14911,7 +14911,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .flags = 0, .zMovePower = 0, .split = SPLIT_PHYSICAL, - .argument = 1, //remove terrain + .argument = 1, // Remove the active field terrain if there is one. .zMoveEffect = 0 }, [MOVE_LETS_SNUGGLE_FOREVER] = diff --git a/src/data/text/abilities.h b/src/data/text/abilities.h index ac11b9de8b..96407c3409 100644 --- a/src/data/text/abilities.h +++ b/src/data/text/abilities.h @@ -254,6 +254,37 @@ static const u8 sChillingNeighDescription[] = _("KOs boost Attack stat."); static const u8 sGrimNeighDescription[] = _("KOs boost Sp. Atk stat."); static const u8 sAsOneIceRiderDescription[] = _("Unnerve and Chilling Neigh."); static const u8 sAsOneShadowRiderDescription[] = _("Unnerve and Grim Neigh."); +static const u8 sLingeringAromaDescription[] = _("Spreads with contact."); +static const u8 sSeedSowerDescription[] = _("Affects terrain when hit."); +static const u8 sThermalExchangeDescription[] = _("Fire hits up Attack."); +static const u8 sAngerShellDescription[] = _("Gets angry at half HP."); +static const u8 sPurifyingSaltDescription[] = _("Protected by pure salts."); +static const u8 sWellBakedBodyDescription[] = _("Strengthened by Fire."); +static const u8 sWindRiderDescription[] = _("Ups Attack if hit by wind."); +static const u8 sGuardDogDescription[] = _("Cannot be intimidated."); +static const u8 sRockyPayloadDescription[] = _("Powers up Rock moves."); +static const u8 sWindPowerDescription[] = _("Gets charged by wind."); +static const u8 sZeroToHeroDescription[] = _("Changes form on switch out."); +static const u8 sCommanderDescription[] = _("Commands from Dondozo."); +static const u8 sElectromorphosisDescription[] = _("Gets Charged on contact."); +static const u8 sProtosynthesisDescription[] = _("Sun boosts best stat."); +static const u8 sQuarkDriveDescription[] = _("Elec. field ups best stat."); +static const u8 sGoodAsGoldDescription[] = _("Avoids status problems."); +static const u8 sVesselOfRuinDescription[] = _("Lowers foes' sp. damage."); +static const u8 sSwordOfRuinDescription[] = _("Lowers foes' defense."); +static const u8 sTabletsOfRuinDescription[] = _("Lowers foes' damage."); +static const u8 sBeadsOfRuinDescription[] = _("Lowers foes' sp. defense."); +static const u8 sOrichalcumPulseDescription[] = _("Summons sunlight in battle."); +static const u8 sHadronEngineDescription[] = _("Field becomes Electric."); +static const u8 sOpportunistDescription[] = _("Copies foe's stat change."); +static const u8 sCudChewDescription[] = _("Eats a used berry again."); +static const u8 sSharpnessDescription[] = _("Strengthens cutting moves."); +static const u8 sSupremeOverlordDescription[] = _("Inherits fallen's strength."); +static const u8 sCostarDescription[] = _("Copies ally's stat changes."); +static const u8 sToxicDebrisDescription[] = _("Throws poison spikes if hit."); +static const u8 sArmorTailDescription[] = _("Protects from priority."); +static const u8 sEarthEaterDescription[] = _("Eats ground to heal HP."); +static const u8 sMyceliumMightDescription[] = _("Status moves never fail."); #if B_EXPANDED_ABILITY_NAMES == TRUE const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = @@ -526,6 +557,37 @@ const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = [ABILITY_GRIM_NEIGH] = _("Grim Neigh"), [ABILITY_AS_ONE_ICE_RIDER] = _("As One"), [ABILITY_AS_ONE_SHADOW_RIDER] = _("As One"), + [ABILITY_LINGERING_AROMA] = _("Lingering Aroma"), + [ABILITY_SEED_SOWER] = _("Seed Sower"), + [ABILITY_THERMAL_EXCHANGE] = _("Thermal Exchange"), + [ABILITY_ANGER_SHELL] = _("Anger Shell"), + [ABILITY_PURIFYING_SALT] = _("Purifying Salt"), + [ABILITY_WELL_BAKED_BODY] = _("Well-Baked Body"), + [ABILITY_WIND_RIDER] = _("Wind Rider"), + [ABILITY_GUARD_DOG] = _("Guard Dog"), + [ABILITY_ROCKY_PAYLOAD] = _("Rocky Payload"), + [ABILITY_WIND_POWER] = _("Wind Power"), + [ABILITY_ZERO_TO_HERO] = _("Zero to Hero"), + [ABILITY_COMMANDER] = _("Commander"), + [ABILITY_ELECTROMORPHOSIS] = _("Electromorphosis"), + [ABILITY_PROTOSYNTHESIS] = _("Protosynthesis"), + [ABILITY_QUARK_DRIVE] = _("Quark Drive"), + [ABILITY_GOOD_AS_GOLD] = _("Good as Gold"), + [ABILITY_VESSEL_OF_RUIN] = _("Vessel of Ruin"), + [ABILITY_SWORD_OF_RUIN] = _("Sword of Ruin"), + [ABILITY_TABLETS_OF_RUIN] = _("Tablets of Ruin"), + [ABILITY_BEADS_OF_RUIN] = _("Beads of Ruin"), + [ABILITY_ORICHALCUM_PULSE] = _("Orichalcum Pulse"), + [ABILITY_HADRON_ENGINE] = _("Hadron Engine"), + [ABILITY_OPPORTUNIST] = _("Opportunist"), + [ABILITY_CUD_CHEW] = _("Cud Chew"), + [ABILITY_SHARPNESS] = _("Sharpness"), + [ABILITY_SUPREME_OVERLORD] = _("Supreme Overlord"), + [ABILITY_COSTAR] = _("Costar"), + [ABILITY_TOXIC_DEBRIS] = _("Toxic Debris"), + [ABILITY_ARMOR_TAIL] = _("Armor Tail"), + [ABILITY_EARTH_EATER] = _("Earth Eater"), + [ABILITY_MYCELIUM_MIGHT] = _("Mycelium Might"), }; #else // 12 characters const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = @@ -798,6 +860,37 @@ const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = [ABILITY_GRIM_NEIGH] = _("Grim Neigh"), [ABILITY_AS_ONE_ICE_RIDER] = _("As One"), [ABILITY_AS_ONE_SHADOW_RIDER] = _("As One"), + [ABILITY_LINGERING_AROMA] = _("LngerngAroma"), + [ABILITY_SEED_SOWER] = _("Seed Sower"), + [ABILITY_THERMAL_EXCHANGE] = _("ThrmlExchnge"), + [ABILITY_ANGER_SHELL] = _("Anger Shell"), + [ABILITY_PURIFYING_SALT] = _("PurfyingSalt"), + [ABILITY_WELL_BAKED_BODY] = _("WellBakedBdy"), + [ABILITY_WIND_RIDER] = _("Wind Rider"), + [ABILITY_GUARD_DOG] = _("Guard Dog"), + [ABILITY_ROCKY_PAYLOAD] = _("RockyPayload"), + [ABILITY_WIND_POWER] = _("Wind Power"), + [ABILITY_ZERO_TO_HERO] = _("Zero to Hero"), + [ABILITY_COMMANDER] = _("Commander"), + [ABILITY_ELECTROMORPHOSIS] = _("Elecmrphosis"), + [ABILITY_PROTOSYNTHESIS] = _("Protosnthsis"), + [ABILITY_QUARK_DRIVE] = _("Quark Drive"), + [ABILITY_GOOD_AS_GOLD] = _("Good as Gold"), + [ABILITY_VESSEL_OF_RUIN] = _("VesselOfRuin"), + [ABILITY_SWORD_OF_RUIN] = _("SwordOfRuin"), + [ABILITY_TABLETS_OF_RUIN] = _("TabltsOfRuin"), + [ABILITY_BEADS_OF_RUIN] = _("BeadsOfRuin"), + [ABILITY_ORICHALCUM_PULSE] = _("OrchlcumPlse"), + [ABILITY_HADRON_ENGINE] = _("HadronEngine"), + [ABILITY_OPPORTUNIST] = _("Opportunist"), + [ABILITY_CUD_CHEW] = _("Cud Chew"), + [ABILITY_SHARPNESS] = _("Sharpness"), + [ABILITY_SUPREME_OVERLORD] = _("SuprmeOvrlrd"), + [ABILITY_COSTAR] = _("Costar"), + [ABILITY_TOXIC_DEBRIS] = _("Toxic Debris"), + [ABILITY_ARMOR_TAIL] = _("Armor Tail"), + [ABILITY_EARTH_EATER] = _("Earth Eater"), + [ABILITY_MYCELIUM_MIGHT] = _("MceliumMight"), }; #endif @@ -1071,4 +1164,35 @@ const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT] = [ABILITY_GRIM_NEIGH] = sGrimNeighDescription, [ABILITY_AS_ONE_ICE_RIDER] = sAsOneIceRiderDescription, [ABILITY_AS_ONE_SHADOW_RIDER] = sAsOneShadowRiderDescription, + [ABILITY_LINGERING_AROMA] = sLingeringAromaDescription, + [ABILITY_SEED_SOWER] = sSeedSowerDescription, + [ABILITY_THERMAL_EXCHANGE] = sThermalExchangeDescription, + [ABILITY_ANGER_SHELL] = sAngerShellDescription, + [ABILITY_PURIFYING_SALT] = sPurifyingSaltDescription, + [ABILITY_WELL_BAKED_BODY] = sWellBakedBodyDescription, + [ABILITY_WIND_RIDER] = sWindRiderDescription, + [ABILITY_GUARD_DOG] = sGuardDogDescription, + [ABILITY_ROCKY_PAYLOAD] = sRockyPayloadDescription, + [ABILITY_WIND_POWER] = sWindPowerDescription, + [ABILITY_ZERO_TO_HERO] = sZeroToHeroDescription, + [ABILITY_COMMANDER] = sCommanderDescription, + [ABILITY_ELECTROMORPHOSIS] = sElectromorphosisDescription, + [ABILITY_PROTOSYNTHESIS] = sProtosynthesisDescription, + [ABILITY_QUARK_DRIVE] = sQuarkDriveDescription, + [ABILITY_GOOD_AS_GOLD] = sGoodAsGoldDescription, + [ABILITY_VESSEL_OF_RUIN] = sVesselOfRuinDescription, + [ABILITY_SWORD_OF_RUIN] = sSwordOfRuinDescription, + [ABILITY_TABLETS_OF_RUIN] = sTabletsOfRuinDescription, + [ABILITY_BEADS_OF_RUIN] = sBeadsOfRuinDescription, + [ABILITY_ORICHALCUM_PULSE] = sOrichalcumPulseDescription, + [ABILITY_HADRON_ENGINE] = sHadronEngineDescription, + [ABILITY_OPPORTUNIST] = sOpportunistDescription, + [ABILITY_CUD_CHEW] = sCudChewDescription, + [ABILITY_SHARPNESS] = sSharpnessDescription, + [ABILITY_SUPREME_OVERLORD] = sSupremeOverlordDescription, + [ABILITY_COSTAR] = sCostarDescription, + [ABILITY_TOXIC_DEBRIS] = sToxicDebrisDescription, + [ABILITY_ARMOR_TAIL] = sArmorTailDescription, + [ABILITY_EARTH_EATER] = sEarthEaterDescription, + [ABILITY_MYCELIUM_MIGHT] = sMyceliumMightDescription, }; diff --git a/src/frontier_util.c b/src/frontier_util.c index d89fca436c..fcdf3a02d8 100644 --- a/src/frontier_util.c +++ b/src/frontier_util.c @@ -497,100 +497,46 @@ static const struct FrontierBrainMon sFrontierBrainsMons[][2][FRONTIER_PARTY_SIZ }, }; -static const u8 sBattlePointAwards[][NUM_FRONTIER_FACILITIES][FRONTIER_MODE_COUNT] = +static const u8 sBattlePointAwards[NUM_FRONTIER_FACILITIES][FRONTIER_MODE_COUNT][30] = { + /* facility, mode, tier */ + [FRONTIER_FACILITY_TOWER] = /* Tier: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 */ { - {1, 2, 3, 3}, {1, 1}, {4, 5}, {1}, {3, 4}, {1}, {5} + [FRONTIER_MODE_SINGLES] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, + [FRONTIER_MODE_DOUBLES] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, + [FRONTIER_MODE_MULTIS] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, + [FRONTIER_MODE_LINK_MULTIS] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, }, + [FRONTIER_FACILITY_DOME] = { - {2, 3, 4, 4}, {1, 1}, {4, 5}, {1}, {3, 4}, {1}, {5} + [FRONTIER_MODE_SINGLES] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 }, + [FRONTIER_MODE_DOUBLES] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 }, }, + [FRONTIER_FACILITY_PALACE] = { - {3, 4, 5, 5}, {2, 2}, {5, 6}, {1}, {4, 5}, {2}, {6} + [FRONTIER_MODE_SINGLES] = { 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15 }, + [FRONTIER_MODE_DOUBLES] = { 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, }, + [FRONTIER_FACILITY_ARENA] = { - {4, 5, 6, 6}, {2, 2}, {5, 6}, {2}, {4, 5}, {2}, {6} + [FRONTIER_MODE_SINGLES] = { 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, }, + [FRONTIER_FACILITY_FACTORY] = { - {5, 6, 7, 7}, {3, 3}, {6, 7}, {2}, {5, 6}, {2}, {7} + [FRONTIER_MODE_SINGLES] = { 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15 }, + [FRONTIER_MODE_DOUBLES] = { 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15 }, }, + [FRONTIER_FACILITY_PIKE] = { - {6, 7, 8, 8}, {3, 3}, {6, 7}, {2}, {5, 6}, {4}, {7} + [FRONTIER_MODE_SINGLES] = { 1, 1, 2, 2, 2, 4, 4, 4, 8, 8, 8, 8, 10, 10, 10, 10, 12, 12, 12, 12, 12, 14, 14, 14, 14, 15, 15, 15, 15, 15 }, }, + [FRONTIER_FACILITY_PYRAMID] = { - {7, 8, 9, 9}, {4, 4}, {7, 8}, {3}, {6, 7}, {4}, {8} - }, - { - {8, 9, 10, 10}, {4, 4}, {7, 8}, {3},{6, 7}, {4}, {8} - }, - { - {9, 10, 11, 11}, {5, 5}, {8, 9}, {4}, {7, 8}, {8}, {9} - }, - { - {10, 11, 12, 12}, {5, 5}, {8, 9}, {4}, {7, 8}, {8}, {9} - }, - { - {11, 12, 13, 13}, {6, 6}, {9, 10}, {5,0}, {8, 9}, {8}, {10} - }, - { - {12, 13, 14, 14}, {6, 6}, {9, 10}, {6,0}, {8, 9}, {8}, {10} - }, - { - {13, 14, 15, 15}, {7, 7}, {10, 11}, {7}, {9, 10}, {10}, {11} - }, - { - {14, 15, 15, 15}, {7, 7}, {10, 11}, {8}, {9, 10}, {10}, {11} - }, - { - {15, 15, 15, 15}, {8, 8}, {11, 12}, {9}, {10, 11}, {10}, {12} - }, - { - {15, 15, 15, 15}, {8, 8}, {11, 12}, {10}, {10, 11}, {10}, {12} - }, - { - {15, 15, 15, 15}, {9, 9}, {12, 13}, {11}, {11, 12}, {12}, {13} - }, - { - {15, 15, 15, 15}, {9, 9}, {12, 13}, {12}, {11, 12}, {12}, {13} - }, - { - {15, 15, 15, 15}, {10, 10}, {13, 14}, {13}, {12, 13}, {12}, {14} - }, - { - {15, 15, 15, 15}, {10, 10}, {13, 14}, {14}, {12, 13}, {12}, {14} - }, - { - {15, 15, 15, 15}, {11, 11}, {14, 15}, {15}, {13, 14}, {12}, {15} - }, - { - {15, 15, 15, 15}, {11, 11}, {14, 15}, {15}, {13, 14}, {14}, {15} - }, - { - {15, 15, 15, 15}, {12, 12}, {15, 15}, {15}, {14, 15}, {14}, {15} - }, - { - {15, 15, 15, 15}, {12, 12}, {15, 15}, {15}, {14, 15}, {14}, {15} - }, - { - {15, 15, 15, 15}, {13, 13}, {15, 15}, {15}, {15, 15}, {14}, {15} - }, - { - {15, 15, 15, 15}, {13, 13}, {15, 15}, {15}, {15, 15}, {15}, {15} - }, - { - {15, 15, 15, 15}, {14, 14}, {15, 15}, {15}, {15, 15}, {15}, {15} - }, - { - {15, 15, 15, 15}, {14, 14}, {15, 15}, {15}, {15, 15}, {15}, {15} - }, - { - {15, 15, 15, 15}, {15, 15}, {15, 15}, {15}, {15, 15}, {15}, {15} - }, - { - {15, 15, 15, 15}, {15, 15}, {15, 15}, {15}, {15, 15}, {15}, {15} + [FRONTIER_MODE_SINGLES] = { 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, }, }; + // Flags to change the conversation when the Frontier Brain is encountered for a battle // First bit is has battled them before and not won yet, second bit is has battled them and won (obtained a Symbol) static const u16 sBattledBrainBitFlags[NUM_FRONTIER_FACILITIES][2] = @@ -1885,10 +1831,10 @@ static void GiveBattlePoints(void) if (challengeNum != 0) challengeNum--; - if (challengeNum >= ARRAY_COUNT(sBattlePointAwards)) - challengeNum = ARRAY_COUNT(sBattlePointAwards) - 1; + if (challengeNum >= ARRAY_COUNT(sBattlePointAwards[0][0])) + challengeNum = ARRAY_COUNT(sBattlePointAwards[0][0]) - 1; - points = sBattlePointAwards[challengeNum][facility][battleMode]; + points = sBattlePointAwards[facility][battleMode][challengeNum]; if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN) points += 10; gSaveBlock2Ptr->frontier.battlePoints += points; @@ -1897,8 +1843,8 @@ static void GiveBattlePoints(void) gSaveBlock2Ptr->frontier.battlePoints = MAX_BATTLE_FRONTIER_POINTS; points = gSaveBlock2Ptr->frontier.cardBattlePoints; - points += sBattlePointAwards[challengeNum][facility][battleMode]; - IncrementDailyBattlePoints(sBattlePointAwards[challengeNum][facility][battleMode]); + points += sBattlePointAwards[facility][battleMode][challengeNum]; + IncrementDailyBattlePoints(sBattlePointAwards[facility][battleMode][challengeNum]); if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN) { points += 10; diff --git a/src/graphics.c b/src/graphics.c index 0126150fd9..c0ca2ff3a6 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -286,6 +286,8 @@ const u32 gBattleAnimSpritePal_Tornado[] = INCBIN_U32("graphics/battle_anims/spr const u32 gBattleAnimSpriteGfx_ZMoveSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/z_move_symbol.4bpp.lz"); const u32 gBattleAnimSpritePal_ZMoveSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/z_move_symbol.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_Teapot[] = INCBIN_U32("graphics/battle_anims/sprites/new/teapot.4bpp.lz"); +const u32 gBattleAnimSpritePal_Teapot[] = INCBIN_U32("graphics/battle_anims/sprites/new/teapot.gbapal.lz"); // Battle anims const u32 gBattleAnimSpriteGfx_Bubble[] = INCBIN_U32("graphics/battle_anims/sprites/bubble.4bpp.lz"); @@ -682,7 +684,7 @@ const u8 gHealthboxElementsGfxTable[] = INCBIN_U8("graphics/battle_interface/hpb "graphics/battle_interface/hpbar_anim.4bpp", "graphics/battle_interface/misc_frameend.4bpp", "graphics/battle_interface/ball_display.4bpp", - "graphics/battle_interface/ball_display_unused_extra.4bpp", + "graphics/battle_interface/ball_caught_indicator.4bpp", "graphics/battle_interface/status2.4bpp", // these three duplicate sets of graphics are for the opponent pokemon "graphics/battle_interface/status3.4bpp", // and are also for use in double battles. they use dynamic palettes so "graphics/battle_interface/status4.4bpp", // coloring them is an extreme headache and wont be done for now diff --git a/src/item_menu.c b/src/item_menu.c index 608e203a62..2746fcf927 100755 --- a/src/item_menu.c +++ b/src/item_menu.c @@ -987,7 +987,7 @@ static void BagMenu_ItemPrintCallback(u8 windowId, u32 itemIndex, u8 y) else { // Print registered icon - if (gSaveBlock1Ptr->registeredItem && gSaveBlock1Ptr->registeredItem == itemId) + if (gSaveBlock1Ptr->registeredItem != ITEM_NONE && gSaveBlock1Ptr->registeredItem == itemId) BlitBitmapToWindow(windowId, sRegisteredSelect_Gfx, 96, y - 1, 24, 16); } } @@ -1909,7 +1909,7 @@ static void ItemMenu_Register(u8 taskId) u16 *cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket]; if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId) - gSaveBlock1Ptr->registeredItem = 0; + gSaveBlock1Ptr->registeredItem = ITEM_NONE; else gSaveBlock1Ptr->registeredItem = gSpecialVar_ItemId; DestroyListMenuTask(tListTaskId, scrollPos, cursorPos); diff --git a/src/new_game.c b/src/new_game.c index 8f8aa9b82b..0efc12d47f 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -182,7 +182,7 @@ void NewGameInitData(void) ResetPokemonStorageSystem(); ClearRoamerData(); ClearRoamerLocationData(); - gSaveBlock1Ptr->registeredItem = 0; + gSaveBlock1Ptr->registeredItem = ITEM_NONE; ClearBag(); NewGameInitPCItems(); ClearPokeblocks(); diff --git a/src/pokemon.c b/src/pokemon.c index 8e8166fb37..9cc2c7407a 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -3481,11 +3481,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, else #endif { - #if P_SHINY_BASE_CHANCE >= GEN_6 - u32 totalRerolls = 1; - #else u32 totalRerolls = 0; - #endif if (CheckBagHasItem(ITEM_SHINY_CHARM, 1)) totalRerolls += I_SHINY_CHARM_REROLLS; if (LURE_STEP_COUNT != 0) @@ -8621,6 +8617,8 @@ void TrySpecialOverworldEvo(void) bool32 ShouldShowFemaleDifferences(u16 species, u32 personality) { + if (species >= NUM_SPECIES) + return FALSE; return (gSpeciesInfo[species].flags & SPECIES_FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE; } diff --git a/src/pokemon_animation.c b/src/pokemon_animation.c index 936ef037d4..8901a666e4 100644 --- a/src/pokemon_animation.c +++ b/src/pokemon_animation.c @@ -907,11 +907,11 @@ u8 GetSpeciesBackAnimSet(u16 species) // as 0xFFFFXXXX instead of the desired 0x02YYXXXX. // By dumb luck, this is not an issue in vanilla. However, // changing the link order revealed this bug. -#if MODERN +#if MODERN || defined(BUGFIX) #define ANIM_SPRITE(taskId) ((struct Sprite *)((gTasks[taskId].tPtrHi << 16) | ((u16)gTasks[taskId].tPtrLo))) #else #define ANIM_SPRITE(taskId) ((struct Sprite *)((gTasks[taskId].tPtrHi << 16) | (gTasks[taskId].tPtrLo))) -#endif //MODERN +#endif //MODERN || BUGFIX static void Task_HandleMonAnimation(u8 taskId) { diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 0e21d1e59e..1e1727f5ea 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -109,6 +109,7 @@ enum { #define PSS_DATA_WINDOW_MOVE_DESCRIPTION 2 #define MOVE_SELECTOR_SPRITES_COUNT 10 +#define TYPE_ICON_SPRITE_COUNT (MAX_MON_MOVES + 1) // for the spriteIds field in PokemonSummaryScreenData enum { @@ -116,7 +117,7 @@ enum SPRITE_ARR_ID_BALL, SPRITE_ARR_ID_STATUS, SPRITE_ARR_ID_TYPE, // 2 for mon types, 5 for move types(4 moves and 1 to learn), used interchangeably, because mon types and move types aren't shown on the same screen - SPRITE_ARR_ID_MOVE_SELECTOR1 = SPRITE_ARR_ID_TYPE + 5, // 10 sprites that make up the selector + SPRITE_ARR_ID_MOVE_SELECTOR1 = SPRITE_ARR_ID_TYPE + TYPE_ICON_SPRITE_COUNT, // 10 sprites that make up the selector SPRITE_ARR_ID_MOVE_SELECTOR2 = SPRITE_ARR_ID_MOVE_SELECTOR1 + MOVE_SELECTOR_SPRITES_COUNT, SPRITE_ARR_ID_COUNT = SPRITE_ARR_ID_MOVE_SELECTOR2 + MOVE_SELECTOR_SPRITES_COUNT }; @@ -3873,7 +3874,7 @@ static void CreateMoveTypeIcons(void) { u8 i; - for (i = SPRITE_ARR_ID_TYPE; i < SPRITE_ARR_ID_TYPE + 5; i++) + for (i = SPRITE_ARR_ID_TYPE; i < SPRITE_ARR_ID_TYPE + TYPE_ICON_SPRITE_COUNT; i++) { if (sMonSummaryScreen->spriteIds[i] == SPRITE_NONE) sMonSummaryScreen->spriteIds[i] = CreateSprite(&sSpriteTemplate_MoveTypes, 0, 0, 2); diff --git a/src/record_mixing.c b/src/record_mixing.c index 5d75f3fc89..d6edd078b7 100644 --- a/src/record_mixing.c +++ b/src/record_mixing.c @@ -59,23 +59,23 @@ struct PlayerRecordRS struct RecordMixingDaycareMail daycareMail; struct RSBattleTowerRecord battleTowerRecord; u16 giftItem; - u16 padding[50]; + u16 filler[50]; }; struct PlayerRecordEmerald { /* 0x0000 */ struct SecretBase secretBases[SECRET_BASES_COUNT]; - /* 0x0c80 */ TVShow tvShows[TV_SHOWS_COUNT]; + /* 0x0C80 */ TVShow tvShows[TV_SHOWS_COUNT]; /* 0x1004 */ PokeNews pokeNews[POKE_NEWS_COUNT]; /* 0x1044 */ OldMan oldMan; /* 0x1084 */ struct DewfordTrend dewfordTrends[SAVED_TRENDS_COUNT]; - /* 0x10ac */ struct RecordMixingDaycareMail daycareMail; + /* 0x10AC */ struct RecordMixingDaycareMail daycareMail; /* 0x1124 */ struct EmeraldBattleTowerRecord battleTowerRecord; /* 0x1210 */ u16 giftItem; /* 0x1214 */ LilycoveLady lilycoveLady; /* 0x1254 */ struct Apprentice apprentices[2]; - /* 0x12dc */ struct PlayerHallRecords hallRecords; - /* 0x1434 */ u8 padding[16]; + /* 0x12DC */ struct PlayerHallRecords hallRecords; + /* 0x1434 */ u8 filler_1434[16]; }; // 0x1444 union PlayerRecord