├── nbproject ├── private │ ├── config.properties │ ├── private.properties │ └── private.xml ├── genfiles.properties ├── project.xml └── project.properties ├── .gitignore ├── src ├── res │ ├── map.png │ ├── icon.png │ ├── items.png │ ├── mapPoint.png │ ├── tl_info.png │ ├── tl_open.png │ ├── tl_save.png │ ├── tilesets │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 23.png │ │ ├── 24.png │ │ ├── 25.png │ │ ├── 26.png │ │ ├── 27.png │ │ ├── 28.png │ │ ├── 29.png │ │ ├── 3.png │ │ ├── 30.png │ │ ├── 31.png │ │ ├── 32.png │ │ ├── 33.png │ │ ├── 34.png │ │ ├── 35.png │ │ ├── 36.png │ │ ├── 37.png │ │ ├── 38.png │ │ ├── 39.png │ │ ├── 4.png │ │ ├── 40.png │ │ ├── 41.png │ │ ├── 42.png │ │ ├── 43.png │ │ ├── 44.png │ │ ├── 45.png │ │ ├── 46.png │ │ ├── 47.png │ │ ├── 48.png │ │ ├── 49.png │ │ ├── 5.png │ │ ├── 50.png │ │ ├── 51.png │ │ ├── 52.png │ │ ├── 53.png │ │ ├── 54.png │ │ ├── 55.png │ │ ├── 56.png │ │ ├── 57.png │ │ ├── 58.png │ │ ├── 59.png │ │ ├── 6.png │ │ ├── 60.png │ │ ├── 61.png │ │ ├── 62.png │ │ ├── 63.png │ │ ├── 64.png │ │ ├── 65.png │ │ ├── 66.png │ │ ├── 67.png │ │ ├── 68.png │ │ ├── 69.png │ │ ├── 7.png │ │ ├── 70.png │ │ ├── 71.png │ │ ├── 72.png │ │ ├── 73.png │ │ ├── 74.png │ │ ├── 75.png │ │ ├── 8.png │ │ └── 9.png │ ├── tl_cancel.png │ ├── tl_save-as.png │ ├── traps │ │ ├── grimy.png │ │ ├── gust.png │ │ ├── mud.png │ │ ├── seal.png │ │ ├── slow.png │ │ ├── spin.png │ │ ├── trip.png │ │ ├── warp.png │ │ ├── zero.png │ │ ├── pitfall.png │ │ ├── poison.png │ │ ├── pokemon.png │ │ ├── slumber.png │ │ ├── spiked.png │ │ ├── sticky.png │ │ ├── summon.png │ │ ├── wonder.png │ │ ├── chestnut.png │ │ ├── explosion.png │ │ └── selfdestruct.png │ ├── tl_to-editor.png │ ├── mapPointSelected.png │ └── lists │ │ ├── types.txt │ │ ├── areas.txt │ │ ├── abilities.txt │ │ ├── dungeons.txt │ │ ├── items.txt │ │ ├── pokemon.txt │ │ └── moves.txt └── com │ └── aurum │ └── mystery2 │ ├── ByteOrder.java │ ├── swing │ ├── DungeonItemsEditor.java │ ├── ExclusivePokemonEditor.java │ ├── JPropertyPanel.java │ ├── AreaEditor.java │ ├── DungeonPokemonEditor.java │ ├── MoneyEditor.java │ ├── CalcProbability.java │ ├── MoneyEditor.form │ ├── AbstractEditor.java │ ├── CalcProbability.form │ ├── MapEditor.java │ ├── AbstractEditor.form │ ├── ItemEditor.java │ └── MoveEditor.java │ ├── game │ ├── DungeonItems.java │ ├── Area.java │ ├── ExclusivePokemon.java │ ├── Floor.java │ ├── DungeonTraps.java │ ├── Item.java │ ├── Dungeon.java │ ├── DungeonLayout.java │ ├── DungeonPokemon.java │ ├── Pokemon.java │ ├── Move.java │ └── RomFile.java │ ├── Lists.java │ ├── exception │ └── UncaughtExceptionHandler.java │ └── BitConverter.java ├── lib └── ini4j-0.5.4.jar ├── manifest.mf ├── README.md └── B24_offsets.ini /nbproject/private/config.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /dist/ 3 | /doc/ 4 | /test/ 5 | /_SCREENS/ 6 | /_TESTS/ -------------------------------------------------------------------------------- /src/res/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/map.png -------------------------------------------------------------------------------- /src/res/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/icon.png -------------------------------------------------------------------------------- /src/res/items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/items.png -------------------------------------------------------------------------------- /lib/ini4j-0.5.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/lib/ini4j-0.5.4.jar -------------------------------------------------------------------------------- /src/res/mapPoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/mapPoint.png -------------------------------------------------------------------------------- /src/res/tl_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tl_info.png -------------------------------------------------------------------------------- /src/res/tl_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tl_open.png -------------------------------------------------------------------------------- /src/res/tl_save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tl_save.png -------------------------------------------------------------------------------- /src/res/tilesets/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/0.png -------------------------------------------------------------------------------- /src/res/tilesets/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/1.png -------------------------------------------------------------------------------- /src/res/tilesets/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/10.png -------------------------------------------------------------------------------- /src/res/tilesets/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/11.png -------------------------------------------------------------------------------- /src/res/tilesets/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/12.png -------------------------------------------------------------------------------- /src/res/tilesets/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/13.png -------------------------------------------------------------------------------- /src/res/tilesets/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/14.png -------------------------------------------------------------------------------- /src/res/tilesets/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/15.png -------------------------------------------------------------------------------- /src/res/tilesets/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/16.png -------------------------------------------------------------------------------- /src/res/tilesets/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/17.png -------------------------------------------------------------------------------- /src/res/tilesets/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/18.png -------------------------------------------------------------------------------- /src/res/tilesets/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/19.png -------------------------------------------------------------------------------- /src/res/tilesets/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/2.png -------------------------------------------------------------------------------- /src/res/tilesets/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/20.png -------------------------------------------------------------------------------- /src/res/tilesets/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/21.png -------------------------------------------------------------------------------- /src/res/tilesets/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/22.png -------------------------------------------------------------------------------- /src/res/tilesets/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/23.png -------------------------------------------------------------------------------- /src/res/tilesets/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/24.png -------------------------------------------------------------------------------- /src/res/tilesets/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/25.png -------------------------------------------------------------------------------- /src/res/tilesets/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/26.png -------------------------------------------------------------------------------- /src/res/tilesets/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/27.png -------------------------------------------------------------------------------- /src/res/tilesets/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/28.png -------------------------------------------------------------------------------- /src/res/tilesets/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/29.png -------------------------------------------------------------------------------- /src/res/tilesets/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/3.png -------------------------------------------------------------------------------- /src/res/tilesets/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/30.png -------------------------------------------------------------------------------- /src/res/tilesets/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/31.png -------------------------------------------------------------------------------- /src/res/tilesets/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/32.png -------------------------------------------------------------------------------- /src/res/tilesets/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/33.png -------------------------------------------------------------------------------- /src/res/tilesets/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/34.png -------------------------------------------------------------------------------- /src/res/tilesets/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/35.png -------------------------------------------------------------------------------- /src/res/tilesets/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/36.png -------------------------------------------------------------------------------- /src/res/tilesets/37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/37.png -------------------------------------------------------------------------------- /src/res/tilesets/38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/38.png -------------------------------------------------------------------------------- /src/res/tilesets/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/39.png -------------------------------------------------------------------------------- /src/res/tilesets/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/4.png -------------------------------------------------------------------------------- /src/res/tilesets/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/40.png -------------------------------------------------------------------------------- /src/res/tilesets/41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/41.png -------------------------------------------------------------------------------- /src/res/tilesets/42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/42.png -------------------------------------------------------------------------------- /src/res/tilesets/43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/43.png -------------------------------------------------------------------------------- /src/res/tilesets/44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/44.png -------------------------------------------------------------------------------- /src/res/tilesets/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/45.png -------------------------------------------------------------------------------- /src/res/tilesets/46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/46.png -------------------------------------------------------------------------------- /src/res/tilesets/47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/47.png -------------------------------------------------------------------------------- /src/res/tilesets/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/48.png -------------------------------------------------------------------------------- /src/res/tilesets/49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/49.png -------------------------------------------------------------------------------- /src/res/tilesets/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/5.png -------------------------------------------------------------------------------- /src/res/tilesets/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/50.png -------------------------------------------------------------------------------- /src/res/tilesets/51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/51.png -------------------------------------------------------------------------------- /src/res/tilesets/52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/52.png -------------------------------------------------------------------------------- /src/res/tilesets/53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/53.png -------------------------------------------------------------------------------- /src/res/tilesets/54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/54.png -------------------------------------------------------------------------------- /src/res/tilesets/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/55.png -------------------------------------------------------------------------------- /src/res/tilesets/56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/56.png -------------------------------------------------------------------------------- /src/res/tilesets/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/57.png -------------------------------------------------------------------------------- /src/res/tilesets/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/58.png -------------------------------------------------------------------------------- /src/res/tilesets/59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/59.png -------------------------------------------------------------------------------- /src/res/tilesets/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/6.png -------------------------------------------------------------------------------- /src/res/tilesets/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/60.png -------------------------------------------------------------------------------- /src/res/tilesets/61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/61.png -------------------------------------------------------------------------------- /src/res/tilesets/62.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/62.png -------------------------------------------------------------------------------- /src/res/tilesets/63.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/63.png -------------------------------------------------------------------------------- /src/res/tilesets/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/64.png -------------------------------------------------------------------------------- /src/res/tilesets/65.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/65.png -------------------------------------------------------------------------------- /src/res/tilesets/66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/66.png -------------------------------------------------------------------------------- /src/res/tilesets/67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/67.png -------------------------------------------------------------------------------- /src/res/tilesets/68.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/68.png -------------------------------------------------------------------------------- /src/res/tilesets/69.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/69.png -------------------------------------------------------------------------------- /src/res/tilesets/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/7.png -------------------------------------------------------------------------------- /src/res/tilesets/70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/70.png -------------------------------------------------------------------------------- /src/res/tilesets/71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/71.png -------------------------------------------------------------------------------- /src/res/tilesets/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/72.png -------------------------------------------------------------------------------- /src/res/tilesets/73.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/73.png -------------------------------------------------------------------------------- /src/res/tilesets/74.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/74.png -------------------------------------------------------------------------------- /src/res/tilesets/75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/75.png -------------------------------------------------------------------------------- /src/res/tilesets/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/8.png -------------------------------------------------------------------------------- /src/res/tilesets/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tilesets/9.png -------------------------------------------------------------------------------- /src/res/tl_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tl_cancel.png -------------------------------------------------------------------------------- /src/res/tl_save-as.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tl_save-as.png -------------------------------------------------------------------------------- /src/res/traps/grimy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/grimy.png -------------------------------------------------------------------------------- /src/res/traps/gust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/gust.png -------------------------------------------------------------------------------- /src/res/traps/mud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/mud.png -------------------------------------------------------------------------------- /src/res/traps/seal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/seal.png -------------------------------------------------------------------------------- /src/res/traps/slow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/slow.png -------------------------------------------------------------------------------- /src/res/traps/spin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/spin.png -------------------------------------------------------------------------------- /src/res/traps/trip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/trip.png -------------------------------------------------------------------------------- /src/res/traps/warp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/warp.png -------------------------------------------------------------------------------- /src/res/traps/zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/zero.png -------------------------------------------------------------------------------- /src/res/tl_to-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/tl_to-editor.png -------------------------------------------------------------------------------- /src/res/traps/pitfall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/pitfall.png -------------------------------------------------------------------------------- /src/res/traps/poison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/poison.png -------------------------------------------------------------------------------- /src/res/traps/pokemon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/pokemon.png -------------------------------------------------------------------------------- /src/res/traps/slumber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/slumber.png -------------------------------------------------------------------------------- /src/res/traps/spiked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/spiked.png -------------------------------------------------------------------------------- /src/res/traps/sticky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/sticky.png -------------------------------------------------------------------------------- /src/res/traps/summon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/summon.png -------------------------------------------------------------------------------- /src/res/traps/wonder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/wonder.png -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /src/res/mapPointSelected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/mapPointSelected.png -------------------------------------------------------------------------------- /src/res/traps/chestnut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/chestnut.png -------------------------------------------------------------------------------- /src/res/traps/explosion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/explosion.png -------------------------------------------------------------------------------- /src/res/traps/selfdestruct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunakazeKun/PMDe/HEAD/src/res/traps/selfdestruct.png -------------------------------------------------------------------------------- /src/res/lists/types.txt: -------------------------------------------------------------------------------- 1 | None 2 | Normal 3 | Fire 4 | Water 5 | Grass 6 | Electric 7 | Ice 8 | Fighting 9 | Poison 10 | Ground 11 | Flying 12 | Psychic 13 | Bug 14 | Rock 15 | Ghost 16 | Dragon 17 | Dark 18 | Steel -------------------------------------------------------------------------------- /nbproject/private/private.properties: -------------------------------------------------------------------------------- 1 | compile.on.save=true 2 | do.depend=false 3 | do.jar=true 4 | javac.debug=true 5 | javadoc.preview=true 6 | user.properties.file=C:\\Users\\Aurum\\AppData\\Roaming\\NetBeans\\8.2\\build.properties 7 | -------------------------------------------------------------------------------- /nbproject/private/private.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=2b4284fc 2 | build.xml.script.CRC32=eb9d1f4a 3 | build.xml.stylesheet.CRC32=8064a381@1.80.1.48 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=c8ac52f0 7 | nbproject/build-impl.xml.script.CRC32=5e6114d7 8 | nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48 9 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | Mystery2 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Riivotree 17 | jar 18 | 19 | jar 20 | clean 21 | jar 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/res/lists/areas.txt: -------------------------------------------------------------------------------- 1 | None 2 | Bountiful Sea 3 | Treasure Sea 4 | Serene Sea 5 | Deep-Sea Floor 6 | Deep-Sea Current 7 | Seafloor Cave 8 | Shallow Beach 9 | Mt. Deepgreen 10 | Mt. Cleft 11 | Mt. Moonview 12 | Rainbow Peak 13 | Wild Plains 14 | Beau Plains 15 | Sky Blue Plains 16 | Safari 17 | Scorched Plains 18 | Sacred Field 19 | Mist-Rise Forest 20 | Flyaway Forest 21 | Overgrown Forest 22 | Energetic Forest 23 | Mushroom Forest 24 | Healing Forest 25 | Transform Forest 26 | Secretive Forest 27 | Rub-a-Dub River 28 | Tadpole Pond 29 | Turtleshell Pond 30 | Mystic Lake 31 | Waterfall Lake 32 | Peanut Swamp 33 | Poison Swamp 34 | Echo Cave 35 | Cryptic Cave 36 | Dragon Cave 37 | Boulder Cave 38 | Jungle 39 | Decrepit Lab 40 | Mt. Discipline 41 | Thunder Meadow 42 | Power Plant 43 | Crater 44 | Furnace Desert 45 | Aged Chamber AN 46 | Aged Chamber O? 47 | Ancient Relic 48 | Darkness Ridge 49 | Frigid Cavern 50 | Ice Floe Beach 51 | Volcanic Pit 52 | Stratos Lookout 53 | Ravaged Field 54 | Magnetic Quarry 55 | Legendary Island 56 | Southern Island 57 | Enclosed Island 58 | Final Island -------------------------------------------------------------------------------- /src/res/lists/abilities.txt: -------------------------------------------------------------------------------- 1 | ------- 2 | Stench 3 | Thick Fat 4 | Rain Dish 5 | Drizzle 6 | Arena Trap 7 | Intimidate 8 | Rock Head 9 | Air Lock 10 | Hyper Cutter 11 | Shadow Tag 12 | Speed Boost 13 | Battle Armor 14 | Sturdy 15 | Suction Cups 16 | Clear Body 17 | Torrent 18 | Guts 19 | Rough Skin 20 | Shell Armor 21 | Natural Cure 22 | Damp 23 | Limber 24 | Magnet Pull 25 | White Smoke 26 | Synchronize 27 | Overgrown 28 | Swift Swim 29 | Sand Stream 30 | Sand Veil 31 | Keen Eye 32 | Inner Focus 33 | Static 34 | Shed Skin 35 | Huge Power 36 | Volt Absorb 37 | Water Absorb 38 | Forecast 39 | Serene Grace 40 | Poison Point 41 | Trace 42 | Oblivious 43 | Truant 44 | Run Away 45 | Sticky Hold 46 | Cloud Nine 47 | Illuminate 48 | Early Bird 49 | Hustle 50 | Drought 51 | Lightningrod 52 | Compoundeyes 53 | Marvel Scale 54 | Wonder Guard 55 | Insomnia 56 | Levitate 57 | Plus 58 | Pressure 59 | Liquid Ooze 60 | Color Change 61 | Soundproof 62 | Effect Spore 63 | Flame Body 64 | Minus 65 | Own Tempo 66 | Magma Armor 67 | Water Veil 68 | Swarm 69 | Cute Charm 70 | Immunity 71 | Blaze 72 | Pickup 73 | Flash Fire 74 | Vital Spirit 75 | Chlorophyll 76 | Pure Power 77 | Shield Dust -------------------------------------------------------------------------------- /src/res/lists/dungeons.txt: -------------------------------------------------------------------------------- 1 | Tiny Woods 2 | Thunderwave Cave 3 | Mt. Steel 4 | Sinister Woods 5 | Silent Chasm 6 | Mt. Thunder 7 | Mt. Thunder Peak 8 | Great Canyon 9 | Lapis Cave 10 | Mt. Blaze 11 | Mt. Blaze Peak 12 | Frosty Forest 13 | Frosty Grotto 14 | Mt. Freeze 15 | Mt. Freeze Peak 16 | Magma Cavern 17 | Magma Cavern Pit 18 | Sky Tower 19 | Sky Tower Summit 20 | Stormy Sea 21 | Silver Trench 22 | Meteor Cave 23 | Mt. Freeze Peak 24 | Western Cave 25 | Boss 3 26 | Boss 4 27 | Wish Cave 28 | Buried Relic 29 | Pitfall Valley 30 | Northern Range 31 | Boss 9 32 | Desert Region 33 | Southern Cavern 34 | Wyvern Hill 35 | Fiery Field 36 | Northwind Field 37 | Solar Cave 38 | Lightning Field 39 | Darknight Relic 40 | Wondrous Sea 41 | Murky Cave 42 | Grand Sea 43 | Uproar Forest 44 | Oddity Cave 45 | Remains Island 46 | Marvelous Sea 47 | Fantasy Strait 48 | Rock Path 49 | Snow Path 50 | Autopilot 51 | D50 52 | D51 53 | Dojo Registration 54 | Howling Forest 55 | D54 56 | Fantasy Strait 57 | Waterfall Pond 58 | Unown Relic 59 | Joyous Tower 60 | Far-off Sea 61 | Mt. Faraway 62 | D61 63 | Purity Forest 64 | D63 65 | ??? 66 | Tiny Woods 67 | Unknown World 68 | Frosty Grotto 69 | Howling Forest 70 | Pokémon Square 71 | Pokémon Square 72 | Rescue Team Base 73 | Rescue Team Base 74 | agb-slot 75 | Client Pokémon 76 | Normal Maze 77 | Fire Maze 78 | Water Maze 79 | Grass Maze 80 | Electric Maze 81 | Ice Maze 82 | Fighting Maze 83 | Ground Maze 84 | Flying Maze 85 | Psychic Maze 86 | Poison Maze 87 | Bug Maze 88 | Rock Maze 89 | Ghost Maze 90 | Dragon Maze 91 | Dark Maze 92 | Steel Maze 93 | Team Shifty 94 | Team Constrictor 95 | Team Hydro 96 | Team Rumblerock 97 | Rescue Team 2 98 | Rescue Team Maze -------------------------------------------------------------------------------- /src/com/aurum/mystery2/ByteOrder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2; 19 | 20 | public enum ByteOrder { 21 | BIG_ENDIAN (new byte[] { (byte) 0xFE, (byte) 0xFF }), // Left to right 22 | LITTLE_ENDIAN (new byte[] { (byte) 0xFF, (byte) 0xFE }); // Right to left 23 | 24 | private final byte[] bom; 25 | private ByteOrder(byte[] identifier) { 26 | this.bom = identifier; 27 | } 28 | 29 | /** 30 | * Returns the BOM. 31 | * @return the BOM. 32 | */ 33 | public byte[] getBOM() { 34 | return bom; 35 | } 36 | 37 | /** 38 | * Returns the byte order for the given BOM. 39 | * @param bom the identifier 40 | * @return the byte order for the given BOM. 41 | */ 42 | public static ByteOrder getByteOrder(byte[] bom) { 43 | return (bom == BIG_ENDIAN.bom) ? BIG_ENDIAN : 44 | (bom == LITTLE_ENDIAN.bom) ? LITTLE_ENDIAN : null; 45 | } 46 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/DungeonItemsEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import com.aurum.mystery2.game.DungeonItems; 21 | import com.aurum.mystery2.game.RomFile; 22 | import javax.swing.DefaultListModel; 23 | 24 | public class DungeonItemsEditor extends AbstractEditor { 25 | private DungeonItems selected; 26 | private DungeonItems.Entry selectedEntry; 27 | private DefaultListModel entryModel; 28 | 29 | public DungeonItemsEditor() { 30 | this(-1); 31 | } 32 | 33 | public DungeonItemsEditor(int items) { 34 | for (int i = 0 ; i < RomFile.current.dungeonItems.size() ; i++) 35 | model.addElement("Items no. " + i); 36 | 37 | list.setSelectedIndex(items); 38 | list.ensureIndexIsVisible(items); 39 | } 40 | 41 | @Override 42 | protected void initProperties() { 43 | setTitle("Dungeon items editor"); 44 | 45 | // Initialize the components 46 | // Add the components to the property panel 47 | } 48 | 49 | @Override 50 | protected void load() { 51 | } 52 | 53 | @Override 54 | protected void save() { 55 | } 56 | 57 | @Override 58 | protected void warningLabel() {} 59 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PMDe 2 | **PMDe** is an editor for **Pokémon Mystery Dungeon: Red Rescue Team**, that allows you to edit most aspects of the game; a full list of features can be found below. It is programmed in Java and developed using the Netbeans IDE. 3 | PMDe uses **ini4j** to store important offsets in the ROM. Additional icons were taken from various **Pretty Office Icons** sets. Tileset previews were created by **SilverDeoxys563**. Also, huge thanks to **BRNMan** and **Crocodile91**! They have already documented a lot about the game's data and ROM structure. 4 | 5 | # Current features 6 | - edit dungeon data (map positions, floors, layouts, Pokémon, traps, ...) 7 | - edit Pokémon data (types, stats, evolutions, ...) 8 | - edit item data 9 | - edit moves data 10 | - edit friend area data (price, unlock conditions, ...) 11 | - edit available starter and partner Pokémon 12 | - edit POKé money factors 13 | 14 | # Supported ROMs 15 | | Game ID | Description | MD5 Checksum | 16 | | -- | ----------- | -------- | 17 | | B24E01 | Pokémon Mystery Dungeon: Red Rescue Team (US) | 2100cf6f17e12cd34f1513647dfa506b | 18 | | B24P01 | Pokémon Mystery Dungeon: Red Rescue Team (EU) | 9837da1fdfe900c52f2109d9718d4e85 | 19 | | B24J01 | Pokémon Fushigi no Dungeon: Aka no Kyuujoutai (JP) | f3647154d85d20f9c8ba66ed8f0a609e | 20 | | B9JE01 | Pokémon Mystery Dungeon: Red Rescue Team (Demo Version) | 779a2a4435e0093a7846798270705c76 | 21 | 22 | # Screenshots 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/DungeonItems.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import java.util.List; 21 | import com.aurum.mystery2.ByteBuffer; 22 | import com.aurum.mystery2.ByteOrder; 23 | 24 | public class DungeonItems implements Cloneable { 25 | // Entry fields 26 | public List entries; 27 | 28 | // Other fields 29 | public int offset; 30 | 31 | // Static fields 32 | 33 | public static class Entry implements Cloneable { 34 | @Override 35 | public Object clone() { 36 | try { 37 | return super.clone(); 38 | } 39 | catch (CloneNotSupportedException ex) { 40 | return null; 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public Object clone() { 47 | try { 48 | return super.clone(); 49 | } 50 | catch (CloneNotSupportedException ex) { 51 | return null; 52 | } 53 | } 54 | 55 | public static DungeonItems unpack(ByteBuffer buffer) { 56 | DungeonItems items = new DungeonItems(); 57 | 58 | items.offset = buffer.position(); 59 | 60 | return items; 61 | } 62 | 63 | public static byte[] pack(DungeonItems pokemon) { 64 | ByteBuffer buffer = new ByteBuffer(-1, ByteOrder.LITTLE_ENDIAN); 65 | return buffer.getBuffer(); 66 | } 67 | } -------------------------------------------------------------------------------- /B24_offsets.ini: -------------------------------------------------------------------------------- 1 | [B24E01] 2 | description = Pok\u00E9mon Mystery Dungeon: Red Rescue Team (US) 3 | dungeonPointerOffset = 0x004A2BF4 4 | pokemonPointerOffset = 0x00357B88 5 | itemPointerOffset = 0x00306570 6 | dungeonMainOffset = 0x00109D30 7 | dungeonFloorsPointerOffset = 0x000902BC 8 | dungeonMapOffset = 0x000D3F14 9 | pokemonStartersOffset = 0x000F278E 10 | pokemonPartnersOffset = 0x000F4264 11 | exclusivePokemonOffset = 0x0010AD0C 12 | areasTextOffset = 0x001139D0 13 | areasMainOffset = 0x0010AA90 14 | movesOffset = 0x003679A0 15 | moneyOffset = 0x0010A3F0 16 | 17 | [B24P01] 18 | description = Pok\u00E9mon Mystery Dungeon: Red Rescue Team (EU) 19 | dungeonPointerOffset = 0x007343A4 20 | pokemonPointerOffset = 0x005FAC6C 21 | itemPointerOffset = 0x005B0940 22 | dungeonMainOffset = 0x00271D98 23 | dungeonFloorsPointerOffset = 0x000961A4 24 | dungeonMapOffset = 0x001ADD6C 25 | pokemonStartersOffset = 0x001B683A 26 | pokemonPartnersOffset = 0x001B68B0 27 | exclusivePokemonOffset = 0x00272D74 28 | areasMainOffset = 0x00272AF8 29 | movesOffset = 0x0060AA84 30 | moneyOffset = 0x00272458 31 | 32 | [B24J01] 33 | description = Pok\u00E9mon Fushigi no Dungeon: Aka no Kyuujoutai (JP) 34 | isJapanese = true 35 | dungeonPointerOffset = 0x004C9EAC 36 | pokemonPointerOffset = 0x00355130 37 | itemPointerOffset = 0x00306670 38 | dungeonMainOffset = 0x0010CC78 39 | dungeonFloorsPointerOffset = 0x0008FD88 40 | dungeonMapOffset = 0x000D4540 41 | pokemonStartersOffset = 0x000F4C14 42 | pokemonPartnersOffset = 0x000F64E4 43 | exclusivePokemonOffset = 0x0010DC4C 44 | areasTextOffset = 0x00116F00 45 | areasMainOffset = 0x0010D9D0 46 | movesOffset = 0x003653D4 47 | moneyOffset = 0x0010D330 48 | 49 | [B9JE01] 50 | description = Pok\u00E9mon Mystery Dungeon: Red Rescue Team (Demo Version) 51 | dungeonPointerOffset = 0x004A2BF4 52 | pokemonPointerOffset = 0x00357B88 53 | itemPointerOffset = 0x00306570 54 | dungeonMainOffset = 0x0010A95C 55 | dungeonFloorsPointerOffset = 0x00090020 56 | dungeonMapOffset = 0x000D4B30 57 | pokemonStartersOffset = 0x000F33A2 58 | pokemonPartnersOffset = 0x000F4E78 59 | exclusivePokemonOffset = 0x0010B938 60 | areasTextOffset = 0x001145FC 61 | areasMainOffset = 0x0010B6BC 62 | movesOffset = 0x003679A0 63 | moneyOffset = 0x0010B01C -------------------------------------------------------------------------------- /src/com/aurum/mystery2/Lists.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2; 19 | 20 | import java.io.BufferedReader; 21 | import java.io.IOException; 22 | import java.io.InputStreamReader; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | public class Lists { 27 | private static List populate(String filepath, int padlength) { 28 | BufferedReader reader = new BufferedReader(new InputStreamReader(Lists.class.getResourceAsStream(filepath))); 29 | List list = new ArrayList(); 30 | 31 | String line; 32 | int index = 0; 33 | try { 34 | while ((line = reader.readLine()) != null) 35 | list.add(Main.debug ? String.format("%0" + padlength + "X", index++) + ": " + line.trim() : line.trim()); 36 | } 37 | catch (IOException ex) { 38 | System.out.println(ex); 39 | } 40 | 41 | return list; 42 | } 43 | 44 | static { 45 | pokemon = populate("/res/lists/pokemon.txt", 3); 46 | dungeons = populate("/res/lists/dungeons.txt", 2); 47 | areas = populate("/res/lists/areas.txt", 2); 48 | items = populate("/res/lists/items.txt", 2); 49 | types = populate("/res/lists/types.txt", 2); 50 | moves = populate("/res/lists/moves.txt", 3); 51 | abilities = populate("/res/lists/abilities.txt", 2); 52 | } 53 | 54 | public static List dungeons, pokemon, items, types, moves, abilities, areas; 55 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/Area.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.ByteBuffer; 21 | import com.aurum.mystery2.ByteOrder; 22 | 23 | public class Area implements Cloneable { 24 | // Entry fields 25 | public int count, condition; 26 | public long price; 27 | 28 | // Other fields 29 | public String name; 30 | public int namePointer; 31 | 32 | // Static fields 33 | public static final int SIZE = 0x8; 34 | 35 | @Override 36 | public String toString() { 37 | return name; 38 | } 39 | 40 | @Override 41 | public Object clone() { 42 | try { 43 | return super.clone(); 44 | } 45 | catch (CloneNotSupportedException ex) { 46 | return null; 47 | } 48 | } 49 | 50 | public static Area unpack(ByteBuffer buffer) { 51 | Area area = new Area(); 52 | 53 | area.count = buffer.readUnsignedShort(); 54 | area.condition = buffer.readUnsignedShort(); 55 | area.price = buffer.readUnsignedInt(); 56 | 57 | return area; 58 | } 59 | 60 | public static byte[] pack(Area area) { 61 | ByteBuffer buffer = new ByteBuffer(SIZE, ByteOrder.LITTLE_ENDIAN); 62 | 63 | buffer.writeUnsignedShort(area.count); 64 | buffer.writeUnsignedShort(area.condition); 65 | buffer.writeUnsignedInt(area.price); 66 | 67 | return buffer.getBuffer(); 68 | } 69 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/exception/UncaughtExceptionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.exception; 19 | 20 | import com.aurum.mystery2.Main; 21 | import java.io.PrintWriter; 22 | import java.io.StringWriter; 23 | import javax.swing.JFrame; 24 | import javax.swing.JScrollPane; 25 | import javax.swing.JTextArea; 26 | 27 | public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { 28 | @Override 29 | public void uncaughtException(Thread t, Throwable e) { 30 | String thread = "Exception in thread " + t.getName(); 31 | System.err.println(thread); 32 | e.printStackTrace(System.err); 33 | 34 | new UncaughtExceptionForm(t, e).setVisible(true); 35 | } 36 | 37 | private final class UncaughtExceptionForm extends JFrame { 38 | public UncaughtExceptionForm(Thread t, Throwable e) { 39 | JScrollPane pane = new JScrollPane(); 40 | JTextArea text = new JTextArea(); 41 | 42 | final StringWriter sw = new StringWriter(); 43 | final PrintWriter pw = new PrintWriter(sw, true); 44 | e.printStackTrace(pw); 45 | 46 | text.setText(sw.getBuffer().toString()); 47 | text.setEditable(false); 48 | text.setCaretPosition(0); 49 | pane.setViewportView(text); 50 | 51 | this.setResizable(false); 52 | this.setIconImage(Main.icon); 53 | this.setTitle(Main.name); 54 | this.setSize(600, 700); 55 | this.setLocationRelativeTo(null); 56 | this.add(pane); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/ExclusivePokemon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.ByteBuffer; 21 | import com.aurum.mystery2.ByteOrder; 22 | import com.aurum.mystery2.Lists; 23 | 24 | public class ExclusivePokemon implements Cloneable { 25 | // Entry fields 26 | public int species; 27 | public boolean red, blue; 28 | 29 | // Static fields 30 | public static int SIZE = 0x4; 31 | 32 | @Override 33 | public String toString() { 34 | return Lists.pokemon.get(species) + ((red && blue) ? " (R & B)" 35 | : (red ? " (R)" 36 | : (blue ? " (B)" 37 | : ""))); 38 | } 39 | 40 | @Override 41 | public Object clone() { 42 | try { 43 | return super.clone(); 44 | } 45 | catch (CloneNotSupportedException ex) { 46 | return null; 47 | } 48 | } 49 | 50 | public static ExclusivePokemon unpack(ByteBuffer buffer) { 51 | ExclusivePokemon exclusive = new ExclusivePokemon(); 52 | 53 | exclusive.species = buffer.readUnsignedShort(); 54 | exclusive.red = buffer.readBoolean(); 55 | exclusive.blue = buffer.readBoolean(); 56 | 57 | return exclusive; 58 | } 59 | 60 | public static byte[] pack(ExclusivePokemon exc) { 61 | ByteBuffer buffer = new ByteBuffer(SIZE, ByteOrder.LITTLE_ENDIAN); 62 | 63 | buffer.writeUnsignedShort(exc.species); 64 | buffer.writeBoolean(exc.red); 65 | buffer.writeBoolean(exc.blue); 66 | 67 | return buffer.getBuffer(); 68 | } 69 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/Floor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.ByteBuffer; 21 | import com.aurum.mystery2.ByteOrder; 22 | 23 | public class Floor implements Cloneable { 24 | // Entry fields 25 | public int layout, pokemon, traps, items, itemsShop, itemsMonster, itemsBuried; 26 | 27 | // Static fields 28 | public static final int SIZE = 0x10; 29 | 30 | @Override 31 | public Object clone() { 32 | try { 33 | return super.clone(); 34 | } 35 | catch (CloneNotSupportedException ex) { 36 | return null; 37 | } 38 | } 39 | 40 | public static Floor unpack(ByteBuffer buffer) { 41 | Floor floor = new Floor(); 42 | 43 | floor.layout = buffer.readUnsignedShort(); 44 | floor.pokemon = buffer.readUnsignedShort(); 45 | floor.traps = buffer.readUnsignedShort(); 46 | floor.items = buffer.readUnsignedShort(); 47 | floor.itemsShop = buffer.readUnsignedShort(); 48 | floor.itemsMonster = buffer.readUnsignedShort(); 49 | floor.itemsBuried = buffer.readUnsignedShort(); 50 | buffer.skip(0x2); 51 | 52 | return floor; 53 | } 54 | 55 | public static byte[] pack(Floor floor) { 56 | ByteBuffer buffer = new ByteBuffer(SIZE, ByteOrder.LITTLE_ENDIAN); 57 | 58 | buffer.writeUnsignedShort(floor.layout); 59 | buffer.writeUnsignedShort(floor.pokemon); 60 | buffer.writeUnsignedShort(floor.traps); 61 | buffer.writeUnsignedShort(floor.items); 62 | buffer.writeUnsignedShort(floor.itemsShop); 63 | buffer.writeUnsignedShort(floor.itemsMonster); 64 | buffer.writeUnsignedShort(floor.itemsBuried); 65 | buffer.writeShort((short) 0x0); 66 | 67 | return buffer.getBuffer(); 68 | } 69 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/DungeonTraps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.ByteBuffer; 21 | import com.aurum.mystery2.ByteOrder; 22 | 23 | public class DungeonTraps implements Cloneable { 24 | // Entry fields 25 | public int[] traps; 26 | 27 | // Other fields 28 | public int offset; 29 | 30 | // Static fields 31 | public static final int SIZE = 0x28; 32 | 33 | @Override 34 | public Object clone() { 35 | try { 36 | DungeonTraps clone = (DungeonTraps) super.clone(); 37 | clone.traps = new int[20]; 38 | System.arraycopy(traps, 0, clone.traps, 0, 20); 39 | return clone; 40 | } 41 | catch (CloneNotSupportedException ex) { 42 | return null; 43 | } 44 | } 45 | 46 | public boolean checkProbabilitySum() { 47 | int sum = 0; 48 | for (int trap : traps) 49 | sum += trap; 50 | return sum != 10000; 51 | } 52 | 53 | public static DungeonTraps unpack(ByteBuffer buffer) { 54 | DungeonTraps trapentry = new DungeonTraps(); 55 | 56 | trapentry.offset = buffer.position(); 57 | trapentry.traps = new int[20]; 58 | int diff = 0; 59 | for (int i = 0 ; i < 20 ; i++) { 60 | int mval = buffer.readUnsignedShort(); 61 | int val = mval; 62 | if (mval != 0) { 63 | val -= diff; 64 | diff = mval; 65 | } 66 | trapentry.traps[i] = val; 67 | } 68 | 69 | return trapentry; 70 | } 71 | 72 | public static byte[] pack(DungeonTraps trapentry) { 73 | ByteBuffer buffer = new ByteBuffer(SIZE, ByteOrder.LITTLE_ENDIAN); 74 | 75 | int sum = 0; 76 | for (int trap : trapentry.traps) 77 | buffer.writeUnsignedShort(sum < 10000 ? ((trap > 0) ? sum += trap : 0) : 0); 78 | 79 | return buffer.getBuffer(); 80 | } 81 | } -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | annotation.processing.enabled=true 2 | annotation.processing.enabled.in.editor=false 3 | annotation.processing.processors.list= 4 | annotation.processing.run.all.processors=true 5 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output 6 | application.title=Mystery2 7 | application.vendor=Aurum 8 | auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml 9 | build.classes.dir=${build.dir}/classes 10 | build.classes.excludes=**/*.java,**/*.form 11 | # This directory is removed when the project is cleaned: 12 | build.dir=build 13 | build.generated.dir=${build.dir}/generated 14 | build.generated.sources.dir=${build.dir}/generated-sources 15 | # Only compile against the classpath explicitly listed here: 16 | build.sysclasspath=ignore 17 | build.test.classes.dir=${build.dir}/test/classes 18 | build.test.results.dir=${build.dir}/test/results 19 | # Uncomment to specify the preferred debugger connection transport: 20 | #debug.transport=dt_socket 21 | debug.classpath=\ 22 | ${run.classpath} 23 | debug.test.classpath=\ 24 | ${run.test.classpath} 25 | # Files in build.classes.dir which should be excluded from distribution jar 26 | dist.archive.excludes= 27 | # This directory is removed when the project is cleaned: 28 | dist.dir=dist 29 | dist.jar=${dist.dir}/Mystery2.jar 30 | dist.javadoc.dir=${dist.dir}/javadoc 31 | endorsed.classpath= 32 | excludes= 33 | file.reference.ini4j-0.5.4.jar=lib/ini4j-0.5.4.jar 34 | includes=** 35 | jar.compress=true 36 | javac.classpath=\ 37 | ${file.reference.ini4j-0.5.4.jar}:\ 38 | ${reference.Riivotree.jar} 39 | # Space-separated list of extra javac options 40 | javac.compilerargs= 41 | javac.deprecation=false 42 | javac.external.vm=true 43 | javac.processorpath=\ 44 | ${javac.classpath} 45 | javac.source=1.8 46 | javac.target=1.8 47 | javac.test.classpath=\ 48 | ${javac.classpath}:\ 49 | ${build.classes.dir} 50 | javac.test.processorpath=\ 51 | ${javac.test.classpath} 52 | javadoc.additionalparam= 53 | javadoc.author=false 54 | javadoc.encoding=${source.encoding} 55 | javadoc.noindex=false 56 | javadoc.nonavbar=false 57 | javadoc.notree=false 58 | javadoc.private=false 59 | javadoc.splitindex=true 60 | javadoc.use=true 61 | javadoc.version=false 62 | javadoc.windowtitle= 63 | main.class=com.aurum.mystery2.Main 64 | manifest.file=manifest.mf 65 | meta.inf.dir=${src.dir}/META-INF 66 | mkdist.disabled=false 67 | platform.active=default_platform 68 | project.Riivotree=../Riivotree 69 | reference.Riivotree.jar=${project.Riivotree}/dist/Riivotree.jar 70 | run.classpath=\ 71 | ${javac.classpath}:\ 72 | ${build.classes.dir} 73 | # Space-separated list of JVM arguments used when running the project. 74 | # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. 75 | # To set system properties for unit tests define test-sys-prop.name=value: 76 | run.jvmargs= 77 | run.test.classpath=\ 78 | ${javac.test.classpath}:\ 79 | ${build.test.classes.dir} 80 | source.encoding=UTF-8 81 | src.dir=src 82 | test.src.dir=test 83 | -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/ExclusivePokemonEditor.java: -------------------------------------------------------------------------------- 1 | package com.aurum.mystery2.swing; 2 | 3 | import com.aurum.mystery2.Lists; 4 | import com.aurum.mystery2.game.ExclusivePokemon; 5 | import com.aurum.mystery2.game.RomFile; 6 | import javax.swing.DefaultComboBoxModel; 7 | import javax.swing.JButton; 8 | import javax.swing.JLabel; 9 | import javax.swing.JComboBox; 10 | import javax.swing.JCheckBox; 11 | 12 | public class ExclusivePokemonEditor extends AbstractEditor { 13 | private ExclusivePokemon selected; 14 | 15 | private JButton btnClear; 16 | 17 | private JLabel lblPokemon; 18 | private JComboBox cmoPokemon; 19 | private JCheckBox chkRed, chkBlue; 20 | 21 | public ExclusivePokemonEditor() { 22 | RomFile.current.exclusivePokemon.forEach((exc) -> { model.addElement(exc.toString()); }); 23 | list.setSelectedIndex(0); 24 | } 25 | 26 | @Override 27 | protected void initProperties() { 28 | setTitle("Exclusive Pokémon editor"); 29 | 30 | // Initialize the components 31 | 32 | lblPokemon = new JLabel("Pokémon"); 33 | cmoPokemon = new JComboBox(); 34 | cmoPokemon.setModel(new DefaultComboBoxModel(Lists.pokemon.toArray())); 35 | chkRed = new JCheckBox("Found in Red Rescue Team"); 36 | chkBlue = new JCheckBox("Found in Blue Rescue Team"); 37 | 38 | // Add the components to the property panel 39 | properties.addCaption("Exclusive Pokémon settings"); 40 | properties.addLabeledComponent(lblPokemon, cmoPokemon); 41 | properties.addComponent(chkRed); 42 | properties.addComponent(chkBlue); 43 | properties.addTerminator(); 44 | 45 | // Create additional toolbar components 46 | btnClear = new JButton("Clear entries"); 47 | btnClear.addActionListener((java.awt.event.ActionEvent evt) -> { 48 | for (int i = 0 ; i < RomFile.current.exclusivePokemon.size() ; i++) { 49 | ExclusivePokemon exc = RomFile.current.exclusivePokemon.get(i); 50 | exc.species = 0; 51 | exc.red = false; 52 | exc.blue = false; 53 | model.set(i, exc.toString()); 54 | } 55 | }); 56 | toolbar.add(btnClear); 57 | } 58 | 59 | @Override 60 | protected void load() { 61 | if (list.getSelectedIndex() < 0) 62 | return; 63 | 64 | selected = (ExclusivePokemon) RomFile.current.exclusivePokemon.get(list.getSelectedIndex()).clone(); 65 | 66 | cmoPokemon.setSelectedIndex(selected.species); 67 | chkRed.setSelected(selected.red); 68 | chkBlue.setSelected(selected.blue); 69 | } 70 | 71 | @Override 72 | protected void save() { 73 | if (selected == null || list.getSelectedIndex() < 0) 74 | return; 75 | 76 | selected.species = cmoPokemon.getSelectedIndex(); 77 | selected.red = chkRed.isSelected(); 78 | selected.blue = chkBlue.isSelected(); 79 | 80 | model.set(list.getSelectedIndex(), selected.toString()); 81 | RomFile.current.exclusivePokemon.set(list.getSelectedIndex(), selected); 82 | } 83 | 84 | @Override 85 | protected void warningLabel() {} 86 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/JPropertyPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import static java.awt.GridBagConstraints.*; 21 | import java.awt.Component; 22 | import java.awt.Font; 23 | import java.awt.GridBagConstraints; 24 | import java.awt.GridBagLayout; 25 | import java.awt.Insets; 26 | import javax.swing.Box; 27 | import javax.swing.JButton; 28 | import javax.swing.JLabel; 29 | import javax.swing.JPanel; 30 | import javax.swing.JSeparator; 31 | import javax.swing.JTextField; 32 | import javax.swing.border.EmptyBorder; 33 | 34 | public class JPropertyPanel extends JPanel { 35 | protected int index; 36 | 37 | public JPropertyPanel() { 38 | super.setLayout(new GridBagLayout()); 39 | super.setBorder(new EmptyBorder(8, 8, 8, 8)); 40 | index = 0; 41 | } 42 | 43 | public void clear() { 44 | index = 0; 45 | removeAll(); 46 | repaint(); 47 | } 48 | 49 | private void prepareComponent(Component c) { 50 | if (c instanceof JTextField) ((JTextField) c).setColumns(20); 51 | } 52 | 53 | public void addCaption(String c) { 54 | JLabel l = new JLabel(c); 55 | l.setFont(l.getFont().deriveFont(Font.BOLD)); 56 | add(l, new GridBagConstraints(0, index++, 3, 1, 1f, 0f, CENTER, HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); 57 | } 58 | 59 | public void addComponent(Component c) { 60 | prepareComponent(c); 61 | 62 | add(c, new GridBagConstraints(0, index++, 3, 1, 0.4f, 0f, CENTER, HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); 63 | } 64 | 65 | public void addLabeledComponent(JLabel l, Component c) { 66 | prepareComponent(c); 67 | 68 | add(l, new GridBagConstraints(0, index, 1, 1, 0.5f, 0f, LINE_START, NONE, new Insets(1, 1, 1, 1), 0, 0)); 69 | add(c, new GridBagConstraints(1, index, 2, 1, 0.5f, 0f, CENTER, HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); 70 | index++; 71 | } 72 | 73 | public void addEditor(JLabel l, Component c, JButton b) { 74 | prepareComponent(c); 75 | 76 | add(l, new GridBagConstraints(0, index, 1, 1, 0.5f, 0f, LINE_START, NONE, new Insets(1, 1, 1, 1), 0, 0)); 77 | add(c, new GridBagConstraints(1, index, 1, 1, 0.5f, 0f, CENTER, HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); 78 | add(b, new GridBagConstraints(2, index, 1, 1, 0.5f, 0f, CENTER, HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0)); 79 | index++; 80 | } 81 | 82 | public void addSeparator() { 83 | add(new JSeparator(), new GridBagConstraints(0, index++, 3, 1, 1f, 0f, LINE_START, HORIZONTAL, new Insets(12, 1, 12, 1), 0, 0)); 84 | } 85 | 86 | public void addTerminator() { 87 | add(Box.createVerticalGlue(), new GridBagConstraints(0, index++, 3, 1, 1f, 1f, CENTER, BOTH, new Insets(1, 1, 1, 1), 0, 0)); 88 | } 89 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/AreaEditor.java: -------------------------------------------------------------------------------- 1 | package com.aurum.mystery2.swing; 2 | 3 | import com.aurum.mystery2.BitConverter; 4 | import com.aurum.mystery2.Lists; 5 | import com.aurum.mystery2.game.Area; 6 | import com.aurum.mystery2.game.RomFile; 7 | import javax.swing.DefaultComboBoxModel; 8 | import javax.swing.JLabel; 9 | import javax.swing.JComboBox; 10 | import javax.swing.JSpinner; 11 | import javax.swing.JTextField; 12 | import javax.swing.SpinnerNumberModel; 13 | 14 | public class AreaEditor extends AbstractEditor { 15 | private Area selected; 16 | 17 | private JLabel lblCondition, lblPrice, lblCount, lblName, lblNamePointer; 18 | private JComboBox cmoCondition; 19 | private JSpinner spnPrice, spnCount; 20 | private JTextField txtName, txtNamePointer; 21 | 22 | public AreaEditor() { 23 | Lists.areas.stream().forEach((area) -> { model.addElement(area); }); 24 | list.setSelectedIndex(0); 25 | } 26 | 27 | @Override 28 | protected void initProperties() { 29 | setTitle("Friend area editor"); 30 | 31 | // Initialize the components 32 | lblName = new JLabel("Name"); 33 | lblNamePointer = new JLabel("Name pointer"); 34 | lblCount = new JLabel("No. of Pokémon"); 35 | lblCondition = new JLabel("Unlock condition"); 36 | lblPrice = new JLabel("Price"); 37 | txtName = new JTextField("00000000"); 38 | txtName.setEditable(false); 39 | txtNamePointer = new JTextField(); 40 | txtNamePointer.setEditable(false); 41 | spnCount = new JSpinner(); 42 | spnCount.setModel(new SpinnerNumberModel(0, 0, 15, 1)); 43 | cmoCondition = new JComboBox(); 44 | cmoCondition.setModel(new DefaultComboBoxModel(new String[] { "0x0: Shop (Story-game)", "0x1: Shop (Post-game)", "0x2: Wonder mail event", "0x3: Legendary request" })); 45 | spnPrice = new JSpinner(); 46 | spnPrice.setModel(new SpinnerNumberModel(Long.valueOf(0L), Long.valueOf(0L), Long.valueOf(99999L), Long.valueOf(1L))); 47 | 48 | // Add the components to the property panel 49 | properties.addCaption("Area settings"); 50 | properties.addLabeledComponent(lblName, txtName); 51 | properties.addLabeledComponent(lblNamePointer, txtNamePointer); 52 | properties.addLabeledComponent(lblCount, spnCount); 53 | properties.addLabeledComponent(lblCondition, cmoCondition); 54 | properties.addLabeledComponent(lblPrice, spnPrice); 55 | properties.addTerminator(); 56 | } 57 | 58 | @Override 59 | protected void load() { 60 | if (list.getSelectedIndex() < 0) 61 | return; 62 | 63 | selected = (Area) RomFile.current.areas.get(list.getSelectedIndex()).clone(); 64 | 65 | txtName.setText(selected.name); 66 | txtName.setCaretPosition(0); 67 | txtNamePointer.setText(BitConverter.toHexIntString(selected.namePointer)); 68 | 69 | spnCount.setValue(selected.count); 70 | cmoCondition.setSelectedIndex(selected.condition); 71 | spnPrice.setValue(selected.price); 72 | } 73 | 74 | @Override 75 | protected void save() { 76 | if (selected == null || list.getSelectedIndex() < 0) 77 | return; 78 | 79 | selected.count = (int) spnCount.getValue(); 80 | selected.condition = cmoCondition.getSelectedIndex(); 81 | selected.price = (long) spnPrice.getValue(); 82 | 83 | RomFile.current.areas.set(list.getSelectedIndex(), selected); 84 | } 85 | 86 | @Override 87 | protected void warningLabel() {} 88 | } -------------------------------------------------------------------------------- /src/res/lists/items.txt: -------------------------------------------------------------------------------- 1 | Nothing 2 | Stick 3 | Iron Thorn 4 | Silver Spike 5 | Gold Fang 6 | Cacnea Spike 7 | Corsola Twig 8 | Gravelerock 9 | Geo Pebble 10 | Mobile Scarf 11 | Heal Ribbon 12 | Twist Band 13 | Scope Lens 14 | Patsy Band 15 | No-Stick Cap 16 | Pierce Band 17 | Joy Ribbon 18 | X-Ray Specs 19 | Persim Band 20 | Power Band 21 | Pecha Scarf 22 | Insomniscope 23 | Warp Scarf 24 | Tight Belt 25 | Sneak Scarf 26 | Gold Ribbon 27 | Goggle Specs 28 | Diet Ribbon 29 | Trap Scarf 30 | Racket Band 31 | Def. Scarf 32 | Stamina Band 33 | Plain Ribbon 34 | Special Band 35 | Zinc Band 36 | Detect Band 37 | Alert Specs 38 | Dodge Scarf 39 | Bounce Band 40 | Curve Band 41 | Whiff Specs 42 | No-Aim Scope 43 | Lockon Specs 44 | Munch Belt 45 | Pass Scarf 46 | Weather Band 47 | Friend Bow 48 | Beauty Scarf 49 | Sun Ribbon 50 | Lunar Ribbon 51 | Ring D 52 | Ring E 53 | Ring F 54 | Heal Seed 55 | Wish Stone 56 | Oran Berry 57 | Sitrus Berry 58 | Eyedrop Seed 59 | Reviver Seed 60 | Blinker Seed 61 | Doom Seed 62 | Allure Seed 63 | Life Seed 64 | Rawst Berry 65 | Hunger Seed 66 | Quick Seed 67 | Pecha Berry 68 | Cheri Berry 69 | Totter Seed 70 | Sleep Seed 71 | Plain Seed 72 | Warp Seed 73 | Blast Seed 74 | Ginseng 75 | Joy Seed 76 | Chesto Berry 77 | Stun Seed 78 | Max Elixir 79 | Protein 80 | Calcium 81 | Iron 82 | Zinc 83 | Apple 84 | Big Apple 85 | Grimy Food 86 | Huge Apple 87 | White Gummi 88 | Red Gummi 89 | Blue Gummi 90 | Grass Gummi 91 | Yellow Gummi 92 | Clear Gummi 93 | Orange Gummi 94 | Pink Gummi 95 | Brown Gummi 96 | Sky Gummi 97 | Gold Gummi 98 | Green Gummi 99 | Gray Gummi 100 | Purple Gummi 101 | Royal Gummi 102 | Black Gummi 103 | Silver Gummi 104 | Banana 105 | Chestnut 106 | POKé 107 | Upgrade 108 | King's Rock 109 | Thunderstone 110 | Deepseascale 111 | Deepseatooth 112 | Sun Stone 113 | Moon Stone 114 | Fire Stone 115 | Water Stone 116 | Metal Coat 117 | Leaf Stone 118 | Dragon Scale 119 | Link Cable 120 | Ice Part 121 | Steel Part 122 | Rock Part 123 | Music Box 124 | Key 125 | Used TM 126 | Focus Punch 127 | Dragon Claw 128 | Water Pulse 129 | Calm Mind 130 | Roar 131 | Toxic 132 | Hail Orb 133 | Bulk Up 134 | Bullet Seed 135 | Hidden Power 136 | Sunny Orb 137 | Taunt 138 | Ice Beam 139 | Blizzard 140 | Hyper Beam 141 | Light Screen 142 | Protect 143 | Rainy Orb 144 | Giga Drain 145 | Safeguard 146 | Frustration 147 | Solarbeam 148 | Iron Tail 149 | Thunderbolt 150 | Thunder 151 | Earthquake 152 | Return 153 | Dig 154 | Psychic 155 | Shadow Ball 156 | Brick Break 157 | Evasion Orb 158 | Reflect 159 | Shock Wave 160 | Flamethrower 161 | Sludge Bomb 162 | Sandy Orb 163 | Fire Blast 164 | Rocky Orb 165 | Aerial Ace 166 | Torment 167 | Facade 168 | Secret Power 169 | Rest 170 | Attract 171 | Thief 172 | Steel Wing 173 | Skill Swap 174 | Snatch Orb 175 | Overheat 176 | Wide Slash 177 | Excavate 178 | Spin Slash 179 | See-Trap Orb 180 | Mug Orb 181 | Rebound Orb 182 | Lob Orb 183 | Switcher Orb 184 | Blowback Orb 185 | Warp Orb 186 | Transfer Orb 187 | Slow Orb 188 | Quick Orb 189 | Luminous Orb 190 | Petrify Orb 191 | Stayaway Orb 192 | Pounce Orb 193 | Trawl Orb 194 | Cleanse Orb 195 | Observer Orb 196 | Decoy Orb 197 | Slumber Orb 198 | Totter Orb 199 | Two-Edge Orb 200 | Silence Orb 201 | Escape Orb 202 | Scanner Orb 203 | Radar Orb 204 | Drought Orb 205 | Trapbust Orb 206 | Rollcall Orb 207 | Invisify Orb 208 | One-Shot Orb 209 | Identify Orb 210 | Vacuum-Cut 211 | Reviver Orb 212 | Shocker Orb 213 | Sizebust Orb 214 | One-Room Orb 215 | Fill-In Orb 216 | Trapper Orb 217 | Possess Orb 218 | Itemizer Orb 219 | Hurl Orb 220 | Mobile Orb 221 | Toss Orb 222 | Stairs Orb 223 | Longtoss Orb 224 | Pierce Orb 225 | Cut 226 | Fly 227 | Surf 228 | Strength 229 | Flash 230 | Rock Smash 231 | Waterfall 232 | Dive 233 | Link Box 234 | Switch Box 235 | Weavile Fig 236 | Mime Jr. Fig 237 | Beatup Orb 238 | G Machine 6 239 | G Machine 7 240 | G Machine 8 -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/Item.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.BitConverter; 21 | import com.aurum.mystery2.ByteBuffer; 22 | import com.aurum.mystery2.ByteOrder; 23 | 24 | public class Item implements Cloneable { 25 | // Entry fields 26 | public String name, desc; 27 | public int namePointer, descPointer; 28 | public long buyPrice, sellPrice; 29 | public short icon, palette, type, subtype, move, order; 30 | public boolean throwDamage; 31 | 32 | // Unknown fields 33 | public short unkThrow1B, unkThrow1C; 34 | public boolean unkFood1, unkFood2; 35 | 36 | // Static fields 37 | public static final int SIZE = 0x20; 38 | 39 | @Override 40 | public String toString() { 41 | return name; 42 | } 43 | 44 | @Override 45 | public Object clone() { 46 | try { 47 | return super.clone(); 48 | } 49 | catch (CloneNotSupportedException ex) { 50 | return null; 51 | } 52 | } 53 | 54 | public static Item unpack(ByteBuffer buffer) { 55 | Item item = new Item(); 56 | 57 | int nextOffset = buffer.position() + SIZE; 58 | 59 | // Fields 60 | item.namePointer = buffer.readInt(); 61 | item.buyPrice = buffer.readUnsignedInt(); 62 | item.sellPrice = buffer.readUnsignedInt(); 63 | item.type = buffer.readUnsignedByte(); 64 | item.icon = buffer.readUnsignedByte(); 65 | buffer.skip(0x2); 66 | item.descPointer = buffer.readInt(); 67 | item.unkFood1 = buffer.readBoolean(); 68 | item.unkFood2 = buffer.readBoolean(); 69 | item.throwDamage = buffer.readBoolean(); 70 | buffer.skip(0x1); 71 | item.move = buffer.readShort(); 72 | item.order = buffer.readUnsignedByte(); 73 | item.unkThrow1B = buffer.readUnsignedByte(); 74 | item.unkThrow1C = buffer.readUnsignedByte(); 75 | item.palette = buffer.readUnsignedByte(); 76 | item.subtype = buffer.readUnsignedByte(); 77 | buffer.skip(0x1); 78 | 79 | // Strings 80 | if (item.namePointer != 0x00000000) item.name = buffer.readStringAt(BitConverter.pointerToOffset(item.namePointer)); 81 | if (item.descPointer != 0x00000000) item.desc = buffer.readStringAt(BitConverter.pointerToOffset(item.descPointer)); 82 | 83 | buffer.seek(nextOffset); 84 | 85 | return item; 86 | } 87 | 88 | public static byte[] pack(Item item) { 89 | ByteBuffer buffer = new ByteBuffer(0x20, ByteOrder.LITTLE_ENDIAN); 90 | 91 | buffer.writeInt(item.namePointer); 92 | buffer.writeUnsignedInt(item.buyPrice); 93 | buffer.writeUnsignedInt(item.sellPrice); 94 | buffer.writeUnsignedByte(item.type); 95 | buffer.writeUnsignedByte(item.icon); 96 | buffer.writeShort((short) 0); 97 | buffer.writeInt(item.descPointer); 98 | buffer.writeBoolean(item.unkFood1); 99 | buffer.writeBoolean(item.unkFood2); 100 | buffer.writeBoolean(item.throwDamage); 101 | buffer.writeByte((byte) 0); 102 | buffer.writeShort(item.move); 103 | buffer.writeUnsignedByte(item.order); 104 | buffer.writeUnsignedByte(item.unkThrow1B); 105 | buffer.writeUnsignedByte(item.unkThrow1C); 106 | buffer.writeUnsignedByte(item.palette); 107 | buffer.writeUnsignedByte(item.subtype); 108 | buffer.writeByte((byte) 0); 109 | 110 | return buffer.getBuffer(); 111 | } 112 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/Dungeon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import com.aurum.mystery2.ByteBuffer; 23 | import com.aurum.mystery2.ByteOrder; 24 | 25 | public class Dungeon implements Cloneable { 26 | // Entry fields 27 | public boolean setLvl1, setNoMoney, setSaveGame, setRecruitable; 28 | public int timer; 29 | public short stair, itemLimit, partyLimit; 30 | public boolean hmFly, hmDive, hmWaterfall, hmSurf, typeWater; 31 | 32 | // Unknown fields 33 | public byte unk1; 34 | public short unk3, unkE; 35 | public boolean unk8, unk9; 36 | 37 | // Other fields 38 | public int mapX, mapY; 39 | public int floorsOffset; 40 | public short floorsCount; 41 | public List floors = new ArrayList(); 42 | 43 | // Static fields 44 | public static final int SIZE = 0x10; 45 | 46 | @Override 47 | public Object clone() { 48 | try { 49 | Dungeon clone = (Dungeon) super.clone(); 50 | clone.floors = new ArrayList(); 51 | for (Floor floor : floors) 52 | clone.floors.add((Floor) floor.clone()); 53 | return clone; 54 | } 55 | catch (CloneNotSupportedException ex) { 56 | return null; 57 | } 58 | } 59 | 60 | public static Dungeon unpack(ByteBuffer buffer) { 61 | Dungeon dungeon = new Dungeon(); 62 | 63 | dungeon.stair = buffer.readUnsignedByte(); 64 | dungeon.unk1 = buffer.readByte(); 65 | dungeon.setRecruitable = buffer.readBoolean(); 66 | dungeon.unk3 = buffer.readUnsignedByte(); 67 | dungeon.itemLimit = buffer.readUnsignedByte(); 68 | dungeon.partyLimit = buffer.readUnsignedByte(); 69 | dungeon.setLvl1 = buffer.readBoolean(); 70 | dungeon.setNoMoney = !buffer.readBoolean(); 71 | dungeon.unk8 = buffer.readBoolean(); 72 | dungeon.unk9 = buffer.readBoolean(); 73 | dungeon.setSaveGame = !buffer.readBoolean(); 74 | 75 | int condmask = buffer.readUnsignedByte(); 76 | dungeon.hmFly = (condmask & 1) != 0; 77 | dungeon.hmDive = (condmask & 2) != 0; 78 | dungeon.hmWaterfall = (condmask & 4) != 0; 79 | dungeon.hmSurf = (condmask & 8) != 0; 80 | dungeon.typeWater = (condmask & 16) != 0; 81 | 82 | dungeon.timer = buffer.readUnsignedShort(); 83 | dungeon.unkE = buffer.readShort(); 84 | 85 | return dungeon; 86 | } 87 | 88 | public static byte[] pack(Dungeon dungeon) { 89 | ByteBuffer buffer = new ByteBuffer(SIZE, ByteOrder.LITTLE_ENDIAN); 90 | 91 | buffer.writeUnsignedByte(dungeon.stair); 92 | buffer.writeByte(dungeon.unk1); 93 | buffer.writeBoolean(dungeon.setRecruitable); 94 | buffer.writeUnsignedByte(dungeon.unk3); 95 | buffer.writeUnsignedByte(dungeon.itemLimit); 96 | buffer.writeUnsignedByte(dungeon.partyLimit); 97 | buffer.writeBoolean(dungeon.setLvl1); 98 | buffer.writeBoolean(!dungeon.setNoMoney); 99 | buffer.writeBoolean(dungeon.unk8); 100 | buffer.writeBoolean(dungeon.unk9); 101 | buffer.writeBoolean(!dungeon.setSaveGame); 102 | 103 | int condmask = 0; 104 | condmask ^= dungeon.hmFly ? 1 : 0; 105 | condmask ^= dungeon.hmDive ? 2 : 0; 106 | condmask ^= dungeon.hmWaterfall ? 4 : 0; 107 | condmask ^= dungeon.hmSurf ? 8 : 0; 108 | condmask ^= dungeon.typeWater ? 16 : 0; 109 | buffer.writeByte((byte) condmask); 110 | 111 | buffer.writeUnsignedShort(dungeon.timer); 112 | buffer.writeShort(dungeon.unkE); 113 | 114 | return buffer.getBuffer(); 115 | } 116 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/DungeonLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.ByteBuffer; 21 | import com.aurum.mystery2.ByteOrder; 22 | 23 | public class DungeonLayout implements Cloneable { 24 | // Entry fields 25 | public int layout1, layout2; 26 | public boolean hasTerrainTiles, hasTerrainPond; 27 | public short no, tileset, music, weather, visibility, event; 28 | public short pokemonDensity, itemDensity, trapDensity, terrainDensity, stickyChance; 29 | public short moneyFactor, shopsFactor, monstersFactor; 30 | 31 | // Unknown fields 32 | public byte unk5; 33 | public int unk18; 34 | public boolean unk9, unkB, unkE; 35 | 36 | // Static fields 37 | public static final int SIZE = 0x1C; 38 | 39 | @Override 40 | public Object clone() { 41 | try { 42 | return super.clone(); 43 | } 44 | catch (CloneNotSupportedException ex) { 45 | return null; 46 | } 47 | } 48 | 49 | public static DungeonLayout unpack(ByteBuffer buffer) { 50 | DungeonLayout layout = new DungeonLayout(); 51 | 52 | layout.layout1 = buffer.readUnsignedShort(); 53 | layout.tileset = buffer.readUnsignedByte(); 54 | layout.music = buffer.readUnsignedByte(); 55 | layout.weather = buffer.readUnsignedByte(); 56 | layout.unk5 = buffer.readByte(); 57 | layout.pokemonDensity = buffer.readUnsignedByte(); 58 | layout.shopsFactor = buffer.readUnsignedByte(); 59 | layout.monstersFactor = buffer.readUnsignedByte(); 60 | layout.unk9 = buffer.readBoolean(); 61 | layout.stickyChance = buffer.readUnsignedByte(); 62 | layout.unkB = buffer.readBoolean(); 63 | layout.hasTerrainPond = buffer.readBoolean(); 64 | layout.hasTerrainTiles = buffer.readBoolean(); 65 | layout.unkE = buffer.readBoolean(); 66 | layout.itemDensity = buffer.readUnsignedByte(); 67 | layout.trapDensity = buffer.readUnsignedByte(); 68 | layout.no = buffer.readUnsignedByte(); 69 | layout.event = buffer.readUnsignedByte(); 70 | layout.layout2 = buffer.readUnsignedShort(); 71 | layout.terrainDensity = buffer.readUnsignedByte(); 72 | layout.visibility = buffer.readUnsignedByte(); 73 | layout.moneyFactor = buffer.readUnsignedByte(); 74 | layout.unk18 = buffer.readInt(); 75 | 76 | return layout; 77 | } 78 | 79 | public static byte[] pack(DungeonLayout layout) { 80 | ByteBuffer buffer = new ByteBuffer(SIZE, ByteOrder.LITTLE_ENDIAN); 81 | 82 | buffer.writeUnsignedShort(layout.layout1); 83 | buffer.writeUnsignedByte(layout.tileset); 84 | buffer.writeUnsignedByte(layout.music); 85 | buffer.writeUnsignedByte(layout.weather); 86 | buffer.writeByte(layout.unk5); 87 | buffer.writeUnsignedByte(layout.pokemonDensity); 88 | buffer.writeUnsignedByte(layout.shopsFactor); 89 | buffer.writeUnsignedByte(layout.monstersFactor); 90 | buffer.writeBoolean(layout.unk9); 91 | buffer.writeUnsignedByte(layout.stickyChance); 92 | buffer.writeBoolean(layout.unkB); 93 | buffer.writeBoolean(layout.hasTerrainPond); 94 | buffer.writeBoolean(layout.hasTerrainTiles); 95 | buffer.writeBoolean(layout.unkE); 96 | buffer.writeUnsignedByte(layout.itemDensity); 97 | buffer.writeUnsignedByte(layout.trapDensity); 98 | buffer.writeUnsignedByte(layout.no); 99 | buffer.writeUnsignedByte(layout.event); 100 | buffer.writeUnsignedShort(layout.layout2); 101 | buffer.writeUnsignedByte(layout.terrainDensity); 102 | buffer.writeUnsignedByte(layout.visibility); 103 | buffer.writeUnsignedByte(layout.moneyFactor); 104 | buffer.writeInt(layout.unk18); 105 | 106 | return buffer.getBuffer(); 107 | } 108 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/DungeonPokemon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.BitConverter; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import com.aurum.mystery2.ByteBuffer; 25 | import com.aurum.mystery2.ByteOrder; 26 | import com.aurum.mystery2.Lists; 27 | 28 | public class DungeonPokemon implements Cloneable { 29 | // Entry fields 30 | public List entries; 31 | 32 | // Other fields 33 | public int offset; 34 | 35 | // Static fields 36 | public static final int SIZE = 0x8; 37 | private static final byte[] NULL = new byte[SIZE]; 38 | 39 | public static class Entry implements Cloneable { 40 | public int species, level, probability; 41 | 42 | @Override 43 | public String toString() { 44 | return Lists.pokemon.get(species) + ": Lv. " + level + " (" + probability + ")"; 45 | } 46 | 47 | @Override 48 | public Object clone() { 49 | try { 50 | return super.clone(); 51 | } 52 | catch (CloneNotSupportedException ex) { 53 | return null; 54 | } 55 | } 56 | } 57 | 58 | @Override 59 | public Object clone() { 60 | try { 61 | DungeonPokemon clone = (DungeonPokemon) super.clone(); 62 | clone.entries = new ArrayList(); 63 | for (Entry entry : entries) 64 | clone.entries.add((Entry) entry.clone()); 65 | return clone; 66 | } 67 | catch (CloneNotSupportedException ex) { 68 | return null; 69 | } 70 | } 71 | 72 | public boolean checkProbabilitySum() { 73 | int sum = 0; 74 | for (Entry entry : entries) 75 | sum += entry.probability; 76 | return sum != 10000; 77 | } 78 | 79 | public static DungeonPokemon unpack(ByteBuffer buffer) { 80 | DungeonPokemon pokemon = new DungeonPokemon(); 81 | 82 | pokemon.offset = buffer.position(); 83 | pokemon.entries = new ArrayList(); 84 | 85 | int storedoffset = buffer.position(); 86 | int diff = 0; 87 | 88 | while(!Arrays.equals(buffer.readBytes(SIZE), NULL)) { 89 | buffer.seek(storedoffset); 90 | 91 | Entry entry = new Entry(); 92 | int mask = buffer.readUnsignedShort(); 93 | entry.level = (mask ^ 0x1A8) / 0x200; 94 | entry.species = mask - 0x200 * entry.level; 95 | entry.probability = buffer.readUnsignedShort(); 96 | int val = entry.probability; 97 | if (val != 0) { 98 | val -= diff; 99 | diff = entry.probability; 100 | } 101 | entry.probability = val; 102 | pokemon.entries.add(entry); 103 | 104 | buffer.skip(0x4); 105 | storedoffset = buffer.position(); 106 | } 107 | 108 | return pokemon; 109 | } 110 | 111 | public static byte[] pack(DungeonPokemon pokemon) { 112 | ByteBuffer buffer = new ByteBuffer(pokemon.entries.size() * 8 + 8, ByteOrder.LITTLE_ENDIAN); 113 | 114 | int sum = 0; 115 | 116 | for (Entry entry : pokemon.entries) { 117 | buffer.writeUnsignedShort(entry.species + entry.level * 0x200); 118 | if (sum < 10000) { 119 | int val = (entry.probability != 0) ? sum += entry.probability : 0; 120 | buffer.writeUnsignedShort(val); 121 | buffer.writeUnsignedShort(val); 122 | } 123 | else { 124 | buffer.writeUnsignedShort(0); 125 | buffer.writeUnsignedShort(0); 126 | } 127 | buffer.writeUnsignedShort(0); 128 | } 129 | 130 | buffer.writeBytes(NULL); 131 | 132 | return buffer.getBuffer(); 133 | } 134 | } -------------------------------------------------------------------------------- /src/res/lists/pokemon.txt: -------------------------------------------------------------------------------- 1 | ?????????? 2 | Bulbasaur 3 | Ivysaur 4 | Venusaur 5 | Charmander 6 | Charmeleon 7 | Charizard 8 | Squirtle 9 | Wartortle 10 | Blastoise 11 | Caterpie 12 | Metapod 13 | Butterfree 14 | Weedle 15 | Kakuna 16 | Beedrill 17 | Pidgey 18 | Pidgeotto 19 | Pidgeot 20 | Rattata 21 | Raticate 22 | Spearow 23 | Fearow 24 | Ekans 25 | Arbok 26 | Pikachu 27 | Raichu 28 | Sandshrew 29 | Sandslash 30 | NidoranF 31 | Nidorina 32 | Nidoqueen 33 | NidoranM 34 | Nidorino 35 | Nidoking 36 | Clefairy 37 | Clefable 38 | Vulpix 39 | Ninetales 40 | Jigglypuff 41 | Wigglytuff 42 | Zubat 43 | Golbat 44 | Oddish 45 | Gloom 46 | Vileplume 47 | Paras 48 | Parasect 49 | Venonat 50 | Venomoth 51 | Diglett 52 | Dugtrio 53 | Meowth 54 | Persian 55 | Psyduck 56 | Golduck 57 | Mankey 58 | Primeape 59 | Growlithe 60 | Arcanine 61 | Poliwag 62 | Poliwhirl 63 | Poliwrath 64 | Abra 65 | Kadabra 66 | Alakazam 67 | Machop 68 | Machoke 69 | Machamp 70 | Bellsprout 71 | Weepinbell 72 | Victreebel 73 | Tentacool 74 | Tentacruel 75 | Geodude 76 | Graveler 77 | Golem 78 | Ponyta 79 | Rapidash 80 | Slowpoke 81 | Slowbro 82 | Magnemite 83 | Magneton 84 | Farfetch'D 85 | Doduo 86 | Dodrio 87 | Seel 88 | Dewgong 89 | Grimer 90 | Muk 91 | Shellder 92 | Cloyster 93 | Gastly 94 | Haunter 95 | Gengar 96 | Onix 97 | Drowzee 98 | Hypno 99 | Krabby 100 | Kingler 101 | Voltorb 102 | Electrode 103 | Exeggcute 104 | Exeggutor 105 | Cubone 106 | Marowak 107 | Hitmonlee 108 | Hitmonchan 109 | Lickitung 110 | Koffing 111 | Weezing 112 | Rhyhorn 113 | Rhydon 114 | Chansey 115 | Tangela 116 | Kangaskhan 117 | Horsea 118 | Seadra 119 | Goldeen 120 | Seaking 121 | Staryu 122 | Starmie 123 | Mr. Mime 124 | Scyther 125 | Jynx 126 | Electabuzz 127 | Magmar 128 | Pinsir 129 | Tauros 130 | Magikarp 131 | Gyarados 132 | Lapras 133 | Ditto 134 | Eevee 135 | Vaporeon 136 | Jolteon 137 | Flareon 138 | Porygon 139 | Omanyte 140 | Omastar 141 | Kabuto 142 | Kabutops 143 | Aerodactyl 144 | Snorlax 145 | Articuno 146 | Zapdos 147 | Moltres 148 | Dratini 149 | Dragonair 150 | Dragonite 151 | Mewtwo 152 | Mew 153 | Chikorita 154 | Bayleef 155 | Meganium 156 | Cyndaquil 157 | Quilava 158 | Typhlosion 159 | Totodile 160 | Croconaw 161 | Feraligatr 162 | Sentret 163 | Furret 164 | Hoothoot 165 | Noctowl 166 | Ledyba 167 | Ledian 168 | Spinarak 169 | Ariados 170 | Crobat 171 | Chinchou 172 | Lanturn 173 | Pichu 174 | Cleffa 175 | Igglybuff 176 | Togepi 177 | Togetic 178 | Natu 179 | Xatu 180 | Mareep 181 | Flaaffy 182 | Ampharos 183 | Bellossom 184 | Marill 185 | Azumarill 186 | Sudowoodo 187 | Politoed 188 | Hoppip 189 | Skiploom 190 | Jumpluff 191 | Aipom 192 | Sunkern 193 | Sunflora 194 | Yanma 195 | Wooper 196 | Quagsire 197 | Espeon 198 | Umbreon 199 | Murkrow 200 | Slowking 201 | Misdreavus 202 | Unown (A) 203 | Unown (B) 204 | Unown (C) 205 | Unown (D) 206 | Unown (E) 207 | Unown (F) 208 | Unown (G) 209 | Unown (H) 210 | Unown (I) 211 | Unown (J) 212 | Unown (K) 213 | Unown (L) 214 | Unown (M) 215 | Unown (N) 216 | Unown (O) 217 | Unown (P) 218 | Unown (Q) 219 | Unown (R) 220 | Unown (S) 221 | Unown (T) 222 | Unown (U) 223 | Unown (V) 224 | Unown (W) 225 | Unown (X) 226 | Unown (Y) 227 | Unown (Z) 228 | Wobbuffet 229 | Girafarig 230 | Pineco 231 | Forretress 232 | Dunsparce 233 | Gligar 234 | Steelix 235 | Snubbull 236 | Granbull 237 | Qwilfish 238 | Scizor 239 | Shuckle 240 | Heracross 241 | Sneasel 242 | Teddiursa 243 | Ursaring 244 | Slugma 245 | Magcargo 246 | Swinub 247 | Piloswine 248 | Corsola 249 | Remoraid 250 | Octillery 251 | Delibird 252 | Mantine 253 | Skarmory 254 | Houndour 255 | Houndoom 256 | Kingdra 257 | Phanpy 258 | Donphan 259 | Porygon2 260 | Stantler 261 | Smeargle 262 | Tyrogue 263 | Hitmontop 264 | Smoochum 265 | Elekid 266 | Magby 267 | Miltank 268 | Blissey 269 | Raikou 270 | Entei 271 | Suicune 272 | Larvitar 273 | Pupitar 274 | Tyranitar 275 | Lugia 276 | Ho-Oh 277 | Celebi 278 | Treecko 279 | Grovyle 280 | Sceptile 281 | Torchic 282 | Combusken 283 | Blaziken 284 | Mudkip 285 | Marshtomp 286 | Swampert 287 | Poochyena 288 | Mightyena 289 | Zigzagoon 290 | Linoone 291 | Wurmple 292 | Silcoon 293 | Beautifly 294 | Cascoon 295 | Dustox 296 | Lotad 297 | Lombre 298 | Ludicolo 299 | Seedot 300 | Nuzleaf 301 | Shiftry 302 | Taillow 303 | Swellow 304 | Wingull 305 | Pelipper 306 | Ralts 307 | Kirlia 308 | Gardevoir 309 | Surskit 310 | Masquerain 311 | Shroomish 312 | Breloom 313 | Slakoth 314 | Vigoroth 315 | Slaking 316 | Nincada 317 | Ninjask 318 | Shedinja 319 | Whismur 320 | Loudred 321 | Exploud 322 | Makuhita 323 | Hariyama 324 | Azurill 325 | Nosepass 326 | Skitty 327 | Delcatty 328 | Sableye 329 | Mawile 330 | Aron 331 | Lairon 332 | Aggron 333 | Meditite 334 | Medicham 335 | Electrike 336 | Manectric 337 | Plusle 338 | Minun 339 | Volbeat 340 | Illumise 341 | Roselia 342 | Gulpin 343 | Swalot 344 | Carvanha 345 | Sharpedo 346 | Wailmer 347 | Wailord 348 | Numel 349 | Camerupt 350 | Torkoal 351 | Spoink 352 | Grumpig 353 | Spinda 354 | Trapinch 355 | Vibrava 356 | Flygon 357 | Cacnea 358 | Cacturne 359 | Swablu 360 | Altaria 361 | Zangoose 362 | Seviper 363 | Lunatone 364 | Solrock 365 | Barboach 366 | Whiscash 367 | Corpish 368 | Crawdaunt 369 | Baltoy 370 | Claydol 371 | Lileep 372 | Cradily 373 | Anorith 374 | Armaldo 375 | Feebas 376 | Milotic 377 | Castform (Normal) 378 | Castform (Snowy) 379 | Castform (Sunny) 380 | Castform (Rainy) 381 | Kecleon 382 | Shuppet 383 | Banette 384 | Duskull 385 | Dusclops 386 | Tropius 387 | Chimecho 388 | Absol 389 | Wynaut 390 | Snorunt 391 | Glalie 392 | Spheal 393 | Sealeo 394 | Walrein 395 | Clamperl 396 | Huntail 397 | Gorebyss 398 | Relicanth 399 | Luvdisc 400 | Bagon 401 | Shelgon 402 | Salamence 403 | Beldum 404 | Metang 405 | Metagross 406 | Regirock 407 | Regice 408 | Registeel 409 | Latias 410 | Latios 411 | Kyogre 412 | Groudon 413 | Rayquaza 414 | Jirachi 415 | Deoxys (Normal) 416 | Unown (!) 417 | Unown (?) 418 | Deoxys (Attack) 419 | Deoxys (Defense) 420 | Deoxys (Speed) 421 | Munchlax 422 | Decoy 423 | Statue 424 | Rayquaza (Cutscene) -------------------------------------------------------------------------------- /src/res/lists/moves.txt: -------------------------------------------------------------------------------- 1 | なにもの? 2 | Iron Tail 3 | Ice Ball 4 | Yawn 5 | Lovely Kiss 6 | Nightmare 7 | Morning Sun 8 | Vital Throw 9 | Dig 10 | Thrash 11 | Sweet Scent 12 | Charm 13 | Rain Dance 14 | Confuse Ray 15 | Hail 16 | Aromatherapy 17 | Bubble 18 | Encore 19 | Cut 20 | Rage 21 | Super Fang 22 | Pain Split 23 | Torment 24 | String Shot 25 | Swagger 26 | Snore 27 | Heal Bell 28 | Screech 29 | Rock Throw 30 | Rock Smash 31 | Rock Slide 32 | Weather Ball 33 | Whirlpool 34 | Fake Tears 35 | Sing 36 | Spite 37 | Air Cutter 38 | Smokescreen 39 | Pursuit 40 | Doubleslap 41 | Mirror Move 42 | Overheat 43 | Aurora Beam 44 | Memento 45 | Octazooka 46 | Flatter 47 | Astonish 48 | Will-o-Wisp 49 | Return 50 | Grudge 51 | Strength 52 | Counter 53 | Flame Wheel 54 | Flamethrower 55 | Odor Sleuth 56 | Sharpen 57 | Double Team 58 | Gust 59 | Harden 60 | Disable 61 | Razor Wind 62 | Bide 63 | Crucnch 64 | Bite 65 | Thunder 66 | Thunderpunch 67 | Endeavor 68 | Facade 69 | Karate Chop 70 | Clamp 71 | Withdraw 72 | Constrict 73 | Brick Break 74 | Rock Tomb 75 | Focus Energy 76 | Focus Punch 77 | Giga Drain 78 | Reversal 79 | Smellingsalt 80 | Spore 81 | Leech Life 82 | Slash 83 | Silver Wind 84 | Metal Sound 85 | Grasswhistle 86 | Tickle 87 | Spider Web 88 | Crabhammer 89 | Haze 90 | Mean Look 91 | Cross Chop 92 | Outrage 93 | Low Kick 94 | Ancient Power 95 | Sythesis 96 | Agility 97 | Rapid Spin 98 | Icy Wind 99 | Mind Reader 100 | Cosmic Power 101 | Sky Attack 102 | Powder Snow 103 | Follow Me 104 | Meteor Smash 105 | Endure 106 | Rollout 107 | Scary Face 108 | Psybeam 109 | Psywave 110 | Psychic 111 | Psycho Boost 112 | Hypnosis 113 | Uproar 114 | Water Spout 115 | Signal Beam 116 | Psych Up 117 | Submission 118 | Recover 119 | Earthquake 120 | Nature Power 121 | Lick 122 | Flail 123 | Tail Whip 124 | Selfdestruct 125 | Stun Spore 126 | Bind 127 | Shadow Punch 128 | Shadow Ball 129 | Charge 130 | Thunderbolt 131 | Mist 132 | Fissure 133 | Extremespeed 134 | Extrasensory 135 | Safeguard 136 | Absorb 137 | Sky Uppercut 138 | Skill Swap 139 | Sketch 140 | Headbutt 141 | Double-Edge 142 | Sandstorm 143 | Sand-Attack 144 | Sand Tomb 145 | Spark 146 | Swift 147 | Kinesis 148 | Smog 149 | Growth 150 | Sacred Fire 151 | Sheer Cold 152 | Solarbeam 153 | Sonicboom 154 | Fly 155 | Tackle 156 | Explosion 157 | Dive 158 | Fire Blast 159 | Waterfall 160 | Muddy Water 161 | Stockpile 162 | Slam 163 | Twister 164 | Bullet Seed 165 | Twineedle 166 | Softboiled 167 | Egg Bomb 168 | Faint Attack 169 | Barrage 170 | Minimize 171 | Seismic Toss 172 | Supersonic 173 | Taunt 174 | Moonlight 175 | Peck 176 | Arm Thrust 177 | Horn Attack 178 | Horn Drill 179 | Wing Attack 180 | Aerial Ace 181 | Icicle Spear 182 | Swords Dance 183 | Vine Whip 184 | Conversion 185 | Conversion 2 186 | Helping Hand 187 | Iron Defense 188 | Teleport 189 | Thundershock 190 | Shock Wave 191 | Quick Attack 192 | Sweet Kiss 193 | Thunder Wave 194 | Zap Cannon 195 | Block 196 | Howl 197 | Poison Gas 198 | Toxic 199 | Poison Fang 200 | Poisonpowder 201 | Poison Sting 202 | Spike Cannon 203 | Acid Armor 204 | Take Down 205 | Jump Kick 206 | Bounce 207 | Hi Jump Kick 208 | Tri Attack 209 | Dragon Claw 210 | Trick 211 | Triple Kick 212 | Drill Peck 213 | Mud Sport 214 | Mud-Slap 215 | Theif 216 | Amnesia 217 | Night Shade 218 | Growl 219 | Slack Off 220 | Surf 221 | Role Play 222 | Needle Arm 223 | Double Kick 224 | Sunny Day 225 | Leer 226 | Wish 227 | Fake Out 228 | Sleep Talk 229 | Pay Day 230 | Assist 231 | Heat Wave 232 | Sleep Powder 233 | Rest 234 | Ingrain 235 | Confusion 236 | Body Slam 237 | Swallow 238 | Curse 239 | Frenzy Plant 240 | Hydro Cannon 241 | Hydro Pump 242 | Hyper Voice 243 | Hyper Beam 244 | Superpower 245 | Steel Wing 246 | Spit Up 247 | Dynamicpunch 248 | Guillotine 249 | Vicegrip 250 | Knock Off 251 | Pound 252 | Razor Leaf 253 | Baton Pass 254 | Petal Dance 255 | Splash 256 | Bubblebeam 257 | Doom Desire 258 | Belly Drum 259 | Barrier 260 | Light Screen 261 | Scratch 262 | Hyper Fang 263 | Ember 264 | Secret Power 265 | Dizzy Punch 266 | Bulk Up 267 | Imprison 268 | Featherdance 269 | Whirlwind 270 | Beat Up 271 | Blizzard 272 | Stomp 273 | Blast Burn 274 | Flash 275 | Teeter Dance 276 | Crush Claw 277 | Blaze Kick 278 | Present 279 | Eruption 280 | Sludge 281 | Sludge Bomb 282 | Glare 283 | Transform 284 | Poison Tail 285 | Roar 286 | Bone Rush 287 | Camouflage 288 | Covet 289 | Tail Glow 290 | Bone Club 291 | Bonemerang 292 | Fire Spin 293 | Fire Punch 294 | Perish Song 295 | Wrap 296 | Spikes 297 | Magnitude 298 | Magical Leaf 299 | Magic Coat 300 | Mud Shot 301 | Mach Punch 302 | Protect 303 | Defense Curl 304 | Rolling Kick 305 | Substitute 306 | Detect 307 | Pin Missile 308 | Water Sport 309 | Water Gun 310 | Mist Ball 311 | Water Pulse 312 | Fury Attack 313 | Fury Swipes 314 | Destiny Bond 315 | False Swipe 316 | Foresight 317 | Mirror Coat 318 | Future Sight 319 | Milk Drink 320 | Calm Mind 321 | Mega Drain 322 | Mega Kick 323 | Mega Punch 324 | Megahorn 325 | Hidden Power 326 | Metal Claw 327 | Attract 328 | Mimic 329 | Frustration 330 | Leech Seed 331 | Metronome 332 | Dream Eater 333 | Acid 334 | Meditate 335 | Snatch 336 | Luster Purge 337 | Leaf Blade 338 | Recycle 339 | Reflect 340 | Refesh 341 | Revenge 342 | Dragon Rage 343 | Dragonbreath 344 | Dragon Dance 345 | Ice Punch 346 | Ice Beam 347 | Fury Cutter 348 | Comet Punch 349 | Skull Bash 350 | Lock-On 351 | Rock Blast 352 | Cotton Spore 353 | Struggle 354 | Aeroblast 355 | Volt Tackle 356 | attack 357 | ようすをみる 358 | がまん 359 | - 360 | - 361 | Wide Slash 362 | Excavate 363 | Spin Slash 364 | See-Trap 365 | Takeaway 366 | Rebound 367 | Bloop Slash 368 | Switcher 369 | Blowback 370 | Warp 371 | Transfer 372 | Slow Down 373 | Speed Boost 374 | Searchlight 375 | Petrify 376 | Stay Away 377 | Pounce 378 | Trawl 379 | Cleanse 380 | Observer 381 | Decoy Maker 382 | Siesta 383 | Totter 384 | Two-Edge 385 | No-Move 386 | Escape 387 | Scan 388 | Power-Ears 389 | Drought 390 | Trap Buster 391 | Wild Call 392 | Invisify 393 | One-Shot 394 | HP Gauge 395 | Vacuum-Cut 396 | Reviver 397 | Shocker 398 | Echo 399 | Famish 400 | One-Room 401 | Fill-In 402 | Trapper 403 | Possess 404 | Itemize 405 | - 406 | - 407 | Hurl 408 | Mobile 409 | Item-Toss 410 | See Stairs 411 | Long Toss 412 | - 413 | Pierce -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/DungeonPokemonEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import com.aurum.mystery2.Lists; 21 | import com.aurum.mystery2.game.DungeonPokemon; 22 | import com.aurum.mystery2.game.RomFile; 23 | import javax.swing.DefaultComboBoxModel; 24 | import javax.swing.DefaultListModel; 25 | import javax.swing.JComboBox; 26 | import javax.swing.JLabel; 27 | import javax.swing.JList; 28 | import javax.swing.JScrollPane; 29 | import javax.swing.JSpinner; 30 | import javax.swing.SpinnerNumberModel; 31 | 32 | public class DungeonPokemonEditor extends AbstractEditor { 33 | private DungeonPokemon selected; 34 | private DungeonPokemon.Entry selectedEntry; 35 | private DefaultListModel entryModel; 36 | 37 | private JList listEntries; 38 | private JScrollPane scroll; 39 | 40 | private JLabel lblPokemon, lblLevel, lblProbability; 41 | private JComboBox cmoPokemon; 42 | private JSpinner spnLevel, spnProbability; 43 | 44 | public DungeonPokemonEditor() { 45 | this(-1); 46 | } 47 | 48 | public DungeonPokemonEditor(int pokemon) { 49 | for (int i = 0 ; i < RomFile.current.dungeonPokemon.size() ; i++) 50 | model.addElement("Pokémon no. " + i); 51 | 52 | list.setSelectedIndex(pokemon); 53 | list.ensureIndexIsVisible(pokemon); 54 | } 55 | 56 | @Override 57 | protected void initProperties() { 58 | setTitle("Dungeon Pokémon editor"); 59 | 60 | // Initialize the components 61 | entryModel = new DefaultListModel(); 62 | listEntries = new JList(); 63 | listEntries.setModel(entryModel); 64 | listEntries.addListSelectionListener((javax.swing.event.ListSelectionEvent evt) -> { 65 | if (selected == null || listEntries.getSelectedIndex() < 0) 66 | return; 67 | 68 | selectedEntry = selected.entries.get(listEntries.getSelectedIndex()); 69 | 70 | cmoPokemon.setSelectedIndex(selectedEntry.species); 71 | spnLevel.setValue(selectedEntry.level); 72 | spnProbability.setValue(selectedEntry.probability); 73 | }); 74 | scroll = new JScrollPane(); 75 | scroll.setViewportView(listEntries); 76 | 77 | lblPokemon = new JLabel("Pokémon"); 78 | lblLevel = new JLabel("Level"); 79 | lblProbability = new JLabel("Probability"); 80 | cmoPokemon = new JComboBox(); 81 | cmoPokemon.setModel(new DefaultComboBoxModel(Lists.pokemon.toArray())); 82 | cmoPokemon.addActionListener((java.awt.event.ActionEvent evt) -> { 83 | if (selectedEntry == null) 84 | return; 85 | 86 | selectedEntry.species = cmoPokemon.getSelectedIndex(); 87 | entryModel.set(listEntries.getSelectedIndex(), selectedEntry.toString()); 88 | }); 89 | spnLevel = new JSpinner(); 90 | spnLevel.setModel(new SpinnerNumberModel(1, 1, 99, 1)); 91 | spnLevel.addChangeListener((javax.swing.event.ChangeEvent evt) -> { 92 | if (selectedEntry == null) 93 | return; 94 | 95 | selectedEntry.level = (int) spnLevel.getValue(); 96 | entryModel.set(listEntries.getSelectedIndex(), selectedEntry.toString()); 97 | }); 98 | spnProbability = new JSpinner(); 99 | spnProbability.setModel(new SpinnerNumberModel(0, 0, 10000, 1)); 100 | spnProbability.setEditor(new JSpinner.NumberEditor(spnProbability, "#,##0,00'%'")); 101 | spnProbability.addChangeListener((javax.swing.event.ChangeEvent evt) -> { 102 | if (selectedEntry == null) 103 | return; 104 | 105 | selectedEntry.probability = (int) spnProbability.getValue(); 106 | entryModel.set(listEntries.getSelectedIndex(), selectedEntry.toString()); 107 | warningLabel(); 108 | }); 109 | 110 | // Add the components to the property panel 111 | properties.addCaption("Entries"); 112 | properties.addComponent(scroll); 113 | properties.addSeparator(); 114 | properties.addCaption("Entry settings"); 115 | properties.addLabeledComponent(lblPokemon, cmoPokemon); 116 | properties.addLabeledComponent(lblLevel, spnLevel); 117 | properties.addLabeledComponent(lblProbability, spnProbability); 118 | properties.addTerminator(); 119 | } 120 | 121 | @Override 122 | protected void load() { 123 | if (list.getSelectedIndex() < 0) 124 | return; 125 | 126 | entryModel.clear(); 127 | selected = (DungeonPokemon) RomFile.current.dungeonPokemon.get(list.getSelectedIndex()).clone(); 128 | selected.entries.forEach((entry) -> { entryModel.addElement(entry.toString()); }); 129 | listEntries.setSelectedIndex(selected.entries.size() > 0 ? 0 : -1); 130 | 131 | warningLabel(); 132 | } 133 | 134 | @Override 135 | protected void save() { 136 | if (selected == null || list.getSelectedIndex() < 0) 137 | return; 138 | 139 | RomFile.current.dungeonPokemon.set(list.getSelectedIndex(), selected); 140 | } 141 | 142 | @Override 143 | protected void warningLabel() { 144 | warningLabel.setText(selected.checkProbabilitySum() ? "Warning! Probability sum does not equal 10000." : ""); 145 | } 146 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/MoneyEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import com.aurum.mystery2.game.RomFile; 21 | 22 | public class MoneyEditor extends javax.swing.JFrame { 23 | 24 | public MoneyEditor() { 25 | initComponents(); 26 | spnFactor.setValue(1); 27 | spnValue.setValue(RomFile.current.moneyfactors[0]); 28 | } 29 | 30 | @SuppressWarnings("unchecked") 31 | // //GEN-BEGIN:initComponents 32 | private void initComponents() { 33 | 34 | lblFactor = new javax.swing.JLabel(); 35 | lblValue = new javax.swing.JLabel(); 36 | spnFactor = new javax.swing.JSpinner(); 37 | spnValue = new javax.swing.JSpinner(); 38 | btnSave = new javax.swing.JButton(); 39 | 40 | setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); 41 | setTitle("POKé factors editor"); 42 | setIconImage(com.aurum.mystery2.Main.icon); 43 | setResizable(false); 44 | 45 | lblFactor.setText("Factor"); 46 | 47 | lblValue.setText("Value"); 48 | 49 | spnFactor.setModel(new javax.swing.SpinnerNumberModel(1, 1, 100, 1)); 50 | spnFactor.addChangeListener(new javax.swing.event.ChangeListener() { 51 | public void stateChanged(javax.swing.event.ChangeEvent evt) { 52 | spnFactorStateChanged(evt); 53 | } 54 | }); 55 | 56 | spnValue.setModel(new javax.swing.SpinnerNumberModel(Long.valueOf(0L), Long.valueOf(0L), Long.valueOf(2147483647L), Long.valueOf(1L))); 57 | spnValue.setEditor(new javax.swing.JSpinner.NumberEditor(spnValue, "0")); 58 | 59 | btnSave.setText("Save"); 60 | btnSave.addActionListener(new java.awt.event.ActionListener() { 61 | public void actionPerformed(java.awt.event.ActionEvent evt) { 62 | btnSaveActionPerformed(evt); 63 | } 64 | }); 65 | 66 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 67 | getContentPane().setLayout(layout); 68 | layout.setHorizontalGroup( 69 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 70 | .addGroup(layout.createSequentialGroup() 71 | .addContainerGap() 72 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 73 | .addGroup(layout.createSequentialGroup() 74 | .addComponent(lblFactor) 75 | .addGap(29, 29, 29) 76 | .addComponent(spnFactor, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE) 77 | .addContainerGap()) 78 | .addGroup(layout.createSequentialGroup() 79 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 80 | .addGroup(layout.createSequentialGroup() 81 | .addComponent(btnSave) 82 | .addGap(0, 0, Short.MAX_VALUE)) 83 | .addGroup(layout.createSequentialGroup() 84 | .addComponent(lblValue) 85 | .addGap(34, 34, 34) 86 | .addComponent(spnValue))) 87 | .addGap(10, 10, 10)))) 88 | ); 89 | layout.setVerticalGroup( 90 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 91 | .addGroup(layout.createSequentialGroup() 92 | .addContainerGap() 93 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 94 | .addComponent(lblFactor) 95 | .addComponent(spnFactor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 96 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 97 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 98 | .addComponent(lblValue) 99 | .addComponent(spnValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 100 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 101 | .addComponent(btnSave) 102 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 103 | ); 104 | 105 | pack(); 106 | setLocationRelativeTo(null); 107 | }// //GEN-END:initComponents 108 | 109 | private void spnFactorStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnFactorStateChanged 110 | spnValue.setValue(RomFile.current.moneyfactors[(int) spnFactor.getValue() - 1]); 111 | }//GEN-LAST:event_spnFactorStateChanged 112 | 113 | private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed 114 | RomFile.current.moneyfactors[(int) spnFactor.getValue() - 1] = (long) spnValue.getValue(); 115 | }//GEN-LAST:event_btnSaveActionPerformed 116 | 117 | // Variables declaration - do not modify//GEN-BEGIN:variables 118 | private javax.swing.JButton btnSave; 119 | private javax.swing.JLabel lblFactor; 120 | private javax.swing.JLabel lblValue; 121 | private javax.swing.JSpinner spnFactor; 122 | private javax.swing.JSpinner spnValue; 123 | // End of variables declaration//GEN-END:variables 124 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/CalcProbability.java: -------------------------------------------------------------------------------- 1 | package com.aurum.mystery2.swing; 2 | 3 | public class CalcProbability extends javax.swing.JFrame { 4 | public CalcProbability() { 5 | initComponents(); 6 | } 7 | 8 | @SuppressWarnings("unchecked") 9 | // //GEN-BEGIN:initComponents 10 | private void initComponents() { 11 | 12 | lblLevel = new javax.swing.JLabel(); 13 | lblFactor = new javax.swing.JLabel(); 14 | spnLevel = new javax.swing.JSpinner(); 15 | spnFactor = new javax.swing.JSpinner(); 16 | chkFriendBow = new javax.swing.JCheckBox(); 17 | btnCalc = new javax.swing.JButton(); 18 | txtResult = new javax.swing.JTextField(); 19 | 20 | setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); 21 | setTitle("Recruitment probabilty calculator"); 22 | setIconImage(com.aurum.mystery2.Main.icon); 23 | setResizable(false); 24 | 25 | lblLevel.setText("Player level"); 26 | 27 | lblFactor.setText("Enemy factor"); 28 | 29 | spnLevel.setModel(new javax.swing.SpinnerNumberModel(1, 1, 100, 1)); 30 | 31 | spnFactor.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1)); 32 | 33 | chkFriendBow.setText("Has Friend Bow"); 34 | 35 | btnCalc.setText("Calculate"); 36 | btnCalc.addActionListener(new java.awt.event.ActionListener() { 37 | public void actionPerformed(java.awt.event.ActionEvent evt) { 38 | btnCalcActionPerformed(evt); 39 | } 40 | }); 41 | 42 | txtResult.setEditable(false); 43 | txtResult.setHorizontalAlignment(javax.swing.JTextField.RIGHT); 44 | txtResult.setText("0.0%"); 45 | 46 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 47 | getContentPane().setLayout(layout); 48 | layout.setHorizontalGroup( 49 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 50 | .addGroup(layout.createSequentialGroup() 51 | .addContainerGap() 52 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 53 | .addComponent(chkFriendBow) 54 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) 55 | .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() 56 | .addComponent(btnCalc) 57 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 58 | .addComponent(txtResult)) 59 | .addGroup(layout.createSequentialGroup() 60 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 61 | .addComponent(lblLevel) 62 | .addComponent(lblFactor)) 63 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 64 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) 65 | .addComponent(spnFactor) 66 | .addComponent(spnLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE))))) 67 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 68 | ); 69 | layout.setVerticalGroup( 70 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 71 | .addGroup(layout.createSequentialGroup() 72 | .addContainerGap() 73 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 74 | .addComponent(lblLevel) 75 | .addComponent(spnLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 76 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 77 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 78 | .addComponent(lblFactor) 79 | .addComponent(spnFactor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 80 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 81 | .addComponent(chkFriendBow) 82 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 83 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 84 | .addComponent(btnCalc) 85 | .addComponent(txtResult, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 86 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 87 | ); 88 | 89 | pack(); 90 | setLocationRelativeTo(null); 91 | }// //GEN-END:initComponents 92 | 93 | private void btnCalcActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCalcActionPerformed 94 | int level = (int) spnLevel.getValue(); 95 | 96 | int levelfactor = 0; 97 | if (level >= 30 && level <= 39) levelfactor = 50; 98 | else if (level >= 30 && level <= 39) levelfactor = 50; 99 | else if (level >= 40 && level <= 49) levelfactor = 75; 100 | else if (level >= 50 && level <= 59) levelfactor = 100; 101 | else if (level >= 60 && level <= 69) levelfactor = 125; 102 | else if (level >= 70 && level <= 79) levelfactor = 150; 103 | else if (level >= 80 && level <= 89) levelfactor = 175; 104 | else if (level >= 90 && level <= 100) levelfactor = 240; 105 | 106 | float sum = (levelfactor + (short) spnFactor.getValue() + (chkFriendBow.isSelected() ? 100F : 0F)) / 10F; 107 | txtResult.setText(Float.toString(sum) + '%'); 108 | }//GEN-LAST:event_btnCalcActionPerformed 109 | 110 | // Variables declaration - do not modify//GEN-BEGIN:variables 111 | private javax.swing.JButton btnCalc; 112 | private javax.swing.JCheckBox chkFriendBow; 113 | private javax.swing.JLabel lblFactor; 114 | private javax.swing.JLabel lblLevel; 115 | private javax.swing.JSpinner spnFactor; 116 | private javax.swing.JSpinner spnLevel; 117 | private javax.swing.JTextField txtResult; 118 | // End of variables declaration//GEN-END:variables 119 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/MoneyEditor.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
119 | -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/AbstractEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import javax.swing.DefaultListModel; 21 | import javax.swing.JFrame; 22 | 23 | public abstract class AbstractEditor extends JFrame { 24 | public AbstractEditor() { 25 | initComponents(); 26 | initProperties(); 27 | } 28 | 29 | protected abstract void initProperties(); 30 | protected abstract void load(); 31 | protected abstract void save(); 32 | protected abstract void warningLabel(); 33 | 34 | @SuppressWarnings("unchecked") 35 | // //GEN-BEGIN:initComponents 36 | private void initComponents() { 37 | 38 | warningLabel = new javax.swing.JLabel(); 39 | scrollList = new javax.swing.JScrollPane(); 40 | list = new javax.swing.JList<>(); 41 | scrollProperties = new javax.swing.JScrollPane(); 42 | properties = new com.aurum.mystery2.swing.JPropertyPanel(); 43 | toolbar = new javax.swing.JToolBar(); 44 | saveButton = new javax.swing.JButton(); 45 | 46 | setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); 47 | setTitle("Abstract editor form"); 48 | setIconImage(com.aurum.mystery2.Main.icon); 49 | setResizable(false); 50 | 51 | warningLabel.setForeground(new java.awt.Color(255, 0, 0)); 52 | warningLabel.setText(" "); 53 | warningLabel.setToolTipText(""); 54 | 55 | list.setModel(model = new DefaultListModel()); 56 | list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 57 | list.setMaximumSize(new java.awt.Dimension(275, 535)); 58 | list.setMinimumSize(new java.awt.Dimension(275, 535)); 59 | list.addListSelectionListener(new javax.swing.event.ListSelectionListener() { 60 | public void valueChanged(javax.swing.event.ListSelectionEvent evt) { 61 | listValueChanged(evt); 62 | } 63 | }); 64 | scrollList.setViewportView(list); 65 | 66 | scrollProperties.setMaximumSize(new java.awt.Dimension(400, 525)); 67 | scrollProperties.setMinimumSize(new java.awt.Dimension(400, 525)); 68 | scrollProperties.setPreferredSize(new java.awt.Dimension(400, 525)); 69 | 70 | properties.setMaximumSize(new java.awt.Dimension(400, 505)); 71 | properties.setMinimumSize(new java.awt.Dimension(400, 505)); 72 | scrollProperties.setViewportView(properties); 73 | 74 | toolbar.setFloatable(false); 75 | toolbar.setRollover(true); 76 | 77 | saveButton.setText("Save entry"); 78 | saveButton.addActionListener(new java.awt.event.ActionListener() { 79 | public void actionPerformed(java.awt.event.ActionEvent evt) { 80 | saveButtonActionPerformed(evt); 81 | } 82 | }); 83 | toolbar.add(saveButton); 84 | 85 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 86 | getContentPane().setLayout(layout); 87 | layout.setHorizontalGroup( 88 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 89 | .addComponent(toolbar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 90 | .addGroup(layout.createSequentialGroup() 91 | .addContainerGap() 92 | .addComponent(scrollList, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE) 93 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 94 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 95 | .addComponent(warningLabel) 96 | .addComponent(scrollProperties, javax.swing.GroupLayout.PREFERRED_SIZE, 500, javax.swing.GroupLayout.PREFERRED_SIZE)) 97 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 98 | ); 99 | layout.setVerticalGroup( 100 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 101 | .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 102 | .addComponent(toolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) 103 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 104 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 105 | .addComponent(scrollList, javax.swing.GroupLayout.PREFERRED_SIZE, 535, javax.swing.GroupLayout.PREFERRED_SIZE) 106 | .addComponent(scrollProperties, javax.swing.GroupLayout.PREFERRED_SIZE, 535, javax.swing.GroupLayout.PREFERRED_SIZE)) 107 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 108 | .addComponent(warningLabel) 109 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 110 | ); 111 | 112 | pack(); 113 | setLocationRelativeTo(null); 114 | }// //GEN-END:initComponents 115 | 116 | private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed 117 | save(); 118 | }//GEN-LAST:event_saveButtonActionPerformed 119 | 120 | private void listValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_listValueChanged 121 | load(); 122 | }//GEN-LAST:event_listValueChanged 123 | 124 | protected DefaultListModel model; 125 | 126 | // Variables declaration - do not modify//GEN-BEGIN:variables 127 | protected javax.swing.JList list; 128 | protected com.aurum.mystery2.swing.JPropertyPanel properties; 129 | protected javax.swing.JButton saveButton; 130 | protected javax.swing.JScrollPane scrollList; 131 | protected javax.swing.JScrollPane scrollProperties; 132 | protected javax.swing.JToolBar toolbar; 133 | protected javax.swing.JLabel warningLabel; 134 | // End of variables declaration//GEN-END:variables 135 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/Pokemon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.BitConverter; 21 | import com.aurum.mystery2.ByteBuffer; 22 | import com.aurum.mystery2.ByteOrder; 23 | 24 | public class Pokemon implements Cloneable { 25 | // Entry fields 26 | public String species, category; 27 | public int speciesPointer, categoryPointer; 28 | public short size, shadow, walkable, recruit, faces; 29 | public short type1, type2, ability1, ability2, area, palette; 30 | public int evolveFrom, evolveType, evolveParam, evolveAddition, speed; 31 | public int hp, atk, spatk, def, spdef, basexp; 32 | public int dexNo, internalNo, parentNo, alphabetNo, lowKick, sizeBust; 33 | public boolean isMoving; 34 | 35 | // Unknown fields 36 | public byte unk1A, unk1B, unk1D, unk30, unk31, unk32; 37 | public int unk22; 38 | public boolean unk33; 39 | 40 | // Static fields 41 | public static final int SIZE = 0x48; 42 | 43 | @Override 44 | public String toString() { 45 | return species; 46 | } 47 | 48 | @Override 49 | public Object clone() { 50 | try { 51 | return super.clone(); 52 | } 53 | catch (CloneNotSupportedException ex) { 54 | return null; 55 | } 56 | } 57 | 58 | public static Pokemon unpack(ByteBuffer buffer) { 59 | Pokemon mon = new Pokemon(); 60 | 61 | int nextOffset = buffer.position() + SIZE; 62 | 63 | // Fields 64 | mon.speciesPointer = buffer.readInt(); 65 | mon.categoryPointer = buffer.readInt(); 66 | mon.palette = buffer.readUnsignedByte(); 67 | mon.size = buffer.readUnsignedByte(); 68 | buffer.skip(0x2); 69 | mon.speed = buffer.readInt(); 70 | mon.faces = buffer.readShort(); 71 | buffer.skip(0x1); 72 | mon.type1 = buffer.readUnsignedByte(); 73 | mon.type2 = buffer.readUnsignedByte(); 74 | mon.walkable = buffer.readUnsignedByte(); 75 | mon.area = buffer.readUnsignedByte(); 76 | mon.ability1 = buffer.readUnsignedByte(); 77 | mon.ability2 = buffer.readUnsignedByte(); 78 | mon.shadow = buffer.readUnsignedByte(); 79 | mon.unk1A = buffer.readByte(); 80 | mon.unk1B = buffer.readByte(); 81 | mon.isMoving = buffer.readBoolean(); 82 | mon.unk1D = buffer.readByte(); 83 | mon.hp = buffer.readUnsignedShort(); 84 | mon.basexp = buffer.readUnsignedShort(); 85 | mon.unk22 = buffer.readUnsignedShort(); 86 | mon.atk = buffer.readUnsignedShort(); 87 | mon.spatk = buffer.readUnsignedShort(); 88 | mon.def = buffer.readUnsignedShort(); 89 | mon.spdef = buffer.readUnsignedShort(); 90 | mon.lowKick = buffer.readUnsignedShort(); 91 | mon.sizeBust = buffer.readUnsignedShort(); 92 | mon.unk30 = buffer.readByte(); 93 | mon.unk31 = buffer.readByte(); 94 | mon.unk32 = buffer.readByte(); 95 | mon.unk33 = buffer.readBoolean(); 96 | mon.evolveFrom = buffer.readUnsignedShort(); 97 | mon.evolveType = buffer.readUnsignedShort(); 98 | mon.evolveParam = buffer.readUnsignedShort(); 99 | mon.evolveAddition = buffer.readUnsignedShort(); 100 | mon.dexNo = buffer.readUnsignedShort(); 101 | mon.internalNo = buffer.readUnsignedShort(); 102 | mon.recruit = buffer.readShort(); 103 | mon.alphabetNo = buffer.readUnsignedShort(); 104 | mon.parentNo = buffer.readUnsignedShort(); 105 | 106 | // Strings 107 | if (mon.speciesPointer != 0x00000000) mon.species = buffer.readStringAt(BitConverter.pointerToOffset(mon.speciesPointer)); 108 | if (mon.categoryPointer != 0x00000000) mon.category = buffer.readStringAt(BitConverter.pointerToOffset(mon.categoryPointer)); 109 | 110 | buffer.seek(nextOffset); 111 | 112 | return mon; 113 | } 114 | 115 | public static byte[] pack(Pokemon pokemon) { 116 | ByteBuffer buffer = new ByteBuffer(0x48, ByteOrder.LITTLE_ENDIAN); 117 | 118 | buffer.writeInt(pokemon.speciesPointer); 119 | buffer.writeInt(pokemon.categoryPointer); 120 | buffer.writeUnsignedByte(pokemon.palette); 121 | buffer.writeUnsignedByte(pokemon.size); 122 | buffer.writeShort((short) 0); 123 | buffer.writeInt(pokemon.speed); 124 | buffer.writeShort(pokemon.faces); 125 | buffer.writeByte((byte) 0); 126 | buffer.writeUnsignedByte(pokemon.type1); 127 | buffer.writeUnsignedByte(pokemon.type2); 128 | buffer.writeUnsignedByte(pokemon.walkable); 129 | buffer.writeUnsignedByte(pokemon.area); 130 | buffer.writeUnsignedByte(pokemon.ability1); 131 | buffer.writeUnsignedByte(pokemon.ability2); 132 | buffer.writeUnsignedByte(pokemon.shadow); 133 | buffer.writeByte(pokemon.unk1A); 134 | buffer.writeByte(pokemon.unk1B); 135 | buffer.writeBoolean(pokemon.isMoving); 136 | buffer.writeByte(pokemon.unk1D); 137 | buffer.writeUnsignedShort(pokemon.hp); 138 | buffer.writeUnsignedShort(pokemon.basexp); 139 | buffer.writeUnsignedShort(pokemon.unk22); 140 | buffer.writeUnsignedShort(pokemon.atk); 141 | buffer.writeUnsignedShort(pokemon.spatk); 142 | buffer.writeUnsignedShort(pokemon.def); 143 | buffer.writeUnsignedShort(pokemon.spdef); 144 | buffer.writeUnsignedShort(pokemon.lowKick); 145 | buffer.writeUnsignedShort(pokemon.sizeBust); 146 | buffer.writeByte(pokemon.unk30); 147 | buffer.writeByte(pokemon.unk31); 148 | buffer.writeByte(pokemon.unk32); 149 | buffer.writeBoolean(pokemon.unk33); 150 | buffer.writeUnsignedShort(pokemon.evolveFrom); 151 | buffer.writeUnsignedShort(pokemon.evolveType); 152 | buffer.writeUnsignedShort(pokemon.evolveParam); 153 | buffer.writeUnsignedShort(pokemon.evolveAddition); 154 | buffer.writeUnsignedShort(pokemon.dexNo); 155 | buffer.writeUnsignedShort(pokemon.internalNo); 156 | buffer.writeShort(pokemon.recruit); 157 | buffer.writeUnsignedShort(pokemon.alphabetNo); 158 | buffer.writeUnsignedShort(pokemon.parentNo); 159 | 160 | return buffer.getBuffer(); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/CalcProbability.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 |
130 | -------------------------------------------------------------------------------- /src/com/aurum/mystery2/BitConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2; 19 | 20 | public class BitConverter { 21 | public static int stringToInt(String value) { 22 | return value != null ? Integer.decode(value) : 0; 23 | } 24 | 25 | public static String toHexByteString(byte value) { 26 | return String.format("%02X", value); 27 | } 28 | 29 | public static String toBinByteString(byte value) { 30 | String ret = Integer.toBinaryString(value & 0xFF); 31 | while (ret.length() < 8) 32 | ret = '0' + ret; 33 | return ret; 34 | } 35 | 36 | public static String toHexShortString(short value) { 37 | return String.format("%04X", value); 38 | } 39 | 40 | public static String toBinShortString(short value) { 41 | String ret = Integer.toBinaryString(value & 0xFFFF); 42 | while (ret.length() < 16) 43 | ret = '0' + ret; 44 | return ret; 45 | } 46 | 47 | public static String toHexIntString(int value) { 48 | return String.format("%08X", value); 49 | } 50 | 51 | public static String toBinIntString(int value) { 52 | String ret = Integer.toBinaryString(value); 53 | while (ret.length() < 32) 54 | ret = '0' + ret; 55 | return ret; 56 | } 57 | 58 | public static int pointerToOffset(int pointer) { 59 | return pointer & 0x07FFFFFF; 60 | } 61 | 62 | public static int offsetToPointer(int offset) { 63 | return offset | 0x08000000; 64 | } 65 | 66 | public static byte[] reverse(byte[] data) { 67 | byte[] ret = new byte[data.length]; 68 | for (int i = 0 ; i < data.length ; i++) 69 | ret[i] = data[data.length - 1 - i]; 70 | return ret; 71 | } 72 | 73 | public static byte toByte(byte[] data, int offset) { 74 | return data[offset]; 75 | } 76 | 77 | public static short toUByte(byte[] data, int offset) { 78 | return (short) (data[offset] & 0xFF); 79 | } 80 | 81 | public static short toShort(byte[] data, ByteOrder endian, int offset) { 82 | byte[] bytes = new byte[Short.BYTES]; 83 | for (int i = 0 ; i < Short.BYTES ; i++) 84 | bytes[i] = data[i+offset]; 85 | bytes = endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes; 86 | return (short) ( 87 | ((bytes[0] & 0xFF) << 8) 88 | | (bytes[1] & 0xFF) 89 | ); 90 | } 91 | 92 | public static int toUShort(byte[] data, ByteOrder endian, int offset) { 93 | return (int) (toShort(data, endian, offset) & 0xFFFF); 94 | } 95 | 96 | public static int toInt(byte[] data, ByteOrder endian, int offset) { 97 | byte[] bytes = new byte[Integer.BYTES]; 98 | for (int i = 0 ; i < Integer.BYTES ; i++) 99 | bytes[i] = data[i+offset]; 100 | bytes = endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes; 101 | return (int) ( 102 | ((bytes[0] & 0xFF) << 24) 103 | | ((bytes[1] & 0xFF) << 16) 104 | | ((bytes[2] & 0xFF) << 8) 105 | | (bytes[3] & 0xFF) 106 | ); 107 | } 108 | 109 | public static long toUInt(byte[] data, ByteOrder endian, int offset) { 110 | return (long) (toInt(data, endian, offset) & 0xFFFFFFFF); 111 | } 112 | 113 | public static long toLong(byte[] data, ByteOrder endian, int offset) { 114 | byte[] bytes = new byte[Long.BYTES]; 115 | for (int i = 0 ; i < Long.BYTES ; i++) 116 | bytes[i] = data[i+offset]; 117 | bytes = endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes; 118 | return (long) ( 119 | ((long) (bytes[0] & 0xFF) << 56) 120 | | ((long) (bytes[1] & 0xFF) << 48) 121 | | ((long) (bytes[2] & 0xFF) << 40) 122 | | ((long) (bytes[3] & 0xFF) << 32) 123 | | ((long) (bytes[4] & 0xFF) << 24) 124 | | ((long) (bytes[5] & 0xFF) << 16) 125 | | ((long) (bytes[6] & 0xFF) << 8) 126 | | (long) (bytes[7] & 0xFF) 127 | ); 128 | } 129 | 130 | public static float toFloat(byte[] data, ByteOrder endian, int offset) { 131 | return Float.intBitsToFloat(toInt(data, endian, offset)); 132 | } 133 | 134 | public static double toDouble(byte[] data, ByteOrder endian, int offset) { 135 | return Double.longBitsToDouble(toLong(data, endian, offset)); 136 | } 137 | 138 | public static char toCharacter(byte[] data, ByteOrder endian, int offset) { 139 | return (char) toShort(data, endian, offset); 140 | } 141 | 142 | public static boolean toBoolean(byte[] data, int offset) { 143 | return data[offset] != 0; 144 | } 145 | 146 | public static byte[] getBytes(short val, ByteOrder endian) { 147 | byte[] bytes = new byte[Short.BYTES]; 148 | bytes[0] = (byte) ((val >> 8) & 0xFF); 149 | bytes[1] = (byte) (val & 0xFF); 150 | return endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes; 151 | } 152 | 153 | public static byte[] getBytes(int val, ByteOrder endian) { 154 | byte[] bytes = new byte[Integer.BYTES]; 155 | bytes[0] = (byte) ((val >> 24) & 0xFF); 156 | bytes[1] = (byte) ((val >> 16) & 0xFF); 157 | bytes[2] = (byte) ((val >> 8) & 0xFF); 158 | bytes[3] = (byte) (val & 0xFF); 159 | return endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes; 160 | } 161 | 162 | public static byte[] getBytes(long val, ByteOrder endian) { 163 | byte[] bytes = new byte[Long.BYTES]; 164 | bytes[0] = (byte) ((val >> 56) & 0xFF); 165 | bytes[1] = (byte) ((val >> 48) & 0xFF); 166 | bytes[2] = (byte) ((val >> 40) & 0xFF); 167 | bytes[3] = (byte) ((val >> 32) & 0xFF); 168 | bytes[4] = (byte) ((val >> 24) & 0xFF); 169 | bytes[5] = (byte) ((val >> 16) & 0xFF); 170 | bytes[6] = (byte) ((val >> 8) & 0xFF); 171 | bytes[7] = (byte) (val & 0xFF); 172 | return endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes; 173 | } 174 | 175 | public static byte[] getBytes(float val, ByteOrder endian) { 176 | return getBytes(Float.floatToIntBits(val), endian); 177 | } 178 | 179 | public static byte[] getBytes(double val, ByteOrder endian) { 180 | return getBytes(Double.doubleToLongBits(val), endian); 181 | } 182 | 183 | public static byte[] getBytes(char val, ByteOrder endian) { 184 | return getBytes((short) val, endian); 185 | } 186 | 187 | public static byte[] getBytes(boolean val) { 188 | return new byte[] { (byte) (val ? 1 : 0) }; 189 | } 190 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/Move.java: -------------------------------------------------------------------------------- 1 | package com.aurum.mystery2.game; 2 | 3 | import com.aurum.mystery2.BitConverter; 4 | import com.aurum.mystery2.ByteBuffer; 5 | import com.aurum.mystery2.ByteOrder; 6 | 7 | public class Move implements Cloneable { 8 | // Entry fields 9 | public String name, desc, log, japUnk1, japUnk2, japNext; 10 | public int namePointer, descPointer, logPointer, japUnk1Pointer, japUnk2Pointer, japNextPointer; 11 | public int type; 12 | public short ap, usesPerRound, range; 13 | public byte accuracy1, accuracy2, critical; 14 | 15 | // Unknown fields 16 | public byte unkD, unk10, unk12; 17 | public short unk4, unk8, unkA; 18 | public boolean unk14, unk15, unk16, unk17, unk18; 19 | 20 | // Static fields 21 | public static final int SIZE = 0x24; 22 | public static final int SIZE_JAP = 0x2C; 23 | 24 | @Override 25 | public String toString() { 26 | return name; 27 | } 28 | 29 | @Override 30 | public Object clone() { 31 | try { 32 | return super.clone(); 33 | } 34 | catch (CloneNotSupportedException ex) { 35 | return null; 36 | } 37 | } 38 | 39 | public static Move unpack(ByteBuffer buffer) { 40 | Move move = new Move(); 41 | 42 | int nextOffset = buffer.position() + (RomFile.current.isJapanese() ? SIZE_JAP : SIZE); 43 | 44 | // Fields 45 | if (RomFile.current.isJapanese()) { 46 | move.namePointer = buffer.readInt(); 47 | move.unk4 = buffer.readShort(); 48 | move.type = buffer.readUnsignedShort(); 49 | move.unk8 = buffer.readShort(); 50 | move.unkA = buffer.readShort(); 51 | move.ap = buffer.readUnsignedByte(); 52 | move.unkD = buffer.readByte(); 53 | move.accuracy1 = buffer.readByte(); 54 | move.accuracy2 = buffer.readByte(); 55 | move.unk10 = buffer.readByte(); 56 | move.usesPerRound = buffer.readUnsignedByte(); 57 | move.unk12 = buffer.readByte(); 58 | move.critical = buffer.readByte(); 59 | move.unk14 = buffer.readBoolean(); 60 | move.unk15 = buffer.readBoolean(); 61 | move.unk16 = buffer.readBoolean(); 62 | move.unk17 = buffer.readBoolean(); 63 | move.unk18 = buffer.readBoolean(); 64 | move.range = buffer.readUnsignedByte(); 65 | buffer.skip(0x2); 66 | move.descPointer = buffer.readInt(); 67 | move.japUnk1Pointer = buffer.readInt(); 68 | move.japUnk2Pointer = buffer.readInt(); 69 | move.logPointer = buffer.readInt(); 70 | move.japNextPointer = buffer.readInt(); 71 | } 72 | else { 73 | move.namePointer = buffer.readInt(); 74 | move.unk4 = buffer.readShort(); 75 | move.type = buffer.readUnsignedShort(); 76 | move.unk8 = buffer.readShort(); 77 | move.unkA = buffer.readShort(); 78 | move.ap = buffer.readUnsignedByte(); 79 | move.unkD = buffer.readByte(); 80 | move.accuracy1 = buffer.readByte(); 81 | move.accuracy2 = buffer.readByte(); 82 | move.unk10 = buffer.readByte(); 83 | move.usesPerRound = buffer.readUnsignedByte(); 84 | move.unk12 = buffer.readByte(); 85 | move.critical = buffer.readByte(); 86 | move.unk14 = buffer.readBoolean(); 87 | move.unk15 = buffer.readBoolean(); 88 | move.unk16 = buffer.readBoolean(); 89 | move.unk17 = buffer.readBoolean(); 90 | move.unk18 = buffer.readBoolean(); 91 | move.range = buffer.readUnsignedByte(); 92 | buffer.skip(0x2); 93 | move.descPointer = buffer.readInt(); 94 | move.logPointer = buffer.readInt(); 95 | } 96 | 97 | // Strings 98 | if (move.namePointer != 0x00000000) move.name = buffer.readStringAt(BitConverter.pointerToOffset(move.namePointer)); 99 | if (move.descPointer != 0x00000000) move.desc = buffer.readStringAt(BitConverter.pointerToOffset(move.descPointer)); 100 | if (move.logPointer != 0x00000000) move.log = buffer.readStringAt(BitConverter.pointerToOffset(move.logPointer)); 101 | if (move.japUnk1Pointer != 0x00000000) move.japUnk1 = buffer.readStringAt(BitConverter.pointerToOffset(move.japUnk1Pointer)); 102 | if (move.japUnk2Pointer != 0x00000000) move.japUnk2 = buffer.readStringAt(BitConverter.pointerToOffset(move.japUnk2Pointer)); 103 | if (move.japNextPointer != 0x00000000) move.japNext = buffer.readStringAt(BitConverter.pointerToOffset(move.japNextPointer)); 104 | 105 | buffer.seek(nextOffset); 106 | 107 | return move; 108 | } 109 | 110 | public static byte[] pack(Move move) { 111 | ByteBuffer buffer = new ByteBuffer(RomFile.current.isJapanese() ? SIZE_JAP : SIZE, ByteOrder.LITTLE_ENDIAN); 112 | 113 | if (RomFile.current.isJapanese()) { 114 | buffer.writeInt(move.namePointer); 115 | buffer.writeShort(move.unk4); 116 | buffer.writeUnsignedShort(move.type); 117 | buffer.writeShort(move.unk8); 118 | buffer.writeShort(move.unkA); 119 | buffer.writeUnsignedByte(move.ap); 120 | buffer.writeByte(move.unkD); 121 | buffer.writeByte(move.accuracy1); 122 | buffer.writeByte(move.accuracy2); 123 | buffer.writeByte(move.unk10); 124 | buffer.writeUnsignedByte(move.usesPerRound); 125 | buffer.writeByte(move.unk12); 126 | buffer.writeByte(move.critical); 127 | buffer.writeBoolean(move.unk14); 128 | buffer.writeBoolean(move.unk15); 129 | buffer.writeBoolean(move.unk16); 130 | buffer.writeBoolean(move.unk17); 131 | buffer.writeBoolean(move.unk18); 132 | buffer.writeUnsignedByte(move.range); 133 | buffer.writeShort((short) 0); 134 | buffer.writeInt(move.descPointer); 135 | buffer.writeInt(move.japUnk1Pointer); 136 | buffer.writeInt(move.japUnk2Pointer); 137 | buffer.writeInt(move.logPointer); 138 | buffer.writeInt(move.japNextPointer); 139 | } 140 | else { 141 | buffer.writeInt(move.namePointer); 142 | buffer.writeShort(move.unk4); 143 | buffer.writeUnsignedShort(move.type); 144 | buffer.writeShort(move.unk8); 145 | buffer.writeShort(move.unkA); 146 | buffer.writeUnsignedByte(move.ap); 147 | buffer.writeByte(move.unkD); 148 | buffer.writeByte(move.accuracy1); 149 | buffer.writeByte(move.accuracy2); 150 | buffer.writeByte(move.unk10); 151 | buffer.writeUnsignedByte(move.usesPerRound); 152 | buffer.writeByte(move.unk12); 153 | buffer.writeByte(move.critical); 154 | buffer.writeBoolean(move.unk14); 155 | buffer.writeBoolean(move.unk15); 156 | buffer.writeBoolean(move.unk16); 157 | buffer.writeBoolean(move.unk17); 158 | buffer.writeBoolean(move.unk18); 159 | buffer.writeUnsignedByte(move.range); 160 | buffer.writeShort((short) 0); 161 | buffer.writeInt(move.descPointer); 162 | buffer.writeInt(move.logPointer); 163 | } 164 | 165 | return buffer.getBuffer(); 166 | } 167 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/MapEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import com.aurum.mystery2.Lists; 21 | import com.aurum.mystery2.Main; 22 | import com.aurum.mystery2.game.Dungeon; 23 | import com.aurum.mystery2.game.RomFile; 24 | import java.awt.Component; 25 | import java.awt.Dimension; 26 | import java.awt.Graphics; 27 | import java.awt.Image; 28 | import java.awt.Toolkit; 29 | import java.awt.event.MouseAdapter; 30 | import java.awt.event.MouseEvent; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | import javax.swing.Icon; 34 | import javax.swing.ImageIcon; 35 | import javax.swing.JLabel; 36 | import javax.swing.JPanel; 37 | import javax.swing.JSpinner; 38 | import javax.swing.SpinnerNumberModel; 39 | 40 | public class MapEditor extends AbstractEditor { 41 | private JMapPoint selected; 42 | private JMapPanel map; 43 | private JLabel lblX,lblY; 44 | private JSpinner spnX, spnY; 45 | 46 | @Override 47 | protected void initProperties() { 48 | setTitle("Map editor"); 49 | 50 | // Initialize the components 51 | map = new JMapPanel(); 52 | lblX = new JLabel("X"); 53 | lblY = new JLabel("Y"); 54 | spnX = new JSpinner(); 55 | spnX.setModel(new SpinnerNumberModel(0, 0, 480, 1)); 56 | spnX.addChangeListener((javax.swing.event.ChangeEvent evt) -> { 57 | selected.setPointX((int) spnX.getValue()); 58 | }); 59 | spnY = new JSpinner(); 60 | spnY.setModel(new SpinnerNumberModel(0, 0, 320, 1)); 61 | spnY.addChangeListener((javax.swing.event.ChangeEvent evt) -> { 62 | selected.setPointY((int) spnY.getValue()); 63 | }); 64 | 65 | // Add the components to the property panel 66 | properties.addComponent(map); 67 | properties.addLabeledComponent(lblX, spnX); 68 | properties.addLabeledComponent(lblY, spnY); 69 | properties.addTerminator(); 70 | 71 | // Add map points 72 | for (int i = 0 ; i < 64 ; i++) { 73 | model.addElement(Lists.dungeons.get(i)); 74 | 75 | Dungeon dungeon = (Dungeon) RomFile.current.dungeons.get(i).clone(); 76 | JMapPoint point = new JMapPoint(i, dungeon.mapX, dungeon.mapY); 77 | point.addMouseListener(new MouseAdapter() { 78 | @Override 79 | public void mouseClicked(MouseEvent evt) { 80 | list.setSelectedIndex(point.getIndex()); 81 | list.ensureIndexIsVisible(point.getIndex()); 82 | } 83 | }); 84 | 85 | map.add(point); 86 | } 87 | } 88 | 89 | @Override 90 | protected void load() { 91 | int selectedIndex = list.getSelectedIndex(); 92 | boolean enable = selectedIndex >= 0; 93 | spnX.setEnabled(enable); 94 | spnY.setEnabled(enable); 95 | 96 | if (!enable) 97 | return; 98 | 99 | selected = map.setSelected(selectedIndex); 100 | spnX.setValue(selected.getPointX()); 101 | spnY.setValue(selected.getPointY()); 102 | } 103 | 104 | @Override 105 | protected void save() { 106 | for (int i = 0 ; i < 64 ; i++) { 107 | Dungeon dungeon = RomFile.current.dungeons.get(i); 108 | dungeon.mapX = map.points().get(i).getPointX(); 109 | dungeon.mapY = map.points().get(i).getPointY(); 110 | } 111 | } 112 | 113 | @Override 114 | protected void warningLabel() {} 115 | 116 | private static class JMapPanel extends JPanel { 117 | private final Image background = Toolkit.getDefaultToolkit().createImage(Main.class.getResource("/res/map.png")); 118 | private List points; 119 | private JMapPoint selectedPoint; 120 | 121 | public JMapPanel() { 122 | super.setLayout(null); 123 | points = new ArrayList(); 124 | super.setMinimumSize(new Dimension(480, 320)); 125 | super.setMaximumSize(new Dimension(480, 320)); 126 | super.setPreferredSize(new Dimension(480, 320)); 127 | } 128 | 129 | public List points() { 130 | return points; 131 | } 132 | 133 | public JMapPoint getSelected() { 134 | return selectedPoint; 135 | } 136 | 137 | public JMapPoint setSelected(int index) { 138 | if (selectedPoint != null) 139 | selectedPoint.setSelected(false); 140 | 141 | selectedPoint = points.get(index); 142 | selectedPoint.setSelected(true); 143 | if (selectedPoint.getIndex() != index) 144 | System.out.println("WARNING! Point indexes are not equal!"); 145 | 146 | return selectedPoint; 147 | } 148 | 149 | @Override 150 | public Component add(Component comp) { 151 | if (comp instanceof JMapPoint) 152 | points.add((JMapPoint) comp); 153 | 154 | super.add(comp); 155 | super.repaint(); 156 | 157 | return comp; 158 | } 159 | 160 | @Override 161 | protected void paintComponent(Graphics g) { 162 | if (background == null) 163 | return; 164 | 165 | g.drawImage(background, 0, 0, this); 166 | } 167 | } 168 | 169 | private static class JMapPoint extends JLabel { 170 | private boolean selected; 171 | private int x, y; 172 | private final int index; 173 | private final Icon mapIcon = new ImageIcon(getClass().getResource("/res/mapPoint.png")); 174 | private final Icon mapIconSelected = new ImageIcon(getClass().getResource("/res/mapPointSelected.png")); 175 | 176 | public JMapPoint(int index, int x, int y) { 177 | this.index = index; 178 | this.x = x; 179 | this.y = y; 180 | this.selected = false; 181 | setIcon(mapIcon); 182 | setBounds(x-5, y-5, 12, 12); 183 | } 184 | 185 | public int getIndex() { 186 | return index; 187 | } 188 | 189 | public int getPointX() { 190 | return x; 191 | } 192 | 193 | public void setPointX(int val) { 194 | x = val; 195 | setBounds(x-5, y-5, 12, 12); 196 | repaint(); 197 | } 198 | 199 | public int getPointY() { 200 | return y; 201 | } 202 | 203 | public void setPointY(int val) { 204 | y = val; 205 | setBounds(x-5, y-5, 12, 12); 206 | repaint(); 207 | } 208 | 209 | public boolean isSelected() { 210 | return selected; 211 | } 212 | 213 | public void setSelected(boolean b) { 214 | selected = b; 215 | setIcon(selected ? mapIconSelected : mapIcon); 216 | repaint(); 217 | } 218 | } 219 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/AbstractEditor.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
165 | -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/ItemEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import com.aurum.mystery2.BitConverter; 21 | import com.aurum.mystery2.Lists; 22 | import com.aurum.mystery2.Main; 23 | import com.aurum.mystery2.game.Item; 24 | import com.aurum.mystery2.game.RomFile; 25 | import java.awt.image.BufferedImage; 26 | import java.io.IOException; 27 | import javax.imageio.ImageIO; 28 | import javax.swing.DefaultComboBoxModel; 29 | import javax.swing.ImageIcon; 30 | import javax.swing.JCheckBox; 31 | import javax.swing.JComboBox; 32 | import javax.swing.JLabel; 33 | import javax.swing.JSlider; 34 | import javax.swing.JSpinner; 35 | import javax.swing.JTextField; 36 | import javax.swing.SpinnerNumberModel; 37 | import javax.swing.SwingConstants; 38 | 39 | public class ItemEditor extends AbstractEditor { 40 | private Item selected; 41 | 42 | private BufferedImage icons; 43 | 44 | private JLabel lblName, lblNamePointer, lblDesc, lblDescPointer; 45 | private JTextField txtName, txtNamePointer, txtDesc, txtDescPointer; 46 | 47 | private JLabel lblPreview, lblIcon, lblPalette; 48 | private JComboBox cmoIcon; 49 | private JSlider sdrPalette; 50 | 51 | private JLabel lblShopPrice, lblSellPrice, lblOrder, lblMove, lblType, lblSubtype; 52 | private JSpinner spnShopPrice, spnSellPrice, spnOrder; 53 | private JComboBox cmoMove, cmoType, cmoSubtype; 54 | 55 | private JLabel lblUnkThrow1, lblUnkThrow2; 56 | private JSpinner spnUnkThrow1, spnUnkThrow2; 57 | private JCheckBox chkThrowingDamage, chkUnkFood1, chkUnkFood2; 58 | 59 | public ItemEditor() { 60 | Lists.items.stream().forEach((item) -> { model.addElement(item); }); 61 | list.setSelectedIndex(0); 62 | } 63 | 64 | @Override 65 | protected void initProperties() { 66 | setTitle("Item editor"); 67 | 68 | // Initialize the components 69 | try { 70 | icons = ImageIO.read(Main.class.getResourceAsStream("/res/items.png")); 71 | } 72 | catch (IOException ex) { 73 | System.err.print(ex); 74 | } 75 | 76 | lblName = new JLabel("Name"); 77 | lblNamePointer = new JLabel("Name pointer"); 78 | lblDesc = new JLabel("Description"); 79 | lblDescPointer = new JLabel("Description pointer"); 80 | txtName = new JTextField(); 81 | txtName.setEditable(false); 82 | txtNamePointer = new JTextField("00000000"); 83 | txtNamePointer.setEditable(false); 84 | txtDesc = new JTextField(); 85 | txtDesc.setEditable(false); 86 | txtDescPointer = new JTextField("00000000"); 87 | txtDescPointer.setEditable(false); 88 | 89 | lblPreview = new JLabel("Preview: "); 90 | lblPreview.setHorizontalTextPosition(SwingConstants.LEFT); 91 | lblIcon = new JLabel("Icon"); 92 | lblPalette = new JLabel("Palette"); 93 | cmoIcon = new JComboBox(); 94 | cmoIcon.setModel(new DefaultComboBoxModel(new String[] { "Spike", "Stone", "Berry", "Apple", "Ribbon", "Box", "Coin", "Note", "TM", "Gear", "Link Box", "Chestnut", "Healing item", "Glasses", "Seed", "Orb", "Key", "Gummi", "Regi part", "Banana", "Scale", "Thrown spike", "Thrown spike (alt.)", "Flower" })); 95 | cmoIcon.addActionListener((java.awt.event.ActionEvent evt) -> { 96 | updateItemIcon(); 97 | }); 98 | sdrPalette = new JSlider(0, 12); 99 | sdrPalette.setPaintLabels(true); 100 | sdrPalette.setPaintTicks(true); 101 | sdrPalette.setMinorTickSpacing(1); 102 | sdrPalette.setMajorTickSpacing(6); 103 | sdrPalette.addChangeListener((javax.swing.event.ChangeEvent evt) -> { 104 | updateItemIcon(); 105 | }); 106 | 107 | lblShopPrice = new JLabel("Shop price"); 108 | lblSellPrice = new JLabel("Sell price"); 109 | lblOrder = new JLabel("Storage order"); 110 | lblMove = new JLabel("Move"); 111 | lblType = new JLabel("Type"); 112 | lblSubtype = new JLabel("Category"); 113 | spnShopPrice = new JSpinner(); 114 | spnShopPrice.setModel(new SpinnerNumberModel(Long.valueOf(0L), Long.valueOf(0L), Long.valueOf(2147483647L), Long.valueOf(1L))); 115 | spnSellPrice = new JSpinner(); 116 | spnSellPrice.setModel(new SpinnerNumberModel(Long.valueOf(0L), Long.valueOf(0L), Long.valueOf(2147483647L), Long.valueOf(1L))); 117 | spnOrder = new JSpinner(); 118 | spnOrder.setModel(new SpinnerNumberModel(Short.valueOf((short)0), Short.valueOf((short)0), Short.valueOf((short)255), Short.valueOf((short)1))); 119 | cmoMove = new JComboBox(); 120 | cmoMove.setModel(new DefaultComboBoxModel(Lists.moves.toArray())); 121 | cmoType = new JComboBox(); 122 | cmoType.setModel(new DefaultComboBoxModel(new String[] { "Throwable", "Rock", "Berry / Seed", "Apple / Gummi", "Hold item", "TM", "Money", "Unused", "Misc.", "Orb", "Link Box", "Used TM" })); 123 | cmoSubtype = new JComboBox(); 124 | cmoSubtype.setModel(new DefaultComboBoxModel(new String[] { "Nothing", "Throwable", "Rocks", "Ribbons", "Food", "Healing items", "Chestnut", "Money / Wish Stone", "Misc.", "TMs", "Link Box", "Specs", "Scarfs", "Orbs" })); 125 | 126 | lblUnkThrow1 = new JLabel("Unk. throwing factor 1"); 127 | lblUnkThrow2 = new JLabel("Unk. throwing factor 2"); 128 | spnUnkThrow1 = new JSpinner(); 129 | spnUnkThrow1.setModel(new SpinnerNumberModel(Short.valueOf((short)0), Short.valueOf((short)0), Short.valueOf((short)255), Short.valueOf((short)1))); 130 | spnUnkThrow2 = new JSpinner(); 131 | spnUnkThrow2.setModel(new SpinnerNumberModel(Short.valueOf((short)0), Short.valueOf((short)0), Short.valueOf((short)255), Short.valueOf((short)1))); 132 | chkThrowingDamage = new JCheckBox("Throwing damage"); 133 | chkUnkFood1 = new JCheckBox("Unk. food bool 1"); 134 | chkUnkFood2 = new JCheckBox("Unk. food bool 2"); 135 | 136 | // Add the components to the property panel 137 | properties.addCaption("Text"); 138 | properties.addLabeledComponent(lblName, txtName); 139 | properties.addLabeledComponent(lblNamePointer, txtNamePointer); 140 | properties.addLabeledComponent(lblDesc, txtDesc); 141 | properties.addLabeledComponent(lblDescPointer, txtDescPointer); 142 | properties.addSeparator(); 143 | properties.addCaption("Sprite"); 144 | properties.addComponent(lblPreview); 145 | properties.addLabeledComponent(lblIcon, cmoIcon); 146 | properties.addLabeledComponent(lblPalette, sdrPalette); 147 | properties.addSeparator(); 148 | properties.addCaption("Misc."); 149 | properties.addLabeledComponent(lblShopPrice, spnShopPrice); 150 | properties.addLabeledComponent(lblSellPrice, spnSellPrice); 151 | properties.addLabeledComponent(lblOrder, spnOrder); 152 | properties.addLabeledComponent(lblMove, cmoMove); 153 | properties.addLabeledComponent(lblType, cmoType); 154 | properties.addLabeledComponent(lblSubtype, cmoSubtype); 155 | properties.addSeparator(); 156 | properties.addLabeledComponent(lblUnkThrow1, spnUnkThrow1); 157 | properties.addLabeledComponent(lblUnkThrow2, spnUnkThrow2); 158 | properties.addComponent(chkThrowingDamage); 159 | properties.addComponent(chkUnkFood1); 160 | properties.addComponent(chkUnkFood2); 161 | properties.addTerminator(); 162 | } 163 | 164 | @Override 165 | protected void load() { 166 | if (list.getSelectedIndex() < 0) 167 | return; 168 | 169 | selected = (Item) RomFile.current.items.get(list.getSelectedIndex()).clone(); 170 | 171 | txtName.setText(selected.name); 172 | txtName.setCaretPosition(0); 173 | txtDesc.setText(selected.desc); 174 | txtDesc.setCaretPosition(0); 175 | spnShopPrice.setValue(selected.buyPrice); 176 | spnSellPrice.setValue(selected.sellPrice); 177 | spnOrder.setValue(selected.order); 178 | cmoMove.setSelectedIndex(selected.move); 179 | cmoType.setSelectedIndex(selected.type); 180 | cmoSubtype.setSelectedIndex(selected.subtype); 181 | 182 | spnUnkThrow1.setValue(selected.unkThrow1B); 183 | spnUnkThrow2.setValue(selected.unkThrow1C); 184 | chkThrowingDamage.setSelected(selected.throwDamage); 185 | chkUnkFood1.setSelected(selected.unkFood1); 186 | chkUnkFood2.setSelected(selected.unkFood2); 187 | 188 | cmoIcon.setSelectedIndex(selected.icon); 189 | sdrPalette.setValue(selected.palette); 190 | 191 | txtNamePointer.setText(BitConverter.toHexIntString(selected.namePointer)); 192 | txtDescPointer.setText(BitConverter.toHexIntString(selected.descPointer)); 193 | } 194 | 195 | @Override 196 | protected void save() { 197 | if (selected == null || list.getSelectedIndex() < 0) 198 | return; 199 | 200 | selected.buyPrice = (long) spnShopPrice.getValue(); 201 | selected.sellPrice = (long) spnSellPrice.getValue(); 202 | selected.order = (short) spnOrder.getValue(); 203 | selected.move = (short) cmoMove.getSelectedIndex(); 204 | selected.type = (short) cmoType.getSelectedIndex(); 205 | selected.subtype = (short) cmoSubtype.getSelectedIndex(); 206 | 207 | selected.unkThrow1B = (short) spnUnkThrow1.getValue(); 208 | selected.unkThrow1C = (short) spnUnkThrow2.getValue(); 209 | selected.throwDamage = chkThrowingDamage.isSelected(); 210 | selected.unkFood1 = chkUnkFood1.isSelected(); 211 | selected.unkFood2 = chkUnkFood2.isSelected(); 212 | 213 | selected.icon = (short) cmoIcon.getSelectedIndex(); 214 | selected.palette = (short) sdrPalette.getValue(); 215 | 216 | RomFile.current.items.set(list.getSelectedIndex(), selected); 217 | } 218 | 219 | @Override 220 | protected void warningLabel() {} 221 | 222 | private void updateItemIcon() { 223 | lblPreview.setIcon(new ImageIcon(icons.getSubimage(sdrPalette.getValue() * 16, cmoIcon.getSelectedIndex() * 16, 16, 16))); 224 | } 225 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/swing/MoveEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.swing; 19 | 20 | import com.aurum.mystery2.BitConverter; 21 | import com.aurum.mystery2.Lists; 22 | import com.aurum.mystery2.game.Move; 23 | import com.aurum.mystery2.game.RomFile; 24 | import javax.swing.DefaultComboBoxModel; 25 | import javax.swing.JCheckBox; 26 | import javax.swing.JComboBox; 27 | import javax.swing.JLabel; 28 | import javax.swing.JSpinner; 29 | import javax.swing.JTextField; 30 | import javax.swing.SpinnerNumberModel; 31 | 32 | public class MoveEditor extends AbstractEditor { 33 | private Move selected; 34 | 35 | private JLabel lblName, lblNamePointer, lblDescription, lblDescriptionPointer, lblLog, lblLogPointer; 36 | private JLabel lblJapUnk1, lblJapUnk1Pointer, lblJapUnk2, lblJapUnk2Pointer, lblJapNext, lblJapNextPointer; 37 | private JTextField txtName, txtNamePointer, txtDesc, txtDescPointer, txtLog, txtLogPointer; 38 | private JTextField txtJapUnk1, txtJapUnk1Pointer, txtJapUnk2, txtJapUnk2Pointer, txtJapNext, txtJapNextPointer; 39 | 40 | private JLabel lblType, lblRange, lblAP, lblCriticalHit, lblAccuracy1, lblAccuracy2; 41 | private JComboBox cmoType, cmoRange; 42 | private JSpinner spnAP, spnCriticalHit, spnAccuracy1, spnAccuracy2; 43 | 44 | private JLabel lblUnk4, lblUnk8, lblUnkA, lblUnkD, lblUnk10, lblUsesPerRound, lblUnk12; 45 | private JSpinner spnUnk4, spnUnk8, spnUnkA, spnUnkD, spnUnk10, spnUsesPerRound, spnUnk12; 46 | private JCheckBox chkUnk14, chkUnk15, chkUnk16, chkUnk17, chkUnk18; 47 | 48 | public MoveEditor() { 49 | Lists.moves.stream().forEach((item) -> { model.addElement(item); }); 50 | list.setSelectedIndex(0); 51 | } 52 | 53 | @Override 54 | protected void initProperties() { 55 | setTitle("Move editor"); 56 | 57 | // Initialize the components 58 | lblName = new JLabel("Name"); 59 | lblNamePointer = new JLabel("Name pointer"); 60 | lblDescription = new JLabel("Description"); 61 | lblDescriptionPointer = new JLabel("Description pointer"); 62 | lblLog = new JLabel("Log"); 63 | lblLogPointer = new JLabel("Log pointer"); 64 | txtName = new JTextField(); 65 | txtName.setEditable(false); 66 | txtNamePointer = new JTextField("00000000"); 67 | txtNamePointer.setEditable(false); 68 | txtDesc = new JTextField(); 69 | txtDesc.setEditable(false); 70 | txtDescPointer = new JTextField("00000000"); 71 | txtDescPointer.setEditable(false); 72 | txtLog = new JTextField(); 73 | txtLog.setEditable(false); 74 | txtLogPointer = new JTextField("00000000"); 75 | txtLogPointer.setEditable(false); 76 | 77 | if (RomFile.current.isJapanese()) { 78 | lblJapUnk1 = new JLabel("Unk. string 1"); 79 | lblJapUnk1Pointer = new JLabel("Unk. string 1 pointer"); 80 | lblJapUnk2 = new JLabel("Unk. string 2"); 81 | lblJapUnk2Pointer = new JLabel("Unk. string 2 pointer"); 82 | lblJapNext = new JLabel("Next move"); 83 | lblJapNextPointer = new JLabel("Next move pointer"); 84 | 85 | txtJapUnk1 = new JTextField(); 86 | txtJapUnk1.setEditable(false); 87 | txtJapUnk1Pointer = new JTextField("00000000"); 88 | txtJapUnk1Pointer.setEditable(false); 89 | txtJapUnk2 = new JTextField(); 90 | txtJapUnk2.setEditable(false); 91 | txtJapUnk2Pointer = new JTextField("00000000"); 92 | txtJapUnk2Pointer.setEditable(false); 93 | txtJapNext = new JTextField(); 94 | txtJapNext.setEditable(false); 95 | txtJapNextPointer = new JTextField("00000000"); 96 | txtJapNextPointer.setEditable(false); 97 | } 98 | 99 | lblType = new JLabel("Type"); 100 | lblRange = new JLabel("Range"); 101 | lblAP = new JLabel("Attack points"); 102 | lblCriticalHit = new JLabel("Critical Hit chance"); 103 | lblUsesPerRound = new JLabel("Uses per round"); 104 | lblAccuracy1 = new JLabel("Accuracy factor 1"); 105 | lblAccuracy2 = new JLabel("Accuracy factor 2"); 106 | cmoType = new JComboBox(); 107 | cmoType.setModel(new DefaultComboBoxModel(Lists.types.toArray())); 108 | cmoRange = new JComboBox(); 109 | cmoRange.setModel(new DefaultComboBoxModel(new String[] { "None", "3 tiles diagonally and in front", "Foes within 1-tile range", "Foe in front, cuts corners", "Partners on floor(?)", "Partners on floor(?)", "Pokémon on floor", "Foes on floor", "Unknown, unused", "Foe at side", "Special", "Foe in front", "Pokémon at side", "Foe up to 2 tiles ahead", "Foes in line", "Foes in room", "Allies in room", "Pokémon in room", "All except user", "User(?)", "User(?)", "User(?)", "Members in room", "Items", "Floor", "Wall", "Pokémon within 1-tile range", "Pokémon within 2-tiles range", "User, cuts corners", "Floor", "Pokémon in front" })); 110 | spnAP = new JSpinner(); 111 | spnAP.setModel(new SpinnerNumberModel(Short.valueOf((short)0), Short.valueOf((short)0), Short.valueOf((short)255), Short.valueOf((short)1))); 112 | spnCriticalHit = new JSpinner(); 113 | spnCriticalHit.setModel(new SpinnerNumberModel((byte)0, null, null, (byte)1)); 114 | spnUsesPerRound = new JSpinner(); 115 | spnUsesPerRound.setModel(new SpinnerNumberModel(Short.valueOf((short)0), Short.valueOf((short)0), Short.valueOf((short)255), Short.valueOf((short)1))); 116 | spnAccuracy1 = new JSpinner(); 117 | spnAccuracy1.setModel(new SpinnerNumberModel((byte)0, null, null, (byte)1)); 118 | spnAccuracy2 = new JSpinner(); 119 | spnAccuracy2.setModel(new SpinnerNumberModel((byte)0, null, null, (byte)1)); 120 | 121 | lblUnk4 = new JLabel("short (0x4)"); 122 | lblUnk8 = new JLabel("short (0x8)"); 123 | lblUnkA = new JLabel("short (0xA)"); 124 | lblUnkD = new JLabel("byte (0xD)"); 125 | lblUnk10 = new JLabel("byte (0x10)"); 126 | lblUnk12 = new JLabel("byte (0x12)"); 127 | spnUnk4 = new JSpinner(); 128 | spnUnk4.setModel(new SpinnerNumberModel((short)0, null, null, (short)1)); 129 | spnUnk8 = new JSpinner(); 130 | spnUnk8.setModel(new SpinnerNumberModel((short)0, null, null, (short)1)); 131 | spnUnkA = new JSpinner(); 132 | spnUnkA.setModel(new SpinnerNumberModel((short)0, null, null, (short)1)); 133 | spnUnkD = new JSpinner(); 134 | spnUnkD.setModel(new SpinnerNumberModel((byte)0, null, null, (byte)1)); 135 | spnUnk10 = new JSpinner(); 136 | spnUnk10.setModel(new SpinnerNumberModel((byte)0, null, null, (byte)1)); 137 | spnUnk12 = new JSpinner(); 138 | spnUnk12.setModel(new SpinnerNumberModel((byte)0, null, null, (byte)1)); 139 | chkUnk14 = new JCheckBox("bool (0x14)"); 140 | chkUnk15 = new JCheckBox("bool (0x15)"); 141 | chkUnk16 = new JCheckBox("bool (0x16)"); 142 | chkUnk17 = new JCheckBox("bool (0x17)"); 143 | chkUnk18 = new JCheckBox("bool (0x18)"); 144 | 145 | // Add the components to the property panel 146 | properties.addCaption("Text"); 147 | properties.addLabeledComponent(lblName, txtName); 148 | properties.addLabeledComponent(lblNamePointer, txtNamePointer); 149 | properties.addLabeledComponent(lblDescription, txtDesc); 150 | properties.addLabeledComponent(lblDescriptionPointer, txtDescPointer); 151 | properties.addLabeledComponent(lblLog, txtLog); 152 | properties.addLabeledComponent(lblLogPointer, txtLogPointer); 153 | if (RomFile.current.isJapanese()) { 154 | properties.addLabeledComponent(lblJapUnk1, txtJapUnk1); 155 | properties.addLabeledComponent(lblJapUnk1Pointer, txtJapUnk1Pointer); 156 | properties.addLabeledComponent(lblJapUnk2, txtJapUnk2); 157 | properties.addLabeledComponent(lblJapUnk2Pointer, txtJapUnk2Pointer); 158 | properties.addLabeledComponent(lblJapNext, txtJapNext); 159 | properties.addLabeledComponent(lblJapNextPointer, txtJapNextPointer); 160 | } 161 | properties.addSeparator(); 162 | properties.addCaption("Misc."); 163 | properties.addLabeledComponent(lblType, cmoType); 164 | properties.addLabeledComponent(lblRange, cmoRange); 165 | properties.addLabeledComponent(lblAP, spnAP); 166 | properties.addLabeledComponent(lblCriticalHit, spnCriticalHit); 167 | properties.addLabeledComponent(lblUsesPerRound, spnUsesPerRound); 168 | properties.addLabeledComponent(lblAccuracy1, spnAccuracy1); 169 | properties.addLabeledComponent(lblAccuracy2, spnAccuracy2); 170 | properties.addSeparator(); 171 | properties.addCaption("Unknown"); 172 | properties.addLabeledComponent(lblUnk4, spnUnk4); 173 | properties.addLabeledComponent(lblUnk8, spnUnk8); 174 | properties.addLabeledComponent(lblUnkA, spnUnkA); 175 | properties.addLabeledComponent(lblUnkD, spnUnkD); 176 | properties.addLabeledComponent(lblUnk10, spnUnk10); 177 | properties.addLabeledComponent(lblUnk12, spnUnk12); 178 | properties.addComponent(chkUnk14); 179 | properties.addComponent(chkUnk15); 180 | properties.addComponent(chkUnk16); 181 | properties.addComponent(chkUnk17); 182 | properties.addComponent(chkUnk18); 183 | properties.addTerminator(); 184 | } 185 | 186 | @Override 187 | protected void load() { 188 | if (list.getSelectedIndex() < 0) 189 | return; 190 | 191 | selected = (Move) RomFile.current.moves.get(list.getSelectedIndex()).clone(); 192 | 193 | txtName.setText(selected.name); 194 | txtName.setCaretPosition(0); 195 | txtNamePointer.setText(BitConverter.toHexIntString(selected.namePointer)); 196 | txtDesc.setText(selected.desc); 197 | txtDesc.setCaretPosition(0); 198 | txtDescPointer.setText(BitConverter.toHexIntString(selected.descPointer)); 199 | txtLog.setText(selected.log); 200 | txtLog.setCaretPosition(0); 201 | txtLogPointer.setText(BitConverter.toHexIntString(selected.logPointer)); 202 | 203 | cmoType.setSelectedIndex(selected.type); 204 | cmoRange.setSelectedIndex(selected.range); 205 | spnAP.setValue(selected.ap); 206 | spnCriticalHit.setValue(selected.critical); 207 | spnUsesPerRound.setValue(selected.usesPerRound); 208 | spnAccuracy1.setValue(selected.accuracy1); 209 | spnAccuracy2.setValue(selected.accuracy2); 210 | 211 | spnUnk4.setValue(selected.unk4); 212 | spnUnk8.setValue(selected.unk8); 213 | spnUnkA.setValue(selected.unkA); 214 | spnUnkD.setValue(selected.unkD); 215 | spnUnk10.setValue(selected.unk10); 216 | spnUnk12.setValue(selected.unk12); 217 | chkUnk14.setSelected(selected.unk14); 218 | chkUnk15.setSelected(selected.unk15); 219 | chkUnk16.setSelected(selected.unk16); 220 | chkUnk17.setSelected(selected.unk17); 221 | chkUnk18.setSelected(selected.unk18); 222 | 223 | if (RomFile.current.isJapanese()) { 224 | txtJapUnk1.setText(selected.japUnk1); 225 | txtJapUnk1.setCaretPosition(0); 226 | txtJapUnk1Pointer.setText(BitConverter.toHexIntString(selected.japUnk1Pointer)); 227 | txtJapUnk2.setText(selected.japUnk2); 228 | txtJapUnk2.setCaretPosition(0); 229 | txtJapUnk2Pointer.setText(BitConverter.toHexIntString(selected.japUnk2Pointer)); 230 | txtJapNext.setText(selected.japNext); 231 | txtJapNext.setCaretPosition(0); 232 | txtJapNextPointer.setText(BitConverter.toHexIntString(selected.japNextPointer)); 233 | } 234 | } 235 | 236 | @Override 237 | protected void save() { 238 | if (selected == null || list.getSelectedIndex() < 0) 239 | return; 240 | 241 | selected.type = cmoType.getSelectedIndex(); 242 | selected.range = (short) cmoRange.getSelectedIndex(); 243 | selected.ap = (short) spnAP.getValue(); 244 | selected.critical = (byte) spnCriticalHit.getValue(); 245 | selected.usesPerRound = (short) spnUsesPerRound.getValue(); 246 | selected.accuracy1 = (byte) spnAccuracy1.getValue(); 247 | selected.accuracy2 = (byte) spnAccuracy2.getValue(); 248 | 249 | selected.unk4 = (short) spnUnk4.getValue(); 250 | selected.unk8 = (short) spnUnk8.getValue(); 251 | selected.unkA = (short) spnUnkA.getValue(); 252 | selected.unkD = (byte) spnUnkD.getValue(); 253 | selected.unk10 = (byte) spnUnk10.getValue(); 254 | selected.unk12 = (byte) spnUnk12.getValue(); 255 | selected.unk14 = chkUnk14.isSelected(); 256 | selected.unk15 = chkUnk15.isSelected(); 257 | selected.unk16 = chkUnk16.isSelected(); 258 | selected.unk17 = chkUnk17.isSelected(); 259 | selected.unk18 = chkUnk18.isSelected(); 260 | 261 | RomFile.current.moves.set(list.getSelectedIndex(), selected); 262 | } 263 | 264 | @Override 265 | protected void warningLabel() {} 266 | } -------------------------------------------------------------------------------- /src/com/aurum/mystery2/game/RomFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 - 2017 Aurum 3 | * 4 | * Mystery is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Mystery is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | package com.aurum.mystery2.game; 19 | 20 | import com.aurum.mystery2.BitConverter; 21 | import java.io.File; 22 | import java.io.FileInputStream; 23 | import java.io.FileOutputStream; 24 | import java.io.IOException; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | import com.aurum.mystery2.ByteBuffer; 28 | import com.aurum.mystery2.ByteOrder; 29 | import org.ini4j.Ini; 30 | import org.ini4j.Profile.Section; 31 | 32 | public class RomFile { 33 | // Static fields 34 | public static RomFile current; 35 | 36 | // Information about the game 37 | private String romId, romName, romDescription; 38 | private boolean isLoaded, isJapanese; 39 | 40 | // IO stuff 41 | private File file; 42 | private ByteBuffer buffer; 43 | 44 | // Parsed data 45 | public List pokemon; 46 | public List exclusivePokemon; 47 | public List items; 48 | public List moves; 49 | public List areas; 50 | public List dungeons; 51 | public List dungeonLayouts; 52 | public List dungeonPokemon; 53 | public List dungeonItems; 54 | public List dungeonTraps; 55 | public int[] starters, partners; 56 | public long[] moneyfactors; 57 | 58 | // Data offsets 59 | private int dungeonPointerOffset, pokemonPointerOffset, itemPointerOffset; 60 | private int dungeonMainOffset, dungeonFloorsPointerOffset, dungeonMapOffset; 61 | private int pokemonStartersOffset, pokemonPartnersOffset, movesOffset, moneyOffset; 62 | private int areasTextOffset, areasMainOffset, exclusivePokemonOffset; 63 | 64 | private int dungeonDataFloorsOffset, dungeonDataLayoutsOffset, dungeonDataItemsOffset, dungeonDataPokemonOffset, dungeonDataTrapsOffset; 65 | private int pokemonDataOffset, itemDataOffset, dungeonFloorsOffset; 66 | 67 | public RomFile(File f) { 68 | file = f; 69 | } 70 | 71 | public RomFile(String f) { 72 | this(new File(f)); 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return romName + " (" + romId + ')'; 78 | } 79 | 80 | public void setFile(File f) { 81 | file = f; 82 | } 83 | 84 | public File getFile() { 85 | return file; 86 | } 87 | 88 | public String getRomId() { 89 | return romId; 90 | } 91 | 92 | public String getRomName() { 93 | return romName; 94 | } 95 | 96 | public String getRomDescription() { 97 | return romDescription; 98 | } 99 | 100 | public boolean isLoaded() { 101 | return isLoaded; 102 | } 103 | 104 | public boolean isJapanese() { 105 | return isJapanese; 106 | } 107 | 108 | public void load() throws IOException { 109 | // load data into buffer 110 | buffer = new ByteBuffer((int) file.length(), ByteOrder.LITTLE_ENDIAN); 111 | 112 | try (FileInputStream in = new FileInputStream(file)) { 113 | in.read(buffer.getBuffer(), 0, in.available()); 114 | } 115 | 116 | // find ROM ID and name 117 | buffer.seek(0xA0); 118 | romName = buffer.readString(0xC); 119 | romId = buffer.readString(0x6); 120 | 121 | // get offsets and additional information from INI file 122 | File ini = new File("B24_offsets.ini"); 123 | 124 | if (ini.isFile() && ini.exists()) { 125 | Section s = new Ini(ini).get(romId); 126 | 127 | romDescription = s.get("description"); 128 | dungeonPointerOffset = BitConverter.stringToInt(s.get("dungeonPointerOffset")); 129 | pokemonPointerOffset = BitConverter.stringToInt(s.get("pokemonPointerOffset")); 130 | itemPointerOffset = BitConverter.stringToInt(s.get("itemPointerOffset")); 131 | dungeonMainOffset = BitConverter.stringToInt(s.get("dungeonMainOffset")); 132 | dungeonFloorsPointerOffset = BitConverter.stringToInt(s.get("dungeonFloorsPointerOffset")); 133 | dungeonMapOffset = BitConverter.stringToInt(s.get("dungeonMapOffset")); 134 | pokemonStartersOffset = BitConverter.stringToInt(s.get("pokemonStartersOffset")); 135 | pokemonPartnersOffset = BitConverter.stringToInt(s.get("pokemonPartnersOffset")); 136 | movesOffset = BitConverter.stringToInt(s.get("movesOffset")); 137 | moneyOffset = BitConverter.stringToInt(s.get("moneyOffset")); 138 | areasTextOffset = BitConverter.stringToInt(s.get("areasTextOffset")); 139 | areasMainOffset = BitConverter.stringToInt(s.get("areasMainOffset")); 140 | exclusivePokemonOffset = BitConverter.stringToInt(s.get("exclusivePokemonOffset")); 141 | isJapanese = Boolean.parseBoolean(s.get("isJapanese")); 142 | isLoaded = true; 143 | } 144 | else { 145 | romDescription = "Unknown game"; 146 | isJapanese = false; 147 | isLoaded = false; 148 | } 149 | } 150 | 151 | public void save() throws IOException { 152 | // major check for potential null pointers 153 | if (!isLoaded) 154 | return; 155 | 156 | // storage of data 157 | storeDungeons(); 158 | storeStarters(); 159 | storePokemon(); 160 | storeItems(); 161 | storeMoves(); 162 | storeAreas(); 163 | storeExclusivePokemon(); 164 | storeMoneyFactors(); 165 | 166 | // create file if it does not exist 167 | if (!(file.exists() && file.isFile())) { 168 | file.getParentFile().mkdirs(); 169 | file.createNewFile(); 170 | } 171 | 172 | // finally, write bytes to file 173 | try (FileOutputStream out = new FileOutputStream(file)) { 174 | out.write(buffer.getBuffer()); 175 | out.flush(); 176 | } 177 | } 178 | 179 | public void loadStarters() { 180 | starters = new int[27]; 181 | partners = new int[11]; 182 | 183 | buffer.seek(pokemonStartersOffset); 184 | for (int i = 0 ; i < 27 ; i++) 185 | starters[i] = buffer.readUnsignedShort(); 186 | 187 | buffer.seek(pokemonPartnersOffset); 188 | for (int i = 0 ; i < 11 ; i++) 189 | partners[i] = buffer.readUnsignedShort(); 190 | } 191 | 192 | public void storeStarters() { 193 | if (starters == null || partners == null) 194 | return; 195 | 196 | buffer.seek(pokemonStartersOffset); 197 | for (int starter : starters) 198 | buffer.writeUnsignedShort(starter); 199 | 200 | buffer.seek(pokemonPartnersOffset); 201 | for (int partner : partners) 202 | buffer.writeUnsignedShort(partner); 203 | } 204 | 205 | public void loadPokemon() { 206 | pokemon = new ArrayList(); 207 | 208 | buffer.seek(pokemonPointerOffset); 209 | buffer.skip(0x4); 210 | buffer.seek(pokemonDataOffset = buffer.readPointerAsOffset()); 211 | 212 | for (int i = 0 ; i < 424; i++) 213 | pokemon.add(Pokemon.unpack(buffer)); 214 | } 215 | 216 | public void storePokemon() { 217 | if (pokemon == null) 218 | return; 219 | 220 | buffer.seek(pokemonDataOffset); 221 | 222 | for (int i = 0 ; i < 424; i++) 223 | buffer.writeBytes(Pokemon.pack(pokemon.get(i))); 224 | } 225 | 226 | public void loadItems() { 227 | items = new ArrayList(); 228 | 229 | buffer.seek(itemPointerOffset); 230 | buffer.skip(0x4); 231 | buffer.seek(itemDataOffset = buffer.readPointerAsOffset()); 232 | 233 | for (int i = 0 ; i < 240 ; i++) 234 | items.add(Item.unpack(buffer)); 235 | } 236 | 237 | public void storeItems() { 238 | if (items == null) 239 | return; 240 | 241 | buffer.seek(itemDataOffset); 242 | 243 | for (int i = 0 ; i < 240 ; i++) 244 | buffer.writeBytes(Item.pack(items.get(i))); 245 | } 246 | 247 | public void loadMoves() { 248 | moves = new ArrayList(); 249 | 250 | buffer.seek(movesOffset); 251 | for (int i = 0 ; i < 413 ; i++) 252 | moves.add(Move.unpack(buffer)); 253 | } 254 | 255 | public void storeMoves() { 256 | if (moves == null) 257 | return; 258 | 259 | buffer.seek(movesOffset); 260 | for (int i = 0 ; i < 413 ; i++) 261 | buffer.writeBytes(Move.pack(moves.get(i))); 262 | } 263 | 264 | public void loadAreas() { 265 | areas = new ArrayList(); 266 | 267 | for (int i = 0 ; i < 58 ; i++) { 268 | // General data 269 | buffer.seek(areasMainOffset + i * Area.SIZE); 270 | Area area = Area.unpack(buffer); 271 | 272 | // Text data 273 | if (areasTextOffset != 0x00000000) { 274 | area.namePointer = buffer.readIntAt(areasTextOffset + i * 0x4); 275 | area.name = buffer.readStringAt(BitConverter.pointerToOffset(area.namePointer)); 276 | } 277 | 278 | areas.add(area); 279 | } 280 | } 281 | 282 | public void storeAreas() { 283 | if (areas == null) 284 | return; 285 | 286 | buffer.seek(areasMainOffset); 287 | for (int i = 0 ; i < 58 ; i++) 288 | buffer.writeBytes(Area.pack(areas.get(i))); 289 | } 290 | 291 | public void loadExclusivePokemon() { 292 | exclusivePokemon = new ArrayList(); 293 | 294 | buffer.seek(exclusivePokemonOffset); 295 | for (int i = 0 ; i < 12 ; i++) 296 | exclusivePokemon.add(ExclusivePokemon.unpack(buffer)); 297 | } 298 | 299 | public void storeExclusivePokemon() { 300 | if (exclusivePokemon == null) 301 | return; 302 | 303 | buffer.seek(exclusivePokemonOffset); 304 | for (int i = 0 ; i < 12 ; i++) 305 | buffer.writeBytes(ExclusivePokemon.pack(exclusivePokemon.get(i))); 306 | } 307 | 308 | public void loadMoneyFactors() { 309 | moneyfactors = new long[100]; 310 | 311 | buffer.seek(moneyOffset); 312 | for (int i = 0 ; i < 100 ; i++) 313 | moneyfactors[i] = buffer.readUnsignedInt(); 314 | } 315 | 316 | public void storeMoneyFactors() { 317 | if (moneyfactors == null) 318 | return; 319 | 320 | buffer.seek(moneyOffset); 321 | for (long moneyfactor : moneyfactors) 322 | buffer.writeUnsignedInt(moneyfactor); 323 | } 324 | 325 | public void loadDungeons() { 326 | dungeons = new ArrayList(); 327 | dungeonLayouts = new ArrayList(); 328 | dungeonPokemon = new ArrayList(); 329 | dungeonItems = new ArrayList(); 330 | dungeonTraps = new ArrayList(); 331 | 332 | // Main pointer offsets 333 | buffer.seek(dungeonPointerOffset); 334 | buffer.skip(0x4); 335 | buffer.seek(buffer.readPointerAsOffset()); 336 | dungeonDataFloorsOffset = buffer.readPointerAsOffset(); 337 | dungeonDataLayoutsOffset = buffer.readPointerAsOffset(); 338 | dungeonDataItemsOffset = buffer.readPointerAsOffset(); 339 | dungeonDataPokemonOffset = buffer.readPointerAsOffset(); 340 | dungeonDataTrapsOffset = buffer.readPointerAsOffset(); 341 | 342 | // General dungeon entries 343 | buffer.seek(dungeonMainOffset); 344 | for (int i = 0 ; i < 98 ; i++) { 345 | dungeons.add(Dungeon.unpack(buffer)); 346 | } 347 | 348 | // Dungeon floor entries and map coordinates 349 | buffer.seek(dungeonFloorsPointerOffset); 350 | dungeonFloorsOffset = buffer.readPointerAsOffset(); 351 | 352 | for (int i = 0 ; i < 64 ; i++) { 353 | Dungeon dungeon = dungeons.get(i); 354 | 355 | // Find the map points 356 | buffer.seek(dungeonMapOffset + i * 0x4); 357 | dungeon.mapX = buffer.readUnsignedShort(); 358 | dungeon.mapY = buffer.readUnsignedShort(); 359 | 360 | // Find the number of floors first 361 | dungeon.floorsCount = buffer.readUnsignedByteAt(dungeonFloorsOffset + i); 362 | 363 | // Load the actual floors 364 | buffer.seek(dungeonDataFloorsOffset + i * 0x4); 365 | buffer.seek(dungeon.floorsOffset = buffer.readPointerAsOffset()); 366 | for (int f = 0 ; f < dungeon.floorsCount ; f++) 367 | dungeon.floors.add(Floor.unpack(buffer)); 368 | } 369 | 370 | // Dungeon layout entries 371 | buffer.seek(dungeonDataLayoutsOffset); 372 | for (int i = 0 ; i < 1764 ; i++) { 373 | dungeonLayouts.add(DungeonLayout.unpack(buffer)); 374 | } 375 | 376 | // Dungeon pokemon entries 377 | for (int i = 0 ; i < 839 ; i++) { 378 | buffer.seek(dungeonDataPokemonOffset + i * 0x4); 379 | buffer.seek(buffer.readPointerAsOffset()); 380 | dungeonPokemon.add(DungeonPokemon.unpack(buffer)); 381 | } 382 | 383 | // Dungeon items entries 384 | for (int i = 0 ; i < 178 ; i++) { 385 | buffer.seek(dungeonDataItemsOffset + i * 0x4); 386 | buffer.seek(buffer.readPointerAsOffset()); 387 | dungeonItems.add(DungeonItems.unpack(buffer)); 388 | } 389 | 390 | // Dungeon traps entries 391 | for (int i = 0 ; i < 148 ; i++) { 392 | buffer.seek(dungeonDataTrapsOffset + i * 0x4); 393 | buffer.seek(buffer.readPointerAsOffset()); 394 | dungeonTraps.add(DungeonTraps.unpack(buffer)); 395 | } 396 | } 397 | 398 | public void storeDungeons() { 399 | if (dungeons == null) 400 | return; 401 | 402 | // General dungeon entries 403 | for (int i = 0 ; i < 98 ; i++) { 404 | Dungeon dungeon = dungeons.get(i); 405 | 406 | // Write map coordinates for actual dungeons only 407 | if (i < 64) { 408 | buffer.seek(dungeonMapOffset + i * 0x4); 409 | buffer.writeUnsignedShort(dungeon.mapX); 410 | buffer.writeUnsignedShort(dungeon.mapY); 411 | } 412 | 413 | // Write floor entries if available 414 | if (dungeon.floors.size() >= 0) { 415 | buffer.seek(dungeon.floorsOffset); 416 | for (Floor floor : dungeon.floors) 417 | buffer.writeBytes(Floor.pack(floor)); 418 | } 419 | 420 | buffer.writeBytesAt(dungeonMainOffset + i * Dungeon.SIZE, Dungeon.pack(dungeon)); 421 | } 422 | 423 | // Dungeon layout entries 424 | buffer.seek(dungeonDataLayoutsOffset); 425 | for (int i = 0 ; i < 1764 ; i++) { 426 | DungeonLayout layout = dungeonLayouts.get(i); 427 | buffer.writeBytes(DungeonLayout.pack(layout)); 428 | } 429 | 430 | // Dungeon pokemon entries 431 | for (int i = 0 ; i < 839 ; i++) { 432 | DungeonPokemon dunmons = dungeonPokemon.get(i); 433 | buffer.writeBytesAt(dunmons.offset, DungeonPokemon.pack(dunmons)); 434 | } 435 | 436 | // Dungeon items entries 437 | /*for (int i = 0 ; i < 178 ; i++) { 438 | DungeonItems dunitems = dungeonItems.get(i); 439 | buffer.writeBytesAt(dunitems.offset, DungeonItems.pack(dunitems)); 440 | }*/ 441 | 442 | // Dungeon traps entries 443 | for (int i = 0 ; i < 148 ; i++) { 444 | DungeonTraps duntraps = dungeonTraps.get(i); 445 | buffer.writeBytesAt(duntraps.offset, DungeonTraps.pack(duntraps)); 446 | } 447 | } 448 | } --------------------------------------------------------------------------------