diff --git a/.all-contributorsrc b/.all-contributorsrc index c8b79ba30e..c4ed2ea558 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -338,6 +338,16 @@ "contributions": [ "code" ] + }, + { + "login": "tustin2121", + "name": "tustin2121", + "avatar_url": "https://avatars.githubusercontent.com/u/794812?v=4", + "profile": "https://tustin2121.github.io/", + "contributions": [ + "doc", + "code" + ] } ], "contributorsPerLine": 7, diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml index 1ab103d6c7..b48cda404c 100644 --- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml +++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml @@ -43,9 +43,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using? options: - - 1.12.1 (Latest release) + - 1.12.2 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.12.1 - 1.12.0 - 1.11.4 - 1.11.3 diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml index 49bf8a5525..95b00ef2d1 100644 --- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml +++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml @@ -43,9 +43,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using? options: - - 1.12.1 (Latest release) + - 1.12.2 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.12.1 - 1.12.0 - 1.11.4 - 1.11.3 diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml index 0d25f6a96a..d955d09cbc 100644 --- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml +++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml @@ -43,9 +43,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using? options: - - 1.12.1 (Latest release) + - 1.12.2 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.12.1 - 1.12.0 - 1.11.4 - 1.11.3 diff --git a/CREDITS.md b/CREDITS.md index ab5c596248..17809a3c3f 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -58,7 +58,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Zatsu
Zatsu

๐Ÿ’ป poetahto
poetahto

๐Ÿ’ป lordraindance2
lordraindance2

๐Ÿ’ป - Pablo Pena
Pablo Pena

๐Ÿ’ป + Pablo Pena
Pablo Pena

๐Ÿ’ป + tustin2121
tustin2121

๐Ÿ“– ๐Ÿ’ป diff --git a/README.md b/README.md index 6d86c27a2a..4cd0a5f161 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you use **`pokeemerald-expansion`**, please credit **RHH (Rom Hacking Hideout)**. Optionally, include the version number for clarity. ``` -Based off RHH's pokeemerald-expansion 1.12.1 https://github.com/rh-hideout/pokeemerald-expansion/ +Based off RHH's pokeemerald-expansion 1.12.2 https://github.com/rh-hideout/pokeemerald-expansion/ ``` Please consider [crediting all contributors](CREDITS.md) involved in the project! diff --git a/asm/macros/battle_frontier/battle_pyramid.inc b/asm/macros/battle_frontier/battle_pyramid.inc index bb5069f18a..42141d9937 100644 --- a/asm/macros/battle_frontier/battle_pyramid.inc +++ b/asm/macros/battle_frontier/battle_pyramid.inc @@ -69,8 +69,8 @@ .endm @ VAR_RESULT is 1 if player is on a Pyramid floor, 2 if on the Pyramid peak, 0 otherwise - .macro pyramid_inchallenge - setvar VAR_0x8004, BATTLE_PYRAMID_FUNC_IS_IN + .macro pyramid_getlocation + setvar VAR_0x8004, BATTLE_PYRAMID_FUNC_CURRENT_LOCATION special CallBattlePyramidFunction .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 6d36b2b530..23c1e10aa9 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2601,6 +2601,8 @@ BattleScript_EffectMagnetRise:: attackcanceler attackstring ppreduce + jumpifstatus3 BS_ATTACKER, STATUS3_ROOTED, BattleScript_ButItFailed + jumpifstatus3 BS_ATTACKER, STATUS3_SMACKED_DOWN, BattleScript_ButItFailed setuserstatus3 STATUS3_MAGNET_RISE, BattleScript_ButItFailed attackanimation waitanimation @@ -3529,6 +3531,7 @@ BattleScript_PowerHerbActivation: BattleScript_EffectTwoTurnsAttack:: jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_TwoTurnMovesSecondTurn jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING, BattleScript_TwoTurnMovesSecondTurn + jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_ATTACKSTRING_PRINTED, BattleScript_EffectHit @ if it's not the first hit tryfiretwoturnmovewithoutcharging BS_ATTACKER, BattleScript_EffectHit @ e.g. Solar Beam call BattleScript_FirstChargingTurn tryfiretwoturnmoveaftercharging BS_ATTACKER, BattleScript_TwoTurnMovesSecondTurn @ e.g. Electro Shot @@ -5773,6 +5776,7 @@ BattleScript_LeechSeedTurnDrainHealBlock:: BattleScript_LeechSeedTurnDrainRecovery:: call BattleScript_LeechSeedTurnDrain BattleScript_LeechSeedTurnDrainGainHp: + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE healthbarupdate BS_TARGET datahpupdate BS_TARGET printfromtable gLeechSeedStringIds @@ -8189,6 +8193,8 @@ BattleScript_MummyActivates:: return BattleScript_WanderingSpiritActivates:: + saveattacker + savetarget .if B_ABILITY_POP_UP == TRUE copybyte gBattlerAbility, gBattlerTarget sethword sABILITY_OVERWRITE, ABILITY_WANDERING_SPIRIT @@ -8205,6 +8211,8 @@ BattleScript_WanderingSpiritActivates:: jumpiffainted BS_TARGET, TRUE, BattleScript_WanderingSpiritActivatesRet switchinabilities BS_TARGET BattleScript_WanderingSpiritActivatesRet: + restoreattacker + restoretarget return BattleScript_TargetsStatWasMaxedOut:: diff --git a/data/scripts/field_poison.inc b/data/scripts/field_poison.inc index ddda34ebaa..1d89bcfdfd 100644 --- a/data/scripts/field_poison.inc +++ b/data/scripts/field_poison.inc @@ -29,9 +29,9 @@ EventScript_FrontierFieldWhiteOut:: waitbuttonpress pike_inchallenge goto_if_eq VAR_RESULT, TRUE, BattleFrontier_BattlePike_EventScript_Retire - pyramid_inchallenge - goto_if_eq VAR_RESULT, 1, BattleFrontier_BattlePyramid_EventScript_WarpToLobbyLost @ On Pyramid floor - goto_if_eq VAR_RESULT, 2, BattleFrontier_BattlePyramid_EventScript_WarpToLobbyLost @ On Pyramid peak + pyramid_getlocation + goto_if_eq VAR_RESULT, PYRAMID_LOCATION_FLOOR, BattleFrontier_BattlePyramid_EventScript_WarpToLobbyLost + goto_if_eq VAR_RESULT, PYRAMID_LOCATION_TOP, BattleFrontier_BattlePyramid_EventScript_WarpToLobbyLost trainerhill_inchallenge goto_if_eq VAR_RESULT, TRUE, TrainerHill_1F_EventScript_Lost special Script_FadeOutMapMusic diff --git a/data/scripts/obtain_item.inc b/data/scripts/obtain_item.inc index c54b2f8dc5..599961c821 100644 --- a/data/scripts/obtain_item.inc +++ b/data/scripts/obtain_item.inc @@ -133,8 +133,8 @@ EventScript_PickUpItem:: waitfanfare waitmessage bufferitemnameplural STR_VAR_2, VAR_0x8004, VAR_0x8005 - pyramid_inchallenge - goto_if_eq VAR_RESULT, TRUE, EventScript_PutBattlePyramidItemInBag + pyramid_getlocation + goto_if_eq VAR_RESULT, PYRAMID_LOCATION_FLOOR, EventScript_PutBattlePyramidItemInBag msgbox gText_PutItemInPocket, MSGBOX_DEFAULT hideitemdescription return diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 258d078cdb..89767de31b 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -20,6 +20,7 @@ - [Day/Night System FAQ](tutorials/dns.md) - [Changelog](./CHANGELOG.md) - [1.12.x]() + - [Version 1.12.2](changelogs/1.12.x/1.12.2.md) - [Version 1.12.1](changelogs/1.12.x/1.12.1.md) - [Version 1.12.0](changelogs/1.12.x/1.12.0.md) - [1.11.x]() diff --git a/docs/changelogs/1.12.x/1.12.2.md b/docs/changelogs/1.12.x/1.12.2.md new file mode 100644 index 0000000000..9f1b210638 --- /dev/null +++ b/docs/changelogs/1.12.x/1.12.2.md @@ -0,0 +1,164 @@ +```md +## How to update +- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`. +- Once you have your remote set up, run the command `git pull RHH expansion/1.12.1 +`. +``` + + +## ๐Ÿงฌ General ๐Ÿงฌ +### Changed +* Changed trainer tutorial to take into account removed palette compression by @hedara90 in [#7044](https://github.com/rh-hideout/pokeemerald-expansion/pull/7044) +* Update CI to ignore allcontributors commits by @pkmnsnfrn in [#7046](https://github.com/rh-hideout/pokeemerald-expansion/pull/7046) +* add bassforte123 as a contributor for code by @allcontributors[bot] in [#7003](https://github.com/rh-hideout/pokeemerald-expansion/pull/7003) +* add iriv24 as a contributor for code by @allcontributors[bot] in [#7059](https://github.com/rh-hideout/pokeemerald-expansion/pull/7059) +* add Bivurnum as a contributor for code by @allcontributors[bot] in [#7067](https://github.com/rh-hideout/pokeemerald-expansion/pull/7067) +* Fixed CI issue introduced 7046 by @pkmnsnfrn in [#7072](https://github.com/rh-hideout/pokeemerald-expansion/pull/7072) +* Added loop iterator style by @hedara90 in [#7092](https://github.com/rh-hideout/pokeemerald-expansion/pull/7092) +* add Emiliasky as a contributor for test by @allcontributors[bot] in [#7082](https://github.com/rh-hideout/pokeemerald-expansion/pull/7082) +* Update CREDITS.md with correct line placement by @pkmnsnfrn in [#7096](https://github.com/rh-hideout/pokeemerald-expansion/pull/7096) +* Fix typo in INSTALL.md by @hedara90 in [#7116](https://github.com/rh-hideout/pokeemerald-expansion/pull/7116) +* Use RGB values for DEFAULT_LIGHT_COLOR by @hedara90 in [#7133](https://github.com/rh-hideout/pokeemerald-expansion/pull/7133) +* Applied Kasen's documentation improvements by @hedara90 in [#7104](https://github.com/rh-hideout/pokeemerald-expansion/pull/7104) +* add fakuzatsu as a contributor for code by @allcontributors[bot] in [#7136](https://github.com/rh-hideout/pokeemerald-expansion/pull/7136) +* Fixed description of `FORM_CHANGE_WITHDRAW` by @AsparagusEduardo in [#7152](https://github.com/rh-hideout/pokeemerald-expansion/pull/7152) +* add poetahto as a contributor for code by @allcontributors[bot] in [#7162](https://github.com/rh-hideout/pokeemerald-expansion/pull/7162) +* Pret merge (19th of June, 2025) by @Bassoonian in [#7163](https://github.com/rh-hideout/pokeemerald-expansion/pull/7163) +* Update the description of OW_OBJECT_VANILLA_SHADOWS by @pkmnsnfrn in [#7184](https://github.com/rh-hideout/pokeemerald-expansion/pull/7184) +* fix: use BackPickId to calculate player intro ball throw animation palette by @pablopenna in [#7193](https://github.com/rh-hideout/pokeemerald-expansion/pull/7193) +* add pablopenna as a contributor for code by @allcontributors[bot] in [#7202](https://github.com/rh-hideout/pokeemerald-expansion/pull/7202) + +### Fixed +* Added line break between Trainer 1 name and Trainer 2 name in sText_TwoTrainersWantToBattle by @grintoul1 in [#7028](https://github.com/rh-hideout/pokeemerald-expansion/pull/7028) +* Fixed Battle Pyramid mon generation by @hedara90 in [#7146](https://github.com/rh-hideout/pokeemerald-expansion/pull/7146) +* force sGFRomHeader to always be present by @DizzyEggg in [#7186](https://github.com/rh-hideout/pokeemerald-expansion/pull/7186) +* force RHH Rom Header to always be present by @DizzyEggg in [#7187](https://github.com/rh-hideout/pokeemerald-expansion/pull/7187) +* Fixed debug flag menu sound by @AsparagusEduardo in [#7190](https://github.com/rh-hideout/pokeemerald-expansion/pull/7190) +* Fix BtlController_EmitChosenMonReturnValue UB by @DizzyEggg in [#7197](https://github.com/rh-hideout/pokeemerald-expansion/pull/7197) +* Backported Safari catch and add to party fix by @hedara90 in [#7192](https://github.com/rh-hideout/pokeemerald-expansion/pull/7192) +* Fix 01_battle_engine_bugs.yaml by @hedara90 in [#7242](https://github.com/rh-hideout/pokeemerald-expansion/pull/7242) + +## ๐Ÿ—บ๏ธ Overworld ๐Ÿ—บ๏ธ +### Fixed +* Bug fix: clear saved follower NPC door warp when doing dive warp by @Bivurnum in [#7065](https://github.com/rh-hideout/pokeemerald-expansion/pull/7065) +* Fix Contest Painting load palette error by @ExMingYan in [#7077](https://github.com/rh-hideout/pokeemerald-expansion/pull/7077) +* Bug fix: Follower NPC no longer retains bike sprite after white out by @Bivurnum in [#7120](https://github.com/rh-hideout/pokeemerald-expansion/pull/7120) +* Bug fix: clear follower npc surf blob on white out by @Bivurnum in [#7153](https://github.com/rh-hideout/pokeemerald-expansion/pull/7153) + +## ๐Ÿ‰ Pokรฉmon ๐Ÿ‰ +### Changed +* Fixes Rapid Spin description (#7178) by @grintoul1 in [#7181](https://github.com/rh-hideout/pokeemerald-expansion/pull/7181) + +### Fixed +* Fixed text width for a lot of forms in HGSS Dex by @AsparagusEduardo in [#7035](https://github.com/rh-hideout/pokeemerald-expansion/pull/7035) +* Fixes Roamers not saving shininess by @i0brendan0 in [#7185](https://github.com/rh-hideout/pokeemerald-expansion/pull/7185) +* [FIX] Prevent caught Pokรฉmon loss in NPC partner battles by @J2M2 in [#7177](https://github.com/rh-hideout/pokeemerald-expansion/pull/7177) + + + +## โš”๏ธ Battle General โš”๏ธ +### Changed +* Fixes large battle messages being cut off instead of being prompted to advance 2 by @PhallenTree in [#7036](https://github.com/rh-hideout/pokeemerald-expansion/pull/7036) +* Battle controller pret documentation by @AlexOn1ine in [#7029](https://github.com/rh-hideout/pokeemerald-expansion/pull/7029) +* Fix typos and some cleanup (mainly in battle files) by @PhallenTree in [#7107](https://github.com/rh-hideout/pokeemerald-expansion/pull/7107) + +### Fixed +* Fixes multi battle party re-order by @AlexOn1ine in [#7042](https://github.com/rh-hideout/pokeemerald-expansion/pull/7042) +* Fixes Aura Wheel + Normalize and Hunger Switch while Transformed/Terastallized by @PhallenTree in [#7061](https://github.com/rh-hideout/pokeemerald-expansion/pull/7061) +* Fixes speed calculation order by @AlexOn1ine in [#7064](https://github.com/rh-hideout/pokeemerald-expansion/pull/7064) +* Bug fix for Grassy Terrain incorrectly healing non-grounded Pokemon by @LinathanZel in [#7058](https://github.com/rh-hideout/pokeemerald-expansion/pull/7058) +* Fixes Wandering Spirit copied ability activation on fainted mon by @AlexOn1ine in [#7066](https://github.com/rh-hideout/pokeemerald-expansion/pull/7066) +* Chloroblast fix by @LinathanZel in [#7008](https://github.com/rh-hideout/pokeemerald-expansion/pull/7008) + + + * Chloroblast causing recoil damage even if the move fails to connect by @LinathanZel in #7007 + + +* [DRAFT] Fix Normalize not boosting Normal type moves if they were already Normal type by @i0brendan0 in [#7060](https://github.com/rh-hideout/pokeemerald-expansion/pull/7060) +* Fixes freeze during a 1v2 double battle by @AlexOn1ine in [#7075](https://github.com/rh-hideout/pokeemerald-expansion/pull/7075) +* Fixes Pursuit potentially causing both battlers to switch into the same mon by @PhallenTree in [#7084](https://github.com/rh-hideout/pokeemerald-expansion/pull/7084) +* Fixed potential mismatch between players and battlers in tests by @AsparagusEduardo in [#7101](https://github.com/rh-hideout/pokeemerald-expansion/pull/7101) +* Fixes Ally Switch in multi battles by @AlexOn1ine in [#7109](https://github.com/rh-hideout/pokeemerald-expansion/pull/7109) +* Add missing flag for Berserk Gene by @AlexOn1ine in [#7151](https://github.com/rh-hideout/pokeemerald-expansion/pull/7151) +* Fixes Neutralizing Gas leaving the field activating unsuppressable abilities again by @PhallenTree in [#7170](https://github.com/rh-hideout/pokeemerald-expansion/pull/7170) +* Fixes Enigma, Kee and Maranga Berry activation timing by @AlexOn1ine in [#7171](https://github.com/rh-hideout/pokeemerald-expansion/pull/7171) +* Fixes wrong Future Sight indexing by @AlexOn1ine in [#7198](https://github.com/rh-hideout/pokeemerald-expansion/pull/7198) +* Fixes OOB for Teatime and Flower Shield by @AlexOn1ine in [#7214](https://github.com/rh-hideout/pokeemerald-expansion/pull/7214) +* Fixes wrong assignment in TrySymbiosis by @AlexOn1ine in [#7221](https://github.com/rh-hideout/pokeemerald-expansion/pull/7221) +* Adds missing healBlockTimer for Baton Pass by @AlexOn1ine in [#7220](https://github.com/rh-hideout/pokeemerald-expansion/pull/7220) +* Jaboca berry triggers instead of being stolen by bug bite by @ghoulslash in [#7237](https://github.com/rh-hideout/pokeemerald-expansion/pull/7237) +* Fixes Scald defrosting target while asleep by @AlexOn1ine in [#7233](https://github.com/rh-hideout/pokeemerald-expansion/pull/7233) +* Fixes Emergency Exit sometimes causing an unrelated battler to become invisible by @PhallenTree in [#7241](https://github.com/rh-hideout/pokeemerald-expansion/pull/7241) + +## ๐Ÿคน Moves ๐Ÿคน +### Changed +* Fix ScaryFace anim for Bitter Malice by @TLM-PsIQ in [#6476](https://github.com/rh-hideout/pokeemerald-expansion/pull/6476) + + + +### Fixed +* Fix savage spin out spider web template by @ghoulslash in [#7137](https://github.com/rh-hideout/pokeemerald-expansion/pull/7137) + +## ๐ŸŽญ Abilities ๐ŸŽญ +### Changed +* Flush textbox for Truant Popup by @ghoulslash in [#7252](https://github.com/rh-hideout/pokeemerald-expansion/pull/7252) + +## ๐Ÿงถ Items ๐Ÿงถ +### Fixed +* Fix sell price display by @cawtds in [#7123](https://github.com/rh-hideout/pokeemerald-expansion/pull/7123) + +## ๐Ÿค– Battle AI ๐Ÿค– +### Fixed +* Added AI_FLAG_PP_STALL_PREVENTION to AI_FLAG_SMART_TRAINER by @AlexOn1ine in [#7112](https://github.com/rh-hideout/pokeemerald-expansion/pull/7112) +* Fix incorrect function parameters used in AI damage calc by @Pawkkie in [#7130](https://github.com/rh-hideout/pokeemerald-expansion/pull/7130) + +## ๐Ÿงน Other Cleanup ๐Ÿงน +* Update CI to ignore allcontributors commits by @pkmnsnfrn in [#7046](https://github.com/rh-hideout/pokeemerald-expansion/pull/7046) +* Update CREDITS.md with correct line placement by @pkmnsnfrn in [#7096](https://github.com/rh-hideout/pokeemerald-expansion/pull/7096) +* Fix typos and some cleanup (mainly in battle files) by @PhallenTree in [#7107](https://github.com/rh-hideout/pokeemerald-expansion/pull/7107) +* Fix typo in INSTALL.md by @hedara90 in [#7116](https://github.com/rh-hideout/pokeemerald-expansion/pull/7116) +* Fixed description of `FORM_CHANGE_WITHDRAW` by @AsparagusEduardo in [#7152](https://github.com/rh-hideout/pokeemerald-expansion/pull/7152) +* Spruce up `FEATURES.md` by @AsparagusEduardo in [#7159](https://github.com/rh-hideout/pokeemerald-expansion/pull/7159) +* Fixes Rapid Spin description (#7178) by @grintoul1 in [#7181](https://github.com/rh-hideout/pokeemerald-expansion/pull/7181) + +## ๐Ÿงช Test Runner ๐Ÿงช +### Changed +* Wrote some missing tests by @AsparagusEduardo in [#7094](https://github.com/rh-hideout/pokeemerald-expansion/pull/7094) +* Fixed KNOWN_FAILING Tera test by @AsparagusEduardo in [#6949](https://github.com/rh-hideout/pokeemerald-expansion/pull/6949) +* Add some tests by @ghoulslash in [#7234](https://github.com/rh-hideout/pokeemerald-expansion/pull/7234) +* Added tests for Toxic Thread by @hedara90 in [#7244](https://github.com/rh-hideout/pokeemerald-expansion/pull/7244) + +### Fixed +* Test runner fixes by @hedara90 in [#7100](https://github.com/rh-hideout/pokeemerald-expansion/pull/7100) +* Fixed Aura Wheel `KNOWN_FAILING` test by @AsparagusEduardo in [#7135](https://github.com/rh-hideout/pokeemerald-expansion/pull/7135) +* Fix AI party count calc being maintained between tests by @AsparagusEduardo in [#7200](https://github.com/rh-hideout/pokeemerald-expansion/pull/7200) +* Fix tests failing with `B_FRIENDSHIP_BOOST` being `TRUE` by @AsparagusEduardo in [#7194](https://github.com/rh-hideout/pokeemerald-expansion/pull/7194) +* Jaboca berry triggers instead of being stolen by bug bite by @ghoulslash in [#7237](https://github.com/rh-hideout/pokeemerald-expansion/pull/7237) + +## ๐Ÿ“š Documentation ๐Ÿ“š +* Changed trainer tutorial to take into account removed palette compression by @hedara90 in [#7044](https://github.com/rh-hideout/pokeemerald-expansion/pull/7044) +* Battle controller pret documentation by @AlexOn1ine in [#7029](https://github.com/rh-hideout/pokeemerald-expansion/pull/7029) +* Added loop iterator style by @hedara90 in [#7092](https://github.com/rh-hideout/pokeemerald-expansion/pull/7092) +* Use RGB values for DEFAULT_LIGHT_COLOR by @hedara90 in [#7133](https://github.com/rh-hideout/pokeemerald-expansion/pull/7133) +* Applied Kasen's documentation improvements by @hedara90 in [#7104](https://github.com/rh-hideout/pokeemerald-expansion/pull/7104) +* Spruce up `FEATURES.md` by @AsparagusEduardo in [#7159](https://github.com/rh-hideout/pokeemerald-expansion/pull/7159) +* Update the description of OW_OBJECT_VANILLA_SHADOWS by @pkmnsnfrn in [#7184](https://github.com/rh-hideout/pokeemerald-expansion/pull/7184) + +## ๐Ÿ“ฆ Branch Synchronisation ๐Ÿ“ฆ +### pret +* 24th of June, 2025 in [#7206](https://github.com/rh-hideout/pokeemerald-expansion/pull/7206) + * Move gTradePlatform_Tilemap to header and change to u32 by @DizzyEggg in [pret#2088](https://github.com/pret/pokeemerald/pull/2088) + * Fix wrong keep temps files directory in makefile by @DizzyEggg in [pret#2156](https://github.com/pret/pokeemerald/pull/2156) + * Fix collision comparison in PlayerNotOnBikeMoving by @GriffinRichards in [pret#2104](https://github.com/pret/pokeemerald/pull/2104) + * Match graphics declarations with externs in graphics.h by @DizzyEggg in [pret#2089](https://github.com/pret/pokeemerald/pull/2089) + +## New Contributors +* @TLM-PsIQ made their first contribution in [#6476](https://github.com/rh-hideout/pokeemerald-expansion/pull/6476) +* @pablopenna made their first contribution in [#7193](https://github.com/rh-hideout/pokeemerald-expansion/pull/7193) +* @J2M2 made their first contribution in [#7177](https://github.com/rh-hideout/pokeemerald-expansion/pull/7177) + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.12.0...expansion/1.12.1 + + + + diff --git a/docs/tutorials/how_to_new_pokemon.md b/docs/tutorials/how_to_new_pokemon.md index de2d41d57c..37c0d28ae3 100644 --- a/docs/tutorials/how_to_new_pokemon.md +++ b/docs/tutorials/how_to_new_pokemon.md @@ -524,9 +524,9 @@ Edit [src/data/graphics/pokemon.h](https://github.com/rh-hideout/pokeemerald-exp ```diff #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 u16 gMonPalette_Pecharunt[] = INCBIN_U16("graphics/pokemon/pecharunt/normal.gbapal"); 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 u16 gMonShinyPalette_Pecharunt[] = INCBIN_U16("graphics/pokemon/pecharunt/shiny.gbapal"); 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"); @@ -534,20 +534,20 @@ Edit [src/data/graphics/pokemon.h](https://github.com/rh-hideout/pokeemerald-exp #if OW_POKEMON_OBJECT_EVENTS const u32 gObjectEventPic_Pecharunt[] = INCBIN_COMP("graphics/pokemon/pecharunt/overworld.4bpp"); #if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE - const u32 gOverworldPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/overworld_normal.gbapal.lz"); - const u32 gShinyOverworldPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/overworld_shiny.gbapal.lz"); + const u16 gOverworldPalette_Pecharunt[] = INCBIN_U16("graphics/pokemon/pecharunt/overworld_normal.gbapal"); + const u16 gShinyOverworldPalette_Pecharunt[] = INCBIN_U16("graphics/pokemon/pecharunt/overworld_shiny.gbapal"); #endif //OW_PKMN_OBJECTS_SHARE_PALETTES #endif //OW_POKEMON_OBJECT_EVENTS #endif //P_FAMILY_PECHARUNT const u32 gMonFrontPic_Egg[] = INCBIN_U32("graphics/pokemon/egg/anim_front.4bpp.lz"); - const u32 gMonPalette_Egg[] = INCBIN_U32("graphics/pokemon/egg/normal.gbapal.lz"); + const u16 gMonPalette_Egg[] = INCBIN_U16("graphics/pokemon/egg/normal.gbapal"); const u8 gMonIcon_Egg[] = INCBIN_U8("graphics/pokemon/egg/icon.4bpp"); + const u32 gMonFrontPic_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/anim_front.4bpp.lz"); + const u32 gMonBackPic_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/back.4bpp.lz"); -+ const u32 gMonPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/normal.gbapal.lz"); -+ const u32 gMonShinyPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/shiny.gbapal.lz"); ++ const u16 gMonPalette_Mewthree[] = INCBIN_U16("graphics/pokemon/mewthree/normal.gbapal"); ++ const u16 gMonShinyPalette_Mewthree[] = INCBIN_U16("graphics/pokemon/mewthree/shiny.gbapal"); + const u8 gMonIcon_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/icon.4bpp"); + const u8 gMonFootprint_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/footprint.1bpp"); ``` diff --git a/include/battle.h b/include/battle.h index d59432e6c1..79cc591980 100644 --- a/include/battle.h +++ b/include/battle.h @@ -666,7 +666,8 @@ struct BattleStruct u8 anyMonHasTransformed:1; // Only used in battle_tv.c u8 multipleSwitchInState:2; u8 multipleSwitchInCursor:3; - u8 padding1:2; + u8 sleepClauseNotBlocked:1; + u8 padding1:1; u8 multipleSwitchInSortedBattlers[MAX_BATTLERS_COUNT]; void (*savedCallback)(void); u16 usedHeldItems[PARTY_SIZE][NUM_BATTLE_SIDES]; // For each party member and side. For harvest, recycle diff --git a/include/battle_pyramid.h b/include/battle_pyramid.h index ec80fdeed3..d55d8d2e93 100644 --- a/include/battle_pyramid.h +++ b/include/battle_pyramid.h @@ -1,13 +1,15 @@ #ifndef GUARD_BATTLE_PYRAMID_H #define GUARD_BATTLE_PYRAMID_H +#include "constants/battle_pyramid.h" + void CallBattlePyramidFunction(void); u16 LocalIdToPyramidTrainerId(u8 localId); bool8 GetBattlePyramidTrainerFlag(u8 eventId); void MarkApproachingPyramidTrainersAsBattled(void); void GenerateBattlePyramidWildMon(void); u8 GetPyramidRunMultiplier(void); -u8 InBattlePyramid(void); +u8 CurrentBattlePyramidLocation(void); bool8 InBattlePyramid_(void); void PausePyramidChallenge(void); void SoftResetInBattlePyramid(void); diff --git a/include/config/test.h b/include/config/test.h index 6122d14aa1..9e880d57c7 100644 --- a/include/config/test.h +++ b/include/config/test.h @@ -1132,6 +1132,10 @@ // Vars #undef B_VAR_DIFFICULTY #define B_VAR_DIFFICULTY TESTING_VAR_DIFFICULTY +#undef B_VAR_STARTING_STATUS +#define B_VAR_STARTING_STATUS TESTING_VAR_STARTING_STATUS +#undef B_VAR_STARTING_STATUS_TIMER +#define B_VAR_STARTING_STATUS_TIMER TESTING_VAR_STARTING_STATUS_TIMER // Flags #undef B_FLAG_SLEEP_CLAUSE diff --git a/include/constants/battle_pyramid.h b/include/constants/battle_pyramid.h index ac80a2d7d3..08fa695cf2 100644 --- a/include/constants/battle_pyramid.h +++ b/include/constants/battle_pyramid.h @@ -43,7 +43,7 @@ #define BATTLE_PYRAMID_FUNC_SET_TRAINERS 9 #define BATTLE_PYRAMID_FUNC_SHOW_HINT_TEXT 10 #define BATTLE_PYRAMID_FUNC_UPDATE_STREAK 11 // unused -#define BATTLE_PYRAMID_FUNC_IS_IN 12 +#define BATTLE_PYRAMID_FUNC_CURRENT_LOCATION 12 #define BATTLE_PYRAMID_FUNC_UPDATE_LIGHT 13 #define BATTLE_PYRAMID_FUNC_CLEAR_HELD_ITEMS 14 #define BATTLE_PYRAMID_FUNC_SET_FLOOR_PALETTE 15 @@ -62,4 +62,8 @@ #define PYRAMID_LIGHT_SET_RADIUS 0 #define PYRAMID_LIGHT_INCR_RADIUS 1 +#define PYRAMID_LOCATION_NONE 0 // Not in the Pyramid +#define PYRAMID_LOCATION_FLOOR 1 +#define PYRAMID_LOCATION_TOP 2 + #endif // GUARD_CONSTANTS_BATTLE_PYRAMID_H diff --git a/include/constants/expansion.h b/include/constants/expansion.h index 11822f8510..cdfaa6228e 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -1,10 +1,10 @@ #ifndef GUARD_CONSTANTS_EXPANSION_H #define GUARD_CONSTANTS_EXPANSION_H -// Last version: 1.12.1 +// Last version: 1.12.2 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 12 -#define EXPANSION_VERSION_PATCH 2 +#define EXPANSION_VERSION_PATCH 3 // FALSE if this this version of Expansion is not a tagged commit, i.e. // it contains unreleased changes. diff --git a/include/constants/vars.h b/include/constants/vars.h index aac52dec0e..a12c2ff3a5 100644 --- a/include/constants/vars.h +++ b/include/constants/vars.h @@ -325,15 +325,15 @@ #define VAR_TEMP_TRANSFERRED_SPECIES VAR_TEMP_1 #if TESTING -#define TESTING_VARS_START 0x9000 -#define TESTING_VAR_DIFFICULTY (TESTING_VARS_START + 0x0) -#define TESTING_VAR_UNUSED_1 (TESTING_VARS_START + 0x1) -#define TESTING_VAR_UNUSED_2 (TESTING_VARS_START + 0x2) -#define TESTING_VAR_UNUSED_3 (TESTING_VARS_START + 0x3) -#define TESTING_VAR_UNUSED_4 (TESTING_VARS_START + 0x4) -#define TESTING_VAR_UNUSED_5 (TESTING_VARS_START + 0x5) -#define TESTING_VAR_UNUSED_6 (TESTING_VARS_START + 0x6) -#define TESTING_VAR_UNUSED_7 (TESTING_VARS_START + 0x7) +#define TESTING_VARS_START 0x9000 +#define TESTING_VAR_DIFFICULTY (TESTING_VARS_START + 0x0) +#define TESTING_VAR_STARTING_STATUS (TESTING_VARS_START + 0x1) +#define TESTING_VAR_STARTING_STATUS_TIMER (TESTING_VARS_START + 0x2) +#define TESTING_VAR_UNUSED_3 (TESTING_VARS_START + 0x3) +#define TESTING_VAR_UNUSED_4 (TESTING_VARS_START + 0x4) +#define TESTING_VAR_UNUSED_5 (TESTING_VARS_START + 0x5) +#define TESTING_VAR_UNUSED_6 (TESTING_VARS_START + 0x6) +#define TESTING_VAR_UNUSED_7 (TESTING_VARS_START + 0x7) #endif // TESTING #endif // GUARD_CONSTANTS_VARS_H diff --git a/include/gba/syscall.h b/include/gba/syscall.h index c922084d5f..50f5781988 100644 --- a/include/gba/syscall.h +++ b/include/gba/syscall.h @@ -61,9 +61,9 @@ void LZ77UnCompWram(const u32 *src, void *dest); void LZ77UnCompVram(const u32 *src, void *dest); -void RLUnCompWram(const void *src, void *dest); +void RLUnCompWram(const u32 *src, void *dest); -void RLUnCompVram(const void *src, void *dest); +void RLUnCompVram(const u32 *src, void *dest); int MultiBoot(struct MultiBootParam *mp); diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 5f2a84017f..37fb95e3fb 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -7,19 +7,36 @@ #define MAPGRID_METATILE_ID_MASK 0x03FF // Bits 0-9 #define MAPGRID_COLLISION_MASK 0x0C00 // Bits 10-11 #define MAPGRID_ELEVATION_MASK 0xF000 // Bits 12-15 +#define MAPGRID_METATILE_ID_SHIFT 0 #define MAPGRID_COLLISION_SHIFT 10 #define MAPGRID_ELEVATION_SHIFT 12 +#define PACK_METATILE(metatileId) PACK(metatileId, MAPGRID_METATILE_ID_SHIFT, MAPGRID_METATILE_ID_MASK) +#define PACK_COLLISION(collision) PACK(collision, MAPGRID_COLLISION_SHIFT, MAPGRID_COLLISION_MASK) +#define PACK_ELEVATION(elevation) PACK(elevation, MAPGRID_ELEVATION_SHIFT, MAPGRID_ELEVATION_MASK) +#define UNPACK_METATILE(data) UNPACK(data, MAPGRID_METATILE_ID_SHIFT, MAPGRID_METATILE_ID_MASK) +#define UNPACK_COLLISION(data) UNPACK(data, MAPGRID_COLLISION_SHIFT, MAPGRID_COLLISION_MASK) +#define UNPACK_ELEVATION(data) UNPACK(data, MAPGRID_ELEVATION_SHIFT, MAPGRID_ELEVATION_MASK) + // An undefined map grid block has all metatile id bits set and nothing else #define MAPGRID_UNDEFINED MAPGRID_METATILE_ID_MASK +// When setting impassability manually GF sets all the collision bits +#define MAPGRID_IMPASSABLE MAPGRID_COLLISION_MASK + // Masks/shifts for metatile attributes // Metatile attributes consist of an 8 bit behavior value, 4 unused bits, and a 4 bit layer type value // This is the data stored in each data/tilesets/*/*/metatile_attributes.bin file #define METATILE_ATTR_BEHAVIOR_MASK 0x00FF // Bits 0-7 #define METATILE_ATTR_LAYER_MASK 0xF000 // Bits 12-15 +#define METATILE_ATTR_BEHAVIOR_SHIFT 0 #define METATILE_ATTR_LAYER_SHIFT 12 +#define PACK_BEHAVIOR(behavior) PACK(behavior, METATILE_ATTR_BEHAVIOR_SHIFT, METATILE_ATTR_BEHAVIOR_MASK) +#define PACK_LAYER_TYPE(layerType) PACK(layerType, METATILE_ATTR_LAYER_SHIFT, METATILE_ATTR_LAYER_MASK) +#define UNPACK_BEHAVIOR(data) UNPACK(data, METATILE_ATTR_BEHAVIOR_SHIFT, METATILE_ATTR_BEHAVIOR_MASK) +#define UNPACK_LAYER_TYPE(data) UNPACK(data, METATILE_ATTR_LAYER_SHIFT, METATILE_ATTR_LAYER_MASK) + enum { METATILE_LAYER_TYPE_NORMAL, // Metatile uses middle and top bg layers METATILE_LAYER_TYPE_COVERED, // Metatile uses bottom and middle bg layers diff --git a/include/global.h b/include/global.h index b58ef3518b..f4c944b64f 100644 --- a/include/global.h +++ b/include/global.h @@ -107,6 +107,9 @@ #define T2_READ_32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) #define T2_READ_PTR(ptr) (void *) T2_READ_32(ptr) +#define PACK(data, shift, mask) ( ((data) << (shift)) & (mask) ) +#define UNPACK(data, shift, mask) ( ((data) & (mask)) >> (shift) ) + // Macros for checking the joypad #define TEST_BUTTON(field, button) ((field) & (button)) #define JOY_NEW(button) TEST_BUTTON(gMain.newKeys, button) diff --git a/include/metaprogram.h b/include/metaprogram.h index be62b2f9e5..9afc369d07 100644 --- a/include/metaprogram.h +++ b/include/metaprogram.h @@ -44,12 +44,12 @@ #define EXCEPT_3(a, ...) __VA_OPT__(EXCEPT_2(__VA_ARGS__)) #define EXCEPT_4(a, ...) __VA_OPT__(EXCEPT_3(__VA_ARGS__)) -/* 'UNPACK (x, y, z)' expands to 'x, y, z'. +/* 'UNPACK_META (x, y, z)' expands to 'x, y, z'. * Useful for passing arguments which may contain commas into a macro. */ -#define UNPACK(...) __VA_ARGS__ +#define UNPACK_META(...) __VA_ARGS__ /* Expands to 'macro(...args, ...)'. */ -#define INVOKE_WITH(macro, args, ...) INVOKE_WITH_(macro, UNPACK args __VA_OPT__(, __VA_ARGS__)) +#define INVOKE_WITH(macro, args, ...) INVOKE_WITH_(macro, UNPACK_META args __VA_OPT__(, __VA_ARGS__)) #define INVOKE_WITH_(macro, ...) macro(__VA_ARGS__) /* Recursive macros. diff --git a/src/battle_bg.c b/src/battle_bg.c index a0df9017c7..887cb8e161 100644 --- a/src/battle_bg.c +++ b/src/battle_bg.c @@ -1028,7 +1028,7 @@ void InitLinkBattleVsScreen(u8 taskId) case 0: if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - for (i = 0; i < MAX_BATTLERS_COUNT; i++) + for (i = 0; i < MAX_LINK_PLAYERS; i++) { name = gLinkPlayers[i].name; linkPlayer = &gLinkPlayers[i]; diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index f6fae5ae57..a139c9bfc3 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -623,6 +623,7 @@ static void OpponentHandleChoosePokemon(u32 battler) { s32 chosenMonId; s32 pokemonInBattle = 1; + enum SwitchType switchType = SWITCH_AFTER_KO; // Choosing Revival Blessing target if ((gBattleResources->bufferA[battler][1] & 0xF) == PARTY_ACTION_CHOOSE_FAINTED_MON) @@ -632,7 +633,9 @@ static void OpponentHandleChoosePokemon(u32 battler) // Switching out else if (gBattleStruct->AI_monToSwitchIntoId[battler] == PARTY_SIZE) { - chosenMonId = GetMostSuitableMonToSwitchInto(battler, SWITCH_AFTER_KO); + if (IsSwitchOutEffect(GetMoveEffect(gCurrentMove)) || gAiLogicData->ejectButtonSwitch || gAiLogicData->ejectPackSwitch) + switchType = SWITCH_MID_BATTLE; + chosenMonId = GetMostSuitableMonToSwitchInto(battler, switchType); if (chosenMonId == PARTY_SIZE) { s32 battler1, battler2, firstId, lastId; diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 269d1ce3fe..c3b159e0ef 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -897,7 +897,10 @@ void HandleInputChooseMove(u32 battler) } else if (JOY_NEW(START_BUTTON)) { - if (gBattleStruct->gimmick.usableGimmick[battler] != GIMMICK_NONE && !HasTrainerUsedGimmick(battler, gBattleStruct->gimmick.usableGimmick[battler])) + if (gBattleStruct->gimmick.usableGimmick[battler] != GIMMICK_NONE + && !HasTrainerUsedGimmick(battler, gBattleStruct->gimmick.usableGimmick[battler]) + && !(gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE + && GetUsableZMove(battler, moveInfo->moves[gMoveSelectionCursor[battler]]) == MOVE_NONE)) { gBattleStruct->gimmick.playerSelect ^= 1; ReloadMoveNames(battler); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index dfd7138bcb..9bee760800 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -294,7 +294,7 @@ static void InitSinglePlayerBtlControllers(void) { u8 multiplayerId; - for (multiplayerId = gRecordedBattleMultiplayerId, i = 0; i < MAX_BATTLERS_COUNT; i++) + for (multiplayerId = gRecordedBattleMultiplayerId, i = 0; i < MAX_LINK_PLAYERS; i++) { switch (gLinkPlayers[i].id) { @@ -536,7 +536,7 @@ static void InitLinkBtlControllers(void) if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) gBattleMainFunc = BeginBattleIntro; - for (i = 0; i < MAX_BATTLERS_COUNT; i++) + for (i = 0; i < MAX_LINK_PLAYERS; i++) { switch (gLinkPlayers[i].id) { diff --git a/src/battle_pyramid.c b/src/battle_pyramid.c index 6e56f4867b..e40fba5c07 100644 --- a/src/battle_pyramid.c +++ b/src/battle_pyramid.c @@ -81,7 +81,7 @@ static void HidePyramidItem(void); static void SetPyramidFacilityTrainers(void); static void ShowPostBattleHintText(void); static void UpdatePyramidWinStreak(void); -static void GetInBattlePyramid(void); +static void GetCurrentBattlePyramidLocation(void); static void UpdatePyramidLightRadius(void); static void ClearPyramidPartyHeldItems(void); static void SetPyramidFloorPalette(void); @@ -805,7 +805,7 @@ static void (*const sBattlePyramidFunctions[])(void) = [BATTLE_PYRAMID_FUNC_SET_TRAINERS] = SetPyramidFacilityTrainers, [BATTLE_PYRAMID_FUNC_SHOW_HINT_TEXT] = ShowPostBattleHintText, [BATTLE_PYRAMID_FUNC_UPDATE_STREAK] = UpdatePyramidWinStreak, - [BATTLE_PYRAMID_FUNC_IS_IN] = GetInBattlePyramid, + [BATTLE_PYRAMID_FUNC_CURRENT_LOCATION] = GetCurrentBattlePyramidLocation, [BATTLE_PYRAMID_FUNC_UPDATE_LIGHT] = UpdatePyramidLightRadius, [BATTLE_PYRAMID_FUNC_CLEAR_HELD_ITEMS] = ClearPyramidPartyHeldItems, [BATTLE_PYRAMID_FUNC_SET_FLOOR_PALETTE] = SetPyramidFloorPalette, @@ -1127,9 +1127,9 @@ static void UpdatePyramidWinStreak(void) gSaveBlock2Ptr->frontier.pyramidRecordStreaks[lvlMode] = gSaveBlock2Ptr->frontier.pyramidWinStreaks[lvlMode]; } -static void GetInBattlePyramid(void) +static void GetCurrentBattlePyramidLocation(void) { - gSpecialVar_Result = InBattlePyramid(); + gSpecialVar_Result = CurrentBattlePyramidLocation(); } static void UpdatePyramidLightRadius(void) @@ -1643,14 +1643,14 @@ u8 GetPyramidRunMultiplier(void) return sPyramidFloorTemplates[id].runMultiplier; } -u8 InBattlePyramid(void) +u8 CurrentBattlePyramidLocation(void) { if (gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR) - return 1; + return PYRAMID_LOCATION_FLOOR; else if (gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP) - return 2; + return PYRAMID_LOCATION_TOP; else - return FALSE; + return PYRAMID_LOCATION_NONE; } bool8 InBattlePyramid_(void) @@ -1661,7 +1661,7 @@ bool8 InBattlePyramid_(void) void PausePyramidChallenge(void) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { RestorePyramidPlayerParty(); gSaveBlock2Ptr->frontier.challengeStatus = CHALLENGE_STATUS_PAUSED; @@ -1672,7 +1672,7 @@ void PausePyramidChallenge(void) void SoftResetInBattlePyramid(void) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) DoSoftReset(); } @@ -1781,6 +1781,7 @@ void GenerateBattlePyramidFloorLayout(u16 *backupMapData, bool8 setPlayerPositio gSaveBlock1Ptr->pos.x = (mapLayout->width * (i % PYRAMID_FLOOR_SQUARES_WIDE)) + x; gSaveBlock1Ptr->pos.y = (mapLayout->height * (i / PYRAMID_FLOOR_SQUARES_WIDE)) + y; } + // Copy the elevation and collision, but overwrite the metatile ID map[x] = (layoutMap[x] & (MAPGRID_ELEVATION_MASK | MAPGRID_COLLISION_MASK)) | METATILE_BattlePyramid_Floor; } else diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index fcd325305c..d749d450d7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2177,7 +2177,7 @@ static void Cmd_adjustdamage(void) u8 param; u32 battlerDef; u32 rand = Random() % 100; - u32 affectionScore = GetBattlerAffectionHearts(gBattlerTarget); + u32 affectionScore; u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); enum BattleMoveEffects moveEffect = GetMoveEffect(gCurrentMove); bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(gCurrentMove); @@ -2221,6 +2221,7 @@ static void Cmd_adjustdamage(void) holdEffect = GetBattlerHoldEffect(battlerDef, TRUE); param = GetBattlerHoldEffectParam(battlerDef); + affectionScore = GetBattlerAffectionHearts(battlerDef); gPotentialItemEffectBattler = battlerDef; @@ -6542,7 +6543,8 @@ static void Cmd_moveend(void) } break; case PROTECT_BANEFUL_BUNKER: - if (!IsProtectivePadsProtected(gBattlerAttacker, GetBattlerHoldEffect(gBattlerAttacker, TRUE))) + if (!IsProtectivePadsProtected(gBattlerAttacker, GetBattlerHoldEffect(gBattlerAttacker, TRUE)) + && CanBePoisoned(gBattlerTarget, gBattlerAttacker, gLastUsedAbility, GetBattlerAbility(gBattlerAttacker))) { gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE; gBattleScripting.moveEffect = MOVE_EFFECT_POISON | MOVE_EFFECT_AFFECTS_USER; @@ -6553,7 +6555,8 @@ static void Cmd_moveend(void) } break; case PROTECT_BURNING_BULWARK: - if (!IsProtectivePadsProtected(gBattlerAttacker, GetBattlerHoldEffect(gBattlerAttacker, TRUE))) + if (!IsProtectivePadsProtected(gBattlerAttacker, GetBattlerHoldEffect(gBattlerAttacker, TRUE)) + && CanBeBurned(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))) { gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE; gBattleScripting.moveEffect = MOVE_EFFECT_BURN | MOVE_EFFECT_AFFECTS_USER; @@ -6727,6 +6730,7 @@ static void Cmd_moveend(void) { BestowItem(BATTLE_PARTNER(i), i); gLastUsedAbility = gBattleMons[BATTLE_PARTNER(i)].ability; + gEffectBattler = i; gBattleScripting.battler = gBattlerAbility = BATTLE_PARTNER(i); gBattlerAttacker = i; BattleScriptPushCursor(); @@ -6825,6 +6829,7 @@ static void Cmd_moveend(void) UpdateStallMons(); if ((gBattleStruct->moveResultFlags[gBattlerTarget] & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)) || (gBattleMons[gBattlerAttacker].status2 & (STATUS2_FLINCHED)) + || gBattleStruct->pledgeMove == TRUE // Is the battler that uses the first Pledge move in the combo || gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility) gBattleStruct->battlerState[gBattlerAttacker].stompingTantrumTimer = 2; @@ -9230,6 +9235,7 @@ static bool32 TrySymbiosis(u32 battler, u32 itemId, bool32 moveEnd) { BestowItem(BATTLE_PARTNER(battler), battler); gLastUsedAbility = gBattleMons[BATTLE_PARTNER(battler)].ability; + gEffectBattler = battler; gBattleScripting.battler = gBattlerAbility = BATTLE_PARTNER(battler); if (moveEnd) BattleScriptPushCursor(); @@ -12189,7 +12195,7 @@ void BS_RemoveStockpileCounters(void) { NATIVE_ARGS(); - if (GetMoveEffect(gCurrentMove) == EFFECT_SWALLOW + if (GetMoveEffect(gCurrentMove) == EFFECT_SPIT_UP && gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_1ST_HIT && IsBattlerAlive(gBattlerTarget)) { @@ -15458,7 +15464,7 @@ static void Cmd_pickup(void) if (!InBattlePike()) // No items in Battle Pike. { - bool32 isInPyramid = InBattlePyramid_(); + bool32 isInPyramid = CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE; for (i = 0; i < PARTY_SIZE; i++) { species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG); @@ -16991,7 +16997,7 @@ static void TryUpdateRoundTurnOrder(void) } // update turn order for round users - for (i = 0; roundUsers[i] != 0xFF && i < 3; i++) + for (i = 0; i < 3 && roundUsers[i] != 0xFF; i++) { gBattlerByTurnOrder[currRounder] = roundUsers[i]; gProtectStructs[roundUsers[i]].quash = TRUE; // Make it so their turn order can't be changed again @@ -16999,7 +17005,7 @@ static void TryUpdateRoundTurnOrder(void) } // Update turn order for non-round users - for (i = 0; nonRoundUsers[i] != 0xFF && i < 3; i++) + for (i = 0; i < 3 && nonRoundUsers[i] != 0xFF; i++) { gBattlerByTurnOrder[currRounder] = nonRoundUsers[i]; currRounder++; diff --git a/src/battle_setup.c b/src/battle_setup.c index 5c6a01c932..6d9083525d 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -337,7 +337,7 @@ static void DoStandardWildBattle(bool32 isDouble) } else if (isDouble) gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { VarSet(VAR_TEMP_E, 0); gBattleTypeFlags |= BATTLE_TYPE_PYRAMID; @@ -356,7 +356,7 @@ void DoStandardWildBattle_Debug(void) StopPlayerAvatar(); gMain.savedCallback = CB2_EndWildBattle; gBattleTypeFlags = 0; - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { VarSet(VAR_TEMP_PLAYING_PYRAMID_MUSIC, 0); gBattleTypeFlags |= BATTLE_TYPE_PYRAMID; @@ -416,7 +416,7 @@ static void DoTrainerBattle(void) static void DoBattlePyramidTrainerHillBattle(void) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) CreateBattleStartTask(GetSpecialBattleTransition(B_TRANSITION_GROUP_B_PYRAMID), 0); else CreateBattleStartTask(GetSpecialBattleTransition(B_TRANSITION_GROUP_TRAINER_HILL), 0); @@ -591,7 +591,7 @@ static void CB2_EndWildBattle(void) HealPlayerParty(); } - if (IsPlayerDefeated(gBattleOutcome) == TRUE && !InBattlePyramid() && !InBattlePike()) + if (IsPlayerDefeated(gBattleOutcome) == TRUE && CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE && !InBattlePike()) { SetMainCallback2(CB2_WhiteOut); } @@ -610,7 +610,7 @@ static void CB2_EndScriptedWildBattle(void) if (IsPlayerDefeated(gBattleOutcome) == TRUE) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); else SetMainCallback2(CB2_WhiteOut); @@ -757,14 +757,14 @@ u8 GetWildBattleTransition(void) if (enemyLevel < playerLevel) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) return B_TRANSITION_BLUR; else return sBattleTransitionTable_Wild[transitionType][0]; } else { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) return B_TRANSITION_GRID_SQUARES; else return sBattleTransitionTable_Wild[transitionType][1]; @@ -1144,7 +1144,7 @@ u8 GetTrainerBattleMode(void) bool8 GetTrainerFlag(void) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) return GetBattlePyramidTrainerFlag(gSelectedObjectEvent); else if (InTrainerHill()) return GetHillTrainerFlag(gSelectedObjectEvent); @@ -1201,7 +1201,7 @@ void BattleSetup_StartTrainerBattle(void) } } - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { VarSet(VAR_TEMP_PLAYING_PYRAMID_MUSIC, 0); gBattleTypeFlags |= BATTLE_TYPE_PYRAMID; @@ -1241,7 +1241,7 @@ void BattleSetup_StartTrainerBattle(void) gWhichTrainerToFaceAfterBattle = 0; gMain.savedCallback = CB2_EndTrainerBattle; - if (InBattlePyramid() || InTrainerHillChallenge()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || InTrainerHillChallenge()) DoBattlePyramidTrainerHillBattle(); else DoTrainerBattle(); @@ -1305,7 +1305,7 @@ static void CB2_EndTrainerBattle(void) } else if (IsPlayerDefeated(gBattleOutcome) == TRUE) { - if (InBattlePyramid() || InTrainerHillChallenge() || (!NoAliveMonsForPlayer()) || FlagGet(B_FLAG_NO_WHITEOUT)) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || InTrainerHillChallenge() || (!NoAliveMonsForPlayer()) || FlagGet(B_FLAG_NO_WHITEOUT)) SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); else SetMainCallback2(CB2_WhiteOut); @@ -1318,7 +1318,7 @@ static void CB2_EndTrainerBattle(void) { SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); DowngradeBadPoison(); - if (!InBattlePyramid() && !InTrainerHillChallenge()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE && !InTrainerHillChallenge()) { RegisterTrainerInMatchCall(); SetBattledTrainersFlags(); @@ -1357,7 +1357,7 @@ void BattleSetup_StartRematchBattle(void) void ShowTrainerIntroSpeech(void) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { if (gNoOfApproachingTrainers == 0 || gNoOfApproachingTrainers == 1) CopyPyramidTrainerSpeechBefore(LocalIdToPyramidTrainerId(gSpecialVar_LastTalked)); diff --git a/src/battle_util.c b/src/battle_util.c index b5e68f9cbd..fb28a6129c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -614,7 +614,7 @@ bool32 TryRunFromBattle(u32 battler) } else if (GetBattlerAbility(battler) == ABILITY_RUN_AWAY) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { gBattleStruct->runTries++; pyramidMultiplier = GetPyramidRunMultiplier(); @@ -647,7 +647,7 @@ bool32 TryRunFromBattle(u32 battler) if (!IsBattlerAlive(runningFromBattler)) runningFromBattler |= BIT_FLANK; - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { pyramidMultiplier = GetPyramidRunMultiplier(); speedVar = (gBattleMons[battler].speed * pyramidMultiplier) / (gBattleMons[runningFromBattler].speed) + (gBattleStruct->runTries * 30); @@ -4627,9 +4627,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_EFFECT_SPORE: { - u32 ability = GetBattlerAbility(gBattlerAttacker); + u32 abilityAtk = GetBattlerAbility(gBattlerAttacker); if ((!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GRASS) || B_POWDER_GRASS < GEN_6) - && ability != ABILITY_OVERCOAT + && abilityAtk != ABILITY_OVERCOAT && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES) { u32 poison, paralysis, sleep; @@ -4657,7 +4657,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerAlive(gBattlerAttacker) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && IsBattlerTurnDamaged(gBattlerTarget) - && CanBeSlept(gBattlerAttacker, gBattlerTarget, ability, NOT_BLOCKED_BY_SLEEP_CLAUSE) + && CanBeSlept(gBattlerTarget, gBattlerAttacker, abilityAtk, NOT_BLOCKED_BY_SLEEP_CLAUSE) && !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), move)) { if (IsSleepClauseEnabled()) @@ -5553,17 +5553,23 @@ bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag) bool32 CanBeSlept(u32 battlerAtk, u32 battlerDef, u32 abilityDef, enum SleepClauseBlock isBlockedBySleepClause) { - if (IsSleepClauseActiveForSide(GetBattlerSide(battlerDef)) && isBlockedBySleepClause) + if (IsSleepClauseActiveForSide(GetBattlerSide(battlerDef)) && isBlockedBySleepClause != NOT_BLOCKED_BY_SLEEP_CLAUSE) return FALSE; + if (isBlockedBySleepClause == NOT_BLOCKED_BY_SLEEP_CLAUSE) + gBattleStruct->sleepClauseNotBlocked = TRUE; + + bool32 effect = FALSE; if (CanSetNonVolatileStatus(battlerAtk, battlerDef, ABILITY_NONE, // attacker ability does not matter abilityDef, MOVE_EFFECT_SLEEP, // also covers yawn STATUS_CHECK_TRIGGER)) - return TRUE; - return FALSE; + effect = TRUE; + + gBattleStruct->sleepClauseNotBlocked = FALSE; + return effect; } bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef) @@ -5714,7 +5720,7 @@ bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u { battleScript = BattleScript_CantMakeAsleep; } - else if (CanSleepDueToSleepClause(battlerAtk, battlerDef, option)) + else if (!gBattleStruct->sleepClauseNotBlocked && CanSleepDueToSleepClause(battlerAtk, battlerDef, option)) { battleScript = BattleScript_SleepClauseBlocked; } @@ -8066,6 +8072,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData u32 battlerAtk = damageCalcData->battlerAtk; u32 battlerDef = damageCalcData->battlerDef; u32 move = damageCalcData->move; + u32 moveEffect = GetMoveEffect(move); u32 i; u32 basePower = GetMovePower(move); @@ -8077,7 +8084,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX) return GetMaxMovePower(move); - switch (GetMoveEffect(move)) + switch (moveEffect) { case EFFECT_PLEDGE: if (gBattleStruct->pledgeMove) @@ -8219,7 +8226,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData } case EFFECT_ECHOED_VOICE: // gBattleStruct->sameMoveTurns incremented in ppreduce - if (gBattleStruct->sameMoveTurns[battlerAtk] != 0) + if (gBattleStruct->sameMoveTurns[battlerAtk] != 0 && GetMoveEffect(gLastResultingMoves[battlerAtk]) == EFFECT_ECHOED_VOICE) { basePower += (basePower * gBattleStruct->sameMoveTurns[battlerAtk]); if (basePower > 200) @@ -8236,18 +8243,15 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData || gDisableStructs[battlerDef].isFirstTurn == 2) basePower *= 2; break; - case EFFECT_ROUND: - for (i = 0; i < gBattlersCount; i++) - { - if (i != battlerAtk && IsBattlerAlive(i) && GetMoveEffect(gLastUsedMove) == EFFECT_ROUND) - { - basePower *= 2; - break; - } - } - break; case EFFECT_FUSION_COMBO: - if (GetMoveEffect(gLastUsedMove) == EFFECT_FUSION_COMBO && move != gLastUsedMove) + if (move == gLastUsedMove) + break; + // fallthrough + case EFFECT_ROUND: + // don't double power due to previous turn's Round/Fusion move + if (gCurrentTurnActionNumber != 0 + && gActionsByTurnOrder[gCurrentTurnActionNumber - 1] == B_ACTION_USE_MOVE + && GetMoveEffect(gLastUsedMove) == moveEffect) basePower *= 2; break; case EFFECT_LASH_OUT: diff --git a/src/braille_puzzles.c b/src/braille_puzzles.c index 31497e137c..217f62d2c7 100644 --- a/src/braille_puzzles.c +++ b/src/braille_puzzles.c @@ -81,9 +81,9 @@ void DoBrailleDigEffect(void) MapGridSetMetatileIdAt( 9 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopLeft); MapGridSetMetatileIdAt(10 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopMid); MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopRight); - MapGridSetMetatileIdAt( 9 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomLeft | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt( 9 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomLeft | MAPGRID_IMPASSABLE); MapGridSetMetatileIdAt(10 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomMid); - MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomRight | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomRight | MAPGRID_IMPASSABLE); DrawWholeMapView(); PlaySE(SE_BANG); FlagSet(FLAG_SYS_BRAILLE_DIG); @@ -207,9 +207,9 @@ static void DoBrailleRegirockEffect(void) MapGridSetMetatileIdAt(7 + MAP_OFFSET, 19 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopLeft); MapGridSetMetatileIdAt(8 + MAP_OFFSET, 19 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopMid); MapGridSetMetatileIdAt(9 + MAP_OFFSET, 19 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopRight); - MapGridSetMetatileIdAt(7 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomLeft | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(7 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomLeft | MAPGRID_IMPASSABLE); MapGridSetMetatileIdAt(8 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomMid); - MapGridSetMetatileIdAt(9 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomRight | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(9 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomRight | MAPGRID_IMPASSABLE); DrawWholeMapView(); PlaySE(SE_BANG); FlagSet(FLAG_SYS_REGIROCK_PUZZLE_COMPLETED); @@ -247,9 +247,9 @@ static void DoBrailleRegisteelEffect(void) MapGridSetMetatileIdAt(7 + MAP_OFFSET, 19 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopLeft); MapGridSetMetatileIdAt(8 + MAP_OFFSET, 19 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopMid); MapGridSetMetatileIdAt(9 + MAP_OFFSET, 19 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_TopRight); - MapGridSetMetatileIdAt(7 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomLeft | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(7 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomLeft | MAPGRID_IMPASSABLE); MapGridSetMetatileIdAt(8 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomMid); - MapGridSetMetatileIdAt(9 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomRight | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(9 + MAP_OFFSET, 20 + MAP_OFFSET, METATILE_Cave_SealedChamberEntrance_BottomRight | MAPGRID_IMPASSABLE); DrawWholeMapView(); PlaySE(SE_BANG); FlagSet(FLAG_SYS_REGISTEEL_PUZZLE_COMPLETED); diff --git a/src/contest_painting.c b/src/contest_painting.c index cb78caac26..4853b9425c 100644 --- a/src/contest_painting.c +++ b/src/contest_painting.c @@ -69,19 +69,19 @@ extern const u8 gContestPaintingTough1[]; extern const u8 gContestPaintingTough2[]; extern const u8 gContestPaintingTough3[]; -static const u16 sPictureFramePalettes[] = INCBIN_U16("graphics/picture_frame/bg.gbapal"); -static const u8 sPictureFrameTiles_Cool[] = INCBIN_U8("graphics/picture_frame/cool.4bpp.rl"); -static const u8 sPictureFrameTiles_Beauty[] = INCBIN_U8("graphics/picture_frame/beauty.4bpp.rl"); -static const u8 sPictureFrameTiles_Cute[] = INCBIN_U8("graphics/picture_frame/cute.4bpp.rl"); -static const u8 sPictureFrameTiles_Smart[] = INCBIN_U8("graphics/picture_frame/smart.4bpp.rl"); -static const u8 sPictureFrameTiles_Tough[] = INCBIN_U8("graphics/picture_frame/tough.4bpp.rl"); -static const u8 sPictureFrameTiles_HallLobby[] = INCBIN_U8("graphics/picture_frame/lobby.4bpp.rl"); -static const u8 sPictureFrameTilemap_Cool[] = INCBIN_U8("graphics/picture_frame/cool_map.bin.rl"); -static const u8 sPictureFrameTilemap_Beauty[] = INCBIN_U8("graphics/picture_frame/beauty_map.bin.rl"); -static const u8 sPictureFrameTilemap_Cute[] = INCBIN_U8("graphics/picture_frame/cute_map.bin.rl"); -static const u8 sPictureFrameTilemap_Smart[] = INCBIN_U8("graphics/picture_frame/smart_map.bin.rl"); -static const u8 sPictureFrameTilemap_Tough[] = INCBIN_U8("graphics/picture_frame/tough_map.bin.rl"); -static const u8 sPictureFrameTilemap_HallLobby[] = INCBIN_U8("graphics/picture_frame/lobby_map.bin.rl"); +static const u16 sPictureFramePalettes[] = INCBIN_U16("graphics/picture_frame/bg.gbapal"); +static const u32 sPictureFrameTiles_Cool[] = INCBIN_U32("graphics/picture_frame/cool.4bpp.rl"); +static const u32 sPictureFrameTiles_Beauty[] = INCBIN_U32("graphics/picture_frame/beauty.4bpp.rl"); +static const u32 sPictureFrameTiles_Cute[] = INCBIN_U32("graphics/picture_frame/cute.4bpp.rl"); +static const u32 sPictureFrameTiles_Smart[] = INCBIN_U32("graphics/picture_frame/smart.4bpp.rl"); +static const u32 sPictureFrameTiles_Tough[] = INCBIN_U32("graphics/picture_frame/tough.4bpp.rl"); +static const u32 sPictureFrameTiles_HallLobby[] = INCBIN_U32("graphics/picture_frame/lobby.4bpp.rl"); +static const u32 sPictureFrameTilemap_Cool[] = INCBIN_U32("graphics/picture_frame/cool_map.bin.rl"); +static const u32 sPictureFrameTilemap_Beauty[] = INCBIN_U32("graphics/picture_frame/beauty_map.bin.rl"); +static const u32 sPictureFrameTilemap_Cute[] = INCBIN_U32("graphics/picture_frame/cute_map.bin.rl"); +static const u32 sPictureFrameTilemap_Smart[] = INCBIN_U32("graphics/picture_frame/smart_map.bin.rl"); +static const u32 sPictureFrameTilemap_Tough[] = INCBIN_U32("graphics/picture_frame/tough_map.bin.rl"); +static const u32 sPictureFrameTilemap_HallLobby[] = INCBIN_U32("graphics/picture_frame/lobby_map.bin.rl"); static const u8 *const sContestCategoryNames_Unused[] = { diff --git a/src/data/region_map/region_map_sections.json.txt b/src/data/region_map/region_map_sections.json.txt index 998a0be78b..fdc1d3b0db 100644 --- a/src/data/region_map/region_map_sections.json.txt +++ b/src/data/region_map/region_map_sections.json.txt @@ -19,9 +19,33 @@ static const u8 sMapName_{{ cleanString(map_section.id) }}_Clone[] = _("{{ map_s const struct RegionMapLocation gRegionMapEntries[] = { ## for map_section in map_sections -{% if existsIn(map_section, "x") and existsIn(map_section, "y") and existsIn(map_section, "width") and existsIn(map_section, "height") and existsIn(map_section, "id") %} - [{{ map_section.id }}] = { {{ map_section.x }}, {{ map_section.y }}, {{ map_section.width }}, {{ map_section.height }}, sMapName_{{ cleanString(map_section.id) }}{% if existsIn(map_section, "name_clone") %}_Clone{% endif %} }, + [{{ map_section.id }}] = { +{% if existsIn(map_section, "x") %} + .x = {{ map_section.x }}, +{% else %} + .x = 0, {% endif %} +{% if existsIn(map_section, "y") %} + .y = {{ map_section.y }}, +{% else %} + .y = 0, +{% endif %} +{% if existsIn(map_section, "width") %} + .width = {{ map_section.width }}, +{% else %} + .width = 1, +{% endif %} +{% if existsIn(map_section, "height") %} + .height = {{ map_section.height }}, +{% else %} + .height = 1, +{% endif %} +{% if existsIn(map_section, "name") %} + .name = sMapName_{{ cleanString(map_section.name) }}{% if existsIn(map_section, "name_clone") %}_Clone{% endif %}, +{% else %} + .name = (const u8[])_(""), +{% endif %} + }, ## endfor }; diff --git a/src/decoration.c b/src/decoration.c index 1608061255..fe01ac4bdc 100644 --- a/src/decoration.c +++ b/src/decoration.c @@ -1227,9 +1227,9 @@ static void ShowDecorationOnMap_(u16 mapX, u16 mapY, u8 decWidth, u8 decHeight, { x = mapX + i; attributes = GetMetatileAttributesById(NUM_TILES_IN_PRIMARY + gDecorations[decoration].tiles[j * decWidth + i]); - if (MetatileBehavior_IsSecretBaseImpassable(attributes & METATILE_ATTR_BEHAVIOR_MASK) == TRUE + if (MetatileBehavior_IsSecretBaseImpassable(UNPACK_BEHAVIOR(attributes)) == TRUE || (gDecorations[decoration].permission != DECORPERM_PASS_FLOOR && (attributes >> METATILE_ATTR_LAYER_SHIFT) != METATILE_LAYER_TYPE_NORMAL)) - impassableFlag = MAPGRID_COLLISION_MASK; + impassableFlag = MAPGRID_IMPASSABLE; else impassableFlag = 0; @@ -1521,6 +1521,17 @@ static bool8 IsFloorOrBoardAndHole(u16 behaviorAt, const struct Decoration *deco return FALSE; } +#ifdef BUGFIX +#define GetLayerType(tileId) UNPACK_LAYER_TYPE(GetMetatileAttributesById(tileId)) +#else +// This incompletely extracts the layer type data. The result is that comparisons against any nonzero +// value in the valid range always have the same result. +// Because GF only compares against 0 (METATILE_LAYER_TYPE_NORMAL) there are no ill effects and it's possible this +// is what they intended. We use the named constant for the comparisons, which implies you can use nonzero constants at +// those locations (which you can't), so to avoid this trap and keep the better documentation this is included as a bug fix. +#define GetLayerType(tileId) GetMetatileAttributesById(tileId) & METATILE_ATTR_LAYER_MASK +#endif + static bool8 CanPlaceDecoration(u8 taskId, const struct Decoration *decoration) { u8 i; @@ -1545,7 +1556,7 @@ static bool8 CanPlaceDecoration(u8 taskId, const struct Decoration *decoration) { curX = gTasks[taskId].tCursorX + j; behaviorAt = MapGridGetMetatileBehaviorAt(curX, curY); - layerType = GetMetatileAttributesById(NUM_TILES_IN_PRIMARY + decoration->tiles[(mapY - 1 - i) * mapX + j]) & METATILE_ATTR_LAYER_MASK; + layerType = GetLayerType(NUM_TILES_IN_PRIMARY + decoration->tiles[(mapY - 1 - i) * mapX + j]); if (!IsFloorOrBoardAndHole(behaviorAt, decoration)) return FALSE; @@ -1566,7 +1577,7 @@ static bool8 CanPlaceDecoration(u8 taskId, const struct Decoration *decoration) { curX = gTasks[taskId].tCursorX + j; behaviorAt = MapGridGetMetatileBehaviorAt(curX, curY); - layerType = GetMetatileAttributesById(NUM_TILES_IN_PRIMARY + decoration->tiles[(mapY - 1 - i) * mapX + j]) & METATILE_ATTR_LAYER_MASK; + layerType = GetLayerType(NUM_TILES_IN_PRIMARY + decoration->tiles[(mapY - 1 - i) * mapX + j]); if (!MetatileBehavior_IsNormal(behaviorAt) && !IsSecretBaseTrainerSpot(behaviorAt, layerType)) return FALSE; @@ -1583,7 +1594,7 @@ static bool8 CanPlaceDecoration(u8 taskId, const struct Decoration *decoration) { curX = gTasks[taskId].tCursorX + j; behaviorAt = MapGridGetMetatileBehaviorAt(curX, curY); - layerType = GetMetatileAttributesById(NUM_TILES_IN_PRIMARY + decoration->tiles[j]) & METATILE_ATTR_LAYER_MASK; + layerType = GetLayerType(NUM_TILES_IN_PRIMARY + decoration->tiles[j]); if (!MetatileBehavior_IsNormal(behaviorAt) && !MetatileBehavior_IsSecretBaseNorthWall(behaviorAt)) return FALSE; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 0c0d5b4694..49c928ea3a 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1481,7 +1481,7 @@ u8 Unref_TryInitLocalObjectEvent(u8 localId) if (gMapHeader.events != NULL) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) objectEventCount = GetNumBattlePyramidObjectEvents(); else if (InTrainerHill()) objectEventCount = HILL_TRAINERS_PER_FLOOR; @@ -2724,7 +2724,7 @@ void TrySpawnLightSprites(s16 camX, s16 camY) if (gMapHeader.events == NULL) return; - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) objectCount = GetNumBattlePyramidObjectEvents(); else if (InTrainerHill()) objectCount = 2; @@ -2756,7 +2756,7 @@ void TrySpawnObjectEvents(s16 cameraX, s16 cameraY) s16 top = gSaveBlock1Ptr->pos.y; s16 bottom = gSaveBlock1Ptr->pos.y + MAP_OFFSET_H + 2; - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) objectCount = GetNumBattlePyramidObjectEvents(); else if (InTrainerHill()) objectCount = HILL_TRAINERS_PER_FLOOR; diff --git a/src/field_poison.c b/src/field_poison.c index 30ae7c21a7..f4be9970a2 100644 --- a/src/field_poison.c +++ b/src/field_poison.c @@ -94,9 +94,9 @@ static void Task_TryFieldPoisonWhiteOut(u8 taskId) { // Battle facilities have their own white out script to handle the challenge loss #ifdef BUGFIX - if (InBattlePyramid() || InBattlePike() || InTrainerHillChallenge()) + if (CurrentBattlePyramidLocation() || InBattlePike() || InTrainerHillChallenge()) #else - if (InBattlePyramid() | InBattlePike() || InTrainerHillChallenge()) + if (CurrentBattlePyramidLocation() | InBattlePike() || InTrainerHillChallenge()) #endif gSpecialVar_Result = FLDPSN_FRONTIER_WHITEOUT; else diff --git a/src/field_specials.c b/src/field_specials.c index ee5d3e971b..0330b51c01 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -680,10 +680,10 @@ void MauvilleGymSetDefaultBarriers(void) MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamH2_On); break; case METATILE_MauvilleGym_GreenBeamH3_Off: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamH3_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamH3_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_GreenBeamH4_Off: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamH4_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamH4_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_RedBeamH1_On: MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamH1_Off); @@ -704,37 +704,37 @@ void MauvilleGymSetDefaultBarriers(void) MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamH2_On); break; case METATILE_MauvilleGym_RedBeamH3_Off: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamH3_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamH3_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_RedBeamH4_Off: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamH4_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamH4_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_GreenBeamV1_On: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_GreenBeamV2_On: MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_FloorTile); break; case METATILE_MauvilleGym_RedBeamV1_On: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_Off | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_Off | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_RedBeamV2_On: MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_FloorTile); break; case METATILE_MauvilleGym_PoleBottom_On: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamV1_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamV1_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_FloorTile: if (MapGridGetMetatileIdAt(x, y - 1) == METATILE_MauvilleGym_GreenBeamV1_On) - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamV2_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_GreenBeamV2_On | MAPGRID_IMPASSABLE); else - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamV2_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamV2_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_PoleBottom_Off: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamV1_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamV1_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_PoleTop_Off: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleTop_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleTop_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_PoleTop_On: MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleTop_Off); @@ -785,10 +785,10 @@ void MauvilleGymDeactivatePuzzle(void) MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_RedBeamH4_Off); break; case METATILE_MauvilleGym_GreenBeamV1_On: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_On | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_On | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_RedBeamV1_On: - MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_Off | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_MauvilleGym_PoleBottom_Off | MAPGRID_IMPASSABLE); break; case METATILE_MauvilleGym_GreenBeamV2_On: case METATILE_MauvilleGym_RedBeamV2_On: @@ -897,8 +897,8 @@ static void PetalburgGymSetDoorMetatiles(u8 roomNumber, u16 metatileId) } for (i = 0; i < nDoors; i++) { - MapGridSetMetatileIdAt(doorCoordsX[i] + MAP_OFFSET, doorCoordsY[i] + MAP_OFFSET, metatileId | MAPGRID_COLLISION_MASK); - MapGridSetMetatileIdAt(doorCoordsX[i] + MAP_OFFSET, doorCoordsY[i] + MAP_OFFSET + 1, (metatileId + METATILE_ROW_WIDTH) | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(doorCoordsX[i] + MAP_OFFSET, doorCoordsY[i] + MAP_OFFSET, metatileId | MAPGRID_IMPASSABLE); + MapGridSetMetatileIdAt(doorCoordsX[i] + MAP_OFFSET, doorCoordsY[i] + MAP_OFFSET + 1, (metatileId + METATILE_ROW_WIDTH) | MAPGRID_IMPASSABLE); } DrawWholeMapView(); } @@ -1098,7 +1098,7 @@ static void PCTurnOnEffect_SetMetatile(s16 isScreenOn, s8 dx, s8 dy) else if (gSpecialVar_0x8004 == PC_LOCATION_MAYS_HOUSE) metatileId = METATILE_BrendansMaysHouse_MayPC_On; } - MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, metatileId | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, metatileId | MAPGRID_IMPASSABLE); } // For this special, gSpecialVar_0x8004 is expected to be some PC_LOCATION_* value. @@ -1141,7 +1141,7 @@ static void PCTurnOffEffect(void) else if (gSpecialVar_0x8004 == PC_LOCATION_MAYS_HOUSE) metatileId = METATILE_BrendansMaysHouse_MayPC_Off; - MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, metatileId | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, metatileId | MAPGRID_IMPASSABLE); DrawWholeMapView(); } @@ -1173,14 +1173,14 @@ static void LotteryCornerComputerEffect(struct Task *task) if (task->tIsScreenOn) { // Screen is on, set it off - MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Normal | MAPGRID_COLLISION_MASK); - MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Normal | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Normal | MAPGRID_IMPASSABLE); + MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Normal | MAPGRID_IMPASSABLE); } else { // Screen is off, set it on - MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Flash | MAPGRID_COLLISION_MASK); - MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Flash | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Flash | MAPGRID_IMPASSABLE); + MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Flash | MAPGRID_IMPASSABLE); } DrawWholeMapView(); @@ -1195,8 +1195,8 @@ static void LotteryCornerComputerEffect(struct Task *task) void EndLotteryCornerComputerEffect(void) { - MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Normal | MAPGRID_COLLISION_MASK); - MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Normal | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Normal | MAPGRID_IMPASSABLE); + MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Normal | MAPGRID_IMPASSABLE); DrawWholeMapView(); } @@ -1976,7 +1976,7 @@ static void Task_MoveElevatorWindowLights(u8 taskId) for (y = 0; y < ELEVATOR_WINDOW_HEIGHT; y++) { for (x = 0; x < ELEVATOR_WINDOW_WIDTH; x++) - MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Ascending[y][tMoveCounter % ELEVATOR_LIGHT_STAGES] | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Ascending[y][tMoveCounter % ELEVATOR_LIGHT_STAGES] | MAPGRID_IMPASSABLE); } } else @@ -1985,7 +1985,7 @@ static void Task_MoveElevatorWindowLights(u8 taskId) for (y = 0; y < ELEVATOR_WINDOW_HEIGHT; y++) { for (x = 0; x < ELEVATOR_WINDOW_WIDTH; x++) - MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Descending[y][tMoveCounter % ELEVATOR_LIGHT_STAGES] | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Descending[y][tMoveCounter % ELEVATOR_LIGHT_STAGES] | MAPGRID_IMPASSABLE); } } DrawWholeMapView(); diff --git a/src/fieldmap.c b/src/fieldmap.c index 255e1b8904..5e8a261cab 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -52,7 +52,7 @@ static inline u16 GetBorderBlockAt(int x, int y) { int i = (x + 1) & 1; i += ((y + 1) & 1) * 2; - return gMapHeader.mapLayout->border[i] | MAPGRID_COLLISION_MASK; + return gMapHeader.mapLayout->border[i] | MAPGRID_IMPASSABLE; } #define AreCoordsWithinMapGridBounds(x, y) (x >= 0 && x < gBackupMapLayout.width && y >= 0 && y < gBackupMapLayout.height) @@ -345,7 +345,7 @@ u8 MapGridGetElevationAt(int x, int y) if (block == MAPGRID_UNDEFINED) return 0; - return block >> MAPGRID_ELEVATION_SHIFT; + return UNPACK_ELEVATION(block); } u8 MapGridGetCollisionAt(int x, int y) @@ -355,7 +355,7 @@ u8 MapGridGetCollisionAt(int x, int y) if (block == MAPGRID_UNDEFINED) return TRUE; - return (block & MAPGRID_COLLISION_MASK) >> MAPGRID_COLLISION_SHIFT; + return UNPACK_COLLISION(block); } u32 MapGridGetMetatileIdAt(int x, int y) @@ -363,21 +363,21 @@ u32 MapGridGetMetatileIdAt(int x, int y) u16 block = GetMapGridBlockAt(x, y); if (block == MAPGRID_UNDEFINED) - return GetBorderBlockAt(x, y) & MAPGRID_METATILE_ID_MASK; + return UNPACK_METATILE(GetBorderBlockAt(x, y)); - return block & MAPGRID_METATILE_ID_MASK; + return UNPACK_METATILE(block); } u32 MapGridGetMetatileBehaviorAt(int x, int y) { u16 metatile = MapGridGetMetatileIdAt(x, y); - return GetMetatileAttributesById(metatile) & METATILE_ATTR_BEHAVIOR_MASK; + return UNPACK_BEHAVIOR(GetMetatileAttributesById(metatile)); } u8 MapGridGetMetatileLayerTypeAt(int x, int y) { u16 metatile = MapGridGetMetatileIdAt(x, y); - return (GetMetatileAttributesById(metatile) & METATILE_ATTR_LAYER_MASK) >> METATILE_ATTR_LAYER_SHIFT; + return UNPACK_LAYER_TYPE(GetMetatileAttributesById(metatile)); } void MapGridSetMetatileIdAt(int x, int y, u16 metatile) @@ -386,6 +386,8 @@ void MapGridSetMetatileIdAt(int x, int y, u16 metatile) if (AreCoordsWithinMapGridBounds(x, y)) { i = x + y * gBackupMapLayout.width; + + // Elevation is ignored in the argument, but copy metatile ID and collision gBackupMapLayout.map[i] = (gBackupMapLayout.map[i] & MAPGRID_ELEVATION_MASK) | (metatile & ~MAPGRID_ELEVATION_MASK); } } @@ -839,7 +841,7 @@ static bool8 SkipCopyingMetatileFromSavedMap(u16 *mapBlock, u16 mapWidth, u8 yMo else mapBlock += mapWidth; - if (IsLargeBreakableDecoration(*mapBlock & MAPGRID_METATILE_ID_MASK, yMode) == TRUE) + if (IsLargeBreakableDecoration(UNPACK_METATILE(*mapBlock), yMode) == TRUE) return TRUE; return FALSE; } diff --git a/src/fldeff_escalator.c b/src/fldeff_escalator.c index eabbd53549..f49b97b0c8 100644 --- a/src/fldeff_escalator.c +++ b/src/fldeff_escalator.c @@ -126,13 +126,13 @@ static void Task_DrawEscalator(u8 taskId) SetEscalatorMetatile(taskId, sEscalatorMetatiles_1F_1, 0); break; case 2: - SetEscalatorMetatile(taskId, sEscalatorMetatiles_1F_2, MAPGRID_COLLISION_MASK); + SetEscalatorMetatile(taskId, sEscalatorMetatiles_1F_2, MAPGRID_IMPASSABLE); break; case 3: SetEscalatorMetatile(taskId, sEscalatorMetatiles_1F_3, 0); break; case 4: - SetEscalatorMetatile(taskId, sEscalatorMetatiles_2F_0, MAPGRID_COLLISION_MASK); + SetEscalatorMetatile(taskId, sEscalatorMetatiles_2F_0, MAPGRID_IMPASSABLE); break; case 5: SetEscalatorMetatile(taskId, sEscalatorMetatiles_2F_1, 0); diff --git a/src/fldeff_misc.c b/src/fldeff_misc.c index d3e6982f29..893d4ab638 100644 --- a/src/fldeff_misc.c +++ b/src/fldeff_misc.c @@ -840,9 +840,9 @@ void DoSecretBasePCTurnOffEffect(void) PlaySE(SE_PC_OFF); if (!VarGet(VAR_CURRENT_SECRET_BASE)) - MapGridSetMetatileIdAt(x, y, METATILE_SecretBase_PC | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_SecretBase_PC | MAPGRID_IMPASSABLE); else - MapGridSetMetatileIdAt(x, y, METATILE_SecretBase_RegisterPC | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_SecretBase_RegisterPC | MAPGRID_IMPASSABLE); CurrentMapDrawMetatileAt(x, y); } @@ -1083,7 +1083,7 @@ static void SpriteCB_SandPillar_BreakTop(struct Sprite *sprite) PlaySE(SE_M_ROCK_THROW); if (MapGridGetMetatileIdAt(gFieldEffectArguments[5], gFieldEffectArguments[6] - 1) == METATILE_SecretBase_SandOrnament_TopWall) - MapGridSetMetatileIdAt(gFieldEffectArguments[5], gFieldEffectArguments[6] - 1, METATILE_SecretBase_Wall_TopMid | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(gFieldEffectArguments[5], gFieldEffectArguments[6] - 1, METATILE_SecretBase_Wall_TopMid | MAPGRID_IMPASSABLE); else MapGridSetMetatileIdAt(gFieldEffectArguments[5], gFieldEffectArguments[6] - 1, METATILE_SecretBase_SandOrnament_BrokenTop); @@ -1103,7 +1103,7 @@ static void SpriteCB_SandPillar_BreakBase(struct Sprite *sprite) } else { - MapGridSetMetatileIdAt(gFieldEffectArguments[5], gFieldEffectArguments[6], METATILE_SecretBase_SandOrnament_BrokenBase | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(gFieldEffectArguments[5], gFieldEffectArguments[6], METATILE_SecretBase_SandOrnament_BrokenBase | MAPGRID_IMPASSABLE); CurrentMapDrawMetatileAt(gFieldEffectArguments[5], gFieldEffectArguments[6]); sprite->data[0] = 0; sprite->callback = SpriteCB_SandPillar_End; diff --git a/src/frontier_pass.c b/src/frontier_pass.c index 12bb1f3ea7..54d25a11e0 100644 --- a/src/frontier_pass.c +++ b/src/frontier_pass.c @@ -917,12 +917,12 @@ static void CB2_ReturnFromRecord(void) sPassData->cursorX = sSavedPassData.cursorX; sPassData->cursorY = sSavedPassData.cursorY; memset(&sSavedPassData, 0, sizeof(sSavedPassData)); - switch (InBattlePyramid()) + switch (CurrentBattlePyramidLocation()) { - case 1: + case PYRAMID_LOCATION_FLOOR: PlayBGM(MUS_B_PYRAMID); break; - case 2: + case PYRAMID_LOCATION_TOP: PlayBGM(MUS_B_PYRAMID_TOP); break; default: diff --git a/src/gpu_regs.c b/src/gpu_regs.c index 3bcc4fd931..d645c1442d 100644 --- a/src/gpu_regs.c +++ b/src/gpu_regs.c @@ -8,7 +8,7 @@ #define EMPTY_SLOT 0xFF -static u8 sGpuRegBuffer[GPU_REG_BUF_SIZE]; +static ALIGNED(2) u8 sGpuRegBuffer[GPU_REG_BUF_SIZE]; // sGpuRegBuffer is read as u16 so it needs to be properly aligned static u8 sGpuRegWaitingList[GPU_REG_BUF_SIZE]; static volatile bool8 sGpuRegBufferLocked; static volatile bool8 sShouldSyncRegIE; diff --git a/src/item.c b/src/item.c index 3fb72703a8..5a27518bde 100644 --- a/src/item.c +++ b/src/item.c @@ -129,7 +129,7 @@ bool8 CheckBagHasItem(u16 itemId, u16 count) if (GetItemPocket(itemId) == 0) return FALSE; - if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) return CheckPyramidBagHasItem(itemId, count); pocket = GetItemPocket(itemId) - 1; // Check for item slots that contain the item @@ -184,7 +184,7 @@ bool8 CheckBagHasSpace(u16 itemId, u16 count) if (GetItemPocket(itemId) == POCKET_NONE) return FALSE; - if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) return CheckPyramidBagHasSpace(itemId, count); return GetFreeSpaceForItemInBag(itemId) >= count; @@ -224,7 +224,7 @@ bool8 AddBagItem(u16 itemId, u16 count) return FALSE; // check Battle Pyramid Bag - if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) { return AddPyramidBagItem(itemId, count); } @@ -326,7 +326,7 @@ bool8 RemoveBagItem(u16 itemId, u16 count) return FALSE; // check Battle Pyramid Bag - if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) { return RemovePyramidBagItem(itemId, count); } diff --git a/src/item_menu.c b/src/item_menu.c index e8d7e44207..ed04369755 100755 --- a/src/item_menu.c +++ b/src/item_menu.c @@ -573,7 +573,7 @@ void CB2_BagMenuFromStartMenu(void) void CB2_BagMenuFromBattle(void) { - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) GoToBagMenu(ITEMMENULOCATION_BATTLE, POCKETS_COUNT, CB2_SetUpReshowBattleScreenAfterMenu2); else GoToBattlePyramidBagMenu(PYRAMIDBAG_LOC_BATTLE, CB2_SetUpReshowBattleScreenAfterMenu2); @@ -2074,7 +2074,7 @@ bool8 UseRegisteredKeyItemOnField(void) { u8 taskId; - if (InUnionRoom() == TRUE || InBattlePyramid() || InBattlePike() || InMultiPartnerRoom() == TRUE) + if (InUnionRoom() == TRUE || CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || InBattlePike() || InMultiPartnerRoom() == TRUE) return FALSE; HideMapNamePopUpWindow(); ChangeBgY_ScreenOff(0, 0, BG_COORD_SET); diff --git a/src/item_use.c b/src/item_use.c index f83fccbbb0..d726364d42 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -128,7 +128,7 @@ static void SetUpItemUseCallback(u8 taskId) type = gTasks[taskId].tEnigmaBerryType - 1; else type = GetItemType(gSpecialVar_ItemId) - 1; - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) { gBagMenu->newScreenCallback = sItemUseCallbacks[type]; Task_FadeAndCloseBagMenu(taskId); @@ -170,7 +170,7 @@ static void DisplayCannotUseItemMessage(u8 taskId, bool8 isUsingRegisteredKeyIte StringExpandPlaceholders(gStringVar4, str); if (!isUsingRegisteredKeyItemOnField) { - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gText_DadsAdvice, Task_CloseBattlePyramidBagMessage); @@ -923,7 +923,7 @@ static void RemoveUsedItem(void) RemoveBagItem(gSpecialVar_ItemId, 1); CopyItemName(gSpecialVar_ItemId, gStringVar2); StringExpandPlaceholders(gStringVar4, gText_PlayerUsedVar2); - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) { UpdatePocketItemList(GetItemPocket(gSpecialVar_ItemId)); UpdatePocketListPosition(GetItemPocket(gSpecialVar_ItemId)); @@ -939,7 +939,7 @@ void ItemUseOutOfBattle_Repel(u8 taskId) { if (REPEL_STEP_COUNT == 0) gTasks[taskId].func = Task_StartUseRepel; - else if (!InBattlePyramid()) + else if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gText_RepelEffectsLingered, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gText_RepelEffectsLingered, Task_CloseBattlePyramidBagMessage); @@ -966,7 +966,7 @@ static void Task_UseRepel(u8 taskId) VarSet(VAR_LAST_REPEL_LURE_USED, gSpecialVar_ItemId); #endif RemoveUsedItem(); - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage); @@ -983,7 +983,7 @@ void ItemUseOutOfBattle_Lure(u8 taskId) { if (LURE_STEP_COUNT == 0) gTasks[taskId].func = Task_StartUseLure; - else if (!InBattlePyramid()) + else if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gText_LureEffectsLingered, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gText_LureEffectsLingered, Task_CloseBattlePyramidBagMessage); @@ -1010,7 +1010,7 @@ static void Task_UseLure(u8 taskId) VarSet(VAR_LAST_REPEL_LURE_USED, gSpecialVar_ItemId); #endif RemoveUsedItem(); - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage); @@ -1029,7 +1029,7 @@ static void Task_UsedBlackWhiteFlute(u8 taskId) if(++gTasks[taskId].data[8] > 7) { PlaySE(SE_GLASS_FLUTE); - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage); @@ -1134,31 +1134,31 @@ void ItemUseInBattle_PokeBall(u8 taskId) case BALL_THROW_ABLE: default: RemoveBagItem(gSpecialVar_ItemId, 1); - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) Task_FadeAndCloseBagMenu(taskId); else CloseBattlePyramidBag(taskId); break; case BALL_THROW_UNABLE_TWO_MONS: - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, sText_CantThrowPokeBall_TwoMons, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_TwoMons, Task_CloseBattlePyramidBagMessage); break; case BALL_THROW_UNABLE_NO_ROOM: - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gText_BoxFull, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gText_BoxFull, Task_CloseBattlePyramidBagMessage); break; case BALL_THROW_UNABLE_SEMI_INVULNERABLE: - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, sText_CantThrowPokeBall_SemiInvulnerable, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_SemiInvulnerable, Task_CloseBattlePyramidBagMessage); break; case BALL_THROW_UNABLE_DISABLED_FLAG: - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, sText_CantThrowPokeBall_Disabled, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_Disabled, Task_CloseBattlePyramidBagMessage); @@ -1168,7 +1168,7 @@ void ItemUseInBattle_PokeBall(u8 taskId) static void ItemUseInBattle_ShowPartyMenu(u8 taskId) { - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) { gBagMenu->newScreenCallback = ChooseMonForInBattleItem; Task_FadeAndCloseBagMenu(taskId); @@ -1316,7 +1316,7 @@ void ItemUseInBattle_BagMenu(u8 taskId) { if (CannotUseItemsInBattle(gSpecialVar_ItemId, NULL)) { - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage); @@ -1327,7 +1327,7 @@ void ItemUseInBattle_BagMenu(u8 taskId) if (!GetItemImportance(gSpecialVar_ItemId) && !(B_TRY_CATCH_TRAINER_BALL >= GEN_4 && (GetItemBattleUsage(gSpecialVar_ItemId) == EFFECT_ITEM_THROW_BALL) && (gBattleTypeFlags & BATTLE_TYPE_TRAINER))) RemoveUsedItem(); ScheduleBgCopyTilemapToVram(2); - if (!InBattlePyramid()) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) gTasks[taskId].func = Task_FadeAndCloseBagMenu; else gTasks[taskId].func = CloseBattlePyramidBag; diff --git a/src/map_name_popup.c b/src/map_name_popup.c index cbc19b797b..0a3ea7cde7 100644 --- a/src/map_name_popup.c +++ b/src/map_name_popup.c @@ -526,7 +526,7 @@ static void ShowMapNamePopUpWindow(void) const u8 *mapDisplayHeaderSource; u8 mapNamePopUpWindowId, secondaryPopUpWindowId; - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { if (gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP) { diff --git a/src/mon_markings.c b/src/mon_markings.c index d7a61c27e7..1de8e413fd 100644 --- a/src/mon_markings.c +++ b/src/mon_markings.c @@ -23,7 +23,7 @@ static void SpriteCB_Cursor(struct Sprite *); static struct Sprite *CreateMarkingComboSprite(u16, u16, const u16 *, u16); static const u16 sMonMarkings_Pal[] = INCBIN_U16("graphics/interface/mon_markings.gbapal"); -static const u8 sMonMarkings_Gfx[] = INCBIN_U8("graphics/interface/mon_markings.4bpp"); +static const ALIGNED(4) u8 sMonMarkings_Gfx[] = INCBIN_U8("graphics/interface/mon_markings.4bpp"); // Alignment needed for dma copy static const struct OamData sOamData_MenuWindow = { diff --git a/src/party_menu.c b/src/party_menu.c index 46592e1413..c525a03518 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3359,7 +3359,7 @@ static void CursorCb_Give(u8 taskId) static void CB2_SelectBagItemToGive(void) { - if (InBattlePyramid() == FALSE) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) GoToBagMenu(ITEMMENULOCATION_PARTY, POCKETS_COUNT, CB2_GiveHoldItem); else GoToBattlePyramidBagMenu(PYRAMIDBAG_LOC_PARTY, CB2_GiveHoldItem); @@ -4599,7 +4599,7 @@ void CB2_ShowPartyMenuForItemUse(void) static void CB2_ReturnToBagMenu(void) { - if (InBattlePyramid() == FALSE) + if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) GoToBagMenu(ITEMMENULOCATION_LAST, POCKETS_COUNT, NULL); else GoToBattlePyramidBagMenu(PYRAMIDBAG_LOC_PREV, gPyramidBagMenuState.exitCallback); @@ -6844,7 +6844,7 @@ void CB2_PartyMenuFromStartMenu(void) // As opposted to by selecting Give in the party menu, which is handled by CursorCb_Give void CB2_ChooseMonToGiveItem(void) { - MainCallback callback = (InBattlePyramid() == FALSE) ? CB2_ReturnToBagMenu : CB2_ReturnToPyramidBagMenu; + MainCallback callback = (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE) ? CB2_ReturnToBagMenu : CB2_ReturnToPyramidBagMenu; InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_GIVE_ITEM, FALSE, PARTY_MSG_GIVE_TO_WHICH_MON, Task_HandleChooseMonInput, callback); gPartyMenu.bagItem = gSpecialVar_ItemId; } diff --git a/src/pokemon.c b/src/pokemon.c index bd5ccf312f..afe4a65125 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -1146,7 +1146,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, { isShiny = TRUE; } - else if (P_ONLY_OBTAINABLE_SHINIES && InBattlePyramid()) + else if (P_ONLY_OBTAINABLE_SHINIES && CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { isShiny = FALSE; } @@ -5220,7 +5220,7 @@ u8 GetTrainerEncounterMusicId(u16 trainerOpponentId) u32 sanitizedTrainerId = SanitizeTrainerId(trainerOpponentId); enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId); - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) return GetTrainerEncounterMusicIdInBattlePyramid(trainerOpponentId); else if (InTrainerHillChallenge()) return GetTrainerEncounterMusicIdInTrainerHill(trainerOpponentId); @@ -6389,7 +6389,7 @@ static bool8 ShouldSkipFriendshipChange(void) { if (gMain.inBattle && gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) return TRUE; - if (!gMain.inBattle && (InBattlePike() || InBattlePyramid())) + if (!gMain.inBattle && (InBattlePike() || CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)) return TRUE; return FALSE; } diff --git a/src/pokenav_main_menu.c b/src/pokenav_main_menu.c index 4a9a5cedf8..455e35fa41 100644 --- a/src/pokenav_main_menu.c +++ b/src/pokenav_main_menu.c @@ -32,7 +32,7 @@ struct Pokenav_MainMenu // Needed to match LoadLeftHeaderGfxForSubMenu. struct CompressedSpriteSheetNoSize { - const u32 *data; // LZ77 compressed palette data + const u32 *data; // Compressed sprite data u32 tag; }; diff --git a/src/scrcmd.c b/src/scrcmd.c index b5077420e3..181b98d100 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -2728,7 +2728,7 @@ bool8 ScrCmd_setmetatile(struct ScriptContext *ctx) if (!isImpassable) MapGridSetMetatileIdAt(x, y, metatileId); else - MapGridSetMetatileIdAt(x, y, metatileId | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, metatileId | MAPGRID_IMPASSABLE); return FALSE; } diff --git a/src/secret_base.c b/src/secret_base.c index de0825b91e..9b73d330c2 100644 --- a/src/secret_base.c +++ b/src/secret_base.c @@ -332,7 +332,7 @@ void ToggleSecretBaseEntranceMetatile(void) { if (sSecretBaseEntranceMetatiles[i].closedMetatileId == metatileId) { - MapGridSetMetatileIdAt(x, y, sSecretBaseEntranceMetatiles[i].openMetatileId | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, sSecretBaseEntranceMetatiles[i].openMetatileId | MAPGRID_IMPASSABLE); CurrentMapDrawMetatileAt(x, y); return; } @@ -343,7 +343,7 @@ void ToggleSecretBaseEntranceMetatile(void) { if (sSecretBaseEntranceMetatiles[i].openMetatileId == metatileId) { - MapGridSetMetatileIdAt(x, y, sSecretBaseEntranceMetatiles[i].closedMetatileId | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, sSecretBaseEntranceMetatiles[i].closedMetatileId | MAPGRID_IMPASSABLE); CurrentMapDrawMetatileAt(x, y); return; } @@ -398,7 +398,7 @@ void SetOccupiedSecretBaseEntranceMetatiles(struct MapEvents const *events) { if (sSecretBaseEntranceMetatiles[i].closedMetatileId == tile_id) { - MapGridSetMetatileIdAt(x, y, sSecretBaseEntranceMetatiles[i].openMetatileId | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, sSecretBaseEntranceMetatiles[i].openMetatileId | MAPGRID_IMPASSABLE); break; } } @@ -477,7 +477,7 @@ static void EnterNewlyCreatedSecretBase_StartFadeIn(void) FindMetatileIdMapCoords(&x, &y, METATILE_SecretBase_PC); x += MAP_OFFSET; y += MAP_OFFSET; - MapGridSetMetatileIdAt(x, y, METATILE_SecretBase_PC | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x, y, METATILE_SecretBase_PC | MAPGRID_IMPASSABLE); CurrentMapDrawMetatileAt(x, y); FadeInFromBlack(); CreateTask(EnterNewlyCreatedSecretBase_WaitFadeIn, 0); @@ -538,13 +538,13 @@ void InitSecretBaseAppearance(bool8 hidePC) { // Another player's secret base. Change PC type to the "Register" PC. FindMetatileIdMapCoords(&x, &y, METATILE_SecretBase_PC); - MapGridSetMetatileIdAt(x + MAP_OFFSET, y + MAP_OFFSET, METATILE_SecretBase_RegisterPC | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x + MAP_OFFSET, y + MAP_OFFSET, METATILE_SecretBase_RegisterPC | MAPGRID_IMPASSABLE); } else if (hidePC == TRUE && VarGet(VAR_SECRET_BASE_INITIALIZED) == 1) { // Change PC to regular ground tile. FindMetatileIdMapCoords(&x, &y, METATILE_SecretBase_PC); - MapGridSetMetatileIdAt(x + MAP_OFFSET, y + MAP_OFFSET, METATILE_SecretBase_Ground | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(x + MAP_OFFSET, y + MAP_OFFSET, METATILE_SecretBase_Ground | MAPGRID_IMPASSABLE); } } } @@ -840,7 +840,7 @@ static void ClosePlayerSecretBaseEntrance(void) { MapGridSetMetatileIdAt(events->bgEvents[i].x + MAP_OFFSET, events->bgEvents[i].y + MAP_OFFSET, - sSecretBaseEntranceMetatiles[j].closedMetatileId | MAPGRID_COLLISION_MASK); + sSecretBaseEntranceMetatiles[j].closedMetatileId | MAPGRID_IMPASSABLE); break; } } diff --git a/src/shop.c b/src/shop.c index ac8a01a9b4..0731344932 100644 --- a/src/shop.c +++ b/src/shop.c @@ -45,6 +45,7 @@ #define TAG_ITEM_ICON_BASE 9110 // immune to time blending #define MAX_ITEMS_SHOWN 8 +#define SHOP_MENU_PALETTE_ID 12 enum { WIN_BUY_SELL_QUIT, @@ -746,7 +747,7 @@ static void BuyMenuDecompressBgGraphics(void) { DecompressAndCopyTileDataToVram(1, gShopMenu_Gfx, 0x3A0, 0x3E3, 0); LZDecompressWram(gShopMenu_Tilemap, sShopData->tilemapBuffers[0]); - LoadPalette(gShopMenu_Pal, BG_PLTT_ID(12), PLTT_SIZE_4BPP); + LoadPalette(gShopMenu_Pal, BG_PLTT_ID(SHOP_MENU_PALETTE_ID), PLTT_SIZE_4BPP); } static void BuyMenuInitWindows(void) @@ -956,7 +957,7 @@ static void BuyMenuCopyMenuBgToBg1TilemapBuffer(void) for (i = 0; i < 1024; i++) { if (src[i] != 0) - dest[i] = src[i] + 0xC3E3; + dest[i] = src[i] + ((SHOP_MENU_PALETTE_ID << 12) | 0x3E3); } } diff --git a/src/start_menu.c b/src/start_menu.c index e15612aa54..b51d0592d8 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -306,7 +306,7 @@ static void BuildStartMenuActions(void) { BuildBattlePikeStartMenu(); } - else if (InBattlePyramid()) + else if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { BuildBattlePyramidStartMenu(); } @@ -468,7 +468,7 @@ static void RemoveExtraStartMenuWindows(void) CopyWindowToVram(sSafariBallsWindowId, COPYWIN_GFX); RemoveWindow(sSafariBallsWindowId); } - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { ClearStdWindowAndFrameToTransparent(sBattlePyramidFloorWindowId, FALSE); RemoveWindow(sBattlePyramidFloorWindowId); @@ -528,7 +528,7 @@ static bool32 InitStartMenuStep(void) case 3: if (GetSafariZoneFlag()) ShowSafariBallsWindow(); - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) ShowPyramidFloorWindow(); sInitStartMenuData[0]++; break; @@ -753,7 +753,7 @@ static bool8 StartMenuPlayerNameCallback(void) static bool8 StartMenuSaveCallback(void) { - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) RemoveExtraStartMenuWindows(); gMenuCallback = SaveStartCallback; // Display save menu @@ -1035,7 +1035,7 @@ static u8 SaveConfirmSaveCallback(void) RemoveStartMenuWindow(); ShowSaveInfoWindow(); - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { ShowSaveMessage(gText_BattlePyramidConfirmRest, SaveYesNoCallback); } diff --git a/src/trainer_hill.c b/src/trainer_hill.c index 3b2b74e1ab..133ddeb73b 100644 --- a/src/trainer_hill.c +++ b/src/trainer_hill.c @@ -707,17 +707,17 @@ bool32 LoadTrainerHillFloorObjectEventScripts(void) return TRUE; } -static u16 GetMetatileForFloor(u8 floorId, u32 x, u32 y, u32 floorWidth) // floorWidth is always 16 +static u16 GetMapDataForFloor(u8 floorId, u32 x, u32 y, u32 floorWidth) // floorWidth is always 16 { bool8 impassable; - u16 metatile; + u16 metatileId; u16 elevation; impassable = (sHillData->floors[floorId].map.collisionData[y] >> (15 - x) & 1); - metatile = sHillData->floors[floorId].map.metatileData[floorWidth * y + x] + NUM_METATILES_IN_PRIMARY; - elevation = 3 << MAPGRID_ELEVATION_SHIFT; + metatileId = sHillData->floors[floorId].map.metatileData[floorWidth * y + x] + NUM_METATILES_IN_PRIMARY; + elevation = PACK_ELEVATION(3); - return ((impassable << MAPGRID_COLLISION_SHIFT) & MAPGRID_COLLISION_MASK) | elevation | (metatile & MAPGRID_METATILE_ID_MASK); + return PACK_COLLISION(impassable) | elevation | PACK_METATILE(metatileId); } void GenerateTrainerHillFloorLayout(u16 *mapArg) @@ -762,7 +762,7 @@ void GenerateTrainerHillFloorLayout(u16 *mapArg) for (y = 0; y < HILL_FLOOR_HEIGHT_MAIN; y++) { for (x = 0; x < HILL_FLOOR_WIDTH; x++) - dst[x] = GetMetatileForFloor(mapId, x, y, HILL_FLOOR_WIDTH); + dst[x] = GetMapDataForFloor(mapId, x, y, HILL_FLOOR_WIDTH); dst += 31; } diff --git a/src/trainer_see.c b/src/trainer_see.c index 0a3b68f8c2..cefb22eef4 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -457,7 +457,7 @@ static u8 CheckTrainer(u8 objectEventId) } } - if (InBattlePyramid()) + if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { if (GetBattlePyramidTrainerFlag(objectEventId)) return 0; diff --git a/src/wild_encounter.c b/src/wild_encounter.c index f77fe272d6..433bda003f 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -384,7 +384,7 @@ enum TimeOfDay GetTimeOfDayForEncounters(u32 headerId, enum WildPokemonArea area if (!OW_TIME_OF_DAY_ENCOUNTERS) return TIME_OF_DAY_DEFAULT; - if (InBattlePike() || InBattlePyramid()) + if (InBattlePike() || CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) { return OW_TIME_OF_DAY_FALLBACK; } @@ -411,7 +411,7 @@ enum TimeOfDay GetTimeOfDayForEncounters(u32 headerId, enum WildPokemonArea area } } - if (wildMonInfo == NULL && !OW_TIME_OF_DAY_DISABLE_FALLBACK) + if (wildMonInfo == NULL && !OW_TIME_OF_DAY_DISABLE_FALLBACK) return OW_TIME_OF_DAY_FALLBACK; else return timeOfDay; @@ -1044,7 +1044,7 @@ bool8 UpdateRepelCounter(void) u16 steps = REPEL_LURE_STEPS(repelLureVar); bool32 isLure = IS_LAST_USED_LURE(repelLureVar); - if (InBattlePike() || InBattlePyramid()) + if (InBattlePike() || CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) return FALSE; if (InUnionRoom() == TRUE) return FALSE; diff --git a/test/battle/ability/effect_spore.c b/test/battle/ability/effect_spore.c index 57f5399b53..ff61683b54 100644 --- a/test/battle/ability/effect_spore.c +++ b/test/battle/ability/effect_spore.c @@ -88,3 +88,21 @@ SINGLE_BATTLE_TEST("Effect Spore causes sleep 11% of the time") STATUS_ICON(player, sleep: TRUE); } } + +SINGLE_BATTLE_TEST("Effect Spore will check if it can inflict status onto attacker, not itself") +{ + PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); + GIVEN { + ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); + ASSUME(MoveMakesContact(MOVE_SCRATCH)); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRELOOM) { Status1(STATUS1_BURN); Ability(ABILITY_EFFECT_SPORE); } + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!"); + STATUS_ICON(player, sleep: TRUE); + } +} diff --git a/test/battle/ability/normalize.c b/test/battle/ability/normalize.c index 2a449f74a5..33fe89c587 100644 --- a/test/battle/ability/normalize.c +++ b/test/battle/ability/normalize.c @@ -156,53 +156,29 @@ SINGLE_BATTLE_TEST("Normalize boosts power of affected moves by 20% (Gen7+)", s1 } } -SINGLE_BATTLE_TEST("Normalize-affected moves become Electric-type under Electrify's effect", s16 damage) +SINGLE_BATTLE_TEST("Normalize-affected moves become Electric-type under Electrify's effect") { - u32 ability, genConfig; - PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_7; } - PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_6; } - PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_7; } - PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_6; } - GIVEN { ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); - WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, genConfig); - PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_WATER_GUN); } - OPPONENT(SPECIES_WOBBUFFET); + PLAYER(SPECIES_SKITTY) { Ability(ABILITY_NORMALIZE); } + OPPONENT(SPECIES_ROOKIDEE) { Item(ITEM_WACAN_BERRY); } } WHEN { TURN { MOVE(opponent, MOVE_ELECTRIFY); MOVE(player, MOVE_WATER_GUN); } } SCENE { - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - if (genConfig >= GEN_7) - EXPECT_EQ(results[0].damage, results[2].damage); - else - EXPECT_EQ(results[1].damage, results[3].damage); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); } } -SINGLE_BATTLE_TEST("Normalize-affected moves become Electric-type under Ion Deluge's effect", s16 damage) +SINGLE_BATTLE_TEST("Normalize-affected moves become Electric-type under Ion Deluge's effect") { - u32 ability, genConfig; - PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_7; } - PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_6; } - PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_7; } - PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_6; } - GIVEN { ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE); - WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, genConfig); - PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_WATER_GUN); } - OPPONENT(SPECIES_WOBBUFFET); + PLAYER(SPECIES_SKITTY) { Ability(ABILITY_NORMALIZE); Moves(MOVE_WATER_GUN); } + OPPONENT(SPECIES_ROOKIDEE) { Item(ITEM_WACAN_BERRY); } } WHEN { TURN { MOVE(opponent, MOVE_ION_DELUGE); MOVE(player, MOVE_WATER_GUN); } } SCENE { - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - if (genConfig >= GEN_7) - EXPECT_EQ(results[0].damage, results[2].damage); - else - EXPECT_EQ(results[1].damage, results[3].damage); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); } } diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 0c9e94695e..03334e04c2 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -1268,3 +1268,18 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI considers 0 hits to KO as los TURN { MOVE(player, MOVE_TACKLE); EXPECT_SEND_OUT(opponent, 2); } } } + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI sees Echoed Voice damage correctly") +{ + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_OMNISCIENT); + PLAYER(SPECIES_WOBBUFFET) { Speed(5); Moves(MOVE_SCRATCH, MOVE_ECHOED_VOICE); } + OPPONENT(SPECIES_ZIGZAGOON) { Speed(4); Level(55); Moves(MOVE_CELEBRATE); } + OPPONENT(SPECIES_DRAPION) { Speed(4); SpDefense(25); Moves(MOVE_WICKED_BLOW); Ability(ABILITY_SNIPER); } + OPPONENT(SPECIES_GASTLY) { Speed(4); Level(1); Moves(MOVE_TACKLE); } + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); EXPECT_MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_SCRATCH); EXPECT_MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_SCRATCH); EXPECT_MOVE(opponent, MOVE_CELEBRATE); EXPECT_SEND_OUT(opponent, 1); } + } +} diff --git a/test/battle/hold_effect/eject_button.c b/test/battle/hold_effect/eject_button.c index 9dd73833a5..681858605b 100644 --- a/test/battle/hold_effect/eject_button.c +++ b/test/battle/hold_effect/eject_button.c @@ -232,3 +232,21 @@ DOUBLE_BATTLE_TEST("Eject Button activation will not trigger an attack from the } } } + +SINGLE_BATTLE_TEST("Eject Button activates after Wandring Spirit") +{ + GIVEN { + PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_YAMASK_GALAR) { Item(ITEM_EJECT_BUTTON); Ability(ABILITY_WANDERING_SPIRIT); } + } WHEN { + TURN { + SWITCH(opponent, 1); + MOVE(player, MOVE_DRAGON_CLAW); + SEND_OUT(opponent, 0); + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CLAW, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + } +} diff --git a/test/battle/move_effect/leech_seed.c b/test/battle/move_effect/leech_seed.c index 56da50a12b..49f963f416 100644 --- a/test/battle/move_effect/leech_seed.c +++ b/test/battle/move_effect/leech_seed.c @@ -66,11 +66,11 @@ DOUBLE_BATTLE_TEST("Leech Seed will drain HP based on speed of the drained mon") OPPONENT(SPECIES_WYNAUT) { Speed(3); } OPPONENT(SPECIES_WOBBUFFET) { Speed(4); } } WHEN { - TURN { - MOVE(playerLeft, MOVE_LEECH_SEED, target: opponentLeft); - MOVE(playerRight, MOVE_LEECH_SEED, target: opponentRight); - MOVE(opponentLeft, MOVE_LEECH_SEED, target: playerLeft); - MOVE(opponentRight, MOVE_LEECH_SEED, target: playerRight); + TURN { + MOVE(playerLeft, MOVE_LEECH_SEED, target: opponentLeft); + MOVE(playerRight, MOVE_LEECH_SEED, target: opponentRight); + MOVE(opponentLeft, MOVE_LEECH_SEED, target: playerLeft); + MOVE(opponentRight, MOVE_LEECH_SEED, target: playerRight); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, opponentRight); @@ -88,6 +88,24 @@ DOUBLE_BATTLE_TEST("Leech Seed will drain HP based on speed of the drained mon") } } +SINGLE_BATTLE_TEST("Leech Seeded recovers health through Substitute") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SUBSTITUTE); } + TURN { MOVE(player, MOVE_LEECH_SEED); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUBSTITUTE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player); + HP_BAR(player); + HP_BAR(opponent); + HP_BAR(player); + } +} + TO_DO_BATTLE_TEST("Leech Seed doesn't affect already seeded targets") TO_DO_BATTLE_TEST("Leech Seed's effect is paused until a new battler replaces the original user's position") // Faint, can't be replaced, then revived. TO_DO_BATTLE_TEST("Leech Seed's effect pause still prevents it from being seeded again") diff --git a/test/battle/move_effect/magic_room.c b/test/battle/move_effect/magic_room.c index b1be6ac5bc..98d55cfd57 100644 --- a/test/battle/move_effect/magic_room.c +++ b/test/battle/move_effect/magic_room.c @@ -35,3 +35,5 @@ DOUBLE_BATTLE_TEST("Magic Room prevents item hold effects") ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight); } } + +TO_DO_BATTLE_TEST("TODO: Write Magic Room (Move Effect) test titles") diff --git a/test/battle/move_effect/magnet_rise.c b/test/battle/move_effect/magnet_rise.c index 9fde0046fd..7e50bb24cb 100644 --- a/test/battle/move_effect/magnet_rise.c +++ b/test/battle/move_effect/magnet_rise.c @@ -1,4 +1,57 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Magic Room (Move Effect) test titles") +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_MAGNET_RISE) == EFFECT_MAGNET_RISE); +} + +SINGLE_BATTLE_TEST("Magnet Rise rises the user into the air, avoiding Ground-type attacks") +{ + GIVEN { + ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(player, MOVE_MAGNET_RISE); MOVE(opponent, MOVE_EARTHQUAKE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGNET_RISE, player); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, opponent); + HP_BAR(player); + } + } +} + +SINGLE_BATTLE_TEST("Magnet Rise fails if the user is Rooted") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_INGRAIN) == EFFECT_INGRAIN); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(player, MOVE_INGRAIN); } + TURN { MOVE(player, MOVE_MAGNET_RISE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGNET_RISE, player); + } +} + +SINGLE_BATTLE_TEST("Magnet Rise fails if the user is Grounded by Smack Down") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SMACK_DOWN) == EFFECT_SMACK_DOWN); + ASSUME(gSpeciesInfo[SPECIES_XATU].types[0] == TYPE_FLYING || gSpeciesInfo[SPECIES_XATU].types[1] == TYPE_FLYING); + PLAYER(SPECIES_XATU); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(opponent, MOVE_SMACK_DOWN); MOVE(player, MOVE_MAGNET_RISE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SMACK_DOWN, opponent); + MESSAGE("Xatu fell straight down!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGNET_RISE, player); + } +} + +TO_DO_BATTLE_TEST("TODO: Write Magnet Rise (Move Effect) test titles") diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c index 09fc4c12bf..6dddfae4e7 100644 --- a/test/battle/move_effect/protect.c +++ b/test/battle/move_effect/protect.c @@ -194,6 +194,27 @@ SINGLE_BATTLE_TEST("Protect: Baneful Bunker poisons pokemon for moves making con } } +SINGLE_BATTLE_TEST("Protect: Baneful Bunker can't poison pokemon if they are already statused") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_WILL_O_WISP); } + TURN { MOVE(opponent, MOVE_BANEFUL_BUNKER); MOVE(player, MOVE_SCRATCH); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WILL_O_WISP, opponent); + STATUS_ICON(player, STATUS1_BURN); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BANEFUL_BUNKER, opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + HP_BAR(opponent); + STATUS_ICON(player, STATUS1_POISON); + } + } +} + SINGLE_BATTLE_TEST("Protect: Burning Bulwark burns pokemon for moves making contact") { u16 usedMove = MOVE_NONE; @@ -226,6 +247,27 @@ SINGLE_BATTLE_TEST("Protect: Burning Bulwark burns pokemon for moves making cont } } +SINGLE_BATTLE_TEST("Protect: Burning Bulwark can't burn pokemon if they are already statused") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TOXIC); } + TURN { MOVE(opponent, MOVE_BURNING_BULWARK); MOVE(player, MOVE_SCRATCH); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, opponent); + STATUS_ICON(player, STATUS1_TOXIC_POISON); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BURNING_BULWARK, opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + HP_BAR(opponent); + STATUS_ICON(player, STATUS1_BURN); + } + } +} + SINGLE_BATTLE_TEST("Protect: Recoil damage is not applied if target was protected") { u32 j, k; diff --git a/test/battle/move_effect/synthesis.c b/test/battle/move_effect/synthesis.c index 6799bd2870..954cf2e854 100644 --- a/test/battle/move_effect/synthesis.c +++ b/test/battle/move_effect/synthesis.c @@ -46,3 +46,21 @@ SINGLE_BATTLE_TEST("Synthesis recovers 1/4 of the user's max HP in Rain, Sandsto HP_BAR(player, damage: -(400 / 4)); } } + +SINGLE_BATTLE_TEST("Synthesis recovers regular amount in sandstorm if holding utility umbrella") +{ + u32 item; + PARAMETRIZE { item = ITEM_LIFE_ORB; } + PARAMETRIZE { item = ITEM_UTILITY_UMBRELLA; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { HP(1); MaxHP(400); Item(item); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SANDSTORM); MOVE(player, MOVE_SYNTHESIS); } + } SCENE { + if (item != ITEM_UTILITY_UMBRELLA) + HP_BAR(player, damage: -(400 / 4)); + else + HP_BAR(player, damage: -(400 / 2)); + } +} diff --git a/test/battle/move_effect/two_turns_attack.c b/test/battle/move_effect/two_turns_attack.c index 4dd79ade46..661a45c110 100644 --- a/test/battle/move_effect/two_turns_attack.c +++ b/test/battle/move_effect/two_turns_attack.c @@ -67,6 +67,36 @@ SINGLE_BATTLE_TEST("Razor Wind doesn't need to charge with Power Herb") } } +DOUBLE_BATTLE_TEST("Razor Wind successfully KOs both opponents") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_POWER_HERB); } + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_WYNAUT) { HP(1); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_RAZOR_WIND); } + } SCENE { + if (B_UPDATED_MOVE_DATA >= GEN_5) { + NOT MESSAGE("Wobbuffet whipped up a whirlwind!"); + MESSAGE("Wobbuffet used Razor Wind!"); + } else + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAZOR_WIND, playerLeft); + if (B_UPDATED_MOVE_DATA < GEN_5) + MESSAGE("Wobbuffet whipped up a whirlwind!"); + else + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAZOR_WIND, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft); + MESSAGE("Wobbuffet became fully charged due to its Power Herb!"); + if (B_UPDATED_MOVE_DATA < GEN_5) + MESSAGE("Wobbuffet used Razor Wind!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAZOR_WIND, playerLeft); + HP_BAR(opponentLeft); + MESSAGE("The opposing Wobbuffet fainted!"); + MESSAGE("The opposing Wynaut fainted!"); + } +} + SINGLE_BATTLE_TEST("Skull Bash needs a charging turn") { GIVEN { diff --git a/test/battle/move_effect_secondary/will_o_wisp.c b/test/battle/move_effect_secondary/will_o_wisp.c deleted file mode 100644 index 08b1bd6c69..0000000000 --- a/test/battle/move_effect_secondary/will_o_wisp.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "global.h" -#include "test/battle.h" - -TO_DO_BATTLE_TEST("TODO: Write Will-O-Wisp (Move Effect) test titles") diff --git a/test/battle/starting_status/terrain.c b/test/battle/starting_status/terrain.c index ab31bbbb96..3d84dba000 100644 --- a/test/battle/starting_status/terrain.c +++ b/test/battle/starting_status/terrain.c @@ -29,19 +29,20 @@ SINGLE_BATTLE_TEST("B_VAR_STARTING_STATUS starts a chosen terrain at the beginni TURN { ; } TURN { ; } } SCENE { - switch (terrain) { - case STARTING_STATUS_GRASSY_TERRAIN: - MESSAGE("Grass grew to cover the battlefield!"); - break; - case STARTING_STATUS_PSYCHIC_TERRAIN: - MESSAGE("The battlefield got weird!"); - break; - case STARTING_STATUS_MISTY_TERRAIN: - MESSAGE("Mist swirled around the battlefield!"); - break; - case STARTING_STATUS_ELECTRIC_TERRAIN: - MESSAGE("An electric current is running across the battlefield!"); - break; + switch (terrain) + { + case STARTING_STATUS_GRASSY_TERRAIN: + MESSAGE("The battlefield is covered with grass!"); + break; + case STARTING_STATUS_PSYCHIC_TERRAIN: + MESSAGE("The battlefield seems weird!"); + break; + case STARTING_STATUS_MISTY_TERRAIN: + MESSAGE("Mist swirls around the battlefield!"); + break; + case STARTING_STATUS_ELECTRIC_TERRAIN: + MESSAGE("An electric current is running across the battlefield!"); + break; } ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_RESTORE_BG); NONE_OF { diff --git a/tools/gbagfx/main.c b/tools/gbagfx/main.c index bb1691c59a..6502b87d6b 100644 --- a/tools/gbagfx/main.c +++ b/tools/gbagfx/main.c @@ -333,6 +333,9 @@ void HandleJascToGbaPaletteCommand(char *inputPath, char *outputPath, int argc, if (numColors < 1) FATAL_ERROR("Number of colors must be positive.\n"); + + if (numColors > 255) + FATAL_ERROR("Number of colors must be less than 256.\n"); } else { diff --git a/tools/preproc/asm_file.cpp b/tools/preproc/asm_file.cpp index 66667935a1..69b412b24e 100644 --- a/tools/preproc/asm_file.cpp +++ b/tools/preproc/asm_file.cpp @@ -679,7 +679,7 @@ void AsmFile::RaiseWarning(const char* format, ...) int AsmFile::SkipWhitespaceAndEol() { int newlines = 0; - while (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' ' || m_buffer[m_pos] == '\n') + while (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' ' || m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') { if (m_buffer[m_pos] == '\n') newlines++; diff --git a/tools/preproc/preproc.cpp b/tools/preproc/preproc.cpp index 20c2de51b6..ac9496d701 100644 --- a/tools/preproc/preproc.cpp +++ b/tools/preproc/preproc.cpp @@ -26,6 +26,11 @@ #include "c_file.h" #include "charmap.h" +#ifdef _WIN32 +#include +#include +#endif + static void UsageAndExit(const char *program); Charmap* g_charmap; @@ -179,6 +184,11 @@ int main(int argc, char **argv) g_charmap = new Charmap(charmap); +#ifdef _WIN32 + // On Windows, piping from stdout can break newlines. Treat stdout as binary stream to avoid this. + _setmode(_fileno(stdout), _O_BINARY); +#endif + const char* extension = GetFileExtension(source); if (!extension)