diff --git a/include/gen2/Gen2Common.h b/include/gen2/Gen2Common.h index 7173e6c..5d30355 100644 --- a/include/gen2/Gen2Common.h +++ b/include/gen2/Gen2Common.h @@ -6,6 +6,16 @@ class Gen2GameReader; class ISaveManager; +// source: https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_II) +#define CRYSTAL_ITEM_ID_GS_BALL 0x73 + +// Based on https://github.com/kwsch/PKHeX/blob/master/PKHeX.Core/Resources/text/script/gen2/flags_c_en.txt +// Look at this file to see more events +#define CRYSTAL_EVENTFLAG_KURT_CAN_CHECK_GSBALL 190 +#define CRYSTAL_EVENTFLAG_KURT_READY_TO_RETURN_GSBALL 191 +#define CRYSTAL_EVENTFLAG_GSBALL_USABLE_IN_ILEX_FOREST_SHRINE 192 +#define CRYSTAL_EVENTFLAG_RECEIVED_GSBALL 832 + enum class Gen2GameType { INVALID, diff --git a/include/gen2/Gen2GameReader.h b/include/gen2/Gen2GameReader.h index b95b233..9bce5a4 100644 --- a/include/gen2/Gen2GameReader.h +++ b/include/gen2/Gen2GameReader.h @@ -181,15 +181,33 @@ public: /** * @brief Unlocks the GS Ball event in Pokemon crystal + * Note: this function is made to be repeatable: it removes an existing GS Ball entry first and resets all the + * GS ball related event flags. + * + * This is for 2 reasons: I screwed up my first versions of PokeMe64: they only gave you the GS Ball item, but didn't + * change any of the event flags. Obviously this has changed now. + * + * Therefore after executing this function, the GS Ball event stats from the beginning again: + * you can get a GS Ball by leaving the Golden Rod Pokemon center, even if you had done the event before + * + * Secondly, it's just nice to be able to trigger the GS Ball/Celebi event more than once. + * + * Don't forget to call finishSave() after using this function! */ void unlockGsBallEvent(); /** * @brief Retrieves the value of the given event flag + * Hint: You can find the number and meaning of various event flags here: + * https://github.com/kwsch/PKHeX/blob/master/PKHeX.Core/Resources/text/script/gen2/flags_c_en.txt */ bool getEventFlag(uint16_t flagNumber); /** * @brief Sets the value of the given event flag number + * Hint: You can find the number and meaning of different event flags here: + * https://github.com/kwsch/PKHeX/blob/master/PKHeX.Core/Resources/text/script/gen2/flags_c_en.txt + * + * Don't forget to call finishSave() after using this function! */ void setEventFlag(uint16_t flagNumber, bool enabled); protected: diff --git a/src/gen2/Gen2GameReader.cpp b/src/gen2/Gen2GameReader.cpp index 4db0409..805fbb7 100644 --- a/src/gen2/Gen2GameReader.cpp +++ b/src/gen2/Gen2GameReader.cpp @@ -695,8 +695,29 @@ bool Gen2GameReader::isGameCrystal() const void Gen2GameReader::unlockGsBallEvent() { + if(!isGameCrystal()) + { + return; + } + + // let's remove the GS ball from the players' inventory first (if it exists) + // this is to cover up my earlier fuck up with PokeMe64 which only handed out the item. + // it also is part of making the event repeatable. + Gen2ItemList itemList = getItemList(Gen2ItemListType::GEN2_ITEMLISTTYPE_KEYITEMPOCKET); + itemList.remove(CRYSTAL_ITEM_ID_GS_BALL); + + // now let's reset the GS Ball related event flags (to make the event repeatable) + setEventFlag(CRYSTAL_EVENTFLAG_RECEIVED_GSBALL, false); + setEventFlag(CRYSTAL_EVENTFLAG_KURT_CAN_CHECK_GSBALL, false); + setEventFlag(CRYSTAL_EVENTFLAG_KURT_READY_TO_RETURN_GSBALL, false); + setEventFlag(CRYSTAL_EVENTFLAG_GSBALL_USABLE_IN_ILEX_FOREST_SHRINE, false); + + // unlock the event itself. This triggers the NPC to stop you when trying to leave the Golden Rod pokémon center + // to give you the GS Ball. + // to be honest I have no clue what the exact meaning of this byte is. But hey, it works! saveManager_.seek(0x3E3C); saveManager_.writeByte(0xB); + // this is a mirror of the previous byte. It's supposedly not needed. But let's just set it to be safe. saveManager_.seek(0x3E44); saveManager_.writeByte(0xB); }