diff --git a/Makefile b/Makefile index 517c78b893..89b442fe34 100644 --- a/Makefile +++ b/Makefile @@ -188,7 +188,7 @@ MAKEFLAGS += --no-print-directory # Secondary expansion is required for dependency variables in object rules. .SECONDEXPANSION: -.PHONY: all rom clean compare tidy tools check-tools mostlyclean clean-tools clean-check-tools $(TOOLDIRS) $(CHECKTOOLDIRS) libagbsyscall agbcc modern tidymodern tidynonmodern check +.PHONY: all rom clean compare tidy tools check-tools mostlyclean clean-tools clean-check-tools $(TOOLDIRS) $(CHECKTOOLDIRS) libagbsyscall agbcc modern tidymodern tidynonmodern check history infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst __SPACE__, ,$(line)))) @@ -255,7 +255,10 @@ endif AUTO_GEN_TARGETS := -all: rom +all: history rom + +history: + @bash ./check_history.sh tools: $(TOOLDIRS) diff --git a/README.md b/README.md index 3caf3c41c6..d7bcb43d00 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # pokeemerald-expansion +### Important: DO NOT use GitHub's "Download Zip" option. Using this option will not download the commit history required to update your expansion version or merge other feature branches. Instead, please read [this guide](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/wiki/The-Basics-of-GitHub) to learn how to fork the repository and clone locally from there. + ## What is pokeemerald-expansion? pokeemerald-expansion is a decomp hack base project based off pret's [pokeemerald](https://github.com/pret/pokeemerald) decompilation project. It's recommended that any new projects that plan on using it, to clone this repository instead of pret's vanilla repository, as we regurlarly incorporate pret's documentation changes. This is ***NOT*** a standalone romhack, and as such, most features will be unavailable and/or unbalanced if played as is. diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index d2a8115089..25e0110a51 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1361,6 +1361,11 @@ .4byte \jumpInstr .endm + .macro itemstatchangeeffects battler:req + callnative BS_RunStatChangeItems + .byte \battler + .endm + .macro allyswitchswapbattlers callnative BS_AllySwitchSwapBattler .endm @@ -1627,6 +1632,10 @@ .4byte \jumpInstr .endm + .macro trygulpmissile + callnative BS_TryGulpMissile + .endm + @ various command changed to more readable macros .macro cancelmultiturnmoves battler:req various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES diff --git a/check_history.sh b/check_history.sh new file mode 100755 index 0000000000..64ea76a807 --- /dev/null +++ b/check_history.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +if [ -e .histignore ] +then + exit 0 +fi + +if [ $GITHUB_ACTION ] +then + exit 0 +fi + +has_hist=false +has_git=1 +if which git >/dev/null +then + has_hist="$(git rev-parse --is-inside-work-tree 2>/dev/null)" +else + has_git=0 +fi + +if [ $has_git -ne 1 ] +then + echo -e "\033[0;31mfatal: \033[0m\033[1;33mgit was not found. You will be unable to use version control, update pokeemerald-expansion, or use feature branches. To use version control, install \`git\` and clone the repository instead of using \"Download Zip\" on GitHub. Run \`touch .histignore\` to ignore this and continue anyways.\033[0m" + exit 1 +fi + +if [ "$has_hist" ] +then + exit 0 +else + echo -e "\033[0;31mfatal: \033[0m\033[1;33mno git history found. You will be unable to use version control, update pokeemerald-expansion, or use feature branches. To use version control, use \`git\` to clone the repository instead of using \"Download Zip\" on GitHub. Run \`touch .histignore\` to ignore this and continue anyways.\033[0m" + exit 1 +fi + diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 539d109037..0b606d3516 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -521,7 +521,7 @@ BattleScript_AffectionBasedStatus_HealFreezeString: printstring STRINGID_ATTACKERMELTEDTHEICE goto BattleScript_AffectionBasedStatusHeal_Continue BattleScript_AffectionBasedStatus_HealFrostbiteString: - printstring STRINGID_ATTACKERHEALEDITSFROSTBITE + printstring STRINGID_ATTACKERMELTEDTHEICE BattleScript_AffectionBasedStatusHeal_Continue: waitmessage B_WAIT_TIME_LONG clearstatus BS_ATTACKER @@ -3804,6 +3804,8 @@ BattleScript_FirstChargingTurnAfterAttackString: BattleScript_TwoTurnMovesSecondPowerHerbActivates: call BattleScript_PowerHerbActivation + trygulpmissile @ Edge case for Cramorant ability Gulp Missile +BattleScript_FromTwoTurnMovesSecondTurnRet: call BattleScript_TwoTurnMovesSecondTurnRet accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE @ before Gen 5, charge moves did not print an attack string on the charge turn @@ -7006,6 +7008,10 @@ BattleScript_UltraBurst:: switchinabilities BS_ATTACKER end3 +BattleScript_GulpMissileFormChange:: + call BattleScript_AttackerFormChange + goto BattleScript_FromTwoTurnMovesSecondTurnRet + BattleScript_AttackerFormChange:: pause 5 copybyte gBattlerAbility, gBattlerAttacker @@ -7049,20 +7055,21 @@ 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_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + consumeberry BS_SCRIPTING, FALSE setbyte sBERRY_OVERRIDE, 0 end3 BattleScript_TargetFormChangeNoPopup: flushtextbox - handleformchange BS_TARGET, 0 - handleformchange BS_TARGET, 1 + handleformchange BS_SCRIPTING, 0 + handleformchange BS_SCRIPTING, 1 playanimation BS_TARGET, B_ANIM_FORM_CHANGE waitanimation - handleformchange BS_TARGET, 2 + handleformchange BS_SCRIPTING, 2 +.if B_DISGUISE_HP_LOSS >= GEN_8 + healthbarupdate BS_SCRIPTING + datahpupdate BS_SCRIPTING +.endif return BattleScript_TargetFormChange:: @@ -7111,9 +7118,7 @@ BattleScript_IllusionOff:: BattleScript_CottonDownActivates:: copybyte sSAVED_BATTLER, gBattlerAttacker - showabilitypopup BS_TARGET - pause B_WAIT_TIME_LONG - destroyabilitypopup + call BattleScript_AbilityPopUpTarget copybyte gEffectBattler, gBattlerTarget swapattackerwithtarget setbyte gBattlerTarget, 0 @@ -7742,11 +7747,12 @@ BattleScript_ActivateWeatherAbilities_Increment: restoretarget return -BattleScript_TryAdrenalineOrb: - jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_ADRENALINE_ORB, BattleScript_TryAdrenalineOrbRet - jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPEED, 12, BattleScript_TryAdrenalineOrbRet +BattleScript_TryIntimidateHoldEffects: + itemstatchangeeffects BS_TARGET + jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_ADRENALINE_ORB, BattleScript_TryIntimidateHoldEffectsRet + jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPEED, 12, BattleScript_TryIntimidateHoldEffectsRet setstatchanger STAT_SPEED, 1, FALSE - statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN | STAT_CHANGE_ALLOW_PTR, BattleScript_TryAdrenalineOrbRet + statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN | STAT_CHANGE_ALLOW_PTR, BattleScript_TryIntimidateHoldEffectsRet playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT setgraphicalstatchangevalues playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 @@ -7755,14 +7761,16 @@ BattleScript_TryAdrenalineOrb: printstring STRINGID_USINGITEMSTATOFPKMNROSE waitmessage B_WAIT_TIME_LONG removeitem BS_TARGET -BattleScript_TryAdrenalineOrbRet: +BattleScript_TryIntimidateHoldEffectsRet: return BattleScript_IntimidateActivates:: - showabilitypopup BS_ATTACKER copybyte sSAVED_BATTLER, gBattlerTarget +.if B_ABILITY_POP_UP == TRUE + showabilitypopup BS_ATTACKER pause B_WAIT_TIME_LONG destroyabilitypopup +.endif setbyte gBattlerTarget, 0 BattleScript_IntimidateLoop: jumpifbyteequal gBattlerTarget, gBattlerAttacker, BattleScript_IntimidateLoopIncrement @@ -7781,7 +7789,7 @@ BattleScript_IntimidateEffect: BattleScript_IntimidateEffect_WaitString: waitmessage B_WAIT_TIME_LONG copybyte sBATTLER, gBattlerTarget - call BattleScript_TryAdrenalineOrb + call BattleScript_TryIntimidateHoldEffects BattleScript_IntimidateLoopIncrement: addbyte gBattlerTarget, 1 jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_IntimidateLoop @@ -7807,14 +7815,16 @@ BattleScript_IntimidateInReverse: call BattleScript_AbilityPopUpTarget pause B_WAIT_TIME_SHORT modifybattlerstatstage BS_TARGET, STAT_ATK, INCREASE, 1, BattleScript_IntimidateLoopIncrement, ANIM_ON - call BattleScript_TryAdrenalineOrb + call BattleScript_TryIntimidateHoldEffects goto BattleScript_IntimidateLoopIncrement BattleScript_SupersweetSyrupActivates:: - showabilitypopup BS_ATTACKER copybyte sSAVED_BATTLER, gBattlerTarget +.if B_ABILITY_POP_UP == TRUE + showabilitypopup BS_ATTACKER pause B_WAIT_TIME_LONG destroyabilitypopup +.endif printstring STRINGID_SUPERSWEETAROMAWAFTS waitmessage B_WAIT_TIME_LONG setbyte gBattlerTarget, 0 @@ -7834,7 +7844,7 @@ BattleScript_SupersweetSyrupEffect: BattleScript_SupersweetSyrupEffect_WaitString: waitmessage B_WAIT_TIME_LONG copybyte sBATTLER, gBattlerTarget - call BattleScript_TryAdrenalineOrb + call BattleScript_TryIntimidateHoldEffects BattleScript_SupersweetSyrupLoopIncrement: addbyte gBattlerTarget, 1 jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_SupersweetSyrupLoop @@ -8707,11 +8717,11 @@ BattleScript_BerryCureFrzRet:: removeitem BS_SCRIPTING return -BattleScript_BerryCureFsbEnd2:: +BattleScript_BerryCureFrbEnd2:: call BattleScript_BerryCureFrzRet end2 -BattleScript_BerryCureFsbRet:: +BattleScript_BerryCureFrbRet:: playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT printstring STRINGID_PKMNSITEMHEALEDFROSTBITE waitmessage B_WAIT_TIME_LONG @@ -9512,7 +9522,7 @@ BattleScript_WellBakedBodyActivates:: attackstring ppreduce pause B_WAIT_TIME_SHORT - showabilitypopup BS_TARGET + call BattleScript_AbilityPopUpTarget orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT modifybattlerstatstage BS_TARGET, STAT_DEF, INCREASE, 1, BattleScript_WellBakedBodyEnd, ANIM_ON BattleScript_WellBakedBodyEnd: @@ -9522,7 +9532,7 @@ BattleScript_WindRiderActivatesMoveEnd:: attackstring ppreduce pause B_WAIT_TIME_SHORT - showabilitypopup BS_TARGET + call BattleScript_AbilityPopUpTarget orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT modifybattlerstatstage BS_TARGET, STAT_ATK, INCREASE, 1, BattleScript_WindRiderActivatesMoveEnd_End, ANIM_ON BattleScript_WindRiderActivatesMoveEnd_End: @@ -9531,7 +9541,7 @@ BattleScript_WindRiderActivatesMoveEnd_End: BattleScript_GoodAsGoldActivates:: attackstring ppreduce - showabilitypopup BS_TARGET + call BattleScript_AbilityPopUpTarget pause B_WAIT_TIME_SHORT printstring STRINGID_ITDOESNTAFFECT waitmessage B_WAIT_TIME_MED diff --git a/data/script_cmd_table.inc b/data/script_cmd_table.inc index 28f22242ca..711b118cc6 100644 --- a/data/script_cmd_table.inc +++ b/data/script_cmd_table.inc @@ -205,8 +205,8 @@ gScriptCmdTable:: .4byte ScrCmd_nop1 @ 0xca .4byte ScrCmd_nop1 @ 0xcb .4byte ScrCmd_nop1 @ 0xcc - .4byte ScrCmd_setmonmodernfatefulencounter @ 0xcd - .4byte ScrCmd_checkmonmodernfatefulencounter @ 0xce + .4byte ScrCmd_setmodernfatefulencounter @ 0xcd + .4byte ScrCmd_checkmodernfatefulencounter @ 0xce .4byte ScrCmd_trywondercardscript @ 0xcf .4byte ScrCmd_nop1 @ 0xd0 .4byte ScrCmd_warpspinenter @ 0xd1 diff --git a/graphics/battle_interface/status.png b/graphics/battle_interface/status.png index 0b212907e5..ceb39fb777 100644 Binary files a/graphics/battle_interface/status.png and b/graphics/battle_interface/status.png differ diff --git a/graphics/battle_interface/status2.png b/graphics/battle_interface/status2.png index 5d7f6459be..ecb72c52de 100644 Binary files a/graphics/battle_interface/status2.png and b/graphics/battle_interface/status2.png differ diff --git a/graphics/battle_interface/status3.png b/graphics/battle_interface/status3.png index 7cc8cd56dc..369564815f 100644 Binary files a/graphics/battle_interface/status3.png and b/graphics/battle_interface/status3.png differ diff --git a/graphics/battle_interface/status4.png b/graphics/battle_interface/status4.png index c5ab2c5e11..119d4f4aa7 100644 Binary files a/graphics/battle_interface/status4.png and b/graphics/battle_interface/status4.png differ diff --git a/graphics/interface/status_icons.png b/graphics/interface/status_icons.png index f93406cfd1..cef7119a40 100644 Binary files a/graphics/interface/status_icons.png and b/graphics/interface/status_icons.png differ diff --git a/graphics/pokemon/annihilape/icon.png b/graphics/pokemon/annihilape/icon.png index 561a4afedd..e45f7583cb 100755 Binary files a/graphics/pokemon/annihilape/icon.png and b/graphics/pokemon/annihilape/icon.png differ diff --git a/graphics/pokemon/arboliva/icon.png b/graphics/pokemon/arboliva/icon.png index 039efb5489..07f763a941 100755 Binary files a/graphics/pokemon/arboliva/icon.png and b/graphics/pokemon/arboliva/icon.png differ diff --git a/graphics/pokemon/arcanine/hisuian/icon.png b/graphics/pokemon/arcanine/hisuian/icon.png index 9fe9007929..215b8d8d6e 100644 Binary files a/graphics/pokemon/arcanine/hisuian/icon.png and b/graphics/pokemon/arcanine/hisuian/icon.png differ diff --git a/graphics/pokemon/archaludon/icon.png b/graphics/pokemon/archaludon/icon.png new file mode 100644 index 0000000000..9ad59de8fe Binary files /dev/null and b/graphics/pokemon/archaludon/icon.png differ diff --git a/graphics/pokemon/arctibax/icon.png b/graphics/pokemon/arctibax/icon.png index cd7aec243e..f15a4e3545 100755 Binary files a/graphics/pokemon/arctibax/icon.png and b/graphics/pokemon/arctibax/icon.png differ diff --git a/graphics/pokemon/armarouge/icon.png b/graphics/pokemon/armarouge/icon.png index 2a348cab51..5cf958e578 100755 Binary files a/graphics/pokemon/armarouge/icon.png and b/graphics/pokemon/armarouge/icon.png differ diff --git a/graphics/pokemon/basculegion/female/icon.png b/graphics/pokemon/basculegion/female/icon.png index fb85ca6c0c..4a0e539212 100644 Binary files a/graphics/pokemon/basculegion/female/icon.png and b/graphics/pokemon/basculegion/female/icon.png differ diff --git a/graphics/pokemon/basculegion/icon.png b/graphics/pokemon/basculegion/icon.png index 579a83d550..6226cf6a59 100644 Binary files a/graphics/pokemon/basculegion/icon.png and b/graphics/pokemon/basculegion/icon.png differ diff --git a/graphics/pokemon/basculin/white_striped/icon.png b/graphics/pokemon/basculin/white_striped/icon.png index a69c4e51a8..bc7287fd62 100644 Binary files a/graphics/pokemon/basculin/white_striped/icon.png and b/graphics/pokemon/basculin/white_striped/icon.png differ diff --git a/graphics/pokemon/baxcalibur/icon.png b/graphics/pokemon/baxcalibur/icon.png index befc75d3c8..e5386582f0 100755 Binary files a/graphics/pokemon/baxcalibur/icon.png and b/graphics/pokemon/baxcalibur/icon.png differ diff --git a/graphics/pokemon/bellibolt/icon.png b/graphics/pokemon/bellibolt/icon.png index 28492e341d..5f2a98c8ef 100755 Binary files a/graphics/pokemon/bellibolt/icon.png and b/graphics/pokemon/bellibolt/icon.png differ diff --git a/graphics/pokemon/bombirdier/icon.png b/graphics/pokemon/bombirdier/icon.png index 06bcf71c86..45e4ac91df 100755 Binary files a/graphics/pokemon/bombirdier/icon.png and b/graphics/pokemon/bombirdier/icon.png differ diff --git a/graphics/pokemon/brambleghast/icon.png b/graphics/pokemon/brambleghast/icon.png index 645ed7014d..ca6a29df23 100755 Binary files a/graphics/pokemon/brambleghast/icon.png and b/graphics/pokemon/brambleghast/icon.png differ diff --git a/graphics/pokemon/bramblin/icon.png b/graphics/pokemon/bramblin/icon.png index 9833e5007b..64fa8677b3 100755 Binary files a/graphics/pokemon/bramblin/icon.png and b/graphics/pokemon/bramblin/icon.png differ diff --git a/graphics/pokemon/braviary/hisuian/icon.png b/graphics/pokemon/braviary/hisuian/icon.png index c2aa449d95..85eb4decd4 100755 Binary files a/graphics/pokemon/braviary/hisuian/icon.png and b/graphics/pokemon/braviary/hisuian/icon.png differ diff --git a/graphics/pokemon/brute_bonnet/icon.png b/graphics/pokemon/brute_bonnet/icon.png index 052517c12d..82161e124d 100755 Binary files a/graphics/pokemon/brute_bonnet/icon.png and b/graphics/pokemon/brute_bonnet/icon.png differ diff --git a/graphics/pokemon/capsakid/icon.png b/graphics/pokemon/capsakid/icon.png index ede6dc9c0c..c10dfa5a9e 100755 Binary files a/graphics/pokemon/capsakid/icon.png and b/graphics/pokemon/capsakid/icon.png differ diff --git a/graphics/pokemon/ceruledge/icon.png b/graphics/pokemon/ceruledge/icon.png index 329d5ede31..4107555cd4 100755 Binary files a/graphics/pokemon/ceruledge/icon.png and b/graphics/pokemon/ceruledge/icon.png differ diff --git a/graphics/pokemon/cetitan/icon.png b/graphics/pokemon/cetitan/icon.png index 2a0db87041..078ee54a48 100755 Binary files a/graphics/pokemon/cetitan/icon.png and b/graphics/pokemon/cetitan/icon.png differ diff --git a/graphics/pokemon/cetoddle/icon.png b/graphics/pokemon/cetoddle/icon.png index b123bf1f81..b01b85d258 100755 Binary files a/graphics/pokemon/cetoddle/icon.png and b/graphics/pokemon/cetoddle/icon.png differ diff --git a/graphics/pokemon/charcadet/icon.png b/graphics/pokemon/charcadet/icon.png index 50d9e46d88..cddec8626b 100755 Binary files a/graphics/pokemon/charcadet/icon.png and b/graphics/pokemon/charcadet/icon.png differ diff --git a/graphics/pokemon/chi_yu/icon.png b/graphics/pokemon/chi_yu/icon.png index 29a9114af0..1aeb8e6c5b 100755 Binary files a/graphics/pokemon/chi_yu/icon.png and b/graphics/pokemon/chi_yu/icon.png differ diff --git a/graphics/pokemon/chien_pao/icon.png b/graphics/pokemon/chien_pao/icon.png index eaad400548..d2626c6554 100755 Binary files a/graphics/pokemon/chien_pao/icon.png and b/graphics/pokemon/chien_pao/icon.png differ diff --git a/graphics/pokemon/clodsire/icon.png b/graphics/pokemon/clodsire/icon.png index bcc0e34e50..277d20250b 100755 Binary files a/graphics/pokemon/clodsire/icon.png and b/graphics/pokemon/clodsire/icon.png differ diff --git a/graphics/pokemon/crocalor/icon.png b/graphics/pokemon/crocalor/icon.png index dea043b25f..615e2e6de0 100755 Binary files a/graphics/pokemon/crocalor/icon.png and b/graphics/pokemon/crocalor/icon.png differ diff --git a/graphics/pokemon/cyclizar/icon.png b/graphics/pokemon/cyclizar/icon.png index 64eba81963..8ab324773e 100755 Binary files a/graphics/pokemon/cyclizar/icon.png and b/graphics/pokemon/cyclizar/icon.png differ diff --git a/graphics/pokemon/dachsbun/icon.png b/graphics/pokemon/dachsbun/icon.png index fe1caf375d..cb05cd3be6 100644 Binary files a/graphics/pokemon/dachsbun/icon.png and b/graphics/pokemon/dachsbun/icon.png differ diff --git a/graphics/pokemon/decidueye/hisuian/icon.png b/graphics/pokemon/decidueye/hisuian/icon.png index 997071396f..bd490472d2 100755 Binary files a/graphics/pokemon/decidueye/hisuian/icon.png and b/graphics/pokemon/decidueye/hisuian/icon.png differ diff --git a/graphics/pokemon/dipplin/icon.png b/graphics/pokemon/dipplin/icon.png index 5fab863bd9..2db7df997f 100644 Binary files a/graphics/pokemon/dipplin/icon.png and b/graphics/pokemon/dipplin/icon.png differ diff --git a/graphics/pokemon/dolliv/icon.png b/graphics/pokemon/dolliv/icon.png index 932b6e62eb..bc2867dc75 100755 Binary files a/graphics/pokemon/dolliv/icon.png and b/graphics/pokemon/dolliv/icon.png differ diff --git a/graphics/pokemon/dondozo/icon.png b/graphics/pokemon/dondozo/icon.png index 066128e0d4..a704280ec0 100755 Binary files a/graphics/pokemon/dondozo/icon.png and b/graphics/pokemon/dondozo/icon.png differ diff --git a/graphics/pokemon/dudunsparce/icon.png b/graphics/pokemon/dudunsparce/icon.png index cf9c3501fe..ed9c479669 100755 Binary files a/graphics/pokemon/dudunsparce/icon.png and b/graphics/pokemon/dudunsparce/icon.png differ diff --git a/graphics/pokemon/eevee/partner/icon.png b/graphics/pokemon/eevee/partner/icon.png new file mode 100644 index 0000000000..b202c18862 Binary files /dev/null and b/graphics/pokemon/eevee/partner/icon.png differ diff --git a/graphics/pokemon/eevee/partner/iconf.png b/graphics/pokemon/eevee/partner/iconf.png new file mode 100644 index 0000000000..c82f753f32 Binary files /dev/null and b/graphics/pokemon/eevee/partner/iconf.png differ diff --git a/graphics/pokemon/electrode/hisuian/icon.png b/graphics/pokemon/electrode/hisuian/icon.png index d624e246cb..76efc29827 100644 Binary files a/graphics/pokemon/electrode/hisuian/icon.png and b/graphics/pokemon/electrode/hisuian/icon.png differ diff --git a/graphics/pokemon/enamorus/icon.png b/graphics/pokemon/enamorus/icon.png index c127c07345..3c808f30b1 100644 Binary files a/graphics/pokemon/enamorus/icon.png and b/graphics/pokemon/enamorus/icon.png differ diff --git a/graphics/pokemon/enamorus/therian/icon.png b/graphics/pokemon/enamorus/therian/icon.png index dfca5087fe..fcaf4f41d3 100644 Binary files a/graphics/pokemon/enamorus/therian/icon.png and b/graphics/pokemon/enamorus/therian/icon.png differ diff --git a/graphics/pokemon/espathra/icon.png b/graphics/pokemon/espathra/icon.png index cdca057311..12039cb258 100755 Binary files a/graphics/pokemon/espathra/icon.png and b/graphics/pokemon/espathra/icon.png differ diff --git a/graphics/pokemon/farigiraf/icon.png b/graphics/pokemon/farigiraf/icon.png index 0ef8b01ae8..a2657d0e5d 100755 Binary files a/graphics/pokemon/farigiraf/icon.png and b/graphics/pokemon/farigiraf/icon.png differ diff --git a/graphics/pokemon/fezandipiti/icon.png b/graphics/pokemon/fezandipiti/icon.png index 1bd6d0bf31..eb150e6db9 100644 Binary files a/graphics/pokemon/fezandipiti/icon.png and b/graphics/pokemon/fezandipiti/icon.png differ diff --git a/graphics/pokemon/fidough/icon.png b/graphics/pokemon/fidough/icon.png index 2a6c4b15f5..eea5ee85e3 100755 Binary files a/graphics/pokemon/fidough/icon.png and b/graphics/pokemon/fidough/icon.png differ diff --git a/graphics/pokemon/finizen/icon.png b/graphics/pokemon/finizen/icon.png index b82b4c673f..b689ed7879 100755 Binary files a/graphics/pokemon/finizen/icon.png and b/graphics/pokemon/finizen/icon.png differ diff --git a/graphics/pokemon/flamigo/icon.png b/graphics/pokemon/flamigo/icon.png index 0f0381579c..f1970373f4 100755 Binary files a/graphics/pokemon/flamigo/icon.png and b/graphics/pokemon/flamigo/icon.png differ diff --git a/graphics/pokemon/flittle/icon.png b/graphics/pokemon/flittle/icon.png index f588d537ef..1f96368e89 100755 Binary files a/graphics/pokemon/flittle/icon.png and b/graphics/pokemon/flittle/icon.png differ diff --git a/graphics/pokemon/floragato/icon.png b/graphics/pokemon/floragato/icon.png index aaf9a3b10d..448ee0d191 100644 Binary files a/graphics/pokemon/floragato/icon.png and b/graphics/pokemon/floragato/icon.png differ diff --git a/graphics/pokemon/flutter_mane/icon.png b/graphics/pokemon/flutter_mane/icon.png index 2b65fc048f..ab756908b9 100755 Binary files a/graphics/pokemon/flutter_mane/icon.png and b/graphics/pokemon/flutter_mane/icon.png differ diff --git a/graphics/pokemon/frigibax/icon.png b/graphics/pokemon/frigibax/icon.png index b50575cd47..e248df892b 100755 Binary files a/graphics/pokemon/frigibax/icon.png and b/graphics/pokemon/frigibax/icon.png differ diff --git a/graphics/pokemon/fuecoco/icon.png b/graphics/pokemon/fuecoco/icon.png index 923e5f03fd..31bcf19b0f 100755 Binary files a/graphics/pokemon/fuecoco/icon.png and b/graphics/pokemon/fuecoco/icon.png differ diff --git a/graphics/pokemon/garganacl/icon.png b/graphics/pokemon/garganacl/icon.png index bc2d038478..e9a0245277 100755 Binary files a/graphics/pokemon/garganacl/icon.png and b/graphics/pokemon/garganacl/icon.png differ diff --git a/graphics/pokemon/gholdengo/icon.png b/graphics/pokemon/gholdengo/icon.png index 99d0e122f2..a49e6561a9 100755 Binary files a/graphics/pokemon/gholdengo/icon.png and b/graphics/pokemon/gholdengo/icon.png differ diff --git a/graphics/pokemon/gimmighoul/icon.png b/graphics/pokemon/gimmighoul/icon.png index 9191406326..79167add31 100644 Binary files a/graphics/pokemon/gimmighoul/icon.png and b/graphics/pokemon/gimmighoul/icon.png differ diff --git a/graphics/pokemon/gimmighoul/roaming/icon.png b/graphics/pokemon/gimmighoul/roaming/icon.png index e803b52554..13ec7881b5 100644 Binary files a/graphics/pokemon/gimmighoul/roaming/icon.png and b/graphics/pokemon/gimmighoul/roaming/icon.png differ diff --git a/graphics/pokemon/glimmet/icon.png b/graphics/pokemon/glimmet/icon.png index 1bc74def32..c7b16b5631 100755 Binary files a/graphics/pokemon/glimmet/icon.png and b/graphics/pokemon/glimmet/icon.png differ diff --git a/graphics/pokemon/glimmora/icon.png b/graphics/pokemon/glimmora/icon.png index 12e50f0cbc..6cc6f8922f 100755 Binary files a/graphics/pokemon/glimmora/icon.png and b/graphics/pokemon/glimmora/icon.png differ diff --git a/graphics/pokemon/goodra/hisuian/icon.png b/graphics/pokemon/goodra/hisuian/icon.png index 3216854349..283617c206 100644 Binary files a/graphics/pokemon/goodra/hisuian/icon.png and b/graphics/pokemon/goodra/hisuian/icon.png differ diff --git a/graphics/pokemon/gouging_fire/icon.png b/graphics/pokemon/gouging_fire/icon.png new file mode 100644 index 0000000000..38e429abbf Binary files /dev/null and b/graphics/pokemon/gouging_fire/icon.png differ diff --git a/graphics/pokemon/grafaiai/icon.png b/graphics/pokemon/grafaiai/icon.png index 9e027481aa..3ba6803542 100755 Binary files a/graphics/pokemon/grafaiai/icon.png and b/graphics/pokemon/grafaiai/icon.png differ diff --git a/graphics/pokemon/great_tusk/icon.png b/graphics/pokemon/great_tusk/icon.png index 30384d570d..60bbe9f419 100755 Binary files a/graphics/pokemon/great_tusk/icon.png and b/graphics/pokemon/great_tusk/icon.png differ diff --git a/graphics/pokemon/greavard/icon.png b/graphics/pokemon/greavard/icon.png index a43e9a3875..96b16a4a8c 100755 Binary files a/graphics/pokemon/greavard/icon.png and b/graphics/pokemon/greavard/icon.png differ diff --git a/graphics/pokemon/growlithe/hisuian/icon.png b/graphics/pokemon/growlithe/hisuian/icon.png index b2b03733f0..71a2ffdbae 100644 Binary files a/graphics/pokemon/growlithe/hisuian/icon.png and b/graphics/pokemon/growlithe/hisuian/icon.png differ diff --git a/graphics/pokemon/houndstone/icon.png b/graphics/pokemon/houndstone/icon.png index 51d26434c8..9777c7b79a 100755 Binary files a/graphics/pokemon/houndstone/icon.png and b/graphics/pokemon/houndstone/icon.png differ diff --git a/graphics/pokemon/hydrapple/icon.png b/graphics/pokemon/hydrapple/icon.png index 352513f998..1d7ce98bc7 100644 Binary files a/graphics/pokemon/hydrapple/icon.png and b/graphics/pokemon/hydrapple/icon.png differ diff --git a/graphics/pokemon/iron_boulder/icon.png b/graphics/pokemon/iron_boulder/icon.png new file mode 100644 index 0000000000..eafb584ccc Binary files /dev/null and b/graphics/pokemon/iron_boulder/icon.png differ diff --git a/graphics/pokemon/iron_bundle/icon.png b/graphics/pokemon/iron_bundle/icon.png index 99b380a543..df537e34d2 100755 Binary files a/graphics/pokemon/iron_bundle/icon.png and b/graphics/pokemon/iron_bundle/icon.png differ diff --git a/graphics/pokemon/iron_crown/icon.png b/graphics/pokemon/iron_crown/icon.png new file mode 100644 index 0000000000..cb127c82df Binary files /dev/null and b/graphics/pokemon/iron_crown/icon.png differ diff --git a/graphics/pokemon/iron_hands/icon.png b/graphics/pokemon/iron_hands/icon.png index d28b62a6d0..5fc933dd96 100755 Binary files a/graphics/pokemon/iron_hands/icon.png and b/graphics/pokemon/iron_hands/icon.png differ diff --git a/graphics/pokemon/iron_jugulis/icon.png b/graphics/pokemon/iron_jugulis/icon.png index 14ae400dfd..c043e15c6c 100755 Binary files a/graphics/pokemon/iron_jugulis/icon.png and b/graphics/pokemon/iron_jugulis/icon.png differ diff --git a/graphics/pokemon/iron_leaves/icon.png b/graphics/pokemon/iron_leaves/icon.png index a5d308e6cb..16eb1d5dc4 100644 Binary files a/graphics/pokemon/iron_leaves/icon.png and b/graphics/pokemon/iron_leaves/icon.png differ diff --git a/graphics/pokemon/iron_moth/icon.png b/graphics/pokemon/iron_moth/icon.png index ac43ad66ea..ff1e7353cb 100755 Binary files a/graphics/pokemon/iron_moth/icon.png and b/graphics/pokemon/iron_moth/icon.png differ diff --git a/graphics/pokemon/iron_thorns/icon.png b/graphics/pokemon/iron_thorns/icon.png index 48391a50c7..2c1e081217 100755 Binary files a/graphics/pokemon/iron_thorns/icon.png and b/graphics/pokemon/iron_thorns/icon.png differ diff --git a/graphics/pokemon/iron_treads/icon.png b/graphics/pokemon/iron_treads/icon.png index a75d7f93c9..25e9038a69 100755 Binary files a/graphics/pokemon/iron_treads/icon.png and b/graphics/pokemon/iron_treads/icon.png differ diff --git a/graphics/pokemon/iron_valiant/icon.png b/graphics/pokemon/iron_valiant/icon.png index c1441e5dd5..2d66aa5aed 100755 Binary files a/graphics/pokemon/iron_valiant/icon.png and b/graphics/pokemon/iron_valiant/icon.png differ diff --git a/graphics/pokemon/kilowattrel/icon.png b/graphics/pokemon/kilowattrel/icon.png index d4e5f7211b..cfa950dd2d 100755 Binary files a/graphics/pokemon/kilowattrel/icon.png and b/graphics/pokemon/kilowattrel/icon.png differ diff --git a/graphics/pokemon/kingambit/icon.png b/graphics/pokemon/kingambit/icon.png index ce85b3c190..c4d91769d9 100755 Binary files a/graphics/pokemon/kingambit/icon.png and b/graphics/pokemon/kingambit/icon.png differ diff --git a/graphics/pokemon/klawf/icon.png b/graphics/pokemon/klawf/icon.png index e7c232f130..6b393ebdfb 100755 Binary files a/graphics/pokemon/klawf/icon.png and b/graphics/pokemon/klawf/icon.png differ diff --git a/graphics/pokemon/kleavor/icon.png b/graphics/pokemon/kleavor/icon.png index 4443cc1433..63d9653597 100644 Binary files a/graphics/pokemon/kleavor/icon.png and b/graphics/pokemon/kleavor/icon.png differ diff --git a/graphics/pokemon/koraidon/icon.png b/graphics/pokemon/koraidon/icon.png index 127a03e5d7..4048255617 100755 Binary files a/graphics/pokemon/koraidon/icon.png and b/graphics/pokemon/koraidon/icon.png differ diff --git a/graphics/pokemon/lechonk/icon.png b/graphics/pokemon/lechonk/icon.png index d368c427be..6123d0773a 100755 Binary files a/graphics/pokemon/lechonk/icon.png and b/graphics/pokemon/lechonk/icon.png differ diff --git a/graphics/pokemon/lilligant/hisuian/icon.png b/graphics/pokemon/lilligant/hisuian/icon.png index c8149843fc..67809d8897 100644 Binary files a/graphics/pokemon/lilligant/hisuian/icon.png and b/graphics/pokemon/lilligant/hisuian/icon.png differ diff --git a/graphics/pokemon/lokix/icon.png b/graphics/pokemon/lokix/icon.png index 205de36a02..e6e944b6b9 100755 Binary files a/graphics/pokemon/lokix/icon.png and b/graphics/pokemon/lokix/icon.png differ diff --git a/graphics/pokemon/mabosstiff/icon.png b/graphics/pokemon/mabosstiff/icon.png index 3b99df2d4a..e18a9d6c1c 100755 Binary files a/graphics/pokemon/mabosstiff/icon.png and b/graphics/pokemon/mabosstiff/icon.png differ diff --git a/graphics/pokemon/maschiff/icon.png b/graphics/pokemon/maschiff/icon.png index f5127dcc42..cb2308d15b 100755 Binary files a/graphics/pokemon/maschiff/icon.png and b/graphics/pokemon/maschiff/icon.png differ diff --git a/graphics/pokemon/maushold/four/icon.png b/graphics/pokemon/maushold/four/icon.png index 97c2d70826..fc6684d61b 100755 Binary files a/graphics/pokemon/maushold/four/icon.png and b/graphics/pokemon/maushold/four/icon.png differ diff --git a/graphics/pokemon/maushold/icon.png b/graphics/pokemon/maushold/icon.png index 728aca58a1..48cb9d2c26 100755 Binary files a/graphics/pokemon/maushold/icon.png and b/graphics/pokemon/maushold/icon.png differ diff --git a/graphics/pokemon/meowscarada/icon.png b/graphics/pokemon/meowscarada/icon.png index 5b79821453..2a6d199d22 100755 Binary files a/graphics/pokemon/meowscarada/icon.png and b/graphics/pokemon/meowscarada/icon.png differ diff --git a/graphics/pokemon/miraidon/icon.png b/graphics/pokemon/miraidon/icon.png index 3ccf056b51..776082feb0 100755 Binary files a/graphics/pokemon/miraidon/icon.png and b/graphics/pokemon/miraidon/icon.png differ diff --git a/graphics/pokemon/munkidori/icon.png b/graphics/pokemon/munkidori/icon.png index 20144ff87e..338d84d3ef 100644 Binary files a/graphics/pokemon/munkidori/icon.png and b/graphics/pokemon/munkidori/icon.png differ diff --git a/graphics/pokemon/nacli/icon.png b/graphics/pokemon/nacli/icon.png index ed0895c1d8..86522af3a1 100755 Binary files a/graphics/pokemon/nacli/icon.png and b/graphics/pokemon/nacli/icon.png differ diff --git a/graphics/pokemon/naclstack/icon.png b/graphics/pokemon/naclstack/icon.png index a536c3818d..133228573b 100755 Binary files a/graphics/pokemon/naclstack/icon.png and b/graphics/pokemon/naclstack/icon.png differ diff --git a/graphics/pokemon/nymble/icon.png b/graphics/pokemon/nymble/icon.png index 791bd0a427..74c4c79b52 100755 Binary files a/graphics/pokemon/nymble/icon.png and b/graphics/pokemon/nymble/icon.png differ diff --git a/graphics/pokemon/ogerpon/cornerstone/icon.png b/graphics/pokemon/ogerpon/cornerstone/icon.png new file mode 100644 index 0000000000..7a8323c815 Binary files /dev/null and b/graphics/pokemon/ogerpon/cornerstone/icon.png differ diff --git a/graphics/pokemon/ogerpon/hearthflame/icon.png b/graphics/pokemon/ogerpon/hearthflame/icon.png new file mode 100644 index 0000000000..108ac492cc Binary files /dev/null and b/graphics/pokemon/ogerpon/hearthflame/icon.png differ diff --git a/graphics/pokemon/ogerpon/icon.png b/graphics/pokemon/ogerpon/icon.png index 65448e8d1d..96f048f15b 100644 Binary files a/graphics/pokemon/ogerpon/icon.png and b/graphics/pokemon/ogerpon/icon.png differ diff --git a/graphics/pokemon/ogerpon/wellspring/icon.png b/graphics/pokemon/ogerpon/wellspring/icon.png new file mode 100644 index 0000000000..0257bc38e9 Binary files /dev/null and b/graphics/pokemon/ogerpon/wellspring/icon.png differ diff --git a/graphics/pokemon/oinkologne/female/icon.png b/graphics/pokemon/oinkologne/female/icon.png index 0acd6e2711..c1b272c73e 100755 Binary files a/graphics/pokemon/oinkologne/female/icon.png and b/graphics/pokemon/oinkologne/female/icon.png differ diff --git a/graphics/pokemon/oinkologne/female/iconTODO.png b/graphics/pokemon/oinkologne/female/iconTODO.png deleted file mode 100755 index 36ce1eb7f8..0000000000 Binary files a/graphics/pokemon/oinkologne/female/iconTODO.png and /dev/null differ diff --git a/graphics/pokemon/oinkologne/icon.png b/graphics/pokemon/oinkologne/icon.png index 0acd6e2711..055bfeab86 100755 Binary files a/graphics/pokemon/oinkologne/icon.png and b/graphics/pokemon/oinkologne/icon.png differ diff --git a/graphics/pokemon/okidogi/icon.png b/graphics/pokemon/okidogi/icon.png index 91984549c3..fd4809f80d 100644 Binary files a/graphics/pokemon/okidogi/icon.png and b/graphics/pokemon/okidogi/icon.png differ diff --git a/graphics/pokemon/orthworm/icon.png b/graphics/pokemon/orthworm/icon.png index 9cb39cc79b..5c4dd54525 100755 Binary files a/graphics/pokemon/orthworm/icon.png and b/graphics/pokemon/orthworm/icon.png differ diff --git a/graphics/pokemon/overqwil/icon.png b/graphics/pokemon/overqwil/icon.png index 661013b728..9af70e8057 100644 Binary files a/graphics/pokemon/overqwil/icon.png and b/graphics/pokemon/overqwil/icon.png differ diff --git a/graphics/pokemon/palafin/hero/icon.png b/graphics/pokemon/palafin/hero/icon.png index 8dd8a11844..8f581581cf 100755 Binary files a/graphics/pokemon/palafin/hero/icon.png and b/graphics/pokemon/palafin/hero/icon.png differ diff --git a/graphics/pokemon/palafin/icon.png b/graphics/pokemon/palafin/icon.png index d24e846fc5..14de30254f 100755 Binary files a/graphics/pokemon/palafin/icon.png and b/graphics/pokemon/palafin/icon.png differ diff --git a/graphics/pokemon/pawmi/icon.png b/graphics/pokemon/pawmi/icon.png index a7fc302fe0..bcef3f24b0 100755 Binary files a/graphics/pokemon/pawmi/icon.png and b/graphics/pokemon/pawmi/icon.png differ diff --git a/graphics/pokemon/pawmo/icon.png b/graphics/pokemon/pawmo/icon.png index 41cc6b4f9a..ef69e9e301 100755 Binary files a/graphics/pokemon/pawmo/icon.png and b/graphics/pokemon/pawmo/icon.png differ diff --git a/graphics/pokemon/pawmot/icon.png b/graphics/pokemon/pawmot/icon.png index cc9d2e942a..90b36e7378 100755 Binary files a/graphics/pokemon/pawmot/icon.png and b/graphics/pokemon/pawmot/icon.png differ diff --git a/graphics/pokemon/pecharunt/back.png b/graphics/pokemon/pecharunt/back.png new file mode 100644 index 0000000000..2948387f01 Binary files /dev/null and b/graphics/pokemon/pecharunt/back.png differ diff --git a/graphics/pokemon/pecharunt/front.png b/graphics/pokemon/pecharunt/front.png new file mode 100644 index 0000000000..9ee6108bf1 Binary files /dev/null and b/graphics/pokemon/pecharunt/front.png differ diff --git a/graphics/pokemon/pecharunt/icon.png b/graphics/pokemon/pecharunt/icon.png new file mode 100644 index 0000000000..1027623748 Binary files /dev/null and b/graphics/pokemon/pecharunt/icon.png differ diff --git a/graphics/pokemon/pecharunt/normal.pal b/graphics/pokemon/pecharunt/normal.pal new file mode 100644 index 0000000000..ae673bc0b9 --- /dev/null +++ b/graphics/pokemon/pecharunt/normal.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +154 212 167 +8 8 8 +68 68 77 +80 11 62 +186 33 155 +36 36 42 +255 39 255 +35 20 68 +92 52 154 +220 147 205 +55 30 102 +139 93 215 +255 255 255 +189 189 189 +129 26 101 +148 50 154 diff --git a/graphics/pokemon/pecharunt/shiny.pal b/graphics/pokemon/pecharunt/shiny.pal new file mode 100644 index 0000000000..da27c6845b --- /dev/null +++ b/graphics/pokemon/pecharunt/shiny.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +154 212 167 +8 8 8 +68 68 77 +80 11 62 +186 33 155 +36 36 42 +255 39 255 +144 80 30 +234 176 47 +220 147 205 +193 133 36 +244 208 96 +255 255 255 +189 189 189 +129 26 101 +148 50 154 diff --git a/graphics/pokemon/pikachu/partner/icon.png b/graphics/pokemon/pikachu/partner/icon.png new file mode 100644 index 0000000000..891f0d1b3e Binary files /dev/null and b/graphics/pokemon/pikachu/partner/icon.png differ diff --git a/graphics/pokemon/pikachu/partner/iconf.png b/graphics/pokemon/pikachu/partner/iconf.png new file mode 100644 index 0000000000..8779879f07 Binary files /dev/null and b/graphics/pokemon/pikachu/partner/iconf.png differ diff --git a/graphics/pokemon/poltchageist/icon.png b/graphics/pokemon/poltchageist/icon.png index 6b686ad08d..55fc98ec84 100644 Binary files a/graphics/pokemon/poltchageist/icon.png and b/graphics/pokemon/poltchageist/icon.png differ diff --git a/graphics/pokemon/quaquaval/icon.png b/graphics/pokemon/quaquaval/icon.png index 4e68d84ff4..d9b37ea902 100755 Binary files a/graphics/pokemon/quaquaval/icon.png and b/graphics/pokemon/quaquaval/icon.png differ diff --git a/graphics/pokemon/quaxly/icon.png b/graphics/pokemon/quaxly/icon.png index 4036957445..6df869ecdc 100755 Binary files a/graphics/pokemon/quaxly/icon.png and b/graphics/pokemon/quaxly/icon.png differ diff --git a/graphics/pokemon/quaxwell/icon.png b/graphics/pokemon/quaxwell/icon.png index 3806542c09..73a2d4ace7 100755 Binary files a/graphics/pokemon/quaxwell/icon.png and b/graphics/pokemon/quaxwell/icon.png differ diff --git a/graphics/pokemon/qwilfish/hisuian/icon.png b/graphics/pokemon/qwilfish/hisuian/icon.png index 6936dfe88d..30b8f5ad61 100644 Binary files a/graphics/pokemon/qwilfish/hisuian/icon.png and b/graphics/pokemon/qwilfish/hisuian/icon.png differ diff --git a/graphics/pokemon/rabsca/icon.png b/graphics/pokemon/rabsca/icon.png index 57c93e30a3..83e9bcbeb7 100755 Binary files a/graphics/pokemon/rabsca/icon.png and b/graphics/pokemon/rabsca/icon.png differ diff --git a/graphics/pokemon/raging_bolt/icon.png b/graphics/pokemon/raging_bolt/icon.png new file mode 100644 index 0000000000..f31beb8293 Binary files /dev/null and b/graphics/pokemon/raging_bolt/icon.png differ diff --git a/graphics/pokemon/rellor/icon.png b/graphics/pokemon/rellor/icon.png index 56ea140347..9c443bcee9 100755 Binary files a/graphics/pokemon/rellor/icon.png and b/graphics/pokemon/rellor/icon.png differ diff --git a/graphics/pokemon/revavroom/icon.png b/graphics/pokemon/revavroom/icon.png index 8d3a2ee0cc..0cece4d451 100755 Binary files a/graphics/pokemon/revavroom/icon.png and b/graphics/pokemon/revavroom/icon.png differ diff --git a/graphics/pokemon/roaring_moon/icon.png b/graphics/pokemon/roaring_moon/icon.png index d8d82fb015..e9dabef1ac 100755 Binary files a/graphics/pokemon/roaring_moon/icon.png and b/graphics/pokemon/roaring_moon/icon.png differ diff --git a/graphics/pokemon/samurott/hisuian/icon.png b/graphics/pokemon/samurott/hisuian/icon.png index fdcbe6718f..8ffa1a3f17 100644 Binary files a/graphics/pokemon/samurott/hisuian/icon.png and b/graphics/pokemon/samurott/hisuian/icon.png differ diff --git a/graphics/pokemon/sandy_shocks/icon.png b/graphics/pokemon/sandy_shocks/icon.png index 99d693a1ac..956607df16 100755 Binary files a/graphics/pokemon/sandy_shocks/icon.png and b/graphics/pokemon/sandy_shocks/icon.png differ diff --git a/graphics/pokemon/scovillain/icon.png b/graphics/pokemon/scovillain/icon.png index f346a1cb48..f0763b3463 100755 Binary files a/graphics/pokemon/scovillain/icon.png and b/graphics/pokemon/scovillain/icon.png differ diff --git a/graphics/pokemon/scream_tail/icon.png b/graphics/pokemon/scream_tail/icon.png index 09ca4083ec..13669394a0 100755 Binary files a/graphics/pokemon/scream_tail/icon.png and b/graphics/pokemon/scream_tail/icon.png differ diff --git a/graphics/pokemon/shroodle/icon.png b/graphics/pokemon/shroodle/icon.png index 1e7a9430d8..0ea3daa36e 100755 Binary files a/graphics/pokemon/shroodle/icon.png and b/graphics/pokemon/shroodle/icon.png differ diff --git a/graphics/pokemon/sinistcha/icon.png b/graphics/pokemon/sinistcha/icon.png index 74fc0b2643..07bb624d17 100644 Binary files a/graphics/pokemon/sinistcha/icon.png and b/graphics/pokemon/sinistcha/icon.png differ diff --git a/graphics/pokemon/skeledirge/icon.png b/graphics/pokemon/skeledirge/icon.png index 901aab95d9..6fb9ba2c44 100755 Binary files a/graphics/pokemon/skeledirge/icon.png and b/graphics/pokemon/skeledirge/icon.png differ diff --git a/graphics/pokemon/sliggoo/hisuian/icon.png b/graphics/pokemon/sliggoo/hisuian/icon.png index c66baae5a9..c2cdfc0bca 100644 Binary files a/graphics/pokemon/sliggoo/hisuian/icon.png and b/graphics/pokemon/sliggoo/hisuian/icon.png differ diff --git a/graphics/pokemon/slither_wing/icon.png b/graphics/pokemon/slither_wing/icon.png index e969280a5d..5eccb7f4f0 100755 Binary files a/graphics/pokemon/slither_wing/icon.png and b/graphics/pokemon/slither_wing/icon.png differ diff --git a/graphics/pokemon/smoliv/icon.png b/graphics/pokemon/smoliv/icon.png index 53b8ffc945..dfddec3177 100755 Binary files a/graphics/pokemon/smoliv/icon.png and b/graphics/pokemon/smoliv/icon.png differ diff --git a/graphics/pokemon/sneasel/hisuian/icon.png b/graphics/pokemon/sneasel/hisuian/icon.png index bd9cae88b9..f2646a7ad0 100644 Binary files a/graphics/pokemon/sneasel/hisuian/icon.png and b/graphics/pokemon/sneasel/hisuian/icon.png differ diff --git a/graphics/pokemon/sneasler/icon.png b/graphics/pokemon/sneasler/icon.png index 4238b0e6a3..d3612a640c 100644 Binary files a/graphics/pokemon/sneasler/icon.png and b/graphics/pokemon/sneasler/icon.png differ diff --git a/graphics/pokemon/spidops/icon.png b/graphics/pokemon/spidops/icon.png index c35aa36c61..cdb680571f 100755 Binary files a/graphics/pokemon/spidops/icon.png and b/graphics/pokemon/spidops/icon.png differ diff --git a/graphics/pokemon/sprigatito/icon.png b/graphics/pokemon/sprigatito/icon.png index 114fcff288..22fc9125d8 100755 Binary files a/graphics/pokemon/sprigatito/icon.png and b/graphics/pokemon/sprigatito/icon.png differ diff --git a/graphics/pokemon/squawkabilly/blue_plumage/icon.png b/graphics/pokemon/squawkabilly/blue_plumage/icon.png index 4ad732211c..3226b3acb2 100755 Binary files a/graphics/pokemon/squawkabilly/blue_plumage/icon.png and b/graphics/pokemon/squawkabilly/blue_plumage/icon.png differ diff --git a/graphics/pokemon/squawkabilly/icon.png b/graphics/pokemon/squawkabilly/icon.png index 540b7521a8..2abbffb286 100644 Binary files a/graphics/pokemon/squawkabilly/icon.png and b/graphics/pokemon/squawkabilly/icon.png differ diff --git a/graphics/pokemon/squawkabilly/white_plumage/icon.png b/graphics/pokemon/squawkabilly/white_plumage/icon.png index a784c6cdda..ecdabe3630 100755 Binary files a/graphics/pokemon/squawkabilly/white_plumage/icon.png and b/graphics/pokemon/squawkabilly/white_plumage/icon.png differ diff --git a/graphics/pokemon/squawkabilly/yellow_plumage/icon.png b/graphics/pokemon/squawkabilly/yellow_plumage/icon.png index a042d981d0..085b3e0e2b 100755 Binary files a/graphics/pokemon/squawkabilly/yellow_plumage/icon.png and b/graphics/pokemon/squawkabilly/yellow_plumage/icon.png differ diff --git a/graphics/pokemon/tadbulb/icon.png b/graphics/pokemon/tadbulb/icon.png index 0341a387fb..de71775609 100755 Binary files a/graphics/pokemon/tadbulb/icon.png and b/graphics/pokemon/tadbulb/icon.png differ diff --git a/graphics/pokemon/tandemaus/icon.png b/graphics/pokemon/tandemaus/icon.png index 8effa87c57..5e8443f8d3 100755 Binary files a/graphics/pokemon/tandemaus/icon.png and b/graphics/pokemon/tandemaus/icon.png differ diff --git a/graphics/pokemon/tarountula/icon.png b/graphics/pokemon/tarountula/icon.png index d4802eb0ea..67f4423f90 100755 Binary files a/graphics/pokemon/tarountula/icon.png and b/graphics/pokemon/tarountula/icon.png differ diff --git a/graphics/pokemon/tatsugiri/droopy/icon.png b/graphics/pokemon/tatsugiri/droopy/icon.png index 48e8c01fd0..041a9a4469 100755 Binary files a/graphics/pokemon/tatsugiri/droopy/icon.png and b/graphics/pokemon/tatsugiri/droopy/icon.png differ diff --git a/graphics/pokemon/tatsugiri/icon.png b/graphics/pokemon/tatsugiri/icon.png index 98fe8aa569..0db952cbd8 100644 Binary files a/graphics/pokemon/tatsugiri/icon.png and b/graphics/pokemon/tatsugiri/icon.png differ diff --git a/graphics/pokemon/tatsugiri/stretchy/icon.png b/graphics/pokemon/tatsugiri/stretchy/icon.png index 1634ec3178..9403a331e3 100755 Binary files a/graphics/pokemon/tatsugiri/stretchy/icon.png and b/graphics/pokemon/tatsugiri/stretchy/icon.png differ diff --git a/graphics/pokemon/tauros/paldean_aqua_breed/icon.png b/graphics/pokemon/tauros/paldean_aqua_breed/icon.png index a0421d7dd0..b2f37e2c13 100644 Binary files a/graphics/pokemon/tauros/paldean_aqua_breed/icon.png and b/graphics/pokemon/tauros/paldean_aqua_breed/icon.png differ diff --git a/graphics/pokemon/tauros/paldean_blaze_breed/icon.png b/graphics/pokemon/tauros/paldean_blaze_breed/icon.png index 25ec7e0463..3eed6b8bd8 100644 Binary files a/graphics/pokemon/tauros/paldean_blaze_breed/icon.png and b/graphics/pokemon/tauros/paldean_blaze_breed/icon.png differ diff --git a/graphics/pokemon/tauros/paldean_combat_breed/icon.png b/graphics/pokemon/tauros/paldean_combat_breed/icon.png index daa2eb7882..22ea3c94f0 100644 Binary files a/graphics/pokemon/tauros/paldean_combat_breed/icon.png and b/graphics/pokemon/tauros/paldean_combat_breed/icon.png differ diff --git a/graphics/pokemon/terapagos/icon.png b/graphics/pokemon/terapagos/icon.png new file mode 100644 index 0000000000..0376369455 Binary files /dev/null and b/graphics/pokemon/terapagos/icon.png differ diff --git a/graphics/pokemon/terapagos/stellar/icon.png b/graphics/pokemon/terapagos/stellar/icon.png new file mode 100644 index 0000000000..f11525da0d Binary files /dev/null and b/graphics/pokemon/terapagos/stellar/icon.png differ diff --git a/graphics/pokemon/terapagos/terastal/icon.png b/graphics/pokemon/terapagos/terastal/icon.png new file mode 100644 index 0000000000..0f15ff3bb6 Binary files /dev/null and b/graphics/pokemon/terapagos/terastal/icon.png differ diff --git a/graphics/pokemon/ting_lu/icon.png b/graphics/pokemon/ting_lu/icon.png index 0b1f975f9e..a4cbc121a2 100755 Binary files a/graphics/pokemon/ting_lu/icon.png and b/graphics/pokemon/ting_lu/icon.png differ diff --git a/graphics/pokemon/tinkatink/icon.png b/graphics/pokemon/tinkatink/icon.png index fc7300cb0a..0eaec6b140 100644 Binary files a/graphics/pokemon/tinkatink/icon.png and b/graphics/pokemon/tinkatink/icon.png differ diff --git a/graphics/pokemon/tinkaton/icon.png b/graphics/pokemon/tinkaton/icon.png index 72ab26b86b..15175f41e2 100755 Binary files a/graphics/pokemon/tinkaton/icon.png and b/graphics/pokemon/tinkaton/icon.png differ diff --git a/graphics/pokemon/tinkatuff/icon.png b/graphics/pokemon/tinkatuff/icon.png index 7ab30334fa..345da19116 100755 Binary files a/graphics/pokemon/tinkatuff/icon.png and b/graphics/pokemon/tinkatuff/icon.png differ diff --git a/graphics/pokemon/toedscool/icon.png b/graphics/pokemon/toedscool/icon.png index 91edeb2472..6021e614df 100755 Binary files a/graphics/pokemon/toedscool/icon.png and b/graphics/pokemon/toedscool/icon.png differ diff --git a/graphics/pokemon/toedscruel/icon.png b/graphics/pokemon/toedscruel/icon.png index fe3f98f9fa..6095eae573 100755 Binary files a/graphics/pokemon/toedscruel/icon.png and b/graphics/pokemon/toedscruel/icon.png differ diff --git a/graphics/pokemon/typhlosion/hisuian/icon.png b/graphics/pokemon/typhlosion/hisuian/icon.png index c3e0474968..58f2f11198 100644 Binary files a/graphics/pokemon/typhlosion/hisuian/icon.png and b/graphics/pokemon/typhlosion/hisuian/icon.png differ diff --git a/graphics/pokemon/ursaluna/bloodmoon/icon.png b/graphics/pokemon/ursaluna/bloodmoon/icon.png new file mode 100644 index 0000000000..e5fbf80555 Binary files /dev/null and b/graphics/pokemon/ursaluna/bloodmoon/icon.png differ diff --git a/graphics/pokemon/ursaluna/icon.png b/graphics/pokemon/ursaluna/icon.png index 8a84704072..d56041d555 100644 Binary files a/graphics/pokemon/ursaluna/icon.png and b/graphics/pokemon/ursaluna/icon.png differ diff --git a/graphics/pokemon/varoom/icon.png b/graphics/pokemon/varoom/icon.png index 7debadffde..e342395296 100755 Binary files a/graphics/pokemon/varoom/icon.png and b/graphics/pokemon/varoom/icon.png differ diff --git a/graphics/pokemon/veluza/icon.png b/graphics/pokemon/veluza/icon.png index 6d06051669..6282d9c37c 100755 Binary files a/graphics/pokemon/veluza/icon.png and b/graphics/pokemon/veluza/icon.png differ diff --git a/graphics/pokemon/voltorb/hisuian/icon.png b/graphics/pokemon/voltorb/hisuian/icon.png index 2a35e4ec33..c3381d7fde 100644 Binary files a/graphics/pokemon/voltorb/hisuian/icon.png and b/graphics/pokemon/voltorb/hisuian/icon.png differ diff --git a/graphics/pokemon/walking_wake/icon.png b/graphics/pokemon/walking_wake/icon.png index 9260531ecf..a3a37af7f1 100644 Binary files a/graphics/pokemon/walking_wake/icon.png and b/graphics/pokemon/walking_wake/icon.png differ diff --git a/graphics/pokemon/wattrel/icon.png b/graphics/pokemon/wattrel/icon.png index a0a8bc9d49..33bf137c90 100755 Binary files a/graphics/pokemon/wattrel/icon.png and b/graphics/pokemon/wattrel/icon.png differ diff --git a/graphics/pokemon/wiglett/icon.png b/graphics/pokemon/wiglett/icon.png index 668309c68e..4c8e951fd8 100755 Binary files a/graphics/pokemon/wiglett/icon.png and b/graphics/pokemon/wiglett/icon.png differ diff --git a/graphics/pokemon/wo_chien/icon.png b/graphics/pokemon/wo_chien/icon.png index 22402d15c5..3772daf861 100755 Binary files a/graphics/pokemon/wo_chien/icon.png and b/graphics/pokemon/wo_chien/icon.png differ diff --git a/graphics/pokemon/wugtrio/icon.png b/graphics/pokemon/wugtrio/icon.png index 1b67044787..f35b1d0456 100755 Binary files a/graphics/pokemon/wugtrio/icon.png and b/graphics/pokemon/wugtrio/icon.png differ diff --git a/graphics/pokemon/wyrdeer/icon.png b/graphics/pokemon/wyrdeer/icon.png index 905dfe083c..7786e2b3a4 100644 Binary files a/graphics/pokemon/wyrdeer/icon.png and b/graphics/pokemon/wyrdeer/icon.png differ diff --git a/graphics/pokemon/zoroark/hisuian/icon.png b/graphics/pokemon/zoroark/hisuian/icon.png index 6c4f6faf1b..a9610d1fdb 100644 Binary files a/graphics/pokemon/zoroark/hisuian/icon.png and b/graphics/pokemon/zoroark/hisuian/icon.png differ diff --git a/graphics/pokemon/zorua/hisuian/icon.png b/graphics/pokemon/zorua/hisuian/icon.png index 17f9229a2f..79faea9a1a 100644 Binary files a/graphics/pokemon/zorua/hisuian/icon.png and b/graphics/pokemon/zorua/hisuian/icon.png differ diff --git a/include/battle.h b/include/battle.h index 58e8d71774..1274ffcbfc 100644 --- a/include/battle.h +++ b/include/battle.h @@ -298,7 +298,8 @@ struct FieldTimer struct WishFutureKnock { u8 futureSightCounter[MAX_BATTLERS_COUNT]; - u8 futureSightAttacker[MAX_BATTLERS_COUNT]; + u8 futureSightBattlerIndex[MAX_BATTLERS_COUNT]; + u8 futureSightPartyIndex[MAX_BATTLERS_COUNT]; u16 futureSightMove[MAX_BATTLERS_COUNT]; u8 wishCounter[MAX_BATTLERS_COUNT]; u8 wishPartyId[MAX_BATTLERS_COUNT]; diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index d77ddfdfbc..540390bb53 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -37,7 +37,7 @@ void BufferMoveToLearnIntoBattleTextBuff2(void); void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags); bool8 UproarWakeUpCheck(u8 battlerId); bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move); -bool32 DoesDisguiseBlockMove(u32 battlerAtk, u32 battlerDef, u32 move); +bool32 DoesDisguiseBlockMove(u32 battler, u32 move); bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget); bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget); bool32 CanUseLastResort(u8 battlerId); diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 13998ac46c..b09ccc2190 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -205,8 +205,8 @@ extern const u8 BattleScript_BerryCureBrnEnd2[]; extern const u8 BattleScript_BerryCureBrnRet[]; extern const u8 BattleScript_BerryCureFrzEnd2[]; extern const u8 BattleScript_BerryCureFrzRet[]; -extern const u8 BattleScript_BerryCureFsbEnd2[]; -extern const u8 BattleScript_BerryCureFsbRet[]; +extern const u8 BattleScript_BerryCureFrbEnd2[]; +extern const u8 BattleScript_BerryCureFrbRet[]; extern const u8 BattleScript_BerryCureSlpEnd2[]; extern const u8 BattleScript_BerryCureSlpRet[]; extern const u8 BattleScript_BerryCureConfusionEnd2[]; @@ -411,6 +411,7 @@ extern const u8 BattleScript_ElectricTerrainPrevents[]; extern const u8 BattleScript_DarkTypePreventsPrankster[]; extern const u8 BattleScript_GulpMissileGorging[]; extern const u8 BattleScript_GulpMissileGulping[]; +extern const u8 BattleScript_GulpMissileFormChange[]; extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[]; extern const u8 BattleScript_DesolateLandActivates[]; extern const u8 BattleScript_PrimordialSeaActivates[]; diff --git a/include/battle_util.h b/include/battle_util.h index 8606e7ae0b..13e03c58dd 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -54,6 +54,7 @@ #define ITEMEFFECT_ORBS 6 #define ITEMEFFECT_LIFEORB_SHELLBELL 7 #define ITEMEFFECT_USE_LAST_ITEM 8 // move end effects for just the battler, not whole field +#define ITEMEFFECT_STATS_CHANGED 9 // For White Herb and Eject Pack #define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK))) diff --git a/include/battle_z_move.h b/include/battle_z_move.h index 697bfa676c..92fb685b2f 100644 --- a/include/battle_z_move.h +++ b/include/battle_z_move.h @@ -21,6 +21,7 @@ void CreateZMoveTriggerSprite(u8, bool8); void HideZMoveTriggerSprite(void); bool32 IsZMoveTriggerSpriteActive(void); void DestroyZMoveTriggerSprite(void); +u16 GetTypeBasedZMove(u16 move, u8 battler); bool32 MoveSelectionDisplayZMove(u16 zmove, u32 battler); void SetZEffect(void); bool32 IsZMoveUsable(u8 battler, u16 moveIndex); diff --git a/include/config/battle.h b/include/config/battle.h index e497cf20bb..ec9966cbee 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -144,6 +144,7 @@ #define B_PROTEAN_LIBERO GEN_LATEST // In Gen9+, Protean and Libero change the user's type only once per Battle. #define B_INTREPID_SWORD GEN_LATEST // In Gen9+, Intrepid Sword raises Attack by one stage only once per Battle. #define B_DAUNTLESS_SHIELD GEN_LATEST // In Gen9+, Dauntless Shield raises Defense by one stage only once per Battle. +#define B_DISGUISE_HP_LOSS GEN_LATEST // In Gen8+, when a Disguised Mimikyu's Disguise is busted, upon changing to its Busted Form it loses HP equal to 1/8 of its maximum HP. // 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/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 6d635fe848..641e644ebc 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -304,9 +304,9 @@ #define MOVEEND_DEFROST 23 #define MOVEEND_RECOIL 24 #define MOVEEND_MAGICIAN 25 // Occurs after final multi-hit strike, and after other items/abilities would activate -#define MOVEEND_EJECT_BUTTON 26 -#define MOVEEND_RED_CARD 27 -#define MOVEEND_EJECT_PACK 28 +#define MOVEEND_EJECT_ITEMS 26 +#define MOVEEND_WHITE_HERB 27 +#define MOVEEND_RED_CARD 28 #define MOVEEND_LIFEORB_SHELLBELL 29 // Includes shell bell, throat spray, etc #define MOVEEND_CHANGED_ITEMS 30 #define MOVEEND_PICKPOCKET 31 diff --git a/include/constants/party_menu.h b/include/constants/party_menu.h index c860b425d4..1f37f3416c 100644 --- a/include/constants/party_menu.h +++ b/include/constants/party_menu.h @@ -11,7 +11,7 @@ #define AILMENT_BRN 5 #define AILMENT_PKRS 6 #define AILMENT_FNT 7 -#define AILMENT_FSB 8 +#define AILMENT_FRB 8 #define PARTY_LAYOUT_SINGLE 0 #define PARTY_LAYOUT_DOUBLE 1 diff --git a/include/data.h b/include/data.h index 6a916212d3..b4490e8cc7 100644 --- a/include/data.h +++ b/include/data.h @@ -67,13 +67,13 @@ struct TrainerMon u8 lvl; u8 ball; u8 friendship; - u8 nature : 5; - bool8 gender : 2; - bool8 isShiny : 1; - u8 dynamaxLevel : 4; - bool8 gigantamaxFactor : 1; - bool8 shouldDynamax : 1; - bool8 shouldTerastal : 1; + u8 nature:5; + bool8 gender:2; + bool8 isShiny:1; + u8 dynamaxLevel:4; + bool8 gigantamaxFactor:1; + bool8 shouldDynamax:1; + bool8 shouldTerastal:1; }; #define TRAINER_PARTY(partyArray) partyArray, .partySize = ARRAY_COUNT(partyArray) diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 276c4340de..d2ae9bc0c5 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -71,6 +71,12 @@ enum ReflectionTypes #define GROUND_EFFECT_FLAG_HOT_SPRINGS (1 << 18) #define GROUND_EFFECT_FLAG_SEAWEED (1 << 19) +// Sprite data for the CameraObject functions +#define sCamera_FollowSpriteId data[0] +#define sCamera_State data[1] +#define sCamera_MoveX data[2] +#define sCamera_MoveY data[3] + struct StepAnimTable { const union AnimCmd *const *anims; @@ -122,7 +128,7 @@ u8 TrySpawnObjectEvent(u8 localId, u8 mapNum, u8 mapGroup); u8 SpawnSpecialObjectEventParameterized(u8 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 elevation); u8 SpawnSpecialObjectEvent(struct ObjectEventTemplate *); void SetSpritePosToMapCoords(s16 mapX, s16 mapY, s16 *destX, s16 *destY); -void CameraObjectReset1(void); +void CameraObjectReset(void); void ObjectEventSetGraphicsId(struct ObjectEvent *, u8 graphicsId); void ObjectEventTurn(struct ObjectEvent *, u8 direction); void ObjectEventTurnByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 direction); @@ -210,7 +216,7 @@ u16 GetObjectPaletteTag(u8 palSlot); void UpdateObjectEventSpriteInvisibility(struct Sprite *sprite, bool8 invisible); s16 GetFigure8XOffset(s16 idx); s16 GetFigure8YOffset(s16 idx); -void CameraObjectReset2(void); +void CameraObjectFreeze(void); u8 GetObjectEventBerryTreeId(u8 objectEventId); void SetBerryTreeJustPicked(u8 mapId, u8 mapNumber, u8 mapGroup); bool8 IsBerryTreeSparkling(u8 localId, u8 mapNum, u8 mapGroup); diff --git a/include/gba/types.h b/include/gba/types.h index 4acaee2d23..65b65187f8 100644 --- a/include/gba/types.h +++ b/include/gba/types.h @@ -2,6 +2,7 @@ #define GUARD_GBA_TYPES_H #include +#include "gba/defines.h" typedef uint8_t u8; typedef uint16_t u16; diff --git a/include/pokemon.h b/include/pokemon.h index 0c3023a820..d37e5f4ae9 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -389,9 +389,9 @@ struct SpeciesInfo /*0x8C*/ /* 0x38 */ u16 trainerScale; /* 0x3A */ u16 trainerOffset; /* 0x3C */ const u8 *description; - /* 0x40 */ u8 bodyColor : 7; + /* 0x40 */ u8 bodyColor:7; // Graphical Data - u8 noFlip : 1; + u8 noFlip:1; /* 0x41 */ u8 frontAnimDelay; /* 0x42 */ u8 frontAnimId; /* 0x43 */ u8 backAnimId; diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 178e913a43..e904bb0c16 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2779,6 +2779,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case ABILITY_WATER_ABSORB: case ABILITY_DRY_SKIN: + case ABILITY_EARTH_EATER: if (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_HP_AWARE)) { RETURN_SCORE_MINUS(10); @@ -4886,6 +4887,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) { if ((effect == EFFECT_HEAL_PULSE || effect == EFFECT_HIT_ENEMY_HEAL_ALLY) || (moveType == TYPE_ELECTRIC && AI_DATA->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_VOLT_ABSORB) + || (moveType == TYPE_GROUND && AI_DATA->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_EARTH_EATER) || (moveType == TYPE_WATER && (AI_DATA->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_DRY_SKIN || AI_DATA->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_WATER_ABSORB))) { if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 231ab442a5..66bea62206 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -356,6 +356,11 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler, bool32 emitResult) absorbingTypeAbilities[0] = ABILITY_SAP_SIPPER; numAbsorbingAbilities = 1; } + else if (gMovesInfo[gLastLandedMoves[battler]].type == TYPE_GROUND) + { + absorbingTypeAbilities[0] = ABILITY_EARTH_EATER; + numAbsorbingAbilities = 1; + } else { return FALSE; @@ -1530,7 +1535,7 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler) s32 currentHP = startingHP; // No damage being dealt - if (damageTaken + statusDamage + recurringDamage == 0) + if (damageTaken + statusDamage + recurringDamage < recurringHealing) return startingHP; // Mon fainted to hazards @@ -1589,7 +1594,7 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler) } // Healing from items occurs before status so we can do the rest in one line - if (currentHP != 0) + if (currentHP >= 0) currentHP = currentHP + recurringHealing - recurringDamage - statusDamage; // Recalculate toxic damage if needed diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 8e0955b1de..cc3f8bd93c 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -410,6 +410,10 @@ bool32 IsDamageMoveUsable(u32 move, u32 battlerAtk, u32 battlerDef) if (moveType == TYPE_GRASS) return TRUE; break; + case ABILITY_EARTH_EATER: + if (moveType == TYPE_GROUND) + return TRUE; + break; } switch (gMovesInfo[move].effect) diff --git a/src/battle_anim_effects_2.c b/src/battle_anim_effects_2.c index 3c4221e098..3324d276fd 100755 --- a/src/battle_anim_effects_2.c +++ b/src/battle_anim_effects_2.c @@ -3734,7 +3734,6 @@ static void AnimTask_UproarDistortion_Step(u8 taskId) static void AnimJaggedMusicNote(struct Sprite *sprite) { - int var1; u8 battler = !gBattleAnimArgs[0] ? gBattleAnimAttacker : gBattleAnimTarget; if (GetBattlerSide(battler) == B_SIDE_OPPONENT) @@ -3745,16 +3744,8 @@ static void AnimJaggedMusicNote(struct Sprite *sprite) sprite->data[0] = 0; sprite->data[1] = (u16)sprite->x << 3; sprite->data[2] = (u16)sprite->y << 3; - - var1 = gBattleAnimArgs[1] << 3; - if (var1 < 0) - var1 += 7; - sprite->data[3] = var1 >> 3; - - var1 = gBattleAnimArgs[2] << 3; - if (var1 < 0) - var1 += 7; - sprite->data[4] = var1 >> 3; + sprite->data[3] = (gBattleAnimArgs[1] << 3) / 8; + sprite->data[4] = (gBattleAnimArgs[2] << 3) / 8; sprite->oam.tileNum += gBattleAnimArgs[3] * 16; sprite->callback = AnimJaggedMusicNote_Step; diff --git a/src/battle_anim_fight.c b/src/battle_anim_fight.c index 90bd9391e3..0db2a92afc 100644 --- a/src/battle_anim_fight.c +++ b/src/battle_anim_fight.c @@ -565,7 +565,7 @@ static void AnimFistOrFootRandomPos(struct Sprite *sprite) y *= -1; if (GetBattlerSide(battler) == B_SIDE_PLAYER) - y += 0xFFF0; + y -= 16; sprite->x += x; sprite->y += y; diff --git a/src/battle_anim_rock.c b/src/battle_anim_rock.c index 7a84757cd9..f9b93a727a 100644 --- a/src/battle_anim_rock.c +++ b/src/battle_anim_rock.c @@ -648,7 +648,6 @@ void AnimTask_Rollout(u8 taskId) { u16 var0, var1, var2, var3; u8 rolloutCounter; - int var5; s16 pan1, pan2; struct Task *task; @@ -672,13 +671,7 @@ void AnimTask_Rollout(u8 taskId) task->data[11] = 0; task->data[9] = 0; task->data[12] = 1; - - var5 = task->data[8]; - if (var5 < 0) - var5 += 7; - - task->data[10] = (var5 >> 3) - 1; - + task->data[10] = (task->data[8] / 8) - 1; task->data[2] = var0 * 8; task->data[3] = var1 * 8; task->data[4] = ((var2 - var0) * 8) / task->data[8]; diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 97b0a061bb..597d0b7c5f 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -744,7 +744,7 @@ static void OpponentHandleEndLinkBattle(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_LINK && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)) { - gMain.inBattle = 0; + gMain.inBattle = FALSE; gMain.callback1 = gPreBattleCallback1; SetMainCallback2(gMain.savedCallback); } diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index c9778f898e..eeca1899b1 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -2146,7 +2146,7 @@ void PlayerHandleExpUpdate(u32 battler) u8 monId = gBattleResources->bufferA[battler][1]; s32 taskId, expPointsToGive; - if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= GetCurrentLevelCap()) + if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL) { PlayerBufferExecCompleted(battler); } diff --git a/src/battle_interface.c b/src/battle_interface.c index 72475e6040..34cdec6e5c 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -74,7 +74,7 @@ enum HEALTHBOX_GFX_STATUS_BRN_BATTLER0, //status brn HEALTHBOX_GFX_34, HEALTHBOX_GFX_35, - HEALTHBOX_GFX_STATUS_FSB_BATTLER0, //status fsb + HEALTHBOX_GFX_STATUS_FRB_BATTLER0, //status frb HEALTHBOX_GFX_116, HEALTHBOX_GFX_117, HEALTHBOX_GFX_36, //misc [Black section] @@ -127,7 +127,7 @@ enum HEALTHBOX_GFX_STATUS_BRN_BATTLER1, //status2 "BRN" HEALTHBOX_GFX_84, HEALTHBOX_GFX_85, - HEALTHBOX_GFX_STATUS_FSB_BATTLER1, //status2 "FSB" + HEALTHBOX_GFX_STATUS_FRB_BATTLER1, //status2 "FRB" HEALTHBOX_GFX_118, HEALTHBOX_GFX_119, HEALTHBOX_GFX_STATUS_PSN_BATTLER2, //status3 "PSN" @@ -145,7 +145,7 @@ enum HEALTHBOX_GFX_STATUS_BRN_BATTLER2, //status3 "BRN" HEALTHBOX_GFX_99, HEALTHBOX_GFX_100, - HEALTHBOX_GFX_STATUS_FSB_BATTLER2, //status3 "FSB" + HEALTHBOX_GFX_STATUS_FRB_BATTLER2, //status3 "FRB" HEALTHBOX_GFX_120, HEALTHBOX_GFX_121, HEALTHBOX_GFX_STATUS_PSN_BATTLER3, //status4 "PSN" @@ -163,7 +163,7 @@ enum HEALTHBOX_GFX_STATUS_BRN_BATTLER3, //status4 "BRN" HEALTHBOX_GFX_114, HEALTHBOX_GFX_115, - HEALTHBOX_GFX_STATUS_FSB_BATTLER3, //status4 "FSB" + HEALTHBOX_GFX_STATUS_FRB_BATTLER3, //status4 "FRB" HEALTHBOX_GFX_122, HEALTHBOX_GFX_123, HEALTHBOX_GFX_FRAME_END, @@ -2389,7 +2389,7 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId) } else if (status & STATUS1_FROSTBITE) { - statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_FSB_BATTLER0, battlerId)); + statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_FRB_BATTLER0, battlerId)); statusPalId = PAL_STATUS_FRZ; } else if (status & STATUS1_PARALYSIS) @@ -2474,15 +2474,15 @@ static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId) else ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER3; break; - case HEALTHBOX_GFX_STATUS_FSB_BATTLER0: + case HEALTHBOX_GFX_STATUS_FRB_BATTLER0: if (battlerId == 0) - ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER0; + ret = HEALTHBOX_GFX_STATUS_FRB_BATTLER0; else if (battlerId == 1) - ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER1; + ret = HEALTHBOX_GFX_STATUS_FRB_BATTLER1; else if (battlerId == 2) - ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER2; + ret = HEALTHBOX_GFX_STATUS_FRB_BATTLER2; else - ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER3; + ret = HEALTHBOX_GFX_STATUS_FRB_BATTLER3; break; case HEALTHBOX_GFX_STATUS_BRN_BATTLER0: if (battlerId == 0) @@ -2688,7 +2688,7 @@ static void MoveBattleBarGraphically(u8 battlerId, u8 whichBar) &gBattleSpritesDataPtr->battleBars[battlerId].currValue, array, B_EXPBAR_PIXELS / 8); level = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_LEVEL); - if (level >= GetCurrentLevelCap()) + if (level >= MAX_LEVEL) { for (i = 0; i < 8; i++) array[i] = 0; diff --git a/src/battle_intro.c b/src/battle_intro.c index c28ed90ffc..a6b1607285 100644 --- a/src/battle_intro.c +++ b/src/battle_intro.c @@ -194,12 +194,12 @@ static void BattleIntroSlide1(u8 taskId) { if (gTasks[taskId].tTerrain == BATTLE_TERRAIN_LONG_GRASS) { - if (gBattle_BG1_Y != 0xFFB0) + if (gBattle_BG1_Y != (u16)(-80)) gBattle_BG1_Y -= 2; } else { - if (gBattle_BG1_Y != 0xFFC8) + if (gBattle_BG1_Y != (u16)(-56)) gBattle_BG1_Y -= 1; } } diff --git a/src/battle_main.c b/src/battle_main.c index cbecf18883..aa2245022a 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -323,7 +323,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_CHOPLE_BERRY, //.gem = ITEM_FIGHTING_GEM, //.zCrystal = ITEM_FIGHTINIUM_Z, - //.plate= ITEM_FIST_PLATE, + //.plate = ITEM_FIST_PLATE, //.memory = ITEM_FIGHTING_MEMORY, //.teraShard = ITEM_FIGHTING_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_FIGHTING, @@ -339,7 +339,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_COBA_BERRY, //.gem = ITEM_FLYING_GEM, //.zCrystal = ITEM_FLYINIUM_Z, - //.plate= ITEM_SKY_PLATE, + //.plate = ITEM_SKY_PLATE, //.memory = ITEM_FLYING_MEMORY, //.teraShard = ITEM_FLYING_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_FLYING, @@ -355,7 +355,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_KEBIA_BERRY, //.gem = ITEM_POISON_GEM, //.zCrystal = ITEM_POISONIUM_Z, - //.plate= ITEM_TOXIC_PLATE, + //.plate = ITEM_TOXIC_PLATE, //.memory = ITEM_POISON_MEMORY, //.teraShard = ITEM_POISON_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_POISON, @@ -371,7 +371,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_SHUCA_BERRY, //.gem = ITEM_GROUND_GEM, //.zCrystal = ITEM_GROUNDIUM_Z, - //.plate= ITEM_EARTH_PLATE, + //.plate = ITEM_EARTH_PLATE, //.memory = ITEM_GROUND_MEMORY, //.teraShard = ITEM_GROUND_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_GROUND, @@ -387,7 +387,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_CHARTI_BERRY, //.gem = ITEM_ROCK_GEM, //.zCrystal = ITEM_ROCKIUM_Z, - //.plate= ITEM_STONE_PLATE, + //.plate = ITEM_STONE_PLATE, //.memory = ITEM_ROCK_MEMORY, //.teraShard = ITEM_ROCK_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_ROCK, @@ -403,7 +403,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_TANGA_BERRY, //.gem = ITEM_BUG_GEM, //.zCrystal = ITEM_BUGINIUM_Z, - //.plate= ITEM_INSECT_PLATE, + //.plate = ITEM_INSECT_PLATE, //.memory = ITEM_BUG_MEMORY, //.teraShard = ITEM_BUG_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_BUG, @@ -419,7 +419,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_KASIB_BERRY, //.gem = ITEM_GHOST_GEM, //.zCrystal = ITEM_GHOSTIUM_Z, - //.plate= ITEM_SPOOKY_PLATE, + //.plate = ITEM_SPOOKY_PLATE, //.memory = ITEM_GHOST_MEMORY, //.teraShard = ITEM_GHOST_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_GHOST, @@ -435,7 +435,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_BABIRI_BERRY, //.gem = ITEM_STEEL_GEM, //.zCrystal = ITEM_STEELIUM_Z, - //.plate= ITEM_IRON_PLATE, + //.plate = ITEM_IRON_PLATE, //.memory = ITEM_STEEL_MEMORY, //.teraShard = ITEM_STEEL_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_STEEL, @@ -457,7 +457,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_OCCA_BERRY, //.gem = ITEM_FIRE_GEM, //.zCrystal = ITEM_FIRIUM_Z, - //.plate= ITEM_FLAME_PLATE, + //.plate = ITEM_FLAME_PLATE, //.memory = ITEM_FIRE_MEMORY, //.teraShard = ITEM_FIRE_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_FIRE, @@ -473,7 +473,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_PASSHO_BERRY, //.gem = ITEM_WATER_GEM, //.zCrystal = ITEM_WATERIUM_Z, - //.plate= ITEM_SPLASH_PLATE, + //.plate = ITEM_SPLASH_PLATE, //.memory = ITEM_WATER_MEMORY, //.teraShard = ITEM_WATER_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_WATER, @@ -489,7 +489,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_RINDO_BERRY, //.gem = ITEM_GRASS_GEM, //.zCrystal = ITEM_GRASSIUM_Z, - //.plate= ITEM_MEADOW_PLATE, + //.plate = ITEM_MEADOW_PLATE, //.memory = ITEM_GRASS_MEMORY, //.teraShard = ITEM_GRASS_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_GRASS, @@ -505,7 +505,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_WACAN_BERRY, //.gem = ITEM_ELECTRIC_GEM, //.zCrystal = ITEM_ELECTRIUM_Z, - //.plate= ITEM_ZAP_PLATE, + //.plate = ITEM_ZAP_PLATE, //.memory = ITEM_ELECTRIC_MEMORY, //.teraShard = ITEM_ELECTRIC_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_ELECTRIC, @@ -521,7 +521,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_PAYAPA_BERRY, //.gem = ITEM_PSYCHIC_GEM, //.zCrystal = ITEM_PSYCHIUM_Z, - //.plate= ITEM_MIND_PLATE, + //.plate = ITEM_MIND_PLATE, //.memory = ITEM_PSYCHIC_MEMORY, //.teraShard = ITEM_PSYCHIC_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_PSYCHIC, @@ -537,7 +537,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_YACHE_BERRY, //.gem = ITEM_ICE_GEM, //.zCrystal = ITEM_ICIUM_Z, - //.plate= ITEM_ICICLE_PLATE, + //.plate = ITEM_ICICLE_PLATE, //.memory = ITEM_ICE_MEMORY, //.teraShard = ITEM_ICE_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_ICE, @@ -553,7 +553,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_HABAN_BERRY, //.gem = ITEM_DRAGON_GEM, //.zCrystal = ITEM_DRAGONIUM_Z, - //.plate= ITEM_DRACO_PLATE, + //.plate = ITEM_DRACO_PLATE, //.memory = ITEM_DRAGON_MEMORY, //.teraShard = ITEM_DRAGON_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_DRAGON, @@ -569,7 +569,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_COLBUR_BERRY, //.gem = ITEM_DARK_GEM, //.zCrystal = ITEM_DARKINIUM_Z, - //.plate= ITEM_DREAD_PLATE, + //.plate = ITEM_DREAD_PLATE, //.memory = ITEM_DARK_MEMORY, //.teraShard = ITEM_DARK_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_DARK, @@ -585,7 +585,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = //.berry = ITEM_ROSELI_BERRY, //.gem = ITEM_FAIRY_GEM, //.zCrystal = ITEM_FAIRIUM_Z, - //.plate= ITEM_PIXIE_PLATE, + //.plate = ITEM_PIXIE_PLATE, //.memory = ITEM_FAIRY_MEMORY, //.teraShard = ITEM_FAIRY_TERA_SHARD, //.arceusForm = SPECIES_ARCEUS_FAIRY, @@ -3254,6 +3254,17 @@ static void BattleMainCB1(void) gBattlerControllerFuncs[battler](battler); } +static void ClearSetBScriptingStruct(void) +{ + // windowsType is set up earlier in BattleInitBgsAndWindows, so we need to save the value + u32 temp = gBattleScripting.windowsType; + memset(&gBattleScripting, 0, sizeof(gBattleScripting)); + + gBattleScripting.windowsType = temp; + gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle; + gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6); +} + static void BattleStartClearSetData(void) { s32 i; @@ -3267,10 +3278,7 @@ static void BattleStartClearSetData(void) memset(&gSideTimers, 0, sizeof(gSideTimers)); memset(&gWishFutureKnock, 0, sizeof(gWishFutureKnock)); memset(&gBattleResults, 0, sizeof(gBattleResults)); - memset(&gBattleScripting, 0, sizeof(gBattleScripting)); - - gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle; - gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6); + ClearSetBScriptingStruct(); for (i = 0; i < MAX_BATTLERS_COUNT; i++) { @@ -4205,11 +4213,11 @@ void BattleTurnPassed(void) if (DoBattlerEndTurnEffects()) return; } + if (HandleWishPerishSongOnTurnEnd()) + return; if (HandleFaintedMonActions()) return; gBattleStruct->faintedActionsState = 0; - if (HandleWishPerishSongOnTurnEnd()) - return; TurnValuesCleanUp(FALSE); gHitMarker &= ~HITMARKER_NO_ATTACKSTRING; @@ -5271,11 +5279,11 @@ static void TurnValuesCleanUp(bool8 var0) gProtectStructs[i].quash = FALSE; gProtectStructs[i].usedCustapBerry = FALSE; gProtectStructs[i].quickDraw = FALSE; + memset(&gQueuedStatBoosts[i], 0, sizeof(struct QueuedStatBoost)); } else { memset(&gProtectStructs[i], 0, sizeof(struct ProtectStruct)); - memset(&gQueuedStatBoosts[i], 0, sizeof(struct QueuedStatBoost)); if (gDisableStructs[i].isFirstTurn) gDisableStructs[i].isFirstTurn--; diff --git a/src/battle_message.c b/src/battle_message.c index 388a9f17ac..dc6dd20639 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -783,7 +783,7 @@ static const u8 sText_AttackerExpelledThePoison[] = _("{B_ATK_NAME_WITH_PREFIX} static const u8 sText_AttackerShookItselfAwake[] = _("{B_ATK_NAME_WITH_PREFIX} shook itself awake!"); static const u8 sText_AttackerBrokeThroughParalysis[] = _("{B_ATK_NAME_WITH_PREFIX} gathered all its energy\nto overcome its paralysis!"); static const u8 sText_AttackerHealedItsBurn[] = _("{B_ATK_NAME_WITH_PREFIX} healed its burn with\nits sheer determination!"); -static const u8 sText_AttackerHealedItsFrostbite[] = _("{B_ATK_NAME_WITH_PREFIX} healed its frostbite with\nits sheer determination!"); +static const u8 sText_AttackerHealedItsFrostbite[] = _("{B_ATK_NAME_WITH_PREFIX} healed its frostbite with\nits sheer determination!"); //not used, "melted the ice" is used instead in PLA static const u8 sText_AttackerMeltedTheIce[] = _("{B_ATK_NAME_WITH_PREFIX} melted the ice with\nits fiery determination!"); static const u8 sText_TargetToughedItOut[] = _("{B_DEF_NAME_WITH_PREFIX} toughed it out\nto show you its best side!"); static const u8 sText_AttackerLostElectricType[] = _("{B_ATK_NAME_WITH_PREFIX} used up all\nof its electricity!"); @@ -4169,7 +4169,7 @@ u32 ShouldDoTrainerSlide(u32 battler, u32 which) case TRAINER_SLIDE_LAST_LOW_HP: if (sTrainerSlides[i].msgLastLowHp != NULL && GetEnemyMonCount(firstId, lastId, TRUE) == 1 - && BattlerHPPercentage(battler, GREATER_THAN_OR_EQUAL, 4) + && BattlerHPPercentage(battler, LESS_THAN_OR_EQUAL, 4) && !gBattleStruct->trainerSlideLowHpMsgDone) { gBattleStruct->trainerSlideLowHpMsgDone = TRUE; diff --git a/src/battle_pyramid.c b/src/battle_pyramid.c index a21034d75a..ce7a0526f2 100644 --- a/src/battle_pyramid.c +++ b/src/battle_pyramid.c @@ -1401,27 +1401,32 @@ void GenerateBattlePyramidWildMon(void) if (reqs->nMoves != 0) moves = AllocZeroed(sizeof(u16) * reqs->nMoves); - + if (reqs->nAbilities != 0) abilities = AllocZeroed(sizeof(u16) * reqs->nAbilities); if (round >= TOTAL_PYRAMID_ROUNDS) round = TOTAL_PYRAMID_ROUNDS - 1; - + id = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL) - 1; // index in table (0-11) -> higher index is lower probability bstLim = 450 + (25*round) + (5*id); // higher BST limit for 'rarer' wild mon rolls while (1) { - species = Random() % FORMS_START; + species = Random() % NUM_SPECIES; + + // check if base species + if (GET_BASE_SPECIES_ID(species) != species) + continue; + // check type if (reqs->type != TYPE_MYSTERY && gSpeciesInfo[species].types[0] != reqs->type && gSpeciesInfo[species].types[1] != reqs->type) continue; - + // check base stat total if (GetTotalBaseStat(species) > bstLim) continue; - + // check moves if (reqs->nMoves != 0) { @@ -1438,7 +1443,7 @@ void GenerateBattlePyramidWildMon(void) if (moveCount == 0) continue; } - + // check abilities if (reqs->nAbilities != 0) { @@ -1460,9 +1465,9 @@ void GenerateBattlePyramidWildMon(void) continue; } // check evos - if (reqs->evoItems[0] != 0 && !CheckBattlePyramidEvoRequirement(species, reqs->evoItems, reqs->nEvoItems)) + if (reqs->evoItems != NULL && !CheckBattlePyramidEvoRequirement(species, reqs->evoItems, reqs->nEvoItems)) continue; - + // we found a species we can use! break; } @@ -1471,7 +1476,7 @@ void GenerateBattlePyramidWildMon(void) SetMonData(&gEnemyParty[0], MON_DATA_SPECIES, &species); StringCopy(name, GetSpeciesName(species)); SetMonData(&gEnemyParty[0], MON_DATA_NICKNAME, &name); - + // set level if (lvl != FRONTIER_LVL_50) { @@ -1507,7 +1512,7 @@ void GenerateBattlePyramidWildMon(void) } Free(moves); } - + // Initialize a random ability num if (gSpeciesInfo[species].abilities[1]) { @@ -1519,7 +1524,7 @@ void GenerateBattlePyramidWildMon(void) i = 0; SetMonData(&gEnemyParty[0], MON_DATA_ABILITY_NUM, &i); } - + // Try to replace with desired ability if (abilities != NULL) { @@ -1533,12 +1538,15 @@ void GenerateBattlePyramidWildMon(void) { // Set this ability num SetMonData(&gEnemyParty[0], MON_DATA_ABILITY_NUM, &id); + break; } } + if (id >= NUM_ABILITY_SLOTS - 1) + break; } Free(abilities); } - + if (gSaveBlock2Ptr->frontier.pyramidWinStreaks[gSaveBlock2Ptr->frontier.lvlMode] >= 140) { id = (Random() % 17) + 15; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 8f870f946b..f74322611b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1515,7 +1515,7 @@ static bool32 AccuracyCalcHelper(u16 move) return TRUE; } // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. - else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) + else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD); @@ -1975,7 +1975,7 @@ static void Cmd_adjustdamage(void) if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) goto END; - if (DoesDisguiseBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) + if (DoesDisguiseBlockMove(gBattlerTarget, gCurrentMove)) { gBattleStruct->enduredDamage |= gBitTable[gBattlerTarget]; goto END; @@ -2227,7 +2227,7 @@ static void Cmd_healthbarupdate(void) { PrepareStringBattle(STRINGID_SUBSTITUTEDAMAGED, battler); } - else if (!DoesDisguiseBlockMove(gBattlerAttacker, battler, gCurrentMove)) + else if (!DoesDisguiseBlockMove(battler, gCurrentMove)) { s16 healthValue = min(gBattleMoveDamage, 10000); // Max damage (10000) not present in R/S, ensures that huge damage values don't change sign @@ -2280,16 +2280,19 @@ static void Cmd_datahpupdate(void) return; } } - else if (DoesDisguiseBlockMove(gBattlerAttacker, battler, gCurrentMove)) + else if (DoesDisguiseBlockMove(battler, gCurrentMove)) { // TODO: Convert this to a proper FORM_CHANGE type. u32 side = GetBattlerSide(battler); + gBattleScripting.battler = battler; if (gBattleStruct->changedSpecies[side][gBattlerPartyIndexes[battler]] == SPECIES_NONE) gBattleStruct->changedSpecies[side][gBattlerPartyIndexes[battler]] = gBattleMons[battler].species; if (gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) gBattleMons[battler].species = SPECIES_MIMIKYU_TOTEM_BUSTED; else gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED; + if (B_DISGUISE_HP_LOSS >= GEN_8) + gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8; BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_TargetFormChange; return; @@ -5849,31 +5852,7 @@ static void Cmd_moveend(void) } gBattleScripting.moveendState++; break; - case MOVEEND_MAGICIAN: - if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MAGICIAN - && gCurrentMove != MOVE_FLING && gCurrentMove != MOVE_NATURAL_GIFT - && gBattleMons[gBattlerAttacker].item == ITEM_NONE - && gBattleMons[gBattlerTarget].item != ITEM_NONE - && IsBattlerAlive(gBattlerAttacker) - && TARGET_TURN_DAMAGED - && CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item) - && !gSpecialStatuses[gBattlerAttacker].gemBoost // In base game, gems are consumed after magician would activate. - && !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]]) - && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove) - && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && (GetBattlerAbility(gBattlerTarget) != ABILITY_STICKY_HOLD || !IsBattlerAlive(gBattlerTarget))) - { - StealTargetItem(gBattlerAttacker, gBattlerTarget); - gBattleScripting.battler = gBattlerAbility = gBattlerAttacker; - gEffectBattler = gBattlerTarget; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MagicianActivates; - gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; - effect = TRUE; - } - gBattleScripting.moveendState++; - break; - case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokémon. + case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokemon. { u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); // Set a flag if move hits either target (for throat spray that can't check damage) @@ -5993,98 +5972,165 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; } - case MOVEEND_EJECT_BUTTON: - if (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET + // The order of abilities/items activating after moves hitting multiple targets is + // 1. Magician + // 2. The fastest mon gets switched out using Eject Button / Eject Pack + // 3. White Herb activates + // 4. Red Card activates + // 5. Life Orb / Shell Bell + // 6. Pickpocket + case MOVEEND_MAGICIAN: + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MAGICIAN + && gCurrentMove != MOVE_FLING && gCurrentMove != MOVE_NATURAL_GIFT + && gBattleMons[gBattlerAttacker].item == ITEM_NONE + && gBattleMons[gBattlerTarget].item != ITEM_NONE && IsBattlerAlive(gBattlerAttacker) - && !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove) - && (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER || (gBattleTypeFlags & BATTLE_TYPE_TRAINER))) + && TARGET_TURN_DAMAGED + && CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item) + && !gSpecialStatuses[gBattlerAttacker].gemBoost // In base game, gems are consumed after magician would activate. + && !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]]) + && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove) + && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && (GetBattlerAbility(gBattlerTarget) != ABILITY_STICKY_HOLD || !IsBattlerAlive(gBattlerTarget))) { - // 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 eject button properly - u8 battlers[4] = {0, 1, 2, 3}; - SortBattlersBySpeed(battlers, FALSE); + StealTargetItem(gBattlerAttacker, gBattlerTarget); + gBattleScripting.battler = gBattlerAbility = gBattlerAttacker; + gEffectBattler = gBattlerTarget; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MagicianActivates; + gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; + effect = TRUE; + } + gBattleScripting.moveendState++; + break; + case MOVEEND_EJECT_ITEMS: + { + // Because sorting the battlers by speed takes lots of cycles, it's better to just check if any of the battlers has the Eject items. + u32 ejectPackBattlers = 0, ejectButtonBattlers = 0, i; for (i = 0; i < gBattlersCount; i++) { - u8 battler = battlers[i]; - // Attacker is the damage-dealer, battler is mon to be switched out - if (IsBattlerAlive(battler) - && gBattlerAttacker != battler - && GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_BUTTON - && BATTLER_TURN_DAMAGED(battler) - && CountUsablePartyMons(battler) > 0) // Has mon to switch into + u32 holdEffect; + if (i == gBattlerAttacker) + continue; + holdEffect = GetBattlerHoldEffect(i, TRUE); + if (holdEffect == HOLD_EFFECT_EJECT_BUTTON) + ejectButtonBattlers |= gBitTable[i]; + else if (holdEffect == HOLD_EFFECT_EJECT_PACK) + ejectPackBattlers |= gBitTable[i]; + } + if (ejectButtonBattlers || ejectPackBattlers) + { + u8 battlers[4] = {0, 1, 2, 3}; + SortBattlersBySpeed(battlers, FALSE); + + for (i = 0; i < gBattlersCount; i++) { - gBattleScripting.battler = battler; - gLastUsedItem = gBattleMons[battler].item; - if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE) - gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_EjectButtonActivates; - effect = TRUE; - break; // Only the fastest Eject Button activates + u32 battler = battlers[i]; + + if (ejectButtonBattlers & gBitTable[battler]) + { + if (TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) // Apparently Sheer Force blocks Eject Button, but not Eject Pack + continue; + // 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 eject button properly + if (!BATTLER_TURN_DAMAGED(battler)) + continue; + } + else if (ejectPackBattlers & gBitTable[battler]) + { + if (!gProtectStructs[battler].statFell || gProtectStructs[battler].disableEjectPack) + continue; + } + else + { + continue; + } + + if (IsBattlerAlive(battler) + && CountUsablePartyMons(battler) > 0 // Has mon to switch into + // Does not activate if attacker used Parting Shot and can switch out + && !(gMovesInfo[gCurrentMove].effect == EFFECT_HIT_SWITCH_TARGET && CanBattlerSwitch(gBattlerAttacker)) + ) + { + gBattleScripting.battler = battler; + gLastUsedItem = gBattleMons[battler].item; + if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE) + gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection + effect = TRUE; + BattleScriptPushCursor(); + if (ejectButtonBattlers & gBitTable[battler]) + { + gBattlescriptCurrInstr = BattleScript_EjectButtonActivates; + } + else // Eject Pack + { + gBattlescriptCurrInstr = BattleScript_EjectPackActivates; + // Are these 2 lines below needed? + gProtectStructs[battler].statFell = FALSE; + gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; + } + break; // Only the fastest Eject item activates + } } } } gBattleScripting.moveendState++; break; + case MOVEEND_WHITE_HERB: + for (i = 0; i < gBattlersCount; i++) + { + if (IsBattlerAlive(i) + && ItemBattleEffects(ITEMEFFECT_STATS_CHANGED, i, FALSE)) + { + effect = TRUE; + break; + } + } + if (!effect) + gBattleScripting.moveendState++; + break; case MOVEEND_RED_CARD: - if ((gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed) - && IsBattlerAlive(gBattlerAttacker) - && !TestIfSheerForceAffected(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 - u8 battlers[4] = {0, 1, 2, 3}; - SortBattlersBySpeed(battlers, FALSE); + u32 redCardBattlers = 0, i; for (i = 0; i < gBattlersCount; i++) { - u8 battler = battlers[i]; - // Search for fastest hit pokemon with a red card - // Attacker is the one to be switched out, battler is one with red card - if (battler != gBattlerAttacker - && IsBattlerAlive(battler) - && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) - && GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_RED_CARD - && BATTLER_TURN_DAMAGED(battler) - && CanBattlerSwitch(gBattlerAttacker)) - { - gLastUsedItem = gBattleMons[battler].item; - gBattleStruct->savedBattlerTarget = gBattleScripting.battler = battler; // Battler with red card - gEffectBattler = gBattlerAttacker; - if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE) - gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_RedCardActivates; - gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; - effect = TRUE; - break; // Only fastest red card activates - } + if (i == gBattlerAttacker) + continue; + if (GetBattlerHoldEffect(i, TRUE) == HOLD_EFFECT_RED_CARD) + redCardBattlers |= gBitTable[i]; } - } - gBattleScripting.moveendState++; - break; - case MOVEEND_EJECT_PACK: - { - u8 battlers[4] = {0, 1, 2, 3}; - SortBattlersBySpeed(battlers, FALSE); - for (i = 0; i < gBattlersCount; i++) + if (redCardBattlers + && (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed) + && IsBattlerAlive(gBattlerAttacker) + && !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove) + && GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG) { - u8 battler = battlers[i]; - if (IsBattlerAlive(battler) - && gProtectStructs[battler].statFell - && gProtectStructs[battler].disableEjectPack == 0 - && GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_PACK - && !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker)) // Does not activate if attacker used Parting Shot and can switch out - && CountUsablePartyMons(battler) > 0) // Has mon to switch into + // 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 + u8 battlers[4] = {0, 1, 2, 3}; + SortBattlersBySpeed(battlers, FALSE); + for (i = 0; i < gBattlersCount; i++) { - gProtectStructs[battler].statFell = FALSE; - gBattleScripting.battler = battler; - gLastUsedItem = gBattleMons[battler].item; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_EjectPackActivates; - gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; - effect = TRUE; - break; // Only fastest eject pack activates + u32 battler = battlers[i]; + // Search for fastest hit pokemon with a red card + // Attacker is the one to be switched out, battler is one with red card + if (redCardBattlers & gBitTable[battler] + && IsBattlerAlive(battler) + && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) + && BATTLER_TURN_DAMAGED(battler) + && CanBattlerSwitch(gBattlerAttacker)) + { + gLastUsedItem = gBattleMons[battler].item; + gBattleStruct->savedBattlerTarget = gBattleScripting.battler = battler; // Battler with red card + gEffectBattler = gBattlerAttacker; + if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE) + gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RedCardActivates; + gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; + effect = TRUE; + break; // Only fastest red card activates + } } } } @@ -10324,6 +10370,7 @@ static void Cmd_various(void) if (cmd->fromBattler) gLastUsedItem = gBattleMons[battler].item; + gBattleStruct->ateBerry[battler & BIT_SIDE] |= gBitTable[gBattlerPartyIndexes[battler]]; gBattleScripting.battler = gEffectBattler = gBattlerTarget = battler; // Cover all berry effect battler cases. e.g. ChangeStatBuffs uses target ID if (ItemBattleEffects(ITEMEFFECT_USE_LAST_ITEM, battler, FALSE)) return; @@ -10960,7 +11007,17 @@ static void Cmd_tryhealhalfhealth(void) static void SetMoveForMirrorMove(u32 move) { gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; - gCurrentMove = move; + // Edge case, we used Z Mirror Move, got the stat boost and now need to use the Z-move + if (gBattleStruct->zmove.toBeUsed[gBattlerAttacker] && !IS_MOVE_STATUS(move)) + { + gCurrentMove = gBattleStruct->zmove.chosenZMove = GetTypeBasedZMove(move, gBattlerAttacker); + QueueZMove(gBattlerAttacker, move); + } + else + { + gCurrentMove = move; + } + SetAtkCancellerForCalledMove(); gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove); @@ -13631,7 +13688,8 @@ static void Cmd_trysetfutureattack(void) { gSideStatuses[GetBattlerSide(gBattlerTarget)] |= SIDE_STATUS_FUTUREATTACK; gWishFutureKnock.futureSightMove[gBattlerTarget] = gCurrentMove; - gWishFutureKnock.futureSightAttacker[gBattlerTarget] = gBattlerAttacker; + gWishFutureKnock.futureSightBattlerIndex[gBattlerTarget] = gBattlerAttacker; + gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] = gBattlerPartyIndexes[gBattlerAttacker]; gWishFutureKnock.futureSightCounter[gBattlerTarget] = 3; if (gCurrentMove == MOVE_DOOM_DESIRE) @@ -14662,13 +14720,13 @@ bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move) return TRUE; } -bool32 DoesDisguiseBlockMove(u32 battlerAtk, u32 battlerDef, u32 move) +bool32 DoesDisguiseBlockMove(u32 battler, u32 move) { - if (!(gBattleMons[battlerDef].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battlerDef].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) - || gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED - || IS_MOVE_STATUS(move) + if (!(gBattleMons[battler].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) + || gBattleMons[battler].status2 & STATUS2_TRANSFORMED + || (!gProtectStructs[battler].confusionSelfDmg && (IS_MOVE_STATUS(move) || gHitMarker & HITMARKER_PASSIVE_DAMAGE)) || gHitMarker & HITMARKER_IGNORE_DISGUISE - || GetBattlerAbility(battlerDef) != ABILITY_DISGUISE) + || GetBattlerAbility(battler) != ABILITY_DISGUISE) return FALSE; else return TRUE; @@ -16677,6 +16735,15 @@ void BS_SetPhotonGeyserCategory(void) gBattlescriptCurrInstr = cmd->nextInstr; } +void BS_RunStatChangeItems(void) +{ + NATIVE_ARGS(u8 battler); + + // Change instruction before calling ItemBattleEffects. + gBattlescriptCurrInstr = cmd->nextInstr; + ItemBattleEffects(ITEMEFFECT_STATS_CHANGED, GetBattlerForBattleScript(cmd->battler), FALSE); +} + static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount) { u32 i; @@ -16738,3 +16805,16 @@ void BS_TryTidyUp(void) gBattlescriptCurrInstr = cmd->nextInstr; } } + +void BS_TryGulpMissile(void) +{ + NATIVE_ARGS(); + + if ((gBattleMons[gBattlerAttacker].species == SPECIES_CRAMORANT) + && (gCurrentMove == MOVE_DIVE) + && (GetBattlerAbility(gBattlerAttacker) == ABILITY_GULP_MISSILE) + && TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_HP_PERCENT)) + gBattlescriptCurrInstr = BattleScript_GulpMissileFormChange; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} diff --git a/src/battle_util.c b/src/battle_util.c index 8e92f3a885..dc7c6352c1 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2964,17 +2964,15 @@ bool32 HandleWishPerishSongOnTurnEnd(void) while (gBattleStruct->wishPerishSongBattlerId < gBattlersCount) { battler = gBattleStruct->wishPerishSongBattlerId; - if (gAbsentBattlerFlags & gBitTable[battler]) - { - gBattleStruct->wishPerishSongBattlerId++; - continue; - } gBattleStruct->wishPerishSongBattlerId++; + if (gWishFutureKnock.futureSightCounter[battler] != 0 && --gWishFutureKnock.futureSightCounter[battler] == 0 - && gBattleMons[battler].hp != 0) + && !(gAbsentBattlerFlags & gBitTable[battler])) { + struct Pokemon *party; + if (gWishFutureKnock.futureSightMove[battler] == MOVE_FUTURE_SIGHT) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FUTURE_SIGHT; else @@ -2983,10 +2981,14 @@ bool32 HandleWishPerishSongOnTurnEnd(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gWishFutureKnock.futureSightMove[battler]); gBattlerTarget = battler; - gBattlerAttacker = gWishFutureKnock.futureSightAttacker[battler]; + gBattlerAttacker = gWishFutureKnock.futureSightBattlerIndex[battler]; gSpecialStatuses[gBattlerTarget].shellBellDmg = IGNORE_SHELL_BELL; gCurrentMove = gWishFutureKnock.futureSightMove[battler]; - SetTypeBeforeUsingMove(gCurrentMove, battler); + + party = GetSideParty(GetBattlerSide(gBattlerAttacker)); + if (&party[gWishFutureKnock.futureSightPartyIndex[gBattlerTarget]] == &party[gBattlerPartyIndexes[gBattlerAttacker]]) + SetTypeBeforeUsingMove(gCurrentMove, gBattlerAttacker); + BattleScriptExecute(BattleScript_MonTookFutureAttack); if (gWishFutureKnock.futureSightCounter[battler] == 0 @@ -2994,6 +2996,7 @@ bool32 HandleWishPerishSongOnTurnEnd(void) { gSideStatuses[GetBattlerSide(gBattlerTarget)] &= ~SIDE_STATUS_FUTUREATTACK; } + return TRUE; } } @@ -3518,6 +3521,9 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) case CANCELLER_Z_MOVES: if (gBattleStruct->zmove.toBeUsed[gBattlerAttacker] != MOVE_NONE) { + // For Z-Mirror Move, so it doesn't play the animation twice. + bool32 alreadyUsed = (gBattleStruct->zmove.used[gBattlerAttacker] == TRUE); + //attacker has a queued z move gBattleStruct->zmove.active = TRUE; gBattleStruct->zmove.activeCategory = gBattleStruct->zmove.categories[gBattlerAttacker]; @@ -3530,13 +3536,19 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) if (gBattleStruct->zmove.activeCategory == DAMAGE_CATEGORY_STATUS) { gBattleStruct->zmove.effect = gMovesInfo[gBattleStruct->zmove.baseMoves[gBattlerAttacker]].zMove.effect; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ZMoveActivateStatus; + if (!alreadyUsed) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ZMoveActivateStatus; + } } else { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ZMoveActivateDamaging; + if (!alreadyUsed) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ZMoveActivateDamaging; + } } effect = 1; } @@ -4930,10 +4942,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_CUD_CHEW: - if (ItemId_GetPocket(GetUsedHeldItem(battler)) == POCKET_BERRIES && gDisableStructs[battler].cudChew == TRUE) + if (gDisableStructs[battler].cudChew == TRUE) { - gLastUsedItem = gBattleStruct->usedHeldItems[battler][GetBattlerSide(battler)]; - gBattleStruct->usedHeldItems[battler][GetBattlerSide(battler)] = ITEM_NONE; + gBattleScripting.battler = battler; + gDisableStructs[battler].cudChew = FALSE; + gLastUsedItem = gBattleStruct->usedHeldItems[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)]; + gBattleStruct->usedHeldItems[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = ITEM_NONE; BattleScriptPushCursorAndCallback(BattleScript_CudChewActivates); effect++; } @@ -5240,6 +5254,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker) && gBattleStruct->overwrittenAbilities[gBattlerAttacker] != GetBattlerAbility(gBattlerTarget) && gBattleMons[gBattlerTarget].ability != ABILITY_MUMMY @@ -5263,6 +5278,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker) && !IsDynamaxed(gBattlerTarget) && !gAbilitiesInfo[gBattleMons[gBattlerAttacker].ability].cantBeSwapped) @@ -5317,6 +5333,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && (CompareStat(gBattlerAttacker, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN) || GetBattlerAbility(gBattlerAttacker) == ABILITY_MIRROR_ARMOR) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker)) { SET_STATCHANGER(STAT_SPEED, 1, TRUE); @@ -5333,6 +5350,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker)) { gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / (B_ROUGH_SKIN_DMG >= GEN_4 ? 8 : 16); @@ -5348,6 +5366,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMons[gBattlerTarget].hp == 0 && IsBattlerAlive(gBattlerAttacker) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker)) { u32 battler; @@ -5395,6 +5414,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED && CanSleep(gBattlerAttacker) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker) && (Random() % 3) == 0) { @@ -5414,6 +5434,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED && CanBePoisoned(gBattlerTarget, gBattlerAttacker) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker) && RandomWeighted(RNG_POISON_POINT, 2, 1)) { @@ -5432,6 +5453,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED && CanBeParalyzed(gBattlerAttacker) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker) && RandomWeighted(RNG_STATIC, 2, 1)) { @@ -5446,6 +5468,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && (IsMoveMakingContact(move, gBattlerAttacker)) && TARGET_TURN_DAMAGED && CanBeBurned(gBattlerAttacker) @@ -5468,6 +5491,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) && AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget) && GetBattlerAbility(gBattlerAttacker) != ABILITY_OBLIVIOUS + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker) && !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)) { @@ -5537,6 +5561,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED && IsBattlerAlive(battler) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && (IsMoveMakingContact(move, gBattlerAttacker)) && !(gStatuses3[gBattlerAttacker] & STATUS3_PERISH_SONG)) { @@ -5667,6 +5692,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && gBattleMons[gBattlerTarget].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && CanBePoisoned(gBattlerAttacker, gBattlerTarget) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(move, gBattlerAttacker) && TARGET_TURN_DAMAGED // Need to actually hit the target && (Random() % 3) == 0) @@ -5695,7 +5721,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_GULP_MISSILE: - if (((gCurrentMove == MOVE_SURF && TARGET_TURN_DAMAGED) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER) + if ((gBattleMons[gBattlerAttacker].species == SPECIES_CRAMORANT) + && ((gCurrentMove == MOVE_SURF && TARGET_TURN_DAMAGED) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER) && TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_HP_PERCENT)) { BattleScriptPushCursor(); @@ -6753,10 +6780,29 @@ static u8 TryConsumeMirrorHerb(u32 battler, bool32 execute) return effect; } +static u32 RestoreWhiteHerbStats(u32 battler) +{ + u32 i, effect = 0; + + for (i = 0; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE) + { + gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE; + effect = ITEM_STATS_CHANGE; + } + } + if (effect != 0) + { + gBattleScripting.battler = battler; + gPotentialItemEffectBattler = battler; + } + return effect; +} + static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect) { u8 effect = 0; - u32 i; switch (holdEffect) { @@ -6871,7 +6917,7 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect) { gBattleMons[battler].status1 &= ~STATUS1_FROSTBITE; BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BerryCureFsbRet; + gBattlescriptCurrInstr = BattleScript_BerryCureFrbRet; effect = ITEM_STATUS_CHANGE; } break; @@ -6936,24 +6982,6 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect) effect = ITEM_STATUS_CHANGE; } break; - case HOLD_EFFECT_RESTORE_STATS: - for (i = 0; i < NUM_BATTLE_STATS; i++) - { - if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE) - { - gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE; - effect = ITEM_STATS_CHANGE; - } - } - if (effect != 0) - { - gBattleScripting.battler = battler; - gPotentialItemEffectBattler = battler; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; - return effect; - } - break; case HOLD_EFFECT_CRITICAL_UP: // lansat berry if (B_BERRIES_INSTANT >= GEN_4 && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) @@ -7023,18 +7051,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) } break; case HOLD_EFFECT_RESTORE_STATS: - for (i = 0; i < NUM_BATTLE_STATS; i++) - { - if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE) - { - gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE; - effect = ITEM_STATS_CHANGE; - } - } + effect = RestoreWhiteHerbStats(battler); if (effect != 0) { - gBattleScripting.battler = battler; - gPotentialItemEffectBattler = battler; gBattlerAttacker = battler; BattleScriptExecute(BattleScript_WhiteHerbEnd2); } @@ -7138,7 +7157,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) && !UnnerveOn(battler, gLastUsedItem)) { gBattleMons[battler].status1 &= ~STATUS1_FROSTBITE; - BattleScriptExecute(BattleScript_BerryCureFsbEnd2); + BattleScriptExecute(BattleScript_BerryCureFrbEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -7317,18 +7336,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) effect = ItemRestorePp(battler, gLastUsedItem, TRUE); break; case HOLD_EFFECT_RESTORE_STATS: - for (i = 0; i < NUM_BATTLE_STATS; i++) - { - if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE) - { - gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE; - effect = ITEM_STATS_CHANGE; - } - } + effect = RestoreWhiteHerbStats(battler); if (effect != 0) { - gBattleScripting.battler = battler; - gPotentialItemEffectBattler = battler; gBattlerAttacker = battler; BattleScriptExecute(BattleScript_WhiteHerbEnd2); } @@ -7451,7 +7461,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) if (gBattleMons[battler].status1 & STATUS1_FROSTBITE && !UnnerveOn(battler, gLastUsedItem)) { gBattleMons[battler].status1 &= ~STATUS1_FROSTBITE; - BattleScriptExecute(BattleScript_BerryCureFsbEnd2); + BattleScriptExecute(BattleScript_BerryCureFrbEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -7719,6 +7729,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) break; case HOLD_EFFECT_ROCKY_HELMET: if (TARGET_TURN_DAMAGED + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(gCurrentMove, gBattlerAttacker) && IsBattlerAlive(gBattlerAttacker) && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) @@ -7839,6 +7850,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) case HOLD_EFFECT_STICKY_BARB: if (TARGET_TURN_DAMAGED && (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS && IsMoveMakingContact(gCurrentMove, gBattlerAttacker) && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && IsBattlerAlive(gBattlerAttacker) @@ -7900,6 +7912,19 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) } } break; + case ITEMEFFECT_STATS_CHANGED: + switch (battlerHoldEffect) + { + case HOLD_EFFECT_RESTORE_STATS: + effect = RestoreWhiteHerbStats(battler); + if (effect != 0) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; + } + break; + } + break; } // Berry was successfully used on a Pokemon. @@ -8210,7 +8235,6 @@ bool32 IsMoveMakingContact(u32 move, u32 battlerAtk) return FALSE; } else if ((atkHoldEffect == HOLD_EFFECT_PUNCHING_GLOVE && gMovesInfo[move].punchingMove) - || atkHoldEffect == HOLD_EFFECT_PROTECTIVE_PADS || GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH) { return FALSE; @@ -9569,8 +9593,7 @@ static inline uq4_12_t GetBurnOrFrostBiteModifier(u32 battlerAtk, u32 move, u32 return UQ_4_12(0.5); if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && IS_MOVE_SPECIAL(move) - && (B_BURN_FACADE_DMG < GEN_6 || gMovesInfo[move].effect != EFFECT_FACADE) - && abilityAtk != ABILITY_GUTS) + && (B_BURN_FACADE_DMG < GEN_6 || gMovesInfo[move].effect != EFFECT_FACADE)) return UQ_4_12(0.5); return UQ_4_12(1.0); } @@ -9860,6 +9883,66 @@ static inline s32 DoMoveDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 updateFlags, typeEffectivenessModifier, weather, holdEffectAtk, holdEffectDef, abilityAtk, abilityDef); } +static inline s32 DoFutureSightAttackDamageCalcVars(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, + bool32 isCrit, bool32 randomFactor, bool32 updateFlags, uq4_12_t typeEffectivenessModifier, u32 weather, + u32 holdEffectDef, u32 abilityDef) +{ + s32 dmg; + u32 userFinalAttack; + u32 targetFinalDefense; + + struct Pokemon *party = GetSideParty(GetBattlerSide(battlerAtk)); + struct Pokemon *partyMon = &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]]; + u32 partyMonLevel = GetMonData(partyMon, MON_DATA_LEVEL, NULL); + u32 partyMonSpecies = GetMonData(partyMon, MON_DATA_SPECIES, NULL); + gBattleMovePower = gMovesInfo[move].power; + + if (IS_MOVE_PHYSICAL(move)) + userFinalAttack = GetMonData(partyMon, MON_DATA_ATK, NULL); + else + userFinalAttack = GetMonData(partyMon, MON_DATA_SPATK, NULL); + + targetFinalDefense = CalcDefenseStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags, ABILITY_NONE, abilityDef, holdEffectDef, weather); + dmg = CalculateBaseDamage(gBattleMovePower, userFinalAttack, partyMonLevel, targetFinalDefense); + + DAMAGE_APPLY_MODIFIER(GetCriticalModifier(isCrit)); + + if (randomFactor) + { + dmg *= 100 - RandomUniform(RNG_DAMAGE_MODIFIER, 0, 15); + dmg /= 100; + } + + // Same type attack bonus + if (gSpeciesInfo[partyMonSpecies].types[0] == moveType || gSpeciesInfo[partyMonSpecies].types[1] == moveType) + DAMAGE_APPLY_MODIFIER(UQ_4_12(1.5)); + else + DAMAGE_APPLY_MODIFIER(UQ_4_12(1.0)); + DAMAGE_APPLY_MODIFIER(typeEffectivenessModifier); + + if (dmg == 0) + dmg = 1; + + gSpecialStatuses[battlerAtk].preventLifeOrbDamage = TRUE; + + return dmg; +} + +static inline s32 DoFutureSightAttackDamageCalc(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, + bool32 isCrit, bool32 randomFactor, bool32 updateFlags, uq4_12_t typeEffectivenessModifier, u32 weather) +{ + u32 holdEffectDef, abilityDef; + + if (typeEffectivenessModifier == UQ_4_12(0.0)) + return 0; + + holdEffectDef = GetBattlerHoldEffect(battlerDef, TRUE); + abilityDef = GetBattlerAbility(battlerDef); + + return DoFutureSightAttackDamageCalcVars(move, battlerAtk, battlerDef, moveType, isCrit, randomFactor, + updateFlags, typeEffectivenessModifier, weather, holdEffectDef, abilityDef); +} + #undef DAMAGE_APPLY_MODIFIER static u32 GetWeather(void) @@ -9872,9 +9955,21 @@ static u32 GetWeather(void) s32 CalculateMoveDamage(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags) { - return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, isCrit, randomFactor, + struct Pokemon *party = GetSideParty(GetBattlerSide(gBattlerAttacker)); + + if (gMovesInfo[move].effect == EFFECT_FUTURE_SIGHT + && (&party[gWishFutureKnock.futureSightPartyIndex[battlerDef]] != &party[gBattlerPartyIndexes[battlerAtk]]) ) + { + return DoFutureSightAttackDamageCalc(move, battlerAtk, battlerDef, moveType, isCrit, randomFactor, + updateFlags, CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, GetBattlerAbility(battlerDef), updateFlags), + GetWeather()); + } + else + { + return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, isCrit, randomFactor, updateFlags, CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, GetBattlerAbility(battlerDef), updateFlags), GetWeather()); + } } // for AI so that typeEffectivenessModifier, weather, abilities and holdEffects are calculated only once diff --git a/src/battle_z_move.c b/src/battle_z_move.c index b65f017f19..203185cfdc 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -47,7 +47,6 @@ // Function Declarations static void SpriteCB_ZMoveTrigger(struct Sprite *sprite); static u16 GetSignatureZMove(u16 move, u16 species, u16 item); -static u16 GetTypeBasedZMove(u16 move, u8 battler); static void ZMoveSelectionDisplayPpNumber(u32 battler); static void ZMoveSelectionDisplayPower(u16 move, u16 zMove); static void ShowZMoveTriggerSprite(u8 battleId); @@ -376,7 +375,7 @@ static u16 GetSignatureZMove(u16 move, u16 species, u16 item) return MOVE_NONE; } -static u16 GetTypeBasedZMove(u16 move, u8 battler) +u16 GetTypeBasedZMove(u16 move, u8 battler) { u8 moveType = gMovesInfo[move].type; diff --git a/src/berry_crush.c b/src/berry_crush.c index baf0e2fb65..2bb03e60a3 100755 --- a/src/berry_crush.c +++ b/src/berry_crush.c @@ -1373,7 +1373,6 @@ static void CreateBerrySprites(struct BerryCrushGame *game, struct BerryCrushGam u8 spriteId; s16 distance, var1; s16 *data; - s32 amplitude; s16 speed; u32 var2; @@ -1395,11 +1394,7 @@ static void CreateBerrySprites(struct BerryCrushGame *game, struct BerryCrushGam sYAccel = 32; sBitfield = 112; // Setting bits in MASK_TARGET_Y distance = gfx->playerCoords[i]->berryXDest - gfx->playerCoords[i]->berryXOffset; - amplitude = distance; - if (distance < 0) - amplitude += 3; - - sAmplitude = amplitude >> 2; + sAmplitude = distance / 4; distance *= 128; var2 = speed + 32; var2 = var2 / 2; diff --git a/src/data/graphics/pokemon.h b/src/data/graphics/pokemon.h index c51f0ce2ec..bc66e64123 100644 --- a/src/data/graphics/pokemon.h +++ b/src/data/graphics/pokemon.h @@ -474,6 +474,11 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u8 gMonIcon_PikachuGigantamax[] = INCBIN_U8("graphics/pokemon/pikachu/gigantamax/icon.4bpp"); #endif //P_GIGANTAMAX_FORMS + const u8 gMonIcon_PikachuPartner[] = INCBIN_U8("graphics/pokemon/pikachu/partner/icon.4bpp"); + #if P_CUSTOM_GENDER_DIFF_ICONS + const u8 gMonIcon_PikachuPartnerF[] = INCBIN_U8("graphics/pokemon/pikachu/partner/iconf.4bpp"); + #endif + const u32 gMonFrontPic_Raichu[] = INCBIN_U32("graphics/pokemon/raichu/anim_front.4bpp.lz"); const u32 gMonPalette_Raichu[] = INCBIN_U32("graphics/pokemon/raichu/normal.gbapal.lz"); const u32 gMonBackPic_Raichu[] = INCBIN_U32("graphics/pokemon/raichu/back.4bpp.lz"); @@ -2267,6 +2272,11 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u8 gMonIcon_EeveeGigantamax[] = INCBIN_U8("graphics/pokemon/eevee/gigantamax/icon.4bpp"); #endif //P_GIGANTAMAX_FORMS + const u8 gMonIcon_EeveePartner[] = INCBIN_U8("graphics/pokemon/eevee/partner/icon.4bpp"); + #if P_CUSTOM_GENDER_DIFF_ICONS + const u8 gMonIcon_EeveePartnerF[] = INCBIN_U8("graphics/pokemon/eevee/partner/iconf.4bpp"); + #endif + const u32 gMonFrontPic_Vaporeon[] = INCBIN_U32("graphics/pokemon/vaporeon/anim_front.4bpp.lz"); const u32 gMonPalette_Vaporeon[] = INCBIN_U32("graphics/pokemon/vaporeon/normal.gbapal.lz"); const u32 gMonBackPic_Vaporeon[] = INCBIN_U32("graphics/pokemon/vaporeon/back.4bpp.lz"); @@ -3538,7 +3548,7 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonPalette_UrsalunaBloodmoon[] = INCBIN_U32("graphics/pokemon/ursaluna/bloodmoon/normal.gbapal.lz"); const u32 gMonBackPic_UrsalunaBloodmoon[] = INCBIN_U32("graphics/pokemon/ursaluna/bloodmoon/back.4bpp.lz"); const u32 gMonShinyPalette_UrsalunaBloodmoon[] = INCBIN_U32("graphics/pokemon/ursaluna/bloodmoon/shiny.gbapal.lz"); - // const u8 gMonIcon_UrsalunaBloodmoon[] = INCBIN_U8("graphics/pokemon/ursaluna/bloodmoon/icon.4bpp"); + const u8 gMonIcon_UrsalunaBloodmoon[] = INCBIN_U8("graphics/pokemon/ursaluna/bloodmoon/icon.4bpp"); #endif //P_GEN_8_CROSS_EVOS #endif //P_FAMILY_TEDDIURSA @@ -11598,7 +11608,7 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonPalette_Archaludon[] = INCBIN_U32("graphics/pokemon/archaludon/normal.gbapal.lz"); const u32 gMonBackPic_Archaludon[] = INCBIN_U32("graphics/pokemon/archaludon/back.4bpp.lz"); const u32 gMonShinyPalette_Archaludon[] = INCBIN_U32("graphics/pokemon/archaludon/shiny.gbapal.lz"); - // const u8 gMonIcon_Archaludon[] = INCBIN_U8("graphics/pokemon/archaludon/icon.4bpp"); + const u8 gMonIcon_Archaludon[] = INCBIN_U8("graphics/pokemon/archaludon/icon.4bpp"); #if P_FOOTPRINTS // const u8 gMonFootprint_Archaludon[] = INCBIN_U8("graphics/pokemon/archaludon/footprint.1bpp"); #endif //P_FOOTPRINTS @@ -12947,19 +12957,19 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonPalette_OgerponWellspringMask[] = INCBIN_U32("graphics/pokemon/ogerpon/wellspring/normal.gbapal.lz"); const u32 gMonBackPic_OgerponWellspringMask[] = INCBIN_U32("graphics/pokemon/ogerpon/wellspring/back.4bpp.lz"); const u32 gMonShinyPalette_OgerponWellspringMask[] = INCBIN_U32("graphics/pokemon/ogerpon/wellspring/shiny.gbapal.lz"); - // const u8 gMonIcon_OgerponWellspringMask[] = INCBIN_U8("graphics/pokemon/ogerpon/wellspring/icon.4bpp"); + const u8 gMonIcon_OgerponWellspringMask[] = INCBIN_U8("graphics/pokemon/ogerpon/wellspring/icon.4bpp"); const u32 gMonFrontPic_OgerponHearthflameMask[] = INCBIN_U32("graphics/pokemon/ogerpon/hearthflame/front.4bpp.lz"); const u32 gMonPalette_OgerponHearthflameMask[] = INCBIN_U32("graphics/pokemon/ogerpon/hearthflame/normal.gbapal.lz"); const u32 gMonBackPic_OgerponHearthflameMask[] = INCBIN_U32("graphics/pokemon/ogerpon/hearthflame/back.4bpp.lz"); const u32 gMonShinyPalette_OgerponHearthflameMask[] = INCBIN_U32("graphics/pokemon/ogerpon/hearthflame/shiny.gbapal.lz"); - // const u8 gMonIcon_OgerponHearthflameMask[] = INCBIN_U8("graphics/pokemon/ogerpon/hearthflame/icon.4bpp"); + const u8 gMonIcon_OgerponHearthflameMask[] = INCBIN_U8("graphics/pokemon/ogerpon/hearthflame/icon.4bpp"); const u32 gMonFrontPic_OgerponCornerstoneMask[] = INCBIN_U32("graphics/pokemon/ogerpon/cornerstone/front.4bpp.lz"); const u32 gMonPalette_OgerponCornerstoneMask[] = INCBIN_U32("graphics/pokemon/ogerpon/cornerstone/normal.gbapal.lz"); const u32 gMonBackPic_OgerponCornerstoneMask[] = INCBIN_U32("graphics/pokemon/ogerpon/cornerstone/back.4bpp.lz"); const u32 gMonShinyPalette_OgerponCornerstoneMask[] = INCBIN_U32("graphics/pokemon/ogerpon/cornerstone/shiny.gbapal.lz"); - // const u8 gMonIcon_OgerponCornerstoneMask[] = INCBIN_U8("graphics/pokemon/ogerpon/cornerstone/icon.4bpp"); + const u8 gMonIcon_OgerponCornerstoneMask[] = INCBIN_U8("graphics/pokemon/ogerpon/cornerstone/icon.4bpp"); // const u32 gMonFrontPic_OgerponTealMaskTera[] = INCBIN_U32("graphics/pokemon/ogerpon/tera/front.4bpp.lz"); // const u32 gMonPalette_OgerponTealMaskTera[] = INCBIN_U32("graphics/pokemon/ogerpon/tera/normal.gbapal.lz"); @@ -12987,7 +12997,7 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonPalette_GougingFire[] = INCBIN_U32("graphics/pokemon/gouging_fire/normal.gbapal.lz"); const u32 gMonBackPic_GougingFire[] = INCBIN_U32("graphics/pokemon/gouging_fire/back.4bpp.lz"); const u32 gMonShinyPalette_GougingFire[] = INCBIN_U32("graphics/pokemon/gouging_fire/shiny.gbapal.lz"); - // const u8 gMonIcon_GougingFire[] = INCBIN_U8("graphics/pokemon/gouging_fire/icon.4bpp"); + const u8 gMonIcon_GougingFire[] = INCBIN_U8("graphics/pokemon/gouging_fire/icon.4bpp"); #if P_FOOTPRINTS // const u8 gMonFootprint_GougingFire[] = INCBIN_U8("graphics/pokemon/gouging_fire/footprint.1bpp"); #endif //P_FOOTPRINTS @@ -12998,7 +13008,7 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonPalette_RagingBolt[] = INCBIN_U32("graphics/pokemon/raging_bolt/normal.gbapal.lz"); const u32 gMonBackPic_RagingBolt[] = INCBIN_U32("graphics/pokemon/raging_bolt/back.4bpp.lz"); const u32 gMonShinyPalette_RagingBolt[] = INCBIN_U32("graphics/pokemon/raging_bolt/shiny.gbapal.lz"); - // const u8 gMonIcon_RagingBolt[] = INCBIN_U8("graphics/pokemon/raging_bolt/icon.4bpp"); + const u8 gMonIcon_RagingBolt[] = INCBIN_U8("graphics/pokemon/raging_bolt/icon.4bpp"); #if P_FOOTPRINTS // const u8 gMonFootprint_RagingBolt[] = INCBIN_U8("graphics/pokemon/raging_bolt/footprint.1bpp"); #endif //P_FOOTPRINTS @@ -13009,7 +13019,7 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonPalette_IronBoulder[] = INCBIN_U32("graphics/pokemon/iron_boulder/normal.gbapal.lz"); const u32 gMonBackPic_IronBoulder[] = INCBIN_U32("graphics/pokemon/iron_boulder/back.4bpp.lz"); const u32 gMonShinyPalette_IronBoulder[] = INCBIN_U32("graphics/pokemon/iron_boulder/shiny.gbapal.lz"); - // const u8 gMonIcon_IronBoulder[] = INCBIN_U8("graphics/pokemon/iron_boulder/icon.4bpp"); + const u8 gMonIcon_IronBoulder[] = INCBIN_U8("graphics/pokemon/iron_boulder/icon.4bpp"); #if P_FOOTPRINTS // const u8 gMonFootprint_IronBoulder[] = INCBIN_U8("graphics/pokemon/iron_boulder/footprint.1bpp"); #endif //P_FOOTPRINTS @@ -13020,7 +13030,7 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonPalette_IronCrown[] = INCBIN_U32("graphics/pokemon/iron_crown/normal.gbapal.lz"); const u32 gMonBackPic_IronCrown[] = INCBIN_U32("graphics/pokemon/iron_crown/back.4bpp.lz"); const u32 gMonShinyPalette_IronCrown[] = INCBIN_U32("graphics/pokemon/iron_crown/shiny.gbapal.lz"); - // const u8 gMonIcon_IronCrown[] = INCBIN_U8("graphics/pokemon/iron_crown/icon.4bpp"); + const u8 gMonIcon_IronCrown[] = INCBIN_U8("graphics/pokemon/iron_crown/icon.4bpp"); #if P_FOOTPRINTS // const u8 gMonFootprint_IronCrown[] = INCBIN_U8("graphics/pokemon/iron_crown/footprint.1bpp"); #endif //P_FOOTPRINTS @@ -13031,7 +13041,7 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar // const u32 gMonPalette_TerapagosNormal[] = INCBIN_U32("graphics/pokemon/terapagos/normal.gbapal.lz"); // const u32 gMonBackPic_TerapagosNormal[] = INCBIN_U32("graphics/pokemon/terapagos/back.4bpp.lz"); // const u32 gMonShinyPalette_TerapagosNormal[] = INCBIN_U32("graphics/pokemon/terapagos/shiny.gbapal.lz"); - // const u8 gMonIcon_TerapagosNormal[] = INCBIN_U8("graphics/pokemon/terapagos/icon.4bpp"); + const u8 gMonIcon_TerapagosNormal[] = INCBIN_U8("graphics/pokemon/terapagos/icon.4bpp"); #if P_FOOTPRINTS // const u8 gMonFootprint_Terapagos[] = INCBIN_U8("graphics/pokemon/terapagos/footprint.1bpp"); #endif //P_FOOTPRINTS @@ -13040,21 +13050,21 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar // const u32 gMonPalette_TerapagosTerastal[] = INCBIN_U32("graphics/pokemon/terapagos/terastal/normal.gbapal.lz"); // const u32 gMonBackPic_TerapagosTerastal[] = INCBIN_U32("graphics/pokemon/terapagos/terastal/back.4bpp.lz"); // const u32 gMonShinyPalette_TerapagosTerastal[] = INCBIN_U32("graphics/pokemon/terapagos/terastal/shiny.gbapal.lz"); - // const u8 gMonIcon_TerapagosTerastal[] = INCBIN_U8("graphics/pokemon/terapagos/terastal/icon.4bpp"); + const u8 gMonIcon_TerapagosTerastal[] = INCBIN_U8("graphics/pokemon/terapagos/terastal/icon.4bpp"); // const u32 gMonFrontPic_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/front.4bpp.lz"); // const u32 gMonPalette_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/normal.gbapal.lz"); // const u32 gMonBackPic_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/back.4bpp.lz"); // const u32 gMonShinyPalette_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/shiny.gbapal.lz"); - // const u8 gMonIcon_TerapagosStellar[] = INCBIN_U8("graphics/pokemon/terapagos/stellar/icon.4bpp"); + const u8 gMonIcon_TerapagosStellar[] = INCBIN_U8("graphics/pokemon/terapagos/stellar/icon.4bpp"); #endif //P_FAMILY_TERAPAGOS #if P_FAMILY_PECHARUNT - // const u32 gMonFrontPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/front.4bpp.lz"); - // const u32 gMonPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/normal.gbapal.lz"); - // const u32 gMonBackPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/back.4bpp.lz"); - // const u32 gMonShinyPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/shiny.gbapal.lz"); - // const u8 gMonIcon_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/icon.4bpp"); + const u32 gMonFrontPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/front.4bpp.lz"); + const u32 gMonPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/normal.gbapal.lz"); + const u32 gMonBackPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/back.4bpp.lz"); + const u32 gMonShinyPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/shiny.gbapal.lz"); + const u8 gMonIcon_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/icon.4bpp"); #if P_FOOTPRINTS // const u8 gMonFootprint_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/footprint.1bpp"); #endif //P_FOOTPRINTS diff --git a/src/data/items.h b/src/data/items.h index 1185f65178..3a65f8758c 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -9412,7 +9412,11 @@ const struct Item gItemsInfo[] = .description = COMPOUND_STRING( "Fires an icy cold\n" "beam that may\n" + #if B_USE_FROSTBITE == TRUE + "give the foe frostbite."), + #else "freeze the foe."), + #endif .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, @@ -9427,7 +9431,11 @@ const struct Item gItemsInfo[] = .description = COMPOUND_STRING( "A brutal snow-and-\n" "wind attack that\n" + #if B_USE_FROSTBITE == TRUE + "may give the foe frostbite."), + #else "may freeze the foe."), + #endif .importance = I_REUSABLE_TMS, .pocket = POCKET_TM_HM, .type = ITEM_USE_PARTY_MENU, diff --git a/src/data/moves_info.h b/src/data/moves_info.h index b19f4a7c43..10e0c8ef28 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -4435,7 +4435,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .name = COMPOUND_STRING("Powder Snow"), .description = COMPOUND_STRING( "Blasts the foe with a snowy\n" + #if B_USE_FROSTBITE == TRUE + "gust. May cause frostbite."), + #else "gust. May cause freezing."), + #endif .effect = EFFECT_HIT, .power = 40, .type = TYPE_ICE, @@ -10166,7 +10170,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .name = COMPOUND_STRING("Ice Fang"), .description = COMPOUND_STRING( "May cause flinching or\n" + #if B_USE_FROSTBITE == TRUE "leave the foe frozen."), + #else + "leave the foe with frostbite."), + #endif .effect = EFFECT_HIT, .power = 65, .type = TYPE_ICE, @@ -13679,7 +13687,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .name = COMPOUND_STRING("Freeze-Dry"), .description = COMPOUND_STRING( "Super effective on Water-\n" + #if B_USE_FROSTBITE == TRUE + "types. May cause frostbite."), + #else "types. May cause freezing."), + #endif .effect = EFFECT_SUPER_EFFECTIVE_ON_ARG, .power = 70, .type = TYPE_ICE, @@ -20232,6 +20244,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, + .ignoresTargetAbility = TRUE, }, [MOVE_MENACING_MOONRAZE_MAELSTROM] = { @@ -20245,6 +20258,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, + .ignoresTargetAbility = TRUE, }, [MOVE_LIGHT_THAT_BURNS_THE_SKY] = { @@ -20258,6 +20272,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, + .ignoresTargetAbility = TRUE, }, [MOVE_SOUL_STEALING_7_STAR_STRIKE] = { diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h index c66b4a7a4e..a12130d568 100644 --- a/src/data/pokemon/species_info/gen_1_families.h +++ b/src/data/pokemon/species_info/gen_1_families.h @@ -3149,10 +3149,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .backAnimId = BACK_ANIM_SHAKE_FLASH_YELLOW, .palette = gMonPalette_Pikachu, .shinyPalette = gMonShinyPalette_Pikachu, - .iconSprite = gMonIcon_Pikachu, + .iconSprite = gMonIcon_PikachuPartner, .iconPalIndex = 2, #if P_CUSTOM_GENDER_DIFF_ICONS == TRUE - .iconSpriteFemale = gMonIcon_PikachuF, + .iconSpriteFemale = gMonIcon_PikachuPartnerF, .iconPalIndexFemale = 2, #endif FOOTPRINT(Pikachu) @@ -13738,8 +13738,12 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .backAnimId = BACK_ANIM_CONCAVE_ARC_SMALL, .palette = gMonPalette_Eevee, .shinyPalette = gMonShinyPalette_Eevee, - .iconSprite = gMonIcon_Eevee, + .iconSprite = gMonIcon_EeveePartner, .iconPalIndex = 2, + #if P_CUSTOM_GENDER_DIFF_ICONS == TRUE + .iconSpriteFemale = gMonIcon_EeveePartnerF, + .iconPalIndexFemale = 2, + #endif FOOTPRINT(Eevee) .cannotBeTraded = TRUE, .allPerfectIVs = TRUE, diff --git a/src/data/pokemon/species_info/gen_2_families.h b/src/data/pokemon/species_info/gen_2_families.h index 68d15b3398..d1d33e3483 100644 --- a/src/data/pokemon/species_info/gen_2_families.h +++ b/src/data/pokemon/species_info/gen_2_families.h @@ -2666,7 +2666,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .palette = gMonPalette_Clodsire, .shinyPalette = gMonShinyPalette_Clodsire, .iconSprite = gMonIcon_Clodsire, - .iconPalIndex = 2, + .iconPalIndex = 0, //FOOTPRINT(Clodsire) .levelUpLearnset = sClodsireLevelUpLearnset, .teachableLearnset = sClodsireTeachableLearnset, @@ -3210,7 +3210,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .palette = gMonPalette_Farigiraf, .shinyPalette = gMonShinyPalette_Farigiraf, .iconSprite = gMonIcon_Farigiraf, - .iconPalIndex = 0, + .iconPalIndex = 1, //FOOTPRINT(Farigiraf) .levelUpLearnset = sFarigirafLevelUpLearnset, .teachableLearnset = sFarigirafTeachableLearnset, @@ -3841,7 +3841,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .palette = gMonPalette_QwilfishHisuian, .shinyPalette = gMonShinyPalette_QwilfishHisuian, .iconSprite = gMonIcon_QwilfishHisuian, - .iconPalIndex = 0, + .iconPalIndex = 1, FOOTPRINT(Qwilfish) .isHisuianForm = TRUE, .levelUpLearnset = sQwilfishHisuianLevelUpLearnset, @@ -4253,7 +4253,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .palette = gMonPalette_SneaselHisuian, .shinyPalette = gMonShinyPalette_SneaselHisuian, .iconSprite = gMonIcon_SneaselHisuian, - .iconPalIndex = 2, + .iconPalIndex = 0, FOOTPRINT(Sneasel) .isHisuianForm = TRUE, .levelUpLearnset = sSneaselHisuianLevelUpLearnset, @@ -4528,8 +4528,8 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = //.backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_UrsalunaBloodmoon, .shinyPalette = gMonShinyPalette_UrsalunaBloodmoon, - //.iconSprite = gMonIcon_UrsalunaBloodmoon, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_UrsalunaBloodmoon, + .iconPalIndex = 2, //FOOTPRINT(UrsalunaBloodmoon) .levelUpLearnset = sUrsalunaBloodmoonLevelUpLearnset, .teachableLearnset = sUrsalunaBloodmoonTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_5_families.h b/src/data/pokemon/species_info/gen_5_families.h index 1edf573743..4b1fea0263 100644 --- a/src/data/pokemon/species_info/gen_5_families.h +++ b/src/data/pokemon/species_info/gen_5_families.h @@ -8591,7 +8591,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = .palette = gMonPalette_Kingambit, .shinyPalette = gMonShinyPalette_Kingambit, .iconSprite = gMonIcon_Kingambit, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Kingambit) .levelUpLearnset = sKingambitLevelUpLearnset, .teachableLearnset = sKingambitTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_8_families.h b/src/data/pokemon/species_info/gen_8_families.h index 1e6abfa420..bb9ff9c087 100644 --- a/src/data/pokemon/species_info/gen_8_families.h +++ b/src/data/pokemon/species_info/gen_8_families.h @@ -2394,7 +2394,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .palette = gMonPalette_Hydrapple, .shinyPalette = gMonShinyPalette_Hydrapple, .iconSprite = gMonIcon_Hydrapple, - .iconPalIndex = 1, + .iconPalIndex = 5, //FOOTPRINT(Hydrapple) .levelUpLearnset = sHydrappleLevelUpLearnset, .teachableLearnset = sHydrappleTeachableLearnset, @@ -5389,8 +5389,8 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_Archaludon, .shinyPalette = gMonShinyPalette_Archaludon, - //.iconSprite = gMonIcon_Archaludon, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_Archaludon, + .iconPalIndex = 0, //FOOTPRINT(Archaludon) .levelUpLearnset = sArchaludonLevelUpLearnset, .teachableLearnset = sArchaludonTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_9_families.h b/src/data/pokemon/species_info/gen_9_families.h index 3efa35edb8..b84f9b24a2 100644 --- a/src/data/pokemon/species_info/gen_9_families.h +++ b/src/data/pokemon/species_info/gen_9_families.h @@ -50,7 +50,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Sprigatito, .shinyPalette = gMonShinyPalette_Sprigatito, .iconSprite = gMonIcon_Sprigatito, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(Sprigatito) .levelUpLearnset = sSprigatitoLevelUpLearnset, .teachableLearnset = sSprigatitoTeachableLearnset, @@ -210,7 +210,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Fuecoco, .shinyPalette = gMonShinyPalette_Fuecoco, .iconSprite = gMonIcon_Fuecoco, - .iconPalIndex = 0, + .iconPalIndex = 2, //FOOTPRINT(Fuecoco) .levelUpLearnset = sFuecocoLevelUpLearnset, .teachableLearnset = sFuecocoTeachableLearnset, @@ -370,7 +370,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Quaxly, .shinyPalette = gMonShinyPalette_Quaxly, .iconSprite = gMonIcon_Quaxly, - .iconPalIndex = 2, + .iconPalIndex = 0, //FOOTPRINT(Quaxly) .levelUpLearnset = sQuaxlyLevelUpLearnset, .teachableLearnset = sQuaxlyTeachableLearnset, @@ -636,7 +636,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_OinkologneFemale, .shinyPalette = gMonShinyPalette_OinkologneFemale, .iconSprite = gMonIcon_OinkologneFemale, - .iconPalIndex = 2, + .iconPalIndex = 0, //FOOTPRINT(Oinkologne) .levelUpLearnset = sOinkologneFemaleLevelUpLearnset, .teachableLearnset = sOinkologneTeachableLearnset, @@ -905,7 +905,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Pawmi, .shinyPalette = gMonShinyPalette_Pawmi, .iconSprite = gMonIcon_Pawmi, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Pawmi) .levelUpLearnset = sPawmiLevelUpLearnset, .teachableLearnset = sPawmiTeachableLearnset, @@ -958,7 +958,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Pawmo, .shinyPalette = gMonShinyPalette_Pawmo, .iconSprite = gMonIcon_Pawmo, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Pawmo) .levelUpLearnset = sPawmoLevelUpLearnset, .teachableLearnset = sPawmoTeachableLearnset, @@ -1011,7 +1011,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Pawmot, .shinyPalette = gMonShinyPalette_Pawmot, .iconSprite = gMonIcon_Pawmot, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Pawmot) .levelUpLearnset = sPawmotLevelUpLearnset, .teachableLearnset = sPawmotTeachableLearnset, @@ -1065,7 +1065,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Tandemaus, .shinyPalette = gMonShinyPalette_Tandemaus, .iconSprite = gMonIcon_Tandemaus, - .iconPalIndex = 0, + .iconPalIndex = 1, //FOOTPRINT(Tandemaus) .levelUpLearnset = sTandemausLevelUpLearnset, .teachableLearnset = sTandemausTeachableLearnset, @@ -1119,7 +1119,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Maushold, .shinyPalette = gMonShinyPalette_Maushold, .iconSprite = gMonIcon_MausholdFamilyOfThree, - .iconPalIndex = 0, + .iconPalIndex = 1, /*FOOTPRINT(Maushold)*/ .levelUpLearnset = sMausholdLevelUpLearnset, .teachableLearnset = sMausholdTeachableLearnset, @@ -1171,7 +1171,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Maushold, .shinyPalette = gMonShinyPalette_Maushold, .iconSprite = gMonIcon_MausholdFamilyOfFour, - .iconPalIndex = 0, + .iconPalIndex = 1, /*FOOTPRINT(Maushold)*/ .levelUpLearnset = sMausholdLevelUpLearnset, .teachableLearnset = sMausholdTeachableLearnset, @@ -1279,7 +1279,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Dachsbun, .shinyPalette = gMonShinyPalette_Dachsbun, .iconSprite = gMonIcon_Dachsbun, - .iconPalIndex = 0, // TODO + .iconPalIndex = 0, //FOOTPRINT(Dachsbun) .levelUpLearnset = sDachsbunLevelUpLearnset, .teachableLearnset = sDachsbunTeachableLearnset, @@ -1439,7 +1439,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Arboliva, .shinyPalette = gMonShinyPalette_Arboliva, .iconSprite = gMonIcon_Arboliva, - .iconPalIndex = 5, + .iconPalIndex = 1, //FOOTPRINT(Arboliva) .levelUpLearnset = sArbolivaLevelUpLearnset, .teachableLearnset = sArbolivaTeachableLearnset, @@ -1546,7 +1546,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_SquawkabillyBluePlumage, .shinyPalette = gMonShinyPalette_SquawkabillyBluePlumage, .iconSprite = gMonIcon_SquawkabillyBluePlumage, - .iconPalIndex = 2, + .iconPalIndex = 0, /*FOOTPRINT(Squawkabilly)*/ .levelUpLearnset = sSquawkabillyLevelUpLearnset, .teachableLearnset = sSquawkabillyTeachableLearnset, @@ -1652,7 +1652,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_SquawkabillyWhitePlumage, .shinyPalette = gMonShinyPalette_SquawkabillyWhitePlumage, .iconSprite = gMonIcon_SquawkabillyWhitePlumage, - .iconPalIndex = 1, + .iconPalIndex = 0, /*FOOTPRINT(Squawkabilly)*/ .levelUpLearnset = sSquawkabillyLevelUpLearnset, .teachableLearnset = sSquawkabillyTeachableLearnset, @@ -1760,7 +1760,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Naclstack, .shinyPalette = gMonShinyPalette_Naclstack, .iconSprite = gMonIcon_Naclstack, - .iconPalIndex = 2, // TODO: recolor + .iconPalIndex = 2, //FOOTPRINT(Naclstack) .levelUpLearnset = sNaclstackLevelUpLearnset, .teachableLearnset = sNaclstackTeachableLearnset, @@ -1867,7 +1867,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Charcadet, .shinyPalette = gMonShinyPalette_Charcadet, .iconSprite = gMonIcon_Charcadet, - .iconPalIndex = 1, + .iconPalIndex = 0, //FOOTPRINT(Charcadet) .levelUpLearnset = sCharcadetLevelUpLearnset, .teachableLearnset = sCharcadetTeachableLearnset, @@ -2028,7 +2028,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Tadbulb, .shinyPalette = gMonShinyPalette_Tadbulb, .iconSprite = gMonIcon_Tadbulb, - .iconPalIndex = 5, // TODO: Redo to 0 + .iconPalIndex = 0, //FOOTPRINT(Tadbulb) .levelUpLearnset = sTadbulbLevelUpLearnset, .teachableLearnset = sTadbulbTeachableLearnset, @@ -2135,7 +2135,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Wattrel, .shinyPalette = gMonShinyPalette_Wattrel, .iconSprite = gMonIcon_Wattrel, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Wattrel) .levelUpLearnset = sWattrelLevelUpLearnset, .teachableLearnset = sWattrelTeachableLearnset, @@ -2188,7 +2188,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Kilowattrel, .shinyPalette = gMonShinyPalette_Kilowattrel, .iconSprite = gMonIcon_Kilowattrel, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Kilowattrel) .levelUpLearnset = sKilowattrelLevelUpLearnset, .teachableLearnset = sKilowattrelTeachableLearnset, @@ -2242,7 +2242,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Maschiff, .shinyPalette = gMonShinyPalette_Maschiff, .iconSprite = gMonIcon_Maschiff, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Maschiff) .levelUpLearnset = sMaschiffLevelUpLearnset, .teachableLearnset = sMaschiffTeachableLearnset, @@ -2295,7 +2295,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Mabosstiff, .shinyPalette = gMonShinyPalette_Mabosstiff, .iconSprite = gMonIcon_Mabosstiff, - .iconPalIndex = 5, + .iconPalIndex = 0, //FOOTPRINT(Mabosstiff) .levelUpLearnset = sMabosstiffLevelUpLearnset, .teachableLearnset = sMabosstiffTeachableLearnset, @@ -2456,7 +2456,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Bramblin, .shinyPalette = gMonShinyPalette_Bramblin, .iconSprite = gMonIcon_Bramblin, - .iconPalIndex = 3, + .iconPalIndex = 1, //FOOTPRINT(Bramblin) .levelUpLearnset = sBramblinLevelUpLearnset, .teachableLearnset = sBramblinTeachableLearnset, @@ -2509,7 +2509,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Brambleghast, .shinyPalette = gMonShinyPalette_Brambleghast, .iconSprite = gMonIcon_Brambleghast, - .iconPalIndex = 5, + .iconPalIndex = 2, //FOOTPRINT(Brambleghast) .levelUpLearnset = sBrambleghastLevelUpLearnset, .teachableLearnset = sBrambleghastTeachableLearnset, @@ -2831,7 +2831,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Rellor, .shinyPalette = gMonShinyPalette_Rellor, .iconSprite = gMonIcon_Rellor, - .iconPalIndex = 5, + .iconPalIndex = 0, //FOOTPRINT(Rellor) .levelUpLearnset = sRellorLevelUpLearnset, .teachableLearnset = sRellorTeachableLearnset, @@ -2938,7 +2938,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Flittle, .shinyPalette = gMonShinyPalette_Flittle, .iconSprite = gMonIcon_Flittle, - .iconPalIndex = 3, + .iconPalIndex = 1, //FOOTPRINT(Flittle) .levelUpLearnset = sFlittleLevelUpLearnset, .teachableLearnset = sFlittleTeachableLearnset, @@ -2991,7 +2991,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Espathra, .shinyPalette = gMonShinyPalette_Espathra, .iconSprite = gMonIcon_Espathra, - .iconPalIndex = 5, + .iconPalIndex = 0, //FOOTPRINT(Espathra) .levelUpLearnset = sEspathraLevelUpLearnset, .teachableLearnset = sEspathraTeachableLearnset, @@ -3098,7 +3098,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Tinkatuff, .shinyPalette = gMonShinyPalette_Tinkatuff, .iconSprite = gMonIcon_Tinkatuff, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(Tinkatuff) .levelUpLearnset = sTinkatuffLevelUpLearnset, .teachableLearnset = sTinkatuffTeachableLearnset, @@ -3151,7 +3151,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Tinkaton, .shinyPalette = gMonShinyPalette_Tinkaton, .iconSprite = gMonIcon_Tinkaton, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(Tinkaton) .levelUpLearnset = sTinkatonLevelUpLearnset, .teachableLearnset = sTinkatonTeachableLearnset, @@ -3527,7 +3527,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Varoom, .shinyPalette = gMonShinyPalette_Varoom, .iconSprite = gMonIcon_Varoom, - .iconPalIndex = 5, + .iconPalIndex = 2, //FOOTPRINT(Varoom) .levelUpLearnset = sVaroomLevelUpLearnset, .teachableLearnset = sVaroomTeachableLearnset, @@ -3580,7 +3580,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Revavroom, .shinyPalette = gMonShinyPalette_Revavroom, .iconSprite = gMonIcon_Revavroom, - .iconPalIndex = 5, + .iconPalIndex = 2, //FOOTPRINT(Revavroom) .levelUpLearnset = sRevavroomLevelUpLearnset, .teachableLearnset = sRevavroomTeachableLearnset, @@ -3688,7 +3688,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Orthworm, .shinyPalette = gMonShinyPalette_Orthworm, .iconSprite = gMonIcon_Orthworm, - .iconPalIndex = 4, + .iconPalIndex = 0, //FOOTPRINT(Orthworm) .levelUpLearnset = sOrthwormLevelUpLearnset, .teachableLearnset = sOrthwormTeachableLearnset, @@ -3851,7 +3851,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Greavard, .shinyPalette = gMonShinyPalette_Greavard, .iconSprite = gMonIcon_Greavard, - .iconPalIndex = 2, + .iconPalIndex = 0, //FOOTPRINT(Greavard) .levelUpLearnset = sGreavardLevelUpLearnset, .teachableLearnset = sGreavardTeachableLearnset, @@ -3904,7 +3904,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Houndstone, .shinyPalette = gMonShinyPalette_Houndstone, .iconSprite = gMonIcon_Houndstone, - .iconPalIndex = 5, + .iconPalIndex = 2, //FOOTPRINT(Houndstone) .levelUpLearnset = sHoundstoneLevelUpLearnset, .teachableLearnset = sHoundstoneTeachableLearnset, @@ -3958,7 +3958,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Flamigo, .shinyPalette = gMonShinyPalette_Flamigo, .iconSprite = gMonIcon_Flamigo, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(Flamigo) .levelUpLearnset = sFlamigoLevelUpLearnset, .teachableLearnset = sFlamigoTeachableLearnset, @@ -4120,7 +4120,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Veluza, .shinyPalette = gMonShinyPalette_Veluza, .iconSprite = gMonIcon_Veluza, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(Veluza) .levelUpLearnset = sVeluzaLevelUpLearnset, .teachableLearnset = sVeluzaTeachableLearnset, @@ -4556,7 +4556,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_FlutterMane, .shinyPalette = gMonShinyPalette_FlutterMane, .iconSprite = gMonIcon_FlutterMane, - .iconPalIndex = 4, + .iconPalIndex = 2, //FOOTPRINT(FlutterMane) .isParadoxForm = TRUE, .levelUpLearnset = sFlutterManeLevelUpLearnset, @@ -4610,7 +4610,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_SlitherWing, .shinyPalette = gMonShinyPalette_SlitherWing, .iconSprite = gMonIcon_SlitherWing, - .iconPalIndex = 3, + .iconPalIndex = 1, //FOOTPRINT(SlitherWing) .isParadoxForm = TRUE, .levelUpLearnset = sSlitherWingLevelUpLearnset, @@ -4720,7 +4720,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_IronTreads, .shinyPalette = gMonShinyPalette_IronTreads, .iconSprite = gMonIcon_IronTreads, - .iconPalIndex = 0, + .iconPalIndex = 1, //FOOTPRINT(IronTreads) .isParadoxForm = TRUE, .levelUpLearnset = sIronTreadsLevelUpLearnset, @@ -4886,7 +4886,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_IronJugulis, .shinyPalette = gMonShinyPalette_IronJugulis, .iconSprite = gMonIcon_IronJugulis, - .iconPalIndex = 2, + .iconPalIndex = 0, //FOOTPRINT(IronJugulis) .isParadoxForm = TRUE, .levelUpLearnset = sIronJugulisLevelUpLearnset, @@ -4942,7 +4942,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_IronMoth, .shinyPalette = gMonShinyPalette_IronMoth, .iconSprite = gMonIcon_IronMoth, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(IronMoth) .isParadoxForm = TRUE, .levelUpLearnset = sIronMothLevelUpLearnset, @@ -5052,7 +5052,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Frigibax, .shinyPalette = gMonShinyPalette_Frigibax, .iconSprite = gMonIcon_Frigibax, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(Frigibax) .levelUpLearnset = sFrigibaxLevelUpLearnset, .teachableLearnset = sFrigibaxTeachableLearnset, @@ -5374,7 +5374,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_WoChien, .shinyPalette = gMonShinyPalette_WoChien, .iconSprite = gMonIcon_WoChien, - .iconPalIndex = 5, + .iconPalIndex = 1, //FOOTPRINT(WoChien) .isLegendary = TRUE, .levelUpLearnset = sWoChienLevelUpLearnset, @@ -5596,7 +5596,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_RoaringMoon, .shinyPalette = gMonShinyPalette_RoaringMoon, .iconSprite = gMonIcon_RoaringMoon, - .iconPalIndex = 3, + .iconPalIndex = 0, //FOOTPRINT(RoaringMoon) .isParadoxForm = TRUE, .levelUpLearnset = sRoaringMoonLevelUpLearnset, @@ -5650,7 +5650,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_IronValiant, .shinyPalette = gMonShinyPalette_IronValiant, .iconSprite = gMonIcon_IronValiant, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(IronValiant) .isParadoxForm = TRUE, .levelUpLearnset = sIronValiantLevelUpLearnset, @@ -5924,7 +5924,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Poltchageist, .shinyPalette = gMonShinyPalette_Poltchageist, .iconSprite = gMonIcon_Poltchageist, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(Poltchageist) .levelUpLearnset = sPoltchageistLevelUpLearnset, .teachableLearnset = sPoltchageistTeachableLearnset, @@ -5977,7 +5977,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .palette = gMonPalette_Poltchageist, .shinyPalette = gMonShinyPalette_Poltchageist, .iconSprite = gMonIcon_Poltchageist, - .iconPalIndex = 4, + .iconPalIndex = 1, //FOOTPRINT(Poltchageist) .levelUpLearnset = sPoltchageistLevelUpLearnset, .teachableLearnset = sPoltchageistTeachableLearnset, @@ -6256,7 +6256,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = #endif //P_FAMILY_FEZANDIPITI #if P_FAMILY_OGERPON -#define OGERPON_SPECIES_INFO(Form, type, ability, color) \ +#define OGERPON_SPECIES_INFO(Form, type, ability, color, iconpalette) \ { \ .baseHP = 80, \ .baseAttack = 120, \ @@ -6297,8 +6297,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = /*.backAnimId = BACK_ANIM_NONE,*/ \ .palette = gMonPalette_Ogerpon##Form, \ .shinyPalette = gMonShinyPalette_Ogerpon##Form, \ - .iconSprite = gMonIcon_OgerponTealMask,/* Each form should have its own icon */ \ - .iconPalIndex = 1, \ + .iconSprite = gMonIcon_Ogerpon##Form, \ + .iconPalIndex = iconpalette, \ /*FOOTPRINT(Ogerpon)*/ \ .levelUpLearnset = sOgerponLevelUpLearnset, \ .teachableLearnset = sOgerponTeachableLearnset, \ @@ -6307,15 +6307,15 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .isLegendary = TRUE, \ } - [SPECIES_OGERPON_TEAL_MASK] = OGERPON_SPECIES_INFO(TealMask, TYPE_GRASS, ABILITY_DEFIANT, BODY_COLOR_GREEN), - [SPECIES_OGERPON_WELLSPRING_MASK] = OGERPON_SPECIES_INFO(WellspringMask, TYPE_WATER, ABILITY_WATER_ABSORB, BODY_COLOR_BLUE), - [SPECIES_OGERPON_HEARTHFLAME_MASK] = OGERPON_SPECIES_INFO(HearthflameMask, TYPE_FIRE, ABILITY_MOLD_BREAKER, BODY_COLOR_RED), - [SPECIES_OGERPON_CORNERSTONE_MASK] = OGERPON_SPECIES_INFO(CornerstoneMask, TYPE_ROCK, ABILITY_STURDY, BODY_COLOR_GRAY), + [SPECIES_OGERPON_TEAL_MASK] = OGERPON_SPECIES_INFO(TealMask, TYPE_GRASS, ABILITY_DEFIANT, BODY_COLOR_GREEN, 1), + [SPECIES_OGERPON_WELLSPRING_MASK] = OGERPON_SPECIES_INFO(WellspringMask, TYPE_WATER, ABILITY_WATER_ABSORB, BODY_COLOR_BLUE, 0), + [SPECIES_OGERPON_HEARTHFLAME_MASK] = OGERPON_SPECIES_INFO(HearthflameMask, TYPE_FIRE, ABILITY_MOLD_BREAKER, BODY_COLOR_RED, 0), + [SPECIES_OGERPON_CORNERSTONE_MASK] = OGERPON_SPECIES_INFO(CornerstoneMask, TYPE_ROCK, ABILITY_STURDY, BODY_COLOR_GRAY, 0), #if P_TERA_FORMS - [SPECIES_OGERPON_TEAL_MASK_TERA] = OGERPON_SPECIES_INFO(TealMask, TYPE_GRASS, ABILITY_EMBODY_ASPECT_TEAL, BODY_COLOR_GREEN), - [SPECIES_OGERPON_WELLSPRING_MASK_TERA] = OGERPON_SPECIES_INFO(WellspringMask, TYPE_WATER, ABILITY_EMBODY_ASPECT_WELLSPRING, BODY_COLOR_BLUE), - [SPECIES_OGERPON_HEARTHFLAME_MASK_TERA] = OGERPON_SPECIES_INFO(HearthflameMask, TYPE_FIRE, ABILITY_EMBODY_ASPECT_HEARTHFLAME, BODY_COLOR_RED), - [SPECIES_OGERPON_CORNERSTONE_MASK_TERA] = OGERPON_SPECIES_INFO(CornerstoneMask, TYPE_ROCK, ABILITY_EMBODY_ASPECT_CORNERSTONE, BODY_COLOR_GRAY), + [SPECIES_OGERPON_TEAL_MASK_TERA] = OGERPON_SPECIES_INFO(TealMask, TYPE_GRASS, ABILITY_EMBODY_ASPECT_TEAL, BODY_COLOR_GREEN, 1), + [SPECIES_OGERPON_WELLSPRING_MASK_TERA] = OGERPON_SPECIES_INFO(WellspringMask, TYPE_WATER, ABILITY_EMBODY_ASPECT_WELLSPRING, BODY_COLOR_BLUE, 0), + [SPECIES_OGERPON_HEARTHFLAME_MASK_TERA] = OGERPON_SPECIES_INFO(HearthflameMask, TYPE_FIRE, ABILITY_EMBODY_ASPECT_HEARTHFLAME, BODY_COLOR_RED, 0), + [SPECIES_OGERPON_CORNERSTONE_MASK_TERA] = OGERPON_SPECIES_INFO(CornerstoneMask, TYPE_ROCK, ABILITY_EMBODY_ASPECT_CORNERSTONE, BODY_COLOR_GRAY, 0), #endif //P_TERA_FORMS #endif //P_FAMILY_OGERPON @@ -6366,8 +6366,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_GougingFire, .shinyPalette = gMonShinyPalette_GougingFire, - //.iconSprite = gMonIcon_GougingFire, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_GougingFire, + .iconPalIndex = 5, //FOOTPRINT(GougingFire) .isParadoxForm = TRUE, .levelUpLearnset = sGougingFireLevelUpLearnset, @@ -6421,8 +6421,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_RagingBolt, .shinyPalette = gMonShinyPalette_RagingBolt, - //.iconSprite = gMonIcon_RagingBolt, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_RagingBolt, + .iconPalIndex = 2, //FOOTPRINT(RagingBolt) .isParadoxForm = TRUE, .levelUpLearnset = sRagingBoltLevelUpLearnset, @@ -6475,8 +6475,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_IronBoulder, .shinyPalette = gMonShinyPalette_IronBoulder, - //.iconSprite = gMonIcon_IronBoulder, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_IronBoulder, + .iconPalIndex = 5, //FOOTPRINT(IronBoulder) .isParadoxForm = TRUE, .levelUpLearnset = sIronBoulderLevelUpLearnset, @@ -6530,8 +6530,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_IronCrown, .shinyPalette = gMonShinyPalette_IronCrown, - //.iconSprite = gMonIcon_IronCrown, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_IronCrown, + .iconPalIndex = 3, //FOOTPRINT(IronCrown) .isParadoxForm = TRUE, .levelUpLearnset = sIronCrownLevelUpLearnset, @@ -6585,8 +6585,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = //.backAnimId = BACK_ANIM_NONE, //.palette = gMonPalette_TerapagosNormal, //.shinyPalette = gMonShinyPalette_TerapagosNormal, - //.iconSprite = gMonIcon_TerapagosNormal, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_TerapagosNormal, + .iconPalIndex = 0, //FOOTPRINT(Terapagos) .isLegendary = TRUE, .levelUpLearnset = sTerapagosLevelUpLearnset, @@ -6641,8 +6641,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = //.backAnimId = BACK_ANIM_NONE, //.palette = gMonPalette_TerapagosTerastal, //.shinyPalette = gMonShinyPalette_TerapagosTerastal, - //.iconSprite = gMonIcon_TerapagosTerastal, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_TerapagosTerastal, + .iconPalIndex = 0, //FOOTPRINT(Terapagos) .isLegendary = TRUE, .levelUpLearnset = sTerapagosLevelUpLearnset, @@ -6696,8 +6696,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = //.backAnimId = BACK_ANIM_NONE, //.palette = gMonPalette_TerapagosStellar, //.shinyPalette = gMonShinyPalette_TerapagosStellar, - //.iconSprite = gMonIcon_TerapagosStellar, - //.iconPalIndex = 0, + .iconSprite = gMonIcon_TerapagosStellar, + .iconPalIndex = 0, //FOOTPRINT(Terapagos) .isLegendary = TRUE, .levelUpLearnset = sTerapagosLevelUpLearnset, @@ -6742,19 +6742,19 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .pokemonOffset = 0, .trainerScale = 365, .trainerOffset = 7, - //.frontPic = gMonFrontPic_Pecharunt, - //.frontPicSize = MON_COORDS_SIZE(64, 64), - .frontPicYOffset = 0, + .frontPic = gMonFrontPic_Pecharunt, + .frontPicSize = MON_COORDS_SIZE(64, 64), + .frontPicYOffset = 13, .frontAnimFrames = sAnims_Pecharunt, - //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - //.backPic = gMonBackPic_Pecharunt, - //.backPicSize = MON_COORDS_SIZE(64, 64), - .backPicYOffset = 0, - //.backAnimId = BACK_ANIM_NONE, - //.palette = gMonPalette_Pecharunt, - //.shinyPalette = gMonShinyPalette_Pecharunt, - //.iconSprite = gMonIcon_Pecharunt, - //.iconPalIndex = 0, + .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + .backPic = gMonBackPic_Pecharunt, + .backPicSize = MON_COORDS_SIZE(64, 64), + .backPicYOffset = 5, + .backAnimId = BACK_ANIM_NONE, + .palette = gMonPalette_Pecharunt, + .shinyPalette = gMonShinyPalette_Pecharunt, + .iconSprite = gMonIcon_Pecharunt, + .iconPalIndex = 0, //FOOTPRINT(Pecharunt) .isMythical = TRUE, .levelUpLearnset = sPecharuntLevelUpLearnset, diff --git a/src/event_object_movement.c b/src/event_object_movement.c index fc14b5127a..10d427e517 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -145,9 +145,9 @@ static u8 FindObjectEventPaletteIndexByTag(u16); static void _PatchObjectPalette(u16, u8); static bool8 ObjectEventDoesElevationMatch(struct ObjectEvent *, u8); static void SpriteCB_CameraObject(struct Sprite *); -static void CameraObject_0(struct Sprite *); -static void CameraObject_1(struct Sprite *); -static void CameraObject_2(struct Sprite *); +static void CameraObject_Init(struct Sprite *); +static void CameraObject_UpdateMove(struct Sprite *); +static void CameraObject_UpdateFrozen(struct Sprite *); static const struct ObjectEventTemplate *FindObjectEventTemplateByLocalId(u8, const struct ObjectEventTemplate *, u8); static void ClearObjectEventMovement(struct ObjectEvent *, struct Sprite *); static void ObjectEventSetSingleMovement(struct ObjectEvent *, struct Sprite *, u8); @@ -194,10 +194,16 @@ static const struct SpriteTemplate sCameraSpriteTemplate = { .callback = SpriteCB_CameraObject }; +enum { + CAMERA_STATE_INIT, + CAMERA_STATE_MOVE, + CAMERA_STATE_FROZEN, +}; + static void (*const sCameraObjectFuncs[])(struct Sprite *) = { - CameraObject_0, - CameraObject_1, - CameraObject_2, + [CAMERA_STATE_INIT] = CameraObject_Init, + [CAMERA_STATE_MOVE] = CameraObject_UpdateMove, + [CAMERA_STATE_FROZEN] = CameraObject_UpdateFrozen, }; #include "data/object_events/object_event_graphics.h" @@ -1837,7 +1843,7 @@ void ObjectEventSetGraphicsId(struct ObjectEvent *objectEvent, u8 graphicsId) sprite->x += 8; sprite->y += 16 + sprite->centerToCornerVecY; if (objectEvent->trackedByCamera) - CameraObjectReset1(); + CameraObjectReset(); } void ObjectEventSetGraphicsIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 graphicsId) @@ -2129,7 +2135,7 @@ void MoveObjectEventToMapCoords(struct ObjectEvent *objectEvent, s16 x, s16 y) sprite->y += 16 + sprite->centerToCornerVecY; ResetObjectEventFldEffData(objectEvent); if (objectEvent->trackedByCamera) - CameraObjectReset1(); + CameraObjectReset(); } void TryMoveObjectEventToMapCoords(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y) @@ -2205,15 +2211,15 @@ void UpdateObjectEventsForCameraUpdate(s16 x, s16 y) RemoveObjectEventsOutsideView(); } -#define sLinkedSpriteId data[0] -#define sState data[1] - -u8 AddCameraObject(u8 linkedSpriteId) +// The "CameraObject" functions below are responsible for an invisible sprite +// that follows the movements of a different sprite (normally the player's sprite) +// and tracks x/y movement distances for the camera so it knows where to move. +u8 AddCameraObject(u8 followSpriteId) { u8 spriteId = CreateSprite(&sCameraSpriteTemplate, 0, 0, 4); gSprites[spriteId].invisible = TRUE; - gSprites[spriteId].sLinkedSpriteId = linkedSpriteId; + gSprites[spriteId].sCamera_FollowSpriteId = followSpriteId; return spriteId; } @@ -2222,35 +2228,37 @@ static void SpriteCB_CameraObject(struct Sprite *sprite) void (*callbacks[ARRAY_COUNT(sCameraObjectFuncs)])(struct Sprite *); memcpy(callbacks, sCameraObjectFuncs, sizeof sCameraObjectFuncs); - callbacks[sprite->sState](sprite); + callbacks[sprite->sCamera_State](sprite); } -static void CameraObject_0(struct Sprite *sprite) +static void CameraObject_Init(struct Sprite *sprite) { - sprite->x = gSprites[sprite->sLinkedSpriteId].x; - sprite->y = gSprites[sprite->sLinkedSpriteId].y; + sprite->x = gSprites[sprite->sCamera_FollowSpriteId].x; + sprite->y = gSprites[sprite->sCamera_FollowSpriteId].y; sprite->invisible = TRUE; - sprite->sState = 1; - CameraObject_1(sprite); + sprite->sCamera_State = CAMERA_STATE_MOVE; + CameraObject_UpdateMove(sprite); } -static void CameraObject_1(struct Sprite *sprite) +static void CameraObject_UpdateMove(struct Sprite *sprite) { - s16 x = gSprites[sprite->sLinkedSpriteId].x; - s16 y = gSprites[sprite->sLinkedSpriteId].y; + s16 x = gSprites[sprite->sCamera_FollowSpriteId].x; + s16 y = gSprites[sprite->sCamera_FollowSpriteId].y; - sprite->data[2] = x - sprite->x; - sprite->data[3] = y - sprite->y; + sprite->sCamera_MoveX = x - sprite->x; + sprite->sCamera_MoveY = y - sprite->y; sprite->x = x; sprite->y = y; } -static void CameraObject_2(struct Sprite *sprite) +// Invisible sprite will continue to follow the parent sprite, +// but no corresponding camera movement will be shown. +static void CameraObject_UpdateFrozen(struct Sprite *sprite) { - sprite->x = gSprites[sprite->sLinkedSpriteId].x; - sprite->y = gSprites[sprite->sLinkedSpriteId].y; - sprite->data[2] = 0; - sprite->data[3] = 0; + sprite->x = gSprites[sprite->sCamera_FollowSpriteId].x; + sprite->y = gSprites[sprite->sCamera_FollowSpriteId].y; + sprite->sCamera_MoveX = 0; + sprite->sCamera_MoveY = 0; } static struct Sprite *FindCameraSprite(void) @@ -2265,51 +2273,43 @@ static struct Sprite *FindCameraSprite(void) return NULL; } -void CameraObjectReset1(void) +void CameraObjectReset(void) { - struct Sprite *camera; - - camera = FindCameraSprite(); + struct Sprite *camera = FindCameraSprite(); if (camera != NULL) { - camera->sState = 0; + camera->sCamera_State = CAMERA_STATE_INIT; camera->callback(camera); } } void CameraObjectSetFollowedSpriteId(u8 spriteId) { - struct Sprite *camera; - - camera = FindCameraSprite(); + struct Sprite *camera = FindCameraSprite(); if (camera != NULL) { - camera->sLinkedSpriteId = spriteId; - CameraObjectReset1(); + camera->sCamera_FollowSpriteId = spriteId; + CameraObjectReset(); } } static u8 UNUSED CameraObjectGetFollowedSpriteId(void) { - struct Sprite *camera; - - camera = FindCameraSprite(); + struct Sprite *camera = FindCameraSprite(); if (camera == NULL) return MAX_SPRITES; - return camera->sLinkedSpriteId; + return camera->sCamera_FollowSpriteId; } -void CameraObjectReset2(void) +void CameraObjectFreeze(void) { - // UB: Possible null dereference -#ifdef UBFIX struct Sprite *camera = FindCameraSprite(); - if (camera) - camera->sState = 2; -#else - FindCameraSprite()->sState = 2; -#endif // UBFIX +#ifdef UBFIX // Possible null dereference + if (camera == NULL) + return; +#endif + camera->sCamera_State = CAMERA_STATE_FROZEN; } u8 CopySprite(struct Sprite *sprite, s16 x, s16 y, u8 subpriority) @@ -8077,14 +8077,18 @@ static void DoGroundEffects_OnSpawn(struct ObjectEvent *objEvent, struct Sprite { u32 flags; +#ifdef BUGFIX + if (objEvent->triggerGroundEffectsOnMove && objEvent->localId != OBJ_EVENT_ID_CAMERA) +#else if (objEvent->triggerGroundEffectsOnMove) +#endif { flags = 0; UpdateObjectEventElevationAndPriority(objEvent, sprite); GetAllGroundEffectFlags_OnSpawn(objEvent, &flags); SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite); DoFlaggedGroundEffects(objEvent, sprite, flags); - objEvent->triggerGroundEffectsOnMove = 0; + objEvent->triggerGroundEffectsOnMove = FALSE; objEvent->disableCoveringGroundEffects = 0; } } @@ -8093,7 +8097,11 @@ static void DoGroundEffects_OnBeginStep(struct ObjectEvent *objEvent, struct Spr { u32 flags; +#ifdef BUGFIX + if (objEvent->triggerGroundEffectsOnMove && objEvent->localId != OBJ_EVENT_ID_CAMERA) +#else if (objEvent->triggerGroundEffectsOnMove) +#endif { flags = 0; UpdateObjectEventElevationAndPriority(objEvent, sprite); @@ -8101,7 +8109,7 @@ static void DoGroundEffects_OnBeginStep(struct ObjectEvent *objEvent, struct Spr SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite); filters_out_some_ground_effects(objEvent, &flags); DoFlaggedGroundEffects(objEvent, sprite, flags); - objEvent->triggerGroundEffectsOnMove = 0; + objEvent->triggerGroundEffectsOnMove = FALSE; objEvent->disableCoveringGroundEffects = 0; } } @@ -8110,7 +8118,11 @@ static void DoGroundEffects_OnFinishStep(struct ObjectEvent *objEvent, struct Sp { u32 flags; +#ifdef BUGFIX + if (objEvent->triggerGroundEffectsOnStop && objEvent->localId != OBJ_EVENT_ID_CAMERA) +#else if (objEvent->triggerGroundEffectsOnStop) +#endif { flags = 0; UpdateObjectEventElevationAndPriority(objEvent, sprite); diff --git a/src/field_camera.c b/src/field_camera.c index 3f7e29208c..31ebc63c05 100644 --- a/src/field_camera.c +++ b/src/field_camera.c @@ -331,8 +331,8 @@ static void CameraUpdateCallback(struct CameraObject *fieldCamera) { if (fieldCamera->spriteId != 0) { - fieldCamera->movementSpeedX = gSprites[fieldCamera->spriteId].data[2]; - fieldCamera->movementSpeedY = gSprites[fieldCamera->spriteId].data[3]; + fieldCamera->movementSpeedX = gSprites[fieldCamera->spriteId].sCamera_MoveX; + fieldCamera->movementSpeedY = gSprites[fieldCamera->spriteId].sCamera_MoveY; } } diff --git a/src/field_effect.c b/src/field_effect.c index bece73b025..dcfbd57078 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -1448,7 +1448,7 @@ static bool8 FallWarpEffect_Init(struct Task *task) struct Sprite *playerSprite; playerObject = &gObjectEvents[gPlayerAvatar.objectEventId]; playerSprite = &gSprites[gPlayerAvatar.spriteId]; - CameraObjectReset2(); + CameraObjectFreeze(); gObjectEvents[gPlayerAvatar.objectEventId].invisible = TRUE; gPlayerAvatar.preventStep = TRUE; ObjectEventSetHeldMovement(playerObject, GetFaceDirectionMovementAction(GetPlayerFacingDirection())); @@ -1544,7 +1544,7 @@ static bool8 FallWarpEffect_End(struct Task *task) { gPlayerAvatar.preventStep = FALSE; UnlockPlayerFieldControls(); - CameraObjectReset1(); + CameraObjectReset(); UnfreezeObjectEvents(); InstallCameraPanAheadCallback(); DestroyTask(FindTaskIdByFunc(Task_FallWarpFieldEffect)); @@ -1583,7 +1583,7 @@ static void Task_EscalatorWarpOut(u8 taskId) static bool8 EscalatorWarpOut_Init(struct Task *task) { FreezeObjectEvents(); - CameraObjectReset2(); + CameraObjectFreeze(); StartEscalator(task->tGoingUp); task->tState++; return FALSE; @@ -1715,7 +1715,7 @@ static bool8 EscalatorWarpIn_Init(struct Task *task) s16 x; s16 y; u8 behavior; - CameraObjectReset2(); + CameraObjectFreeze(); objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId]; ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(DIR_EAST)); PlayerGetDestCoords(&x, &y); @@ -1815,7 +1815,7 @@ static bool8 EscalatorWarpIn_End(struct Task *task) objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId]; if (ObjectEventClearHeldMovementIfFinished(objectEvent)) { - CameraObjectReset1(); + CameraObjectReset(); UnlockPlayerFieldControls(); ObjectEventSetHeldMovement(objectEvent, GetWalkNormalMovementAction(DIR_EAST)); DestroyTask(FindTaskIdByFunc(Task_EscalatorWarpIn)); @@ -1961,7 +1961,7 @@ static void Task_LavaridgeGymB1FWarp(u8 taskId) static bool8 LavaridgeGymB1FWarpEffect_Init(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite) { FreezeObjectEvents(); - CameraObjectReset2(); + CameraObjectFreeze(); SetCameraPanningCallback(NULL); gPlayerAvatar.preventStep = TRUE; objectEvent->fixedPriority = 1; @@ -2076,7 +2076,7 @@ static void Task_LavaridgeGymB1FWarpExit(u8 taskId) static bool8 LavaridgeGymB1FWarpExitEffect_Init(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite) { - CameraObjectReset2(); + CameraObjectFreeze(); FreezeObjectEvents(); gPlayerAvatar.preventStep = TRUE; objectEvent->invisible = TRUE; @@ -2105,7 +2105,7 @@ static bool8 LavaridgeGymB1FWarpExitEffect_PopOut(struct Task *task, struct Obje { task->data[0]++; objectEvent->invisible = FALSE; - CameraObjectReset1(); + CameraObjectReset(); PlaySE(SE_M_DIG); ObjectEventSetHeldMovement(objectEvent, GetJumpMovementAction(DIR_EAST)); } @@ -2154,7 +2154,7 @@ static void Task_LavaridgeGym1FWarp(u8 taskId) static bool8 LavaridgeGym1FWarpEffect_Init(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite) { FreezeObjectEvents(); - CameraObjectReset2(); + CameraObjectFreeze(); gPlayerAvatar.preventStep = TRUE; objectEvent->fixedPriority = 1; task->data[0]++; @@ -2374,7 +2374,7 @@ static void TeleportWarpOutFieldEffect_Init(struct Task *task) { LockPlayerFieldControls(); FreezeObjectEvents(); - CameraObjectReset2(); + CameraObjectFreeze(); task->data[15] = GetPlayerFacingDirection(); task->tState++; } @@ -2456,7 +2456,7 @@ static void FieldCallback_TeleportWarpIn(void) FreezeObjectEvents(); gFieldCallback = NULL; gObjectEvents[gPlayerAvatar.objectEventId].invisible = TRUE; - CameraObjectReset2(); + CameraObjectFreeze(); CreateTask(Task_TeleportWarpIn, 0); } @@ -2500,7 +2500,7 @@ static void TeleportWarpInFieldEffect_SpinEnter(struct Task *task) if (task->data[13] == 0) { task->data[13]++; - objectEvent->triggerGroundEffectsOnMove = 1; + objectEvent->triggerGroundEffectsOnMove = TRUE; sprite->subspriteMode = task->data[14]; } } else @@ -2540,7 +2540,7 @@ static void TeleportWarpInFieldEffect_SpinGround(struct Task *task) if ((++task->data[2]) > 4 && task->data[14] == objectEvent->facingDirection) { UnlockPlayerFieldControls(); - CameraObjectReset1(); + CameraObjectReset(); UnfreezeObjectEvents(); DestroyTask(FindTaskIdByFunc(Task_TeleportWarpIn)); } @@ -3272,7 +3272,7 @@ static void FlyOutFieldEffect_FlyOffWithBird(struct Task *task) objectEvent->inanimate = FALSE; objectEvent->hasShadow = FALSE; SetFlyBirdPlayerSpriteId(task->tBirdSpriteId, objectEvent->spriteId); - CameraObjectReset2(); + CameraObjectFreeze(); task->tState++; } } @@ -3487,7 +3487,7 @@ static void FlyInFieldEffect_BirdSwoopDown(struct Task *task) SetSurfBlob_BobState(objectEvent->fieldEffectSpriteId, BOB_NONE); } ObjectEventSetGraphicsId(objectEvent, GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_SURFING)); - CameraObjectReset2(); + CameraObjectFreeze(); ObjectEventTurn(objectEvent, DIR_WEST); StartSpriteAnim(&gSprites[objectEvent->spriteId], ANIM_GET_ON_OFF_POKEMON_WEST); objectEvent->invisible = FALSE; diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 99cab7fd77..50438863af 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -1665,6 +1665,10 @@ static void Task_WaitStopSurfing(u8 taskId) gPlayerAvatar.preventStep = FALSE; UnlockPlayerFieldControls(); DestroySprite(&gSprites[playerObjEvent->fieldEffectSpriteId]); +#ifdef BUGFIX + // If this is not defined but the player steps into grass from surfing, they will appear over the grass instead of in the grass. + playerObjEvent->triggerGroundEffectsOnMove = TRUE; +#endif DestroyTask(taskId); } } @@ -2095,7 +2099,7 @@ static void Task_DoPlayerSpinExit(u8 taskId) tSpeed = 1; tCurY = (u16)(sprite->y + sprite->y2) << 4; sprite->y2 = 0; - CameraObjectReset2(); + CameraObjectFreeze(); object->fixedPriority = TRUE; sprite->oam.priority = 0; sprite->subpriority = 0; @@ -2164,7 +2168,7 @@ static void Task_DoPlayerSpinEntrance(u8 taskId) tSubpriority = sprite->subpriority; tCurY = -((u16)sprite->y2 + 32) * 16; sprite->y2 = 0; - CameraObjectReset2(); + CameraObjectFreeze(); object->fixedPriority = TRUE; sprite->oam.priority = 1; sprite->subpriority = 0; @@ -2199,7 +2203,7 @@ static void Task_DoPlayerSpinEntrance(u8 taskId) object->fixedPriority = 0; sprite->oam.priority = tPriority; sprite->subpriority = tSubpriority; - CameraObjectReset1(); + CameraObjectReset(); DestroyTask(taskId); } break; diff --git a/src/field_weather.c b/src/field_weather.c index 0f0b137d9a..118db10bed 100644 --- a/src/field_weather.c +++ b/src/field_weather.c @@ -279,7 +279,6 @@ static void BuildColorMaps(void) u16 brightnessDelta; u16 colorMapIndex; u16 baseBrightness; - u32 remainingBrightness; s16 diff; sPaletteColorMapTypes = sBasePaletteColorMapTypes; @@ -307,11 +306,7 @@ static void BuildColorMaps(void) } baseBrightness = curBrightness; - remainingBrightness = 0x1f00 - curBrightness; - if ((0x1f00 - curBrightness) < 0) - remainingBrightness += 0xf; - - brightnessDelta = remainingBrightness / (NUM_WEATHER_COLOR_MAPS - 3); + brightnessDelta = (0x1f00 - curBrightness) / (NUM_WEATHER_COLOR_MAPS - 3); if (colorVal < 12) { // For shadows (color values < 12), the remaining color mappings are diff --git a/src/international_string_util.c b/src/international_string_util.c index 160e201b60..feba03c97f 100644 --- a/src/international_string_util.c +++ b/src/international_string_util.c @@ -75,10 +75,7 @@ int Intl_GetListMenuWidth(const struct ListMenuTemplate *listMenu) } finalWidth = maxWidth + listMenu->item_X + 9; - if (finalWidth < 0) - finalWidth += 7; - - finalWidth >>= 3; + finalWidth /= 8; if (finalWidth > 28) finalWidth = 28; diff --git a/src/overworld.c b/src/overworld.c index 8878af8748..478dd4784a 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -3096,7 +3096,7 @@ static void SetPlayerFacingDirection(u8 linkPlayerId, u8 facing) { if (facing > FACING_FORCED_RIGHT) { - objEvent->triggerGroundEffectsOnMove = 1; + objEvent->triggerGroundEffectsOnMove = TRUE; } else { @@ -3245,7 +3245,7 @@ static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion) sprite = &gSprites[objEvent->spriteId]; sprite->coordOffsetEnabled = TRUE; sprite->data[0] = linkPlayerId; - objEvent->triggerGroundEffectsOnMove = 0; + objEvent->triggerGroundEffectsOnMove = FALSE; } } diff --git a/src/party_menu.c b/src/party_menu.c index 7044244709..fc0a66c5a6 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -2093,7 +2093,7 @@ u8 GetAilmentFromStatus(u32 status) if (status & STATUS1_BURN) return AILMENT_BRN; if (status & STATUS1_FROSTBITE) - return AILMENT_FSB; + return AILMENT_FRB; return AILMENT_NONE; } diff --git a/src/pokemon_animation.c b/src/pokemon_animation.c index 69f6003a4e..acf3d4b91f 100644 --- a/src/pokemon_animation.c +++ b/src/pokemon_animation.c @@ -4583,29 +4583,24 @@ static void ShrinkGrowVibrate(struct Sprite *sprite) } else { - u8 posY_unsigned; - s8 posY_signed; - s32 posY; - s16 index = (u16)(sprite->data[2] % sprite->data[6] * 256) / sprite->data[6] % 256; + s8 sinY; + u16 y; + s16 index = ((u16)(sprite->data[2] % sprite->data[6] * 256) / sprite->data[6]) % 256; if (sprite->data[2] % 2 == 0) { sprite->data[4] = Sin(index, 32) + 256; sprite->data[5] = Sin(index, 32) + 256; - posY_unsigned = Sin(index, 32); - posY_signed = posY_unsigned; + sinY = Sin(index, 32); } else { sprite->data[4] = Sin(index, 8) + 256; sprite->data[5] = Sin(index, 8) + 256; - posY_unsigned = Sin(index, 8); - posY_signed = posY_unsigned; + sinY = Sin(index, 8); } - posY = posY_signed; - if (posY < 0) - posY += 7; - sprite->y2 = (u32)(posY) >> 3; + y = sinY / 8; + sprite->y2 = y; HandleSetAffineData(sprite, sprite->data[4], sprite->data[5], 0); } diff --git a/src/scrcmd.c b/src/scrcmd.c index 1e95c8ebd9..2695409460 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -2311,7 +2311,7 @@ bool8 ScrCmd_lockfortrainer(struct ScriptContext *ctx) } // This command will set a Pokémon's modernFatefulEncounter bit; there is no similar command to clear it. -bool8 ScrCmd_setmonmodernfatefulencounter(struct ScriptContext *ctx) +bool8 ScrCmd_setmodernfatefulencounter(struct ScriptContext *ctx) { bool8 isModernFatefulEncounter = TRUE; u16 partyIndex = VarGet(ScriptReadHalfword(ctx)); @@ -2320,7 +2320,7 @@ bool8 ScrCmd_setmonmodernfatefulencounter(struct ScriptContext *ctx) return FALSE; } -bool8 ScrCmd_checkmonmodernfatefulencounter(struct ScriptContext *ctx) +bool8 ScrCmd_checkmodernfatefulencounter(struct ScriptContext *ctx) { u16 partyIndex = VarGet(ScriptReadHalfword(ctx)); diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index a0bc7d8e16..31e40fa31a 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -347,7 +347,9 @@ u32 ScriptGiveMonParameterized(u16 species, u8 level, u16 item, u8 ball, u8 natu // moves for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] == MOVE_NONE || moves[i] >= MOVES_COUNT) + if (moves[0] == MOVE_NONE) + break; + if (moves[i] >= MOVES_COUNT) continue; SetMonMoveSlot(&mon, moves[i], i); } @@ -400,7 +402,7 @@ u32 ScriptGiveMonParameterized(u16 species, u8 level, u16 item, u8 ball, u8 natu } // set pokédex flags - nationalDexNum = SpeciesToNationalPokedexNum(species); + nationalDexNum = SpeciesToNationalPokedexNum(species); switch (sentToPc) { case MON_GIVEN_TO_PARTY: @@ -514,7 +516,7 @@ void Script_SetStatus1(struct ScriptContext *ctx) } } else - { + { SetMonData(&gPlayerParty[slot], MON_DATA_STATUS, &status1); } } diff --git a/src/trainer_see.c b/src/trainer_see.c index ee10747cdf..7a88d3cf46 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -623,7 +623,7 @@ static bool8 JumpInPlaceBuriedTrainer(u8 taskId, struct Task *task, struct Objec if (gSprites[task->tOutOfAshSpriteId].animCmdIndex == 2) { trainerObj->fixedPriority = 0; - trainerObj->triggerGroundEffectsOnMove = 1; + trainerObj->triggerGroundEffectsOnMove = TRUE; sprite = &gSprites[trainerObj->spriteId]; sprite->oam.priority = 2; diff --git a/test/battle/ability/defiant.c b/test/battle/ability/defiant.c index 3463cad18d..d464dd2443 100644 --- a/test/battle/ability/defiant.c +++ b/test/battle/ability/defiant.c @@ -175,3 +175,104 @@ DOUBLE_BATTLE_TEST("Defiant is activated by Cotton Down for non-ally pokemon") EXPECT_EQ(playerRight->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 2); } } + +SINGLE_BATTLE_TEST("Defiant activates before White Herb") +{ + u32 move; + + PARAMETRIZE { move = MOVE_LEER; } + PARAMETRIZE { move = MOVE_GROWL; } + + GIVEN { + PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); Item(ITEM_WHITE_HERB); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + + ABILITY_POPUP(player, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack sharply rose!"); + + if (move == MOVE_LEER) { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Mankey's White Herb restored its status!"); + } else { + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Mankey's White Herb restored its status!"); + } + } + } THEN { + if (move == MOVE_LEER) { + EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE); + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 2); + } else { + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } + } +} + +SINGLE_BATTLE_TEST("Defiant activates for each stat that is lowered") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TICKLE].effect == EFFECT_TICKLE); + PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TICKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TICKLE, opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + + MESSAGE("Mankey's Attack fell!"); + ABILITY_POPUP(player, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack sharply rose!"); + + MESSAGE("Mankey's Defense fell!"); + ABILITY_POPUP(player, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack sharply rose!"); + + } THEN { + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 3); + } +} + +SINGLE_BATTLE_TEST("Defiant doesn't activate if the pokemon lowers it's own stats") +{ + u32 move; + + PARAMETRIZE { move = MOVE_SUPERPOWER; } + PARAMETRIZE { move = MOVE_CLOSE_COMBAT; } + PARAMETRIZE { move = MOVE_MAKE_IT_RAIN; } + PARAMETRIZE { move = MOVE_SPIN_OUT; } + + GIVEN { + ASSUME(MoveHasAdditionalEffectSelf(MOVE_SUPERPOWER, MOVE_EFFECT_ATK_DEF_DOWN)); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_CLOSE_COMBAT, MOVE_EFFECT_DEF_SPDEF_DOWN)); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_MAKE_IT_RAIN, MOVE_EFFECT_SP_ATK_MINUS_1)); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_SPIN_OUT, MOVE_EFFECT_SPD_MINUS_2)); + PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + + NONE_OF { + ABILITY_POPUP(player, ABILITY_DEFIANT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Mankey's Attack sharply rose!"); + } + } THEN { + if (move == MOVE_SUPERPOWER) + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE - 1); + else + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE); + } +} diff --git a/test/battle/ability/disguise.c b/test/battle/ability/disguise.c new file mode 100644 index 0000000000..7d3e36bf78 --- /dev/null +++ b/test/battle/ability/disguise.c @@ -0,0 +1,123 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_AERIAL_ACE].category == DAMAGE_CATEGORY_PHYSICAL); +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing to its busted form") +{ + s16 disguiseDamage; + + GIVEN { + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_AERIAL_ACE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, opponent); + ABILITY_POPUP(player, ABILITY_DISGUISE); + HP_BAR(player, captureDamage: &disguiseDamage); + } THEN { + EXPECT_EQ(player->species, SPECIES_MIMIKYU_BUSTED); + EXPECT_EQ(disguiseDamage, player->maxHP / 8); + } +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu takes no damage from a confusion hit and changes to its busted form") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_CONFUSE_RAY); } + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFUSE_RAY, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, player); + MESSAGE("Mimikyu became confused!"); + MESSAGE("Mimikyu is confused!"); + MESSAGE("It hurt itself in its confusion!"); + NOT HP_BAR(player); + ABILITY_POPUP(player, ABILITY_DISGUISE); + } THEN { + EXPECT_EQ(player->species, SPECIES_MIMIKYU_BUSTED); + } +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu's Air Balloon will pop upon changing to its busted form") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_AIR_BALLOON].holdEffect == HOLD_EFFECT_AIR_BALLOON); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); Item(ITEM_AIR_BALLOON); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_AERIAL_ACE); } + } SCENE { + MESSAGE("Mimikyu floats in the air with its Air Balloon!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, opponent); + NOT HP_BAR(player); + ABILITY_POPUP(player, ABILITY_DISGUISE); + MESSAGE("Mimikyu's Air Balloon popped!"); + } THEN { + EXPECT_EQ(player->species, SPECIES_MIMIKYU_BUSTED); + } +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from secondary damage without breaking the disguise") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_STEALTH_ROCK); } + TURN { SWITCH(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponent); + HP_BAR(player); + MESSAGE("Pointed stones dug into Mimikyu!"); + } THEN { + EXPECT_EQ(player->species, SPECIES_MIMIKYU_DISGUISED); + } +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from Rocky Helmet without breaking the disguise") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_ROCKY_HELMET].holdEffect == HOLD_EFFECT_ROCKY_HELMET); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ROCKY_HELMET); } + } WHEN { + TURN { MOVE(player, MOVE_AERIAL_ACE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + HP_BAR(player); + MESSAGE("Mimikyu was hurt by Foe Wobbuffet's Rocky Helmet!"); + } THEN { + EXPECT_EQ(player->species, SPECIES_MIMIKYU_DISGUISED); + } +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from Rough Skin without breaking the disguise") +{ + GIVEN { + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_CARVANHA) { Ability(ABILITY_ROUGH_SKIN); } + } WHEN { + TURN { MOVE(player, MOVE_AERIAL_ACE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, player); + HP_BAR(opponent); + ABILITY_POPUP(opponent, ABILITY_ROUGH_SKIN); + HP_BAR(player); + MESSAGE("Mimikyu was hurt by Foe Carvanha's Rough Skin!"); + } THEN { + EXPECT_EQ(player->species, SPECIES_MIMIKYU_DISGUISED); + } +} diff --git a/test/battle/ability/gulp_missile.c b/test/battle/ability/gulp_missile.c new file mode 100644 index 0000000000..680208506d --- /dev/null +++ b/test/battle/ability/gulp_missile.c @@ -0,0 +1,137 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + // ASSUME(gMovesInfo[MOVE_AERIAL_ACE].category == DAMAGE_CATEGORY_PHYSICAL); +} + +SINGLE_BATTLE_TEST("(Gulp Missile) If base Cramorant hits target with Surf it transforms into Gulping form if max HP is over 1/2") +{ + GIVEN { + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SURF); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player); + HP_BAR(opponent); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + } THEN { + EXPECT_EQ(player->species, SPECIES_CRAMORANT_GULPING); + } +} + +SINGLE_BATTLE_TEST("(Gulp Missile) If base Cramorant hits target with Surf it transforms into Gorging form if max HP is under 1/2") +{ + GIVEN { + PLAYER(SPECIES_CRAMORANT) { HP(120); MaxHP(250); Ability(ABILITY_GULP_MISSILE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SURF); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player); + HP_BAR(opponent); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + } THEN { + EXPECT_EQ(player->species, SPECIES_CRAMORANT_GORGING); + } +} + +SINGLE_BATTLE_TEST("(Gulp Missile) If base Cramorant is under water it transforms into one of its forms") +{ + GIVEN { + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_DIVE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DIVE, player); + NOT HP_BAR(opponent); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + } THEN { + EXPECT_EQ(player->species, SPECIES_CRAMORANT_GULPING); + } +} + +SINGLE_BATTLE_TEST("(Gulp Missile) Power Herb does not prevent Cramaront from transforming") +{ + GIVEN { + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); Item(ITEM_POWER_HERB); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_DIVE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DIVE, player); + MESSAGE("Cramorant became fully charged due to its Power Herb!"); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + HP_BAR(opponent); + } THEN { + EXPECT_EQ(player->species, SPECIES_CRAMORANT_GULPING); + } +} + +SINGLE_BATTLE_TEST("(Gulp Missile) Transformed Cramorant deal 1/4 of damage opposing mon if hit by a damaging move, Gulping also lowers defense") +{ + s16 gulpMissileDamage; + + GIVEN { + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SURF); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player); + HP_BAR(opponent); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + HP_BAR(player); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + HP_BAR(opponent, captureDamage: &gulpMissileDamage); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's Defense fell!"); + } THEN { + EXPECT_EQ(gulpMissileDamage, opponent->maxHP / 4); + } +} + +SINGLE_BATTLE_TEST("(Gulp Missile) Cramorant in Gorging paralyzes the target if hit by a damaging move") +{ + GIVEN { + PLAYER(SPECIES_CRAMORANT) { HP(120); MaxHP(250); Ability(ABILITY_GULP_MISSILE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SURF); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player); + HP_BAR(opponent); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + HP_BAR(player); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, opponent); + STATUS_ICON(opponent, paralysis: TRUE); + } +} + +SINGLE_BATTLE_TEST("(Gulp Missile) triggers even if the user is fainted by opposing mon") +{ + // See: https://github.com/rh-hideout/pokeemerald-expansion/issues/4143 + KNOWN_FAILING; + GIVEN { + PLAYER(SPECIES_CRAMORANT) { HP(1); MaxHP(250); Ability(ABILITY_GULP_MISSILE); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SURF); MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player); + HP_BAR(opponent); + ABILITY_POPUP(player, ABILITY_GULP_MISSILE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + HP_BAR(player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, opponent); + STATUS_ICON(opponent, paralysis: TRUE); + } +} diff --git a/test/battle/ai.c b/test/battle/ai.c index b52400acc9..c8a64faceb 100644 --- a/test/battle/ai.c +++ b/test/battle/ai.c @@ -526,6 +526,25 @@ AI_SINGLE_BATTLE_TEST("AI will choose either Rock Tomb or Bulldoze if Stat drop } } +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Number of hits to KO calculation checks whether incoming damage is less than recurring healing to avoid an infinite loop") +{ + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES); + PLAYER(SPECIES_VENUSAUR) { Level(30); Moves(MOVE_TACKLE); } + // Opponent party courtesy of Skolgrahd, who triggered the bug in the first place + OPPONENT(SPECIES_PIKACHU) { Level(100); Moves(MOVE_ZIPPY_ZAP, MOVE_EXTREME_SPEED, MOVE_IRON_TAIL, MOVE_KNOCK_OFF); } + OPPONENT(SPECIES_NINETALES_ALOLAN) { Level(100); Moves(MOVE_AURORA_VEIL, MOVE_BLIZZARD, MOVE_MOONBLAST, MOVE_DISABLE); } + OPPONENT(SPECIES_WEAVILE) { Level(100); Moves(MOVE_NIGHT_SLASH, MOVE_TRIPLE_AXEL, MOVE_ICE_SHARD, MOVE_FAKE_OUT); } + OPPONENT(SPECIES_DITTO) { Level(100); Moves(MOVE_TRANSFORM); } + OPPONENT(SPECIES_TYPHLOSION) { Level(100); Moves(MOVE_ERUPTION, MOVE_HEAT_WAVE, MOVE_FOCUS_BLAST, MOVE_EXTRASENSORY); } + OPPONENT(SPECIES_UMBREON) { Level(100); Item(ITEM_LEFTOVERS); Moves(MOVE_FOUL_PLAY, MOVE_SNARL, MOVE_HELPING_HAND, MOVE_THUNDER_WAVE); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVES(opponent, MOVE_ZIPPY_ZAP, MOVE_EXTREME_SPEED, MOVE_IRON_TAIL, MOVE_KNOCK_OFF); } + } SCENE { + MESSAGE("Venusaur fainted!"); + } +} + AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI will not switch in a Pokemon which is slower and gets 1HKOed after fainting") { bool32 alakazamFirst; diff --git a/test/battle/hold_effect/protective_pads.c b/test/battle/hold_effect/protective_pads.c new file mode 100644 index 0000000000..914118d2d8 --- /dev/null +++ b/test/battle/hold_effect/protective_pads.c @@ -0,0 +1,75 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gItemsInfo[ITEM_PROTECTIVE_PADS].holdEffect == HOLD_EFFECT_PROTECTIVE_PADS); + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE); +} + +SINGLE_BATTLE_TEST("Protective Pads protected moves still make direct contact", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_KLUTZ; } + PARAMETRIZE { ability = ABILITY_FLUFFY; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PROTECTIVE_PADS); } + OPPONENT(SPECIES_STUFFUL) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + MESSAGE("Wobbuffet used Tackle!"); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, UQ_4_12(0.5), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Protective Pads doesn't reduce tough claws damage", s16 damage) +{ + u32 item; + PARAMETRIZE { item = ITEM_NONE; } + PARAMETRIZE { item = ITEM_PROTECTIVE_PADS; } + GIVEN { + PLAYER(SPECIES_BINACLE) { Ability(ABILITY_TOUGH_CLAWS); Item(item); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + MESSAGE("Binacle used Tackle!"); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Protective Pads doesn't invalid unseen fist") +{ + GIVEN { + PLAYER(SPECIES_URSHIFU_RAPID_STRIKE_STYLE) { Ability(ABILITY_UNSEEN_FIST); Item(ITEM_PROTECTIVE_PADS); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent); + } +} + +SINGLE_BATTLE_TEST("Protective Pads protects from Rocly Helmet Damage") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PROTECTIVE_PADS); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ROCKY_HELMET); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent); + NONE_OF { + HP_BAR(player); + MESSAGE("Wobbuffet was hurt by Foe Wobbuffet's Rocky Helmet!"); + } + } +} diff --git a/test/battle/hold_effect/white_herb.c b/test/battle/hold_effect/white_herb.c index 0103115658..fb455f47c6 100644 --- a/test/battle/hold_effect/white_herb.c +++ b/test/battle/hold_effect/white_herb.c @@ -55,10 +55,10 @@ DOUBLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimi ABILITY_POPUP(playerLeft, ABILITY_INTIMIDATE); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); MESSAGE("Foe Wobbuffet's White Herb restored its status!"); + + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight); MESSAGE("Foe Wynaut's White Herb restored its status!"); } THEN { @@ -71,7 +71,6 @@ DOUBLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimi SINGLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimidate while switching in") { - KNOWN_FAILING; GIVEN { PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } OPPONENT(SPECIES_WOBBUFFET); @@ -95,7 +94,6 @@ SINGLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimi } } - SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move happened") { u16 species; @@ -104,7 +102,6 @@ SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move PARAMETRIZE { species = SPECIES_SLIGGOO_HISUIAN; ability = ABILITY_GOOEY; } PARAMETRIZE { species = SPECIES_DUGTRIO_ALOLAN; ability = ABILITY_TANGLING_HAIR; } - KNOWN_FAILING; GIVEN { ASSUME(gMovesInfo[MOVE_DUAL_WINGBEAT].strikeCount == 2); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } @@ -114,10 +111,11 @@ SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_DUAL_WINGBEAT, player); ABILITY_POPUP(opponent, ability); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Wobbuffet's Speed fell!"); ABILITY_POPUP(opponent, ability); - MESSAGE("Wobbuffet's Speed fell!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Speed fell!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); MESSAGE("Wobbuffet's White Herb restored its status!"); } THEN { @@ -133,7 +131,6 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o PARAMETRIZE { move = MOVE_THIEF; } PARAMETRIZE { move = MOVE_KNOCK_OFF; } - KNOWN_FAILING; // Knock off fails, Thief is fine GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE); ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF); @@ -143,14 +140,16 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o TURN { MOVE(opponent, move); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, move, opponent); - if (move == MOVE_THIEF) + if (move == MOVE_THIEF) { MESSAGE("Foe Wobbuffet stole Slugma's White Herb!"); - else - MESSAGE("Foe Wobbuffet knocked off Slugma's White Herb!"); + } ABILITY_POPUP(player, ABILITY_WEAK_ARMOR); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Slugma's Weak Armor lowered its Defense!"); MESSAGE("Slugma's Weak Armor raised its Speed!"); + if (move == MOVE_KNOCK_OFF) { + MESSAGE("Foe Wobbuffet knocked off Slugma's White Herb!"); + } NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); MESSAGE("Wobbuffet's White Herb restored its status!"); @@ -163,7 +162,6 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o SINGLE_BATTLE_TEST("White Herb wont have time to activate if Magician steals it") { - KNOWN_FAILING; // White Herb is activated GIVEN { PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); } OPPONENT(SPECIES_FENNEKIN) { Ability(ABILITY_MAGICIAN); } @@ -171,11 +169,12 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if Magician steals it" TURN { MOVE(opponent, MOVE_TACKLE); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + ABILITY_POPUP(player, ABILITY_WEAK_ARMOR); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Slugma's Weak Armor lowered its Defense!"); + MESSAGE("Slugma's Weak Armor raised its Speed!"); ABILITY_POPUP(opponent, ABILITY_MAGICIAN); - ABILITY_POPUP(player, ABILITY_WEAK_ARMOR); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Slugma's Weak Armor lowered its Defense!"); - MESSAGE("Slugma's Weak Armor raised its Speed!"); + MESSAGE("Foe Fennekin stole Slugma's White Herb!"); NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); MESSAGE("Wobbuffet's White Herb restored its status!"); @@ -186,33 +185,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if Magician steals it" } } -SINGLE_BATTLE_TEST("White Herb wont have time to activate if Pickpocket steals it") -{ - KNOWN_FAILING; // White Herb is activated - GIVEN { - ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_TWO_DOWN)); - PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); } - OPPONENT(SPECIES_SNEASEL) { Ability(ABILITY_PICKPOCKET); } - } WHEN { - TURN { MOVE(player, MOVE_LEAF_STORM); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_LEAF_STORM, player); - ABILITY_POPUP(player, ABILITY_PICKPOCKET); - ABILITY_POPUP(player, ABILITY_WEAK_ARMOR); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Slugma's Weak Armor lowered its Defense!"); - MESSAGE("Slugma's Weak Armor raised its Speed!"); - NONE_OF { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); - MESSAGE("Wobbuffet's White Herb restored its status!"); - } - } THEN { - EXPECT(player->statStages[STAT_DEF] = DEFAULT_STAT_STAGE - 1); - EXPECT(player->statStages[STAT_SPEED] = DEFAULT_STAT_STAGE + 1); - } -} - -SINGLE_BATTLE_TEST("White Herb restores stats after Defiant or Competitive were triggered") +SINGLE_BATTLE_TEST("White Herb has correct interactions with Intimidate triggered Defiant and Competitive") { u16 species; u16 ability; @@ -220,7 +193,6 @@ SINGLE_BATTLE_TEST("White Herb restores stats after Defiant or Competitive were PARAMETRIZE { species = SPECIES_IGGLYBUFF; ability = ABILITY_COMPETITIVE; } PARAMETRIZE { species = SPECIES_MANKEY; ability = ABILITY_DEFIANT; } - KNOWN_FAILING; GIVEN { PLAYER(species) { Ability(ability); Item(ITEM_WHITE_HERB); } OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } @@ -230,16 +202,18 @@ SINGLE_BATTLE_TEST("White Herb restores stats after Defiant or Competitive were ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); ABILITY_POPUP(player, ability); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); - MESSAGE("Wobbuffet's White Herb restored its status!"); + // Defiant activates first, so White Herb doesn't have a chance to trigger. + if (ability == ABILITY_COMPETITIVE) { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Igglybuff's White Herb restored its status!"); + } } THEN { - EXPECT(player->item == ITEM_NONE); - if (species == SPECIES_IGGLYBUFF) - { + if (ability == ABILITY_COMPETITIVE) { + EXPECT(player->item == ITEM_NONE); EXPECT(player->statStages[STAT_ATK] = DEFAULT_STAT_STAGE); EXPECT(player->statStages[STAT_SPATK] = DEFAULT_STAT_STAGE + 2); + } else { + EXPECT(player->statStages[STAT_ATK] = DEFAULT_STAT_STAGE + 1); } - else - EXPECT(player->statStages[STAT_ATK] = DEFAULT_STAT_STAGE + 3); } } diff --git a/test/battle/move_effect/cud_chuw.c b/test/battle/move_effect/cud_chuw.c new file mode 100644 index 0000000000..ba59d355a4 --- /dev/null +++ b/test/battle/move_effect/cud_chuw.c @@ -0,0 +1,49 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Cud Chuw will activate Kee Berry effect again on the next turn") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_KEE_BERRY].holdEffect == HOLD_EFFECT_KEE_BERRY); + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TAUROS_PALDEAN_COMBAT_BREED) { Ability(ABILITY_CUD_CHEW); Item(ITEM_KEE_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_CELEBRATE);} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + ABILITY_POPUP(opponent, ABILITY_CUD_CHEW); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 2); + } +} + +SINGLE_BATTLE_TEST("Cud Chuw will activate Oran Berry effect again on the next turn") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); + ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); + ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TAUROS_PALDEAN_COMBAT_BREED) { MaxHP(60); HP(60); Ability(ABILITY_CUD_CHEW); Item(ITEM_ORAN_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_DRAGON_RAGE); } + TURN { MOVE(player, MOVE_CELEBRATE);} + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_RAGE, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + ABILITY_POPUP(opponent, ABILITY_CUD_CHEW); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + } THEN { + EXPECT_EQ(opponent->hp, 40); + } +} diff --git a/test/battle/move_effect/future_sight.c b/test/battle/move_effect/future_sight.c new file mode 100644 index 0000000000..6a163a736d --- /dev/null +++ b/test/battle/move_effect/future_sight.c @@ -0,0 +1,134 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_SEED_FLARE].power == gMovesInfo[MOVE_FUTURE_SIGHT].power); + ASSUME(gMovesInfo[MOVE_SEED_FLARE].category == gMovesInfo[MOVE_FUTURE_SIGHT].category); +} + +SINGLE_BATTLE_TEST("Future Sight uses Sp. Atk stat of the original user without modifiers") +{ + u32 item; + s16 seedFlareDmg; + s16 futureSightDmg; + + PARAMETRIZE { item = ITEM_TWISTED_SPOON; } + PARAMETRIZE { item = ITEM_PSYCHIC_GEM; } + + GIVEN { + PLAYER(SPECIES_PIKACHU) { Item(item); } + PLAYER(SPECIES_RAICHU) { Item(item); } + OPPONENT(SPECIES_REGICE); + } WHEN { + TURN { MOVE(player, MOVE_SEED_FLARE, WITH_RNG(RNG_SECONDARY_EFFECT, FALSE)); } + TURN { MOVE(player, MOVE_FUTURE_SIGHT); } + TURN { SWITCH(player, 1); } + TURN { } + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SEED_FLARE, player); + HP_BAR(opponent, captureDamage: &seedFlareDmg); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player); + MESSAGE("Foe Regice took the Future Sight attack!"); + HP_BAR(opponent, captureDamage: &futureSightDmg); + } THEN { + EXPECT_EQ(seedFlareDmg, futureSightDmg); + } +} + +SINGLE_BATTLE_TEST("Future Sight is not boosted by Life Orb is original user if not on the field") +{ + s16 seedFlareDmg; + s16 futureSightDmg; + + GIVEN { + PLAYER(SPECIES_PIKACHU); + PLAYER(SPECIES_RAICHU) { Item(ITEM_LIFE_ORB); } + OPPONENT(SPECIES_REGICE); + } WHEN { + TURN { MOVE(player, MOVE_SEED_FLARE, WITH_RNG(RNG_SECONDARY_EFFECT, FALSE)); } + TURN { MOVE(player, MOVE_FUTURE_SIGHT); } + TURN { SWITCH(player, 1); } + TURN { } + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SEED_FLARE, player); + HP_BAR(opponent, captureDamage: &seedFlareDmg); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player); + MESSAGE("Foe Regice took the Future Sight attack!"); + HP_BAR(opponent, captureDamage: &futureSightDmg); + NOT MESSAGE("Raichu was hurt by its Life Orb!"); + } THEN { + EXPECT_EQ(seedFlareDmg, futureSightDmg); + } +} + +SINGLE_BATTLE_TEST("Future Sight receives STAB from party mon") +{ + s16 seedFlareDmg; + s16 futureSightDmg; + + GIVEN { + PLAYER(SPECIES_RALTS); + PLAYER(SPECIES_RAICHU); + OPPONENT(SPECIES_REGICE); + } WHEN { + TURN { MOVE(player, MOVE_SEED_FLARE, WITH_RNG(RNG_SECONDARY_EFFECT, FALSE)); } + TURN { MOVE(player, MOVE_FUTURE_SIGHT); } + TURN { SWITCH(player, 1); } + TURN { } + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SEED_FLARE, player); + HP_BAR(opponent, captureDamage: &seedFlareDmg); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player); + HP_BAR(opponent, captureDamage: &futureSightDmg); + } THEN { + EXPECT_MUL_EQ(seedFlareDmg, Q_4_12(1.5), futureSightDmg); + } +} + +SINGLE_BATTLE_TEST("Future Sight is affected by type effectiveness") +{ + GIVEN { + PLAYER(SPECIES_PIKACHU); + PLAYER(SPECIES_RAICHU); + OPPONENT(SPECIES_HOUNDOOM); + } WHEN { + TURN { MOVE(player, MOVE_SEED_FLARE, WITH_RNG(RNG_SECONDARY_EFFECT, FALSE)); } + TURN { MOVE(player, MOVE_FUTURE_SIGHT); } + TURN { SWITCH(player, 1); } + TURN { } + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SEED_FLARE, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player); + MESSAGE("Foe Houndoom took the Future Sight attack!"); + MESSAGE("It doesn't affect Foe Houndoom…"); + NOT HP_BAR(opponent); + } +} + +SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints before it is about to get hit") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(player, MOVE_FUTURE_SIGHT); } + TURN { MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_MEMENTO); SEND_OUT(opponent, 1); } + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_MEMENTO, opponent); + MESSAGE("Foe Wobbuffet fainted!"); + MESSAGE("2 sent out Wynaut!"); + NOT MESSAGE("Foe Wynaut took the Future Sight attack!"); + } +} diff --git a/test/battle/move_effect/stuff_cheeks.c b/test/battle/move_effect/stuff_cheeks.c index c9a8b325e2..a7a4ab1d34 100644 --- a/test/battle/move_effect/stuff_cheeks.c +++ b/test/battle/move_effect/stuff_cheeks.c @@ -104,3 +104,28 @@ SINGLE_BATTLE_TEST("Stuff Cheeks fails if the user's berry is removed before the } } +SINGLE_BATTLE_TEST("Belch cannot be used if the user has not eaten a berry") +{ + u16 item = 0; + PARAMETRIZE { item = ITEM_NONE; } + PARAMETRIZE { item = ITEM_ORAN_BERRY; } + GIVEN { + PLAYER(SPECIES_SKWOVET) { Item(item); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (item == ITEM_NONE) + TURN { MOVE(player, MOVE_BELCH, allowed: FALSE); MOVE(player, MOVE_CELEBRATE); } + else { + TURN { MOVE(player, MOVE_STUFF_CHEEKS); } + TURN { MOVE(player, MOVE_BELCH); } + } + } SCENE { + if (item == ITEM_NONE) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + } + else { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player); + } + } +} diff --git a/test/pokemon.c b/test/pokemon.c index 7cd2ab5769..1ae655ab3c 100644 --- a/test/pokemon.c +++ b/test/pokemon.c @@ -193,6 +193,22 @@ TEST("givemon [simple]") EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100); } +TEST("givemon [moves]") +{ + ZeroPlayerPartyMons(); + + RUN_OVERWORLD_SCRIPT( + givemon SPECIES_WOBBUFFET, 100, move1=MOVE_TACKLE, move2=MOVE_SPLASH, move3=MOVE_NONE, move4=MOVE_NONE; + ); + + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE1), MOVE_TACKLE); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE2), MOVE_SPLASH); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE3), MOVE_NONE); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE4), MOVE_NONE); +} + TEST("givemon [all]") { ZeroPlayerPartyMons();